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 moves to/from AX_REG into xchg with -Oz.
3248 [(set (match_operand:SWI48 0 "general_reg_operand")
3249 (match_operand:SWI48 1 "general_reg_operand"))]
3251 && ((REGNO (operands[0]) == AX_REG)
3252 != (REGNO (operands[1]) == AX_REG))
3253 && optimize_insn_for_size_p ()
3254 && peep2_reg_dead_p (1, operands[1])"
3255 [(parallel [(set (match_dup 0) (match_dup 1))
3256 (set (match_dup 1) (match_dup 0))])])
3258 (define_expand "movstrict<mode>"
3259 [(set (strict_low_part (match_operand:SWI12 0 "register_operand"))
3260 (match_operand:SWI12 1 "general_operand"))]
3263 gcc_assert (SUBREG_P (operands[0]));
3264 if ((TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun))
3265 || !VALID_INT_MODE_P (GET_MODE (SUBREG_REG (operands[0]))))
3269 (define_insn "*movstrict<mode>_1"
3270 [(set (strict_low_part
3271 (match_operand:SWI12 0 "register_operand" "+<r>"))
3272 (match_operand:SWI12 1 "general_operand" "<r>mn"))]
3273 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
3274 "mov{<imodesuffix>}\t{%1, %0|%0, %1}"
3275 [(set_attr "type" "imov")
3276 (set_attr "mode" "<MODE>")])
3278 (define_insn "*movstrict<mode>_xor"
3279 [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>"))
3280 (match_operand:SWI12 1 "const0_operand"))
3281 (clobber (reg:CC FLAGS_REG))]
3283 "xor{<imodesuffix>}\t%0, %0"
3284 [(set_attr "type" "alu1")
3285 (set_attr "mode" "<MODE>")
3286 (set_attr "length_immediate" "0")])
3288 (define_expand "extv<mode>"
3289 [(set (match_operand:SWI24 0 "register_operand")
3290 (sign_extract:SWI24 (match_operand:SWI24 1 "register_operand")
3291 (match_operand:SI 2 "const_int_operand")
3292 (match_operand:SI 3 "const_int_operand")))]
3295 /* Handle extractions from %ah et al. */
3296 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
3299 unsigned int regno = reg_or_subregno (operands[1]);
3301 /* Be careful to expand only with registers having upper parts. */
3302 if (regno <= LAST_VIRTUAL_REGISTER && !QI_REGNO_P (regno))
3303 operands[1] = copy_to_reg (operands[1]);
3306 (define_insn "*extv<mode>"
3307 [(set (match_operand:SWI24 0 "register_operand" "=R")
3308 (sign_extract:SWI24 (match_operand 1 "int248_register_operand" "Q")
3312 "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
3313 [(set_attr "type" "imovx")
3314 (set_attr "mode" "SI")])
3316 (define_expand "extzv<mode>"
3317 [(set (match_operand:SWI248 0 "register_operand")
3318 (zero_extract:SWI248 (match_operand:SWI248 1 "register_operand")
3319 (match_operand:SI 2 "const_int_operand")
3320 (match_operand:SI 3 "const_int_operand")))]
3323 if (ix86_expand_pextr (operands))
3326 /* Handle extractions from %ah et al. */
3327 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
3330 unsigned int regno = reg_or_subregno (operands[1]);
3332 /* Be careful to expand only with registers having upper parts. */
3333 if (regno <= LAST_VIRTUAL_REGISTER && !QI_REGNO_P (regno))
3334 operands[1] = copy_to_reg (operands[1]);
3337 (define_insn "*extzv<mode>"
3338 [(set (match_operand:SWI248 0 "register_operand" "=R")
3339 (zero_extract:SWI248 (match_operand 1 "int248_register_operand" "Q")
3343 "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
3344 [(set_attr "type" "imovx")
3345 (set_attr "mode" "SI")])
3347 (define_insn "*extzvqi_mem_rex64"
3348 [(set (match_operand:QI 0 "norex_memory_operand" "=Bn")
3350 (match_operator:SWI248 2 "extract_operator"
3351 [(match_operand 1 "int248_register_operand" "Q")
3353 (const_int 8)]) 0))]
3354 "TARGET_64BIT && reload_completed"
3355 "mov{b}\t{%h1, %0|%0, %h1}"
3356 [(set_attr "type" "imov")
3357 (set_attr "mode" "QI")])
3359 (define_insn "*extzvqi"
3360 [(set (match_operand:QI 0 "nonimmediate_operand" "=QBc,?R,m")
3362 (match_operator:SWI248 2 "extract_operator"
3363 [(match_operand 1 "int248_register_operand" "Q,Q,Q")
3365 (const_int 8)]) 0))]
3368 switch (get_attr_type (insn))
3371 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
3373 return "mov{b}\t{%h1, %0|%0, %h1}";
3376 [(set_attr "isa" "*,*,nox64")
3378 (if_then_else (and (match_operand:QI 0 "register_operand")
3379 (ior (not (match_operand:QI 0 "QIreg_operand"))
3380 (match_test "TARGET_MOVX")))
3381 (const_string "imovx")
3382 (const_string "imov")))
3384 (if_then_else (eq_attr "type" "imovx")
3386 (const_string "QI")))])
3389 [(set (match_operand:QI 0 "register_operand")
3391 (match_operator:SWI248 3 "extract_operator"
3392 [(match_operand 1 "int248_register_operand")
3395 (set (match_operand:QI 2 "norex_memory_operand") (match_dup 0))]
3397 && peep2_reg_dead_p (2, operands[0])"
3403 (const_int 8)]) 0))])
3405 (define_expand "insv<mode>"
3406 [(set (zero_extract:SWI248 (match_operand:SWI248 0 "register_operand")
3407 (match_operand:SI 1 "const_int_operand")
3408 (match_operand:SI 2 "const_int_operand"))
3409 (match_operand:SWI248 3 "register_operand"))]
3414 if (ix86_expand_pinsr (operands))
3417 /* Handle insertions to %ah et al. */
3418 if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
3421 unsigned int regno = reg_or_subregno (operands[0]);
3423 /* Be careful to expand only with registers having upper parts. */
3424 if (regno <= LAST_VIRTUAL_REGISTER && !QI_REGNO_P (regno))
3425 dst = copy_to_reg (operands[0]);
3429 emit_insn (gen_insv_1 (<MODE>mode, dst, operands[3]));
3431 /* Fix up the destination if needed. */
3432 if (dst != operands[0])
3433 emit_move_insn (operands[0], dst);
3438 (define_insn "*insvqi_1_mem_rex64"
3439 [(set (zero_extract:SWI248
3440 (match_operand 0 "int248_register_operand" "+Q")
3444 (match_operand:QI 1 "norex_memory_operand" "Bn") 0))]
3445 "TARGET_64BIT && reload_completed"
3446 "mov{b}\t{%1, %h0|%h0, %1}"
3447 [(set_attr "type" "imov")
3448 (set_attr "mode" "QI")])
3450 (define_insn "@insv<mode>_1"
3451 [(set (zero_extract:SWI248
3452 (match_operand 0 "int248_register_operand" "+Q,Q")
3455 (match_operand:SWI248 1 "general_operand" "QnBc,m"))]
3458 if (CONST_INT_P (operands[1]))
3459 operands[1] = gen_int_mode (INTVAL (operands[1]), QImode);
3460 return "mov{b}\t{%b1, %h0|%h0, %b1}";
3462 [(set_attr "isa" "*,nox64")
3463 (set_attr "type" "imov")
3464 (set_attr "mode" "QI")])
3466 (define_insn "*insvqi_1"
3467 [(set (zero_extract:SWI248
3468 (match_operand 0 "int248_register_operand" "+Q,Q")
3472 (match_operand:QI 1 "general_operand" "QnBc,m") 0))]
3474 "mov{b}\t{%1, %h0|%h0, %1}"
3475 [(set_attr "isa" "*,nox64")
3476 (set_attr "type" "imov")
3477 (set_attr "mode" "QI")])
3480 [(set (match_operand:QI 0 "register_operand")
3481 (match_operand:QI 1 "norex_memory_operand"))
3482 (set (zero_extract:SWI248 (match_operand 2 "int248_register_operand")
3485 (subreg:SWI248 (match_dup 0) 0))]
3487 && peep2_reg_dead_p (2, operands[0])"
3488 [(set (zero_extract:SWI248 (match_dup 2)
3491 (subreg:SWI248 (match_dup 1) 0))])
3493 ;; Eliminate redundant insv, e.g. xorl %eax,%eax; movb $0, %ah
3495 [(parallel [(set (match_operand:SWI48 0 "general_reg_operand")
3497 (clobber (reg:CC FLAGS_REG))])
3498 (set (zero_extract:SWI248 (match_operand 1 "int248_register_operand")
3502 "REGNO (operands[0]) == REGNO (operands[1])"
3503 [(parallel [(set (match_operand:SWI48 0 "general_reg_operand")
3505 (clobber (reg:CC FLAGS_REG))])])
3507 ;; Combine movl followed by movb.
3509 [(set (match_operand:SWI48 0 "general_reg_operand")
3510 (match_operand:SWI48 1 "const_int_operand"))
3511 (set (zero_extract:SWI248 (match_operand 2 "int248_register_operand")
3514 (match_operand:SWI248 3 "const_int_operand"))]
3515 "REGNO (operands[0]) == REGNO (operands[2])"
3516 [(set (match_operand:SWI48 0 "general_reg_operand")
3519 HOST_WIDE_INT tmp = INTVAL (operands[1]) & ~(HOST_WIDE_INT)0xff00;
3520 tmp |= (INTVAL (operands[3]) & 0xff) << 8;
3521 operands[4] = gen_int_mode (tmp, <SWI48:MODE>mode);
3524 (define_insn "*insvqi_2"
3525 [(set (zero_extract:SWI248
3526 (match_operand 0 "int248_register_operand" "+Q")
3529 (match_operator:SWI248 2 "extract_operator"
3530 [(match_operand 1 "int248_register_operand" "Q")
3534 "mov{b}\t{%h1, %h0|%h0, %h1}"
3535 [(set_attr "type" "imov")
3536 (set_attr "mode" "QI")])
3538 (define_insn "*insvqi_3"
3539 [(set (zero_extract:SWI248
3540 (match_operand 0 "int248_register_operand" "+Q")
3544 (match_operand:SWI248 1 "register_operand" "Q")
3547 "mov{b}\t{%h1, %h0|%h0, %h1}"
3548 [(set_attr "type" "imov")
3549 (set_attr "mode" "QI")])
3551 (define_code_iterator any_or_plus [plus ior xor])
3553 (define_insn_and_split "*insvti_highpart_1"
3554 [(set (match_operand:TI 0 "nonimmediate_operand" "=ro,r,r,&r")
3557 (match_operand:TI 1 "nonimmediate_operand" "r,m,r,m")
3558 (match_operand:TI 3 "const_scalar_int_operand" "n,n,n,n"))
3561 (match_operand:DI 2 "nonimmediate_operand" "r,r,m,m"))
3564 && CONST_WIDE_INT_P (operands[3])
3565 && CONST_WIDE_INT_NUNITS (operands[3]) == 2
3566 && CONST_WIDE_INT_ELT (operands[3], 0) == -1
3567 && CONST_WIDE_INT_ELT (operands[3], 1) == 0"
3569 "&& reload_completed"
3572 operands[4] = gen_lowpart (DImode, operands[1]);
3573 split_double_concat (TImode, operands[0], operands[4], operands[2]);
3577 ;; Floating point push instructions.
3579 (define_insn "*pushtf"
3580 [(set (match_operand:TF 0 "push_operand" "=<,<")
3581 (match_operand:TF 1 "general_no_elim_operand" "v,*roC"))]
3582 "TARGET_64BIT || TARGET_SSE"
3584 /* This insn should be already split before reg-stack. */
3587 [(set_attr "isa" "*,x64")
3588 (set_attr "type" "multi")
3589 (set_attr "unit" "sse,*")
3590 (set_attr "mode" "TF,DI")])
3592 ;; %%% Kill this when call knows how to work this out.
3594 [(set (match_operand:TF 0 "push_operand")
3595 (match_operand:TF 1 "sse_reg_operand"))]
3596 "TARGET_SSE && reload_completed"
3597 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -16)))
3598 (set (match_dup 0) (match_dup 1))]
3600 /* Preserve memory attributes. */
3601 operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
3604 (define_insn "*pushxf"
3605 [(set (match_operand:XF 0 "push_operand" "=<,<,<,<,<")
3606 (match_operand:XF 1 "general_no_elim_operand" "f,r,*r,oF,oC"))]
3609 /* This insn should be already split before reg-stack. */
3612 [(set_attr "isa" "*,*,*,nox64,x64")
3613 (set_attr "type" "multi")
3614 (set_attr "unit" "i387,*,*,*,*")
3616 (cond [(eq_attr "alternative" "1,2,3,4")
3617 (if_then_else (match_test "TARGET_64BIT")
3619 (const_string "SI"))
3621 (const_string "XF")))
3622 (set (attr "preferred_for_size")
3623 (cond [(eq_attr "alternative" "1")
3624 (symbol_ref "false")]
3625 (symbol_ref "true")))])
3627 ;; %%% Kill this when call knows how to work this out.
3629 [(set (match_operand:XF 0 "push_operand")
3630 (match_operand:XF 1 "fp_register_operand"))]
3632 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
3633 (set (match_dup 0) (match_dup 1))]
3635 operands[2] = GEN_INT (-PUSH_ROUNDING (GET_MODE_SIZE (XFmode)));
3636 /* Preserve memory attributes. */
3637 operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
3640 (define_insn "*pushdf"
3641 [(set (match_operand:DF 0 "push_operand" "=<,<,<,<,<,<")
3642 (match_operand:DF 1 "general_no_elim_operand" "f,r,*r,oF,rmC,v"))]
3645 /* This insn should be already split before reg-stack. */
3648 [(set_attr "isa" "*,nox64,nox64,nox64,x64,sse2")
3649 (set_attr "type" "multi")
3650 (set_attr "unit" "i387,*,*,*,*,sse")
3651 (set_attr "mode" "DF,SI,SI,SI,DI,DF")
3652 (set (attr "preferred_for_size")
3653 (cond [(eq_attr "alternative" "1")
3654 (symbol_ref "false")]
3655 (symbol_ref "true")))
3656 (set (attr "preferred_for_speed")
3657 (cond [(eq_attr "alternative" "1")
3658 (symbol_ref "TARGET_INTEGER_DFMODE_MOVES")]
3659 (symbol_ref "true")))])
3661 ;; %%% Kill this when call knows how to work this out.
3663 [(set (match_operand:DF 0 "push_operand")
3664 (match_operand:DF 1 "any_fp_register_operand"))]
3666 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
3667 (set (match_dup 0) (match_dup 1))]
3669 /* Preserve memory attributes. */
3670 operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
3673 (define_mode_iterator HFBF [HF BF])
3675 (define_insn "*push<mode>_rex64"
3676 [(set (match_operand:HFBF 0 "push_operand" "=X,X")
3677 (match_operand:HFBF 1 "nonmemory_no_elim_operand" "r,x"))]
3680 /* Anything else should be already split before reg-stack. */
3681 gcc_assert (which_alternative == 0);
3682 return "push{q}\t%q1";
3684 [(set_attr "isa" "*,sse4")
3685 (set_attr "type" "push,multi")
3686 (set_attr "mode" "DI,TI")])
3688 (define_insn "*push<mode>"
3689 [(set (match_operand:HFBF 0 "push_operand" "=X,X")
3690 (match_operand:HFBF 1 "general_no_elim_operand" "rmF,x"))]
3693 /* Anything else should be already split before reg-stack. */
3694 gcc_assert (which_alternative == 0);
3695 return "push{l}\t%k1";
3697 [(set_attr "isa" "*,sse4")
3698 (set_attr "type" "push,multi")
3699 (set_attr "mode" "SI,TI")])
3701 (define_insn "*pushsf_rex64"
3702 [(set (match_operand:SF 0 "push_operand" "=X,X,X")
3703 (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,v"))]
3706 /* Anything else should be already split before reg-stack. */
3707 if (which_alternative != 1)
3709 return "push{q}\t%q1";
3711 [(set_attr "type" "multi,push,multi")
3712 (set_attr "unit" "i387,*,*")
3713 (set_attr "mode" "SF,DI,SF")])
3715 (define_insn "*pushsf"
3716 [(set (match_operand:SF 0 "push_operand" "=<,<,<")
3717 (match_operand:SF 1 "general_no_elim_operand" "f,rmF,v"))]
3720 /* Anything else should be already split before reg-stack. */
3721 if (which_alternative != 1)
3723 return "push{l}\t%1";
3725 [(set_attr "type" "multi,push,multi")
3726 (set_attr "unit" "i387,*,*")
3727 (set_attr "mode" "SF,SI,SF")])
3729 (define_mode_iterator MODESH [SF HF BF])
3730 ;; %%% Kill this when call knows how to work this out.
3732 [(set (match_operand:MODESH 0 "push_operand")
3733 (match_operand:MODESH 1 "any_fp_register_operand"))]
3735 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
3736 (set (match_dup 0) (match_dup 1))]
3738 rtx op = XEXP (operands[0], 0);
3739 if (GET_CODE (op) == PRE_DEC)
3741 gcc_assert (!TARGET_64BIT);
3746 op = XEXP (XEXP (op, 1), 1);
3747 gcc_assert (CONST_INT_P (op));
3750 /* Preserve memory attributes. */
3751 operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
3755 [(set (match_operand:SF 0 "push_operand")
3756 (match_operand:SF 1 "memory_operand"))]
3758 && find_constant_src (insn)"
3759 [(set (match_dup 0) (match_dup 2))]
3760 "operands[2] = find_constant_src (curr_insn);")
3763 [(set (match_operand 0 "push_operand")
3764 (match_operand 1 "general_gr_operand"))]
3766 && (GET_MODE (operands[0]) == TFmode
3767 || GET_MODE (operands[0]) == XFmode
3768 || GET_MODE (operands[0]) == DFmode)"
3770 "ix86_split_long_move (operands); DONE;")
3772 ;; Floating point move instructions.
3774 (define_expand "movtf"
3775 [(set (match_operand:TF 0 "nonimmediate_operand")
3776 (match_operand:TF 1 "nonimmediate_operand"))]
3777 "TARGET_64BIT || TARGET_SSE"
3778 "ix86_expand_move (TFmode, operands); DONE;")
3780 (define_expand "mov<mode>"
3781 [(set (match_operand:X87MODEFH 0 "nonimmediate_operand")
3782 (match_operand:X87MODEFH 1 "general_operand"))]
3784 "ix86_expand_move (<MODE>mode, operands); DONE;")
3786 (define_insn "*movtf_internal"
3787 [(set (match_operand:TF 0 "nonimmediate_operand" "=v,v ,m,?*r ,!o")
3788 (match_operand:TF 1 "general_operand" "C ,vm,v,*roF,*rC"))]
3789 "(TARGET_64BIT || TARGET_SSE)
3790 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3791 && (lra_in_progress || reload_completed
3792 || !CONST_DOUBLE_P (operands[1])
3793 || (standard_sse_constant_p (operands[1], TFmode) == 1
3794 && !memory_operand (operands[0], TFmode))
3795 || (!TARGET_MEMORY_MISMATCH_STALL
3796 && memory_operand (operands[0], TFmode)))"
3798 switch (get_attr_type (insn))
3801 return standard_sse_constant_opcode (insn, operands);
3804 return ix86_output_ssemov (insn, operands);
3813 [(set_attr "isa" "*,*,*,x64,x64")
3814 (set_attr "type" "sselog1,ssemov,ssemov,multi,multi")
3815 (set (attr "prefix")
3816 (if_then_else (eq_attr "type" "sselog1,ssemov")
3817 (const_string "maybe_vex")
3818 (const_string "orig")))
3820 (cond [(eq_attr "alternative" "3,4")
3822 (match_test "TARGET_AVX")
3824 (ior (not (match_test "TARGET_SSE2"))
3825 (match_test "optimize_function_for_size_p (cfun)"))
3826 (const_string "V4SF")
3827 (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
3828 (const_string "V4SF")
3829 (and (eq_attr "alternative" "2")
3830 (match_test "TARGET_SSE_TYPELESS_STORES"))
3831 (const_string "V4SF")
3833 (const_string "TI")))])
3836 [(set (match_operand:TF 0 "nonimmediate_gr_operand")
3837 (match_operand:TF 1 "general_gr_operand"))]
3840 "ix86_split_long_move (operands); DONE;")
3842 ;; Possible store forwarding (partial memory) stall
3843 ;; in alternatives 4, 6, 7 and 8.
3844 (define_insn "*movxf_internal"
3845 [(set (match_operand:XF 0 "nonimmediate_operand"
3846 "=f,m,f,?r ,!o,?*r ,!o,!o,!o,r ,o ,o")
3847 (match_operand:XF 1 "general_operand"
3848 "fm,f,G,roF,r ,*roF,*r,F ,C ,roF,rF,rC"))]
3849 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3850 && (lra_in_progress || reload_completed
3851 || !CONST_DOUBLE_P (operands[1])
3852 || ((optimize_function_for_size_p (cfun)
3853 || (ix86_cmodel == CM_LARGE || ix86_cmodel == CM_LARGE_PIC))
3854 && standard_80387_constant_p (operands[1]) > 0
3855 && !memory_operand (operands[0], XFmode))
3856 || (!TARGET_MEMORY_MISMATCH_STALL
3857 && memory_operand (operands[0], XFmode))
3858 || !TARGET_HARD_XF_REGS)"
3860 switch (get_attr_type (insn))
3863 if (which_alternative == 2)
3864 return standard_80387_constant_opcode (operands[1]);
3865 return output_387_reg_move (insn, operands);
3875 (cond [(eq_attr "alternative" "7,10")
3876 (const_string "nox64")
3877 (eq_attr "alternative" "8,11")
3878 (const_string "x64")
3880 (const_string "*")))
3882 (cond [(eq_attr "alternative" "3,4,5,6,7,8,9,10,11")
3883 (const_string "multi")
3885 (const_string "fmov")))
3887 (cond [(eq_attr "alternative" "3,4,5,6,7,8,9,10,11")
3888 (if_then_else (match_test "TARGET_64BIT")
3890 (const_string "SI"))
3892 (const_string "XF")))
3893 (set (attr "preferred_for_size")
3894 (cond [(eq_attr "alternative" "3,4")
3895 (symbol_ref "false")]
3896 (symbol_ref "true")))
3897 (set (attr "enabled")
3898 (cond [(eq_attr "alternative" "9,10,11")
3900 (match_test "TARGET_HARD_XF_REGS")
3901 (symbol_ref "false")
3903 (not (match_test "TARGET_HARD_XF_REGS"))
3904 (symbol_ref "false")
3906 (const_string "*")))])
3909 [(set (match_operand:XF 0 "nonimmediate_gr_operand")
3910 (match_operand:XF 1 "general_gr_operand"))]
3913 "ix86_split_long_move (operands); DONE;")
3915 ;; Possible store forwarding (partial memory) stall in alternatives 4, 6 and 7.
3916 (define_insn "*movdf_internal"
3917 [(set (match_operand:DF 0 "nonimmediate_operand"
3918 "=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")
3919 (match_operand:DF 1 "general_operand"
3920 "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"))]
3921 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3922 && (lra_in_progress || reload_completed
3923 || !CONST_DOUBLE_P (operands[1])
3924 || ((optimize_function_for_size_p (cfun)
3925 || (ix86_cmodel == CM_LARGE || ix86_cmodel == CM_LARGE_PIC))
3926 && IS_STACK_MODE (DFmode)
3927 && standard_80387_constant_p (operands[1]) > 0
3928 && !memory_operand (operands[0], DFmode))
3929 || (TARGET_SSE2 && TARGET_SSE_MATH
3930 && standard_sse_constant_p (operands[1], DFmode) == 1
3931 && !memory_operand (operands[0], DFmode))
3932 || ((TARGET_64BIT || !TARGET_MEMORY_MISMATCH_STALL)
3933 && memory_operand (operands[0], DFmode))
3934 || !TARGET_HARD_DF_REGS)"
3936 switch (get_attr_type (insn))
3939 if (which_alternative == 2)
3940 return standard_80387_constant_opcode (operands[1]);
3941 return output_387_reg_move (insn, operands);
3947 if (get_attr_mode (insn) == MODE_SI)
3948 return "mov{l}\t{%1, %k0|%k0, %1}";
3949 else if (which_alternative == 11)
3950 return "movabs{q}\t{%1, %0|%0, %1}";
3952 return "mov{q}\t{%1, %0|%0, %1}";
3955 return standard_sse_constant_opcode (insn, operands);
3958 return ix86_output_ssemov (insn, operands);
3965 (cond [(eq_attr "alternative" "3,4,5,6,7,22,23")
3966 (const_string "nox64")
3967 (eq_attr "alternative" "8,9,10,11,24,25")
3968 (const_string "x64")
3969 (eq_attr "alternative" "12,13,14,15")
3970 (const_string "sse2")
3971 (eq_attr "alternative" "20,21")
3972 (const_string "x64_sse2")
3974 (const_string "*")))
3976 (cond [(eq_attr "alternative" "0,1,2")
3977 (const_string "fmov")
3978 (eq_attr "alternative" "3,4,5,6,7,22,23")
3979 (const_string "multi")
3980 (eq_attr "alternative" "8,9,10,11,24,25")
3981 (const_string "imov")
3982 (eq_attr "alternative" "12,16")
3983 (const_string "sselog1")
3985 (const_string "ssemov")))
3987 (if_then_else (eq_attr "alternative" "11")
3989 (const_string "*")))
3990 (set (attr "length_immediate")
3991 (if_then_else (eq_attr "alternative" "11")
3993 (const_string "*")))
3994 (set (attr "prefix")
3995 (if_then_else (eq_attr "type" "sselog1,ssemov")
3996 (const_string "maybe_vex")
3997 (const_string "orig")))
3998 (set (attr "prefix_data16")
4000 (ior (and (eq_attr "type" "ssemov") (eq_attr "mode" "DI"))
4001 (eq_attr "mode" "V1DF"))
4003 (const_string "*")))
4005 (cond [(eq_attr "alternative" "3,4,5,6,7,10,22,23")
4007 (eq_attr "alternative" "8,9,11,20,21,24,25")
4010 /* xorps is one byte shorter for non-AVX targets. */
4011 (eq_attr "alternative" "12,16")
4012 (cond [(match_test "TARGET_AVX")
4013 (const_string "V2DF")
4014 (ior (not (match_test "TARGET_SSE2"))
4015 (match_test "optimize_function_for_size_p (cfun)"))
4016 (const_string "V4SF")
4017 (match_test "TARGET_SSE_LOAD0_BY_PXOR")
4020 (const_string "V2DF"))
4022 /* For architectures resolving dependencies on
4023 whole SSE registers use movapd to break dependency
4024 chains, otherwise use short move to avoid extra work. */
4026 /* movaps is one byte shorter for non-AVX targets. */
4027 (eq_attr "alternative" "13,17")
4028 (cond [(match_test "TARGET_AVX")
4030 (ior (not (match_test "TARGET_SSE2"))
4031 (match_test "optimize_function_for_size_p (cfun)"))
4032 (const_string "V4SF")
4033 (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
4034 (const_string "V4SF")
4035 (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
4036 (const_string "V2DF")
4038 (const_string "DF"))
4040 /* For architectures resolving dependencies on register
4041 parts we may avoid extra work to zero out upper part
4043 (eq_attr "alternative" "14,18")
4044 (cond [(not (match_test "TARGET_SSE2"))
4045 (const_string "V2SF")
4046 (match_test "TARGET_AVX")
4048 (match_test "TARGET_SSE_SPLIT_REGS")
4049 (const_string "V1DF")
4051 (const_string "DF"))
4053 (and (eq_attr "alternative" "15,19")
4054 (not (match_test "TARGET_SSE2")))
4055 (const_string "V2SF")
4057 (const_string "DF")))
4058 (set (attr "preferred_for_size")
4059 (cond [(eq_attr "alternative" "3,4")
4060 (symbol_ref "false")]
4061 (symbol_ref "true")))
4062 (set (attr "preferred_for_speed")
4063 (cond [(eq_attr "alternative" "3,4")
4064 (symbol_ref "TARGET_INTEGER_DFMODE_MOVES")
4065 (eq_attr "alternative" "20")
4066 (symbol_ref "TARGET_INTER_UNIT_MOVES_FROM_VEC")
4067 (eq_attr "alternative" "21")
4068 (symbol_ref "TARGET_INTER_UNIT_MOVES_TO_VEC")
4070 (symbol_ref "true")))
4071 (set (attr "enabled")
4072 (cond [(eq_attr "alternative" "22,23,24,25")
4074 (match_test "TARGET_HARD_DF_REGS")
4075 (symbol_ref "false")
4077 (not (match_test "TARGET_HARD_DF_REGS"))
4078 (symbol_ref "false")
4080 (const_string "*")))])
4083 [(set (match_operand:DF 0 "nonimmediate_gr_operand")
4084 (match_operand:DF 1 "general_gr_operand"))]
4085 "!TARGET_64BIT && reload_completed"
4087 "ix86_split_long_move (operands); DONE;")
4089 (define_insn "*movsf_internal"
4090 [(set (match_operand:SF 0 "nonimmediate_operand"
4091 "=Yf*f,m ,Yf*f,?r ,?m,v,v,v,m,?r,?v,!*y,!*y,!m,!r,!*y,r ,m")
4092 (match_operand:SF 1 "general_operand"
4093 "Yf*fm,Yf*f,G ,rmF,rF,C,v,m,v,v ,r ,*y ,m ,*y,*y,r ,rmF,rF"))]
4094 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
4095 && (lra_in_progress || reload_completed
4096 || !CONST_DOUBLE_P (operands[1])
4097 || ((optimize_function_for_size_p (cfun)
4098 || (ix86_cmodel == CM_LARGE || ix86_cmodel == CM_LARGE_PIC))
4099 && IS_STACK_MODE (SFmode)
4100 && standard_80387_constant_p (operands[1]) > 0)
4101 || (TARGET_SSE && TARGET_SSE_MATH
4102 && standard_sse_constant_p (operands[1], SFmode) == 1)
4103 || memory_operand (operands[0], SFmode)
4104 || !TARGET_HARD_SF_REGS)"
4106 switch (get_attr_type (insn))
4109 if (which_alternative == 2)
4110 return standard_80387_constant_opcode (operands[1]);
4111 return output_387_reg_move (insn, operands);
4114 return "mov{l}\t{%1, %0|%0, %1}";
4117 return standard_sse_constant_opcode (insn, operands);
4120 return ix86_output_ssemov (insn, operands);
4123 switch (get_attr_mode (insn))
4126 return "movq\t{%1, %0|%0, %1}";
4128 return "movd\t{%1, %0|%0, %1}";
4139 (cond [(eq_attr "alternative" "9,10")
4140 (const_string "sse2")
4142 (const_string "*")))
4144 (cond [(eq_attr "alternative" "0,1,2")
4145 (const_string "fmov")
4146 (eq_attr "alternative" "3,4,16,17")
4147 (const_string "imov")
4148 (eq_attr "alternative" "5")
4149 (const_string "sselog1")
4150 (eq_attr "alternative" "11,12,13,14,15")
4151 (const_string "mmxmov")
4153 (const_string "ssemov")))
4154 (set (attr "prefix")
4155 (if_then_else (eq_attr "type" "sselog1,ssemov")
4156 (const_string "maybe_vex")
4157 (const_string "orig")))
4158 (set (attr "prefix_data16")
4159 (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
4161 (const_string "*")))
4163 (cond [(eq_attr "alternative" "3,4,9,10,12,13,14,15,16,17")
4165 (eq_attr "alternative" "11")
4167 (eq_attr "alternative" "5")
4168 (cond [(and (match_test "TARGET_AVX512F")
4169 (not (match_test "TARGET_PREFER_AVX256")))
4170 (const_string "V16SF")
4171 (match_test "TARGET_AVX")
4172 (const_string "V4SF")
4173 (ior (not (match_test "TARGET_SSE2"))
4174 (match_test "optimize_function_for_size_p (cfun)"))
4175 (const_string "V4SF")
4176 (match_test "TARGET_SSE_LOAD0_BY_PXOR")
4179 (const_string "V4SF"))
4181 /* For architectures resolving dependencies on
4182 whole SSE registers use APS move to break dependency
4183 chains, otherwise use short move to avoid extra work.
4185 Do the same for architectures resolving dependencies on
4186 the parts. While in DF mode it is better to always handle
4187 just register parts, the SF mode is different due to lack
4188 of instructions to load just part of the register. It is
4189 better to maintain the whole registers in single format
4190 to avoid problems on using packed logical operations. */
4191 (eq_attr "alternative" "6")
4192 (cond [(ior (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
4193 (match_test "TARGET_SSE_SPLIT_REGS"))
4194 (const_string "V4SF")
4196 (const_string "SF"))
4198 (const_string "SF")))
4199 (set (attr "preferred_for_speed")
4200 (cond [(eq_attr "alternative" "9,14")
4201 (symbol_ref "TARGET_INTER_UNIT_MOVES_FROM_VEC")
4202 (eq_attr "alternative" "10,15")
4203 (symbol_ref "TARGET_INTER_UNIT_MOVES_TO_VEC")
4205 (symbol_ref "true")))
4206 (set (attr "enabled")
4207 (cond [(eq_attr "alternative" "16,17")
4209 (match_test "TARGET_HARD_SF_REGS")
4210 (symbol_ref "false")
4212 (not (match_test "TARGET_HARD_SF_REGS"))
4213 (symbol_ref "false")
4215 (const_string "*")))])
4217 (define_mode_attr hfbfconstf
4220 (define_insn "*mov<mode>_internal"
4221 [(set (match_operand:HFBF 0 "nonimmediate_operand"
4222 "=?r,?r,?r,?m,v,v,?r,m,?v,v")
4223 (match_operand:HFBF 1 "general_operand"
4224 "r ,F ,m ,r<hfbfconstf>,C,v, v,v,r ,m"))]
4225 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
4228 || !CONST_DOUBLE_P (operands[1])
4230 && standard_sse_constant_p (operands[1], <MODE>mode) == 1)
4231 || memory_operand (operands[0], <MODE>mode))"
4233 switch (get_attr_type (insn))
4236 /* movzwl is faster than movw on p2 due to partial word stalls,
4237 though not as fast as an aligned movl. */
4238 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
4241 return ix86_output_ssemov (insn, operands);
4244 if (satisfies_constraint_C (operands[1]))
4245 return standard_sse_constant_opcode (insn, operands);
4247 if (SSE_REG_P (operands[0]))
4248 return "%vpinsrw\t{$0, %1, %d0|%d0, %1, 0}";
4250 return "%vpextrw\t{$0, %1, %0|%0, %1, 0}";
4253 if (get_attr_mode (insn) == MODE_SI)
4254 return "mov{l}\t{%k1, %k0|%k0, %k1}";
4256 return "mov{w}\t{%1, %0|%0, %1}";
4260 (cond [(eq_attr "alternative" "4,5,6,8,9")
4261 (const_string "sse2")
4262 (eq_attr "alternative" "7")
4263 (const_string "sse4")
4265 (const_string "*")))
4267 (cond [(eq_attr "alternative" "4")
4268 (const_string "sselog1")
4269 (eq_attr "alternative" "5,6,8")
4270 (const_string "ssemov")
4271 (eq_attr "alternative" "7,9")
4273 (match_test ("TARGET_AVX512FP16"))
4274 (const_string "ssemov")
4275 (const_string "sselog1"))
4276 (match_test "optimize_function_for_size_p (cfun)")
4277 (const_string "imov")
4278 (and (eq_attr "alternative" "0")
4279 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
4280 (not (match_test "TARGET_HIMODE_MATH"))))
4281 (const_string "imov")
4282 (and (eq_attr "alternative" "1,2")
4283 (match_operand:HI 1 "aligned_operand"))
4284 (const_string "imov")
4285 (and (match_test "TARGET_MOVX")
4286 (eq_attr "alternative" "0,2"))
4287 (const_string "imovx")
4289 (const_string "imov")))
4290 (set (attr "prefix")
4291 (cond [(eq_attr "alternative" "4,5,6,7,8,9")
4292 (const_string "maybe_vex")
4294 (const_string "orig")))
4296 (cond [(eq_attr "alternative" "4")
4297 (const_string "V4SF")
4298 (eq_attr "alternative" "6,8")
4300 (match_test "TARGET_AVX512FP16")
4302 (const_string "SI"))
4303 (eq_attr "alternative" "7,9")
4305 (match_test "TARGET_AVX512FP16")
4307 (const_string "TI"))
4308 (eq_attr "alternative" "5")
4309 (cond [(match_test "TARGET_AVX512FP16")
4311 (ior (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
4312 (match_test "TARGET_SSE_SPLIT_REGS"))
4313 (const_string "V4SF")
4315 (const_string "SF"))
4316 (eq_attr "type" "imovx")
4318 (and (eq_attr "alternative" "1,2")
4319 (match_operand:HI 1 "aligned_operand"))
4321 (and (eq_attr "alternative" "0")
4322 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
4323 (not (match_test "TARGET_HIMODE_MATH"))))
4326 (const_string "HI")))
4327 (set (attr "enabled")
4328 (cond [(and (match_test "<MODE>mode == BFmode")
4329 (eq_attr "alternative" "1"))
4330 (symbol_ref "false")
4332 (const_string "*")))])
4335 [(set (match_operand 0 "any_fp_register_operand")
4336 (match_operand 1 "memory_operand"))]
4338 && (GET_MODE (operands[0]) == TFmode
4339 || GET_MODE (operands[0]) == XFmode
4340 || GET_MODE (operands[0]) == DFmode
4341 || GET_MODE (operands[0]) == SFmode)
4342 && ix86_standard_x87sse_constant_load_p (insn, operands[0])"
4343 [(set (match_dup 0) (match_dup 2))]
4344 "operands[2] = find_constant_src (curr_insn);")
4347 [(set (match_operand 0 "any_fp_register_operand")
4348 (float_extend (match_operand 1 "memory_operand")))]
4350 && (GET_MODE (operands[0]) == TFmode
4351 || GET_MODE (operands[0]) == XFmode
4352 || GET_MODE (operands[0]) == DFmode)
4353 && ix86_standard_x87sse_constant_load_p (insn, operands[0])"
4354 [(set (match_dup 0) (match_dup 2))]
4355 "operands[2] = find_constant_src (curr_insn);")
4357 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
4359 [(set (match_operand:X87MODEF 0 "fp_register_operand")
4360 (match_operand:X87MODEF 1 "immediate_operand"))]
4362 && (standard_80387_constant_p (operands[1]) == 8
4363 || standard_80387_constant_p (operands[1]) == 9)"
4364 [(set (match_dup 0)(match_dup 1))
4366 (neg:X87MODEF (match_dup 0)))]
4368 if (real_isnegzero (CONST_DOUBLE_REAL_VALUE (operands[1])))
4369 operands[1] = CONST0_RTX (<MODE>mode);
4371 operands[1] = CONST1_RTX (<MODE>mode);
4374 (define_insn "*swapxf"
4375 [(set (match_operand:XF 0 "register_operand" "+f")
4376 (match_operand:XF 1 "register_operand" "+f"))
4381 if (STACK_TOP_P (operands[0]))
4386 [(set_attr "type" "fxch")
4387 (set_attr "mode" "XF")])
4390 ;; Zero extension instructions
4392 (define_insn_and_split "zero_extendditi2"
4393 [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
4394 (zero_extend:TI (match_operand:DI 1 "nonimmediate_operand" "rm,r")))]
4397 "&& reload_completed"
4398 [(set (match_dup 3) (match_dup 1))
4399 (set (match_dup 4) (const_int 0))]
4400 "split_double_mode (TImode, &operands[0], 1, &operands[3], &operands[4]);")
4402 (define_expand "zero_extendsidi2"
4403 [(set (match_operand:DI 0 "nonimmediate_operand")
4404 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand")))])
4406 (define_insn "*zero_extendsidi2"
4407 [(set (match_operand:DI 0 "nonimmediate_operand"
4408 "=r,?r,?o,r ,o,?*y,?!*y,$r,$v,$x,*x,*v,*r,*k")
4410 (match_operand:SI 1 "x86_64_zext_operand"
4411 "0 ,rm,r ,rmWz,0,r ,m ,v ,r ,m ,*x,*v,*k,*km")))]
4414 switch (get_attr_type (insn))
4417 if (ix86_use_lea_for_mov (insn, operands))
4418 return "lea{l}\t{%E1, %k0|%k0, %E1}";
4420 return "mov{l}\t{%1, %k0|%k0, %1}";
4426 return "movd\t{%1, %0|%0, %1}";
4429 if (SSE_REG_P (operands[0]) && SSE_REG_P (operands[1]))
4431 if (EXT_REX_SSE_REG_P (operands[0])
4432 || EXT_REX_SSE_REG_P (operands[1]))
4433 return "vpmovzxdq\t{%t1, %g0|%g0, %t1}";
4435 return "%vpmovzxdq\t{%1, %0|%0, %1}";
4438 if (GENERAL_REG_P (operands[0]))
4439 return "%vmovd\t{%1, %k0|%k0, %1}";
4441 return "%vmovd\t{%1, %0|%0, %1}";
4444 return "kmovd\t{%1, %k0|%k0, %1}";
4451 (cond [(eq_attr "alternative" "0,1,2")
4452 (const_string "nox64")
4453 (eq_attr "alternative" "3")
4454 (const_string "x64")
4455 (eq_attr "alternative" "7,8,9")
4456 (const_string "sse2")
4457 (eq_attr "alternative" "10")
4458 (const_string "sse4")
4459 (eq_attr "alternative" "11")
4460 (const_string "avx512f")
4461 (eq_attr "alternative" "12")
4462 (const_string "x64_avx512bw")
4463 (eq_attr "alternative" "13")
4464 (const_string "avx512bw")
4466 (const_string "*")))
4467 (set (attr "mmx_isa")
4468 (if_then_else (eq_attr "alternative" "5,6")
4469 (const_string "native")
4470 (const_string "*")))
4472 (cond [(eq_attr "alternative" "0,1,2,4")
4473 (const_string "multi")
4474 (eq_attr "alternative" "5,6")
4475 (const_string "mmxmov")
4476 (eq_attr "alternative" "7")
4477 (if_then_else (match_test "TARGET_64BIT")
4478 (const_string "ssemov")
4479 (const_string "multi"))
4480 (eq_attr "alternative" "8,9,10,11")
4481 (const_string "ssemov")
4482 (eq_attr "alternative" "12,13")
4483 (const_string "mskmov")
4485 (const_string "imovx")))
4486 (set (attr "prefix_extra")
4487 (if_then_else (eq_attr "alternative" "10,11")
4489 (const_string "*")))
4490 (set (attr "prefix")
4491 (if_then_else (eq_attr "type" "ssemov")
4492 (const_string "maybe_vex")
4493 (const_string "orig")))
4494 (set (attr "prefix_0f")
4495 (if_then_else (eq_attr "type" "imovx")
4497 (const_string "*")))
4499 (cond [(eq_attr "alternative" "5,6")
4501 (and (eq_attr "alternative" "7")
4502 (match_test "TARGET_64BIT"))
4504 (eq_attr "alternative" "8,10,11")
4507 (const_string "SI")))
4508 (set (attr "preferred_for_speed")
4509 (cond [(eq_attr "alternative" "7")
4510 (symbol_ref "TARGET_INTER_UNIT_MOVES_FROM_VEC")
4511 (eq_attr "alternative" "5,8")
4512 (symbol_ref "TARGET_INTER_UNIT_MOVES_TO_VEC")
4514 (symbol_ref "true")))])
4517 [(set (match_operand:DI 0 "memory_operand")
4518 (zero_extend:DI (match_operand:SI 1 "memory_operand")))]
4520 [(set (match_dup 4) (const_int 0))]
4521 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
4524 [(set (match_operand:DI 0 "general_reg_operand")
4525 (zero_extend:DI (match_operand:SI 1 "general_reg_operand")))]
4526 "!TARGET_64BIT && reload_completed
4527 && REGNO (operands[0]) == REGNO (operands[1])"
4528 [(set (match_dup 4) (const_int 0))]
4529 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
4532 [(set (match_operand:DI 0 "nonimmediate_gr_operand")
4533 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand")))]
4534 "!TARGET_64BIT && reload_completed
4535 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
4536 [(set (match_dup 3) (match_dup 1))
4537 (set (match_dup 4) (const_int 0))]
4538 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
4540 (define_mode_attr kmov_isa
4541 [(QI "avx512dq") (HI "avx512f") (SI "avx512bw") (DI "avx512bw")])
4543 (define_insn "zero_extend<mode>di2"
4544 [(set (match_operand:DI 0 "register_operand" "=r,*r,*k")
4546 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m,*k,*km")))]
4549 movz{<imodesuffix>l|x}\t{%1, %k0|%k0, %1}
4550 kmov<mskmodesuffix>\t{%1, %k0|%k0, %1}
4551 kmov<mskmodesuffix>\t{%1, %k0|%k0, %1}"
4552 [(set_attr "isa" "*,<kmov_isa>,<kmov_isa>")
4553 (set_attr "type" "imovx,mskmov,mskmov")
4554 (set_attr "mode" "SI,<MODE>,<MODE>")])
4556 (define_expand "zero_extend<mode>si2"
4557 [(set (match_operand:SI 0 "register_operand")
4558 (zero_extend:SI (match_operand:SWI12 1 "nonimmediate_operand")))]
4561 if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
4563 operands[1] = force_reg (<MODE>mode, operands[1]);
4564 emit_insn (gen_zero_extend<mode>si2_and (operands[0], operands[1]));
4569 (define_insn_and_split "zero_extend<mode>si2_and"
4570 [(set (match_operand:SI 0 "register_operand" "=r,?&<r>")
4572 (match_operand:SWI12 1 "nonimmediate_operand" "0,<r>m")))
4573 (clobber (reg:CC FLAGS_REG))]
4574 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
4576 "&& reload_completed"
4577 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (match_dup 2)))
4578 (clobber (reg:CC FLAGS_REG))])]
4580 if (!REG_P (operands[1])
4581 || REGNO (operands[0]) != REGNO (operands[1]))
4583 ix86_expand_clear (operands[0]);
4585 gcc_assert (!TARGET_PARTIAL_REG_STALL);
4586 emit_insn (gen_rtx_SET
4587 (gen_rtx_STRICT_LOW_PART
4588 (VOIDmode, gen_lowpart (<MODE>mode, operands[0])),
4593 operands[2] = GEN_INT (GET_MODE_MASK (<MODE>mode));
4595 [(set_attr "type" "alu1")
4596 (set_attr "mode" "SI")])
4598 (define_insn "*zero_extend<mode>si2"
4599 [(set (match_operand:SI 0 "register_operand" "=r,*r,*k")
4601 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m,*k,*km")))]
4602 "!(TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))"
4604 movz{<imodesuffix>l|x}\t{%1, %0|%0, %1}
4605 kmov<mskmodesuffix>\t{%1, %0|%0, %1}
4606 kmov<mskmodesuffix>\t{%1, %0|%0, %1}"
4607 [(set_attr "isa" "*,<kmov_isa>,<kmov_isa>")
4608 (set_attr "type" "imovx,mskmov,mskmov")
4609 (set_attr "mode" "SI,<MODE>,<MODE>")])
4611 (define_expand "zero_extendqihi2"
4612 [(set (match_operand:HI 0 "register_operand")
4613 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand")))]
4616 if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
4618 operands[1] = force_reg (QImode, operands[1]);
4619 emit_insn (gen_zero_extendqihi2_and (operands[0], operands[1]));
4624 (define_insn_and_split "zero_extendqihi2_and"
4625 [(set (match_operand:HI 0 "register_operand" "=r,?&q")
4626 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
4627 (clobber (reg:CC FLAGS_REG))]
4628 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
4630 "&& reload_completed"
4631 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
4632 (clobber (reg:CC FLAGS_REG))])]
4634 if (!REG_P (operands[1])
4635 || REGNO (operands[0]) != REGNO (operands[1]))
4637 ix86_expand_clear (operands[0]);
4639 gcc_assert (!TARGET_PARTIAL_REG_STALL);
4640 emit_insn (gen_rtx_SET
4641 (gen_rtx_STRICT_LOW_PART
4642 (VOIDmode, gen_lowpart (QImode, operands[0])),
4647 operands[0] = gen_lowpart (SImode, operands[0]);
4649 [(set_attr "type" "alu1")
4650 (set_attr "mode" "SI")])
4652 ; zero extend to SImode to avoid partial register stalls
4653 (define_insn "*zero_extendqihi2"
4654 [(set (match_operand:HI 0 "register_operand" "=r,*r,*k")
4655 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,*k,*km")))]
4656 "!(TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))"
4658 movz{bl|x}\t{%1, %k0|%k0, %1}
4659 kmovb\t{%1, %k0|%k0, %1}
4660 kmovb\t{%1, %0|%0, %1}"
4661 [(set_attr "isa" "*,avx512dq,avx512dq")
4662 (set_attr "type" "imovx,mskmov,mskmov")
4663 (set_attr "mode" "SI,QI,QI")])
4665 ;; Transform xorl; mov[bw] (set strict_low_part) into movz[bw]l.
4667 [(parallel [(set (match_operand:SWI48 0 "general_reg_operand")
4669 (clobber (reg:CC FLAGS_REG))])
4670 (set (strict_low_part (match_operand:SWI12 1 "general_reg_operand"))
4671 (match_operand:SWI12 2 "nonimmediate_operand"))]
4672 "REGNO (operands[0]) == REGNO (operands[1])
4673 && (<SWI48:MODE>mode != SImode
4674 || !TARGET_ZERO_EXTEND_WITH_AND
4675 || !optimize_function_for_speed_p (cfun))"
4676 [(set (match_dup 0) (zero_extend:SWI48 (match_dup 2)))])
4678 ;; Likewise, but preserving FLAGS_REG.
4680 [(set (match_operand:SWI48 0 "general_reg_operand") (const_int 0))
4681 (set (strict_low_part (match_operand:SWI12 1 "general_reg_operand"))
4682 (match_operand:SWI12 2 "nonimmediate_operand"))]
4683 "REGNO (operands[0]) == REGNO (operands[1])
4684 && (<SWI48:MODE>mode != SImode
4685 || !TARGET_ZERO_EXTEND_WITH_AND
4686 || !optimize_function_for_speed_p (cfun))"
4687 [(set (match_dup 0) (zero_extend:SWI48 (match_dup 2)))])
4689 ;; Sign extension instructions
4691 (define_expand "extendsidi2"
4692 [(set (match_operand:DI 0 "register_operand")
4693 (sign_extend:DI (match_operand:SI 1 "register_operand")))]
4698 emit_insn (gen_extendsidi2_1 (operands[0], operands[1]));
4703 (define_insn "*extendsidi2_rex64"
4704 [(set (match_operand:DI 0 "register_operand" "=*a,r")
4705 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
4709 movs{lq|x}\t{%1, %0|%0, %1}"
4710 [(set_attr "type" "imovx")
4711 (set_attr "mode" "DI")
4712 (set_attr "prefix_0f" "0")
4713 (set_attr "modrm" "0,1")])
4715 (define_insn "extendsidi2_1"
4716 [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
4717 (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
4718 (clobber (reg:CC FLAGS_REG))
4719 (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
4723 (define_insn "extendditi2"
4724 [(set (match_operand:TI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
4725 (sign_extend:TI (match_operand:DI 1 "register_operand" "0,0,r,r")))
4726 (clobber (reg:CC FLAGS_REG))
4727 (clobber (match_scratch:DI 2 "=X,X,X,&r"))]
4731 ;; Split the memory case. If the source register doesn't die, it will stay
4732 ;; this way, if it does die, following peephole2s take care of it.
4734 [(set (match_operand:<DWI> 0 "memory_operand")
4735 (sign_extend:<DWI> (match_operand:DWIH 1 "register_operand")))
4736 (clobber (reg:CC FLAGS_REG))
4737 (clobber (match_operand:DWIH 2 "register_operand"))]
4741 rtx bits = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT - 1);
4743 split_double_mode (<DWI>mode, &operands[0], 1, &operands[3], &operands[4]);
4745 emit_move_insn (operands[3], operands[1]);
4747 /* Generate a cltd if possible and doing so it profitable. */
4748 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
4749 && REGNO (operands[1]) == AX_REG
4750 && REGNO (operands[2]) == DX_REG)
4752 emit_insn (gen_ashr<mode>3_cvt (operands[2], operands[1], bits));
4756 emit_move_insn (operands[2], operands[1]);
4757 emit_insn (gen_ashr<mode>3_cvt (operands[2], operands[2], bits));
4759 emit_move_insn (operands[4], operands[2]);
4763 ;; Peepholes for the case where the source register does die, after
4764 ;; being split with the above splitter.
4766 [(set (match_operand:DWIH 0 "memory_operand")
4767 (match_operand:DWIH 1 "general_reg_operand"))
4768 (set (match_operand:DWIH 2 "general_reg_operand") (match_dup 1))
4769 (parallel [(set (match_dup 2)
4770 (ashiftrt:DWIH (match_dup 2)
4771 (match_operand 4 "const_int_operand")))
4772 (clobber (reg:CC FLAGS_REG))])
4773 (set (match_operand:DWIH 3 "memory_operand") (match_dup 2))]
4774 "REGNO (operands[1]) != REGNO (operands[2])
4775 && INTVAL (operands[4]) == (<MODE_SIZE> * BITS_PER_UNIT - 1)
4776 && peep2_reg_dead_p (2, operands[1])
4777 && peep2_reg_dead_p (4, operands[2])
4778 && !reg_mentioned_p (operands[2], operands[3])"
4779 [(set (match_dup 0) (match_dup 1))
4780 (parallel [(set (match_dup 1) (ashiftrt:DWIH (match_dup 1) (match_dup 4)))
4781 (clobber (reg:CC FLAGS_REG))])
4782 (set (match_dup 3) (match_dup 1))])
4785 [(set (match_operand:DWIH 0 "memory_operand")
4786 (match_operand:DWIH 1 "general_reg_operand"))
4787 (parallel [(set (match_operand:DWIH 2 "general_reg_operand")
4788 (ashiftrt:DWIH (match_dup 1)
4789 (match_operand 4 "const_int_operand")))
4790 (clobber (reg:CC FLAGS_REG))])
4791 (set (match_operand:DWIH 3 "memory_operand") (match_dup 2))]
4792 "/* cltd is shorter than sarl $31, %eax */
4793 !optimize_function_for_size_p (cfun)
4794 && REGNO (operands[1]) == AX_REG
4795 && REGNO (operands[2]) == DX_REG
4796 && INTVAL (operands[4]) == (<MODE_SIZE> * BITS_PER_UNIT - 1)
4797 && peep2_reg_dead_p (2, operands[1])
4798 && peep2_reg_dead_p (3, operands[2])
4799 && !reg_mentioned_p (operands[2], operands[3])"
4800 [(set (match_dup 0) (match_dup 1))
4801 (parallel [(set (match_dup 1) (ashiftrt:DWIH (match_dup 1) (match_dup 4)))
4802 (clobber (reg:CC FLAGS_REG))])
4803 (set (match_dup 3) (match_dup 1))])
4805 ;; Extend to register case. Optimize case where source and destination
4806 ;; registers match and cases where we can use cltd.
4808 [(set (match_operand:<DWI> 0 "register_operand")
4809 (sign_extend:<DWI> (match_operand:DWIH 1 "register_operand")))
4810 (clobber (reg:CC FLAGS_REG))
4811 (clobber (match_scratch:DWIH 2))]
4815 rtx bits = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT - 1);
4817 split_double_mode (<DWI>mode, &operands[0], 1, &operands[3], &operands[4]);
4819 if (REGNO (operands[3]) != REGNO (operands[1]))
4820 emit_move_insn (operands[3], operands[1]);
4822 rtx src = operands[1];
4823 if (REGNO (operands[3]) == AX_REG)
4826 /* Generate a cltd if possible and doing so it profitable. */
4827 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
4828 && REGNO (src) == AX_REG
4829 && REGNO (operands[4]) == DX_REG)
4831 emit_insn (gen_ashr<mode>3_cvt (operands[4], src, bits));
4835 if (REGNO (operands[4]) != REGNO (operands[1]))
4836 emit_move_insn (operands[4], operands[1]);
4838 emit_insn (gen_ashr<mode>3_cvt (operands[4], operands[4], bits));
4842 (define_insn "extend<mode>di2"
4843 [(set (match_operand:DI 0 "register_operand" "=r")
4845 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
4847 "movs{<imodesuffix>q|x}\t{%1, %0|%0, %1}"
4848 [(set_attr "type" "imovx")
4849 (set_attr "mode" "DI")])
4851 (define_insn "extendhisi2"
4852 [(set (match_operand:SI 0 "register_operand" "=*a,r")
4853 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
4856 switch (get_attr_prefix_0f (insn))
4859 return "{cwtl|cwde}";
4861 return "movs{wl|x}\t{%1, %0|%0, %1}";
4864 [(set_attr "type" "imovx")
4865 (set_attr "mode" "SI")
4866 (set (attr "prefix_0f")
4867 ;; movsx is short decodable while cwtl is vector decoded.
4868 (if_then_else (and (eq_attr "cpu" "!k6")
4869 (eq_attr "alternative" "0"))
4871 (const_string "1")))
4872 (set (attr "znver1_decode")
4873 (if_then_else (eq_attr "prefix_0f" "0")
4874 (const_string "double")
4875 (const_string "direct")))
4877 (if_then_else (eq_attr "prefix_0f" "0")
4879 (const_string "1")))])
4881 (define_insn "*extendhisi2_zext"
4882 [(set (match_operand:DI 0 "register_operand" "=*a,r")
4885 (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
4888 switch (get_attr_prefix_0f (insn))
4891 return "{cwtl|cwde}";
4893 return "movs{wl|x}\t{%1, %k0|%k0, %1}";
4896 [(set_attr "type" "imovx")
4897 (set_attr "mode" "SI")
4898 (set (attr "prefix_0f")
4899 ;; movsx is short decodable while cwtl is vector decoded.
4900 (if_then_else (and (eq_attr "cpu" "!k6")
4901 (eq_attr "alternative" "0"))
4903 (const_string "1")))
4905 (if_then_else (eq_attr "prefix_0f" "0")
4907 (const_string "1")))])
4909 (define_insn "extendqisi2"
4910 [(set (match_operand:SI 0 "register_operand" "=r")
4911 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
4913 "movs{bl|x}\t{%1, %0|%0, %1}"
4914 [(set_attr "type" "imovx")
4915 (set_attr "mode" "SI")])
4917 (define_insn "*extendqisi2_zext"
4918 [(set (match_operand:DI 0 "register_operand" "=r")
4920 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
4922 "movs{bl|x}\t{%1, %k0|%k0, %1}"
4923 [(set_attr "type" "imovx")
4924 (set_attr "mode" "SI")])
4926 (define_insn "extendqihi2"
4927 [(set (match_operand:HI 0 "register_operand" "=*a,r")
4928 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
4931 switch (get_attr_prefix_0f (insn))
4934 return "{cbtw|cbw}";
4936 return "movs{bw|x}\t{%1, %0|%0, %1}";
4939 [(set_attr "type" "imovx")
4940 (set_attr "mode" "HI")
4941 (set (attr "prefix_0f")
4942 ;; movsx is short decodable while cwtl is vector decoded.
4943 (if_then_else (and (eq_attr "cpu" "!k6")
4944 (eq_attr "alternative" "0"))
4946 (const_string "1")))
4948 (if_then_else (eq_attr "prefix_0f" "0")
4950 (const_string "1")))])
4952 (define_insn "*extendqi<SWI24:mode>_ext_1"
4953 [(set (match_operand:SWI24 0 "register_operand" "=R")
4956 (match_operator:SWI248 2 "extract_operator"
4957 [(match_operand 1 "int248_register_operand" "Q")
4959 (const_int 8)]) 0)))]
4961 "movs{b<SWI24:imodesuffix>|x}\t{%h1, %0|%0, %h1}"
4962 [(set_attr "type" "imovx")
4963 (set_attr "mode" "<SWI24:MODE>")])
4965 ;; Conversions between float and double.
4967 ;; These are all no-ops in the model used for the 80387.
4968 ;; So just emit moves.
4970 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
4972 [(set (match_operand:DF 0 "push_operand")
4973 (float_extend:DF (match_operand:SF 1 "fp_register_operand")))]
4975 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
4976 (set (mem:DF (reg:P SP_REG)) (float_extend:DF (match_dup 1)))])
4979 [(set (match_operand:XF 0 "push_operand")
4980 (float_extend:XF (match_operand:MODEF 1 "fp_register_operand")))]
4982 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
4983 (set (mem:XF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
4984 "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
4986 (define_expand "extendsfdf2"
4987 [(set (match_operand:DF 0 "nonimm_ssenomem_operand")
4988 (float_extend:DF (match_operand:SF 1 "general_operand")))]
4989 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4991 /* ??? Needed for compress_float_constant since all fp constants
4992 are TARGET_LEGITIMATE_CONSTANT_P. */
4993 if (CONST_DOUBLE_P (operands[1]))
4995 if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
4996 && standard_80387_constant_p (operands[1]) > 0)
4998 operands[1] = simplify_const_unary_operation
4999 (FLOAT_EXTEND, DFmode, operands[1], SFmode);
5000 emit_move_insn_1 (operands[0], operands[1]);
5003 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
5007 (define_insn "*extendsfdf2"
5008 [(set (match_operand:DF 0 "nonimm_ssenomem_operand" "=f,m,v,v")
5010 (match_operand:SF 1 "nonimmediate_operand" "fm,f,v,m")))]
5011 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
5013 switch (which_alternative)
5017 return output_387_reg_move (insn, operands);
5020 return "%vcvtss2sd\t{%d1, %0|%0, %d1}";
5022 return "%vcvtss2sd\t{%1, %d0|%d0, %1}";
5028 [(set_attr "type" "fmov,fmov,ssecvt,ssecvt")
5029 (set_attr "avx_partial_xmm_update" "false,false,false,true")
5030 (set_attr "prefix" "orig,orig,maybe_vex,maybe_vex")
5031 (set_attr "mode" "SF,XF,DF,DF")
5032 (set (attr "enabled")
5034 (match_test ("TARGET_SSE2 && TARGET_SSE_MATH"))
5036 (eq_attr "alternative" "0,1")
5037 (symbol_ref "TARGET_MIX_SSE_I387")
5038 (symbol_ref "true"))
5040 (eq_attr "alternative" "0,1")
5042 (symbol_ref "false"))))])
5044 /* For converting SF(xmm2) to DF(xmm1), use the following code instead of
5046 unpcklps xmm2,xmm2 ; packed conversion might crash on signaling NaNs
5048 We do the conversion post reload to avoid producing of 128bit spills
5049 that might lead to ICE on 32bit target. The sequence unlikely combine
5052 [(set (match_operand:DF 0 "sse_reg_operand")
5054 (match_operand:SF 1 "nonimmediate_operand")))]
5055 "TARGET_USE_VECTOR_FP_CONVERTS
5056 && optimize_insn_for_speed_p ()
5058 && (!EXT_REX_SSE_REG_P (operands[0])
5059 || TARGET_AVX512VL)"
5064 (parallel [(const_int 0) (const_int 1)]))))]
5066 operands[2] = lowpart_subreg (V2DFmode, operands[0], DFmode);
5067 operands[3] = lowpart_subreg (V4SFmode, operands[0], DFmode);
5068 /* Use movss for loading from memory, unpcklps reg, reg for registers.
5069 Try to avoid move when unpacking can be done in source. */
5070 if (REG_P (operands[1]))
5072 /* If it is unsafe to overwrite upper half of source, we need
5073 to move to destination and unpack there. */
5074 if (REGNO (operands[0]) != REGNO (operands[1])
5075 || (EXT_REX_SSE_REG_P (operands[1])
5076 && !TARGET_AVX512VL))
5078 rtx tmp = lowpart_subreg (SFmode, operands[0], DFmode);
5079 emit_move_insn (tmp, operands[1]);
5082 operands[3] = lowpart_subreg (V4SFmode, operands[1], SFmode);
5083 /* FIXME: vec_interleave_lowv4sf for AVX512VL should allow
5084 =v, v, then vbroadcastss will be only needed for AVX512F without
5086 if (!EXT_REX_SSE_REGNO_P (REGNO (operands[3])))
5087 emit_insn (gen_vec_interleave_lowv4sf (operands[3], operands[3],
5091 rtx tmp = lowpart_subreg (V16SFmode, operands[3], V4SFmode);
5092 emit_insn (gen_avx512f_vec_dupv16sf_1 (tmp, tmp));
5096 emit_insn (gen_vec_setv4sf_0 (operands[3],
5097 CONST0_RTX (V4SFmode), operands[1]));
5100 ;; It's more profitable to split and then extend in the same register.
5102 [(set (match_operand:DF 0 "sse_reg_operand")
5104 (match_operand:SF 1 "memory_operand")))]
5105 "TARGET_SPLIT_MEM_OPND_FOR_FP_CONVERTS
5106 && optimize_insn_for_speed_p ()"
5107 [(set (match_dup 2) (match_dup 1))
5108 (set (match_dup 0) (float_extend:DF (match_dup 2)))]
5109 "operands[2] = lowpart_subreg (SFmode, operands[0], DFmode);")
5111 ;; Break partial SSE register dependency stall. This splitter should split
5112 ;; late in the pass sequence (after register rename pass), so allocated
5113 ;; registers won't change anymore
5116 [(set (match_operand:DF 0 "sse_reg_operand")
5118 (match_operand:SF 1 "nonimmediate_operand")))]
5120 && TARGET_SSE_PARTIAL_REG_FP_CONVERTS_DEPENDENCY
5121 && epilogue_completed
5122 && optimize_function_for_speed_p (cfun)
5123 && (!REG_P (operands[1])
5124 || (!TARGET_AVX && REGNO (operands[0]) != REGNO (operands[1])))
5125 && (!EXT_REX_SSE_REG_P (operands[0])
5126 || TARGET_AVX512VL)"
5135 operands[0] = lowpart_subreg (V2DFmode, operands[0], DFmode);
5136 emit_move_insn (operands[0], CONST0_RTX (V2DFmode));
5139 (define_expand "extendhfsf2"
5140 [(set (match_operand:SF 0 "register_operand")
5142 (match_operand:HF 1 "nonimmediate_operand")))]
5143 "TARGET_AVX512FP16 || TARGET_F16C || TARGET_AVX512VL"
5145 if (!TARGET_AVX512FP16)
5147 rtx res = gen_reg_rtx (V4SFmode);
5148 rtx tmp = gen_reg_rtx (V8HFmode);
5149 rtx zero = force_reg (V8HFmode, CONST0_RTX (V8HFmode));
5151 emit_insn (gen_vec_setv8hf_0 (tmp, zero, operands[1]));
5152 emit_insn (gen_vcvtph2ps (res, gen_lowpart (V8HImode, tmp)));
5153 emit_move_insn (operands[0], gen_lowpart (SFmode, res));
5158 (define_expand "extendhfdf2"
5159 [(set (match_operand:DF 0 "register_operand")
5161 (match_operand:HF 1 "nonimmediate_operand")))]
5162 "TARGET_AVX512FP16")
5164 (define_insn "*extendhf<mode>2"
5165 [(set (match_operand:MODEF 0 "register_operand" "=v")
5167 (match_operand:HF 1 "nonimmediate_operand" "vm")))]
5169 "vcvtsh2<ssemodesuffix>\t{%1, %0, %0|%0, %0, %1}"
5170 [(set_attr "type" "ssecvt")
5171 (set_attr "prefix" "evex")
5172 (set_attr "mode" "<MODE>")])
5174 (define_expand "extendbfsf2"
5175 [(set (match_operand:SF 0 "register_operand")
5177 [(match_operand:BF 1 "register_operand")]
5179 "TARGET_SSE2 && !HONOR_NANS (BFmode)")
5181 ;; Don't use float_extend since psrlld doesn't raise
5182 ;; exceptions and turn a sNaN into a qNaN.
5183 (define_insn "extendbfsf2_1"
5184 [(set (match_operand:SF 0 "register_operand" "=x,Yw")
5186 [(match_operand:BF 1 "register_operand" " 0,Yw")]
5190 pslld\t{$16, %0|%0, 16}
5191 vpslld\t{$16, %1, %0|%0, %1, 16}"
5192 [(set_attr "isa" "noavx,avx")
5193 (set_attr "type" "sseishft1")
5194 (set_attr "length_immediate" "1")
5195 (set_attr "prefix_data16" "1,*")
5196 (set_attr "prefix" "orig,vex")
5197 (set_attr "mode" "TI")
5198 (set_attr "memory" "none")])
5200 (define_expand "extend<mode>xf2"
5201 [(set (match_operand:XF 0 "nonimmediate_operand")
5202 (float_extend:XF (match_operand:MODEF 1 "general_operand")))]
5205 /* ??? Needed for compress_float_constant since all fp constants
5206 are TARGET_LEGITIMATE_CONSTANT_P. */
5207 if (CONST_DOUBLE_P (operands[1]))
5209 if (standard_80387_constant_p (operands[1]) > 0)
5211 operands[1] = simplify_const_unary_operation
5212 (FLOAT_EXTEND, XFmode, operands[1], <MODE>mode);
5213 emit_move_insn_1 (operands[0], operands[1]);
5216 operands[1] = validize_mem (force_const_mem (<MODE>mode, operands[1]));
5220 (define_insn "*extend<mode>xf2_i387"
5221 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
5223 (match_operand:MODEF 1 "nonimmediate_operand" "fm,f")))]
5225 "* return output_387_reg_move (insn, operands);"
5226 [(set_attr "type" "fmov")
5227 (set_attr "mode" "<MODE>,XF")])
5229 ;; %%% This seems like bad news.
5230 ;; This cannot output into an f-reg because there is no way to be sure
5231 ;; of truncating in that case. Otherwise this is just like a simple move
5232 ;; insn. So we pretend we can output to a reg in order to get better
5233 ;; register preferencing, but we really use a stack slot.
5235 ;; Conversion from DFmode to SFmode.
5237 (define_insn "truncdfsf2"
5238 [(set (match_operand:SF 0 "nonimm_ssenomem_operand" "=m,f,v,v")
5240 (match_operand:DF 1 "register_ssemem_operand" "f,f,v,m")))]
5241 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
5243 switch (which_alternative)
5247 return output_387_reg_move (insn, operands);
5250 return "%vcvtsd2ss\t{%d1, %0|%0, %d1}";
5252 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
5258 [(set_attr "type" "fmov,fmov,ssecvt,ssecvt")
5259 (set_attr "avx_partial_xmm_update" "false,false,false,true")
5260 (set_attr "mode" "SF")
5261 (set (attr "enabled")
5263 (match_test ("TARGET_SSE2 && TARGET_SSE_MATH"))
5264 (cond [(eq_attr "alternative" "0")
5265 (symbol_ref "TARGET_MIX_SSE_I387")
5266 (eq_attr "alternative" "1")
5267 (symbol_ref "TARGET_MIX_SSE_I387
5268 && flag_unsafe_math_optimizations")
5270 (symbol_ref "true"))
5271 (cond [(eq_attr "alternative" "0")
5273 (eq_attr "alternative" "1")
5274 (symbol_ref "flag_unsafe_math_optimizations")
5276 (symbol_ref "false"))))])
5278 /* For converting DF(xmm2) to SF(xmm1), use the following code instead of
5280 unpcklpd xmm2,xmm2 ; packed conversion might crash on signaling NaNs
5282 We do the conversion post reload to avoid producing of 128bit spills
5283 that might lead to ICE on 32bit target. The sequence unlikely combine
5286 [(set (match_operand:SF 0 "sse_reg_operand")
5288 (match_operand:DF 1 "nonimmediate_operand")))]
5289 "TARGET_USE_VECTOR_FP_CONVERTS
5290 && optimize_insn_for_speed_p ()
5292 && (!EXT_REX_SSE_REG_P (operands[0])
5293 || TARGET_AVX512VL)"
5296 (float_truncate:V2SF
5300 operands[2] = lowpart_subreg (V4SFmode, operands[0], SFmode);
5301 operands[3] = CONST0_RTX (V2SFmode);
5302 operands[4] = lowpart_subreg (V2DFmode, operands[0], SFmode);
5303 /* Use movsd for loading from memory, unpcklpd for registers.
5304 Try to avoid move when unpacking can be done in source, or SSE3
5305 movddup is available. */
5306 if (REG_P (operands[1]))
5308 if ((!TARGET_SSE3 && REGNO (operands[0]) != REGNO (operands[1]))
5309 || (EXT_REX_SSE_REG_P (operands[1]) && !TARGET_AVX512VL))
5311 rtx tmp = lowpart_subreg (DFmode, operands[0], SFmode);
5312 emit_move_insn (tmp, operands[1]);
5315 else if (!TARGET_SSE3)
5316 operands[4] = lowpart_subreg (V2DFmode, operands[1], DFmode);
5317 emit_insn (gen_vec_dupv2df (operands[4], operands[1]));
5320 emit_insn (gen_vec_concatv2df (operands[4], operands[1],
5321 CONST0_RTX (DFmode)));
5324 ;; It's more profitable to split and then truncate in the same register.
5326 [(set (match_operand:SF 0 "sse_reg_operand")
5328 (match_operand:DF 1 "memory_operand")))]
5329 "TARGET_SPLIT_MEM_OPND_FOR_FP_CONVERTS
5330 && optimize_insn_for_speed_p ()"
5331 [(set (match_dup 2) (match_dup 1))
5332 (set (match_dup 0) (float_truncate:SF (match_dup 2)))]
5333 "operands[2] = lowpart_subreg (DFmode, operands[0], SFmode);")
5335 ;; Break partial SSE register dependency stall. This splitter should split
5336 ;; late in the pass sequence (after register rename pass), so allocated
5337 ;; registers won't change anymore
5340 [(set (match_operand:SF 0 "sse_reg_operand")
5342 (match_operand:DF 1 "nonimmediate_operand")))]
5344 && TARGET_SSE_PARTIAL_REG_FP_CONVERTS_DEPENDENCY
5345 && epilogue_completed
5346 && optimize_function_for_speed_p (cfun)
5347 && (!REG_P (operands[1])
5348 || (!TARGET_AVX && REGNO (operands[0]) != REGNO (operands[1])))
5349 && (!EXT_REX_SSE_REG_P (operands[0])
5350 || TARGET_AVX512VL)"
5359 operands[0] = lowpart_subreg (V4SFmode, operands[0], SFmode);
5360 emit_move_insn (operands[0], CONST0_RTX (V4SFmode));
5363 ;; Conversion from XFmode to {SF,DF}mode
5365 (define_insn "truncxf<mode>2"
5366 [(set (match_operand:MODEF 0 "nonimmediate_operand" "=m,f")
5367 (float_truncate:MODEF
5368 (match_operand:XF 1 "register_operand" "f,f")))]
5370 "* return output_387_reg_move (insn, operands);"
5371 [(set_attr "type" "fmov")
5372 (set_attr "mode" "<MODE>")
5373 (set (attr "enabled")
5374 (cond [(eq_attr "alternative" "1")
5375 (symbol_ref "flag_unsafe_math_optimizations")
5377 (symbol_ref "true")))])
5379 ;; Conversion from {SF,DF}mode to HFmode.
5381 (define_expand "truncsfhf2"
5382 [(set (match_operand:HF 0 "register_operand")
5384 (match_operand:SF 1 "nonimmediate_operand")))]
5385 "TARGET_AVX512FP16 || TARGET_F16C || TARGET_AVX512VL"
5387 if (!TARGET_AVX512FP16)
5389 rtx res = gen_reg_rtx (V8HFmode);
5390 rtx tmp = gen_reg_rtx (V4SFmode);
5391 rtx zero = force_reg (V4SFmode, CONST0_RTX (V4SFmode));
5393 emit_insn (gen_vec_setv4sf_0 (tmp, zero, operands[1]));
5394 emit_insn (gen_vcvtps2ph (gen_lowpart (V8HImode, res), tmp, GEN_INT (4)));
5395 emit_move_insn (operands[0], gen_lowpart (HFmode, res));
5400 (define_expand "truncdfhf2"
5401 [(set (match_operand:HF 0 "register_operand")
5403 (match_operand:DF 1 "nonimmediate_operand")))]
5404 "TARGET_AVX512FP16")
5406 (define_insn "*trunc<mode>hf2"
5407 [(set (match_operand:HF 0 "register_operand" "=v")
5409 (match_operand:MODEF 1 "nonimmediate_operand" "vm")))]
5411 "vcvt<ssemodesuffix>2sh\t{%1, %d0|%d0, %1}"
5412 [(set_attr "type" "ssecvt")
5413 (set_attr "prefix" "evex")
5414 (set_attr "mode" "HF")])
5416 (define_insn "truncsfbf2"
5417 [(set (match_operand:BF 0 "register_operand" "=x, v")
5419 (match_operand:SF 1 "register_operand" "x,v")))]
5420 "((TARGET_AVX512BF16 && TARGET_AVX512VL) || TARGET_AVXNECONVERT)
5421 && !HONOR_NANS (BFmode) && flag_unsafe_math_optimizations"
5423 %{vex%} vcvtneps2bf16\t{%1, %0|%0, %1}
5424 vcvtneps2bf16\t{%1, %0|%0, %1}"
5425 [(set_attr "isa" "avxneconvert,avx512bf16vl")
5426 (set_attr "prefix" "vex,evex")])
5428 ;; Signed conversion to DImode.
5430 (define_expand "fix_truncxfdi2"
5431 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand")
5432 (fix:DI (match_operand:XF 1 "register_operand")))
5433 (clobber (reg:CC FLAGS_REG))])]
5438 emit_insn (gen_fix_truncdi_i387_fisttp (operands[0], operands[1]));
5443 (define_expand "fix_trunc<mode>di2"
5444 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand")
5445 (fix:DI (match_operand:MODEF 1 "register_operand")))
5446 (clobber (reg:CC FLAGS_REG))])]
5447 "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
5450 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
5452 emit_insn (gen_fix_truncdi_i387_fisttp (operands[0], operands[1]));
5455 if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
5457 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
5458 emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
5459 if (out != operands[0])
5460 emit_move_insn (operands[0], out);
5465 (define_insn "fix<fixunssuffix>_trunchf<mode>2"
5466 [(set (match_operand:SWI48 0 "register_operand" "=r")
5468 (match_operand:HF 1 "nonimmediate_operand" "vm")))]
5470 "vcvttsh2<fixsuffix>si\t{%1, %0|%0, %1}"
5471 [(set_attr "type" "sseicvt")
5472 (set_attr "prefix" "evex")
5473 (set_attr "mode" "<MODE>")])
5475 ;; Signed conversion to SImode.
5477 (define_expand "fix_truncxfsi2"
5478 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand")
5479 (fix:SI (match_operand:XF 1 "register_operand")))
5480 (clobber (reg:CC FLAGS_REG))])]
5485 emit_insn (gen_fix_truncsi_i387_fisttp (operands[0], operands[1]));
5490 (define_expand "fix_trunc<mode>si2"
5491 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand")
5492 (fix:SI (match_operand:MODEF 1 "register_operand")))
5493 (clobber (reg:CC FLAGS_REG))])]
5494 "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
5497 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
5499 emit_insn (gen_fix_truncsi_i387_fisttp (operands[0], operands[1]));
5502 if (SSE_FLOAT_MODE_P (<MODE>mode))
5504 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
5505 emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
5506 if (out != operands[0])
5507 emit_move_insn (operands[0], out);
5512 ;; Signed conversion to HImode.
5514 (define_expand "fix_trunc<mode>hi2"
5515 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand")
5516 (fix:HI (match_operand:X87MODEF 1 "register_operand")))
5517 (clobber (reg:CC FLAGS_REG))])]
5519 && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
5523 emit_insn (gen_fix_trunchi_i387_fisttp (operands[0], operands[1]));
5528 ;; Unsigned conversion to DImode
5530 (define_insn "fixuns_trunc<mode>di2"
5531 [(set (match_operand:DI 0 "register_operand" "=r")
5533 (match_operand:MODEF 1 "nonimmediate_operand" "vm")))]
5534 "TARGET_64BIT && TARGET_AVX512F && TARGET_SSE_MATH"
5535 "vcvtt<ssemodesuffix>2usi\t{%1, %0|%0, %1}"
5536 [(set_attr "type" "sseicvt")
5537 (set_attr "prefix" "evex")
5538 (set_attr "mode" "DI")])
5540 ;; Unsigned conversion to SImode.
5542 (define_expand "fixuns_trunc<mode>si2"
5544 [(set (match_operand:SI 0 "register_operand")
5546 (match_operand:MODEF 1 "nonimmediate_operand")))
5548 (clobber (scratch:<ssevecmode>))
5549 (clobber (scratch:<ssevecmode>))])]
5550 "(!TARGET_64BIT || TARGET_AVX512F) && TARGET_SSE2 && TARGET_SSE_MATH"
5552 machine_mode mode = <MODE>mode;
5553 machine_mode vecmode = <ssevecmode>mode;
5554 REAL_VALUE_TYPE TWO31r;
5559 emit_insn (gen_fixuns_trunc<mode>si2_avx512f (operands[0], operands[1]));
5563 if (optimize_insn_for_size_p ())
5566 real_ldexp (&TWO31r, &dconst1, 31);
5567 two31 = const_double_from_real_value (TWO31r, mode);
5568 two31 = ix86_build_const_vector (vecmode, true, two31);
5569 operands[2] = force_reg (vecmode, two31);
5572 (define_insn "fixuns_trunc<mode>si2_avx512f"
5573 [(set (match_operand:SI 0 "register_operand" "=r")
5575 (match_operand:MODEF 1 "nonimmediate_operand" "vm")))]
5576 "TARGET_AVX512F && TARGET_SSE_MATH"
5577 "vcvtt<ssemodesuffix>2usi\t{%1, %0|%0, %1}"
5578 [(set_attr "type" "sseicvt")
5579 (set_attr "prefix" "evex")
5580 (set_attr "mode" "SI")])
5582 (define_insn "*fixuns_trunchfsi2zext"
5583 [(set (match_operand:DI 0 "register_operand" "=r")
5586 (match_operand:HF 1 "nonimmediate_operand" "vm"))))]
5587 "TARGET_64BIT && TARGET_AVX512FP16"
5588 "vcvttsh2usi\t{%1, %k0|%k0, %1}"
5589 [(set_attr "type" "sseicvt")
5590 (set_attr "prefix" "evex")
5591 (set_attr "mode" "SI")])
5593 (define_insn "*fixuns_trunc<mode>si2_avx512f_zext"
5594 [(set (match_operand:DI 0 "register_operand" "=r")
5597 (match_operand:MODEF 1 "nonimmediate_operand" "vm"))))]
5598 "TARGET_64BIT && TARGET_AVX512F && TARGET_SSE_MATH"
5599 "vcvtt<ssemodesuffix>2usi\t{%1, %k0|%k0, %1}"
5600 [(set_attr "type" "sseicvt")
5601 (set_attr "prefix" "evex")
5602 (set_attr "mode" "SI")])
5604 (define_insn_and_split "*fixuns_trunc<mode>_1"
5605 [(set (match_operand:SI 0 "register_operand" "=&x,&x")
5607 (match_operand:MODEF 3 "nonimmediate_operand" "xm,xm")))
5608 (use (match_operand:<ssevecmode> 4 "nonimmediate_operand" "m,x"))
5609 (clobber (match_scratch:<ssevecmode> 1 "=x,&x"))
5610 (clobber (match_scratch:<ssevecmode> 2 "=x,x"))]
5611 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH
5612 && optimize_function_for_speed_p (cfun)"
5614 "&& reload_completed"
5617 ix86_split_convert_uns_si_sse (operands);
5621 ;; Unsigned conversion to HImode.
5622 ;; Without these patterns, we'll try the unsigned SI conversion which
5623 ;; is complex for SSE, rather than the signed SI conversion, which isn't.
5625 (define_expand "fixuns_trunchfhi2"
5627 (fix:SI (match_operand:HF 1 "nonimmediate_operand")))
5628 (set (match_operand:HI 0 "nonimmediate_operand")
5629 (subreg:HI (match_dup 2) 0))]
5631 "operands[2] = gen_reg_rtx (SImode);")
5633 (define_expand "fixuns_trunc<mode>hi2"
5635 (fix:SI (match_operand:MODEF 1 "nonimmediate_operand")))
5636 (set (match_operand:HI 0 "nonimmediate_operand")
5637 (subreg:HI (match_dup 2) 0))]
5638 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
5639 "operands[2] = gen_reg_rtx (SImode);")
5641 ;; When SSE is available, it is always faster to use it!
5642 (define_insn "fix_trunc<MODEF:mode><SWI48:mode>_sse"
5643 [(set (match_operand:SWI48 0 "register_operand" "=r,r")
5644 (fix:SWI48 (match_operand:MODEF 1 "nonimmediate_operand" "v,m")))]
5645 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode)
5646 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
5647 "%vcvtt<MODEF:ssemodesuffix>2si<SWI48:rex64suffix>\t{%1, %0|%0, %1}"
5648 [(set_attr "type" "sseicvt")
5649 (set_attr "prefix" "maybe_vex")
5650 (set (attr "prefix_rex")
5652 (match_test "<SWI48:MODE>mode == DImode")
5654 (const_string "*")))
5655 (set_attr "mode" "<MODEF:MODE>")
5656 (set_attr "athlon_decode" "double,vector")
5657 (set_attr "amdfam10_decode" "double,double")
5658 (set_attr "bdver1_decode" "double,double")])
5660 ;; Avoid vector decoded forms of the instruction.
5662 [(match_scratch:MODEF 2 "x")
5663 (set (match_operand:SWI48 0 "register_operand")
5664 (fix:SWI48 (match_operand:MODEF 1 "memory_operand")))]
5665 "TARGET_AVOID_VECTOR_DECODE
5666 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode)
5667 && optimize_insn_for_speed_p ()"
5668 [(set (match_dup 2) (match_dup 1))
5669 (set (match_dup 0) (fix:SWI48 (match_dup 2)))])
5671 (define_insn "fix_trunc<mode>_i387_fisttp"
5672 [(set (match_operand:SWI248x 0 "nonimmediate_operand" "=m")
5673 (fix:SWI248x (match_operand 1 "register_operand" "f")))
5674 (clobber (match_scratch:XF 2 "=&f"))]
5675 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5677 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
5678 && (TARGET_64BIT || <MODE>mode != DImode))
5679 && TARGET_SSE_MATH)"
5680 "* return output_fix_trunc (insn, operands, true);"
5681 [(set_attr "type" "fisttp")
5682 (set_attr "mode" "<MODE>")])
5684 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
5685 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
5686 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
5687 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
5688 ;; function in i386.cc.
5689 (define_insn_and_split "*fix_trunc<mode>_i387_1"
5690 [(set (match_operand:SWI248x 0 "nonimmediate_operand")
5691 (fix:SWI248x (match_operand 1 "register_operand")))
5692 (clobber (reg:CC FLAGS_REG))]
5693 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5695 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
5696 && (TARGET_64BIT || <MODE>mode != DImode))
5697 && ix86_pre_reload_split ()"
5702 ix86_optimize_mode_switching[I387_TRUNC] = 1;
5704 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
5705 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
5707 emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
5708 operands[2], operands[3]));
5711 [(set_attr "type" "fistp")
5712 (set_attr "i387_cw" "trunc")
5713 (set_attr "mode" "<MODE>")])
5715 (define_insn "fix_truncdi_i387"
5716 [(set (match_operand:DI 0 "nonimmediate_operand" "=m")
5717 (fix:DI (match_operand 1 "register_operand" "f")))
5718 (use (match_operand:HI 2 "memory_operand" "m"))
5719 (use (match_operand:HI 3 "memory_operand" "m"))
5720 (clobber (match_scratch:XF 4 "=&f"))]
5721 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5723 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
5724 "* return output_fix_trunc (insn, operands, false);"
5725 [(set_attr "type" "fistp")
5726 (set_attr "i387_cw" "trunc")
5727 (set_attr "mode" "DI")])
5729 (define_insn "fix_trunc<mode>_i387"
5730 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m")
5731 (fix:SWI24 (match_operand 1 "register_operand" "f")))
5732 (use (match_operand:HI 2 "memory_operand" "m"))
5733 (use (match_operand:HI 3 "memory_operand" "m"))]
5734 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5736 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
5737 "* return output_fix_trunc (insn, operands, false);"
5738 [(set_attr "type" "fistp")
5739 (set_attr "i387_cw" "trunc")
5740 (set_attr "mode" "<MODE>")])
5742 (define_insn "x86_fnstcw_1"
5743 [(set (match_operand:HI 0 "memory_operand" "=m")
5744 (unspec:HI [(const_int 0)] UNSPEC_FSTCW))]
5747 [(set (attr "length")
5748 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
5749 (set_attr "mode" "HI")
5750 (set_attr "unit" "i387")
5751 (set_attr "bdver1_decode" "vector")])
5753 ;; Conversion between fixed point and floating point.
5755 ;; Even though we only accept memory inputs, the backend _really_
5756 ;; wants to be able to do this between registers. Thankfully, LRA
5757 ;; will fix this up for us during register allocation.
5759 (define_insn "floathi<mode>2"
5760 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5761 (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "m")))]
5763 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5764 || TARGET_MIX_SSE_I387)"
5766 [(set_attr "type" "fmov")
5767 (set_attr "mode" "<MODE>")
5768 (set_attr "znver1_decode" "double")
5769 (set_attr "fp_int_src" "true")])
5771 (define_insn "float<SWI48x:mode>xf2"
5772 [(set (match_operand:XF 0 "register_operand" "=f")
5773 (float:XF (match_operand:SWI48x 1 "nonimmediate_operand" "m")))]
5776 [(set_attr "type" "fmov")
5777 (set_attr "mode" "XF")
5778 (set_attr "znver1_decode" "double")
5779 (set_attr "fp_int_src" "true")])
5781 (define_expand "float<SWI48x:mode><MODEF:mode>2"
5782 [(set (match_operand:MODEF 0 "register_operand")
5783 (float:MODEF (match_operand:SWI48x 1 "nonimmediate_operand")))]
5784 "(TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI48x:MODE>mode))
5785 || (SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5786 && ((<SWI48x:MODE>mode != DImode) || TARGET_64BIT))")
5788 (define_insn "*float<SWI48:mode><MODEF:mode>2"
5789 [(set (match_operand:MODEF 0 "register_operand" "=f,v,v")
5791 (match_operand:SWI48 1 "nonimmediate_operand" "m,r,m")))]
5792 "(TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI48:MODE>mode))
5793 || (SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)"
5796 %vcvtsi2<MODEF:ssemodesuffix><SWI48:rex64suffix>\t{%1, %d0|%d0, %1}
5797 %vcvtsi2<MODEF:ssemodesuffix><SWI48:rex64suffix>\t{%1, %d0|%d0, %1}"
5798 [(set_attr "type" "fmov,sseicvt,sseicvt")
5799 (set_attr "avx_partial_xmm_update" "false,true,true")
5800 (set_attr "prefix" "orig,maybe_vex,maybe_vex")
5801 (set_attr "mode" "<MODEF:MODE>")
5802 (set (attr "prefix_rex")
5804 (and (eq_attr "prefix" "maybe_vex")
5805 (match_test "<SWI48:MODE>mode == DImode"))
5807 (const_string "*")))
5808 (set_attr "unit" "i387,*,*")
5809 (set_attr "athlon_decode" "*,double,direct")
5810 (set_attr "amdfam10_decode" "*,vector,double")
5811 (set_attr "bdver1_decode" "*,double,direct")
5812 (set_attr "znver1_decode" "double,*,*")
5813 (set_attr "fp_int_src" "true")
5814 (set (attr "enabled")
5816 (match_test ("SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"))
5818 (eq_attr "alternative" "0")
5819 (symbol_ref "TARGET_MIX_SSE_I387
5820 && X87_ENABLE_FLOAT (<MODEF:MODE>mode,
5822 (symbol_ref "true"))
5824 (eq_attr "alternative" "0")
5826 (symbol_ref "false"))))
5827 (set (attr "preferred_for_speed")
5828 (cond [(eq_attr "alternative" "1")
5829 (symbol_ref "TARGET_INTER_UNIT_CONVERSIONS")]
5830 (symbol_ref "true")))])
5832 (define_insn "float<floatunssuffix><mode>hf2"
5833 [(set (match_operand:HF 0 "register_operand" "=v")
5835 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))]
5837 "vcvt<floatsuffix>si2sh<rex64suffix>\t{%1, %d0|%d0, %1}"
5838 [(set_attr "type" "sseicvt")
5839 (set_attr "prefix" "evex")
5840 (set_attr "mode" "HF")])
5842 (define_insn "*floatdi<MODEF:mode>2_i387"
5843 [(set (match_operand:MODEF 0 "register_operand" "=f")
5844 (float:MODEF (match_operand:DI 1 "nonimmediate_operand" "m")))]
5846 && TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, DImode)"
5848 [(set_attr "type" "fmov")
5849 (set_attr "mode" "<MODEF:MODE>")
5850 (set_attr "znver1_decode" "double")
5851 (set_attr "fp_int_src" "true")])
5853 ;; Try TARGET_USE_VECTOR_CONVERTS, but not so hard as to require extra memory
5854 ;; slots when !TARGET_INTER_UNIT_MOVES_TO_VEC disables the general_regs
5855 ;; alternative in sse2_loadld.
5857 [(set (match_operand:MODEF 0 "sse_reg_operand")
5858 (float:MODEF (match_operand:SI 1 "nonimmediate_operand")))]
5860 && TARGET_USE_VECTOR_CONVERTS
5861 && optimize_function_for_speed_p (cfun)
5863 && (MEM_P (operands[1]) || TARGET_INTER_UNIT_MOVES_TO_VEC)
5864 && (!EXT_REX_SSE_REG_P (operands[0])
5865 || TARGET_AVX512VL)"
5868 operands[3] = lowpart_subreg (<ssevecmode>mode, operands[0], <MODE>mode);
5869 operands[4] = lowpart_subreg (V4SImode, operands[0], <MODE>mode);
5871 emit_insn (gen_sse2_loadld (operands[4],
5872 CONST0_RTX (V4SImode), operands[1]));
5874 if (<ssevecmode>mode == V4SFmode)
5875 emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
5877 emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
5881 ;; Avoid store forwarding (partial memory) stall penalty
5882 ;; by passing DImode value through XMM registers. */
5885 [(set (match_operand:X87MODEF 0 "register_operand")
5887 (match_operand:DI 1 "register_operand")))]
5888 "!TARGET_64BIT && TARGET_INTER_UNIT_MOVES_TO_VEC
5889 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5890 && TARGET_SSE2 && optimize_function_for_speed_p (cfun)
5891 && can_create_pseudo_p ()"
5894 rtx s = assign_386_stack_local (DImode, SLOT_FLOATxFDI_387);
5895 emit_insn (gen_floatdi<mode>2_i387_with_xmm (operands[0], operands[1], s));
5899 (define_insn_and_split "floatdi<X87MODEF:mode>2_i387_with_xmm"
5900 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5902 (match_operand:DI 1 "register_operand" "r,r")))
5903 (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
5904 (clobber (match_scratch:V4SI 3 "=x,x"))
5905 (clobber (match_scratch:V4SI 4 "=X,x"))]
5906 "!TARGET_64BIT && TARGET_INTER_UNIT_MOVES_TO_VEC
5907 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5908 && TARGET_SSE2 && optimize_function_for_speed_p (cfun)"
5910 "&& reload_completed"
5911 [(set (match_dup 2) (match_dup 3))
5912 (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5914 /* The DImode arrived in a pair of integral registers (e.g. %edx:%eax).
5915 Assemble the 64-bit DImode value in an xmm register. */
5916 emit_insn (gen_sse2_loadld (operands[3], CONST0_RTX (V4SImode),
5917 gen_lowpart (SImode, operands[1])));
5919 emit_insn (gen_sse4_1_pinsrd (operands[3], operands[3],
5920 gen_highpart (SImode, operands[1]),
5924 emit_insn (gen_sse2_loadld (operands[4], CONST0_RTX (V4SImode),
5925 gen_highpart (SImode, operands[1])));
5926 emit_insn (gen_vec_interleave_lowv4si (operands[3], operands[3],
5929 operands[3] = gen_lowpart (DImode, operands[3]);
5931 [(set_attr "isa" "sse4,*")
5932 (set_attr "type" "multi")
5933 (set_attr "mode" "<X87MODEF:MODE>")
5934 (set_attr "unit" "i387")
5935 (set_attr "fp_int_src" "true")])
5937 ;; Break partial SSE register dependency stall. This splitter should split
5938 ;; late in the pass sequence (after register rename pass), so allocated
5939 ;; registers won't change anymore
5942 [(set (match_operand:MODEF 0 "sse_reg_operand")
5943 (float:MODEF (match_operand:SWI48 1 "nonimmediate_operand")))]
5945 && TARGET_SSE_PARTIAL_REG_CONVERTS_DEPENDENCY
5946 && epilogue_completed
5947 && optimize_function_for_speed_p (cfun)
5948 && (!EXT_REX_SSE_REG_P (operands[0])
5949 || TARGET_AVX512VL)"
5951 (vec_merge:<MODEF:ssevecmode>
5952 (vec_duplicate:<MODEF:ssevecmode>
5958 const machine_mode vmode = <MODEF:ssevecmode>mode;
5960 operands[0] = lowpart_subreg (vmode, operands[0], <MODEF:MODE>mode);
5961 emit_move_insn (operands[0], CONST0_RTX (vmode));
5964 (define_expand "floatuns<SWI12:mode><MODEF:mode>2"
5965 [(set (match_operand:MODEF 0 "register_operand")
5966 (unsigned_float:MODEF
5967 (match_operand:SWI12 1 "nonimmediate_operand")))]
5969 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
5971 operands[1] = convert_to_mode (SImode, operands[1], 1);
5972 emit_insn (gen_floatsi<MODEF:mode>2 (operands[0], operands[1]));
5976 (define_insn "*floatuns<SWI48:mode><MODEF:mode>2_avx512"
5977 [(set (match_operand:MODEF 0 "register_operand" "=v")
5978 (unsigned_float:MODEF
5979 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))]
5980 "TARGET_AVX512F && TARGET_SSE_MATH"
5981 "vcvtusi2<MODEF:ssemodesuffix><SWI48:rex64suffix>\t{%1, %0, %0|%0, %0, %1}"
5982 [(set_attr "type" "sseicvt")
5983 (set_attr "avx_partial_xmm_update" "true")
5984 (set_attr "prefix" "evex")
5985 (set_attr "mode" "<MODEF:MODE>")])
5987 ;; Avoid store forwarding (partial memory) stall penalty by extending
5988 ;; SImode value to DImode through XMM register instead of pushing two
5989 ;; SImode values to stack. Also note that fild loads from memory only.
5991 (define_insn_and_split "floatunssi<mode>2_i387_with_xmm"
5992 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5993 (unsigned_float:X87MODEF
5994 (match_operand:SI 1 "nonimmediate_operand" "rm")))
5995 (clobber (match_operand:DI 2 "memory_operand" "=m"))
5996 (clobber (match_scratch:DI 3 "=x"))]
5998 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5999 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC"
6001 "&& reload_completed"
6002 [(set (match_dup 3) (zero_extend:DI (match_dup 1)))
6003 (set (match_dup 2) (match_dup 3))
6005 (float:X87MODEF (match_dup 2)))]
6007 [(set_attr "type" "multi")
6008 (set_attr "mode" "<MODE>")])
6010 (define_expand "floatunssi<mode>2"
6011 [(set (match_operand:X87MODEF 0 "register_operand")
6012 (unsigned_float:X87MODEF
6013 (match_operand:SI 1 "nonimmediate_operand")))]
6015 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
6016 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC)
6017 || ((!TARGET_64BIT || TARGET_AVX512F)
6018 && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
6020 if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
6022 emit_insn (gen_floatunssi<mode>2_i387_with_xmm
6023 (operands[0], operands[1],
6024 assign_386_stack_local (DImode, SLOT_TEMP)));
6027 if (!TARGET_AVX512F)
6029 ix86_expand_convert_uns_si<mode>_sse (operands[0], operands[1]);
6034 (define_expand "floatunsdisf2"
6035 [(set (match_operand:SF 0 "register_operand")
6037 (match_operand:DI 1 "nonimmediate_operand")))]
6038 "TARGET_64BIT && TARGET_SSE && TARGET_SSE_MATH"
6040 if (!TARGET_AVX512F)
6042 x86_emit_floatuns (operands);
6047 (define_expand "floatunsdidf2"
6048 [(set (match_operand:DF 0 "register_operand")
6050 (match_operand:DI 1 "nonimmediate_operand")))]
6051 "((TARGET_64BIT && TARGET_AVX512F)
6052 || TARGET_KEEPS_VECTOR_ALIGNED_STACK)
6053 && TARGET_SSE2 && TARGET_SSE_MATH"
6057 ix86_expand_convert_uns_didf_sse (operands[0], operands[1]);
6060 if (!TARGET_AVX512F)
6062 x86_emit_floatuns (operands);
6067 ;; Load effective address instructions
6069 (define_insn "*lea<mode>"
6070 [(set (match_operand:SWI48 0 "register_operand" "=r")
6071 (match_operand:SWI48 1 "address_no_seg_operand" "Ts"))]
6072 "ix86_hardreg_mov_ok (operands[0], operands[1])"
6074 if (SImode_address_operand (operands[1], VOIDmode))
6076 gcc_assert (TARGET_64BIT);
6077 return "lea{l}\t{%E1, %k0|%k0, %E1}";
6080 return "lea{<imodesuffix>}\t{%E1, %0|%0, %E1}";
6082 [(set_attr "type" "lea")
6085 (match_operand 1 "SImode_address_operand")
6087 (const_string "<MODE>")))])
6090 [(set (match_operand:SWI48 0 "register_operand")
6091 (match_operand:SWI48 1 "address_no_seg_operand"))]
6092 "ix86_hardreg_mov_ok (operands[0], operands[1])
6093 && peep2_regno_dead_p (0, FLAGS_REG)
6094 && ix86_avoid_lea_for_addr (peep2_next_insn (0), operands)"
6097 machine_mode mode = <MODE>mode;
6099 /* Emit all operations in SImode for zero-extended addresses. */
6100 if (SImode_address_operand (operands[1], VOIDmode))
6103 ix86_split_lea_for_addr (peep2_next_insn (0), operands, mode);
6105 /* Zero-extend return register to DImode for zero-extended addresses. */
6106 if (mode != <MODE>mode)
6107 emit_insn (gen_zero_extendsidi2 (operands[0],
6108 gen_lowpart (mode, operands[0])));
6113 ;; ix86_split_lea_for_addr emits the shifts as MULT to avoid it from being
6114 ;; peephole2 optimized back into a lea. Split that into the shift during
6115 ;; the following split pass.
6117 [(set (match_operand:SWI48 0 "general_reg_operand")
6118 (mult:SWI48 (match_dup 0) (match_operand:SWI48 1 "const1248_operand")))
6119 (clobber (reg:CC FLAGS_REG))]
6121 [(parallel [(set (match_dup 0) (ashift:SWI48 (match_dup 0) (match_dup 1)))
6122 (clobber (reg:CC FLAGS_REG))])]
6123 "operands[1] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
6127 (define_expand "add<mode>3"
6128 [(set (match_operand:SDWIM 0 "nonimmediate_operand")
6129 (plus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")
6130 (match_operand:SDWIM 2 "<general_hilo_operand>")))]
6132 "ix86_expand_binary_operator (PLUS, <MODE>mode, operands); DONE;")
6134 (define_insn_and_split "*add<dwi>3_doubleword"
6135 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro,r")
6137 (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0")
6138 (match_operand:<DWI> 2 "x86_64_hilo_general_operand" "r<di>,o")))
6139 (clobber (reg:CC FLAGS_REG))]
6140 "ix86_binary_operator_ok (PLUS, <DWI>mode, operands)"
6142 "&& reload_completed"
6143 [(parallel [(set (reg:CCC FLAGS_REG)
6145 (plus:DWIH (match_dup 1) (match_dup 2))
6148 (plus:DWIH (match_dup 1) (match_dup 2)))])
6149 (parallel [(set (match_dup 3)
6152 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
6155 (clobber (reg:CC FLAGS_REG))])]
6157 split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
6158 if (operands[2] == const0_rtx)
6160 if (operands[5] != const0_rtx)
6161 ix86_expand_binary_operator (PLUS, <MODE>mode, &operands[3]);
6162 else if (!rtx_equal_p (operands[3], operands[4]))
6163 emit_move_insn (operands[3], operands[4]);
6165 emit_note (NOTE_INSN_DELETED);
6170 (define_insn_and_split "*add<dwi>3_doubleword_zext"
6171 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
6174 (match_operand:DWIH 2 "nonimmediate_operand" "rm,r"))
6175 (match_operand:<DWI> 1 "nonimmediate_operand" "0,0")))
6176 (clobber (reg:CC FLAGS_REG))]
6177 "ix86_binary_operator_ok (UNKNOWN, <DWI>mode, operands)"
6179 "&& reload_completed"
6180 [(parallel [(set (reg:CCC FLAGS_REG)
6182 (plus:DWIH (match_dup 1) (match_dup 2))
6185 (plus:DWIH (match_dup 1) (match_dup 2)))])
6186 (parallel [(set (match_dup 3)
6189 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
6192 (clobber (reg:CC FLAGS_REG))])]
6193 "split_double_mode (<DWI>mode, &operands[0], 2, &operands[0], &operands[3]);")
6195 (define_insn_and_split "*add<dwi>3_doubleword_concat"
6196 [(set (match_operand:<DWI> 0 "register_operand" "=&r")
6201 (match_operand:DWIH 2 "nonimmediate_operand" "rm"))
6202 (match_operand:QI 3 "const_int_operand"))
6204 (match_operand:DWIH 4 "nonimmediate_operand" "rm")))
6205 (match_operand:<DWI> 1 "register_operand" "0")))
6206 (clobber (reg:CC FLAGS_REG))]
6207 "INTVAL (operands[3]) == <MODE_SIZE> * BITS_PER_UNIT"
6209 "&& reload_completed"
6210 [(parallel [(set (reg:CCC FLAGS_REG)
6212 (plus:DWIH (match_dup 1) (match_dup 4))
6215 (plus:DWIH (match_dup 1) (match_dup 4)))])
6216 (parallel [(set (match_dup 5)
6219 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
6222 (clobber (reg:CC FLAGS_REG))])]
6223 "split_double_mode (<DWI>mode, &operands[0], 2, &operands[0], &operands[5]);")
6225 (define_insn "*add<mode>_1"
6226 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r,r,r")
6228 (match_operand:SWI48 1 "nonimmediate_operand" "%0,0,r,r")
6229 (match_operand:SWI48 2 "x86_64_general_operand" "re,BM,0,le")))
6230 (clobber (reg:CC FLAGS_REG))]
6231 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6233 switch (get_attr_type (insn))
6239 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6240 if (operands[2] == const1_rtx)
6241 return "inc{<imodesuffix>}\t%0";
6244 gcc_assert (operands[2] == constm1_rtx);
6245 return "dec{<imodesuffix>}\t%0";
6249 /* For most processors, ADD is faster than LEA. This alternative
6250 was added to use ADD as much as possible. */
6251 if (which_alternative == 2)
6252 std::swap (operands[1], operands[2]);
6254 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6255 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6256 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6258 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6262 (cond [(eq_attr "alternative" "3")
6263 (const_string "lea")
6264 (match_operand:SWI48 2 "incdec_operand")
6265 (const_string "incdec")
6267 (const_string "alu")))
6268 (set (attr "length_immediate")
6270 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6272 (const_string "*")))
6273 (set_attr "mode" "<MODE>")])
6275 ;; It may seem that nonimmediate operand is proper one for operand 1.
6276 ;; The addsi_1 pattern allows nonimmediate operand at that place and
6277 ;; we take care in ix86_binary_operator_ok to not allow two memory
6278 ;; operands so proper swapping will be done in reload. This allow
6279 ;; patterns constructed from addsi_1 to match.
6281 (define_insn "addsi_1_zext"
6282 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6284 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r,r")
6285 (match_operand:SI 2 "x86_64_general_operand" "rBMe,0,le"))))
6286 (clobber (reg:CC FLAGS_REG))]
6287 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6289 switch (get_attr_type (insn))
6295 if (operands[2] == const1_rtx)
6296 return "inc{l}\t%k0";
6299 gcc_assert (operands[2] == constm1_rtx);
6300 return "dec{l}\t%k0";
6304 /* For most processors, ADD is faster than LEA. This alternative
6305 was added to use ADD as much as possible. */
6306 if (which_alternative == 1)
6307 std::swap (operands[1], operands[2]);
6309 if (x86_maybe_negate_const_int (&operands[2], SImode))
6310 return "sub{l}\t{%2, %k0|%k0, %2}";
6312 return "add{l}\t{%2, %k0|%k0, %2}";
6316 (cond [(eq_attr "alternative" "2")
6317 (const_string "lea")
6318 (match_operand:SI 2 "incdec_operand")
6319 (const_string "incdec")
6321 (const_string "alu")))
6322 (set (attr "length_immediate")
6324 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6326 (const_string "*")))
6327 (set_attr "mode" "SI")])
6329 (define_insn "*addhi_1"
6330 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r,Yp")
6331 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r,Yp")
6332 (match_operand:HI 2 "general_operand" "rn,m,0,ln")))
6333 (clobber (reg:CC FLAGS_REG))]
6334 "ix86_binary_operator_ok (PLUS, HImode, operands)"
6336 switch (get_attr_type (insn))
6342 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6343 if (operands[2] == const1_rtx)
6344 return "inc{w}\t%0";
6347 gcc_assert (operands[2] == constm1_rtx);
6348 return "dec{w}\t%0";
6352 /* For most processors, ADD is faster than LEA. This alternative
6353 was added to use ADD as much as possible. */
6354 if (which_alternative == 2)
6355 std::swap (operands[1], operands[2]);
6357 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6358 if (x86_maybe_negate_const_int (&operands[2], HImode))
6359 return "sub{w}\t{%2, %0|%0, %2}";
6361 return "add{w}\t{%2, %0|%0, %2}";
6365 (cond [(eq_attr "alternative" "3")
6366 (const_string "lea")
6367 (match_operand:HI 2 "incdec_operand")
6368 (const_string "incdec")
6370 (const_string "alu")))
6371 (set (attr "length_immediate")
6373 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6375 (const_string "*")))
6376 (set_attr "mode" "HI,HI,HI,SI")])
6378 (define_insn "*addqi_1"
6379 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,q,r,r,Yp")
6380 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,q,0,r,Yp")
6381 (match_operand:QI 2 "general_operand" "qn,m,0,rn,0,ln")))
6382 (clobber (reg:CC FLAGS_REG))]
6383 "ix86_binary_operator_ok (PLUS, QImode, operands)"
6385 bool widen = (get_attr_mode (insn) != MODE_QI);
6387 switch (get_attr_type (insn))
6393 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6394 if (operands[2] == const1_rtx)
6395 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6398 gcc_assert (operands[2] == constm1_rtx);
6399 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6403 /* For most processors, ADD is faster than LEA. These alternatives
6404 were added to use ADD as much as possible. */
6405 if (which_alternative == 2 || which_alternative == 4)
6406 std::swap (operands[1], operands[2]);
6408 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6409 if (x86_maybe_negate_const_int (&operands[2], QImode))
6412 return "sub{l}\t{%2, %k0|%k0, %2}";
6414 return "sub{b}\t{%2, %0|%0, %2}";
6417 return "add{l}\t{%k2, %k0|%k0, %k2}";
6419 return "add{b}\t{%2, %0|%0, %2}";
6423 (cond [(eq_attr "alternative" "5")
6424 (const_string "lea")
6425 (match_operand:QI 2 "incdec_operand")
6426 (const_string "incdec")
6428 (const_string "alu")))
6429 (set (attr "length_immediate")
6431 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6433 (const_string "*")))
6434 (set_attr "mode" "QI,QI,QI,SI,SI,SI")
6435 ;; Potential partial reg stall on alternatives 3 and 4.
6436 (set (attr "preferred_for_speed")
6437 (cond [(eq_attr "alternative" "3,4")
6438 (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
6439 (symbol_ref "true")))])
6441 ;; Alternative 1 is needed to work around LRA limitation, see PR82524.
6442 (define_insn_and_split "*add<mode>_1_slp"
6443 [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>,&<r>"))
6444 (plus:SWI12 (match_operand:SWI12 1 "nonimmediate_operand" "%0,!<r>")
6445 (match_operand:SWI12 2 "general_operand" "<r>mn,<r>mn")))
6446 (clobber (reg:CC FLAGS_REG))]
6447 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
6449 if (which_alternative)
6452 switch (get_attr_type (insn))
6455 if (operands[2] == const1_rtx)
6456 return "inc{<imodesuffix>}\t%0";
6459 gcc_assert (operands[2] == constm1_rtx);
6460 return "dec{<imodesuffix>}\t%0";
6464 if (x86_maybe_negate_const_int (&operands[2], QImode))
6465 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6467 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6470 "&& reload_completed"
6471 [(set (strict_low_part (match_dup 0)) (match_dup 1))
6473 [(set (strict_low_part (match_dup 0))
6474 (plus:SWI12 (match_dup 0) (match_dup 2)))
6475 (clobber (reg:CC FLAGS_REG))])]
6478 (if_then_else (match_operand:QI 2 "incdec_operand")
6479 (const_string "incdec")
6480 (const_string "alu")))
6481 (set_attr "mode" "<MODE>")])
6483 ;; Split non destructive adds if we cannot use lea.
6485 [(set (match_operand:SWI48 0 "register_operand")
6486 (plus:SWI48 (match_operand:SWI48 1 "register_operand")
6487 (match_operand:SWI48 2 "x86_64_nonmemory_operand")))
6488 (clobber (reg:CC FLAGS_REG))]
6489 "reload_completed && ix86_avoid_lea_for_add (insn, operands)"
6490 [(set (match_dup 0) (match_dup 1))
6491 (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 2)))
6492 (clobber (reg:CC FLAGS_REG))])])
6494 ;; Split non destructive adds if we cannot use lea.
6496 [(set (match_operand:DI 0 "register_operand")
6498 (plus:SI (match_operand:SI 1 "register_operand")
6499 (match_operand:SI 2 "x86_64_nonmemory_operand"))))
6500 (clobber (reg:CC FLAGS_REG))]
6502 && reload_completed && ix86_avoid_lea_for_add (insn, operands)"
6503 [(set (match_dup 3) (match_dup 1))
6504 (parallel [(set (match_dup 0)
6505 (zero_extend:DI (plus:SI (match_dup 3) (match_dup 2))))
6506 (clobber (reg:CC FLAGS_REG))])]
6507 "operands[3] = gen_lowpart (SImode, operands[0]);")
6509 ;; Convert add to the lea pattern to avoid flags dependency.
6511 [(set (match_operand:SWI 0 "register_operand")
6512 (plus:SWI (match_operand:SWI 1 "register_operand")
6513 (match_operand:SWI 2 "<nonmemory_operand>")))
6514 (clobber (reg:CC FLAGS_REG))]
6515 "reload_completed && ix86_lea_for_add_ok (insn, operands)"
6517 (plus:<LEAMODE> (match_dup 1) (match_dup 2)))]
6519 if (<MODE>mode != <LEAMODE>mode)
6521 operands[0] = gen_lowpart (<LEAMODE>mode, operands[0]);
6522 operands[1] = gen_lowpart (<LEAMODE>mode, operands[1]);
6523 operands[2] = gen_lowpart (<LEAMODE>mode, operands[2]);
6527 ;; Convert add to the lea pattern to avoid flags dependency.
6529 [(set (match_operand:DI 0 "register_operand")
6531 (plus:SI (match_operand:SI 1 "register_operand")
6532 (match_operand:SI 2 "x86_64_nonmemory_operand"))))
6533 (clobber (reg:CC FLAGS_REG))]
6534 "TARGET_64BIT && reload_completed && ix86_lea_for_add_ok (insn, operands)"
6536 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))])
6538 (define_insn "*add<mode>_2"
6539 [(set (reg FLAGS_REG)
6542 (match_operand:SWI 1 "nonimmediate_operand" "%0,0,<r>")
6543 (match_operand:SWI 2 "<general_operand>" "<r><i>,<m>,0"))
6545 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>,<r>")
6546 (plus:SWI (match_dup 1) (match_dup 2)))]
6547 "ix86_match_ccmode (insn, CCGOCmode)
6548 && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6550 switch (get_attr_type (insn))
6553 if (operands[2] == const1_rtx)
6554 return "inc{<imodesuffix>}\t%0";
6557 gcc_assert (operands[2] == constm1_rtx);
6558 return "dec{<imodesuffix>}\t%0";
6562 if (which_alternative == 2)
6563 std::swap (operands[1], operands[2]);
6565 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6566 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6567 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6569 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6573 (if_then_else (match_operand:SWI 2 "incdec_operand")
6574 (const_string "incdec")
6575 (const_string "alu")))
6576 (set (attr "length_immediate")
6578 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6580 (const_string "*")))
6581 (set_attr "mode" "<MODE>")])
6583 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6584 (define_insn "*addsi_2_zext"
6585 [(set (reg FLAGS_REG)
6587 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
6588 (match_operand:SI 2 "x86_64_general_operand" "rBMe,0"))
6590 (set (match_operand:DI 0 "register_operand" "=r,r")
6591 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6592 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6593 && ix86_binary_operator_ok (PLUS, SImode, operands)"
6595 switch (get_attr_type (insn))
6598 if (operands[2] == const1_rtx)
6599 return "inc{l}\t%k0";
6602 gcc_assert (operands[2] == constm1_rtx);
6603 return "dec{l}\t%k0";
6607 if (which_alternative == 1)
6608 std::swap (operands[1], operands[2]);
6610 if (x86_maybe_negate_const_int (&operands[2], SImode))
6611 return "sub{l}\t{%2, %k0|%k0, %2}";
6613 return "add{l}\t{%2, %k0|%k0, %2}";
6617 (if_then_else (match_operand:SI 2 "incdec_operand")
6618 (const_string "incdec")
6619 (const_string "alu")))
6620 (set (attr "length_immediate")
6622 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6624 (const_string "*")))
6625 (set_attr "mode" "SI")])
6627 (define_insn "*add<mode>_3"
6628 [(set (reg FLAGS_REG)
6630 (neg:SWI (match_operand:SWI 2 "<general_operand>" "<g>,0"))
6631 (match_operand:SWI 1 "nonimmediate_operand" "%0,<r>")))
6632 (clobber (match_scratch:SWI 0 "=<r>,<r>"))]
6633 "ix86_match_ccmode (insn, CCZmode)
6634 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6636 switch (get_attr_type (insn))
6639 if (operands[2] == const1_rtx)
6640 return "inc{<imodesuffix>}\t%0";
6643 gcc_assert (operands[2] == constm1_rtx);
6644 return "dec{<imodesuffix>}\t%0";
6648 if (which_alternative == 1)
6649 std::swap (operands[1], operands[2]);
6651 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6652 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6653 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6655 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6659 (if_then_else (match_operand:SWI 2 "incdec_operand")
6660 (const_string "incdec")
6661 (const_string "alu")))
6662 (set (attr "length_immediate")
6664 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6666 (const_string "*")))
6667 (set_attr "mode" "<MODE>")])
6669 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6670 (define_insn "*addsi_3_zext"
6671 [(set (reg FLAGS_REG)
6673 (neg:SI (match_operand:SI 2 "x86_64_general_operand" "rBMe,0"))
6674 (match_operand:SI 1 "nonimmediate_operand" "%0,r")))
6675 (set (match_operand:DI 0 "register_operand" "=r,r")
6676 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6677 "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
6678 && ix86_binary_operator_ok (PLUS, SImode, operands)"
6680 switch (get_attr_type (insn))
6683 if (operands[2] == const1_rtx)
6684 return "inc{l}\t%k0";
6687 gcc_assert (operands[2] == constm1_rtx);
6688 return "dec{l}\t%k0";
6692 if (which_alternative == 1)
6693 std::swap (operands[1], operands[2]);
6695 if (x86_maybe_negate_const_int (&operands[2], SImode))
6696 return "sub{l}\t{%2, %k0|%k0, %2}";
6698 return "add{l}\t{%2, %k0|%k0, %2}";
6702 (if_then_else (match_operand:SI 2 "incdec_operand")
6703 (const_string "incdec")
6704 (const_string "alu")))
6705 (set (attr "length_immediate")
6707 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6709 (const_string "*")))
6710 (set_attr "mode" "SI")])
6712 ; For comparisons against 1, -1 and 128, we may generate better code
6713 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
6714 ; is matched then. We can't accept general immediate, because for
6715 ; case of overflows, the result is messed up.
6716 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6717 ; only for comparisons not depending on it.
6719 (define_insn "*adddi_4"
6720 [(set (reg FLAGS_REG)
6722 (match_operand:DI 1 "nonimmediate_operand" "0")
6723 (match_operand:DI 2 "x86_64_immediate_operand" "e")))
6724 (clobber (match_scratch:DI 0 "=r"))]
6726 && ix86_match_ccmode (insn, CCGCmode)"
6728 switch (get_attr_type (insn))
6731 if (operands[2] == constm1_rtx)
6732 return "inc{q}\t%0";
6735 gcc_assert (operands[2] == const1_rtx);
6736 return "dec{q}\t%0";
6740 if (x86_maybe_negate_const_int (&operands[2], DImode))
6741 return "add{q}\t{%2, %0|%0, %2}";
6743 return "sub{q}\t{%2, %0|%0, %2}";
6747 (if_then_else (match_operand:DI 2 "incdec_operand")
6748 (const_string "incdec")
6749 (const_string "alu")))
6750 (set (attr "length_immediate")
6752 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6754 (const_string "*")))
6755 (set_attr "mode" "DI")])
6757 ; For comparisons against 1, -1 and 128, we may generate better code
6758 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
6759 ; is matched then. We can't accept general immediate, because for
6760 ; case of overflows, the result is messed up.
6761 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6762 ; only for comparisons not depending on it.
6764 (define_insn "*add<mode>_4"
6765 [(set (reg FLAGS_REG)
6767 (match_operand:SWI124 1 "nonimmediate_operand" "0")
6768 (match_operand:SWI124 2 "const_int_operand")))
6769 (clobber (match_scratch:SWI124 0 "=<r>"))]
6770 "ix86_match_ccmode (insn, CCGCmode)"
6772 switch (get_attr_type (insn))
6775 if (operands[2] == constm1_rtx)
6776 return "inc{<imodesuffix>}\t%0";
6779 gcc_assert (operands[2] == const1_rtx);
6780 return "dec{<imodesuffix>}\t%0";
6784 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6785 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6787 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6791 (if_then_else (match_operand:<MODE> 2 "incdec_operand")
6792 (const_string "incdec")
6793 (const_string "alu")))
6794 (set (attr "length_immediate")
6796 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6798 (const_string "*")))
6799 (set_attr "mode" "<MODE>")])
6801 (define_insn "*add<mode>_5"
6802 [(set (reg FLAGS_REG)
6805 (match_operand:SWI 1 "nonimmediate_operand" "%0,<r>")
6806 (match_operand:SWI 2 "<general_operand>" "<g>,0"))
6808 (clobber (match_scratch:SWI 0 "=<r>,<r>"))]
6809 "ix86_match_ccmode (insn, CCGOCmode)
6810 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6812 switch (get_attr_type (insn))
6815 if (operands[2] == const1_rtx)
6816 return "inc{<imodesuffix>}\t%0";
6819 gcc_assert (operands[2] == constm1_rtx);
6820 return "dec{<imodesuffix>}\t%0";
6824 if (which_alternative == 1)
6825 std::swap (operands[1], operands[2]);
6827 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6828 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6829 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6831 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6835 (if_then_else (match_operand:SWI 2 "incdec_operand")
6836 (const_string "incdec")
6837 (const_string "alu")))
6838 (set (attr "length_immediate")
6840 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6842 (const_string "*")))
6843 (set_attr "mode" "<MODE>")])
6845 (define_insn "*addqi_ext<mode>_0"
6846 [(set (match_operand:QI 0 "nonimm_x64constmem_operand" "=QBc,m")
6849 (match_operator:SWI248 3 "extract_operator"
6850 [(match_operand 2 "int248_register_operand" "Q,Q")
6853 (match_operand:QI 1 "nonimm_x64constmem_operand" "0,0")))
6854 (clobber (reg:CC FLAGS_REG))]
6856 "add{b}\t{%h2, %0|%0, %h2}"
6857 [(set_attr "isa" "*,nox64")
6858 (set_attr "type" "alu")
6859 (set_attr "mode" "QI")])
6861 (define_expand "addqi_ext_1"
6863 [(set (zero_extract:HI (match_operand:HI 0 "register_operand")
6869 (zero_extract:HI (match_operand:HI 1 "register_operand")
6872 (match_operand:QI 2 "const_int_operand")) 0))
6873 (clobber (reg:CC FLAGS_REG))])])
6875 (define_insn "*addqi_ext<mode>_1"
6876 [(set (zero_extract:SWI248
6877 (match_operand 0 "int248_register_operand" "+Q,Q")
6883 (match_operator:SWI248 3 "extract_operator"
6884 [(match_operand 1 "int248_register_operand" "0,0")
6887 (match_operand:QI 2 "general_x64constmem_operand" "QnBc,m")) 0))
6888 (clobber (reg:CC FLAGS_REG))]
6889 "/* FIXME: without this LRA can't reload this pattern, see PR82524. */
6890 rtx_equal_p (operands[0], operands[1])"
6892 switch (get_attr_type (insn))
6895 if (operands[2] == const1_rtx)
6896 return "inc{b}\t%h0";
6899 gcc_assert (operands[2] == constm1_rtx);
6900 return "dec{b}\t%h0";
6904 return "add{b}\t{%2, %h0|%h0, %2}";
6907 [(set_attr "isa" "*,nox64")
6909 (if_then_else (match_operand:QI 2 "incdec_operand")
6910 (const_string "incdec")
6911 (const_string "alu")))
6912 (set_attr "mode" "QI")])
6914 (define_insn "*addqi_ext<mode>_2"
6915 [(set (zero_extract:SWI248
6916 (match_operand 0 "int248_register_operand" "+Q")
6922 (match_operator:SWI248 3 "extract_operator"
6923 [(match_operand 1 "int248_register_operand" "%0")
6927 (match_operator:SWI248 4 "extract_operator"
6928 [(match_operand 2 "int248_register_operand" "Q")
6930 (const_int 8)]) 0)) 0))
6931 (clobber (reg:CC FLAGS_REG))]
6932 "/* FIXME: without this LRA can't reload this pattern, see PR82524. */
6933 rtx_equal_p (operands[0], operands[1])
6934 || rtx_equal_p (operands[0], operands[2])"
6935 "add{b}\t{%h2, %h0|%h0, %h2}"
6936 [(set_attr "type" "alu")
6937 (set_attr "mode" "QI")])
6939 ;; Like DWI, but use POImode instead of OImode.
6940 (define_mode_attr DPWI [(QI "HI") (HI "SI") (SI "DI") (DI "TI") (TI "POI")])
6942 ;; Add with jump on overflow.
6943 (define_expand "addv<mode>4"
6944 [(parallel [(set (reg:CCO FLAGS_REG)
6948 (match_operand:SWIDWI 1 "nonimmediate_operand"))
6951 (plus:SWIDWI (match_dup 1)
6952 (match_operand:SWIDWI 2
6953 "<general_hilo_operand>")))))
6954 (set (match_operand:SWIDWI 0 "register_operand")
6955 (plus:SWIDWI (match_dup 1) (match_dup 2)))])
6956 (set (pc) (if_then_else
6957 (eq (reg:CCO FLAGS_REG) (const_int 0))
6958 (label_ref (match_operand 3))
6962 ix86_fixup_binary_operands_no_copy (PLUS, <MODE>mode, operands);
6963 if (CONST_SCALAR_INT_P (operands[2]))
6964 operands[4] = operands[2];
6966 operands[4] = gen_rtx_SIGN_EXTEND (<DPWI>mode, operands[2]);
6969 (define_insn "*addv<mode>4"
6970 [(set (reg:CCO FLAGS_REG)
6973 (match_operand:SWI 1 "nonimmediate_operand" "%0,0"))
6975 (match_operand:SWI 2 "<general_sext_operand>" "<r>We,m")))
6977 (plus:SWI (match_dup 1) (match_dup 2)))))
6978 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6979 (plus:SWI (match_dup 1) (match_dup 2)))]
6980 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6981 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6982 [(set_attr "type" "alu")
6983 (set_attr "mode" "<MODE>")])
6985 (define_insn "addv<mode>4_1"
6986 [(set (reg:CCO FLAGS_REG)
6989 (match_operand:SWI 1 "nonimmediate_operand" "0"))
6990 (match_operand:<DWI> 3 "const_int_operand"))
6994 (match_operand:SWI 2 "x86_64_immediate_operand" "<i>")))))
6995 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
6996 (plus:SWI (match_dup 1) (match_dup 2)))]
6997 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)
6998 && CONST_INT_P (operands[2])
6999 && INTVAL (operands[2]) == INTVAL (operands[3])"
7000 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
7001 [(set_attr "type" "alu")
7002 (set_attr "mode" "<MODE>")
7003 (set (attr "length_immediate")
7004 (cond [(match_test "IN_RANGE (INTVAL (operands[2]), -128, 127)")
7006 (match_test "<MODE_SIZE> == 8")
7008 (const_string "<MODE_SIZE>")))])
7010 ;; Quad word integer modes as mode attribute.
7011 (define_mode_attr QPWI [(SI "TI") (DI "POI")])
7013 (define_insn_and_split "*addv<dwi>4_doubleword"
7014 [(set (reg:CCO FLAGS_REG)
7018 (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0"))
7020 (match_operand:<DWI> 2 "nonimmediate_operand" "r,o")))
7022 (plus:<DWI> (match_dup 1) (match_dup 2)))))
7023 (set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro,r")
7024 (plus:<DWI> (match_dup 1) (match_dup 2)))]
7025 "ix86_binary_operator_ok (PLUS, <DWI>mode, operands)"
7027 "&& reload_completed"
7028 [(parallel [(set (reg:CCC FLAGS_REG)
7030 (plus:DWIH (match_dup 1) (match_dup 2))
7033 (plus:DWIH (match_dup 1) (match_dup 2)))])
7034 (parallel [(set (reg:CCO FLAGS_REG)
7038 (ltu:<DWI> (reg:CC FLAGS_REG) (const_int 0))
7039 (sign_extend:<DWI> (match_dup 4)))
7040 (sign_extend:<DWI> (match_dup 5)))
7044 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
7050 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
7054 split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
7057 (define_insn_and_split "*addv<dwi>4_doubleword_1"
7058 [(set (reg:CCO FLAGS_REG)
7062 (match_operand:<DWI> 1 "nonimmediate_operand" "%0"))
7063 (match_operand:<QPWI> 3 "const_scalar_int_operand" "n"))
7067 (match_operand:<DWI> 2 "x86_64_hilo_general_operand" "<di>")))))
7068 (set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro")
7069 (plus:<DWI> (match_dup 1) (match_dup 2)))]
7070 "ix86_binary_operator_ok (PLUS, <DWI>mode, operands)
7071 && CONST_SCALAR_INT_P (operands[2])
7072 && rtx_equal_p (operands[2], operands[3])"
7074 "&& reload_completed"
7075 [(parallel [(set (reg:CCC FLAGS_REG)
7077 (plus:DWIH (match_dup 1) (match_dup 2))
7080 (plus:DWIH (match_dup 1) (match_dup 2)))])
7081 (parallel [(set (reg:CCO FLAGS_REG)
7085 (ltu:<DWI> (reg:CC FLAGS_REG) (const_int 0))
7086 (sign_extend:<DWI> (match_dup 4)))
7091 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
7097 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
7101 split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
7102 if (operands[2] == const0_rtx)
7104 emit_insn (gen_addv<mode>4_1 (operands[3], operands[4], operands[5],
7110 (define_insn "*addv<mode>4_overflow_1"
7111 [(set (reg:CCO FLAGS_REG)
7115 (match_operator:<DWI> 4 "ix86_carry_flag_operator"
7116 [(match_operand 3 "flags_reg_operand") (const_int 0)])
7118 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")))
7120 (match_operand:SWI 2 "<general_sext_operand>" "rWe,m")))
7124 (match_operator:SWI 5 "ix86_carry_flag_operator"
7125 [(match_dup 3) (const_int 0)])
7128 (set (match_operand:SWI 0 "nonimmediate_operand" "=rm,r")
7131 (match_op_dup 5 [(match_dup 3) (const_int 0)])
7134 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
7135 "adc{<imodesuffix>}\t{%2, %0|%0, %2}"
7136 [(set_attr "type" "alu")
7137 (set_attr "mode" "<MODE>")])
7139 (define_insn "*addv<mode>4_overflow_2"
7140 [(set (reg:CCO FLAGS_REG)
7144 (match_operator:<DWI> 4 "ix86_carry_flag_operator"
7145 [(match_operand 3 "flags_reg_operand") (const_int 0)])
7147 (match_operand:SWI 1 "nonimmediate_operand" "%0")))
7148 (match_operand:<DWI> 6 "const_int_operand" "n"))
7152 (match_operator:SWI 5 "ix86_carry_flag_operator"
7153 [(match_dup 3) (const_int 0)])
7155 (match_operand:SWI 2 "x86_64_immediate_operand" "e")))))
7156 (set (match_operand:SWI 0 "nonimmediate_operand" "=rm")
7159 (match_op_dup 5 [(match_dup 3) (const_int 0)])
7162 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)
7163 && CONST_INT_P (operands[2])
7164 && INTVAL (operands[2]) == INTVAL (operands[6])"
7165 "adc{<imodesuffix>}\t{%2, %0|%0, %2}"
7166 [(set_attr "type" "alu")
7167 (set_attr "mode" "<MODE>")
7168 (set (attr "length_immediate")
7169 (if_then_else (match_test "IN_RANGE (INTVAL (operands[2]), -128, 127)")
7171 (const_string "4")))])
7173 (define_expand "uaddv<mode>4"
7174 [(parallel [(set (reg:CCC FLAGS_REG)
7177 (match_operand:SWIDWI 1 "nonimmediate_operand")
7178 (match_operand:SWIDWI 2 "<general_hilo_operand>"))
7180 (set (match_operand:SWIDWI 0 "register_operand")
7181 (plus:SWIDWI (match_dup 1) (match_dup 2)))])
7182 (set (pc) (if_then_else
7183 (ltu (reg:CCC FLAGS_REG) (const_int 0))
7184 (label_ref (match_operand 3))
7187 "ix86_fixup_binary_operands_no_copy (PLUS, <MODE>mode, operands);")
7189 ;; The lea patterns for modes less than 32 bits need to be matched by
7190 ;; several insns converted to real lea by splitters.
7192 (define_insn_and_split "*lea<mode>_general_1"
7193 [(set (match_operand:SWI12 0 "register_operand" "=r")
7195 (plus:SWI12 (match_operand:SWI12 1 "register_no_SP_operand" "l")
7196 (match_operand:SWI12 2 "register_operand" "r"))
7197 (match_operand:SWI12 3 "immediate_operand" "i")))]
7198 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
7200 "&& reload_completed"
7203 (plus:SI (match_dup 1) (match_dup 2))
7206 operands[0] = gen_lowpart (SImode, operands[0]);
7207 operands[1] = gen_lowpart (SImode, operands[1]);
7208 operands[2] = gen_lowpart (SImode, operands[2]);
7209 operands[3] = gen_lowpart (SImode, operands[3]);
7211 [(set_attr "type" "lea")
7212 (set_attr "mode" "SI")])
7214 (define_insn_and_split "*lea<mode>_general_2"
7215 [(set (match_operand:SWI12 0 "register_operand" "=r")
7217 (mult:SWI12 (match_operand:SWI12 1 "register_no_SP_operand" "l")
7218 (match_operand 2 "const248_operand" "n"))
7219 (match_operand:SWI12 3 "nonmemory_operand" "ri")))]
7220 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
7222 "&& reload_completed"
7225 (mult:SI (match_dup 1) (match_dup 2))
7228 operands[0] = gen_lowpart (SImode, operands[0]);
7229 operands[1] = gen_lowpart (SImode, operands[1]);
7230 operands[3] = gen_lowpart (SImode, operands[3]);
7232 [(set_attr "type" "lea")
7233 (set_attr "mode" "SI")])
7235 (define_insn_and_split "*lea<mode>_general_2b"
7236 [(set (match_operand:SWI12 0 "register_operand" "=r")
7238 (ashift:SWI12 (match_operand:SWI12 1 "register_no_SP_operand" "l")
7239 (match_operand 2 "const123_operand" "n"))
7240 (match_operand:SWI12 3 "nonmemory_operand" "ri")))]
7241 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
7243 "&& reload_completed"
7246 (ashift:SI (match_dup 1) (match_dup 2))
7249 operands[0] = gen_lowpart (SImode, operands[0]);
7250 operands[1] = gen_lowpart (SImode, operands[1]);
7251 operands[3] = gen_lowpart (SImode, operands[3]);
7253 [(set_attr "type" "lea")
7254 (set_attr "mode" "SI")])
7256 (define_insn_and_split "*lea<mode>_general_3"
7257 [(set (match_operand:SWI12 0 "register_operand" "=r")
7260 (mult:SWI12 (match_operand:SWI12 1 "register_no_SP_operand" "l")
7261 (match_operand 2 "const248_operand" "n"))
7262 (match_operand:SWI12 3 "register_operand" "r"))
7263 (match_operand:SWI12 4 "immediate_operand" "i")))]
7264 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
7266 "&& reload_completed"
7270 (mult:SI (match_dup 1) (match_dup 2))
7274 operands[0] = gen_lowpart (SImode, operands[0]);
7275 operands[1] = gen_lowpart (SImode, operands[1]);
7276 operands[3] = gen_lowpart (SImode, operands[3]);
7277 operands[4] = gen_lowpart (SImode, operands[4]);
7279 [(set_attr "type" "lea")
7280 (set_attr "mode" "SI")])
7282 (define_insn_and_split "*lea<mode>_general_3b"
7283 [(set (match_operand:SWI12 0 "register_operand" "=r")
7286 (ashift:SWI12 (match_operand:SWI12 1 "register_no_SP_operand" "l")
7287 (match_operand 2 "const123_operand" "n"))
7288 (match_operand:SWI12 3 "register_operand" "r"))
7289 (match_operand:SWI12 4 "immediate_operand" "i")))]
7290 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
7292 "&& reload_completed"
7296 (ashift:SI (match_dup 1) (match_dup 2))
7300 operands[0] = gen_lowpart (SImode, operands[0]);
7301 operands[1] = gen_lowpart (SImode, operands[1]);
7302 operands[3] = gen_lowpart (SImode, operands[3]);
7303 operands[4] = gen_lowpart (SImode, operands[4]);
7305 [(set_attr "type" "lea")
7306 (set_attr "mode" "SI")])
7308 (define_insn_and_split "*lea<mode>_general_4"
7309 [(set (match_operand:SWI12 0 "register_operand" "=r")
7312 (match_operand:SWI12 1 "register_no_SP_operand" "l")
7313 (match_operand 2 "const_0_to_3_operand"))
7314 (match_operand 3 "const_int_operand")))]
7315 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7316 && ((unsigned HOST_WIDE_INT) INTVAL (operands[3])
7317 < (HOST_WIDE_INT_1U << INTVAL (operands[2])))"
7319 "&& reload_completed"
7322 (mult:SI (match_dup 1) (match_dup 2))
7325 operands[0] = gen_lowpart (SImode, operands[0]);
7326 operands[1] = gen_lowpart (SImode, operands[1]);
7327 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
7329 [(set_attr "type" "lea")
7330 (set_attr "mode" "SI")])
7332 (define_insn_and_split "*lea<mode>_general_4"
7333 [(set (match_operand:SWI48 0 "register_operand" "=r")
7336 (match_operand:SWI48 1 "register_no_SP_operand" "l")
7337 (match_operand 2 "const_0_to_3_operand"))
7338 (match_operand 3 "const_int_operand")))]
7339 "(unsigned HOST_WIDE_INT) INTVAL (operands[3])
7340 < (HOST_WIDE_INT_1U << INTVAL (operands[2]))"
7342 "&& reload_completed"
7345 (mult:SWI48 (match_dup 1) (match_dup 2))
7347 "operands[2] = GEN_INT (1 << INTVAL (operands[2]));"
7348 [(set_attr "type" "lea")
7349 (set_attr "mode" "<MODE>")])
7351 ;; Subtract instructions
7353 (define_expand "sub<mode>3"
7354 [(set (match_operand:SDWIM 0 "nonimmediate_operand")
7355 (minus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")
7356 (match_operand:SDWIM 2 "<general_hilo_operand>")))]
7358 "ix86_expand_binary_operator (MINUS, <MODE>mode, operands); DONE;")
7360 (define_insn_and_split "*sub<dwi>3_doubleword"
7361 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro,r")
7363 (match_operand:<DWI> 1 "nonimmediate_operand" "0,0")
7364 (match_operand:<DWI> 2 "x86_64_hilo_general_operand" "r<di>,o")))
7365 (clobber (reg:CC FLAGS_REG))]
7366 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
7368 "&& reload_completed"
7369 [(parallel [(set (reg:CC FLAGS_REG)
7370 (compare:CC (match_dup 1) (match_dup 2)))
7372 (minus:DWIH (match_dup 1) (match_dup 2)))])
7373 (parallel [(set (match_dup 3)
7377 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0)))
7379 (clobber (reg:CC FLAGS_REG))])]
7381 split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
7382 if (operands[2] == const0_rtx)
7384 ix86_expand_binary_operator (MINUS, <MODE>mode, &operands[3]);
7389 (define_insn_and_split "*sub<dwi>3_doubleword_zext"
7390 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
7392 (match_operand:<DWI> 1 "nonimmediate_operand" "0,0")
7394 (match_operand:DWIH 2 "nonimmediate_operand" "rm,r"))))
7395 (clobber (reg:CC FLAGS_REG))]
7396 "ix86_binary_operator_ok (UNKNOWN, <DWI>mode, operands)"
7398 "&& reload_completed"
7399 [(parallel [(set (reg:CC FLAGS_REG)
7400 (compare:CC (match_dup 1) (match_dup 2)))
7402 (minus:DWIH (match_dup 1) (match_dup 2)))])
7403 (parallel [(set (match_dup 3)
7407 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0)))
7409 (clobber (reg:CC FLAGS_REG))])]
7410 "split_double_mode (<DWI>mode, &operands[0], 2, &operands[0], &operands[3]);")
7412 (define_insn "*sub<mode>_1"
7413 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
7415 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
7416 (match_operand:SWI 2 "<general_operand>" "<r><i>,<m>")))
7417 (clobber (reg:CC FLAGS_REG))]
7418 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
7419 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
7420 [(set_attr "type" "alu")
7421 (set_attr "mode" "<MODE>")])
7423 (define_insn "*subsi_1_zext"
7424 [(set (match_operand:DI 0 "register_operand" "=r")
7426 (minus:SI (match_operand:SI 1 "register_operand" "0")
7427 (match_operand:SI 2 "x86_64_general_operand" "rBMe"))))
7428 (clobber (reg:CC FLAGS_REG))]
7429 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
7430 "sub{l}\t{%2, %k0|%k0, %2}"
7431 [(set_attr "type" "alu")
7432 (set_attr "mode" "SI")])
7434 ;; Alternative 1 is needed to work around LRA limitation, see PR82524.
7435 (define_insn_and_split "*sub<mode>_1_slp"
7436 [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>,&<r>"))
7437 (minus:SWI12 (match_operand:SWI12 1 "register_operand" "0,!<r>")
7438 (match_operand:SWI12 2 "general_operand" "<r>mn,<r>mn")))
7439 (clobber (reg:CC FLAGS_REG))]
7440 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
7442 sub{<imodesuffix>}\t{%2, %0|%0, %2}
7444 "&& reload_completed"
7445 [(set (strict_low_part (match_dup 0)) (match_dup 1))
7447 [(set (strict_low_part (match_dup 0))
7448 (minus:SWI12 (match_dup 0) (match_dup 2)))
7449 (clobber (reg:CC FLAGS_REG))])]
7451 [(set_attr "type" "alu")
7452 (set_attr "mode" "<MODE>")])
7454 (define_insn "*sub<mode>_2"
7455 [(set (reg FLAGS_REG)
7458 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
7459 (match_operand:SWI 2 "<general_operand>" "<r><i>,<m>"))
7461 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
7462 (minus:SWI (match_dup 1) (match_dup 2)))]
7463 "ix86_match_ccmode (insn, CCGOCmode)
7464 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
7465 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
7466 [(set_attr "type" "alu")
7467 (set_attr "mode" "<MODE>")])
7469 (define_insn "*subsi_2_zext"
7470 [(set (reg FLAGS_REG)
7472 (minus:SI (match_operand:SI 1 "register_operand" "0")
7473 (match_operand:SI 2 "x86_64_general_operand" "rBMe"))
7475 (set (match_operand:DI 0 "register_operand" "=r")
7477 (minus:SI (match_dup 1)
7479 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
7480 && ix86_binary_operator_ok (MINUS, SImode, operands)"
7481 "sub{l}\t{%2, %k0|%k0, %2}"
7482 [(set_attr "type" "alu")
7483 (set_attr "mode" "SI")])
7485 (define_insn "*subqi_ext<mode>_0"
7486 [(set (match_operand:QI 0 "nonimm_x64constmem_operand" "=QBc,m")
7488 (match_operand:QI 1 "nonimm_x64constmem_operand" "0,0")
7490 (match_operator:SWI248 3 "extract_operator"
7491 [(match_operand 2 "int248_register_operand" "Q,Q")
7493 (const_int 8)]) 0)))
7494 (clobber (reg:CC FLAGS_REG))]
7496 "sub{b}\t{%h2, %0|%0, %h2}"
7497 [(set_attr "isa" "*,nox64")
7498 (set_attr "type" "alu")
7499 (set_attr "mode" "QI")])
7501 (define_insn "*subqi_ext<mode>_2"
7502 [(set (zero_extract:SWI248
7503 (match_operand 0 "int248_register_operand" "+Q")
7509 (match_operator:SWI248 3 "extract_operator"
7510 [(match_operand 1 "int248_register_operand" "0")
7514 (match_operator:SWI248 4 "extract_operator"
7515 [(match_operand 2 "int248_register_operand" "Q")
7517 (const_int 8)]) 0)) 0))
7518 (clobber (reg:CC FLAGS_REG))]
7519 "/* FIXME: without this LRA can't reload this pattern, see PR82524. */
7520 rtx_equal_p (operands[0], operands[1])"
7521 "sub{b}\t{%h2, %h0|%h0, %h2}"
7522 [(set_attr "type" "alu")
7523 (set_attr "mode" "QI")])
7525 ;; Subtract with jump on overflow.
7526 (define_expand "subv<mode>4"
7527 [(parallel [(set (reg:CCO FLAGS_REG)
7531 (match_operand:SWIDWI 1 "nonimmediate_operand"))
7534 (minus:SWIDWI (match_dup 1)
7535 (match_operand:SWIDWI 2
7536 "<general_hilo_operand>")))))
7537 (set (match_operand:SWIDWI 0 "register_operand")
7538 (minus:SWIDWI (match_dup 1) (match_dup 2)))])
7539 (set (pc) (if_then_else
7540 (eq (reg:CCO FLAGS_REG) (const_int 0))
7541 (label_ref (match_operand 3))
7545 ix86_fixup_binary_operands_no_copy (MINUS, <MODE>mode, operands);
7546 if (CONST_SCALAR_INT_P (operands[2]))
7547 operands[4] = operands[2];
7549 operands[4] = gen_rtx_SIGN_EXTEND (<DPWI>mode, operands[2]);
7552 (define_insn "*subv<mode>4"
7553 [(set (reg:CCO FLAGS_REG)
7554 (eq:CCO (minus:<DWI>
7556 (match_operand:SWI 1 "nonimmediate_operand" "0,0"))
7558 (match_operand:SWI 2 "<general_sext_operand>" "<r>We,m")))
7560 (minus:SWI (match_dup 1) (match_dup 2)))))
7561 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
7562 (minus:SWI (match_dup 1) (match_dup 2)))]
7563 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
7564 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
7565 [(set_attr "type" "alu")
7566 (set_attr "mode" "<MODE>")])
7568 (define_insn "subv<mode>4_1"
7569 [(set (reg:CCO FLAGS_REG)
7570 (eq:CCO (minus:<DWI>
7572 (match_operand:SWI 1 "nonimmediate_operand" "0"))
7573 (match_operand:<DWI> 3 "const_int_operand"))
7577 (match_operand:SWI 2 "x86_64_immediate_operand" "<i>")))))
7578 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
7579 (minus:SWI (match_dup 1) (match_dup 2)))]
7580 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)
7581 && CONST_INT_P (operands[2])
7582 && INTVAL (operands[2]) == INTVAL (operands[3])"
7583 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
7584 [(set_attr "type" "alu")
7585 (set_attr "mode" "<MODE>")
7586 (set (attr "length_immediate")
7587 (cond [(match_test "IN_RANGE (INTVAL (operands[2]), -128, 127)")
7589 (match_test "<MODE_SIZE> == 8")
7591 (const_string "<MODE_SIZE>")))])
7593 (define_insn_and_split "*subv<dwi>4_doubleword"
7594 [(set (reg:CCO FLAGS_REG)
7598 (match_operand:<DWI> 1 "nonimmediate_operand" "0,0"))
7600 (match_operand:<DWI> 2 "nonimmediate_operand" "r,o")))
7602 (minus:<DWI> (match_dup 1) (match_dup 2)))))
7603 (set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro,r")
7604 (minus:<DWI> (match_dup 1) (match_dup 2)))]
7605 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
7607 "&& reload_completed"
7608 [(parallel [(set (reg:CC FLAGS_REG)
7609 (compare:CC (match_dup 1) (match_dup 2)))
7611 (minus:DWIH (match_dup 1) (match_dup 2)))])
7612 (parallel [(set (reg:CCO FLAGS_REG)
7616 (sign_extend:<DWI> (match_dup 4))
7617 (ltu:<DWI> (reg:CC FLAGS_REG) (const_int 0)))
7618 (sign_extend:<DWI> (match_dup 5)))
7623 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0)))
7629 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0)))
7632 split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
7635 (define_insn_and_split "*subv<dwi>4_doubleword_1"
7636 [(set (reg:CCO FLAGS_REG)
7640 (match_operand:<DWI> 1 "nonimmediate_operand" "0"))
7641 (match_operand:<QPWI> 3 "const_scalar_int_operand"))
7645 (match_operand:<DWI> 2 "x86_64_hilo_general_operand" "<di>")))))
7646 (set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro")
7647 (minus:<DWI> (match_dup 1) (match_dup 2)))]
7648 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)
7649 && CONST_SCALAR_INT_P (operands[2])
7650 && rtx_equal_p (operands[2], operands[3])"
7652 "&& reload_completed"
7653 [(parallel [(set (reg:CC FLAGS_REG)
7654 (compare:CC (match_dup 1) (match_dup 2)))
7656 (minus:DWIH (match_dup 1) (match_dup 2)))])
7657 (parallel [(set (reg:CCO FLAGS_REG)
7661 (sign_extend:<DWI> (match_dup 4))
7662 (ltu:<DWI> (reg:CC FLAGS_REG) (const_int 0)))
7668 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0)))
7674 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0)))
7677 split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
7678 if (operands[2] == const0_rtx)
7680 emit_insn (gen_subv<mode>4_1 (operands[3], operands[4], operands[5],
7686 (define_insn "*subv<mode>4_overflow_1"
7687 [(set (reg:CCO FLAGS_REG)
7692 (match_operand:SWI 1 "nonimmediate_operand" "%0,0"))
7693 (match_operator:<DWI> 4 "ix86_carry_flag_operator"
7694 [(match_operand 3 "flags_reg_operand") (const_int 0)]))
7696 (match_operand:SWI 2 "<general_sext_operand>" "rWe,m")))
7701 (match_operator:SWI 5 "ix86_carry_flag_operator"
7702 [(match_dup 3) (const_int 0)]))
7704 (set (match_operand:SWI 0 "nonimmediate_operand" "=rm,r")
7708 (match_op_dup 5 [(match_dup 3) (const_int 0)]))
7710 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
7711 "sbb{<imodesuffix>}\t{%2, %0|%0, %2}"
7712 [(set_attr "type" "alu")
7713 (set_attr "mode" "<MODE>")])
7715 (define_insn "*subv<mode>4_overflow_2"
7716 [(set (reg:CCO FLAGS_REG)
7721 (match_operand:SWI 1 "nonimmediate_operand" "%0"))
7722 (match_operator:<DWI> 4 "ix86_carry_flag_operator"
7723 [(match_operand 3 "flags_reg_operand") (const_int 0)]))
7724 (match_operand:<DWI> 6 "const_int_operand" "n"))
7729 (match_operator:SWI 5 "ix86_carry_flag_operator"
7730 [(match_dup 3) (const_int 0)]))
7731 (match_operand:SWI 2 "x86_64_immediate_operand" "e")))))
7732 (set (match_operand:SWI 0 "nonimmediate_operand" "=rm")
7736 (match_op_dup 5 [(match_dup 3) (const_int 0)]))
7738 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)
7739 && CONST_INT_P (operands[2])
7740 && INTVAL (operands[2]) == INTVAL (operands[6])"
7741 "sbb{<imodesuffix>}\t{%2, %0|%0, %2}"
7742 [(set_attr "type" "alu")
7743 (set_attr "mode" "<MODE>")
7744 (set (attr "length_immediate")
7745 (if_then_else (match_test "IN_RANGE (INTVAL (operands[2]), -128, 127)")
7747 (const_string "4")))])
7749 (define_expand "usubv<mode>4"
7750 [(parallel [(set (reg:CC FLAGS_REG)
7752 (match_operand:SWI 1 "nonimmediate_operand")
7753 (match_operand:SWI 2 "<general_operand>")))
7754 (set (match_operand:SWI 0 "register_operand")
7755 (minus:SWI (match_dup 1) (match_dup 2)))])
7756 (set (pc) (if_then_else
7757 (ltu (reg:CC FLAGS_REG) (const_int 0))
7758 (label_ref (match_operand 3))
7761 "ix86_fixup_binary_operands_no_copy (MINUS, <MODE>mode, operands);")
7763 (define_insn "*sub<mode>_3"
7764 [(set (reg FLAGS_REG)
7765 (compare (match_operand:SWI 1 "nonimmediate_operand" "0,0")
7766 (match_operand:SWI 2 "<general_operand>" "<r><i>,<m>")))
7767 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
7768 (minus:SWI (match_dup 1) (match_dup 2)))]
7769 "ix86_match_ccmode (insn, CCmode)
7770 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
7771 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
7772 [(set_attr "type" "alu")
7773 (set_attr "mode" "<MODE>")])
7777 [(set (reg:CC FLAGS_REG)
7778 (compare:CC (match_operand:SWI 0 "general_reg_operand")
7779 (match_operand:SWI 1 "general_gr_operand")))
7781 (minus:SWI (match_dup 0) (match_dup 1)))])]
7782 "find_regno_note (peep2_next_insn (0), REG_UNUSED, REGNO (operands[0])) != 0"
7783 [(set (reg:CC FLAGS_REG)
7784 (compare:CC (match_dup 0) (match_dup 1)))])
7787 [(set (match_operand:SWI 0 "general_reg_operand")
7788 (match_operand:SWI 1 "memory_operand"))
7789 (parallel [(set (reg:CC FLAGS_REG)
7790 (compare:CC (match_dup 0)
7791 (match_operand:SWI 2 "memory_operand")))
7793 (minus:SWI (match_dup 0) (match_dup 2)))])
7794 (set (match_dup 1) (match_dup 0))]
7795 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
7796 && peep2_reg_dead_p (3, operands[0])
7797 && !reg_overlap_mentioned_p (operands[0], operands[1])
7798 && !reg_overlap_mentioned_p (operands[0], operands[2])"
7799 [(set (match_dup 0) (match_dup 2))
7800 (parallel [(set (reg:CC FLAGS_REG)
7801 (compare:CC (match_dup 1) (match_dup 0)))
7803 (minus:SWI (match_dup 1) (match_dup 0)))])])
7805 ;; decl %eax; cmpl $-1, %eax; jne .Lxx; can be optimized into
7806 ;; subl $1, %eax; jnc .Lxx;
7809 [(set (match_operand:SWI 0 "general_reg_operand")
7810 (plus:SWI (match_dup 0) (const_int -1)))
7811 (clobber (reg FLAGS_REG))])
7812 (set (reg:CCZ FLAGS_REG)
7813 (compare:CCZ (match_dup 0) (const_int -1)))
7815 (if_then_else (match_operator 1 "bt_comparison_operator"
7816 [(reg:CCZ FLAGS_REG) (const_int 0)])
7819 "peep2_regno_dead_p (3, FLAGS_REG)"
7821 [(set (reg:CC FLAGS_REG)
7822 (compare:CC (match_dup 0) (const_int 1)))
7824 (minus:SWI (match_dup 0) (const_int 1)))])
7826 (if_then_else (match_dup 3)
7830 rtx cc = gen_rtx_REG (CCmode, FLAGS_REG);
7831 operands[3] = gen_rtx_fmt_ee (GET_CODE (operands[1]) == NE
7832 ? GEU : LTU, VOIDmode, cc, const0_rtx);
7835 ;; Help combine use borrow flag to test for -1 after dec (add $-1).
7836 (define_insn_and_split "*dec_cmov<mode>"
7837 [(set (match_operand:SWI248 0 "register_operand" "=r")
7838 (if_then_else:SWI248
7839 (match_operator 1 "bt_comparison_operator"
7840 [(match_operand:SWI248 2 "register_operand" "0") (const_int 0)])
7841 (plus:SWI248 (match_dup 2) (const_int -1))
7842 (match_operand:SWI248 3 "nonimmediate_operand" "rm")))
7843 (clobber (reg:CC FLAGS_REG))]
7846 "&& reload_completed"
7847 [(parallel [(set (reg:CC FLAGS_REG)
7848 (compare:CC (match_dup 2) (const_int 1)))
7849 (set (match_dup 0) (minus:SWI248 (match_dup 2) (const_int 1)))])
7851 (if_then_else:SWI248 (match_dup 4) (match_dup 0) (match_dup 3)))]
7853 rtx cc = gen_rtx_REG (CCCmode, FLAGS_REG);
7854 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[1]) == NE
7855 ? GEU : LTU, VOIDmode, cc, const0_rtx);
7858 (define_insn "*subsi_3_zext"
7859 [(set (reg FLAGS_REG)
7860 (compare (match_operand:SI 1 "register_operand" "0")
7861 (match_operand:SI 2 "x86_64_general_operand" "rBMe")))
7862 (set (match_operand:DI 0 "register_operand" "=r")
7864 (minus:SI (match_dup 1)
7866 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
7867 && ix86_binary_operator_ok (MINUS, SImode, operands)"
7868 "sub{l}\t{%2, %1|%1, %2}"
7869 [(set_attr "type" "alu")
7870 (set_attr "mode" "SI")])
7872 ;; Add with carry and subtract with borrow
7874 (define_insn "@add<mode>3_carry"
7875 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
7878 (match_operator:SWI 4 "ix86_carry_flag_operator"
7879 [(match_operand 3 "flags_reg_operand") (const_int 0)])
7880 (match_operand:SWI 1 "nonimmediate_operand" "%0,0"))
7881 (match_operand:SWI 2 "<general_operand>" "<r><i>,<m>")))
7882 (clobber (reg:CC FLAGS_REG))]
7883 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
7884 "adc{<imodesuffix>}\t{%2, %0|%0, %2}"
7885 [(set_attr "type" "alu")
7886 (set_attr "use_carry" "1")
7887 (set_attr "pent_pair" "pu")
7888 (set_attr "mode" "<MODE>")])
7891 [(set (match_operand:SWI 0 "general_reg_operand")
7892 (match_operand:SWI 1 "memory_operand"))
7893 (parallel [(set (match_dup 0)
7896 (match_operator:SWI 4 "ix86_carry_flag_operator"
7897 [(match_operand 3 "flags_reg_operand")
7900 (match_operand:SWI 2 "memory_operand")))
7901 (clobber (reg:CC FLAGS_REG))])
7902 (set (match_dup 1) (match_dup 0))]
7903 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
7904 && peep2_reg_dead_p (3, operands[0])
7905 && !reg_overlap_mentioned_p (operands[0], operands[1])
7906 && !reg_overlap_mentioned_p (operands[0], operands[2])"
7907 [(set (match_dup 0) (match_dup 2))
7908 (parallel [(set (match_dup 1)
7909 (plus:SWI (plus:SWI (match_op_dup 4
7910 [(match_dup 3) (const_int 0)])
7913 (clobber (reg:CC FLAGS_REG))])])
7916 [(set (match_operand:SWI 0 "general_reg_operand")
7917 (match_operand:SWI 1 "memory_operand"))
7918 (parallel [(set (match_dup 0)
7921 (match_operator:SWI 4 "ix86_carry_flag_operator"
7922 [(match_operand 3 "flags_reg_operand")
7925 (match_operand:SWI 2 "memory_operand")))
7926 (clobber (reg:CC FLAGS_REG))])
7927 (set (match_operand:SWI 5 "general_reg_operand") (match_dup 0))
7928 (set (match_dup 1) (match_dup 5))]
7929 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
7930 && peep2_reg_dead_p (3, operands[0])
7931 && peep2_reg_dead_p (4, operands[5])
7932 && !reg_overlap_mentioned_p (operands[0], operands[1])
7933 && !reg_overlap_mentioned_p (operands[0], operands[2])
7934 && !reg_overlap_mentioned_p (operands[5], operands[1])"
7935 [(set (match_dup 0) (match_dup 2))
7936 (parallel [(set (match_dup 1)
7937 (plus:SWI (plus:SWI (match_op_dup 4
7938 [(match_dup 3) (const_int 0)])
7941 (clobber (reg:CC FLAGS_REG))])])
7943 (define_insn "*add<mode>3_carry_0"
7944 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
7946 (match_operator:SWI 2 "ix86_carry_flag_operator"
7947 [(reg FLAGS_REG) (const_int 0)])
7948 (match_operand:SWI 1 "nonimmediate_operand" "0")))
7949 (clobber (reg:CC FLAGS_REG))]
7950 "!MEM_P (operands[0]) || rtx_equal_p (operands[0], operands[1])"
7951 "adc{<imodesuffix>}\t{$0, %0|%0, 0}"
7952 [(set_attr "type" "alu")
7953 (set_attr "use_carry" "1")
7954 (set_attr "pent_pair" "pu")
7955 (set_attr "mode" "<MODE>")])
7957 (define_insn "*add<mode>3_carry_0r"
7958 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
7960 (match_operator:SWI 2 "ix86_carry_flag_unset_operator"
7961 [(reg FLAGS_REG) (const_int 0)])
7962 (match_operand:SWI 1 "nonimmediate_operand" "0")))
7963 (clobber (reg:CC FLAGS_REG))]
7964 "!MEM_P (operands[0]) || rtx_equal_p (operands[0], operands[1])"
7965 "sbb{<imodesuffix>}\t{$-1, %0|%0, -1}"
7966 [(set_attr "type" "alu")
7967 (set_attr "use_carry" "1")
7968 (set_attr "pent_pair" "pu")
7969 (set_attr "mode" "<MODE>")])
7971 (define_insn "*addsi3_carry_zext"
7972 [(set (match_operand:DI 0 "register_operand" "=r")
7975 (plus:SI (match_operator:SI 3 "ix86_carry_flag_operator"
7976 [(reg FLAGS_REG) (const_int 0)])
7977 (match_operand:SI 1 "register_operand" "%0"))
7978 (match_operand:SI 2 "x86_64_general_operand" "rBMe"))))
7979 (clobber (reg:CC FLAGS_REG))]
7980 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
7981 "adc{l}\t{%2, %k0|%k0, %2}"
7982 [(set_attr "type" "alu")
7983 (set_attr "use_carry" "1")
7984 (set_attr "pent_pair" "pu")
7985 (set_attr "mode" "SI")])
7987 (define_insn "*addsi3_carry_zext_0"
7988 [(set (match_operand:DI 0 "register_operand" "=r")
7990 (plus:SI (match_operator:SI 2 "ix86_carry_flag_operator"
7991 [(reg FLAGS_REG) (const_int 0)])
7992 (match_operand:SI 1 "register_operand" "0"))))
7993 (clobber (reg:CC FLAGS_REG))]
7995 "adc{l}\t{$0, %k0|%k0, 0}"
7996 [(set_attr "type" "alu")
7997 (set_attr "use_carry" "1")
7998 (set_attr "pent_pair" "pu")
7999 (set_attr "mode" "SI")])
8001 (define_insn "*addsi3_carry_zext_0r"
8002 [(set (match_operand:DI 0 "register_operand" "=r")
8004 (plus:SI (match_operator:SI 2 "ix86_carry_flag_unset_operator"
8005 [(reg FLAGS_REG) (const_int 0)])
8006 (match_operand:SI 1 "register_operand" "0"))))
8007 (clobber (reg:CC FLAGS_REG))]
8009 "sbb{l}\t{$-1, %k0|%k0, -1}"
8010 [(set_attr "type" "alu")
8011 (set_attr "use_carry" "1")
8012 (set_attr "pent_pair" "pu")
8013 (set_attr "mode" "SI")])
8015 ;; There is no point to generate ADCX instruction. ADC is shorter and faster.
8017 (define_insn "addcarry<mode>"
8018 [(set (reg:CCC FLAGS_REG)
8023 (match_operator:SWI48 5 "ix86_carry_flag_operator"
8024 [(match_operand 3 "flags_reg_operand") (const_int 0)])
8025 (match_operand:SWI48 1 "nonimmediate_operand" "%0,0"))
8026 (match_operand:SWI48 2 "nonimmediate_operand" "r,rm")))
8028 (zero_extend:<DWI> (match_dup 2))
8029 (match_operator:<DWI> 4 "ix86_carry_flag_operator"
8030 [(match_dup 3) (const_int 0)]))))
8031 (set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
8032 (plus:SWI48 (plus:SWI48 (match_op_dup 5
8033 [(match_dup 3) (const_int 0)])
8036 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
8037 "adc{<imodesuffix>}\t{%2, %0|%0, %2}"
8038 [(set_attr "type" "alu")
8039 (set_attr "use_carry" "1")
8040 (set_attr "pent_pair" "pu")
8041 (set_attr "mode" "<MODE>")])
8044 [(parallel [(set (reg:CCC FLAGS_REG)
8049 (match_operator:SWI48 4 "ix86_carry_flag_operator"
8050 [(match_operand 2 "flags_reg_operand")
8052 (match_operand:SWI48 0 "general_reg_operand"))
8053 (match_operand:SWI48 1 "memory_operand")))
8055 (zero_extend:<DWI> (match_dup 1))
8056 (match_operator:<DWI> 3 "ix86_carry_flag_operator"
8057 [(match_dup 2) (const_int 0)]))))
8059 (plus:SWI48 (plus:SWI48 (match_op_dup 4
8060 [(match_dup 2) (const_int 0)])
8063 (set (match_dup 1) (match_dup 0))]
8064 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
8065 && peep2_reg_dead_p (2, operands[0])
8066 && !reg_overlap_mentioned_p (operands[0], operands[1])"
8067 [(parallel [(set (reg:CCC FLAGS_REG)
8073 [(match_dup 2) (const_int 0)])
8077 (zero_extend:<DWI> (match_dup 0))
8079 [(match_dup 2) (const_int 0)]))))
8081 (plus:SWI48 (plus:SWI48 (match_op_dup 4
8082 [(match_dup 2) (const_int 0)])
8087 [(set (match_operand:SWI48 0 "general_reg_operand")
8088 (match_operand:SWI48 1 "memory_operand"))
8089 (parallel [(set (reg:CCC FLAGS_REG)
8094 (match_operator:SWI48 5 "ix86_carry_flag_operator"
8095 [(match_operand 3 "flags_reg_operand")
8098 (match_operand:SWI48 2 "memory_operand")))
8100 (zero_extend:<DWI> (match_dup 2))
8101 (match_operator:<DWI> 4 "ix86_carry_flag_operator"
8102 [(match_dup 3) (const_int 0)]))))
8104 (plus:SWI48 (plus:SWI48 (match_op_dup 5
8105 [(match_dup 3) (const_int 0)])
8108 (set (match_dup 1) (match_dup 0))]
8109 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
8110 && peep2_reg_dead_p (3, operands[0])
8111 && !reg_overlap_mentioned_p (operands[0], operands[1])
8112 && !reg_overlap_mentioned_p (operands[0], operands[2])"
8113 [(set (match_dup 0) (match_dup 2))
8114 (parallel [(set (reg:CCC FLAGS_REG)
8120 [(match_dup 3) (const_int 0)])
8124 (zero_extend:<DWI> (match_dup 0))
8126 [(match_dup 3) (const_int 0)]))))
8128 (plus:SWI48 (plus:SWI48 (match_op_dup 5
8129 [(match_dup 3) (const_int 0)])
8134 [(parallel [(set (reg:CCC FLAGS_REG)
8139 (match_operator:SWI48 4 "ix86_carry_flag_operator"
8140 [(match_operand 2 "flags_reg_operand")
8142 (match_operand:SWI48 0 "general_reg_operand"))
8143 (match_operand:SWI48 1 "memory_operand")))
8145 (zero_extend:<DWI> (match_dup 1))
8146 (match_operator:<DWI> 3 "ix86_carry_flag_operator"
8147 [(match_dup 2) (const_int 0)]))))
8149 (plus:SWI48 (plus:SWI48 (match_op_dup 4
8150 [(match_dup 2) (const_int 0)])
8153 (set (match_operand:QI 5 "general_reg_operand")
8154 (ltu:QI (reg:CCC FLAGS_REG) (const_int 0)))
8155 (set (match_operand:SWI48 6 "general_reg_operand")
8156 (zero_extend:SWI48 (match_dup 5)))
8157 (set (match_dup 1) (match_dup 0))]
8158 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
8159 && peep2_reg_dead_p (4, operands[0])
8160 && !reg_overlap_mentioned_p (operands[0], operands[1])
8161 && !reg_overlap_mentioned_p (operands[0], operands[5])
8162 && !reg_overlap_mentioned_p (operands[5], operands[1])
8163 && !reg_overlap_mentioned_p (operands[0], operands[6])
8164 && !reg_overlap_mentioned_p (operands[6], operands[1])"
8165 [(parallel [(set (reg:CCC FLAGS_REG)
8171 [(match_dup 2) (const_int 0)])
8175 (zero_extend:<DWI> (match_dup 0))
8177 [(match_dup 2) (const_int 0)]))))
8179 (plus:SWI48 (plus:SWI48 (match_op_dup 4
8180 [(match_dup 2) (const_int 0)])
8183 (set (match_dup 5) (ltu:QI (reg:CCC FLAGS_REG) (const_int 0)))
8184 (set (match_dup 6) (zero_extend:SWI48 (match_dup 5)))])
8186 (define_expand "addcarry<mode>_0"
8188 [(set (reg:CCC FLAGS_REG)
8191 (match_operand:SWI48 1 "nonimmediate_operand")
8192 (match_operand:SWI48 2 "x86_64_general_operand"))
8194 (set (match_operand:SWI48 0 "nonimmediate_operand")
8195 (plus:SWI48 (match_dup 1) (match_dup 2)))])]
8196 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)")
8198 (define_insn "*addcarry<mode>_1"
8199 [(set (reg:CCC FLAGS_REG)
8204 (match_operator:SWI48 5 "ix86_carry_flag_operator"
8205 [(match_operand 3 "flags_reg_operand") (const_int 0)])
8206 (match_operand:SWI48 1 "nonimmediate_operand" "%0"))
8207 (match_operand:SWI48 2 "x86_64_immediate_operand" "e")))
8209 (match_operand:<DWI> 6 "const_scalar_int_operand")
8210 (match_operator:<DWI> 4 "ix86_carry_flag_operator"
8211 [(match_dup 3) (const_int 0)]))))
8212 (set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
8213 (plus:SWI48 (plus:SWI48 (match_op_dup 5
8214 [(match_dup 3) (const_int 0)])
8217 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)
8218 && CONST_INT_P (operands[2])
8219 /* Check that operands[6] is operands[2] zero extended from
8220 <MODE>mode to <DWI>mode. */
8221 && ((<MODE>mode == SImode || INTVAL (operands[2]) >= 0)
8222 ? (CONST_INT_P (operands[6])
8223 && UINTVAL (operands[6]) == (UINTVAL (operands[2])
8224 & GET_MODE_MASK (<MODE>mode)))
8225 : (CONST_WIDE_INT_P (operands[6])
8226 && CONST_WIDE_INT_NUNITS (operands[6]) == 2
8227 && ((unsigned HOST_WIDE_INT) CONST_WIDE_INT_ELT (operands[6], 0)
8228 == UINTVAL (operands[2]))
8229 && CONST_WIDE_INT_ELT (operands[6], 1) == 0))"
8230 "adc{<imodesuffix>}\t{%2, %0|%0, %2}"
8231 [(set_attr "type" "alu")
8232 (set_attr "use_carry" "1")
8233 (set_attr "pent_pair" "pu")
8234 (set_attr "mode" "<MODE>")
8235 (set (attr "length_immediate")
8236 (if_then_else (match_test "IN_RANGE (INTVAL (operands[2]), -128, 127)")
8238 (const_string "4")))])
8240 (define_insn "@sub<mode>3_carry"
8241 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
8244 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
8245 (match_operator:SWI 4 "ix86_carry_flag_operator"
8246 [(match_operand 3 "flags_reg_operand") (const_int 0)]))
8247 (match_operand:SWI 2 "<general_operand>" "<r><i>,<m>")))
8248 (clobber (reg:CC FLAGS_REG))]
8249 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
8250 "sbb{<imodesuffix>}\t{%2, %0|%0, %2}"
8251 [(set_attr "type" "alu")
8252 (set_attr "use_carry" "1")
8253 (set_attr "pent_pair" "pu")
8254 (set_attr "mode" "<MODE>")])
8257 [(set (match_operand:SWI 0 "general_reg_operand")
8258 (match_operand:SWI 1 "memory_operand"))
8259 (parallel [(set (match_dup 0)
8263 (match_operator:SWI 4 "ix86_carry_flag_operator"
8264 [(match_operand 3 "flags_reg_operand")
8266 (match_operand:SWI 2 "memory_operand")))
8267 (clobber (reg:CC FLAGS_REG))])
8268 (set (match_dup 1) (match_dup 0))]
8269 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
8270 && peep2_reg_dead_p (3, operands[0])
8271 && !reg_overlap_mentioned_p (operands[0], operands[1])
8272 && !reg_overlap_mentioned_p (operands[0], operands[2])"
8273 [(set (match_dup 0) (match_dup 2))
8274 (parallel [(set (match_dup 1)
8275 (minus:SWI (minus:SWI (match_dup 1)
8277 [(match_dup 3) (const_int 0)]))
8279 (clobber (reg:CC FLAGS_REG))])])
8282 [(set (match_operand:SWI 0 "general_reg_operand")
8283 (match_operand:SWI 1 "memory_operand"))
8284 (parallel [(set (match_dup 0)
8288 (match_operator:SWI 4 "ix86_carry_flag_operator"
8289 [(match_operand 3 "flags_reg_operand")
8291 (match_operand:SWI 2 "memory_operand")))
8292 (clobber (reg:CC FLAGS_REG))])
8293 (set (match_operand:SWI 5 "general_reg_operand") (match_dup 0))
8294 (set (match_dup 1) (match_dup 5))]
8295 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
8296 && peep2_reg_dead_p (3, operands[0])
8297 && peep2_reg_dead_p (4, operands[5])
8298 && !reg_overlap_mentioned_p (operands[0], operands[1])
8299 && !reg_overlap_mentioned_p (operands[0], operands[2])
8300 && !reg_overlap_mentioned_p (operands[5], operands[1])"
8301 [(set (match_dup 0) (match_dup 2))
8302 (parallel [(set (match_dup 1)
8303 (minus:SWI (minus:SWI (match_dup 1)
8305 [(match_dup 3) (const_int 0)]))
8307 (clobber (reg:CC FLAGS_REG))])])
8309 (define_insn "*sub<mode>3_carry_0"
8310 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8312 (match_operand:SWI 1 "nonimmediate_operand" "0")
8313 (match_operator:SWI 2 "ix86_carry_flag_operator"
8314 [(reg FLAGS_REG) (const_int 0)])))
8315 (clobber (reg:CC FLAGS_REG))]
8316 "!MEM_P (operands[0]) || rtx_equal_p (operands[0], operands[1])"
8317 "sbb{<imodesuffix>}\t{$0, %0|%0, 0}"
8318 [(set_attr "type" "alu")
8319 (set_attr "use_carry" "1")
8320 (set_attr "pent_pair" "pu")
8321 (set_attr "mode" "<MODE>")])
8323 (define_insn "*sub<mode>3_carry_0r"
8324 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8326 (match_operand:SWI 1 "nonimmediate_operand" "0")
8327 (match_operator:SWI 2 "ix86_carry_flag_unset_operator"
8328 [(reg FLAGS_REG) (const_int 0)])))
8329 (clobber (reg:CC FLAGS_REG))]
8330 "!MEM_P (operands[0]) || rtx_equal_p (operands[0], operands[1])"
8331 "adc{<imodesuffix>}\t{$-1, %0|%0, -1}"
8332 [(set_attr "type" "alu")
8333 (set_attr "use_carry" "1")
8334 (set_attr "pent_pair" "pu")
8335 (set_attr "mode" "<MODE>")])
8337 (define_insn "*subsi3_carry_zext"
8338 [(set (match_operand:DI 0 "register_operand" "=r")
8342 (match_operand:SI 1 "register_operand" "0")
8343 (match_operator:SI 3 "ix86_carry_flag_operator"
8344 [(reg FLAGS_REG) (const_int 0)]))
8345 (match_operand:SI 2 "x86_64_general_operand" "rBMe"))))
8346 (clobber (reg:CC FLAGS_REG))]
8347 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
8348 "sbb{l}\t{%2, %k0|%k0, %2}"
8349 [(set_attr "type" "alu")
8350 (set_attr "use_carry" "1")
8351 (set_attr "pent_pair" "pu")
8352 (set_attr "mode" "SI")])
8354 (define_insn "*subsi3_carry_zext_0"
8355 [(set (match_operand:DI 0 "register_operand" "=r")
8358 (match_operand:SI 1 "register_operand" "0")
8359 (match_operator:SI 2 "ix86_carry_flag_operator"
8360 [(reg FLAGS_REG) (const_int 0)]))))
8361 (clobber (reg:CC FLAGS_REG))]
8363 "sbb{l}\t{$0, %k0|%k0, 0}"
8364 [(set_attr "type" "alu")
8365 (set_attr "use_carry" "1")
8366 (set_attr "pent_pair" "pu")
8367 (set_attr "mode" "SI")])
8369 (define_insn "*subsi3_carry_zext_0r"
8370 [(set (match_operand:DI 0 "register_operand" "=r")
8373 (match_operand:SI 1 "register_operand" "0")
8374 (match_operator:SI 2 "ix86_carry_flag_unset_operator"
8375 [(reg FLAGS_REG) (const_int 0)]))))
8376 (clobber (reg:CC FLAGS_REG))]
8378 "adc{l}\t{$-1, %k0|%k0, -1}"
8379 [(set_attr "type" "alu")
8380 (set_attr "use_carry" "1")
8381 (set_attr "pent_pair" "pu")
8382 (set_attr "mode" "SI")])
8384 (define_insn "@sub<mode>3_carry_ccc"
8385 [(set (reg:CCC FLAGS_REG)
8387 (zero_extend:<DWI> (match_operand:DWIH 1 "register_operand" "0"))
8389 (ltu:<DWI> (reg:CC FLAGS_REG) (const_int 0))
8391 (match_operand:DWIH 2 "x86_64_sext_operand" "rmWe")))))
8392 (clobber (match_scratch:DWIH 0 "=r"))]
8394 "sbb{<imodesuffix>}\t{%2, %0|%0, %2}"
8395 [(set_attr "type" "alu")
8396 (set_attr "mode" "<MODE>")])
8398 (define_insn "*sub<mode>3_carry_ccc_1"
8399 [(set (reg:CCC FLAGS_REG)
8401 (zero_extend:<DWI> (match_operand:DWIH 1 "register_operand" "0"))
8403 (ltu:<DWI> (reg:CC FLAGS_REG) (const_int 0))
8404 (match_operand:<DWI> 2 "x86_64_dwzext_immediate_operand" "Wf"))))
8405 (clobber (match_scratch:DWIH 0 "=r"))]
8408 operands[3] = simplify_subreg (<MODE>mode, operands[2], <DWI>mode, 0);
8409 return "sbb{<imodesuffix>}\t{%3, %0|%0, %3}";
8411 [(set_attr "type" "alu")
8412 (set_attr "mode" "<MODE>")])
8414 ;; The sign flag is set from the
8415 ;; (compare (match_dup 1) (plus:DWIH (ltu:DWIH ...) (match_dup 2)))
8416 ;; result, the overflow flag likewise, but the overflow flag is also
8417 ;; set if the (plus:DWIH (ltu:DWIH ...) (match_dup 2)) overflows.
8418 (define_insn "@sub<mode>3_carry_ccgz"
8419 [(set (reg:CCGZ FLAGS_REG)
8420 (unspec:CCGZ [(match_operand:DWIH 1 "register_operand" "0")
8421 (match_operand:DWIH 2 "x86_64_general_operand" "rBMe")
8422 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))]
8424 (clobber (match_scratch:DWIH 0 "=r"))]
8426 "sbb{<imodesuffix>}\t{%2, %0|%0, %2}"
8427 [(set_attr "type" "alu")
8428 (set_attr "mode" "<MODE>")])
8430 (define_insn "subborrow<mode>"
8431 [(set (reg:CCC FLAGS_REG)
8434 (match_operand:SWI48 1 "nonimmediate_operand" "0,0"))
8436 (match_operator:<DWI> 4 "ix86_carry_flag_operator"
8437 [(match_operand 3 "flags_reg_operand") (const_int 0)])
8439 (match_operand:SWI48 2 "nonimmediate_operand" "r,rm")))))
8440 (set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
8441 (minus:SWI48 (minus:SWI48
8443 (match_operator:SWI48 5 "ix86_carry_flag_operator"
8444 [(match_dup 3) (const_int 0)]))
8446 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
8447 "sbb{<imodesuffix>}\t{%2, %0|%0, %2}"
8448 [(set_attr "type" "alu")
8449 (set_attr "use_carry" "1")
8450 (set_attr "pent_pair" "pu")
8451 (set_attr "mode" "<MODE>")])
8454 [(set (match_operand:SWI48 0 "general_reg_operand")
8455 (match_operand:SWI48 1 "memory_operand"))
8456 (parallel [(set (reg:CCC FLAGS_REG)
8458 (zero_extend:<DWI> (match_dup 0))
8460 (match_operator:<DWI> 4 "ix86_carry_flag_operator"
8461 [(match_operand 3 "flags_reg_operand") (const_int 0)])
8463 (match_operand:SWI48 2 "memory_operand")))))
8468 (match_operator:SWI48 5 "ix86_carry_flag_operator"
8469 [(match_dup 3) (const_int 0)]))
8471 (set (match_dup 1) (match_dup 0))]
8472 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
8473 && peep2_reg_dead_p (3, operands[0])
8474 && !reg_overlap_mentioned_p (operands[0], operands[1])
8475 && !reg_overlap_mentioned_p (operands[0], operands[2])"
8476 [(set (match_dup 0) (match_dup 2))
8477 (parallel [(set (reg:CCC FLAGS_REG)
8479 (zero_extend:<DWI> (match_dup 1))
8480 (plus:<DWI> (match_op_dup 4
8481 [(match_dup 3) (const_int 0)])
8482 (zero_extend:<DWI> (match_dup 0)))))
8484 (minus:SWI48 (minus:SWI48 (match_dup 1)
8486 [(match_dup 3) (const_int 0)]))
8490 [(set (match_operand:SWI48 6 "general_reg_operand")
8491 (match_operand:SWI48 7 "memory_operand"))
8492 (set (match_operand:SWI48 8 "general_reg_operand")
8493 (match_operand:SWI48 9 "memory_operand"))
8494 (parallel [(set (reg:CCC FLAGS_REG)
8497 (match_operand:SWI48 0 "general_reg_operand"))
8499 (match_operator:<DWI> 4 "ix86_carry_flag_operator"
8500 [(match_operand 3 "flags_reg_operand") (const_int 0)])
8502 (match_operand:SWI48 2 "general_reg_operand")))))
8507 (match_operator:SWI48 5 "ix86_carry_flag_operator"
8508 [(match_dup 3) (const_int 0)]))
8510 (set (match_operand:SWI48 1 "memory_operand") (match_dup 0))]
8511 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
8512 && peep2_reg_dead_p (4, operands[0])
8513 && peep2_reg_dead_p (3, operands[2])
8514 && !reg_overlap_mentioned_p (operands[0], operands[1])
8515 && !reg_overlap_mentioned_p (operands[2], operands[1])
8516 && !reg_overlap_mentioned_p (operands[6], operands[9])
8517 && (rtx_equal_p (operands[6], operands[0])
8518 ? (rtx_equal_p (operands[7], operands[1])
8519 && rtx_equal_p (operands[8], operands[2]))
8520 : (rtx_equal_p (operands[8], operands[0])
8521 && rtx_equal_p (operands[9], operands[1])
8522 && rtx_equal_p (operands[6], operands[2])))"
8523 [(set (match_dup 0) (match_dup 9))
8524 (parallel [(set (reg:CCC FLAGS_REG)
8526 (zero_extend:<DWI> (match_dup 1))
8527 (plus:<DWI> (match_op_dup 4
8528 [(match_dup 3) (const_int 0)])
8529 (zero_extend:<DWI> (match_dup 0)))))
8531 (minus:SWI48 (minus:SWI48 (match_dup 1)
8533 [(match_dup 3) (const_int 0)]))
8536 if (!rtx_equal_p (operands[6], operands[0]))
8537 operands[9] = operands[7];
8541 [(set (match_operand:SWI48 6 "general_reg_operand")
8542 (match_operand:SWI48 7 "memory_operand"))
8543 (set (match_operand:SWI48 8 "general_reg_operand")
8544 (match_operand:SWI48 9 "memory_operand"))
8545 (parallel [(set (reg:CCC FLAGS_REG)
8548 (match_operand:SWI48 0 "general_reg_operand"))
8550 (match_operator:<DWI> 4 "ix86_carry_flag_operator"
8551 [(match_operand 3 "flags_reg_operand") (const_int 0)])
8553 (match_operand:SWI48 2 "general_reg_operand")))))
8558 (match_operator:SWI48 5 "ix86_carry_flag_operator"
8559 [(match_dup 3) (const_int 0)]))
8561 (set (match_operand:QI 10 "general_reg_operand")
8562 (ltu:QI (reg:CCC FLAGS_REG) (const_int 0)))
8563 (set (match_operand:SWI48 11 "general_reg_operand")
8564 (zero_extend:SWI48 (match_dup 10)))
8565 (set (match_operand:SWI48 1 "memory_operand") (match_dup 0))]
8566 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
8567 && peep2_reg_dead_p (6, operands[0])
8568 && peep2_reg_dead_p (3, operands[2])
8569 && !reg_overlap_mentioned_p (operands[0], operands[1])
8570 && !reg_overlap_mentioned_p (operands[2], operands[1])
8571 && !reg_overlap_mentioned_p (operands[6], operands[9])
8572 && !reg_overlap_mentioned_p (operands[0], operands[10])
8573 && !reg_overlap_mentioned_p (operands[10], operands[1])
8574 && !reg_overlap_mentioned_p (operands[0], operands[11])
8575 && !reg_overlap_mentioned_p (operands[11], operands[1])
8576 && (rtx_equal_p (operands[6], operands[0])
8577 ? (rtx_equal_p (operands[7], operands[1])
8578 && rtx_equal_p (operands[8], operands[2]))
8579 : (rtx_equal_p (operands[8], operands[0])
8580 && rtx_equal_p (operands[9], operands[1])
8581 && rtx_equal_p (operands[6], operands[2])))"
8582 [(set (match_dup 0) (match_dup 9))
8583 (parallel [(set (reg:CCC FLAGS_REG)
8585 (zero_extend:<DWI> (match_dup 1))
8586 (plus:<DWI> (match_op_dup 4
8587 [(match_dup 3) (const_int 0)])
8588 (zero_extend:<DWI> (match_dup 0)))))
8590 (minus:SWI48 (minus:SWI48 (match_dup 1)
8592 [(match_dup 3) (const_int 0)]))
8594 (set (match_dup 10) (ltu:QI (reg:CCC FLAGS_REG) (const_int 0)))
8595 (set (match_dup 11) (zero_extend:SWI48 (match_dup 10)))]
8597 if (!rtx_equal_p (operands[6], operands[0]))
8598 operands[9] = operands[7];
8601 (define_expand "subborrow<mode>_0"
8603 [(set (reg:CC FLAGS_REG)
8605 (match_operand:SWI48 1 "nonimmediate_operand")
8606 (match_operand:SWI48 2 "<general_operand>")))
8607 (set (match_operand:SWI48 0 "register_operand")
8608 (minus:SWI48 (match_dup 1) (match_dup 2)))])]
8609 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)")
8611 (define_expand "uaddc<mode>5"
8612 [(match_operand:SWI48 0 "register_operand")
8613 (match_operand:SWI48 1 "register_operand")
8614 (match_operand:SWI48 2 "register_operand")
8615 (match_operand:SWI48 3 "register_operand")
8616 (match_operand:SWI48 4 "nonmemory_operand")]
8619 rtx cf = gen_rtx_REG (CCCmode, FLAGS_REG), pat, pat2;
8620 if (operands[4] == const0_rtx)
8621 emit_insn (gen_addcarry<mode>_0 (operands[0], operands[2], operands[3]));
8624 ix86_expand_carry (operands[4]);
8625 pat = gen_rtx_LTU (<DWI>mode, cf, const0_rtx);
8626 pat2 = gen_rtx_LTU (<MODE>mode, cf, const0_rtx);
8627 emit_insn (gen_addcarry<mode> (operands[0], operands[2], operands[3],
8630 rtx cc = gen_reg_rtx (QImode);
8631 pat = gen_rtx_LTU (QImode, cf, const0_rtx);
8632 emit_insn (gen_rtx_SET (cc, pat));
8633 emit_insn (gen_zero_extendqi<mode>2 (operands[1], cc));
8637 (define_expand "usubc<mode>5"
8638 [(match_operand:SWI48 0 "register_operand")
8639 (match_operand:SWI48 1 "register_operand")
8640 (match_operand:SWI48 2 "register_operand")
8641 (match_operand:SWI48 3 "register_operand")
8642 (match_operand:SWI48 4 "nonmemory_operand")]
8646 if (operands[4] == const0_rtx)
8648 cf = gen_rtx_REG (CCmode, FLAGS_REG);
8649 emit_insn (gen_subborrow<mode>_0 (operands[0], operands[2],
8654 cf = gen_rtx_REG (CCCmode, FLAGS_REG);
8655 ix86_expand_carry (operands[4]);
8656 pat = gen_rtx_LTU (<DWI>mode, cf, const0_rtx);
8657 pat2 = gen_rtx_LTU (<MODE>mode, cf, const0_rtx);
8658 emit_insn (gen_subborrow<mode> (operands[0], operands[2], operands[3],
8661 rtx cc = gen_reg_rtx (QImode);
8662 pat = gen_rtx_LTU (QImode, cf, const0_rtx);
8663 emit_insn (gen_rtx_SET (cc, pat));
8664 emit_insn (gen_zero_extendqi<mode>2 (operands[1], cc));
8668 (define_mode_iterator CC_CCC [CC CCC])
8670 ;; Pre-reload splitter to optimize
8671 ;; *setcc_qi followed by *addqi3_cconly_overflow_1 with the same QI
8672 ;; operand and no intervening flags modifications into nothing.
8673 (define_insn_and_split "*setcc_qi_addqi3_cconly_overflow_1_<mode>"
8674 [(set (reg:CCC FLAGS_REG)
8675 (compare:CCC (neg:QI (geu:QI (reg:CC_CCC FLAGS_REG) (const_int 0)))
8676 (ltu:QI (reg:CC_CCC FLAGS_REG) (const_int 0))))]
8677 "ix86_pre_reload_split ()"
8681 "emit_note (NOTE_INSN_DELETED); DONE;")
8683 ;; Set the carry flag from the carry flag.
8684 (define_insn_and_split "*setccc"
8685 [(set (reg:CCC FLAGS_REG)
8686 (reg:CCC FLAGS_REG))]
8687 "ix86_pre_reload_split ()"
8691 "emit_note (NOTE_INSN_DELETED); DONE;")
8693 ;; Set the carry flag from the carry flag.
8694 (define_insn_and_split "*setcc_qi_negqi_ccc_1_<mode>"
8695 [(set (reg:CCC FLAGS_REG)
8696 (ltu:CCC (reg:CC_CCC FLAGS_REG) (const_int 0)))]
8697 "ix86_pre_reload_split ()"
8701 "emit_note (NOTE_INSN_DELETED); DONE;")
8703 ;; Set the carry flag from the carry flag.
8704 (define_insn_and_split "*setcc_qi_negqi_ccc_2_<mode>"
8705 [(set (reg:CCC FLAGS_REG)
8706 (unspec:CCC [(ltu:QI (reg:CC_CCC FLAGS_REG) (const_int 0))
8707 (const_int 0)] UNSPEC_CC_NE))]
8708 "ix86_pre_reload_split ()"
8712 "emit_note (NOTE_INSN_DELETED); DONE;")
8714 ;; Overflow setting add instructions
8716 (define_expand "addqi3_cconly_overflow"
8718 [(set (reg:CCC FLAGS_REG)
8721 (match_operand:QI 0 "nonimmediate_operand")
8722 (match_operand:QI 1 "general_operand"))
8724 (clobber (scratch:QI))])]
8725 "!(MEM_P (operands[0]) && MEM_P (operands[1]))")
8727 (define_insn "*add<mode>3_cconly_overflow_1"
8728 [(set (reg:CCC FLAGS_REG)
8731 (match_operand:SWI 1 "nonimmediate_operand" "%0")
8732 (match_operand:SWI 2 "<general_operand>" "<g>"))
8734 (clobber (match_scratch:SWI 0 "=<r>"))]
8735 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
8736 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
8737 [(set_attr "type" "alu")
8738 (set_attr "mode" "<MODE>")])
8740 (define_insn "*add<mode>3_cc_overflow_1"
8741 [(set (reg:CCC FLAGS_REG)
8744 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
8745 (match_operand:SWI 2 "<general_operand>" "<r><i>,<m>"))
8747 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
8748 (plus:SWI (match_dup 1) (match_dup 2)))]
8749 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
8750 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
8751 [(set_attr "type" "alu")
8752 (set_attr "mode" "<MODE>")])
8755 [(parallel [(set (reg:CCC FLAGS_REG)
8757 (plus:SWI (match_operand:SWI 0 "general_reg_operand")
8758 (match_operand:SWI 1 "memory_operand"))
8760 (set (match_dup 0) (plus:SWI (match_dup 0) (match_dup 1)))])
8761 (set (match_dup 1) (match_dup 0))]
8762 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
8763 && peep2_reg_dead_p (2, operands[0])
8764 && !reg_overlap_mentioned_p (operands[0], operands[1])"
8765 [(parallel [(set (reg:CCC FLAGS_REG)
8767 (plus:SWI (match_dup 1) (match_dup 0))
8769 (set (match_dup 1) (plus:SWI (match_dup 1) (match_dup 0)))])])
8772 [(set (match_operand:SWI 0 "general_reg_operand")
8773 (match_operand:SWI 1 "memory_operand"))
8774 (parallel [(set (reg:CCC FLAGS_REG)
8776 (plus:SWI (match_dup 0)
8777 (match_operand:SWI 2 "memory_operand"))
8779 (set (match_dup 0) (plus:SWI (match_dup 0) (match_dup 2)))])
8780 (set (match_dup 1) (match_dup 0))]
8781 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
8782 && peep2_reg_dead_p (3, operands[0])
8783 && !reg_overlap_mentioned_p (operands[0], operands[1])
8784 && !reg_overlap_mentioned_p (operands[0], operands[2])"
8785 [(set (match_dup 0) (match_dup 2))
8786 (parallel [(set (reg:CCC FLAGS_REG)
8788 (plus:SWI (match_dup 1) (match_dup 0))
8790 (set (match_dup 1) (plus:SWI (match_dup 1) (match_dup 0)))])])
8792 (define_insn "*addsi3_zext_cc_overflow_1"
8793 [(set (reg:CCC FLAGS_REG)
8796 (match_operand:SI 1 "nonimmediate_operand" "%0")
8797 (match_operand:SI 2 "x86_64_general_operand" "rBMe"))
8799 (set (match_operand:DI 0 "register_operand" "=r")
8800 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
8801 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
8802 "add{l}\t{%2, %k0|%k0, %2}"
8803 [(set_attr "type" "alu")
8804 (set_attr "mode" "SI")])
8806 (define_insn "*add<mode>3_cconly_overflow_2"
8807 [(set (reg:CCC FLAGS_REG)
8810 (match_operand:SWI 1 "nonimmediate_operand" "%0")
8811 (match_operand:SWI 2 "<general_operand>" "<g>"))
8813 (clobber (match_scratch:SWI 0 "=<r>"))]
8814 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
8815 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
8816 [(set_attr "type" "alu")
8817 (set_attr "mode" "<MODE>")])
8819 (define_insn "*add<mode>3_cc_overflow_2"
8820 [(set (reg:CCC FLAGS_REG)
8823 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
8824 (match_operand:SWI 2 "<general_operand>" "<r><i>,<m>"))
8826 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
8827 (plus:SWI (match_dup 1) (match_dup 2)))]
8828 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
8829 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
8830 [(set_attr "type" "alu")
8831 (set_attr "mode" "<MODE>")])
8833 (define_insn "*addsi3_zext_cc_overflow_2"
8834 [(set (reg:CCC FLAGS_REG)
8837 (match_operand:SI 1 "nonimmediate_operand" "%0")
8838 (match_operand:SI 2 "x86_64_general_operand" "rBMe"))
8840 (set (match_operand:DI 0 "register_operand" "=r")
8841 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
8842 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
8843 "add{l}\t{%2, %k0|%k0, %2}"
8844 [(set_attr "type" "alu")
8845 (set_attr "mode" "SI")])
8847 (define_insn_and_split "*add<dwi>3_doubleword_cc_overflow_1"
8848 [(set (reg:CCC FLAGS_REG)
8851 (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0")
8852 (match_operand:<DWI> 2 "x86_64_hilo_general_operand" "r<di>,o"))
8854 (set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro,r")
8855 (plus:<DWI> (match_dup 1) (match_dup 2)))]
8856 "ix86_binary_operator_ok (PLUS, <DWI>mode, operands)"
8858 "&& reload_completed"
8859 [(parallel [(set (reg:CCC FLAGS_REG)
8861 (plus:DWIH (match_dup 1) (match_dup 2))
8864 (plus:DWIH (match_dup 1) (match_dup 2)))])
8865 (parallel [(set (reg:CCC FLAGS_REG)
8870 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
8875 (ltu:<DWI> (reg:CC FLAGS_REG) (const_int 0)))))
8878 (plus:DWIH (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
8882 split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
8883 if (operands[2] == const0_rtx)
8885 emit_insn (gen_addcarry<mode>_0 (operands[3], operands[4], operands[5]));
8888 if (CONST_INT_P (operands[5]))
8889 operands[6] = simplify_unary_operation (ZERO_EXTEND, <DWI>mode,
8890 operands[5], <MODE>mode);
8892 operands[6] = gen_rtx_ZERO_EXTEND (<DWI>mode, operands[5]);
8895 ;; x == 0 with zero flag test can be done also as x < 1U with carry flag
8896 ;; test, where the latter is preferrable if we have some carry consuming
8898 ;; For x != 0, we need to use x < 1U with negation of carry, i.e.
8900 (define_insn_and_split "*add<mode>3_eq"
8901 [(set (match_operand:SWI 0 "nonimmediate_operand")
8904 (eq:SWI (match_operand 3 "int_nonimmediate_operand") (const_int 0))
8905 (match_operand:SWI 1 "nonimmediate_operand"))
8906 (match_operand:SWI 2 "<general_operand>")))
8907 (clobber (reg:CC FLAGS_REG))]
8908 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)
8909 && ix86_pre_reload_split ()"
8912 [(set (reg:CC FLAGS_REG)
8913 (compare:CC (match_dup 3) (const_int 1)))
8914 (parallel [(set (match_dup 0)
8916 (plus:SWI (ltu:SWI (reg:CC FLAGS_REG) (const_int 0))
8919 (clobber (reg:CC FLAGS_REG))])])
8921 (define_insn_and_split "*add<mode>3_ne"
8922 [(set (match_operand:SWI 0 "nonimmediate_operand")
8925 (ne:SWI (match_operand 3 "int_nonimmediate_operand") (const_int 0))
8926 (match_operand:SWI 1 "nonimmediate_operand"))
8927 (match_operand:SWI 2 "<immediate_operand>")))
8928 (clobber (reg:CC FLAGS_REG))]
8929 "CONST_INT_P (operands[2])
8930 && (<MODE>mode != DImode
8931 || INTVAL (operands[2]) != HOST_WIDE_INT_C (-0x80000000))
8932 && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)
8933 && ix86_pre_reload_split ()"
8936 [(set (reg:CC FLAGS_REG)
8937 (compare:CC (match_dup 3) (const_int 1)))
8938 (parallel [(set (match_dup 0)
8940 (minus:SWI (match_dup 1)
8941 (ltu:SWI (reg:CC FLAGS_REG) (const_int 0)))
8943 (clobber (reg:CC FLAGS_REG))])]
8945 operands[2] = gen_int_mode (~INTVAL (operands[2]),
8946 <MODE>mode == DImode ? SImode : <MODE>mode);
8949 (define_insn_and_split "*add<mode>3_eq_0"
8950 [(set (match_operand:SWI 0 "nonimmediate_operand")
8952 (eq:SWI (match_operand 2 "int_nonimmediate_operand") (const_int 0))
8953 (match_operand:SWI 1 "<general_operand>")))
8954 (clobber (reg:CC FLAGS_REG))]
8955 "ix86_unary_operator_ok (PLUS, <MODE>mode, operands)
8956 && ix86_pre_reload_split ()"
8959 [(set (reg:CC FLAGS_REG)
8960 (compare:CC (match_dup 2) (const_int 1)))
8961 (parallel [(set (match_dup 0)
8962 (plus:SWI (ltu:SWI (reg:CC FLAGS_REG) (const_int 0))
8964 (clobber (reg:CC FLAGS_REG))])]
8966 if (!nonimmediate_operand (operands[1], <MODE>mode))
8967 operands[1] = force_reg (<MODE>mode, operands[1]);
8970 (define_insn_and_split "*add<mode>3_ne_0"
8971 [(set (match_operand:SWI 0 "nonimmediate_operand")
8973 (ne:SWI (match_operand 2 "int_nonimmediate_operand") (const_int 0))
8974 (match_operand:SWI 1 "<general_operand>")))
8975 (clobber (reg:CC FLAGS_REG))]
8976 "ix86_unary_operator_ok (PLUS, <MODE>mode, operands)
8977 && ix86_pre_reload_split ()"
8980 [(set (reg:CC FLAGS_REG)
8981 (compare:CC (match_dup 2) (const_int 1)))
8982 (parallel [(set (match_dup 0)
8983 (minus:SWI (minus:SWI
8985 (ltu:SWI (reg:CC FLAGS_REG) (const_int 0)))
8987 (clobber (reg:CC FLAGS_REG))])]
8989 if (!nonimmediate_operand (operands[1], <MODE>mode))
8990 operands[1] = force_reg (<MODE>mode, operands[1]);
8993 (define_insn_and_split "*sub<mode>3_eq"
8994 [(set (match_operand:SWI 0 "nonimmediate_operand")
8997 (match_operand:SWI 1 "nonimmediate_operand")
8998 (eq:SWI (match_operand 3 "int_nonimmediate_operand")
9000 (match_operand:SWI 2 "<general_operand>")))
9001 (clobber (reg:CC FLAGS_REG))]
9002 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)
9003 && ix86_pre_reload_split ()"
9006 [(set (reg:CC FLAGS_REG)
9007 (compare:CC (match_dup 3) (const_int 1)))
9008 (parallel [(set (match_dup 0)
9010 (minus:SWI (match_dup 1)
9011 (ltu:SWI (reg:CC FLAGS_REG) (const_int 0)))
9013 (clobber (reg:CC FLAGS_REG))])])
9015 (define_insn_and_split "*sub<mode>3_ne"
9016 [(set (match_operand:SWI 0 "nonimmediate_operand")
9019 (match_operand:SWI 1 "nonimmediate_operand")
9020 (ne:SWI (match_operand 3 "int_nonimmediate_operand")
9022 (match_operand:SWI 2 "<immediate_operand>")))
9023 (clobber (reg:CC FLAGS_REG))]
9024 "CONST_INT_P (operands[2])
9025 && (<MODE>mode != DImode
9026 || INTVAL (operands[2]) != HOST_WIDE_INT_C (-0x80000000))
9027 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)
9028 && ix86_pre_reload_split ()"
9031 [(set (reg:CC FLAGS_REG)
9032 (compare:CC (match_dup 3) (const_int 1)))
9033 (parallel [(set (match_dup 0)
9035 (plus:SWI (ltu:SWI (reg:CC FLAGS_REG) (const_int 0))
9038 (clobber (reg:CC FLAGS_REG))])]
9040 operands[2] = gen_int_mode (INTVAL (operands[2]) - 1,
9041 <MODE>mode == DImode ? SImode : <MODE>mode);
9044 (define_insn_and_split "*sub<mode>3_eq_1"
9045 [(set (match_operand:SWI 0 "nonimmediate_operand")
9048 (match_operand:SWI 1 "nonimmediate_operand")
9049 (eq:SWI (match_operand 3 "int_nonimmediate_operand")
9051 (match_operand:SWI 2 "<immediate_operand>")))
9052 (clobber (reg:CC FLAGS_REG))]
9053 "CONST_INT_P (operands[2])
9054 && (<MODE>mode != DImode
9055 || INTVAL (operands[2]) != HOST_WIDE_INT_C (-0x80000000))
9056 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)
9057 && ix86_pre_reload_split ()"
9060 [(set (reg:CC FLAGS_REG)
9061 (compare:CC (match_dup 3) (const_int 1)))
9062 (parallel [(set (match_dup 0)
9064 (minus:SWI (match_dup 1)
9065 (ltu:SWI (reg:CC FLAGS_REG) (const_int 0)))
9067 (clobber (reg:CC FLAGS_REG))])]
9069 operands[2] = gen_int_mode (-INTVAL (operands[2]),
9070 <MODE>mode == DImode ? SImode : <MODE>mode);
9073 (define_insn_and_split "*sub<mode>3_eq_0"
9074 [(set (match_operand:SWI 0 "nonimmediate_operand")
9076 (match_operand:SWI 1 "<general_operand>")
9077 (eq:SWI (match_operand 2 "int_nonimmediate_operand") (const_int 0))))
9078 (clobber (reg:CC FLAGS_REG))]
9079 "ix86_unary_operator_ok (MINUS, <MODE>mode, operands)
9080 && ix86_pre_reload_split ()"
9083 [(set (reg:CC FLAGS_REG)
9084 (compare:CC (match_dup 2) (const_int 1)))
9085 (parallel [(set (match_dup 0)
9086 (minus:SWI (match_dup 1)
9087 (ltu:SWI (reg:CC FLAGS_REG) (const_int 0))))
9088 (clobber (reg:CC FLAGS_REG))])]
9090 if (!nonimmediate_operand (operands[1], <MODE>mode))
9091 operands[1] = force_reg (<MODE>mode, operands[1]);
9094 (define_insn_and_split "*sub<mode>3_ne_0"
9095 [(set (match_operand:SWI 0 "nonimmediate_operand")
9097 (match_operand:SWI 1 "<general_operand>")
9098 (ne:SWI (match_operand 2 "int_nonimmediate_operand") (const_int 0))))
9099 (clobber (reg:CC FLAGS_REG))]
9100 "ix86_unary_operator_ok (MINUS, <MODE>mode, operands)
9101 && ix86_pre_reload_split ()"
9104 [(set (reg:CC FLAGS_REG)
9105 (compare:CC (match_dup 2) (const_int 1)))
9106 (parallel [(set (match_dup 0)
9108 (ltu:SWI (reg:CC FLAGS_REG) (const_int 0))
9111 (clobber (reg:CC FLAGS_REG))])]
9113 if (!nonimmediate_operand (operands[1], <MODE>mode))
9114 operands[1] = force_reg (<MODE>mode, operands[1]);
9117 ;; The patterns that match these are at the end of this file.
9119 (define_expand "<insn>xf3"
9120 [(set (match_operand:XF 0 "register_operand")
9122 (match_operand:XF 1 "register_operand")
9123 (match_operand:XF 2 "register_operand")))]
9126 (define_expand "<insn>hf3"
9127 [(set (match_operand:HF 0 "register_operand")
9129 (match_operand:HF 1 "register_operand")
9130 (match_operand:HF 2 "nonimmediate_operand")))]
9131 "TARGET_AVX512FP16")
9133 (define_expand "<insn><mode>3"
9134 [(set (match_operand:MODEF 0 "register_operand")
9136 (match_operand:MODEF 1 "register_operand")
9137 (match_operand:MODEF 2 "nonimmediate_operand")))]
9138 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
9139 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
9141 ;; Multiply instructions
9143 (define_expand "mul<mode>3"
9144 [(parallel [(set (match_operand:SWIM248 0 "register_operand")
9146 (match_operand:SWIM248 1 "register_operand")
9147 (match_operand:SWIM248 2 "<general_operand>")))
9148 (clobber (reg:CC FLAGS_REG))])])
9150 (define_expand "mulqi3"
9151 [(parallel [(set (match_operand:QI 0 "register_operand")
9153 (match_operand:QI 1 "register_operand")
9154 (match_operand:QI 2 "nonimmediate_operand")))
9155 (clobber (reg:CC FLAGS_REG))])]
9156 "TARGET_QIMODE_MATH")
9159 ;; IMUL reg32/64, reg32/64, imm8 Direct
9160 ;; IMUL reg32/64, mem32/64, imm8 VectorPath
9161 ;; IMUL reg32/64, reg32/64, imm32 Direct
9162 ;; IMUL reg32/64, mem32/64, imm32 VectorPath
9163 ;; IMUL reg32/64, reg32/64 Direct
9164 ;; IMUL reg32/64, mem32/64 Direct
9166 ;; On BDVER1, all above IMULs use DirectPath
9169 ;; IMUL reg16, reg16, imm8 VectorPath
9170 ;; IMUL reg16, mem16, imm8 VectorPath
9171 ;; IMUL reg16, reg16, imm16 VectorPath
9172 ;; IMUL reg16, mem16, imm16 VectorPath
9173 ;; IMUL reg16, reg16 Direct
9174 ;; IMUL reg16, mem16 Direct
9176 ;; On BDVER1, all HI MULs use DoublePath
9178 (define_insn "*mul<mode>3_1"
9179 [(set (match_operand:SWIM248 0 "register_operand" "=r,r,r")
9181 (match_operand:SWIM248 1 "nonimmediate_operand" "%rm,rm,0")
9182 (match_operand:SWIM248 2 "<general_operand>" "K,<i>,<m>r")))
9183 (clobber (reg:CC FLAGS_REG))]
9184 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
9186 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
9187 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
9188 imul{<imodesuffix>}\t{%2, %0|%0, %2}"
9189 [(set_attr "type" "imul")
9190 (set_attr "prefix_0f" "0,0,1")
9191 (set (attr "athlon_decode")
9192 (cond [(eq_attr "cpu" "athlon")
9193 (const_string "vector")
9194 (eq_attr "alternative" "1")
9195 (const_string "vector")
9196 (and (eq_attr "alternative" "2")
9197 (ior (match_test "<MODE>mode == HImode")
9198 (match_operand 1 "memory_operand")))
9199 (const_string "vector")]
9200 (const_string "direct")))
9201 (set (attr "amdfam10_decode")
9202 (cond [(and (eq_attr "alternative" "0,1")
9203 (ior (match_test "<MODE>mode == HImode")
9204 (match_operand 1 "memory_operand")))
9205 (const_string "vector")]
9206 (const_string "direct")))
9207 (set (attr "bdver1_decode")
9209 (match_test "<MODE>mode == HImode")
9210 (const_string "double")
9211 (const_string "direct")))
9212 (set_attr "mode" "<MODE>")])
9214 (define_insn "*mulsi3_1_zext"
9215 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
9217 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
9218 (match_operand:SI 2 "x86_64_general_operand" "K,e,BMr"))))
9219 (clobber (reg:CC FLAGS_REG))]
9221 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9223 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
9224 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
9225 imul{l}\t{%2, %k0|%k0, %2}"
9226 [(set_attr "type" "imul")
9227 (set_attr "prefix_0f" "0,0,1")
9228 (set (attr "athlon_decode")
9229 (cond [(eq_attr "cpu" "athlon")
9230 (const_string "vector")
9231 (eq_attr "alternative" "1")
9232 (const_string "vector")
9233 (and (eq_attr "alternative" "2")
9234 (match_operand 1 "memory_operand"))
9235 (const_string "vector")]
9236 (const_string "direct")))
9237 (set (attr "amdfam10_decode")
9238 (cond [(and (eq_attr "alternative" "0,1")
9239 (match_operand 1 "memory_operand"))
9240 (const_string "vector")]
9241 (const_string "direct")))
9242 (set_attr "bdver1_decode" "direct")
9243 (set_attr "mode" "SI")])
9245 ;;On AMDFAM10 and BDVER1
9249 (define_insn "*mulqi3_1"
9250 [(set (match_operand:QI 0 "register_operand" "=a")
9251 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
9252 (match_operand:QI 2 "nonimmediate_operand" "qm")))
9253 (clobber (reg:CC FLAGS_REG))]
9255 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9257 [(set_attr "type" "imul")
9258 (set_attr "length_immediate" "0")
9259 (set (attr "athlon_decode")
9260 (if_then_else (eq_attr "cpu" "athlon")
9261 (const_string "vector")
9262 (const_string "direct")))
9263 (set_attr "amdfam10_decode" "direct")
9264 (set_attr "bdver1_decode" "direct")
9265 (set_attr "mode" "QI")])
9267 ;; Multiply with jump on overflow.
9268 (define_expand "mulv<mode>4"
9269 [(parallel [(set (reg:CCO FLAGS_REG)
9272 (match_operand:SWI248 1 "register_operand"))
9275 (mult:SWI248 (match_dup 1)
9276 (match_operand:SWI248 2
9277 "<general_operand>")))))
9278 (set (match_operand:SWI248 0 "register_operand")
9279 (mult:SWI248 (match_dup 1) (match_dup 2)))])
9280 (set (pc) (if_then_else
9281 (eq (reg:CCO FLAGS_REG) (const_int 0))
9282 (label_ref (match_operand 3))
9286 if (CONST_INT_P (operands[2]))
9287 operands[4] = operands[2];
9289 operands[4] = gen_rtx_SIGN_EXTEND (<DWI>mode, operands[2]);
9292 (define_insn "*mulv<mode>4"
9293 [(set (reg:CCO FLAGS_REG)
9296 (match_operand:SWI48 1 "nonimmediate_operand" "%rm,0"))
9298 (match_operand:SWI48 2 "x86_64_sext_operand" "We,mr")))
9300 (mult:SWI48 (match_dup 1) (match_dup 2)))))
9301 (set (match_operand:SWI48 0 "register_operand" "=r,r")
9302 (mult:SWI48 (match_dup 1) (match_dup 2)))]
9303 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
9305 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
9306 imul{<imodesuffix>}\t{%2, %0|%0, %2}"
9307 [(set_attr "type" "imul")
9308 (set_attr "prefix_0f" "0,1")
9309 (set (attr "athlon_decode")
9310 (cond [(eq_attr "cpu" "athlon")
9311 (const_string "vector")
9312 (eq_attr "alternative" "0")
9313 (const_string "vector")
9314 (and (eq_attr "alternative" "1")
9315 (match_operand 1 "memory_operand"))
9316 (const_string "vector")]
9317 (const_string "direct")))
9318 (set (attr "amdfam10_decode")
9319 (cond [(and (eq_attr "alternative" "1")
9320 (match_operand 1 "memory_operand"))
9321 (const_string "vector")]
9322 (const_string "direct")))
9323 (set_attr "bdver1_decode" "direct")
9324 (set_attr "mode" "<MODE>")])
9326 (define_insn "*mulvhi4"
9327 [(set (reg:CCO FLAGS_REG)
9330 (match_operand:HI 1 "nonimmediate_operand" "%0"))
9332 (match_operand:HI 2 "nonimmediate_operand" "mr")))
9334 (mult:HI (match_dup 1) (match_dup 2)))))
9335 (set (match_operand:HI 0 "register_operand" "=r")
9336 (mult:HI (match_dup 1) (match_dup 2)))]
9337 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
9338 "imul{w}\t{%2, %0|%0, %2}"
9339 [(set_attr "type" "imul")
9340 (set_attr "prefix_0f" "1")
9341 (set_attr "athlon_decode" "vector")
9342 (set_attr "amdfam10_decode" "direct")
9343 (set_attr "bdver1_decode" "double")
9344 (set_attr "mode" "HI")])
9346 (define_insn "*mulv<mode>4_1"
9347 [(set (reg:CCO FLAGS_REG)
9350 (match_operand:SWI248 1 "nonimmediate_operand" "rm,rm"))
9351 (match_operand:<DWI> 3 "const_int_operand" "K,i"))
9353 (mult:SWI248 (match_dup 1)
9354 (match_operand:SWI248 2
9355 "<immediate_operand>" "K,<i>")))))
9356 (set (match_operand:SWI248 0 "register_operand" "=r,r")
9357 (mult:SWI248 (match_dup 1) (match_dup 2)))]
9358 "!(MEM_P (operands[1]) && MEM_P (operands[2]))
9359 && CONST_INT_P (operands[2])
9360 && INTVAL (operands[2]) == INTVAL (operands[3])"
9361 "imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}"
9362 [(set_attr "type" "imul")
9363 (set (attr "prefix_0f")
9365 (match_test "<MODE>mode == HImode")
9367 (const_string "*")))
9368 (set (attr "athlon_decode")
9369 (cond [(eq_attr "cpu" "athlon")
9370 (const_string "vector")
9371 (eq_attr "alternative" "1")
9372 (const_string "vector")]
9373 (const_string "direct")))
9374 (set (attr "amdfam10_decode")
9375 (cond [(ior (match_test "<MODE>mode == HImode")
9376 (match_operand 1 "memory_operand"))
9377 (const_string "vector")]
9378 (const_string "direct")))
9379 (set (attr "bdver1_decode")
9381 (match_test "<MODE>mode == HImode")
9382 (const_string "double")
9383 (const_string "direct")))
9384 (set_attr "mode" "<MODE>")
9385 (set (attr "length_immediate")
9386 (cond [(eq_attr "alternative" "0")
9388 (match_test "<MODE_SIZE> == 8")
9390 (const_string "<MODE_SIZE>")))])
9392 (define_expand "umulv<mode>4"
9393 [(parallel [(set (reg:CCO FLAGS_REG)
9396 (match_operand:SWI248 1
9397 "nonimmediate_operand"))
9399 (match_operand:SWI248 2
9400 "nonimmediate_operand")))
9402 (mult:SWI248 (match_dup 1) (match_dup 2)))))
9403 (set (match_operand:SWI248 0 "register_operand")
9404 (mult:SWI248 (match_dup 1) (match_dup 2)))
9405 (clobber (scratch:SWI248))])
9406 (set (pc) (if_then_else
9407 (eq (reg:CCO FLAGS_REG) (const_int 0))
9408 (label_ref (match_operand 3))
9412 if (MEM_P (operands[1]) && MEM_P (operands[2]))
9413 operands[1] = force_reg (<MODE>mode, operands[1]);
9416 (define_insn "*umulv<mode>4"
9417 [(set (reg:CCO FLAGS_REG)
9420 (match_operand:SWI248 1 "nonimmediate_operand" "%0"))
9422 (match_operand:SWI248 2 "nonimmediate_operand" "rm")))
9424 (mult:SWI248 (match_dup 1) (match_dup 2)))))
9425 (set (match_operand:SWI248 0 "register_operand" "=a")
9426 (mult:SWI248 (match_dup 1) (match_dup 2)))
9427 (clobber (match_scratch:SWI248 3 "=d"))]
9428 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
9429 "mul{<imodesuffix>}\t%2"
9430 [(set_attr "type" "imul")
9431 (set_attr "length_immediate" "0")
9432 (set (attr "athlon_decode")
9433 (if_then_else (eq_attr "cpu" "athlon")
9434 (const_string "vector")
9435 (const_string "double")))
9436 (set_attr "amdfam10_decode" "double")
9437 (set_attr "bdver1_decode" "direct")
9438 (set_attr "mode" "<MODE>")])
9440 (define_expand "<u>mulvqi4"
9441 [(parallel [(set (reg:CCO FLAGS_REG)
9444 (match_operand:QI 1 "nonimmediate_operand"))
9446 (match_operand:QI 2 "nonimmediate_operand")))
9448 (mult:QI (match_dup 1) (match_dup 2)))))
9449 (set (match_operand:QI 0 "register_operand")
9450 (mult:QI (match_dup 1) (match_dup 2)))])
9451 (set (pc) (if_then_else
9452 (eq (reg:CCO FLAGS_REG) (const_int 0))
9453 (label_ref (match_operand 3))
9455 "TARGET_QIMODE_MATH"
9457 if (MEM_P (operands[1]) && MEM_P (operands[2]))
9458 operands[1] = force_reg (QImode, operands[1]);
9461 (define_insn "*<u>mulvqi4"
9462 [(set (reg:CCO FLAGS_REG)
9465 (match_operand:QI 1 "nonimmediate_operand" "%0"))
9467 (match_operand:QI 2 "nonimmediate_operand" "qm")))
9469 (mult:QI (match_dup 1) (match_dup 2)))))
9470 (set (match_operand:QI 0 "register_operand" "=a")
9471 (mult:QI (match_dup 1) (match_dup 2)))]
9473 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9474 "<sgnprefix>mul{b}\t%2"
9475 [(set_attr "type" "imul")
9476 (set_attr "length_immediate" "0")
9477 (set (attr "athlon_decode")
9478 (if_then_else (eq_attr "cpu" "athlon")
9479 (const_string "vector")
9480 (const_string "direct")))
9481 (set_attr "amdfam10_decode" "direct")
9482 (set_attr "bdver1_decode" "direct")
9483 (set_attr "mode" "QI")])
9485 (define_expand "<u>mul<mode><dwi>3"
9486 [(parallel [(set (match_operand:<DWI> 0 "register_operand")
9489 (match_operand:DWIH 1 "nonimmediate_operand"))
9491 (match_operand:DWIH 2 "register_operand"))))
9492 (clobber (reg:CC FLAGS_REG))])])
9494 (define_expand "<u>mulqihi3"
9495 [(parallel [(set (match_operand:HI 0 "register_operand")
9498 (match_operand:QI 1 "nonimmediate_operand"))
9500 (match_operand:QI 2 "register_operand"))))
9501 (clobber (reg:CC FLAGS_REG))])]
9502 "TARGET_QIMODE_MATH")
9504 (define_insn "*bmi2_umul<mode><dwi>3_1"
9505 [(set (match_operand:DWIH 0 "register_operand" "=r")
9507 (match_operand:DWIH 2 "nonimmediate_operand" "%d")
9508 (match_operand:DWIH 3 "nonimmediate_operand" "rm")))
9509 (set (match_operand:DWIH 1 "register_operand" "=r")
9512 (mult:<DWI> (zero_extend:<DWI> (match_dup 2))
9513 (zero_extend:<DWI> (match_dup 3)))
9514 (match_operand:QI 4 "const_int_operand"))))]
9515 "TARGET_BMI2 && INTVAL (operands[4]) == <MODE_SIZE> * BITS_PER_UNIT
9516 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
9517 "mulx\t{%3, %0, %1|%1, %0, %3}"
9518 [(set_attr "type" "imulx")
9519 (set_attr "prefix" "vex")
9520 (set_attr "mode" "<MODE>")])
9522 (define_insn "*umul<mode><dwi>3_1"
9523 [(set (match_operand:<DWI> 0 "register_operand" "=r,A")
9526 (match_operand:DWIH 1 "nonimmediate_operand" "%d,0"))
9528 (match_operand:DWIH 2 "nonimmediate_operand" "rm,rm"))))
9529 (clobber (reg:CC FLAGS_REG))]
9530 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
9533 mul{<imodesuffix>}\t%2"
9534 [(set_attr "isa" "bmi2,*")
9535 (set_attr "type" "imulx,imul")
9536 (set_attr "length_immediate" "*,0")
9537 (set (attr "athlon_decode")
9538 (cond [(eq_attr "alternative" "1")
9539 (if_then_else (eq_attr "cpu" "athlon")
9540 (const_string "vector")
9541 (const_string "double"))]
9542 (const_string "*")))
9543 (set_attr "amdfam10_decode" "*,double")
9544 (set_attr "bdver1_decode" "*,direct")
9545 (set_attr "prefix" "vex,orig")
9546 (set_attr "mode" "<MODE>")])
9548 ;; Convert mul to the mulx pattern to avoid flags dependency.
9550 [(set (match_operand:<DWI> 0 "register_operand")
9553 (match_operand:DWIH 1 "register_operand"))
9555 (match_operand:DWIH 2 "nonimmediate_operand"))))
9556 (clobber (reg:CC FLAGS_REG))]
9557 "TARGET_BMI2 && reload_completed
9558 && REGNO (operands[1]) == DX_REG"
9559 [(parallel [(set (match_dup 3)
9560 (mult:DWIH (match_dup 1) (match_dup 2)))
9564 (mult:<DWI> (zero_extend:<DWI> (match_dup 1))
9565 (zero_extend:<DWI> (match_dup 2)))
9568 split_double_mode (<DWI>mode, &operands[0], 1, &operands[3], &operands[4]);
9570 operands[5] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT);
9573 (define_insn "*mul<mode><dwi>3_1"
9574 [(set (match_operand:<DWI> 0 "register_operand" "=A")
9577 (match_operand:DWIH 1 "nonimmediate_operand" "%0"))
9579 (match_operand:DWIH 2 "nonimmediate_operand" "rm"))))
9580 (clobber (reg:CC FLAGS_REG))]
9581 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
9582 "imul{<imodesuffix>}\t%2"
9583 [(set_attr "type" "imul")
9584 (set_attr "length_immediate" "0")
9585 (set (attr "athlon_decode")
9586 (if_then_else (eq_attr "cpu" "athlon")
9587 (const_string "vector")
9588 (const_string "double")))
9589 (set_attr "amdfam10_decode" "double")
9590 (set_attr "bdver1_decode" "direct")
9591 (set_attr "mode" "<MODE>")])
9593 (define_insn "*<u>mulqihi3_1"
9594 [(set (match_operand:HI 0 "register_operand" "=a")
9597 (match_operand:QI 1 "nonimmediate_operand" "%0"))
9599 (match_operand:QI 2 "nonimmediate_operand" "qm"))))
9600 (clobber (reg:CC FLAGS_REG))]
9602 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9603 "<sgnprefix>mul{b}\t%2"
9604 [(set_attr "type" "imul")
9605 (set_attr "length_immediate" "0")
9606 (set (attr "athlon_decode")
9607 (if_then_else (eq_attr "cpu" "athlon")
9608 (const_string "vector")
9609 (const_string "direct")))
9610 (set_attr "amdfam10_decode" "direct")
9611 (set_attr "bdver1_decode" "direct")
9612 (set_attr "mode" "QI")])
9614 ;; Highpart multiplication patterns
9615 (define_insn "<s>mul<mode>3_highpart"
9616 [(set (match_operand:DWIH 0 "register_operand" "=d")
9617 (any_mul_highpart:DWIH
9618 (match_operand:DWIH 1 "register_operand" "%a")
9619 (match_operand:DWIH 2 "nonimmediate_operand" "rm")))
9620 (clobber (match_scratch:DWIH 3 "=1"))
9621 (clobber (reg:CC FLAGS_REG))]
9623 "<sgnprefix>mul{<imodesuffix>}\t%2"
9624 [(set_attr "type" "imul")
9625 (set_attr "length_immediate" "0")
9626 (set (attr "athlon_decode")
9627 (if_then_else (eq_attr "cpu" "athlon")
9628 (const_string "vector")
9629 (const_string "double")))
9630 (set_attr "amdfam10_decode" "double")
9631 (set_attr "bdver1_decode" "direct")
9632 (set_attr "mode" "<MODE>")])
9634 (define_insn "*<s>mulsi3_highpart_zext"
9635 [(set (match_operand:DI 0 "register_operand" "=d")
9637 (any_mul_highpart:SI
9638 (match_operand:SI 1 "register_operand" "%a")
9639 (match_operand:SI 2 "nonimmediate_operand" "rm"))))
9640 (clobber (match_scratch:SI 3 "=1"))
9641 (clobber (reg:CC FLAGS_REG))]
9643 "<sgnprefix>mul{l}\t%2"
9644 [(set_attr "type" "imul")
9645 (set_attr "length_immediate" "0")
9646 (set (attr "athlon_decode")
9647 (if_then_else (eq_attr "cpu" "athlon")
9648 (const_string "vector")
9649 (const_string "double")))
9650 (set_attr "amdfam10_decode" "double")
9651 (set_attr "bdver1_decode" "direct")
9652 (set_attr "mode" "SI")])
9654 (define_insn "*<s>muldi3_highpart_1"
9655 [(set (match_operand:DI 0 "register_operand" "=d")
9660 (match_operand:DI 1 "nonimmediate_operand" "%a"))
9662 (match_operand:DI 2 "nonimmediate_operand" "rm")))
9664 (clobber (match_scratch:DI 3 "=1"))
9665 (clobber (reg:CC FLAGS_REG))]
9667 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9668 "<sgnprefix>mul{q}\t%2"
9669 [(set_attr "type" "imul")
9670 (set_attr "length_immediate" "0")
9671 (set (attr "athlon_decode")
9672 (if_then_else (eq_attr "cpu" "athlon")
9673 (const_string "vector")
9674 (const_string "double")))
9675 (set_attr "amdfam10_decode" "double")
9676 (set_attr "bdver1_decode" "direct")
9677 (set_attr "mode" "DI")])
9679 (define_insn "*<s>mulsi3_highpart_zext"
9680 [(set (match_operand:DI 0 "register_operand" "=d")
9681 (zero_extend:DI (truncate:SI
9683 (mult:DI (any_extend:DI
9684 (match_operand:SI 1 "nonimmediate_operand" "%a"))
9686 (match_operand:SI 2 "nonimmediate_operand" "rm")))
9688 (clobber (match_scratch:SI 3 "=1"))
9689 (clobber (reg:CC FLAGS_REG))]
9691 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9692 "<sgnprefix>mul{l}\t%2"
9693 [(set_attr "type" "imul")
9694 (set_attr "length_immediate" "0")
9695 (set (attr "athlon_decode")
9696 (if_then_else (eq_attr "cpu" "athlon")
9697 (const_string "vector")
9698 (const_string "double")))
9699 (set_attr "amdfam10_decode" "double")
9700 (set_attr "bdver1_decode" "direct")
9701 (set_attr "mode" "SI")])
9703 (define_insn "*<s>mulsi3_highpart_1"
9704 [(set (match_operand:SI 0 "register_operand" "=d")
9709 (match_operand:SI 1 "nonimmediate_operand" "%a"))
9711 (match_operand:SI 2 "nonimmediate_operand" "rm")))
9713 (clobber (match_scratch:SI 3 "=1"))
9714 (clobber (reg:CC FLAGS_REG))]
9715 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
9716 "<sgnprefix>mul{l}\t%2"
9717 [(set_attr "type" "imul")
9718 (set_attr "length_immediate" "0")
9719 (set (attr "athlon_decode")
9720 (if_then_else (eq_attr "cpu" "athlon")
9721 (const_string "vector")
9722 (const_string "double")))
9723 (set_attr "amdfam10_decode" "double")
9724 (set_attr "bdver1_decode" "direct")
9725 (set_attr "mode" "SI")])
9727 ;; Highpart multiplication peephole2s to tweak register allocation.
9728 ;; mov imm,%rdx; mov %rdi,%rax; imulq %rdx -> mov imm,%rax; imulq %rdi
9730 [(set (match_operand:SWI48 0 "general_reg_operand")
9731 (match_operand:SWI48 1 "immediate_operand"))
9732 (set (match_operand:SWI48 2 "general_reg_operand")
9733 (match_operand:SWI48 3 "general_reg_operand"))
9734 (parallel [(set (match_operand:SWI48 4 "general_reg_operand")
9735 (any_mul_highpart:SWI48 (match_dup 2) (match_dup 0)))
9736 (clobber (match_dup 2))
9737 (clobber (reg:CC FLAGS_REG))])]
9738 "REGNO (operands[3]) != AX_REG
9739 && REGNO (operands[0]) != REGNO (operands[2])
9740 && REGNO (operands[0]) != REGNO (operands[3])
9741 && (REGNO (operands[0]) == REGNO (operands[4])
9742 || peep2_reg_dead_p (3, operands[0]))"
9743 [(set (match_dup 2) (match_dup 1))
9744 (parallel [(set (match_dup 4)
9745 (any_mul_highpart:SWI48 (match_dup 2) (match_dup 3)))
9746 (clobber (match_dup 2))
9747 (clobber (reg:CC FLAGS_REG))])])
9750 [(set (match_operand:SI 0 "general_reg_operand")
9751 (match_operand:SI 1 "immediate_operand"))
9752 (set (match_operand:SI 2 "general_reg_operand")
9753 (match_operand:SI 3 "general_reg_operand"))
9754 (parallel [(set (match_operand:DI 4 "general_reg_operand")
9756 (any_mul_highpart:SI (match_dup 2) (match_dup 0))))
9757 (clobber (match_dup 2))
9758 (clobber (reg:CC FLAGS_REG))])]
9760 && REGNO (operands[3]) != AX_REG
9761 && REGNO (operands[0]) != REGNO (operands[2])
9762 && REGNO (operands[2]) != REGNO (operands[3])
9763 && REGNO (operands[0]) != REGNO (operands[3])
9764 && (REGNO (operands[0]) == REGNO (operands[4])
9765 || peep2_reg_dead_p (3, operands[0]))"
9766 [(set (match_dup 2) (match_dup 1))
9767 (parallel [(set (match_dup 4)
9769 (any_mul_highpart:SI (match_dup 2) (match_dup 3))))
9770 (clobber (match_dup 2))
9771 (clobber (reg:CC FLAGS_REG))])])
9773 ;; The patterns that match these are at the end of this file.
9775 (define_expand "mulxf3"
9776 [(set (match_operand:XF 0 "register_operand")
9777 (mult:XF (match_operand:XF 1 "register_operand")
9778 (match_operand:XF 2 "register_operand")))]
9781 (define_expand "mulhf3"
9782 [(set (match_operand:HF 0 "register_operand")
9783 (mult:HF (match_operand:HF 1 "register_operand")
9784 (match_operand:HF 2 "nonimmediate_operand")))]
9785 "TARGET_AVX512FP16")
9787 (define_expand "mul<mode>3"
9788 [(set (match_operand:MODEF 0 "register_operand")
9789 (mult:MODEF (match_operand:MODEF 1 "register_operand")
9790 (match_operand:MODEF 2 "nonimmediate_operand")))]
9791 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
9792 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
9794 ;; Divide instructions
9796 ;; The patterns that match these are at the end of this file.
9798 (define_expand "divxf3"
9799 [(set (match_operand:XF 0 "register_operand")
9800 (div:XF (match_operand:XF 1 "register_operand")
9801 (match_operand:XF 2 "register_operand")))]
9804 /* There is no more precision loss than Newton-Rhapson approximation
9805 when using HFmode rcp/rsqrt, so do the transformation directly under
9806 TARGET_RECIP_DIV and fast-math. */
9807 (define_expand "divhf3"
9808 [(set (match_operand:HF 0 "register_operand")
9809 (div:HF (match_operand:HF 1 "register_operand")
9810 (match_operand:HF 2 "nonimmediate_operand")))]
9813 if (TARGET_RECIP_DIV
9814 && optimize_insn_for_speed_p ()
9815 && flag_finite_math_only && !flag_trapping_math
9816 && flag_unsafe_math_optimizations)
9818 rtx op = gen_reg_rtx (HFmode);
9819 operands[2] = force_reg (HFmode, operands[2]);
9820 emit_insn (gen_rcphf2 (op, operands[2]));
9821 emit_insn (gen_mulhf3 (operands[0], operands[1], op));
9826 (define_expand "div<mode>3"
9827 [(set (match_operand:MODEF 0 "register_operand")
9828 (div:MODEF (match_operand:MODEF 1 "register_operand")
9829 (match_operand:MODEF 2 "nonimmediate_operand")))]
9830 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
9831 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
9833 if (<MODE>mode == SFmode
9834 && TARGET_SSE && TARGET_SSE_MATH
9836 && optimize_insn_for_speed_p ()
9837 && flag_finite_math_only && !flag_trapping_math
9838 && flag_unsafe_math_optimizations)
9840 ix86_emit_swdivsf (operands[0], operands[1],
9841 operands[2], SFmode);
9846 ;; Divmod instructions.
9848 (define_code_iterator any_div [div udiv])
9849 (define_code_attr paired_mod [(div "mod") (udiv "umod")])
9851 (define_expand "<u>divmod<mode>4"
9852 [(parallel [(set (match_operand:SWIM248 0 "register_operand")
9854 (match_operand:SWIM248 1 "register_operand")
9855 (match_operand:SWIM248 2 "nonimmediate_operand")))
9856 (set (match_operand:SWIM248 3 "register_operand")
9857 (<paired_mod>:SWIM248 (match_dup 1) (match_dup 2)))
9858 (clobber (reg:CC FLAGS_REG))])])
9860 ;; Split with 8bit unsigned divide:
9861 ;; if (dividend an divisor are in [0-255])
9862 ;; use 8bit unsigned integer divide
9864 ;; use original integer divide
9866 [(set (match_operand:SWI48 0 "register_operand")
9867 (any_div:SWI48 (match_operand:SWI48 2 "register_operand")
9868 (match_operand:SWI48 3 "nonimmediate_operand")))
9869 (set (match_operand:SWI48 1 "register_operand")
9870 (<paired_mod>:SWI48 (match_dup 2) (match_dup 3)))
9871 (clobber (reg:CC FLAGS_REG))]
9872 "TARGET_USE_8BIT_IDIV
9873 && TARGET_QIMODE_MATH
9874 && can_create_pseudo_p ()
9875 && !optimize_insn_for_size_p ()"
9877 "ix86_split_idivmod (<MODE>mode, operands, <u_bool>); DONE;")
9880 [(set (match_operand:DI 0 "register_operand")
9882 (any_div:SI (match_operand:SI 2 "register_operand")
9883 (match_operand:SI 3 "nonimmediate_operand"))))
9884 (set (match_operand:SI 1 "register_operand")
9885 (<paired_mod>:SI (match_dup 2) (match_dup 3)))
9886 (clobber (reg:CC FLAGS_REG))]
9888 && TARGET_USE_8BIT_IDIV
9889 && TARGET_QIMODE_MATH
9890 && can_create_pseudo_p ()
9891 && !optimize_insn_for_size_p ()"
9893 "ix86_split_idivmod (SImode, operands, <u_bool>); DONE;")
9896 [(set (match_operand:DI 1 "register_operand")
9898 (<paired_mod>:SI (match_operand:SI 2 "register_operand")
9899 (match_operand:SI 3 "nonimmediate_operand"))))
9900 (set (match_operand:SI 0 "register_operand")
9901 (any_div:SI (match_dup 2) (match_dup 3)))
9902 (clobber (reg:CC FLAGS_REG))]
9904 && TARGET_USE_8BIT_IDIV
9905 && TARGET_QIMODE_MATH
9906 && can_create_pseudo_p ()
9907 && !optimize_insn_for_size_p ()"
9909 "ix86_split_idivmod (SImode, operands, <u_bool>); DONE;")
9911 (define_insn_and_split "divmod<mode>4_1"
9912 [(set (match_operand:SWI48 0 "register_operand" "=a")
9913 (div:SWI48 (match_operand:SWI48 2 "register_operand" "0")
9914 (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
9915 (set (match_operand:SWI48 1 "register_operand" "=&d")
9916 (mod:SWI48 (match_dup 2) (match_dup 3)))
9917 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
9918 (clobber (reg:CC FLAGS_REG))]
9922 [(parallel [(set (match_dup 1)
9923 (ashiftrt:SWI48 (match_dup 4) (match_dup 5)))
9924 (clobber (reg:CC FLAGS_REG))])
9925 (parallel [(set (match_dup 0)
9926 (div:SWI48 (match_dup 2) (match_dup 3)))
9928 (mod:SWI48 (match_dup 2) (match_dup 3)))
9930 (clobber (reg:CC FLAGS_REG))])]
9932 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
9934 if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
9935 operands[4] = operands[2];
9938 /* Avoid use of cltd in favor of a mov+shift. */
9939 emit_move_insn (operands[1], operands[2]);
9940 operands[4] = operands[1];
9943 [(set_attr "type" "multi")
9944 (set_attr "mode" "<MODE>")])
9946 (define_insn_and_split "udivmod<mode>4_1"
9947 [(set (match_operand:SWI48 0 "register_operand" "=a")
9948 (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "0")
9949 (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
9950 (set (match_operand:SWI48 1 "register_operand" "=&d")
9951 (umod:SWI48 (match_dup 2) (match_dup 3)))
9952 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
9953 (clobber (reg:CC FLAGS_REG))]
9957 [(set (match_dup 1) (const_int 0))
9958 (parallel [(set (match_dup 0)
9959 (udiv:SWI48 (match_dup 2) (match_dup 3)))
9961 (umod:SWI48 (match_dup 2) (match_dup 3)))
9963 (clobber (reg:CC FLAGS_REG))])]
9965 [(set_attr "type" "multi")
9966 (set_attr "mode" "<MODE>")])
9968 (define_insn_and_split "divmodsi4_zext_1"
9969 [(set (match_operand:DI 0 "register_operand" "=a")
9971 (div:SI (match_operand:SI 2 "register_operand" "0")
9972 (match_operand:SI 3 "nonimmediate_operand" "rm"))))
9973 (set (match_operand:SI 1 "register_operand" "=&d")
9974 (mod:SI (match_dup 2) (match_dup 3)))
9975 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
9976 (clobber (reg:CC FLAGS_REG))]
9979 "&& reload_completed"
9980 [(parallel [(set (match_dup 1)
9981 (ashiftrt:SI (match_dup 4) (match_dup 5)))
9982 (clobber (reg:CC FLAGS_REG))])
9983 (parallel [(set (match_dup 0)
9984 (zero_extend:DI (div:SI (match_dup 2) (match_dup 3))))
9986 (mod:SI (match_dup 2) (match_dup 3)))
9988 (clobber (reg:CC FLAGS_REG))])]
9990 operands[5] = GEN_INT (GET_MODE_BITSIZE (SImode)-1);
9992 if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
9993 operands[4] = operands[2];
9996 /* Avoid use of cltd in favor of a mov+shift. */
9997 emit_move_insn (operands[1], operands[2]);
9998 operands[4] = operands[1];
10001 [(set_attr "type" "multi")
10002 (set_attr "mode" "SI")])
10004 (define_insn_and_split "udivmodsi4_zext_1"
10005 [(set (match_operand:DI 0 "register_operand" "=a")
10007 (udiv:SI (match_operand:SI 2 "register_operand" "0")
10008 (match_operand:SI 3 "nonimmediate_operand" "rm"))))
10009 (set (match_operand:SI 1 "register_operand" "=&d")
10010 (umod:SI (match_dup 2) (match_dup 3)))
10011 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
10012 (clobber (reg:CC FLAGS_REG))]
10015 "&& reload_completed"
10016 [(set (match_dup 1) (const_int 0))
10017 (parallel [(set (match_dup 0)
10018 (zero_extend:DI (udiv:SI (match_dup 2) (match_dup 3))))
10020 (umod:SI (match_dup 2) (match_dup 3)))
10021 (use (match_dup 1))
10022 (clobber (reg:CC FLAGS_REG))])]
10024 [(set_attr "type" "multi")
10025 (set_attr "mode" "SI")])
10027 (define_insn_and_split "divmodsi4_zext_2"
10028 [(set (match_operand:DI 1 "register_operand" "=&d")
10030 (mod:SI (match_operand:SI 2 "register_operand" "0")
10031 (match_operand:SI 3 "nonimmediate_operand" "rm"))))
10032 (set (match_operand:SI 0 "register_operand" "=a")
10033 (div:SI (match_dup 2) (match_dup 3)))
10034 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
10035 (clobber (reg:CC FLAGS_REG))]
10038 "&& reload_completed"
10039 [(parallel [(set (match_dup 6)
10040 (ashiftrt:SI (match_dup 4) (match_dup 5)))
10041 (clobber (reg:CC FLAGS_REG))])
10042 (parallel [(set (match_dup 1)
10043 (zero_extend:DI (mod:SI (match_dup 2) (match_dup 3))))
10045 (div:SI (match_dup 2) (match_dup 3)))
10046 (use (match_dup 6))
10047 (clobber (reg:CC FLAGS_REG))])]
10049 operands[5] = GEN_INT (GET_MODE_BITSIZE (SImode)-1);
10050 operands[6] = gen_lowpart (SImode, operands[1]);
10052 if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
10053 operands[4] = operands[2];
10056 /* Avoid use of cltd in favor of a mov+shift. */
10057 emit_move_insn (operands[6], operands[2]);
10058 operands[4] = operands[6];
10061 [(set_attr "type" "multi")
10062 (set_attr "mode" "SI")])
10064 (define_insn_and_split "udivmodsi4_zext_2"
10065 [(set (match_operand:DI 1 "register_operand" "=&d")
10067 (umod:SI (match_operand:SI 2 "register_operand" "0")
10068 (match_operand:SI 3 "nonimmediate_operand" "rm"))))
10069 (set (match_operand:SI 0 "register_operand" "=a")
10070 (udiv:SI (match_dup 2) (match_dup 3)))
10071 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
10072 (clobber (reg:CC FLAGS_REG))]
10075 "&& reload_completed"
10076 [(set (match_dup 4) (const_int 0))
10077 (parallel [(set (match_dup 1)
10078 (zero_extend:DI (umod:SI (match_dup 2) (match_dup 3))))
10080 (udiv:SI (match_dup 2) (match_dup 3)))
10081 (use (match_dup 4))
10082 (clobber (reg:CC FLAGS_REG))])]
10083 "operands[4] = gen_lowpart (SImode, operands[1]);"
10084 [(set_attr "type" "multi")
10085 (set_attr "mode" "SI")])
10087 (define_insn_and_split "*divmod<mode>4"
10088 [(set (match_operand:SWIM248 0 "register_operand" "=a")
10089 (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
10090 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
10091 (set (match_operand:SWIM248 1 "register_operand" "=&d")
10092 (mod:SWIM248 (match_dup 2) (match_dup 3)))
10093 (clobber (reg:CC FLAGS_REG))]
10097 [(parallel [(set (match_dup 1)
10098 (ashiftrt:SWIM248 (match_dup 4) (match_dup 5)))
10099 (clobber (reg:CC FLAGS_REG))])
10100 (parallel [(set (match_dup 0)
10101 (div:SWIM248 (match_dup 2) (match_dup 3)))
10103 (mod:SWIM248 (match_dup 2) (match_dup 3)))
10104 (use (match_dup 1))
10105 (clobber (reg:CC FLAGS_REG))])]
10107 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
10109 if (<MODE>mode != HImode
10110 && (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD))
10111 operands[4] = operands[2];
10114 /* Avoid use of cltd in favor of a mov+shift. */
10115 emit_move_insn (operands[1], operands[2]);
10116 operands[4] = operands[1];
10119 [(set_attr "type" "multi")
10120 (set_attr "mode" "<MODE>")])
10122 (define_insn_and_split "*udivmod<mode>4"
10123 [(set (match_operand:SWIM248 0 "register_operand" "=a")
10124 (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
10125 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
10126 (set (match_operand:SWIM248 1 "register_operand" "=&d")
10127 (umod:SWIM248 (match_dup 2) (match_dup 3)))
10128 (clobber (reg:CC FLAGS_REG))]
10132 [(set (match_dup 1) (const_int 0))
10133 (parallel [(set (match_dup 0)
10134 (udiv:SWIM248 (match_dup 2) (match_dup 3)))
10136 (umod:SWIM248 (match_dup 2) (match_dup 3)))
10137 (use (match_dup 1))
10138 (clobber (reg:CC FLAGS_REG))])]
10140 [(set_attr "type" "multi")
10141 (set_attr "mode" "<MODE>")])
10143 ;; Optimize division or modulo by constant power of 2, if the constant
10144 ;; materializes only after expansion.
10145 (define_insn_and_split "*udivmod<mode>4_pow2"
10146 [(set (match_operand:SWI48 0 "register_operand" "=r")
10147 (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "0")
10148 (match_operand:SWI48 3 "const_int_operand")))
10149 (set (match_operand:SWI48 1 "register_operand" "=r")
10150 (umod:SWI48 (match_dup 2) (match_dup 3)))
10151 (clobber (reg:CC FLAGS_REG))]
10152 "IN_RANGE (exact_log2 (UINTVAL (operands[3])), 1, 31)"
10154 "&& reload_completed"
10155 [(set (match_dup 1) (match_dup 2))
10156 (parallel [(set (match_dup 0) (lshiftrt:<MODE> (match_dup 2) (match_dup 4)))
10157 (clobber (reg:CC FLAGS_REG))])
10158 (parallel [(set (match_dup 1) (and:<MODE> (match_dup 1) (match_dup 5)))
10159 (clobber (reg:CC FLAGS_REG))])]
10161 int v = exact_log2 (UINTVAL (operands[3]));
10162 operands[4] = GEN_INT (v);
10163 operands[5] = GEN_INT ((HOST_WIDE_INT_1U << v) - 1);
10165 [(set_attr "type" "multi")
10166 (set_attr "mode" "<MODE>")])
10168 (define_insn_and_split "*divmodsi4_zext_1"
10169 [(set (match_operand:DI 0 "register_operand" "=a")
10171 (div:SI (match_operand:SI 2 "register_operand" "0")
10172 (match_operand:SI 3 "nonimmediate_operand" "rm"))))
10173 (set (match_operand:SI 1 "register_operand" "=&d")
10174 (mod:SI (match_dup 2) (match_dup 3)))
10175 (clobber (reg:CC FLAGS_REG))]
10178 "&& reload_completed"
10179 [(parallel [(set (match_dup 1)
10180 (ashiftrt:SI (match_dup 4) (match_dup 5)))
10181 (clobber (reg:CC FLAGS_REG))])
10182 (parallel [(set (match_dup 0)
10183 (zero_extend:DI (div:SI (match_dup 2) (match_dup 3))))
10185 (mod:SI (match_dup 2) (match_dup 3)))
10186 (use (match_dup 1))
10187 (clobber (reg:CC FLAGS_REG))])]
10189 operands[5] = GEN_INT (GET_MODE_BITSIZE (SImode)-1);
10191 if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
10192 operands[4] = operands[2];
10195 /* Avoid use of cltd in favor of a mov+shift. */
10196 emit_move_insn (operands[1], operands[2]);
10197 operands[4] = operands[1];
10200 [(set_attr "type" "multi")
10201 (set_attr "mode" "SI")])
10203 (define_insn_and_split "*udivmodsi4_zext_1"
10204 [(set (match_operand:DI 0 "register_operand" "=a")
10206 (udiv:SI (match_operand:SI 2 "register_operand" "0")
10207 (match_operand:SI 3 "nonimmediate_operand" "rm"))))
10208 (set (match_operand:SI 1 "register_operand" "=&d")
10209 (umod:SI (match_dup 2) (match_dup 3)))
10210 (clobber (reg:CC FLAGS_REG))]
10213 "&& reload_completed"
10214 [(set (match_dup 1) (const_int 0))
10215 (parallel [(set (match_dup 0)
10216 (zero_extend:DI (udiv:SI (match_dup 2) (match_dup 3))))
10218 (umod:SI (match_dup 2) (match_dup 3)))
10219 (use (match_dup 1))
10220 (clobber (reg:CC FLAGS_REG))])]
10222 [(set_attr "type" "multi")
10223 (set_attr "mode" "SI")])
10225 (define_insn_and_split "*udivmodsi4_pow2_zext_1"
10226 [(set (match_operand:DI 0 "register_operand" "=r")
10228 (udiv:SI (match_operand:SI 2 "register_operand" "0")
10229 (match_operand:SI 3 "const_int_operand"))))
10230 (set (match_operand:SI 1 "register_operand" "=r")
10231 (umod:SI (match_dup 2) (match_dup 3)))
10232 (clobber (reg:CC FLAGS_REG))]
10234 && IN_RANGE (exact_log2 (UINTVAL (operands[3])), 1, 31)"
10236 "&& reload_completed"
10237 [(set (match_dup 1) (match_dup 2))
10238 (parallel [(set (match_dup 0)
10239 (zero_extend:DI (lshiftrt:SI (match_dup 2) (match_dup 4))))
10240 (clobber (reg:CC FLAGS_REG))])
10241 (parallel [(set (match_dup 1) (and:SI (match_dup 1) (match_dup 5)))
10242 (clobber (reg:CC FLAGS_REG))])]
10244 int v = exact_log2 (UINTVAL (operands[3]));
10245 operands[4] = GEN_INT (v);
10246 operands[5] = GEN_INT ((HOST_WIDE_INT_1U << v) - 1);
10248 [(set_attr "type" "multi")
10249 (set_attr "mode" "SI")])
10251 (define_insn_and_split "*divmodsi4_zext_2"
10252 [(set (match_operand:DI 1 "register_operand" "=&d")
10254 (mod:SI (match_operand:SI 2 "register_operand" "0")
10255 (match_operand:SI 3 "nonimmediate_operand" "rm"))))
10256 (set (match_operand:SI 0 "register_operand" "=a")
10257 (div:SI (match_dup 2) (match_dup 3)))
10258 (clobber (reg:CC FLAGS_REG))]
10261 "&& reload_completed"
10262 [(parallel [(set (match_dup 6)
10263 (ashiftrt:SI (match_dup 4) (match_dup 5)))
10264 (clobber (reg:CC FLAGS_REG))])
10265 (parallel [(set (match_dup 1)
10266 (zero_extend:DI (mod:SI (match_dup 2) (match_dup 3))))
10268 (div:SI (match_dup 2) (match_dup 3)))
10269 (use (match_dup 6))
10270 (clobber (reg:CC FLAGS_REG))])]
10272 operands[5] = GEN_INT (GET_MODE_BITSIZE (SImode)-1);
10273 operands[6] = gen_lowpart (SImode, operands[1]);
10275 if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
10276 operands[4] = operands[2];
10279 /* Avoid use of cltd in favor of a mov+shift. */
10280 emit_move_insn (operands[6], operands[2]);
10281 operands[4] = operands[6];
10284 [(set_attr "type" "multi")
10285 (set_attr "mode" "SI")])
10287 (define_insn_and_split "*udivmodsi4_zext_2"
10288 [(set (match_operand:DI 1 "register_operand" "=&d")
10290 (umod:SI (match_operand:SI 2 "register_operand" "0")
10291 (match_operand:SI 3 "nonimmediate_operand" "rm"))))
10292 (set (match_operand:SI 0 "register_operand" "=a")
10293 (udiv:SI (match_dup 2) (match_dup 3)))
10294 (clobber (reg:CC FLAGS_REG))]
10297 "&& reload_completed"
10298 [(set (match_dup 4) (const_int 0))
10299 (parallel [(set (match_dup 1)
10300 (zero_extend:DI (umod:SI (match_dup 2) (match_dup 3))))
10302 (udiv:SI (match_dup 2) (match_dup 3)))
10303 (use (match_dup 4))
10304 (clobber (reg:CC FLAGS_REG))])]
10305 "operands[4] = gen_lowpart (SImode, operands[1]);"
10306 [(set_attr "type" "multi")
10307 (set_attr "mode" "SI")])
10309 (define_insn_and_split "*udivmodsi4_pow2_zext_2"
10310 [(set (match_operand:DI 1 "register_operand" "=r")
10312 (umod:SI (match_operand:SI 2 "register_operand" "0")
10313 (match_operand:SI 3 "const_int_operand"))))
10314 (set (match_operand:SI 0 "register_operand" "=r")
10315 (udiv:SI (match_dup 2) (match_dup 3)))
10316 (clobber (reg:CC FLAGS_REG))]
10318 && IN_RANGE (exact_log2 (UINTVAL (operands[3])), 1, 31)"
10320 "&& reload_completed"
10321 [(set (match_dup 1) (match_dup 2))
10322 (parallel [(set (match_dup 0) (lshiftrt:SI (match_dup 2) (match_dup 4)))
10323 (clobber (reg:CC FLAGS_REG))])
10324 (parallel [(set (match_dup 1)
10325 (zero_extend:DI (and:SI (match_dup 1) (match_dup 5))))
10326 (clobber (reg:CC FLAGS_REG))])]
10328 int v = exact_log2 (UINTVAL (operands[3]));
10329 operands[4] = GEN_INT (v);
10330 operands[5] = GEN_INT ((HOST_WIDE_INT_1U << v) - 1);
10332 [(set_attr "type" "multi")
10333 (set_attr "mode" "SI")])
10335 (define_insn "*<u>divmod<mode>4_noext"
10336 [(set (match_operand:SWIM248 0 "register_operand" "=a")
10338 (match_operand:SWIM248 2 "register_operand" "0")
10339 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
10340 (set (match_operand:SWIM248 1 "register_operand" "=d")
10341 (<paired_mod>:SWIM248 (match_dup 2) (match_dup 3)))
10342 (use (match_operand:SWIM248 4 "register_operand" "1"))
10343 (clobber (reg:CC FLAGS_REG))]
10345 "<sgnprefix>div{<imodesuffix>}\t%3"
10346 [(set_attr "type" "idiv")
10347 (set_attr "mode" "<MODE>")])
10349 (define_insn "*<u>divmodsi4_noext_zext_1"
10350 [(set (match_operand:DI 0 "register_operand" "=a")
10352 (any_div:SI (match_operand:SI 2 "register_operand" "0")
10353 (match_operand:SI 3 "nonimmediate_operand" "rm"))))
10354 (set (match_operand:SI 1 "register_operand" "=d")
10355 (<paired_mod>:SI (match_dup 2) (match_dup 3)))
10356 (use (match_operand:SI 4 "register_operand" "1"))
10357 (clobber (reg:CC FLAGS_REG))]
10359 "<sgnprefix>div{l}\t%3"
10360 [(set_attr "type" "idiv")
10361 (set_attr "mode" "SI")])
10363 (define_insn "*<u>divmodsi4_noext_zext_2"
10364 [(set (match_operand:DI 1 "register_operand" "=d")
10366 (<paired_mod>:SI (match_operand:SI 2 "register_operand" "0")
10367 (match_operand:SI 3 "nonimmediate_operand" "rm"))))
10368 (set (match_operand:SI 0 "register_operand" "=a")
10369 (any_div:SI (match_dup 2) (match_dup 3)))
10370 (use (match_operand:SI 4 "register_operand" "1"))
10371 (clobber (reg:CC FLAGS_REG))]
10373 "<sgnprefix>div{l}\t%3"
10374 [(set_attr "type" "idiv")
10375 (set_attr "mode" "SI")])
10377 ;; Avoid sign-extension (using cdq) for constant numerators.
10378 (define_insn_and_split "*divmodsi4_const"
10379 [(set (match_operand:SI 0 "register_operand" "=&a")
10380 (div:SI (match_operand:SI 2 "const_int_operand")
10381 (match_operand:SI 3 "nonimmediate_operand" "rm")))
10382 (set (match_operand:SI 1 "register_operand" "=&d")
10383 (mod:SI (match_dup 2) (match_dup 3)))
10384 (clobber (reg:CC FLAGS_REG))]
10385 "!optimize_function_for_size_p (cfun)"
10387 "&& reload_completed"
10388 [(set (match_dup 0) (match_dup 2))
10389 (set (match_dup 1) (match_dup 4))
10390 (parallel [(set (match_dup 0)
10391 (div:SI (match_dup 0) (match_dup 3)))
10393 (mod:SI (match_dup 0) (match_dup 3)))
10394 (use (match_dup 1))
10395 (clobber (reg:CC FLAGS_REG))])]
10397 operands[4] = INTVAL (operands[2]) < 0 ? constm1_rtx : const0_rtx;
10399 [(set_attr "type" "multi")
10400 (set_attr "mode" "SI")])
10402 (define_expand "divmodqi4"
10403 [(parallel [(set (match_operand:QI 0 "register_operand")
10405 (match_operand:QI 1 "register_operand")
10406 (match_operand:QI 2 "nonimmediate_operand")))
10407 (set (match_operand:QI 3 "register_operand")
10408 (mod:QI (match_dup 1) (match_dup 2)))
10409 (clobber (reg:CC FLAGS_REG))])]
10410 "TARGET_QIMODE_MATH"
10415 tmp0 = gen_reg_rtx (HImode);
10416 tmp1 = gen_reg_rtx (HImode);
10418 /* Extend operands[1] to HImode. Generate 8bit divide. Result is in AX. */
10419 emit_insn (gen_extendqihi2 (tmp1, operands[1]));
10420 emit_insn (gen_divmodhiqi3 (tmp0, tmp1, operands[2]));
10422 /* Extract remainder from AH. */
10423 tmp1 = gen_rtx_ZERO_EXTRACT (HImode, tmp0, GEN_INT (8), GEN_INT (8));
10424 tmp1 = lowpart_subreg (QImode, tmp1, HImode);
10425 rtx_insn *insn = emit_move_insn (operands[3], tmp1);
10427 mod = gen_rtx_MOD (QImode, operands[1], operands[2]);
10428 set_unique_reg_note (insn, REG_EQUAL, mod);
10430 /* Extract quotient from AL. */
10431 insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
10433 div = gen_rtx_DIV (QImode, operands[1], operands[2]);
10434 set_unique_reg_note (insn, REG_EQUAL, div);
10439 (define_expand "udivmodqi4"
10440 [(parallel [(set (match_operand:QI 0 "register_operand")
10442 (match_operand:QI 1 "register_operand")
10443 (match_operand:QI 2 "nonimmediate_operand")))
10444 (set (match_operand:QI 3 "register_operand")
10445 (umod:QI (match_dup 1) (match_dup 2)))
10446 (clobber (reg:CC FLAGS_REG))])]
10447 "TARGET_QIMODE_MATH"
10452 tmp0 = gen_reg_rtx (HImode);
10453 tmp1 = gen_reg_rtx (HImode);
10455 /* Extend operands[1] to HImode. Generate 8bit divide. Result is in AX. */
10456 emit_insn (gen_zero_extendqihi2 (tmp1, operands[1]));
10457 emit_insn (gen_udivmodhiqi3 (tmp0, tmp1, operands[2]));
10459 /* Extract remainder from AH. */
10460 tmp1 = gen_rtx_ZERO_EXTRACT (HImode, tmp0, GEN_INT (8), GEN_INT (8));
10461 tmp1 = lowpart_subreg (QImode, tmp1, HImode);
10462 rtx_insn *insn = emit_move_insn (operands[3], tmp1);
10464 mod = gen_rtx_UMOD (QImode, operands[1], operands[2]);
10465 set_unique_reg_note (insn, REG_EQUAL, mod);
10467 /* Extract quotient from AL. */
10468 insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
10470 div = gen_rtx_UDIV (QImode, operands[1], operands[2]);
10471 set_unique_reg_note (insn, REG_EQUAL, div);
10476 ;; Divide AX by r/m8, with result stored in
10479 ;; Change div/mod to HImode and extend the second argument to HImode
10480 ;; so that mode of div/mod matches with mode of arguments. Otherwise
10481 ;; combine may fail.
10482 (define_insn "<u>divmodhiqi3"
10483 [(set (match_operand:HI 0 "register_operand" "=a")
10488 (mod:HI (match_operand:HI 1 "register_operand" "0")
10490 (match_operand:QI 2 "nonimmediate_operand" "qm")))))
10494 (div:HI (match_dup 1) (any_extend:HI (match_dup 2)))))))
10495 (clobber (reg:CC FLAGS_REG))]
10496 "TARGET_QIMODE_MATH"
10497 "<sgnprefix>div{b}\t%2"
10498 [(set_attr "type" "idiv")
10499 (set_attr "mode" "QI")])
10501 ;; We cannot use div/idiv for double division, because it causes
10502 ;; "division by zero" on the overflow and that's not what we expect
10503 ;; from truncate. Because true (non truncating) double division is
10504 ;; never generated, we can't create this insn anyway.
10507 ; [(set (match_operand:SI 0 "register_operand" "=a")
10509 ; (udiv:DI (match_operand:DI 1 "register_operand" "A")
10511 ; (match_operand:SI 2 "nonimmediate_operand" "rm")))))
10512 ; (set (match_operand:SI 3 "register_operand" "=d")
10514 ; (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
10515 ; (clobber (reg:CC FLAGS_REG))]
10517 ; "div{l}\t{%2, %0|%0, %2}"
10518 ; [(set_attr "type" "idiv")])
10520 ;;- Logical AND instructions
10522 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
10523 ;; Note that this excludes ah.
10525 (define_expand "@test<mode>_ccno_1"
10526 [(set (reg:CCNO FLAGS_REG)
10529 (match_operand:SWI48 0 "nonimmediate_operand")
10530 (match_operand:SWI48 1 "<nonmemory_szext_operand>"))
10533 (define_expand "testqi_ccz_1"
10534 [(set (reg:CCZ FLAGS_REG)
10537 (match_operand:QI 0 "nonimmediate_operand")
10538 (match_operand:QI 1 "nonmemory_operand"))
10541 (define_insn "*testdi_1"
10542 [(set (reg FLAGS_REG)
10545 (match_operand:DI 0 "nonimmediate_operand" "%r,rm")
10546 (match_operand:DI 1 "x86_64_szext_nonmemory_operand" "Z,re"))
10549 && ix86_match_ccmode
10551 /* If we are going to emit testl instead of testq, and the operands[1]
10552 constant might have the SImode sign bit set, make sure the sign
10553 flag isn't tested, because the instruction will set the sign flag
10554 based on bit 31 rather than bit 63. If it isn't CONST_INT,
10555 conservatively assume it might have bit 31 set. */
10556 (satisfies_constraint_Z (operands[1])
10557 && (!CONST_INT_P (operands[1])
10558 || val_signbit_known_set_p (SImode, INTVAL (operands[1]))))
10559 ? CCZmode : CCNOmode)"
10561 test{l}\t{%k1, %k0|%k0, %k1}
10562 test{q}\t{%1, %0|%0, %1}"
10563 [(set_attr "type" "test")
10564 (set_attr "mode" "SI,DI")])
10566 (define_insn "*testqi_1_maybe_si"
10567 [(set (reg FLAGS_REG)
10570 (match_operand:QI 0 "nonimmediate_operand" "%qm,qm,r")
10571 (match_operand:QI 1 "nonmemory_operand" "q,n,n"))
10573 "ix86_match_ccmode (insn,
10574 CONST_INT_P (operands[1])
10575 && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
10577 if (get_attr_mode (insn) == MODE_SI)
10579 if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
10580 operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
10581 return "test{l}\t{%1, %k0|%k0, %1}";
10583 return "test{b}\t{%1, %0|%0, %1}";
10585 [(set_attr "type" "test")
10587 (cond [(eq_attr "alternative" "2")
10588 (const_string "SI")
10589 (and (match_test "optimize_insn_for_size_p ()")
10590 (and (match_operand 0 "ext_QIreg_operand")
10591 (match_operand 1 "const_0_to_127_operand")))
10592 (const_string "SI")
10594 (const_string "QI")))
10595 (set_attr "pent_pair" "uv,np,np")])
10597 (define_insn "*test<mode>_1"
10598 [(set (reg FLAGS_REG)
10601 (match_operand:SWI124 0 "nonimmediate_operand" "%<r>m,*a,<r>m")
10602 (match_operand:SWI124 1 "<nonmemory_szext_operand>" "<r>,<i>,<i>"))
10604 "ix86_match_ccmode (insn, CCNOmode)"
10605 "test{<imodesuffix>}\t{%1, %0|%0, %1}"
10606 [(set_attr "type" "test")
10607 (set_attr "mode" "<MODE>")
10608 (set_attr "pent_pair" "uv,uv,np")])
10610 (define_expand "testqi_ext_1_ccno"
10611 [(set (reg:CCNO FLAGS_REG)
10616 (match_operand:HI 0 "register_operand")
10619 (match_operand:QI 1 "const_int_operand"))
10622 (define_insn "*testqi_ext<mode>_1"
10623 [(set (reg FLAGS_REG)
10627 (match_operator:SWI248 2 "extract_operator"
10628 [(match_operand 0 "int248_register_operand" "Q,Q")
10631 (match_operand:QI 1 "general_x64constmem_operand" "QnBc,m"))
10633 "ix86_match_ccmode (insn, CCNOmode)"
10634 "test{b}\t{%1, %h0|%h0, %1}"
10635 [(set_attr "isa" "*,nox64")
10636 (set_attr "type" "test")
10637 (set_attr "mode" "QI")])
10639 (define_insn "*testqi_ext<mode>_2"
10640 [(set (reg FLAGS_REG)
10644 (match_operator:SWI248 2 "extract_operator"
10645 [(match_operand 0 "int248_register_operand" "Q")
10649 (match_operator:SWI248 3 "extract_operator"
10650 [(match_operand 1 "int248_register_operand" "Q")
10652 (const_int 8)]) 0))
10654 "ix86_match_ccmode (insn, CCNOmode)"
10655 "test{b}\t{%h1, %h0|%h0, %h1}"
10656 [(set_attr "type" "test")
10657 (set_attr "mode" "QI")])
10659 ;; Provide a *testti instruction that STV can implement using ptest.
10660 ;; This pattern splits into *andti3_doubleword and *cmpti_doubleword.
10661 (define_insn_and_split "*testti_doubleword"
10662 [(set (reg:CCZ FLAGS_REG)
10664 (and:TI (match_operand:TI 0 "register_operand")
10665 (match_operand:TI 1 "general_operand"))
10668 && ix86_pre_reload_split ()"
10671 [(parallel [(set (match_dup 2) (and:TI (match_dup 0) (match_dup 1)))
10672 (clobber (reg:CC FLAGS_REG))])
10673 (set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 2) (const_int 0)))]
10675 operands[2] = gen_reg_rtx (TImode);
10676 if (!x86_64_hilo_general_operand (operands[1], TImode))
10677 operands[1] = force_reg (TImode, operands[1]);
10680 ;; Combine likes to form bit extractions for some tests. Humor it.
10681 (define_insn_and_split "*testqi_ext_3"
10682 [(set (match_operand 0 "flags_reg_operand")
10683 (match_operator 1 "compare_operator"
10684 [(zero_extract:SWI248
10685 (match_operand 2 "int_nonimmediate_operand" "rm")
10686 (match_operand 3 "const_int_operand")
10687 (match_operand 4 "const_int_operand"))
10689 "/* Ensure that resulting mask is zero or sign extended operand. */
10690 INTVAL (operands[4]) >= 0
10691 && ((INTVAL (operands[3]) > 0
10692 && INTVAL (operands[3]) + INTVAL (operands[4]) <= 32)
10693 || (<MODE>mode == DImode
10694 && INTVAL (operands[3]) > 32
10695 && INTVAL (operands[3]) + INTVAL (operands[4]) == 64))
10696 && ix86_match_ccmode (insn,
10697 /* If zero_extract mode precision is the same
10698 as len, the SF of the zero_extract
10699 comparison will be the most significant
10700 extracted bit, but this could be matched
10701 after splitting only for pos 0 len all bits
10702 trivial extractions. Require CCZmode. */
10703 (GET_MODE_PRECISION (<MODE>mode)
10704 == INTVAL (operands[3]))
10705 /* Otherwise, require CCZmode if we'd use a mask
10706 with the most significant bit set and can't
10707 widen it to wider mode. *testdi_1 also
10708 requires CCZmode if the mask has bit
10709 31 set and all bits above it clear. */
10710 || (INTVAL (operands[3]) + INTVAL (operands[4])
10712 /* We can't widen also if val is not a REG. */
10713 || (INTVAL (operands[3]) + INTVAL (operands[4])
10714 == GET_MODE_PRECISION (GET_MODE (operands[2]))
10715 && !register_operand (operands[2],
10716 GET_MODE (operands[2])))
10717 /* And we shouldn't widen if
10718 TARGET_PARTIAL_REG_STALL. */
10719 || (TARGET_PARTIAL_REG_STALL
10720 && (INTVAL (operands[3]) + INTVAL (operands[4])
10721 >= (paradoxical_subreg_p (operands[2])
10723 (GET_MODE (SUBREG_REG (operands[2])))
10725 ? GET_MODE_PRECISION
10726 (GET_MODE (SUBREG_REG (operands[2])))
10727 : GET_MODE_PRECISION
10728 (GET_MODE (operands[2])))))
10729 ? CCZmode : CCNOmode)"
10732 [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
10734 rtx val = operands[2];
10735 HOST_WIDE_INT len = INTVAL (operands[3]);
10736 HOST_WIDE_INT pos = INTVAL (operands[4]);
10737 machine_mode mode = GET_MODE (val);
10739 if (SUBREG_P (val))
10741 machine_mode submode = GET_MODE (SUBREG_REG (val));
10743 /* Narrow paradoxical subregs to prevent partial register stalls. */
10744 if (GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode)
10745 && GET_MODE_CLASS (submode) == MODE_INT
10746 && (GET_MODE (operands[0]) == CCZmode
10747 || pos + len < GET_MODE_PRECISION (submode)
10748 || REG_P (SUBREG_REG (val))))
10750 val = SUBREG_REG (val);
10755 /* Small HImode tests can be converted to QImode. */
10757 && register_operand (val, HImode))
10759 rtx nval = gen_lowpart (QImode, val);
10761 || GET_MODE (operands[0]) == CCZmode
10769 gcc_assert (pos + len <= GET_MODE_PRECISION (mode));
10771 /* If the mask is going to have the sign bit set in the mode
10772 we want to do the comparison in and user isn't interested just
10773 in the zero flag, then we must widen the target mode. */
10774 if (pos + len == GET_MODE_PRECISION (mode)
10775 && GET_MODE (operands[0]) != CCZmode)
10777 gcc_assert (pos + len < 32 && !MEM_P (val));
10779 val = gen_lowpart (mode, val);
10783 = wi::shifted_mask (pos, len, false, GET_MODE_PRECISION (mode));
10785 operands[2] = gen_rtx_AND (mode, val, immed_wide_int_const (mask, mode));
10788 ;; Split and;cmp (as optimized by combine) into not;test
10789 ;; Except when TARGET_BMI provides andn (*andn_<mode>_ccno).
10790 (define_insn_and_split "*test<mode>_not"
10791 [(set (reg:CCZ FLAGS_REG)
10794 (not:SWI (match_operand:SWI 0 "register_operand"))
10795 (match_operand:SWI 1 "<nonmemory_szext_operand>"))
10797 "ix86_pre_reload_split ()
10798 && (!TARGET_BMI || !REG_P (operands[1]))"
10801 [(set (match_dup 2) (not:SWI (match_dup 0)))
10802 (set (reg:CCZ FLAGS_REG)
10803 (compare:CCZ (and:SWI (match_dup 2) (match_dup 1))
10805 "operands[2] = gen_reg_rtx (<MODE>mode);")
10807 ;; Split and;cmp (as optimized by combine) into andn;cmp $0
10808 (define_insn_and_split "*test<mode>_not_doubleword"
10809 [(set (reg:CCZ FLAGS_REG)
10812 (not:DWI (match_operand:DWI 0 "nonimmediate_operand"))
10813 (match_operand:DWI 1 "nonimmediate_operand"))
10815 "ix86_pre_reload_split ()"
10819 [(set (match_dup 2) (and:DWI (not:DWI (match_dup 0)) (match_dup 1)))
10820 (clobber (reg:CC FLAGS_REG))])
10821 (set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 2) (const_int 0)))]
10823 operands[0] = force_reg (<MODE>mode, operands[0]);
10824 operands[2] = gen_reg_rtx (<MODE>mode);
10827 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
10828 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
10829 ;; this is relatively important trick.
10830 ;; Do the conversion only post-reload to avoid limiting of the register class
10833 [(set (match_operand 0 "flags_reg_operand")
10834 (match_operator 1 "compare_operator"
10835 [(and (match_operand 2 "QIreg_operand")
10836 (match_operand 3 "const_int_operand"))
10839 && GET_MODE (operands[2]) != QImode
10840 && ((ix86_match_ccmode (insn, CCZmode)
10841 && !(INTVAL (operands[3]) & ~(255 << 8)))
10842 || (ix86_match_ccmode (insn, CCNOmode)
10843 && !(INTVAL (operands[3]) & ~(127 << 8))))"
10844 [(set (match_dup 0)
10848 (zero_extract:HI (match_dup 2)
10854 operands[2] = gen_lowpart (HImode, operands[2]);
10855 operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, QImode);
10859 [(set (match_operand 0 "flags_reg_operand")
10860 (match_operator 1 "compare_operator"
10861 [(and (match_operand 2 "nonimmediate_operand")
10862 (match_operand 3 "const_int_operand"))
10865 && GET_MODE (operands[2]) != QImode
10866 && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
10867 && ((ix86_match_ccmode (insn, CCZmode)
10868 && !(INTVAL (operands[3]) & ~255))
10869 || (ix86_match_ccmode (insn, CCNOmode)
10870 && !(INTVAL (operands[3]) & ~127)))"
10871 [(set (match_dup 0)
10872 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
10875 operands[2] = gen_lowpart (QImode, operands[2]);
10876 operands[3] = gen_int_mode (INTVAL (operands[3]), QImode);
10879 ;; %%% This used to optimize known byte-wide and operations to memory,
10880 ;; and sometimes to QImode registers. If this is considered useful,
10881 ;; it should be done with splitters.
10883 (define_expand "and<mode>3"
10884 [(set (match_operand:SDWIM 0 "nonimmediate_operand")
10885 (and:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")
10886 (match_operand:SDWIM 2 "<general_szext_operand>")))]
10889 machine_mode mode = <MODE>mode;
10891 if (GET_MODE_SIZE (<MODE>mode) > UNITS_PER_WORD
10892 && !x86_64_hilo_general_operand (operands[2], <MODE>mode))
10893 operands[2] = force_reg (<MODE>mode, operands[2]);
10895 if (GET_MODE_SIZE (<MODE>mode) <= UNITS_PER_WORD
10896 && const_int_operand (operands[2], <MODE>mode)
10897 && register_operand (operands[0], <MODE>mode)
10898 && !(TARGET_ZERO_EXTEND_WITH_AND
10899 && optimize_function_for_speed_p (cfun)))
10901 unsigned HOST_WIDE_INT ival = UINTVAL (operands[2]);
10903 if (ival == GET_MODE_MASK (SImode))
10905 else if (ival == GET_MODE_MASK (HImode))
10907 else if (ival == GET_MODE_MASK (QImode))
10911 if (mode != <MODE>mode)
10912 emit_insn (gen_extend_insn
10913 (operands[0], gen_lowpart (mode, operands[1]),
10914 <MODE>mode, mode, 1));
10916 ix86_expand_binary_operator (AND, <MODE>mode, operands);
10921 (define_insn_and_split "*and<dwi>3_doubleword"
10922 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro,r")
10924 (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0")
10925 (match_operand:<DWI> 2 "x86_64_hilo_general_operand" "r<di>,o")))
10926 (clobber (reg:CC FLAGS_REG))]
10927 "ix86_binary_operator_ok (AND, <DWI>mode, operands)"
10929 "&& reload_completed"
10930 [(const_int:DWIH 0)]
10932 bool emit_insn_deleted_note_p = false;
10934 split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
10936 if (operands[2] == const0_rtx)
10937 emit_move_insn (operands[0], const0_rtx);
10938 else if (operands[2] == constm1_rtx)
10939 emit_insn_deleted_note_p = true;
10941 ix86_expand_binary_operator (AND, <MODE>mode, &operands[0]);
10943 if (operands[5] == const0_rtx)
10944 emit_move_insn (operands[3], const0_rtx);
10945 else if (operands[5] == constm1_rtx)
10947 if (emit_insn_deleted_note_p)
10948 emit_note (NOTE_INSN_DELETED);
10951 ix86_expand_binary_operator (AND, <MODE>mode, &operands[3]);
10956 (define_insn "*anddi_1"
10957 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r,?k")
10959 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm,k")
10960 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,m,L,k")))
10961 (clobber (reg:CC FLAGS_REG))]
10962 "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
10964 and{l}\t{%k2, %k0|%k0, %k2}
10965 and{q}\t{%2, %0|%0, %2}
10966 and{q}\t{%2, %0|%0, %2}
10969 [(set_attr "isa" "x64,x64,x64,x64,avx512bw")
10970 (set_attr "type" "alu,alu,alu,imovx,msklog")
10971 (set_attr "length_immediate" "*,*,*,0,*")
10972 (set (attr "prefix_rex")
10974 (and (eq_attr "type" "imovx")
10975 (and (match_test "INTVAL (operands[2]) == 0xff")
10976 (match_operand 1 "ext_QIreg_operand")))
10978 (const_string "*")))
10979 (set_attr "mode" "SI,DI,DI,SI,DI")])
10981 (define_insn_and_split "*anddi_1_btr"
10982 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10984 (match_operand:DI 1 "nonimmediate_operand" "%0")
10985 (match_operand:DI 2 "const_int_operand" "n")))
10986 (clobber (reg:CC FLAGS_REG))]
10987 "TARGET_64BIT && TARGET_USE_BT
10988 && ix86_binary_operator_ok (AND, DImode, operands)
10989 && IN_RANGE (exact_log2 (~INTVAL (operands[2])), 31, 63)"
10991 "&& reload_completed"
10992 [(parallel [(set (zero_extract:DI (match_dup 0)
10996 (clobber (reg:CC FLAGS_REG))])]
10997 "operands[3] = GEN_INT (exact_log2 (~INTVAL (operands[2])));"
10998 [(set_attr "type" "alu1")
10999 (set_attr "prefix_0f" "1")
11000 (set_attr "znver1_decode" "double")
11001 (set_attr "mode" "DI")])
11003 ;; Turn *anddi_1 into *andsi_1_zext if possible.
11005 [(set (match_operand:DI 0 "register_operand")
11006 (and:DI (subreg:DI (match_operand:SI 1 "register_operand") 0)
11007 (match_operand:DI 2 "x86_64_zext_immediate_operand")))
11008 (clobber (reg:CC FLAGS_REG))]
11010 [(parallel [(set (match_dup 0)
11011 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))
11012 (clobber (reg:CC FLAGS_REG))])]
11014 if (GET_CODE (operands[2]) == SYMBOL_REF
11015 || GET_CODE (operands[2]) == LABEL_REF)
11017 operands[2] = shallow_copy_rtx (operands[2]);
11018 PUT_MODE (operands[2], SImode);
11020 else if (GET_CODE (operands[2]) == CONST)
11022 /* (const:DI (plus:DI (symbol_ref:DI ("...")) (const_int N))) */
11023 operands[2] = copy_rtx (operands[2]);
11024 PUT_MODE (operands[2], SImode);
11025 PUT_MODE (XEXP (operands[2], 0), SImode);
11026 PUT_MODE (XEXP (XEXP (operands[2], 0), 0), SImode);
11029 operands[2] = gen_lowpart (SImode, operands[2]);
11032 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
11033 (define_insn "*andsi_1_zext"
11034 [(set (match_operand:DI 0 "register_operand" "=r")
11036 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
11037 (match_operand:SI 2 "x86_64_general_operand" "rBMe"))))
11038 (clobber (reg:CC FLAGS_REG))]
11039 "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
11040 "and{l}\t{%2, %k0|%k0, %2}"
11041 [(set_attr "type" "alu")
11042 (set_attr "mode" "SI")])
11044 (define_insn "*and<mode>_1"
11045 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=rm,r,Ya,?k")
11046 (and:SWI24 (match_operand:SWI24 1 "nonimmediate_operand" "%0,0,qm,k")
11047 (match_operand:SWI24 2 "<general_operand>" "r<i>,<m>,L,k")))
11048 (clobber (reg:CC FLAGS_REG))]
11049 "ix86_binary_operator_ok (AND, <MODE>mode, operands)"
11051 and{<imodesuffix>}\t{%2, %0|%0, %2}
11052 and{<imodesuffix>}\t{%2, %0|%0, %2}
11056 (cond [(eq_attr "alternative" "3")
11057 (if_then_else (eq_attr "mode" "SI")
11058 (const_string "avx512bw")
11059 (const_string "avx512f"))
11061 (const_string "*")))
11062 (set_attr "type" "alu,alu,imovx,msklog")
11063 (set_attr "length_immediate" "*,*,0,*")
11064 (set (attr "prefix_rex")
11066 (and (eq_attr "type" "imovx")
11067 (and (match_test "INTVAL (operands[2]) == 0xff")
11068 (match_operand 1 "ext_QIreg_operand")))
11070 (const_string "*")))
11071 (set_attr "mode" "<MODE>,<MODE>,SI,<MODE>")])
11073 (define_insn "*andqi_1"
11074 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,?k")
11075 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,k")
11076 (match_operand:QI 2 "general_operand" "qn,m,rn,k")))
11077 (clobber (reg:CC FLAGS_REG))]
11078 "ix86_binary_operator_ok (AND, QImode, operands)"
11080 and{b}\t{%2, %0|%0, %2}
11081 and{b}\t{%2, %0|%0, %2}
11082 and{l}\t{%k2, %k0|%k0, %k2}
11084 [(set_attr "type" "alu,alu,alu,msklog")
11086 (cond [(eq_attr "alternative" "2")
11087 (const_string "SI")
11088 (and (eq_attr "alternative" "3")
11089 (match_test "!TARGET_AVX512DQ"))
11090 (const_string "HI")
11092 (const_string "QI")))
11093 ;; Potential partial reg stall on alternative 2.
11094 (set (attr "preferred_for_speed")
11095 (cond [(eq_attr "alternative" "2")
11096 (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
11097 (symbol_ref "true")))])
11099 ;; Alternative 1 is needed to work around LRA limitation, see PR82524.
11100 (define_insn_and_split "*and<mode>_1_slp"
11101 [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>,&<r>"))
11102 (and:SWI12 (match_operand:SWI12 1 "nonimmediate_operand" "%0,!<r>")
11103 (match_operand:SWI12 2 "general_operand" "<r>mn,<r>mn")))
11104 (clobber (reg:CC FLAGS_REG))]
11105 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
11107 and{<imodesuffix>}\t{%2, %0|%0, %2}
11109 "&& reload_completed"
11110 [(set (strict_low_part (match_dup 0)) (match_dup 1))
11112 [(set (strict_low_part (match_dup 0))
11113 (and:SWI12 (match_dup 0) (match_dup 2)))
11114 (clobber (reg:CC FLAGS_REG))])]
11116 [(set_attr "type" "alu")
11117 (set_attr "mode" "<MODE>")])
11120 [(set (match_operand:SWI248 0 "register_operand")
11121 (and:SWI248 (match_operand:SWI248 1 "nonimmediate_operand")
11122 (match_operand:SWI248 2 "const_int_operand")))
11123 (clobber (reg:CC FLAGS_REG))]
11125 && (!REG_P (operands[1])
11126 || REGNO (operands[0]) != REGNO (operands[1]))"
11129 unsigned HOST_WIDE_INT ival = UINTVAL (operands[2]);
11132 if (ival == GET_MODE_MASK (SImode))
11134 else if (ival == GET_MODE_MASK (HImode))
11136 else if (ival == GET_MODE_MASK (QImode))
11139 gcc_unreachable ();
11141 /* Zero extend to SImode to avoid partial register stalls. */
11142 if (<MODE_SIZE> < GET_MODE_SIZE (SImode))
11143 operands[0] = gen_lowpart (SImode, operands[0]);
11145 emit_insn (gen_extend_insn
11146 (operands[0], gen_lowpart (mode, operands[1]),
11147 GET_MODE (operands[0]), mode, 1));
11152 [(set (match_operand:SWI48 0 "register_operand")
11153 (and:SWI48 (match_dup 0)
11154 (const_int -65536)))
11155 (clobber (reg:CC FLAGS_REG))]
11156 "(TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)
11157 || optimize_function_for_size_p (cfun)"
11158 [(set (strict_low_part (match_dup 1)) (const_int 0))]
11159 "operands[1] = gen_lowpart (HImode, operands[0]);")
11162 [(set (match_operand:SWI248 0 "any_QIreg_operand")
11163 (and:SWI248 (match_dup 0)
11165 (clobber (reg:CC FLAGS_REG))]
11166 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
11167 && reload_completed"
11168 [(set (strict_low_part (match_dup 1)) (const_int 0))]
11169 "operands[1] = gen_lowpart (QImode, operands[0]);")
11172 [(set (match_operand:SWI248 0 "QIreg_operand")
11173 (and:SWI248 (match_dup 0)
11174 (const_int -65281)))
11175 (clobber (reg:CC FLAGS_REG))]
11176 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
11177 && reload_completed"
11179 [(set (zero_extract:HI (match_dup 0)
11185 (zero_extract:HI (match_dup 0)
11189 (zero_extract:HI (match_dup 0)
11191 (const_int 8)) 0)) 0))
11192 (clobber (reg:CC FLAGS_REG))])]
11193 "operands[0] = gen_lowpart (HImode, operands[0]);")
11195 (define_insn "*anddi_2"
11196 [(set (reg FLAGS_REG)
11199 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
11200 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,m"))
11202 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r")
11203 (and:DI (match_dup 1) (match_dup 2)))]
11205 && ix86_match_ccmode
11207 /* If we are going to emit andl instead of andq, and the operands[2]
11208 constant might have the SImode sign bit set, make sure the sign
11209 flag isn't tested, because the instruction will set the sign flag
11210 based on bit 31 rather than bit 63. If it isn't CONST_INT,
11211 conservatively assume it might have bit 31 set. */
11212 (satisfies_constraint_Z (operands[2])
11213 && (!CONST_INT_P (operands[2])
11214 || val_signbit_known_set_p (SImode, INTVAL (operands[2]))))
11215 ? CCZmode : CCNOmode)
11216 && ix86_binary_operator_ok (AND, DImode, operands)"
11218 and{l}\t{%k2, %k0|%k0, %k2}
11219 and{q}\t{%2, %0|%0, %2}
11220 and{q}\t{%2, %0|%0, %2}"
11221 [(set_attr "type" "alu")
11222 (set_attr "mode" "SI,DI,DI")])
11224 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
11225 (define_insn "*andsi_2_zext"
11226 [(set (reg FLAGS_REG)
11228 (match_operand:SI 1 "nonimmediate_operand" "%0")
11229 (match_operand:SI 2 "x86_64_general_operand" "rBMe"))
11231 (set (match_operand:DI 0 "register_operand" "=r")
11232 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
11233 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
11234 && ix86_binary_operator_ok (AND, SImode, operands)"
11235 "and{l}\t{%2, %k0|%k0, %2}"
11236 [(set_attr "type" "alu")
11237 (set_attr "mode" "SI")])
11239 (define_insn "*andqi_2_maybe_si"
11240 [(set (reg FLAGS_REG)
11242 (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
11243 (match_operand:QI 2 "general_operand" "qn,m,n"))
11245 (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
11246 (and:QI (match_dup 1) (match_dup 2)))]
11247 "ix86_binary_operator_ok (AND, QImode, operands)
11248 && ix86_match_ccmode (insn,
11249 CONST_INT_P (operands[2])
11250 && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
11252 if (get_attr_mode (insn) == MODE_SI)
11254 if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
11255 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
11256 return "and{l}\t{%2, %k0|%k0, %2}";
11258 return "and{b}\t{%2, %0|%0, %2}";
11260 [(set_attr "type" "alu")
11262 (cond [(eq_attr "alternative" "2")
11263 (const_string "SI")
11264 (and (match_test "optimize_insn_for_size_p ()")
11265 (and (match_operand 0 "ext_QIreg_operand")
11266 (match_operand 2 "const_0_to_127_operand")))
11267 (const_string "SI")
11269 (const_string "QI")))
11270 ;; Potential partial reg stall on alternative 2.
11271 (set (attr "preferred_for_speed")
11272 (cond [(eq_attr "alternative" "2")
11273 (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
11274 (symbol_ref "true")))])
11276 (define_insn "*and<mode>_2"
11277 [(set (reg FLAGS_REG)
11278 (compare (and:SWI124
11279 (match_operand:SWI124 1 "nonimmediate_operand" "%0,0")
11280 (match_operand:SWI124 2 "<general_operand>" "<r><i>,<m>"))
11282 (set (match_operand:SWI124 0 "nonimmediate_operand" "=<r>m,<r>")
11283 (and:SWI124 (match_dup 1) (match_dup 2)))]
11284 "ix86_match_ccmode (insn, CCNOmode)
11285 && ix86_binary_operator_ok (AND, <MODE>mode, operands)"
11286 "and{<imodesuffix>}\t{%2, %0|%0, %2}"
11287 [(set_attr "type" "alu")
11288 (set_attr "mode" "<MODE>")])
11290 (define_insn "*andqi_ext<mode>_0"
11291 [(set (match_operand:QI 0 "nonimm_x64constmem_operand" "=QBc,m")
11294 (match_operator:SWI248 3 "extract_operator"
11295 [(match_operand 2 "int248_register_operand" "Q,Q")
11298 (match_operand:QI 1 "nonimm_x64constmem_operand" "0,0")))
11299 (clobber (reg:CC FLAGS_REG))]
11301 "and{b}\t{%h2, %0|%0, %h2}"
11302 [(set_attr "isa" "*,nox64")
11303 (set_attr "type" "alu")
11304 (set_attr "mode" "QI")])
11306 (define_expand "andqi_ext_1"
11308 [(set (zero_extract:HI (match_operand:HI 0 "register_operand")
11314 (zero_extract:HI (match_operand:HI 1 "register_operand")
11317 (match_operand:QI 2 "const_int_operand")) 0))
11318 (clobber (reg:CC FLAGS_REG))])])
11320 (define_insn "*andqi_ext<mode>_1"
11321 [(set (zero_extract:SWI248
11322 (match_operand 0 "int248_register_operand" "+Q,Q")
11328 (match_operator:SWI248 3 "extract_operator"
11329 [(match_operand 1 "int248_register_operand" "0,0")
11332 (match_operand:QI 2 "general_x64constmem_operand" "QnBc,m")) 0))
11333 (clobber (reg:CC FLAGS_REG))]
11334 "/* FIXME: without this LRA can't reload this pattern, see PR82524. */
11335 rtx_equal_p (operands[0], operands[1])"
11336 "and{b}\t{%2, %h0|%h0, %2}"
11337 [(set_attr "isa" "*,nox64")
11338 (set_attr "type" "alu")
11339 (set_attr "mode" "QI")])
11341 ;; Generated by peephole translating test to and. This shows up
11342 ;; often in fp comparisons.
11343 (define_insn "*andqi_ext<mode>_1_cc"
11344 [(set (reg FLAGS_REG)
11348 (match_operator:SWI248 3 "extract_operator"
11349 [(match_operand 1 "int248_register_operand" "0,0")
11352 (match_operand:QI 2 "general_x64constmem_operand" "QnBc,m"))
11354 (set (zero_extract:SWI248
11355 (match_operand 0 "int248_register_operand" "+Q,Q")
11365 (match_dup 2)) 0))]
11366 "ix86_match_ccmode (insn, CCNOmode)
11367 /* FIXME: without this LRA can't reload this pattern, see PR82524. */
11368 && rtx_equal_p (operands[0], operands[1])"
11369 "and{b}\t{%2, %h0|%h0, %2}"
11370 [(set_attr "isa" "*,nox64")
11371 (set_attr "type" "alu")
11372 (set_attr "mode" "QI")])
11374 (define_insn "*andqi_ext<mode>_2"
11375 [(set (zero_extract:SWI248
11376 (match_operand 0 "int248_register_operand" "+Q")
11382 (match_operator:SWI248 3 "extract_operator"
11383 [(match_operand 1 "int248_register_operand" "%0")
11387 (match_operator:SWI248 4 "extract_operator"
11388 [(match_operand 2 "int248_register_operand" "Q")
11390 (const_int 8)]) 0)) 0))
11391 (clobber (reg:CC FLAGS_REG))]
11392 "/* FIXME: without this LRA can't reload this pattern, see PR82524. */
11393 rtx_equal_p (operands[0], operands[1])
11394 || rtx_equal_p (operands[0], operands[2])"
11395 "and{b}\t{%h2, %h0|%h0, %h2}"
11396 [(set_attr "type" "alu")
11397 (set_attr "mode" "QI")])
11399 ;; *andqi_ext<mode>_3 is defined via *<code>qi_ext<mode>_3 below.
11401 ;; Convert wide AND instructions with immediate operand to shorter QImode
11402 ;; equivalents when possible.
11403 ;; Don't do the splitting with memory operands, since it introduces risk
11404 ;; of memory mismatch stalls. We may want to do the splitting for optimizing
11405 ;; for size, but that can (should?) be handled by generic code instead.
11407 [(set (match_operand:SWI248 0 "QIreg_operand")
11408 (and:SWI248 (match_operand:SWI248 1 "register_operand")
11409 (match_operand:SWI248 2 "const_int_operand")))
11410 (clobber (reg:CC FLAGS_REG))]
11412 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
11413 && !(~INTVAL (operands[2]) & ~(255 << 8))"
11415 [(set (zero_extract:HI (match_dup 0)
11421 (zero_extract:HI (match_dup 1)
11425 (clobber (reg:CC FLAGS_REG))])]
11427 operands[0] = gen_lowpart (HImode, operands[0]);
11428 operands[1] = gen_lowpart (HImode, operands[1]);
11429 operands[2] = gen_int_mode (INTVAL (operands[2]) >> 8, QImode);
11432 ;; Since AND can be encoded with sign extended immediate, this is only
11433 ;; profitable when 7th bit is not set.
11435 [(set (match_operand:SWI248 0 "any_QIreg_operand")
11436 (and:SWI248 (match_operand:SWI248 1 "general_operand")
11437 (match_operand:SWI248 2 "const_int_operand")))
11438 (clobber (reg:CC FLAGS_REG))]
11440 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
11441 && !(~INTVAL (operands[2]) & ~255)
11442 && !(INTVAL (operands[2]) & 128)"
11443 [(parallel [(set (strict_low_part (match_dup 0))
11444 (and:QI (match_dup 1)
11446 (clobber (reg:CC FLAGS_REG))])]
11448 operands[0] = gen_lowpart (QImode, operands[0]);
11449 operands[1] = gen_lowpart (QImode, operands[1]);
11450 operands[2] = gen_int_mode (INTVAL (operands[2]), QImode);
11453 (define_insn_and_split "*andn<dwi>3_doubleword_bmi"
11454 [(set (match_operand:<DWI> 0 "register_operand" "=&r,r,r")
11456 (not:<DWI> (match_operand:<DWI> 1 "register_operand" "r,0,r"))
11457 (match_operand:<DWI> 2 "nonimmediate_operand" "ro,ro,0")))
11458 (clobber (reg:CC FLAGS_REG))]
11461 "&& reload_completed"
11462 [(parallel [(set (match_dup 0)
11463 (and:DWIH (not:DWIH (match_dup 1)) (match_dup 2)))
11464 (clobber (reg:CC FLAGS_REG))])
11465 (parallel [(set (match_dup 3)
11466 (and:DWIH (not:DWIH (match_dup 4)) (match_dup 5)))
11467 (clobber (reg:CC FLAGS_REG))])]
11468 "split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);")
11470 (define_insn_and_split "*andn<mode>3_doubleword"
11471 [(set (match_operand:DWI 0 "register_operand")
11473 (not:DWI (match_operand:DWI 1 "register_operand"))
11474 (match_operand:DWI 2 "nonimmediate_operand")))
11475 (clobber (reg:CC FLAGS_REG))]
11477 && ix86_pre_reload_split ()"
11480 [(set (match_dup 3) (not:DWI (match_dup 1)))
11481 (parallel [(set (match_dup 0)
11482 (and:DWI (match_dup 3) (match_dup 2)))
11483 (clobber (reg:CC FLAGS_REG))])]
11484 "operands[3] = gen_reg_rtx (<MODE>mode);")
11486 (define_insn "*andn<mode>_1"
11487 [(set (match_operand:SWI48 0 "register_operand" "=r,r,?k")
11489 (not:SWI48 (match_operand:SWI48 1 "register_operand" "r,r,k"))
11490 (match_operand:SWI48 2 "nonimmediate_operand" "r,m,k")))
11491 (clobber (reg:CC FLAGS_REG))]
11492 "TARGET_BMI || TARGET_AVX512BW"
11494 andn\t{%2, %1, %0|%0, %1, %2}
11495 andn\t{%2, %1, %0|%0, %1, %2}
11497 [(set_attr "isa" "bmi,bmi,avx512bw")
11498 (set_attr "type" "bitmanip,bitmanip,msklog")
11499 (set_attr "btver2_decode" "direct, double,*")
11500 (set_attr "mode" "<MODE>")])
11502 (define_insn "*andn<mode>_1"
11503 [(set (match_operand:SWI12 0 "register_operand" "=r,?k")
11505 (not:SWI12 (match_operand:SWI12 1 "register_operand" "r,k"))
11506 (match_operand:SWI12 2 "register_operand" "r,k")))
11507 (clobber (reg:CC FLAGS_REG))]
11508 "TARGET_BMI || TARGET_AVX512BW"
11510 andn\t{%k2, %k1, %k0|%k0, %k1, %k2}
11512 [(set_attr "isa" "bmi,avx512f")
11513 (set_attr "type" "bitmanip,msklog")
11514 (set_attr "btver2_decode" "direct,*")
11516 (cond [(eq_attr "alternative" "0")
11517 (const_string "SI")
11518 (and (eq_attr "alternative" "1")
11519 (match_test "!TARGET_AVX512DQ"))
11520 (const_string "HI")
11522 (const_string "<MODE>")))])
11524 (define_insn "*andn_<mode>_ccno"
11525 [(set (reg FLAGS_REG)
11528 (not:SWI48 (match_operand:SWI48 1 "register_operand" "r,r"))
11529 (match_operand:SWI48 2 "nonimmediate_operand" "r,m"))
11531 (clobber (match_scratch:SWI48 0 "=r,r"))]
11532 "TARGET_BMI && ix86_match_ccmode (insn, CCNOmode)"
11533 "andn\t{%2, %1, %0|%0, %1, %2}"
11534 [(set_attr "type" "bitmanip")
11535 (set_attr "btver2_decode" "direct, double")
11536 (set_attr "mode" "<MODE>")])
11538 ;; Split *andnsi_1 after reload with -Oz when not;and is shorter.
11540 [(set (match_operand:SI 0 "register_operand")
11541 (and:SI (not:SI (match_operand:SI 1 "register_operand"))
11542 (match_operand:SI 2 "nonimmediate_operand")))
11543 (clobber (reg:CC FLAGS_REG))]
11545 && optimize_insn_for_size_p () && optimize_size > 1
11546 && REGNO (operands[0]) == REGNO (operands[1])
11547 && LEGACY_INT_REG_P (operands[0])
11548 && !REX_INT_REG_P (operands[2])
11549 && !reg_overlap_mentioned_p (operands[0], operands[2])"
11550 [(set (match_dup 0) (not:SI (match_dup 1)))
11551 (parallel [(set (match_dup 0) (and:SI (match_dup 0) (match_dup 2)))
11552 (clobber (reg:CC FLAGS_REG))])])
11554 ;; Split *andn_si_ccno with -Oz when not;test is shorter.
11556 [(set (match_operand 0 "flags_reg_operand")
11557 (match_operator 1 "compare_operator"
11558 [(and:SI (not:SI (match_operand:SI 2 "general_reg_operand"))
11559 (match_operand:SI 3 "nonimmediate_operand"))
11561 (clobber (match_dup 2))]
11563 && optimize_insn_for_size_p () && optimize_size > 1
11564 && LEGACY_INT_REG_P (operands[2])
11565 && !REX_INT_REG_P (operands[3])
11566 && !reg_overlap_mentioned_p (operands[2], operands[3])"
11567 [(set (match_dup 2) (not:SI (match_dup 2)))
11568 (set (match_dup 0) (match_op_dup 1
11569 [(and:SI (match_dup 3) (match_dup 2))
11572 ;; Variant 1 of 4: Split ((A | B) ^ A) ^ C as (B & ~A) ^ C.
11574 [(set (match_operand:SWI48 0 "register_operand")
11577 (ior:SWI48 (match_operand:SWI48 1 "register_operand")
11578 (match_operand:SWI48 2 "nonimmediate_operand"))
11580 (match_operand:SWI48 3 "nonimmediate_operand")))
11581 (clobber (reg:CC FLAGS_REG))]
11584 [(set (match_dup 4) (and:SWI48 (not:SWI48 (match_dup 1)) (match_dup 2)))
11585 (clobber (reg:CC FLAGS_REG))])
11587 [(set (match_dup 0) (xor:SWI48 (match_dup 4) (match_dup 3)))
11588 (clobber (reg:CC FLAGS_REG))])]
11589 "operands[4] = gen_reg_rtx (<MODE>mode);")
11591 ;; Variant 2 of 4: Split ((A | B) ^ B) ^ C as (A & ~B) ^ C.
11593 [(set (match_operand:SWI48 0 "register_operand")
11596 (ior:SWI48 (match_operand:SWI48 1 "register_operand")
11597 (match_operand:SWI48 2 "register_operand"))
11599 (match_operand:SWI48 3 "nonimmediate_operand")))
11600 (clobber (reg:CC FLAGS_REG))]
11603 [(set (match_dup 4) (and:SWI48 (not:SWI48 (match_dup 2)) (match_dup 1)))
11604 (clobber (reg:CC FLAGS_REG))])
11606 [(set (match_dup 0) (xor:SWI48 (match_dup 4) (match_dup 3)))
11607 (clobber (reg:CC FLAGS_REG))])]
11608 "operands[4] = gen_reg_rtx (<MODE>mode);")
11610 ;; Variant 3 of 4: Split ((A | B) ^ C) ^ A as (B & ~A) ^ C.
11612 [(set (match_operand:SWI48 0 "register_operand")
11615 (ior:SWI48 (match_operand:SWI48 1 "register_operand")
11616 (match_operand:SWI48 2 "nonimmediate_operand"))
11617 (match_operand:SWI48 3 "nonimmediate_operand"))
11619 (clobber (reg:CC FLAGS_REG))]
11622 [(set (match_dup 4) (and:SWI48 (not:SWI48 (match_dup 1)) (match_dup 2)))
11623 (clobber (reg:CC FLAGS_REG))])
11625 [(set (match_dup 0) (xor:SWI48 (match_dup 4) (match_dup 3)))
11626 (clobber (reg:CC FLAGS_REG))])]
11627 "operands[4] = gen_reg_rtx (<MODE>mode);")
11629 ;; Variant 4 of 4: Split ((A | B) ^ C) ^ B as (A & ~B) ^ C.
11631 [(set (match_operand:SWI48 0 "register_operand")
11634 (ior:SWI48 (match_operand:SWI48 1 "register_operand")
11635 (match_operand:SWI48 2 "register_operand"))
11636 (match_operand:SWI48 3 "nonimmediate_operand"))
11638 (clobber (reg:CC FLAGS_REG))]
11641 [(set (match_dup 4) (and:SWI48 (not:SWI48 (match_dup 2)) (match_dup 1)))
11642 (clobber (reg:CC FLAGS_REG))])
11644 [(set (match_dup 0) (xor:SWI48 (match_dup 4) (match_dup 3)))
11645 (clobber (reg:CC FLAGS_REG))])]
11646 "operands[4] = gen_reg_rtx (<MODE>mode);")
11648 ;; Logical inclusive and exclusive OR instructions
11650 ;; %%% This used to optimize known byte-wide and operations to memory.
11651 ;; If this is considered useful, it should be done with splitters.
11653 (define_expand "<code><mode>3"
11654 [(set (match_operand:SDWIM 0 "nonimmediate_operand")
11655 (any_or:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")
11656 (match_operand:SDWIM 2 "<general_operand>")))]
11659 if (GET_MODE_SIZE (<MODE>mode) > UNITS_PER_WORD
11660 && !x86_64_hilo_general_operand (operands[2], <MODE>mode))
11661 operands[2] = force_reg (<MODE>mode, operands[2]);
11663 ix86_expand_binary_operator (<CODE>, <MODE>mode, operands);
11667 (define_insn_and_split "*<code><dwi>3_doubleword"
11668 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro,r")
11670 (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0")
11671 (match_operand:<DWI> 2 "x86_64_hilo_general_operand" "r<di>,o")))
11672 (clobber (reg:CC FLAGS_REG))]
11673 "ix86_binary_operator_ok (<CODE>, <DWI>mode, operands)"
11675 "&& reload_completed"
11676 [(const_int:DWIH 0)]
11678 /* This insn may disappear completely when operands[2] == const0_rtx
11679 and operands[0] == operands[1], which requires a NOTE_INSN_DELETED. */
11680 bool emit_insn_deleted_note_p = false;
11682 split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
11684 if (operands[2] == const0_rtx)
11685 emit_insn_deleted_note_p = true;
11686 else if (operands[2] == constm1_rtx)
11689 emit_move_insn (operands[0], constm1_rtx);
11691 ix86_expand_unary_operator (NOT, <MODE>mode, &operands[0]);
11694 ix86_expand_binary_operator (<CODE>, <MODE>mode, &operands[0]);
11696 if (operands[5] == const0_rtx)
11698 if (emit_insn_deleted_note_p)
11699 emit_note (NOTE_INSN_DELETED);
11701 else if (operands[5] == constm1_rtx)
11704 emit_move_insn (operands[3], constm1_rtx);
11706 ix86_expand_unary_operator (NOT, <MODE>mode, &operands[3]);
11709 ix86_expand_binary_operator (<CODE>, <MODE>mode, &operands[3]);
11714 (define_insn "*<code><mode>_1"
11715 [(set (match_operand:SWI248 0 "nonimmediate_operand" "=rm,r,?k")
11717 (match_operand:SWI248 1 "nonimmediate_operand" "%0,0,k")
11718 (match_operand:SWI248 2 "<general_operand>" "r<i>,<m>,k")))
11719 (clobber (reg:CC FLAGS_REG))]
11720 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
11722 <logic>{<imodesuffix>}\t{%2, %0|%0, %2}
11723 <logic>{<imodesuffix>}\t{%2, %0|%0, %2}
11726 (cond [(eq_attr "alternative" "2")
11727 (if_then_else (eq_attr "mode" "SI,DI")
11728 (const_string "avx512bw")
11729 (const_string "avx512f"))
11731 (const_string "*")))
11732 (set_attr "type" "alu, alu, msklog")
11733 (set_attr "mode" "<MODE>")])
11735 (define_insn_and_split "*notxor<mode>_1"
11736 [(set (match_operand:SWI248 0 "nonimmediate_operand" "=rm,r,?k")
11739 (match_operand:SWI248 1 "nonimmediate_operand" "%0,0,k")
11740 (match_operand:SWI248 2 "<general_operand>" "r<i>,<m>,k"))))
11741 (clobber (reg:CC FLAGS_REG))]
11742 "ix86_binary_operator_ok (XOR, <MODE>mode, operands)"
11744 "&& reload_completed"
11746 [(set (match_dup 0)
11747 (xor:SWI248 (match_dup 1) (match_dup 2)))
11748 (clobber (reg:CC FLAGS_REG))])
11750 (not:SWI248 (match_dup 0)))]
11752 if (MASK_REG_P (operands[0]))
11754 emit_insn (gen_kxnor<mode> (operands[0], operands[1], operands[2]));
11759 (cond [(eq_attr "alternative" "2")
11760 (if_then_else (eq_attr "mode" "SI,DI")
11761 (const_string "avx512bw")
11762 (const_string "avx512f"))
11764 (const_string "*")))
11765 (set_attr "type" "alu, alu, msklog")
11766 (set_attr "mode" "<MODE>")])
11768 (define_insn_and_split "*iordi_1_bts"
11769 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11771 (match_operand:DI 1 "nonimmediate_operand" "%0")
11772 (match_operand:DI 2 "const_int_operand" "n")))
11773 (clobber (reg:CC FLAGS_REG))]
11774 "TARGET_64BIT && TARGET_USE_BT
11775 && ix86_binary_operator_ok (IOR, DImode, operands)
11776 && IN_RANGE (exact_log2 (INTVAL (operands[2])), 31, 63)"
11778 "&& reload_completed"
11779 [(parallel [(set (zero_extract:DI (match_dup 0)
11783 (clobber (reg:CC FLAGS_REG))])]
11784 "operands[3] = GEN_INT (exact_log2 (INTVAL (operands[2])));"
11785 [(set_attr "type" "alu1")
11786 (set_attr "prefix_0f" "1")
11787 (set_attr "znver1_decode" "double")
11788 (set_attr "mode" "DI")])
11790 (define_insn_and_split "*xordi_1_btc"
11791 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11793 (match_operand:DI 1 "nonimmediate_operand" "%0")
11794 (match_operand:DI 2 "const_int_operand" "n")))
11795 (clobber (reg:CC FLAGS_REG))]
11796 "TARGET_64BIT && TARGET_USE_BT
11797 && ix86_binary_operator_ok (XOR, DImode, operands)
11798 && IN_RANGE (exact_log2 (INTVAL (operands[2])), 31, 63)"
11800 "&& reload_completed"
11801 [(parallel [(set (zero_extract:DI (match_dup 0)
11804 (not:DI (zero_extract:DI (match_dup 0)
11807 (clobber (reg:CC FLAGS_REG))])]
11808 "operands[3] = GEN_INT (exact_log2 (INTVAL (operands[2])));"
11809 [(set_attr "type" "alu1")
11810 (set_attr "prefix_0f" "1")
11811 (set_attr "znver1_decode" "double")
11812 (set_attr "mode" "DI")])
11814 ;; Optimize a ^ ((a ^ b) & mask) to (~mask & a) | (b & mask)
11815 (define_insn_and_split "*xor2andn"
11816 [(set (match_operand:SWI248 0 "register_operand")
11820 (match_operand:SWI248 1 "nonimmediate_operand")
11821 (match_operand:SWI248 2 "nonimmediate_operand"))
11822 (match_operand:SWI248 3 "nonimmediate_operand"))
11824 (clobber (reg:CC FLAGS_REG))]
11825 "TARGET_BMI && ix86_pre_reload_split ()"
11828 [(parallel [(set (match_dup 4)
11833 (clobber (reg:CC FLAGS_REG))])
11834 (parallel [(set (match_dup 5)
11838 (clobber (reg:CC FLAGS_REG))])
11839 (parallel [(set (match_dup 0)
11843 (clobber (reg:CC FLAGS_REG))])]
11845 operands[1] = force_reg (<MODE>mode, operands[1]);
11846 operands[3] = force_reg (<MODE>mode, operands[3]);
11847 operands[4] = gen_reg_rtx (<MODE>mode);
11848 operands[5] = gen_reg_rtx (<MODE>mode);
11851 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
11852 (define_insn "*<code>si_1_zext"
11853 [(set (match_operand:DI 0 "register_operand" "=r")
11855 (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
11856 (match_operand:SI 2 "x86_64_general_operand" "rBMe"))))
11857 (clobber (reg:CC FLAGS_REG))]
11858 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
11859 "<logic>{l}\t{%2, %k0|%k0, %2}"
11860 [(set_attr "type" "alu")
11861 (set_attr "mode" "SI")])
11863 (define_insn "*<code>si_1_zext_imm"
11864 [(set (match_operand:DI 0 "register_operand" "=r")
11866 (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
11867 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
11868 (clobber (reg:CC FLAGS_REG))]
11869 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
11870 "<logic>{l}\t{%2, %k0|%k0, %2}"
11871 [(set_attr "type" "alu")
11872 (set_attr "mode" "SI")])
11874 (define_insn "*<code>qi_1"
11875 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,?k")
11876 (any_or:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,k")
11877 (match_operand:QI 2 "general_operand" "qn,m,rn,k")))
11878 (clobber (reg:CC FLAGS_REG))]
11879 "ix86_binary_operator_ok (<CODE>, QImode, operands)"
11881 <logic>{b}\t{%2, %0|%0, %2}
11882 <logic>{b}\t{%2, %0|%0, %2}
11883 <logic>{l}\t{%k2, %k0|%k0, %k2}
11885 [(set_attr "isa" "*,*,*,avx512f")
11886 (set_attr "type" "alu,alu,alu,msklog")
11888 (cond [(eq_attr "alternative" "2")
11889 (const_string "SI")
11890 (and (eq_attr "alternative" "3")
11891 (match_test "!TARGET_AVX512DQ"))
11892 (const_string "HI")
11894 (const_string "QI")))
11895 ;; Potential partial reg stall on alternative 2.
11896 (set (attr "preferred_for_speed")
11897 (cond [(eq_attr "alternative" "2")
11898 (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
11899 (symbol_ref "true")))])
11901 (define_insn_and_split "*notxorqi_1"
11902 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,?k")
11904 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,k")
11905 (match_operand:QI 2 "general_operand" "qn,m,rn,k"))))
11906 (clobber (reg:CC FLAGS_REG))]
11907 "ix86_binary_operator_ok (XOR, QImode, operands)"
11909 "&& reload_completed"
11911 [(set (match_dup 0)
11912 (xor:QI (match_dup 1) (match_dup 2)))
11913 (clobber (reg:CC FLAGS_REG))])
11915 (not:QI (match_dup 0)))]
11917 if (mask_reg_operand (operands[0], QImode))
11919 emit_insn (gen_kxnorqi (operands[0], operands[1], operands[2]));
11923 [(set_attr "isa" "*,*,*,avx512f")
11924 (set_attr "type" "alu,alu,alu,msklog")
11926 (cond [(eq_attr "alternative" "2")
11927 (const_string "SI")
11928 (and (eq_attr "alternative" "3")
11929 (match_test "!TARGET_AVX512DQ"))
11930 (const_string "HI")
11932 (const_string "QI")))
11933 ;; Potential partial reg stall on alternative 2.
11934 (set (attr "preferred_for_speed")
11935 (cond [(eq_attr "alternative" "2")
11936 (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
11937 (symbol_ref "true")))])
11939 ;; Alternative 1 is needed to work around LRA limitation, see PR82524.
11940 (define_insn_and_split "*<code><mode>_1_slp"
11941 [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>,&<r>"))
11942 (any_or:SWI12 (match_operand:SWI12 1 "nonimmediate_operand" "%0,!<r>")
11943 (match_operand:SWI12 2 "general_operand" "<r>mn,<r>mn")))
11944 (clobber (reg:CC FLAGS_REG))]
11945 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
11947 <logic>{<imodesuffix>}\t{%2, %0|%0, %2}
11949 "&& reload_completed"
11950 [(set (strict_low_part (match_dup 0)) (match_dup 1))
11952 [(set (strict_low_part (match_dup 0))
11953 (any_or:SWI12 (match_dup 0) (match_dup 2)))
11954 (clobber (reg:CC FLAGS_REG))])]
11956 [(set_attr "type" "alu")
11957 (set_attr "mode" "<MODE>")])
11959 ;; convert (sign_extend:WIDE (any_logic:NARROW (memory, immediate)))
11960 ;; to (any_logic:WIDE (sign_extend (memory)), (sign_extend (immediate))).
11961 ;; This eliminates sign extension after logic operation.
11964 [(set (match_operand:SWI248 0 "register_operand")
11965 (sign_extend:SWI248
11966 (any_logic:QI (match_operand:QI 1 "memory_operand")
11967 (match_operand:QI 2 "const_int_operand"))))]
11969 [(set (match_dup 3) (sign_extend:SWI248 (match_dup 1)))
11970 (set (match_dup 0) (any_logic:SWI248 (match_dup 3) (match_dup 2)))]
11971 "operands[3] = gen_reg_rtx (<MODE>mode);")
11974 [(set (match_operand:SWI48 0 "register_operand")
11976 (any_logic:HI (match_operand:HI 1 "memory_operand")
11977 (match_operand:HI 2 "const_int_operand"))))]
11979 [(set (match_dup 3) (sign_extend:SWI48 (match_dup 1)))
11980 (set (match_dup 0) (any_logic:SWI48 (match_dup 3) (match_dup 2)))]
11981 "operands[3] = gen_reg_rtx (<MODE>mode);")
11984 [(set (match_operand:DI 0 "register_operand")
11986 (any_logic:SI (match_operand:SI 1 "memory_operand")
11987 (match_operand:SI 2 "const_int_operand"))))]
11989 [(set (match_dup 3) (sign_extend:DI (match_dup 1)))
11990 (set (match_dup 0) (any_logic:DI (match_dup 3) (match_dup 2)))]
11991 "operands[3] = gen_reg_rtx (DImode);")
11993 (define_insn "*<code><mode>_2"
11994 [(set (reg FLAGS_REG)
11995 (compare (any_or:SWI
11996 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
11997 (match_operand:SWI 2 "<general_operand>" "<r><i>,<m>"))
11999 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
12000 (any_or:SWI (match_dup 1) (match_dup 2)))]
12001 "ix86_match_ccmode (insn, CCNOmode)
12002 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
12003 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
12004 [(set_attr "type" "alu")
12005 (set_attr "mode" "<MODE>")])
12007 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
12008 ;; ??? Special case for immediate operand is missing - it is tricky.
12009 (define_insn "*<code>si_2_zext"
12010 [(set (reg FLAGS_REG)
12011 (compare (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
12012 (match_operand:SI 2 "x86_64_general_operand" "rBMe"))
12014 (set (match_operand:DI 0 "register_operand" "=r")
12015 (zero_extend:DI (any_or:SI (match_dup 1) (match_dup 2))))]
12016 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
12017 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
12018 "<logic>{l}\t{%2, %k0|%k0, %2}"
12019 [(set_attr "type" "alu")
12020 (set_attr "mode" "SI")])
12022 (define_insn "*<code>si_2_zext_imm"
12023 [(set (reg FLAGS_REG)
12024 (compare (any_or:SI
12025 (match_operand:SI 1 "nonimmediate_operand" "%0")
12026 (match_operand:SI 2 "x86_64_zext_immediate_operand" "Z"))
12028 (set (match_operand:DI 0 "register_operand" "=r")
12029 (any_or:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
12030 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
12031 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
12032 "<logic>{l}\t{%2, %k0|%k0, %2}"
12033 [(set_attr "type" "alu")
12034 (set_attr "mode" "SI")])
12036 (define_insn "*<code><mode>_3"
12037 [(set (reg FLAGS_REG)
12038 (compare (any_or:SWI
12039 (match_operand:SWI 1 "nonimmediate_operand" "%0")
12040 (match_operand:SWI 2 "<general_operand>" "<g>"))
12042 (clobber (match_scratch:SWI 0 "=<r>"))]
12043 "ix86_match_ccmode (insn, CCNOmode)
12044 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12045 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
12046 [(set_attr "type" "alu")
12047 (set_attr "mode" "<MODE>")])
12049 (define_insn "*<code>qi_ext<mode>_0"
12050 [(set (match_operand:QI 0 "nonimm_x64constmem_operand" "=QBc,m")
12053 (match_operator:SWI248 3 "extract_operator"
12054 [(match_operand 2 "int248_register_operand" "Q,Q")
12057 (match_operand:QI 1 "nonimm_x64constmem_operand" "0,0")))
12058 (clobber (reg:CC FLAGS_REG))]
12060 "<logic>{b}\t{%h2, %0|%0, %h2}"
12061 [(set_attr "isa" "*,nox64")
12062 (set_attr "type" "alu")
12063 (set_attr "mode" "QI")])
12065 (define_insn "*<code>qi_ext<mode>_1"
12066 [(set (zero_extract:SWI248
12067 (match_operand 0 "int248_register_operand" "+Q,Q")
12073 (match_operator:SWI248 3 "extract_operator"
12074 [(match_operand 1 "int248_register_operand" "0,0")
12077 (match_operand:QI 2 "general_x64constmem_operand" "QnBc,m")) 0))
12078 (clobber (reg:CC FLAGS_REG))]
12079 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
12080 /* FIXME: without this LRA can't reload this pattern, see PR82524. */
12081 && rtx_equal_p (operands[0], operands[1])"
12082 "<logic>{b}\t{%2, %h0|%h0, %2}"
12083 [(set_attr "isa" "*,nox64")
12084 (set_attr "type" "alu")
12085 (set_attr "mode" "QI")])
12087 (define_insn "*<code>qi_ext<mode>_2"
12088 [(set (zero_extract:SWI248
12089 (match_operand 0 "int248_register_operand" "+Q")
12095 (match_operator:SWI248 3 "extract_operator"
12096 [(match_operand 1 "int248_register_operand" "%0")
12100 (match_operator:SWI248 4 "extract_operator"
12101 [(match_operand 2 "int248_register_operand" "Q")
12103 (const_int 8)]) 0)) 0))
12104 (clobber (reg:CC FLAGS_REG))]
12105 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
12106 /* FIXME: without this LRA can't reload this pattern, see PR82524. */
12107 && (rtx_equal_p (operands[0], operands[1])
12108 || rtx_equal_p (operands[0], operands[2]))"
12109 "<logic>{b}\t{%h2, %h0|%h0, %h2}"
12110 [(set_attr "type" "alu")
12111 (set_attr "mode" "QI")])
12113 (define_insn "*<code>qi_ext<mode>_3"
12114 [(set (zero_extract:SWI248
12115 (match_operand 0 "int248_register_operand" "+Q")
12118 (zero_extract:SWI248
12120 (match_operand 1 "int248_register_operand" "%0")
12121 (match_operand 2 "int248_register_operand" "Q"))
12124 (clobber (reg:CC FLAGS_REG))]
12125 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
12126 /* FIXME: without this LRA can't reload this pattern, see PR82524. */
12127 && (rtx_equal_p (operands[0], operands[1])
12128 || rtx_equal_p (operands[0], operands[2]))"
12129 "<logic>{b}\t{%h2, %h0|%h0, %h2}"
12130 [(set_attr "type" "alu")
12131 (set_attr "mode" "QI")])
12133 ;; Convert wide OR instructions with immediate operand to shorter QImode
12134 ;; equivalents when possible.
12135 ;; Don't do the splitting with memory operands, since it introduces risk
12136 ;; of memory mismatch stalls. We may want to do the splitting for optimizing
12137 ;; for size, but that can (should?) be handled by generic code instead.
12139 [(set (match_operand:SWI248 0 "QIreg_operand")
12140 (any_or:SWI248 (match_operand:SWI248 1 "register_operand")
12141 (match_operand:SWI248 2 "const_int_operand")))
12142 (clobber (reg:CC FLAGS_REG))]
12144 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
12145 && !(INTVAL (operands[2]) & ~(255 << 8))"
12147 [(set (zero_extract:HI (match_dup 0)
12153 (zero_extract:HI (match_dup 1)
12157 (clobber (reg:CC FLAGS_REG))])]
12159 /* Handle the case where INTVAL (operands[2]) == 0. */
12160 if (operands[2] == const0_rtx)
12162 if (!rtx_equal_p (operands[0], operands[1]))
12163 emit_move_insn (operands[0], operands[1]);
12165 emit_note (NOTE_INSN_DELETED);
12168 operands[0] = gen_lowpart (HImode, operands[0]);
12169 operands[1] = gen_lowpart (HImode, operands[1]);
12170 operands[2] = gen_int_mode (INTVAL (operands[2]) >> 8, QImode);
12173 ;; Since OR can be encoded with sign extended immediate, this is only
12174 ;; profitable when 7th bit is set.
12176 [(set (match_operand:SWI248 0 "any_QIreg_operand")
12177 (any_or:SWI248 (match_operand:SWI248 1 "general_operand")
12178 (match_operand:SWI248 2 "const_int_operand")))
12179 (clobber (reg:CC FLAGS_REG))]
12181 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
12182 && !(INTVAL (operands[2]) & ~255)
12183 && (INTVAL (operands[2]) & 128)"
12184 [(parallel [(set (strict_low_part (match_dup 0))
12185 (any_or:QI (match_dup 1)
12187 (clobber (reg:CC FLAGS_REG))])]
12189 operands[0] = gen_lowpart (QImode, operands[0]);
12190 operands[1] = gen_lowpart (QImode, operands[1]);
12191 operands[2] = gen_int_mode (INTVAL (operands[2]), QImode);
12194 (define_expand "xorqi_ext_1_cc"
12196 [(set (reg:CCNO FLAGS_REG)
12200 (zero_extract:HI (match_operand:HI 1 "register_operand")
12203 (match_operand:QI 2 "const_int_operand"))
12205 (set (zero_extract:HI (match_operand:HI 0 "register_operand")
12211 (zero_extract:HI (match_dup 1)
12214 (match_dup 2)) 0))])])
12216 (define_insn "*xorqi_ext<mode>_1_cc"
12217 [(set (reg FLAGS_REG)
12221 (match_operator:SWI248 3 "extract_operator"
12222 [(match_operand 1 "int248_register_operand" "0,0")
12225 (match_operand:QI 2 "general_x64constmem_operand" "QnBc,m"))
12227 (set (zero_extract:SWI248
12228 (match_operand 0 "int248_register_operand" "+Q,Q")
12238 (match_dup 2)) 0))]
12239 "ix86_match_ccmode (insn, CCNOmode)
12240 /* FIXME: without this LRA can't reload this pattern, see PR82524. */
12241 && rtx_equal_p (operands[0], operands[1])"
12242 "xor{b}\t{%2, %h0|%h0, %2}"
12243 [(set_attr "isa" "*,nox64")
12244 (set_attr "type" "alu")
12245 (set_attr "mode" "QI")])
12247 ;; Peephole2 rega = 0; rega op= regb into rega = regb.
12249 [(parallel [(set (match_operand:SWI 0 "general_reg_operand")
12251 (clobber (reg:CC FLAGS_REG))])
12252 (parallel [(set (match_dup 0)
12253 (any_or_plus:SWI (match_dup 0)
12254 (match_operand:SWI 1 "<general_operand>")))
12255 (clobber (reg:CC FLAGS_REG))])]
12257 [(set (match_dup 0) (match_dup 1))])
12259 ;; Split DST = (HI<<32)|LO early to minimize register usage.
12260 (define_insn_and_split "*concat<mode><dwi>3_1"
12261 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro,r")
12263 (ashift:<DWI> (match_operand:<DWI> 1 "register_operand" "r,r")
12264 (match_operand:QI 2 "const_int_operand"))
12266 (match_operand:DWIH 3 "nonimmediate_operand" "r,m"))))]
12267 "INTVAL (operands[2]) == <MODE_SIZE> * BITS_PER_UNIT"
12269 "&& reload_completed"
12272 split_double_concat (<DWI>mode, operands[0], operands[3],
12273 gen_lowpart (<MODE>mode, operands[1]));
12277 (define_insn_and_split "*concat<mode><dwi>3_2"
12278 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro,r")
12281 (match_operand:DWIH 1 "nonimmediate_operand" "r,m"))
12282 (ashift:<DWI> (match_operand:<DWI> 2 "register_operand" "r,r")
12283 (match_operand:QI 3 "const_int_operand"))))]
12284 "INTVAL (operands[3]) == <MODE_SIZE> * BITS_PER_UNIT"
12286 "&& reload_completed"
12289 split_double_concat (<DWI>mode, operands[0], operands[1],
12290 gen_lowpart (<MODE>mode, operands[2]));
12294 (define_insn_and_split "*concat<mode><dwi>3_3"
12295 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro,r,r,&r")
12299 (match_operand:DWIH 1 "nonimmediate_operand" "r,m,r,m"))
12300 (match_operand:QI 2 "const_int_operand"))
12302 (match_operand:DWIH 3 "nonimmediate_operand" "r,r,m,m"))))]
12303 "INTVAL (operands[2]) == <MODE_SIZE> * BITS_PER_UNIT"
12305 "&& reload_completed"
12308 split_double_concat (<DWI>mode, operands[0], operands[3], operands[1]);
12312 (define_insn_and_split "*concat<mode><dwi>3_4"
12313 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro,r,r,&r")
12316 (match_operand:DWIH 1 "nonimmediate_operand" "r,m,r,m"))
12319 (match_operand:DWIH 2 "nonimmediate_operand" "r,r,m,m"))
12320 (match_operand:QI 3 "const_int_operand"))))]
12321 "INTVAL (operands[3]) == <MODE_SIZE> * BITS_PER_UNIT"
12323 "&& reload_completed"
12326 split_double_concat (<DWI>mode, operands[0], operands[1], operands[2]);
12330 (define_insn_and_split "*concat<half><mode>3_5"
12331 [(set (match_operand:DWI 0 "nonimmediate_operand" "=r,o,o")
12333 (ashift:DWI (match_operand:DWI 1 "register_operand" "r,r,r")
12334 (match_operand:QI 2 "const_int_operand"))
12335 (match_operand:DWI 3 "const_scalar_int_operand" "n,n,Wd")))]
12336 "INTVAL (operands[2]) == <MODE_SIZE> * BITS_PER_UNIT / 2
12337 && (<MODE>mode == DImode
12338 ? CONST_INT_P (operands[3])
12339 && (UINTVAL (operands[3]) & ~GET_MODE_MASK (SImode)) == 0
12340 : CONST_INT_P (operands[3])
12341 ? INTVAL (operands[3]) >= 0
12342 : CONST_WIDE_INT_NUNITS (operands[3]) == 2
12343 && CONST_WIDE_INT_ELT (operands[3], 1) == 0)
12344 && !(CONST_INT_P (operands[3])
12345 ? ix86_endbr_immediate_operand (operands[3], VOIDmode)
12346 : ix86_endbr_immediate_operand (GEN_INT (CONST_WIDE_INT_ELT (operands[3],
12350 "&& reload_completed"
12353 rtx op3 = simplify_subreg (<HALF>mode, operands[3], <MODE>mode, 0);
12354 split_double_concat (<MODE>mode, operands[0], op3,
12355 gen_lowpart (<HALF>mode, operands[1]));
12358 [(set_attr "isa" "*,nox64,x64")])
12360 (define_insn_and_split "*concat<mode><dwi>3_6"
12361 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o,o,r")
12365 (match_operand:DWIH 1 "nonimmediate_operand" "r,r,r,m"))
12366 (match_operand:QI 2 "const_int_operand"))
12367 (match_operand:<DWI> 3 "const_scalar_int_operand" "n,n,Wd,n")))]
12368 "INTVAL (operands[2]) == <MODE_SIZE> * BITS_PER_UNIT
12369 && (<DWI>mode == DImode
12370 ? CONST_INT_P (operands[3])
12371 && (UINTVAL (operands[3]) & ~GET_MODE_MASK (SImode)) == 0
12372 : CONST_INT_P (operands[3])
12373 ? INTVAL (operands[3]) >= 0
12374 : CONST_WIDE_INT_NUNITS (operands[3]) == 2
12375 && CONST_WIDE_INT_ELT (operands[3], 1) == 0)
12376 && !(CONST_INT_P (operands[3])
12377 ? ix86_endbr_immediate_operand (operands[3], VOIDmode)
12378 : ix86_endbr_immediate_operand (GEN_INT (CONST_WIDE_INT_ELT (operands[3],
12382 "&& reload_completed"
12385 rtx op3 = simplify_subreg (<MODE>mode, operands[3], <DWI>mode, 0);
12386 split_double_concat (<DWI>mode, operands[0], op3, operands[1]);
12389 [(set_attr "isa" "*,nox64,x64,*")])
12391 (define_insn_and_split "*concat<mode><dwi>3_7"
12392 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o,o,r")
12395 (match_operand:DWIH 1 "nonimmediate_operand" "r,r,r,m"))
12396 (match_operand:<DWI> 2 "const_scalar_int_operand" "n,n,Wd,n")))]
12397 "<DWI>mode == DImode
12398 ? CONST_INT_P (operands[2])
12399 && (UINTVAL (operands[2]) & GET_MODE_MASK (SImode)) == 0
12400 && !ix86_endbr_immediate_operand (operands[2], VOIDmode)
12401 : CONST_WIDE_INT_P (operands[2])
12402 && CONST_WIDE_INT_NUNITS (operands[2]) == 2
12403 && CONST_WIDE_INT_ELT (operands[2], 0) == 0
12404 && !ix86_endbr_immediate_operand (GEN_INT (CONST_WIDE_INT_ELT (operands[2],
12408 "&& reload_completed"
12412 if (<DWI>mode == DImode)
12413 op2 = gen_int_mode (INTVAL (operands[2]) >> 32, <MODE>mode);
12415 op2 = gen_int_mode (CONST_WIDE_INT_ELT (operands[2], 1), <MODE>mode);
12416 split_double_concat (<DWI>mode, operands[0], operands[1], op2);
12419 [(set_attr "isa" "*,nox64,x64,*")])
12421 ;; Negation instructions
12423 (define_expand "neg<mode>2"
12424 [(set (match_operand:SDWIM 0 "nonimmediate_operand")
12425 (neg:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")))]
12427 "ix86_expand_unary_operator (NEG, <MODE>mode, operands); DONE;")
12429 (define_insn_and_split "*neg<dwi>2_doubleword"
12430 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro")
12431 (neg:<DWI> (match_operand:<DWI> 1 "nonimmediate_operand" "0")))
12432 (clobber (reg:CC FLAGS_REG))]
12433 "ix86_unary_operator_ok (NEG, <DWI>mode, operands)"
12435 "&& reload_completed"
12437 [(set (reg:CCC FLAGS_REG)
12438 (unspec:CCC [(match_dup 1) (const_int 0)] UNSPEC_CC_NE))
12439 (set (match_dup 0) (neg:DWIH (match_dup 1)))])
12441 [(set (match_dup 2)
12442 (plus:DWIH (plus:DWIH (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
12445 (clobber (reg:CC FLAGS_REG))])
12447 [(set (match_dup 2)
12448 (neg:DWIH (match_dup 2)))
12449 (clobber (reg:CC FLAGS_REG))])]
12450 "split_double_mode (<DWI>mode, &operands[0], 2, &operands[0], &operands[2]);")
12463 [(set (match_operand:SWI48 0 "general_reg_operand")
12464 (match_operand:SWI48 1 "nonimmediate_gr_operand"))
12466 [(set (reg:CCC FLAGS_REG)
12467 (unspec:CCC [(match_operand:SWI48 2 "general_reg_operand")
12468 (const_int 0)] UNSPEC_CC_NE))
12469 (set (match_dup 2) (neg:SWI48 (match_dup 2)))])
12471 [(set (match_dup 0)
12472 (plus:SWI48 (plus:SWI48
12473 (ltu:SWI48 (reg:CC FLAGS_REG) (const_int 0))
12476 (clobber (reg:CC FLAGS_REG))])
12478 [(set (match_dup 0)
12479 (neg:SWI48 (match_dup 0)))
12480 (clobber (reg:CC FLAGS_REG))])]
12481 "REGNO (operands[0]) != REGNO (operands[2])
12482 && !reg_mentioned_p (operands[0], operands[1])
12483 && !reg_mentioned_p (operands[2], operands[1])"
12485 [(set (reg:CCC FLAGS_REG)
12486 (unspec:CCC [(match_dup 2) (const_int 0)] UNSPEC_CC_NE))
12487 (set (match_dup 2) (neg:SWI48 (match_dup 2)))])
12489 [(set (match_dup 0)
12490 (minus:SWI48 (minus:SWI48
12492 (ltu:SWI48 (reg:CC FLAGS_REG) (const_int 0)))
12494 (clobber (reg:CC FLAGS_REG))])]
12495 "ix86_expand_clear (operands[0]);")
12504 ;; sbbl %edx, %edx // *x86_mov<mode>cc_0_m1
12508 [(set (match_operand:SWI48 0 "general_reg_operand") (const_int 0))
12509 (clobber (reg:CC FLAGS_REG))])
12511 [(set (reg:CCC FLAGS_REG)
12512 (unspec:CCC [(match_operand:SWI48 1 "general_reg_operand")
12513 (const_int 0)] UNSPEC_CC_NE))
12514 (set (match_dup 1) (neg:SWI48 (match_dup 1)))])
12516 [(set (match_dup 0)
12517 (plus:SWI48 (plus:SWI48
12518 (ltu:SWI48 (reg:CC FLAGS_REG) (const_int 0))
12521 (clobber (reg:CC FLAGS_REG))])
12523 [(set (match_dup 0)
12524 (neg:SWI48 (match_dup 0)))
12525 (clobber (reg:CC FLAGS_REG))])]
12526 "REGNO (operands[0]) != REGNO (operands[1])"
12528 [(set (reg:CCC FLAGS_REG)
12529 (unspec:CCC [(match_dup 1) (const_int 0)] UNSPEC_CC_NE))
12530 (set (match_dup 1) (neg:SWI48 (match_dup 1)))])
12532 [(set (match_dup 0)
12533 (if_then_else:SWI48 (ltu:SWI48 (reg:CC FLAGS_REG) (const_int 0))
12536 (clobber (reg:CC FLAGS_REG))])])
12538 (define_insn "*neg<mode>_1"
12539 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
12540 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")))
12541 (clobber (reg:CC FLAGS_REG))]
12542 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
12543 "neg{<imodesuffix>}\t%0"
12544 [(set_attr "type" "negnot")
12545 (set_attr "mode" "<MODE>")])
12547 (define_insn "*negsi_1_zext"
12548 [(set (match_operand:DI 0 "register_operand" "=r")
12550 (neg:SI (match_operand:SI 1 "register_operand" "0"))))
12551 (clobber (reg:CC FLAGS_REG))]
12552 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
12554 [(set_attr "type" "negnot")
12555 (set_attr "mode" "SI")])
12557 ;; Alternative 1 is needed to work around LRA limitation, see PR82524.
12558 (define_insn_and_split "*neg<mode>_1_slp"
12559 [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>,&<r>"))
12560 (neg:SWI12 (match_operand:SWI12 1 "register_operand" "0,!<r>")))
12561 (clobber (reg:CC FLAGS_REG))]
12562 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
12564 neg{<imodesuffix>}\t%0
12566 "&& reload_completed"
12567 [(set (strict_low_part (match_dup 0)) (match_dup 1))
12569 [(set (strict_low_part (match_dup 0))
12570 (neg:SWI12 (match_dup 0)))
12571 (clobber (reg:CC FLAGS_REG))])]
12573 [(set_attr "type" "negnot")
12574 (set_attr "mode" "<MODE>")])
12576 (define_insn "*neg<mode>_2"
12577 [(set (reg FLAGS_REG)
12579 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
12581 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
12582 (neg:SWI (match_dup 1)))]
12583 "ix86_match_ccmode (insn, CCGOCmode)
12584 && ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
12585 "neg{<imodesuffix>}\t%0"
12586 [(set_attr "type" "negnot")
12587 (set_attr "mode" "<MODE>")])
12589 (define_insn "*negsi_2_zext"
12590 [(set (reg FLAGS_REG)
12592 (neg:SI (match_operand:SI 1 "register_operand" "0"))
12594 (set (match_operand:DI 0 "register_operand" "=r")
12596 (neg:SI (match_dup 1))))]
12597 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
12598 && ix86_unary_operator_ok (NEG, SImode, operands)"
12600 [(set_attr "type" "negnot")
12601 (set_attr "mode" "SI")])
12603 (define_insn "*neg<mode>_ccc_1"
12604 [(set (reg:CCC FLAGS_REG)
12606 [(match_operand:SWI 1 "nonimmediate_operand" "0")
12607 (const_int 0)] UNSPEC_CC_NE))
12608 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
12609 (neg:SWI (match_dup 1)))]
12611 "neg{<imodesuffix>}\t%0"
12612 [(set_attr "type" "negnot")
12613 (set_attr "mode" "<MODE>")])
12615 (define_insn "*neg<mode>_ccc_2"
12616 [(set (reg:CCC FLAGS_REG)
12618 [(match_operand:SWI 1 "nonimmediate_operand" "0")
12619 (const_int 0)] UNSPEC_CC_NE))
12620 (clobber (match_scratch:SWI 0 "=<r>"))]
12622 "neg{<imodesuffix>}\t%0"
12623 [(set_attr "type" "negnot")
12624 (set_attr "mode" "<MODE>")])
12626 (define_expand "x86_neg<mode>_ccc"
12628 [(set (reg:CCC FLAGS_REG)
12629 (unspec:CCC [(match_operand:SWI48 1 "register_operand")
12630 (const_int 0)] UNSPEC_CC_NE))
12631 (set (match_operand:SWI48 0 "register_operand")
12632 (neg:SWI48 (match_dup 1)))])])
12634 (define_insn "*negqi_ext<mode>_2"
12635 [(set (zero_extract:SWI248
12636 (match_operand 0 "int248_register_operand" "+Q")
12642 (match_operator:SWI248 2 "extract_operator"
12643 [(match_operand 1 "int248_register_operand" "0")
12645 (const_int 8)]) 0)) 0))
12646 (clobber (reg:CC FLAGS_REG))]
12647 "/* FIXME: without this LRA can't reload this pattern, see PR82524. */
12648 rtx_equal_p (operands[0], operands[1])"
12650 [(set_attr "type" "negnot")
12651 (set_attr "mode" "QI")])
12653 ;; Negate with jump on overflow.
12654 (define_expand "negv<mode>3"
12655 [(parallel [(set (reg:CCO FLAGS_REG)
12657 [(match_operand:SWI 1 "register_operand")
12658 (match_dup 3)] UNSPEC_CC_NE))
12659 (set (match_operand:SWI 0 "register_operand")
12660 (neg:SWI (match_dup 1)))])
12661 (set (pc) (if_then_else
12662 (eq (reg:CCO FLAGS_REG) (const_int 0))
12663 (label_ref (match_operand 2))
12668 = gen_int_mode (HOST_WIDE_INT_1U << (GET_MODE_BITSIZE (<MODE>mode) - 1),
12672 (define_insn "*negv<mode>3"
12673 [(set (reg:CCO FLAGS_REG)
12674 (unspec:CCO [(match_operand:SWI 1 "nonimmediate_operand" "0")
12675 (match_operand:SWI 2 "const_int_operand")]
12677 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
12678 (neg:SWI (match_dup 1)))]
12679 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)
12680 && mode_signbit_p (<MODE>mode, operands[2])"
12681 "neg{<imodesuffix>}\t%0"
12682 [(set_attr "type" "negnot")
12683 (set_attr "mode" "<MODE>")])
12685 ;; Optimize *negsi_1 followed by *cmpsi_ccno_1 (PR target/91384)
12687 [(set (match_operand:SWI 0 "general_reg_operand")
12688 (match_operand:SWI 1 "general_reg_operand"))
12689 (parallel [(set (match_dup 0) (neg:SWI (match_dup 0)))
12690 (clobber (reg:CC FLAGS_REG))])
12691 (set (reg:CCZ FLAGS_REG) (compare:CCZ (match_dup 1) (const_int 0)))]
12693 [(set (match_dup 0) (match_dup 1))
12694 (parallel [(set (reg:CCZ FLAGS_REG)
12695 (compare:CCZ (neg:SWI (match_dup 0)) (const_int 0)))
12696 (set (match_dup 0) (neg:SWI (match_dup 0)))])])
12698 ;; Special expand pattern to handle integer mode abs
12700 (define_expand "abs<mode>2"
12702 [(set (match_operand:SDWIM 0 "register_operand")
12704 (match_operand:SDWIM 1 "general_operand")))
12705 (clobber (reg:CC FLAGS_REG))])]
12707 && (<MODE>mode != QImode || !TARGET_PARTIAL_REG_STALL)"
12709 if (TARGET_EXPAND_ABS)
12711 machine_mode mode = <MODE>mode;
12712 operands[1] = force_reg (mode, operands[1]);
12714 /* Generate rtx abs using:
12715 abs (x) = (((signed) x >> (W-1)) ^ x) - ((signed) x >> (W-1)) */
12717 rtx shift_amount = gen_int_mode (GET_MODE_PRECISION (mode) - 1, QImode);
12718 rtx shift_dst = expand_simple_binop (mode, ASHIFTRT, operands[1],
12719 shift_amount, NULL_RTX,
12721 rtx xor_dst = expand_simple_binop (mode, XOR, shift_dst, operands[1],
12722 operands[0], 0, OPTAB_DIRECT);
12723 rtx minus_dst = expand_simple_binop (mode, MINUS, xor_dst, shift_dst,
12724 operands[0], 0, OPTAB_DIRECT);
12725 if (!rtx_equal_p (minus_dst, operands[0]))
12726 emit_move_insn (operands[0], minus_dst);
12731 (define_insn_and_split "*abs<dwi>2_doubleword"
12732 [(set (match_operand:<DWI> 0 "register_operand")
12734 (match_operand:<DWI> 1 "general_operand")))
12735 (clobber (reg:CC FLAGS_REG))]
12737 && ix86_pre_reload_split ()"
12741 [(set (reg:CCC FLAGS_REG)
12742 (unspec:CCC [(match_dup 1) (const_int 0)] UNSPEC_CC_NE))
12743 (set (match_dup 2) (neg:DWIH (match_dup 1)))])
12745 [(set (match_dup 5)
12746 (plus:DWIH (plus:DWIH (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
12749 (clobber (reg:CC FLAGS_REG))])
12751 [(set (reg:CCGOC FLAGS_REG)
12753 (neg:DWIH (match_dup 5))
12756 (neg:DWIH (match_dup 5)))])
12759 (ge (reg:CCGOC FLAGS_REG) (const_int 0))
12764 (ge (reg:CCGOC FLAGS_REG) (const_int 0))
12768 operands[1] = force_reg (<DWI>mode, operands[1]);
12769 operands[2] = gen_reg_rtx (<DWI>mode);
12771 split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
12774 (define_insn_and_split "*nabs<dwi>2_doubleword"
12775 [(set (match_operand:<DWI> 0 "register_operand")
12778 (match_operand:<DWI> 1 "general_operand"))))
12779 (clobber (reg:CC FLAGS_REG))]
12781 && ix86_pre_reload_split ()"
12785 [(set (reg:CCC FLAGS_REG)
12786 (unspec:CCC [(match_dup 1) (const_int 0)] UNSPEC_CC_NE))
12787 (set (match_dup 2) (neg:DWIH (match_dup 1)))])
12789 [(set (match_dup 5)
12790 (plus:DWIH (plus:DWIH (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
12793 (clobber (reg:CC FLAGS_REG))])
12795 [(set (reg:CCGOC FLAGS_REG)
12797 (neg:DWIH (match_dup 5))
12800 (neg:DWIH (match_dup 5)))])
12803 (lt (reg:CCGOC FLAGS_REG) (const_int 0))
12808 (lt (reg:CCGOC FLAGS_REG) (const_int 0))
12812 operands[1] = force_reg (<DWI>mode, operands[1]);
12813 operands[2] = gen_reg_rtx (<DWI>mode);
12815 split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
12818 (define_insn_and_split "*abs<mode>2_1"
12819 [(set (match_operand:SWI 0 "register_operand")
12821 (match_operand:SWI 1 "general_operand")))
12822 (clobber (reg:CC FLAGS_REG))]
12824 && (<MODE>mode != QImode || !TARGET_PARTIAL_REG_STALL)
12825 && ix86_pre_reload_split ()"
12829 [(set (reg:CCGOC FLAGS_REG)
12831 (neg:SWI (match_dup 1))
12834 (neg:SWI (match_dup 1)))])
12837 (ge (reg:CCGOC FLAGS_REG) (const_int 0))
12841 operands[1] = force_reg (<MODE>mode, operands[1]);
12842 operands[2] = gen_reg_rtx (<MODE>mode);
12845 (define_insn_and_split "*nabs<mode>2_1"
12846 [(set (match_operand:SWI 0 "register_operand")
12849 (match_operand:SWI 1 "general_operand"))))
12850 (clobber (reg:CC FLAGS_REG))]
12852 && (<MODE>mode != QImode || !TARGET_PARTIAL_REG_STALL)
12853 && ix86_pre_reload_split ()"
12857 [(set (reg:CCGOC FLAGS_REG)
12859 (neg:SWI (match_dup 1))
12862 (neg:SWI (match_dup 1)))])
12865 (lt (reg:CCGOC FLAGS_REG) (const_int 0))
12869 operands[1] = force_reg (<MODE>mode, operands[1]);
12870 operands[2] = gen_reg_rtx (<MODE>mode);
12873 (define_expand "<code>tf2"
12874 [(set (match_operand:TF 0 "register_operand")
12875 (absneg:TF (match_operand:TF 1 "register_operand")))]
12877 "ix86_expand_fp_absneg_operator (<CODE>, TFmode, operands); DONE;")
12879 (define_insn_and_split "*<code>tf2_1"
12880 [(set (match_operand:TF 0 "register_operand" "=x,x,Yv,Yv")
12882 (match_operand:TF 1 "vector_operand" "0,xBm,Yv,m")))
12883 (use (match_operand:TF 2 "vector_operand" "xBm,0,Yvm,Yv"))]
12886 "&& reload_completed"
12887 [(set (match_dup 0)
12888 (<absneg_op>:TF (match_dup 1) (match_dup 2)))]
12892 if (MEM_P (operands[1]))
12893 std::swap (operands[1], operands[2]);
12897 if (operands_match_p (operands[0], operands[2]))
12898 std::swap (operands[1], operands[2]);
12901 [(set_attr "isa" "noavx,noavx,avx,avx")])
12903 (define_insn_and_split "*nabstf2_1"
12904 [(set (match_operand:TF 0 "register_operand" "=x,x,Yv,Yv")
12907 (match_operand:TF 1 "vector_operand" "0,xBm,Yv,m"))))
12908 (use (match_operand:TF 2 "vector_operand" "xBm,0,Yvm,Yv"))]
12911 "&& reload_completed"
12912 [(set (match_dup 0)
12913 (ior:TF (match_dup 1) (match_dup 2)))]
12917 if (MEM_P (operands[1]))
12918 std::swap (operands[1], operands[2]);
12922 if (operands_match_p (operands[0], operands[2]))
12923 std::swap (operands[1], operands[2]);
12926 [(set_attr "isa" "noavx,noavx,avx,avx")])
12928 (define_expand "<code>hf2"
12929 [(set (match_operand:HF 0 "register_operand")
12930 (absneg:HF (match_operand:HF 1 "register_operand")))]
12931 "TARGET_AVX512FP16"
12932 "ix86_expand_fp_absneg_operator (<CODE>, HFmode, operands); DONE;")
12934 (define_expand "<code><mode>2"
12935 [(set (match_operand:X87MODEF 0 "register_operand")
12936 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand")))]
12937 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
12938 "ix86_expand_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
12940 ;; Changing of sign for FP values is doable using integer unit too.
12941 (define_insn "*<code><mode>2_i387_1"
12942 [(set (match_operand:X87MODEF 0 "register_operand" "=f,!r")
12944 (match_operand:X87MODEF 1 "register_operand" "0,0")))
12945 (clobber (reg:CC FLAGS_REG))]
12946 "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
12950 [(set (match_operand:X87MODEF 0 "fp_register_operand")
12951 (absneg:X87MODEF (match_operand:X87MODEF 1 "fp_register_operand")))
12952 (clobber (reg:CC FLAGS_REG))]
12953 "TARGET_80387 && reload_completed"
12954 [(set (match_dup 0) (absneg:X87MODEF (match_dup 1)))])
12957 [(set (match_operand:X87MODEF 0 "general_reg_operand")
12958 (absneg:X87MODEF (match_operand:X87MODEF 1 "general_reg_operand")))
12959 (clobber (reg:CC FLAGS_REG))]
12960 "TARGET_80387 && reload_completed"
12962 "ix86_split_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
12964 (define_insn_and_split "*<code>hf2_1"
12965 [(set (match_operand:HF 0 "register_operand" "=Yv")
12967 (match_operand:HF 1 "register_operand" "Yv")))
12968 (use (match_operand:V8HF 2 "vector_operand" "Yvm"))
12969 (clobber (reg:CC FLAGS_REG))]
12970 "TARGET_AVX512FP16"
12972 "&& reload_completed"
12973 [(set (match_dup 0)
12974 (<absneg_op>:V8HF (match_dup 1) (match_dup 2)))]
12976 operands[0] = lowpart_subreg (V8HFmode, operands[0], HFmode);
12977 operands[1] = lowpart_subreg (V8HFmode, operands[1], HFmode);
12980 (define_insn "*<code><mode>2_1"
12981 [(set (match_operand:MODEF 0 "register_operand" "=x,x,Yv,f,!r")
12983 (match_operand:MODEF 1 "register_operand" "0,x,Yv,0,0")))
12984 (use (match_operand:<ssevecmode> 2 "vector_operand" "xBm,0,Yvm,X,X"))
12985 (clobber (reg:CC FLAGS_REG))]
12986 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
12988 [(set_attr "isa" "noavx,noavx,avx,*,*")
12989 (set (attr "enabled")
12991 (match_test ("SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"))
12993 (eq_attr "alternative" "3,4")
12994 (symbol_ref "TARGET_MIX_SSE_I387")
12995 (const_string "*"))
12997 (eq_attr "alternative" "3,4")
12998 (symbol_ref "true")
12999 (symbol_ref "false"))))])
13002 [(set (match_operand:MODEF 0 "sse_reg_operand")
13004 (match_operand:MODEF 1 "sse_reg_operand")))
13005 (use (match_operand:<ssevecmodef> 2 "vector_operand"))
13006 (clobber (reg:CC FLAGS_REG))]
13007 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13008 && reload_completed"
13009 [(set (match_dup 0)
13010 (<absneg_op>:<ssevecmodef> (match_dup 1) (match_dup 2)))]
13012 machine_mode mode = <MODE>mode;
13013 machine_mode vmode = <ssevecmodef>mode;
13015 operands[0] = lowpart_subreg (vmode, operands[0], mode);
13016 operands[1] = lowpart_subreg (vmode, operands[1], mode);
13018 if (!TARGET_AVX && operands_match_p (operands[0], operands[2]))
13019 std::swap (operands[1], operands[2]);
13023 [(set (match_operand:MODEF 0 "fp_register_operand")
13024 (absneg:MODEF (match_operand:MODEF 1 "fp_register_operand")))
13025 (use (match_operand 2))
13026 (clobber (reg:CC FLAGS_REG))]
13027 "TARGET_80387 && reload_completed"
13028 [(set (match_dup 0) (absneg:MODEF (match_dup 1)))])
13031 [(set (match_operand:MODEF 0 "general_reg_operand")
13032 (absneg:MODEF (match_operand:MODEF 1 "general_reg_operand")))
13033 (use (match_operand 2))
13034 (clobber (reg:CC FLAGS_REG))]
13035 "TARGET_80387 && reload_completed"
13037 "ix86_split_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
13039 (define_insn_and_split "*nabs<mode>2_1"
13040 [(set (match_operand:MODEF 0 "register_operand" "=x,x,Yv")
13043 (match_operand:MODEF 1 "register_operand" "0,x,Yv"))))
13044 (use (match_operand:<ssevecmode> 2 "vector_operand" "xBm,0,Yvm"))]
13045 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
13047 "&& reload_completed"
13048 [(set (match_dup 0)
13049 (ior:<ssevecmodef> (match_dup 1) (match_dup 2)))]
13051 machine_mode mode = <MODE>mode;
13052 machine_mode vmode = <ssevecmodef>mode;
13054 operands[0] = lowpart_subreg (vmode, operands[0], mode);
13055 operands[1] = lowpart_subreg (vmode, operands[1], mode);
13057 if (!TARGET_AVX && operands_match_p (operands[0], operands[2]))
13058 std::swap (operands[1], operands[2]);
13060 [(set_attr "isa" "noavx,noavx,avx")])
13062 ;; Conditionalize these after reload. If they match before reload, we
13063 ;; lose the clobber and ability to use integer instructions.
13065 (define_insn "*<code><mode>2_i387"
13066 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
13067 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "0")))]
13068 "TARGET_80387 && reload_completed"
13069 "<absneg_mnemonic>"
13070 [(set_attr "type" "fsgn")
13071 (set_attr "mode" "<MODE>")])
13073 ;; Copysign instructions
13075 (define_expand "copysign<mode>3"
13076 [(match_operand:SSEMODEF 0 "register_operand")
13077 (match_operand:SSEMODEF 1 "nonmemory_operand")
13078 (match_operand:SSEMODEF 2 "register_operand")]
13079 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13080 || (TARGET_SSE && (<MODE>mode == TFmode))
13081 || (TARGET_AVX512FP16 && (<MODE>mode ==HFmode))"
13082 "ix86_expand_copysign (operands); DONE;")
13084 (define_expand "xorsign<mode>3"
13085 [(match_operand:MODEFH 0 "register_operand")
13086 (match_operand:MODEFH 1 "register_operand")
13087 (match_operand:MODEFH 2 "register_operand")]
13088 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13089 || <MODE>mode == HFmode"
13091 if (rtx_equal_p (operands[1], operands[2]))
13092 emit_insn (gen_abs<mode>2 (operands[0], operands[1]));
13094 ix86_expand_xorsign (operands);
13098 ;; One complement instructions
13100 (define_expand "one_cmpl<mode>2"
13101 [(set (match_operand:SDWIM 0 "nonimmediate_operand")
13102 (not:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")))]
13104 "ix86_expand_unary_operator (NOT, <MODE>mode, operands); DONE;")
13106 (define_insn_and_split "*one_cmpl<dwi>2_doubleword"
13107 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro")
13108 (not:<DWI> (match_operand:<DWI> 1 "nonimmediate_operand" "0")))]
13109 "ix86_unary_operator_ok (NOT, <DWI>mode, operands)"
13111 "&& reload_completed"
13112 [(set (match_dup 0)
13113 (not:DWIH (match_dup 1)))
13115 (not:DWIH (match_dup 3)))]
13116 "split_double_mode (<DWI>mode, &operands[0], 2, &operands[0], &operands[2]);")
13118 (define_insn "*one_cmpl<mode>2_1"
13119 [(set (match_operand:SWI248 0 "nonimmediate_operand" "=rm,?k")
13120 (not:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "0,k")))]
13121 "ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
13123 not{<imodesuffix>}\t%0
13126 (cond [(eq_attr "alternative" "1")
13127 (if_then_else (eq_attr "mode" "SI,DI")
13128 (const_string "avx512bw")
13129 (const_string "avx512f"))
13131 (const_string "*")))
13132 (set_attr "type" "negnot,msklog")
13133 (set_attr "mode" "<MODE>")])
13135 (define_insn "*one_cmplsi2_1_zext"
13136 [(set (match_operand:DI 0 "register_operand" "=r,?k")
13138 (not:SI (match_operand:SI 1 "register_operand" "0,k"))))]
13139 "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
13143 [(set_attr "isa" "x64,avx512bw")
13144 (set_attr "type" "negnot,msklog")
13145 (set_attr "mode" "SI,SI")])
13147 (define_insn "*one_cmplqi2_1"
13148 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,?k")
13149 (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,k")))]
13150 "ix86_unary_operator_ok (NOT, QImode, operands)"
13155 [(set_attr "isa" "*,*,avx512f")
13156 (set_attr "type" "negnot,negnot,msklog")
13158 (cond [(eq_attr "alternative" "1")
13159 (const_string "SI")
13160 (and (eq_attr "alternative" "2")
13161 (match_test "!TARGET_AVX512DQ"))
13162 (const_string "HI")
13164 (const_string "QI")))
13165 ;; Potential partial reg stall on alternative 1.
13166 (set (attr "preferred_for_speed")
13167 (cond [(eq_attr "alternative" "1")
13168 (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
13169 (symbol_ref "true")))])
13171 ;; Alternative 1 is needed to work around LRA limitation, see PR82524.
13172 (define_insn_and_split "*one_cmpl<mode>_1_slp"
13173 [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>,&<r>"))
13174 (not:SWI12 (match_operand:SWI12 1 "register_operand" "0,!<r>")))]
13175 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
13177 not{<imodesuffix>}\t%0
13179 "&& reload_completed"
13180 [(set (strict_low_part (match_dup 0)) (match_dup 1))
13181 (set (strict_low_part (match_dup 0))
13182 (not:SWI12 (match_dup 0)))]
13184 [(set_attr "type" "negnot")
13185 (set_attr "mode" "<MODE>")])
13187 (define_insn "*one_cmpl<mode>2_2"
13188 [(set (reg FLAGS_REG)
13189 (compare (not:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
13191 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
13192 (not:SWI (match_dup 1)))]
13193 "ix86_match_ccmode (insn, CCNOmode)
13194 && ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
13196 [(set_attr "type" "alu1")
13197 (set_attr "mode" "<MODE>")])
13200 [(set (match_operand 0 "flags_reg_operand")
13201 (match_operator 2 "compare_operator"
13202 [(not:SWI (match_operand:SWI 3 "nonimmediate_operand"))
13204 (set (match_operand:SWI 1 "nonimmediate_operand")
13205 (not:SWI (match_dup 3)))]
13206 "ix86_match_ccmode (insn, CCNOmode)"
13207 [(parallel [(set (match_dup 0)
13208 (match_op_dup 2 [(xor:SWI (match_dup 3) (const_int -1))
13211 (xor:SWI (match_dup 3) (const_int -1)))])])
13213 (define_insn "*one_cmplsi2_2_zext"
13214 [(set (reg FLAGS_REG)
13215 (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
13217 (set (match_operand:DI 0 "register_operand" "=r")
13218 (zero_extend:DI (not:SI (match_dup 1))))]
13219 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
13220 && ix86_unary_operator_ok (NOT, SImode, operands)"
13222 [(set_attr "type" "alu1")
13223 (set_attr "mode" "SI")])
13226 [(set (match_operand 0 "flags_reg_operand")
13227 (match_operator 2 "compare_operator"
13228 [(not:SI (match_operand:SI 3 "register_operand"))
13230 (set (match_operand:DI 1 "register_operand")
13231 (zero_extend:DI (not:SI (match_dup 3))))]
13232 "ix86_match_ccmode (insn, CCNOmode)"
13233 [(parallel [(set (match_dup 0)
13234 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
13237 (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])])
13239 ;; Shift instructions
13241 ;; DImode shifts are implemented using the i386 "shift double" opcode,
13242 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem". If the shift count
13243 ;; is variable, then the count is in %cl and the "imm" operand is dropped
13244 ;; from the assembler input.
13246 ;; This instruction shifts the target reg/mem as usual, but instead of
13247 ;; shifting in zeros, bits are shifted in from reg operand. If the insn
13248 ;; is a left shift double, bits are taken from the high order bits of
13249 ;; reg, else if the insn is a shift right double, bits are taken from the
13250 ;; low order bits of reg. So if %eax is "1234" and %edx is "5678",
13251 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
13253 ;; Since sh[lr]d does not change the `reg' operand, that is done
13254 ;; separately, making all shifts emit pairs of shift double and normal
13255 ;; shift. Since sh[lr]d does not shift more than 31 bits, and we wish to
13256 ;; support a 63 bit shift, each shift where the count is in a reg expands
13257 ;; to a pair of shifts, a branch, a shift by 32 and a label.
13259 ;; If the shift count is a constant, we need never emit more than one
13260 ;; shift pair, instead using moves and sign extension for counts greater
13263 (define_expand "ashl<mode>3"
13264 [(set (match_operand:SDWIM 0 "<shift_operand>")
13265 (ashift:SDWIM (match_operand:SDWIM 1 "<ashl_input_operand>")
13266 (match_operand:QI 2 "nonmemory_operand")))]
13268 "ix86_expand_binary_operator (ASHIFT, <MODE>mode, operands); DONE;")
13270 (define_insn_and_split "*ashl<dwi>3_doubleword_mask"
13271 [(set (match_operand:<DWI> 0 "register_operand")
13273 (match_operand:<DWI> 1 "register_operand")
13276 (match_operand 2 "int248_register_operand" "c")
13277 (match_operand 3 "const_int_operand")) 0)))
13278 (clobber (reg:CC FLAGS_REG))]
13279 "((INTVAL (operands[3]) & (<MODE_SIZE> * BITS_PER_UNIT)) == 0
13280 || ((INTVAL (operands[3]) & (2 * <MODE_SIZE> * BITS_PER_UNIT - 1))
13281 == (2 * <MODE_SIZE> * BITS_PER_UNIT - 1)))
13282 && ix86_pre_reload_split ()"
13286 [(set (match_dup 6)
13287 (ior:DWIH (ashift:DWIH (match_dup 6)
13288 (and:QI (match_dup 2) (match_dup 8)))
13290 (lshiftrt:<DWI> (zero_extend:<DWI> (match_dup 5))
13291 (minus:QI (match_dup 9)
13292 (and:QI (match_dup 2) (match_dup 8)))) 0)))
13293 (clobber (reg:CC FLAGS_REG))])
13295 [(set (match_dup 4)
13296 (ashift:DWIH (match_dup 5) (match_dup 2)))
13297 (clobber (reg:CC FLAGS_REG))])]
13299 if ((INTVAL (operands[3]) & (<MODE_SIZE> * BITS_PER_UNIT)) != 0)
13301 operands[2] = force_reg (GET_MODE (operands[2]), operands[2]);
13302 operands[2] = gen_lowpart (QImode, operands[2]);
13303 emit_insn (gen_ashl<dwi>3_doubleword (operands[0], operands[1],
13308 split_double_mode (<DWI>mode, &operands[0], 2, &operands[4], &operands[6]);
13310 operands[8] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT - 1);
13311 operands[9] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT);
13313 if ((INTVAL (operands[3]) & ((<MODE_SIZE> * BITS_PER_UNIT) - 1))
13314 != ((<MODE_SIZE> * BITS_PER_UNIT) - 1))
13317 xops[0] = gen_reg_rtx (GET_MODE (operands[2]));
13318 xops[1] = operands[2];
13319 xops[2] = GEN_INT (INTVAL (operands[3])
13320 & ((<MODE_SIZE> * BITS_PER_UNIT) - 1));
13321 ix86_expand_binary_operator (AND, GET_MODE (operands[2]), xops);
13322 operands[2] = xops[0];
13325 operands[2] = force_reg (GET_MODE (operands[2]), operands[2]);
13326 operands[2] = gen_lowpart (QImode, operands[2]);
13328 if (!rtx_equal_p (operands[6], operands[7]))
13329 emit_move_insn (operands[6], operands[7]);
13332 (define_insn_and_split "*ashl<dwi>3_doubleword_mask_1"
13333 [(set (match_operand:<DWI> 0 "register_operand")
13335 (match_operand:<DWI> 1 "register_operand")
13337 (match_operand:QI 2 "register_operand" "c")
13338 (match_operand:QI 3 "const_int_operand"))))
13339 (clobber (reg:CC FLAGS_REG))]
13340 "((INTVAL (operands[3]) & (<MODE_SIZE> * BITS_PER_UNIT)) == 0
13341 || ((INTVAL (operands[3]) & (2 * <MODE_SIZE> * BITS_PER_UNIT - 1))
13342 == (2 * <MODE_SIZE> * BITS_PER_UNIT - 1)))
13343 && ix86_pre_reload_split ()"
13347 [(set (match_dup 6)
13348 (ior:DWIH (ashift:DWIH (match_dup 6)
13349 (and:QI (match_dup 2) (match_dup 8)))
13351 (lshiftrt:<DWI> (zero_extend:<DWI> (match_dup 5))
13352 (minus:QI (match_dup 9)
13353 (and:QI (match_dup 2) (match_dup 8)))) 0)))
13354 (clobber (reg:CC FLAGS_REG))])
13356 [(set (match_dup 4)
13357 (ashift:DWIH (match_dup 5) (match_dup 2)))
13358 (clobber (reg:CC FLAGS_REG))])]
13360 if ((INTVAL (operands[3]) & (<MODE_SIZE> * BITS_PER_UNIT)) != 0)
13362 emit_insn (gen_ashl<dwi>3_doubleword (operands[0], operands[1],
13367 split_double_mode (<DWI>mode, &operands[0], 2, &operands[4], &operands[6]);
13369 operands[8] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT - 1);
13370 operands[9] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT);
13372 if ((INTVAL (operands[3]) & ((<MODE_SIZE> * BITS_PER_UNIT) - 1))
13373 != ((<MODE_SIZE> * BITS_PER_UNIT) - 1))
13375 rtx tem = gen_reg_rtx (QImode);
13376 emit_insn (gen_andqi3 (tem, operands[2], operands[3]));
13380 if (!rtx_equal_p (operands[6], operands[7]))
13381 emit_move_insn (operands[6], operands[7]);
13384 (define_insn "ashl<mode>3_doubleword"
13385 [(set (match_operand:DWI 0 "register_operand" "=&r")
13386 (ashift:DWI (match_operand:DWI 1 "reg_or_pm1_operand" "0n")
13387 (match_operand:QI 2 "nonmemory_operand" "<S>c")))
13388 (clobber (reg:CC FLAGS_REG))]
13391 [(set_attr "type" "multi")])
13394 [(set (match_operand:DWI 0 "register_operand")
13395 (ashift:DWI (match_operand:DWI 1 "nonmemory_operand")
13396 (match_operand:QI 2 "nonmemory_operand")))
13397 (clobber (reg:CC FLAGS_REG))]
13398 "epilogue_completed"
13400 "ix86_split_ashl (operands, NULL_RTX, <MODE>mode); DONE;")
13402 ;; By default we don't ask for a scratch register, because when DWImode
13403 ;; values are manipulated, registers are already at a premium. But if
13404 ;; we have one handy, we won't turn it away.
13407 [(match_scratch:DWIH 3 "r")
13408 (parallel [(set (match_operand:<DWI> 0 "register_operand")
13410 (match_operand:<DWI> 1 "nonmemory_operand")
13411 (match_operand:QI 2 "nonmemory_operand")))
13412 (clobber (reg:CC FLAGS_REG))])
13416 "ix86_split_ashl (operands, operands[3], <DWI>mode); DONE;")
13418 (define_insn_and_split "*ashl<dwi>3_doubleword_highpart"
13419 [(set (match_operand:<DWI> 0 "register_operand" "=r")
13421 (any_extend:<DWI> (match_operand:DWIH 1 "nonimmediate_operand" "rm"))
13422 (match_operand:QI 2 "const_int_operand")))
13423 (clobber (reg:CC FLAGS_REG))]
13424 "INTVAL (operands[2]) >= <MODE_SIZE> * BITS_PER_UNIT
13425 && INTVAL (operands[2]) < <MODE_SIZE> * BITS_PER_UNIT * 2"
13427 "&& reload_completed"
13430 split_double_mode (<DWI>mode, &operands[0], 1, &operands[0], &operands[3]);
13431 int bits = INTVAL (operands[2]) - (<MODE_SIZE> * BITS_PER_UNIT);
13432 if (!rtx_equal_p (operands[3], operands[1]))
13433 emit_move_insn (operands[3], operands[1]);
13435 emit_insn (gen_ashl<mode>3 (operands[3], operands[3], GEN_INT (bits)));
13436 ix86_expand_clear (operands[0]);
13440 (define_insn "x86_64_shld"
13441 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
13442 (ior:DI (ashift:DI (match_dup 0)
13443 (and:QI (match_operand:QI 2 "nonmemory_operand" "Jc")
13448 (match_operand:DI 1 "register_operand" "r"))
13449 (minus:QI (const_int 64)
13450 (and:QI (match_dup 2) (const_int 63)))) 0)))
13451 (clobber (reg:CC FLAGS_REG))]
13453 "shld{q}\t{%s2%1, %0|%0, %1, %2}"
13454 [(set_attr "type" "ishift")
13455 (set_attr "prefix_0f" "1")
13456 (set_attr "mode" "DI")
13457 (set_attr "athlon_decode" "vector")
13458 (set_attr "amdfam10_decode" "vector")
13459 (set_attr "bdver1_decode" "vector")])
13461 (define_insn "x86_64_shld_1"
13462 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
13463 (ior:DI (ashift:DI (match_dup 0)
13464 (match_operand:QI 2 "const_0_to_63_operand"))
13468 (match_operand:DI 1 "register_operand" "r"))
13469 (match_operand:QI 3 "const_0_to_255_operand")) 0)))
13470 (clobber (reg:CC FLAGS_REG))]
13472 && INTVAL (operands[3]) == 64 - INTVAL (operands[2])"
13473 "shld{q}\t{%2, %1, %0|%0, %1, %2}"
13474 [(set_attr "type" "ishift")
13475 (set_attr "prefix_0f" "1")
13476 (set_attr "mode" "DI")
13477 (set_attr "length_immediate" "1")
13478 (set_attr "athlon_decode" "vector")
13479 (set_attr "amdfam10_decode" "vector")
13480 (set_attr "bdver1_decode" "vector")])
13482 (define_insn_and_split "*x86_64_shld_shrd_1_nozext"
13483 [(set (match_operand:DI 0 "nonimmediate_operand")
13484 (ior:DI (ashift:DI (match_operand:DI 4 "nonimmediate_operand")
13485 (match_operand:QI 2 "const_0_to_63_operand"))
13487 (match_operand:DI 1 "nonimmediate_operand")
13488 (match_operand:QI 3 "const_0_to_63_operand"))))
13489 (clobber (reg:CC FLAGS_REG))]
13491 && INTVAL (operands[3]) == 64 - INTVAL (operands[2])
13492 && ix86_pre_reload_split ()"
13497 if (rtx_equal_p (operands[4], operands[0]))
13499 operands[1] = force_reg (DImode, operands[1]);
13500 emit_insn (gen_x86_64_shld_1 (operands[0], operands[1], operands[2], operands[3]));
13502 else if (rtx_equal_p (operands[1], operands[0]))
13504 operands[4] = force_reg (DImode, operands[4]);
13505 emit_insn (gen_x86_64_shrd_1 (operands[0], operands[4], operands[3], operands[2]));
13509 operands[1] = force_reg (DImode, operands[1]);
13510 rtx tmp = gen_reg_rtx (DImode);
13511 emit_move_insn (tmp, operands[4]);
13512 emit_insn (gen_x86_64_shld_1 (tmp, operands[1], operands[2], operands[3]));
13513 emit_move_insn (operands[0], tmp);
13518 (define_insn_and_split "*x86_64_shld_2"
13519 [(set (match_operand:DI 0 "nonimmediate_operand")
13520 (ior:DI (ashift:DI (match_dup 0)
13521 (match_operand:QI 2 "nonmemory_operand"))
13522 (lshiftrt:DI (match_operand:DI 1 "register_operand")
13523 (minus:QI (const_int 64) (match_dup 2)))))
13524 (clobber (reg:CC FLAGS_REG))]
13525 "TARGET_64BIT && ix86_pre_reload_split ()"
13528 [(parallel [(set (match_dup 0)
13529 (ior:DI (ashift:DI (match_dup 0)
13530 (and:QI (match_dup 2) (const_int 63)))
13533 (zero_extend:TI (match_dup 1))
13534 (minus:QI (const_int 64)
13535 (and:QI (match_dup 2)
13536 (const_int 63)))) 0)))
13537 (clobber (reg:CC FLAGS_REG))])])
13539 (define_insn "x86_shld"
13540 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
13541 (ior:SI (ashift:SI (match_dup 0)
13542 (and:QI (match_operand:QI 2 "nonmemory_operand" "Ic")
13547 (match_operand:SI 1 "register_operand" "r"))
13548 (minus:QI (const_int 32)
13549 (and:QI (match_dup 2) (const_int 31)))) 0)))
13550 (clobber (reg:CC FLAGS_REG))]
13552 "shld{l}\t{%s2%1, %0|%0, %1, %2}"
13553 [(set_attr "type" "ishift")
13554 (set_attr "prefix_0f" "1")
13555 (set_attr "mode" "SI")
13556 (set_attr "pent_pair" "np")
13557 (set_attr "athlon_decode" "vector")
13558 (set_attr "amdfam10_decode" "vector")
13559 (set_attr "bdver1_decode" "vector")])
13561 (define_insn "x86_shld_1"
13562 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
13563 (ior:SI (ashift:SI (match_dup 0)
13564 (match_operand:QI 2 "const_0_to_31_operand"))
13568 (match_operand:SI 1 "register_operand" "r"))
13569 (match_operand:QI 3 "const_0_to_63_operand")) 0)))
13570 (clobber (reg:CC FLAGS_REG))]
13571 "INTVAL (operands[3]) == 32 - INTVAL (operands[2])"
13572 "shld{l}\t{%2, %1, %0|%0, %1, %2}"
13573 [(set_attr "type" "ishift")
13574 (set_attr "prefix_0f" "1")
13575 (set_attr "length_immediate" "1")
13576 (set_attr "mode" "SI")
13577 (set_attr "pent_pair" "np")
13578 (set_attr "athlon_decode" "vector")
13579 (set_attr "amdfam10_decode" "vector")
13580 (set_attr "bdver1_decode" "vector")])
13582 (define_insn_and_split "*x86_shld_shrd_1_nozext"
13583 [(set (match_operand:SI 0 "nonimmediate_operand")
13584 (ior:SI (ashift:SI (match_operand:SI 4 "nonimmediate_operand")
13585 (match_operand:QI 2 "const_0_to_31_operand"))
13587 (match_operand:SI 1 "nonimmediate_operand")
13588 (match_operand:QI 3 "const_0_to_31_operand"))))
13589 (clobber (reg:CC FLAGS_REG))]
13590 "INTVAL (operands[3]) == 32 - INTVAL (operands[2])
13591 && ix86_pre_reload_split ()"
13596 if (rtx_equal_p (operands[4], operands[0]))
13598 operands[1] = force_reg (SImode, operands[1]);
13599 emit_insn (gen_x86_shld_1 (operands[0], operands[1], operands[2], operands[3]));
13601 else if (rtx_equal_p (operands[1], operands[0]))
13603 operands[4] = force_reg (SImode, operands[4]);
13604 emit_insn (gen_x86_shrd_1 (operands[0], operands[4], operands[3], operands[2]));
13608 operands[1] = force_reg (SImode, operands[1]);
13609 rtx tmp = gen_reg_rtx (SImode);
13610 emit_move_insn (tmp, operands[4]);
13611 emit_insn (gen_x86_shld_1 (tmp, operands[1], operands[2], operands[3]));
13612 emit_move_insn (operands[0], tmp);
13617 (define_insn_and_split "*x86_shld_2"
13618 [(set (match_operand:SI 0 "nonimmediate_operand")
13619 (ior:SI (ashift:SI (match_dup 0)
13620 (match_operand:QI 2 "nonmemory_operand"))
13621 (lshiftrt:SI (match_operand:SI 1 "register_operand")
13622 (minus:QI (const_int 32) (match_dup 2)))))
13623 (clobber (reg:CC FLAGS_REG))]
13624 "TARGET_64BIT && ix86_pre_reload_split ()"
13627 [(parallel [(set (match_dup 0)
13628 (ior:SI (ashift:SI (match_dup 0)
13629 (and:QI (match_dup 2) (const_int 31)))
13632 (zero_extend:DI (match_dup 1))
13633 (minus:QI (const_int 32)
13634 (and:QI (match_dup 2)
13635 (const_int 31)))) 0)))
13636 (clobber (reg:CC FLAGS_REG))])])
13638 (define_expand "@x86_shift<mode>_adj_1"
13639 [(set (reg:CCZ FLAGS_REG)
13640 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand")
13643 (set (match_operand:SWI48 0 "register_operand")
13644 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
13645 (match_operand:SWI48 1 "register_operand")
13648 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
13649 (match_operand:SWI48 3 "register_operand")
13652 "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
13654 (define_expand "@x86_shift<mode>_adj_2"
13655 [(use (match_operand:SWI48 0 "register_operand"))
13656 (use (match_operand:SWI48 1 "register_operand"))
13657 (use (match_operand:QI 2 "register_operand"))]
13660 rtx_code_label *label = gen_label_rtx ();
13663 emit_insn (gen_testqi_ccz_1 (operands[2],
13664 GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
13666 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
13667 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
13668 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
13669 gen_rtx_LABEL_REF (VOIDmode, label),
13671 tmp = emit_jump_insn (gen_rtx_SET (pc_rtx, tmp));
13672 JUMP_LABEL (tmp) = label;
13674 emit_move_insn (operands[0], operands[1]);
13675 ix86_expand_clear (operands[1]);
13677 emit_label (label);
13678 LABEL_NUSES (label) = 1;
13683 ;; Avoid useless masking of count operand.
13684 (define_insn_and_split "*ashl<mode>3_mask"
13685 [(set (match_operand:SWI48 0 "nonimmediate_operand")
13687 (match_operand:SWI48 1 "nonimmediate_operand")
13690 (match_operand 2 "int248_register_operand" "c,r")
13691 (match_operand 3 "const_int_operand")) 0)))
13692 (clobber (reg:CC FLAGS_REG))]
13693 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)
13694 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
13695 == GET_MODE_BITSIZE (<MODE>mode)-1
13696 && ix86_pre_reload_split ()"
13700 [(set (match_dup 0)
13701 (ashift:SWI48 (match_dup 1)
13703 (clobber (reg:CC FLAGS_REG))])]
13705 operands[2] = force_reg (GET_MODE (operands[2]), operands[2]);
13706 operands[2] = gen_lowpart (QImode, operands[2]);
13708 [(set_attr "isa" "*,bmi2")])
13710 (define_insn_and_split "*ashl<mode>3_mask_1"
13711 [(set (match_operand:SWI48 0 "nonimmediate_operand")
13713 (match_operand:SWI48 1 "nonimmediate_operand")
13715 (match_operand:QI 2 "register_operand" "c,r")
13716 (match_operand:QI 3 "const_int_operand"))))
13717 (clobber (reg:CC FLAGS_REG))]
13718 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)
13719 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
13720 == GET_MODE_BITSIZE (<MODE>mode)-1
13721 && ix86_pre_reload_split ()"
13725 [(set (match_dup 0)
13726 (ashift:SWI48 (match_dup 1)
13728 (clobber (reg:CC FLAGS_REG))])]
13730 [(set_attr "isa" "*,bmi2")])
13732 (define_insn "*bmi2_ashl<mode>3_1"
13733 [(set (match_operand:SWI48 0 "register_operand" "=r")
13734 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13735 (match_operand:SWI48 2 "register_operand" "r")))]
13737 "shlx\t{%2, %1, %0|%0, %1, %2}"
13738 [(set_attr "type" "ishiftx")
13739 (set_attr "mode" "<MODE>")])
13741 (define_insn "*ashl<mode>3_1"
13742 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r,r,?k")
13743 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,l,rm,k")
13744 (match_operand:QI 2 "nonmemory_operand" "c<S>,M,r,<KS>")))
13745 (clobber (reg:CC FLAGS_REG))]
13746 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
13748 switch (get_attr_type (insn))
13756 gcc_assert (operands[2] == const1_rtx);
13757 gcc_assert (rtx_equal_p (operands[0], operands[1]));
13758 return "add{<imodesuffix>}\t%0, %0";
13761 if (operands[2] == const1_rtx
13762 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
13763 return "sal{<imodesuffix>}\t%0";
13765 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
13768 [(set_attr "isa" "*,*,bmi2,avx512bw")
13770 (cond [(eq_attr "alternative" "1")
13771 (const_string "lea")
13772 (eq_attr "alternative" "2")
13773 (const_string "ishiftx")
13774 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
13775 (match_operand 0 "register_operand"))
13776 (match_operand 2 "const1_operand"))
13777 (const_string "alu")
13778 (eq_attr "alternative" "3")
13779 (const_string "msklog")
13781 (const_string "ishift")))
13782 (set (attr "length_immediate")
13784 (ior (eq_attr "type" "alu")
13785 (and (eq_attr "type" "ishift")
13786 (and (match_operand 2 "const1_operand")
13787 (ior (match_test "TARGET_SHIFT1")
13788 (match_test "optimize_function_for_size_p (cfun)")))))
13790 (const_string "*")))
13791 (set_attr "mode" "<MODE>")])
13793 ;; Convert shift to the shiftx pattern to avoid flags dependency.
13795 [(set (match_operand:SWI48 0 "register_operand")
13796 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
13797 (match_operand:QI 2 "register_operand")))
13798 (clobber (reg:CC FLAGS_REG))]
13799 "TARGET_BMI2 && reload_completed"
13800 [(set (match_dup 0)
13801 (ashift:SWI48 (match_dup 1) (match_dup 2)))]
13802 "operands[2] = gen_lowpart (<MODE>mode, operands[2]);")
13804 (define_insn "*bmi2_ashlsi3_1_zext"
13805 [(set (match_operand:DI 0 "register_operand" "=r")
13807 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
13808 (match_operand:SI 2 "register_operand" "r"))))]
13809 "TARGET_64BIT && TARGET_BMI2"
13810 "shlx\t{%2, %1, %k0|%k0, %1, %2}"
13811 [(set_attr "type" "ishiftx")
13812 (set_attr "mode" "SI")])
13814 (define_insn "*ashlsi3_1_zext"
13815 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
13817 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l,rm")
13818 (match_operand:QI 2 "nonmemory_operand" "cI,M,r"))))
13819 (clobber (reg:CC FLAGS_REG))]
13820 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
13822 switch (get_attr_type (insn))
13829 gcc_assert (operands[2] == const1_rtx);
13830 return "add{l}\t%k0, %k0";
13833 if (operands[2] == const1_rtx
13834 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
13835 return "sal{l}\t%k0";
13837 return "sal{l}\t{%2, %k0|%k0, %2}";
13840 [(set_attr "isa" "*,*,bmi2")
13842 (cond [(eq_attr "alternative" "1")
13843 (const_string "lea")
13844 (eq_attr "alternative" "2")
13845 (const_string "ishiftx")
13846 (and (match_test "TARGET_DOUBLE_WITH_ADD")
13847 (match_operand 2 "const1_operand"))
13848 (const_string "alu")
13850 (const_string "ishift")))
13851 (set (attr "length_immediate")
13853 (ior (eq_attr "type" "alu")
13854 (and (eq_attr "type" "ishift")
13855 (and (match_operand 2 "const1_operand")
13856 (ior (match_test "TARGET_SHIFT1")
13857 (match_test "optimize_function_for_size_p (cfun)")))))
13859 (const_string "*")))
13860 (set_attr "mode" "SI")])
13862 ;; Convert shift to the shiftx pattern to avoid flags dependency.
13864 [(set (match_operand:DI 0 "register_operand")
13866 (ashift:SI (match_operand:SI 1 "nonimmediate_operand")
13867 (match_operand:QI 2 "register_operand"))))
13868 (clobber (reg:CC FLAGS_REG))]
13869 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
13870 [(set (match_dup 0)
13871 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
13872 "operands[2] = gen_lowpart (SImode, operands[2]);")
13874 (define_insn "*ashlhi3_1"
13875 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,Yp,?k")
13876 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l,k")
13877 (match_operand:QI 2 "nonmemory_operand" "cI,M,Ww")))
13878 (clobber (reg:CC FLAGS_REG))]
13879 "ix86_binary_operator_ok (ASHIFT, HImode, operands)"
13881 switch (get_attr_type (insn))
13888 gcc_assert (operands[2] == const1_rtx);
13889 return "add{w}\t%0, %0";
13892 if (operands[2] == const1_rtx
13893 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
13894 return "sal{w}\t%0";
13896 return "sal{w}\t{%2, %0|%0, %2}";
13899 [(set_attr "isa" "*,*,avx512f")
13901 (cond [(eq_attr "alternative" "1")
13902 (const_string "lea")
13903 (eq_attr "alternative" "2")
13904 (const_string "msklog")
13905 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
13906 (match_operand 0 "register_operand"))
13907 (match_operand 2 "const1_operand"))
13908 (const_string "alu")
13910 (const_string "ishift")))
13911 (set (attr "length_immediate")
13913 (ior (eq_attr "type" "alu")
13914 (and (eq_attr "type" "ishift")
13915 (and (match_operand 2 "const1_operand")
13916 (ior (match_test "TARGET_SHIFT1")
13917 (match_test "optimize_function_for_size_p (cfun)")))))
13919 (const_string "*")))
13920 (set_attr "mode" "HI,SI,HI")])
13922 (define_insn "*ashlqi3_1"
13923 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,Yp,?k")
13924 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l,k")
13925 (match_operand:QI 2 "nonmemory_operand" "cI,cI,M,Wb")))
13926 (clobber (reg:CC FLAGS_REG))]
13927 "ix86_binary_operator_ok (ASHIFT, QImode, operands)"
13929 switch (get_attr_type (insn))
13936 gcc_assert (operands[2] == const1_rtx);
13937 if (REG_P (operands[1]) && !ANY_QI_REGNO_P (REGNO (operands[1])))
13938 return "add{l}\t%k0, %k0";
13940 return "add{b}\t%0, %0";
13943 if (operands[2] == const1_rtx
13944 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
13946 if (get_attr_mode (insn) == MODE_SI)
13947 return "sal{l}\t%k0";
13949 return "sal{b}\t%0";
13953 if (get_attr_mode (insn) == MODE_SI)
13954 return "sal{l}\t{%2, %k0|%k0, %2}";
13956 return "sal{b}\t{%2, %0|%0, %2}";
13960 [(set_attr "isa" "*,*,*,avx512dq")
13962 (cond [(eq_attr "alternative" "2")
13963 (const_string "lea")
13964 (eq_attr "alternative" "3")
13965 (const_string "msklog")
13966 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
13967 (match_operand 0 "register_operand"))
13968 (match_operand 2 "const1_operand"))
13969 (const_string "alu")
13971 (const_string "ishift")))
13972 (set (attr "length_immediate")
13974 (ior (eq_attr "type" "alu")
13975 (and (eq_attr "type" "ishift")
13976 (and (match_operand 2 "const1_operand")
13977 (ior (match_test "TARGET_SHIFT1")
13978 (match_test "optimize_function_for_size_p (cfun)")))))
13980 (const_string "*")))
13981 (set_attr "mode" "QI,SI,SI,QI")
13982 ;; Potential partial reg stall on alternative 1.
13983 (set (attr "preferred_for_speed")
13984 (cond [(eq_attr "alternative" "1")
13985 (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
13986 (symbol_ref "true")))])
13988 ;; Alternative 1 is needed to work around LRA limitation, see PR82524.
13989 (define_insn_and_split "*ashl<mode>3_1_slp"
13990 [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>,&<r>"))
13991 (ashift:SWI12 (match_operand:SWI12 1 "register_operand" "0,!<r>")
13992 (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
13993 (clobber (reg:CC FLAGS_REG))]
13994 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
13996 if (which_alternative)
13999 switch (get_attr_type (insn))
14002 gcc_assert (operands[2] == const1_rtx);
14003 return "add{<imodesuffix>}\t%0, %0";
14006 if (operands[2] == const1_rtx
14007 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
14008 return "sal{<imodesuffix>}\t%0";
14010 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
14013 "&& reload_completed"
14014 [(set (strict_low_part (match_dup 0)) (match_dup 1))
14016 [(set (strict_low_part (match_dup 0))
14017 (ashift:SWI12 (match_dup 0) (match_dup 2)))
14018 (clobber (reg:CC FLAGS_REG))])]
14020 [(set (attr "type")
14021 (cond [(and (match_test "TARGET_DOUBLE_WITH_ADD")
14022 (match_operand 2 "const1_operand"))
14023 (const_string "alu")
14025 (const_string "ishift")))
14026 (set (attr "length_immediate")
14028 (ior (eq_attr "type" "alu")
14029 (and (eq_attr "type" "ishift")
14030 (and (match_operand 2 "const1_operand")
14031 (ior (match_test "TARGET_SHIFT1")
14032 (match_test "optimize_function_for_size_p (cfun)")))))
14034 (const_string "*")))
14035 (set_attr "mode" "<MODE>")])
14037 ;; Convert ashift to the lea pattern to avoid flags dependency.
14039 [(set (match_operand:SWI 0 "general_reg_operand")
14040 (ashift:SWI (match_operand:SWI 1 "index_reg_operand")
14041 (match_operand 2 "const_0_to_3_operand")))
14042 (clobber (reg:CC FLAGS_REG))]
14044 && REGNO (operands[0]) != REGNO (operands[1])"
14045 [(set (match_dup 0)
14046 (mult:<LEAMODE> (match_dup 1) (match_dup 2)))]
14048 if (<MODE>mode != <LEAMODE>mode)
14050 operands[0] = gen_lowpart (<LEAMODE>mode, operands[0]);
14051 operands[1] = gen_lowpart (<LEAMODE>mode, operands[1]);
14053 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
14056 ;; Convert ashift to the lea pattern to avoid flags dependency.
14058 [(set (match_operand:DI 0 "general_reg_operand")
14060 (ashift:SI (match_operand:SI 1 "index_reg_operand")
14061 (match_operand 2 "const_0_to_3_operand"))))
14062 (clobber (reg:CC FLAGS_REG))]
14063 "TARGET_64BIT && reload_completed
14064 && REGNO (operands[0]) != REGNO (operands[1])"
14065 [(set (match_dup 0)
14066 (zero_extend:DI (mult:SI (match_dup 1) (match_dup 2))))]
14068 operands[1] = gen_lowpart (SImode, operands[1]);
14069 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
14072 ;; This pattern can't accept a variable shift count, since shifts by
14073 ;; zero don't affect the flags. We assume that shifts by constant
14074 ;; zero are optimized away.
14075 (define_insn "*ashl<mode>3_cmp"
14076 [(set (reg FLAGS_REG)
14078 (ashift:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
14079 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
14081 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
14082 (ashift:SWI (match_dup 1) (match_dup 2)))]
14083 "(optimize_function_for_size_p (cfun)
14084 || !TARGET_PARTIAL_FLAG_REG_STALL
14085 || (operands[2] == const1_rtx
14087 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
14088 && ix86_match_ccmode (insn, CCGOCmode)
14089 && ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
14091 switch (get_attr_type (insn))
14094 gcc_assert (operands[2] == const1_rtx);
14095 return "add{<imodesuffix>}\t%0, %0";
14098 if (operands[2] == const1_rtx
14099 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
14100 return "sal{<imodesuffix>}\t%0";
14102 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
14105 [(set (attr "type")
14106 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
14107 (match_operand 0 "register_operand"))
14108 (match_operand 2 "const1_operand"))
14109 (const_string "alu")
14111 (const_string "ishift")))
14112 (set (attr "length_immediate")
14114 (ior (eq_attr "type" "alu")
14115 (and (eq_attr "type" "ishift")
14116 (and (match_operand 2 "const1_operand")
14117 (ior (match_test "TARGET_SHIFT1")
14118 (match_test "optimize_function_for_size_p (cfun)")))))
14120 (const_string "*")))
14121 (set_attr "mode" "<MODE>")])
14123 (define_insn "*ashlsi3_cmp_zext"
14124 [(set (reg FLAGS_REG)
14126 (ashift:SI (match_operand:SI 1 "register_operand" "0")
14127 (match_operand:QI 2 "const_1_to_31_operand"))
14129 (set (match_operand:DI 0 "register_operand" "=r")
14130 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
14132 && (optimize_function_for_size_p (cfun)
14133 || !TARGET_PARTIAL_FLAG_REG_STALL
14134 || (operands[2] == const1_rtx
14136 || TARGET_DOUBLE_WITH_ADD)))
14137 && ix86_match_ccmode (insn, CCGOCmode)
14138 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
14140 switch (get_attr_type (insn))
14143 gcc_assert (operands[2] == const1_rtx);
14144 return "add{l}\t%k0, %k0";
14147 if (operands[2] == const1_rtx
14148 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
14149 return "sal{l}\t%k0";
14151 return "sal{l}\t{%2, %k0|%k0, %2}";
14154 [(set (attr "type")
14155 (cond [(and (match_test "TARGET_DOUBLE_WITH_ADD")
14156 (match_operand 2 "const1_operand"))
14157 (const_string "alu")
14159 (const_string "ishift")))
14160 (set (attr "length_immediate")
14162 (ior (eq_attr "type" "alu")
14163 (and (eq_attr "type" "ishift")
14164 (and (match_operand 2 "const1_operand")
14165 (ior (match_test "TARGET_SHIFT1")
14166 (match_test "optimize_function_for_size_p (cfun)")))))
14168 (const_string "*")))
14169 (set_attr "mode" "SI")])
14171 (define_insn "*ashl<mode>3_cconly"
14172 [(set (reg FLAGS_REG)
14174 (ashift:SWI (match_operand:SWI 1 "register_operand" "0")
14175 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
14177 (clobber (match_scratch:SWI 0 "=<r>"))]
14178 "(optimize_function_for_size_p (cfun)
14179 || !TARGET_PARTIAL_FLAG_REG_STALL
14180 || (operands[2] == const1_rtx
14182 || TARGET_DOUBLE_WITH_ADD)))
14183 && ix86_match_ccmode (insn, CCGOCmode)"
14185 switch (get_attr_type (insn))
14188 gcc_assert (operands[2] == const1_rtx);
14189 return "add{<imodesuffix>}\t%0, %0";
14192 if (operands[2] == const1_rtx
14193 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
14194 return "sal{<imodesuffix>}\t%0";
14196 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
14199 [(set (attr "type")
14200 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
14201 (match_operand 0 "register_operand"))
14202 (match_operand 2 "const1_operand"))
14203 (const_string "alu")
14205 (const_string "ishift")))
14206 (set (attr "length_immediate")
14208 (ior (eq_attr "type" "alu")
14209 (and (eq_attr "type" "ishift")
14210 (and (match_operand 2 "const1_operand")
14211 (ior (match_test "TARGET_SHIFT1")
14212 (match_test "optimize_function_for_size_p (cfun)")))))
14214 (const_string "*")))
14215 (set_attr "mode" "<MODE>")])
14217 (define_insn "*ashlqi_ext<mode>_2"
14218 [(set (zero_extract:SWI248
14219 (match_operand 0 "int248_register_operand" "+Q")
14225 (match_operator:SWI248 3 "extract_operator"
14226 [(match_operand 1 "int248_register_operand" "0")
14229 (match_operand:QI 2 "nonmemory_operand" "cI")) 0))
14230 (clobber (reg:CC FLAGS_REG))]
14231 "/* FIXME: without this LRA can't reload this pattern, see PR82524. */
14232 rtx_equal_p (operands[0], operands[1])"
14234 switch (get_attr_type (insn))
14237 gcc_assert (operands[2] == const1_rtx);
14238 return "add{b}\t%h0, %h0";
14241 if (operands[2] == const1_rtx
14242 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
14243 return "sal{b}\t%h0";
14245 return "sal{b}\t{%2, %h0|%h0, %2}";
14248 [(set (attr "type")
14249 (cond [(and (match_test "TARGET_DOUBLE_WITH_ADD")
14250 (match_operand 2 "const1_operand"))
14251 (const_string "alu")
14253 (const_string "ishift")))
14254 (set (attr "length_immediate")
14256 (ior (eq_attr "type" "alu")
14257 (and (eq_attr "type" "ishift")
14258 (and (match_operand 2 "const1_operand")
14259 (ior (match_test "TARGET_SHIFT1")
14260 (match_test "optimize_function_for_size_p (cfun)")))))
14262 (const_string "*")))
14263 (set_attr "mode" "QI")])
14265 ;; See comment above `ashl<mode>3' about how this works.
14267 (define_expand "<insn><mode>3"
14268 [(set (match_operand:SDWIM 0 "<shift_operand>")
14269 (any_shiftrt:SDWIM (match_operand:SDWIM 1 "<shift_operand>")
14270 (match_operand:QI 2 "nonmemory_operand")))]
14272 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
14274 ;; Avoid useless masking of count operand.
14275 (define_insn_and_split "*<insn><mode>3_mask"
14276 [(set (match_operand:SWI48 0 "nonimmediate_operand")
14278 (match_operand:SWI48 1 "nonimmediate_operand")
14281 (match_operand 2 "int248_register_operand" "c,r")
14282 (match_operand 3 "const_int_operand")) 0)))
14283 (clobber (reg:CC FLAGS_REG))]
14284 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
14285 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
14286 == GET_MODE_BITSIZE (<MODE>mode)-1
14287 && ix86_pre_reload_split ()"
14291 [(set (match_dup 0)
14292 (any_shiftrt:SWI48 (match_dup 1)
14294 (clobber (reg:CC FLAGS_REG))])]
14296 operands[2] = force_reg (GET_MODE (operands[2]), operands[2]);
14297 operands[2] = gen_lowpart (QImode, operands[2]);
14299 [(set_attr "isa" "*,bmi2")])
14301 (define_insn_and_split "*<insn><mode>3_mask_1"
14302 [(set (match_operand:SWI48 0 "nonimmediate_operand")
14304 (match_operand:SWI48 1 "nonimmediate_operand")
14306 (match_operand:QI 2 "register_operand" "c,r")
14307 (match_operand:QI 3 "const_int_operand"))))
14308 (clobber (reg:CC FLAGS_REG))]
14309 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
14310 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
14311 == GET_MODE_BITSIZE (<MODE>mode)-1
14312 && ix86_pre_reload_split ()"
14316 [(set (match_dup 0)
14317 (any_shiftrt:SWI48 (match_dup 1)
14319 (clobber (reg:CC FLAGS_REG))])]
14321 [(set_attr "isa" "*,bmi2")])
14323 (define_insn_and_split "*<insn><dwi>3_doubleword_mask"
14324 [(set (match_operand:<DWI> 0 "register_operand")
14326 (match_operand:<DWI> 1 "register_operand")
14329 (match_operand 2 "int248_register_operand" "c")
14330 (match_operand 3 "const_int_operand")) 0)))
14331 (clobber (reg:CC FLAGS_REG))]
14332 "((INTVAL (operands[3]) & (<MODE_SIZE> * BITS_PER_UNIT)) == 0
14333 || ((INTVAL (operands[3]) & (2 * <MODE_SIZE> * BITS_PER_UNIT - 1))
14334 == (2 * <MODE_SIZE> * BITS_PER_UNIT - 1)))
14335 && ix86_pre_reload_split ()"
14339 [(set (match_dup 4)
14340 (ior:DWIH (lshiftrt:DWIH (match_dup 4)
14341 (and:QI (match_dup 2) (match_dup 8)))
14343 (ashift:<DWI> (zero_extend:<DWI> (match_dup 7))
14344 (minus:QI (match_dup 9)
14345 (and:QI (match_dup 2) (match_dup 8)))) 0)))
14346 (clobber (reg:CC FLAGS_REG))])
14348 [(set (match_dup 6)
14349 (any_shiftrt:DWIH (match_dup 7) (match_dup 2)))
14350 (clobber (reg:CC FLAGS_REG))])]
14352 if ((INTVAL (operands[3]) & (<MODE_SIZE> * BITS_PER_UNIT)) != 0)
14354 operands[2] = force_reg (GET_MODE (operands[2]), operands[2]);
14355 operands[2] = gen_lowpart (QImode, operands[2]);
14356 emit_insn (gen_<insn><dwi>3_doubleword (operands[0], operands[1],
14361 split_double_mode (<DWI>mode, &operands[0], 2, &operands[4], &operands[6]);
14363 operands[8] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT - 1);
14364 operands[9] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT);
14366 if ((INTVAL (operands[3]) & ((<MODE_SIZE> * BITS_PER_UNIT) - 1))
14367 != ((<MODE_SIZE> * BITS_PER_UNIT) - 1))
14370 xops[0] = gen_reg_rtx (GET_MODE (operands[2]));
14371 xops[1] = operands[2];
14372 xops[2] = GEN_INT (INTVAL (operands[3])
14373 & ((<MODE_SIZE> * BITS_PER_UNIT) - 1));
14374 ix86_expand_binary_operator (AND, GET_MODE (operands[2]), xops);
14375 operands[2] = xops[0];
14378 operands[2] = force_reg (GET_MODE (operands[2]), operands[2]);
14379 operands[2] = gen_lowpart (QImode, operands[2]);
14381 if (!rtx_equal_p (operands[4], operands[5]))
14382 emit_move_insn (operands[4], operands[5]);
14385 (define_insn_and_split "*<insn><dwi>3_doubleword_mask_1"
14386 [(set (match_operand:<DWI> 0 "register_operand")
14388 (match_operand:<DWI> 1 "register_operand")
14390 (match_operand:QI 2 "register_operand" "c")
14391 (match_operand:QI 3 "const_int_operand"))))
14392 (clobber (reg:CC FLAGS_REG))]
14393 "((INTVAL (operands[3]) & (<MODE_SIZE> * BITS_PER_UNIT)) == 0
14394 || ((INTVAL (operands[3]) & (2 * <MODE_SIZE> * BITS_PER_UNIT - 1))
14395 == (2 * <MODE_SIZE> * BITS_PER_UNIT - 1)))
14396 && ix86_pre_reload_split ()"
14400 [(set (match_dup 4)
14401 (ior:DWIH (lshiftrt:DWIH (match_dup 4)
14402 (and:QI (match_dup 2) (match_dup 8)))
14404 (ashift:<DWI> (zero_extend:<DWI> (match_dup 7))
14405 (minus:QI (match_dup 9)
14406 (and:QI (match_dup 2) (match_dup 8)))) 0)))
14407 (clobber (reg:CC FLAGS_REG))])
14409 [(set (match_dup 6)
14410 (any_shiftrt:DWIH (match_dup 7) (match_dup 2)))
14411 (clobber (reg:CC FLAGS_REG))])]
14413 if ((INTVAL (operands[3]) & (<MODE_SIZE> * BITS_PER_UNIT)) != 0)
14415 emit_insn (gen_<insn><dwi>3_doubleword (operands[0], operands[1],
14420 split_double_mode (<DWI>mode, &operands[0], 2, &operands[4], &operands[6]);
14422 operands[8] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT - 1);
14423 operands[9] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT);
14425 if ((INTVAL (operands[3]) & ((<MODE_SIZE> * BITS_PER_UNIT) - 1))
14426 != ((<MODE_SIZE> * BITS_PER_UNIT) - 1))
14428 rtx tem = gen_reg_rtx (QImode);
14429 emit_insn (gen_andqi3 (tem, operands[2], operands[3]));
14433 if (!rtx_equal_p (operands[4], operands[5]))
14434 emit_move_insn (operands[4], operands[5]);
14437 (define_insn_and_split "<insn><mode>3_doubleword"
14438 [(set (match_operand:DWI 0 "register_operand" "=&r")
14439 (any_shiftrt:DWI (match_operand:DWI 1 "register_operand" "0")
14440 (match_operand:QI 2 "nonmemory_operand" "<S>c")))
14441 (clobber (reg:CC FLAGS_REG))]
14444 "epilogue_completed"
14446 "ix86_split_<insn> (operands, NULL_RTX, <MODE>mode); DONE;"
14447 [(set_attr "type" "multi")])
14449 ;; By default we don't ask for a scratch register, because when DWImode
14450 ;; values are manipulated, registers are already at a premium. But if
14451 ;; we have one handy, we won't turn it away.
14454 [(match_scratch:DWIH 3 "r")
14455 (parallel [(set (match_operand:<DWI> 0 "register_operand")
14457 (match_operand:<DWI> 1 "register_operand")
14458 (match_operand:QI 2 "nonmemory_operand")))
14459 (clobber (reg:CC FLAGS_REG))])
14463 "ix86_split_<insn> (operands, operands[3], <DWI>mode); DONE;")
14465 (define_insn "x86_64_shrd"
14466 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
14467 (ior:DI (lshiftrt:DI (match_dup 0)
14468 (and:QI (match_operand:QI 2 "nonmemory_operand" "Jc")
14473 (match_operand:DI 1 "register_operand" "r"))
14474 (minus:QI (const_int 64)
14475 (and:QI (match_dup 2) (const_int 63)))) 0)))
14476 (clobber (reg:CC FLAGS_REG))]
14478 "shrd{q}\t{%s2%1, %0|%0, %1, %2}"
14479 [(set_attr "type" "ishift")
14480 (set_attr "prefix_0f" "1")
14481 (set_attr "mode" "DI")
14482 (set_attr "athlon_decode" "vector")
14483 (set_attr "amdfam10_decode" "vector")
14484 (set_attr "bdver1_decode" "vector")])
14486 (define_insn "x86_64_shrd_1"
14487 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
14488 (ior:DI (lshiftrt:DI (match_dup 0)
14489 (match_operand:QI 2 "const_0_to_63_operand"))
14493 (match_operand:DI 1 "register_operand" "r"))
14494 (match_operand:QI 3 "const_0_to_255_operand")) 0)))
14495 (clobber (reg:CC FLAGS_REG))]
14497 && INTVAL (operands[3]) == 64 - INTVAL (operands[2])"
14498 "shrd{q}\t{%2, %1, %0|%0, %1, %2}"
14499 [(set_attr "type" "ishift")
14500 (set_attr "prefix_0f" "1")
14501 (set_attr "length_immediate" "1")
14502 (set_attr "mode" "DI")
14503 (set_attr "athlon_decode" "vector")
14504 (set_attr "amdfam10_decode" "vector")
14505 (set_attr "bdver1_decode" "vector")])
14507 (define_insn_and_split "*x86_64_shrd_shld_1_nozext"
14508 [(set (match_operand:DI 0 "nonimmediate_operand")
14509 (ior:DI (lshiftrt:DI (match_operand:DI 4 "nonimmediate_operand")
14510 (match_operand:QI 2 "const_0_to_63_operand"))
14512 (match_operand:DI 1 "nonimmediate_operand")
14513 (match_operand:QI 3 "const_0_to_63_operand"))))
14514 (clobber (reg:CC FLAGS_REG))]
14516 && INTVAL (operands[3]) == 64 - INTVAL (operands[2])
14517 && ix86_pre_reload_split ()"
14522 if (rtx_equal_p (operands[4], operands[0]))
14524 operands[1] = force_reg (DImode, operands[1]);
14525 emit_insn (gen_x86_64_shrd_1 (operands[0], operands[1], operands[2], operands[3]));
14527 else if (rtx_equal_p (operands[1], operands[0]))
14529 operands[4] = force_reg (DImode, operands[4]);
14530 emit_insn (gen_x86_64_shld_1 (operands[0], operands[4], operands[3], operands[2]));
14534 operands[1] = force_reg (DImode, operands[1]);
14535 rtx tmp = gen_reg_rtx (DImode);
14536 emit_move_insn (tmp, operands[4]);
14537 emit_insn (gen_x86_64_shrd_1 (tmp, operands[1], operands[2], operands[3]));
14538 emit_move_insn (operands[0], tmp);
14543 (define_insn_and_split "*x86_64_shrd_2"
14544 [(set (match_operand:DI 0 "nonimmediate_operand")
14545 (ior:DI (lshiftrt:DI (match_dup 0)
14546 (match_operand:QI 2 "nonmemory_operand"))
14547 (ashift:DI (match_operand:DI 1 "register_operand")
14548 (minus:QI (const_int 64) (match_dup 2)))))
14549 (clobber (reg:CC FLAGS_REG))]
14550 "TARGET_64BIT && ix86_pre_reload_split ()"
14553 [(parallel [(set (match_dup 0)
14554 (ior:DI (lshiftrt:DI (match_dup 0)
14555 (and:QI (match_dup 2) (const_int 63)))
14558 (zero_extend:TI (match_dup 1))
14559 (minus:QI (const_int 64)
14560 (and:QI (match_dup 2)
14561 (const_int 63)))) 0)))
14562 (clobber (reg:CC FLAGS_REG))])])
14564 (define_insn "x86_shrd"
14565 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
14566 (ior:SI (lshiftrt:SI (match_dup 0)
14567 (and:QI (match_operand:QI 2 "nonmemory_operand" "Ic")
14572 (match_operand:SI 1 "register_operand" "r"))
14573 (minus:QI (const_int 32)
14574 (and:QI (match_dup 2) (const_int 31)))) 0)))
14575 (clobber (reg:CC FLAGS_REG))]
14577 "shrd{l}\t{%s2%1, %0|%0, %1, %2}"
14578 [(set_attr "type" "ishift")
14579 (set_attr "prefix_0f" "1")
14580 (set_attr "mode" "SI")
14581 (set_attr "pent_pair" "np")
14582 (set_attr "athlon_decode" "vector")
14583 (set_attr "amdfam10_decode" "vector")
14584 (set_attr "bdver1_decode" "vector")])
14586 (define_insn "x86_shrd_1"
14587 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
14588 (ior:SI (lshiftrt:SI (match_dup 0)
14589 (match_operand:QI 2 "const_0_to_31_operand"))
14593 (match_operand:SI 1 "register_operand" "r"))
14594 (match_operand:QI 3 "const_0_to_63_operand")) 0)))
14595 (clobber (reg:CC FLAGS_REG))]
14596 "INTVAL (operands[3]) == 32 - INTVAL (operands[2])"
14597 "shrd{l}\t{%2, %1, %0|%0, %1, %2}"
14598 [(set_attr "type" "ishift")
14599 (set_attr "prefix_0f" "1")
14600 (set_attr "length_immediate" "1")
14601 (set_attr "mode" "SI")
14602 (set_attr "pent_pair" "np")
14603 (set_attr "athlon_decode" "vector")
14604 (set_attr "amdfam10_decode" "vector")
14605 (set_attr "bdver1_decode" "vector")])
14607 (define_insn_and_split "*x86_shrd_shld_1_nozext"
14608 [(set (match_operand:SI 0 "nonimmediate_operand")
14609 (ior:SI (lshiftrt:SI (match_operand:SI 4 "nonimmediate_operand")
14610 (match_operand:QI 2 "const_0_to_31_operand"))
14612 (match_operand:SI 1 "nonimmediate_operand")
14613 (match_operand:QI 3 "const_0_to_31_operand"))))
14614 (clobber (reg:CC FLAGS_REG))]
14615 "INTVAL (operands[3]) == 32 - INTVAL (operands[2])
14616 && ix86_pre_reload_split ()"
14621 if (rtx_equal_p (operands[4], operands[0]))
14623 operands[1] = force_reg (SImode, operands[1]);
14624 emit_insn (gen_x86_shrd_1 (operands[0], operands[1], operands[2], operands[3]));
14626 else if (rtx_equal_p (operands[1], operands[0]))
14628 operands[4] = force_reg (SImode, operands[4]);
14629 emit_insn (gen_x86_shld_1 (operands[0], operands[4], operands[3], operands[2]));
14633 operands[1] = force_reg (SImode, operands[1]);
14634 rtx tmp = gen_reg_rtx (SImode);
14635 emit_move_insn (tmp, operands[4]);
14636 emit_insn (gen_x86_shrd_1 (tmp, operands[1], operands[2], operands[3]));
14637 emit_move_insn (operands[0], tmp);
14642 (define_insn_and_split "*x86_shrd_2"
14643 [(set (match_operand:SI 0 "nonimmediate_operand")
14644 (ior:SI (lshiftrt:SI (match_dup 0)
14645 (match_operand:QI 2 "nonmemory_operand"))
14646 (ashift:SI (match_operand:SI 1 "register_operand")
14647 (minus:QI (const_int 32) (match_dup 2)))))
14648 (clobber (reg:CC FLAGS_REG))]
14649 "TARGET_64BIT && ix86_pre_reload_split ()"
14652 [(parallel [(set (match_dup 0)
14653 (ior:SI (lshiftrt:SI (match_dup 0)
14654 (and:QI (match_dup 2) (const_int 31)))
14657 (zero_extend:DI (match_dup 1))
14658 (minus:QI (const_int 32)
14659 (and:QI (match_dup 2)
14660 (const_int 31)))) 0)))
14661 (clobber (reg:CC FLAGS_REG))])])
14663 ;; Base name for insn mnemonic.
14664 (define_mode_attr cvt_mnemonic
14665 [(SI "{cltd|cdq}") (DI "{cqto|cqo}")])
14667 (define_insn "ashr<mode>3_cvt"
14668 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=*d,rm")
14670 (match_operand:SWI48 1 "nonimmediate_operand" "*a,0")
14671 (match_operand:QI 2 "const_int_operand")))
14672 (clobber (reg:CC FLAGS_REG))]
14673 "INTVAL (operands[2]) == GET_MODE_BITSIZE (<MODE>mode)-1
14674 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
14675 && ix86_binary_operator_ok (ASHIFTRT, <MODE>mode, operands)"
14678 sar{<imodesuffix>}\t{%2, %0|%0, %2}"
14679 [(set_attr "type" "imovx,ishift")
14680 (set_attr "prefix_0f" "0,*")
14681 (set_attr "length_immediate" "0,*")
14682 (set_attr "modrm" "0,1")
14683 (set_attr "mode" "<MODE>")])
14685 (define_insn "*ashrsi3_cvt_zext"
14686 [(set (match_operand:DI 0 "register_operand" "=*d,r")
14688 (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
14689 (match_operand:QI 2 "const_int_operand"))))
14690 (clobber (reg:CC FLAGS_REG))]
14691 "TARGET_64BIT && INTVAL (operands[2]) == 31
14692 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
14693 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
14696 sar{l}\t{%2, %k0|%k0, %2}"
14697 [(set_attr "type" "imovx,ishift")
14698 (set_attr "prefix_0f" "0,*")
14699 (set_attr "length_immediate" "0,*")
14700 (set_attr "modrm" "0,1")
14701 (set_attr "mode" "SI")])
14703 (define_expand "@x86_shift<mode>_adj_3"
14704 [(use (match_operand:SWI48 0 "register_operand"))
14705 (use (match_operand:SWI48 1 "register_operand"))
14706 (use (match_operand:QI 2 "register_operand"))]
14709 rtx_code_label *label = gen_label_rtx ();
14712 emit_insn (gen_testqi_ccz_1 (operands[2],
14713 GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
14715 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
14716 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
14717 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
14718 gen_rtx_LABEL_REF (VOIDmode, label),
14720 tmp = emit_jump_insn (gen_rtx_SET (pc_rtx, tmp));
14721 JUMP_LABEL (tmp) = label;
14723 emit_move_insn (operands[0], operands[1]);
14724 emit_insn (gen_ashr<mode>3_cvt (operands[1], operands[1],
14725 GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1)));
14726 emit_label (label);
14727 LABEL_NUSES (label) = 1;
14732 (define_insn "*bmi2_<insn><mode>3_1"
14733 [(set (match_operand:SWI48 0 "register_operand" "=r")
14734 (any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
14735 (match_operand:SWI48 2 "register_operand" "r")))]
14737 "<shift>x\t{%2, %1, %0|%0, %1, %2}"
14738 [(set_attr "type" "ishiftx")
14739 (set_attr "mode" "<MODE>")])
14741 (define_insn "*ashr<mode>3_1"
14742 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
14744 (match_operand:SWI48 1 "nonimmediate_operand" "0,rm")
14745 (match_operand:QI 2 "nonmemory_operand" "c<S>,r")))
14746 (clobber (reg:CC FLAGS_REG))]
14747 "ix86_binary_operator_ok (ASHIFTRT, <MODE>mode, operands)"
14749 switch (get_attr_type (insn))
14755 if (operands[2] == const1_rtx
14756 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
14757 return "sar{<imodesuffix>}\t%0";
14759 return "sar{<imodesuffix>}\t{%2, %0|%0, %2}";
14762 [(set_attr "isa" "*,bmi2")
14763 (set_attr "type" "ishift,ishiftx")
14764 (set (attr "length_immediate")
14766 (and (match_operand 2 "const1_operand")
14767 (ior (match_test "TARGET_SHIFT1")
14768 (match_test "optimize_function_for_size_p (cfun)")))
14770 (const_string "*")))
14771 (set_attr "mode" "<MODE>")])
14773 ;; Specialization of *lshr<mode>3_1 below, extracting the SImode
14774 ;; highpart of a DI to be extracted, but allowing it to be clobbered.
14775 (define_insn_and_split "*highpartdisi2"
14776 [(set (subreg:DI (match_operand:SI 0 "register_operand" "=r,x,?k") 0)
14777 (lshiftrt:DI (match_operand:DI 1 "register_operand" "0,0,k")
14779 (clobber (reg:CC FLAGS_REG))]
14782 "&& reload_completed"
14784 [(set (match_dup 0) (lshiftrt:DI (match_dup 1) (const_int 32)))
14785 (clobber (reg:CC FLAGS_REG))])]
14787 if (SSE_REG_P (operands[0]))
14789 rtx tmp = gen_rtx_REG (V4SImode, REGNO (operands[0]));
14790 emit_insn (gen_sse_shufps_v4si (tmp, tmp, tmp,
14791 const1_rtx, const1_rtx,
14792 GEN_INT (5), GEN_INT (5)));
14795 operands[0] = gen_rtx_REG (DImode, REGNO (operands[0]));
14798 (define_insn "*lshr<mode>3_1"
14799 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r,?k")
14801 (match_operand:SWI48 1 "nonimmediate_operand" "0,rm,k")
14802 (match_operand:QI 2 "nonmemory_operand" "c<S>,r,<KS>")))
14803 (clobber (reg:CC FLAGS_REG))]
14804 "ix86_binary_operator_ok (LSHIFTRT, <MODE>mode, operands)"
14806 switch (get_attr_type (insn))
14813 if (operands[2] == const1_rtx
14814 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
14815 return "shr{<imodesuffix>}\t%0";
14817 return "shr{<imodesuffix>}\t{%2, %0|%0, %2}";
14820 [(set_attr "isa" "*,bmi2,avx512bw")
14821 (set_attr "type" "ishift,ishiftx,msklog")
14822 (set (attr "length_immediate")
14824 (and (and (match_operand 2 "const1_operand")
14825 (eq_attr "alternative" "0"))
14826 (ior (match_test "TARGET_SHIFT1")
14827 (match_test "optimize_function_for_size_p (cfun)")))
14829 (const_string "*")))
14830 (set_attr "mode" "<MODE>")])
14832 ;; Convert shift to the shiftx pattern to avoid flags dependency.
14834 [(set (match_operand:SWI48 0 "register_operand")
14835 (any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
14836 (match_operand:QI 2 "register_operand")))
14837 (clobber (reg:CC FLAGS_REG))]
14838 "TARGET_BMI2 && reload_completed"
14839 [(set (match_dup 0)
14840 (any_shiftrt:SWI48 (match_dup 1) (match_dup 2)))]
14841 "operands[2] = gen_lowpart (<MODE>mode, operands[2]);")
14843 (define_insn "*bmi2_<insn>si3_1_zext"
14844 [(set (match_operand:DI 0 "register_operand" "=r")
14846 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
14847 (match_operand:SI 2 "register_operand" "r"))))]
14848 "TARGET_64BIT && TARGET_BMI2"
14849 "<shift>x\t{%2, %1, %k0|%k0, %1, %2}"
14850 [(set_attr "type" "ishiftx")
14851 (set_attr "mode" "SI")])
14853 (define_insn "*<insn>si3_1_zext"
14854 [(set (match_operand:DI 0 "register_operand" "=r,r")
14856 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm")
14857 (match_operand:QI 2 "nonmemory_operand" "cI,r"))))
14858 (clobber (reg:CC FLAGS_REG))]
14859 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
14861 switch (get_attr_type (insn))
14867 if (operands[2] == const1_rtx
14868 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
14869 return "<shift>{l}\t%k0";
14871 return "<shift>{l}\t{%2, %k0|%k0, %2}";
14874 [(set_attr "isa" "*,bmi2")
14875 (set_attr "type" "ishift,ishiftx")
14876 (set (attr "length_immediate")
14878 (and (match_operand 2 "const1_operand")
14879 (ior (match_test "TARGET_SHIFT1")
14880 (match_test "optimize_function_for_size_p (cfun)")))
14882 (const_string "*")))
14883 (set_attr "mode" "SI")])
14885 ;; Convert shift to the shiftx pattern to avoid flags dependency.
14887 [(set (match_operand:DI 0 "register_operand")
14889 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand")
14890 (match_operand:QI 2 "register_operand"))))
14891 (clobber (reg:CC FLAGS_REG))]
14892 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
14893 [(set (match_dup 0)
14894 (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
14895 "operands[2] = gen_lowpart (SImode, operands[2]);")
14897 (define_insn "*ashr<mode>3_1"
14898 [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m")
14900 (match_operand:SWI12 1 "nonimmediate_operand" "0")
14901 (match_operand:QI 2 "nonmemory_operand" "c<S>")))
14902 (clobber (reg:CC FLAGS_REG))]
14903 "ix86_binary_operator_ok (ASHIFTRT, <MODE>mode, operands)"
14905 if (operands[2] == const1_rtx
14906 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
14907 return "sar{<imodesuffix>}\t%0";
14909 return "sar{<imodesuffix>}\t{%2, %0|%0, %2}";
14911 [(set_attr "type" "ishift")
14912 (set (attr "length_immediate")
14914 (and (match_operand 2 "const1_operand")
14915 (ior (match_test "TARGET_SHIFT1")
14916 (match_test "optimize_function_for_size_p (cfun)")))
14918 (const_string "*")))
14919 (set_attr "mode" "<MODE>")])
14921 (define_insn "*lshrqi3_1"
14922 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,?k")
14924 (match_operand:QI 1 "nonimmediate_operand" "0, k")
14925 (match_operand:QI 2 "nonmemory_operand" "cI,Wb")))
14926 (clobber (reg:CC FLAGS_REG))]
14927 "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
14929 switch (get_attr_type (insn))
14932 if (operands[2] == const1_rtx
14933 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
14934 return "shr{b}\t%0";
14936 return "shr{b}\t{%2, %0|%0, %2}";
14940 gcc_unreachable ();
14943 [(set_attr "isa" "*,avx512dq")
14944 (set_attr "type" "ishift,msklog")
14945 (set (attr "length_immediate")
14947 (and (and (match_operand 2 "const1_operand")
14948 (eq_attr "alternative" "0"))
14949 (ior (match_test "TARGET_SHIFT1")
14950 (match_test "optimize_function_for_size_p (cfun)")))
14952 (const_string "*")))
14953 (set_attr "mode" "QI")])
14955 (define_insn "*lshrhi3_1"
14956 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm, ?k")
14958 (match_operand:HI 1 "nonimmediate_operand" "0, k")
14959 (match_operand:QI 2 "nonmemory_operand" "cI, Ww")))
14960 (clobber (reg:CC FLAGS_REG))]
14961 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
14963 switch (get_attr_type (insn))
14966 if (operands[2] == const1_rtx
14967 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
14968 return "shr{w}\t%0";
14970 return "shr{w}\t{%2, %0|%0, %2}";
14974 gcc_unreachable ();
14977 [(set_attr "isa" "*, avx512f")
14978 (set_attr "type" "ishift,msklog")
14979 (set (attr "length_immediate")
14981 (and (and (match_operand 2 "const1_operand")
14982 (eq_attr "alternative" "0"))
14983 (ior (match_test "TARGET_SHIFT1")
14984 (match_test "optimize_function_for_size_p (cfun)")))
14986 (const_string "*")))
14987 (set_attr "mode" "HI")])
14989 ;; Alternative 1 is needed to work around LRA limitation, see PR82524.
14990 (define_insn_and_split "*<insn><mode>3_1_slp"
14991 [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>,&<r>"))
14992 (any_shiftrt:SWI12 (match_operand:SWI12 1 "register_operand" "0,!<r>")
14993 (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
14994 (clobber (reg:CC FLAGS_REG))]
14995 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
14997 if (which_alternative)
15000 if (operands[2] == const1_rtx
15001 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
15002 return "<shift>{<imodesuffix>}\t%0";
15004 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
15006 "&& reload_completed"
15007 [(set (strict_low_part (match_dup 0)) (match_dup 1))
15009 [(set (strict_low_part (match_dup 0))
15010 (any_shiftrt:SWI12 (match_dup 0) (match_dup 2)))
15011 (clobber (reg:CC FLAGS_REG))])]
15013 [(set_attr "type" "ishift")
15014 (set (attr "length_immediate")
15016 (and (match_operand 2 "const1_operand")
15017 (ior (match_test "TARGET_SHIFT1")
15018 (match_test "optimize_function_for_size_p (cfun)")))
15020 (const_string "*")))
15021 (set_attr "mode" "<MODE>")])
15023 ;; This pattern can't accept a variable shift count, since shifts by
15024 ;; zero don't affect the flags. We assume that shifts by constant
15025 ;; zero are optimized away.
15026 (define_insn "*<insn><mode>3_cmp"
15027 [(set (reg FLAGS_REG)
15030 (match_operand:SWI 1 "nonimmediate_operand" "0")
15031 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
15033 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
15034 (any_shiftrt:SWI (match_dup 1) (match_dup 2)))]
15035 "(optimize_function_for_size_p (cfun)
15036 || !TARGET_PARTIAL_FLAG_REG_STALL
15037 || (operands[2] == const1_rtx
15039 && ix86_match_ccmode (insn, CCGOCmode)
15040 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
15042 if (operands[2] == const1_rtx
15043 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
15044 return "<shift>{<imodesuffix>}\t%0";
15046 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
15048 [(set_attr "type" "ishift")
15049 (set (attr "length_immediate")
15051 (and (match_operand 2 "const1_operand")
15052 (ior (match_test "TARGET_SHIFT1")
15053 (match_test "optimize_function_for_size_p (cfun)")))
15055 (const_string "*")))
15056 (set_attr "mode" "<MODE>")])
15058 (define_insn "*<insn>si3_cmp_zext"
15059 [(set (reg FLAGS_REG)
15061 (any_shiftrt:SI (match_operand:SI 1 "register_operand" "0")
15062 (match_operand:QI 2 "const_1_to_31_operand"))
15064 (set (match_operand:DI 0 "register_operand" "=r")
15065 (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
15067 && (optimize_function_for_size_p (cfun)
15068 || !TARGET_PARTIAL_FLAG_REG_STALL
15069 || (operands[2] == const1_rtx
15071 && ix86_match_ccmode (insn, CCGOCmode)
15072 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
15074 if (operands[2] == const1_rtx
15075 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
15076 return "<shift>{l}\t%k0";
15078 return "<shift>{l}\t{%2, %k0|%k0, %2}";
15080 [(set_attr "type" "ishift")
15081 (set (attr "length_immediate")
15083 (and (match_operand 2 "const1_operand")
15084 (ior (match_test "TARGET_SHIFT1")
15085 (match_test "optimize_function_for_size_p (cfun)")))
15087 (const_string "*")))
15088 (set_attr "mode" "SI")])
15090 (define_insn "*<insn><mode>3_cconly"
15091 [(set (reg FLAGS_REG)
15094 (match_operand:SWI 1 "register_operand" "0")
15095 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
15097 (clobber (match_scratch:SWI 0 "=<r>"))]
15098 "(optimize_function_for_size_p (cfun)
15099 || !TARGET_PARTIAL_FLAG_REG_STALL
15100 || (operands[2] == const1_rtx
15102 && ix86_match_ccmode (insn, CCGOCmode)"
15104 if (operands[2] == const1_rtx
15105 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
15106 return "<shift>{<imodesuffix>}\t%0";
15108 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
15110 [(set_attr "type" "ishift")
15111 (set (attr "length_immediate")
15113 (and (match_operand 2 "const1_operand")
15114 (ior (match_test "TARGET_SHIFT1")
15115 (match_test "optimize_function_for_size_p (cfun)")))
15117 (const_string "*")))
15118 (set_attr "mode" "<MODE>")])
15120 (define_insn "*<insn>qi_ext<mode>_2"
15121 [(set (zero_extract:SWI248
15122 (match_operand 0 "int248_register_operand" "+Q")
15128 (match_operator:SWI248 3 "extract_operator"
15129 [(match_operand 1 "int248_register_operand" "0")
15132 (match_operand:QI 2 "nonmemory_operand" "cI")) 0))
15133 (clobber (reg:CC FLAGS_REG))]
15134 "/* FIXME: without this LRA can't reload this pattern, see PR82524. */
15135 rtx_equal_p (operands[0], operands[1])"
15137 if (operands[2] == const1_rtx
15138 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
15139 return "<shift>{b}\t%h0";
15141 return "<shift>{b}\t{%2, %h0|%h0, %2}";
15143 [(set_attr "type" "ishift")
15144 (set (attr "length_immediate")
15146 (and (match_operand 2 "const1_operand")
15147 (ior (match_test "TARGET_SHIFT1")
15148 (match_test "optimize_function_for_size_p (cfun)")))
15150 (const_string "*")))
15151 (set_attr "mode" "QI")])
15153 ;; Rotate instructions
15155 (define_expand "<insn>ti3"
15156 [(set (match_operand:TI 0 "register_operand")
15157 (any_rotate:TI (match_operand:TI 1 "register_operand")
15158 (match_operand:QI 2 "nonmemory_operand")))]
15161 if (const_1_to_63_operand (operands[2], VOIDmode))
15162 emit_insn (gen_ix86_<insn>ti3_doubleword
15163 (operands[0], operands[1], operands[2]));
15164 else if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) == 64)
15165 emit_insn (gen_<insn>64ti2_doubleword (operands[0], operands[1]));
15168 rtx amount = force_reg (QImode, operands[2]);
15169 rtx src_lo = gen_lowpart (DImode, operands[1]);
15170 rtx src_hi = gen_highpart (DImode, operands[1]);
15171 rtx tmp_lo = gen_reg_rtx (DImode);
15172 rtx tmp_hi = gen_reg_rtx (DImode);
15173 emit_move_insn (tmp_lo, src_lo);
15174 emit_move_insn (tmp_hi, src_hi);
15175 rtx (*shiftd) (rtx, rtx, rtx)
15176 = (<CODE> == ROTATE) ? gen_x86_64_shld : gen_x86_64_shrd;
15177 emit_insn (shiftd (tmp_lo, src_hi, amount));
15178 emit_insn (shiftd (tmp_hi, src_lo, amount));
15179 rtx dst_lo = gen_lowpart (DImode, operands[0]);
15180 rtx dst_hi = gen_highpart (DImode, operands[0]);
15181 emit_move_insn (dst_lo, tmp_lo);
15182 emit_move_insn (dst_hi, tmp_hi);
15183 emit_insn (gen_x86_shiftdi_adj_1 (dst_lo, dst_hi, amount, tmp_lo));
15188 (define_expand "<insn>di3"
15189 [(set (match_operand:DI 0 "shiftdi_operand")
15190 (any_rotate:DI (match_operand:DI 1 "shiftdi_operand")
15191 (match_operand:QI 2 "nonmemory_operand")))]
15195 ix86_expand_binary_operator (<CODE>, DImode, operands);
15196 else if (const_1_to_31_operand (operands[2], VOIDmode))
15197 emit_insn (gen_ix86_<insn>di3_doubleword
15198 (operands[0], operands[1], operands[2]));
15199 else if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) == 32)
15200 emit_insn (gen_<insn>32di2_doubleword (operands[0], operands[1]));
15207 (define_expand "<insn><mode>3"
15208 [(set (match_operand:SWIM124 0 "nonimmediate_operand")
15209 (any_rotate:SWIM124 (match_operand:SWIM124 1 "nonimmediate_operand")
15210 (match_operand:QI 2 "nonmemory_operand")))]
15212 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
15214 ;; Avoid useless masking of count operand.
15215 (define_insn_and_split "*<insn><mode>3_mask"
15216 [(set (match_operand:SWI 0 "nonimmediate_operand")
15218 (match_operand:SWI 1 "nonimmediate_operand")
15221 (match_operand 2 "int248_register_operand" "c")
15222 (match_operand 3 "const_int_operand")) 0)))
15223 (clobber (reg:CC FLAGS_REG))]
15224 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
15225 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
15226 == GET_MODE_BITSIZE (<MODE>mode)-1
15227 && ix86_pre_reload_split ()"
15231 [(set (match_dup 0)
15232 (any_rotate:SWI (match_dup 1)
15234 (clobber (reg:CC FLAGS_REG))])]
15236 operands[2] = force_reg (GET_MODE (operands[2]), operands[2]);
15237 operands[2] = gen_lowpart (QImode, operands[2]);
15241 [(set (match_operand:SWI 0 "register_operand")
15243 (match_operand:SWI 1 "const_int_operand")
15246 (match_operand 2 "int248_register_operand")
15247 (match_operand 3 "const_int_operand")) 0)))]
15248 "(INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode) - 1))
15249 == GET_MODE_BITSIZE (<MODE>mode) - 1"
15250 [(set (match_dup 4) (match_dup 1))
15252 (any_rotate:SWI (match_dup 4)
15253 (subreg:QI (match_dup 2) 0)))]
15254 "operands[4] = gen_reg_rtx (<MODE>mode);")
15256 (define_insn_and_split "*<insn><mode>3_mask_1"
15257 [(set (match_operand:SWI 0 "nonimmediate_operand")
15259 (match_operand:SWI 1 "nonimmediate_operand")
15261 (match_operand:QI 2 "register_operand" "c")
15262 (match_operand:QI 3 "const_int_operand"))))
15263 (clobber (reg:CC FLAGS_REG))]
15264 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
15265 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
15266 == GET_MODE_BITSIZE (<MODE>mode)-1
15267 && ix86_pre_reload_split ()"
15271 [(set (match_dup 0)
15272 (any_rotate:SWI (match_dup 1)
15274 (clobber (reg:CC FLAGS_REG))])])
15277 [(set (match_operand:SWI 0 "register_operand")
15279 (match_operand:SWI 1 "const_int_operand")
15281 (match_operand:QI 2 "register_operand")
15282 (match_operand:QI 3 "const_int_operand"))))]
15283 "(INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode) - 1))
15284 == GET_MODE_BITSIZE (<MODE>mode) - 1"
15285 [(set (match_dup 4) (match_dup 1))
15287 (any_rotate:SWI (match_dup 4) (match_dup 2)))]
15288 "operands[4] = gen_reg_rtx (<MODE>mode);")
15290 ;; Implement rotation using two double-precision
15291 ;; shift instructions and a scratch register.
15293 (define_insn_and_split "ix86_rotl<dwi>3_doubleword"
15294 [(set (match_operand:<DWI> 0 "register_operand" "=r")
15295 (rotate:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
15296 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
15297 (clobber (reg:CC FLAGS_REG))
15298 (clobber (match_scratch:DWIH 3 "=&r"))]
15302 [(set (match_dup 3) (match_dup 4))
15304 [(set (match_dup 4)
15305 (ior:DWIH (ashift:DWIH (match_dup 4)
15306 (and:QI (match_dup 2) (match_dup 6)))
15308 (lshiftrt:<DWI> (zero_extend:<DWI> (match_dup 5))
15309 (minus:QI (match_dup 7)
15310 (and:QI (match_dup 2)
15311 (match_dup 6)))) 0)))
15312 (clobber (reg:CC FLAGS_REG))])
15314 [(set (match_dup 5)
15315 (ior:DWIH (ashift:DWIH (match_dup 5)
15316 (and:QI (match_dup 2) (match_dup 6)))
15318 (lshiftrt:<DWI> (zero_extend:<DWI> (match_dup 3))
15319 (minus:QI (match_dup 7)
15320 (and:QI (match_dup 2)
15321 (match_dup 6)))) 0)))
15322 (clobber (reg:CC FLAGS_REG))])]
15324 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode) - 1);
15325 operands[7] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
15327 split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
15330 (define_insn_and_split "ix86_rotr<dwi>3_doubleword"
15331 [(set (match_operand:<DWI> 0 "register_operand" "=r")
15332 (rotatert:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
15333 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
15334 (clobber (reg:CC FLAGS_REG))
15335 (clobber (match_scratch:DWIH 3 "=&r"))]
15339 [(set (match_dup 3) (match_dup 4))
15341 [(set (match_dup 4)
15342 (ior:DWIH (lshiftrt:DWIH (match_dup 4)
15343 (and:QI (match_dup 2) (match_dup 6)))
15345 (ashift:<DWI> (zero_extend:<DWI> (match_dup 5))
15346 (minus:QI (match_dup 7)
15347 (and:QI (match_dup 2)
15348 (match_dup 6)))) 0)))
15349 (clobber (reg:CC FLAGS_REG))])
15351 [(set (match_dup 5)
15352 (ior:DWIH (lshiftrt:DWIH (match_dup 5)
15353 (and:QI (match_dup 2) (match_dup 6)))
15355 (ashift:<DWI> (zero_extend:<DWI> (match_dup 3))
15356 (minus:QI (match_dup 7)
15357 (and:QI (match_dup 2)
15358 (match_dup 6)))) 0)))
15359 (clobber (reg:CC FLAGS_REG))])]
15361 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode) - 1);
15362 operands[7] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
15364 split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
15367 (define_insn_and_split "<insn>32di2_doubleword"
15368 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
15369 (any_rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0,r,o")
15373 "&& reload_completed"
15374 [(set (match_dup 0) (match_dup 3))
15375 (set (match_dup 2) (match_dup 1))]
15377 split_double_mode (DImode, &operands[0], 2, &operands[0], &operands[2]);
15378 if (rtx_equal_p (operands[0], operands[1]))
15380 emit_insn (gen_swapsi (operands[0], operands[2]));
15385 (define_insn_and_split "<insn>64ti2_doubleword"
15386 [(set (match_operand:TI 0 "register_operand" "=r,r,r")
15387 (any_rotate:TI (match_operand:TI 1 "nonimmediate_operand" "0,r,o")
15391 "&& reload_completed"
15392 [(set (match_dup 0) (match_dup 3))
15393 (set (match_dup 2) (match_dup 1))]
15395 split_double_mode (TImode, &operands[0], 2, &operands[0], &operands[2]);
15396 if (rtx_equal_p (operands[0], operands[1]))
15398 emit_insn (gen_swapdi (operands[0], operands[2]));
15403 (define_mode_attr rorx_immediate_operand
15404 [(SI "const_0_to_31_operand")
15405 (DI "const_0_to_63_operand")])
15407 (define_insn "*bmi2_rorx<mode>3_1"
15408 [(set (match_operand:SWI48 0 "register_operand" "=r")
15410 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
15411 (match_operand:QI 2 "<rorx_immediate_operand>" "<S>")))]
15412 "TARGET_BMI2 && !optimize_function_for_size_p (cfun)"
15413 "rorx\t{%2, %1, %0|%0, %1, %2}"
15414 [(set_attr "type" "rotatex")
15415 (set_attr "mode" "<MODE>")])
15417 (define_insn "*<insn><mode>3_1"
15418 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
15420 (match_operand:SWI48 1 "nonimmediate_operand" "0,rm")
15421 (match_operand:QI 2 "nonmemory_operand" "c<S>,<S>")))
15422 (clobber (reg:CC FLAGS_REG))]
15423 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
15425 switch (get_attr_type (insn))
15431 if (operands[2] == const1_rtx
15432 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
15433 return "<rotate>{<imodesuffix>}\t%0";
15435 return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
15438 [(set_attr "isa" "*,bmi2")
15439 (set_attr "type" "rotate,rotatex")
15440 (set (attr "preferred_for_size")
15441 (cond [(eq_attr "alternative" "0")
15442 (symbol_ref "true")]
15443 (symbol_ref "false")))
15444 (set (attr "length_immediate")
15446 (and (eq_attr "type" "rotate")
15447 (and (match_operand 2 "const1_operand")
15448 (ior (match_test "TARGET_SHIFT1")
15449 (match_test "optimize_function_for_size_p (cfun)"))))
15451 (const_string "*")))
15452 (set_attr "mode" "<MODE>")])
15454 ;; Convert rotate to the rotatex pattern to avoid flags dependency.
15456 [(set (match_operand:SWI48 0 "register_operand")
15457 (rotate:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
15458 (match_operand:QI 2 "const_int_operand")))
15459 (clobber (reg:CC FLAGS_REG))]
15460 "TARGET_BMI2 && reload_completed && !optimize_function_for_size_p (cfun)"
15461 [(set (match_dup 0)
15462 (rotatert:SWI48 (match_dup 1) (match_dup 2)))]
15464 int bitsize = GET_MODE_BITSIZE (<MODE>mode);
15466 operands[2] = GEN_INT ((bitsize - INTVAL (operands[2])) % bitsize);
15470 [(set (match_operand:SWI48 0 "register_operand")
15471 (rotatert:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
15472 (match_operand:QI 2 "const_int_operand")))
15473 (clobber (reg:CC FLAGS_REG))]
15474 "TARGET_BMI2 && reload_completed && !optimize_function_for_size_p (cfun)"
15475 [(set (match_dup 0)
15476 (rotatert:SWI48 (match_dup 1) (match_dup 2)))])
15478 (define_insn "*bmi2_rorxsi3_1_zext"
15479 [(set (match_operand:DI 0 "register_operand" "=r")
15481 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
15482 (match_operand:QI 2 "const_0_to_31_operand"))))]
15483 "TARGET_64BIT && TARGET_BMI2 && !optimize_function_for_size_p (cfun)"
15484 "rorx\t{%2, %1, %k0|%k0, %1, %2}"
15485 [(set_attr "type" "rotatex")
15486 (set_attr "mode" "SI")])
15488 (define_insn "*<insn>si3_1_zext"
15489 [(set (match_operand:DI 0 "register_operand" "=r,r")
15491 (any_rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm")
15492 (match_operand:QI 2 "nonmemory_operand" "cI,I"))))
15493 (clobber (reg:CC FLAGS_REG))]
15494 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
15496 switch (get_attr_type (insn))
15502 if (operands[2] == const1_rtx
15503 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
15504 return "<rotate>{l}\t%k0";
15506 return "<rotate>{l}\t{%2, %k0|%k0, %2}";
15509 [(set_attr "isa" "*,bmi2")
15510 (set_attr "type" "rotate,rotatex")
15511 (set (attr "preferred_for_size")
15512 (cond [(eq_attr "alternative" "0")
15513 (symbol_ref "true")]
15514 (symbol_ref "false")))
15515 (set (attr "length_immediate")
15517 (and (eq_attr "type" "rotate")
15518 (and (match_operand 2 "const1_operand")
15519 (ior (match_test "TARGET_SHIFT1")
15520 (match_test "optimize_function_for_size_p (cfun)"))))
15522 (const_string "*")))
15523 (set_attr "mode" "SI")])
15525 ;; Convert rotate to the rotatex pattern to avoid flags dependency.
15527 [(set (match_operand:DI 0 "register_operand")
15529 (rotate:SI (match_operand:SI 1 "nonimmediate_operand")
15530 (match_operand:QI 2 "const_int_operand"))))
15531 (clobber (reg:CC FLAGS_REG))]
15532 "TARGET_64BIT && TARGET_BMI2 && reload_completed
15533 && !optimize_function_for_size_p (cfun)"
15534 [(set (match_dup 0)
15535 (zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))]
15537 int bitsize = GET_MODE_BITSIZE (SImode);
15539 operands[2] = GEN_INT ((bitsize - INTVAL (operands[2])) % bitsize);
15543 [(set (match_operand:DI 0 "register_operand")
15545 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand")
15546 (match_operand:QI 2 "const_int_operand"))))
15547 (clobber (reg:CC FLAGS_REG))]
15548 "TARGET_64BIT && TARGET_BMI2 && reload_completed
15549 && !optimize_function_for_size_p (cfun)"
15550 [(set (match_dup 0)
15551 (zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))])
15553 (define_insn "*<insn><mode>3_1"
15554 [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m")
15555 (any_rotate:SWI12 (match_operand:SWI12 1 "nonimmediate_operand" "0")
15556 (match_operand:QI 2 "nonmemory_operand" "c<S>")))
15557 (clobber (reg:CC FLAGS_REG))]
15558 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
15560 if (operands[2] == const1_rtx
15561 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
15562 return "<rotate>{<imodesuffix>}\t%0";
15564 return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
15566 [(set_attr "type" "rotate")
15567 (set (attr "length_immediate")
15569 (and (match_operand 2 "const1_operand")
15570 (ior (match_test "TARGET_SHIFT1")
15571 (match_test "optimize_function_for_size_p (cfun)")))
15573 (const_string "*")))
15574 (set_attr "mode" "<MODE>")])
15576 ;; Alternative 1 is needed to work around LRA limitation, see PR82524.
15577 (define_insn_and_split "*<insn><mode>3_1_slp"
15578 [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>,&<r>"))
15579 (any_rotate:SWI12 (match_operand:SWI12 1 "register_operand" "0,!<r>")
15580 (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
15581 (clobber (reg:CC FLAGS_REG))]
15582 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
15584 if (which_alternative)
15587 if (operands[2] == const1_rtx
15588 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
15589 return "<rotate>{<imodesuffix>}\t%0";
15591 return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
15593 "&& reload_completed"
15594 [(set (strict_low_part (match_dup 0)) (match_dup 1))
15596 [(set (strict_low_part (match_dup 0))
15597 (any_rotate:SWI12 (match_dup 0) (match_dup 2)))
15598 (clobber (reg:CC FLAGS_REG))])]
15600 [(set_attr "type" "rotate")
15601 (set (attr "length_immediate")
15603 (and (match_operand 2 "const1_operand")
15604 (ior (match_test "TARGET_SHIFT1")
15605 (match_test "optimize_function_for_size_p (cfun)")))
15607 (const_string "*")))
15608 (set_attr "mode" "<MODE>")])
15611 [(set (match_operand:HI 0 "QIreg_operand")
15612 (any_rotate:HI (match_dup 0) (const_int 8)))
15613 (clobber (reg:CC FLAGS_REG))]
15615 && (TARGET_USE_XCHGB || optimize_function_for_size_p (cfun))"
15616 [(parallel [(set (strict_low_part (match_dup 0))
15617 (bswap:HI (match_dup 0)))
15618 (clobber (reg:CC FLAGS_REG))])])
15620 ;; Bit set / bit test instructions
15622 ;; %%% bts, btr, btc
15624 ;; These instructions are *slow* when applied to memory.
15626 (define_code_attr btsc [(ior "bts") (xor "btc")])
15628 (define_insn "*<btsc><mode>"
15629 [(set (match_operand:SWI48 0 "register_operand" "=r")
15631 (ashift:SWI48 (const_int 1)
15632 (match_operand:QI 2 "register_operand" "r"))
15633 (match_operand:SWI48 1 "register_operand" "0")))
15634 (clobber (reg:CC FLAGS_REG))]
15636 "<btsc>{<imodesuffix>}\t{%<k>2, %0|%0, %<k>2}"
15637 [(set_attr "type" "alu1")
15638 (set_attr "prefix_0f" "1")
15639 (set_attr "znver1_decode" "double")
15640 (set_attr "mode" "<MODE>")])
15642 ;; Avoid useless masking of count operand.
15643 (define_insn_and_split "*<btsc><mode>_mask"
15644 [(set (match_operand:SWI48 0 "register_operand")
15650 (match_operand 1 "int248_register_operand")
15651 (match_operand 2 "const_int_operand")) 0))
15652 (match_operand:SWI48 3 "register_operand")))
15653 (clobber (reg:CC FLAGS_REG))]
15655 && (INTVAL (operands[2]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
15656 == GET_MODE_BITSIZE (<MODE>mode)-1
15657 && ix86_pre_reload_split ()"
15661 [(set (match_dup 0)
15663 (ashift:SWI48 (const_int 1)
15666 (clobber (reg:CC FLAGS_REG))])]
15668 operands[1] = force_reg (GET_MODE (operands[1]), operands[1]);
15669 operands[1] = gen_lowpart (QImode, operands[1]);
15672 (define_insn_and_split "*<btsc><mode>_mask_1"
15673 [(set (match_operand:SWI48 0 "register_operand")
15678 (match_operand:QI 1 "register_operand")
15679 (match_operand:QI 2 "const_int_operand")))
15680 (match_operand:SWI48 3 "register_operand")))
15681 (clobber (reg:CC FLAGS_REG))]
15683 && (INTVAL (operands[2]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
15684 == GET_MODE_BITSIZE (<MODE>mode)-1
15685 && ix86_pre_reload_split ()"
15689 [(set (match_dup 0)
15691 (ashift:SWI48 (const_int 1)
15694 (clobber (reg:CC FLAGS_REG))])])
15696 (define_insn "*btr<mode>"
15697 [(set (match_operand:SWI48 0 "register_operand" "=r")
15699 (rotate:SWI48 (const_int -2)
15700 (match_operand:QI 2 "register_operand" "r"))
15701 (match_operand:SWI48 1 "register_operand" "0")))
15702 (clobber (reg:CC FLAGS_REG))]
15704 "btr{<imodesuffix>}\t{%<k>2, %0|%0, %<k>2}"
15705 [(set_attr "type" "alu1")
15706 (set_attr "prefix_0f" "1")
15707 (set_attr "znver1_decode" "double")
15708 (set_attr "mode" "<MODE>")])
15710 ;; Avoid useless masking of count operand.
15711 (define_insn_and_split "*btr<mode>_mask"
15712 [(set (match_operand:SWI48 0 "register_operand")
15718 (match_operand 1 "int248_register_operand")
15719 (match_operand 2 "const_int_operand")) 0))
15720 (match_operand:SWI48 3 "register_operand")))
15721 (clobber (reg:CC FLAGS_REG))]
15723 && (INTVAL (operands[2]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
15724 == GET_MODE_BITSIZE (<MODE>mode)-1
15725 && ix86_pre_reload_split ()"
15729 [(set (match_dup 0)
15731 (rotate:SWI48 (const_int -2)
15734 (clobber (reg:CC FLAGS_REG))])]
15736 operands[1] = force_reg (GET_MODE (operands[1]), operands[1]);
15737 operands[1] = gen_lowpart (QImode, operands[1]);
15740 (define_insn_and_split "*btr<mode>_mask_1"
15741 [(set (match_operand:SWI48 0 "register_operand")
15746 (match_operand:QI 1 "register_operand")
15747 (match_operand:QI 2 "const_int_operand")))
15748 (match_operand:SWI48 3 "register_operand")))
15749 (clobber (reg:CC FLAGS_REG))]
15751 && (INTVAL (operands[2]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
15752 == GET_MODE_BITSIZE (<MODE>mode)-1
15753 && ix86_pre_reload_split ()"
15757 [(set (match_dup 0)
15759 (rotate:SWI48 (const_int -2)
15762 (clobber (reg:CC FLAGS_REG))])])
15764 (define_insn_and_split "*btr<mode>_1"
15765 [(set (match_operand:SWI12 0 "register_operand")
15768 (rotate:SI (const_int -2)
15769 (match_operand:QI 2 "register_operand")) 0)
15770 (match_operand:SWI12 1 "nonimmediate_operand")))
15771 (clobber (reg:CC FLAGS_REG))]
15772 "TARGET_USE_BT && ix86_pre_reload_split ()"
15776 [(set (match_dup 0)
15777 (and:SI (rotate:SI (const_int -2) (match_dup 2))
15779 (clobber (reg:CC FLAGS_REG))])]
15781 operands[0] = lowpart_subreg (SImode, operands[0], <MODE>mode);
15782 operands[1] = force_reg (<MODE>mode, operands[1]);
15783 operands[1] = lowpart_subreg (SImode, operands[1], <MODE>mode);
15786 (define_insn_and_split "*btr<mode>_2"
15787 [(set (zero_extract:HI
15788 (match_operand:SWI12 0 "nonimmediate_operand")
15790 (zero_extend:SI (match_operand:QI 1 "register_operand")))
15792 (clobber (reg:CC FLAGS_REG))]
15793 "TARGET_USE_BT && ix86_pre_reload_split ()"
15795 "&& MEM_P (operands[0])"
15796 [(set (match_dup 2) (match_dup 0))
15798 [(set (match_dup 3)
15799 (and:SI (rotate:SI (const_int -2) (match_dup 1))
15801 (clobber (reg:CC FLAGS_REG))])
15802 (set (match_dup 0) (match_dup 5))]
15804 operands[2] = gen_reg_rtx (<MODE>mode);
15805 operands[5] = gen_reg_rtx (<MODE>mode);
15806 operands[3] = lowpart_subreg (SImode, operands[5], <MODE>mode);
15807 operands[4] = lowpart_subreg (SImode, operands[2], <MODE>mode);
15811 [(set (zero_extract:HI
15812 (match_operand:SWI12 0 "register_operand")
15814 (zero_extend:SI (match_operand:QI 1 "register_operand")))
15816 (clobber (reg:CC FLAGS_REG))]
15817 "TARGET_USE_BT && ix86_pre_reload_split ()"
15819 [(set (match_dup 0)
15820 (and:SI (rotate:SI (const_int -2) (match_dup 1))
15822 (clobber (reg:CC FLAGS_REG))])]
15824 operands[2] = lowpart_subreg (SImode, operands[0], <MODE>mode);
15825 operands[0] = lowpart_subreg (SImode, operands[0], <MODE>mode);
15828 ;; These instructions are never faster than the corresponding
15829 ;; and/ior/xor operations when using immediate operand, so with
15830 ;; 32-bit there's no point. But in 64-bit, we can't hold the
15831 ;; relevant immediates within the instruction itself, so operating
15832 ;; on bits in the high 32-bits of a register becomes easier.
15834 ;; These are slow on Nocona, but fast on Athlon64. We do require the use
15835 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
15836 ;; negdf respectively, so they can never be disabled entirely.
15838 (define_insn "*btsq_imm"
15839 [(set (zero_extract:DI (match_operand:DI 0 "nonimmediate_operand" "+rm")
15841 (match_operand 1 "const_0_to_63_operand"))
15843 (clobber (reg:CC FLAGS_REG))]
15844 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
15845 "bts{q}\t{%1, %0|%0, %1}"
15846 [(set_attr "type" "alu1")
15847 (set_attr "prefix_0f" "1")
15848 (set_attr "znver1_decode" "double")
15849 (set_attr "mode" "DI")])
15851 (define_insn "*btrq_imm"
15852 [(set (zero_extract:DI (match_operand:DI 0 "nonimmediate_operand" "+rm")
15854 (match_operand 1 "const_0_to_63_operand"))
15856 (clobber (reg:CC FLAGS_REG))]
15857 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
15858 "btr{q}\t{%1, %0|%0, %1}"
15859 [(set_attr "type" "alu1")
15860 (set_attr "prefix_0f" "1")
15861 (set_attr "znver1_decode" "double")
15862 (set_attr "mode" "DI")])
15864 (define_insn "*btcq_imm"
15865 [(set (zero_extract:DI (match_operand:DI 0 "nonimmediate_operand" "+rm")
15867 (match_operand 1 "const_0_to_63_operand"))
15868 (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
15869 (clobber (reg:CC FLAGS_REG))]
15870 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
15871 "btc{q}\t{%1, %0|%0, %1}"
15872 [(set_attr "type" "alu1")
15873 (set_attr "prefix_0f" "1")
15874 (set_attr "znver1_decode" "double")
15875 (set_attr "mode" "DI")])
15877 ;; Allow Nocona to avoid these instructions if a register is available.
15880 [(match_scratch:DI 2 "r")
15881 (parallel [(set (zero_extract:DI
15882 (match_operand:DI 0 "nonimmediate_operand")
15884 (match_operand 1 "const_0_to_63_operand"))
15886 (clobber (reg:CC FLAGS_REG))])]
15887 "TARGET_64BIT && !TARGET_USE_BT"
15888 [(parallel [(set (match_dup 0)
15889 (ior:DI (match_dup 0) (match_dup 3)))
15890 (clobber (reg:CC FLAGS_REG))])]
15892 int i = INTVAL (operands[1]);
15894 operands[3] = gen_int_mode (HOST_WIDE_INT_1U << i, DImode);
15896 if (!x86_64_immediate_operand (operands[3], DImode))
15898 emit_move_insn (operands[2], operands[3]);
15899 operands[3] = operands[2];
15904 [(match_scratch:DI 2 "r")
15905 (parallel [(set (zero_extract:DI
15906 (match_operand:DI 0 "nonimmediate_operand")
15908 (match_operand 1 "const_0_to_63_operand"))
15910 (clobber (reg:CC FLAGS_REG))])]
15911 "TARGET_64BIT && !TARGET_USE_BT"
15912 [(parallel [(set (match_dup 0)
15913 (and:DI (match_dup 0) (match_dup 3)))
15914 (clobber (reg:CC FLAGS_REG))])]
15916 int i = INTVAL (operands[1]);
15918 operands[3] = gen_int_mode (~(HOST_WIDE_INT_1U << i), DImode);
15920 if (!x86_64_immediate_operand (operands[3], DImode))
15922 emit_move_insn (operands[2], operands[3]);
15923 operands[3] = operands[2];
15928 [(match_scratch:DI 2 "r")
15929 (parallel [(set (zero_extract:DI
15930 (match_operand:DI 0 "nonimmediate_operand")
15932 (match_operand 1 "const_0_to_63_operand"))
15933 (not:DI (zero_extract:DI
15934 (match_dup 0) (const_int 1) (match_dup 1))))
15935 (clobber (reg:CC FLAGS_REG))])]
15936 "TARGET_64BIT && !TARGET_USE_BT"
15937 [(parallel [(set (match_dup 0)
15938 (xor:DI (match_dup 0) (match_dup 3)))
15939 (clobber (reg:CC FLAGS_REG))])]
15941 int i = INTVAL (operands[1]);
15943 operands[3] = gen_int_mode (HOST_WIDE_INT_1U << i, DImode);
15945 if (!x86_64_immediate_operand (operands[3], DImode))
15947 emit_move_insn (operands[2], operands[3]);
15948 operands[3] = operands[2];
15954 (define_insn "*bt<mode>"
15955 [(set (reg:CCC FLAGS_REG)
15957 (zero_extract:SWI48
15958 (match_operand:SWI48 0 "nonimmediate_operand" "r,m")
15960 (match_operand:SI 1 "nonmemory_operand" "r<S>,<S>"))
15964 switch (get_attr_mode (insn))
15967 return "bt{l}\t{%1, %k0|%k0, %1}";
15970 return "bt{q}\t{%q1, %0|%0, %q1}";
15973 gcc_unreachable ();
15976 [(set_attr "type" "alu1")
15977 (set_attr "prefix_0f" "1")
15980 (and (match_test "CONST_INT_P (operands[1])")
15981 (match_test "INTVAL (operands[1]) < 32"))
15982 (const_string "SI")
15983 (const_string "<MODE>")))])
15985 (define_insn_and_split "*jcc_bt<mode>"
15987 (if_then_else (match_operator 0 "bt_comparison_operator"
15988 [(zero_extract:SWI48
15989 (match_operand:SWI48 1 "nonimmediate_operand")
15991 (match_operand:SI 2 "nonmemory_operand"))
15993 (label_ref (match_operand 3))
15995 (clobber (reg:CC FLAGS_REG))]
15996 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
15997 && (CONST_INT_P (operands[2])
15998 ? (INTVAL (operands[2]) < GET_MODE_BITSIZE (<MODE>mode)
15999 && INTVAL (operands[2])
16000 >= (optimize_function_for_size_p (cfun) ? 8 : 32))
16001 : !memory_operand (operands[1], <MODE>mode))
16002 && ix86_pre_reload_split ()"
16005 [(set (reg:CCC FLAGS_REG)
16007 (zero_extract:SWI48
16013 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
16014 (label_ref (match_dup 3))
16017 operands[0] = shallow_copy_rtx (operands[0]);
16018 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
16021 (define_insn_and_split "*jcc_bt<mode>_1"
16023 (if_then_else (match_operator 0 "bt_comparison_operator"
16024 [(zero_extract:SWI48
16025 (match_operand:SWI48 1 "register_operand")
16028 (match_operand:QI 2 "register_operand")))
16030 (label_ref (match_operand 3))
16032 (clobber (reg:CC FLAGS_REG))]
16033 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
16034 && ix86_pre_reload_split ()"
16037 [(set (reg:CCC FLAGS_REG)
16039 (zero_extract:SWI48
16045 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
16046 (label_ref (match_dup 3))
16049 operands[2] = lowpart_subreg (SImode, operands[2], QImode);
16050 operands[0] = shallow_copy_rtx (operands[0]);
16051 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
16054 ;; Avoid useless masking of bit offset operand.
16055 (define_insn_and_split "*jcc_bt<mode>_mask"
16057 (if_then_else (match_operator 0 "bt_comparison_operator"
16058 [(zero_extract:SWI48
16059 (match_operand:SWI48 1 "register_operand")
16062 (match_operand:SI 2 "register_operand")
16063 (match_operand 3 "const_int_operand")))])
16064 (label_ref (match_operand 4))
16066 (clobber (reg:CC FLAGS_REG))]
16067 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
16068 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
16069 == GET_MODE_BITSIZE (<MODE>mode)-1
16070 && ix86_pre_reload_split ()"
16073 [(set (reg:CCC FLAGS_REG)
16075 (zero_extract:SWI48
16081 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
16082 (label_ref (match_dup 4))
16085 operands[0] = shallow_copy_rtx (operands[0]);
16086 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
16089 (define_insn_and_split "*jcc_bt<mode>_mask_1"
16091 (if_then_else (match_operator 0 "bt_comparison_operator"
16092 [(zero_extract:SWI48
16093 (match_operand:SWI48 1 "register_operand")
16098 (match_operand 2 "int248_register_operand")
16099 (match_operand 3 "const_int_operand")) 0)))])
16100 (label_ref (match_operand 4))
16102 (clobber (reg:CC FLAGS_REG))]
16103 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
16104 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
16105 == GET_MODE_BITSIZE (<MODE>mode)-1
16106 && ix86_pre_reload_split ()"
16109 [(set (reg:CCC FLAGS_REG)
16111 (zero_extract:SWI48
16117 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
16118 (label_ref (match_dup 4))
16121 operands[2] = force_reg (GET_MODE (operands[2]), operands[2]);
16122 operands[2] = gen_lowpart (SImode, operands[2]);
16123 operands[0] = shallow_copy_rtx (operands[0]);
16124 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
16127 ;; Help combine recognize bt followed by cmov
16129 [(set (match_operand:SWI248 0 "register_operand")
16130 (if_then_else:SWI248
16131 (match_operator 5 "bt_comparison_operator"
16132 [(zero_extract:SWI48
16133 (match_operand:SWI48 1 "register_operand")
16135 (zero_extend:SI (match_operand:QI 2 "register_operand")))
16137 (match_operand:SWI248 3 "nonimmediate_operand")
16138 (match_operand:SWI248 4 "nonimmediate_operand")))]
16139 "TARGET_USE_BT && TARGET_CMOVE
16140 && !(MEM_P (operands[3]) && MEM_P (operands[4]))
16141 && ix86_pre_reload_split ()"
16142 [(set (reg:CCC FLAGS_REG)
16144 (zero_extract:SWI48 (match_dup 1) (const_int 1) (match_dup 2))
16147 (if_then_else:SWI248 (eq (reg:CCC FLAGS_REG) (const_int 0))
16151 if (GET_CODE (operands[5]) == EQ)
16152 std::swap (operands[3], operands[4]);
16153 operands[2] = lowpart_subreg (SImode, operands[2], QImode);
16156 ;; Help combine recognize bt followed by setc
16157 (define_insn_and_split "*bt<mode>_setcqi"
16158 [(set (subreg:SWI48 (match_operand:QI 0 "register_operand") 0)
16159 (zero_extract:SWI48
16160 (match_operand:SWI48 1 "register_operand")
16162 (zero_extend:SI (match_operand:QI 2 "register_operand"))))
16163 (clobber (reg:CC FLAGS_REG))]
16164 "TARGET_USE_BT && ix86_pre_reload_split ()"
16167 [(set (reg:CCC FLAGS_REG)
16169 (zero_extract:SWI48 (match_dup 1) (const_int 1) (match_dup 2))
16172 (eq:QI (reg:CCC FLAGS_REG) (const_int 0)))]
16174 operands[2] = lowpart_subreg (SImode, operands[2], QImode);
16177 ;; Help combine recognize bt followed by setnc
16178 (define_insn_and_split "*bt<mode>_setncqi"
16179 [(set (match_operand:QI 0 "register_operand")
16183 (lshiftrt:SWI48 (match_operand:SWI48 1 "register_operand")
16184 (match_operand:QI 2 "register_operand")) 0))
16186 (clobber (reg:CC FLAGS_REG))]
16187 "TARGET_USE_BT && ix86_pre_reload_split ()"
16190 [(set (reg:CCC FLAGS_REG)
16192 (zero_extract:SWI48 (match_dup 1) (const_int 1) (match_dup 2))
16195 (ne:QI (reg:CCC FLAGS_REG) (const_int 0)))]
16197 operands[2] = lowpart_subreg (SImode, operands[2], QImode);
16200 (define_insn_and_split "*bt<mode>_setnc<mode>"
16201 [(set (match_operand:SWI48 0 "register_operand")
16204 (lshiftrt:SWI48 (match_operand:SWI48 1 "register_operand")
16205 (match_operand:QI 2 "register_operand")))
16207 (clobber (reg:CC FLAGS_REG))]
16208 "TARGET_USE_BT && ix86_pre_reload_split ()"
16211 [(set (reg:CCC FLAGS_REG)
16213 (zero_extract:SWI48 (match_dup 1) (const_int 1) (match_dup 2))
16216 (ne:QI (reg:CCC FLAGS_REG) (const_int 0)))
16217 (set (match_dup 0) (zero_extend:SWI48 (match_dup 3)))]
16219 operands[2] = lowpart_subreg (SImode, operands[2], QImode);
16220 operands[3] = gen_reg_rtx (QImode);
16223 ;; Store-flag instructions.
16226 [(set (match_operand:QI 0 "nonimmediate_operand")
16227 (match_operator:QI 1 "add_comparison_operator"
16228 [(not:SWI (match_operand:SWI 2 "register_operand"))
16229 (match_operand:SWI 3 "nonimmediate_operand")]))]
16231 [(set (reg:CCC FLAGS_REG)
16233 (plus:SWI (match_dup 2) (match_dup 3))
16236 (match_op_dup 1 [(reg:CCC FLAGS_REG) (const_int 0)]))])
16239 [(set (match_operand:QI 0 "nonimmediate_operand")
16240 (match_operator:QI 1 "shr_comparison_operator"
16241 [(match_operand:DI 2 "register_operand")
16242 (match_operand 3 "const_int_operand")]))]
16244 && IN_RANGE (exact_log2 (UINTVAL (operands[3]) + 1), 32, 63)"
16245 [(set (reg:CCZ FLAGS_REG)
16247 (lshiftrt:DI (match_dup 2) (match_dup 4))
16250 (match_op_dup 1 [(reg:CCZ FLAGS_REG) (const_int 0)]))]
16252 enum rtx_code new_code;
16254 operands[1] = shallow_copy_rtx (operands[1]);
16255 switch (GET_CODE (operands[1]))
16257 case GTU: new_code = NE; break;
16258 case LEU: new_code = EQ; break;
16259 default: gcc_unreachable ();
16261 PUT_CODE (operands[1], new_code);
16263 operands[4] = GEN_INT (exact_log2 (UINTVAL (operands[3]) + 1));
16266 ;; For all sCOND expanders, also expand the compare or test insn that
16267 ;; generates cc0. Generate an equality comparison if `seq' or `sne'.
16269 (define_insn_and_split "*setcc_di_1"
16270 [(set (match_operand:DI 0 "register_operand" "=q")
16271 (match_operator:DI 1 "ix86_comparison_operator"
16272 [(reg FLAGS_REG) (const_int 0)]))]
16273 "TARGET_64BIT && !TARGET_PARTIAL_REG_STALL"
16275 "&& reload_completed"
16276 [(set (match_dup 2) (match_dup 1))
16277 (set (match_dup 0) (zero_extend:DI (match_dup 2)))]
16279 operands[1] = shallow_copy_rtx (operands[1]);
16280 PUT_MODE (operands[1], QImode);
16281 operands[2] = gen_lowpart (QImode, operands[0]);
16284 (define_insn_and_split "*setcc_<mode>_1_and"
16285 [(set (match_operand:SWI24 0 "register_operand" "=q")
16286 (match_operator:SWI24 1 "ix86_comparison_operator"
16287 [(reg FLAGS_REG) (const_int 0)]))
16288 (clobber (reg:CC FLAGS_REG))]
16289 "!TARGET_PARTIAL_REG_STALL
16290 && TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
16292 "&& reload_completed"
16293 [(set (match_dup 2) (match_dup 1))
16294 (parallel [(set (match_dup 0) (zero_extend:SWI24 (match_dup 2)))
16295 (clobber (reg:CC FLAGS_REG))])]
16297 operands[1] = shallow_copy_rtx (operands[1]);
16298 PUT_MODE (operands[1], QImode);
16299 operands[2] = gen_lowpart (QImode, operands[0]);
16302 (define_insn_and_split "*setcc_<mode>_1_movzbl"
16303 [(set (match_operand:SWI24 0 "register_operand" "=q")
16304 (match_operator:SWI24 1 "ix86_comparison_operator"
16305 [(reg FLAGS_REG) (const_int 0)]))]
16306 "!TARGET_PARTIAL_REG_STALL
16307 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
16309 "&& reload_completed"
16310 [(set (match_dup 2) (match_dup 1))
16311 (set (match_dup 0) (zero_extend:SWI24 (match_dup 2)))]
16313 operands[1] = shallow_copy_rtx (operands[1]);
16314 PUT_MODE (operands[1], QImode);
16315 operands[2] = gen_lowpart (QImode, operands[0]);
16318 (define_insn "*setcc_qi"
16319 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
16320 (match_operator:QI 1 "ix86_comparison_operator"
16321 [(reg FLAGS_REG) (const_int 0)]))]
16324 [(set_attr "type" "setcc")
16325 (set_attr "mode" "QI")])
16327 (define_insn "*setcc_qi_slp"
16328 [(set (strict_low_part (match_operand:QI 0 "register_operand" "+q"))
16329 (match_operator:QI 1 "ix86_comparison_operator"
16330 [(reg FLAGS_REG) (const_int 0)]))]
16333 [(set_attr "type" "setcc")
16334 (set_attr "mode" "QI")])
16336 ;; In general it is not safe to assume too much about CCmode registers,
16337 ;; so simplify-rtx stops when it sees a second one. Under certain
16338 ;; conditions this is safe on x86, so help combine not create
16345 [(set (match_operand:QI 0 "nonimmediate_operand")
16346 (ne:QI (match_operator 1 "ix86_comparison_operator"
16347 [(reg FLAGS_REG) (const_int 0)])
16350 [(set (match_dup 0) (match_dup 1))]
16352 operands[1] = shallow_copy_rtx (operands[1]);
16353 PUT_MODE (operands[1], QImode);
16357 [(set (strict_low_part (match_operand:QI 0 "register_operand"))
16358 (ne:QI (match_operator 1 "ix86_comparison_operator"
16359 [(reg FLAGS_REG) (const_int 0)])
16362 [(set (match_dup 0) (match_dup 1))]
16364 operands[1] = shallow_copy_rtx (operands[1]);
16365 PUT_MODE (operands[1], QImode);
16369 [(set (match_operand:QI 0 "nonimmediate_operand")
16370 (eq:QI (match_operator 1 "ix86_comparison_operator"
16371 [(reg FLAGS_REG) (const_int 0)])
16374 [(set (match_dup 0) (match_dup 1))]
16376 operands[1] = shallow_copy_rtx (operands[1]);
16377 PUT_MODE (operands[1], QImode);
16378 PUT_CODE (operands[1],
16379 ix86_reverse_condition (GET_CODE (operands[1]),
16380 GET_MODE (XEXP (operands[1], 0))));
16382 /* Make sure that (a) the CCmode we have for the flags is strong
16383 enough for the reversed compare or (b) we have a valid FP compare. */
16384 if (! ix86_comparison_operator (operands[1], VOIDmode))
16389 [(set (strict_low_part (match_operand:QI 0 "register_operand"))
16390 (eq:QI (match_operator 1 "ix86_comparison_operator"
16391 [(reg FLAGS_REG) (const_int 0)])
16394 [(set (match_dup 0) (match_dup 1))]
16396 operands[1] = shallow_copy_rtx (operands[1]);
16397 PUT_MODE (operands[1], QImode);
16398 PUT_CODE (operands[1],
16399 ix86_reverse_condition (GET_CODE (operands[1]),
16400 GET_MODE (XEXP (operands[1], 0))));
16402 /* Make sure that (a) the CCmode we have for the flags is strong
16403 enough for the reversed compare or (b) we have a valid FP compare. */
16404 if (! ix86_comparison_operator (operands[1], VOIDmode))
16408 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
16409 ;; subsequent logical operations are used to imitate conditional moves.
16410 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
16413 (define_insn "setcc_<mode>_sse"
16414 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
16415 (match_operator:MODEF 3 "sse_comparison_operator"
16416 [(match_operand:MODEF 1 "register_operand" "0,x")
16417 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
16418 "SSE_FLOAT_MODE_P (<MODE>mode)"
16420 cmp%D3<ssemodesuffix>\t{%2, %0|%0, %2}
16421 vcmp%D3<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
16422 [(set_attr "isa" "noavx,avx")
16423 (set_attr "type" "ssecmp")
16424 (set_attr "length_immediate" "1")
16425 (set_attr "prefix" "orig,vex")
16426 (set_attr "mode" "<MODE>")])
16428 (define_insn "setcc_hf_mask"
16429 [(set (match_operand:QI 0 "register_operand" "=k")
16431 [(match_operand:HF 1 "register_operand" "v")
16432 (match_operand:HF 2 "nonimmediate_operand" "vm")
16433 (match_operand:SI 3 "const_0_to_31_operand")]
16435 "TARGET_AVX512FP16"
16436 "vcmpsh\t{%3, %2, %1, %0|%0, %1, %2, %3}"
16437 [(set_attr "type" "ssecmp")
16438 (set_attr "prefix" "evex")
16439 (set_attr "mode" "HF")])
16442 ;; Basic conditional jump instructions.
16447 (match_operator 1 "add_comparison_operator"
16448 [(not:SWI (match_operand:SWI 2 "register_operand"))
16449 (match_operand:SWI 3 "nonimmediate_operand")])
16450 (label_ref (match_operand 0))
16453 [(set (reg:CCC FLAGS_REG)
16455 (plus:SWI (match_dup 2) (match_dup 3))
16458 (if_then_else (match_op_dup 1 [(reg:CCC FLAGS_REG) (const_int 0)])
16459 (label_ref (match_operand 0))
16465 (match_operator 1 "shr_comparison_operator"
16466 [(match_operand:DI 2 "register_operand")
16467 (match_operand 3 "const_int_operand")])
16468 (label_ref (match_operand 0))
16471 && IN_RANGE (exact_log2 (UINTVAL (operands[3]) + 1), 32, 63)"
16472 [(set (reg:CCZ FLAGS_REG)
16474 (lshiftrt:DI (match_dup 2) (match_dup 4))
16477 (if_then_else (match_op_dup 1 [(reg:CCZ FLAGS_REG) (const_int 0)])
16478 (label_ref (match_operand 0))
16481 enum rtx_code new_code;
16483 operands[1] = shallow_copy_rtx (operands[1]);
16484 switch (GET_CODE (operands[1]))
16486 case GTU: new_code = NE; break;
16487 case LEU: new_code = EQ; break;
16488 default: gcc_unreachable ();
16490 PUT_CODE (operands[1], new_code);
16492 operands[4] = GEN_INT (exact_log2 (UINTVAL (operands[3]) + 1));
16495 ;; We ignore the overflow flag for signed branch instructions.
16497 (define_insn "*jcc"
16499 (if_then_else (match_operator 1 "ix86_comparison_operator"
16500 [(reg FLAGS_REG) (const_int 0)])
16501 (label_ref (match_operand 0))
16505 [(set_attr "type" "ibr")
16506 (set_attr "modrm" "0")
16507 (set (attr "length")
16509 (and (ge (minus (match_dup 0) (pc))
16511 (lt (minus (match_dup 0) (pc))
16516 ;; In general it is not safe to assume too much about CCmode registers,
16517 ;; so simplify-rtx stops when it sees a second one. Under certain
16518 ;; conditions this is safe on x86, so help combine not create
16526 (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
16527 [(reg FLAGS_REG) (const_int 0)])
16529 (label_ref (match_operand 1))
16533 (if_then_else (match_dup 0)
16534 (label_ref (match_dup 1))
16537 operands[0] = shallow_copy_rtx (operands[0]);
16538 PUT_MODE (operands[0], VOIDmode);
16543 (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
16544 [(reg FLAGS_REG) (const_int 0)])
16546 (label_ref (match_operand 1))
16550 (if_then_else (match_dup 0)
16551 (label_ref (match_dup 1))
16554 operands[0] = shallow_copy_rtx (operands[0]);
16555 PUT_MODE (operands[0], VOIDmode);
16556 PUT_CODE (operands[0],
16557 ix86_reverse_condition (GET_CODE (operands[0]),
16558 GET_MODE (XEXP (operands[0], 0))));
16560 /* Make sure that (a) the CCmode we have for the flags is strong
16561 enough for the reversed compare or (b) we have a valid FP compare. */
16562 if (! ix86_comparison_operator (operands[0], VOIDmode))
16566 ;; Unconditional and other jump instructions
16568 (define_insn "jump"
16570 (label_ref (match_operand 0)))]
16573 [(set_attr "type" "ibr")
16574 (set_attr "modrm" "0")
16575 (set (attr "length")
16577 (and (ge (minus (match_dup 0) (pc))
16579 (lt (minus (match_dup 0) (pc))
16584 (define_expand "indirect_jump"
16585 [(set (pc) (match_operand 0 "indirect_branch_operand"))]
16588 if (TARGET_X32 || TARGET_INDIRECT_BRANCH_REGISTER)
16589 operands[0] = convert_memory_address (word_mode, operands[0]);
16590 cfun->machine->has_local_indirect_jump = true;
16593 (define_insn "*indirect_jump"
16594 [(set (pc) (match_operand:W 0 "indirect_branch_operand" "rBw"))]
16596 "* return ix86_output_indirect_jmp (operands[0]);"
16597 [(set (attr "type")
16598 (if_then_else (match_test "(cfun->machine->indirect_branch_type
16599 != indirect_branch_keep)")
16600 (const_string "multi")
16601 (const_string "ibr")))
16602 (set_attr "length_immediate" "0")])
16604 (define_expand "tablejump"
16605 [(parallel [(set (pc) (match_operand 0 "indirect_branch_operand"))
16606 (use (label_ref (match_operand 1)))])]
16609 /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
16610 relative. Convert the relative address to an absolute address. */
16614 enum rtx_code code;
16616 /* We can't use @GOTOFF for text labels on VxWorks;
16617 see gotoff_operand. */
16618 if (TARGET_64BIT || TARGET_VXWORKS_RTP)
16622 op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
16624 else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
16628 op1 = pic_offset_table_rtx;
16633 op0 = pic_offset_table_rtx;
16637 operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
16641 if (TARGET_X32 || TARGET_INDIRECT_BRANCH_REGISTER)
16642 operands[0] = convert_memory_address (word_mode, operands[0]);
16643 cfun->machine->has_local_indirect_jump = true;
16646 (define_insn "*tablejump_1"
16647 [(set (pc) (match_operand:W 0 "indirect_branch_operand" "rBw"))
16648 (use (label_ref (match_operand 1)))]
16650 "* return ix86_output_indirect_jmp (operands[0]);"
16651 [(set (attr "type")
16652 (if_then_else (match_test "(cfun->machine->indirect_branch_type
16653 != indirect_branch_keep)")
16654 (const_string "multi")
16655 (const_string "ibr")))
16656 (set_attr "length_immediate" "0")])
16658 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
16661 [(set (match_operand 4 "flags_reg_operand") (match_operand 0))
16662 (set (match_operand:QI 1 "register_operand")
16663 (match_operator:QI 2 "ix86_comparison_operator"
16664 [(reg FLAGS_REG) (const_int 0)]))
16665 (set (match_operand 3 "any_QIreg_operand")
16666 (zero_extend (match_dup 1)))]
16667 "(peep2_reg_dead_p (3, operands[1])
16668 || operands_match_p (operands[1], operands[3]))
16669 && ! reg_overlap_mentioned_p (operands[3], operands[0])
16670 && peep2_regno_dead_p (0, FLAGS_REG)"
16671 [(set (match_dup 4) (match_dup 0))
16672 (set (strict_low_part (match_dup 5))
16675 operands[5] = gen_lowpart (QImode, operands[3]);
16676 ix86_expand_clear (operands[3]);
16680 [(parallel [(set (match_operand 5 "flags_reg_operand") (match_operand 0))
16681 (match_operand 4)])
16682 (set (match_operand:QI 1 "register_operand")
16683 (match_operator:QI 2 "ix86_comparison_operator"
16684 [(reg FLAGS_REG) (const_int 0)]))
16685 (set (match_operand 3 "any_QIreg_operand")
16686 (zero_extend (match_dup 1)))]
16687 "(peep2_reg_dead_p (3, operands[1])
16688 || operands_match_p (operands[1], operands[3]))
16689 && ! reg_overlap_mentioned_p (operands[3], operands[0])
16690 && ! reg_overlap_mentioned_p (operands[3], operands[4])
16691 && ! reg_set_p (operands[3], operands[4])
16692 && peep2_regno_dead_p (0, FLAGS_REG)"
16693 [(parallel [(set (match_dup 5) (match_dup 0))
16695 (set (strict_low_part (match_dup 6))
16698 operands[6] = gen_lowpart (QImode, operands[3]);
16699 ix86_expand_clear (operands[3]);
16703 [(set (match_operand 6 "flags_reg_operand") (match_operand 0))
16704 (parallel [(set (match_operand 7 "flags_reg_operand") (match_operand 1))
16705 (match_operand 5)])
16706 (set (match_operand:QI 2 "register_operand")
16707 (match_operator:QI 3 "ix86_comparison_operator"
16708 [(reg FLAGS_REG) (const_int 0)]))
16709 (set (match_operand 4 "any_QIreg_operand")
16710 (zero_extend (match_dup 2)))]
16711 "(peep2_reg_dead_p (4, operands[2])
16712 || operands_match_p (operands[2], operands[4]))
16713 && ! reg_overlap_mentioned_p (operands[4], operands[0])
16714 && ! reg_overlap_mentioned_p (operands[4], operands[1])
16715 && ! reg_overlap_mentioned_p (operands[4], operands[5])
16716 && ! reg_set_p (operands[4], operands[5])
16717 && refers_to_regno_p (FLAGS_REG, operands[1], (rtx *)NULL)
16718 && peep2_regno_dead_p (0, FLAGS_REG)"
16719 [(set (match_dup 6) (match_dup 0))
16720 (parallel [(set (match_dup 7) (match_dup 1))
16722 (set (strict_low_part (match_dup 8))
16725 operands[8] = gen_lowpart (QImode, operands[4]);
16726 ix86_expand_clear (operands[4]);
16729 ;; Similar, but match zero extend with andsi3.
16732 [(set (match_operand 4 "flags_reg_operand") (match_operand 0))
16733 (set (match_operand:QI 1 "register_operand")
16734 (match_operator:QI 2 "ix86_comparison_operator"
16735 [(reg FLAGS_REG) (const_int 0)]))
16736 (parallel [(set (match_operand:SI 3 "any_QIreg_operand")
16737 (and:SI (match_dup 3) (const_int 255)))
16738 (clobber (reg:CC FLAGS_REG))])]
16739 "REGNO (operands[1]) == REGNO (operands[3])
16740 && ! reg_overlap_mentioned_p (operands[3], operands[0])
16741 && peep2_regno_dead_p (0, FLAGS_REG)"
16742 [(set (match_dup 4) (match_dup 0))
16743 (set (strict_low_part (match_dup 5))
16746 operands[5] = gen_lowpart (QImode, operands[3]);
16747 ix86_expand_clear (operands[3]);
16751 [(parallel [(set (match_operand 5 "flags_reg_operand") (match_operand 0))
16752 (match_operand 4)])
16753 (set (match_operand:QI 1 "register_operand")
16754 (match_operator:QI 2 "ix86_comparison_operator"
16755 [(reg FLAGS_REG) (const_int 0)]))
16756 (parallel [(set (match_operand 3 "any_QIreg_operand")
16757 (zero_extend (match_dup 1)))
16758 (clobber (reg:CC FLAGS_REG))])]
16759 "(peep2_reg_dead_p (3, operands[1])
16760 || operands_match_p (operands[1], operands[3]))
16761 && ! reg_overlap_mentioned_p (operands[3], operands[0])
16762 && ! reg_overlap_mentioned_p (operands[3], operands[4])
16763 && ! reg_set_p (operands[3], operands[4])
16764 && peep2_regno_dead_p (0, FLAGS_REG)"
16765 [(parallel [(set (match_dup 5) (match_dup 0))
16767 (set (strict_low_part (match_dup 6))
16770 operands[6] = gen_lowpart (QImode, operands[3]);
16771 ix86_expand_clear (operands[3]);
16775 [(set (match_operand 6 "flags_reg_operand") (match_operand 0))
16776 (parallel [(set (match_operand 7 "flags_reg_operand") (match_operand 1))
16777 (match_operand 5)])
16778 (set (match_operand:QI 2 "register_operand")
16779 (match_operator:QI 3 "ix86_comparison_operator"
16780 [(reg FLAGS_REG) (const_int 0)]))
16781 (parallel [(set (match_operand 4 "any_QIreg_operand")
16782 (zero_extend (match_dup 2)))
16783 (clobber (reg:CC FLAGS_REG))])]
16784 "(peep2_reg_dead_p (4, operands[2])
16785 || operands_match_p (operands[2], operands[4]))
16786 && ! reg_overlap_mentioned_p (operands[4], operands[0])
16787 && ! reg_overlap_mentioned_p (operands[4], operands[1])
16788 && ! reg_overlap_mentioned_p (operands[4], operands[5])
16789 && ! reg_set_p (operands[4], operands[5])
16790 && refers_to_regno_p (FLAGS_REG, operands[1], (rtx *)NULL)
16791 && peep2_regno_dead_p (0, FLAGS_REG)"
16792 [(set (match_dup 6) (match_dup 0))
16793 (parallel [(set (match_dup 7) (match_dup 1))
16795 (set (strict_low_part (match_dup 8))
16798 operands[8] = gen_lowpart (QImode, operands[4]);
16799 ix86_expand_clear (operands[4]);
16802 ;; Call instructions.
16804 ;; The predicates normally associated with named expanders are not properly
16805 ;; checked for calls. This is a bug in the generic code, but it isn't that
16806 ;; easy to fix. Ignore it for now and be prepared to fix things up.
16808 ;; P6 processors will jump to the address after the decrement when %esp
16809 ;; is used as a call operand, so they will execute return address as a code.
16810 ;; See Pentium Pro errata 70, Pentium 2 errata A33 and Pentium 3 errata E17.
16812 ;; Register constraint for call instruction.
16813 (define_mode_attr c [(SI "l") (DI "r")])
16815 ;; Call subroutine returning no value.
16817 (define_expand "call"
16818 [(call (match_operand:QI 0)
16820 (use (match_operand 2))]
16823 ix86_expand_call (NULL, operands[0], operands[1],
16824 operands[2], NULL, false);
16828 (define_expand "sibcall"
16829 [(call (match_operand:QI 0)
16831 (use (match_operand 2))]
16834 ix86_expand_call (NULL, operands[0], operands[1],
16835 operands[2], NULL, true);
16839 (define_insn "*call"
16840 [(call (mem:QI (match_operand:W 0 "call_insn_operand" "<c>BwBz"))
16841 (match_operand 1))]
16842 "!SIBLING_CALL_P (insn)"
16843 "* return ix86_output_call_insn (insn, operands[0]);"
16844 [(set_attr "type" "call")])
16846 ;; This covers both call and sibcall since only GOT slot is allowed.
16847 (define_insn "*call_got_x32"
16848 [(call (mem:QI (zero_extend:DI
16849 (match_operand:SI 0 "GOT_memory_operand" "Bg")))
16850 (match_operand 1))]
16853 rtx fnaddr = gen_const_mem (DImode, XEXP (operands[0], 0));
16854 return ix86_output_call_insn (insn, fnaddr);
16856 [(set_attr "type" "call")])
16858 ;; Since sibcall never returns, we can only use call-clobbered register
16860 (define_insn "*sibcall_GOT_32"
16863 (match_operand:SI 0 "register_no_elim_operand" "U")
16864 (match_operand:SI 1 "GOT32_symbol_operand"))))
16865 (match_operand 2))]
16868 && !TARGET_INDIRECT_BRANCH_REGISTER
16869 && SIBLING_CALL_P (insn)"
16871 rtx fnaddr = gen_rtx_PLUS (SImode, operands[0], operands[1]);
16872 fnaddr = gen_const_mem (SImode, fnaddr);
16873 return ix86_output_call_insn (insn, fnaddr);
16875 [(set_attr "type" "call")])
16877 (define_insn "*sibcall"
16878 [(call (mem:QI (match_operand:W 0 "sibcall_insn_operand" "UBsBz"))
16879 (match_operand 1))]
16880 "SIBLING_CALL_P (insn)"
16881 "* return ix86_output_call_insn (insn, operands[0]);"
16882 [(set_attr "type" "call")])
16884 (define_insn "*sibcall_memory"
16885 [(call (mem:QI (match_operand:W 0 "memory_operand" "m"))
16887 (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
16888 "!TARGET_X32 && !TARGET_INDIRECT_BRANCH_REGISTER"
16889 "* return ix86_output_call_insn (insn, operands[0]);"
16890 [(set_attr "type" "call")])
16893 [(set (match_operand:W 0 "register_operand")
16894 (match_operand:W 1 "memory_operand"))
16895 (call (mem:QI (match_dup 0))
16896 (match_operand 3))]
16898 && !TARGET_INDIRECT_BRANCH_REGISTER
16899 && SIBLING_CALL_P (peep2_next_insn (1))
16900 && !reg_mentioned_p (operands[0],
16901 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (1)))"
16902 [(parallel [(call (mem:QI (match_dup 1))
16904 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
16907 [(set (match_operand:W 0 "register_operand")
16908 (match_operand:W 1 "memory_operand"))
16909 (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
16910 (call (mem:QI (match_dup 0))
16911 (match_operand 3))]
16913 && !TARGET_INDIRECT_BRANCH_REGISTER
16914 && SIBLING_CALL_P (peep2_next_insn (2))
16915 && !reg_mentioned_p (operands[0],
16916 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (2)))"
16917 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
16918 (parallel [(call (mem:QI (match_dup 1))
16920 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
16922 (define_expand "call_pop"
16923 [(parallel [(call (match_operand:QI 0)
16924 (match_operand:SI 1))
16925 (set (reg:SI SP_REG)
16926 (plus:SI (reg:SI SP_REG)
16927 (match_operand:SI 3)))])]
16930 ix86_expand_call (NULL, operands[0], operands[1],
16931 operands[2], operands[3], false);
16935 (define_insn "*call_pop"
16936 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lBwBz"))
16938 (set (reg:SI SP_REG)
16939 (plus:SI (reg:SI SP_REG)
16940 (match_operand:SI 2 "immediate_operand" "i")))]
16941 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
16942 "* return ix86_output_call_insn (insn, operands[0]);"
16943 [(set_attr "type" "call")])
16945 (define_insn "*sibcall_pop"
16946 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "UBsBz"))
16948 (set (reg:SI SP_REG)
16949 (plus:SI (reg:SI SP_REG)
16950 (match_operand:SI 2 "immediate_operand" "i")))]
16951 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
16952 "* return ix86_output_call_insn (insn, operands[0]);"
16953 [(set_attr "type" "call")])
16955 (define_insn "*sibcall_pop_memory"
16956 [(call (mem:QI (match_operand:SI 0 "memory_operand" "Bs"))
16958 (set (reg:SI SP_REG)
16959 (plus:SI (reg:SI SP_REG)
16960 (match_operand:SI 2 "immediate_operand" "i")))
16961 (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
16963 "* return ix86_output_call_insn (insn, operands[0]);"
16964 [(set_attr "type" "call")])
16967 [(set (match_operand:SI 0 "register_operand")
16968 (match_operand:SI 1 "memory_operand"))
16969 (parallel [(call (mem:QI (match_dup 0))
16971 (set (reg:SI SP_REG)
16972 (plus:SI (reg:SI SP_REG)
16973 (match_operand:SI 4 "immediate_operand")))])]
16974 "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (1))
16975 && !reg_mentioned_p (operands[0],
16976 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (1)))"
16977 [(parallel [(call (mem:QI (match_dup 1))
16979 (set (reg:SI SP_REG)
16980 (plus:SI (reg:SI SP_REG)
16982 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
16985 [(set (match_operand:SI 0 "register_operand")
16986 (match_operand:SI 1 "memory_operand"))
16987 (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
16988 (parallel [(call (mem:QI (match_dup 0))
16990 (set (reg:SI SP_REG)
16991 (plus:SI (reg:SI SP_REG)
16992 (match_operand:SI 4 "immediate_operand")))])]
16993 "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (2))
16994 && !reg_mentioned_p (operands[0],
16995 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (2)))"
16996 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
16997 (parallel [(call (mem:QI (match_dup 1))
16999 (set (reg:SI SP_REG)
17000 (plus:SI (reg:SI SP_REG)
17002 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
17004 ;; Combining simple memory jump instruction
17007 [(set (match_operand:W 0 "register_operand")
17008 (match_operand:W 1 "memory_operand"))
17009 (set (pc) (match_dup 0))]
17011 && !TARGET_INDIRECT_BRANCH_REGISTER
17012 && peep2_reg_dead_p (2, operands[0])"
17013 [(set (pc) (match_dup 1))])
17015 ;; Call subroutine, returning value in operand 0
17017 (define_expand "call_value"
17018 [(set (match_operand 0)
17019 (call (match_operand:QI 1)
17020 (match_operand 2)))
17021 (use (match_operand 3))]
17024 ix86_expand_call (operands[0], operands[1], operands[2],
17025 operands[3], NULL, false);
17029 (define_expand "sibcall_value"
17030 [(set (match_operand 0)
17031 (call (match_operand:QI 1)
17032 (match_operand 2)))
17033 (use (match_operand 3))]
17036 ix86_expand_call (operands[0], operands[1], operands[2],
17037 operands[3], NULL, true);
17041 (define_insn "*call_value"
17042 [(set (match_operand 0)
17043 (call (mem:QI (match_operand:W 1 "call_insn_operand" "<c>BwBz"))
17044 (match_operand 2)))]
17045 "!SIBLING_CALL_P (insn)"
17046 "* return ix86_output_call_insn (insn, operands[1]);"
17047 [(set_attr "type" "callv")])
17049 ;; This covers both call and sibcall since only GOT slot is allowed.
17050 (define_insn "*call_value_got_x32"
17051 [(set (match_operand 0)
17054 (match_operand:SI 1 "GOT_memory_operand" "Bg")))
17055 (match_operand 2)))]
17058 rtx fnaddr = gen_const_mem (DImode, XEXP (operands[1], 0));
17059 return ix86_output_call_insn (insn, fnaddr);
17061 [(set_attr "type" "callv")])
17063 ;; Since sibcall never returns, we can only use call-clobbered register
17065 (define_insn "*sibcall_value_GOT_32"
17066 [(set (match_operand 0)
17069 (match_operand:SI 1 "register_no_elim_operand" "U")
17070 (match_operand:SI 2 "GOT32_symbol_operand"))))
17071 (match_operand 3)))]
17074 && !TARGET_INDIRECT_BRANCH_REGISTER
17075 && SIBLING_CALL_P (insn)"
17077 rtx fnaddr = gen_rtx_PLUS (SImode, operands[1], operands[2]);
17078 fnaddr = gen_const_mem (SImode, fnaddr);
17079 return ix86_output_call_insn (insn, fnaddr);
17081 [(set_attr "type" "callv")])
17083 (define_insn "*sibcall_value"
17084 [(set (match_operand 0)
17085 (call (mem:QI (match_operand:W 1 "sibcall_insn_operand" "UBsBz"))
17086 (match_operand 2)))]
17087 "SIBLING_CALL_P (insn)"
17088 "* return ix86_output_call_insn (insn, operands[1]);"
17089 [(set_attr "type" "callv")])
17091 (define_insn "*sibcall_value_memory"
17092 [(set (match_operand 0)
17093 (call (mem:QI (match_operand:W 1 "memory_operand" "m"))
17094 (match_operand 2)))
17095 (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
17096 "!TARGET_X32 && !TARGET_INDIRECT_BRANCH_REGISTER"
17097 "* return ix86_output_call_insn (insn, operands[1]);"
17098 [(set_attr "type" "callv")])
17101 [(set (match_operand:W 0 "register_operand")
17102 (match_operand:W 1 "memory_operand"))
17103 (set (match_operand 2)
17104 (call (mem:QI (match_dup 0))
17105 (match_operand 3)))]
17107 && !TARGET_INDIRECT_BRANCH_REGISTER
17108 && SIBLING_CALL_P (peep2_next_insn (1))
17109 && !reg_mentioned_p (operands[0],
17110 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (1)))"
17111 [(parallel [(set (match_dup 2)
17112 (call (mem:QI (match_dup 1))
17114 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
17117 [(set (match_operand:W 0 "register_operand")
17118 (match_operand:W 1 "memory_operand"))
17119 (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
17120 (set (match_operand 2)
17121 (call (mem:QI (match_dup 0))
17122 (match_operand 3)))]
17124 && !TARGET_INDIRECT_BRANCH_REGISTER
17125 && SIBLING_CALL_P (peep2_next_insn (2))
17126 && !reg_mentioned_p (operands[0],
17127 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (2)))"
17128 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
17129 (parallel [(set (match_dup 2)
17130 (call (mem:QI (match_dup 1))
17132 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
17134 (define_expand "call_value_pop"
17135 [(parallel [(set (match_operand 0)
17136 (call (match_operand:QI 1)
17137 (match_operand:SI 2)))
17138 (set (reg:SI SP_REG)
17139 (plus:SI (reg:SI SP_REG)
17140 (match_operand:SI 4)))])]
17143 ix86_expand_call (operands[0], operands[1], operands[2],
17144 operands[3], operands[4], false);
17148 (define_insn "*call_value_pop"
17149 [(set (match_operand 0)
17150 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lBwBz"))
17151 (match_operand 2)))
17152 (set (reg:SI SP_REG)
17153 (plus:SI (reg:SI SP_REG)
17154 (match_operand:SI 3 "immediate_operand" "i")))]
17155 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
17156 "* return ix86_output_call_insn (insn, operands[1]);"
17157 [(set_attr "type" "callv")])
17159 (define_insn "*sibcall_value_pop"
17160 [(set (match_operand 0)
17161 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "UBsBz"))
17162 (match_operand 2)))
17163 (set (reg:SI SP_REG)
17164 (plus:SI (reg:SI SP_REG)
17165 (match_operand:SI 3 "immediate_operand" "i")))]
17166 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
17167 "* return ix86_output_call_insn (insn, operands[1]);"
17168 [(set_attr "type" "callv")])
17170 (define_insn "*sibcall_value_pop_memory"
17171 [(set (match_operand 0)
17172 (call (mem:QI (match_operand:SI 1 "memory_operand" "m"))
17173 (match_operand 2)))
17174 (set (reg:SI SP_REG)
17175 (plus:SI (reg:SI SP_REG)
17176 (match_operand:SI 3 "immediate_operand" "i")))
17177 (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
17179 "* return ix86_output_call_insn (insn, operands[1]);"
17180 [(set_attr "type" "callv")])
17183 [(set (match_operand:SI 0 "register_operand")
17184 (match_operand:SI 1 "memory_operand"))
17185 (parallel [(set (match_operand 2)
17186 (call (mem:QI (match_dup 0))
17187 (match_operand 3)))
17188 (set (reg:SI SP_REG)
17189 (plus:SI (reg:SI SP_REG)
17190 (match_operand:SI 4 "immediate_operand")))])]
17191 "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (1))
17192 && !reg_mentioned_p (operands[0],
17193 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (1)))"
17194 [(parallel [(set (match_dup 2)
17195 (call (mem:QI (match_dup 1))
17197 (set (reg:SI SP_REG)
17198 (plus:SI (reg:SI SP_REG)
17200 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
17203 [(set (match_operand:SI 0 "register_operand")
17204 (match_operand:SI 1 "memory_operand"))
17205 (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
17206 (parallel [(set (match_operand 2)
17207 (call (mem:QI (match_dup 0))
17208 (match_operand 3)))
17209 (set (reg:SI SP_REG)
17210 (plus:SI (reg:SI SP_REG)
17211 (match_operand:SI 4 "immediate_operand")))])]
17212 "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (2))
17213 && !reg_mentioned_p (operands[0],
17214 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (2)))"
17215 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
17216 (parallel [(set (match_dup 2)
17217 (call (mem:QI (match_dup 1))
17219 (set (reg:SI SP_REG)
17220 (plus:SI (reg:SI SP_REG)
17222 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
17224 ;; Call subroutine returning any type.
17226 (define_expand "untyped_call"
17227 [(parallel [(call (match_operand 0)
17230 (match_operand 2)])]
17235 /* In order to give reg-stack an easier job in validating two
17236 coprocessor registers as containing a possible return value,
17237 simply pretend the untyped call returns a complex long double
17240 We can't use SSE_REGPARM_MAX here since callee is unprototyped
17241 and should have the default ABI. */
17243 ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
17244 ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
17245 operands[0], const0_rtx,
17246 GEN_INT ((TARGET_64BIT
17247 ? (ix86_abi == SYSV_ABI
17248 ? X86_64_SSE_REGPARM_MAX
17249 : X86_64_MS_SSE_REGPARM_MAX)
17250 : X86_32_SSE_REGPARM_MAX)
17254 for (i = 0; i < XVECLEN (operands[2], 0); i++)
17256 rtx set = XVECEXP (operands[2], 0, i);
17257 emit_move_insn (SET_DEST (set), SET_SRC (set));
17260 /* The optimizer does not know that the call sets the function value
17261 registers we stored in the result block. We avoid problems by
17262 claiming that all hard registers are used and clobbered at this
17264 emit_insn (gen_blockage ());
17269 ;; Prologue and epilogue instructions
17271 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
17272 ;; all of memory. This blocks insns from being moved across this point.
17274 (define_insn "blockage"
17275 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
17278 [(set_attr "length" "0")])
17280 ;; Do not schedule instructions accessing memory across this point.
17282 (define_expand "memory_blockage"
17283 [(set (match_dup 0)
17284 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
17287 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
17288 MEM_VOLATILE_P (operands[0]) = 1;
17291 (define_insn "*memory_blockage"
17292 [(set (match_operand:BLK 0)
17293 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
17296 [(set_attr "length" "0")])
17298 ;; As USE insns aren't meaningful after reload, this is used instead
17299 ;; to prevent deleting instructions setting registers for PIC code
17300 (define_insn "prologue_use"
17301 [(unspec_volatile [(match_operand 0)] UNSPECV_PROLOGUE_USE)]
17304 [(set_attr "length" "0")])
17306 ;; Insn emitted into the body of a function to return from a function.
17307 ;; This is only done if the function's epilogue is known to be simple.
17308 ;; See comments for ix86_can_use_return_insn_p in i386.cc.
17310 (define_expand "return"
17312 "ix86_can_use_return_insn_p ()"
17314 if (crtl->args.pops_args)
17316 rtx popc = GEN_INT (crtl->args.pops_args);
17317 emit_jump_insn (gen_simple_return_pop_internal (popc));
17322 ;; We need to disable this for TARGET_SEH, as otherwise
17323 ;; shrink-wrapped prologue gets enabled too. This might exceed
17324 ;; the maximum size of prologue in unwind information.
17325 ;; Also disallow shrink-wrapping if using stack slot to pass the
17326 ;; static chain pointer - the first instruction has to be pushl %esi
17327 ;; and it can't be moved around, as we use alternate entry points
17329 ;; Also disallow for ms_hook_prologue functions which have frame
17330 ;; pointer set up in function label which is correctly handled in
17331 ;; ix86_expand_{prologue|epligoue}() only.
17333 (define_expand "simple_return"
17335 "!TARGET_SEH && !ix86_static_chain_on_stack && !ix86_function_ms_hook_prologue (cfun->decl)"
17337 if (crtl->args.pops_args)
17339 rtx popc = GEN_INT (crtl->args.pops_args);
17340 emit_jump_insn (gen_simple_return_pop_internal (popc));
17345 (define_insn "simple_return_internal"
17348 "* return ix86_output_function_return (false);"
17349 [(set_attr "length" "1")
17350 (set_attr "atom_unit" "jeu")
17351 (set_attr "length_immediate" "0")
17352 (set_attr "modrm" "0")])
17354 (define_insn "interrupt_return"
17356 (unspec [(const_int 0)] UNSPEC_INTERRUPT_RETURN)]
17359 return TARGET_64BIT ? (TARGET_UINTR ? "uiret" : "iretq") : "iret";
17362 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
17363 ;; instruction Athlon and K8 have.
17365 (define_insn "simple_return_internal_long"
17367 (unspec [(const_int 0)] UNSPEC_REP)]
17369 "* return ix86_output_function_return (true);"
17370 [(set_attr "length" "2")
17371 (set_attr "atom_unit" "jeu")
17372 (set_attr "length_immediate" "0")
17373 (set_attr "prefix_rep" "1")
17374 (set_attr "modrm" "0")])
17376 (define_insn_and_split "simple_return_pop_internal"
17378 (use (match_operand:SI 0 "const_int_operand"))]
17381 "&& cfun->machine->function_return_type != indirect_branch_keep"
17383 "ix86_split_simple_return_pop_internal (operands[0]); DONE;"
17384 [(set_attr "length" "3")
17385 (set_attr "atom_unit" "jeu")
17386 (set_attr "length_immediate" "2")
17387 (set_attr "modrm" "0")])
17389 (define_expand "simple_return_indirect_internal"
17392 (use (match_operand 0 "register_operand"))])])
17394 (define_insn "*simple_return_indirect_internal<mode>"
17396 (use (match_operand:W 0 "register_operand" "r"))]
17398 "* return ix86_output_indirect_function_return (operands[0]);"
17399 [(set (attr "type")
17400 (if_then_else (match_test "(cfun->machine->indirect_branch_type
17401 != indirect_branch_keep)")
17402 (const_string "multi")
17403 (const_string "ibr")))
17404 (set_attr "length_immediate" "0")])
17410 [(set_attr "length" "1")
17411 (set_attr "length_immediate" "0")
17412 (set_attr "modrm" "0")])
17414 ;; Generate nops. Operand 0 is the number of nops, up to 8.
17415 (define_insn "nops"
17416 [(unspec_volatile [(match_operand 0 "const_int_operand")]
17420 int num = INTVAL (operands[0]);
17422 gcc_assert (IN_RANGE (num, 1, 8));
17425 fputs ("\tnop\n", asm_out_file);
17429 [(set (attr "length") (symbol_ref "INTVAL (operands[0])"))
17430 (set_attr "length_immediate" "0")
17431 (set_attr "modrm" "0")])
17433 ;; Pad to 16-byte boundary, max skip in op0. Used to avoid
17434 ;; branch prediction penalty for the third jump in a 16-byte
17438 [(unspec_volatile [(match_operand 0)] UNSPECV_ALIGN)]
17441 #ifdef ASM_OUTPUT_MAX_SKIP_ALIGN
17442 ASM_OUTPUT_MAX_SKIP_ALIGN (asm_out_file, 4, (int)INTVAL (operands[0]));
17444 /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
17445 The align insn is used to avoid 3 jump instructions in the row to improve
17446 branch prediction and the benefits hardly outweigh the cost of extra 8
17447 nops on the average inserted by full alignment pseudo operation. */
17451 [(set_attr "length" "16")])
17453 (define_expand "prologue"
17456 "ix86_expand_prologue (); DONE;")
17458 (define_expand "set_got"
17460 [(set (match_operand:SI 0 "register_operand")
17461 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
17462 (clobber (reg:CC FLAGS_REG))])]
17465 if (flag_pic && !TARGET_VXWORKS_RTP)
17466 ix86_pc_thunk_call_expanded = true;
17469 (define_insn "*set_got"
17470 [(set (match_operand:SI 0 "register_operand" "=r")
17471 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
17472 (clobber (reg:CC FLAGS_REG))]
17474 "* return output_set_got (operands[0], NULL_RTX);"
17475 [(set_attr "type" "multi")
17476 (set_attr "length" "12")])
17478 (define_expand "set_got_labelled"
17480 [(set (match_operand:SI 0 "register_operand")
17481 (unspec:SI [(label_ref (match_operand 1))]
17483 (clobber (reg:CC FLAGS_REG))])]
17486 if (flag_pic && !TARGET_VXWORKS_RTP)
17487 ix86_pc_thunk_call_expanded = true;
17490 (define_insn "*set_got_labelled"
17491 [(set (match_operand:SI 0 "register_operand" "=r")
17492 (unspec:SI [(label_ref (match_operand 1))]
17494 (clobber (reg:CC FLAGS_REG))]
17496 "* return output_set_got (operands[0], operands[1]);"
17497 [(set_attr "type" "multi")
17498 (set_attr "length" "12")])
17500 (define_insn "set_got_rex64"
17501 [(set (match_operand:DI 0 "register_operand" "=r")
17502 (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
17504 "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}"
17505 [(set_attr "type" "lea")
17506 (set_attr "length_address" "4")
17507 (set_attr "mode" "DI")])
17509 (define_insn "set_rip_rex64"
17510 [(set (match_operand:DI 0 "register_operand" "=r")
17511 (unspec:DI [(label_ref (match_operand 1))] UNSPEC_SET_RIP))]
17513 "lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}"
17514 [(set_attr "type" "lea")
17515 (set_attr "length_address" "4")
17516 (set_attr "mode" "DI")])
17518 (define_insn "set_got_offset_rex64"
17519 [(set (match_operand:DI 0 "register_operand" "=r")
17521 [(label_ref (match_operand 1))]
17522 UNSPEC_SET_GOT_OFFSET))]
17524 "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}"
17525 [(set_attr "type" "imov")
17526 (set_attr "length_immediate" "0")
17527 (set_attr "length_address" "8")
17528 (set_attr "mode" "DI")])
17530 (define_expand "epilogue"
17533 "ix86_expand_epilogue (1); DONE;")
17535 (define_expand "sibcall_epilogue"
17538 "ix86_expand_epilogue (0); DONE;")
17540 (define_expand "eh_return"
17541 [(use (match_operand 0 "register_operand"))]
17544 rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
17546 /* Tricky bit: we write the address of the handler to which we will
17547 be returning into someone else's stack frame, one word below the
17548 stack address we wish to restore. */
17549 tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
17550 tmp = plus_constant (Pmode, tmp, -UNITS_PER_WORD);
17551 /* Return address is always in word_mode. */
17552 tmp = gen_rtx_MEM (word_mode, tmp);
17553 if (GET_MODE (ra) != word_mode)
17554 ra = convert_to_mode (word_mode, ra, 1);
17555 emit_move_insn (tmp, ra);
17557 emit_jump_insn (gen_eh_return_internal ());
17562 (define_insn_and_split "eh_return_internal"
17566 "epilogue_completed"
17568 "ix86_expand_epilogue (2); DONE;")
17570 (define_expand "@leave_<mode>"
17572 [(set (reg:W SP_REG) (plus:W (reg:W BP_REG) (match_dup 0)))
17573 (set (reg:W BP_REG) (mem:W (reg:W BP_REG)))
17574 (clobber (mem:BLK (scratch)))])]
17576 "operands[0] = GEN_INT (<MODE_SIZE>);")
17578 (define_insn "*leave"
17579 [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
17580 (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
17581 (clobber (mem:BLK (scratch)))]
17584 [(set_attr "type" "leave")])
17586 (define_insn "*leave_rex64"
17587 [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
17588 (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
17589 (clobber (mem:BLK (scratch)))]
17592 [(set_attr "type" "leave")])
17594 ;; Handle -fsplit-stack.
17596 (define_expand "split_stack_prologue"
17600 ix86_expand_split_stack_prologue ();
17604 ;; In order to support the call/return predictor, we use a return
17605 ;; instruction which the middle-end doesn't see.
17606 (define_insn "split_stack_return"
17607 [(unspec_volatile [(match_operand:SI 0 "const_int_operand")]
17608 UNSPECV_SPLIT_STACK_RETURN)]
17611 if (operands[0] == const0_rtx)
17616 [(set_attr "atom_unit" "jeu")
17617 (set_attr "modrm" "0")
17618 (set (attr "length")
17619 (if_then_else (match_operand:SI 0 "const0_operand")
17622 (set (attr "length_immediate")
17623 (if_then_else (match_operand:SI 0 "const0_operand")
17627 ;; If there are operand 0 bytes available on the stack, jump to
17630 (define_expand "split_stack_space_check"
17631 [(set (pc) (if_then_else
17632 (ltu (minus (reg SP_REG)
17633 (match_operand 0 "register_operand"))
17635 (label_ref (match_operand 1))
17639 rtx reg = gen_reg_rtx (Pmode);
17641 emit_insn (gen_sub3_insn (reg, stack_pointer_rtx, operands[0]));
17643 operands[2] = ix86_split_stack_guard ();
17644 ix86_expand_branch (GEU, reg, operands[2], operands[1]);
17649 ;; Bit manipulation instructions.
17651 (define_expand "ffs<mode>2"
17652 [(set (match_dup 2) (const_int -1))
17653 (parallel [(set (match_dup 3) (match_dup 4))
17654 (set (match_operand:SWI48 0 "register_operand")
17656 (match_operand:SWI48 1 "nonimmediate_operand")))])
17657 (set (match_dup 0) (if_then_else:SWI48
17658 (eq (match_dup 3) (const_int 0))
17661 (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (const_int 1)))
17662 (clobber (reg:CC FLAGS_REG))])]
17665 machine_mode flags_mode;
17667 if (<MODE>mode == SImode && !TARGET_CMOVE)
17669 emit_insn (gen_ffssi2_no_cmove (operands[0], operands [1]));
17673 flags_mode = TARGET_BMI ? CCCmode : CCZmode;
17675 operands[2] = gen_reg_rtx (<MODE>mode);
17676 operands[3] = gen_rtx_REG (flags_mode, FLAGS_REG);
17677 operands[4] = gen_rtx_COMPARE (flags_mode, operands[1], const0_rtx);
17680 (define_insn_and_split "ffssi2_no_cmove"
17681 [(set (match_operand:SI 0 "register_operand" "=r")
17682 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
17683 (clobber (match_scratch:SI 2 "=&q"))
17684 (clobber (reg:CC FLAGS_REG))]
17687 "&& reload_completed"
17688 [(parallel [(set (match_dup 4) (match_dup 5))
17689 (set (match_dup 0) (ctz:SI (match_dup 1)))])
17690 (set (strict_low_part (match_dup 3))
17691 (eq:QI (match_dup 4) (const_int 0)))
17692 (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
17693 (clobber (reg:CC FLAGS_REG))])
17694 (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
17695 (clobber (reg:CC FLAGS_REG))])
17696 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
17697 (clobber (reg:CC FLAGS_REG))])]
17699 machine_mode flags_mode = TARGET_BMI ? CCCmode : CCZmode;
17701 operands[3] = gen_lowpart (QImode, operands[2]);
17702 operands[4] = gen_rtx_REG (flags_mode, FLAGS_REG);
17703 operands[5] = gen_rtx_COMPARE (flags_mode, operands[1], const0_rtx);
17705 ix86_expand_clear (operands[2]);
17708 (define_insn_and_split "*tzcnt<mode>_1"
17709 [(set (reg:CCC FLAGS_REG)
17710 (compare:CCC (match_operand:SWI48 1 "nonimmediate_operand" "rm")
17712 (set (match_operand:SWI48 0 "register_operand" "=r")
17713 (ctz:SWI48 (match_dup 1)))]
17715 "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
17716 "&& TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
17717 && optimize_function_for_speed_p (cfun)
17718 && !reg_mentioned_p (operands[0], operands[1])"
17720 [(set (reg:CCC FLAGS_REG)
17721 (compare:CCC (match_dup 1) (const_int 0)))
17723 (ctz:SWI48 (match_dup 1)))
17724 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)])]
17725 "ix86_expand_clear (operands[0]);"
17726 [(set_attr "type" "alu1")
17727 (set_attr "prefix_0f" "1")
17728 (set_attr "prefix_rep" "1")
17729 (set_attr "btver2_decode" "double")
17730 (set_attr "mode" "<MODE>")])
17732 ; False dependency happens when destination is only updated by tzcnt,
17733 ; lzcnt or popcnt. There is no false dependency when destination is
17734 ; also used in source.
17735 (define_insn "*tzcnt<mode>_1_falsedep"
17736 [(set (reg:CCC FLAGS_REG)
17737 (compare:CCC (match_operand:SWI48 1 "nonimmediate_operand" "rm")
17739 (set (match_operand:SWI48 0 "register_operand" "=r")
17740 (ctz:SWI48 (match_dup 1)))
17741 (unspec [(match_operand:SWI48 2 "register_operand" "0")]
17742 UNSPEC_INSN_FALSE_DEP)]
17744 "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
17745 [(set_attr "type" "alu1")
17746 (set_attr "prefix_0f" "1")
17747 (set_attr "prefix_rep" "1")
17748 (set_attr "btver2_decode" "double")
17749 (set_attr "mode" "<MODE>")])
17751 (define_insn "*bsf<mode>_1"
17752 [(set (reg:CCZ FLAGS_REG)
17753 (compare:CCZ (match_operand:SWI48 1 "nonimmediate_operand" "rm")
17755 (set (match_operand:SWI48 0 "register_operand" "=r")
17756 (ctz:SWI48 (match_dup 1)))]
17758 "bsf{<imodesuffix>}\t{%1, %0|%0, %1}"
17759 [(set_attr "type" "alu1")
17760 (set_attr "prefix_0f" "1")
17761 (set_attr "btver2_decode" "double")
17762 (set_attr "znver1_decode" "vector")
17763 (set_attr "mode" "<MODE>")])
17765 (define_insn_and_split "ctz<mode>2"
17766 [(set (match_operand:SWI48 0 "register_operand" "=r")
17768 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
17769 (clobber (reg:CC FLAGS_REG))]
17773 return "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
17774 else if (optimize_function_for_size_p (cfun))
17776 else if (TARGET_CPU_P (GENERIC))
17777 /* tzcnt expands to 'rep bsf' and we can use it even if !TARGET_BMI. */
17778 return "rep%; bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
17780 return "bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
17782 "(TARGET_BMI || TARGET_CPU_P (GENERIC))
17783 && TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
17784 && optimize_function_for_speed_p (cfun)
17785 && !reg_mentioned_p (operands[0], operands[1])"
17787 [(set (match_dup 0)
17788 (ctz:SWI48 (match_dup 1)))
17789 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
17790 (clobber (reg:CC FLAGS_REG))])]
17791 "ix86_expand_clear (operands[0]);"
17792 [(set_attr "type" "alu1")
17793 (set_attr "prefix_0f" "1")
17794 (set (attr "prefix_rep")
17796 (ior (match_test "TARGET_BMI")
17797 (and (not (match_test "optimize_function_for_size_p (cfun)"))
17798 (match_test "TARGET_CPU_P (GENERIC)")))
17800 (const_string "0")))
17801 (set_attr "mode" "<MODE>")])
17803 ; False dependency happens when destination is only updated by tzcnt,
17804 ; lzcnt or popcnt. There is no false dependency when destination is
17805 ; also used in source.
17806 (define_insn "*ctz<mode>2_falsedep"
17807 [(set (match_operand:SWI48 0 "register_operand" "=r")
17809 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
17810 (unspec [(match_operand:SWI48 2 "register_operand" "0")]
17811 UNSPEC_INSN_FALSE_DEP)
17812 (clobber (reg:CC FLAGS_REG))]
17816 return "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
17817 else if (TARGET_CPU_P (GENERIC))
17818 /* tzcnt expands to 'rep bsf' and we can use it even if !TARGET_BMI. */
17819 return "rep%; bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
17821 gcc_unreachable ();
17823 [(set_attr "type" "alu1")
17824 (set_attr "prefix_0f" "1")
17825 (set_attr "prefix_rep" "1")
17826 (set_attr "mode" "<MODE>")])
17828 (define_insn_and_split "*ctzsi2_zext"
17829 [(set (match_operand:DI 0 "register_operand" "=r")
17833 (match_operand:SI 1 "nonimmediate_operand" "rm")) 0)
17835 (clobber (reg:CC FLAGS_REG))]
17836 "TARGET_BMI && TARGET_64BIT"
17837 "tzcnt{l}\t{%1, %k0|%k0, %1}"
17838 "&& TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
17839 && optimize_function_for_speed_p (cfun)
17840 && !reg_mentioned_p (operands[0], operands[1])"
17842 [(set (match_dup 0)
17843 (and:DI (subreg:DI (ctz:SI (match_dup 1)) 0) (const_int 63)))
17844 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
17845 (clobber (reg:CC FLAGS_REG))])]
17846 "ix86_expand_clear (operands[0]);"
17847 [(set_attr "type" "alu1")
17848 (set_attr "prefix_0f" "1")
17849 (set_attr "prefix_rep" "1")
17850 (set_attr "mode" "SI")])
17852 ; False dependency happens when destination is only updated by tzcnt,
17853 ; lzcnt or popcnt. There is no false dependency when destination is
17854 ; also used in source.
17855 (define_insn "*ctzsi2_zext_falsedep"
17856 [(set (match_operand:DI 0 "register_operand" "=r")
17860 (match_operand:SI 1 "nonimmediate_operand" "rm")) 0)
17862 (unspec [(match_operand:DI 2 "register_operand" "0")]
17863 UNSPEC_INSN_FALSE_DEP)
17864 (clobber (reg:CC FLAGS_REG))]
17865 "TARGET_BMI && TARGET_64BIT"
17866 "tzcnt{l}\t{%1, %k0|%k0, %1}"
17867 [(set_attr "type" "alu1")
17868 (set_attr "prefix_0f" "1")
17869 (set_attr "prefix_rep" "1")
17870 (set_attr "mode" "SI")])
17872 (define_insn_and_split "*ctzsidi2_<s>ext"
17873 [(set (match_operand:DI 0 "register_operand" "=r")
17876 (match_operand:SI 1 "nonimmediate_operand" "rm"))))
17877 (clobber (reg:CC FLAGS_REG))]
17881 return "tzcnt{l}\t{%1, %k0|%k0, %1}";
17882 else if (TARGET_CPU_P (GENERIC)
17883 && !optimize_function_for_size_p (cfun))
17884 /* tzcnt expands to 'rep bsf' and we can use it even if !TARGET_BMI. */
17885 return "rep%; bsf{l}\t{%1, %k0|%k0, %1}";
17886 return "bsf{l}\t{%1, %k0|%k0, %1}";
17888 "(TARGET_BMI || TARGET_CPU_P (GENERIC))
17889 && TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
17890 && optimize_function_for_speed_p (cfun)
17891 && !reg_mentioned_p (operands[0], operands[1])"
17893 [(set (match_dup 0)
17894 (any_extend:DI (ctz:SI (match_dup 1))))
17895 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
17896 (clobber (reg:CC FLAGS_REG))])]
17897 "ix86_expand_clear (operands[0]);"
17898 [(set_attr "type" "alu1")
17899 (set_attr "prefix_0f" "1")
17900 (set (attr "prefix_rep")
17902 (ior (match_test "TARGET_BMI")
17903 (and (not (match_test "optimize_function_for_size_p (cfun)"))
17904 (match_test "TARGET_CPU_P (GENERIC)")))
17906 (const_string "0")))
17907 (set_attr "mode" "SI")])
17909 (define_insn "*ctzsidi2_<s>ext_falsedep"
17910 [(set (match_operand:DI 0 "register_operand" "=r")
17913 (match_operand:SI 1 "nonimmediate_operand" "rm"))))
17914 (unspec [(match_operand:DI 2 "register_operand" "0")]
17915 UNSPEC_INSN_FALSE_DEP)
17916 (clobber (reg:CC FLAGS_REG))]
17920 return "tzcnt{l}\t{%1, %k0|%k0, %1}";
17921 else if (TARGET_CPU_P (GENERIC))
17922 /* tzcnt expands to 'rep bsf' and we can use it even if !TARGET_BMI. */
17923 return "rep%; bsf{l}\t{%1, %k0|%k0, %1}";
17925 gcc_unreachable ();
17927 [(set_attr "type" "alu1")
17928 (set_attr "prefix_0f" "1")
17929 (set_attr "prefix_rep" "1")
17930 (set_attr "mode" "SI")])
17932 (define_insn "bsr_rex64"
17933 [(set (reg:CCZ FLAGS_REG)
17934 (compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "rm")
17936 (set (match_operand:DI 0 "register_operand" "=r")
17937 (minus:DI (const_int 63)
17938 (clz:DI (match_dup 1))))]
17940 "bsr{q}\t{%1, %0|%0, %1}"
17941 [(set_attr "type" "alu1")
17942 (set_attr "prefix_0f" "1")
17943 (set_attr "znver1_decode" "vector")
17944 (set_attr "mode" "DI")])
17946 (define_insn "bsr_rex64_1"
17947 [(set (match_operand:DI 0 "register_operand" "=r")
17948 (minus:DI (const_int 63)
17949 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
17950 (clobber (reg:CC FLAGS_REG))]
17951 "!TARGET_LZCNT && TARGET_64BIT"
17952 "bsr{q}\t{%1, %0|%0, %1}"
17953 [(set_attr "type" "alu1")
17954 (set_attr "prefix_0f" "1")
17955 (set_attr "znver1_decode" "vector")
17956 (set_attr "mode" "DI")])
17958 (define_insn "bsr_rex64_1_zext"
17959 [(set (match_operand:DI 0 "register_operand" "=r")
17961 (minus:SI (const_int 63)
17963 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))
17965 (clobber (reg:CC FLAGS_REG))]
17966 "!TARGET_LZCNT && TARGET_64BIT"
17967 "bsr{q}\t{%1, %0|%0, %1}"
17968 [(set_attr "type" "alu1")
17969 (set_attr "prefix_0f" "1")
17970 (set_attr "znver1_decode" "vector")
17971 (set_attr "mode" "DI")])
17974 [(set (reg:CCZ FLAGS_REG)
17975 (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "rm")
17977 (set (match_operand:SI 0 "register_operand" "=r")
17978 (minus:SI (const_int 31)
17979 (clz:SI (match_dup 1))))]
17981 "bsr{l}\t{%1, %0|%0, %1}"
17982 [(set_attr "type" "alu1")
17983 (set_attr "prefix_0f" "1")
17984 (set_attr "znver1_decode" "vector")
17985 (set_attr "mode" "SI")])
17987 (define_insn "bsr_1"
17988 [(set (match_operand:SI 0 "register_operand" "=r")
17989 (minus:SI (const_int 31)
17990 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
17991 (clobber (reg:CC FLAGS_REG))]
17993 "bsr{l}\t{%1, %0|%0, %1}"
17994 [(set_attr "type" "alu1")
17995 (set_attr "prefix_0f" "1")
17996 (set_attr "znver1_decode" "vector")
17997 (set_attr "mode" "SI")])
17999 (define_insn "bsr_zext_1"
18000 [(set (match_operand:DI 0 "register_operand" "=r")
18004 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))))
18005 (clobber (reg:CC FLAGS_REG))]
18006 "!TARGET_LZCNT && TARGET_64BIT"
18007 "bsr{l}\t{%1, %k0|%k0, %1}"
18008 [(set_attr "type" "alu1")
18009 (set_attr "prefix_0f" "1")
18010 (set_attr "znver1_decode" "vector")
18011 (set_attr "mode" "SI")])
18013 ; As bsr is undefined behavior on zero and for other input
18014 ; values it is in range 0 to 63, we can optimize away sign-extends.
18015 (define_insn_and_split "*bsr_rex64_2"
18016 [(set (match_operand:DI 0 "register_operand")
18021 (subreg:SI (clz:DI (match_operand:DI 1 "nonimmediate_operand"))
18024 (clobber (reg:CC FLAGS_REG))]
18025 "!TARGET_LZCNT && TARGET_64BIT && ix86_pre_reload_split ()"
18028 [(parallel [(set (reg:CCZ FLAGS_REG)
18029 (compare:CCZ (match_dup 1) (const_int 0)))
18031 (minus:DI (const_int 63) (clz:DI (match_dup 1))))])
18032 (parallel [(set (match_dup 0)
18033 (zero_extend:DI (xor:SI (match_dup 3) (const_int 63))))
18034 (clobber (reg:CC FLAGS_REG))])]
18036 operands[2] = gen_reg_rtx (DImode);
18037 operands[3] = lowpart_subreg (SImode, operands[2], DImode);
18040 (define_insn_and_split "*bsr_2"
18041 [(set (match_operand:DI 0 "register_operand")
18046 (clz:SI (match_operand:SI 1 "nonimmediate_operand")))
18048 (clobber (reg:CC FLAGS_REG))]
18049 "!TARGET_LZCNT && TARGET_64BIT && ix86_pre_reload_split ()"
18052 [(parallel [(set (reg:CCZ FLAGS_REG)
18053 (compare:CCZ (match_dup 1) (const_int 0)))
18055 (minus:SI (const_int 31) (clz:SI (match_dup 1))))])
18056 (parallel [(set (match_dup 0)
18057 (zero_extend:DI (xor:SI (match_dup 2) (const_int 31))))
18058 (clobber (reg:CC FLAGS_REG))])]
18059 "operands[2] = gen_reg_rtx (SImode);")
18061 ; Splitters to optimize 64 - __builtin_clzl (x) or 32 - __builtin_clz (x).
18062 ; Again, as for !TARGET_LZCNT CLZ is UB at zero, CLZ is guaranteed to be
18063 ; in [0, 63] or [0, 31] range.
18065 [(set (match_operand:SI 0 "register_operand")
18067 (match_operand:SI 2 "const_int_operand")
18069 (minus:SI (const_int 63)
18071 (clz:DI (match_operand:DI 1 "nonimmediate_operand"))
18074 "!TARGET_LZCNT && TARGET_64BIT && ix86_pre_reload_split ()"
18075 [(set (match_dup 3)
18076 (minus:DI (const_int 63) (clz:DI (match_dup 1))))
18078 (plus:SI (match_dup 5) (match_dup 4)))]
18080 operands[3] = gen_reg_rtx (DImode);
18081 operands[5] = lowpart_subreg (SImode, operands[3], DImode);
18082 if (INTVAL (operands[2]) == 63)
18084 emit_insn (gen_bsr_rex64_1_zext (operands[3], operands[1]));
18085 emit_move_insn (operands[0], operands[5]);
18088 operands[4] = gen_int_mode (UINTVAL (operands[2]) - 63, SImode);
18092 [(set (match_operand:SI 0 "register_operand")
18094 (match_operand:SI 2 "const_int_operand")
18096 (minus:SI (const_int 31)
18097 (clz:SI (match_operand:SI 1 "nonimmediate_operand")))
18099 "!TARGET_LZCNT && ix86_pre_reload_split ()"
18100 [(set (match_dup 3)
18101 (minus:SI (const_int 31) (clz:SI (match_dup 1))))
18103 (plus:SI (match_dup 3) (match_dup 4)))]
18105 if (INTVAL (operands[2]) == 31)
18107 emit_insn (gen_bsr_1 (operands[0], operands[1]));
18110 operands[3] = gen_reg_rtx (SImode);
18111 operands[4] = gen_int_mode (UINTVAL (operands[2]) - 31, SImode);
18115 [(set (match_operand:DI 0 "register_operand")
18117 (match_operand:DI 2 "const_int_operand")
18120 (minus:SI (const_int 63)
18122 (clz:DI (match_operand:DI 1 "nonimmediate_operand"))
18127 && ix86_pre_reload_split ()
18128 && ((unsigned HOST_WIDE_INT)
18129 trunc_int_for_mode (UINTVAL (operands[2]) - 63, SImode)
18130 == UINTVAL (operands[2]) - 63)"
18131 [(set (match_dup 3)
18132 (minus:DI (const_int 63) (clz:DI (match_dup 1))))
18134 (plus:DI (match_dup 3) (match_dup 4)))]
18136 if (INTVAL (operands[2]) == 63)
18138 emit_insn (gen_bsr_rex64_1 (operands[0], operands[1]));
18141 operands[3] = gen_reg_rtx (DImode);
18142 operands[4] = GEN_INT (UINTVAL (operands[2]) - 63);
18146 [(set (match_operand:DI 0 "register_operand")
18148 (match_operand:DI 2 "const_int_operand")
18151 (minus:SI (const_int 31)
18152 (clz:SI (match_operand:SI 1 "nonimmediate_operand")))
18153 (const_int 31)))))]
18156 && ix86_pre_reload_split ()
18157 && ((unsigned HOST_WIDE_INT)
18158 trunc_int_for_mode (UINTVAL (operands[2]) - 31, SImode)
18159 == UINTVAL (operands[2]) - 31)"
18160 [(set (match_dup 3)
18161 (zero_extend:DI (minus:SI (const_int 31) (clz:SI (match_dup 1)))))
18163 (plus:DI (match_dup 3) (match_dup 4)))]
18165 if (INTVAL (operands[2]) == 31)
18167 emit_insn (gen_bsr_zext_1 (operands[0], operands[1]));
18170 operands[3] = gen_reg_rtx (DImode);
18171 operands[4] = GEN_INT (UINTVAL (operands[2]) - 31);
18174 (define_expand "clz<mode>2"
18176 [(set (reg:CCZ FLAGS_REG)
18177 (compare:CCZ (match_operand:SWI48 1 "nonimmediate_operand" "rm")
18179 (set (match_dup 3) (minus:SWI48
18181 (clz:SWI48 (match_dup 1))))])
18183 [(set (match_operand:SWI48 0 "register_operand")
18184 (xor:SWI48 (match_dup 3) (match_dup 2)))
18185 (clobber (reg:CC FLAGS_REG))])]
18190 emit_insn (gen_clz<mode>2_lzcnt (operands[0], operands[1]));
18193 operands[2] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
18194 operands[3] = gen_reg_rtx (<MODE>mode);
18197 (define_insn_and_split "clz<mode>2_lzcnt"
18198 [(set (match_operand:SWI48 0 "register_operand" "=r")
18200 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
18201 (clobber (reg:CC FLAGS_REG))]
18203 "lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
18204 "&& TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
18205 && optimize_function_for_speed_p (cfun)
18206 && !reg_mentioned_p (operands[0], operands[1])"
18208 [(set (match_dup 0)
18209 (clz:SWI48 (match_dup 1)))
18210 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
18211 (clobber (reg:CC FLAGS_REG))])]
18212 "ix86_expand_clear (operands[0]);"
18213 [(set_attr "prefix_rep" "1")
18214 (set_attr "type" "bitmanip")
18215 (set_attr "mode" "<MODE>")])
18217 ; False dependency happens when destination is only updated by tzcnt,
18218 ; lzcnt or popcnt. There is no false dependency when destination is
18219 ; also used in source.
18220 (define_insn "*clz<mode>2_lzcnt_falsedep"
18221 [(set (match_operand:SWI48 0 "register_operand" "=r")
18223 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
18224 (unspec [(match_operand:SWI48 2 "register_operand" "0")]
18225 UNSPEC_INSN_FALSE_DEP)
18226 (clobber (reg:CC FLAGS_REG))]
18228 "lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
18229 [(set_attr "prefix_rep" "1")
18230 (set_attr "type" "bitmanip")
18231 (set_attr "mode" "<MODE>")])
18233 (define_insn_and_split "*clzsi2_lzcnt_zext"
18234 [(set (match_operand:DI 0 "register_operand" "=r")
18238 (match_operand:SI 1 "nonimmediate_operand" "rm")) 0)
18240 (clobber (reg:CC FLAGS_REG))]
18241 "TARGET_LZCNT && TARGET_64BIT"
18242 "lzcnt{l}\t{%1, %k0|%k0, %1}"
18243 "&& TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
18244 && optimize_function_for_speed_p (cfun)
18245 && !reg_mentioned_p (operands[0], operands[1])"
18247 [(set (match_dup 0)
18248 (and:DI (subreg:DI (clz:SI (match_dup 1)) 0) (const_int 63)))
18249 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
18250 (clobber (reg:CC FLAGS_REG))])]
18251 "ix86_expand_clear (operands[0]);"
18252 [(set_attr "prefix_rep" "1")
18253 (set_attr "type" "bitmanip")
18254 (set_attr "mode" "SI")])
18256 ; False dependency happens when destination is only updated by tzcnt,
18257 ; lzcnt or popcnt. There is no false dependency when destination is
18258 ; also used in source.
18259 (define_insn "*clzsi2_lzcnt_zext_falsedep"
18260 [(set (match_operand:DI 0 "register_operand" "=r")
18264 (match_operand:SWI48 1 "nonimmediate_operand" "rm")) 0)
18266 (unspec [(match_operand:DI 2 "register_operand" "0")]
18267 UNSPEC_INSN_FALSE_DEP)
18268 (clobber (reg:CC FLAGS_REG))]
18270 "lzcnt{l}\t{%1, %k0|%k0, %1}"
18271 [(set_attr "prefix_rep" "1")
18272 (set_attr "type" "bitmanip")
18273 (set_attr "mode" "SI")])
18275 (define_insn_and_split "*clzsi2_lzcnt_zext_2"
18276 [(set (match_operand:DI 0 "register_operand" "=r")
18278 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
18279 (clobber (reg:CC FLAGS_REG))]
18280 "TARGET_LZCNT && TARGET_64BIT"
18281 "lzcnt{l}\t{%1, %k0|%k0, %1}"
18282 "&& TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
18283 && optimize_function_for_speed_p (cfun)
18284 && !reg_mentioned_p (operands[0], operands[1])"
18286 [(set (match_dup 0)
18287 (zero_extend:DI (clz:SI (match_dup 1))))
18288 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
18289 (clobber (reg:CC FLAGS_REG))])]
18290 "ix86_expand_clear (operands[0]);"
18291 [(set_attr "prefix_rep" "1")
18292 (set_attr "type" "bitmanip")
18293 (set_attr "mode" "SI")])
18295 ; False dependency happens when destination is only updated by tzcnt,
18296 ; lzcnt or popcnt. There is no false dependency when destination is
18297 ; also used in source.
18298 (define_insn "*clzsi2_lzcnt_zext_2_falsedep"
18299 [(set (match_operand:DI 0 "register_operand" "=r")
18301 (clz:SI (match_operand:SWI48 1 "nonimmediate_operand" "rm"))))
18302 (unspec [(match_operand:DI 2 "register_operand" "0")]
18303 UNSPEC_INSN_FALSE_DEP)
18304 (clobber (reg:CC FLAGS_REG))]
18306 "lzcnt{l}\t{%1, %k0|%k0, %1}"
18307 [(set_attr "prefix_rep" "1")
18308 (set_attr "type" "bitmanip")
18309 (set_attr "mode" "SI")])
18311 (define_int_iterator LT_ZCNT
18312 [(UNSPEC_TZCNT "TARGET_BMI")
18313 (UNSPEC_LZCNT "TARGET_LZCNT")])
18315 (define_int_attr lt_zcnt
18316 [(UNSPEC_TZCNT "tzcnt")
18317 (UNSPEC_LZCNT "lzcnt")])
18319 (define_int_attr lt_zcnt_type
18320 [(UNSPEC_TZCNT "alu1")
18321 (UNSPEC_LZCNT "bitmanip")])
18323 ;; Version of lzcnt/tzcnt that is expanded from intrinsics. This version
18324 ;; provides operand size as output when source operand is zero.
18326 (define_insn_and_split "<lt_zcnt>_<mode>"
18327 [(set (match_operand:SWI48 0 "register_operand" "=r")
18329 [(match_operand:SWI48 1 "nonimmediate_operand" "rm")] LT_ZCNT))
18330 (clobber (reg:CC FLAGS_REG))]
18332 "<lt_zcnt>{<imodesuffix>}\t{%1, %0|%0, %1}"
18333 "&& TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
18334 && optimize_function_for_speed_p (cfun)
18335 && !reg_mentioned_p (operands[0], operands[1])"
18337 [(set (match_dup 0)
18338 (unspec:SWI48 [(match_dup 1)] LT_ZCNT))
18339 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
18340 (clobber (reg:CC FLAGS_REG))])]
18341 "ix86_expand_clear (operands[0]);"
18342 [(set_attr "type" "<lt_zcnt_type>")
18343 (set_attr "prefix_0f" "1")
18344 (set_attr "prefix_rep" "1")
18345 (set_attr "mode" "<MODE>")])
18347 ; False dependency happens when destination is only updated by tzcnt,
18348 ; lzcnt or popcnt. There is no false dependency when destination is
18349 ; also used in source.
18350 (define_insn "*<lt_zcnt>_<mode>_falsedep"
18351 [(set (match_operand:SWI48 0 "register_operand" "=r")
18353 [(match_operand:SWI48 1 "nonimmediate_operand" "rm")] LT_ZCNT))
18354 (unspec [(match_operand:SWI48 2 "register_operand" "0")]
18355 UNSPEC_INSN_FALSE_DEP)
18356 (clobber (reg:CC FLAGS_REG))]
18358 "<lt_zcnt>{<imodesuffix>}\t{%1, %0|%0, %1}"
18359 [(set_attr "type" "<lt_zcnt_type>")
18360 (set_attr "prefix_0f" "1")
18361 (set_attr "prefix_rep" "1")
18362 (set_attr "mode" "<MODE>")])
18364 (define_insn "<lt_zcnt>_hi"
18365 [(set (match_operand:HI 0 "register_operand" "=r")
18367 [(match_operand:HI 1 "nonimmediate_operand" "rm")] LT_ZCNT))
18368 (clobber (reg:CC FLAGS_REG))]
18370 "<lt_zcnt>{w}\t{%1, %0|%0, %1}"
18371 [(set_attr "type" "<lt_zcnt_type>")
18372 (set_attr "prefix_0f" "1")
18373 (set_attr "prefix_rep" "1")
18374 (set_attr "mode" "HI")])
18376 ;; BMI instructions.
18378 (define_insn "bmi_bextr_<mode>"
18379 [(set (match_operand:SWI48 0 "register_operand" "=r,r")
18380 (unspec:SWI48 [(match_operand:SWI48 1 "nonimmediate_operand" "r,m")
18381 (match_operand:SWI48 2 "register_operand" "r,r")]
18383 (clobber (reg:CC FLAGS_REG))]
18385 "bextr\t{%2, %1, %0|%0, %1, %2}"
18386 [(set_attr "type" "bitmanip")
18387 (set_attr "btver2_decode" "direct, double")
18388 (set_attr "mode" "<MODE>")])
18390 (define_insn "*bmi_bextr_<mode>_ccz"
18391 [(set (reg:CCZ FLAGS_REG)
18393 (unspec:SWI48 [(match_operand:SWI48 1 "nonimmediate_operand" "r,m")
18394 (match_operand:SWI48 2 "register_operand" "r,r")]
18397 (clobber (match_scratch:SWI48 0 "=r,r"))]
18399 "bextr\t{%2, %1, %0|%0, %1, %2}"
18400 [(set_attr "type" "bitmanip")
18401 (set_attr "btver2_decode" "direct, double")
18402 (set_attr "mode" "<MODE>")])
18404 (define_insn "*bmi_blsi_<mode>"
18405 [(set (match_operand:SWI48 0 "register_operand" "=r")
18408 (match_operand:SWI48 1 "nonimmediate_operand" "rm"))
18410 (clobber (reg:CC FLAGS_REG))]
18412 "blsi\t{%1, %0|%0, %1}"
18413 [(set_attr "type" "bitmanip")
18414 (set_attr "btver2_decode" "double")
18415 (set_attr "mode" "<MODE>")])
18417 (define_insn "*bmi_blsi_<mode>_cmp"
18418 [(set (reg FLAGS_REG)
18421 (neg:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm"))
18424 (set (match_operand:SWI48 0 "register_operand" "=r")
18425 (and:SWI48 (neg:SWI48 (match_dup 1)) (match_dup 1)))]
18426 "TARGET_BMI && ix86_match_ccmode (insn, CCNOmode)"
18427 "blsi\t{%1, %0|%0, %1}"
18428 [(set_attr "type" "bitmanip")
18429 (set_attr "btver2_decode" "double")
18430 (set_attr "mode" "<MODE>")])
18432 (define_insn "*bmi_blsi_<mode>_ccno"
18433 [(set (reg FLAGS_REG)
18436 (neg:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm"))
18439 (clobber (match_scratch:SWI48 0 "=r"))]
18440 "TARGET_BMI && ix86_match_ccmode (insn, CCNOmode)"
18441 "blsi\t{%1, %0|%0, %1}"
18442 [(set_attr "type" "bitmanip")
18443 (set_attr "btver2_decode" "double")
18444 (set_attr "mode" "<MODE>")])
18446 (define_insn "*bmi_blsmsk_<mode>"
18447 [(set (match_operand:SWI48 0 "register_operand" "=r")
18450 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
18453 (clobber (reg:CC FLAGS_REG))]
18455 "blsmsk\t{%1, %0|%0, %1}"
18456 [(set_attr "type" "bitmanip")
18457 (set_attr "btver2_decode" "double")
18458 (set_attr "mode" "<MODE>")])
18460 (define_insn "*bmi_blsr_<mode>"
18461 [(set (match_operand:SWI48 0 "register_operand" "=r")
18464 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
18467 (clobber (reg:CC FLAGS_REG))]
18469 "blsr\t{%1, %0|%0, %1}"
18470 [(set_attr "type" "bitmanip")
18471 (set_attr "btver2_decode" "double")
18472 (set_attr "mode" "<MODE>")])
18474 (define_insn "*bmi_blsr_<mode>_cmp"
18475 [(set (reg:CCZ FLAGS_REG)
18479 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
18483 (set (match_operand:SWI48 0 "register_operand" "=r")
18490 "blsr\t{%1, %0|%0, %1}"
18491 [(set_attr "type" "bitmanip")
18492 (set_attr "btver2_decode" "double")
18493 (set_attr "mode" "<MODE>")])
18495 (define_insn "*bmi_blsr_<mode>_ccz"
18496 [(set (reg:CCZ FLAGS_REG)
18500 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
18504 (clobber (match_scratch:SWI48 0 "=r"))]
18506 "blsr\t{%1, %0|%0, %1}"
18507 [(set_attr "type" "bitmanip")
18508 (set_attr "btver2_decode" "double")
18509 (set_attr "mode" "<MODE>")])
18511 ;; BMI2 instructions.
18512 (define_expand "bmi2_bzhi_<mode>3"
18514 [(set (match_operand:SWI48 0 "register_operand")
18515 (if_then_else:SWI48
18516 (ne:QI (and:SWI48 (match_operand:SWI48 2 "register_operand")
18519 (zero_extract:SWI48
18520 (match_operand:SWI48 1 "nonimmediate_operand")
18521 (umin:SWI48 (and:SWI48 (match_dup 2) (const_int 255))
18525 (clobber (reg:CC FLAGS_REG))])]
18527 "operands[3] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT);")
18529 (define_insn "*bmi2_bzhi_<mode>3"
18530 [(set (match_operand:SWI48 0 "register_operand" "=r")
18531 (if_then_else:SWI48
18532 (ne:QI (and:SWI48 (match_operand:SWI48 2 "register_operand" "r")
18535 (zero_extract:SWI48
18536 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
18537 (umin:SWI48 (and:SWI48 (match_dup 2) (const_int 255))
18538 (match_operand:SWI48 3 "const_int_operand"))
18541 (clobber (reg:CC FLAGS_REG))]
18542 "TARGET_BMI2 && INTVAL (operands[3]) == <MODE_SIZE> * BITS_PER_UNIT"
18543 "bzhi\t{%2, %1, %0|%0, %1, %2}"
18544 [(set_attr "type" "bitmanip")
18545 (set_attr "prefix" "vex")
18546 (set_attr "mode" "<MODE>")])
18548 (define_insn "*bmi2_bzhi_<mode>3_1"
18549 [(set (match_operand:SWI48 0 "register_operand" "=r")
18550 (if_then_else:SWI48
18551 (ne:QI (match_operand:QI 2 "register_operand" "r") (const_int 0))
18552 (zero_extract:SWI48
18553 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
18554 (umin:SWI48 (zero_extend:SWI48 (match_dup 2))
18555 (match_operand:SWI48 3 "const_int_operand"))
18558 (clobber (reg:CC FLAGS_REG))]
18559 "TARGET_BMI2 && INTVAL (operands[3]) == <MODE_SIZE> * BITS_PER_UNIT"
18560 "bzhi\t{%<k>2, %1, %0|%0, %1, %<k>2}"
18561 [(set_attr "type" "bitmanip")
18562 (set_attr "prefix" "vex")
18563 (set_attr "mode" "<MODE>")])
18565 (define_insn "*bmi2_bzhi_<mode>3_1_ccz"
18566 [(set (reg:CCZ FLAGS_REG)
18568 (if_then_else:SWI48
18569 (ne:QI (match_operand:QI 2 "register_operand" "r") (const_int 0))
18570 (zero_extract:SWI48
18571 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
18572 (umin:SWI48 (zero_extend:SWI48 (match_dup 2))
18573 (match_operand:SWI48 3 "const_int_operand"))
18577 (clobber (match_scratch:SWI48 0 "=r"))]
18578 "TARGET_BMI2 && INTVAL (operands[3]) == <MODE_SIZE> * BITS_PER_UNIT"
18579 "bzhi\t{%<k>2, %1, %0|%0, %1, %<k>2}"
18580 [(set_attr "type" "bitmanip")
18581 (set_attr "prefix" "vex")
18582 (set_attr "mode" "<MODE>")])
18584 (define_insn "*bmi2_bzhi_<mode>3_2"
18585 [(set (match_operand:SWI48 0 "register_operand" "=r")
18588 (ashift:SWI48 (const_int 1)
18589 (match_operand:QI 2 "register_operand" "r"))
18591 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
18592 (clobber (reg:CC FLAGS_REG))]
18594 "bzhi\t{%<k>2, %1, %0|%0, %1, %<k>2}"
18595 [(set_attr "type" "bitmanip")
18596 (set_attr "prefix" "vex")
18597 (set_attr "mode" "<MODE>")])
18599 (define_insn "*bmi2_bzhi_<mode>3_3"
18600 [(set (match_operand:SWI48 0 "register_operand" "=r")
18603 (ashift:SWI48 (const_int -1)
18604 (match_operand:QI 2 "register_operand" "r")))
18605 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
18606 (clobber (reg:CC FLAGS_REG))]
18608 "bzhi\t{%<k>2, %1, %0|%0, %1, %<k>2}"
18609 [(set_attr "type" "bitmanip")
18610 (set_attr "prefix" "vex")
18611 (set_attr "mode" "<MODE>")])
18613 (define_insn "*bmi2_bzhi_zero_extendsidi_4"
18614 [(set (match_operand:DI 0 "register_operand" "=r")
18618 (ashift:SI (const_int 1)
18619 (match_operand:QI 2 "register_operand" "r"))
18621 (match_operand:SI 1 "nonimmediate_operand" "rm"))))
18622 (clobber (reg:CC FLAGS_REG))]
18623 "TARGET_64BIT && TARGET_BMI2"
18624 "bzhi\t{%q2, %q1, %q0|%q0, %q1, %q2}"
18625 [(set_attr "type" "bitmanip")
18626 (set_attr "prefix" "vex")
18627 (set_attr "mode" "DI")])
18629 (define_insn "*bmi2_bzhi_zero_extendsidi_5"
18630 [(set (match_operand:DI 0 "register_operand" "=r")
18634 (ashift:SI (const_int 1)
18635 (match_operand:QI 2 "register_operand" "r"))
18637 (match_operand:DI 1 "nonimmediate_operand" "rm")))
18638 (clobber (reg:CC FLAGS_REG))]
18639 "TARGET_64BIT && TARGET_BMI2"
18640 "bzhi\t{%q2, %q1, %q0|%q0, %q1, %q2}"
18641 [(set_attr "type" "bitmanip")
18642 (set_attr "prefix" "vex")
18643 (set_attr "mode" "DI")])
18645 (define_insn "bmi2_pdep_<mode>3"
18646 [(set (match_operand:SWI48 0 "register_operand" "=r")
18647 (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
18648 (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
18651 "pdep\t{%2, %1, %0|%0, %1, %2}"
18652 [(set_attr "type" "bitmanip")
18653 (set_attr "prefix" "vex")
18654 (set_attr "mode" "<MODE>")])
18656 (define_insn "bmi2_pext_<mode>3"
18657 [(set (match_operand:SWI48 0 "register_operand" "=r")
18658 (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
18659 (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
18662 "pext\t{%2, %1, %0|%0, %1, %2}"
18663 [(set_attr "type" "bitmanip")
18664 (set_attr "prefix" "vex")
18665 (set_attr "mode" "<MODE>")])
18667 ;; TBM instructions.
18668 (define_insn "@tbm_bextri_<mode>"
18669 [(set (match_operand:SWI48 0 "register_operand" "=r")
18670 (zero_extract:SWI48
18671 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
18672 (match_operand 2 "const_0_to_255_operand")
18673 (match_operand 3 "const_0_to_255_operand")))
18674 (clobber (reg:CC FLAGS_REG))]
18677 operands[2] = GEN_INT (INTVAL (operands[2]) << 8 | INTVAL (operands[3]));
18678 return "bextr\t{%2, %1, %0|%0, %1, %2}";
18680 [(set_attr "type" "bitmanip")
18681 (set_attr "mode" "<MODE>")])
18683 (define_insn "*tbm_blcfill_<mode>"
18684 [(set (match_operand:SWI48 0 "register_operand" "=r")
18687 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
18690 (clobber (reg:CC FLAGS_REG))]
18692 "blcfill\t{%1, %0|%0, %1}"
18693 [(set_attr "type" "bitmanip")
18694 (set_attr "mode" "<MODE>")])
18696 (define_insn "*tbm_blci_<mode>"
18697 [(set (match_operand:SWI48 0 "register_operand" "=r")
18701 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
18704 (clobber (reg:CC FLAGS_REG))]
18706 "blci\t{%1, %0|%0, %1}"
18707 [(set_attr "type" "bitmanip")
18708 (set_attr "mode" "<MODE>")])
18710 (define_insn "*tbm_blcic_<mode>"
18711 [(set (match_operand:SWI48 0 "register_operand" "=r")
18714 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
18718 (clobber (reg:CC FLAGS_REG))]
18720 "blcic\t{%1, %0|%0, %1}"
18721 [(set_attr "type" "bitmanip")
18722 (set_attr "mode" "<MODE>")])
18724 (define_insn "*tbm_blcmsk_<mode>"
18725 [(set (match_operand:SWI48 0 "register_operand" "=r")
18728 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
18731 (clobber (reg:CC FLAGS_REG))]
18733 "blcmsk\t{%1, %0|%0, %1}"
18734 [(set_attr "type" "bitmanip")
18735 (set_attr "mode" "<MODE>")])
18737 (define_insn "*tbm_blcs_<mode>"
18738 [(set (match_operand:SWI48 0 "register_operand" "=r")
18741 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
18744 (clobber (reg:CC FLAGS_REG))]
18746 "blcs\t{%1, %0|%0, %1}"
18747 [(set_attr "type" "bitmanip")
18748 (set_attr "mode" "<MODE>")])
18750 (define_insn "*tbm_blsfill_<mode>"
18751 [(set (match_operand:SWI48 0 "register_operand" "=r")
18754 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
18757 (clobber (reg:CC FLAGS_REG))]
18759 "blsfill\t{%1, %0|%0, %1}"
18760 [(set_attr "type" "bitmanip")
18761 (set_attr "mode" "<MODE>")])
18763 (define_insn "*tbm_blsic_<mode>"
18764 [(set (match_operand:SWI48 0 "register_operand" "=r")
18767 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
18771 (clobber (reg:CC FLAGS_REG))]
18773 "blsic\t{%1, %0|%0, %1}"
18774 [(set_attr "type" "bitmanip")
18775 (set_attr "mode" "<MODE>")])
18777 (define_insn "*tbm_t1mskc_<mode>"
18778 [(set (match_operand:SWI48 0 "register_operand" "=r")
18781 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
18785 (clobber (reg:CC FLAGS_REG))]
18787 "t1mskc\t{%1, %0|%0, %1}"
18788 [(set_attr "type" "bitmanip")
18789 (set_attr "mode" "<MODE>")])
18791 (define_insn "*tbm_tzmsk_<mode>"
18792 [(set (match_operand:SWI48 0 "register_operand" "=r")
18795 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
18799 (clobber (reg:CC FLAGS_REG))]
18801 "tzmsk\t{%1, %0|%0, %1}"
18802 [(set_attr "type" "bitmanip")
18803 (set_attr "mode" "<MODE>")])
18805 (define_insn_and_split "popcount<mode>2"
18806 [(set (match_operand:SWI48 0 "register_operand" "=r")
18808 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
18809 (clobber (reg:CC FLAGS_REG))]
18813 return "popcnt\t{%1, %0|%0, %1}";
18815 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
18818 "&& TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
18819 && optimize_function_for_speed_p (cfun)
18820 && !reg_mentioned_p (operands[0], operands[1])"
18822 [(set (match_dup 0)
18823 (popcount:SWI48 (match_dup 1)))
18824 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
18825 (clobber (reg:CC FLAGS_REG))])]
18826 "ix86_expand_clear (operands[0]);"
18827 [(set_attr "prefix_rep" "1")
18828 (set_attr "type" "bitmanip")
18829 (set_attr "mode" "<MODE>")])
18831 ; False dependency happens when destination is only updated by tzcnt,
18832 ; lzcnt or popcnt. There is no false dependency when destination is
18833 ; also used in source.
18834 (define_insn "*popcount<mode>2_falsedep"
18835 [(set (match_operand:SWI48 0 "register_operand" "=r")
18837 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
18838 (unspec [(match_operand:SWI48 2 "register_operand" "0")]
18839 UNSPEC_INSN_FALSE_DEP)
18840 (clobber (reg:CC FLAGS_REG))]
18844 return "popcnt\t{%1, %0|%0, %1}";
18846 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
18849 [(set_attr "prefix_rep" "1")
18850 (set_attr "type" "bitmanip")
18851 (set_attr "mode" "<MODE>")])
18853 (define_insn_and_split "*popcountsi2_zext"
18854 [(set (match_operand:DI 0 "register_operand" "=r")
18858 (match_operand:SI 1 "nonimmediate_operand" "rm")) 0)
18860 (clobber (reg:CC FLAGS_REG))]
18861 "TARGET_POPCNT && TARGET_64BIT"
18864 return "popcnt\t{%1, %k0|%k0, %1}";
18866 return "popcnt{l}\t{%1, %k0|%k0, %1}";
18869 "&& TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
18870 && optimize_function_for_speed_p (cfun)
18871 && !reg_mentioned_p (operands[0], operands[1])"
18873 [(set (match_dup 0)
18874 (and:DI (subreg:DI (popcount:SI (match_dup 1)) 0) (const_int 63)))
18875 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
18876 (clobber (reg:CC FLAGS_REG))])]
18877 "ix86_expand_clear (operands[0]);"
18878 [(set_attr "prefix_rep" "1")
18879 (set_attr "type" "bitmanip")
18880 (set_attr "mode" "SI")])
18882 ; False dependency happens when destination is only updated by tzcnt,
18883 ; lzcnt or popcnt. There is no false dependency when destination is
18884 ; also used in source.
18885 (define_insn "*popcountsi2_zext_falsedep"
18886 [(set (match_operand:DI 0 "register_operand" "=r")
18890 (match_operand:SI 1 "nonimmediate_operand" "rm")) 0)
18892 (unspec [(match_operand:DI 2 "register_operand" "0")]
18893 UNSPEC_INSN_FALSE_DEP)
18894 (clobber (reg:CC FLAGS_REG))]
18895 "TARGET_POPCNT && TARGET_64BIT"
18898 return "popcnt\t{%1, %k0|%k0, %1}";
18900 return "popcnt{l}\t{%1, %k0|%k0, %1}";
18903 [(set_attr "prefix_rep" "1")
18904 (set_attr "type" "bitmanip")
18905 (set_attr "mode" "SI")])
18907 (define_insn_and_split "*popcountsi2_zext_2"
18908 [(set (match_operand:DI 0 "register_operand" "=r")
18910 (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
18911 (clobber (reg:CC FLAGS_REG))]
18912 "TARGET_POPCNT && TARGET_64BIT"
18915 return "popcnt\t{%1, %k0|%k0, %1}";
18917 return "popcnt{l}\t{%1, %k0|%k0, %1}";
18920 "&& TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
18921 && optimize_function_for_speed_p (cfun)
18922 && !reg_mentioned_p (operands[0], operands[1])"
18924 [(set (match_dup 0)
18925 (zero_extend:DI (popcount:SI (match_dup 1))))
18926 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
18927 (clobber (reg:CC FLAGS_REG))])]
18928 "ix86_expand_clear (operands[0]);"
18929 [(set_attr "prefix_rep" "1")
18930 (set_attr "type" "bitmanip")
18931 (set_attr "mode" "SI")])
18933 ; False dependency happens when destination is only updated by tzcnt,
18934 ; lzcnt or popcnt. There is no false dependency when destination is
18935 ; also used in source.
18936 (define_insn "*popcountsi2_zext_2_falsedep"
18937 [(set (match_operand:DI 0 "register_operand" "=r")
18939 (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
18940 (unspec [(match_operand:DI 2 "register_operand" "0")]
18941 UNSPEC_INSN_FALSE_DEP)
18942 (clobber (reg:CC FLAGS_REG))]
18943 "TARGET_POPCNT && TARGET_64BIT"
18946 return "popcnt\t{%1, %k0|%k0, %1}";
18948 return "popcnt{l}\t{%1, %k0|%k0, %1}";
18951 [(set_attr "prefix_rep" "1")
18952 (set_attr "type" "bitmanip")
18953 (set_attr "mode" "SI")])
18955 (define_insn_and_split "*popcounthi2_1"
18956 [(set (match_operand:SI 0 "register_operand")
18958 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand"))))
18959 (clobber (reg:CC FLAGS_REG))]
18961 && ix86_pre_reload_split ()"
18966 rtx tmp = gen_reg_rtx (HImode);
18968 emit_insn (gen_popcounthi2 (tmp, operands[1]));
18969 emit_insn (gen_zero_extendhisi2 (operands[0], tmp));
18973 (define_insn_and_split "*popcounthi2_2"
18974 [(set (match_operand:SI 0 "register_operand")
18976 (popcount:HI (match_operand:HI 1 "nonimmediate_operand"))))
18977 (clobber (reg:CC FLAGS_REG))]
18979 && ix86_pre_reload_split ()"
18984 rtx tmp = gen_reg_rtx (HImode);
18986 emit_insn (gen_popcounthi2 (tmp, operands[1]));
18987 emit_insn (gen_zero_extendhisi2 (operands[0], tmp));
18991 (define_insn "popcounthi2"
18992 [(set (match_operand:HI 0 "register_operand" "=r")
18994 (match_operand:HI 1 "nonimmediate_operand" "rm")))
18995 (clobber (reg:CC FLAGS_REG))]
18999 return "popcnt\t{%1, %0|%0, %1}";
19001 return "popcnt{w}\t{%1, %0|%0, %1}";
19004 [(set_attr "prefix_rep" "1")
19005 (set_attr "type" "bitmanip")
19006 (set_attr "mode" "HI")])
19008 (define_expand "bswapdi2"
19009 [(set (match_operand:DI 0 "register_operand")
19010 (bswap:DI (match_operand:DI 1 "nonimmediate_operand")))]
19014 operands[1] = force_reg (DImode, operands[1]);
19017 (define_expand "bswapsi2"
19018 [(set (match_operand:SI 0 "register_operand")
19019 (bswap:SI (match_operand:SI 1 "nonimmediate_operand")))]
19024 else if (TARGET_BSWAP)
19025 operands[1] = force_reg (SImode, operands[1]);
19028 rtx x = operands[0];
19030 emit_move_insn (x, operands[1]);
19031 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
19032 emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
19033 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
19038 (define_insn "*bswap<mode>2_movbe"
19039 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,r,m")
19040 (bswap:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,m,r")))]
19042 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
19045 movbe{<imodesuffix>}\t{%1, %0|%0, %1}
19046 movbe{<imodesuffix>}\t{%1, %0|%0, %1}"
19047 [(set_attr "type" "bitmanip,imov,imov")
19048 (set_attr "modrm" "0,1,1")
19049 (set_attr "prefix_0f" "*,1,1")
19050 (set_attr "prefix_extra" "*,1,1")
19051 (set_attr "mode" "<MODE>")])
19053 (define_insn "*bswap<mode>2"
19054 [(set (match_operand:SWI48 0 "register_operand" "=r")
19055 (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "0")))]
19058 [(set_attr "type" "bitmanip")
19059 (set_attr "modrm" "0")
19060 (set_attr "mode" "<MODE>")])
19062 (define_expand "bswaphi2"
19063 [(set (match_operand:HI 0 "register_operand")
19064 (bswap:HI (match_operand:HI 1 "nonimmediate_operand")))]
19067 (define_insn "*bswaphi2_movbe"
19068 [(set (match_operand:HI 0 "nonimmediate_operand" "=Q,r,m")
19069 (bswap:HI (match_operand:HI 1 "nonimmediate_operand" "0,m,r")))]
19071 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
19073 xchg{b}\t{%h0, %b0|%b0, %h0}
19074 movbe{w}\t{%1, %0|%0, %1}
19075 movbe{w}\t{%1, %0|%0, %1}"
19076 [(set_attr "type" "imov")
19077 (set_attr "modrm" "*,1,1")
19078 (set_attr "prefix_0f" "*,1,1")
19079 (set_attr "prefix_extra" "*,1,1")
19080 (set_attr "pent_pair" "np,*,*")
19081 (set_attr "athlon_decode" "vector,*,*")
19082 (set_attr "amdfam10_decode" "double,*,*")
19083 (set_attr "bdver1_decode" "double,*,*")
19084 (set_attr "mode" "QI,HI,HI")])
19087 [(set (match_operand:HI 0 "general_reg_operand")
19088 (bswap:HI (match_dup 0)))]
19090 && !(TARGET_USE_XCHGB || optimize_function_for_size_p (cfun))
19091 && peep2_regno_dead_p (0, FLAGS_REG)"
19092 [(parallel [(set (match_dup 0) (rotate:HI (match_dup 0) (const_int 8)))
19093 (clobber (reg:CC FLAGS_REG))])])
19095 (define_insn "bswaphi_lowpart"
19096 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
19097 (bswap:HI (match_dup 0)))
19098 (clobber (reg:CC FLAGS_REG))]
19101 xchg{b}\t{%h0, %b0|%b0, %h0}
19102 rol{w}\t{$8, %0|%0, 8}"
19103 [(set (attr "preferred_for_size")
19104 (cond [(eq_attr "alternative" "0")
19105 (symbol_ref "true")]
19106 (symbol_ref "false")))
19107 (set (attr "preferred_for_speed")
19108 (cond [(eq_attr "alternative" "0")
19109 (symbol_ref "TARGET_USE_XCHGB")]
19110 (symbol_ref "!TARGET_USE_XCHGB")))
19111 (set_attr "length" "2,4")
19112 (set_attr "mode" "QI,HI")])
19114 (define_expand "paritydi2"
19115 [(set (match_operand:DI 0 "register_operand")
19116 (parity:DI (match_operand:DI 1 "register_operand")))]
19119 rtx scratch = gen_reg_rtx (QImode);
19120 rtx hipart1 = gen_reg_rtx (SImode);
19121 rtx lopart1 = gen_reg_rtx (SImode);
19122 rtx xor1 = gen_reg_rtx (SImode);
19123 rtx shift2 = gen_reg_rtx (SImode);
19124 rtx hipart2 = gen_reg_rtx (HImode);
19125 rtx lopart2 = gen_reg_rtx (HImode);
19126 rtx xor2 = gen_reg_rtx (HImode);
19130 rtx shift1 = gen_reg_rtx (DImode);
19131 emit_insn (gen_lshrdi3 (shift1, operands[1], GEN_INT (32)));
19132 emit_move_insn (hipart1, gen_lowpart (SImode, shift1));
19135 emit_move_insn (hipart1, gen_highpart (SImode, operands[1]));
19137 emit_move_insn (lopart1, gen_lowpart (SImode, operands[1]));
19138 emit_insn (gen_xorsi3 (xor1, hipart1, lopart1));
19140 emit_insn (gen_lshrsi3 (shift2, xor1, GEN_INT (16)));
19141 emit_move_insn (hipart2, gen_lowpart (HImode, shift2));
19142 emit_move_insn (lopart2, gen_lowpart (HImode, xor1));
19143 emit_insn (gen_xorhi3 (xor2, hipart2, lopart2));
19145 emit_insn (gen_parityhi2_cmp (xor2));
19147 ix86_expand_setcc (scratch, ORDERED,
19148 gen_rtx_REG (CCmode, FLAGS_REG), const0_rtx);
19151 emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
19154 rtx tmp = gen_reg_rtx (SImode);
19156 emit_insn (gen_zero_extendqisi2 (tmp, scratch));
19157 emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
19162 (define_expand "paritysi2"
19163 [(set (match_operand:SI 0 "register_operand")
19164 (parity:SI (match_operand:SI 1 "register_operand")))]
19167 rtx scratch = gen_reg_rtx (QImode);
19168 rtx shift = gen_reg_rtx (SImode);
19169 rtx hipart = gen_reg_rtx (HImode);
19170 rtx lopart = gen_reg_rtx (HImode);
19171 rtx tmp = gen_reg_rtx (HImode);
19173 emit_insn (gen_lshrsi3 (shift, operands[1], GEN_INT (16)));
19174 emit_move_insn (hipart, gen_lowpart (HImode, shift));
19175 emit_move_insn (lopart, gen_lowpart (HImode, operands[1]));
19176 emit_insn (gen_xorhi3 (tmp, hipart, lopart));
19178 emit_insn (gen_parityhi2_cmp (tmp));
19180 ix86_expand_setcc (scratch, ORDERED,
19181 gen_rtx_REG (CCmode, FLAGS_REG), const0_rtx);
19183 emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
19187 (define_expand "parityhi2"
19188 [(set (match_operand:HI 0 "register_operand")
19189 (parity:HI (match_operand:HI 1 "register_operand")))]
19192 rtx scratch = gen_reg_rtx (QImode);
19194 emit_insn (gen_parityhi2_cmp (operands[1]));
19196 ix86_expand_setcc (scratch, ORDERED,
19197 gen_rtx_REG (CCmode, FLAGS_REG), const0_rtx);
19199 emit_insn (gen_zero_extendqihi2 (operands[0], scratch));
19203 (define_expand "parityqi2"
19204 [(set (match_operand:QI 0 "register_operand")
19205 (parity:QI (match_operand:QI 1 "register_operand")))]
19208 emit_insn (gen_parityqi2_cmp (operands[1]));
19210 ix86_expand_setcc (operands[0], ORDERED,
19211 gen_rtx_REG (CCmode, FLAGS_REG), const0_rtx);
19215 (define_insn "parityhi2_cmp"
19216 [(set (reg:CC FLAGS_REG)
19217 (unspec:CC [(match_operand:HI 0 "register_operand" "+Q")]
19219 (clobber (match_dup 0))]
19221 "xor{b}\t{%h0, %b0|%b0, %h0}"
19222 [(set_attr "length" "2")
19223 (set_attr "mode" "QI")])
19225 (define_insn "parityqi2_cmp"
19226 [(set (reg:CC FLAGS_REG)
19227 (unspec:CC [(match_operand:QI 0 "register_operand" "q")]
19231 [(set_attr "mode" "QI")])
19233 ;; Replace zero_extend:HI followed by parityhi2_cmp with parityqi2_cmp
19235 [(set (match_operand:HI 0 "register_operand")
19236 (zero_extend:HI (match_operand:QI 1 "general_reg_operand")))
19237 (parallel [(set (reg:CC FLAGS_REG)
19238 (unspec:CC [(match_dup 0)] UNSPEC_PARITY))
19239 (clobber (match_dup 0))])]
19241 [(set (reg:CC FLAGS_REG)
19242 (unspec:CC [(match_dup 1)] UNSPEC_PARITY))])
19244 ;; Eliminate QImode popcount&1 using parity flag
19246 [(set (match_operand:SI 0 "register_operand")
19247 (zero_extend:SI (match_operand:QI 1 "general_reg_operand")))
19248 (parallel [(set (match_operand:SI 2 "register_operand")
19249 (popcount:SI (match_dup 0)))
19250 (clobber (reg:CC FLAGS_REG))])
19251 (set (reg:CCZ FLAGS_REG)
19252 (compare:CCZ (and:QI (match_operand:QI 3 "register_operand")
19255 (set (pc) (if_then_else (match_operator 4 "bt_comparison_operator"
19256 [(reg:CCZ FLAGS_REG)
19258 (label_ref (match_operand 5))
19260 "REGNO (operands[2]) == REGNO (operands[3])
19261 && peep2_reg_dead_p (3, operands[0])
19262 && peep2_reg_dead_p (3, operands[2])
19263 && peep2_regno_dead_p (4, FLAGS_REG)"
19264 [(set (reg:CC FLAGS_REG)
19265 (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
19266 (set (pc) (if_then_else (match_op_dup 4 [(reg:CC FLAGS_REG)
19268 (label_ref (match_dup 5))
19271 operands[4] = shallow_copy_rtx (operands[4]);
19272 PUT_CODE (operands[4], GET_CODE (operands[4]) == EQ ? UNORDERED : ORDERED);
19275 ;; Eliminate HImode popcount&1 using parity flag
19277 [(match_scratch:HI 0 "Q")
19278 (parallel [(set (match_operand:HI 1 "register_operand")
19280 (match_operand:HI 2 "nonimmediate_operand")))
19281 (clobber (reg:CC FLAGS_REG))])
19282 (set (match_operand 3 "register_operand")
19283 (zero_extend (match_dup 1)))
19284 (set (reg:CCZ FLAGS_REG)
19285 (compare:CCZ (and:QI (match_operand:QI 4 "register_operand")
19288 (set (pc) (if_then_else (match_operator 5 "bt_comparison_operator"
19289 [(reg:CCZ FLAGS_REG)
19291 (label_ref (match_operand 6))
19293 "REGNO (operands[3]) == REGNO (operands[4])
19294 && peep2_reg_dead_p (3, operands[1])
19295 && peep2_reg_dead_p (3, operands[3])
19296 && peep2_regno_dead_p (4, FLAGS_REG)"
19297 [(set (match_dup 0) (match_dup 2))
19298 (parallel [(set (reg:CC FLAGS_REG)
19299 (unspec:CC [(match_dup 0)] UNSPEC_PARITY))
19300 (clobber (match_dup 0))])
19301 (set (pc) (if_then_else (match_op_dup 5 [(reg:CC FLAGS_REG)
19303 (label_ref (match_dup 6))
19306 operands[5] = shallow_copy_rtx (operands[5]);
19307 PUT_CODE (operands[5], GET_CODE (operands[5]) == EQ ? UNORDERED : ORDERED);
19310 ;; Eliminate HImode popcount&1 using parity flag (variant 2)
19312 [(match_scratch:HI 0 "Q")
19313 (parallel [(set (match_operand:HI 1 "register_operand")
19315 (match_operand:HI 2 "nonimmediate_operand")))
19316 (clobber (reg:CC FLAGS_REG))])
19317 (set (reg:CCZ FLAGS_REG)
19318 (compare:CCZ (and:QI (match_operand:QI 3 "register_operand")
19321 (set (pc) (if_then_else (match_operator 4 "bt_comparison_operator"
19322 [(reg:CCZ FLAGS_REG)
19324 (label_ref (match_operand 5))
19326 "REGNO (operands[1]) == REGNO (operands[3])
19327 && peep2_reg_dead_p (2, operands[1])
19328 && peep2_reg_dead_p (2, operands[3])
19329 && peep2_regno_dead_p (3, FLAGS_REG)"
19330 [(set (match_dup 0) (match_dup 2))
19331 (parallel [(set (reg:CC FLAGS_REG)
19332 (unspec:CC [(match_dup 0)] UNSPEC_PARITY))
19333 (clobber (match_dup 0))])
19334 (set (pc) (if_then_else (match_op_dup 4 [(reg:CC FLAGS_REG)
19336 (label_ref (match_dup 5))
19339 operands[4] = shallow_copy_rtx (operands[4]);
19340 PUT_CODE (operands[4], GET_CODE (operands[4]) == EQ ? UNORDERED : ORDERED);
19344 ;; Thread-local storage patterns for ELF.
19346 ;; Note that these code sequences must appear exactly as shown
19347 ;; in order to allow linker relaxation.
19349 (define_insn "*tls_global_dynamic_32_gnu"
19350 [(set (match_operand:SI 0 "register_operand" "=a")
19352 [(match_operand:SI 1 "register_operand" "Yb")
19353 (match_operand 2 "tls_symbolic_operand")
19354 (match_operand 3 "constant_call_address_operand" "Bz")
19357 (clobber (match_scratch:SI 4 "=d"))
19358 (clobber (match_scratch:SI 5 "=c"))
19359 (clobber (reg:CC FLAGS_REG))]
19360 "!TARGET_64BIT && TARGET_GNU_TLS"
19362 if (TARGET_SUN_TLS || flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT)
19364 ("lea{l}\t{%E2@tlsgd(,%1,1), %0|%0, %E2@tlsgd[%1*1]}", operands);
19367 ("lea{l}\t{%E2@tlsgd(%1), %0|%0, %E2@tlsgd[%1]}", operands);
19368 if (TARGET_SUN_TLS)
19369 #ifdef HAVE_AS_IX86_TLSGDPLT
19370 return "call\t%a2@tlsgdplt";
19372 return "call\t%p3@plt";
19374 if (flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT)
19375 return "call\t%P3";
19376 return "call\t{*%p3@GOT(%1)|[DWORD PTR %p3@GOT[%1]]}";
19378 [(set_attr "type" "multi")
19379 (set_attr "length" "12")])
19381 (define_expand "tls_global_dynamic_32"
19383 [(set (match_operand:SI 0 "register_operand")
19384 (unspec:SI [(match_operand:SI 2 "register_operand")
19385 (match_operand 1 "tls_symbolic_operand")
19386 (match_operand 3 "constant_call_address_operand")
19389 (clobber (scratch:SI))
19390 (clobber (scratch:SI))
19391 (clobber (reg:CC FLAGS_REG))])]
19393 "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
19395 (define_insn "*tls_global_dynamic_64_<mode>"
19396 [(set (match_operand:P 0 "register_operand" "=a")
19398 (mem:QI (match_operand 2 "constant_call_address_operand" "Bz"))
19399 (match_operand 3)))
19400 (unspec:P [(match_operand 1 "tls_symbolic_operand")
19406 /* The .loc directive has effect for 'the immediately following assembly
19407 instruction'. So for a sequence:
19411 the 'immediately following assembly instruction' is insn1.
19412 We want to emit an insn prefix here, but if we use .byte (as shown in
19413 'ELF Handling For Thread-Local Storage'), a preceding .loc will point
19414 inside the insn sequence, rather than to the start. After relaxation
19415 of the sequence by the linker, the .loc might point inside an insn.
19416 Use data16 prefix instead, which doesn't have this problem. */
19417 fputs ("\tdata16", asm_out_file);
19419 ("lea{q}\t{%E1@tlsgd(%%rip), %%rdi|rdi, %E1@tlsgd[rip]}", operands);
19420 if (TARGET_SUN_TLS || flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT)
19421 fputs (ASM_SHORT "0x6666\n", asm_out_file);
19423 fputs (ASM_BYTE "0x66\n", asm_out_file);
19424 fputs ("\trex64\n", asm_out_file);
19425 if (TARGET_SUN_TLS)
19426 return "call\t%p2@plt";
19427 if (flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT)
19428 return "call\t%P2";
19429 return "call\t{*%p2@GOTPCREL(%%rip)|[QWORD PTR %p2@GOTPCREL[rip]]}";
19431 [(set_attr "type" "multi")
19432 (set (attr "length")
19433 (symbol_ref "TARGET_X32 ? 15 : 16"))])
19435 (define_insn "*tls_global_dynamic_64_largepic"
19436 [(set (match_operand:DI 0 "register_operand" "=a")
19438 (mem:QI (plus:DI (match_operand:DI 2 "register_operand" "b")
19439 (match_operand:DI 3 "immediate_operand" "i")))
19440 (match_operand 4)))
19441 (unspec:DI [(match_operand 1 "tls_symbolic_operand")
19444 "TARGET_64BIT && ix86_cmodel == CM_LARGE_PIC && !TARGET_PECOFF
19445 && GET_CODE (operands[3]) == CONST
19446 && GET_CODE (XEXP (operands[3], 0)) == UNSPEC
19447 && XINT (XEXP (operands[3], 0), 1) == UNSPEC_PLTOFF"
19450 ("lea{q}\t{%E1@tlsgd(%%rip), %%rdi|rdi, %E1@tlsgd[rip]}", operands);
19451 output_asm_insn ("movabs{q}\t{%3, %%rax|rax, %3}", operands);
19452 output_asm_insn ("add{q}\t{%2, %%rax|rax, %2}", operands);
19453 return "call\t{*%%rax|rax}";
19455 [(set_attr "type" "multi")
19456 (set_attr "length" "22")])
19458 (define_expand "@tls_global_dynamic_64_<mode>"
19460 [(set (match_operand:P 0 "register_operand")
19462 (mem:QI (match_operand 2))
19464 (unspec:P [(match_operand 1 "tls_symbolic_operand")
19468 "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
19470 (define_insn "*tls_local_dynamic_base_32_gnu"
19471 [(set (match_operand:SI 0 "register_operand" "=a")
19473 [(match_operand:SI 1 "register_operand" "Yb")
19474 (match_operand 2 "constant_call_address_operand" "Bz")
19476 UNSPEC_TLS_LD_BASE))
19477 (clobber (match_scratch:SI 3 "=d"))
19478 (clobber (match_scratch:SI 4 "=c"))
19479 (clobber (reg:CC FLAGS_REG))]
19480 "!TARGET_64BIT && TARGET_GNU_TLS"
19483 ("lea{l}\t{%&@tlsldm(%1), %0|%0, %&@tlsldm[%1]}", operands);
19484 if (TARGET_SUN_TLS)
19486 if (HAVE_AS_IX86_TLSLDMPLT)
19487 return "call\t%&@tlsldmplt";
19489 return "call\t%p2@plt";
19491 if (flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT)
19492 return "call\t%P2";
19493 return "call\t{*%p2@GOT(%1)|[DWORD PTR %p2@GOT[%1]]}";
19495 [(set_attr "type" "multi")
19496 (set_attr "length" "11")])
19498 (define_expand "tls_local_dynamic_base_32"
19500 [(set (match_operand:SI 0 "register_operand")
19502 [(match_operand:SI 1 "register_operand")
19503 (match_operand 2 "constant_call_address_operand")
19505 UNSPEC_TLS_LD_BASE))
19506 (clobber (scratch:SI))
19507 (clobber (scratch:SI))
19508 (clobber (reg:CC FLAGS_REG))])]
19510 "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
19512 (define_insn "*tls_local_dynamic_base_64_<mode>"
19513 [(set (match_operand:P 0 "register_operand" "=a")
19515 (mem:QI (match_operand 1 "constant_call_address_operand" "Bz"))
19516 (match_operand 2)))
19517 (unspec:P [(reg:P SP_REG)] UNSPEC_TLS_LD_BASE)]
19521 ("lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}", operands);
19522 if (TARGET_SUN_TLS)
19523 return "call\t%p1@plt";
19524 if (flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT)
19525 return "call\t%P1";
19526 return "call\t{*%p1@GOTPCREL(%%rip)|[QWORD PTR %p1@GOTPCREL[rip]]}";
19528 [(set_attr "type" "multi")
19529 (set_attr "length" "12")])
19531 (define_insn "*tls_local_dynamic_base_64_largepic"
19532 [(set (match_operand:DI 0 "register_operand" "=a")
19534 (mem:QI (plus:DI (match_operand:DI 1 "register_operand" "b")
19535 (match_operand:DI 2 "immediate_operand" "i")))
19536 (match_operand 3)))
19537 (unspec:DI [(reg:DI SP_REG)] UNSPEC_TLS_LD_BASE)]
19538 "TARGET_64BIT && ix86_cmodel == CM_LARGE_PIC && !TARGET_PECOFF
19539 && GET_CODE (operands[2]) == CONST
19540 && GET_CODE (XEXP (operands[2], 0)) == UNSPEC
19541 && XINT (XEXP (operands[2], 0), 1) == UNSPEC_PLTOFF"
19544 ("lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}", operands);
19545 output_asm_insn ("movabs{q}\t{%2, %%rax|rax, %2}", operands);
19546 output_asm_insn ("add{q}\t{%1, %%rax|rax, %1}", operands);
19547 return "call\t{*%%rax|rax}";
19549 [(set_attr "type" "multi")
19550 (set_attr "length" "22")])
19552 (define_expand "@tls_local_dynamic_base_64_<mode>"
19554 [(set (match_operand:P 0 "register_operand")
19556 (mem:QI (match_operand 1))
19558 (unspec:P [(reg:P SP_REG)] UNSPEC_TLS_LD_BASE)])]
19560 "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
19562 ;; Local dynamic of a single variable is a lose. Show combine how
19563 ;; to convert that back to global dynamic.
19565 (define_insn_and_split "*tls_local_dynamic_32_once"
19566 [(set (match_operand:SI 0 "register_operand" "=a")
19568 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
19569 (match_operand 2 "constant_call_address_operand" "Bz")
19571 UNSPEC_TLS_LD_BASE)
19572 (const:SI (unspec:SI
19573 [(match_operand 3 "tls_symbolic_operand")]
19575 (clobber (match_scratch:SI 4 "=d"))
19576 (clobber (match_scratch:SI 5 "=c"))
19577 (clobber (reg:CC FLAGS_REG))]
19582 [(set (match_dup 0)
19583 (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)
19586 (clobber (match_dup 4))
19587 (clobber (match_dup 5))
19588 (clobber (reg:CC FLAGS_REG))])])
19590 ;; Load and add the thread base pointer from %<tp_seg>:0.
19591 (define_expand "get_thread_pointer<mode>"
19592 [(set (match_operand:PTR 0 "register_operand")
19593 (unspec:PTR [(const_int 0)] UNSPEC_TP))]
19596 /* targetm is not visible in the scope of the condition. */
19597 if (!targetm.have_tls)
19598 error ("%<__builtin_thread_pointer%> is not supported on this target");
19601 (define_insn_and_split "*load_tp_<mode>"
19602 [(set (match_operand:PTR 0 "register_operand" "=r")
19603 (unspec:PTR [(const_int 0)] UNSPEC_TP))]
19607 [(set (match_dup 0)
19610 addr_space_t as = DEFAULT_TLS_SEG_REG;
19612 operands[1] = gen_const_mem (<MODE>mode, const0_rtx);
19613 set_mem_addr_space (operands[1], as);
19616 (define_insn_and_split "*load_tp_x32_zext"
19617 [(set (match_operand:DI 0 "register_operand" "=r")
19619 (unspec:SI [(const_int 0)] UNSPEC_TP)))]
19623 [(set (match_dup 0)
19624 (zero_extend:DI (match_dup 1)))]
19626 addr_space_t as = DEFAULT_TLS_SEG_REG;
19628 operands[1] = gen_const_mem (SImode, const0_rtx);
19629 set_mem_addr_space (operands[1], as);
19632 (define_insn_and_split "*add_tp_<mode>"
19633 [(set (match_operand:PTR 0 "register_operand" "=r")
19635 (unspec:PTR [(const_int 0)] UNSPEC_TP)
19636 (match_operand:PTR 1 "register_operand" "0")))
19637 (clobber (reg:CC FLAGS_REG))]
19642 [(set (match_dup 0)
19643 (plus:PTR (match_dup 1) (match_dup 2)))
19644 (clobber (reg:CC FLAGS_REG))])]
19646 addr_space_t as = DEFAULT_TLS_SEG_REG;
19648 operands[2] = gen_const_mem (<MODE>mode, const0_rtx);
19649 set_mem_addr_space (operands[2], as);
19652 (define_insn_and_split "*add_tp_x32_zext"
19653 [(set (match_operand:DI 0 "register_operand" "=r")
19655 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
19656 (match_operand:SI 1 "register_operand" "0"))))
19657 (clobber (reg:CC FLAGS_REG))]
19662 [(set (match_dup 0)
19664 (plus:SI (match_dup 1) (match_dup 2))))
19665 (clobber (reg:CC FLAGS_REG))])]
19667 addr_space_t as = DEFAULT_TLS_SEG_REG;
19669 operands[2] = gen_const_mem (SImode, const0_rtx);
19670 set_mem_addr_space (operands[2], as);
19673 ;; The Sun linker took the AMD64 TLS spec literally and can only handle
19674 ;; %rax as destination of the initial executable code sequence.
19675 (define_insn "tls_initial_exec_64_sun"
19676 [(set (match_operand:DI 0 "register_operand" "=a")
19678 [(match_operand 1 "tls_symbolic_operand")]
19679 UNSPEC_TLS_IE_SUN))
19680 (clobber (reg:CC FLAGS_REG))]
19681 "TARGET_64BIT && TARGET_SUN_TLS"
19684 ("mov{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}", operands);
19685 return "add{q}\t{%a1@gottpoff(%%rip), %0|%0, %a1@gottpoff[rip]}";
19687 [(set_attr "type" "multi")])
19689 ;; GNU2 TLS patterns can be split.
19691 (define_expand "tls_dynamic_gnu2_32"
19692 [(set (match_dup 3)
19693 (plus:SI (match_operand:SI 2 "register_operand")
19695 (unspec:SI [(match_operand 1 "tls_symbolic_operand")]
19698 [(set (match_operand:SI 0 "register_operand")
19699 (unspec:SI [(match_dup 1) (match_dup 3)
19700 (match_dup 2) (reg:SI SP_REG)]
19702 (clobber (reg:CC FLAGS_REG))])]
19703 "!TARGET_64BIT && TARGET_GNU2_TLS"
19705 operands[3] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
19706 ix86_tls_descriptor_calls_expanded_in_cfun = true;
19709 (define_insn "*tls_dynamic_gnu2_lea_32"
19710 [(set (match_operand:SI 0 "register_operand" "=r")
19711 (plus:SI (match_operand:SI 1 "register_operand" "b")
19713 (unspec:SI [(match_operand 2 "tls_symbolic_operand")]
19714 UNSPEC_TLSDESC))))]
19715 "!TARGET_64BIT && TARGET_GNU2_TLS"
19716 "lea{l}\t{%E2@TLSDESC(%1), %0|%0, %E2@TLSDESC[%1]}"
19717 [(set_attr "type" "lea")
19718 (set_attr "mode" "SI")
19719 (set_attr "length" "6")
19720 (set_attr "length_address" "4")])
19722 (define_insn "*tls_dynamic_gnu2_call_32"
19723 [(set (match_operand:SI 0 "register_operand" "=a")
19724 (unspec:SI [(match_operand 1 "tls_symbolic_operand")
19725 (match_operand:SI 2 "register_operand" "0")
19726 ;; we have to make sure %ebx still points to the GOT
19727 (match_operand:SI 3 "register_operand" "b")
19730 (clobber (reg:CC FLAGS_REG))]
19731 "!TARGET_64BIT && TARGET_GNU2_TLS"
19732 "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
19733 [(set_attr "type" "call")
19734 (set_attr "length" "2")
19735 (set_attr "length_address" "0")])
19737 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
19738 [(set (match_operand:SI 0 "register_operand" "=&a")
19740 (unspec:SI [(match_operand 3 "tls_modbase_operand")
19741 (match_operand:SI 4)
19742 (match_operand:SI 2 "register_operand" "b")
19745 (const:SI (unspec:SI
19746 [(match_operand 1 "tls_symbolic_operand")]
19748 (clobber (reg:CC FLAGS_REG))]
19749 "!TARGET_64BIT && TARGET_GNU2_TLS"
19752 [(set (match_dup 0) (match_dup 5))]
19754 operands[5] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
19755 emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
19758 (define_expand "@tls_dynamic_gnu2_64_<mode>"
19759 [(set (match_dup 2)
19760 (unspec:PTR [(match_operand 1 "tls_symbolic_operand")]
19763 [(set (match_operand:PTR 0 "register_operand")
19764 (unspec:PTR [(match_dup 1) (match_dup 2) (reg:PTR SP_REG)]
19766 (clobber (reg:CC FLAGS_REG))])]
19767 "TARGET_64BIT && TARGET_GNU2_TLS"
19769 operands[2] = can_create_pseudo_p () ? gen_reg_rtx (ptr_mode) : operands[0];
19770 ix86_tls_descriptor_calls_expanded_in_cfun = true;
19773 (define_insn "*tls_dynamic_gnu2_lea_64_<mode>"
19774 [(set (match_operand:PTR 0 "register_operand" "=r")
19775 (unspec:PTR [(match_operand 1 "tls_symbolic_operand")]
19777 "TARGET_64BIT && TARGET_GNU2_TLS"
19778 "lea%z0\t{%E1@TLSDESC(%%rip), %0|%0, %E1@TLSDESC[rip]}"
19779 [(set_attr "type" "lea")
19780 (set_attr "mode" "<MODE>")
19781 (set_attr "length" "7")
19782 (set_attr "length_address" "4")])
19784 (define_insn "*tls_dynamic_gnu2_call_64_<mode>"
19785 [(set (match_operand:PTR 0 "register_operand" "=a")
19786 (unspec:PTR [(match_operand 1 "tls_symbolic_operand")
19787 (match_operand:PTR 2 "register_operand" "0")
19790 (clobber (reg:CC FLAGS_REG))]
19791 "TARGET_64BIT && TARGET_GNU2_TLS"
19792 "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
19793 [(set_attr "type" "call")
19794 (set_attr "length" "2")
19795 (set_attr "length_address" "0")])
19797 (define_insn_and_split "*tls_dynamic_gnu2_combine_64_<mode>"
19798 [(set (match_operand:PTR 0 "register_operand" "=&a")
19800 (unspec:PTR [(match_operand 2 "tls_modbase_operand")
19801 (match_operand:PTR 3)
19804 (const:PTR (unspec:PTR
19805 [(match_operand 1 "tls_symbolic_operand")]
19807 (clobber (reg:CC FLAGS_REG))]
19808 "TARGET_64BIT && TARGET_GNU2_TLS"
19811 [(set (match_dup 0) (match_dup 4))]
19813 operands[4] = can_create_pseudo_p () ? gen_reg_rtx (ptr_mode) : operands[0];
19814 emit_insn (gen_tls_dynamic_gnu2_64 (ptr_mode, operands[4], operands[1]));
19818 [(match_operand 0 "tls_address_pattern")]
19819 "TARGET_TLS_DIRECT_SEG_REFS"
19821 "operands[0] = ix86_rewrite_tls_address (operands[0]);")
19824 ;; These patterns match the binary 387 instructions for addM3, subM3,
19825 ;; mulM3 and divM3. There are three patterns for each of DFmode and
19826 ;; SFmode. The first is the normal insn, the second the same insn but
19827 ;; with one operand a conversion, and the third the same insn but with
19828 ;; the other operand a conversion. The conversion may be SFmode or
19829 ;; SImode if the target mode DFmode, but only SImode if the target mode
19832 ;; Gcc is slightly more smart about handling normal two address instructions
19833 ;; so use special patterns for add and mull.
19835 (define_insn "*fop_xf_comm_i387"
19836 [(set (match_operand:XF 0 "register_operand" "=f")
19837 (match_operator:XF 3 "binary_fp_operator"
19838 [(match_operand:XF 1 "register_operand" "%0")
19839 (match_operand:XF 2 "register_operand" "f")]))]
19841 && COMMUTATIVE_ARITH_P (operands[3])"
19842 "* return output_387_binary_op (insn, operands);"
19843 [(set (attr "type")
19844 (if_then_else (match_operand:XF 3 "mult_operator")
19845 (const_string "fmul")
19846 (const_string "fop")))
19847 (set_attr "mode" "XF")])
19849 (define_insn "*fop_<mode>_comm"
19850 [(set (match_operand:MODEF 0 "register_operand" "=f,x,v")
19851 (match_operator:MODEF 3 "binary_fp_operator"
19852 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,0,v")
19853 (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm,vm")]))]
19854 "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
19855 || (TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)))
19856 && COMMUTATIVE_ARITH_P (operands[3])
19857 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
19858 "* return output_387_binary_op (insn, operands);"
19859 [(set (attr "type")
19860 (if_then_else (eq_attr "alternative" "1,2")
19861 (if_then_else (match_operand:MODEF 3 "mult_operator")
19862 (const_string "ssemul")
19863 (const_string "sseadd"))
19864 (if_then_else (match_operand:MODEF 3 "mult_operator")
19865 (const_string "fmul")
19866 (const_string "fop"))))
19867 (set_attr "isa" "*,noavx,avx")
19868 (set_attr "prefix" "orig,orig,vex")
19869 (set_attr "mode" "<MODE>")
19870 (set (attr "enabled")
19872 (match_test ("SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"))
19874 (eq_attr "alternative" "0")
19875 (symbol_ref "TARGET_MIX_SSE_I387
19876 && X87_ENABLE_ARITH (<MODE>mode)")
19877 (const_string "*"))
19879 (eq_attr "alternative" "0")
19880 (symbol_ref "true")
19881 (symbol_ref "false"))))])
19883 (define_insn "*<insn>hf"
19884 [(set (match_operand:HF 0 "register_operand" "=v")
19885 (plusminusmultdiv:HF
19886 (match_operand:HF 1 "nonimmediate_operand" "<comm>v")
19887 (match_operand:HF 2 "nonimmediate_operand" "vm")))]
19889 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
19890 "v<insn>sh\t{%2, %1, %0|%0, %1, %2}"
19891 [(set_attr "prefix" "evex")
19892 (set_attr "mode" "HF")])
19894 (define_insn "*rcpsf2_sse"
19895 [(set (match_operand:SF 0 "register_operand" "=x,x,x")
19896 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "0,x,m")]
19898 "TARGET_SSE && TARGET_SSE_MATH"
19900 %vrcpss\t{%d1, %0|%0, %d1}
19901 %vrcpss\t{%d1, %0|%0, %d1}
19902 %vrcpss\t{%1, %d0|%d0, %1}"
19903 [(set_attr "type" "sse")
19904 (set_attr "atom_sse_attr" "rcp")
19905 (set_attr "btver2_sse_attr" "rcp")
19906 (set_attr "prefix" "maybe_vex")
19907 (set_attr "mode" "SF")
19908 (set_attr "avx_partial_xmm_update" "false,false,true")
19909 (set (attr "preferred_for_speed")
19910 (cond [(match_test "TARGET_AVX")
19911 (symbol_ref "true")
19912 (eq_attr "alternative" "1,2")
19913 (symbol_ref "!TARGET_SSE_PARTIAL_REG_DEPENDENCY")
19915 (symbol_ref "true")))])
19917 (define_insn "rcphf2"
19918 [(set (match_operand:HF 0 "register_operand" "=v,v")
19919 (unspec:HF [(match_operand:HF 1 "nonimmediate_operand" "v,m")]
19921 "TARGET_AVX512FP16"
19923 vrcpsh\t{%d1, %0|%0, %d1}
19924 vrcpsh\t{%1, %d0|%d0, %1}"
19925 [(set_attr "type" "sse")
19926 (set_attr "prefix" "evex")
19927 (set_attr "mode" "HF")
19928 (set_attr "avx_partial_xmm_update" "false,true")])
19930 (define_insn "*fop_xf_1_i387"
19931 [(set (match_operand:XF 0 "register_operand" "=f,f")
19932 (match_operator:XF 3 "binary_fp_operator"
19933 [(match_operand:XF 1 "register_operand" "0,f")
19934 (match_operand:XF 2 "register_operand" "f,0")]))]
19936 && !COMMUTATIVE_ARITH_P (operands[3])"
19937 "* return output_387_binary_op (insn, operands);"
19938 [(set (attr "type")
19939 (if_then_else (match_operand:XF 3 "div_operator")
19940 (const_string "fdiv")
19941 (const_string "fop")))
19942 (set_attr "mode" "XF")])
19944 (define_insn "*fop_<mode>_1"
19945 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,v")
19946 (match_operator:MODEF 3 "binary_fp_operator"
19947 [(match_operand:MODEF 1
19948 "x87nonimm_ssenomem_operand" "0,fm,0,v")
19949 (match_operand:MODEF 2
19950 "nonimmediate_operand" "fm,0,xm,vm")]))]
19951 "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
19952 || (TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)))
19953 && !COMMUTATIVE_ARITH_P (operands[3])
19954 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
19955 "* return output_387_binary_op (insn, operands);"
19956 [(set (attr "type")
19957 (if_then_else (eq_attr "alternative" "2,3")
19958 (if_then_else (match_operand:MODEF 3 "div_operator")
19959 (const_string "ssediv")
19960 (const_string "sseadd"))
19961 (if_then_else (match_operand:MODEF 3 "div_operator")
19962 (const_string "fdiv")
19963 (const_string "fop"))))
19964 (set_attr "isa" "*,*,noavx,avx")
19965 (set_attr "prefix" "orig,orig,orig,vex")
19966 (set_attr "mode" "<MODE>")
19967 (set (attr "enabled")
19969 (match_test ("SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"))
19971 (eq_attr "alternative" "0,1")
19972 (symbol_ref "TARGET_MIX_SSE_I387
19973 && X87_ENABLE_ARITH (<MODE>mode)")
19974 (const_string "*"))
19976 (eq_attr "alternative" "0,1")
19977 (symbol_ref "true")
19978 (symbol_ref "false"))))])
19980 (define_insn "*fop_<X87MODEF:mode>_2_i387"
19981 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
19982 (match_operator:X87MODEF 3 "binary_fp_operator"
19984 (match_operand:SWI24 1 "nonimmediate_operand" "m"))
19985 (match_operand:X87MODEF 2 "register_operand" "0")]))]
19986 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI24:MODE>mode)
19987 && !(SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
19988 && (TARGET_USE_<SWI24:MODE>MODE_FIOP
19989 || optimize_function_for_size_p (cfun))"
19990 "* return output_387_binary_op (insn, operands);"
19991 [(set (attr "type")
19992 (cond [(match_operand:X87MODEF 3 "mult_operator")
19993 (const_string "fmul")
19994 (match_operand:X87MODEF 3 "div_operator")
19995 (const_string "fdiv")
19997 (const_string "fop")))
19998 (set_attr "fp_int_src" "true")
19999 (set_attr "mode" "<SWI24:MODE>")])
20001 (define_insn "*fop_<X87MODEF:mode>_3_i387"
20002 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
20003 (match_operator:X87MODEF 3 "binary_fp_operator"
20004 [(match_operand:X87MODEF 1 "register_operand" "0")
20006 (match_operand:SWI24 2 "nonimmediate_operand" "m"))]))]
20007 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI24:MODE>mode)
20008 && !(SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
20009 && (TARGET_USE_<SWI24:MODE>MODE_FIOP
20010 || optimize_function_for_size_p (cfun))"
20011 "* return output_387_binary_op (insn, operands);"
20012 [(set (attr "type")
20013 (cond [(match_operand:X87MODEF 3 "mult_operator")
20014 (const_string "fmul")
20015 (match_operand:X87MODEF 3 "div_operator")
20016 (const_string "fdiv")
20018 (const_string "fop")))
20019 (set_attr "fp_int_src" "true")
20020 (set_attr "mode" "<SWI24:MODE>")])
20022 (define_insn "*fop_xf_4_i387"
20023 [(set (match_operand:XF 0 "register_operand" "=f,f")
20024 (match_operator:XF 3 "binary_fp_operator"
20026 (match_operand:MODEF 1 "nonimmediate_operand" "fm,0"))
20027 (match_operand:XF 2 "register_operand" "0,f")]))]
20029 "* return output_387_binary_op (insn, operands);"
20030 [(set (attr "type")
20031 (cond [(match_operand:XF 3 "mult_operator")
20032 (const_string "fmul")
20033 (match_operand:XF 3 "div_operator")
20034 (const_string "fdiv")
20036 (const_string "fop")))
20037 (set_attr "mode" "<MODE>")])
20039 (define_insn "*fop_df_4_i387"
20040 [(set (match_operand:DF 0 "register_operand" "=f,f")
20041 (match_operator:DF 3 "binary_fp_operator"
20043 (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
20044 (match_operand:DF 2 "register_operand" "0,f")]))]
20045 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
20046 && !(SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
20047 "* return output_387_binary_op (insn, operands);"
20048 [(set (attr "type")
20049 (cond [(match_operand:DF 3 "mult_operator")
20050 (const_string "fmul")
20051 (match_operand:DF 3 "div_operator")
20052 (const_string "fdiv")
20054 (const_string "fop")))
20055 (set_attr "mode" "SF")])
20057 (define_insn "*fop_xf_5_i387"
20058 [(set (match_operand:XF 0 "register_operand" "=f,f")
20059 (match_operator:XF 3 "binary_fp_operator"
20060 [(match_operand:XF 1 "register_operand" "0,f")
20062 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
20064 "* return output_387_binary_op (insn, operands);"
20065 [(set (attr "type")
20066 (cond [(match_operand:XF 3 "mult_operator")
20067 (const_string "fmul")
20068 (match_operand:XF 3 "div_operator")
20069 (const_string "fdiv")
20071 (const_string "fop")))
20072 (set_attr "mode" "<MODE>")])
20074 (define_insn "*fop_df_5_i387"
20075 [(set (match_operand:DF 0 "register_operand" "=f,f")
20076 (match_operator:DF 3 "binary_fp_operator"
20077 [(match_operand:DF 1 "register_operand" "0,f")
20079 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
20080 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
20081 && !(SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
20082 "* return output_387_binary_op (insn, operands);"
20083 [(set (attr "type")
20084 (cond [(match_operand:DF 3 "mult_operator")
20085 (const_string "fmul")
20086 (match_operand:DF 3 "div_operator")
20087 (const_string "fdiv")
20089 (const_string "fop")))
20090 (set_attr "mode" "SF")])
20092 (define_insn "*fop_xf_6_i387"
20093 [(set (match_operand:XF 0 "register_operand" "=f,f")
20094 (match_operator:XF 3 "binary_fp_operator"
20096 (match_operand:MODEF 1 "register_operand" "0,f"))
20098 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
20100 "* return output_387_binary_op (insn, operands);"
20101 [(set (attr "type")
20102 (cond [(match_operand:XF 3 "mult_operator")
20103 (const_string "fmul")
20104 (match_operand:XF 3 "div_operator")
20105 (const_string "fdiv")
20107 (const_string "fop")))
20108 (set_attr "mode" "<MODE>")])
20110 (define_insn "*fop_df_6_i387"
20111 [(set (match_operand:DF 0 "register_operand" "=f,f")
20112 (match_operator:DF 3 "binary_fp_operator"
20114 (match_operand:SF 1 "register_operand" "0,f"))
20116 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
20117 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
20118 && !(SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
20119 "* return output_387_binary_op (insn, operands);"
20120 [(set (attr "type")
20121 (cond [(match_operand:DF 3 "mult_operator")
20122 (const_string "fmul")
20123 (match_operand:DF 3 "div_operator")
20124 (const_string "fdiv")
20126 (const_string "fop")))
20127 (set_attr "mode" "SF")])
20129 ;; FPU special functions.
20131 ;; This pattern implements a no-op XFmode truncation for
20132 ;; all fancy i386 XFmode math functions.
20134 (define_insn "truncxf<mode>2_i387_noop_unspec"
20135 [(set (match_operand:MODEF 0 "nonimmediate_operand" "=mf")
20136 (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")]
20137 UNSPEC_TRUNC_NOOP))]
20138 "TARGET_USE_FANCY_MATH_387"
20139 "* return output_387_reg_move (insn, operands);"
20140 [(set_attr "type" "fmov")
20141 (set_attr "mode" "<MODE>")])
20143 (define_insn "sqrtxf2"
20144 [(set (match_operand:XF 0 "register_operand" "=f")
20145 (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
20146 "TARGET_USE_FANCY_MATH_387"
20148 [(set_attr "type" "fpspc")
20149 (set_attr "mode" "XF")
20150 (set_attr "athlon_decode" "direct")
20151 (set_attr "amdfam10_decode" "direct")
20152 (set_attr "bdver1_decode" "direct")])
20154 (define_insn "*rsqrtsf2_sse"
20155 [(set (match_operand:SF 0 "register_operand" "=x,x,x")
20156 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "0,x,m")]
20158 "TARGET_SSE && TARGET_SSE_MATH"
20160 %vrsqrtss\t{%d1, %0|%0, %d1}
20161 %vrsqrtss\t{%d1, %0|%0, %d1}
20162 %vrsqrtss\t{%1, %d0|%d0, %1}"
20163 [(set_attr "type" "sse")
20164 (set_attr "atom_sse_attr" "rcp")
20165 (set_attr "btver2_sse_attr" "rcp")
20166 (set_attr "prefix" "maybe_vex")
20167 (set_attr "mode" "SF")
20168 (set_attr "avx_partial_xmm_update" "false,false,true")
20169 (set (attr "preferred_for_speed")
20170 (cond [(match_test "TARGET_AVX")
20171 (symbol_ref "true")
20172 (eq_attr "alternative" "1,2")
20173 (symbol_ref "!TARGET_SSE_PARTIAL_REG_DEPENDENCY")
20175 (symbol_ref "true")))])
20177 (define_expand "rsqrtsf2"
20178 [(set (match_operand:SF 0 "register_operand")
20179 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand")]
20181 "TARGET_SSE && TARGET_SSE_MATH"
20183 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
20187 (define_insn "rsqrthf2"
20188 [(set (match_operand:HF 0 "register_operand" "=v,v")
20189 (unspec:HF [(match_operand:HF 1 "nonimmediate_operand" "v,m")]
20191 "TARGET_AVX512FP16"
20193 vrsqrtsh\t{%d1, %0|%0, %d1}
20194 vrsqrtsh\t{%1, %d0|%d0, %1}"
20195 [(set_attr "type" "sse")
20196 (set_attr "prefix" "evex")
20197 (set_attr "avx_partial_xmm_update" "false,true")
20198 (set_attr "mode" "HF")])
20200 (define_insn "sqrthf2"
20201 [(set (match_operand:HF 0 "register_operand" "=v,v")
20203 (match_operand:HF 1 "nonimmediate_operand" "v,m")))]
20204 "TARGET_AVX512FP16"
20206 vsqrtsh\t{%d1, %0|%0, %d1}
20207 vsqrtsh\t{%1, %d0|%d0, %1}"
20208 [(set_attr "type" "sse")
20209 (set_attr "prefix" "evex")
20210 (set_attr "avx_partial_xmm_update" "false,true")
20211 (set_attr "mode" "HF")])
20213 (define_insn "*sqrt<mode>2_sse"
20214 [(set (match_operand:MODEF 0 "register_operand" "=v,v,v")
20216 (match_operand:MODEF 1 "nonimmediate_operand" "0,v,m")))]
20217 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
20219 %vsqrt<ssemodesuffix>\t{%d1, %0|%0, %d1}
20220 %vsqrt<ssemodesuffix>\t{%d1, %0|%0, %d1}
20221 %vsqrt<ssemodesuffix>\t{%1, %d0|%d0, %1}"
20222 [(set_attr "type" "sse")
20223 (set_attr "atom_sse_attr" "sqrt")
20224 (set_attr "btver2_sse_attr" "sqrt")
20225 (set_attr "prefix" "maybe_vex")
20226 (set_attr "avx_partial_xmm_update" "false,false,true")
20227 (set_attr "mode" "<MODE>")
20228 (set (attr "preferred_for_speed")
20229 (cond [(match_test "TARGET_AVX")
20230 (symbol_ref "true")
20231 (eq_attr "alternative" "1,2")
20232 (symbol_ref "!TARGET_SSE_PARTIAL_REG_DEPENDENCY")
20234 (symbol_ref "true")))])
20236 (define_expand "sqrt<mode>2"
20237 [(set (match_operand:MODEF 0 "register_operand")
20239 (match_operand:MODEF 1 "nonimmediate_operand")))]
20240 "(TARGET_USE_FANCY_MATH_387 && X87_ENABLE_ARITH (<MODE>mode))
20241 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
20243 if (<MODE>mode == SFmode
20244 && TARGET_SSE && TARGET_SSE_MATH
20245 && TARGET_RECIP_SQRT
20246 && !optimize_function_for_size_p (cfun)
20247 && flag_finite_math_only && !flag_trapping_math
20248 && flag_unsafe_math_optimizations)
20250 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
20254 if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
20256 rtx op0 = gen_reg_rtx (XFmode);
20257 rtx op1 = gen_reg_rtx (XFmode);
20259 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
20260 emit_insn (gen_sqrtxf2 (op0, op1));
20261 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
20266 (define_expand "hypot<mode>3"
20267 [(use (match_operand:MODEF 0 "register_operand"))
20268 (use (match_operand:MODEF 1 "general_operand"))
20269 (use (match_operand:MODEF 2 "general_operand"))]
20270 "TARGET_USE_FANCY_MATH_387
20271 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
20272 || TARGET_MIX_SSE_I387)
20273 && flag_finite_math_only
20274 && flag_unsafe_math_optimizations"
20276 rtx op0 = gen_reg_rtx (XFmode);
20277 rtx op1 = gen_reg_rtx (XFmode);
20278 rtx op2 = gen_reg_rtx (XFmode);
20280 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
20281 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
20283 emit_insn (gen_mulxf3 (op1, op1, op1));
20284 emit_insn (gen_mulxf3 (op2, op2, op2));
20285 emit_insn (gen_addxf3 (op0, op2, op1));
20286 emit_insn (gen_sqrtxf2 (op0, op0));
20288 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
20292 (define_insn "x86_fnstsw_1"
20293 [(set (match_operand:HI 0 "register_operand" "=a")
20294 (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
20297 [(set_attr "length" "2")
20298 (set_attr "mode" "SI")
20299 (set_attr "unit" "i387")])
20301 (define_insn "fpremxf4_i387"
20302 [(set (match_operand:XF 0 "register_operand" "=f")
20303 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
20304 (match_operand:XF 3 "register_operand" "1")]
20306 (set (match_operand:XF 1 "register_operand" "=f")
20307 (unspec:XF [(match_dup 2) (match_dup 3)]
20309 (set (reg:CCFP FPSR_REG)
20310 (unspec:CCFP [(match_dup 2) (match_dup 3)]
20312 "TARGET_USE_FANCY_MATH_387"
20314 [(set_attr "type" "fpspc")
20315 (set_attr "znver1_decode" "vector")
20316 (set_attr "mode" "XF")])
20318 (define_expand "fmodxf3"
20319 [(use (match_operand:XF 0 "register_operand"))
20320 (use (match_operand:XF 1 "general_operand"))
20321 (use (match_operand:XF 2 "general_operand"))]
20322 "TARGET_USE_FANCY_MATH_387"
20324 rtx_code_label *label = gen_label_rtx ();
20326 rtx op1 = gen_reg_rtx (XFmode);
20327 rtx op2 = gen_reg_rtx (XFmode);
20329 emit_move_insn (op2, operands[2]);
20330 emit_move_insn (op1, operands[1]);
20332 emit_label (label);
20333 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
20334 ix86_emit_fp_unordered_jump (label);
20335 LABEL_NUSES (label) = 1;
20337 emit_move_insn (operands[0], op1);
20341 (define_expand "fmod<mode>3"
20342 [(use (match_operand:MODEF 0 "register_operand"))
20343 (use (match_operand:MODEF 1 "general_operand"))
20344 (use (match_operand:MODEF 2 "general_operand"))]
20345 "TARGET_USE_FANCY_MATH_387"
20347 rtx (*gen_truncxf) (rtx, rtx);
20349 rtx_code_label *label = gen_label_rtx ();
20351 rtx op1 = gen_reg_rtx (XFmode);
20352 rtx op2 = gen_reg_rtx (XFmode);
20354 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
20355 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
20357 emit_label (label);
20358 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
20359 ix86_emit_fp_unordered_jump (label);
20360 LABEL_NUSES (label) = 1;
20362 /* Truncate the result properly for strict SSE math. */
20363 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
20364 && !TARGET_MIX_SSE_I387)
20365 gen_truncxf = gen_truncxf<mode>2;
20367 gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
20369 emit_insn (gen_truncxf (operands[0], op1));
20373 (define_insn "fprem1xf4_i387"
20374 [(set (match_operand:XF 0 "register_operand" "=f")
20375 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
20376 (match_operand:XF 3 "register_operand" "1")]
20378 (set (match_operand:XF 1 "register_operand" "=f")
20379 (unspec:XF [(match_dup 2) (match_dup 3)]
20381 (set (reg:CCFP FPSR_REG)
20382 (unspec:CCFP [(match_dup 2) (match_dup 3)]
20384 "TARGET_USE_FANCY_MATH_387"
20386 [(set_attr "type" "fpspc")
20387 (set_attr "znver1_decode" "vector")
20388 (set_attr "mode" "XF")])
20390 (define_expand "remainderxf3"
20391 [(use (match_operand:XF 0 "register_operand"))
20392 (use (match_operand:XF 1 "general_operand"))
20393 (use (match_operand:XF 2 "general_operand"))]
20394 "TARGET_USE_FANCY_MATH_387"
20396 rtx_code_label *label = gen_label_rtx ();
20398 rtx op1 = gen_reg_rtx (XFmode);
20399 rtx op2 = gen_reg_rtx (XFmode);
20401 emit_move_insn (op2, operands[2]);
20402 emit_move_insn (op1, operands[1]);
20404 emit_label (label);
20405 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
20406 ix86_emit_fp_unordered_jump (label);
20407 LABEL_NUSES (label) = 1;
20409 emit_move_insn (operands[0], op1);
20413 (define_expand "remainder<mode>3"
20414 [(use (match_operand:MODEF 0 "register_operand"))
20415 (use (match_operand:MODEF 1 "general_operand"))
20416 (use (match_operand:MODEF 2 "general_operand"))]
20417 "TARGET_USE_FANCY_MATH_387"
20419 rtx (*gen_truncxf) (rtx, rtx);
20421 rtx_code_label *label = gen_label_rtx ();
20423 rtx op1 = gen_reg_rtx (XFmode);
20424 rtx op2 = gen_reg_rtx (XFmode);
20426 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
20427 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
20429 emit_label (label);
20431 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
20432 ix86_emit_fp_unordered_jump (label);
20433 LABEL_NUSES (label) = 1;
20435 /* Truncate the result properly for strict SSE math. */
20436 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
20437 && !TARGET_MIX_SSE_I387)
20438 gen_truncxf = gen_truncxf<mode>2;
20440 gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
20442 emit_insn (gen_truncxf (operands[0], op1));
20446 (define_int_iterator SINCOS
20450 (define_int_attr sincos
20451 [(UNSPEC_SIN "sin")
20452 (UNSPEC_COS "cos")])
20454 (define_insn "<sincos>xf2"
20455 [(set (match_operand:XF 0 "register_operand" "=f")
20456 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
20458 "TARGET_USE_FANCY_MATH_387
20459 && flag_unsafe_math_optimizations"
20461 [(set_attr "type" "fpspc")
20462 (set_attr "znver1_decode" "vector")
20463 (set_attr "mode" "XF")])
20465 (define_expand "<sincos><mode>2"
20466 [(set (match_operand:MODEF 0 "register_operand")
20467 (unspec:MODEF [(match_operand:MODEF 1 "general_operand")]
20469 "TARGET_USE_FANCY_MATH_387
20470 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
20471 || TARGET_MIX_SSE_I387)
20472 && flag_unsafe_math_optimizations"
20474 rtx op0 = gen_reg_rtx (XFmode);
20475 rtx op1 = gen_reg_rtx (XFmode);
20477 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
20478 emit_insn (gen_<sincos>xf2 (op0, op1));
20479 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
20483 (define_insn "sincosxf3"
20484 [(set (match_operand:XF 0 "register_operand" "=f")
20485 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
20486 UNSPEC_SINCOS_COS))
20487 (set (match_operand:XF 1 "register_operand" "=f")
20488 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
20489 "TARGET_USE_FANCY_MATH_387
20490 && flag_unsafe_math_optimizations"
20492 [(set_attr "type" "fpspc")
20493 (set_attr "znver1_decode" "vector")
20494 (set_attr "mode" "XF")])
20496 (define_expand "sincos<mode>3"
20497 [(use (match_operand:MODEF 0 "register_operand"))
20498 (use (match_operand:MODEF 1 "register_operand"))
20499 (use (match_operand:MODEF 2 "general_operand"))]
20500 "TARGET_USE_FANCY_MATH_387
20501 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
20502 || TARGET_MIX_SSE_I387)
20503 && flag_unsafe_math_optimizations"
20505 rtx op0 = gen_reg_rtx (XFmode);
20506 rtx op1 = gen_reg_rtx (XFmode);
20507 rtx op2 = gen_reg_rtx (XFmode);
20509 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
20510 emit_insn (gen_sincosxf3 (op0, op1, op2));
20511 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
20512 emit_insn (gen_truncxf<mode>2 (operands[1], op1));
20516 (define_insn "fptanxf4_i387"
20517 [(set (match_operand:SF 0 "register_operand" "=f")
20518 (match_operand:SF 3 "const1_operand"))
20519 (set (match_operand:XF 1 "register_operand" "=f")
20520 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
20522 "TARGET_USE_FANCY_MATH_387
20523 && flag_unsafe_math_optimizations"
20525 [(set_attr "type" "fpspc")
20526 (set_attr "znver1_decode" "vector")
20527 (set_attr "mode" "XF")])
20529 (define_expand "tanxf2"
20530 [(use (match_operand:XF 0 "register_operand"))
20531 (use (match_operand:XF 1 "register_operand"))]
20532 "TARGET_USE_FANCY_MATH_387
20533 && flag_unsafe_math_optimizations"
20535 rtx one = gen_reg_rtx (SFmode);
20536 emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1],
20537 CONST1_RTX (SFmode)));
20541 (define_expand "tan<mode>2"
20542 [(use (match_operand:MODEF 0 "register_operand"))
20543 (use (match_operand:MODEF 1 "general_operand"))]
20544 "TARGET_USE_FANCY_MATH_387
20545 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
20546 || TARGET_MIX_SSE_I387)
20547 && flag_unsafe_math_optimizations"
20549 rtx op0 = gen_reg_rtx (XFmode);
20550 rtx op1 = gen_reg_rtx (XFmode);
20552 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
20553 emit_insn (gen_tanxf2 (op0, op1));
20554 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
20558 (define_insn "atan2xf3"
20559 [(set (match_operand:XF 0 "register_operand" "=f")
20560 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
20561 (match_operand:XF 1 "register_operand" "f")]
20563 (clobber (match_scratch:XF 3 "=1"))]
20564 "TARGET_USE_FANCY_MATH_387
20565 && flag_unsafe_math_optimizations"
20567 [(set_attr "type" "fpspc")
20568 (set_attr "znver1_decode" "vector")
20569 (set_attr "mode" "XF")])
20571 (define_expand "atan2<mode>3"
20572 [(use (match_operand:MODEF 0 "register_operand"))
20573 (use (match_operand:MODEF 1 "general_operand"))
20574 (use (match_operand:MODEF 2 "general_operand"))]
20575 "TARGET_USE_FANCY_MATH_387
20576 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
20577 || TARGET_MIX_SSE_I387)
20578 && flag_unsafe_math_optimizations"
20580 rtx op0 = gen_reg_rtx (XFmode);
20581 rtx op1 = gen_reg_rtx (XFmode);
20582 rtx op2 = gen_reg_rtx (XFmode);
20584 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
20585 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
20587 emit_insn (gen_atan2xf3 (op0, op1, op2));
20588 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
20592 (define_expand "atanxf2"
20593 [(parallel [(set (match_operand:XF 0 "register_operand")
20594 (unspec:XF [(match_dup 2)
20595 (match_operand:XF 1 "register_operand")]
20597 (clobber (scratch:XF))])]
20598 "TARGET_USE_FANCY_MATH_387
20599 && flag_unsafe_math_optimizations"
20600 "operands[2] = force_reg (XFmode, CONST1_RTX (XFmode));")
20602 (define_expand "atan<mode>2"
20603 [(use (match_operand:MODEF 0 "register_operand"))
20604 (use (match_operand:MODEF 1 "general_operand"))]
20605 "TARGET_USE_FANCY_MATH_387
20606 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
20607 || TARGET_MIX_SSE_I387)
20608 && flag_unsafe_math_optimizations"
20610 rtx op0 = gen_reg_rtx (XFmode);
20611 rtx op1 = gen_reg_rtx (XFmode);
20613 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
20614 emit_insn (gen_atanxf2 (op0, op1));
20615 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
20619 (define_expand "asinxf2"
20620 [(set (match_dup 2)
20621 (mult:XF (match_operand:XF 1 "register_operand")
20623 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
20624 (set (match_dup 5) (sqrt:XF (match_dup 4)))
20625 (parallel [(set (match_operand:XF 0 "register_operand")
20626 (unspec:XF [(match_dup 5) (match_dup 1)]
20628 (clobber (scratch:XF))])]
20629 "TARGET_USE_FANCY_MATH_387
20630 && flag_unsafe_math_optimizations"
20634 for (i = 2; i < 6; i++)
20635 operands[i] = gen_reg_rtx (XFmode);
20637 emit_move_insn (operands[3], CONST1_RTX (XFmode));
20640 (define_expand "asin<mode>2"
20641 [(use (match_operand:MODEF 0 "register_operand"))
20642 (use (match_operand:MODEF 1 "general_operand"))]
20643 "TARGET_USE_FANCY_MATH_387
20644 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
20645 || TARGET_MIX_SSE_I387)
20646 && flag_unsafe_math_optimizations"
20648 rtx op0 = gen_reg_rtx (XFmode);
20649 rtx op1 = gen_reg_rtx (XFmode);
20651 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
20652 emit_insn (gen_asinxf2 (op0, op1));
20653 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
20657 (define_expand "acosxf2"
20658 [(set (match_dup 2)
20659 (mult:XF (match_operand:XF 1 "register_operand")
20661 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
20662 (set (match_dup 5) (sqrt:XF (match_dup 4)))
20663 (parallel [(set (match_operand:XF 0 "register_operand")
20664 (unspec:XF [(match_dup 1) (match_dup 5)]
20666 (clobber (scratch:XF))])]
20667 "TARGET_USE_FANCY_MATH_387
20668 && flag_unsafe_math_optimizations"
20672 for (i = 2; i < 6; i++)
20673 operands[i] = gen_reg_rtx (XFmode);
20675 emit_move_insn (operands[3], CONST1_RTX (XFmode));
20678 (define_expand "acos<mode>2"
20679 [(use (match_operand:MODEF 0 "register_operand"))
20680 (use (match_operand:MODEF 1 "general_operand"))]
20681 "TARGET_USE_FANCY_MATH_387
20682 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
20683 || TARGET_MIX_SSE_I387)
20684 && flag_unsafe_math_optimizations"
20686 rtx op0 = gen_reg_rtx (XFmode);
20687 rtx op1 = gen_reg_rtx (XFmode);
20689 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
20690 emit_insn (gen_acosxf2 (op0, op1));
20691 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
20695 (define_expand "sinhxf2"
20696 [(use (match_operand:XF 0 "register_operand"))
20697 (use (match_operand:XF 1 "register_operand"))]
20698 "TARGET_USE_FANCY_MATH_387
20699 && flag_finite_math_only
20700 && flag_unsafe_math_optimizations"
20702 ix86_emit_i387_sinh (operands[0], operands[1]);
20706 (define_expand "sinh<mode>2"
20707 [(use (match_operand:MODEF 0 "register_operand"))
20708 (use (match_operand:MODEF 1 "general_operand"))]
20709 "TARGET_USE_FANCY_MATH_387
20710 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
20711 || TARGET_MIX_SSE_I387)
20712 && flag_finite_math_only
20713 && flag_unsafe_math_optimizations"
20715 rtx op0 = gen_reg_rtx (XFmode);
20716 rtx op1 = gen_reg_rtx (XFmode);
20718 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
20719 emit_insn (gen_sinhxf2 (op0, op1));
20720 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
20724 (define_expand "coshxf2"
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 ix86_emit_i387_cosh (operands[0], operands[1]);
20734 (define_expand "cosh<mode>2"
20735 [(use (match_operand:MODEF 0 "register_operand"))
20736 (use (match_operand:MODEF 1 "general_operand"))]
20737 "TARGET_USE_FANCY_MATH_387
20738 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
20739 || TARGET_MIX_SSE_I387)
20740 && flag_unsafe_math_optimizations"
20742 rtx op0 = gen_reg_rtx (XFmode);
20743 rtx op1 = gen_reg_rtx (XFmode);
20745 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
20746 emit_insn (gen_coshxf2 (op0, op1));
20747 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
20751 (define_expand "tanhxf2"
20752 [(use (match_operand:XF 0 "register_operand"))
20753 (use (match_operand:XF 1 "register_operand"))]
20754 "TARGET_USE_FANCY_MATH_387
20755 && flag_unsafe_math_optimizations"
20757 ix86_emit_i387_tanh (operands[0], operands[1]);
20761 (define_expand "tanh<mode>2"
20762 [(use (match_operand:MODEF 0 "register_operand"))
20763 (use (match_operand:MODEF 1 "general_operand"))]
20764 "TARGET_USE_FANCY_MATH_387
20765 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
20766 || TARGET_MIX_SSE_I387)
20767 && flag_unsafe_math_optimizations"
20769 rtx op0 = gen_reg_rtx (XFmode);
20770 rtx op1 = gen_reg_rtx (XFmode);
20772 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
20773 emit_insn (gen_tanhxf2 (op0, op1));
20774 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
20778 (define_expand "asinhxf2"
20779 [(use (match_operand:XF 0 "register_operand"))
20780 (use (match_operand:XF 1 "register_operand"))]
20781 "TARGET_USE_FANCY_MATH_387
20782 && flag_finite_math_only
20783 && flag_unsafe_math_optimizations"
20785 ix86_emit_i387_asinh (operands[0], operands[1]);
20789 (define_expand "asinh<mode>2"
20790 [(use (match_operand:MODEF 0 "register_operand"))
20791 (use (match_operand:MODEF 1 "general_operand"))]
20792 "TARGET_USE_FANCY_MATH_387
20793 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
20794 || TARGET_MIX_SSE_I387)
20795 && flag_finite_math_only
20796 && flag_unsafe_math_optimizations"
20798 rtx op0 = gen_reg_rtx (XFmode);
20799 rtx op1 = gen_reg_rtx (XFmode);
20801 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
20802 emit_insn (gen_asinhxf2 (op0, op1));
20803 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
20807 (define_expand "acoshxf2"
20808 [(use (match_operand:XF 0 "register_operand"))
20809 (use (match_operand:XF 1 "register_operand"))]
20810 "TARGET_USE_FANCY_MATH_387
20811 && flag_unsafe_math_optimizations"
20813 ix86_emit_i387_acosh (operands[0], operands[1]);
20817 (define_expand "acosh<mode>2"
20818 [(use (match_operand:MODEF 0 "register_operand"))
20819 (use (match_operand:MODEF 1 "general_operand"))]
20820 "TARGET_USE_FANCY_MATH_387
20821 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
20822 || TARGET_MIX_SSE_I387)
20823 && flag_unsafe_math_optimizations"
20825 rtx op0 = gen_reg_rtx (XFmode);
20826 rtx op1 = gen_reg_rtx (XFmode);
20828 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
20829 emit_insn (gen_acoshxf2 (op0, op1));
20830 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
20834 (define_expand "atanhxf2"
20835 [(use (match_operand:XF 0 "register_operand"))
20836 (use (match_operand:XF 1 "register_operand"))]
20837 "TARGET_USE_FANCY_MATH_387
20838 && flag_unsafe_math_optimizations"
20840 ix86_emit_i387_atanh (operands[0], operands[1]);
20844 (define_expand "atanh<mode>2"
20845 [(use (match_operand:MODEF 0 "register_operand"))
20846 (use (match_operand:MODEF 1 "general_operand"))]
20847 "TARGET_USE_FANCY_MATH_387
20848 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
20849 || TARGET_MIX_SSE_I387)
20850 && flag_unsafe_math_optimizations"
20852 rtx op0 = gen_reg_rtx (XFmode);
20853 rtx op1 = gen_reg_rtx (XFmode);
20855 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
20856 emit_insn (gen_atanhxf2 (op0, op1));
20857 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
20861 (define_insn "fyl2xxf3_i387"
20862 [(set (match_operand:XF 0 "register_operand" "=f")
20863 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
20864 (match_operand:XF 2 "register_operand" "f")]
20866 (clobber (match_scratch:XF 3 "=2"))]
20867 "TARGET_USE_FANCY_MATH_387
20868 && flag_unsafe_math_optimizations"
20870 [(set_attr "type" "fpspc")
20871 (set_attr "znver1_decode" "vector")
20872 (set_attr "mode" "XF")])
20874 (define_expand "logxf2"
20875 [(parallel [(set (match_operand:XF 0 "register_operand")
20876 (unspec:XF [(match_operand:XF 1 "register_operand")
20877 (match_dup 2)] UNSPEC_FYL2X))
20878 (clobber (scratch:XF))])]
20879 "TARGET_USE_FANCY_MATH_387
20880 && flag_unsafe_math_optimizations"
20883 = force_reg (XFmode, standard_80387_constant_rtx (4)); /* fldln2 */
20886 (define_expand "log<mode>2"
20887 [(use (match_operand:MODEF 0 "register_operand"))
20888 (use (match_operand:MODEF 1 "general_operand"))]
20889 "TARGET_USE_FANCY_MATH_387
20890 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
20891 || TARGET_MIX_SSE_I387)
20892 && flag_unsafe_math_optimizations"
20894 rtx op0 = gen_reg_rtx (XFmode);
20895 rtx op1 = gen_reg_rtx (XFmode);
20897 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
20898 emit_insn (gen_logxf2 (op0, op1));
20899 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
20903 (define_expand "log10xf2"
20904 [(parallel [(set (match_operand:XF 0 "register_operand")
20905 (unspec:XF [(match_operand:XF 1 "register_operand")
20906 (match_dup 2)] UNSPEC_FYL2X))
20907 (clobber (scratch:XF))])]
20908 "TARGET_USE_FANCY_MATH_387
20909 && flag_unsafe_math_optimizations"
20912 = force_reg (XFmode, standard_80387_constant_rtx (3)); /* fldlg2 */
20915 (define_expand "log10<mode>2"
20916 [(use (match_operand:MODEF 0 "register_operand"))
20917 (use (match_operand:MODEF 1 "general_operand"))]
20918 "TARGET_USE_FANCY_MATH_387
20919 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
20920 || TARGET_MIX_SSE_I387)
20921 && flag_unsafe_math_optimizations"
20923 rtx op0 = gen_reg_rtx (XFmode);
20924 rtx op1 = gen_reg_rtx (XFmode);
20926 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
20927 emit_insn (gen_log10xf2 (op0, op1));
20928 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
20932 (define_expand "log2xf2"
20933 [(parallel [(set (match_operand:XF 0 "register_operand")
20934 (unspec:XF [(match_operand:XF 1 "register_operand")
20935 (match_dup 2)] UNSPEC_FYL2X))
20936 (clobber (scratch:XF))])]
20937 "TARGET_USE_FANCY_MATH_387
20938 && flag_unsafe_math_optimizations"
20939 "operands[2] = force_reg (XFmode, CONST1_RTX (XFmode));")
20941 (define_expand "log2<mode>2"
20942 [(use (match_operand:MODEF 0 "register_operand"))
20943 (use (match_operand:MODEF 1 "general_operand"))]
20944 "TARGET_USE_FANCY_MATH_387
20945 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
20946 || TARGET_MIX_SSE_I387)
20947 && flag_unsafe_math_optimizations"
20949 rtx op0 = gen_reg_rtx (XFmode);
20950 rtx op1 = gen_reg_rtx (XFmode);
20952 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
20953 emit_insn (gen_log2xf2 (op0, op1));
20954 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
20958 (define_insn "fyl2xp1xf3_i387"
20959 [(set (match_operand:XF 0 "register_operand" "=f")
20960 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
20961 (match_operand:XF 2 "register_operand" "f")]
20963 (clobber (match_scratch:XF 3 "=2"))]
20964 "TARGET_USE_FANCY_MATH_387
20965 && flag_unsafe_math_optimizations"
20967 [(set_attr "type" "fpspc")
20968 (set_attr "znver1_decode" "vector")
20969 (set_attr "mode" "XF")])
20971 (define_expand "log1pxf2"
20972 [(use (match_operand:XF 0 "register_operand"))
20973 (use (match_operand:XF 1 "register_operand"))]
20974 "TARGET_USE_FANCY_MATH_387
20975 && flag_unsafe_math_optimizations"
20977 ix86_emit_i387_log1p (operands[0], operands[1]);
20981 (define_expand "log1p<mode>2"
20982 [(use (match_operand:MODEF 0 "register_operand"))
20983 (use (match_operand:MODEF 1 "general_operand"))]
20984 "TARGET_USE_FANCY_MATH_387
20985 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
20986 || TARGET_MIX_SSE_I387)
20987 && flag_unsafe_math_optimizations"
20989 rtx op0 = gen_reg_rtx (XFmode);
20990 rtx op1 = gen_reg_rtx (XFmode);
20992 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
20993 emit_insn (gen_log1pxf2 (op0, op1));
20994 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
20998 (define_insn "fxtractxf3_i387"
20999 [(set (match_operand:XF 0 "register_operand" "=f")
21000 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
21001 UNSPEC_XTRACT_FRACT))
21002 (set (match_operand:XF 1 "register_operand" "=f")
21003 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
21004 "TARGET_USE_FANCY_MATH_387
21005 && flag_unsafe_math_optimizations"
21007 [(set_attr "type" "fpspc")
21008 (set_attr "znver1_decode" "vector")
21009 (set_attr "mode" "XF")])
21011 (define_expand "logbxf2"
21012 [(parallel [(set (match_dup 2)
21013 (unspec:XF [(match_operand:XF 1 "register_operand")]
21014 UNSPEC_XTRACT_FRACT))
21015 (set (match_operand:XF 0 "register_operand")
21016 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
21017 "TARGET_USE_FANCY_MATH_387
21018 && flag_unsafe_math_optimizations"
21019 "operands[2] = gen_reg_rtx (XFmode);")
21021 (define_expand "logb<mode>2"
21022 [(use (match_operand:MODEF 0 "register_operand"))
21023 (use (match_operand:MODEF 1 "general_operand"))]
21024 "TARGET_USE_FANCY_MATH_387
21025 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21026 || TARGET_MIX_SSE_I387)
21027 && flag_unsafe_math_optimizations"
21029 rtx op0 = gen_reg_rtx (XFmode);
21030 rtx op1 = gen_reg_rtx (XFmode);
21032 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
21033 emit_insn (gen_logbxf2 (op0, op1));
21034 emit_insn (gen_truncxf<mode>2 (operands[0], op1));
21038 (define_expand "ilogbxf2"
21039 [(use (match_operand:SI 0 "register_operand"))
21040 (use (match_operand:XF 1 "register_operand"))]
21041 "TARGET_USE_FANCY_MATH_387
21042 && flag_unsafe_math_optimizations"
21046 if (optimize_insn_for_size_p ())
21049 op0 = gen_reg_rtx (XFmode);
21050 op1 = gen_reg_rtx (XFmode);
21052 emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
21053 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
21057 (define_expand "ilogb<mode>2"
21058 [(use (match_operand:SI 0 "register_operand"))
21059 (use (match_operand:MODEF 1 "general_operand"))]
21060 "TARGET_USE_FANCY_MATH_387
21061 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21062 || TARGET_MIX_SSE_I387)
21063 && flag_unsafe_math_optimizations"
21067 if (optimize_insn_for_size_p ())
21070 op0 = gen_reg_rtx (XFmode);
21071 op1 = gen_reg_rtx (XFmode);
21072 op2 = gen_reg_rtx (XFmode);
21074 emit_insn (gen_extend<mode>xf2 (op2, operands[1]));
21075 emit_insn (gen_fxtractxf3_i387 (op0, op1, op2));
21076 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
21080 (define_insn "*f2xm1xf2_i387"
21081 [(set (match_operand:XF 0 "register_operand" "=f")
21082 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
21084 "TARGET_USE_FANCY_MATH_387
21085 && flag_unsafe_math_optimizations"
21087 [(set_attr "type" "fpspc")
21088 (set_attr "znver1_decode" "vector")
21089 (set_attr "mode" "XF")])
21091 (define_insn "fscalexf4_i387"
21092 [(set (match_operand:XF 0 "register_operand" "=f")
21093 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
21094 (match_operand:XF 3 "register_operand" "1")]
21095 UNSPEC_FSCALE_FRACT))
21096 (set (match_operand:XF 1 "register_operand" "=f")
21097 (unspec:XF [(match_dup 2) (match_dup 3)]
21098 UNSPEC_FSCALE_EXP))]
21099 "TARGET_USE_FANCY_MATH_387
21100 && flag_unsafe_math_optimizations"
21102 [(set_attr "type" "fpspc")
21103 (set_attr "znver1_decode" "vector")
21104 (set_attr "mode" "XF")])
21106 (define_expand "expNcorexf3"
21107 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand")
21108 (match_operand:XF 2 "register_operand")))
21109 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
21110 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
21111 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
21112 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
21113 (parallel [(set (match_operand:XF 0 "register_operand")
21114 (unspec:XF [(match_dup 8) (match_dup 4)]
21115 UNSPEC_FSCALE_FRACT))
21117 (unspec:XF [(match_dup 8) (match_dup 4)]
21118 UNSPEC_FSCALE_EXP))])]
21119 "TARGET_USE_FANCY_MATH_387
21120 && flag_unsafe_math_optimizations"
21124 for (i = 3; i < 10; i++)
21125 operands[i] = gen_reg_rtx (XFmode);
21127 emit_move_insn (operands[7], CONST1_RTX (XFmode));
21130 (define_expand "expxf2"
21131 [(use (match_operand:XF 0 "register_operand"))
21132 (use (match_operand:XF 1 "register_operand"))]
21133 "TARGET_USE_FANCY_MATH_387
21134 && flag_unsafe_math_optimizations"
21136 rtx op2 = force_reg (XFmode, standard_80387_constant_rtx (5)); /* fldl2e */
21138 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
21142 (define_expand "exp<mode>2"
21143 [(use (match_operand:MODEF 0 "register_operand"))
21144 (use (match_operand:MODEF 1 "general_operand"))]
21145 "TARGET_USE_FANCY_MATH_387
21146 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21147 || TARGET_MIX_SSE_I387)
21148 && flag_unsafe_math_optimizations"
21150 rtx op0 = gen_reg_rtx (XFmode);
21151 rtx op1 = gen_reg_rtx (XFmode);
21153 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
21154 emit_insn (gen_expxf2 (op0, op1));
21155 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
21159 (define_expand "exp10xf2"
21160 [(use (match_operand:XF 0 "register_operand"))
21161 (use (match_operand:XF 1 "register_operand"))]
21162 "TARGET_USE_FANCY_MATH_387
21163 && flag_unsafe_math_optimizations"
21165 rtx op2 = force_reg (XFmode, standard_80387_constant_rtx (6)); /* fldl2t */
21167 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
21171 (define_expand "exp10<mode>2"
21172 [(use (match_operand:MODEF 0 "register_operand"))
21173 (use (match_operand:MODEF 1 "general_operand"))]
21174 "TARGET_USE_FANCY_MATH_387
21175 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21176 || TARGET_MIX_SSE_I387)
21177 && flag_unsafe_math_optimizations"
21179 rtx op0 = gen_reg_rtx (XFmode);
21180 rtx op1 = gen_reg_rtx (XFmode);
21182 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
21183 emit_insn (gen_exp10xf2 (op0, op1));
21184 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
21188 (define_expand "exp2xf2"
21189 [(use (match_operand:XF 0 "register_operand"))
21190 (use (match_operand:XF 1 "register_operand"))]
21191 "TARGET_USE_FANCY_MATH_387
21192 && flag_unsafe_math_optimizations"
21194 rtx op2 = force_reg (XFmode, CONST1_RTX (XFmode));
21196 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
21200 (define_expand "exp2<mode>2"
21201 [(use (match_operand:MODEF 0 "register_operand"))
21202 (use (match_operand:MODEF 1 "general_operand"))]
21203 "TARGET_USE_FANCY_MATH_387
21204 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21205 || TARGET_MIX_SSE_I387)
21206 && flag_unsafe_math_optimizations"
21208 rtx op0 = gen_reg_rtx (XFmode);
21209 rtx op1 = gen_reg_rtx (XFmode);
21211 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
21212 emit_insn (gen_exp2xf2 (op0, op1));
21213 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
21217 (define_expand "expm1xf2"
21218 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand")
21220 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
21221 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
21222 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
21223 (parallel [(set (match_dup 7)
21224 (unspec:XF [(match_dup 6) (match_dup 4)]
21225 UNSPEC_FSCALE_FRACT))
21227 (unspec:XF [(match_dup 6) (match_dup 4)]
21228 UNSPEC_FSCALE_EXP))])
21229 (parallel [(set (match_dup 10)
21230 (unspec:XF [(match_dup 9) (match_dup 8)]
21231 UNSPEC_FSCALE_FRACT))
21232 (set (match_dup 11)
21233 (unspec:XF [(match_dup 9) (match_dup 8)]
21234 UNSPEC_FSCALE_EXP))])
21235 (set (match_dup 12) (minus:XF (match_dup 10) (match_dup 9)))
21236 (set (match_operand:XF 0 "register_operand")
21237 (plus:XF (match_dup 12) (match_dup 7)))]
21238 "TARGET_USE_FANCY_MATH_387
21239 && flag_unsafe_math_optimizations"
21243 for (i = 2; i < 13; i++)
21244 operands[i] = gen_reg_rtx (XFmode);
21246 emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
21247 emit_move_insn (operands[9], CONST1_RTX (XFmode));
21250 (define_expand "expm1<mode>2"
21251 [(use (match_operand:MODEF 0 "register_operand"))
21252 (use (match_operand:MODEF 1 "general_operand"))]
21253 "TARGET_USE_FANCY_MATH_387
21254 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21255 || TARGET_MIX_SSE_I387)
21256 && flag_unsafe_math_optimizations"
21258 rtx op0 = gen_reg_rtx (XFmode);
21259 rtx op1 = gen_reg_rtx (XFmode);
21261 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
21262 emit_insn (gen_expm1xf2 (op0, op1));
21263 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
21267 (define_insn "avx512f_scalef<mode>2"
21268 [(set (match_operand:MODEF 0 "register_operand" "=v")
21270 [(match_operand:MODEF 1 "register_operand" "v")
21271 (match_operand:MODEF 2 "nonimmediate_operand" "vm")]
21274 "vscalef<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
21275 [(set_attr "prefix" "evex")
21276 (set_attr "mode" "<MODE>")])
21278 (define_expand "ldexpxf3"
21279 [(match_operand:XF 0 "register_operand")
21280 (match_operand:XF 1 "register_operand")
21281 (match_operand:SI 2 "register_operand")]
21282 "TARGET_USE_FANCY_MATH_387
21283 && flag_unsafe_math_optimizations"
21285 rtx tmp1 = gen_reg_rtx (XFmode);
21286 rtx tmp2 = gen_reg_rtx (XFmode);
21288 emit_insn (gen_floatsixf2 (tmp1, operands[2]));
21289 emit_insn (gen_fscalexf4_i387 (operands[0], tmp2,
21290 operands[1], tmp1));
21294 (define_expand "ldexp<mode>3"
21295 [(use (match_operand:MODEF 0 "register_operand"))
21296 (use (match_operand:MODEF 1 "general_operand"))
21297 (use (match_operand:SI 2 "register_operand"))]
21298 "((TARGET_USE_FANCY_MATH_387
21299 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21300 || TARGET_MIX_SSE_I387))
21301 || (TARGET_AVX512F && TARGET_SSE_MATH))
21302 && flag_unsafe_math_optimizations"
21304 /* Prefer avx512f version. */
21305 if (TARGET_AVX512F && TARGET_SSE_MATH)
21307 rtx op2 = gen_reg_rtx (<MODE>mode);
21308 operands[1] = force_reg (<MODE>mode, operands[1]);
21310 emit_insn (gen_floatsi<mode>2 (op2, operands[2]));
21311 emit_insn (gen_avx512f_scalef<mode>2 (operands[0], operands[1], op2));
21315 rtx op0 = gen_reg_rtx (XFmode);
21316 rtx op1 = gen_reg_rtx (XFmode);
21318 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
21319 emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
21320 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
21325 (define_expand "scalbxf3"
21326 [(parallel [(set (match_operand:XF 0 " register_operand")
21327 (unspec:XF [(match_operand:XF 1 "register_operand")
21328 (match_operand:XF 2 "register_operand")]
21329 UNSPEC_FSCALE_FRACT))
21331 (unspec:XF [(match_dup 1) (match_dup 2)]
21332 UNSPEC_FSCALE_EXP))])]
21333 "TARGET_USE_FANCY_MATH_387
21334 && flag_unsafe_math_optimizations"
21335 "operands[3] = gen_reg_rtx (XFmode);")
21337 (define_expand "scalb<mode>3"
21338 [(use (match_operand:MODEF 0 "register_operand"))
21339 (use (match_operand:MODEF 1 "general_operand"))
21340 (use (match_operand:MODEF 2 "general_operand"))]
21341 "TARGET_USE_FANCY_MATH_387
21342 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21343 || TARGET_MIX_SSE_I387)
21344 && flag_unsafe_math_optimizations"
21346 rtx op0 = gen_reg_rtx (XFmode);
21347 rtx op1 = gen_reg_rtx (XFmode);
21348 rtx op2 = gen_reg_rtx (XFmode);
21350 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
21351 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
21352 emit_insn (gen_scalbxf3 (op0, op1, op2));
21353 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
21357 (define_expand "significandxf2"
21358 [(parallel [(set (match_operand:XF 0 "register_operand")
21359 (unspec:XF [(match_operand:XF 1 "register_operand")]
21360 UNSPEC_XTRACT_FRACT))
21362 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
21363 "TARGET_USE_FANCY_MATH_387
21364 && flag_unsafe_math_optimizations"
21365 "operands[2] = gen_reg_rtx (XFmode);")
21367 (define_expand "significand<mode>2"
21368 [(use (match_operand:MODEF 0 "register_operand"))
21369 (use (match_operand:MODEF 1 "general_operand"))]
21370 "TARGET_USE_FANCY_MATH_387
21371 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21372 || TARGET_MIX_SSE_I387)
21373 && flag_unsafe_math_optimizations"
21375 rtx op0 = gen_reg_rtx (XFmode);
21376 rtx op1 = gen_reg_rtx (XFmode);
21378 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
21379 emit_insn (gen_significandxf2 (op0, op1));
21380 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
21385 (define_insn "sse4_1_round<mode>2"
21386 [(set (match_operand:MODEFH 0 "register_operand" "=x,x,x,v,v")
21388 [(match_operand:MODEFH 1 "nonimmediate_operand" "0,x,m,v,m")
21389 (match_operand:SI 2 "const_0_to_15_operand")]
21393 %vround<ssemodesuffix>\t{%2, %d1, %0|%0, %d1, %2}
21394 %vround<ssemodesuffix>\t{%2, %d1, %0|%0, %d1, %2}
21395 %vround<ssemodesuffix>\t{%2, %1, %d0|%d0, %1, %2}
21396 vrndscale<ssemodesuffix>\t{%2, %d1, %0|%0, %d1, %2}
21397 vrndscale<ssemodesuffix>\t{%2, %1, %d0|%d0, %1, %2}"
21398 [(set_attr "type" "ssecvt")
21399 (set_attr "prefix_extra" "1,1,1,*,*")
21400 (set_attr "length_immediate" "*,*,*,1,1")
21401 (set_attr "prefix" "maybe_vex,maybe_vex,maybe_vex,evex,evex")
21402 (set_attr "isa" "noavx512f,noavx512f,noavx512f,avx512f,avx512f")
21403 (set_attr "avx_partial_xmm_update" "false,false,true,false,true")
21404 (set_attr "mode" "<MODE>")
21405 (set (attr "preferred_for_speed")
21406 (cond [(match_test "TARGET_AVX")
21407 (symbol_ref "true")
21408 (eq_attr "alternative" "1,2")
21409 (symbol_ref "!TARGET_SSE_PARTIAL_REG_DEPENDENCY")
21411 (symbol_ref "true")))])
21413 (define_insn "rintxf2"
21414 [(set (match_operand:XF 0 "register_operand" "=f")
21415 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
21417 "TARGET_USE_FANCY_MATH_387"
21419 [(set_attr "type" "fpspc")
21420 (set_attr "znver1_decode" "vector")
21421 (set_attr "mode" "XF")])
21423 (define_expand "rinthf2"
21424 [(match_operand:HF 0 "register_operand")
21425 (match_operand:HF 1 "nonimmediate_operand")]
21426 "TARGET_AVX512FP16"
21428 emit_insn (gen_sse4_1_roundhf2 (operands[0],
21430 GEN_INT (ROUND_MXCSR)));
21434 (define_expand "rint<mode>2"
21435 [(use (match_operand:MODEF 0 "register_operand"))
21436 (use (match_operand:MODEF 1 "nonimmediate_operand"))]
21437 "TARGET_USE_FANCY_MATH_387
21438 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
21440 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21443 emit_insn (gen_sse4_1_round<mode>2
21444 (operands[0], operands[1], GEN_INT (ROUND_MXCSR)));
21446 ix86_expand_rint (operands[0], operands[1]);
21450 rtx op0 = gen_reg_rtx (XFmode);
21451 rtx op1 = gen_reg_rtx (XFmode);
21453 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
21454 emit_insn (gen_rintxf2 (op0, op1));
21455 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
21460 (define_expand "nearbyintxf2"
21461 [(set (match_operand:XF 0 "register_operand")
21462 (unspec:XF [(match_operand:XF 1 "register_operand")]
21464 "TARGET_USE_FANCY_MATH_387
21465 && !flag_trapping_math")
21467 (define_expand "nearbyinthf2"
21468 [(match_operand:HF 0 "register_operand")
21469 (match_operand:HF 1 "nonimmediate_operand")]
21470 "TARGET_AVX512FP16"
21472 emit_insn (gen_sse4_1_roundhf2 (operands[0],
21474 GEN_INT (ROUND_MXCSR | ROUND_NO_EXC)));
21478 (define_expand "nearbyint<mode>2"
21479 [(use (match_operand:MODEF 0 "register_operand"))
21480 (use (match_operand:MODEF 1 "nonimmediate_operand"))]
21481 "(TARGET_USE_FANCY_MATH_387
21482 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21483 || TARGET_MIX_SSE_I387)
21484 && !flag_trapping_math)
21485 || (TARGET_SSE4_1 && TARGET_SSE_MATH)"
21487 if (TARGET_SSE4_1 && TARGET_SSE_MATH)
21488 emit_insn (gen_sse4_1_round<mode>2
21489 (operands[0], operands[1], GEN_INT (ROUND_MXCSR
21493 rtx op0 = gen_reg_rtx (XFmode);
21494 rtx op1 = gen_reg_rtx (XFmode);
21496 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
21497 emit_insn (gen_nearbyintxf2 (op0, op1));
21498 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
21503 (define_expand "round<mode>2"
21504 [(match_operand:X87MODEF 0 "register_operand")
21505 (match_operand:X87MODEF 1 "nonimmediate_operand")]
21506 "(TARGET_USE_FANCY_MATH_387
21507 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21508 || TARGET_MIX_SSE_I387)
21509 && flag_unsafe_math_optimizations
21510 && (flag_fp_int_builtin_inexact || !flag_trapping_math))
21511 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
21512 && !flag_trapping_math && !flag_rounding_math)"
21514 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
21515 && !flag_trapping_math && !flag_rounding_math)
21519 operands[1] = force_reg (<MODE>mode, operands[1]);
21520 ix86_expand_round_sse4 (operands[0], operands[1]);
21522 else if (TARGET_64BIT || (<MODE>mode != DFmode))
21523 ix86_expand_round (operands[0], operands[1]);
21525 ix86_expand_rounddf_32 (operands[0], operands[1]);
21529 operands[1] = force_reg (<MODE>mode, operands[1]);
21530 ix86_emit_i387_round (operands[0], operands[1]);
21535 (define_insn "lrintxfdi2"
21536 [(set (match_operand:DI 0 "nonimmediate_operand" "=m")
21537 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
21539 (clobber (match_scratch:XF 2 "=&f"))]
21540 "TARGET_USE_FANCY_MATH_387"
21541 "* return output_fix_trunc (insn, operands, false);"
21542 [(set_attr "type" "fpspc")
21543 (set_attr "mode" "DI")])
21545 (define_insn "lrintxf<mode>2"
21546 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m")
21547 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
21549 "TARGET_USE_FANCY_MATH_387"
21550 "* return output_fix_trunc (insn, operands, false);"
21551 [(set_attr "type" "fpspc")
21552 (set_attr "mode" "<MODE>")])
21554 (define_expand "lrint<MODEF:mode><SWI48:mode>2"
21555 [(set (match_operand:SWI48 0 "register_operand")
21556 (unspec:SWI48 [(match_operand:MODEF 1 "nonimmediate_operand")]
21557 UNSPEC_FIX_NOTRUNC))]
21558 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH")
21560 (define_expand "lround<X87MODEF:mode><SWI248x:mode>2"
21561 [(match_operand:SWI248x 0 "nonimmediate_operand")
21562 (match_operand:X87MODEF 1 "register_operand")]
21563 "(TARGET_USE_FANCY_MATH_387
21564 && (!(SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
21565 || TARGET_MIX_SSE_I387)
21566 && flag_unsafe_math_optimizations)
21567 || (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
21568 && <SWI248x:MODE>mode != HImode
21569 && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT)
21570 && !flag_trapping_math && !flag_rounding_math)"
21572 if (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
21573 && <SWI248x:MODE>mode != HImode
21574 && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT)
21575 && !flag_trapping_math && !flag_rounding_math)
21576 ix86_expand_lround (operands[0], operands[1]);
21578 ix86_emit_i387_round (operands[0], operands[1]);
21582 (define_int_iterator FRNDINT_ROUNDING
21583 [UNSPEC_FRNDINT_ROUNDEVEN
21584 UNSPEC_FRNDINT_FLOOR
21585 UNSPEC_FRNDINT_CEIL
21586 UNSPEC_FRNDINT_TRUNC])
21588 (define_int_iterator FIST_ROUNDING
21592 ;; Base name for define_insn
21593 (define_int_attr rounding_insn
21594 [(UNSPEC_FRNDINT_ROUNDEVEN "roundeven")
21595 (UNSPEC_FRNDINT_FLOOR "floor")
21596 (UNSPEC_FRNDINT_CEIL "ceil")
21597 (UNSPEC_FRNDINT_TRUNC "btrunc")
21598 (UNSPEC_FIST_FLOOR "floor")
21599 (UNSPEC_FIST_CEIL "ceil")])
21601 (define_int_attr rounding
21602 [(UNSPEC_FRNDINT_ROUNDEVEN "roundeven")
21603 (UNSPEC_FRNDINT_FLOOR "floor")
21604 (UNSPEC_FRNDINT_CEIL "ceil")
21605 (UNSPEC_FRNDINT_TRUNC "trunc")
21606 (UNSPEC_FIST_FLOOR "floor")
21607 (UNSPEC_FIST_CEIL "ceil")])
21609 (define_int_attr ROUNDING
21610 [(UNSPEC_FRNDINT_ROUNDEVEN "ROUNDEVEN")
21611 (UNSPEC_FRNDINT_FLOOR "FLOOR")
21612 (UNSPEC_FRNDINT_CEIL "CEIL")
21613 (UNSPEC_FRNDINT_TRUNC "TRUNC")
21614 (UNSPEC_FIST_FLOOR "FLOOR")
21615 (UNSPEC_FIST_CEIL "CEIL")])
21617 ;; Rounding mode control word calculation could clobber FLAGS_REG.
21618 (define_insn_and_split "frndintxf2_<rounding>"
21619 [(set (match_operand:XF 0 "register_operand")
21620 (unspec:XF [(match_operand:XF 1 "register_operand")]
21622 (clobber (reg:CC FLAGS_REG))]
21623 "TARGET_USE_FANCY_MATH_387
21624 && (flag_fp_int_builtin_inexact || !flag_trapping_math)
21625 && ix86_pre_reload_split ()"
21630 ix86_optimize_mode_switching[I387_<ROUNDING>] = 1;
21632 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
21633 operands[3] = assign_386_stack_local (HImode, SLOT_CW_<ROUNDING>);
21635 emit_insn (gen_frndintxf2_<rounding>_i387 (operands[0], operands[1],
21636 operands[2], operands[3]));
21639 [(set_attr "type" "frndint")
21640 (set_attr "i387_cw" "<rounding>")
21641 (set_attr "mode" "XF")])
21643 (define_insn "frndintxf2_<rounding>_i387"
21644 [(set (match_operand:XF 0 "register_operand" "=f")
21645 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
21647 (use (match_operand:HI 2 "memory_operand" "m"))
21648 (use (match_operand:HI 3 "memory_operand" "m"))]
21649 "TARGET_USE_FANCY_MATH_387
21650 && (flag_fp_int_builtin_inexact || !flag_trapping_math)"
21651 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
21652 [(set_attr "type" "frndint")
21653 (set_attr "i387_cw" "<rounding>")
21654 (set_attr "mode" "XF")])
21656 (define_expand "<rounding_insn>xf2"
21657 [(parallel [(set (match_operand:XF 0 "register_operand")
21658 (unspec:XF [(match_operand:XF 1 "register_operand")]
21660 (clobber (reg:CC FLAGS_REG))])]
21661 "TARGET_USE_FANCY_MATH_387
21662 && (flag_fp_int_builtin_inexact || !flag_trapping_math)")
21664 (define_expand "<rounding_insn>hf2"
21665 [(parallel [(set (match_operand:HF 0 "register_operand")
21666 (unspec:HF [(match_operand:HF 1 "register_operand")]
21668 (clobber (reg:CC FLAGS_REG))])]
21669 "TARGET_AVX512FP16"
21671 emit_insn (gen_sse4_1_roundhf2 (operands[0], operands[1],
21672 GEN_INT (ROUND_<ROUNDING> | ROUND_NO_EXC)));
21676 (define_expand "<rounding_insn><mode>2"
21677 [(parallel [(set (match_operand:MODEF 0 "register_operand")
21678 (unspec:MODEF [(match_operand:MODEF 1 "register_operand")]
21680 (clobber (reg:CC FLAGS_REG))])]
21681 "(TARGET_USE_FANCY_MATH_387
21682 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
21683 || TARGET_MIX_SSE_I387)
21684 && (flag_fp_int_builtin_inexact || !flag_trapping_math))
21685 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
21687 || (ROUND_<ROUNDING> != ROUND_ROUNDEVEN
21688 && (flag_fp_int_builtin_inexact || !flag_trapping_math))))"
21690 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
21692 || (ROUND_<ROUNDING> != ROUND_ROUNDEVEN
21693 && (flag_fp_int_builtin_inexact || !flag_trapping_math))))
21696 emit_insn (gen_sse4_1_round<mode>2
21697 (operands[0], operands[1],
21698 GEN_INT (ROUND_<ROUNDING> | ROUND_NO_EXC)));
21699 else if (TARGET_64BIT || (<MODE>mode != DFmode))
21701 if (ROUND_<ROUNDING> == ROUND_FLOOR)
21702 ix86_expand_floorceil (operands[0], operands[1], true);
21703 else if (ROUND_<ROUNDING> == ROUND_CEIL)
21704 ix86_expand_floorceil (operands[0], operands[1], false);
21705 else if (ROUND_<ROUNDING> == ROUND_TRUNC)
21706 ix86_expand_trunc (operands[0], operands[1]);
21708 gcc_unreachable ();
21712 if (ROUND_<ROUNDING> == ROUND_FLOOR)
21713 ix86_expand_floorceildf_32 (operands[0], operands[1], true);
21714 else if (ROUND_<ROUNDING> == ROUND_CEIL)
21715 ix86_expand_floorceildf_32 (operands[0], operands[1], false);
21716 else if (ROUND_<ROUNDING> == ROUND_TRUNC)
21717 ix86_expand_truncdf_32 (operands[0], operands[1]);
21719 gcc_unreachable ();
21724 rtx op0 = gen_reg_rtx (XFmode);
21725 rtx op1 = gen_reg_rtx (XFmode);
21727 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
21728 emit_insn (gen_frndintxf2_<rounding> (op0, op1));
21729 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
21734 ;; Rounding mode control word calculation could clobber FLAGS_REG.
21735 (define_insn_and_split "*fist<mode>2_<rounding>_1"
21736 [(set (match_operand:SWI248x 0 "nonimmediate_operand")
21737 (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
21739 (clobber (reg:CC FLAGS_REG))]
21740 "TARGET_USE_FANCY_MATH_387
21741 && flag_unsafe_math_optimizations
21742 && ix86_pre_reload_split ()"
21747 ix86_optimize_mode_switching[I387_<ROUNDING>] = 1;
21749 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
21750 operands[3] = assign_386_stack_local (HImode, SLOT_CW_<ROUNDING>);
21752 emit_insn (gen_fist<mode>2_<rounding> (operands[0], operands[1],
21753 operands[2], operands[3]));
21756 [(set_attr "type" "fistp")
21757 (set_attr "i387_cw" "<rounding>")
21758 (set_attr "mode" "<MODE>")])
21760 (define_insn "fistdi2_<rounding>"
21761 [(set (match_operand:DI 0 "nonimmediate_operand" "=m")
21762 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
21764 (use (match_operand:HI 2 "memory_operand" "m"))
21765 (use (match_operand:HI 3 "memory_operand" "m"))
21766 (clobber (match_scratch:XF 4 "=&f"))]
21767 "TARGET_USE_FANCY_MATH_387
21768 && flag_unsafe_math_optimizations"
21769 "* return output_fix_trunc (insn, operands, false);"
21770 [(set_attr "type" "fistp")
21771 (set_attr "i387_cw" "<rounding>")
21772 (set_attr "mode" "DI")])
21774 (define_insn "fist<mode>2_<rounding>"
21775 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m")
21776 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
21778 (use (match_operand:HI 2 "memory_operand" "m"))
21779 (use (match_operand:HI 3 "memory_operand" "m"))]
21780 "TARGET_USE_FANCY_MATH_387
21781 && flag_unsafe_math_optimizations"
21782 "* return output_fix_trunc (insn, operands, false);"
21783 [(set_attr "type" "fistp")
21784 (set_attr "i387_cw" "<rounding>")
21785 (set_attr "mode" "<MODE>")])
21787 (define_expand "l<rounding_insn>xf<mode>2"
21788 [(parallel [(set (match_operand:SWI248x 0 "nonimmediate_operand")
21789 (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
21791 (clobber (reg:CC FLAGS_REG))])]
21792 "TARGET_USE_FANCY_MATH_387
21793 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
21794 && flag_unsafe_math_optimizations")
21796 (define_expand "l<rounding_insn><MODEF:mode><SWI48:mode>2"
21797 [(parallel [(set (match_operand:SWI48 0 "nonimmediate_operand")
21798 (unspec:SWI48 [(match_operand:MODEF 1 "register_operand")]
21800 (clobber (reg:CC FLAGS_REG))])]
21801 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
21802 && (TARGET_SSE4_1 || !flag_trapping_math)"
21806 rtx tmp = gen_reg_rtx (<MODEF:MODE>mode);
21808 emit_insn (gen_sse4_1_round<MODEF:mode>2
21809 (tmp, operands[1], GEN_INT (ROUND_<ROUNDING>
21811 emit_insn (gen_fix_trunc<MODEF:mode><SWI48:mode>2
21812 (operands[0], tmp));
21814 else if (ROUND_<ROUNDING> == ROUND_FLOOR)
21815 ix86_expand_lfloorceil (operands[0], operands[1], true);
21816 else if (ROUND_<ROUNDING> == ROUND_CEIL)
21817 ix86_expand_lfloorceil (operands[0], operands[1], false);
21819 gcc_unreachable ();
21824 (define_insn "fxam<mode>2_i387"
21825 [(set (match_operand:HI 0 "register_operand" "=a")
21827 [(match_operand:X87MODEF 1 "register_operand" "f")]
21829 "TARGET_USE_FANCY_MATH_387"
21830 "fxam\n\tfnstsw\t%0"
21831 [(set_attr "type" "multi")
21832 (set_attr "length" "4")
21833 (set_attr "unit" "i387")
21834 (set_attr "mode" "<MODE>")])
21836 (define_expand "signbittf2"
21837 [(use (match_operand:SI 0 "register_operand"))
21838 (use (match_operand:TF 1 "register_operand"))]
21843 rtx mask = ix86_build_signbit_mask (TFmode, 0, 0);
21844 rtx scratch = gen_reg_rtx (QImode);
21846 emit_insn (gen_ptesttf2 (operands[1], mask));
21847 ix86_expand_setcc (scratch, NE,
21848 gen_rtx_REG (CCZmode, FLAGS_REG), const0_rtx);
21850 emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
21854 emit_insn (gen_sse_movmskps (operands[0],
21855 gen_lowpart (V4SFmode, operands[1])));
21856 emit_insn (gen_andsi3 (operands[0], operands[0], GEN_INT (0x8)));
21861 (define_expand "signbitxf2"
21862 [(use (match_operand:SI 0 "register_operand"))
21863 (use (match_operand:XF 1 "register_operand"))]
21864 "TARGET_USE_FANCY_MATH_387"
21866 rtx scratch = gen_reg_rtx (HImode);
21868 emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
21869 emit_insn (gen_andsi3 (operands[0],
21870 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
21874 (define_insn "movmsk_df"
21875 [(set (match_operand:SI 0 "register_operand" "=r")
21877 [(match_operand:DF 1 "register_operand" "x")]
21879 "SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH"
21880 "%vmovmskpd\t{%1, %0|%0, %1}"
21881 [(set_attr "type" "ssemov")
21882 (set_attr "prefix" "maybe_vex")
21883 (set_attr "mode" "DF")])
21885 ;; Use movmskpd in SSE mode to avoid store forwarding stall
21886 ;; for 32bit targets and movq+shrq sequence for 64bit targets.
21887 (define_expand "signbitdf2"
21888 [(use (match_operand:SI 0 "register_operand"))
21889 (use (match_operand:DF 1 "register_operand"))]
21890 "TARGET_USE_FANCY_MATH_387
21891 || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
21893 if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)
21895 emit_insn (gen_movmsk_df (operands[0], operands[1]));
21896 emit_insn (gen_andsi3 (operands[0], operands[0], const1_rtx));
21900 rtx scratch = gen_reg_rtx (HImode);
21902 emit_insn (gen_fxamdf2_i387 (scratch, operands[1]));
21903 emit_insn (gen_andsi3 (operands[0],
21904 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
21909 (define_expand "signbitsf2"
21910 [(use (match_operand:SI 0 "register_operand"))
21911 (use (match_operand:SF 1 "register_operand"))]
21912 "TARGET_USE_FANCY_MATH_387
21913 && !(SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH)"
21915 rtx scratch = gen_reg_rtx (HImode);
21917 emit_insn (gen_fxamsf2_i387 (scratch, operands[1]));
21918 emit_insn (gen_andsi3 (operands[0],
21919 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
21923 ;; Block operation instructions
21926 [(unspec_volatile [(const_int 0)] UNSPECV_CLD)]
21929 [(set_attr "length" "1")
21930 (set_attr "length_immediate" "0")
21931 (set_attr "modrm" "0")])
21933 (define_expand "cpymem<mode>"
21934 [(use (match_operand:BLK 0 "memory_operand"))
21935 (use (match_operand:BLK 1 "memory_operand"))
21936 (use (match_operand:SWI48 2 "nonmemory_operand"))
21937 (use (match_operand:SWI48 3 "const_int_operand"))
21938 (use (match_operand:SI 4 "const_int_operand"))
21939 (use (match_operand:SI 5 "const_int_operand"))
21940 (use (match_operand:SI 6 ""))
21941 (use (match_operand:SI 7 ""))
21942 (use (match_operand:SI 8 ""))]
21945 if (ix86_expand_set_or_cpymem (operands[0], operands[1],
21946 operands[2], NULL, operands[3],
21947 operands[4], operands[5],
21948 operands[6], operands[7],
21949 operands[8], false))
21955 ;; Most CPUs don't like single string operations
21956 ;; Handle this case here to simplify previous expander.
21958 (define_expand "strmov"
21959 [(set (match_dup 4) (match_operand 3 "memory_operand"))
21960 (set (match_operand 1 "memory_operand") (match_dup 4))
21961 (parallel [(set (match_operand 0 "register_operand") (match_dup 5))
21962 (clobber (reg:CC FLAGS_REG))])
21963 (parallel [(set (match_operand 2 "register_operand") (match_dup 6))
21964 (clobber (reg:CC FLAGS_REG))])]
21967 /* Can't use this for non-default address spaces. */
21968 if (!ADDR_SPACE_GENERIC_P (MEM_ADDR_SPACE (operands[3])))
21971 int piece_size = GET_MODE_SIZE (GET_MODE (operands[1]));
21973 /* If .md ever supports :P for Pmode, these can be directly
21974 in the pattern above. */
21975 operands[5] = plus_constant (Pmode, operands[0], piece_size);
21976 operands[6] = plus_constant (Pmode, operands[2], piece_size);
21978 /* Can't use this if the user has appropriated esi or edi. */
21979 if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
21980 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG]))
21982 emit_insn (gen_strmov_singleop (operands[0], operands[1],
21983 operands[2], operands[3],
21984 operands[5], operands[6]));
21988 operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
21991 (define_expand "strmov_singleop"
21992 [(parallel [(set (match_operand 1 "memory_operand")
21993 (match_operand 3 "memory_operand"))
21994 (set (match_operand 0 "register_operand")
21996 (set (match_operand 2 "register_operand")
21997 (match_operand 5))])]
22001 ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
22004 (define_insn "*strmovdi_rex_1"
22005 [(set (mem:DI (match_operand:P 2 "register_operand" "0"))
22006 (mem:DI (match_operand:P 3 "register_operand" "1")))
22007 (set (match_operand:P 0 "register_operand" "=D")
22008 (plus:P (match_dup 2)
22010 (set (match_operand:P 1 "register_operand" "=S")
22011 (plus:P (match_dup 3)
22014 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG])
22015 && ix86_check_no_addr_space (insn)"
22017 [(set_attr "type" "str")
22018 (set_attr "memory" "both")
22019 (set_attr "mode" "DI")])
22021 (define_insn "*strmovsi_1"
22022 [(set (mem:SI (match_operand:P 2 "register_operand" "0"))
22023 (mem:SI (match_operand:P 3 "register_operand" "1")))
22024 (set (match_operand:P 0 "register_operand" "=D")
22025 (plus:P (match_dup 2)
22027 (set (match_operand:P 1 "register_operand" "=S")
22028 (plus:P (match_dup 3)
22030 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])
22031 && ix86_check_no_addr_space (insn)"
22033 [(set_attr "type" "str")
22034 (set_attr "memory" "both")
22035 (set_attr "mode" "SI")])
22037 (define_insn "*strmovhi_1"
22038 [(set (mem:HI (match_operand:P 2 "register_operand" "0"))
22039 (mem:HI (match_operand:P 3 "register_operand" "1")))
22040 (set (match_operand:P 0 "register_operand" "=D")
22041 (plus:P (match_dup 2)
22043 (set (match_operand:P 1 "register_operand" "=S")
22044 (plus:P (match_dup 3)
22046 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])
22047 && ix86_check_no_addr_space (insn)"
22049 [(set_attr "type" "str")
22050 (set_attr "memory" "both")
22051 (set_attr "mode" "HI")])
22053 (define_insn "*strmovqi_1"
22054 [(set (mem:QI (match_operand:P 2 "register_operand" "0"))
22055 (mem:QI (match_operand:P 3 "register_operand" "1")))
22056 (set (match_operand:P 0 "register_operand" "=D")
22057 (plus:P (match_dup 2)
22059 (set (match_operand:P 1 "register_operand" "=S")
22060 (plus:P (match_dup 3)
22062 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])
22063 && ix86_check_no_addr_space (insn)"
22065 [(set_attr "type" "str")
22066 (set_attr "memory" "both")
22067 (set (attr "prefix_rex")
22069 (match_test "<P:MODE>mode == DImode")
22071 (const_string "*")))
22072 (set_attr "mode" "QI")])
22074 (define_expand "rep_mov"
22075 [(parallel [(set (match_operand 4 "register_operand") (const_int 0))
22076 (set (match_operand 0 "register_operand")
22078 (set (match_operand 2 "register_operand")
22080 (set (match_operand 1 "memory_operand")
22081 (match_operand 3 "memory_operand"))
22082 (use (match_dup 4))])]
22086 ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
22089 (define_insn "*rep_movdi_rex64"
22090 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
22091 (set (match_operand:P 0 "register_operand" "=D")
22092 (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
22094 (match_operand:P 3 "register_operand" "0")))
22095 (set (match_operand:P 1 "register_operand" "=S")
22096 (plus:P (ashift:P (match_dup 5) (const_int 3))
22097 (match_operand:P 4 "register_operand" "1")))
22098 (set (mem:BLK (match_dup 3))
22099 (mem:BLK (match_dup 4)))
22100 (use (match_dup 5))]
22102 && !(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
22103 && ix86_check_no_addr_space (insn)"
22105 [(set_attr "type" "str")
22106 (set_attr "prefix_rep" "1")
22107 (set_attr "memory" "both")
22108 (set_attr "mode" "DI")])
22110 (define_insn "*rep_movsi"
22111 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
22112 (set (match_operand:P 0 "register_operand" "=D")
22113 (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
22115 (match_operand:P 3 "register_operand" "0")))
22116 (set (match_operand:P 1 "register_operand" "=S")
22117 (plus:P (ashift:P (match_dup 5) (const_int 2))
22118 (match_operand:P 4 "register_operand" "1")))
22119 (set (mem:BLK (match_dup 3))
22120 (mem:BLK (match_dup 4)))
22121 (use (match_dup 5))]
22122 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
22123 && ix86_check_no_addr_space (insn)"
22124 "%^rep{%;} movs{l|d}"
22125 [(set_attr "type" "str")
22126 (set_attr "prefix_rep" "1")
22127 (set_attr "memory" "both")
22128 (set_attr "mode" "SI")])
22130 (define_insn "*rep_movqi"
22131 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
22132 (set (match_operand:P 0 "register_operand" "=D")
22133 (plus:P (match_operand:P 3 "register_operand" "0")
22134 (match_operand:P 5 "register_operand" "2")))
22135 (set (match_operand:P 1 "register_operand" "=S")
22136 (plus:P (match_operand:P 4 "register_operand" "1") (match_dup 5)))
22137 (set (mem:BLK (match_dup 3))
22138 (mem:BLK (match_dup 4)))
22139 (use (match_dup 5))]
22140 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
22141 && ix86_check_no_addr_space (insn)"
22143 [(set_attr "type" "str")
22144 (set_attr "prefix_rep" "1")
22145 (set_attr "memory" "both")
22146 (set_attr "mode" "QI")])
22148 (define_expand "setmem<mode>"
22149 [(use (match_operand:BLK 0 "memory_operand"))
22150 (use (match_operand:SWI48 1 "nonmemory_operand"))
22151 (use (match_operand:QI 2 "nonmemory_operand"))
22152 (use (match_operand 3 "const_int_operand"))
22153 (use (match_operand:SI 4 "const_int_operand"))
22154 (use (match_operand:SI 5 "const_int_operand"))
22155 (use (match_operand:SI 6 ""))
22156 (use (match_operand:SI 7 ""))
22157 (use (match_operand:SI 8 ""))]
22160 if (ix86_expand_set_or_cpymem (operands[0], NULL,
22161 operands[1], operands[2],
22162 operands[3], operands[4],
22163 operands[5], operands[6],
22164 operands[7], operands[8], true))
22170 ;; Most CPUs don't like single string operations
22171 ;; Handle this case here to simplify previous expander.
22173 (define_expand "strset"
22174 [(set (match_operand 1 "memory_operand")
22175 (match_operand 2 "register_operand"))
22176 (parallel [(set (match_operand 0 "register_operand")
22178 (clobber (reg:CC FLAGS_REG))])]
22181 /* Can't use this for non-default address spaces. */
22182 if (!ADDR_SPACE_GENERIC_P (MEM_ADDR_SPACE (operands[1])))
22185 if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
22186 operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
22188 /* If .md ever supports :P for Pmode, this can be directly
22189 in the pattern above. */
22190 operands[3] = plus_constant (Pmode, operands[0],
22191 GET_MODE_SIZE (GET_MODE (operands[2])));
22193 /* Can't use this if the user has appropriated eax or edi. */
22194 if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
22195 && !(fixed_regs[AX_REG] || fixed_regs[DI_REG]))
22197 emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
22203 (define_expand "strset_singleop"
22204 [(parallel [(set (match_operand 1 "memory_operand")
22205 (match_operand 2 "register_operand"))
22206 (set (match_operand 0 "register_operand")
22208 (unspec [(const_int 0)] UNSPEC_STOS)])]
22212 ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
22215 (define_insn "*strsetdi_rex_1"
22216 [(set (mem:DI (match_operand:P 1 "register_operand" "0"))
22217 (match_operand:DI 2 "register_operand" "a"))
22218 (set (match_operand:P 0 "register_operand" "=D")
22219 (plus:P (match_dup 1)
22221 (unspec [(const_int 0)] UNSPEC_STOS)]
22223 && !(fixed_regs[AX_REG] || fixed_regs[DI_REG])
22224 && ix86_check_no_addr_space (insn)"
22226 [(set_attr "type" "str")
22227 (set_attr "memory" "store")
22228 (set_attr "mode" "DI")])
22230 (define_insn "*strsetsi_1"
22231 [(set (mem:SI (match_operand:P 1 "register_operand" "0"))
22232 (match_operand:SI 2 "register_operand" "a"))
22233 (set (match_operand:P 0 "register_operand" "=D")
22234 (plus:P (match_dup 1)
22236 (unspec [(const_int 0)] UNSPEC_STOS)]
22237 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])
22238 && ix86_check_no_addr_space (insn)"
22240 [(set_attr "type" "str")
22241 (set_attr "memory" "store")
22242 (set_attr "mode" "SI")])
22244 (define_insn "*strsethi_1"
22245 [(set (mem:HI (match_operand:P 1 "register_operand" "0"))
22246 (match_operand:HI 2 "register_operand" "a"))
22247 (set (match_operand:P 0 "register_operand" "=D")
22248 (plus:P (match_dup 1)
22250 (unspec [(const_int 0)] UNSPEC_STOS)]
22251 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])
22252 && ix86_check_no_addr_space (insn)"
22254 [(set_attr "type" "str")
22255 (set_attr "memory" "store")
22256 (set_attr "mode" "HI")])
22258 (define_insn "*strsetqi_1"
22259 [(set (mem:QI (match_operand:P 1 "register_operand" "0"))
22260 (match_operand:QI 2 "register_operand" "a"))
22261 (set (match_operand:P 0 "register_operand" "=D")
22262 (plus:P (match_dup 1)
22264 (unspec [(const_int 0)] UNSPEC_STOS)]
22265 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])
22266 && ix86_check_no_addr_space (insn)"
22268 [(set_attr "type" "str")
22269 (set_attr "memory" "store")
22270 (set (attr "prefix_rex")
22272 (match_test "<P:MODE>mode == DImode")
22274 (const_string "*")))
22275 (set_attr "mode" "QI")])
22277 (define_expand "rep_stos"
22278 [(parallel [(set (match_operand 1 "register_operand") (const_int 0))
22279 (set (match_operand 0 "register_operand")
22281 (set (match_operand 2 "memory_operand") (const_int 0))
22282 (use (match_operand 3 "register_operand"))
22283 (use (match_dup 1))])]
22287 ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
22290 (define_insn "*rep_stosdi_rex64"
22291 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
22292 (set (match_operand:P 0 "register_operand" "=D")
22293 (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
22295 (match_operand:P 3 "register_operand" "0")))
22296 (set (mem:BLK (match_dup 3))
22298 (use (match_operand:DI 2 "register_operand" "a"))
22299 (use (match_dup 4))]
22301 && !(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])
22302 && ix86_check_no_addr_space (insn)"
22304 [(set_attr "type" "str")
22305 (set_attr "prefix_rep" "1")
22306 (set_attr "memory" "store")
22307 (set_attr "mode" "DI")])
22309 (define_insn "*rep_stossi"
22310 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
22311 (set (match_operand:P 0 "register_operand" "=D")
22312 (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
22314 (match_operand:P 3 "register_operand" "0")))
22315 (set (mem:BLK (match_dup 3))
22317 (use (match_operand:SI 2 "register_operand" "a"))
22318 (use (match_dup 4))]
22319 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])
22320 && ix86_check_no_addr_space (insn)"
22321 "%^rep{%;} stos{l|d}"
22322 [(set_attr "type" "str")
22323 (set_attr "prefix_rep" "1")
22324 (set_attr "memory" "store")
22325 (set_attr "mode" "SI")])
22327 (define_insn "*rep_stosqi"
22328 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
22329 (set (match_operand:P 0 "register_operand" "=D")
22330 (plus:P (match_operand:P 3 "register_operand" "0")
22331 (match_operand:P 4 "register_operand" "1")))
22332 (set (mem:BLK (match_dup 3))
22334 (use (match_operand:QI 2 "register_operand" "a"))
22335 (use (match_dup 4))]
22336 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])
22337 && ix86_check_no_addr_space (insn)"
22339 [(set_attr "type" "str")
22340 (set_attr "prefix_rep" "1")
22341 (set_attr "memory" "store")
22342 (set (attr "prefix_rex")
22344 (match_test "<P:MODE>mode == DImode")
22346 (const_string "*")))
22347 (set_attr "mode" "QI")])
22349 (define_expand "cmpmemsi"
22350 [(set (match_operand:SI 0 "register_operand" "")
22351 (compare:SI (match_operand:BLK 1 "memory_operand" "")
22352 (match_operand:BLK 2 "memory_operand" "") ) )
22353 (use (match_operand 3 "general_operand"))
22354 (use (match_operand 4 "immediate_operand"))]
22357 if (ix86_expand_cmpstrn_or_cmpmem (operands[0], operands[1],
22358 operands[2], operands[3],
22359 operands[4], false))
22365 (define_expand "cmpstrnsi"
22366 [(set (match_operand:SI 0 "register_operand")
22367 (compare:SI (match_operand:BLK 1 "general_operand")
22368 (match_operand:BLK 2 "general_operand")))
22369 (use (match_operand 3 "general_operand"))
22370 (use (match_operand 4 "immediate_operand"))]
22373 if (ix86_expand_cmpstrn_or_cmpmem (operands[0], operands[1],
22374 operands[2], operands[3],
22375 operands[4], true))
22381 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
22383 (define_expand "cmpintqi"
22384 [(set (match_dup 1)
22385 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
22387 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
22388 (parallel [(set (match_operand:QI 0 "register_operand")
22389 (minus:QI (match_dup 1)
22391 (clobber (reg:CC FLAGS_REG))])]
22394 operands[1] = gen_reg_rtx (QImode);
22395 operands[2] = gen_reg_rtx (QImode);
22398 ;; memcmp recognizers. The `cmpsb' opcode does nothing if the count is
22399 ;; zero. Emit extra code to make sure that a zero-length compare is EQ.
22401 (define_expand "cmpstrnqi_nz_1"
22402 [(parallel [(set (reg:CC FLAGS_REG)
22403 (compare:CC (match_operand 4 "memory_operand")
22404 (match_operand 5 "memory_operand")))
22405 (use (match_operand 2 "register_operand"))
22406 (use (match_operand:SI 3 "immediate_operand"))
22407 (clobber (match_operand 0 "register_operand"))
22408 (clobber (match_operand 1 "register_operand"))
22409 (clobber (match_dup 2))])]
22413 ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
22416 (define_insn "*cmpstrnqi_nz_1"
22417 [(set (reg:CC FLAGS_REG)
22418 (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
22419 (mem:BLK (match_operand:P 5 "register_operand" "1"))))
22420 (use (match_operand:P 6 "register_operand" "2"))
22421 (use (match_operand:SI 3 "immediate_operand" "i"))
22422 (clobber (match_operand:P 0 "register_operand" "=S"))
22423 (clobber (match_operand:P 1 "register_operand" "=D"))
22424 (clobber (match_operand:P 2 "register_operand" "=c"))]
22425 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
22426 && ix86_check_no_addr_space (insn)"
22428 [(set_attr "type" "str")
22429 (set_attr "mode" "QI")
22430 (set (attr "prefix_rex")
22432 (match_test "<P:MODE>mode == DImode")
22434 (const_string "*")))
22435 (set_attr "prefix_rep" "1")])
22437 ;; The same, but the count is not known to not be zero.
22439 (define_expand "cmpstrnqi_1"
22440 [(parallel [(set (reg:CC FLAGS_REG)
22441 (if_then_else:CC (ne (match_operand 2 "register_operand")
22443 (compare:CC (match_operand 4 "memory_operand")
22444 (match_operand 5 "memory_operand"))
22446 (use (match_operand:SI 3 "immediate_operand"))
22447 (use (reg:CC FLAGS_REG))
22448 (clobber (match_operand 0 "register_operand"))
22449 (clobber (match_operand 1 "register_operand"))
22450 (clobber (match_dup 2))])]
22454 ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
22457 (define_insn "*cmpstrnqi_1"
22458 [(set (reg:CC FLAGS_REG)
22459 (if_then_else:CC (ne (match_operand:P 6 "register_operand" "2")
22461 (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
22462 (mem:BLK (match_operand:P 5 "register_operand" "1")))
22464 (use (match_operand:SI 3 "immediate_operand" "i"))
22465 (use (reg:CC FLAGS_REG))
22466 (clobber (match_operand:P 0 "register_operand" "=S"))
22467 (clobber (match_operand:P 1 "register_operand" "=D"))
22468 (clobber (match_operand:P 2 "register_operand" "=c"))]
22469 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
22470 && ix86_check_no_addr_space (insn)"
22472 [(set_attr "type" "str")
22473 (set_attr "mode" "QI")
22474 (set (attr "prefix_rex")
22476 (match_test "<P:MODE>mode == DImode")
22478 (const_string "*")))
22479 (set_attr "prefix_rep" "1")])
22481 (define_expand "strlen<mode>"
22482 [(set (match_operand:P 0 "register_operand")
22483 (unspec:P [(match_operand:BLK 1 "general_operand")
22484 (match_operand:QI 2 "immediate_operand")
22485 (match_operand 3 "immediate_operand")]
22489 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
22495 (define_expand "strlenqi_1"
22496 [(parallel [(set (match_operand 0 "register_operand")
22498 (clobber (match_operand 1 "register_operand"))
22499 (clobber (reg:CC FLAGS_REG))])]
22503 ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
22506 (define_insn "*strlenqi_1"
22507 [(set (match_operand:P 0 "register_operand" "=&c")
22508 (unspec:P [(mem:BLK (match_operand:P 5 "register_operand" "1"))
22509 (match_operand:QI 2 "register_operand" "a")
22510 (match_operand:P 3 "immediate_operand" "i")
22511 (match_operand:P 4 "register_operand" "0")] UNSPEC_SCAS))
22512 (clobber (match_operand:P 1 "register_operand" "=D"))
22513 (clobber (reg:CC FLAGS_REG))]
22514 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])
22515 && ix86_check_no_addr_space (insn)"
22516 "%^repnz{%;} scasb"
22517 [(set_attr "type" "str")
22518 (set_attr "mode" "QI")
22519 (set (attr "prefix_rex")
22521 (match_test "<P:MODE>mode == DImode")
22523 (const_string "*")))
22524 (set_attr "prefix_rep" "1")])
22526 ;; Peephole optimizations to clean up after cmpstrn*. This should be
22527 ;; handled in combine, but it is not currently up to the task.
22528 ;; When used for their truth value, the cmpstrn* expanders generate
22537 ;; The intermediate three instructions are unnecessary.
22539 ;; This one handles cmpstrn*_nz_1...
22542 (set (reg:CC FLAGS_REG)
22543 (compare:CC (mem:BLK (match_operand 4 "register_operand"))
22544 (mem:BLK (match_operand 5 "register_operand"))))
22545 (use (match_operand 6 "register_operand"))
22546 (use (match_operand:SI 3 "immediate_operand"))
22547 (clobber (match_operand 0 "register_operand"))
22548 (clobber (match_operand 1 "register_operand"))
22549 (clobber (match_operand 2 "register_operand"))])
22550 (set (match_operand:QI 7 "register_operand")
22551 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
22552 (set (match_operand:QI 8 "register_operand")
22553 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
22554 (set (reg FLAGS_REG)
22555 (compare (match_dup 7) (match_dup 8)))
22557 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
22559 (set (reg:CC FLAGS_REG)
22560 (compare:CC (mem:BLK (match_dup 4))
22561 (mem:BLK (match_dup 5))))
22562 (use (match_dup 6))
22563 (use (match_dup 3))
22564 (clobber (match_dup 0))
22565 (clobber (match_dup 1))
22566 (clobber (match_dup 2))])])
22568 ;; ...and this one handles cmpstrn*_1.
22571 (set (reg:CC FLAGS_REG)
22572 (if_then_else:CC (ne (match_operand 6 "register_operand")
22574 (compare:CC (mem:BLK (match_operand 4 "register_operand"))
22575 (mem:BLK (match_operand 5 "register_operand")))
22577 (use (match_operand:SI 3 "immediate_operand"))
22578 (use (reg:CC FLAGS_REG))
22579 (clobber (match_operand 0 "register_operand"))
22580 (clobber (match_operand 1 "register_operand"))
22581 (clobber (match_operand 2 "register_operand"))])
22582 (set (match_operand:QI 7 "register_operand")
22583 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
22584 (set (match_operand:QI 8 "register_operand")
22585 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
22586 (set (reg FLAGS_REG)
22587 (compare (match_dup 7) (match_dup 8)))
22589 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
22591 (set (reg:CC FLAGS_REG)
22592 (if_then_else:CC (ne (match_dup 6)
22594 (compare:CC (mem:BLK (match_dup 4))
22595 (mem:BLK (match_dup 5)))
22597 (use (match_dup 3))
22598 (use (reg:CC FLAGS_REG))
22599 (clobber (match_dup 0))
22600 (clobber (match_dup 1))
22601 (clobber (match_dup 2))])])
22603 ;; Conditional move instructions.
22605 (define_expand "mov<mode>cc"
22606 [(set (match_operand:SWIM 0 "register_operand")
22607 (if_then_else:SWIM (match_operand 1 "comparison_operator")
22608 (match_operand:SWIM 2 "<general_operand>")
22609 (match_operand:SWIM 3 "<general_operand>")))]
22611 "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
22613 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
22614 ;; the register first winds up with `sbbl $0,reg', which is also weird.
22615 ;; So just document what we're doing explicitly.
22617 (define_expand "x86_mov<mode>cc_0_m1"
22619 [(set (match_operand:SWI48 0 "register_operand")
22620 (if_then_else:SWI48
22621 (match_operator:SWI48 2 "ix86_carry_flag_operator"
22622 [(match_operand 1 "flags_reg_operand")
22626 (clobber (reg:CC FLAGS_REG))])])
22628 (define_insn "*x86_mov<mode>cc_0_m1"
22629 [(set (match_operand:SWI48 0 "register_operand" "=r")
22630 (if_then_else:SWI48 (match_operator 1 "ix86_carry_flag_operator"
22631 [(reg FLAGS_REG) (const_int 0)])
22634 (clobber (reg:CC FLAGS_REG))]
22636 "sbb{<imodesuffix>}\t%0, %0"
22637 [(set_attr "type" "alu1")
22638 (set_attr "use_carry" "1")
22639 (set_attr "pent_pair" "pu")
22640 (set_attr "mode" "<MODE>")
22641 (set_attr "length_immediate" "0")])
22643 (define_insn "*x86_mov<mode>cc_0_m1_se"
22644 [(set (match_operand:SWI48 0 "register_operand" "=r")
22645 (sign_extract:SWI48 (match_operator 1 "ix86_carry_flag_operator"
22646 [(reg FLAGS_REG) (const_int 0)])
22649 (clobber (reg:CC FLAGS_REG))]
22651 "sbb{<imodesuffix>}\t%0, %0"
22652 [(set_attr "type" "alu1")
22653 (set_attr "use_carry" "1")
22654 (set_attr "pent_pair" "pu")
22655 (set_attr "mode" "<MODE>")
22656 (set_attr "length_immediate" "0")])
22658 (define_insn "*x86_mov<mode>cc_0_m1_neg"
22659 [(set (match_operand:SWI 0 "register_operand" "=<r>")
22660 (neg:SWI (match_operator 1 "ix86_carry_flag_operator"
22661 [(reg FLAGS_REG) (const_int 0)])))
22662 (clobber (reg:CC FLAGS_REG))]
22664 "sbb{<imodesuffix>}\t%0, %0"
22665 [(set_attr "type" "alu1")
22666 (set_attr "use_carry" "1")
22667 (set_attr "pent_pair" "pu")
22668 (set_attr "mode" "<MODE>")
22669 (set_attr "length_immediate" "0")])
22671 (define_expand "x86_mov<mode>cc_0_m1_neg"
22673 [(set (match_operand:SWI48 0 "register_operand")
22674 (neg:SWI48 (ltu:SWI48 (reg:CCC FLAGS_REG) (const_int 0))))
22675 (clobber (reg:CC FLAGS_REG))])])
22678 [(set (match_operand:SWI48 0 "register_operand")
22681 (match_operand 1 "int_nonimmediate_operand")
22682 (match_operand 2 "const_int_operand"))))]
22683 "x86_64_immediate_operand (operands[2], VOIDmode)
22684 && INTVAL (operands[2]) != -1
22685 && INTVAL (operands[2]) != 2147483647"
22686 [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
22688 (neg:SWI48 (ltu:SWI48 (reg:CC FLAGS_REG) (const_int 0))))]
22689 "operands[2] = GEN_INT (INTVAL (operands[2]) + 1);")
22692 [(set (match_operand:SWI 0 "register_operand")
22695 (match_operand 1 "int_nonimmediate_operand")
22698 [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (const_int 1)))
22700 (neg:SWI (ltu:SWI (reg:CC FLAGS_REG) (const_int 0))))])
22703 [(set (match_operand:SWI 0 "register_operand")
22706 (match_operand 1 "int_nonimmediate_operand")
22709 [(set (reg:CCC FLAGS_REG)
22710 (unspec:CCC [(match_dup 1) (const_int 0)] UNSPEC_CC_NE))
22712 (neg:SWI (ltu:SWI (reg:CCC FLAGS_REG) (const_int 0))))])
22714 (define_insn "*mov<mode>cc_noc"
22715 [(set (match_operand:SWI248 0 "register_operand" "=r,r")
22716 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
22717 [(reg FLAGS_REG) (const_int 0)])
22718 (match_operand:SWI248 2 "nonimmediate_operand" "rm,0")
22719 (match_operand:SWI248 3 "nonimmediate_operand" "0,rm")))]
22720 "TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
22722 cmov%O2%C1\t{%2, %0|%0, %2}
22723 cmov%O2%c1\t{%3, %0|%0, %3}"
22724 [(set_attr "type" "icmov")
22725 (set_attr "mode" "<MODE>")])
22727 (define_insn "*movsicc_noc_zext"
22728 [(set (match_operand:DI 0 "register_operand" "=r,r")
22729 (if_then_else:DI (match_operator 1 "ix86_comparison_operator"
22730 [(reg FLAGS_REG) (const_int 0)])
22732 (match_operand:SI 2 "nonimmediate_operand" "rm,0"))
22734 (match_operand:SI 3 "nonimmediate_operand" "0,rm"))))]
22736 && TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
22738 cmov%O2%C1\t{%2, %k0|%k0, %2}
22739 cmov%O2%c1\t{%3, %k0|%k0, %3}"
22740 [(set_attr "type" "icmov")
22741 (set_attr "mode" "SI")])
22743 (define_insn "*movsicc_noc_zext_1"
22744 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r")
22746 (if_then_else:SI (match_operator 1 "ix86_comparison_operator"
22747 [(reg FLAGS_REG) (const_int 0)])
22748 (match_operand:SI 2 "nonimmediate_operand" "rm,0")
22749 (match_operand:SI 3 "nonimmediate_operand" "0,rm"))))]
22751 && TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
22753 cmov%O2%C1\t{%2, %k0|%k0, %2}
22754 cmov%O2%c1\t{%3, %k0|%k0, %3}"
22755 [(set_attr "type" "icmov")
22756 (set_attr "mode" "SI")])
22759 ;; Don't do conditional moves with memory inputs. This splitter helps
22760 ;; register starved x86_32 by forcing inputs into registers before reload.
22762 [(set (match_operand:SWI248 0 "register_operand")
22763 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
22764 [(reg FLAGS_REG) (const_int 0)])
22765 (match_operand:SWI248 2 "nonimmediate_operand")
22766 (match_operand:SWI248 3 "nonimmediate_operand")))]
22767 "!TARGET_64BIT && TARGET_CMOVE
22768 && TARGET_AVOID_MEM_OPND_FOR_CMOVE
22769 && (MEM_P (operands[2]) || MEM_P (operands[3]))
22770 && can_create_pseudo_p ()
22771 && optimize_insn_for_speed_p ()"
22772 [(set (match_dup 0)
22773 (if_then_else:SWI248 (match_dup 1) (match_dup 2) (match_dup 3)))]
22775 operands[2] = force_reg (<MODE>mode, operands[2]);
22776 operands[3] = force_reg (<MODE>mode, operands[3]);
22779 (define_insn "*movqicc_noc"
22780 [(set (match_operand:QI 0 "register_operand" "=r,r")
22781 (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
22782 [(reg FLAGS_REG) (const_int 0)])
22783 (match_operand:QI 2 "register_operand" "r,0")
22784 (match_operand:QI 3 "register_operand" "0,r")))]
22785 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
22787 [(set_attr "type" "icmov")
22788 (set_attr "mode" "QI")])
22791 [(set (match_operand:SWI12 0 "register_operand")
22792 (if_then_else:SWI12 (match_operator 1 "ix86_comparison_operator"
22793 [(reg FLAGS_REG) (const_int 0)])
22794 (match_operand:SWI12 2 "register_operand")
22795 (match_operand:SWI12 3 "register_operand")))]
22796 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL
22797 && reload_completed"
22798 [(set (match_dup 0)
22799 (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
22801 operands[0] = gen_lowpart (SImode, operands[0]);
22802 operands[2] = gen_lowpart (SImode, operands[2]);
22803 operands[3] = gen_lowpart (SImode, operands[3]);
22806 ;; Don't do conditional moves with memory inputs
22808 [(match_scratch:SWI248 4 "r")
22809 (set (match_operand:SWI248 0 "register_operand")
22810 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
22811 [(reg FLAGS_REG) (const_int 0)])
22812 (match_operand:SWI248 2 "nonimmediate_operand")
22813 (match_operand:SWI248 3 "nonimmediate_operand")))]
22814 "TARGET_CMOVE && TARGET_AVOID_MEM_OPND_FOR_CMOVE
22815 && (MEM_P (operands[2]) || MEM_P (operands[3]))
22816 && optimize_insn_for_speed_p ()"
22817 [(set (match_dup 4) (match_dup 5))
22819 (if_then_else:SWI248 (match_dup 1) (match_dup 2) (match_dup 3)))]
22821 if (MEM_P (operands[2]))
22823 operands[5] = operands[2];
22824 operands[2] = operands[4];
22826 else if (MEM_P (operands[3]))
22828 operands[5] = operands[3];
22829 operands[3] = operands[4];
22832 gcc_unreachable ();
22836 [(match_scratch:SI 4 "r")
22837 (set (match_operand:DI 0 "register_operand")
22838 (if_then_else:DI (match_operator 1 "ix86_comparison_operator"
22839 [(reg FLAGS_REG) (const_int 0)])
22841 (match_operand:SI 2 "nonimmediate_operand"))
22843 (match_operand:SI 3 "nonimmediate_operand"))))]
22845 && TARGET_CMOVE && TARGET_AVOID_MEM_OPND_FOR_CMOVE
22846 && (MEM_P (operands[2]) || MEM_P (operands[3]))
22847 && optimize_insn_for_speed_p ()"
22848 [(set (match_dup 4) (match_dup 5))
22850 (if_then_else:DI (match_dup 1)
22851 (zero_extend:DI (match_dup 2))
22852 (zero_extend:DI (match_dup 3))))]
22854 if (MEM_P (operands[2]))
22856 operands[5] = operands[2];
22857 operands[2] = operands[4];
22859 else if (MEM_P (operands[3]))
22861 operands[5] = operands[3];
22862 operands[3] = operands[4];
22865 gcc_unreachable ();
22868 ;; Eliminate a reg-reg mov by inverting the condition of a cmov (#1).
22869 ;; mov r0,r1; dec r0; mov r2,r3; cmov r0,r2 -> dec r1; mov r0,r3; cmov r0, r1
22871 [(set (match_operand:SWI248 0 "general_reg_operand")
22872 (match_operand:SWI248 1 "general_reg_operand"))
22873 (parallel [(set (reg FLAGS_REG) (match_operand 5))
22874 (set (match_dup 0) (match_operand:SWI248 6))])
22875 (set (match_operand:SWI248 2 "general_reg_operand")
22876 (match_operand:SWI248 3 "general_gr_operand"))
22878 (if_then_else:SWI248 (match_operator 4 "ix86_comparison_operator"
22879 [(reg FLAGS_REG) (const_int 0)])
22883 && REGNO (operands[2]) != REGNO (operands[0])
22884 && REGNO (operands[2]) != REGNO (operands[1])
22885 && peep2_reg_dead_p (1, operands[1])
22886 && peep2_reg_dead_p (4, operands[2])
22887 && !reg_overlap_mentioned_p (operands[0], operands[3])"
22888 [(parallel [(set (match_dup 7) (match_dup 8))
22889 (set (match_dup 1) (match_dup 9))])
22890 (set (match_dup 0) (match_dup 3))
22891 (set (match_dup 0) (if_then_else:SWI248 (match_dup 4)
22895 operands[7] = SET_DEST (XVECEXP (PATTERN (peep2_next_insn (1)), 0, 0));
22897 = ix86_replace_reg_with_reg (operands[5], operands[0], operands[1]);
22899 = ix86_replace_reg_with_reg (operands[6], operands[0], operands[1]);
22902 ;; Eliminate a reg-reg mov by inverting the condition of a cmov (#2).
22903 ;; mov r2,r3; mov r0,r1; dec r0; cmov r0,r2 -> dec r1; mov r0,r3; cmov r0, r1
22905 [(set (match_operand:SWI248 2 "general_reg_operand")
22906 (match_operand:SWI248 3 "general_gr_operand"))
22907 (set (match_operand:SWI248 0 "general_reg_operand")
22908 (match_operand:SWI248 1 "general_reg_operand"))
22909 (parallel [(set (reg FLAGS_REG) (match_operand 5))
22910 (set (match_dup 0) (match_operand:SWI248 6))])
22912 (if_then_else:SWI248 (match_operator 4 "ix86_comparison_operator"
22913 [(reg FLAGS_REG) (const_int 0)])
22917 && REGNO (operands[2]) != REGNO (operands[0])
22918 && REGNO (operands[2]) != REGNO (operands[1])
22919 && peep2_reg_dead_p (2, operands[1])
22920 && peep2_reg_dead_p (4, operands[2])
22921 && !reg_overlap_mentioned_p (operands[0], operands[3])
22922 && !reg_mentioned_p (operands[2], operands[6])"
22923 [(parallel [(set (match_dup 7) (match_dup 8))
22924 (set (match_dup 1) (match_dup 9))])
22925 (set (match_dup 0) (match_dup 3))
22926 (set (match_dup 0) (if_then_else:SWI248 (match_dup 4)
22930 operands[7] = SET_DEST (XVECEXP (PATTERN (peep2_next_insn (2)), 0, 0));
22932 = ix86_replace_reg_with_reg (operands[5], operands[0], operands[1]);
22934 = ix86_replace_reg_with_reg (operands[6], operands[0], operands[1]);
22937 (define_insn "movhf_mask"
22938 [(set (match_operand:HF 0 "nonimmediate_operand" "=v,m,v")
22940 [(match_operand:HF 1 "nonimmediate_operand" "m,v,v")
22941 (match_operand:HF 2 "nonimm_or_0_operand" "0C,0C,0C")
22942 (match_operand:QI 3 "register_operand" "Yk,Yk,Yk")]
22943 UNSPEC_MOVCC_MASK))]
22944 "TARGET_AVX512FP16"
22946 vmovsh\t{%1, %0%{%3%}%N2|%0%{%3%}%N2, %1}
22947 vmovsh\t{%1, %0%{%3%}%N2|%0%{%3%}%N2, %1}
22948 vmovsh\t{%d1, %0%{%3%}%N2|%0%{%3%}%N2, %d1}"
22949 [(set_attr "type" "ssemov")
22950 (set_attr "prefix" "evex")
22951 (set_attr "mode" "HF")])
22953 (define_expand "movhfcc"
22954 [(set (match_operand:HF 0 "register_operand")
22956 (match_operand 1 "comparison_operator")
22957 (match_operand:HF 2 "register_operand")
22958 (match_operand:HF 3 "register_operand")))]
22959 "TARGET_AVX512FP16"
22960 "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
22962 (define_expand "mov<mode>cc"
22963 [(set (match_operand:X87MODEF 0 "register_operand")
22964 (if_then_else:X87MODEF
22965 (match_operand 1 "comparison_operator")
22966 (match_operand:X87MODEF 2 "register_operand")
22967 (match_operand:X87MODEF 3 "register_operand")))]
22968 "(TARGET_80387 && TARGET_CMOVE)
22969 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
22970 "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
22972 (define_insn "*movxfcc_1"
22973 [(set (match_operand:XF 0 "register_operand" "=f,f")
22974 (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
22975 [(reg FLAGS_REG) (const_int 0)])
22976 (match_operand:XF 2 "register_operand" "f,0")
22977 (match_operand:XF 3 "register_operand" "0,f")))]
22978 "TARGET_80387 && TARGET_CMOVE"
22980 fcmov%F1\t{%2, %0|%0, %2}
22981 fcmov%f1\t{%3, %0|%0, %3}"
22982 [(set_attr "type" "fcmov")
22983 (set_attr "mode" "XF")])
22985 (define_insn "*movdfcc_1"
22986 [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r,r ,r")
22987 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
22988 [(reg FLAGS_REG) (const_int 0)])
22989 (match_operand:DF 2 "nonimmediate_operand"
22991 (match_operand:DF 3 "nonimmediate_operand"
22992 "0 ,f,0 ,rm,0, rm")))]
22993 "TARGET_80387 && TARGET_CMOVE
22994 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
22996 fcmov%F1\t{%2, %0|%0, %2}
22997 fcmov%f1\t{%3, %0|%0, %3}
23000 cmov%O2%C1\t{%2, %0|%0, %2}
23001 cmov%O2%c1\t{%3, %0|%0, %3}"
23002 [(set_attr "isa" "*,*,nox64,nox64,x64,x64")
23003 (set_attr "type" "fcmov,fcmov,multi,multi,icmov,icmov")
23004 (set_attr "mode" "DF,DF,DI,DI,DI,DI")])
23007 [(set (match_operand:DF 0 "general_reg_operand")
23008 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
23009 [(reg FLAGS_REG) (const_int 0)])
23010 (match_operand:DF 2 "nonimmediate_operand")
23011 (match_operand:DF 3 "nonimmediate_operand")))]
23012 "!TARGET_64BIT && reload_completed"
23013 [(set (match_dup 2)
23014 (if_then_else:SI (match_dup 1) (match_dup 4) (match_dup 5)))
23016 (if_then_else:SI (match_dup 1) (match_dup 6) (match_dup 7)))]
23018 split_double_mode (DImode, &operands[2], 2, &operands[4], &operands[6]);
23019 split_double_mode (DImode, &operands[0], 1, &operands[2], &operands[3]);
23022 (define_insn "*movsfcc_1_387"
23023 [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
23024 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
23025 [(reg FLAGS_REG) (const_int 0)])
23026 (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
23027 (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
23028 "TARGET_80387 && TARGET_CMOVE
23029 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
23031 fcmov%F1\t{%2, %0|%0, %2}
23032 fcmov%f1\t{%3, %0|%0, %3}
23033 cmov%O2%C1\t{%2, %0|%0, %2}
23034 cmov%O2%c1\t{%3, %0|%0, %3}"
23035 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
23036 (set_attr "mode" "SF,SF,SI,SI")])
23038 ;; Don't do conditional moves with memory inputs. This splitter helps
23039 ;; register starved x86_32 by forcing inputs into registers before reload.
23041 [(set (match_operand:MODEF 0 "register_operand")
23042 (if_then_else:MODEF (match_operator 1 "ix86_comparison_operator"
23043 [(reg FLAGS_REG) (const_int 0)])
23044 (match_operand:MODEF 2 "nonimmediate_operand")
23045 (match_operand:MODEF 3 "nonimmediate_operand")))]
23046 "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
23047 && TARGET_AVOID_MEM_OPND_FOR_CMOVE
23048 && (MEM_P (operands[2]) || MEM_P (operands[3]))
23049 && can_create_pseudo_p ()
23050 && optimize_insn_for_speed_p ()"
23051 [(set (match_dup 0)
23052 (if_then_else:MODEF (match_dup 1) (match_dup 2) (match_dup 3)))]
23054 operands[2] = force_reg (<MODE>mode, operands[2]);
23055 operands[3] = force_reg (<MODE>mode, operands[3]);
23058 ;; Don't do conditional moves with memory inputs
23060 [(match_scratch:MODEF 4 "r")
23061 (set (match_operand:MODEF 0 "general_reg_operand")
23062 (if_then_else:MODEF (match_operator 1 "fcmov_comparison_operator"
23063 [(reg FLAGS_REG) (const_int 0)])
23064 (match_operand:MODEF 2 "nonimmediate_operand")
23065 (match_operand:MODEF 3 "nonimmediate_operand")))]
23066 "(<MODE>mode != DFmode || TARGET_64BIT)
23067 && TARGET_80387 && TARGET_CMOVE
23068 && TARGET_AVOID_MEM_OPND_FOR_CMOVE
23069 && (MEM_P (operands[2]) || MEM_P (operands[3]))
23070 && optimize_insn_for_speed_p ()"
23071 [(set (match_dup 4) (match_dup 5))
23073 (if_then_else:MODEF (match_dup 1) (match_dup 2) (match_dup 3)))]
23075 if (MEM_P (operands[2]))
23077 operands[5] = operands[2];
23078 operands[2] = operands[4];
23080 else if (MEM_P (operands[3]))
23082 operands[5] = operands[3];
23083 operands[3] = operands[4];
23086 gcc_unreachable ();
23089 ;; All moves in XOP pcmov instructions are 128 bits and hence we restrict
23090 ;; the scalar versions to have only XMM registers as operands.
23092 ;; XOP conditional move
23093 (define_insn "*xop_pcmov_<mode>"
23094 [(set (match_operand:MODEF 0 "register_operand" "=x")
23095 (if_then_else:MODEF
23096 (match_operand:MODEF 1 "register_operand" "x")
23097 (match_operand:MODEF 2 "register_operand" "x")
23098 (match_operand:MODEF 3 "register_operand" "x")))]
23100 "vpcmov\t{%1, %3, %2, %0|%0, %2, %3, %1}"
23101 [(set_attr "type" "sse4arg")])
23103 ;; These versions of the min/max patterns are intentionally ignorant of
23104 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
23105 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
23106 ;; are undefined in this condition, we're certain this is correct.
23108 (define_insn "<code><mode>3"
23109 [(set (match_operand:MODEF 0 "register_operand" "=x,v")
23111 (match_operand:MODEF 1 "nonimmediate_operand" "%0,v")
23112 (match_operand:MODEF 2 "nonimmediate_operand" "xm,vm")))]
23113 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
23115 <maxmin_float><ssemodesuffix>\t{%2, %0|%0, %2}
23116 v<maxmin_float><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
23117 [(set_attr "isa" "noavx,avx")
23118 (set_attr "prefix" "orig,vex")
23119 (set_attr "type" "sseadd")
23120 (set_attr "mode" "<MODE>")])
23122 (define_insn "<code>hf3"
23123 [(set (match_operand:HF 0 "register_operand" "=v")
23125 (match_operand:HF 1 "nonimmediate_operand" "%v")
23126 (match_operand:HF 2 "nonimmediate_operand" "vm")))]
23127 "TARGET_AVX512FP16"
23128 "v<maxmin_float>sh\t{%2, %1, %0|%0, %1, %2}"
23129 [(set_attr "prefix" "evex")
23130 (set_attr "type" "sseadd")
23131 (set_attr "mode" "HF")])
23133 ;; These versions of the min/max patterns implement exactly the operations
23134 ;; min = (op1 < op2 ? op1 : op2)
23135 ;; max = (!(op1 < op2) ? op1 : op2)
23136 ;; Their operands are not commutative, and thus they may be used in the
23137 ;; presence of -0.0 and NaN.
23139 (define_insn "*ieee_s<ieee_maxmin>hf3"
23140 [(set (match_operand:HF 0 "register_operand" "=v")
23142 [(match_operand:HF 1 "register_operand" "v")
23143 (match_operand:HF 2 "nonimmediate_operand" "vm")]
23145 "TARGET_AVX512FP16"
23146 "v<ieee_maxmin>sh\t{%2, %1, %0|%0, %1, %2}"
23147 [(set_attr "prefix" "evex")
23148 (set_attr "type" "sseadd")
23149 (set_attr "mode" "HF")])
23151 (define_insn "*ieee_s<ieee_maxmin><mode>3"
23152 [(set (match_operand:MODEF 0 "register_operand" "=x,v")
23154 [(match_operand:MODEF 1 "register_operand" "0,v")
23155 (match_operand:MODEF 2 "nonimmediate_operand" "xm,vm")]
23157 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
23159 <ieee_maxmin><ssemodesuffix>\t{%2, %0|%0, %2}
23160 v<ieee_maxmin><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
23161 [(set_attr "isa" "noavx,avx")
23162 (set_attr "prefix" "orig,maybe_evex")
23163 (set_attr "type" "sseadd")
23164 (set_attr "mode" "<MODE>")])
23166 ;; Operands order in min/max instruction matters for signed zero and NANs.
23167 (define_insn_and_split "*ieee_max<mode>3_1"
23168 [(set (match_operand:MODEF 0 "register_operand")
23170 [(match_operand:MODEF 1 "register_operand")
23171 (match_operand:MODEF 2 "register_operand")
23173 (match_operand:MODEF 3 "register_operand")
23174 (match_operand:MODEF 4 "register_operand"))]
23176 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
23177 && (rtx_equal_p (operands[1], operands[3])
23178 && rtx_equal_p (operands[2], operands[4]))
23179 && ix86_pre_reload_split ()"
23182 [(set (match_dup 0)
23186 UNSPEC_IEEE_MAX))])
23188 (define_insn_and_split "*ieee_min<mode>3_1"
23189 [(set (match_operand:MODEF 0 "register_operand")
23191 [(match_operand:MODEF 1 "register_operand")
23192 (match_operand:MODEF 2 "register_operand")
23194 (match_operand:MODEF 3 "register_operand")
23195 (match_operand:MODEF 4 "register_operand"))]
23197 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
23198 && (rtx_equal_p (operands[1], operands[4])
23199 && rtx_equal_p (operands[2], operands[3]))
23200 && ix86_pre_reload_split ()"
23203 [(set (match_dup 0)
23207 UNSPEC_IEEE_MIN))])
23209 ;; Make two stack loads independent:
23211 ;; fld %st(0) -> fld bb
23212 ;; fmul bb fmul %st(1), %st
23214 ;; Actually we only match the last two instructions for simplicity.
23217 [(set (match_operand 0 "fp_register_operand")
23218 (match_operand 1 "fp_register_operand"))
23220 (match_operator 2 "binary_fp_operator"
23222 (match_operand 3 "memory_operand")]))]
23223 "REGNO (operands[0]) != REGNO (operands[1])"
23224 [(set (match_dup 0) (match_dup 3))
23227 [(match_dup 5) (match_dup 4)]))]
23229 operands[4] = operands[0];
23230 operands[5] = operands[1];
23232 /* The % modifier is not operational anymore in peephole2's, so we have to
23233 swap the operands manually in the case of addition and multiplication. */
23234 if (COMMUTATIVE_ARITH_P (operands[2]))
23235 std::swap (operands[4], operands[5]);
23239 [(set (match_operand 0 "fp_register_operand")
23240 (match_operand 1 "fp_register_operand"))
23242 (match_operator 2 "binary_fp_operator"
23243 [(match_operand 3 "memory_operand")
23245 "REGNO (operands[0]) != REGNO (operands[1])"
23246 [(set (match_dup 0) (match_dup 3))
23249 [(match_dup 4) (match_dup 5)]))]
23251 operands[4] = operands[0];
23252 operands[5] = operands[1];
23254 /* The % modifier is not operational anymore in peephole2's, so we have to
23255 swap the operands manually in the case of addition and multiplication. */
23256 if (COMMUTATIVE_ARITH_P (operands[2]))
23257 std::swap (operands[4], operands[5]);
23260 ;; Conditional addition patterns
23261 (define_expand "add<mode>cc"
23262 [(match_operand:SWI 0 "register_operand")
23263 (match_operand 1 "ordered_comparison_operator")
23264 (match_operand:SWI 2 "register_operand")
23265 (match_operand:SWI 3 "const_int_operand")]
23267 "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
23269 ;; min/max patterns
23271 (define_code_attr maxmin_rel
23272 [(smax "GE") (smin "LE") (umax "GEU") (umin "LEU")])
23274 (define_expand "<code><mode>3"
23276 [(set (match_operand:SDWIM 0 "register_operand")
23278 (match_operand:SDWIM 1 "register_operand")
23279 (match_operand:SDWIM 2 "general_operand")))
23280 (clobber (reg:CC FLAGS_REG))])]
23282 && (<MODE>mode != QImode || !TARGET_PARTIAL_REG_STALL)")
23284 (define_insn_and_split "*<code><dwi>3_doubleword"
23285 [(set (match_operand:<DWI> 0 "register_operand")
23287 (match_operand:<DWI> 1 "register_operand")
23288 (match_operand:<DWI> 2 "general_operand")))
23289 (clobber (reg:CC FLAGS_REG))]
23291 && ix86_pre_reload_split ()"
23294 [(set (match_dup 0)
23295 (if_then_else:DWIH (match_dup 6)
23299 (if_then_else:DWIH (match_dup 6)
23303 operands[2] = force_reg (<DWI>mode, operands[2]);
23305 split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
23307 rtx cmplo[2] = { operands[1], operands[2] };
23308 rtx cmphi[2] = { operands[4], operands[5] };
23310 enum rtx_code code = <maxmin_rel>;
23315 std::swap (cmplo[0], cmplo[1]);
23316 std::swap (cmphi[0], cmphi[1]);
23317 code = swap_condition (code);
23322 bool uns = (code == GEU);
23323 rtx (*sbb_insn) (machine_mode, rtx, rtx, rtx)
23324 = uns ? gen_sub3_carry_ccc : gen_sub3_carry_ccgz;
23326 emit_insn (gen_cmp_1 (<MODE>mode, cmplo[0], cmplo[1]));
23328 rtx tmp = gen_rtx_SCRATCH (<MODE>mode);
23329 emit_insn (sbb_insn (<MODE>mode, tmp, cmphi[0], cmphi[1]));
23331 rtx flags = gen_rtx_REG (uns ? CCCmode : CCGZmode, FLAGS_REG);
23332 operands[6] = gen_rtx_fmt_ee (code, VOIDmode, flags, const0_rtx);
23338 gcc_unreachable ();
23342 (define_insn_and_split "*<code><mode>3_1"
23343 [(set (match_operand:SWI 0 "register_operand")
23345 (match_operand:SWI 1 "register_operand")
23346 (match_operand:SWI 2 "general_operand")))
23347 (clobber (reg:CC FLAGS_REG))]
23349 && (<MODE>mode != QImode || !TARGET_PARTIAL_REG_STALL)
23350 && ix86_pre_reload_split ()"
23353 [(set (match_dup 0)
23354 (if_then_else:SWI (match_dup 3)
23358 machine_mode mode = <MODE>mode;
23359 rtx cmp_op = operands[2];
23361 operands[2] = force_reg (mode, cmp_op);
23363 enum rtx_code code = <maxmin_rel>;
23365 if (cmp_op == const1_rtx)
23367 /* Convert smax (x, 1) into (x > 0 ? x : 1).
23368 Convert umax (x, 1) into (x != 0 ? x : 1).
23369 Convert ?min (x, 1) into (x <= 0 ? x : 1). */
23370 cmp_op = const0_rtx;
23373 else if (code == GEU)
23376 /* Convert smin (x, -1) into (x < 0 ? x : -1). */
23377 else if (cmp_op == constm1_rtx && code == LE)
23379 cmp_op = const0_rtx;
23382 /* Convert smax (x, -1) into (x >= 0 ? x : -1). */
23383 else if (cmp_op == constm1_rtx && code == GE)
23384 cmp_op = const0_rtx;
23385 else if (cmp_op != const0_rtx)
23386 cmp_op = operands[2];
23388 machine_mode cmpmode = SELECT_CC_MODE (code, operands[1], cmp_op);
23389 rtx flags = gen_rtx_REG (cmpmode, FLAGS_REG);
23391 rtx tmp = gen_rtx_COMPARE (cmpmode, operands[1], cmp_op);
23392 emit_insn (gen_rtx_SET (flags, tmp));
23394 operands[3] = gen_rtx_fmt_ee (code, VOIDmode, flags, const0_rtx);
23397 ;; Avoid clearing a register between a flags setting comparison and its use,
23398 ;; i.e. prefer "xorl %eax,%eax; test/cmp" over "test/cmp; movl $0, %eax".
23400 [(set (reg FLAGS_REG) (match_operand 0))
23401 (set (match_operand:SWI 1 "general_reg_operand") (const_int 0))]
23402 "peep2_regno_dead_p (0, FLAGS_REG)
23403 && !reg_overlap_mentioned_p (operands[1], operands[0])"
23404 [(set (match_dup 2) (match_dup 0))]
23406 operands[2] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
23407 ix86_expand_clear (operands[1]);
23410 ;; When optimizing for size, zeroing memory should use a register.
23412 [(match_scratch:SWI48 0 "r")
23413 (set (match_operand:SWI48 1 "memory_operand") (const_int 0))
23414 (set (match_operand:SWI48 2 "memory_operand") (const_int 0))
23415 (set (match_operand:SWI48 3 "memory_operand") (const_int 0))
23416 (set (match_operand:SWI48 4 "memory_operand") (const_int 0))]
23417 "optimize_insn_for_size_p () && peep2_regno_dead_p (0, FLAGS_REG)"
23420 ix86_expand_clear (operands[0]);
23421 emit_move_insn (operands[1], operands[0]);
23422 emit_move_insn (operands[2], operands[0]);
23423 emit_move_insn (operands[3], operands[0]);
23424 ix86_last_zero_store_uid
23425 = INSN_UID (emit_move_insn (operands[4], operands[0]));
23430 [(match_scratch:SWI48 0 "r")
23431 (set (match_operand:SWI48 1 "memory_operand") (const_int 0))
23432 (set (match_operand:SWI48 2 "memory_operand") (const_int 0))]
23433 "optimize_insn_for_size_p () && peep2_regno_dead_p (0, FLAGS_REG)"
23436 ix86_expand_clear (operands[0]);
23437 emit_move_insn (operands[1], operands[0]);
23438 ix86_last_zero_store_uid
23439 = INSN_UID (emit_move_insn (operands[2], operands[0]));
23444 [(match_scratch:SWI48 0 "r")
23445 (set (match_operand:SWI48 1 "memory_operand") (const_int 0))]
23446 "optimize_insn_for_size_p () && peep2_regno_dead_p (0, FLAGS_REG)"
23449 ix86_expand_clear (operands[0]);
23450 ix86_last_zero_store_uid
23451 = INSN_UID (emit_move_insn (operands[1], operands[0]));
23456 [(set (match_operand:SWI48 5 "memory_operand")
23457 (match_operand:SWI48 0 "general_reg_operand"))
23458 (set (match_operand:SWI48 1 "memory_operand") (const_int 0))
23459 (set (match_operand:SWI48 2 "memory_operand") (const_int 0))
23460 (set (match_operand:SWI48 3 "memory_operand") (const_int 0))
23461 (set (match_operand:SWI48 4 "memory_operand") (const_int 0))]
23462 "optimize_insn_for_size_p ()
23463 && INSN_UID (peep2_next_insn (0)) == ix86_last_zero_store_uid"
23466 emit_move_insn (operands[5], operands[0]);
23467 emit_move_insn (operands[1], operands[0]);
23468 emit_move_insn (operands[2], operands[0]);
23469 emit_move_insn (operands[3], operands[0]);
23470 ix86_last_zero_store_uid
23471 = INSN_UID (emit_move_insn (operands[4], operands[0]));
23476 [(set (match_operand:SWI48 3 "memory_operand")
23477 (match_operand:SWI48 0 "general_reg_operand"))
23478 (set (match_operand:SWI48 1 "memory_operand") (const_int 0))
23479 (set (match_operand:SWI48 2 "memory_operand") (const_int 0))]
23480 "optimize_insn_for_size_p ()
23481 && INSN_UID (peep2_next_insn (0)) == ix86_last_zero_store_uid"
23484 emit_move_insn (operands[3], operands[0]);
23485 emit_move_insn (operands[1], operands[0]);
23486 ix86_last_zero_store_uid
23487 = INSN_UID (emit_move_insn (operands[2], operands[0]));
23492 [(set (match_operand:SWI48 2 "memory_operand")
23493 (match_operand:SWI48 0 "general_reg_operand"))
23494 (set (match_operand:SWI48 1 "memory_operand") (const_int 0))]
23495 "optimize_insn_for_size_p ()
23496 && INSN_UID (peep2_next_insn (0)) == ix86_last_zero_store_uid"
23499 emit_move_insn (operands[2], operands[0]);
23500 ix86_last_zero_store_uid
23501 = INSN_UID (emit_move_insn (operands[1], operands[0]));
23505 ;; Reload dislikes loading constants directly into class_likely_spilled
23506 ;; hard registers. Try to tidy things up here.
23508 [(set (match_operand:SWI 0 "general_reg_operand")
23509 (match_operand:SWI 1 "x86_64_general_operand"))
23510 (set (match_operand:SWI 2 "general_reg_operand")
23512 "peep2_reg_dead_p (2, operands[0])"
23513 [(set (match_dup 2) (match_dup 1))])
23515 ;; Misc patterns (?)
23517 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
23518 ;; Otherwise there will be nothing to keep
23520 ;; [(set (reg ebp) (reg esp))]
23521 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
23522 ;; (clobber (eflags)]
23523 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
23525 ;; in proper program order.
23527 (define_insn "@pro_epilogue_adjust_stack_add_<mode>"
23528 [(set (match_operand:P 0 "register_operand" "=r,r")
23529 (plus:P (match_operand:P 1 "register_operand" "0,r")
23530 (match_operand:P 2 "<nonmemory_operand>" "r<i>,l<i>")))
23531 (clobber (reg:CC FLAGS_REG))
23532 (clobber (mem:BLK (scratch)))]
23535 switch (get_attr_type (insn))
23538 return "mov{<imodesuffix>}\t{%1, %0|%0, %1}";
23541 gcc_assert (rtx_equal_p (operands[0], operands[1]));
23542 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
23543 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
23545 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
23548 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
23549 return "lea{<imodesuffix>}\t{%E2, %0|%0, %E2}";
23552 [(set (attr "type")
23553 (cond [(and (eq_attr "alternative" "0")
23554 (not (match_test "TARGET_OPT_AGU")))
23555 (const_string "alu")
23556 (match_operand:<MODE> 2 "const0_operand")
23557 (const_string "imov")
23559 (const_string "lea")))
23560 (set (attr "length_immediate")
23561 (cond [(eq_attr "type" "imov")
23563 (and (eq_attr "type" "alu")
23564 (match_operand 2 "const128_operand"))
23567 (const_string "*")))
23568 (set_attr "mode" "<MODE>")])
23570 (define_insn "@pro_epilogue_adjust_stack_sub_<mode>"
23571 [(set (match_operand:P 0 "register_operand" "=r")
23572 (minus:P (match_operand:P 1 "register_operand" "0")
23573 (match_operand:P 2 "register_operand" "r")))
23574 (clobber (reg:CC FLAGS_REG))
23575 (clobber (mem:BLK (scratch)))]
23577 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
23578 [(set_attr "type" "alu")
23579 (set_attr "mode" "<MODE>")])
23581 (define_insn "@allocate_stack_worker_probe_<mode>"
23582 [(set (match_operand:P 0 "register_operand" "=a")
23583 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
23584 UNSPECV_STACK_PROBE))
23585 (clobber (reg:CC FLAGS_REG))]
23586 "ix86_target_stack_probe ()"
23587 "call\t___chkstk_ms"
23588 [(set_attr "type" "multi")
23589 (set_attr "length" "5")])
23591 (define_expand "allocate_stack"
23592 [(match_operand 0 "register_operand")
23593 (match_operand 1 "general_operand")]
23594 "ix86_target_stack_probe ()"
23598 #ifndef CHECK_STACK_LIMIT
23599 #define CHECK_STACK_LIMIT 0
23602 if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
23603 && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
23607 x = copy_to_mode_reg (Pmode, operands[1]);
23609 emit_insn (gen_allocate_stack_worker_probe (Pmode, x, x));
23612 x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, x,
23613 stack_pointer_rtx, 0, OPTAB_DIRECT);
23615 if (x != stack_pointer_rtx)
23616 emit_move_insn (stack_pointer_rtx, x);
23618 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
23622 (define_expand "probe_stack"
23623 [(match_operand 0 "memory_operand")]
23626 emit_insn (gen_probe_stack_1
23627 (word_mode, operands[0], const0_rtx));
23631 ;; Use OR for stack probes, this is shorter.
23632 (define_insn "@probe_stack_1_<mode>"
23633 [(set (match_operand:W 0 "memory_operand" "=m")
23634 (unspec:W [(match_operand:W 1 "const0_operand")]
23635 UNSPEC_PROBE_STACK))
23636 (clobber (reg:CC FLAGS_REG))]
23638 "or{<imodesuffix>}\t{%1, %0|%0, %1}"
23639 [(set_attr "type" "alu1")
23640 (set_attr "mode" "<MODE>")
23641 (set_attr "length_immediate" "1")])
23643 (define_insn "@adjust_stack_and_probe_<mode>"
23644 [(set (match_operand:P 0 "register_operand" "=r")
23645 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
23646 UNSPECV_PROBE_STACK_RANGE))
23647 (set (reg:P SP_REG)
23648 (minus:P (reg:P SP_REG) (match_operand:P 2 "const_int_operand")))
23649 (clobber (reg:CC FLAGS_REG))
23650 (clobber (mem:BLK (scratch)))]
23652 "* return output_adjust_stack_and_probe (operands[0]);"
23653 [(set_attr "type" "multi")])
23655 (define_insn "@probe_stack_range_<mode>"
23656 [(set (match_operand:P 0 "register_operand" "=r")
23657 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
23658 (match_operand:P 2 "const_int_operand")]
23659 UNSPECV_PROBE_STACK_RANGE))
23660 (clobber (reg:CC FLAGS_REG))]
23662 "* return output_probe_stack_range (operands[0], operands[2]);"
23663 [(set_attr "type" "multi")])
23665 (define_expand "builtin_setjmp_receiver"
23666 [(label_ref (match_operand 0))]
23667 "!TARGET_64BIT && flag_pic"
23673 rtx_code_label *label_rtx = gen_label_rtx ();
23674 emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
23675 xops[0] = xops[1] = pic_offset_table_rtx;
23676 xops[2] = machopic_gen_offset (gen_rtx_LABEL_REF (SImode, label_rtx));
23677 ix86_expand_binary_operator (MINUS, SImode, xops);
23681 emit_insn (gen_set_got (pic_offset_table_rtx));
23685 (define_expand "save_stack_nonlocal"
23686 [(set (match_operand 0 "memory_operand")
23687 (match_operand 1 "register_operand"))]
23692 if (flag_cf_protection & CF_RETURN)
23694 /* Copy shadow stack pointer to the first slot
23695 and stack pointer to the second slot. */
23696 rtx ssp_slot = adjust_address (operands[0], word_mode, 0);
23697 stack_slot = adjust_address (operands[0], Pmode, UNITS_PER_WORD);
23699 rtx reg_ssp = force_reg (word_mode, const0_rtx);
23700 emit_insn (gen_rdssp (word_mode, reg_ssp, reg_ssp));
23701 emit_move_insn (ssp_slot, reg_ssp);
23704 stack_slot = adjust_address (operands[0], Pmode, 0);
23705 emit_move_insn (stack_slot, operands[1]);
23709 (define_expand "restore_stack_nonlocal"
23710 [(set (match_operand 0 "register_operand" "")
23711 (match_operand 1 "memory_operand" ""))]
23716 if (flag_cf_protection & CF_RETURN)
23718 /* Restore shadow stack pointer from the first slot
23719 and stack pointer from the second slot. */
23720 rtx ssp_slot = adjust_address (operands[1], word_mode, 0);
23721 stack_slot = adjust_address (operands[1], Pmode, UNITS_PER_WORD);
23723 /* Get the current shadow stack pointer. The code below will check if
23724 SHSTK feature is enabled. If it is not enabled the RDSSP instruction
23726 rtx reg_ssp = force_reg (word_mode, const0_rtx);
23727 emit_insn (gen_rdssp (word_mode, reg_ssp, reg_ssp));
23729 /* Compare through subtraction the saved and the current ssp
23730 to decide if ssp has to be adjusted. */
23731 reg_ssp = expand_simple_binop (word_mode, MINUS,
23733 reg_ssp, 1, OPTAB_DIRECT);
23735 /* Compare and jump over adjustment code. */
23736 rtx noadj_label = gen_label_rtx ();
23737 emit_cmp_and_jump_insns (reg_ssp, const0_rtx, EQ, NULL_RTX,
23738 word_mode, 1, noadj_label);
23740 /* Compute the number of frames to adjust. */
23741 rtx reg_adj = gen_lowpart (ptr_mode, reg_ssp);
23742 rtx reg_adj_neg = expand_simple_unop (ptr_mode, NEG, reg_adj,
23745 reg_adj = expand_simple_binop (ptr_mode, LSHIFTRT, reg_adj_neg,
23746 GEN_INT (exact_log2 (UNITS_PER_WORD)),
23747 reg_adj, 1, OPTAB_DIRECT);
23749 /* Check if number of frames <= 255 so no loop is needed. */
23750 rtx inc_label = gen_label_rtx ();
23751 emit_cmp_and_jump_insns (reg_adj, GEN_INT (255), LEU, NULL_RTX,
23752 ptr_mode, 1, inc_label);
23754 /* Adjust the ssp in a loop. */
23755 rtx loop_label = gen_label_rtx ();
23756 emit_label (loop_label);
23757 LABEL_NUSES (loop_label) = 1;
23759 rtx reg_255 = force_reg (word_mode, GEN_INT (255));
23760 emit_insn (gen_incssp (word_mode, reg_255));
23762 reg_adj = expand_simple_binop (ptr_mode, MINUS,
23763 reg_adj, GEN_INT (255),
23764 reg_adj, 1, OPTAB_DIRECT);
23766 /* Compare and jump to the loop label. */
23767 emit_cmp_and_jump_insns (reg_adj, GEN_INT (255), GTU, NULL_RTX,
23768 ptr_mode, 1, loop_label);
23770 emit_label (inc_label);
23771 LABEL_NUSES (inc_label) = 1;
23773 emit_insn (gen_incssp (word_mode, reg_ssp));
23775 emit_label (noadj_label);
23776 LABEL_NUSES (noadj_label) = 1;
23779 stack_slot = adjust_address (operands[1], Pmode, 0);
23780 emit_move_insn (operands[0], stack_slot);
23785 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
23786 ;; Do not split instructions with mask registers.
23788 [(set (match_operand 0 "general_reg_operand")
23789 (match_operator 3 "promotable_binary_operator"
23790 [(match_operand 1 "general_reg_operand")
23791 (match_operand 2 "aligned_operand")]))
23792 (clobber (reg:CC FLAGS_REG))]
23793 "! TARGET_PARTIAL_REG_STALL && reload_completed
23794 && ((GET_MODE (operands[0]) == HImode
23795 && ((optimize_function_for_speed_p (cfun) && !TARGET_FAST_PREFIX)
23796 /* ??? next two lines just !satisfies_constraint_K (...) */
23797 || !CONST_INT_P (operands[2])
23798 || satisfies_constraint_K (operands[2])))
23799 || (GET_MODE (operands[0]) == QImode
23800 && (TARGET_PROMOTE_QImode || optimize_function_for_size_p (cfun))))"
23801 [(parallel [(set (match_dup 0)
23802 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
23803 (clobber (reg:CC FLAGS_REG))])]
23805 operands[0] = gen_lowpart (SImode, operands[0]);
23806 operands[1] = gen_lowpart (SImode, operands[1]);
23807 if (GET_CODE (operands[3]) != ASHIFT)
23808 operands[2] = gen_lowpart (SImode, operands[2]);
23809 operands[3] = shallow_copy_rtx (operands[3]);
23810 PUT_MODE (operands[3], SImode);
23813 ; Promote the QImode tests, as i386 has encoding of the AND
23814 ; instruction with 32-bit sign-extended immediate and thus the
23815 ; instruction size is unchanged, except in the %eax case for
23816 ; which it is increased by one byte, hence the ! optimize_size.
23818 [(set (match_operand 0 "flags_reg_operand")
23819 (match_operator 2 "compare_operator"
23820 [(and (match_operand 3 "aligned_operand")
23821 (match_operand 4 "const_int_operand"))
23823 (set (match_operand 1 "register_operand")
23824 (and (match_dup 3) (match_dup 4)))]
23825 "! TARGET_PARTIAL_REG_STALL && reload_completed
23826 && optimize_insn_for_speed_p ()
23827 && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
23828 || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))
23829 /* Ensure that the operand will remain sign-extended immediate. */
23830 && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)"
23831 [(parallel [(set (match_dup 0)
23832 (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
23835 (and:SI (match_dup 3) (match_dup 4)))])]
23838 = gen_int_mode (INTVAL (operands[4])
23839 & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
23840 operands[1] = gen_lowpart (SImode, operands[1]);
23841 operands[3] = gen_lowpart (SImode, operands[3]);
23844 ; Don't promote the QImode tests, as i386 doesn't have encoding of
23845 ; the TEST instruction with 32-bit sign-extended immediate and thus
23846 ; the instruction size would at least double, which is not what we
23847 ; want even with ! optimize_size.
23849 [(set (match_operand 0 "flags_reg_operand")
23850 (match_operator 1 "compare_operator"
23851 [(and (match_operand:HI 2 "aligned_operand")
23852 (match_operand:HI 3 "const_int_operand"))
23854 "! TARGET_PARTIAL_REG_STALL && reload_completed
23855 && ! TARGET_FAST_PREFIX
23856 && optimize_insn_for_speed_p ()
23857 /* Ensure that the operand will remain sign-extended immediate. */
23858 && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)"
23859 [(set (match_dup 0)
23860 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
23864 = gen_int_mode (INTVAL (operands[3])
23865 & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
23866 operands[2] = gen_lowpart (SImode, operands[2]);
23870 [(set (match_operand 0 "register_operand")
23871 (neg (match_operand 1 "register_operand")))
23872 (clobber (reg:CC FLAGS_REG))]
23873 "! TARGET_PARTIAL_REG_STALL && reload_completed
23874 && (GET_MODE (operands[0]) == HImode
23875 || (GET_MODE (operands[0]) == QImode
23876 && (TARGET_PROMOTE_QImode
23877 || optimize_insn_for_size_p ())))"
23878 [(parallel [(set (match_dup 0)
23879 (neg:SI (match_dup 1)))
23880 (clobber (reg:CC FLAGS_REG))])]
23882 operands[0] = gen_lowpart (SImode, operands[0]);
23883 operands[1] = gen_lowpart (SImode, operands[1]);
23886 ;; Do not split instructions with mask regs.
23888 [(set (match_operand 0 "general_reg_operand")
23889 (not (match_operand 1 "general_reg_operand")))]
23890 "! TARGET_PARTIAL_REG_STALL && reload_completed
23891 && (GET_MODE (operands[0]) == HImode
23892 || (GET_MODE (operands[0]) == QImode
23893 && (TARGET_PROMOTE_QImode
23894 || optimize_insn_for_size_p ())))"
23895 [(set (match_dup 0)
23896 (not:SI (match_dup 1)))]
23898 operands[0] = gen_lowpart (SImode, operands[0]);
23899 operands[1] = gen_lowpart (SImode, operands[1]);
23902 ;; RTL Peephole optimizations, run before sched2. These primarily look to
23903 ;; transform a complex memory operation into two memory to register operations.
23905 ;; Don't push memory operands
23907 [(set (match_operand:SWI 0 "push_operand")
23908 (match_operand:SWI 1 "memory_operand"))
23909 (match_scratch:SWI 2 "<r>")]
23910 "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
23911 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
23912 [(set (match_dup 2) (match_dup 1))
23913 (set (match_dup 0) (match_dup 2))])
23915 ;; We need to handle SFmode only, because DFmode and XFmode are split to
23918 [(set (match_operand:SF 0 "push_operand")
23919 (match_operand:SF 1 "memory_operand"))
23920 (match_scratch:SF 2 "r")]
23921 "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
23922 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
23923 [(set (match_dup 2) (match_dup 1))
23924 (set (match_dup 0) (match_dup 2))])
23926 ;; Don't move an immediate directly to memory when the instruction
23927 ;; gets too big, or if LCP stalls are a problem for 16-bit moves.
23929 [(match_scratch:SWI124 1 "<r>")
23930 (set (match_operand:SWI124 0 "memory_operand")
23932 "optimize_insn_for_speed_p ()
23933 && ((<MODE>mode == HImode
23934 && TARGET_LCP_STALL)
23935 || (!TARGET_USE_MOV0
23936 && TARGET_SPLIT_LONG_MOVES
23937 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn))
23938 && peep2_regno_dead_p (0, FLAGS_REG)"
23939 [(parallel [(set (match_dup 2) (const_int 0))
23940 (clobber (reg:CC FLAGS_REG))])
23941 (set (match_dup 0) (match_dup 1))]
23942 "operands[2] = gen_lowpart (SImode, operands[1]);")
23945 [(match_scratch:SWI124 2 "<r>")
23946 (set (match_operand:SWI124 0 "memory_operand")
23947 (match_operand:SWI124 1 "immediate_operand"))]
23948 "optimize_insn_for_speed_p ()
23949 && ((<MODE>mode == HImode
23950 && TARGET_LCP_STALL)
23951 || (TARGET_SPLIT_LONG_MOVES
23952 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn))"
23953 [(set (match_dup 2) (match_dup 1))
23954 (set (match_dup 0) (match_dup 2))])
23956 ;; Don't compare memory with zero, load and use a test instead.
23958 [(set (match_operand 0 "flags_reg_operand")
23959 (match_operator 1 "compare_operator"
23960 [(match_operand:SI 2 "memory_operand")
23962 (match_scratch:SI 3 "r")]
23963 "optimize_insn_for_speed_p () && ix86_match_ccmode (insn, CCNOmode)"
23964 [(set (match_dup 3) (match_dup 2))
23965 (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))])
23967 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
23968 ;; Don't split NOTs with a displacement operand, because resulting XOR
23969 ;; will not be pairable anyway.
23971 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
23972 ;; represented using a modRM byte. The XOR replacement is long decoded,
23973 ;; so this split helps here as well.
23975 ;; Note: Can't do this as a regular split because we can't get proper
23976 ;; lifetime information then.
23979 [(set (match_operand:SWI124 0 "nonimmediate_gr_operand")
23980 (not:SWI124 (match_operand:SWI124 1 "nonimmediate_gr_operand")))]
23981 "optimize_insn_for_speed_p ()
23982 && ((TARGET_NOT_UNPAIRABLE
23983 && (!MEM_P (operands[0])
23984 || !memory_displacement_operand (operands[0], <MODE>mode)))
23985 || (TARGET_NOT_VECTORMODE
23986 && long_memory_operand (operands[0], <MODE>mode)))
23987 && peep2_regno_dead_p (0, FLAGS_REG)"
23988 [(parallel [(set (match_dup 0)
23989 (xor:SWI124 (match_dup 1) (const_int -1)))
23990 (clobber (reg:CC FLAGS_REG))])])
23992 ;; Non pairable "test imm, reg" instructions can be translated to
23993 ;; "and imm, reg" if reg dies. The "and" form is also shorter (one
23994 ;; byte opcode instead of two, have a short form for byte operands),
23995 ;; so do it for other CPUs as well. Given that the value was dead,
23996 ;; this should not create any new dependencies. Pass on the sub-word
23997 ;; versions if we're concerned about partial register stalls.
24000 [(set (match_operand 0 "flags_reg_operand")
24001 (match_operator 1 "compare_operator"
24002 [(and:SI (match_operand:SI 2 "register_operand")
24003 (match_operand:SI 3 "immediate_operand"))
24005 "ix86_match_ccmode (insn, CCNOmode)
24006 && (REGNO (operands[2]) != AX_REG
24007 || satisfies_constraint_K (operands[3]))
24008 && peep2_reg_dead_p (1, operands[2])"
24010 [(set (match_dup 0)
24011 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
24014 (and:SI (match_dup 2) (match_dup 3)))])])
24016 ;; We don't need to handle HImode case, because it will be promoted to SImode
24017 ;; on ! TARGET_PARTIAL_REG_STALL
24020 [(set (match_operand 0 "flags_reg_operand")
24021 (match_operator 1 "compare_operator"
24022 [(and:QI (match_operand:QI 2 "register_operand")
24023 (match_operand:QI 3 "immediate_operand"))
24025 "! TARGET_PARTIAL_REG_STALL
24026 && ix86_match_ccmode (insn, CCNOmode)
24027 && REGNO (operands[2]) != AX_REG
24028 && peep2_reg_dead_p (1, operands[2])"
24030 [(set (match_dup 0)
24031 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
24034 (and:QI (match_dup 2) (match_dup 3)))])])
24037 [(set (match_operand 0 "flags_reg_operand")
24038 (match_operator 1 "compare_operator"
24041 (match_operator:SWI248 4 "extract_operator"
24042 [(match_operand 2 "int248_register_operand")
24045 (match_operand 3 "const_int_operand"))
24047 "! TARGET_PARTIAL_REG_STALL
24048 && ix86_match_ccmode (insn, CCNOmode)
24049 && REGNO (operands[2]) != AX_REG
24050 && peep2_reg_dead_p (1, operands[2])"
24052 [(set (match_dup 0)
24056 (match_op_dup 4 [(match_dup 2)
24061 (set (zero_extract:SWI248 (match_dup 2)
24067 (match_op_dup 4 [(match_dup 2)
24070 (match_dup 3)) 0))])])
24072 ;; Don't do logical operations with memory inputs.
24074 [(match_scratch:SWI 2 "<r>")
24075 (parallel [(set (match_operand:SWI 0 "register_operand")
24076 (match_operator:SWI 3 "arith_or_logical_operator"
24078 (match_operand:SWI 1 "memory_operand")]))
24079 (clobber (reg:CC FLAGS_REG))])]
24080 "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
24081 [(set (match_dup 2) (match_dup 1))
24082 (parallel [(set (match_dup 0)
24083 (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
24084 (clobber (reg:CC FLAGS_REG))])])
24087 [(match_scratch:SWI 2 "<r>")
24088 (parallel [(set (match_operand:SWI 0 "register_operand")
24089 (match_operator:SWI 3 "arith_or_logical_operator"
24090 [(match_operand:SWI 1 "memory_operand")
24092 (clobber (reg:CC FLAGS_REG))])]
24093 "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
24094 [(set (match_dup 2) (match_dup 1))
24095 (parallel [(set (match_dup 0)
24096 (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
24097 (clobber (reg:CC FLAGS_REG))])])
24099 ;; Prefer Load+RegOp to Mov+MemOp. Watch out for cases when
24100 ;; the memory address refers to the destination of the load!
24103 [(set (match_operand:SWI 0 "general_reg_operand")
24104 (match_operand:SWI 1 "general_reg_operand"))
24105 (parallel [(set (match_dup 0)
24106 (match_operator:SWI 3 "commutative_operator"
24108 (match_operand:SWI 2 "memory_operand")]))
24109 (clobber (reg:CC FLAGS_REG))])]
24110 "REGNO (operands[0]) != REGNO (operands[1])
24111 && (<MODE>mode != QImode
24112 || any_QIreg_operand (operands[1], QImode))"
24113 [(set (match_dup 0) (match_dup 4))
24114 (parallel [(set (match_dup 0)
24115 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))
24116 (clobber (reg:CC FLAGS_REG))])]
24119 = ix86_replace_reg_with_reg (operands[2], operands[0], operands[1]);
24123 [(set (match_operand 0 "mmx_reg_operand")
24124 (match_operand 1 "mmx_reg_operand"))
24126 (match_operator 3 "commutative_operator"
24128 (match_operand 2 "memory_operand")]))]
24129 "REGNO (operands[0]) != REGNO (operands[1])"
24130 [(set (match_dup 0) (match_dup 2))
24132 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))])
24135 [(set (match_operand 0 "sse_reg_operand")
24136 (match_operand 1 "sse_reg_operand"))
24138 (match_operator 3 "commutative_operator"
24140 (match_operand 2 "memory_operand")]))]
24141 "REGNO (operands[0]) != REGNO (operands[1])
24142 /* Punt if operands[1] is %[xy]mm16+ and AVX512BW is not enabled,
24143 as EVEX encoded vpadd[bw], vpmullw, vpmin[su][bw] and vpmax[su][bw]
24144 instructions require AVX512BW and AVX512VL, but with the original
24145 instructions it might require just AVX512VL.
24146 AVX512VL is implied from TARGET_HARD_REGNO_MODE_OK. */
24147 && (!EXT_REX_SSE_REGNO_P (REGNO (operands[1]))
24149 || GET_MODE_SIZE (GET_MODE_INNER (GET_MODE (operands[0]))) > 2
24150 || logic_operator (operands[3], VOIDmode))"
24151 [(set (match_dup 0) (match_dup 2))
24153 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))])
24155 ; Don't do logical operations with memory outputs
24157 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
24158 ; instruction into two 1-uop insns plus a 2-uop insn. That last has
24159 ; the same decoder scheduling characteristics as the original.
24162 [(match_scratch:SWI 2 "<r>")
24163 (parallel [(set (match_operand:SWI 0 "memory_operand")
24164 (match_operator:SWI 3 "arith_or_logical_operator"
24166 (match_operand:SWI 1 "<nonmemory_operand>")]))
24167 (clobber (reg:CC FLAGS_REG))])]
24168 "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())"
24169 [(set (match_dup 2) (match_dup 0))
24170 (parallel [(set (match_dup 2)
24171 (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
24172 (clobber (reg:CC FLAGS_REG))])
24173 (set (match_dup 0) (match_dup 2))])
24176 [(match_scratch:SWI 2 "<r>")
24177 (parallel [(set (match_operand:SWI 0 "memory_operand")
24178 (match_operator:SWI 3 "arith_or_logical_operator"
24179 [(match_operand:SWI 1 "<nonmemory_operand>")
24181 (clobber (reg:CC FLAGS_REG))])]
24182 "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())"
24183 [(set (match_dup 2) (match_dup 0))
24184 (parallel [(set (match_dup 2)
24185 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
24186 (clobber (reg:CC FLAGS_REG))])
24187 (set (match_dup 0) (match_dup 2))])
24189 ;; Attempt to use arith or logical operations with memory outputs with
24190 ;; setting of flags.
24192 [(set (match_operand:SWI 0 "register_operand")
24193 (match_operand:SWI 1 "memory_operand"))
24194 (parallel [(set (match_dup 0)
24195 (match_operator:SWI 3 "plusminuslogic_operator"
24197 (match_operand:SWI 2 "<nonmemory_operand>")]))
24198 (clobber (reg:CC FLAGS_REG))])
24199 (set (match_dup 1) (match_dup 0))
24200 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
24201 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
24202 && peep2_reg_dead_p (4, operands[0])
24203 && !reg_overlap_mentioned_p (operands[0], operands[1])
24204 && !reg_overlap_mentioned_p (operands[0], operands[2])
24205 && (<MODE>mode != QImode
24206 || immediate_operand (operands[2], QImode)
24207 || any_QIreg_operand (operands[2], QImode))
24208 && ix86_match_ccmode (peep2_next_insn (3),
24209 (GET_CODE (operands[3]) == PLUS
24210 || GET_CODE (operands[3]) == MINUS)
24211 ? CCGOCmode : CCNOmode)"
24212 [(parallel [(set (match_dup 4) (match_dup 6))
24213 (set (match_dup 1) (match_dup 5))])]
24215 operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
24217 = gen_rtx_fmt_ee (GET_CODE (operands[3]), GET_MODE (operands[3]),
24218 copy_rtx (operands[1]),
24221 = gen_rtx_COMPARE (GET_MODE (operands[4]),
24222 copy_rtx (operands[5]),
24226 ;; Likewise for cmpelim optimized pattern.
24228 [(set (match_operand:SWI 0 "register_operand")
24229 (match_operand:SWI 1 "memory_operand"))
24230 (parallel [(set (reg FLAGS_REG)
24231 (compare (match_operator:SWI 3 "plusminuslogic_operator"
24233 (match_operand:SWI 2 "<nonmemory_operand>")])
24235 (set (match_dup 0) (match_dup 3))])
24236 (set (match_dup 1) (match_dup 0))]
24237 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
24238 && peep2_reg_dead_p (3, operands[0])
24239 && !reg_overlap_mentioned_p (operands[0], operands[1])
24240 && !reg_overlap_mentioned_p (operands[0], operands[2])
24241 && ix86_match_ccmode (peep2_next_insn (1),
24242 (GET_CODE (operands[3]) == PLUS
24243 || GET_CODE (operands[3]) == MINUS)
24244 ? CCGOCmode : CCNOmode)"
24245 [(parallel [(set (match_dup 4) (match_dup 6))
24246 (set (match_dup 1) (match_dup 5))])]
24248 operands[4] = SET_DEST (XVECEXP (PATTERN (peep2_next_insn (1)), 0, 0));
24250 = gen_rtx_fmt_ee (GET_CODE (operands[3]), GET_MODE (operands[3]),
24251 copy_rtx (operands[1]), operands[2]);
24253 = gen_rtx_COMPARE (GET_MODE (operands[4]), copy_rtx (operands[5]),
24257 ;; Likewise for instances where we have a lea pattern.
24259 [(set (match_operand:SWI 0 "register_operand")
24260 (match_operand:SWI 1 "memory_operand"))
24261 (set (match_operand:<LEAMODE> 3 "register_operand")
24262 (plus:<LEAMODE> (match_operand:<LEAMODE> 4 "register_operand")
24263 (match_operand:<LEAMODE> 2 "<nonmemory_operand>")))
24264 (set (match_dup 1) (match_operand:SWI 5 "register_operand"))
24265 (set (reg FLAGS_REG) (compare (match_dup 5) (const_int 0)))]
24266 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
24267 && REGNO (operands[4]) == REGNO (operands[0])
24268 && REGNO (operands[5]) == REGNO (operands[3])
24269 && peep2_reg_dead_p (4, operands[3])
24270 && ((REGNO (operands[0]) == REGNO (operands[3]))
24271 || peep2_reg_dead_p (2, operands[0]))
24272 && !reg_overlap_mentioned_p (operands[0], operands[1])
24273 && !reg_overlap_mentioned_p (operands[3], operands[1])
24274 && !reg_overlap_mentioned_p (operands[0], operands[2])
24275 && (<MODE>mode != QImode
24276 || immediate_operand (operands[2], QImode)
24277 || any_QIreg_operand (operands[2], QImode))
24278 && ix86_match_ccmode (peep2_next_insn (3), CCGOCmode)"
24279 [(parallel [(set (match_dup 6) (match_dup 8))
24280 (set (match_dup 1) (match_dup 7))])]
24282 operands[6] = SET_DEST (PATTERN (peep2_next_insn (3)));
24284 = gen_rtx_PLUS (<MODE>mode,
24285 copy_rtx (operands[1]),
24286 gen_lowpart (<MODE>mode, operands[2]));
24288 = gen_rtx_COMPARE (GET_MODE (operands[6]),
24289 copy_rtx (operands[7]),
24294 [(parallel [(set (match_operand:SWI 0 "register_operand")
24295 (match_operator:SWI 2 "plusminuslogic_operator"
24297 (match_operand:SWI 1 "memory_operand")]))
24298 (clobber (reg:CC FLAGS_REG))])
24299 (set (match_dup 1) (match_dup 0))
24300 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
24301 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
24302 && COMMUTATIVE_ARITH_P (operands[2])
24303 && peep2_reg_dead_p (3, operands[0])
24304 && !reg_overlap_mentioned_p (operands[0], operands[1])
24305 && ix86_match_ccmode (peep2_next_insn (2),
24306 GET_CODE (operands[2]) == PLUS
24307 ? CCGOCmode : CCNOmode)"
24308 [(parallel [(set (match_dup 3) (match_dup 5))
24309 (set (match_dup 1) (match_dup 4))])]
24311 operands[3] = SET_DEST (PATTERN (peep2_next_insn (2)));
24313 = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
24314 copy_rtx (operands[1]),
24317 = gen_rtx_COMPARE (GET_MODE (operands[3]),
24318 copy_rtx (operands[4]),
24322 ;; Likewise for cmpelim optimized pattern.
24324 [(parallel [(set (reg FLAGS_REG)
24325 (compare (match_operator:SWI 2 "plusminuslogic_operator"
24326 [(match_operand:SWI 0 "register_operand")
24327 (match_operand:SWI 1 "memory_operand")])
24329 (set (match_dup 0) (match_dup 2))])
24330 (set (match_dup 1) (match_dup 0))]
24331 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
24332 && COMMUTATIVE_ARITH_P (operands[2])
24333 && peep2_reg_dead_p (2, operands[0])
24334 && !reg_overlap_mentioned_p (operands[0], operands[1])
24335 && ix86_match_ccmode (peep2_next_insn (0),
24336 GET_CODE (operands[2]) == PLUS
24337 ? CCGOCmode : CCNOmode)"
24338 [(parallel [(set (match_dup 3) (match_dup 5))
24339 (set (match_dup 1) (match_dup 4))])]
24341 operands[3] = SET_DEST (XVECEXP (PATTERN (peep2_next_insn (0)), 0, 0));
24343 = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
24344 copy_rtx (operands[1]), operands[0]);
24346 = gen_rtx_COMPARE (GET_MODE (operands[3]), copy_rtx (operands[4]),
24351 [(set (match_operand:SWI12 0 "register_operand")
24352 (match_operand:SWI12 1 "memory_operand"))
24353 (parallel [(set (match_operand:SI 4 "register_operand")
24354 (match_operator:SI 3 "plusminuslogic_operator"
24356 (match_operand:SI 2 "nonmemory_operand")]))
24357 (clobber (reg:CC FLAGS_REG))])
24358 (set (match_dup 1) (match_dup 0))
24359 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
24360 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
24361 && REGNO (operands[0]) == REGNO (operands[4])
24362 && peep2_reg_dead_p (4, operands[0])
24363 && (<MODE>mode != QImode
24364 || immediate_operand (operands[2], SImode)
24365 || any_QIreg_operand (operands[2], SImode))
24366 && !reg_overlap_mentioned_p (operands[0], operands[1])
24367 && !reg_overlap_mentioned_p (operands[0], operands[2])
24368 && ix86_match_ccmode (peep2_next_insn (3),
24369 (GET_CODE (operands[3]) == PLUS
24370 || GET_CODE (operands[3]) == MINUS)
24371 ? CCGOCmode : CCNOmode)"
24372 [(parallel [(set (match_dup 5) (match_dup 7))
24373 (set (match_dup 1) (match_dup 6))])]
24375 operands[5] = SET_DEST (PATTERN (peep2_next_insn (3)));
24377 = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
24378 copy_rtx (operands[1]),
24379 gen_lowpart (<MODE>mode, operands[2]));
24381 = gen_rtx_COMPARE (GET_MODE (operands[5]),
24382 copy_rtx (operands[6]),
24386 ;; peephole2 comes before regcprop, so deal also with a case that
24387 ;; would be cleaned up by regcprop.
24389 [(set (match_operand:SWI 0 "register_operand")
24390 (match_operand:SWI 1 "memory_operand"))
24391 (parallel [(set (match_dup 0)
24392 (match_operator:SWI 3 "plusminuslogic_operator"
24394 (match_operand:SWI 2 "<nonmemory_operand>")]))
24395 (clobber (reg:CC FLAGS_REG))])
24396 (set (match_operand:SWI 4 "register_operand") (match_dup 0))
24397 (set (match_dup 1) (match_dup 4))
24398 (set (reg FLAGS_REG) (compare (match_dup 4) (const_int 0)))]
24399 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
24400 && peep2_reg_dead_p (3, operands[0])
24401 && peep2_reg_dead_p (5, operands[4])
24402 && !reg_overlap_mentioned_p (operands[0], operands[1])
24403 && !reg_overlap_mentioned_p (operands[0], operands[2])
24404 && !reg_overlap_mentioned_p (operands[4], operands[1])
24405 && (<MODE>mode != QImode
24406 || immediate_operand (operands[2], QImode)
24407 || any_QIreg_operand (operands[2], QImode))
24408 && ix86_match_ccmode (peep2_next_insn (4),
24409 (GET_CODE (operands[3]) == PLUS
24410 || GET_CODE (operands[3]) == MINUS)
24411 ? CCGOCmode : CCNOmode)"
24412 [(parallel [(set (match_dup 5) (match_dup 7))
24413 (set (match_dup 1) (match_dup 6))])]
24415 operands[5] = SET_DEST (PATTERN (peep2_next_insn (4)));
24417 = gen_rtx_fmt_ee (GET_CODE (operands[3]), GET_MODE (operands[3]),
24418 copy_rtx (operands[1]),
24421 = gen_rtx_COMPARE (GET_MODE (operands[5]),
24422 copy_rtx (operands[6]),
24427 [(set (match_operand:SWI12 0 "register_operand")
24428 (match_operand:SWI12 1 "memory_operand"))
24429 (parallel [(set (match_operand:SI 4 "register_operand")
24430 (match_operator:SI 3 "plusminuslogic_operator"
24432 (match_operand:SI 2 "nonmemory_operand")]))
24433 (clobber (reg:CC FLAGS_REG))])
24434 (set (match_operand:SWI12 5 "register_operand") (match_dup 0))
24435 (set (match_dup 1) (match_dup 5))
24436 (set (reg FLAGS_REG) (compare (match_dup 5) (const_int 0)))]
24437 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
24438 && REGNO (operands[0]) == REGNO (operands[4])
24439 && peep2_reg_dead_p (3, operands[0])
24440 && peep2_reg_dead_p (5, operands[5])
24441 && (<MODE>mode != QImode
24442 || immediate_operand (operands[2], SImode)
24443 || any_QIreg_operand (operands[2], SImode))
24444 && !reg_overlap_mentioned_p (operands[0], operands[1])
24445 && !reg_overlap_mentioned_p (operands[0], operands[2])
24446 && !reg_overlap_mentioned_p (operands[5], operands[1])
24447 && ix86_match_ccmode (peep2_next_insn (4),
24448 (GET_CODE (operands[3]) == PLUS
24449 || GET_CODE (operands[3]) == MINUS)
24450 ? CCGOCmode : CCNOmode)"
24451 [(parallel [(set (match_dup 6) (match_dup 8))
24452 (set (match_dup 1) (match_dup 7))])]
24454 operands[6] = SET_DEST (PATTERN (peep2_next_insn (4)));
24456 = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
24457 copy_rtx (operands[1]),
24458 gen_lowpart (<MODE>mode, operands[2]));
24460 = gen_rtx_COMPARE (GET_MODE (operands[6]),
24461 copy_rtx (operands[7]),
24465 ;; Likewise for cmpelim optimized pattern.
24467 [(set (match_operand:SWI 0 "register_operand")
24468 (match_operand:SWI 1 "memory_operand"))
24469 (parallel [(set (reg FLAGS_REG)
24470 (compare (match_operator:SWI 3 "plusminuslogic_operator"
24472 (match_operand:SWI 2 "<nonmemory_operand>")])
24474 (set (match_dup 0) (match_dup 3))])
24475 (set (match_operand:SWI 4 "register_operand") (match_dup 0))
24476 (set (match_dup 1) (match_dup 4))]
24477 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
24478 && peep2_reg_dead_p (3, operands[0])
24479 && peep2_reg_dead_p (4, operands[4])
24480 && !reg_overlap_mentioned_p (operands[0], operands[1])
24481 && !reg_overlap_mentioned_p (operands[0], operands[2])
24482 && !reg_overlap_mentioned_p (operands[4], operands[1])
24483 && ix86_match_ccmode (peep2_next_insn (1),
24484 (GET_CODE (operands[3]) == PLUS
24485 || GET_CODE (operands[3]) == MINUS)
24486 ? CCGOCmode : CCNOmode)"
24487 [(parallel [(set (match_dup 5) (match_dup 7))
24488 (set (match_dup 1) (match_dup 6))])]
24490 operands[5] = SET_DEST (XVECEXP (PATTERN (peep2_next_insn (1)), 0, 0));
24492 = gen_rtx_fmt_ee (GET_CODE (operands[3]), GET_MODE (operands[3]),
24493 copy_rtx (operands[1]), operands[2]);
24495 = gen_rtx_COMPARE (GET_MODE (operands[5]), copy_rtx (operands[6]),
24499 ;; Special cases for xor, where (x ^= y) != 0 is (misoptimized)
24500 ;; into x = z; x ^= y; x != z
24502 [(set (match_operand:SWI 0 "register_operand")
24503 (match_operand:SWI 1 "memory_operand"))
24504 (set (match_operand:SWI 3 "register_operand") (match_dup 0))
24505 (parallel [(set (match_operand:SWI 4 "register_operand")
24506 (xor:SWI (match_dup 4)
24507 (match_operand:SWI 2 "<nonmemory_operand>")))
24508 (clobber (reg:CC FLAGS_REG))])
24509 (set (match_dup 1) (match_dup 4))
24510 (set (reg:CCZ FLAGS_REG)
24511 (compare:CCZ (match_operand:SWI 5 "register_operand")
24512 (match_operand:SWI 6 "<nonmemory_operand>")))]
24513 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
24514 && (REGNO (operands[4]) == REGNO (operands[0])
24515 || REGNO (operands[4]) == REGNO (operands[3]))
24516 && (rtx_equal_p (operands[REGNO (operands[4]) == REGNO (operands[0])
24517 ? 3 : 0], operands[5])
24518 ? rtx_equal_p (operands[2], operands[6])
24519 : rtx_equal_p (operands[2], operands[5])
24520 && rtx_equal_p (operands[REGNO (operands[4]) == REGNO (operands[0])
24521 ? 3 : 0], operands[6]))
24522 && peep2_reg_dead_p (4, operands[4])
24523 && peep2_reg_dead_p (5, operands[REGNO (operands[4]) == REGNO (operands[0])
24525 && !reg_overlap_mentioned_p (operands[0], operands[1])
24526 && !reg_overlap_mentioned_p (operands[0], operands[2])
24527 && !reg_overlap_mentioned_p (operands[3], operands[0])
24528 && !reg_overlap_mentioned_p (operands[3], operands[1])
24529 && !reg_overlap_mentioned_p (operands[3], operands[2])
24530 && (<MODE>mode != QImode
24531 || immediate_operand (operands[2], QImode)
24532 || any_QIreg_operand (operands[2], QImode))"
24533 [(parallel [(set (match_dup 7) (match_dup 9))
24534 (set (match_dup 1) (match_dup 8))])]
24536 operands[7] = SET_DEST (PATTERN (peep2_next_insn (4)));
24537 operands[8] = gen_rtx_XOR (<MODE>mode, copy_rtx (operands[1]),
24540 = gen_rtx_COMPARE (GET_MODE (operands[7]),
24541 copy_rtx (operands[8]),
24546 [(set (match_operand:SWI12 0 "register_operand")
24547 (match_operand:SWI12 1 "memory_operand"))
24548 (set (match_operand:SWI12 3 "register_operand") (match_dup 0))
24549 (parallel [(set (match_operand:SI 4 "register_operand")
24550 (xor:SI (match_dup 4)
24551 (match_operand:SI 2 "<nonmemory_operand>")))
24552 (clobber (reg:CC FLAGS_REG))])
24553 (set (match_dup 1) (match_operand:SWI12 5 "register_operand"))
24554 (set (reg:CCZ FLAGS_REG)
24555 (compare:CCZ (match_operand:SWI12 6 "register_operand")
24556 (match_operand:SWI12 7 "<nonmemory_operand>")))]
24557 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
24558 && (REGNO (operands[5]) == REGNO (operands[0])
24559 || REGNO (operands[5]) == REGNO (operands[3]))
24560 && REGNO (operands[5]) == REGNO (operands[4])
24561 && (rtx_equal_p (operands[REGNO (operands[5]) == REGNO (operands[0])
24562 ? 3 : 0], operands[6])
24563 ? (REG_P (operands[2])
24564 ? REG_P (operands[7]) && REGNO (operands[2]) == REGNO (operands[7])
24565 : rtx_equal_p (operands[2], operands[7]))
24566 : (rtx_equal_p (operands[REGNO (operands[5]) == REGNO (operands[0])
24567 ? 3 : 0], operands[7])
24568 && REG_P (operands[2])
24569 && REGNO (operands[2]) == REGNO (operands[6])))
24570 && peep2_reg_dead_p (4, operands[5])
24571 && peep2_reg_dead_p (5, operands[REGNO (operands[5]) == REGNO (operands[0])
24573 && !reg_overlap_mentioned_p (operands[0], operands[1])
24574 && !reg_overlap_mentioned_p (operands[0], operands[2])
24575 && !reg_overlap_mentioned_p (operands[3], operands[0])
24576 && !reg_overlap_mentioned_p (operands[3], operands[1])
24577 && !reg_overlap_mentioned_p (operands[3], operands[2])
24578 && (<MODE>mode != QImode
24579 || immediate_operand (operands[2], SImode)
24580 || any_QIreg_operand (operands[2], SImode))"
24581 [(parallel [(set (match_dup 8) (match_dup 10))
24582 (set (match_dup 1) (match_dup 9))])]
24584 operands[8] = SET_DEST (PATTERN (peep2_next_insn (4)));
24585 operands[9] = gen_rtx_XOR (<MODE>mode, copy_rtx (operands[1]),
24586 gen_lowpart (<MODE>mode, operands[2]));
24588 = gen_rtx_COMPARE (GET_MODE (operands[8]),
24589 copy_rtx (operands[9]),
24593 ;; Attempt to optimize away memory stores of values the memory already
24594 ;; has. See PR79593.
24596 [(set (match_operand 0 "register_operand")
24597 (match_operand 1 "memory_operand"))
24598 (set (match_operand 2 "memory_operand") (match_dup 0))]
24599 "!MEM_VOLATILE_P (operands[1])
24600 && !MEM_VOLATILE_P (operands[2])
24601 && rtx_equal_p (operands[1], operands[2])
24602 && !reg_overlap_mentioned_p (operands[0], operands[2])"
24603 [(set (match_dup 0) (match_dup 1))])
24605 ;; Attempt to always use XOR for zeroing registers (including FP modes).
24607 [(set (match_operand 0 "general_reg_operand")
24608 (match_operand 1 "const0_operand"))]
24609 "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
24610 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
24611 && peep2_regno_dead_p (0, FLAGS_REG)"
24612 [(parallel [(set (match_dup 0) (const_int 0))
24613 (clobber (reg:CC FLAGS_REG))])]
24614 "operands[0] = gen_lowpart (word_mode, operands[0]);")
24617 [(set (strict_low_part (match_operand:SWI12 0 "general_reg_operand"))
24619 "(! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
24620 && peep2_regno_dead_p (0, FLAGS_REG)"
24621 [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
24622 (clobber (reg:CC FLAGS_REG))])])
24624 ;; For HI, SI and DI modes, or $-1,reg is smaller than mov $-1,reg.
24626 [(set (match_operand:SWI248 0 "general_reg_operand")
24628 "(TARGET_MOVE_M1_VIA_OR || optimize_insn_for_size_p ())
24629 && peep2_regno_dead_p (0, FLAGS_REG)"
24630 [(parallel [(set (match_dup 0) (const_int -1))
24631 (clobber (reg:CC FLAGS_REG))])]
24633 if (<MODE_SIZE> < GET_MODE_SIZE (SImode))
24634 operands[0] = gen_lowpart (SImode, operands[0]);
24637 ;; Attempt to convert simple lea to add/shift.
24638 ;; These can be created by move expanders.
24639 ;; Disable PLUS peepholes on TARGET_OPT_AGU, since all
24640 ;; relevant lea instructions were already split.
24643 [(set (match_operand:SWI48 0 "register_operand")
24644 (plus:SWI48 (match_dup 0)
24645 (match_operand:SWI48 1 "<nonmemory_operand>")))]
24647 && peep2_regno_dead_p (0, FLAGS_REG)"
24648 [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1)))
24649 (clobber (reg:CC FLAGS_REG))])])
24652 [(set (match_operand:SWI48 0 "register_operand")
24653 (plus:SWI48 (match_operand:SWI48 1 "<nonmemory_operand>")
24656 && peep2_regno_dead_p (0, FLAGS_REG)"
24657 [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1)))
24658 (clobber (reg:CC FLAGS_REG))])])
24661 [(set (match_operand:DI 0 "register_operand")
24663 (plus:SI (match_operand:SI 1 "register_operand")
24664 (match_operand:SI 2 "nonmemory_operand"))))]
24665 "TARGET_64BIT && !TARGET_OPT_AGU
24666 && REGNO (operands[0]) == REGNO (operands[1])
24667 && peep2_regno_dead_p (0, FLAGS_REG)"
24668 [(parallel [(set (match_dup 0)
24669 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))
24670 (clobber (reg:CC FLAGS_REG))])])
24673 [(set (match_operand:DI 0 "register_operand")
24675 (plus:SI (match_operand:SI 1 "nonmemory_operand")
24676 (match_operand:SI 2 "register_operand"))))]
24677 "TARGET_64BIT && !TARGET_OPT_AGU
24678 && REGNO (operands[0]) == REGNO (operands[2])
24679 && peep2_regno_dead_p (0, FLAGS_REG)"
24680 [(parallel [(set (match_dup 0)
24681 (zero_extend:DI (plus:SI (match_dup 2) (match_dup 1))))
24682 (clobber (reg:CC FLAGS_REG))])])
24685 [(set (match_operand:SWI48 0 "register_operand")
24686 (mult:SWI48 (match_dup 0)
24687 (match_operand:SWI48 1 "const_int_operand")))]
24688 "pow2p_hwi (INTVAL (operands[1]))
24689 && peep2_regno_dead_p (0, FLAGS_REG)"
24690 [(parallel [(set (match_dup 0) (ashift:SWI48 (match_dup 0) (match_dup 1)))
24691 (clobber (reg:CC FLAGS_REG))])]
24692 "operands[1] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
24695 [(set (match_operand:DI 0 "register_operand")
24697 (mult:SI (match_operand:SI 1 "register_operand")
24698 (match_operand:SI 2 "const_int_operand"))))]
24700 && pow2p_hwi (INTVAL (operands[2]))
24701 && REGNO (operands[0]) == REGNO (operands[1])
24702 && peep2_regno_dead_p (0, FLAGS_REG)"
24703 [(parallel [(set (match_dup 0)
24704 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))
24705 (clobber (reg:CC FLAGS_REG))])]
24706 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
24708 ;; The ESP adjustments can be done by the push and pop instructions. Resulting
24709 ;; code is shorter, since push is only 1 byte, while add imm, %esp is 3 bytes.
24710 ;; On many CPUs it is also faster, since special hardware to avoid esp
24711 ;; dependencies is present.
24713 ;; While some of these conversions may be done using splitters, we use
24714 ;; peepholes in order to allow combine_stack_adjustments pass to see
24715 ;; nonobfuscated RTL.
24717 ;; Convert prologue esp subtractions to push.
24718 ;; We need register to push. In order to keep verify_flow_info happy we have
24720 ;; - use scratch and clobber it in order to avoid dependencies
24721 ;; - use already live register
24722 ;; We can't use the second way right now, since there is no reliable way how to
24723 ;; verify that given register is live. First choice will also most likely in
24724 ;; fewer dependencies. On the place of esp adjustments it is very likely that
24725 ;; call clobbered registers are dead. We may want to use base pointer as an
24726 ;; alternative when no register is available later.
24729 [(match_scratch:W 1 "r")
24730 (parallel [(set (reg:P SP_REG)
24731 (plus:P (reg:P SP_REG)
24732 (match_operand:P 0 "const_int_operand")))
24733 (clobber (reg:CC FLAGS_REG))
24734 (clobber (mem:BLK (scratch)))])]
24735 "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
24736 && INTVAL (operands[0]) == -GET_MODE_SIZE (word_mode)
24737 && !ix86_red_zone_used"
24738 [(clobber (match_dup 1))
24739 (parallel [(set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
24740 (clobber (mem:BLK (scratch)))])])
24743 [(match_scratch:W 1 "r")
24744 (parallel [(set (reg:P SP_REG)
24745 (plus:P (reg:P SP_REG)
24746 (match_operand:P 0 "const_int_operand")))
24747 (clobber (reg:CC FLAGS_REG))
24748 (clobber (mem:BLK (scratch)))])]
24749 "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
24750 && INTVAL (operands[0]) == -2*GET_MODE_SIZE (word_mode)
24751 && !ix86_red_zone_used"
24752 [(clobber (match_dup 1))
24753 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
24754 (parallel [(set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
24755 (clobber (mem:BLK (scratch)))])])
24757 ;; Convert esp subtractions to push.
24759 [(match_scratch:W 1 "r")
24760 (parallel [(set (reg:P SP_REG)
24761 (plus:P (reg:P SP_REG)
24762 (match_operand:P 0 "const_int_operand")))
24763 (clobber (reg:CC FLAGS_REG))])]
24764 "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
24765 && INTVAL (operands[0]) == -GET_MODE_SIZE (word_mode)
24766 && !ix86_red_zone_used"
24767 [(clobber (match_dup 1))
24768 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
24771 [(match_scratch:W 1 "r")
24772 (parallel [(set (reg:P SP_REG)
24773 (plus:P (reg:P SP_REG)
24774 (match_operand:P 0 "const_int_operand")))
24775 (clobber (reg:CC FLAGS_REG))])]
24776 "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
24777 && INTVAL (operands[0]) == -2*GET_MODE_SIZE (word_mode)
24778 && !ix86_red_zone_used"
24779 [(clobber (match_dup 1))
24780 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
24781 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
24783 ;; Convert epilogue deallocator to pop.
24785 [(match_scratch:W 1 "r")
24786 (parallel [(set (reg:P SP_REG)
24787 (plus:P (reg:P SP_REG)
24788 (match_operand:P 0 "const_int_operand")))
24789 (clobber (reg:CC FLAGS_REG))
24790 (clobber (mem:BLK (scratch)))])]
24791 "(TARGET_SINGLE_POP || optimize_insn_for_size_p ())
24792 && INTVAL (operands[0]) == GET_MODE_SIZE (word_mode)"
24793 [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
24794 (clobber (mem:BLK (scratch)))])])
24796 ;; Two pops case is tricky, since pop causes dependency
24797 ;; on destination register. We use two registers if available.
24799 [(match_scratch:W 1 "r")
24800 (match_scratch:W 2 "r")
24801 (parallel [(set (reg:P SP_REG)
24802 (plus:P (reg:P SP_REG)
24803 (match_operand:P 0 "const_int_operand")))
24804 (clobber (reg:CC FLAGS_REG))
24805 (clobber (mem:BLK (scratch)))])]
24806 "(TARGET_DOUBLE_POP || optimize_insn_for_size_p ())
24807 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
24808 [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
24809 (clobber (mem:BLK (scratch)))])
24810 (set (match_dup 2) (mem:W (post_inc:P (reg:P SP_REG))))])
24813 [(match_scratch:W 1 "r")
24814 (parallel [(set (reg:P SP_REG)
24815 (plus:P (reg:P SP_REG)
24816 (match_operand:P 0 "const_int_operand")))
24817 (clobber (reg:CC FLAGS_REG))
24818 (clobber (mem:BLK (scratch)))])]
24819 "optimize_insn_for_size_p ()
24820 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
24821 [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
24822 (clobber (mem:BLK (scratch)))])
24823 (set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
24825 ;; Convert esp additions to pop.
24827 [(match_scratch:W 1 "r")
24828 (parallel [(set (reg:P SP_REG)
24829 (plus:P (reg:P SP_REG)
24830 (match_operand:P 0 "const_int_operand")))
24831 (clobber (reg:CC FLAGS_REG))])]
24832 "INTVAL (operands[0]) == GET_MODE_SIZE (word_mode)"
24833 [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
24835 ;; Two pops case is tricky, since pop causes dependency
24836 ;; on destination register. We use two registers if available.
24838 [(match_scratch:W 1 "r")
24839 (match_scratch:W 2 "r")
24840 (parallel [(set (reg:P SP_REG)
24841 (plus:P (reg:P SP_REG)
24842 (match_operand:P 0 "const_int_operand")))
24843 (clobber (reg:CC FLAGS_REG))])]
24844 "INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
24845 [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
24846 (set (match_dup 2) (mem:W (post_inc:P (reg:P SP_REG))))])
24849 [(match_scratch:W 1 "r")
24850 (parallel [(set (reg:P SP_REG)
24851 (plus:P (reg:P SP_REG)
24852 (match_operand:P 0 "const_int_operand")))
24853 (clobber (reg:CC FLAGS_REG))])]
24854 "optimize_insn_for_size_p ()
24855 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
24856 [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
24857 (set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
24859 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
24860 ;; required and register dies. Similarly for 128 to -128.
24862 [(set (match_operand 0 "flags_reg_operand")
24863 (match_operator 1 "compare_operator"
24864 [(match_operand 2 "register_operand")
24865 (match_operand 3 "const_int_operand")]))]
24866 "(((!TARGET_FUSE_CMP_AND_BRANCH || optimize_insn_for_size_p ())
24867 && incdec_operand (operands[3], GET_MODE (operands[3])))
24868 || (!TARGET_FUSE_CMP_AND_BRANCH
24869 && INTVAL (operands[3]) == 128))
24870 && ix86_match_ccmode (insn, CCGCmode)
24871 && peep2_reg_dead_p (1, operands[2])"
24872 [(parallel [(set (match_dup 0)
24873 (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
24874 (clobber (match_dup 2))])])
24876 ;; Convert imul by three, five and nine into lea
24879 [(set (match_operand:SWI48 0 "register_operand")
24880 (mult:SWI48 (match_operand:SWI48 1 "register_operand")
24881 (match_operand:SWI48 2 "const359_operand")))
24882 (clobber (reg:CC FLAGS_REG))])]
24883 "!TARGET_PARTIAL_REG_STALL
24884 || <MODE>mode == SImode
24885 || optimize_function_for_size_p (cfun)"
24886 [(set (match_dup 0)
24887 (plus:SWI48 (mult:SWI48 (match_dup 1) (match_dup 2))
24889 "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
24893 [(set (match_operand:SWI48 0 "register_operand")
24894 (mult:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
24895 (match_operand:SWI48 2 "const359_operand")))
24896 (clobber (reg:CC FLAGS_REG))])]
24897 "optimize_insn_for_speed_p ()
24898 && (!TARGET_PARTIAL_REG_STALL || <MODE>mode == SImode)"
24899 [(set (match_dup 0) (match_dup 1))
24901 (plus:SWI48 (mult:SWI48 (match_dup 0) (match_dup 2))
24903 "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
24905 ;; imul $32bit_imm, mem, reg is vector decoded, while
24906 ;; imul $32bit_imm, reg, reg is direct decoded.
24908 [(match_scratch:SWI48 3 "r")
24909 (parallel [(set (match_operand:SWI48 0 "register_operand")
24910 (mult:SWI48 (match_operand:SWI48 1 "memory_operand")
24911 (match_operand:SWI48 2 "immediate_operand")))
24912 (clobber (reg:CC FLAGS_REG))])]
24913 "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
24914 && !satisfies_constraint_K (operands[2])"
24915 [(set (match_dup 3) (match_dup 1))
24916 (parallel [(set (match_dup 0) (mult:SWI48 (match_dup 3) (match_dup 2)))
24917 (clobber (reg:CC FLAGS_REG))])])
24920 [(match_scratch:SI 3 "r")
24921 (parallel [(set (match_operand:DI 0 "register_operand")
24923 (mult:SI (match_operand:SI 1 "memory_operand")
24924 (match_operand:SI 2 "immediate_operand"))))
24925 (clobber (reg:CC FLAGS_REG))])]
24927 && TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
24928 && !satisfies_constraint_K (operands[2])"
24929 [(set (match_dup 3) (match_dup 1))
24930 (parallel [(set (match_dup 0)
24931 (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
24932 (clobber (reg:CC FLAGS_REG))])])
24934 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
24935 ;; Convert it into imul reg, reg
24936 ;; It would be better to force assembler to encode instruction using long
24937 ;; immediate, but there is apparently no way to do so.
24939 [(parallel [(set (match_operand:SWI248 0 "register_operand")
24941 (match_operand:SWI248 1 "nonimmediate_operand")
24942 (match_operand:SWI248 2 "const_int_operand")))
24943 (clobber (reg:CC FLAGS_REG))])
24944 (match_scratch:SWI248 3 "r")]
24945 "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
24946 && satisfies_constraint_K (operands[2])"
24947 [(set (match_dup 3) (match_dup 2))
24948 (parallel [(set (match_dup 0) (mult:SWI248 (match_dup 0) (match_dup 3)))
24949 (clobber (reg:CC FLAGS_REG))])]
24951 if (!rtx_equal_p (operands[0], operands[1]))
24952 emit_move_insn (operands[0], operands[1]);
24955 ;; After splitting up read-modify operations, array accesses with memory
24956 ;; operands might end up in form:
24958 ;; movl 4(%esp), %edx
24960 ;; instead of pre-splitting:
24962 ;; addl 4(%esp), %eax
24964 ;; movl 4(%esp), %edx
24965 ;; leal (%edx,%eax,4), %eax
24968 [(match_scratch:W 5 "r")
24969 (parallel [(set (match_operand 0 "register_operand")
24970 (ashift (match_operand 1 "register_operand")
24971 (match_operand 2 "const_int_operand")))
24972 (clobber (reg:CC FLAGS_REG))])
24973 (parallel [(set (match_operand 3 "register_operand")
24974 (plus (match_dup 0)
24975 (match_operand 4 "x86_64_general_operand")))
24976 (clobber (reg:CC FLAGS_REG))])]
24977 "IN_RANGE (INTVAL (operands[2]), 1, 3)
24978 /* Validate MODE for lea. */
24979 && ((!TARGET_PARTIAL_REG_STALL
24980 && (GET_MODE (operands[0]) == QImode
24981 || GET_MODE (operands[0]) == HImode))
24982 || GET_MODE (operands[0]) == SImode
24983 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
24984 && (rtx_equal_p (operands[0], operands[3])
24985 || peep2_reg_dead_p (2, operands[0]))
24986 /* We reorder load and the shift. */
24987 && !reg_overlap_mentioned_p (operands[0], operands[4])"
24988 [(set (match_dup 5) (match_dup 4))
24989 (set (match_dup 0) (match_dup 1))]
24991 machine_mode op1mode = GET_MODE (operands[1]);
24992 machine_mode mode = op1mode == DImode ? DImode : SImode;
24993 int scale = 1 << INTVAL (operands[2]);
24994 rtx index = gen_lowpart (word_mode, operands[1]);
24995 rtx base = gen_lowpart (word_mode, operands[5]);
24996 rtx dest = gen_lowpart (mode, operands[3]);
24998 operands[1] = gen_rtx_PLUS (word_mode, base,
24999 gen_rtx_MULT (word_mode, index, GEN_INT (scale)));
25000 if (mode != word_mode)
25001 operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
25003 operands[5] = base;
25004 if (op1mode != word_mode)
25005 operands[5] = gen_lowpart (op1mode, operands[5]);
25007 operands[0] = dest;
25010 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
25011 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
25012 ;; caught for use by garbage collectors and the like. Using an insn that
25013 ;; maps to SIGILL makes it more likely the program will rightfully die.
25014 ;; Keeping with tradition, "6" is in honor of #UD.
25015 (define_insn "trap"
25016 [(trap_if (const_int 1) (const_int 6))]
25019 #ifdef HAVE_AS_IX86_UD2
25022 return ASM_SHORT "0x0b0f";
25025 [(set_attr "length" "2")])
25028 [(unspec_volatile [(const_int 0)] UNSPECV_UD2)]
25031 #ifdef HAVE_AS_IX86_UD2
25034 return ASM_SHORT "0x0b0f";
25037 [(set_attr "length" "2")])
25039 (define_expand "prefetch"
25040 [(prefetch (match_operand 0 "address_operand")
25041 (match_operand:SI 1 "const_int_operand")
25042 (match_operand:SI 2 "const_int_operand"))]
25043 "TARGET_3DNOW || TARGET_PREFETCH_SSE || TARGET_PRFCHW || TARGET_PREFETCHWT1"
25045 bool write = operands[1] != const0_rtx;
25046 int locality = INTVAL (operands[2]);
25048 gcc_assert (IN_RANGE (locality, 0, 3));
25050 /* Use 3dNOW prefetch in case we are asking for write prefetch not
25051 supported by SSE counterpart (non-SSE2 athlon machines) or the
25052 SSE prefetch is not available (K6 machines). Otherwise use SSE
25053 prefetch as it allows specifying of locality. */
25057 if (TARGET_PREFETCHWT1)
25058 operands[2] = GEN_INT (MAX (locality, 2));
25059 else if (TARGET_PRFCHW)
25060 operands[2] = GEN_INT (3);
25061 else if (TARGET_3DNOW && !TARGET_SSE2)
25062 operands[2] = GEN_INT (3);
25063 else if (TARGET_PREFETCH_SSE)
25064 operands[1] = const0_rtx;
25067 gcc_assert (TARGET_3DNOW);
25068 operands[2] = GEN_INT (3);
25073 if (TARGET_PREFETCH_SSE)
25077 gcc_assert (TARGET_3DNOW);
25078 operands[2] = GEN_INT (3);
25083 (define_insn "*prefetch_sse"
25084 [(prefetch (match_operand 0 "address_operand" "p")
25086 (match_operand:SI 1 "const_int_operand"))]
25087 "TARGET_PREFETCH_SSE"
25089 static const char * const patterns[4] = {
25090 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
25093 int locality = INTVAL (operands[1]);
25094 gcc_assert (IN_RANGE (locality, 0, 3));
25096 return patterns[locality];
25098 [(set_attr "type" "sse")
25099 (set_attr "atom_sse_attr" "prefetch")
25100 (set (attr "length_address")
25101 (symbol_ref "memory_address_length (operands[0], false)"))
25102 (set_attr "memory" "none")])
25104 (define_insn "*prefetch_3dnow"
25105 [(prefetch (match_operand 0 "address_operand" "p")
25106 (match_operand:SI 1 "const_int_operand")
25108 "TARGET_3DNOW || TARGET_PRFCHW || TARGET_PREFETCHWT1"
25110 if (operands[1] == const0_rtx)
25111 return "prefetch\t%a0";
25113 return "prefetchw\t%a0";
25115 [(set_attr "type" "mmx")
25116 (set (attr "length_address")
25117 (symbol_ref "memory_address_length (operands[0], false)"))
25118 (set_attr "memory" "none")])
25120 (define_insn "*prefetch_prefetchwt1"
25121 [(prefetch (match_operand 0 "address_operand" "p")
25124 "TARGET_PREFETCHWT1"
25125 "prefetchwt1\t%a0";
25126 [(set_attr "type" "sse")
25127 (set (attr "length_address")
25128 (symbol_ref "memory_address_length (operands[0], false)"))
25129 (set_attr "memory" "none")])
25131 (define_insn "prefetchi"
25132 [(unspec_volatile [(match_operand 0 "local_func_symbolic_operand" "p")
25133 (match_operand:SI 1 "const_int_operand")]
25134 UNSPECV_PREFETCHI)]
25135 "TARGET_PREFETCHI && TARGET_64BIT"
25137 static const char * const patterns[2] = {
25138 "prefetchit1\t%0", "prefetchit0\t%0"
25141 int locality = INTVAL (operands[1]);
25142 gcc_assert (IN_RANGE (locality, 2, 3));
25144 return patterns[locality - 2];
25146 [(set_attr "type" "sse")
25147 (set (attr "length_address")
25148 (symbol_ref "memory_address_length (operands[0], false)"))
25149 (set_attr "memory" "none")])
25151 (define_expand "stack_protect_set"
25152 [(match_operand 0 "memory_operand")
25153 (match_operand 1 "memory_operand")]
25156 emit_insn (gen_stack_protect_set_1
25157 (ptr_mode, operands[0], operands[1]));
25161 (define_insn "@stack_protect_set_1_<mode>"
25162 [(set (match_operand:PTR 0 "memory_operand" "=m")
25163 (unspec:PTR [(match_operand:PTR 1 "memory_operand" "m")]
25165 (set (match_scratch:PTR 2 "=&r") (const_int 0))
25166 (clobber (reg:CC FLAGS_REG))]
25169 output_asm_insn ("mov{<imodesuffix>}\t{%1, %2|%2, %1}", operands);
25170 output_asm_insn ("mov{<imodesuffix>}\t{%2, %0|%0, %2}", operands);
25171 return "xor{l}\t%k2, %k2";
25173 [(set_attr "type" "multi")])
25175 ;; Patterns and peephole2s to optimize stack_protect_set_1_<mode>
25176 ;; immediately followed by *mov{s,d}i_internal to the same register,
25177 ;; where we can avoid the xor{l} above. We don't split this, so that
25178 ;; scheduling or anything else doesn't separate the *stack_protect_set*
25179 ;; pattern from the set of the register that overwrites the register
25180 ;; with a new value.
25181 (define_insn "*stack_protect_set_2_<mode>"
25182 [(set (match_operand:PTR 0 "memory_operand" "=m")
25183 (unspec:PTR [(match_operand:PTR 3 "memory_operand" "m")]
25185 (set (match_operand:SI 1 "register_operand" "=&r")
25186 (match_operand:SI 2 "general_operand" "g"))
25187 (clobber (reg:CC FLAGS_REG))]
25189 && !reg_overlap_mentioned_p (operands[1], operands[2])"
25191 output_asm_insn ("mov{<imodesuffix>}\t{%3, %<k>1|%<k>1, %3}", operands);
25192 output_asm_insn ("mov{<imodesuffix>}\t{%<k>1, %0|%0, %<k>1}", operands);
25193 if (pic_32bit_operand (operands[2], SImode)
25194 || ix86_use_lea_for_mov (insn, operands + 1))
25195 return "lea{l}\t{%E2, %1|%1, %E2}";
25197 return "mov{l}\t{%2, %1|%1, %2}";
25199 [(set_attr "type" "multi")
25200 (set_attr "length" "24")])
25203 [(parallel [(set (match_operand:PTR 0 "memory_operand")
25204 (unspec:PTR [(match_operand:PTR 1 "memory_operand")]
25206 (set (match_operand:PTR 2 "general_reg_operand") (const_int 0))
25207 (clobber (reg:CC FLAGS_REG))])
25208 (set (match_operand:SI 3 "general_reg_operand")
25209 (match_operand:SI 4))]
25210 "REGNO (operands[2]) == REGNO (operands[3])
25211 && general_operand (operands[4], SImode)
25212 && (general_reg_operand (operands[4], SImode)
25213 || memory_operand (operands[4], SImode)
25214 || immediate_operand (operands[4], SImode))
25215 && !reg_overlap_mentioned_p (operands[3], operands[4])"
25216 [(parallel [(set (match_dup 0)
25217 (unspec:PTR [(match_dup 1)] UNSPEC_SP_SET))
25218 (set (match_dup 3) (match_dup 4))
25219 (clobber (reg:CC FLAGS_REG))])])
25221 (define_insn "*stack_protect_set_3"
25222 [(set (match_operand:DI 0 "memory_operand" "=m,m,m")
25223 (unspec:DI [(match_operand:DI 3 "memory_operand" "m,m,m")]
25225 (set (match_operand:DI 1 "register_operand" "=&r,r,r")
25226 (match_operand:DI 2 "general_operand" "Z,rem,i"))
25227 (clobber (reg:CC FLAGS_REG))]
25229 && reload_completed
25230 && !reg_overlap_mentioned_p (operands[1], operands[2])"
25232 output_asm_insn ("mov{q}\t{%3, %1|%1, %3}", operands);
25233 output_asm_insn ("mov{q}\t{%1, %0|%0, %1}", operands);
25234 if (pic_32bit_operand (operands[2], DImode))
25235 return "lea{q}\t{%E2, %1|%1, %E2}";
25236 else if (which_alternative == 0)
25237 return "mov{l}\t{%k2, %k1|%k1, %k2}";
25238 else if (which_alternative == 2)
25239 return "movabs{q}\t{%2, %1|%1, %2}";
25240 else if (ix86_use_lea_for_mov (insn, operands + 1))
25241 return "lea{q}\t{%E2, %1|%1, %E2}";
25243 return "mov{q}\t{%2, %1|%1, %2}";
25245 [(set_attr "type" "multi")
25246 (set_attr "length" "24")])
25249 [(parallel [(set (match_operand:DI 0 "memory_operand")
25250 (unspec:DI [(match_operand:DI 1 "memory_operand")]
25252 (set (match_operand:DI 2 "general_reg_operand") (const_int 0))
25253 (clobber (reg:CC FLAGS_REG))])
25254 (set (match_dup 2) (match_operand:DI 3))]
25256 && general_operand (operands[3], DImode)
25257 && (general_reg_operand (operands[3], DImode)
25258 || memory_operand (operands[3], DImode)
25259 || x86_64_zext_immediate_operand (operands[3], DImode)
25260 || x86_64_immediate_operand (operands[3], DImode)
25261 || (CONSTANT_P (operands[3])
25262 && (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[3]))))
25263 && !reg_overlap_mentioned_p (operands[2], operands[3])"
25264 [(parallel [(set (match_dup 0)
25265 (unspec:PTR [(match_dup 1)] UNSPEC_SP_SET))
25266 (set (match_dup 2) (match_dup 3))
25267 (clobber (reg:CC FLAGS_REG))])])
25269 (define_expand "stack_protect_test"
25270 [(match_operand 0 "memory_operand")
25271 (match_operand 1 "memory_operand")
25275 rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
25277 emit_insn (gen_stack_protect_test_1
25278 (ptr_mode, flags, operands[0], operands[1]));
25280 emit_jump_insn (gen_cbranchcc4 (gen_rtx_EQ (VOIDmode, flags, const0_rtx),
25281 flags, const0_rtx, operands[2]));
25285 (define_insn "@stack_protect_test_1_<mode>"
25286 [(set (match_operand:CCZ 0 "flags_reg_operand")
25287 (unspec:CCZ [(match_operand:PTR 1 "memory_operand" "m")
25288 (match_operand:PTR 2 "memory_operand" "m")]
25290 (clobber (match_scratch:PTR 3 "=&r"))]
25293 output_asm_insn ("mov{<imodesuffix>}\t{%1, %3|%3, %1}", operands);
25294 return "sub{<imodesuffix>}\t{%2, %3|%3, %2}";
25296 [(set_attr "type" "multi")])
25298 (define_insn "sse4_2_crc32<mode>"
25299 [(set (match_operand:SI 0 "register_operand" "=r")
25301 [(match_operand:SI 1 "register_operand" "0")
25302 (match_operand:SWI124 2 "nonimmediate_operand" "<r>m")]
25305 "crc32{<imodesuffix>}\t{%2, %0|%0, %2}"
25306 [(set_attr "type" "sselog1")
25307 (set_attr "prefix_rep" "1")
25308 (set_attr "prefix_extra" "1")
25309 (set (attr "prefix_data16")
25310 (if_then_else (match_operand:HI 2)
25312 (const_string "*")))
25313 (set (attr "prefix_rex")
25314 (if_then_else (match_operand:QI 2 "ext_QIreg_operand")
25316 (const_string "*")))
25317 (set_attr "mode" "SI")])
25319 (define_insn "sse4_2_crc32di"
25320 [(set (match_operand:DI 0 "register_operand" "=r")
25323 [(match_operand:SI 1 "register_operand" "0")
25324 (match_operand:DI 2 "nonimmediate_operand" "rm")]
25326 "TARGET_64BIT && TARGET_CRC32"
25327 "crc32{q}\t{%2, %0|%0, %2}"
25328 [(set_attr "type" "sselog1")
25329 (set_attr "prefix_rep" "1")
25330 (set_attr "prefix_extra" "1")
25331 (set_attr "mode" "DI")])
25333 (define_insn "rdpmc"
25334 [(set (match_operand:DI 0 "register_operand" "=A")
25335 (unspec_volatile:DI [(match_operand:SI 1 "register_operand" "c")]
25339 [(set_attr "type" "other")
25340 (set_attr "length" "2")])
25342 (define_insn "rdpmc_rex64"
25343 [(set (match_operand:DI 0 "register_operand" "=a")
25344 (unspec_volatile:DI [(match_operand:SI 2 "register_operand" "c")]
25346 (set (match_operand:DI 1 "register_operand" "=d")
25347 (unspec_volatile:DI [(match_dup 2)] UNSPECV_RDPMC))]
25350 [(set_attr "type" "other")
25351 (set_attr "length" "2")])
25353 (define_insn "rdtsc"
25354 [(set (match_operand:DI 0 "register_operand" "=A")
25355 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
25358 [(set_attr "type" "other")
25359 (set_attr "length" "2")])
25361 (define_insn "rdtsc_rex64"
25362 [(set (match_operand:DI 0 "register_operand" "=a")
25363 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))
25364 (set (match_operand:DI 1 "register_operand" "=d")
25365 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
25368 [(set_attr "type" "other")
25369 (set_attr "length" "2")])
25371 (define_insn "rdtscp"
25372 [(set (match_operand:DI 0 "register_operand" "=A")
25373 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
25374 (set (match_operand:SI 1 "register_operand" "=c")
25375 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
25378 [(set_attr "type" "other")
25379 (set_attr "length" "3")])
25381 (define_insn "rdtscp_rex64"
25382 [(set (match_operand:DI 0 "register_operand" "=a")
25383 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
25384 (set (match_operand:DI 1 "register_operand" "=d")
25385 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
25386 (set (match_operand:SI 2 "register_operand" "=c")
25387 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
25390 [(set_attr "type" "other")
25391 (set_attr "length" "3")])
25393 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
25395 ;; FXSR, XSAVE and XSAVEOPT instructions
25397 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
25399 (define_insn "fxsave"
25400 [(set (match_operand:BLK 0 "memory_operand" "=m")
25401 (unspec_volatile:BLK [(const_int 0)] UNSPECV_FXSAVE))]
25404 [(set_attr "type" "other")
25405 (set_attr "memory" "store")
25406 (set (attr "length")
25407 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
25409 (define_insn "fxsave64"
25410 [(set (match_operand:BLK 0 "memory_operand" "=m")
25411 (unspec_volatile:BLK [(const_int 0)] UNSPECV_FXSAVE64))]
25412 "TARGET_64BIT && TARGET_FXSR"
25414 [(set_attr "type" "other")
25415 (set_attr "memory" "store")
25416 (set (attr "length")
25417 (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
25419 (define_insn "fxrstor"
25420 [(unspec_volatile [(match_operand:BLK 0 "memory_operand" "m")]
25424 [(set_attr "type" "other")
25425 (set_attr "memory" "load")
25426 (set (attr "length")
25427 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
25429 (define_insn "fxrstor64"
25430 [(unspec_volatile [(match_operand:BLK 0 "memory_operand" "m")]
25431 UNSPECV_FXRSTOR64)]
25432 "TARGET_64BIT && TARGET_FXSR"
25434 [(set_attr "type" "other")
25435 (set_attr "memory" "load")
25436 (set (attr "length")
25437 (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
25439 (define_int_iterator ANY_XSAVE
25441 (UNSPECV_XSAVEOPT "TARGET_XSAVEOPT")
25442 (UNSPECV_XSAVEC "TARGET_XSAVEC")
25443 (UNSPECV_XSAVES "TARGET_XSAVES")])
25445 (define_int_iterator ANY_XSAVE64
25447 (UNSPECV_XSAVEOPT64 "TARGET_XSAVEOPT")
25448 (UNSPECV_XSAVEC64 "TARGET_XSAVEC")
25449 (UNSPECV_XSAVES64 "TARGET_XSAVES")])
25451 (define_int_attr xsave
25452 [(UNSPECV_XSAVE "xsave")
25453 (UNSPECV_XSAVE64 "xsave64")
25454 (UNSPECV_XSAVEOPT "xsaveopt")
25455 (UNSPECV_XSAVEOPT64 "xsaveopt64")
25456 (UNSPECV_XSAVEC "xsavec")
25457 (UNSPECV_XSAVEC64 "xsavec64")
25458 (UNSPECV_XSAVES "xsaves")
25459 (UNSPECV_XSAVES64 "xsaves64")])
25461 (define_int_iterator ANY_XRSTOR
25463 (UNSPECV_XRSTORS "TARGET_XSAVES")])
25465 (define_int_iterator ANY_XRSTOR64
25467 (UNSPECV_XRSTORS64 "TARGET_XSAVES")])
25469 (define_int_attr xrstor
25470 [(UNSPECV_XRSTOR "xrstor")
25471 (UNSPECV_XRSTOR64 "xrstor")
25472 (UNSPECV_XRSTORS "xrstors")
25473 (UNSPECV_XRSTORS64 "xrstors")])
25475 (define_insn "<xsave>"
25476 [(set (match_operand:BLK 0 "memory_operand" "=m")
25477 (unspec_volatile:BLK
25478 [(match_operand:DI 1 "register_operand" "A")]
25480 "!TARGET_64BIT && TARGET_XSAVE"
25482 [(set_attr "type" "other")
25483 (set_attr "memory" "store")
25484 (set (attr "length")
25485 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
25487 (define_insn "<xsave>_rex64"
25488 [(set (match_operand:BLK 0 "memory_operand" "=m")
25489 (unspec_volatile:BLK
25490 [(match_operand:SI 1 "register_operand" "a")
25491 (match_operand:SI 2 "register_operand" "d")]
25493 "TARGET_64BIT && TARGET_XSAVE"
25495 [(set_attr "type" "other")
25496 (set_attr "memory" "store")
25497 (set (attr "length")
25498 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
25500 (define_insn "<xsave>"
25501 [(set (match_operand:BLK 0 "memory_operand" "=m")
25502 (unspec_volatile:BLK
25503 [(match_operand:SI 1 "register_operand" "a")
25504 (match_operand:SI 2 "register_operand" "d")]
25506 "TARGET_64BIT && TARGET_XSAVE"
25508 [(set_attr "type" "other")
25509 (set_attr "memory" "store")
25510 (set (attr "length")
25511 (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
25513 (define_insn "<xrstor>"
25514 [(unspec_volatile:BLK
25515 [(match_operand:BLK 0 "memory_operand" "m")
25516 (match_operand:DI 1 "register_operand" "A")]
25518 "!TARGET_64BIT && TARGET_XSAVE"
25520 [(set_attr "type" "other")
25521 (set_attr "memory" "load")
25522 (set (attr "length")
25523 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
25525 (define_insn "<xrstor>_rex64"
25526 [(unspec_volatile:BLK
25527 [(match_operand:BLK 0 "memory_operand" "m")
25528 (match_operand:SI 1 "register_operand" "a")
25529 (match_operand:SI 2 "register_operand" "d")]
25531 "TARGET_64BIT && TARGET_XSAVE"
25533 [(set_attr "type" "other")
25534 (set_attr "memory" "load")
25535 (set (attr "length")
25536 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
25538 (define_insn "<xrstor>64"
25539 [(unspec_volatile:BLK
25540 [(match_operand:BLK 0 "memory_operand" "m")
25541 (match_operand:SI 1 "register_operand" "a")
25542 (match_operand:SI 2 "register_operand" "d")]
25544 "TARGET_64BIT && TARGET_XSAVE"
25546 [(set_attr "type" "other")
25547 (set_attr "memory" "load")
25548 (set (attr "length")
25549 (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
25551 (define_insn "xsetbv"
25552 [(unspec_volatile:SI
25553 [(match_operand:SI 0 "register_operand" "c")
25554 (match_operand:DI 1 "register_operand" "A")]
25556 "!TARGET_64BIT && TARGET_XSAVE"
25558 [(set_attr "type" "other")])
25560 (define_insn "xsetbv_rex64"
25561 [(unspec_volatile:SI
25562 [(match_operand:SI 0 "register_operand" "c")
25563 (match_operand:SI 1 "register_operand" "a")
25564 (match_operand:SI 2 "register_operand" "d")]
25566 "TARGET_64BIT && TARGET_XSAVE"
25568 [(set_attr "type" "other")])
25570 (define_insn "xgetbv"
25571 [(set (match_operand:DI 0 "register_operand" "=A")
25572 (unspec_volatile:DI [(match_operand:SI 1 "register_operand" "c")]
25574 "!TARGET_64BIT && TARGET_XSAVE"
25576 [(set_attr "type" "other")])
25578 (define_insn "xgetbv_rex64"
25579 [(set (match_operand:DI 0 "register_operand" "=a")
25580 (unspec_volatile:DI [(match_operand:SI 2 "register_operand" "c")]
25582 (set (match_operand:DI 1 "register_operand" "=d")
25583 (unspec_volatile:DI [(match_dup 2)] UNSPECV_XGETBV))]
25584 "TARGET_64BIT && TARGET_XSAVE"
25586 [(set_attr "type" "other")])
25588 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
25590 ;; Floating-point instructions for atomic compound assignments
25592 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
25594 ; Clobber all floating-point registers on environment save and restore
25595 ; to ensure that the TOS value saved at fnstenv is valid after fldenv.
25596 (define_insn "fnstenv"
25597 [(set (match_operand:BLK 0 "memory_operand" "=m")
25598 (unspec_volatile:BLK [(const_int 0)] UNSPECV_FNSTENV))
25599 (clobber (reg:XF ST0_REG))
25600 (clobber (reg:XF ST1_REG))
25601 (clobber (reg:XF ST2_REG))
25602 (clobber (reg:XF ST3_REG))
25603 (clobber (reg:XF ST4_REG))
25604 (clobber (reg:XF ST5_REG))
25605 (clobber (reg:XF ST6_REG))
25606 (clobber (reg:XF ST7_REG))]
25609 [(set_attr "type" "other")
25610 (set_attr "memory" "store")
25611 (set (attr "length")
25612 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))])
25614 (define_insn "fldenv"
25615 [(unspec_volatile [(match_operand:BLK 0 "memory_operand" "m")]
25617 (clobber (reg:XF ST0_REG))
25618 (clobber (reg:XF ST1_REG))
25619 (clobber (reg:XF ST2_REG))
25620 (clobber (reg:XF ST3_REG))
25621 (clobber (reg:XF ST4_REG))
25622 (clobber (reg:XF ST5_REG))
25623 (clobber (reg:XF ST6_REG))
25624 (clobber (reg:XF ST7_REG))]
25627 [(set_attr "type" "other")
25628 (set_attr "memory" "load")
25629 (set (attr "length")
25630 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))])
25632 (define_insn "fnstsw"
25633 [(set (match_operand:HI 0 "nonimmediate_operand" "=a,m")
25634 (unspec_volatile:HI [(const_int 0)] UNSPECV_FNSTSW))]
25637 [(set_attr "type" "other,other")
25638 (set_attr "memory" "none,store")
25639 (set (attr "length")
25640 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))])
25642 (define_insn "fnclex"
25643 [(unspec_volatile [(const_int 0)] UNSPECV_FNCLEX)]
25646 [(set_attr "type" "other")
25647 (set_attr "memory" "none")
25648 (set_attr "length" "2")])
25650 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
25652 ;; LWP instructions
25654 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
25656 (define_insn "@lwp_llwpcb<mode>"
25657 [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
25658 UNSPECV_LLWP_INTRINSIC)]
25661 [(set_attr "type" "lwp")
25662 (set_attr "mode" "<MODE>")
25663 (set_attr "length" "5")])
25665 (define_insn "@lwp_slwpcb<mode>"
25666 [(set (match_operand:P 0 "register_operand" "=r")
25667 (unspec_volatile:P [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
25670 [(set_attr "type" "lwp")
25671 (set_attr "mode" "<MODE>")
25672 (set_attr "length" "5")])
25674 (define_insn "@lwp_lwpval<mode>"
25675 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")
25676 (match_operand:SI 1 "nonimmediate_operand" "rm")
25677 (match_operand:SI 2 "const_int_operand")]
25678 UNSPECV_LWPVAL_INTRINSIC)]
25680 "lwpval\t{%2, %1, %0|%0, %1, %2}"
25681 [(set_attr "type" "lwp")
25682 (set_attr "mode" "<MODE>")
25683 (set (attr "length")
25684 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
25686 (define_insn "@lwp_lwpins<mode>"
25687 [(set (reg:CCC FLAGS_REG)
25688 (unspec_volatile:CCC [(match_operand:SWI48 0 "register_operand" "r")
25689 (match_operand:SI 1 "nonimmediate_operand" "rm")
25690 (match_operand:SI 2 "const_int_operand")]
25691 UNSPECV_LWPINS_INTRINSIC))]
25693 "lwpins\t{%2, %1, %0|%0, %1, %2}"
25694 [(set_attr "type" "lwp")
25695 (set_attr "mode" "<MODE>")
25696 (set (attr "length")
25697 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
25699 (define_int_iterator RDFSGSBASE
25703 (define_int_iterator WRFSGSBASE
25707 (define_int_attr fsgs
25708 [(UNSPECV_RDFSBASE "fs")
25709 (UNSPECV_RDGSBASE "gs")
25710 (UNSPECV_WRFSBASE "fs")
25711 (UNSPECV_WRGSBASE "gs")])
25713 (define_insn "rd<fsgs>base<mode>"
25714 [(set (match_operand:SWI48 0 "register_operand" "=r")
25715 (unspec_volatile:SWI48 [(const_int 0)] RDFSGSBASE))]
25716 "TARGET_64BIT && TARGET_FSGSBASE"
25718 [(set_attr "type" "other")
25719 (set_attr "prefix_extra" "2")])
25721 (define_insn "wr<fsgs>base<mode>"
25722 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
25724 "TARGET_64BIT && TARGET_FSGSBASE"
25726 [(set_attr "type" "other")
25727 (set_attr "prefix_extra" "2")])
25729 (define_insn "ptwrite<mode>"
25730 [(unspec_volatile [(match_operand:SWI48 0 "nonimmediate_operand" "rm")]
25734 [(set_attr "type" "other")
25735 (set_attr "prefix_extra" "2")])
25737 (define_insn "@rdrand<mode>"
25738 [(set (match_operand:SWI248 0 "register_operand" "=r")
25739 (unspec_volatile:SWI248 [(const_int 0)] UNSPECV_RDRAND))
25740 (set (reg:CCC FLAGS_REG)
25741 (unspec_volatile:CCC [(const_int 0)] UNSPECV_RDRAND))]
25744 [(set_attr "type" "other")
25745 (set_attr "prefix_extra" "1")])
25747 (define_insn "@rdseed<mode>"
25748 [(set (match_operand:SWI248 0 "register_operand" "=r")
25749 (unspec_volatile:SWI248 [(const_int 0)] UNSPECV_RDSEED))
25750 (set (reg:CCC FLAGS_REG)
25751 (unspec_volatile:CCC [(const_int 0)] UNSPECV_RDSEED))]
25754 [(set_attr "type" "other")
25755 (set_attr "prefix_extra" "1")])
25757 (define_expand "pause"
25758 [(set (match_dup 0)
25759 (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
25762 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
25763 MEM_VOLATILE_P (operands[0]) = 1;
25766 ;; Use "rep; nop", instead of "pause", to support older assemblers.
25767 ;; They have the same encoding.
25768 (define_insn "*pause"
25769 [(set (match_operand:BLK 0)
25770 (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
25773 [(set_attr "length" "2")
25774 (set_attr "memory" "unknown")])
25776 ;; CET instructions
25777 (define_insn "@rdssp<mode>"
25778 [(set (match_operand:SWI48 0 "register_operand" "=r")
25779 (unspec_volatile:SWI48 [(match_operand:SWI48 1 "register_operand" "0")]
25780 UNSPECV_NOP_RDSSP))]
25781 "TARGET_SHSTK || (flag_cf_protection & CF_RETURN)"
25782 "rdssp<mskmodesuffix>\t%0"
25783 [(set_attr "length" "6")
25784 (set_attr "type" "other")])
25786 (define_insn "@incssp<mode>"
25787 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
25789 "TARGET_SHSTK || (flag_cf_protection & CF_RETURN)"
25790 "incssp<mskmodesuffix>\t%0"
25791 [(set_attr "length" "4")
25792 (set_attr "type" "other")])
25794 (define_insn "saveprevssp"
25795 [(unspec_volatile [(const_int 0)] UNSPECV_SAVEPREVSSP)]
25798 [(set_attr "length" "5")
25799 (set_attr "type" "other")])
25801 (define_insn "rstorssp"
25802 [(unspec_volatile [(match_operand:DI 0 "memory_operand" "m")]
25806 [(set_attr "length" "5")
25807 (set_attr "type" "other")])
25809 (define_insn "@wrss<mode>"
25810 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")
25811 (match_operand:SWI48 1 "memory_operand" "m")]
25814 "wrss<mskmodesuffix>\t%0, %1"
25815 [(set_attr "length" "3")
25816 (set_attr "type" "other")])
25818 (define_insn "@wruss<mode>"
25819 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")
25820 (match_operand:SWI48 1 "memory_operand" "m")]
25823 "wruss<mskmodesuffix>\t%0, %1"
25824 [(set_attr "length" "4")
25825 (set_attr "type" "other")])
25827 (define_insn "setssbsy"
25828 [(unspec_volatile [(const_int 0)] UNSPECV_SETSSBSY)]
25831 [(set_attr "length" "4")
25832 (set_attr "type" "other")])
25834 (define_insn "clrssbsy"
25835 [(unspec_volatile [(match_operand:DI 0 "memory_operand" "m")]
25839 [(set_attr "length" "4")
25840 (set_attr "type" "other")])
25842 (define_insn "nop_endbr"
25843 [(unspec_volatile [(const_int 0)] UNSPECV_NOP_ENDBR)]
25844 "(flag_cf_protection & CF_BRANCH)"
25846 return TARGET_64BIT ? "endbr64" : "endbr32";
25848 [(set_attr "length" "4")
25849 (set_attr "length_immediate" "0")
25850 (set_attr "modrm" "0")])
25853 (define_expand "xbegin"
25854 [(set (match_operand:SI 0 "register_operand")
25855 (unspec_volatile:SI [(const_int 0)] UNSPECV_XBEGIN))]
25858 rtx_code_label *label = gen_label_rtx ();
25860 /* xbegin is emitted as jump_insn, so reload won't be able
25861 to reload its operand. Force the value into AX hard register. */
25862 rtx ax_reg = gen_rtx_REG (SImode, AX_REG);
25863 emit_move_insn (ax_reg, constm1_rtx);
25865 emit_jump_insn (gen_xbegin_1 (ax_reg, label));
25867 emit_label (label);
25868 LABEL_NUSES (label) = 1;
25870 emit_move_insn (operands[0], ax_reg);
25875 (define_insn "xbegin_1"
25877 (if_then_else (ne (unspec [(const_int 0)] UNSPEC_XBEGIN_ABORT)
25879 (label_ref (match_operand 1))
25881 (set (match_operand:SI 0 "register_operand" "+a")
25882 (unspec_volatile:SI [(match_dup 0)] UNSPECV_XBEGIN))]
25885 [(set_attr "type" "other")
25886 (set_attr "length" "6")])
25888 (define_insn "xend"
25889 [(unspec_volatile [(const_int 0)] UNSPECV_XEND)]
25892 [(set_attr "type" "other")
25893 (set_attr "length" "3")])
25895 (define_insn "xabort"
25896 [(unspec_volatile [(match_operand:SI 0 "const_0_to_255_operand")]
25900 [(set_attr "type" "other")
25901 (set_attr "length" "3")])
25903 (define_expand "xtest"
25904 [(set (match_operand:QI 0 "register_operand")
25905 (unspec_volatile:QI [(const_int 0)] UNSPECV_XTEST))]
25908 emit_insn (gen_xtest_1 ());
25910 ix86_expand_setcc (operands[0], NE,
25911 gen_rtx_REG (CCZmode, FLAGS_REG), const0_rtx);
25915 (define_insn "xtest_1"
25916 [(set (reg:CCZ FLAGS_REG)
25917 (unspec_volatile:CCZ [(const_int 0)] UNSPECV_XTEST))]
25920 [(set_attr "type" "other")
25921 (set_attr "length" "3")])
25923 (define_insn "clwb"
25924 [(unspec_volatile [(match_operand 0 "address_operand" "p")]
25928 [(set_attr "type" "sse")
25929 (set_attr "atom_sse_attr" "fence")
25930 (set_attr "memory" "unknown")])
25932 (define_insn "clflushopt"
25933 [(unspec_volatile [(match_operand 0 "address_operand" "p")]
25934 UNSPECV_CLFLUSHOPT)]
25935 "TARGET_CLFLUSHOPT"
25937 [(set_attr "type" "sse")
25938 (set_attr "atom_sse_attr" "fence")
25939 (set_attr "memory" "unknown")])
25941 ;; MONITORX and MWAITX
25942 (define_insn "mwaitx"
25943 [(unspec_volatile [(match_operand:SI 0 "register_operand" "c")
25944 (match_operand:SI 1 "register_operand" "a")
25945 (match_operand:SI 2 "register_operand" "b")]
25948 ;; 64bit version is "mwaitx %rax,%rcx,%rbx". But only lower 32bits are used.
25949 ;; Since 32bit register operands are implicitly zero extended to 64bit,
25950 ;; we only need to set up 32bit registers.
25952 [(set_attr "length" "3")])
25954 (define_insn "@monitorx_<mode>"
25955 [(unspec_volatile [(match_operand:P 0 "register_operand" "a")
25956 (match_operand:SI 1 "register_operand" "c")
25957 (match_operand:SI 2 "register_operand" "d")]
25960 ;; 64bit version is "monitorx %rax,%rcx,%rdx". But only lower 32bits in
25961 ;; RCX and RDX are used. Since 32bit register operands are implicitly
25962 ;; zero extended to 64bit, we only need to set up 32bit registers.
25964 [(set (attr "length")
25965 (symbol_ref ("(Pmode != word_mode) + 3")))])
25968 (define_insn "@clzero_<mode>"
25969 [(unspec_volatile [(match_operand: P 0 "register_operand" "a")]
25973 [(set_attr "length" "3")
25974 (set_attr "memory" "unknown")])
25976 ;; RDPKRU and WRPKRU
25978 (define_expand "rdpkru"
25980 [(set (match_operand:SI 0 "register_operand")
25981 (unspec_volatile:SI [(match_dup 1)] UNSPECV_PKU))
25982 (set (match_dup 2) (const_int 0))])]
25985 operands[1] = force_reg (SImode, const0_rtx);
25986 operands[2] = gen_reg_rtx (SImode);
25989 (define_insn "*rdpkru"
25990 [(set (match_operand:SI 0 "register_operand" "=a")
25991 (unspec_volatile:SI [(match_operand:SI 2 "register_operand" "c")]
25993 (set (match_operand:SI 1 "register_operand" "=d")
25997 [(set_attr "type" "other")])
25999 (define_expand "wrpkru"
26000 [(unspec_volatile:SI
26001 [(match_operand:SI 0 "register_operand")
26002 (match_dup 1) (match_dup 2)] UNSPECV_PKU)]
26005 operands[1] = force_reg (SImode, const0_rtx);
26006 operands[2] = force_reg (SImode, const0_rtx);
26009 (define_insn "*wrpkru"
26010 [(unspec_volatile:SI
26011 [(match_operand:SI 0 "register_operand" "a")
26012 (match_operand:SI 1 "register_operand" "d")
26013 (match_operand:SI 2 "register_operand" "c")] UNSPECV_PKU)]
26016 [(set_attr "type" "other")])
26018 (define_insn "rdpid"
26019 [(set (match_operand:SI 0 "register_operand" "=r")
26020 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDPID))]
26021 "!TARGET_64BIT && TARGET_RDPID"
26023 [(set_attr "type" "other")])
26025 (define_insn "rdpid_rex64"
26026 [(set (match_operand:DI 0 "register_operand" "=r")
26027 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDPID))]
26028 "TARGET_64BIT && TARGET_RDPID"
26030 [(set_attr "type" "other")])
26032 ;; Intirinsics for > i486
26034 (define_insn "wbinvd"
26035 [(unspec_volatile [(const_int 0)] UNSPECV_WBINVD)]
26038 [(set_attr "type" "other")])
26040 (define_insn "wbnoinvd"
26041 [(unspec_volatile [(const_int 0)] UNSPECV_WBNOINVD)]
26044 [(set_attr "type" "other")])
26046 ;; MOVDIRI and MOVDIR64B
26048 (define_insn "movdiri<mode>"
26049 [(set (match_operand:SWI48 0 "memory_operand" "=m")
26050 (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")]
26053 "movdiri\t{%1, %0|%0, %1}"
26054 [(set_attr "type" "other")])
26056 (define_insn "@movdir64b_<mode>"
26057 [(set (mem:XI (match_operand:P 0 "register_operand" "r"))
26058 (unspec:XI [(match_operand:XI 1 "memory_operand" "m")]
26059 UNSPEC_MOVDIR64B))]
26061 "movdir64b\t{%1, %0|%0, %1}"
26062 [(set_attr "type" "other")])
26065 (define_int_iterator TSXLDTRK [UNSPECV_XSUSLDTRK UNSPECV_XRESLDTRK])
26066 (define_int_attr tsxldtrk [(UNSPECV_XSUSLDTRK "xsusldtrk")
26067 (UNSPECV_XRESLDTRK "xresldtrk")])
26068 (define_insn "<tsxldtrk>"
26069 [(unspec_volatile [(const_int 0)] TSXLDTRK)]
26072 [(set_attr "type" "other")
26073 (set_attr "length" "4")])
26075 ;; ENQCMD and ENQCMDS
26077 (define_int_iterator ENQCMD [UNSPECV_ENQCMD UNSPECV_ENQCMDS])
26078 (define_int_attr enqcmd_sfx [(UNSPECV_ENQCMD "") (UNSPECV_ENQCMDS "s")])
26080 (define_insn "@enqcmd<enqcmd_sfx>_<mode>"
26081 [(set (reg:CCZ FLAGS_REG)
26082 (unspec_volatile:CCZ [(match_operand:P 0 "register_operand" "r")
26083 (match_operand:XI 1 "memory_operand" "m")]
26086 "enqcmd<enqcmd_sfx>\t{%1, %0|%0, %1}"
26087 [(set_attr "type" "other")])
26090 (define_int_iterator UINTR [UNSPECV_CLUI UNSPECV_STUI])
26091 (define_int_attr uintr [(UNSPECV_CLUI "clui") (UNSPECV_STUI "stui")])
26093 (define_insn "<uintr>"
26094 [(unspec_volatile [(const_int 0)] UINTR)]
26095 "TARGET_UINTR && TARGET_64BIT"
26097 [(set_attr "type" "other")
26098 (set_attr "length" "4")])
26100 (define_insn "testui"
26101 [(set (reg:CCC FLAGS_REG)
26102 (unspec_volatile:CCC [(const_int 0)] UNSPECV_TESTUI))]
26103 "TARGET_UINTR && TARGET_64BIT"
26105 [(set_attr "type" "other")
26106 (set_attr "length" "4")])
26108 (define_insn "senduipi"
26110 [(match_operand:DI 0 "register_operand" "r")]
26112 "TARGET_UINTR && TARGET_64BIT"
26114 [(set_attr "type" "other")
26115 (set_attr "length" "4")])
26119 (define_insn "umwait"
26120 [(set (reg:CCC FLAGS_REG)
26121 (unspec_volatile:CCC [(match_operand:SI 0 "register_operand" "r")
26122 (match_operand:DI 1 "register_operand" "A")]
26124 "!TARGET_64BIT && TARGET_WAITPKG"
26126 [(set_attr "length" "3")])
26128 (define_insn "umwait_rex64"
26129 [(set (reg:CCC FLAGS_REG)
26130 (unspec_volatile:CCC [(match_operand:SI 0 "register_operand" "r")
26131 (match_operand:SI 1 "register_operand" "a")
26132 (match_operand:SI 2 "register_operand" "d")]
26134 "TARGET_64BIT && TARGET_WAITPKG"
26136 [(set_attr "length" "3")])
26138 (define_insn "@umonitor_<mode>"
26139 [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
26143 [(set (attr "length")
26144 (symbol_ref ("(Pmode != word_mode) + 3")))])
26146 (define_insn "tpause"
26147 [(set (reg:CCC FLAGS_REG)
26148 (unspec_volatile:CCC [(match_operand:SI 0 "register_operand" "r")
26149 (match_operand:DI 1 "register_operand" "A")]
26151 "!TARGET_64BIT && TARGET_WAITPKG"
26153 [(set_attr "length" "3")])
26155 (define_insn "tpause_rex64"
26156 [(set (reg:CCC FLAGS_REG)
26157 (unspec_volatile:CCC [(match_operand:SI 0 "register_operand" "r")
26158 (match_operand:SI 1 "register_operand" "a")
26159 (match_operand:SI 2 "register_operand" "d")]
26161 "TARGET_64BIT && TARGET_WAITPKG"
26163 [(set_attr "length" "3")])
26165 (define_insn "cldemote"
26166 [(unspec_volatile[(match_operand 0 "address_operand" "p")]
26170 [(set_attr "type" "other")
26171 (set_attr "memory" "unknown")])
26173 (define_insn "speculation_barrier"
26174 [(unspec_volatile [(const_int 0)] UNSPECV_SPECULATION_BARRIER)]
26177 [(set_attr "type" "other")
26178 (set_attr "length" "3")])
26180 (define_insn "serialize"
26181 [(unspec_volatile [(const_int 0)] UNSPECV_SERIALIZE)]
26184 [(set_attr "type" "other")
26185 (set_attr "length" "3")])
26187 (define_insn "patchable_area"
26188 [(unspec_volatile [(match_operand 0 "const_int_operand")
26189 (match_operand 1 "const_int_operand")]
26190 UNSPECV_PATCHABLE_AREA)]
26193 ix86_output_patchable_area (INTVAL (operands[0]),
26194 INTVAL (operands[1]) != 0);
26197 [(set (attr "length") (symbol_ref "INTVAL (operands[0])"))
26198 (set_attr "length_immediate" "0")
26199 (set_attr "modrm" "0")])
26201 (define_insn "hreset"
26202 [(unspec_volatile [(match_operand:SI 0 "register_operand" "a")]
26206 [(set_attr "type" "other")
26207 (set_attr "length" "4")])
26209 ;; Spaceship optimization
26210 (define_expand "spaceship<mode>3"
26211 [(match_operand:SI 0 "register_operand")
26212 (match_operand:MODEF 1 "cmp_fp_expander_operand")
26213 (match_operand:MODEF 2 "cmp_fp_expander_operand")]
26214 "(TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
26215 && (TARGET_CMOVE || (TARGET_SAHF && TARGET_USE_SAHF))"
26217 ix86_expand_fp_spaceship (operands[0], operands[1], operands[2]);
26221 (define_expand "spaceshipxf3"
26222 [(match_operand:SI 0 "register_operand")
26223 (match_operand:XF 1 "nonmemory_operand")
26224 (match_operand:XF 2 "nonmemory_operand")]
26225 "TARGET_80387 && (TARGET_CMOVE || (TARGET_SAHF && TARGET_USE_SAHF))"
26227 ix86_expand_fp_spaceship (operands[0], operands[1], operands[2]);
26231 ;; Defined because the generic expand_builtin_issignaling for XFmode
26232 ;; only tests for sNaNs, but i387 treats also pseudo numbers as always
26234 (define_expand "issignalingxf2"
26235 [(match_operand:SI 0 "register_operand")
26236 (match_operand:XF 1 "general_operand")]
26239 rtx temp = operands[1];
26242 rtx mem = assign_stack_temp (XFmode, GET_MODE_SIZE (XFmode));
26243 emit_move_insn (mem, temp);
26246 rtx ex = adjust_address (temp, HImode, 8);
26247 rtx hi = adjust_address (temp, SImode, 4);
26248 rtx lo = adjust_address (temp, SImode, 0);
26249 rtx val = GEN_INT (HOST_WIDE_INT_M1U << 30);
26250 rtx mask = GEN_INT (0x7fff);
26251 rtx bit = GEN_INT (HOST_WIDE_INT_1U << 30);
26253 ((ex & mask) && (int) hi >= 0)
26254 || ((ex & mask) == mask && ((hi ^ bit) | ((lo | -lo) >> 31)) > val). */
26255 rtx nlo = expand_unop (SImode, neg_optab, lo, NULL_RTX, 0);
26256 lo = expand_binop (SImode, ior_optab, lo, nlo,
26257 NULL_RTX, 1, OPTAB_LIB_WIDEN);
26258 lo = expand_shift (RSHIFT_EXPR, SImode, lo, 31, NULL_RTX, 1);
26259 temp = expand_binop (SImode, xor_optab, hi, bit,
26260 NULL_RTX, 1, OPTAB_LIB_WIDEN);
26261 temp = expand_binop (SImode, ior_optab, temp, lo,
26262 NULL_RTX, 1, OPTAB_LIB_WIDEN);
26263 temp = emit_store_flag_force (gen_reg_rtx (SImode), GTU, temp, val,
26265 ex = expand_binop (HImode, and_optab, ex, mask,
26266 NULL_RTX, 1, OPTAB_LIB_WIDEN);
26267 rtx temp2 = emit_store_flag_force (gen_reg_rtx (SImode), NE,
26268 ex, const0_rtx, SImode, 1, 1);
26269 ex = emit_store_flag_force (gen_reg_rtx (SImode), EQ,
26270 ex, mask, HImode, 1, 1);
26271 temp = expand_binop (SImode, and_optab, temp, ex,
26272 NULL_RTX, 1, OPTAB_LIB_WIDEN);
26273 rtx temp3 = emit_store_flag_force (gen_reg_rtx (SImode), GE,
26274 hi, const0_rtx, SImode, 0, 1);
26275 temp2 = expand_binop (SImode, and_optab, temp2, temp3,
26276 NULL_RTX, 1, OPTAB_LIB_WIDEN);
26277 temp = expand_binop (SImode, ior_optab, temp, temp2,
26278 NULL_RTX, 1, OPTAB_LIB_WIDEN);
26279 emit_move_insn (operands[0], temp);
26285 (include "sync.md")