1 ;; GCC machine description for IA-32 and x86-64.
2 ;; Copyright (C) 1988-2020 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
117 ;; For SSE/MMX support:
125 ;; Generic math support
128 UNSPEC_IEEE_MIN ; not commutative
129 UNSPEC_IEEE_MAX ; not commutative
131 ;; x87 Floating point
144 UNSPEC_FRNDINT_ROUNDEVEN
151 ;; x87 Double output FP
176 ;; For LZCNT suppoprt
188 UNSPEC_INTERRUPT_RETURN
190 ;; For MOVDIRI and MOVDIR64B support
195 (define_c_enum "unspecv" [
199 UNSPECV_PROBE_STACK_RANGE
202 UNSPECV_SPLIT_STACK_RETURN
208 UNSPECV_LLWP_INTRINSIC
209 UNSPECV_SLWP_INTRINSIC
210 UNSPECV_LWPVAL_INTRINSIC
211 UNSPECV_LWPINS_INTRINSIC
237 ;; For atomic compound assignments.
243 ;; For RDRAND support
246 ;; For RDSEED support
260 ;; For CLFLUSHOPT support
263 ;; For MONITORX and MWAITX support
267 ;; For CLZERO support
270 ;; For RDPKRU and WRPKRU support
287 ;; For TSXLDTRK support
291 ;; For WAITPKG support
302 ;; For CLDEMOTE support
305 ;; For Speculation Barrier support
306 UNSPECV_SPECULATION_BARRIER
310 ;; For ENQCMD and ENQCMDS support
314 ;; For SERIALIZE support
317 ;; For patchable area support
318 UNSPECV_PATCHABLE_AREA
320 ;; For HRESET support
324 ;; Constants to represent rounding modes in the ROUND instruction
326 [(ROUND_ROUNDEVEN 0x0)
334 ;; Constants to represent AVX512F embeded rounding
336 [(ROUND_NEAREST_INT 0)
344 ;; Constants to represent pcomtrue/pcomfalse variants
354 ;; Constants used in the XOP pperm instruction
356 [(PPERM_SRC 0x00) /* copy source */
357 (PPERM_INVERT 0x20) /* invert source */
358 (PPERM_REVERSE 0x40) /* bit reverse source */
359 (PPERM_REV_INV 0x60) /* bit reverse & invert src */
360 (PPERM_ZERO 0x80) /* all 0's */
361 (PPERM_ONES 0xa0) /* all 1's */
362 (PPERM_SIGN 0xc0) /* propagate sign bit */
363 (PPERM_INV_SIGN 0xe0) /* invert & propagate sign */
364 (PPERM_SRC1 0x00) /* use first source byte */
365 (PPERM_SRC2 0x10) /* use second source byte */
368 ;; Registers by name.
446 (FIRST_PSEUDO_REG 76)
449 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
452 ;; In C guard expressions, put expressions which may be compile-time
453 ;; constants first. This allows for better optimization. For
454 ;; example, write "TARGET_64BIT && reload_completed", not
455 ;; "reload_completed && TARGET_64BIT".
459 (define_attr "cpu" "none,pentium,pentiumpro,geode,k6,athlon,k8,core2,nehalem,
460 atom,slm,glm,haswell,generic,amdfam10,bdver1,bdver2,bdver3,
461 bdver4,btver2,znver1,znver2"
462 (const (symbol_ref "ix86_schedule")))
464 ;; A basic instruction type. Refinements due to arguments to be
465 ;; provided in other attributes.
468 alu,alu1,negnot,imov,imovx,lea,
469 incdec,ishift,ishiftx,ishift1,rotate,rotatex,rotate1,
470 imul,imulx,idiv,icmp,test,ibr,setcc,icmov,
471 push,pop,call,callv,leave,
473 fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,
474 fxch,fistp,fisttp,frndint,
475 sse,ssemov,sseadd,sseadd1,sseiadd,sseiadd1,
476 ssemul,sseimul,ssediv,sselog,sselog1,
477 sseishft,sseishft1,ssecmp,ssecomi,
478 ssecvt,ssecvt1,sseicvt,sseins,
479 sseshuf,sseshuf1,ssemuladd,sse4arg,
481 mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
482 (const_string "other"))
484 ;; Main data type used by the insn
486 "unknown,none,QI,HI,SI,DI,TI,OI,XI,SF,DF,XF,TF,V16SF,V8SF,V4DF,V4SF,
488 (const_string "unknown"))
490 ;; The CPU unit operations uses.
491 (define_attr "unit" "integer,i387,sse,mmx,unknown"
492 (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,
493 fxch,fistp,fisttp,frndint")
494 (const_string "i387")
495 (eq_attr "type" "sse,ssemov,sseadd,sseadd1,sseiadd,sseiadd1,
496 ssemul,sseimul,ssediv,sselog,sselog1,
497 sseishft,sseishft1,ssecmp,ssecomi,
498 ssecvt,ssecvt1,sseicvt,sseins,
499 sseshuf,sseshuf1,ssemuladd,sse4arg,mskmov")
501 (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
503 (eq_attr "type" "other")
504 (const_string "unknown")]
505 (const_string "integer")))
507 ;; The (bounding maximum) length of an instruction immediate.
508 (define_attr "length_immediate" ""
509 (cond [(eq_attr "type" "incdec,setcc,icmov,str,lea,other,multi,idiv,leave,
510 bitmanip,imulx,msklog,mskmov")
512 (eq_attr "unit" "i387,sse,mmx")
514 (eq_attr "type" "alu,alu1,negnot,imovx,ishift,ishiftx,ishift1,
515 rotate,rotatex,rotate1,imul,icmp,push,pop")
516 (symbol_ref "ix86_attr_length_immediate_default (insn, true)")
517 (eq_attr "type" "imov,test")
518 (symbol_ref "ix86_attr_length_immediate_default (insn, false)")
519 (eq_attr "type" "call")
520 (if_then_else (match_operand 0 "constant_call_address_operand")
523 (eq_attr "type" "callv")
524 (if_then_else (match_operand 1 "constant_call_address_operand")
527 ;; We don't know the size before shorten_branches. Expect
528 ;; the instruction to fit for better scheduling.
529 (eq_attr "type" "ibr")
532 (symbol_ref "/* Update immediate_length and other attributes! */
533 gcc_unreachable (),1")))
535 ;; The (bounding maximum) length of an instruction address.
536 (define_attr "length_address" ""
537 (cond [(eq_attr "type" "str,other,multi,fxch")
539 (and (eq_attr "type" "call")
540 (match_operand 0 "constant_call_address_operand"))
542 (and (eq_attr "type" "callv")
543 (match_operand 1 "constant_call_address_operand"))
546 (symbol_ref "ix86_attr_length_address_default (insn)")))
548 ;; Set when length prefix is used.
549 (define_attr "prefix_data16" ""
550 (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
552 (eq_attr "mode" "HI")
554 (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF,TI"))
559 ;; Set when string REP prefix is used.
560 (define_attr "prefix_rep" ""
561 (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
563 (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
568 ;; Set when 0f opcode prefix is used.
569 (define_attr "prefix_0f" ""
571 (ior (eq_attr "type" "imovx,setcc,icmov,bitmanip,msklog,mskmov")
572 (eq_attr "unit" "sse,mmx"))
576 ;; Set when REX opcode prefix is used.
577 (define_attr "prefix_rex" ""
578 (cond [(not (match_test "TARGET_64BIT"))
580 (and (eq_attr "mode" "DI")
581 (and (eq_attr "type" "!push,pop,call,callv,leave,ibr")
582 (eq_attr "unit" "!mmx")))
584 (and (eq_attr "mode" "QI")
585 (match_test "x86_extended_QIreg_mentioned_p (insn)"))
587 (match_test "x86_extended_reg_mentioned_p (insn)")
589 (and (eq_attr "type" "imovx")
590 (match_operand:QI 1 "ext_QIreg_operand"))
595 ;; There are also additional prefixes in 3DNOW, SSSE3.
596 ;; ssemuladd,sse4arg default to 0f24/0f25 and DREX byte,
597 ;; sseiadd1,ssecvt1 to 0f7a with no DREX byte.
598 ;; 3DNOW has 0f0f prefix, SSSE3 and SSE4_{1,2} 0f38/0f3a.
599 (define_attr "prefix_extra" ""
600 (cond [(eq_attr "type" "ssemuladd,sse4arg")
602 (eq_attr "type" "sseiadd1,ssecvt1")
607 ;; Prefix used: original, VEX or maybe VEX.
608 (define_attr "prefix" "orig,vex,maybe_vex,evex,maybe_evex"
609 (cond [(eq_attr "mode" "OI,V8SF,V4DF")
611 (eq_attr "mode" "XI,V16SF,V8DF")
612 (const_string "evex")
614 (const_string "orig")))
616 ;; VEX W bit is used.
617 (define_attr "prefix_vex_w" "" (const_int 0))
619 ;; The length of VEX prefix
620 ;; Only instructions with 0f prefix can have 2 byte VEX prefix,
621 ;; 0f38/0f3a prefixes can't. In i386.md 0f3[8a] is
622 ;; still prefix_0f 1, with prefix_extra 1.
623 (define_attr "length_vex" ""
624 (if_then_else (and (eq_attr "prefix_0f" "1")
625 (eq_attr "prefix_extra" "0"))
626 (if_then_else (eq_attr "prefix_vex_w" "1")
627 (symbol_ref "ix86_attr_length_vex_default (insn, true, true)")
628 (symbol_ref "ix86_attr_length_vex_default (insn, true, false)"))
629 (if_then_else (eq_attr "prefix_vex_w" "1")
630 (symbol_ref "ix86_attr_length_vex_default (insn, false, true)")
631 (symbol_ref "ix86_attr_length_vex_default (insn, false, false)"))))
633 ;; 4-bytes evex prefix and 1 byte opcode.
634 (define_attr "length_evex" "" (const_int 5))
636 ;; Set when modrm byte is used.
637 (define_attr "modrm" ""
638 (cond [(eq_attr "type" "str,leave")
640 (eq_attr "unit" "i387")
642 (and (eq_attr "type" "incdec")
643 (and (not (match_test "TARGET_64BIT"))
644 (ior (match_operand:SI 1 "register_operand")
645 (match_operand:HI 1 "register_operand"))))
647 (and (eq_attr "type" "push")
648 (not (match_operand 1 "memory_operand")))
650 (and (eq_attr "type" "pop")
651 (not (match_operand 0 "memory_operand")))
653 (and (eq_attr "type" "imov")
654 (and (not (eq_attr "mode" "DI"))
655 (ior (and (match_operand 0 "register_operand")
656 (match_operand 1 "immediate_operand"))
657 (ior (and (match_operand 0 "ax_reg_operand")
658 (match_operand 1 "memory_displacement_only_operand"))
659 (and (match_operand 0 "memory_displacement_only_operand")
660 (match_operand 1 "ax_reg_operand"))))))
662 (and (eq_attr "type" "call")
663 (match_operand 0 "constant_call_address_operand"))
665 (and (eq_attr "type" "callv")
666 (match_operand 1 "constant_call_address_operand"))
668 (and (eq_attr "type" "alu,alu1,icmp,test")
669 (match_operand 0 "ax_reg_operand"))
670 (symbol_ref "(get_attr_length_immediate (insn) <= (get_attr_mode (insn) != MODE_QI))")
674 ;; The (bounding maximum) length of an instruction in bytes.
675 ;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
676 ;; Later we may want to split them and compute proper length as for
678 (define_attr "length" ""
679 (cond [(eq_attr "type" "other,multi,fistp,frndint")
681 (eq_attr "type" "fcmp")
683 (eq_attr "unit" "i387")
685 (plus (attr "prefix_data16")
686 (attr "length_address")))
687 (ior (eq_attr "prefix" "evex")
688 (and (ior (eq_attr "prefix" "maybe_evex")
689 (eq_attr "prefix" "maybe_vex"))
690 (match_test "TARGET_AVX512F")))
691 (plus (attr "length_evex")
692 (plus (attr "length_immediate")
694 (attr "length_address"))))
695 (ior (eq_attr "prefix" "vex")
696 (and (ior (eq_attr "prefix" "maybe_vex")
697 (eq_attr "prefix" "maybe_evex"))
698 (match_test "TARGET_AVX")))
699 (plus (attr "length_vex")
700 (plus (attr "length_immediate")
702 (attr "length_address"))))]
703 (plus (plus (attr "modrm")
704 (plus (attr "prefix_0f")
705 (plus (attr "prefix_rex")
706 (plus (attr "prefix_extra")
708 (plus (attr "prefix_rep")
709 (plus (attr "prefix_data16")
710 (plus (attr "length_immediate")
711 (attr "length_address")))))))
713 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
714 ;; `store' if there is a simple memory reference therein, or `unknown'
715 ;; if the instruction is complex.
717 (define_attr "memory" "none,load,store,both,unknown"
718 (cond [(eq_attr "type" "other,multi,str,lwp")
719 (const_string "unknown")
720 (eq_attr "type" "lea,fcmov,fpspc")
721 (const_string "none")
722 (eq_attr "type" "fistp,leave")
723 (const_string "both")
724 (eq_attr "type" "frndint")
725 (const_string "load")
726 (eq_attr "type" "push")
727 (if_then_else (match_operand 1 "memory_operand")
728 (const_string "both")
729 (const_string "store"))
730 (eq_attr "type" "pop")
731 (if_then_else (match_operand 0 "memory_operand")
732 (const_string "both")
733 (const_string "load"))
734 (eq_attr "type" "setcc")
735 (if_then_else (match_operand 0 "memory_operand")
736 (const_string "store")
737 (const_string "none"))
738 (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
739 (if_then_else (ior (match_operand 0 "memory_operand")
740 (match_operand 1 "memory_operand"))
741 (const_string "load")
742 (const_string "none"))
743 (eq_attr "type" "ibr")
744 (if_then_else (match_operand 0 "memory_operand")
745 (const_string "load")
746 (const_string "none"))
747 (eq_attr "type" "call")
748 (if_then_else (match_operand 0 "constant_call_address_operand")
749 (const_string "none")
750 (const_string "load"))
751 (eq_attr "type" "callv")
752 (if_then_else (match_operand 1 "constant_call_address_operand")
753 (const_string "none")
754 (const_string "load"))
755 (and (eq_attr "type" "alu1,negnot,ishift1,rotate1,sselog1,sseshuf1")
756 (match_operand 1 "memory_operand"))
757 (const_string "both")
758 (and (match_operand 0 "memory_operand")
759 (match_operand 1 "memory_operand"))
760 (const_string "both")
761 (match_operand 0 "memory_operand")
762 (const_string "store")
763 (match_operand 1 "memory_operand")
764 (const_string "load")
766 "!alu1,negnot,ishift1,rotate1,
767 imov,imovx,icmp,test,bitmanip,
769 sse,ssemov,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,
770 sselog1,sseshuf1,sseadd1,sseiadd1,sseishft1,
771 mmx,mmxmov,mmxcmp,mmxcvt,mskmov,msklog")
772 (match_operand 2 "memory_operand"))
773 (const_string "load")
774 (and (eq_attr "type" "icmov,ssemuladd,sse4arg")
775 (match_operand 3 "memory_operand"))
776 (const_string "load")
778 (const_string "none")))
780 ;; Indicates if an instruction has both an immediate and a displacement.
782 (define_attr "imm_disp" "false,true,unknown"
783 (cond [(eq_attr "type" "other,multi")
784 (const_string "unknown")
785 (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
786 (and (match_operand 0 "memory_displacement_operand")
787 (match_operand 1 "immediate_operand")))
788 (const_string "true")
789 (and (eq_attr "type" "alu,ishift,ishiftx,rotate,rotatex,imul,idiv")
790 (and (match_operand 0 "memory_displacement_operand")
791 (match_operand 2 "immediate_operand")))
792 (const_string "true")
794 (const_string "false")))
796 ;; Indicates if an FP operation has an integer source.
798 (define_attr "fp_int_src" "false,true"
799 (const_string "false"))
801 ;; Defines rounding mode of an FP operation.
803 (define_attr "i387_cw" "roundeven,floor,ceil,trunc,uninitialized,any"
804 (const_string "any"))
806 ;; Define attribute to indicate AVX insns with partial XMM register update.
807 (define_attr "avx_partial_xmm_update" "false,true"
808 (const_string "false"))
810 ;; Define attribute to classify add/sub insns that consumes carry flag (CF)
811 (define_attr "use_carry" "0,1" (const_string "0"))
813 ;; Define attribute to indicate unaligned ssemov insns
814 (define_attr "movu" "0,1" (const_string "0"))
816 ;; Used to control the "enabled" attribute on a per-instruction basis.
817 (define_attr "isa" "base,x64,x64_sse2,x64_sse4,x64_sse4_noavx,x64_avx,nox64,
818 sse_noavx,sse2,sse2_noavx,sse3,sse3_noavx,sse4,sse4_noavx,
819 avx,noavx,avx2,noavx2,bmi,bmi2,fma4,fma,avx512f,noavx512f,
820 avx512bw,noavx512bw,avx512dq,noavx512dq,
821 avx512vl,noavx512vl,x64_avx512dq,x64_avx512bw"
822 (const_string "base"))
824 ;; Define instruction set of MMX instructions
825 (define_attr "mmx_isa" "base,native,sse,sse_noavx,avx"
826 (const_string "base"))
828 (define_attr "enabled" ""
829 (cond [(eq_attr "isa" "x64") (symbol_ref "TARGET_64BIT")
830 (eq_attr "isa" "x64_sse2")
831 (symbol_ref "TARGET_64BIT && TARGET_SSE2")
832 (eq_attr "isa" "x64_sse4")
833 (symbol_ref "TARGET_64BIT && TARGET_SSE4_1")
834 (eq_attr "isa" "x64_sse4_noavx")
835 (symbol_ref "TARGET_64BIT && TARGET_SSE4_1 && !TARGET_AVX")
836 (eq_attr "isa" "x64_avx")
837 (symbol_ref "TARGET_64BIT && TARGET_AVX")
838 (eq_attr "isa" "x64_avx512dq")
839 (symbol_ref "TARGET_64BIT && TARGET_AVX512DQ")
840 (eq_attr "isa" "x64_avx512bw")
841 (symbol_ref "TARGET_64BIT && TARGET_AVX512BW")
842 (eq_attr "isa" "nox64") (symbol_ref "!TARGET_64BIT")
843 (eq_attr "isa" "sse2") (symbol_ref "TARGET_SSE2")
844 (eq_attr "isa" "sse_noavx")
845 (symbol_ref "TARGET_SSE && !TARGET_AVX")
846 (eq_attr "isa" "sse2_noavx")
847 (symbol_ref "TARGET_SSE2 && !TARGET_AVX")
848 (eq_attr "isa" "sse3") (symbol_ref "TARGET_SSE3")
849 (eq_attr "isa" "sse3_noavx")
850 (symbol_ref "TARGET_SSE3 && !TARGET_AVX")
851 (eq_attr "isa" "sse4") (symbol_ref "TARGET_SSE4_1")
852 (eq_attr "isa" "sse4_noavx")
853 (symbol_ref "TARGET_SSE4_1 && !TARGET_AVX")
854 (eq_attr "isa" "avx") (symbol_ref "TARGET_AVX")
855 (eq_attr "isa" "noavx") (symbol_ref "!TARGET_AVX")
856 (eq_attr "isa" "avx2") (symbol_ref "TARGET_AVX2")
857 (eq_attr "isa" "noavx2") (symbol_ref "!TARGET_AVX2")
858 (eq_attr "isa" "bmi") (symbol_ref "TARGET_BMI")
859 (eq_attr "isa" "bmi2") (symbol_ref "TARGET_BMI2")
860 (eq_attr "isa" "fma4") (symbol_ref "TARGET_FMA4")
861 (eq_attr "isa" "fma") (symbol_ref "TARGET_FMA")
862 (eq_attr "isa" "avx512f") (symbol_ref "TARGET_AVX512F")
863 (eq_attr "isa" "noavx512f") (symbol_ref "!TARGET_AVX512F")
864 (eq_attr "isa" "avx512bw") (symbol_ref "TARGET_AVX512BW")
865 (eq_attr "isa" "noavx512bw") (symbol_ref "!TARGET_AVX512BW")
866 (eq_attr "isa" "avx512dq") (symbol_ref "TARGET_AVX512DQ")
867 (eq_attr "isa" "noavx512dq") (symbol_ref "!TARGET_AVX512DQ")
868 (eq_attr "isa" "avx512vl") (symbol_ref "TARGET_AVX512VL")
869 (eq_attr "isa" "noavx512vl") (symbol_ref "!TARGET_AVX512VL")
871 (eq_attr "mmx_isa" "native")
872 (symbol_ref "!TARGET_MMX_WITH_SSE")
873 (eq_attr "mmx_isa" "sse")
874 (symbol_ref "TARGET_MMX_WITH_SSE")
875 (eq_attr "mmx_isa" "sse_noavx")
876 (symbol_ref "TARGET_MMX_WITH_SSE && !TARGET_AVX")
877 (eq_attr "mmx_isa" "avx")
878 (symbol_ref "TARGET_MMX_WITH_SSE && TARGET_AVX")
882 (define_attr "preferred_for_size" "" (const_int 1))
883 (define_attr "preferred_for_speed" "" (const_int 1))
885 ;; Describe a user's asm statement.
886 (define_asm_attributes
887 [(set_attr "length" "128")
888 (set_attr "type" "multi")])
890 (define_code_iterator plusminus [plus minus])
892 (define_code_iterator sat_plusminus [ss_plus us_plus ss_minus us_minus])
894 (define_code_iterator multdiv [mult div])
896 ;; Base name for define_insn
897 (define_code_attr plusminus_insn
898 [(plus "add") (ss_plus "ssadd") (us_plus "usadd")
899 (minus "sub") (ss_minus "sssub") (us_minus "ussub")])
901 ;; Base name for insn mnemonic.
902 (define_code_attr plusminus_mnemonic
903 [(plus "add") (ss_plus "adds") (us_plus "addus")
904 (minus "sub") (ss_minus "subs") (us_minus "subus")])
905 (define_code_attr multdiv_mnemonic
906 [(mult "mul") (div "div")])
908 ;; Mark commutative operators as such in constraints.
909 (define_code_attr comm [(plus "%") (ss_plus "%") (us_plus "%")
910 (minus "") (ss_minus "") (us_minus "")])
912 ;; Mapping of max and min
913 (define_code_iterator maxmin [smax smin umax umin])
915 ;; Mapping of signed max and min
916 (define_code_iterator smaxmin [smax smin])
918 ;; Mapping of unsigned max and min
919 (define_code_iterator umaxmin [umax umin])
921 ;; Base name for integer and FP insn mnemonic
922 (define_code_attr maxmin_int [(smax "maxs") (smin "mins")
923 (umax "maxu") (umin "minu")])
924 (define_code_attr maxmin_float [(smax "max") (smin "min")])
926 (define_int_iterator IEEE_MAXMIN
930 (define_int_attr ieee_maxmin
931 [(UNSPEC_IEEE_MAX "max")
932 (UNSPEC_IEEE_MIN "min")])
934 ;; Mapping of logic operators
935 (define_code_iterator any_logic [and ior xor])
936 (define_code_iterator any_or [ior xor])
937 (define_code_iterator fpint_logic [and xor])
939 ;; Base name for insn mnemonic.
940 (define_code_attr logic [(and "and") (ior "or") (xor "xor")])
942 ;; Mapping of logic-shift operators
943 (define_code_iterator any_lshift [ashift lshiftrt])
945 ;; Mapping of shift-right operators
946 (define_code_iterator any_shiftrt [lshiftrt ashiftrt])
948 ;; Mapping of all shift operators
949 (define_code_iterator any_shift [ashift lshiftrt ashiftrt])
951 ;; Base name for define_insn
952 (define_code_attr shift_insn
953 [(ashift "ashl") (lshiftrt "lshr") (ashiftrt "ashr")])
955 ;; Base name for insn mnemonic.
956 (define_code_attr shift [(ashift "sll") (lshiftrt "shr") (ashiftrt "sar")])
957 (define_code_attr vshift [(ashift "sll") (lshiftrt "srl") (ashiftrt "sra")])
959 ;; Mapping of rotate operators
960 (define_code_iterator any_rotate [rotate rotatert])
962 ;; Base name for define_insn
963 (define_code_attr rotate_insn [(rotate "rotl") (rotatert "rotr")])
965 ;; Base name for insn mnemonic.
966 (define_code_attr rotate [(rotate "rol") (rotatert "ror")])
968 ;; Mapping of abs neg operators
969 (define_code_iterator absneg [abs neg])
971 ;; Mapping of abs neg operators to logic operation
972 (define_code_attr absneg_op [(abs "and") (neg "xor")])
974 ;; Base name for x87 insn mnemonic.
975 (define_code_attr absneg_mnemonic [(abs "fabs") (neg "fchs")])
977 ;; Used in signed and unsigned widening multiplications.
978 (define_code_iterator any_extend [sign_extend zero_extend])
980 ;; Prefix for insn menmonic.
981 (define_code_attr sgnprefix [(sign_extend "i") (zero_extend "")
982 (div "i") (udiv "")])
983 ;; Prefix for define_insn
984 (define_code_attr s [(sign_extend "s") (zero_extend "u")])
985 (define_code_attr u [(sign_extend "") (zero_extend "u")
986 (div "") (udiv "u")])
987 (define_code_attr u_bool [(sign_extend "false") (zero_extend "true")
988 (div "false") (udiv "true")])
990 ;; Used in signed and unsigned truncations.
991 (define_code_iterator any_truncate [ss_truncate truncate us_truncate])
992 ;; Instruction suffix for truncations.
993 (define_code_attr trunsuffix [(ss_truncate "s") (truncate "") (us_truncate "us")])
995 ;; Used in signed and unsigned fix.
996 (define_code_iterator any_fix [fix unsigned_fix])
997 (define_code_attr fixsuffix [(fix "") (unsigned_fix "u")])
998 (define_code_attr fixunssuffix [(fix "") (unsigned_fix "uns")])
999 (define_code_attr fixprefix [(fix "s") (unsigned_fix "u")])
1001 ;; Used in signed and unsigned float.
1002 (define_code_iterator any_float [float unsigned_float])
1003 (define_code_attr floatsuffix [(float "") (unsigned_float "u")])
1004 (define_code_attr floatunssuffix [(float "") (unsigned_float "uns")])
1005 (define_code_attr floatprefix [(float "s") (unsigned_float "u")])
1007 ;; All integer modes.
1008 (define_mode_iterator SWI1248x [QI HI SI DI])
1010 ;; All integer modes without QImode.
1011 (define_mode_iterator SWI248x [HI SI DI])
1013 ;; All integer modes without QImode and HImode.
1014 (define_mode_iterator SWI48x [SI DI])
1016 ;; All integer modes without SImode and DImode.
1017 (define_mode_iterator SWI12 [QI HI])
1019 ;; All integer modes without DImode.
1020 (define_mode_iterator SWI124 [QI HI SI])
1022 ;; All integer modes without QImode and DImode.
1023 (define_mode_iterator SWI24 [HI SI])
1025 ;; Single word integer modes.
1026 (define_mode_iterator SWI [QI HI SI (DI "TARGET_64BIT")])
1028 ;; Single word integer modes without QImode.
1029 (define_mode_iterator SWI248 [HI SI (DI "TARGET_64BIT")])
1031 ;; Single word integer modes without QImode and HImode.
1032 (define_mode_iterator SWI48 [SI (DI "TARGET_64BIT")])
1034 ;; All math-dependant single and double word integer modes.
1035 (define_mode_iterator SDWIM [(QI "TARGET_QIMODE_MATH")
1036 (HI "TARGET_HIMODE_MATH")
1037 SI DI (TI "TARGET_64BIT")])
1039 ;; Math-dependant single word integer modes.
1040 (define_mode_iterator SWIM [(QI "TARGET_QIMODE_MATH")
1041 (HI "TARGET_HIMODE_MATH")
1042 SI (DI "TARGET_64BIT")])
1044 ;; Math-dependant integer modes without DImode.
1045 (define_mode_iterator SWIM124 [(QI "TARGET_QIMODE_MATH")
1046 (HI "TARGET_HIMODE_MATH")
1049 ;; Math-dependant integer modes with DImode (enabled for 32bit with STV).
1050 (define_mode_iterator SWIM1248s
1051 [(QI "TARGET_QIMODE_MATH")
1052 (HI "TARGET_HIMODE_MATH")
1053 SI (DI "TARGET_64BIT || (TARGET_STV && TARGET_SSE2)")])
1055 ;; Math-dependant single word integer modes without QImode.
1056 (define_mode_iterator SWIM248 [(HI "TARGET_HIMODE_MATH")
1057 SI (DI "TARGET_64BIT")])
1059 ;; Double word integer modes.
1060 (define_mode_iterator DWI [(DI "!TARGET_64BIT")
1061 (TI "TARGET_64BIT")])
1063 ;; SWI and DWI together.
1064 (define_mode_iterator SWIDWI [QI HI SI DI (TI "TARGET_64BIT")])
1066 ;; SWI48 and DWI together.
1067 (define_mode_iterator SWI48DWI [SI DI (TI "TARGET_64BIT")])
1069 ;; GET_MODE_SIZE for selected modes. As GET_MODE_SIZE is not
1070 ;; compile time constant, it is faster to use <MODE_SIZE> than
1071 ;; GET_MODE_SIZE (<MODE>mode). For XFmode which depends on
1072 ;; command line options just use GET_MODE_SIZE macro.
1073 (define_mode_attr MODE_SIZE [(QI "1") (HI "2") (SI "4") (DI "8") (TI "16")
1074 (SF "4") (DF "8") (XF "GET_MODE_SIZE (XFmode)")
1075 (V16QI "16") (V32QI "32") (V64QI "64")
1076 (V8HI "16") (V16HI "32") (V32HI "64")
1077 (V4SI "16") (V8SI "32") (V16SI "64")
1078 (V2DI "16") (V4DI "32") (V8DI "64")
1079 (V1TI "16") (V2TI "32") (V4TI "64")
1080 (V2DF "16") (V4DF "32") (V8DF "64")
1081 (V4SF "16") (V8SF "32") (V16SF "64")])
1083 ;; Double word integer modes as mode attribute.
1084 (define_mode_attr DWI [(QI "HI") (HI "SI") (SI "DI") (DI "TI") (TI "OI")])
1085 (define_mode_attr dwi [(QI "hi") (HI "si") (SI "di") (DI "ti") (TI "oi")])
1087 ;; LEA mode corresponding to an integer mode
1088 (define_mode_attr LEAMODE [(QI "SI") (HI "SI") (SI "SI") (DI "DI")])
1090 ;; Half mode for double word integer modes.
1091 (define_mode_iterator DWIH [(SI "!TARGET_64BIT")
1092 (DI "TARGET_64BIT")])
1094 ;; Instruction suffix for integer modes.
1095 (define_mode_attr imodesuffix [(QI "b") (HI "w") (SI "l") (DI "q")])
1097 ;; Instruction suffix for masks.
1098 (define_mode_attr mskmodesuffix [(QI "b") (HI "w") (SI "d") (DI "q")])
1100 ;; Pointer size prefix for integer modes (Intel asm dialect)
1101 (define_mode_attr iptrsize [(QI "BYTE")
1106 ;; Register class for integer modes.
1107 (define_mode_attr r [(QI "q") (HI "r") (SI "r") (DI "r")])
1109 ;; Immediate operand constraint for integer modes.
1110 (define_mode_attr i [(QI "n") (HI "n") (SI "e") (DI "e")])
1112 ;; General operand constraint for word modes.
1113 (define_mode_attr g [(QI "qmn") (HI "rmn") (SI "rme") (DI "rme")])
1115 ;; Immediate operand constraint for double integer modes.
1116 (define_mode_attr di [(SI "nF") (DI "Wd")])
1118 ;; Immediate operand constraint for shifts.
1119 (define_mode_attr S [(QI "I") (HI "I") (SI "I") (DI "J") (TI "O")])
1121 ;; Print register name in the specified mode.
1122 (define_mode_attr k [(QI "b") (HI "w") (SI "k") (DI "q")])
1124 ;; General operand predicate for integer modes.
1125 (define_mode_attr general_operand
1126 [(QI "general_operand")
1127 (HI "general_operand")
1128 (SI "x86_64_general_operand")
1129 (DI "x86_64_general_operand")
1130 (TI "x86_64_general_operand")])
1132 ;; General operand predicate for integer modes, where for TImode
1133 ;; we need both words of the operand to be general operands.
1134 (define_mode_attr general_hilo_operand
1135 [(QI "general_operand")
1136 (HI "general_operand")
1137 (SI "x86_64_general_operand")
1138 (DI "x86_64_general_operand")
1139 (TI "x86_64_hilo_general_operand")])
1141 ;; General sign extend operand predicate for integer modes,
1142 ;; which disallows VOIDmode operands and thus it is suitable
1143 ;; for use inside sign_extend.
1144 (define_mode_attr general_sext_operand
1145 [(QI "sext_operand")
1147 (SI "x86_64_sext_operand")
1148 (DI "x86_64_sext_operand")])
1150 ;; General sign/zero extend operand predicate for integer modes.
1151 (define_mode_attr general_szext_operand
1152 [(QI "general_operand")
1153 (HI "general_operand")
1154 (SI "x86_64_szext_general_operand")
1155 (DI "x86_64_szext_general_operand")])
1157 (define_mode_attr nonmemory_szext_operand
1158 [(QI "nonmemory_operand")
1159 (HI "nonmemory_operand")
1160 (SI "x86_64_szext_nonmemory_operand")
1161 (DI "x86_64_szext_nonmemory_operand")])
1163 ;; Immediate operand predicate for integer modes.
1164 (define_mode_attr immediate_operand
1165 [(QI "immediate_operand")
1166 (HI "immediate_operand")
1167 (SI "x86_64_immediate_operand")
1168 (DI "x86_64_immediate_operand")])
1170 ;; Nonmemory operand predicate for integer modes.
1171 (define_mode_attr nonmemory_operand
1172 [(QI "nonmemory_operand")
1173 (HI "nonmemory_operand")
1174 (SI "x86_64_nonmemory_operand")
1175 (DI "x86_64_nonmemory_operand")])
1177 ;; Operand predicate for shifts.
1178 (define_mode_attr shift_operand
1179 [(QI "nonimmediate_operand")
1180 (HI "nonimmediate_operand")
1181 (SI "nonimmediate_operand")
1182 (DI "shiftdi_operand")
1183 (TI "register_operand")])
1185 ;; Operand predicate for shift argument.
1186 (define_mode_attr shift_immediate_operand
1187 [(QI "const_1_to_31_operand")
1188 (HI "const_1_to_31_operand")
1189 (SI "const_1_to_31_operand")
1190 (DI "const_1_to_63_operand")])
1192 ;; Input operand predicate for arithmetic left shifts.
1193 (define_mode_attr ashl_input_operand
1194 [(QI "nonimmediate_operand")
1195 (HI "nonimmediate_operand")
1196 (SI "nonimmediate_operand")
1197 (DI "ashldi_input_operand")
1198 (TI "reg_or_pm1_operand")])
1200 ;; SSE and x87 SFmode and DFmode floating point modes
1201 (define_mode_iterator MODEF [SF DF])
1203 ;; All x87 floating point modes
1204 (define_mode_iterator X87MODEF [SF DF XF])
1206 ;; All SSE floating point modes
1207 (define_mode_iterator SSEMODEF [SF DF TF])
1208 (define_mode_attr ssevecmodef [(SF "V4SF") (DF "V2DF") (TF "TF")])
1210 ;; SSE instruction suffix for various modes
1211 (define_mode_attr ssemodesuffix
1212 [(SF "ss") (DF "sd")
1213 (V16SF "ps") (V8DF "pd")
1214 (V8SF "ps") (V4DF "pd")
1215 (V4SF "ps") (V2DF "pd")
1216 (V16QI "b") (V8HI "w") (V4SI "d") (V2DI "q")
1217 (V32QI "b") (V16HI "w") (V8SI "d") (V4DI "q")
1218 (V64QI "b") (V32HI "w") (V16SI "d") (V8DI "q")])
1220 ;; SSE vector suffix for floating point modes
1221 (define_mode_attr ssevecmodesuffix [(SF "ps") (DF "pd")])
1223 ;; SSE vector mode corresponding to a scalar mode
1224 (define_mode_attr ssevecmode
1225 [(QI "V16QI") (HI "V8HI") (SI "V4SI") (DI "V2DI") (SF "V4SF") (DF "V2DF")])
1226 (define_mode_attr ssevecmodelower
1227 [(QI "v16qi") (HI "v8hi") (SI "v4si") (DI "v2di") (SF "v4sf") (DF "v2df")])
1229 ;; AVX512F vector mode corresponding to a scalar mode
1230 (define_mode_attr avx512fvecmode
1231 [(QI "V64QI") (HI "V32HI") (SI "V16SI") (DI "V8DI") (SF "V16SF") (DF "V8DF")])
1233 ;; Instruction suffix for REX 64bit operators.
1234 (define_mode_attr rex64suffix [(SI "{l}") (DI "{q}")])
1235 (define_mode_attr rex64namesuffix [(SI "") (DI "q")])
1237 ;; This mode iterator allows :P to be used for patterns that operate on
1238 ;; pointer-sized quantities. Exactly one of the two alternatives will match.
1239 (define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
1241 ;; This mode iterator allows :W to be used for patterns that operate on
1242 ;; word_mode sized quantities.
1243 (define_mode_iterator W
1244 [(SI "word_mode == SImode") (DI "word_mode == DImode")])
1246 ;; This mode iterator allows :PTR to be used for patterns that operate on
1247 ;; ptr_mode sized quantities.
1248 (define_mode_iterator PTR
1249 [(SI "ptr_mode == SImode") (DI "ptr_mode == DImode")])
1251 ;; Scheduling descriptions
1253 (include "pentium.md")
1256 (include "athlon.md")
1257 (include "bdver1.md")
1258 (include "bdver3.md")
1259 (include "btver2.md")
1260 (include "znver1.md")
1261 (include "geode.md")
1265 (include "core2.md")
1266 (include "haswell.md")
1269 ;; Operand and operator predicates and constraints
1271 (include "predicates.md")
1272 (include "constraints.md")
1275 ;; Compare and branch/compare and store instructions.
1277 (define_expand "cbranch<mode>4"
1278 [(set (reg:CC FLAGS_REG)
1279 (compare:CC (match_operand:SDWIM 1 "nonimmediate_operand")
1280 (match_operand:SDWIM 2 "<general_operand>")))
1281 (set (pc) (if_then_else
1282 (match_operator 0 "ordered_comparison_operator"
1283 [(reg:CC FLAGS_REG) (const_int 0)])
1284 (label_ref (match_operand 3))
1288 if (MEM_P (operands[1]) && MEM_P (operands[2]))
1289 operands[1] = force_reg (<MODE>mode, operands[1]);
1290 ix86_expand_branch (GET_CODE (operands[0]),
1291 operands[1], operands[2], operands[3]);
1295 (define_expand "cstore<mode>4"
1296 [(set (reg:CC FLAGS_REG)
1297 (compare:CC (match_operand:SWIM 2 "nonimmediate_operand")
1298 (match_operand:SWIM 3 "<general_operand>")))
1299 (set (match_operand:QI 0 "register_operand")
1300 (match_operator 1 "ordered_comparison_operator"
1301 [(reg:CC FLAGS_REG) (const_int 0)]))]
1304 if (MEM_P (operands[2]) && MEM_P (operands[3]))
1305 operands[2] = force_reg (<MODE>mode, operands[2]);
1306 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1307 operands[2], operands[3]);
1311 (define_expand "@cmp<mode>_1"
1312 [(set (reg:CC FLAGS_REG)
1313 (compare:CC (match_operand:SWI48 0 "nonimmediate_operand")
1314 (match_operand:SWI48 1 "<general_operand>")))])
1316 (define_mode_iterator SWI1248_AVX512BWDQ_64
1317 [(QI "TARGET_AVX512DQ") HI
1318 (SI "TARGET_AVX512BW") (DI "TARGET_AVX512BW && TARGET_64BIT")])
1320 (define_insn "*cmp<mode>_ccz_1"
1321 [(set (reg FLAGS_REG)
1322 (compare (match_operand:SWI1248_AVX512BWDQ_64 0
1323 "nonimmediate_operand" "<r>,?m<r>,$k")
1324 (match_operand:SWI1248_AVX512BWDQ_64 1 "const0_operand")))]
1325 "TARGET_AVX512F && ix86_match_ccmode (insn, CCZmode)"
1327 test{<imodesuffix>}\t%0, %0
1328 cmp{<imodesuffix>}\t{%1, %0|%0, %1}
1329 kortest<mskmodesuffix>\t%0, %0"
1330 [(set_attr "type" "test,icmp,msklog")
1331 (set_attr "length_immediate" "0,1,*")
1332 (set_attr "prefix" "*,*,vex")
1333 (set_attr "mode" "<MODE>")])
1335 (define_insn "*cmp<mode>_ccno_1"
1336 [(set (reg FLAGS_REG)
1337 (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>,?m<r>")
1338 (match_operand:SWI 1 "const0_operand")))]
1339 "ix86_match_ccmode (insn, CCNOmode)"
1341 test{<imodesuffix>}\t%0, %0
1342 cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1343 [(set_attr "type" "test,icmp")
1344 (set_attr "length_immediate" "0,1")
1345 (set_attr "mode" "<MODE>")])
1347 (define_insn "*cmp<mode>_1"
1348 [(set (reg FLAGS_REG)
1349 (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
1350 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m")))]
1351 "ix86_match_ccmode (insn, CCmode)"
1352 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1353 [(set_attr "type" "icmp")
1354 (set_attr "mode" "<MODE>")])
1356 (define_insn "*cmp<mode>_minus_1"
1357 [(set (reg FLAGS_REG)
1359 (minus:SWI (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
1360 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
1362 "ix86_match_ccmode (insn, CCGOCmode)"
1363 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1364 [(set_attr "type" "icmp")
1365 (set_attr "mode" "<MODE>")])
1367 (define_insn "*cmpqi_ext<mode>_1"
1368 [(set (reg FLAGS_REG)
1370 (match_operand:QI 0 "nonimmediate_operand" "QBc,m")
1372 (zero_extract:SWI248
1373 (match_operand:SWI248 1 "register_operand" "Q,Q")
1375 (const_int 8)) 0)))]
1376 "ix86_match_ccmode (insn, CCmode)"
1377 "cmp{b}\t{%h1, %0|%0, %h1}"
1378 [(set_attr "isa" "*,nox64")
1379 (set_attr "type" "icmp")
1380 (set_attr "mode" "QI")])
1382 (define_insn "*cmpqi_ext<mode>_2"
1383 [(set (reg FLAGS_REG)
1386 (zero_extract:SWI248
1387 (match_operand:SWI248 0 "register_operand" "Q")
1390 (match_operand:QI 1 "const0_operand")))]
1391 "ix86_match_ccmode (insn, CCNOmode)"
1393 [(set_attr "type" "test")
1394 (set_attr "length_immediate" "0")
1395 (set_attr "mode" "QI")])
1397 (define_expand "cmpqi_ext_3"
1398 [(set (reg:CC FLAGS_REG)
1402 (match_operand:HI 0 "register_operand")
1405 (match_operand:QI 1 "const_int_operand")))])
1407 (define_insn "*cmpqi_ext<mode>_3"
1408 [(set (reg FLAGS_REG)
1411 (zero_extract:SWI248
1412 (match_operand:SWI248 0 "register_operand" "Q,Q")
1415 (match_operand:QI 1 "general_operand" "QnBc,m")))]
1416 "ix86_match_ccmode (insn, CCmode)"
1417 "cmp{b}\t{%1, %h0|%h0, %1}"
1418 [(set_attr "isa" "*,nox64")
1419 (set_attr "type" "icmp")
1420 (set_attr "mode" "QI")])
1422 (define_insn "*cmpqi_ext<mode>_4"
1423 [(set (reg FLAGS_REG)
1426 (zero_extract:SWI248
1427 (match_operand:SWI248 0 "register_operand" "Q")
1431 (zero_extract:SWI248
1432 (match_operand:SWI248 1 "register_operand" "Q")
1434 (const_int 8)) 0)))]
1435 "ix86_match_ccmode (insn, CCmode)"
1436 "cmp{b}\t{%h1, %h0|%h0, %h1}"
1437 [(set_attr "type" "icmp")
1438 (set_attr "mode" "QI")])
1440 ;; These implement float point compares.
1441 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
1442 ;; which would allow mix and match FP modes on the compares. Which is what
1443 ;; the old patterns did, but with many more of them.
1445 (define_expand "cbranchxf4"
1446 [(set (reg:CC FLAGS_REG)
1447 (compare:CC (match_operand:XF 1 "nonmemory_operand")
1448 (match_operand:XF 2 "nonmemory_operand")))
1449 (set (pc) (if_then_else
1450 (match_operator 0 "ix86_fp_comparison_operator"
1453 (label_ref (match_operand 3))
1457 ix86_expand_branch (GET_CODE (operands[0]),
1458 operands[1], operands[2], operands[3]);
1462 (define_expand "cstorexf4"
1463 [(set (reg:CC FLAGS_REG)
1464 (compare:CC (match_operand:XF 2 "nonmemory_operand")
1465 (match_operand:XF 3 "nonmemory_operand")))
1466 (set (match_operand:QI 0 "register_operand")
1467 (match_operator 1 "ix86_fp_comparison_operator"
1472 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1473 operands[2], operands[3]);
1477 (define_expand "cbranch<mode>4"
1478 [(set (reg:CC FLAGS_REG)
1479 (compare:CC (match_operand:MODEF 1 "cmp_fp_expander_operand")
1480 (match_operand:MODEF 2 "cmp_fp_expander_operand")))
1481 (set (pc) (if_then_else
1482 (match_operator 0 "ix86_fp_comparison_operator"
1485 (label_ref (match_operand 3))
1487 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1489 ix86_expand_branch (GET_CODE (operands[0]),
1490 operands[1], operands[2], operands[3]);
1494 (define_expand "cstore<mode>4"
1495 [(set (reg:CC FLAGS_REG)
1496 (compare:CC (match_operand:MODEF 2 "cmp_fp_expander_operand")
1497 (match_operand:MODEF 3 "cmp_fp_expander_operand")))
1498 (set (match_operand:QI 0 "register_operand")
1499 (match_operator 1 "ix86_fp_comparison_operator"
1502 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1504 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1505 operands[2], operands[3]);
1509 (define_expand "cbranchcc4"
1510 [(set (pc) (if_then_else
1511 (match_operator 0 "comparison_operator"
1512 [(match_operand 1 "flags_reg_operand")
1513 (match_operand 2 "const0_operand")])
1514 (label_ref (match_operand 3))
1518 ix86_expand_branch (GET_CODE (operands[0]),
1519 operands[1], operands[2], operands[3]);
1523 (define_expand "cstorecc4"
1524 [(set (match_operand:QI 0 "register_operand")
1525 (match_operator 1 "comparison_operator"
1526 [(match_operand 2 "flags_reg_operand")
1527 (match_operand 3 "const0_operand")]))]
1530 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1531 operands[2], operands[3]);
1535 ;; FP compares, step 1:
1536 ;; Set the FP condition codes and move fpsr to ax.
1538 ;; We may not use "#" to split and emit these
1539 ;; due to reg-stack pops killing fpsr.
1541 (define_insn "*cmpxf_i387"
1542 [(set (match_operand:HI 0 "register_operand" "=a")
1545 (match_operand:XF 1 "register_operand" "f")
1546 (match_operand:XF 2 "reg_or_0_operand" "fC"))]
1549 "* return output_fp_compare (insn, operands, false, false);"
1550 [(set_attr "type" "multi")
1551 (set_attr "unit" "i387")
1552 (set_attr "mode" "XF")])
1554 (define_insn "*cmp<mode>_i387"
1555 [(set (match_operand:HI 0 "register_operand" "=a")
1558 (match_operand:MODEF 1 "register_operand" "f")
1559 (match_operand:MODEF 2 "nonimm_or_0_operand" "fmC"))]
1562 "* return output_fp_compare (insn, operands, false, false);"
1563 [(set_attr "type" "multi")
1564 (set_attr "unit" "i387")
1565 (set_attr "mode" "<MODE>")])
1567 (define_insn "*cmp<X87MODEF:mode>_<SWI24:mode>_i387"
1568 [(set (match_operand:HI 0 "register_operand" "=a")
1571 (match_operand:X87MODEF 1 "register_operand" "f")
1573 (match_operand:SWI24 2 "nonimmediate_operand" "m")))]
1576 && (TARGET_USE_<SWI24:MODE>MODE_FIOP
1577 || optimize_function_for_size_p (cfun))"
1578 "* return output_fp_compare (insn, operands, false, false);"
1579 [(set_attr "type" "multi")
1580 (set_attr "unit" "i387")
1581 (set_attr "fp_int_src" "true")
1582 (set_attr "mode" "<SWI24:MODE>")])
1584 (define_insn "*cmpu<mode>_i387"
1585 [(set (match_operand:HI 0 "register_operand" "=a")
1589 (match_operand:X87MODEF 1 "register_operand" "f")
1590 (match_operand:X87MODEF 2 "register_operand" "f"))]
1594 "* return output_fp_compare (insn, operands, false, true);"
1595 [(set_attr "type" "multi")
1596 (set_attr "unit" "i387")
1597 (set_attr "mode" "<MODE>")])
1599 ;; FP compares, step 2:
1600 ;; Get ax into flags, general case.
1602 (define_insn "x86_sahf_1"
1603 [(set (reg:CC FLAGS_REG)
1604 (unspec:CC [(match_operand:HI 0 "register_operand" "a")]
1608 #ifndef HAVE_AS_IX86_SAHF
1610 return ASM_BYTE "0x9e";
1615 [(set_attr "length" "1")
1616 (set_attr "athlon_decode" "vector")
1617 (set_attr "amdfam10_decode" "direct")
1618 (set_attr "bdver1_decode" "direct")
1619 (set_attr "mode" "SI")])
1621 ;; Pentium Pro can do both steps in one go.
1622 ;; (these instructions set flags directly)
1624 (define_subst_attr "unord" "unord_subst" "" "u")
1625 (define_subst_attr "unordered" "unord_subst" "false" "true")
1627 (define_subst "unord_subst"
1628 [(set (match_operand:CCFP 0)
1629 (match_operand:CCFP 1))]
1636 (define_insn "*cmpi<unord>xf_i387"
1637 [(set (reg:CCFP FLAGS_REG)
1639 (match_operand:XF 0 "register_operand" "f")
1640 (match_operand:XF 1 "register_operand" "f")))]
1641 "TARGET_80387 && TARGET_CMOVE"
1642 "* return output_fp_compare (insn, operands, true, <unordered>);"
1643 [(set_attr "type" "fcmp")
1644 (set_attr "mode" "XF")
1645 (set_attr "athlon_decode" "vector")
1646 (set_attr "amdfam10_decode" "direct")
1647 (set_attr "bdver1_decode" "double")
1648 (set_attr "znver1_decode" "double")])
1650 (define_insn "*cmpi<unord><MODEF:mode>"
1651 [(set (reg:CCFP FLAGS_REG)
1653 (match_operand:MODEF 0 "register_operand" "f,v")
1654 (match_operand:MODEF 1 "register_ssemem_operand" "f,vm")))]
1655 "(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
1656 || (TARGET_80387 && TARGET_CMOVE)"
1658 * return output_fp_compare (insn, operands, true, <unordered>);
1659 %v<unord>comi<MODEF:ssemodesuffix>\t{%1, %0|%0, %1}"
1660 [(set_attr "type" "fcmp,ssecomi")
1661 (set_attr "prefix" "orig,maybe_vex")
1662 (set_attr "mode" "<MODEF:MODE>")
1663 (set_attr "prefix_rep" "*,0")
1664 (set (attr "prefix_data16")
1665 (cond [(eq_attr "alternative" "0")
1667 (eq_attr "mode" "DF")
1670 (const_string "0")))
1671 (set_attr "athlon_decode" "vector")
1672 (set_attr "amdfam10_decode" "direct")
1673 (set_attr "bdver1_decode" "double")
1674 (set_attr "znver1_decode" "double")
1675 (set (attr "enabled")
1677 (match_test ("SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"))
1679 (eq_attr "alternative" "0")
1680 (symbol_ref "TARGET_MIX_SSE_I387")
1681 (symbol_ref "true"))
1683 (eq_attr "alternative" "0")
1685 (symbol_ref "false"))))])
1687 ;; Push/pop instructions.
1689 (define_insn_and_split "*pushv1ti2"
1690 [(set (match_operand:V1TI 0 "push_operand" "=<")
1691 (match_operand:V1TI 1 "register_operand" "v"))]
1692 "TARGET_64BIT && TARGET_STV"
1694 "&& reload_completed"
1695 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
1696 (set (match_dup 0) (match_dup 1))]
1698 operands[2] = GEN_INT (-PUSH_ROUNDING (GET_MODE_SIZE (V1TImode)));
1699 /* Preserve memory attributes. */
1700 operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
1702 [(set_attr "type" "multi")
1703 (set_attr "mode" "TI")])
1705 (define_insn "*push<mode>2"
1706 [(set (match_operand:DWI 0 "push_operand" "=<,<")
1707 (match_operand:DWI 1 "general_no_elim_operand" "riF*o,*v"))]
1710 [(set_attr "type" "multi")
1711 (set_attr "mode" "<MODE>")])
1714 [(set (match_operand:DWI 0 "push_operand")
1715 (match_operand:DWI 1 "general_gr_operand"))]
1718 "ix86_split_long_move (operands); DONE;")
1720 (define_insn "*pushdi2_rex64"
1721 [(set (match_operand:DI 0 "push_operand" "=<,<,!<")
1722 (match_operand:DI 1 "general_no_elim_operand" "re*m,*v,n"))]
1728 [(set_attr "type" "push,multi,multi")
1729 (set_attr "mode" "DI")])
1731 ;; Convert impossible pushes of immediate to existing instructions.
1732 ;; First try to get scratch register and go through it. In case this
1733 ;; fails, push sign extended lower part first and then overwrite
1734 ;; upper part by 32bit move.
1737 [(match_scratch:DI 2 "r")
1738 (set (match_operand:DI 0 "push_operand")
1739 (match_operand:DI 1 "immediate_operand"))]
1741 && !symbolic_operand (operands[1], DImode)
1742 && !x86_64_immediate_operand (operands[1], DImode)"
1743 [(set (match_dup 2) (match_dup 1))
1744 (set (match_dup 0) (match_dup 2))])
1747 [(set (match_operand:DI 0 "push_operand")
1748 (match_operand:DI 1 "immediate_operand"))]
1749 "TARGET_64BIT && epilogue_completed
1750 && !symbolic_operand (operands[1], DImode)
1751 && !x86_64_immediate_operand (operands[1], DImode)"
1752 [(set (match_dup 0) (match_dup 1))
1753 (set (match_dup 2) (match_dup 3))]
1755 split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1757 operands[1] = gen_lowpart (DImode, operands[2]);
1758 operands[2] = gen_rtx_MEM (SImode,
1759 plus_constant (Pmode, stack_pointer_rtx, 4));
1762 ;; For TARGET_64BIT we always round up to 8 bytes.
1763 (define_insn "*pushsi2_rex64"
1764 [(set (match_operand:SI 0 "push_operand" "=X,X")
1765 (match_operand:SI 1 "nonmemory_no_elim_operand" "re,*v"))]
1770 [(set_attr "type" "push,multi")
1771 (set_attr "mode" "DI")])
1773 (define_insn "*pushsi2"
1774 [(set (match_operand:SI 0 "push_operand" "=<,<")
1775 (match_operand:SI 1 "general_no_elim_operand" "ri*m,*v"))]
1780 [(set_attr "type" "push,multi")
1781 (set_attr "mode" "SI")])
1784 [(set (match_operand:SWI48DWI 0 "push_operand")
1785 (match_operand:SWI48DWI 1 "sse_reg_operand"))]
1786 "TARGET_SSE && reload_completed"
1787 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
1788 (set (match_dup 0) (match_dup 1))]
1790 operands[2] = GEN_INT (-PUSH_ROUNDING (GET_MODE_SIZE (<SWI48DWI:MODE>mode)));
1791 /* Preserve memory attributes. */
1792 operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
1795 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1796 ;; "push a byte/word". But actually we use push{l,q}, which has
1797 ;; the effect of rounding the amount pushed up to a word.
1799 (define_insn "*push<mode>2"
1800 [(set (match_operand:SWI12 0 "push_operand" "=X")
1801 (match_operand:SWI12 1 "nonmemory_no_elim_operand" "rn"))]
1803 "* return TARGET_64BIT ? \"push{q}\t%q1\" : \"push{l}\t%k1\";"
1804 [(set_attr "type" "push")
1806 (if_then_else (match_test "TARGET_64BIT")
1808 (const_string "SI")))])
1810 (define_insn "*push<mode>2_prologue"
1811 [(set (match_operand:W 0 "push_operand" "=<")
1812 (match_operand:W 1 "general_no_elim_operand" "r<i>*m"))
1813 (clobber (mem:BLK (scratch)))]
1815 "push{<imodesuffix>}\t%1"
1816 [(set_attr "type" "push")
1817 (set_attr "mode" "<MODE>")])
1819 (define_insn "*pop<mode>1"
1820 [(set (match_operand:W 0 "nonimmediate_operand" "=r*m")
1821 (match_operand:W 1 "pop_operand" ">"))]
1823 "pop{<imodesuffix>}\t%0"
1824 [(set_attr "type" "pop")
1825 (set_attr "mode" "<MODE>")])
1827 (define_insn "*pop<mode>1_epilogue"
1828 [(set (match_operand:W 0 "nonimmediate_operand" "=r*m")
1829 (match_operand:W 1 "pop_operand" ">"))
1830 (clobber (mem:BLK (scratch)))]
1832 "pop{<imodesuffix>}\t%0"
1833 [(set_attr "type" "pop")
1834 (set_attr "mode" "<MODE>")])
1836 (define_insn "*pushfl<mode>2"
1837 [(set (match_operand:W 0 "push_operand" "=<")
1838 (match_operand:W 1 "flags_reg_operand"))]
1840 "pushf{<imodesuffix>}"
1841 [(set_attr "type" "push")
1842 (set_attr "mode" "<MODE>")])
1844 (define_insn "*popfl<mode>1"
1845 [(set (match_operand:W 0 "flags_reg_operand")
1846 (match_operand:W 1 "pop_operand" ">"))]
1848 "popf{<imodesuffix>}"
1849 [(set_attr "type" "pop")
1850 (set_attr "mode" "<MODE>")])
1853 ;; Reload patterns to support multi-word load/store
1854 ;; with non-offsetable address.
1855 (define_expand "reload_noff_store"
1856 [(parallel [(match_operand 0 "memory_operand" "=m")
1857 (match_operand 1 "register_operand" "r")
1858 (match_operand:DI 2 "register_operand" "=&r")])]
1861 rtx mem = operands[0];
1862 rtx addr = XEXP (mem, 0);
1864 emit_move_insn (operands[2], addr);
1865 mem = replace_equiv_address_nv (mem, operands[2]);
1867 emit_insn (gen_rtx_SET (mem, operands[1]));
1871 (define_expand "reload_noff_load"
1872 [(parallel [(match_operand 0 "register_operand" "=r")
1873 (match_operand 1 "memory_operand" "m")
1874 (match_operand:DI 2 "register_operand" "=r")])]
1877 rtx mem = operands[1];
1878 rtx addr = XEXP (mem, 0);
1880 emit_move_insn (operands[2], addr);
1881 mem = replace_equiv_address_nv (mem, operands[2]);
1883 emit_insn (gen_rtx_SET (operands[0], mem));
1887 ;; Move instructions.
1889 (define_expand "movxi"
1890 [(set (match_operand:XI 0 "nonimmediate_operand")
1891 (match_operand:XI 1 "general_operand"))]
1893 "ix86_expand_vector_move (XImode, operands); DONE;")
1895 (define_expand "movoi"
1896 [(set (match_operand:OI 0 "nonimmediate_operand")
1897 (match_operand:OI 1 "general_operand"))]
1899 "ix86_expand_vector_move (OImode, operands); DONE;")
1901 (define_expand "movti"
1902 [(set (match_operand:TI 0 "nonimmediate_operand")
1903 (match_operand:TI 1 "general_operand"))]
1904 "TARGET_64BIT || TARGET_SSE"
1907 ix86_expand_move (TImode, operands);
1909 ix86_expand_vector_move (TImode, operands);
1913 ;; This expands to what emit_move_complex would generate if we didn't
1914 ;; have a movti pattern. Having this avoids problems with reload on
1915 ;; 32-bit targets when SSE is present, but doesn't seem to be harmful
1916 ;; to have around all the time.
1917 (define_expand "movcdi"
1918 [(set (match_operand:CDI 0 "nonimmediate_operand")
1919 (match_operand:CDI 1 "general_operand"))]
1922 if (push_operand (operands[0], CDImode))
1923 emit_move_complex_push (CDImode, operands[0], operands[1]);
1925 emit_move_complex_parts (operands[0], operands[1]);
1929 (define_expand "mov<mode>"
1930 [(set (match_operand:SWI1248x 0 "nonimmediate_operand")
1931 (match_operand:SWI1248x 1 "general_operand"))]
1933 "ix86_expand_move (<MODE>mode, operands); DONE;")
1935 (define_insn "*mov<mode>_xor"
1936 [(set (match_operand:SWI48 0 "register_operand" "=r")
1937 (match_operand:SWI48 1 "const0_operand"))
1938 (clobber (reg:CC FLAGS_REG))]
1941 [(set_attr "type" "alu1")
1942 (set_attr "mode" "SI")
1943 (set_attr "length_immediate" "0")])
1945 (define_insn "*mov<mode>_or"
1946 [(set (match_operand:SWI48 0 "register_operand" "=r")
1947 (match_operand:SWI48 1 "constm1_operand"))
1948 (clobber (reg:CC FLAGS_REG))]
1950 "or{<imodesuffix>}\t{%1, %0|%0, %1}"
1951 [(set_attr "type" "alu1")
1952 (set_attr "mode" "<MODE>")
1953 (set_attr "length_immediate" "1")])
1955 (define_insn "*movxi_internal_avx512f"
1956 [(set (match_operand:XI 0 "nonimmediate_operand" "=v,v ,v ,m")
1957 (match_operand:XI 1 "nonimmediate_or_sse_const_operand" " C,BC,vm,v"))]
1959 && (register_operand (operands[0], XImode)
1960 || register_operand (operands[1], XImode))"
1962 switch (get_attr_type (insn))
1965 return standard_sse_constant_opcode (insn, operands);
1968 return ix86_output_ssemov (insn, operands);
1974 [(set_attr "type" "sselog1,sselog1,ssemov,ssemov")
1975 (set_attr "prefix" "evex")
1976 (set_attr "mode" "XI")])
1978 (define_insn "*movoi_internal_avx"
1979 [(set (match_operand:OI 0 "nonimmediate_operand" "=v,v ,v ,m")
1980 (match_operand:OI 1 "nonimmediate_or_sse_const_operand" " C,BC,vm,v"))]
1982 && (register_operand (operands[0], OImode)
1983 || register_operand (operands[1], OImode))"
1985 switch (get_attr_type (insn))
1988 return standard_sse_constant_opcode (insn, operands);
1991 return ix86_output_ssemov (insn, operands);
1997 [(set_attr "isa" "*,avx2,*,*")
1998 (set_attr "type" "sselog1,sselog1,ssemov,ssemov")
1999 (set_attr "prefix" "vex")
2000 (set_attr "mode" "OI")])
2002 (define_insn "*movti_internal"
2003 [(set (match_operand:TI 0 "nonimmediate_operand" "=!r ,o ,v,v ,v ,m,?r,?Yd")
2004 (match_operand:TI 1 "general_operand" "riFo,re,C,BC,vm,v,Yd,r"))]
2006 && !(MEM_P (operands[0]) && MEM_P (operands[1])))
2008 && nonimmediate_or_sse_const_operand (operands[1], TImode)
2009 && (register_operand (operands[0], TImode)
2010 || register_operand (operands[1], TImode)))"
2012 switch (get_attr_type (insn))
2018 return standard_sse_constant_opcode (insn, operands);
2021 return ix86_output_ssemov (insn, operands);
2028 (cond [(eq_attr "alternative" "0,1,6,7")
2029 (const_string "x64")
2030 (eq_attr "alternative" "3")
2031 (const_string "sse2")
2033 (const_string "*")))
2035 (cond [(eq_attr "alternative" "0,1,6,7")
2036 (const_string "multi")
2037 (eq_attr "alternative" "2,3")
2038 (const_string "sselog1")
2040 (const_string "ssemov")))
2041 (set (attr "prefix")
2042 (if_then_else (eq_attr "type" "sselog1,ssemov")
2043 (const_string "maybe_vex")
2044 (const_string "orig")))
2046 (cond [(eq_attr "alternative" "0,1")
2048 (match_test "TARGET_AVX")
2050 (ior (not (match_test "TARGET_SSE2"))
2051 (match_test "optimize_function_for_size_p (cfun)"))
2052 (const_string "V4SF")
2053 (and (eq_attr "alternative" "5")
2054 (match_test "TARGET_SSE_TYPELESS_STORES"))
2055 (const_string "V4SF")
2057 (const_string "TI")))
2058 (set (attr "preferred_for_speed")
2059 (cond [(eq_attr "alternative" "6")
2060 (symbol_ref "TARGET_INTER_UNIT_MOVES_FROM_VEC")
2061 (eq_attr "alternative" "7")
2062 (symbol_ref "TARGET_INTER_UNIT_MOVES_TO_VEC")
2064 (symbol_ref "true")))])
2067 [(set (match_operand:TI 0 "sse_reg_operand")
2068 (match_operand:TI 1 "general_reg_operand"))]
2069 "TARGET_64BIT && TARGET_SSE4_1
2070 && reload_completed"
2073 (vec_duplicate:V2DI (match_dup 3))
2077 operands[2] = lowpart_subreg (V2DImode, operands[0], TImode);
2078 operands[3] = gen_highpart (DImode, operands[1]);
2080 emit_move_insn (gen_lowpart (DImode, operands[0]),
2081 gen_lowpart (DImode, operands[1]));
2084 (define_insn "*movdi_internal"
2085 [(set (match_operand:DI 0 "nonimmediate_operand"
2086 "=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")
2087 (match_operand:DI 1 "general_operand"
2088 "riFo,riF,Z,rem,i,re,C ,*y,m ,*y,*y,r ,C ,*v,m ,*v,v,*Yd,r ,*v,r ,*x ,*y ,*r,*km,*k,*k,CBC"))]
2089 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2091 switch (get_attr_type (insn))
2094 return "kmovq\t{%1, %0|%0, %1}";
2097 if (operands[1] == const0_rtx)
2098 return "kxorq\t%0, %0, %0";
2099 else if (operands[1] == constm1_rtx)
2100 return "kxnorq\t%0, %0, %0";
2107 return "pxor\t%0, %0";
2110 /* Handle broken assemblers that require movd instead of movq. */
2111 if (!HAVE_AS_IX86_INTERUNIT_MOVQ
2112 && (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1])))
2113 return "movd\t{%1, %0|%0, %1}";
2114 return "movq\t{%1, %0|%0, %1}";
2117 return standard_sse_constant_opcode (insn, operands);
2120 return ix86_output_ssemov (insn, operands);
2123 if (SSE_REG_P (operands[0]))
2124 return "movq2dq\t{%1, %0|%0, %1}";
2126 return "movdq2q\t{%1, %0|%0, %1}";
2129 return "lea{q}\t{%E1, %0|%0, %E1}";
2132 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2133 if (get_attr_mode (insn) == MODE_SI)
2134 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2135 else if (which_alternative == 4)
2136 return "movabs{q}\t{%1, %0|%0, %1}";
2137 else if (ix86_use_lea_for_mov (insn, operands))
2138 return "lea{q}\t{%E1, %0|%0, %E1}";
2140 return "mov{q}\t{%1, %0|%0, %1}";
2147 (cond [(eq_attr "alternative" "0,1,17,18")
2148 (const_string "nox64")
2149 (eq_attr "alternative" "2,3,4,5,10,11,23,25")
2150 (const_string "x64")
2151 (eq_attr "alternative" "19,20")
2152 (const_string "x64_sse2")
2153 (eq_attr "alternative" "21,22")
2154 (const_string "sse2")
2156 (const_string "*")))
2158 (cond [(eq_attr "alternative" "0,1,17,18")
2159 (const_string "multi")
2160 (eq_attr "alternative" "6")
2161 (const_string "mmx")
2162 (eq_attr "alternative" "7,8,9,10,11")
2163 (const_string "mmxmov")
2164 (eq_attr "alternative" "12")
2165 (const_string "sselog1")
2166 (eq_attr "alternative" "13,14,15,16,19,20")
2167 (const_string "ssemov")
2168 (eq_attr "alternative" "21,22")
2169 (const_string "ssecvt")
2170 (eq_attr "alternative" "23,24,25,26")
2171 (const_string "mskmov")
2172 (eq_attr "alternative" "27")
2173 (const_string "msklog")
2174 (and (match_operand 0 "register_operand")
2175 (match_operand 1 "pic_32bit_operand"))
2176 (const_string "lea")
2178 (const_string "imov")))
2181 (and (eq_attr "alternative" "4") (eq_attr "type" "imov"))
2183 (const_string "*")))
2184 (set (attr "length_immediate")
2186 (and (eq_attr "alternative" "4") (eq_attr "type" "imov"))
2188 (const_string "*")))
2189 (set (attr "prefix_rex")
2191 (eq_attr "alternative" "10,11,19,20")
2193 (const_string "*")))
2194 (set (attr "prefix")
2195 (if_then_else (eq_attr "type" "sselog1,ssemov")
2196 (const_string "maybe_vex")
2197 (const_string "orig")))
2198 (set (attr "prefix_data16")
2199 (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "DI"))
2201 (const_string "*")))
2203 (cond [(eq_attr "alternative" "2")
2205 (eq_attr "alternative" "12,13")
2206 (cond [(match_test "TARGET_AVX")
2208 (ior (not (match_test "TARGET_SSE2"))
2209 (match_test "optimize_function_for_size_p (cfun)"))
2210 (const_string "V4SF")
2212 (const_string "TI"))
2214 (and (eq_attr "alternative" "14,15,16")
2215 (not (match_test "TARGET_SSE2")))
2216 (const_string "V2SF")
2218 (const_string "DI")))
2219 (set (attr "preferred_for_speed")
2220 (cond [(eq_attr "alternative" "10,17,19")
2221 (symbol_ref "TARGET_INTER_UNIT_MOVES_FROM_VEC")
2222 (eq_attr "alternative" "11,18,20")
2223 (symbol_ref "TARGET_INTER_UNIT_MOVES_TO_VEC")
2225 (symbol_ref "true")))
2226 (set (attr "enabled")
2227 (cond [(eq_attr "alternative" "15")
2229 (match_test "TARGET_STV && TARGET_SSE2")
2230 (symbol_ref "false")
2232 (eq_attr "alternative" "16")
2234 (match_test "TARGET_STV && TARGET_SSE2")
2236 (symbol_ref "false"))
2238 (const_string "*")))])
2241 [(set (match_operand:<DWI> 0 "general_reg_operand")
2242 (match_operand:<DWI> 1 "sse_reg_operand"))]
2244 && reload_completed"
2248 (parallel [(const_int 1)])))]
2250 operands[2] = gen_highpart (<MODE>mode, operands[0]);
2251 operands[3] = lowpart_subreg (<ssevecmode>mode, operands[1], <DWI>mode);
2253 emit_move_insn (gen_lowpart (<MODE>mode, operands[0]),
2254 gen_lowpart (<MODE>mode, operands[1]));
2258 [(set (match_operand:DWI 0 "nonimmediate_gr_operand")
2259 (match_operand:DWI 1 "general_gr_operand"))]
2262 "ix86_split_long_move (operands); DONE;")
2265 [(set (match_operand:DI 0 "sse_reg_operand")
2266 (match_operand:DI 1 "general_reg_operand"))]
2267 "!TARGET_64BIT && TARGET_SSE4_1
2268 && reload_completed"
2271 (vec_duplicate:V4SI (match_dup 3))
2275 operands[2] = lowpart_subreg (V4SImode, operands[0], DImode);
2276 operands[3] = gen_highpart (SImode, operands[1]);
2278 emit_move_insn (gen_lowpart (SImode, operands[0]),
2279 gen_lowpart (SImode, operands[1]));
2282 ;; movabsq $0x0012345678000000, %rax is longer
2283 ;; than movl $0x12345678, %eax; shlq $24, %rax.
2285 [(set (match_operand:DI 0 "register_operand")
2286 (match_operand:DI 1 "const_int_operand"))]
2288 && optimize_insn_for_size_p ()
2289 && LEGACY_INT_REG_P (operands[0])
2290 && !x86_64_immediate_operand (operands[1], DImode)
2291 && !x86_64_zext_immediate_operand (operands[1], DImode)
2292 && !((UINTVAL (operands[1]) >> ctz_hwi (UINTVAL (operands[1])))
2293 & ~(HOST_WIDE_INT) 0xffffffff)
2294 && peep2_regno_dead_p (0, FLAGS_REG)"
2295 [(set (match_dup 0) (match_dup 1))
2296 (parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
2297 (clobber (reg:CC FLAGS_REG))])]
2299 int shift = ctz_hwi (UINTVAL (operands[1]));
2300 operands[1] = gen_int_mode (UINTVAL (operands[1]) >> shift, DImode);
2301 operands[2] = gen_int_mode (shift, QImode);
2304 (define_insn "*movsi_internal"
2305 [(set (match_operand:SI 0 "nonimmediate_operand"
2306 "=r,m ,*y,*y,?*y,?m,?r,?*y,*v,*v,*v,m ,?r,?*v,*k,*k ,*rm,*k")
2307 (match_operand:SI 1 "general_operand"
2308 "g ,re,C ,*y,m ,*y,*y,r ,C ,*v,m ,*v,*v,r ,*r,*km,*k ,CBC"))]
2309 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2311 switch (get_attr_type (insn))
2314 return standard_sse_constant_opcode (insn, operands);
2317 return "kmovd\t{%1, %0|%0, %1}";
2320 if (operands[1] == const0_rtx)
2321 return "kxord\t%0, %0, %0";
2322 else if (operands[1] == constm1_rtx)
2323 return "kxnord\t%0, %0, %0";
2327 return ix86_output_ssemov (insn, operands);
2330 return "pxor\t%0, %0";
2333 switch (get_attr_mode (insn))
2336 return "movq\t{%1, %0|%0, %1}";
2338 return "movd\t{%1, %0|%0, %1}";
2345 return "lea{l}\t{%E1, %0|%0, %E1}";
2348 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2349 if (ix86_use_lea_for_mov (insn, operands))
2350 return "lea{l}\t{%E1, %0|%0, %E1}";
2352 return "mov{l}\t{%1, %0|%0, %1}";
2359 (cond [(eq_attr "alternative" "12,13")
2360 (const_string "sse2")
2362 (const_string "*")))
2364 (cond [(eq_attr "alternative" "2")
2365 (const_string "mmx")
2366 (eq_attr "alternative" "3,4,5,6,7")
2367 (const_string "mmxmov")
2368 (eq_attr "alternative" "8")
2369 (const_string "sselog1")
2370 (eq_attr "alternative" "9,10,11,12,13")
2371 (const_string "ssemov")
2372 (eq_attr "alternative" "14,15,16")
2373 (const_string "mskmov")
2374 (eq_attr "alternative" "17")
2375 (const_string "msklog")
2376 (and (match_operand 0 "register_operand")
2377 (match_operand 1 "pic_32bit_operand"))
2378 (const_string "lea")
2380 (const_string "imov")))
2381 (set (attr "prefix")
2382 (if_then_else (eq_attr "type" "sselog1,ssemov")
2383 (const_string "maybe_vex")
2384 (const_string "orig")))
2385 (set (attr "prefix_data16")
2386 (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
2388 (const_string "*")))
2390 (cond [(eq_attr "alternative" "2,3")
2392 (eq_attr "alternative" "8,9")
2393 (cond [(match_test "TARGET_AVX")
2395 (ior (not (match_test "TARGET_SSE2"))
2396 (match_test "optimize_function_for_size_p (cfun)"))
2397 (const_string "V4SF")
2399 (const_string "TI"))
2401 (and (eq_attr "alternative" "10,11")
2402 (not (match_test "TARGET_SSE2")))
2405 (const_string "SI")))
2406 (set (attr "preferred_for_speed")
2407 (cond [(eq_attr "alternative" "6,12")
2408 (symbol_ref "TARGET_INTER_UNIT_MOVES_FROM_VEC")
2409 (eq_attr "alternative" "7,13")
2410 (symbol_ref "TARGET_INTER_UNIT_MOVES_TO_VEC")
2412 (symbol_ref "true")))])
2414 (define_insn "*movhi_internal"
2415 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r ,r ,m ,*k,*k ,*r,*m,*k")
2416 (match_operand:HI 1 "general_operand" "r ,rn,rm,rn,*r,*km,*k,*k,CBC"))]
2417 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2419 switch (get_attr_type (insn))
2422 /* movzwl is faster than movw on p2 due to partial word stalls,
2423 though not as fast as an aligned movl. */
2424 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
2427 switch (which_alternative)
2430 return "kmovw\t{%k1, %0|%0, %k1}";
2432 return "kmovw\t{%1, %k0|%k0, %1}";
2435 return "kmovw\t{%1, %0|%0, %1}";
2441 if (operands[1] == const0_rtx)
2442 return "kxorw\t%0, %0, %0";
2443 else if (operands[1] == constm1_rtx)
2444 return "kxnorw\t%0, %0, %0";
2448 if (get_attr_mode (insn) == MODE_SI)
2449 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2451 return "mov{w}\t{%1, %0|%0, %1}";
2455 (cond [(eq_attr "alternative" "4,5,6,7")
2456 (const_string "mskmov")
2457 (eq_attr "alternative" "8")
2458 (const_string "msklog")
2459 (match_test "optimize_function_for_size_p (cfun)")
2460 (const_string "imov")
2461 (and (eq_attr "alternative" "0")
2462 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2463 (not (match_test "TARGET_HIMODE_MATH"))))
2464 (const_string "imov")
2465 (and (eq_attr "alternative" "1,2")
2466 (match_operand:HI 1 "aligned_operand"))
2467 (const_string "imov")
2468 (and (match_test "TARGET_MOVX")
2469 (eq_attr "alternative" "0,2"))
2470 (const_string "imovx")
2472 (const_string "imov")))
2473 (set (attr "prefix")
2474 (if_then_else (eq_attr "alternative" "4,5,6,7,8")
2475 (const_string "vex")
2476 (const_string "orig")))
2478 (cond [(eq_attr "type" "imovx")
2480 (and (eq_attr "alternative" "1,2")
2481 (match_operand:HI 1 "aligned_operand"))
2483 (and (eq_attr "alternative" "0")
2484 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2485 (not (match_test "TARGET_HIMODE_MATH"))))
2488 (const_string "HI")))])
2490 ;; Situation is quite tricky about when to choose full sized (SImode) move
2491 ;; over QImode moves. For Q_REG -> Q_REG move we use full size only for
2492 ;; partial register dependency machines (such as AMD Athlon), where QImode
2493 ;; moves issue extra dependency and for partial register stalls machines
2494 ;; that don't use QImode patterns (and QImode move cause stall on the next
2497 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
2498 ;; register stall machines with, where we use QImode instructions, since
2499 ;; partial register stall can be caused there. Then we use movzx.
2501 (define_insn "*movqi_internal"
2502 [(set (match_operand:QI 0 "nonimmediate_operand"
2503 "=Q,R,r,q,q,r,r ,?r,m ,*k,*k,*r,*m,*k,*k,*k")
2504 (match_operand:QI 1 "general_operand"
2505 "Q ,R,r,n,m,q,rn, m,qn,*r,*k,*k,*k,*m,C,BC"))]
2506 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2512 switch (get_attr_type (insn))
2515 gcc_assert (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]));
2516 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
2519 switch (which_alternative)
2522 ops = "kmov%s\t{%%k1, %%0|%%0, %%k1}";
2525 ops = "kmov%s\t{%%1, %%k0|%%k0, %%1}";
2529 gcc_assert (TARGET_AVX512DQ);
2532 ops = "kmov%s\t{%%1, %%0|%%0, %%1}";
2538 suffix = (get_attr_mode (insn) == MODE_HI) ? "w" : "b";
2540 snprintf (buf, sizeof (buf), ops, suffix);
2541 output_asm_insn (buf, operands);
2545 if (operands[1] == const0_rtx)
2547 if (get_attr_mode (insn) == MODE_HI)
2548 return "kxorw\t%0, %0, %0";
2550 return "kxorb\t%0, %0, %0";
2552 else if (operands[1] == constm1_rtx)
2554 gcc_assert (TARGET_AVX512DQ);
2555 return "kxnorb\t%0, %0, %0";
2560 if (get_attr_mode (insn) == MODE_SI)
2561 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2563 return "mov{b}\t{%1, %0|%0, %1}";
2567 (cond [(eq_attr "alternative" "1,2")
2568 (const_string "x64")
2569 (eq_attr "alternative" "12,13,15")
2570 (const_string "avx512dq")
2572 (const_string "*")))
2574 (cond [(eq_attr "alternative" "9,10,11,12,13")
2575 (const_string "mskmov")
2576 (eq_attr "alternative" "14,15")
2577 (const_string "msklog")
2578 (and (eq_attr "alternative" "7")
2579 (not (match_operand:QI 1 "aligned_operand")))
2580 (const_string "imovx")
2581 (match_test "optimize_function_for_size_p (cfun)")
2582 (const_string "imov")
2583 (and (eq_attr "alternative" "5")
2584 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2585 (not (match_test "TARGET_QIMODE_MATH"))))
2586 (const_string "imov")
2587 (eq_attr "alternative" "5,7")
2588 (const_string "imovx")
2589 (and (match_test "TARGET_MOVX")
2590 (eq_attr "alternative" "4"))
2591 (const_string "imovx")
2593 (const_string "imov")))
2594 (set (attr "prefix")
2595 (if_then_else (eq_attr "alternative" "9,10,11,12,13,14,15")
2596 (const_string "vex")
2597 (const_string "orig")))
2599 (cond [(eq_attr "alternative" "5,6,7")
2601 (eq_attr "alternative" "8")
2603 (and (eq_attr "alternative" "9,10,11,14")
2604 (not (match_test "TARGET_AVX512DQ")))
2606 (eq_attr "type" "imovx")
2608 ;; For -Os, 8-bit immediates are always shorter than 32-bit
2610 (and (eq_attr "type" "imov")
2611 (and (eq_attr "alternative" "3")
2612 (match_test "optimize_function_for_size_p (cfun)")))
2614 ;; For -Os, movl where one or both operands are NON_Q_REGS
2615 ;; and both are LEGACY_REGS is shorter than movb.
2616 ;; Otherwise movb and movl sizes are the same, so decide purely
2617 ;; based on speed factors.
2618 (and (eq_attr "type" "imov")
2619 (and (eq_attr "alternative" "1")
2620 (match_test "optimize_function_for_size_p (cfun)")))
2622 (and (eq_attr "type" "imov")
2623 (and (eq_attr "alternative" "0,1,2,3")
2624 (and (match_test "TARGET_PARTIAL_REG_DEPENDENCY")
2625 (not (match_test "TARGET_PARTIAL_REG_STALL")))))
2627 ;; Avoid partial register stalls when not using QImode arithmetic
2628 (and (eq_attr "type" "imov")
2629 (and (eq_attr "alternative" "0,1,2,3")
2630 (and (match_test "TARGET_PARTIAL_REG_STALL")
2631 (not (match_test "TARGET_QIMODE_MATH")))))
2634 (const_string "QI")))])
2636 /* Reload dislikes loading 0/-1 directly into mask registers.
2637 Try to tidy things up here. */
2639 [(set (match_operand:SWI 0 "general_reg_operand")
2640 (match_operand:SWI 1 "immediate_operand"))
2641 (set (match_operand:SWI 2 "mask_reg_operand")
2643 "peep2_reg_dead_p (2, operands[0])
2644 && (const0_operand (operands[1], <MODE>mode)
2645 || (constm1_operand (operands[1], <MODE>mode)
2646 && (<MODE_SIZE> > 1 || TARGET_AVX512DQ)))"
2647 [(set (match_dup 2) (match_dup 1))])
2649 ;; Stores and loads of ax to arbitrary constant address.
2650 ;; We fake an second form of instruction to force reload to load address
2651 ;; into register when rax is not available
2652 (define_insn "*movabs<mode>_1"
2653 [(set (mem:SWI1248x (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2654 (match_operand:SWI1248x 1 "nonmemory_operand" "a,r<i>"))]
2655 "TARGET_LP64 && ix86_check_movabs (insn, 0)"
2657 /* Recover the full memory rtx. */
2658 operands[0] = SET_DEST (PATTERN (insn));
2659 switch (which_alternative)
2662 return "movabs{<imodesuffix>}\t{%1, %P0|<iptrsize> PTR [%P0], %1}";
2664 return "mov{<imodesuffix>}\t{%1, %0|%0, %1}";
2669 [(set_attr "type" "imov")
2670 (set_attr "modrm" "0,*")
2671 (set_attr "length_address" "8,0")
2672 (set_attr "length_immediate" "0,*")
2673 (set_attr "memory" "store")
2674 (set_attr "mode" "<MODE>")])
2676 (define_insn "*movabs<mode>_2"
2677 [(set (match_operand:SWI1248x 0 "register_operand" "=a,r")
2678 (mem:SWI1248x (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2679 "TARGET_LP64 && ix86_check_movabs (insn, 1)"
2681 /* Recover the full memory rtx. */
2682 operands[1] = SET_SRC (PATTERN (insn));
2683 switch (which_alternative)
2686 return "movabs{<imodesuffix>}\t{%P1, %0|%0, <iptrsize> PTR [%P1]}";
2688 return "mov{<imodesuffix>}\t{%1, %0|%0, %1}";
2693 [(set_attr "type" "imov")
2694 (set_attr "modrm" "0,*")
2695 (set_attr "length_address" "8,0")
2696 (set_attr "length_immediate" "0")
2697 (set_attr "memory" "load")
2698 (set_attr "mode" "<MODE>")])
2700 (define_insn "*swap<mode>"
2701 [(set (match_operand:SWI48 0 "register_operand" "+r")
2702 (match_operand:SWI48 1 "register_operand" "+r"))
2706 "xchg{<imodesuffix>}\t%1, %0"
2707 [(set_attr "type" "imov")
2708 (set_attr "mode" "<MODE>")
2709 (set_attr "pent_pair" "np")
2710 (set_attr "athlon_decode" "vector")
2711 (set_attr "amdfam10_decode" "double")
2712 (set_attr "bdver1_decode" "double")])
2714 (define_insn "*swap<mode>"
2715 [(set (match_operand:SWI12 0 "register_operand" "+<r>,r")
2716 (match_operand:SWI12 1 "register_operand" "+<r>,r"))
2721 xchg{<imodesuffix>}\t%1, %0
2723 [(set_attr "type" "imov")
2724 (set_attr "mode" "<MODE>,SI")
2725 (set (attr "preferred_for_size")
2726 (cond [(eq_attr "alternative" "0")
2727 (symbol_ref "false")]
2728 (symbol_ref "true")))
2729 ;; Potential partial reg stall on alternative 1.
2730 (set (attr "preferred_for_speed")
2731 (cond [(eq_attr "alternative" "1")
2732 (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
2733 (symbol_ref "true")))
2734 (set_attr "pent_pair" "np")
2735 (set_attr "athlon_decode" "vector")
2736 (set_attr "amdfam10_decode" "double")
2737 (set_attr "bdver1_decode" "double")])
2740 [(set (match_operand:SWI 0 "general_reg_operand")
2741 (match_operand:SWI 1 "general_reg_operand"))
2743 (match_operand:SWI 2 "general_reg_operand"))
2744 (set (match_dup 2) (match_dup 0))]
2745 "peep2_reg_dead_p (3, operands[0])
2746 && optimize_insn_for_size_p ()"
2747 [(parallel [(set (match_dup 1) (match_dup 2))
2748 (set (match_dup 2) (match_dup 1))])])
2750 (define_expand "movstrict<mode>"
2751 [(set (strict_low_part (match_operand:SWI12 0 "register_operand"))
2752 (match_operand:SWI12 1 "general_operand"))]
2755 gcc_assert (SUBREG_P (operands[0]));
2756 if ((TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun))
2757 || !VALID_INT_MODE_P (GET_MODE (SUBREG_REG (operands[0]))))
2761 (define_insn "*movstrict<mode>_1"
2762 [(set (strict_low_part
2763 (match_operand:SWI12 0 "register_operand" "+<r>"))
2764 (match_operand:SWI12 1 "general_operand" "<r>mn"))]
2765 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
2766 "mov{<imodesuffix>}\t{%1, %0|%0, %1}"
2767 [(set_attr "type" "imov")
2768 (set_attr "mode" "<MODE>")])
2770 (define_insn "*movstrict<mode>_xor"
2771 [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>"))
2772 (match_operand:SWI12 1 "const0_operand"))
2773 (clobber (reg:CC FLAGS_REG))]
2775 "xor{<imodesuffix>}\t%0, %0"
2776 [(set_attr "type" "alu1")
2777 (set_attr "mode" "<MODE>")
2778 (set_attr "length_immediate" "0")])
2780 (define_expand "extv<mode>"
2781 [(set (match_operand:SWI24 0 "register_operand")
2782 (sign_extract:SWI24 (match_operand:SWI24 1 "register_operand")
2783 (match_operand:SI 2 "const_int_operand")
2784 (match_operand:SI 3 "const_int_operand")))]
2787 /* Handle extractions from %ah et al. */
2788 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
2791 unsigned int regno = reg_or_subregno (operands[1]);
2793 /* Be careful to expand only with registers having upper parts. */
2794 if (regno <= LAST_VIRTUAL_REGISTER && !QI_REGNO_P (regno))
2795 operands[1] = copy_to_reg (operands[1]);
2798 (define_insn "*extv<mode>"
2799 [(set (match_operand:SWI24 0 "register_operand" "=R")
2800 (sign_extract:SWI24 (match_operand:SWI24 1 "register_operand" "Q")
2804 "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
2805 [(set_attr "type" "imovx")
2806 (set_attr "mode" "SI")])
2808 (define_expand "extzv<mode>"
2809 [(set (match_operand:SWI248 0 "register_operand")
2810 (zero_extract:SWI248 (match_operand:SWI248 1 "register_operand")
2811 (match_operand:SI 2 "const_int_operand")
2812 (match_operand:SI 3 "const_int_operand")))]
2815 if (ix86_expand_pextr (operands))
2818 /* Handle extractions from %ah et al. */
2819 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
2822 unsigned int regno = reg_or_subregno (operands[1]);
2824 /* Be careful to expand only with registers having upper parts. */
2825 if (regno <= LAST_VIRTUAL_REGISTER && !QI_REGNO_P (regno))
2826 operands[1] = copy_to_reg (operands[1]);
2829 (define_insn "*extzvqi_mem_rex64"
2830 [(set (match_operand:QI 0 "norex_memory_operand" "=Bn")
2832 (zero_extract:SWI248
2833 (match_operand:SWI248 1 "register_operand" "Q")
2836 "TARGET_64BIT && reload_completed"
2837 "mov{b}\t{%h1, %0|%0, %h1}"
2838 [(set_attr "type" "imov")
2839 (set_attr "mode" "QI")])
2841 (define_insn "*extzv<mode>"
2842 [(set (match_operand:SWI248 0 "register_operand" "=R")
2843 (zero_extract:SWI248 (match_operand:SWI248 1 "register_operand" "Q")
2847 "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
2848 [(set_attr "type" "imovx")
2849 (set_attr "mode" "SI")])
2851 (define_insn "*extzvqi"
2852 [(set (match_operand:QI 0 "nonimmediate_operand" "=QBc,?R,m")
2854 (zero_extract:SWI248
2855 (match_operand:SWI248 1 "register_operand" "Q,Q,Q")
2860 switch (get_attr_type (insn))
2863 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2865 return "mov{b}\t{%h1, %0|%0, %h1}";
2868 [(set_attr "isa" "*,*,nox64")
2870 (if_then_else (and (match_operand:QI 0 "register_operand")
2871 (ior (not (match_operand:QI 0 "QIreg_operand"))
2872 (match_test "TARGET_MOVX")))
2873 (const_string "imovx")
2874 (const_string "imov")))
2876 (if_then_else (eq_attr "type" "imovx")
2878 (const_string "QI")))])
2881 [(set (match_operand:QI 0 "register_operand")
2883 (zero_extract:SWI248 (match_operand:SWI248 1 "register_operand")
2886 (set (match_operand:QI 2 "norex_memory_operand") (match_dup 0))]
2888 && peep2_reg_dead_p (2, operands[0])"
2891 (zero_extract:SWI248 (match_dup 1)
2893 (const_int 8)) 0))])
2895 (define_expand "insv<mode>"
2896 [(set (zero_extract:SWI248 (match_operand:SWI248 0 "register_operand")
2897 (match_operand:SI 1 "const_int_operand")
2898 (match_operand:SI 2 "const_int_operand"))
2899 (match_operand:SWI248 3 "register_operand"))]
2904 if (ix86_expand_pinsr (operands))
2907 /* Handle insertions to %ah et al. */
2908 if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
2911 unsigned int regno = reg_or_subregno (operands[0]);
2913 /* Be careful to expand only with registers having upper parts. */
2914 if (regno <= LAST_VIRTUAL_REGISTER && !QI_REGNO_P (regno))
2915 dst = copy_to_reg (operands[0]);
2919 emit_insn (gen_insv_1 (<MODE>mode, dst, operands[3]));
2921 /* Fix up the destination if needed. */
2922 if (dst != operands[0])
2923 emit_move_insn (operands[0], dst);
2928 (define_insn "*insvqi_1_mem_rex64"
2929 [(set (zero_extract:SWI248
2930 (match_operand:SWI248 0 "register_operand" "+Q")
2934 (match_operand:QI 1 "norex_memory_operand" "Bn") 0))]
2935 "TARGET_64BIT && reload_completed"
2936 "mov{b}\t{%1, %h0|%h0, %1}"
2937 [(set_attr "type" "imov")
2938 (set_attr "mode" "QI")])
2940 (define_insn "@insv<mode>_1"
2941 [(set (zero_extract:SWI248
2942 (match_operand:SWI248 0 "register_operand" "+Q,Q")
2945 (match_operand:SWI248 1 "general_operand" "QnBc,m"))]
2948 if (CONST_INT_P (operands[1]))
2949 operands[1] = gen_int_mode (INTVAL (operands[1]), QImode);
2950 return "mov{b}\t{%b1, %h0|%h0, %b1}";
2952 [(set_attr "isa" "*,nox64")
2953 (set_attr "type" "imov")
2954 (set_attr "mode" "QI")])
2956 (define_insn "*insvqi_1"
2957 [(set (zero_extract:SWI248
2958 (match_operand:SWI248 0 "register_operand" "+Q,Q")
2962 (match_operand:QI 1 "general_operand" "QnBc,m") 0))]
2964 "mov{b}\t{%1, %h0|%h0, %1}"
2965 [(set_attr "isa" "*,nox64")
2966 (set_attr "type" "imov")
2967 (set_attr "mode" "QI")])
2970 [(set (match_operand:QI 0 "register_operand")
2971 (match_operand:QI 1 "norex_memory_operand"))
2972 (set (zero_extract:SWI248 (match_operand:SWI248 2 "register_operand")
2975 (subreg:SWI248 (match_dup 0) 0))]
2977 && peep2_reg_dead_p (2, operands[0])"
2978 [(set (zero_extract:SWI248 (match_dup 2)
2981 (subreg:SWI248 (match_dup 1) 0))])
2983 (define_code_iterator any_extract [sign_extract zero_extract])
2985 (define_insn "*insvqi_2"
2986 [(set (zero_extract:SWI248
2987 (match_operand:SWI248 0 "register_operand" "+Q")
2991 (match_operand:SWI248 1 "register_operand" "Q")
2995 "mov{b}\t{%h1, %h0|%h0, %h1}"
2996 [(set_attr "type" "imov")
2997 (set_attr "mode" "QI")])
2999 (define_insn "*insvqi_3"
3000 [(set (zero_extract:SWI248
3001 (match_operand:SWI248 0 "register_operand" "+Q")
3005 (match_operand:SWI248 1 "register_operand" "Q")
3008 "mov{b}\t{%h1, %h0|%h0, %h1}"
3009 [(set_attr "type" "imov")
3010 (set_attr "mode" "QI")])
3012 ;; Floating point push instructions.
3014 (define_insn "*pushtf"
3015 [(set (match_operand:TF 0 "push_operand" "=<,<")
3016 (match_operand:TF 1 "general_no_elim_operand" "v,*roC"))]
3017 "TARGET_64BIT || TARGET_SSE"
3019 /* This insn should be already split before reg-stack. */
3022 [(set_attr "isa" "*,x64")
3023 (set_attr "type" "multi")
3024 (set_attr "unit" "sse,*")
3025 (set_attr "mode" "TF,DI")])
3027 ;; %%% Kill this when call knows how to work this out.
3029 [(set (match_operand:TF 0 "push_operand")
3030 (match_operand:TF 1 "sse_reg_operand"))]
3031 "TARGET_SSE && reload_completed"
3032 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -16)))
3033 (set (match_dup 0) (match_dup 1))]
3035 /* Preserve memory attributes. */
3036 operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
3039 (define_insn_and_split "*pushxf_rounded"
3043 (plus:P (reg:P SP_REG) (const_int -16))))
3044 (match_operand:XF 0 "nonmemory_no_elim_operand" "f,r,*r,C"))]
3048 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -16)))
3049 (set (match_dup 1) (match_dup 0))]
3051 rtx pat = PATTERN (curr_insn);
3052 operands[1] = SET_DEST (pat);
3054 /* Preserve memory attributes. */
3055 operands[1] = replace_equiv_address (operands[1], stack_pointer_rtx);
3057 [(set_attr "type" "multi")
3058 (set_attr "unit" "i387,*,*,*")
3060 (cond [(eq_attr "alternative" "1,2,3")
3063 (const_string "XF")))
3064 (set (attr "preferred_for_size")
3065 (cond [(eq_attr "alternative" "1")
3066 (symbol_ref "false")]
3067 (symbol_ref "true")))])
3069 (define_insn "*pushxf"
3070 [(set (match_operand:XF 0 "push_operand" "=<,<,<,<,<")
3071 (match_operand:XF 1 "general_no_elim_operand" "f,r,*r,oF,oC"))]
3074 /* This insn should be already split before reg-stack. */
3077 [(set_attr "isa" "*,*,*,nox64,x64")
3078 (set_attr "type" "multi")
3079 (set_attr "unit" "i387,*,*,*,*")
3081 (cond [(eq_attr "alternative" "1,2,3,4")
3082 (if_then_else (match_test "TARGET_64BIT")
3084 (const_string "SI"))
3086 (const_string "XF")))
3087 (set (attr "preferred_for_size")
3088 (cond [(eq_attr "alternative" "1")
3089 (symbol_ref "false")]
3090 (symbol_ref "true")))])
3092 ;; %%% Kill this when call knows how to work this out.
3094 [(set (match_operand:XF 0 "push_operand")
3095 (match_operand:XF 1 "fp_register_operand"))]
3097 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
3098 (set (match_dup 0) (match_dup 1))]
3100 operands[2] = GEN_INT (-PUSH_ROUNDING (GET_MODE_SIZE (XFmode)));
3101 /* Preserve memory attributes. */
3102 operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
3105 (define_insn "*pushdf"
3106 [(set (match_operand:DF 0 "push_operand" "=<,<,<,<,<,<")
3107 (match_operand:DF 1 "general_no_elim_operand" "f,r,*r,oF,rmC,v"))]
3110 /* This insn should be already split before reg-stack. */
3113 [(set_attr "isa" "*,nox64,nox64,nox64,x64,sse2")
3114 (set_attr "type" "multi")
3115 (set_attr "unit" "i387,*,*,*,*,sse")
3116 (set_attr "mode" "DF,SI,SI,SI,DI,DF")
3117 (set (attr "preferred_for_size")
3118 (cond [(eq_attr "alternative" "1")
3119 (symbol_ref "false")]
3120 (symbol_ref "true")))
3121 (set (attr "preferred_for_speed")
3122 (cond [(eq_attr "alternative" "1")
3123 (symbol_ref "TARGET_INTEGER_DFMODE_MOVES")]
3124 (symbol_ref "true")))])
3126 ;; %%% Kill this when call knows how to work this out.
3128 [(set (match_operand:DF 0 "push_operand")
3129 (match_operand:DF 1 "any_fp_register_operand"))]
3131 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
3132 (set (match_dup 0) (match_dup 1))]
3134 /* Preserve memory attributes. */
3135 operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
3138 (define_insn "*pushsf_rex64"
3139 [(set (match_operand:SF 0 "push_operand" "=X,X,X")
3140 (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,v"))]
3143 /* Anything else should be already split before reg-stack. */
3144 if (which_alternative != 1)
3146 return "push{q}\t%q1";
3148 [(set_attr "type" "multi,push,multi")
3149 (set_attr "unit" "i387,*,*")
3150 (set_attr "mode" "SF,DI,SF")])
3152 (define_insn "*pushsf"
3153 [(set (match_operand:SF 0 "push_operand" "=<,<,<")
3154 (match_operand:SF 1 "general_no_elim_operand" "f,rmF,v"))]
3157 /* Anything else should be already split before reg-stack. */
3158 if (which_alternative != 1)
3160 return "push{l}\t%1";
3162 [(set_attr "type" "multi,push,multi")
3163 (set_attr "unit" "i387,*,*")
3164 (set_attr "mode" "SF,SI,SF")])
3166 ;; %%% Kill this when call knows how to work this out.
3168 [(set (match_operand:SF 0 "push_operand")
3169 (match_operand:SF 1 "any_fp_register_operand"))]
3171 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
3172 (set (match_dup 0) (match_dup 1))]
3174 rtx op = XEXP (operands[0], 0);
3175 if (GET_CODE (op) == PRE_DEC)
3177 gcc_assert (!TARGET_64BIT);
3182 op = XEXP (XEXP (op, 1), 1);
3183 gcc_assert (CONST_INT_P (op));
3186 /* Preserve memory attributes. */
3187 operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
3191 [(set (match_operand:SF 0 "push_operand")
3192 (match_operand:SF 1 "memory_operand"))]
3194 && find_constant_src (insn)"
3195 [(set (match_dup 0) (match_dup 2))]
3196 "operands[2] = find_constant_src (curr_insn);")
3199 [(set (match_operand 0 "push_operand")
3200 (match_operand 1 "general_gr_operand"))]
3202 && (GET_MODE (operands[0]) == TFmode
3203 || GET_MODE (operands[0]) == XFmode
3204 || GET_MODE (operands[0]) == DFmode)"
3206 "ix86_split_long_move (operands); DONE;")
3208 ;; Floating point move instructions.
3210 (define_expand "movtf"
3211 [(set (match_operand:TF 0 "nonimmediate_operand")
3212 (match_operand:TF 1 "nonimmediate_operand"))]
3213 "TARGET_64BIT || TARGET_SSE"
3214 "ix86_expand_move (TFmode, operands); DONE;")
3216 (define_expand "mov<mode>"
3217 [(set (match_operand:X87MODEF 0 "nonimmediate_operand")
3218 (match_operand:X87MODEF 1 "general_operand"))]
3220 "ix86_expand_move (<MODE>mode, operands); DONE;")
3222 (define_insn "*movtf_internal"
3223 [(set (match_operand:TF 0 "nonimmediate_operand" "=v,v ,m,?*r ,!o")
3224 (match_operand:TF 1 "general_operand" "C ,vm,v,*roF,*rC"))]
3225 "(TARGET_64BIT || TARGET_SSE)
3226 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3227 && (lra_in_progress || reload_completed
3228 || !CONST_DOUBLE_P (operands[1])
3229 || ((optimize_function_for_size_p (cfun)
3230 || (ix86_cmodel == CM_LARGE || ix86_cmodel == CM_LARGE_PIC))
3231 && standard_sse_constant_p (operands[1], TFmode) == 1
3232 && !memory_operand (operands[0], TFmode))
3233 || (!TARGET_MEMORY_MISMATCH_STALL
3234 && memory_operand (operands[0], TFmode)))"
3236 switch (get_attr_type (insn))
3239 return standard_sse_constant_opcode (insn, operands);
3242 return ix86_output_ssemov (insn, operands);
3251 [(set_attr "isa" "*,*,*,x64,x64")
3252 (set_attr "type" "sselog1,ssemov,ssemov,multi,multi")
3253 (set (attr "prefix")
3254 (if_then_else (eq_attr "type" "sselog1,ssemov")
3255 (const_string "maybe_vex")
3256 (const_string "orig")))
3258 (cond [(eq_attr "alternative" "3,4")
3260 (match_test "TARGET_AVX")
3262 (ior (not (match_test "TARGET_SSE2"))
3263 (match_test "optimize_function_for_size_p (cfun)"))
3264 (const_string "V4SF")
3265 (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
3266 (const_string "V4SF")
3267 (and (eq_attr "alternative" "2")
3268 (match_test "TARGET_SSE_TYPELESS_STORES"))
3269 (const_string "V4SF")
3271 (const_string "TI")))])
3274 [(set (match_operand:TF 0 "nonimmediate_gr_operand")
3275 (match_operand:TF 1 "general_gr_operand"))]
3278 "ix86_split_long_move (operands); DONE;")
3280 ;; Possible store forwarding (partial memory) stall
3281 ;; in alternatives 4, 6, 7 and 8.
3282 (define_insn "*movxf_internal"
3283 [(set (match_operand:XF 0 "nonimmediate_operand"
3284 "=f,m,f,?r ,!o,?*r ,!o,!o,!o,r ,o ,o")
3285 (match_operand:XF 1 "general_operand"
3286 "fm,f,G,roF,r ,*roF,*r,F ,C ,roF,rF,rC"))]
3287 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3288 && (lra_in_progress || reload_completed
3289 || !CONST_DOUBLE_P (operands[1])
3290 || ((optimize_function_for_size_p (cfun)
3291 || (ix86_cmodel == CM_LARGE || ix86_cmodel == CM_LARGE_PIC))
3292 && standard_80387_constant_p (operands[1]) > 0
3293 && !memory_operand (operands[0], XFmode))
3294 || (!TARGET_MEMORY_MISMATCH_STALL
3295 && memory_operand (operands[0], XFmode))
3296 || !TARGET_HARD_XF_REGS)"
3298 switch (get_attr_type (insn))
3301 if (which_alternative == 2)
3302 return standard_80387_constant_opcode (operands[1]);
3303 return output_387_reg_move (insn, operands);
3313 (cond [(eq_attr "alternative" "7,10")
3314 (const_string "nox64")
3315 (eq_attr "alternative" "8,11")
3316 (const_string "x64")
3318 (const_string "*")))
3320 (cond [(eq_attr "alternative" "3,4,5,6,7,8,9,10,11")
3321 (const_string "multi")
3323 (const_string "fmov")))
3325 (cond [(eq_attr "alternative" "3,4,5,6,7,8,9,10,11")
3326 (if_then_else (match_test "TARGET_64BIT")
3328 (const_string "SI"))
3330 (const_string "XF")))
3331 (set (attr "preferred_for_size")
3332 (cond [(eq_attr "alternative" "3,4")
3333 (symbol_ref "false")]
3334 (symbol_ref "true")))
3335 (set (attr "enabled")
3336 (cond [(eq_attr "alternative" "9,10,11")
3338 (match_test "TARGET_HARD_XF_REGS")
3339 (symbol_ref "false")
3341 (not (match_test "TARGET_HARD_XF_REGS"))
3342 (symbol_ref "false")
3344 (const_string "*")))])
3347 [(set (match_operand:XF 0 "nonimmediate_gr_operand")
3348 (match_operand:XF 1 "general_gr_operand"))]
3351 "ix86_split_long_move (operands); DONE;")
3353 ;; Possible store forwarding (partial memory) stall in alternatives 4, 6 and 7.
3354 (define_insn "*movdf_internal"
3355 [(set (match_operand:DF 0 "nonimmediate_operand"
3356 "=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")
3357 (match_operand:DF 1 "general_operand"
3358 "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"))]
3359 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3360 && (lra_in_progress || reload_completed
3361 || !CONST_DOUBLE_P (operands[1])
3362 || ((optimize_function_for_size_p (cfun)
3363 || (ix86_cmodel == CM_LARGE || ix86_cmodel == CM_LARGE_PIC))
3364 && ((IS_STACK_MODE (DFmode)
3365 && standard_80387_constant_p (operands[1]) > 0)
3366 || (TARGET_SSE2 && TARGET_SSE_MATH
3367 && standard_sse_constant_p (operands[1], DFmode) == 1))
3368 && !memory_operand (operands[0], DFmode))
3369 || ((TARGET_64BIT || !TARGET_MEMORY_MISMATCH_STALL)
3370 && memory_operand (operands[0], DFmode))
3371 || !TARGET_HARD_DF_REGS)"
3373 switch (get_attr_type (insn))
3376 if (which_alternative == 2)
3377 return standard_80387_constant_opcode (operands[1]);
3378 return output_387_reg_move (insn, operands);
3384 if (get_attr_mode (insn) == MODE_SI)
3385 return "mov{l}\t{%1, %k0|%k0, %1}";
3386 else if (which_alternative == 11)
3387 return "movabs{q}\t{%1, %0|%0, %1}";
3389 return "mov{q}\t{%1, %0|%0, %1}";
3392 return standard_sse_constant_opcode (insn, operands);
3395 return ix86_output_ssemov (insn, operands);
3402 (cond [(eq_attr "alternative" "3,4,5,6,7,22,23")
3403 (const_string "nox64")
3404 (eq_attr "alternative" "8,9,10,11,24,25")
3405 (const_string "x64")
3406 (eq_attr "alternative" "12,13,14,15")
3407 (const_string "sse2")
3408 (eq_attr "alternative" "20,21")
3409 (const_string "x64_sse2")
3411 (const_string "*")))
3413 (cond [(eq_attr "alternative" "0,1,2")
3414 (const_string "fmov")
3415 (eq_attr "alternative" "3,4,5,6,7,22,23")
3416 (const_string "multi")
3417 (eq_attr "alternative" "8,9,10,11,24,25")
3418 (const_string "imov")
3419 (eq_attr "alternative" "12,16")
3420 (const_string "sselog1")
3422 (const_string "ssemov")))
3424 (if_then_else (eq_attr "alternative" "11")
3426 (const_string "*")))
3427 (set (attr "length_immediate")
3428 (if_then_else (eq_attr "alternative" "11")
3430 (const_string "*")))
3431 (set (attr "prefix")
3432 (if_then_else (eq_attr "type" "sselog1,ssemov")
3433 (const_string "maybe_vex")
3434 (const_string "orig")))
3435 (set (attr "prefix_data16")
3437 (ior (and (eq_attr "type" "ssemov") (eq_attr "mode" "DI"))
3438 (eq_attr "mode" "V1DF"))
3440 (const_string "*")))
3442 (cond [(eq_attr "alternative" "3,4,5,6,7,10,22,23")
3444 (eq_attr "alternative" "8,9,11,20,21,24,25")
3447 /* xorps is one byte shorter for non-AVX targets. */
3448 (eq_attr "alternative" "12,16")
3449 (cond [(match_test "TARGET_AVX")
3450 (const_string "V2DF")
3451 (ior (not (match_test "TARGET_SSE2"))
3452 (match_test "optimize_function_for_size_p (cfun)"))
3453 (const_string "V4SF")
3454 (match_test "TARGET_SSE_LOAD0_BY_PXOR")
3457 (const_string "V2DF"))
3459 /* For architectures resolving dependencies on
3460 whole SSE registers use movapd to break dependency
3461 chains, otherwise use short move to avoid extra work. */
3463 /* movaps is one byte shorter for non-AVX targets. */
3464 (eq_attr "alternative" "13,17")
3465 (cond [(match_test "TARGET_AVX")
3467 (ior (not (match_test "TARGET_SSE2"))
3468 (match_test "optimize_function_for_size_p (cfun)"))
3469 (const_string "V4SF")
3470 (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
3471 (const_string "V4SF")
3472 (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3473 (const_string "V2DF")
3475 (const_string "DF"))
3477 /* For architectures resolving dependencies on register
3478 parts we may avoid extra work to zero out upper part
3480 (eq_attr "alternative" "14,18")
3481 (cond [(not (match_test "TARGET_SSE2"))
3482 (const_string "V2SF")
3483 (match_test "TARGET_AVX")
3485 (match_test "TARGET_SSE_SPLIT_REGS")
3486 (const_string "V1DF")
3488 (const_string "DF"))
3490 (and (eq_attr "alternative" "15,19")
3491 (not (match_test "TARGET_SSE2")))
3492 (const_string "V2SF")
3494 (const_string "DF")))
3495 (set (attr "preferred_for_size")
3496 (cond [(eq_attr "alternative" "3,4")
3497 (symbol_ref "false")]
3498 (symbol_ref "true")))
3499 (set (attr "preferred_for_speed")
3500 (cond [(eq_attr "alternative" "3,4")
3501 (symbol_ref "TARGET_INTEGER_DFMODE_MOVES")
3502 (eq_attr "alternative" "20")
3503 (symbol_ref "TARGET_INTER_UNIT_MOVES_FROM_VEC")
3504 (eq_attr "alternative" "21")
3505 (symbol_ref "TARGET_INTER_UNIT_MOVES_TO_VEC")
3507 (symbol_ref "true")))
3508 (set (attr "enabled")
3509 (cond [(eq_attr "alternative" "22,23,24,25")
3511 (match_test "TARGET_HARD_DF_REGS")
3512 (symbol_ref "false")
3514 (not (match_test "TARGET_HARD_DF_REGS"))
3515 (symbol_ref "false")
3517 (const_string "*")))])
3520 [(set (match_operand:DF 0 "nonimmediate_gr_operand")
3521 (match_operand:DF 1 "general_gr_operand"))]
3522 "!TARGET_64BIT && reload_completed"
3524 "ix86_split_long_move (operands); DONE;")
3526 (define_insn "*movsf_internal"
3527 [(set (match_operand:SF 0 "nonimmediate_operand"
3528 "=Yf*f,m ,Yf*f,?r ,?m,v,v,v,m,?r,?v,!*y,!*y,!m,!r,!*y,r ,m")
3529 (match_operand:SF 1 "general_operand"
3530 "Yf*fm,Yf*f,G ,rmF,rF,C,v,m,v,v ,r ,*y ,m ,*y,*y,r ,rmF,rF"))]
3531 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3532 && (lra_in_progress || reload_completed
3533 || !CONST_DOUBLE_P (operands[1])
3534 || ((optimize_function_for_size_p (cfun)
3535 || (ix86_cmodel == CM_LARGE || ix86_cmodel == CM_LARGE_PIC))
3536 && ((IS_STACK_MODE (SFmode)
3537 && standard_80387_constant_p (operands[1]) > 0)
3538 || (TARGET_SSE && TARGET_SSE_MATH
3539 && standard_sse_constant_p (operands[1], SFmode) == 1)))
3540 || memory_operand (operands[0], SFmode)
3541 || !TARGET_HARD_SF_REGS)"
3543 switch (get_attr_type (insn))
3546 if (which_alternative == 2)
3547 return standard_80387_constant_opcode (operands[1]);
3548 return output_387_reg_move (insn, operands);
3551 return "mov{l}\t{%1, %0|%0, %1}";
3554 return standard_sse_constant_opcode (insn, operands);
3557 return ix86_output_ssemov (insn, operands);
3560 switch (get_attr_mode (insn))
3563 return "movq\t{%1, %0|%0, %1}";
3565 return "movd\t{%1, %0|%0, %1}";
3576 (cond [(eq_attr "alternative" "9,10")
3577 (const_string "sse2")
3579 (const_string "*")))
3581 (cond [(eq_attr "alternative" "0,1,2")
3582 (const_string "fmov")
3583 (eq_attr "alternative" "3,4,16,17")
3584 (const_string "imov")
3585 (eq_attr "alternative" "5")
3586 (const_string "sselog1")
3587 (eq_attr "alternative" "11,12,13,14,15")
3588 (const_string "mmxmov")
3590 (const_string "ssemov")))
3591 (set (attr "prefix")
3592 (if_then_else (eq_attr "type" "sselog1,ssemov")
3593 (const_string "maybe_vex")
3594 (const_string "orig")))
3595 (set (attr "prefix_data16")
3596 (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
3598 (const_string "*")))
3600 (cond [(eq_attr "alternative" "3,4,9,10,12,13,14,15,16,17")
3602 (eq_attr "alternative" "11")
3604 (eq_attr "alternative" "5")
3605 (cond [(and (match_test "TARGET_AVX512F")
3606 (not (match_test "TARGET_PREFER_AVX256")))
3607 (const_string "V16SF")
3608 (match_test "TARGET_AVX")
3609 (const_string "V4SF")
3610 (ior (not (match_test "TARGET_SSE2"))
3611 (match_test "optimize_function_for_size_p (cfun)"))
3612 (const_string "V4SF")
3613 (match_test "TARGET_SSE_LOAD0_BY_PXOR")
3616 (const_string "V4SF"))
3618 /* For architectures resolving dependencies on
3619 whole SSE registers use APS move to break dependency
3620 chains, otherwise use short move to avoid extra work.
3622 Do the same for architectures resolving dependencies on
3623 the parts. While in DF mode it is better to always handle
3624 just register parts, the SF mode is different due to lack
3625 of instructions to load just part of the register. It is
3626 better to maintain the whole registers in single format
3627 to avoid problems on using packed logical operations. */
3628 (eq_attr "alternative" "6")
3629 (cond [(ior (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3630 (match_test "TARGET_SSE_SPLIT_REGS"))
3631 (const_string "V4SF")
3633 (const_string "SF"))
3635 (const_string "SF")))
3636 (set (attr "preferred_for_speed")
3637 (cond [(eq_attr "alternative" "9,14")
3638 (symbol_ref "TARGET_INTER_UNIT_MOVES_FROM_VEC")
3639 (eq_attr "alternative" "10,15")
3640 (symbol_ref "TARGET_INTER_UNIT_MOVES_TO_VEC")
3642 (symbol_ref "true")))
3643 (set (attr "enabled")
3644 (cond [(eq_attr "alternative" "16,17")
3646 (match_test "TARGET_HARD_SF_REGS")
3647 (symbol_ref "false")
3649 (not (match_test "TARGET_HARD_SF_REGS"))
3650 (symbol_ref "false")
3652 (const_string "*")))])
3655 [(set (match_operand 0 "any_fp_register_operand")
3656 (match_operand 1 "memory_operand"))]
3658 && (GET_MODE (operands[0]) == TFmode
3659 || GET_MODE (operands[0]) == XFmode
3660 || GET_MODE (operands[0]) == DFmode
3661 || GET_MODE (operands[0]) == SFmode)
3662 && ix86_standard_x87sse_constant_load_p (insn, operands[0])"
3663 [(set (match_dup 0) (match_dup 2))]
3664 "operands[2] = find_constant_src (curr_insn);")
3667 [(set (match_operand 0 "any_fp_register_operand")
3668 (float_extend (match_operand 1 "memory_operand")))]
3670 && (GET_MODE (operands[0]) == TFmode
3671 || GET_MODE (operands[0]) == XFmode
3672 || GET_MODE (operands[0]) == DFmode)
3673 && ix86_standard_x87sse_constant_load_p (insn, operands[0])"
3674 [(set (match_dup 0) (match_dup 2))]
3675 "operands[2] = find_constant_src (curr_insn);")
3677 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
3679 [(set (match_operand:X87MODEF 0 "fp_register_operand")
3680 (match_operand:X87MODEF 1 "immediate_operand"))]
3682 && (standard_80387_constant_p (operands[1]) == 8
3683 || standard_80387_constant_p (operands[1]) == 9)"
3684 [(set (match_dup 0)(match_dup 1))
3686 (neg:X87MODEF (match_dup 0)))]
3688 if (real_isnegzero (CONST_DOUBLE_REAL_VALUE (operands[1])))
3689 operands[1] = CONST0_RTX (<MODE>mode);
3691 operands[1] = CONST1_RTX (<MODE>mode);
3694 (define_insn "*swapxf"
3695 [(set (match_operand:XF 0 "register_operand" "+f")
3696 (match_operand:XF 1 "register_operand" "+f"))
3701 if (STACK_TOP_P (operands[0]))
3706 [(set_attr "type" "fxch")
3707 (set_attr "mode" "XF")])
3710 ;; Zero extension instructions
3712 (define_expand "zero_extendsidi2"
3713 [(set (match_operand:DI 0 "nonimmediate_operand")
3714 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand")))])
3716 (define_insn "*zero_extendsidi2"
3717 [(set (match_operand:DI 0 "nonimmediate_operand"
3718 "=r,?r,?o,r ,o,?*y,?!*y,$r,$v,$x,*x,*v,*r,*k")
3720 (match_operand:SI 1 "x86_64_zext_operand"
3721 "0 ,rm,r ,rmWz,0,r ,m ,v ,r ,m ,*x,*v,*k,*km")))]
3724 switch (get_attr_type (insn))
3727 if (ix86_use_lea_for_mov (insn, operands))
3728 return "lea{l}\t{%E1, %k0|%k0, %E1}";
3730 return "mov{l}\t{%1, %k0|%k0, %1}";
3736 return "movd\t{%1, %0|%0, %1}";
3739 if (SSE_REG_P (operands[0]) && SSE_REG_P (operands[1]))
3741 if (EXT_REX_SSE_REG_P (operands[0])
3742 || EXT_REX_SSE_REG_P (operands[1]))
3743 return "vpmovzxdq\t{%t1, %g0|%g0, %t1}";
3745 return "%vpmovzxdq\t{%1, %0|%0, %1}";
3748 if (GENERAL_REG_P (operands[0]))
3749 return "%vmovd\t{%1, %k0|%k0, %1}";
3751 return "%vmovd\t{%1, %0|%0, %1}";
3754 return "kmovd\t{%1, %k0|%k0, %1}";
3761 (cond [(eq_attr "alternative" "0,1,2")
3762 (const_string "nox64")
3763 (eq_attr "alternative" "3")
3764 (const_string "x64")
3765 (eq_attr "alternative" "7,8,9")
3766 (const_string "sse2")
3767 (eq_attr "alternative" "10")
3768 (const_string "sse4")
3769 (eq_attr "alternative" "11")
3770 (const_string "avx512f")
3771 (eq_attr "alternative" "12")
3772 (const_string "x64_avx512bw")
3773 (eq_attr "alternative" "13")
3774 (const_string "avx512bw")
3776 (const_string "*")))
3777 (set (attr "mmx_isa")
3778 (if_then_else (eq_attr "alternative" "5,6")
3779 (const_string "native")
3780 (const_string "*")))
3782 (cond [(eq_attr "alternative" "0,1,2,4")
3783 (const_string "multi")
3784 (eq_attr "alternative" "5,6")
3785 (const_string "mmxmov")
3786 (eq_attr "alternative" "7")
3787 (if_then_else (match_test "TARGET_64BIT")
3788 (const_string "ssemov")
3789 (const_string "multi"))
3790 (eq_attr "alternative" "8,9,10,11")
3791 (const_string "ssemov")
3792 (eq_attr "alternative" "12,13")
3793 (const_string "mskmov")
3795 (const_string "imovx")))
3796 (set (attr "prefix_extra")
3797 (if_then_else (eq_attr "alternative" "10,11")
3799 (const_string "*")))
3800 (set (attr "prefix")
3801 (if_then_else (eq_attr "type" "ssemov")
3802 (const_string "maybe_vex")
3803 (const_string "orig")))
3804 (set (attr "prefix_0f")
3805 (if_then_else (eq_attr "type" "imovx")
3807 (const_string "*")))
3809 (cond [(eq_attr "alternative" "5,6")
3811 (and (eq_attr "alternative" "7")
3812 (match_test "TARGET_64BIT"))
3814 (eq_attr "alternative" "8,10,11")
3817 (const_string "SI")))
3818 (set (attr "preferred_for_speed")
3819 (cond [(eq_attr "alternative" "7")
3820 (symbol_ref "TARGET_INTER_UNIT_MOVES_FROM_VEC")
3821 (eq_attr "alternative" "5,8")
3822 (symbol_ref "TARGET_INTER_UNIT_MOVES_TO_VEC")
3824 (symbol_ref "true")))])
3827 [(set (match_operand:DI 0 "memory_operand")
3828 (zero_extend:DI (match_operand:SI 1 "memory_operand")))]
3830 [(set (match_dup 4) (const_int 0))]
3831 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3834 [(set (match_operand:DI 0 "general_reg_operand")
3835 (zero_extend:DI (match_operand:SI 1 "general_reg_operand")))]
3836 "!TARGET_64BIT && reload_completed
3837 && REGNO (operands[0]) == REGNO (operands[1])"
3838 [(set (match_dup 4) (const_int 0))]
3839 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3842 [(set (match_operand:DI 0 "nonimmediate_gr_operand")
3843 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand")))]
3844 "!TARGET_64BIT && reload_completed
3845 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
3846 [(set (match_dup 3) (match_dup 1))
3847 (set (match_dup 4) (const_int 0))]
3848 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3850 (define_mode_attr kmov_isa
3851 [(QI "avx512dq") (HI "avx512f") (SI "avx512bw") (DI "avx512bw")])
3853 (define_insn "zero_extend<mode>di2"
3854 [(set (match_operand:DI 0 "register_operand" "=r,*r,*k")
3856 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m,*k,*km")))]
3859 movz{<imodesuffix>l|x}\t{%1, %k0|%k0, %1}
3860 kmov<mskmodesuffix>\t{%1, %k0|%k0, %1}
3861 kmov<mskmodesuffix>\t{%1, %k0|%k0, %1}"
3862 [(set_attr "isa" "*,<kmov_isa>,<kmov_isa>")
3863 (set_attr "type" "imovx,mskmov,mskmov")
3864 (set_attr "mode" "SI,<MODE>,<MODE>")])
3866 (define_expand "zero_extend<mode>si2"
3867 [(set (match_operand:SI 0 "register_operand")
3868 (zero_extend:SI (match_operand:SWI12 1 "nonimmediate_operand")))]
3871 if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3873 operands[1] = force_reg (<MODE>mode, operands[1]);
3874 emit_insn (gen_zero_extend<mode>si2_and (operands[0], operands[1]));
3879 (define_insn_and_split "zero_extend<mode>si2_and"
3880 [(set (match_operand:SI 0 "register_operand" "=r,?&<r>")
3882 (match_operand:SWI12 1 "nonimmediate_operand" "0,<r>m")))
3883 (clobber (reg:CC FLAGS_REG))]
3884 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3886 "&& reload_completed"
3887 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (match_dup 2)))
3888 (clobber (reg:CC FLAGS_REG))])]
3890 if (!REG_P (operands[1])
3891 || REGNO (operands[0]) != REGNO (operands[1]))
3893 ix86_expand_clear (operands[0]);
3895 gcc_assert (!TARGET_PARTIAL_REG_STALL);
3896 emit_insn (gen_rtx_SET
3897 (gen_rtx_STRICT_LOW_PART
3898 (VOIDmode, gen_lowpart (<MODE>mode, operands[0])),
3903 operands[2] = GEN_INT (GET_MODE_MASK (<MODE>mode));
3905 [(set_attr "type" "alu1")
3906 (set_attr "mode" "SI")])
3908 (define_insn "*zero_extend<mode>si2"
3909 [(set (match_operand:SI 0 "register_operand" "=r,*r,*k")
3911 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m,*k,*km")))]
3912 "!(TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))"
3914 movz{<imodesuffix>l|x}\t{%1, %0|%0, %1}
3915 kmov<mskmodesuffix>\t{%1, %0|%0, %1}
3916 kmov<mskmodesuffix>\t{%1, %0|%0, %1}"
3917 [(set_attr "isa" "*,<kmov_isa>,<kmov_isa>")
3918 (set_attr "type" "imovx,mskmov,mskmov")
3919 (set_attr "mode" "SI,<MODE>,<MODE>")])
3921 (define_expand "zero_extendqihi2"
3922 [(set (match_operand:HI 0 "register_operand")
3923 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand")))]
3926 if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3928 operands[1] = force_reg (QImode, operands[1]);
3929 emit_insn (gen_zero_extendqihi2_and (operands[0], operands[1]));
3934 (define_insn_and_split "zero_extendqihi2_and"
3935 [(set (match_operand:HI 0 "register_operand" "=r,?&q")
3936 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3937 (clobber (reg:CC FLAGS_REG))]
3938 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3940 "&& reload_completed"
3941 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
3942 (clobber (reg:CC FLAGS_REG))])]
3944 if (!REG_P (operands[1])
3945 || REGNO (operands[0]) != REGNO (operands[1]))
3947 ix86_expand_clear (operands[0]);
3949 gcc_assert (!TARGET_PARTIAL_REG_STALL);
3950 emit_insn (gen_rtx_SET
3951 (gen_rtx_STRICT_LOW_PART
3952 (VOIDmode, gen_lowpart (QImode, operands[0])),
3957 operands[0] = gen_lowpart (SImode, operands[0]);
3959 [(set_attr "type" "alu1")
3960 (set_attr "mode" "SI")])
3962 ; zero extend to SImode to avoid partial register stalls
3963 (define_insn "*zero_extendqihi2"
3964 [(set (match_operand:HI 0 "register_operand" "=r,*r,*k")
3965 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,*k,*km")))]
3966 "!(TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))"
3968 movz{bl|x}\t{%1, %k0|%k0, %1}
3969 kmovb\t{%1, %k0|%k0, %1}
3970 kmovb\t{%1, %0|%0, %1}"
3971 [(set_attr "isa" "*,avx512dq,avx512dq")
3972 (set_attr "type" "imovx,mskmov,mskmov")
3973 (set_attr "mode" "SI,QI,QI")])
3975 ;; Sign extension instructions
3977 (define_expand "extendsidi2"
3978 [(set (match_operand:DI 0 "register_operand")
3979 (sign_extend:DI (match_operand:SI 1 "register_operand")))]
3984 emit_insn (gen_extendsidi2_1 (operands[0], operands[1]));
3989 (define_insn "*extendsidi2_rex64"
3990 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3991 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3995 movs{lq|x}\t{%1, %0|%0, %1}"
3996 [(set_attr "type" "imovx")
3997 (set_attr "mode" "DI")
3998 (set_attr "prefix_0f" "0")
3999 (set_attr "modrm" "0,1")])
4001 (define_insn "extendsidi2_1"
4002 [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
4003 (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
4004 (clobber (reg:CC FLAGS_REG))
4005 (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
4009 ;; Split the memory case. If the source register doesn't die, it will stay
4010 ;; this way, if it does die, following peephole2s take care of it.
4012 [(set (match_operand:DI 0 "memory_operand")
4013 (sign_extend:DI (match_operand:SI 1 "register_operand")))
4014 (clobber (reg:CC FLAGS_REG))
4015 (clobber (match_operand:SI 2 "register_operand"))]
4019 split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
4021 emit_move_insn (operands[3], operands[1]);
4023 /* Generate a cltd if possible and doing so it profitable. */
4024 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
4025 && REGNO (operands[1]) == AX_REG
4026 && REGNO (operands[2]) == DX_REG)
4028 emit_insn (gen_ashrsi3_cvt (operands[2], operands[1], GEN_INT (31)));
4032 emit_move_insn (operands[2], operands[1]);
4033 emit_insn (gen_ashrsi3_cvt (operands[2], operands[2], GEN_INT (31)));
4035 emit_move_insn (operands[4], operands[2]);
4039 ;; Peepholes for the case where the source register does die, after
4040 ;; being split with the above splitter.
4042 [(set (match_operand:SI 0 "memory_operand")
4043 (match_operand:SI 1 "general_reg_operand"))
4044 (set (match_operand:SI 2 "general_reg_operand") (match_dup 1))
4045 (parallel [(set (match_dup 2)
4046 (ashiftrt:SI (match_dup 2) (const_int 31)))
4047 (clobber (reg:CC FLAGS_REG))])
4048 (set (match_operand:SI 3 "memory_operand") (match_dup 2))]
4049 "REGNO (operands[1]) != REGNO (operands[2])
4050 && peep2_reg_dead_p (2, operands[1])
4051 && peep2_reg_dead_p (4, operands[2])
4052 && !reg_mentioned_p (operands[2], operands[3])"
4053 [(set (match_dup 0) (match_dup 1))
4054 (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
4055 (clobber (reg:CC FLAGS_REG))])
4056 (set (match_dup 3) (match_dup 1))])
4059 [(set (match_operand:SI 0 "memory_operand")
4060 (match_operand:SI 1 "general_reg_operand"))
4061 (parallel [(set (match_operand:SI 2 "general_reg_operand")
4062 (ashiftrt:SI (match_dup 1) (const_int 31)))
4063 (clobber (reg:CC FLAGS_REG))])
4064 (set (match_operand:SI 3 "memory_operand") (match_dup 2))]
4065 "/* cltd is shorter than sarl $31, %eax */
4066 !optimize_function_for_size_p (cfun)
4067 && REGNO (operands[1]) == AX_REG
4068 && REGNO (operands[2]) == DX_REG
4069 && peep2_reg_dead_p (2, operands[1])
4070 && peep2_reg_dead_p (3, operands[2])
4071 && !reg_mentioned_p (operands[2], operands[3])"
4072 [(set (match_dup 0) (match_dup 1))
4073 (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
4074 (clobber (reg:CC FLAGS_REG))])
4075 (set (match_dup 3) (match_dup 1))])
4077 ;; Extend to register case. Optimize case where source and destination
4078 ;; registers match and cases where we can use cltd.
4080 [(set (match_operand:DI 0 "register_operand")
4081 (sign_extend:DI (match_operand:SI 1 "register_operand")))
4082 (clobber (reg:CC FLAGS_REG))
4083 (clobber (match_scratch:SI 2))]
4087 split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
4089 if (REGNO (operands[3]) != REGNO (operands[1]))
4090 emit_move_insn (operands[3], operands[1]);
4092 /* Generate a cltd if possible and doing so it profitable. */
4093 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
4094 && REGNO (operands[3]) == AX_REG
4095 && REGNO (operands[4]) == DX_REG)
4097 emit_insn (gen_ashrsi3_cvt (operands[4], operands[3], GEN_INT (31)));
4101 if (REGNO (operands[4]) != REGNO (operands[1]))
4102 emit_move_insn (operands[4], operands[1]);
4104 emit_insn (gen_ashrsi3_cvt (operands[4], operands[4], GEN_INT (31)));
4108 (define_insn "extend<mode>di2"
4109 [(set (match_operand:DI 0 "register_operand" "=r")
4111 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
4113 "movs{<imodesuffix>q|x}\t{%1, %0|%0, %1}"
4114 [(set_attr "type" "imovx")
4115 (set_attr "mode" "DI")])
4117 (define_insn "extendhisi2"
4118 [(set (match_operand:SI 0 "register_operand" "=*a,r")
4119 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
4122 switch (get_attr_prefix_0f (insn))
4125 return "{cwtl|cwde}";
4127 return "movs{wl|x}\t{%1, %0|%0, %1}";
4130 [(set_attr "type" "imovx")
4131 (set_attr "mode" "SI")
4132 (set (attr "prefix_0f")
4133 ;; movsx is short decodable while cwtl is vector decoded.
4134 (if_then_else (and (eq_attr "cpu" "!k6")
4135 (eq_attr "alternative" "0"))
4137 (const_string "1")))
4138 (set (attr "znver1_decode")
4139 (if_then_else (eq_attr "prefix_0f" "0")
4140 (const_string "double")
4141 (const_string "direct")))
4143 (if_then_else (eq_attr "prefix_0f" "0")
4145 (const_string "1")))])
4147 (define_insn "*extendhisi2_zext"
4148 [(set (match_operand:DI 0 "register_operand" "=*a,r")
4151 (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
4154 switch (get_attr_prefix_0f (insn))
4157 return "{cwtl|cwde}";
4159 return "movs{wl|x}\t{%1, %k0|%k0, %1}";
4162 [(set_attr "type" "imovx")
4163 (set_attr "mode" "SI")
4164 (set (attr "prefix_0f")
4165 ;; movsx is short decodable while cwtl is vector decoded.
4166 (if_then_else (and (eq_attr "cpu" "!k6")
4167 (eq_attr "alternative" "0"))
4169 (const_string "1")))
4171 (if_then_else (eq_attr "prefix_0f" "0")
4173 (const_string "1")))])
4175 (define_insn "extendqisi2"
4176 [(set (match_operand:SI 0 "register_operand" "=r")
4177 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
4179 "movs{bl|x}\t{%1, %0|%0, %1}"
4180 [(set_attr "type" "imovx")
4181 (set_attr "mode" "SI")])
4183 (define_insn "*extendqisi2_zext"
4184 [(set (match_operand:DI 0 "register_operand" "=r")
4186 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
4188 "movs{bl|x}\t{%1, %k0|%k0, %1}"
4189 [(set_attr "type" "imovx")
4190 (set_attr "mode" "SI")])
4192 (define_insn "extendqihi2"
4193 [(set (match_operand:HI 0 "register_operand" "=*a,r")
4194 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
4197 switch (get_attr_prefix_0f (insn))
4200 return "{cbtw|cbw}";
4202 return "movs{bw|x}\t{%1, %0|%0, %1}";
4205 [(set_attr "type" "imovx")
4206 (set_attr "mode" "HI")
4207 (set (attr "prefix_0f")
4208 ;; movsx is short decodable while cwtl is vector decoded.
4209 (if_then_else (and (eq_attr "cpu" "!k6")
4210 (eq_attr "alternative" "0"))
4212 (const_string "1")))
4214 (if_then_else (eq_attr "prefix_0f" "0")
4216 (const_string "1")))])
4218 ;; Conversions between float and double.
4220 ;; These are all no-ops in the model used for the 80387.
4221 ;; So just emit moves.
4223 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
4225 [(set (match_operand:DF 0 "push_operand")
4226 (float_extend:DF (match_operand:SF 1 "fp_register_operand")))]
4228 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
4229 (set (mem:DF (reg:P SP_REG)) (float_extend:DF (match_dup 1)))])
4232 [(set (match_operand:XF 0 "push_operand")
4233 (float_extend:XF (match_operand:MODEF 1 "fp_register_operand")))]
4235 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
4236 (set (mem:XF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
4237 "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
4239 (define_expand "extendsfdf2"
4240 [(set (match_operand:DF 0 "nonimm_ssenomem_operand")
4241 (float_extend:DF (match_operand:SF 1 "general_operand")))]
4242 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4244 /* ??? Needed for compress_float_constant since all fp constants
4245 are TARGET_LEGITIMATE_CONSTANT_P. */
4246 if (CONST_DOUBLE_P (operands[1]))
4248 if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
4249 && standard_80387_constant_p (operands[1]) > 0)
4251 operands[1] = simplify_const_unary_operation
4252 (FLOAT_EXTEND, DFmode, operands[1], SFmode);
4253 emit_move_insn_1 (operands[0], operands[1]);
4256 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
4260 (define_insn "*extendsfdf2"
4261 [(set (match_operand:DF 0 "nonimm_ssenomem_operand" "=f,m,v,v")
4263 (match_operand:SF 1 "nonimmediate_operand" "fm,f,v,m")))]
4264 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4266 switch (which_alternative)
4270 return output_387_reg_move (insn, operands);
4273 return "%vcvtss2sd\t{%d1, %0|%0, %d1}";
4275 return "%vcvtss2sd\t{%1, %d0|%d0, %1}";
4281 [(set_attr "type" "fmov,fmov,ssecvt,ssecvt")
4282 (set_attr "avx_partial_xmm_update" "false,false,false,true")
4283 (set_attr "prefix" "orig,orig,maybe_vex,maybe_vex")
4284 (set_attr "mode" "SF,XF,DF,DF")
4285 (set (attr "enabled")
4287 (match_test ("TARGET_SSE2 && TARGET_SSE_MATH"))
4289 (eq_attr "alternative" "0,1")
4290 (symbol_ref "TARGET_MIX_SSE_I387")
4291 (symbol_ref "true"))
4293 (eq_attr "alternative" "0,1")
4295 (symbol_ref "false"))))])
4297 /* For converting SF(xmm2) to DF(xmm1), use the following code instead of
4299 unpcklps xmm2,xmm2 ; packed conversion might crash on signaling NaNs
4301 We do the conversion post reload to avoid producing of 128bit spills
4302 that might lead to ICE on 32bit target. The sequence unlikely combine
4305 [(set (match_operand:DF 0 "sse_reg_operand")
4307 (match_operand:SF 1 "nonimmediate_operand")))]
4308 "TARGET_USE_VECTOR_FP_CONVERTS
4309 && optimize_insn_for_speed_p ()
4311 && (!EXT_REX_SSE_REG_P (operands[0])
4312 || TARGET_AVX512VL)"
4317 (parallel [(const_int 0) (const_int 1)]))))]
4319 operands[2] = lowpart_subreg (V2DFmode, operands[0], DFmode);
4320 operands[3] = lowpart_subreg (V4SFmode, operands[0], DFmode);
4321 /* Use movss for loading from memory, unpcklps reg, reg for registers.
4322 Try to avoid move when unpacking can be done in source. */
4323 if (REG_P (operands[1]))
4325 /* If it is unsafe to overwrite upper half of source, we need
4326 to move to destination and unpack there. */
4327 if (REGNO (operands[0]) != REGNO (operands[1])
4328 || (EXT_REX_SSE_REG_P (operands[1])
4329 && !TARGET_AVX512VL))
4331 rtx tmp = lowpart_subreg (SFmode, operands[0], DFmode);
4332 emit_move_insn (tmp, operands[1]);
4335 operands[3] = lowpart_subreg (V4SFmode, operands[1], SFmode);
4336 /* FIXME: vec_interleave_lowv4sf for AVX512VL should allow
4337 =v, v, then vbroadcastss will be only needed for AVX512F without
4339 if (!EXT_REX_SSE_REGNO_P (REGNO (operands[3])))
4340 emit_insn (gen_vec_interleave_lowv4sf (operands[3], operands[3],
4344 rtx tmp = lowpart_subreg (V16SFmode, operands[3], V4SFmode);
4345 emit_insn (gen_avx512f_vec_dupv16sf_1 (tmp, tmp));
4349 emit_insn (gen_vec_setv4sf_0 (operands[3],
4350 CONST0_RTX (V4SFmode), operands[1]));
4353 ;; It's more profitable to split and then extend in the same register.
4355 [(set (match_operand:DF 0 "sse_reg_operand")
4357 (match_operand:SF 1 "memory_operand")))]
4358 "TARGET_SPLIT_MEM_OPND_FOR_FP_CONVERTS
4359 && optimize_insn_for_speed_p ()"
4360 [(set (match_dup 2) (match_dup 1))
4361 (set (match_dup 0) (float_extend:DF (match_dup 2)))]
4362 "operands[2] = lowpart_subreg (SFmode, operands[0], DFmode);")
4364 ;; Break partial SSE register dependency stall. This splitter should split
4365 ;; late in the pass sequence (after register rename pass), so allocated
4366 ;; registers won't change anymore
4369 [(set (match_operand:DF 0 "sse_reg_operand")
4371 (match_operand:SF 1 "nonimmediate_operand")))]
4373 && TARGET_SSE_PARTIAL_REG_DEPENDENCY && epilogue_completed
4374 && optimize_function_for_speed_p (cfun)
4375 && (!REG_P (operands[1])
4376 || (!TARGET_AVX && REGNO (operands[0]) != REGNO (operands[1])))
4377 && (!EXT_REX_SSE_REG_P (operands[0])
4378 || TARGET_AVX512VL)"
4387 operands[0] = lowpart_subreg (V2DFmode, operands[0], DFmode);
4388 emit_move_insn (operands[0], CONST0_RTX (V2DFmode));
4391 (define_expand "extend<mode>xf2"
4392 [(set (match_operand:XF 0 "nonimmediate_operand")
4393 (float_extend:XF (match_operand:MODEF 1 "general_operand")))]
4396 /* ??? Needed for compress_float_constant since all fp constants
4397 are TARGET_LEGITIMATE_CONSTANT_P. */
4398 if (CONST_DOUBLE_P (operands[1]))
4400 if (standard_80387_constant_p (operands[1]) > 0)
4402 operands[1] = simplify_const_unary_operation
4403 (FLOAT_EXTEND, XFmode, operands[1], <MODE>mode);
4404 emit_move_insn_1 (operands[0], operands[1]);
4407 operands[1] = validize_mem (force_const_mem (<MODE>mode, operands[1]));
4411 (define_insn "*extend<mode>xf2_i387"
4412 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
4414 (match_operand:MODEF 1 "nonimmediate_operand" "fm,f")))]
4416 "* return output_387_reg_move (insn, operands);"
4417 [(set_attr "type" "fmov")
4418 (set_attr "mode" "<MODE>,XF")])
4420 ;; %%% This seems like bad news.
4421 ;; This cannot output into an f-reg because there is no way to be sure
4422 ;; of truncating in that case. Otherwise this is just like a simple move
4423 ;; insn. So we pretend we can output to a reg in order to get better
4424 ;; register preferencing, but we really use a stack slot.
4426 ;; Conversion from DFmode to SFmode.
4428 (define_insn "truncdfsf2"
4429 [(set (match_operand:SF 0 "nonimm_ssenomem_operand" "=m,f,v,v")
4431 (match_operand:DF 1 "register_ssemem_operand" "f,f,v,m")))]
4432 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4434 switch (which_alternative)
4438 return output_387_reg_move (insn, operands);
4441 return "%vcvtsd2ss\t{%d1, %0|%0, %d1}";
4443 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4449 [(set_attr "type" "fmov,fmov,ssecvt,ssecvt")
4450 (set_attr "avx_partial_xmm_update" "false,false,false,true")
4451 (set_attr "mode" "SF")
4452 (set (attr "enabled")
4454 (match_test ("TARGET_SSE2 && TARGET_SSE_MATH"))
4455 (cond [(eq_attr "alternative" "0")
4456 (symbol_ref "TARGET_MIX_SSE_I387")
4457 (eq_attr "alternative" "1")
4458 (symbol_ref "TARGET_MIX_SSE_I387
4459 && flag_unsafe_math_optimizations")
4461 (symbol_ref "true"))
4462 (cond [(eq_attr "alternative" "0")
4464 (eq_attr "alternative" "1")
4465 (symbol_ref "flag_unsafe_math_optimizations")
4467 (symbol_ref "false"))))])
4469 /* For converting DF(xmm2) to SF(xmm1), use the following code instead of
4471 unpcklpd xmm2,xmm2 ; packed conversion might crash on signaling NaNs
4473 We do the conversion post reload to avoid producing of 128bit spills
4474 that might lead to ICE on 32bit target. The sequence unlikely combine
4477 [(set (match_operand:SF 0 "sse_reg_operand")
4479 (match_operand:DF 1 "nonimmediate_operand")))]
4480 "TARGET_USE_VECTOR_FP_CONVERTS
4481 && optimize_insn_for_speed_p ()
4483 && (!EXT_REX_SSE_REG_P (operands[0])
4484 || TARGET_AVX512VL)"
4487 (float_truncate:V2SF
4491 operands[2] = lowpart_subreg (V4SFmode, operands[0], SFmode);
4492 operands[3] = CONST0_RTX (V2SFmode);
4493 operands[4] = lowpart_subreg (V2DFmode, operands[0], SFmode);
4494 /* Use movsd for loading from memory, unpcklpd for registers.
4495 Try to avoid move when unpacking can be done in source, or SSE3
4496 movddup is available. */
4497 if (REG_P (operands[1]))
4500 && REGNO (operands[0]) != REGNO (operands[1]))
4502 rtx tmp = lowpart_subreg (DFmode, operands[0], SFmode);
4503 emit_move_insn (tmp, operands[1]);
4506 else if (!TARGET_SSE3)
4507 operands[4] = lowpart_subreg (V2DFmode, operands[1], DFmode);
4508 emit_insn (gen_vec_dupv2df (operands[4], operands[1]));
4511 emit_insn (gen_vec_concatv2df (operands[4], operands[1],
4512 CONST0_RTX (DFmode)));
4515 ;; It's more profitable to split and then truncate in the same register.
4517 [(set (match_operand:SF 0 "sse_reg_operand")
4519 (match_operand:DF 1 "memory_operand")))]
4520 "TARGET_SPLIT_MEM_OPND_FOR_FP_CONVERTS
4521 && optimize_insn_for_speed_p ()"
4522 [(set (match_dup 2) (match_dup 1))
4523 (set (match_dup 0) (float_truncate:SF (match_dup 2)))]
4524 "operands[2] = lowpart_subreg (DFmode, operands[0], SFmode);")
4526 ;; Break partial SSE register dependency stall. This splitter should split
4527 ;; late in the pass sequence (after register rename pass), so allocated
4528 ;; registers won't change anymore
4531 [(set (match_operand:SF 0 "sse_reg_operand")
4533 (match_operand:DF 1 "nonimmediate_operand")))]
4535 && TARGET_SSE_PARTIAL_REG_DEPENDENCY && epilogue_completed
4536 && optimize_function_for_speed_p (cfun)
4537 && (!REG_P (operands[1])
4538 || (!TARGET_AVX && REGNO (operands[0]) != REGNO (operands[1])))
4539 && (!EXT_REX_SSE_REG_P (operands[0])
4540 || TARGET_AVX512VL)"
4549 operands[0] = lowpart_subreg (V4SFmode, operands[0], SFmode);
4550 emit_move_insn (operands[0], CONST0_RTX (V4SFmode));
4553 ;; Conversion from XFmode to {SF,DF}mode
4555 (define_insn "truncxf<mode>2"
4556 [(set (match_operand:MODEF 0 "nonimmediate_operand" "=m,f")
4557 (float_truncate:MODEF
4558 (match_operand:XF 1 "register_operand" "f,f")))]
4560 "* return output_387_reg_move (insn, operands);"
4561 [(set_attr "type" "fmov")
4562 (set_attr "mode" "<MODE>")
4563 (set (attr "enabled")
4564 (cond [(eq_attr "alternative" "1")
4565 (symbol_ref "flag_unsafe_math_optimizations")
4567 (symbol_ref "true")))])
4569 ;; Signed conversion to DImode.
4571 (define_expand "fix_truncxfdi2"
4572 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand")
4573 (fix:DI (match_operand:XF 1 "register_operand")))
4574 (clobber (reg:CC FLAGS_REG))])]
4579 emit_insn (gen_fix_truncdi_i387_fisttp (operands[0], operands[1]));
4584 (define_expand "fix_trunc<mode>di2"
4585 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand")
4586 (fix:DI (match_operand:MODEF 1 "register_operand")))
4587 (clobber (reg:CC FLAGS_REG))])]
4588 "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4591 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4593 emit_insn (gen_fix_truncdi_i387_fisttp (operands[0], operands[1]));
4596 if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4598 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4599 emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4600 if (out != operands[0])
4601 emit_move_insn (operands[0], out);
4606 ;; Signed conversion to SImode.
4608 (define_expand "fix_truncxfsi2"
4609 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand")
4610 (fix:SI (match_operand:XF 1 "register_operand")))
4611 (clobber (reg:CC FLAGS_REG))])]
4616 emit_insn (gen_fix_truncsi_i387_fisttp (operands[0], operands[1]));
4621 (define_expand "fix_trunc<mode>si2"
4622 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand")
4623 (fix:SI (match_operand:MODEF 1 "register_operand")))
4624 (clobber (reg:CC FLAGS_REG))])]
4625 "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4628 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4630 emit_insn (gen_fix_truncsi_i387_fisttp (operands[0], operands[1]));
4633 if (SSE_FLOAT_MODE_P (<MODE>mode))
4635 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4636 emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4637 if (out != operands[0])
4638 emit_move_insn (operands[0], out);
4643 ;; Signed conversion to HImode.
4645 (define_expand "fix_trunc<mode>hi2"
4646 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand")
4647 (fix:HI (match_operand:X87MODEF 1 "register_operand")))
4648 (clobber (reg:CC FLAGS_REG))])]
4650 && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4654 emit_insn (gen_fix_trunchi_i387_fisttp (operands[0], operands[1]));
4659 ;; Unsigned conversion to DImode
4661 (define_insn "fixuns_trunc<mode>di2"
4662 [(set (match_operand:DI 0 "register_operand" "=r")
4664 (match_operand:MODEF 1 "nonimmediate_operand" "vm")))]
4665 "TARGET_64BIT && TARGET_AVX512F && TARGET_SSE_MATH"
4666 "vcvtt<ssemodesuffix>2usi\t{%1, %0|%0, %1}"
4667 [(set_attr "type" "sseicvt")
4668 (set_attr "prefix" "evex")
4669 (set_attr "mode" "DI")])
4671 ;; Unsigned conversion to SImode.
4673 (define_expand "fixuns_trunc<mode>si2"
4675 [(set (match_operand:SI 0 "register_operand")
4677 (match_operand:MODEF 1 "nonimmediate_operand")))
4679 (clobber (scratch:<ssevecmode>))
4680 (clobber (scratch:<ssevecmode>))])]
4681 "(!TARGET_64BIT || TARGET_AVX512F) && TARGET_SSE2 && TARGET_SSE_MATH"
4683 machine_mode mode = <MODE>mode;
4684 machine_mode vecmode = <ssevecmode>mode;
4685 REAL_VALUE_TYPE TWO31r;
4690 emit_insn (gen_fixuns_trunc<mode>si2_avx512f (operands[0], operands[1]));
4694 if (optimize_insn_for_size_p ())
4697 real_ldexp (&TWO31r, &dconst1, 31);
4698 two31 = const_double_from_real_value (TWO31r, mode);
4699 two31 = ix86_build_const_vector (vecmode, true, two31);
4700 operands[2] = force_reg (vecmode, two31);
4703 (define_insn "fixuns_trunc<mode>si2_avx512f"
4704 [(set (match_operand:SI 0 "register_operand" "=r")
4706 (match_operand:MODEF 1 "nonimmediate_operand" "vm")))]
4707 "TARGET_AVX512F && TARGET_SSE_MATH"
4708 "vcvtt<ssemodesuffix>2usi\t{%1, %0|%0, %1}"
4709 [(set_attr "type" "sseicvt")
4710 (set_attr "prefix" "evex")
4711 (set_attr "mode" "SI")])
4713 (define_insn "*fixuns_trunc<mode>si2_avx512f_zext"
4714 [(set (match_operand:DI 0 "register_operand" "=r")
4717 (match_operand:MODEF 1 "nonimmediate_operand" "vm"))))]
4718 "TARGET_64BIT && TARGET_AVX512F && TARGET_SSE_MATH"
4719 "vcvtt<ssemodesuffix>2usi\t{%1, %k0|%k0, %1}"
4720 [(set_attr "type" "sseicvt")
4721 (set_attr "prefix" "evex")
4722 (set_attr "mode" "SI")])
4724 (define_insn_and_split "*fixuns_trunc<mode>_1"
4725 [(set (match_operand:SI 0 "register_operand" "=&x,&x")
4727 (match_operand:MODEF 3 "nonimmediate_operand" "xm,xm")))
4728 (use (match_operand:<ssevecmode> 4 "nonimmediate_operand" "m,x"))
4729 (clobber (match_scratch:<ssevecmode> 1 "=x,&x"))
4730 (clobber (match_scratch:<ssevecmode> 2 "=x,x"))]
4731 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH
4732 && optimize_function_for_speed_p (cfun)"
4734 "&& reload_completed"
4737 ix86_split_convert_uns_si_sse (operands);
4741 ;; Unsigned conversion to HImode.
4742 ;; Without these patterns, we'll try the unsigned SI conversion which
4743 ;; is complex for SSE, rather than the signed SI conversion, which isn't.
4745 (define_expand "fixuns_trunc<mode>hi2"
4747 (fix:SI (match_operand:MODEF 1 "nonimmediate_operand")))
4748 (set (match_operand:HI 0 "nonimmediate_operand")
4749 (subreg:HI (match_dup 2) 0))]
4750 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
4751 "operands[2] = gen_reg_rtx (SImode);")
4753 ;; When SSE is available, it is always faster to use it!
4754 (define_insn "fix_trunc<MODEF:mode><SWI48:mode>_sse"
4755 [(set (match_operand:SWI48 0 "register_operand" "=r,r")
4756 (fix:SWI48 (match_operand:MODEF 1 "nonimmediate_operand" "v,m")))]
4757 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode)
4758 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4759 "%vcvtt<MODEF:ssemodesuffix>2si<SWI48:rex64suffix>\t{%1, %0|%0, %1}"
4760 [(set_attr "type" "sseicvt")
4761 (set_attr "prefix" "maybe_vex")
4762 (set (attr "prefix_rex")
4764 (match_test "<SWI48:MODE>mode == DImode")
4766 (const_string "*")))
4767 (set_attr "mode" "<MODEF:MODE>")
4768 (set_attr "athlon_decode" "double,vector")
4769 (set_attr "amdfam10_decode" "double,double")
4770 (set_attr "bdver1_decode" "double,double")])
4772 ;; Avoid vector decoded forms of the instruction.
4774 [(match_scratch:MODEF 2 "x")
4775 (set (match_operand:SWI48 0 "register_operand")
4776 (fix:SWI48 (match_operand:MODEF 1 "memory_operand")))]
4777 "TARGET_AVOID_VECTOR_DECODE
4778 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode)
4779 && optimize_insn_for_speed_p ()"
4780 [(set (match_dup 2) (match_dup 1))
4781 (set (match_dup 0) (fix:SWI48 (match_dup 2)))])
4783 (define_insn "fix_trunc<mode>_i387_fisttp"
4784 [(set (match_operand:SWI248x 0 "nonimmediate_operand" "=m")
4785 (fix:SWI248x (match_operand 1 "register_operand" "f")))
4786 (clobber (match_scratch:XF 2 "=&f"))]
4787 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4789 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4790 && (TARGET_64BIT || <MODE>mode != DImode))
4791 && TARGET_SSE_MATH)"
4792 "* return output_fix_trunc (insn, operands, true);"
4793 [(set_attr "type" "fisttp")
4794 (set_attr "mode" "<MODE>")])
4796 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4797 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4798 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4799 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4800 ;; function in i386.c.
4801 (define_insn_and_split "*fix_trunc<mode>_i387_1"
4802 [(set (match_operand:SWI248x 0 "nonimmediate_operand")
4803 (fix:SWI248x (match_operand 1 "register_operand")))
4804 (clobber (reg:CC FLAGS_REG))]
4805 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4807 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4808 && (TARGET_64BIT || <MODE>mode != DImode))
4809 && ix86_pre_reload_split ()"
4814 ix86_optimize_mode_switching[I387_TRUNC] = 1;
4816 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
4817 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
4819 emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4820 operands[2], operands[3]));
4823 [(set_attr "type" "fistp")
4824 (set_attr "i387_cw" "trunc")
4825 (set_attr "mode" "<MODE>")])
4827 (define_insn "fix_truncdi_i387"
4828 [(set (match_operand:DI 0 "nonimmediate_operand" "=m")
4829 (fix:DI (match_operand 1 "register_operand" "f")))
4830 (use (match_operand:HI 2 "memory_operand" "m"))
4831 (use (match_operand:HI 3 "memory_operand" "m"))
4832 (clobber (match_scratch:XF 4 "=&f"))]
4833 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4835 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4836 "* return output_fix_trunc (insn, operands, false);"
4837 [(set_attr "type" "fistp")
4838 (set_attr "i387_cw" "trunc")
4839 (set_attr "mode" "DI")])
4841 (define_insn "fix_trunc<mode>_i387"
4842 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m")
4843 (fix:SWI24 (match_operand 1 "register_operand" "f")))
4844 (use (match_operand:HI 2 "memory_operand" "m"))
4845 (use (match_operand:HI 3 "memory_operand" "m"))]
4846 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4848 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4849 "* return output_fix_trunc (insn, operands, false);"
4850 [(set_attr "type" "fistp")
4851 (set_attr "i387_cw" "trunc")
4852 (set_attr "mode" "<MODE>")])
4854 (define_insn "x86_fnstcw_1"
4855 [(set (match_operand:HI 0 "memory_operand" "=m")
4856 (unspec:HI [(const_int 0)] UNSPEC_FSTCW))]
4859 [(set (attr "length")
4860 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
4861 (set_attr "mode" "HI")
4862 (set_attr "unit" "i387")
4863 (set_attr "bdver1_decode" "vector")])
4865 ;; Conversion between fixed point and floating point.
4867 ;; Even though we only accept memory inputs, the backend _really_
4868 ;; wants to be able to do this between registers. Thankfully, LRA
4869 ;; will fix this up for us during register allocation.
4871 (define_insn "floathi<mode>2"
4872 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
4873 (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "m")))]
4875 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4876 || TARGET_MIX_SSE_I387)"
4878 [(set_attr "type" "fmov")
4879 (set_attr "mode" "<MODE>")
4880 (set_attr "znver1_decode" "double")
4881 (set_attr "fp_int_src" "true")])
4883 (define_insn "float<SWI48x:mode>xf2"
4884 [(set (match_operand:XF 0 "register_operand" "=f")
4885 (float:XF (match_operand:SWI48x 1 "nonimmediate_operand" "m")))]
4888 [(set_attr "type" "fmov")
4889 (set_attr "mode" "XF")
4890 (set_attr "znver1_decode" "double")
4891 (set_attr "fp_int_src" "true")])
4893 (define_expand "float<SWI48x:mode><MODEF:mode>2"
4894 [(set (match_operand:MODEF 0 "register_operand")
4895 (float:MODEF (match_operand:SWI48x 1 "nonimmediate_operand")))]
4896 "(TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI48x:MODE>mode))
4897 || (SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
4898 && ((<SWI48x:MODE>mode != DImode) || TARGET_64BIT))")
4900 (define_insn "*float<SWI48:mode><MODEF:mode>2"
4901 [(set (match_operand:MODEF 0 "register_operand" "=f,v,v")
4903 (match_operand:SWI48 1 "nonimmediate_operand" "m,r,m")))]
4904 "(TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI48:MODE>mode))
4905 || (SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)"
4908 %vcvtsi2<MODEF:ssemodesuffix><SWI48:rex64suffix>\t{%1, %d0|%d0, %1}
4909 %vcvtsi2<MODEF:ssemodesuffix><SWI48:rex64suffix>\t{%1, %d0|%d0, %1}"
4910 [(set_attr "type" "fmov,sseicvt,sseicvt")
4911 (set_attr "avx_partial_xmm_update" "false,true,true")
4912 (set_attr "prefix" "orig,maybe_vex,maybe_vex")
4913 (set_attr "mode" "<MODEF:MODE>")
4914 (set (attr "prefix_rex")
4916 (and (eq_attr "prefix" "maybe_vex")
4917 (match_test "<SWI48:MODE>mode == DImode"))
4919 (const_string "*")))
4920 (set_attr "unit" "i387,*,*")
4921 (set_attr "athlon_decode" "*,double,direct")
4922 (set_attr "amdfam10_decode" "*,vector,double")
4923 (set_attr "bdver1_decode" "*,double,direct")
4924 (set_attr "znver1_decode" "double,*,*")
4925 (set_attr "fp_int_src" "true")
4926 (set (attr "enabled")
4928 (match_test ("SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"))
4930 (eq_attr "alternative" "0")
4931 (symbol_ref "TARGET_MIX_SSE_I387
4932 && X87_ENABLE_FLOAT (<MODEF:MODE>mode,
4934 (symbol_ref "true"))
4936 (eq_attr "alternative" "0")
4938 (symbol_ref "false"))))
4939 (set (attr "preferred_for_speed")
4940 (cond [(eq_attr "alternative" "1")
4941 (symbol_ref "TARGET_INTER_UNIT_CONVERSIONS")]
4942 (symbol_ref "true")))])
4944 (define_insn "*floatdi<MODEF:mode>2_i387"
4945 [(set (match_operand:MODEF 0 "register_operand" "=f")
4946 (float:MODEF (match_operand:DI 1 "nonimmediate_operand" "m")))]
4948 && TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, DImode)"
4950 [(set_attr "type" "fmov")
4951 (set_attr "mode" "<MODEF:MODE>")
4952 (set_attr "znver1_decode" "double")
4953 (set_attr "fp_int_src" "true")])
4955 ;; Try TARGET_USE_VECTOR_CONVERTS, but not so hard as to require extra memory
4956 ;; slots when !TARGET_INTER_UNIT_MOVES_TO_VEC disables the general_regs
4957 ;; alternative in sse2_loadld.
4959 [(set (match_operand:MODEF 0 "sse_reg_operand")
4960 (float:MODEF (match_operand:SI 1 "nonimmediate_operand")))]
4962 && TARGET_USE_VECTOR_CONVERTS
4963 && optimize_function_for_speed_p (cfun)
4965 && (MEM_P (operands[1]) || TARGET_INTER_UNIT_MOVES_TO_VEC)
4966 && (!EXT_REX_SSE_REG_P (operands[0])
4967 || TARGET_AVX512VL)"
4970 operands[3] = lowpart_subreg (<ssevecmode>mode, operands[0], <MODE>mode);
4971 operands[4] = lowpart_subreg (V4SImode, operands[0], <MODE>mode);
4973 emit_insn (gen_sse2_loadld (operands[4],
4974 CONST0_RTX (V4SImode), operands[1]));
4976 if (<ssevecmode>mode == V4SFmode)
4977 emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
4979 emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
4983 ;; Avoid store forwarding (partial memory) stall penalty
4984 ;; by passing DImode value through XMM registers. */
4987 [(set (match_operand:X87MODEF 0 "register_operand")
4989 (match_operand:DI 1 "register_operand")))]
4990 "!TARGET_64BIT && TARGET_INTER_UNIT_MOVES_TO_VEC
4991 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
4992 && TARGET_SSE2 && optimize_function_for_speed_p (cfun)
4993 && can_create_pseudo_p ()"
4996 emit_insn (gen_floatdi<mode>2_i387_with_xmm
4997 (operands[0], operands[1],
4998 assign_386_stack_local (DImode, SLOT_TEMP)));
5002 (define_insn_and_split "floatdi<X87MODEF:mode>2_i387_with_xmm"
5003 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5005 (match_operand:DI 1 "register_operand" "r,r")))
5006 (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
5007 (clobber (match_scratch:V4SI 3 "=x,x"))
5008 (clobber (match_scratch:V4SI 4 "=X,x"))]
5009 "!TARGET_64BIT && TARGET_INTER_UNIT_MOVES_TO_VEC
5010 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5011 && TARGET_SSE2 && optimize_function_for_speed_p (cfun)"
5013 "&& reload_completed"
5014 [(set (match_dup 2) (match_dup 3))
5015 (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5017 /* The DImode arrived in a pair of integral registers (e.g. %edx:%eax).
5018 Assemble the 64-bit DImode value in an xmm register. */
5019 emit_insn (gen_sse2_loadld (operands[3], CONST0_RTX (V4SImode),
5020 gen_lowpart (SImode, operands[1])));
5022 emit_insn (gen_sse4_1_pinsrd (operands[3], operands[3],
5023 gen_highpart (SImode, operands[1]),
5027 emit_insn (gen_sse2_loadld (operands[4], CONST0_RTX (V4SImode),
5028 gen_highpart (SImode, operands[1])));
5029 emit_insn (gen_vec_interleave_lowv4si (operands[3], operands[3],
5032 operands[3] = gen_lowpart (DImode, operands[3]);
5034 [(set_attr "isa" "sse4,*")
5035 (set_attr "type" "multi")
5036 (set_attr "mode" "<X87MODEF:MODE>")
5037 (set_attr "unit" "i387")
5038 (set_attr "fp_int_src" "true")])
5040 ;; Break partial SSE register dependency stall. This splitter should split
5041 ;; late in the pass sequence (after register rename pass), so allocated
5042 ;; registers won't change anymore
5045 [(set (match_operand:MODEF 0 "sse_reg_operand")
5046 (float:MODEF (match_operand:SWI48 1 "nonimmediate_operand")))]
5048 && TARGET_SSE_PARTIAL_REG_DEPENDENCY && epilogue_completed
5049 && optimize_function_for_speed_p (cfun)
5050 && (!EXT_REX_SSE_REG_P (operands[0])
5051 || TARGET_AVX512VL)"
5053 (vec_merge:<MODEF:ssevecmode>
5054 (vec_duplicate:<MODEF:ssevecmode>
5060 const machine_mode vmode = <MODEF:ssevecmode>mode;
5062 operands[0] = lowpart_subreg (vmode, operands[0], <MODEF:MODE>mode);
5063 emit_move_insn (operands[0], CONST0_RTX (vmode));
5066 (define_expand "floatuns<SWI12:mode><MODEF:mode>2"
5067 [(set (match_operand:MODEF 0 "register_operand")
5068 (unsigned_float:MODEF
5069 (match_operand:SWI12 1 "nonimmediate_operand")))]
5071 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
5073 operands[1] = convert_to_mode (SImode, operands[1], 1);
5074 emit_insn (gen_floatsi<MODEF:mode>2 (operands[0], operands[1]));
5078 (define_insn "*floatuns<SWI48:mode><MODEF:mode>2_avx512"
5079 [(set (match_operand:MODEF 0 "register_operand" "=v")
5080 (unsigned_float:MODEF
5081 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))]
5082 "TARGET_AVX512F && TARGET_SSE_MATH"
5083 "vcvtusi2<MODEF:ssemodesuffix><SWI48:rex64suffix>\t{%1, %0, %0|%0, %0, %1}"
5084 [(set_attr "type" "sseicvt")
5085 (set_attr "avx_partial_xmm_update" "true")
5086 (set_attr "prefix" "evex")
5087 (set_attr "mode" "<MODEF:MODE>")])
5089 ;; Avoid store forwarding (partial memory) stall penalty by extending
5090 ;; SImode value to DImode through XMM register instead of pushing two
5091 ;; SImode values to stack. Also note that fild loads from memory only.
5093 (define_insn_and_split "floatunssi<mode>2_i387_with_xmm"
5094 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5095 (unsigned_float:X87MODEF
5096 (match_operand:SI 1 "nonimmediate_operand" "rm")))
5097 (clobber (match_operand:DI 2 "memory_operand" "=m"))
5098 (clobber (match_scratch:DI 3 "=x"))]
5100 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5101 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC"
5103 "&& reload_completed"
5104 [(set (match_dup 3) (zero_extend:DI (match_dup 1)))
5105 (set (match_dup 2) (match_dup 3))
5107 (float:X87MODEF (match_dup 2)))]
5109 [(set_attr "type" "multi")
5110 (set_attr "mode" "<MODE>")])
5112 (define_expand "floatunssi<mode>2"
5113 [(set (match_operand:X87MODEF 0 "register_operand")
5114 (unsigned_float:X87MODEF
5115 (match_operand:SI 1 "nonimmediate_operand")))]
5117 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5118 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC)
5119 || ((!TARGET_64BIT || TARGET_AVX512F)
5120 && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
5122 if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
5124 emit_insn (gen_floatunssi<mode>2_i387_with_xmm
5125 (operands[0], operands[1],
5126 assign_386_stack_local (DImode, SLOT_TEMP)));
5129 if (!TARGET_AVX512F)
5131 ix86_expand_convert_uns_si<mode>_sse (operands[0], operands[1]);
5136 (define_expand "floatunsdisf2"
5137 [(set (match_operand:SF 0 "register_operand")
5139 (match_operand:DI 1 "nonimmediate_operand")))]
5140 "TARGET_64BIT && TARGET_SSE && TARGET_SSE_MATH"
5142 if (!TARGET_AVX512F)
5144 x86_emit_floatuns (operands);
5149 (define_expand "floatunsdidf2"
5150 [(set (match_operand:DF 0 "register_operand")
5152 (match_operand:DI 1 "nonimmediate_operand")))]
5153 "((TARGET_64BIT && TARGET_AVX512F)
5154 || TARGET_KEEPS_VECTOR_ALIGNED_STACK)
5155 && TARGET_SSE2 && TARGET_SSE_MATH"
5159 ix86_expand_convert_uns_didf_sse (operands[0], operands[1]);
5162 if (!TARGET_AVX512F)
5164 x86_emit_floatuns (operands);
5169 ;; Load effective address instructions
5171 (define_insn_and_split "*lea<mode>"
5172 [(set (match_operand:SWI48 0 "register_operand" "=r")
5173 (match_operand:SWI48 1 "address_no_seg_operand" "Ts"))]
5176 if (SImode_address_operand (operands[1], VOIDmode))
5178 gcc_assert (TARGET_64BIT);
5179 return "lea{l}\t{%E1, %k0|%k0, %E1}";
5182 return "lea{<imodesuffix>}\t{%E1, %0|%0, %E1}";
5184 "reload_completed && ix86_avoid_lea_for_addr (insn, operands)"
5187 machine_mode mode = <MODE>mode;
5190 /* ix86_avoid_lea_for_addr re-recognizes insn and may
5191 change operands[] array behind our back. */
5192 pat = PATTERN (curr_insn);
5194 operands[0] = SET_DEST (pat);
5195 operands[1] = SET_SRC (pat);
5197 /* Emit all operations in SImode for zero-extended addresses. */
5198 if (SImode_address_operand (operands[1], VOIDmode))
5201 ix86_split_lea_for_addr (curr_insn, operands, mode);
5203 /* Zero-extend return register to DImode for zero-extended addresses. */
5204 if (mode != <MODE>mode)
5205 emit_insn (gen_zero_extendsidi2
5206 (operands[0], gen_lowpart (mode, operands[0])));
5210 [(set_attr "type" "lea")
5213 (match_operand 1 "SImode_address_operand")
5215 (const_string "<MODE>")))])
5219 (define_expand "add<mode>3"
5220 [(set (match_operand:SDWIM 0 "nonimmediate_operand")
5221 (plus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")
5222 (match_operand:SDWIM 2 "<general_hilo_operand>")))]
5224 "ix86_expand_binary_operator (PLUS, <MODE>mode, operands); DONE;")
5226 (define_insn_and_split "*add<dwi>3_doubleword"
5227 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro,r")
5229 (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0")
5230 (match_operand:<DWI> 2 "x86_64_hilo_general_operand" "r<di>,o")))
5231 (clobber (reg:CC FLAGS_REG))]
5232 "ix86_binary_operator_ok (PLUS, <DWI>mode, operands)"
5235 [(parallel [(set (reg:CCC FLAGS_REG)
5237 (plus:DWIH (match_dup 1) (match_dup 2))
5240 (plus:DWIH (match_dup 1) (match_dup 2)))])
5241 (parallel [(set (match_dup 3)
5244 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
5247 (clobber (reg:CC FLAGS_REG))])]
5249 split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
5250 if (operands[2] == const0_rtx)
5252 ix86_expand_binary_operator (PLUS, <MODE>mode, &operands[3]);
5257 (define_insn "*add<mode>_1"
5258 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r,r,r")
5260 (match_operand:SWI48 1 "nonimmediate_operand" "%0,0,r,r")
5261 (match_operand:SWI48 2 "x86_64_general_operand" "re,m,0,le")))
5262 (clobber (reg:CC FLAGS_REG))]
5263 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5265 switch (get_attr_type (insn))
5271 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5272 if (operands[2] == const1_rtx)
5273 return "inc{<imodesuffix>}\t%0";
5276 gcc_assert (operands[2] == constm1_rtx);
5277 return "dec{<imodesuffix>}\t%0";
5281 /* For most processors, ADD is faster than LEA. This alternative
5282 was added to use ADD as much as possible. */
5283 if (which_alternative == 2)
5284 std::swap (operands[1], operands[2]);
5286 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5287 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5288 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5290 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5294 (cond [(eq_attr "alternative" "3")
5295 (const_string "lea")
5296 (match_operand:SWI48 2 "incdec_operand")
5297 (const_string "incdec")
5299 (const_string "alu")))
5300 (set (attr "length_immediate")
5302 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5304 (const_string "*")))
5305 (set_attr "mode" "<MODE>")])
5307 ;; It may seem that nonimmediate operand is proper one for operand 1.
5308 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5309 ;; we take care in ix86_binary_operator_ok to not allow two memory
5310 ;; operands so proper swapping will be done in reload. This allow
5311 ;; patterns constructed from addsi_1 to match.
5313 (define_insn "addsi_1_zext"
5314 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
5316 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r,r")
5317 (match_operand:SI 2 "x86_64_general_operand" "rme,0,le"))))
5318 (clobber (reg:CC FLAGS_REG))]
5319 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5321 switch (get_attr_type (insn))
5327 if (operands[2] == const1_rtx)
5328 return "inc{l}\t%k0";
5331 gcc_assert (operands[2] == constm1_rtx);
5332 return "dec{l}\t%k0";
5336 /* For most processors, ADD is faster than LEA. This alternative
5337 was added to use ADD as much as possible. */
5338 if (which_alternative == 1)
5339 std::swap (operands[1], operands[2]);
5341 if (x86_maybe_negate_const_int (&operands[2], SImode))
5342 return "sub{l}\t{%2, %k0|%k0, %2}";
5344 return "add{l}\t{%2, %k0|%k0, %2}";
5348 (cond [(eq_attr "alternative" "2")
5349 (const_string "lea")
5350 (match_operand:SI 2 "incdec_operand")
5351 (const_string "incdec")
5353 (const_string "alu")))
5354 (set (attr "length_immediate")
5356 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5358 (const_string "*")))
5359 (set_attr "mode" "SI")])
5361 (define_insn "*addhi_1"
5362 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r,Yp")
5363 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r,Yp")
5364 (match_operand:HI 2 "general_operand" "rn,m,0,ln")))
5365 (clobber (reg:CC FLAGS_REG))]
5366 "ix86_binary_operator_ok (PLUS, HImode, operands)"
5368 switch (get_attr_type (insn))
5374 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5375 if (operands[2] == const1_rtx)
5376 return "inc{w}\t%0";
5379 gcc_assert (operands[2] == constm1_rtx);
5380 return "dec{w}\t%0";
5384 /* For most processors, ADD is faster than LEA. This alternative
5385 was added to use ADD as much as possible. */
5386 if (which_alternative == 2)
5387 std::swap (operands[1], operands[2]);
5389 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5390 if (x86_maybe_negate_const_int (&operands[2], HImode))
5391 return "sub{w}\t{%2, %0|%0, %2}";
5393 return "add{w}\t{%2, %0|%0, %2}";
5397 (cond [(eq_attr "alternative" "3")
5398 (const_string "lea")
5399 (match_operand:HI 2 "incdec_operand")
5400 (const_string "incdec")
5402 (const_string "alu")))
5403 (set (attr "length_immediate")
5405 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5407 (const_string "*")))
5408 (set_attr "mode" "HI,HI,HI,SI")])
5410 (define_insn "*addqi_1"
5411 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,q,r,r,Yp")
5412 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,q,0,r,Yp")
5413 (match_operand:QI 2 "general_operand" "qn,m,0,rn,0,ln")))
5414 (clobber (reg:CC FLAGS_REG))]
5415 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5417 bool widen = (get_attr_mode (insn) != MODE_QI);
5419 switch (get_attr_type (insn))
5425 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5426 if (operands[2] == const1_rtx)
5427 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
5430 gcc_assert (operands[2] == constm1_rtx);
5431 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
5435 /* For most processors, ADD is faster than LEA. These alternatives
5436 were added to use ADD as much as possible. */
5437 if (which_alternative == 2 || which_alternative == 4)
5438 std::swap (operands[1], operands[2]);
5440 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5441 if (x86_maybe_negate_const_int (&operands[2], QImode))
5444 return "sub{l}\t{%2, %k0|%k0, %2}";
5446 return "sub{b}\t{%2, %0|%0, %2}";
5449 return "add{l}\t{%k2, %k0|%k0, %k2}";
5451 return "add{b}\t{%2, %0|%0, %2}";
5455 (cond [(eq_attr "alternative" "5")
5456 (const_string "lea")
5457 (match_operand:QI 2 "incdec_operand")
5458 (const_string "incdec")
5460 (const_string "alu")))
5461 (set (attr "length_immediate")
5463 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5465 (const_string "*")))
5466 (set_attr "mode" "QI,QI,QI,SI,SI,SI")
5467 ;; Potential partial reg stall on alternatives 3 and 4.
5468 (set (attr "preferred_for_speed")
5469 (cond [(eq_attr "alternative" "3,4")
5470 (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
5471 (symbol_ref "true")))])
5473 (define_insn "*add<mode>_1_slp"
5474 [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>"))
5475 (plus:SWI12 (match_operand:SWI12 1 "nonimmediate_operand" "%0")
5476 (match_operand:SWI12 2 "general_operand" "<r>mn")))
5477 (clobber (reg:CC FLAGS_REG))]
5478 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
5479 /* FIXME: without this LRA can't reload this pattern, see PR82524. */
5480 && (rtx_equal_p (operands[0], operands[1])
5481 || rtx_equal_p (operands[0], operands[2]))"
5483 switch (get_attr_type (insn))
5486 if (operands[2] == const1_rtx)
5487 return "inc{<imodesuffix>}\t%0";
5490 gcc_assert (operands[2] == constm1_rtx);
5491 return "dec{<imodesuffix>}\t%0";
5495 if (x86_maybe_negate_const_int (&operands[2], QImode))
5496 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5498 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5502 (if_then_else (match_operand:QI 2 "incdec_operand")
5503 (const_string "incdec")
5504 (const_string "alu")))
5505 (set_attr "mode" "<MODE>")])
5507 ;; Split non destructive adds if we cannot use lea.
5509 [(set (match_operand:SWI48 0 "register_operand")
5510 (plus:SWI48 (match_operand:SWI48 1 "register_operand")
5511 (match_operand:SWI48 2 "x86_64_nonmemory_operand")))
5512 (clobber (reg:CC FLAGS_REG))]
5513 "reload_completed && ix86_avoid_lea_for_add (insn, operands)"
5514 [(set (match_dup 0) (match_dup 1))
5515 (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 2)))
5516 (clobber (reg:CC FLAGS_REG))])])
5518 ;; Split non destructive adds if we cannot use lea.
5520 [(set (match_operand:DI 0 "register_operand")
5522 (plus:SI (match_operand:SI 1 "register_operand")
5523 (match_operand:SI 2 "x86_64_nonmemory_operand"))))
5524 (clobber (reg:CC FLAGS_REG))]
5526 && reload_completed && ix86_avoid_lea_for_add (insn, operands)"
5527 [(set (match_dup 3) (match_dup 1))
5528 (parallel [(set (match_dup 0)
5529 (zero_extend:DI (plus:SI (match_dup 3) (match_dup 2))))
5530 (clobber (reg:CC FLAGS_REG))])]
5531 "operands[3] = gen_lowpart (SImode, operands[0]);")
5533 ;; Convert add to the lea pattern to avoid flags dependency.
5535 [(set (match_operand:SWI 0 "register_operand")
5536 (plus:SWI (match_operand:SWI 1 "register_operand")
5537 (match_operand:SWI 2 "<nonmemory_operand>")))
5538 (clobber (reg:CC FLAGS_REG))]
5539 "reload_completed && ix86_lea_for_add_ok (insn, operands)"
5541 (plus:<LEAMODE> (match_dup 1) (match_dup 2)))]
5543 if (<MODE>mode != <LEAMODE>mode)
5545 operands[0] = gen_lowpart (<LEAMODE>mode, operands[0]);
5546 operands[1] = gen_lowpart (<LEAMODE>mode, operands[1]);
5547 operands[2] = gen_lowpart (<LEAMODE>mode, operands[2]);
5551 ;; Convert add to the lea pattern to avoid flags dependency.
5553 [(set (match_operand:DI 0 "register_operand")
5555 (plus:SI (match_operand:SI 1 "register_operand")
5556 (match_operand:SI 2 "x86_64_nonmemory_operand"))))
5557 (clobber (reg:CC FLAGS_REG))]
5558 "TARGET_64BIT && reload_completed && ix86_lea_for_add_ok (insn, operands)"
5560 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))])
5562 (define_insn "*add<mode>_2"
5563 [(set (reg FLAGS_REG)
5566 (match_operand:SWI 1 "nonimmediate_operand" "%0,0,<r>")
5567 (match_operand:SWI 2 "<general_operand>" "<r><i>,m,0"))
5569 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>,<r>")
5570 (plus:SWI (match_dup 1) (match_dup 2)))]
5571 "ix86_match_ccmode (insn, CCGOCmode)
5572 && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5574 switch (get_attr_type (insn))
5577 if (operands[2] == const1_rtx)
5578 return "inc{<imodesuffix>}\t%0";
5581 gcc_assert (operands[2] == constm1_rtx);
5582 return "dec{<imodesuffix>}\t%0";
5586 if (which_alternative == 2)
5587 std::swap (operands[1], operands[2]);
5589 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5590 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5591 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5593 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5597 (if_then_else (match_operand:SWI 2 "incdec_operand")
5598 (const_string "incdec")
5599 (const_string "alu")))
5600 (set (attr "length_immediate")
5602 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5604 (const_string "*")))
5605 (set_attr "mode" "<MODE>")])
5607 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5608 (define_insn "*addsi_2_zext"
5609 [(set (reg FLAGS_REG)
5611 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
5612 (match_operand:SI 2 "x86_64_general_operand" "rme,0"))
5614 (set (match_operand:DI 0 "register_operand" "=r,r")
5615 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5616 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5617 && ix86_binary_operator_ok (PLUS, SImode, operands)"
5619 switch (get_attr_type (insn))
5622 if (operands[2] == const1_rtx)
5623 return "inc{l}\t%k0";
5626 gcc_assert (operands[2] == constm1_rtx);
5627 return "dec{l}\t%k0";
5631 if (which_alternative == 1)
5632 std::swap (operands[1], operands[2]);
5634 if (x86_maybe_negate_const_int (&operands[2], SImode))
5635 return "sub{l}\t{%2, %k0|%k0, %2}";
5637 return "add{l}\t{%2, %k0|%k0, %2}";
5641 (if_then_else (match_operand:SI 2 "incdec_operand")
5642 (const_string "incdec")
5643 (const_string "alu")))
5644 (set (attr "length_immediate")
5646 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5648 (const_string "*")))
5649 (set_attr "mode" "SI")])
5651 (define_insn "*add<mode>_3"
5652 [(set (reg FLAGS_REG)
5654 (neg:SWI (match_operand:SWI 2 "<general_operand>" "<g>,0"))
5655 (match_operand:SWI 1 "nonimmediate_operand" "%0,<r>")))
5656 (clobber (match_scratch:SWI 0 "=<r>,<r>"))]
5657 "ix86_match_ccmode (insn, CCZmode)
5658 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
5660 switch (get_attr_type (insn))
5663 if (operands[2] == const1_rtx)
5664 return "inc{<imodesuffix>}\t%0";
5667 gcc_assert (operands[2] == constm1_rtx);
5668 return "dec{<imodesuffix>}\t%0";
5672 if (which_alternative == 1)
5673 std::swap (operands[1], operands[2]);
5675 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5676 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5677 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5679 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5683 (if_then_else (match_operand:SWI 2 "incdec_operand")
5684 (const_string "incdec")
5685 (const_string "alu")))
5686 (set (attr "length_immediate")
5688 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5690 (const_string "*")))
5691 (set_attr "mode" "<MODE>")])
5693 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5694 (define_insn "*addsi_3_zext"
5695 [(set (reg FLAGS_REG)
5697 (neg:SI (match_operand:SI 2 "x86_64_general_operand" "rme,0"))
5698 (match_operand:SI 1 "nonimmediate_operand" "%0,r")))
5699 (set (match_operand:DI 0 "register_operand" "=r,r")
5700 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5701 "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
5702 && ix86_binary_operator_ok (PLUS, SImode, operands)"
5704 switch (get_attr_type (insn))
5707 if (operands[2] == const1_rtx)
5708 return "inc{l}\t%k0";
5711 gcc_assert (operands[2] == constm1_rtx);
5712 return "dec{l}\t%k0";
5716 if (which_alternative == 1)
5717 std::swap (operands[1], operands[2]);
5719 if (x86_maybe_negate_const_int (&operands[2], SImode))
5720 return "sub{l}\t{%2, %k0|%k0, %2}";
5722 return "add{l}\t{%2, %k0|%k0, %2}";
5726 (if_then_else (match_operand:SI 2 "incdec_operand")
5727 (const_string "incdec")
5728 (const_string "alu")))
5729 (set (attr "length_immediate")
5731 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5733 (const_string "*")))
5734 (set_attr "mode" "SI")])
5736 ; For comparisons against 1, -1 and 128, we may generate better code
5737 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
5738 ; is matched then. We can't accept general immediate, because for
5739 ; case of overflows, the result is messed up.
5740 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5741 ; only for comparisons not depending on it.
5743 (define_insn "*adddi_4"
5744 [(set (reg FLAGS_REG)
5746 (match_operand:DI 1 "nonimmediate_operand" "0")
5747 (match_operand:DI 2 "x86_64_immediate_operand" "e")))
5748 (clobber (match_scratch:DI 0 "=r"))]
5750 && ix86_match_ccmode (insn, CCGCmode)"
5752 switch (get_attr_type (insn))
5755 if (operands[2] == constm1_rtx)
5756 return "inc{q}\t%0";
5759 gcc_assert (operands[2] == const1_rtx);
5760 return "dec{q}\t%0";
5764 if (x86_maybe_negate_const_int (&operands[2], DImode))
5765 return "add{q}\t{%2, %0|%0, %2}";
5767 return "sub{q}\t{%2, %0|%0, %2}";
5771 (if_then_else (match_operand:DI 2 "incdec_operand")
5772 (const_string "incdec")
5773 (const_string "alu")))
5774 (set (attr "length_immediate")
5776 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5778 (const_string "*")))
5779 (set_attr "mode" "DI")])
5781 ; For comparisons against 1, -1 and 128, we may generate better code
5782 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
5783 ; is matched then. We can't accept general immediate, because for
5784 ; case of overflows, the result is messed up.
5785 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5786 ; only for comparisons not depending on it.
5788 (define_insn "*add<mode>_4"
5789 [(set (reg FLAGS_REG)
5791 (match_operand:SWI124 1 "nonimmediate_operand" "0")
5792 (match_operand:SWI124 2 "const_int_operand" "n")))
5793 (clobber (match_scratch:SWI124 0 "=<r>"))]
5794 "ix86_match_ccmode (insn, CCGCmode)"
5796 switch (get_attr_type (insn))
5799 if (operands[2] == constm1_rtx)
5800 return "inc{<imodesuffix>}\t%0";
5803 gcc_assert (operands[2] == const1_rtx);
5804 return "dec{<imodesuffix>}\t%0";
5808 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5809 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5811 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5815 (if_then_else (match_operand:<MODE> 2 "incdec_operand")
5816 (const_string "incdec")
5817 (const_string "alu")))
5818 (set (attr "length_immediate")
5820 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5822 (const_string "*")))
5823 (set_attr "mode" "<MODE>")])
5825 (define_insn "*add<mode>_5"
5826 [(set (reg FLAGS_REG)
5829 (match_operand:SWI 1 "nonimmediate_operand" "%0,<r>")
5830 (match_operand:SWI 2 "<general_operand>" "<g>,0"))
5832 (clobber (match_scratch:SWI 0 "=<r>,<r>"))]
5833 "ix86_match_ccmode (insn, CCGOCmode)
5834 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
5836 switch (get_attr_type (insn))
5839 if (operands[2] == const1_rtx)
5840 return "inc{<imodesuffix>}\t%0";
5843 gcc_assert (operands[2] == constm1_rtx);
5844 return "dec{<imodesuffix>}\t%0";
5848 if (which_alternative == 1)
5849 std::swap (operands[1], operands[2]);
5851 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5852 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5853 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5855 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5859 (if_then_else (match_operand:SWI 2 "incdec_operand")
5860 (const_string "incdec")
5861 (const_string "alu")))
5862 (set (attr "length_immediate")
5864 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5866 (const_string "*")))
5867 (set_attr "mode" "<MODE>")])
5869 (define_expand "addqi_ext_1"
5871 [(set (zero_extract:HI (match_operand:HI 0 "register_operand")
5877 (zero_extract:HI (match_operand:HI 1 "register_operand")
5880 (match_operand:QI 2 "const_int_operand")) 0))
5881 (clobber (reg:CC FLAGS_REG))])])
5883 (define_insn "*addqi_ext<mode>_1"
5884 [(set (zero_extract:SWI248
5885 (match_operand:SWI248 0 "register_operand" "+Q,Q")
5891 (zero_extract:SWI248
5892 (match_operand:SWI248 1 "register_operand" "0,0")
5895 (match_operand:QI 2 "general_operand" "QnBc,m")) 0))
5896 (clobber (reg:CC FLAGS_REG))]
5897 "/* FIXME: without this LRA can't reload this pattern, see PR82524. */
5898 rtx_equal_p (operands[0], operands[1])"
5900 switch (get_attr_type (insn))
5903 if (operands[2] == const1_rtx)
5904 return "inc{b}\t%h0";
5907 gcc_assert (operands[2] == constm1_rtx);
5908 return "dec{b}\t%h0";
5912 return "add{b}\t{%2, %h0|%h0, %2}";
5915 [(set_attr "isa" "*,nox64")
5917 (if_then_else (match_operand:QI 2 "incdec_operand")
5918 (const_string "incdec")
5919 (const_string "alu")))
5920 (set_attr "mode" "QI")])
5922 (define_insn "*addqi_ext<mode>_2"
5923 [(set (zero_extract:SWI248
5924 (match_operand:SWI248 0 "register_operand" "+Q")
5930 (zero_extract:SWI248
5931 (match_operand:SWI248 1 "register_operand" "%0")
5935 (zero_extract:SWI248
5936 (match_operand:SWI248 2 "register_operand" "Q")
5938 (const_int 8)) 0)) 0))
5939 (clobber (reg:CC FLAGS_REG))]
5940 "/* FIXME: without this LRA can't reload this pattern, see PR82524. */
5941 rtx_equal_p (operands[0], operands[1])
5942 || rtx_equal_p (operands[0], operands[2])"
5943 "add{b}\t{%h2, %h0|%h0, %h2}"
5944 [(set_attr "type" "alu")
5945 (set_attr "mode" "QI")])
5947 ;; Like DWI, but use POImode instead of OImode.
5948 (define_mode_attr DPWI [(QI "HI") (HI "SI") (SI "DI") (DI "TI") (TI "POI")])
5950 ;; Add with jump on overflow.
5951 (define_expand "addv<mode>4"
5952 [(parallel [(set (reg:CCO FLAGS_REG)
5956 (match_operand:SWIDWI 1 "nonimmediate_operand"))
5959 (plus:SWIDWI (match_dup 1)
5960 (match_operand:SWIDWI 2
5961 "<general_hilo_operand>")))))
5962 (set (match_operand:SWIDWI 0 "register_operand")
5963 (plus:SWIDWI (match_dup 1) (match_dup 2)))])
5964 (set (pc) (if_then_else
5965 (eq (reg:CCO FLAGS_REG) (const_int 0))
5966 (label_ref (match_operand 3))
5970 ix86_fixup_binary_operands_no_copy (PLUS, <MODE>mode, operands);
5971 if (CONST_SCALAR_INT_P (operands[2]))
5972 operands[4] = operands[2];
5974 operands[4] = gen_rtx_SIGN_EXTEND (<DPWI>mode, operands[2]);
5977 (define_insn "*addv<mode>4"
5978 [(set (reg:CCO FLAGS_REG)
5981 (match_operand:SWI 1 "nonimmediate_operand" "%0,0"))
5983 (match_operand:SWI 2 "<general_sext_operand>" "<r>We,m")))
5985 (plus:SWI (match_dup 1) (match_dup 2)))))
5986 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
5987 (plus:SWI (match_dup 1) (match_dup 2)))]
5988 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5989 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
5990 [(set_attr "type" "alu")
5991 (set_attr "mode" "<MODE>")])
5993 (define_insn "addv<mode>4_1"
5994 [(set (reg:CCO FLAGS_REG)
5997 (match_operand:SWI 1 "nonimmediate_operand" "0"))
5998 (match_operand:<DWI> 3 "const_int_operand" "i"))
6002 (match_operand:SWI 2 "x86_64_immediate_operand" "<i>")))))
6003 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
6004 (plus:SWI (match_dup 1) (match_dup 2)))]
6005 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)
6006 && CONST_INT_P (operands[2])
6007 && INTVAL (operands[2]) == INTVAL (operands[3])"
6008 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6009 [(set_attr "type" "alu")
6010 (set_attr "mode" "<MODE>")
6011 (set (attr "length_immediate")
6012 (cond [(match_test "IN_RANGE (INTVAL (operands[2]), -128, 127)")
6014 (match_test "<MODE_SIZE> == 8")
6016 (const_string "<MODE_SIZE>")))])
6018 ;; Quad word integer modes as mode attribute.
6019 (define_mode_attr QPWI [(SI "TI") (DI "POI")])
6021 (define_insn_and_split "*addv<dwi>4_doubleword"
6022 [(set (reg:CCO FLAGS_REG)
6026 (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0"))
6028 (match_operand:<DWI> 2 "nonimmediate_operand" "r,o")))
6030 (plus:<DWI> (match_dup 1) (match_dup 2)))))
6031 (set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro,r")
6032 (plus:<DWI> (match_dup 1) (match_dup 2)))]
6033 "ix86_binary_operator_ok (PLUS, <DWI>mode, operands)"
6036 [(parallel [(set (reg:CCC FLAGS_REG)
6038 (plus:DWIH (match_dup 1) (match_dup 2))
6041 (plus:DWIH (match_dup 1) (match_dup 2)))])
6042 (parallel [(set (reg:CCO FLAGS_REG)
6046 (ltu:<DWI> (reg:CC FLAGS_REG) (const_int 0))
6047 (sign_extend:<DWI> (match_dup 4)))
6048 (sign_extend:<DWI> (match_dup 5)))
6052 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
6058 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
6062 split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
6065 (define_insn_and_split "*addv<dwi>4_doubleword_1"
6066 [(set (reg:CCO FLAGS_REG)
6070 (match_operand:<DWI> 1 "nonimmediate_operand" "%0"))
6071 (match_operand:<QPWI> 3 "const_scalar_int_operand" ""))
6075 (match_operand:<DWI> 2 "x86_64_hilo_general_operand" "<di>")))))
6076 (set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro")
6077 (plus:<DWI> (match_dup 1) (match_dup 2)))]
6078 "ix86_binary_operator_ok (PLUS, <DWI>mode, operands)
6079 && CONST_SCALAR_INT_P (operands[2])
6080 && rtx_equal_p (operands[2], operands[3])"
6083 [(parallel [(set (reg:CCC FLAGS_REG)
6085 (plus:DWIH (match_dup 1) (match_dup 2))
6088 (plus:DWIH (match_dup 1) (match_dup 2)))])
6089 (parallel [(set (reg:CCO FLAGS_REG)
6093 (ltu:<DWI> (reg:CC FLAGS_REG) (const_int 0))
6094 (sign_extend:<DWI> (match_dup 4)))
6099 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
6105 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
6109 split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
6110 if (operands[2] == const0_rtx)
6112 emit_insn (gen_addv<mode>4_1 (operands[3], operands[4], operands[5],
6118 (define_insn "*addv<mode>4_overflow_1"
6119 [(set (reg:CCO FLAGS_REG)
6123 (match_operator:<DWI> 4 "ix86_carry_flag_operator"
6124 [(match_operand 3 "flags_reg_operand") (const_int 0)])
6126 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")))
6128 (match_operand:SWI 2 "<general_sext_operand>" "rWe,m")))
6132 (match_operator:SWI 5 "ix86_carry_flag_operator"
6133 [(match_dup 3) (const_int 0)])
6136 (set (match_operand:SWI 0 "nonimmediate_operand" "=rm,r")
6139 (match_op_dup 5 [(match_dup 3) (const_int 0)])
6142 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6143 "adc{<imodesuffix>}\t{%2, %0|%0, %2}"
6144 [(set_attr "type" "alu")
6145 (set_attr "mode" "<MODE>")])
6147 (define_insn "*addv<mode>4_overflow_2"
6148 [(set (reg:CCO FLAGS_REG)
6152 (match_operator:<DWI> 4 "ix86_carry_flag_operator"
6153 [(match_operand 3 "flags_reg_operand") (const_int 0)])
6155 (match_operand:SWI 1 "nonimmediate_operand" "%0")))
6156 (match_operand:<DWI> 6 "const_int_operand" ""))
6160 (match_operator:SWI 5 "ix86_carry_flag_operator"
6161 [(match_dup 3) (const_int 0)])
6163 (match_operand:SWI 2 "x86_64_immediate_operand" "e")))))
6164 (set (match_operand:SWI 0 "nonimmediate_operand" "=rm")
6167 (match_op_dup 5 [(match_dup 3) (const_int 0)])
6170 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)
6171 && CONST_INT_P (operands[2])
6172 && INTVAL (operands[2]) == INTVAL (operands[6])"
6173 "adc{<imodesuffix>}\t{%2, %0|%0, %2}"
6174 [(set_attr "type" "alu")
6175 (set_attr "mode" "<MODE>")
6176 (set (attr "length_immediate")
6177 (if_then_else (match_test "IN_RANGE (INTVAL (operands[2]), -128, 127)")
6179 (const_string "4")))])
6181 (define_expand "uaddv<mode>4"
6182 [(parallel [(set (reg:CCC FLAGS_REG)
6185 (match_operand:SWIDWI 1 "nonimmediate_operand")
6186 (match_operand:SWIDWI 2 "<general_hilo_operand>"))
6188 (set (match_operand:SWIDWI 0 "register_operand")
6189 (plus:SWIDWI (match_dup 1) (match_dup 2)))])
6190 (set (pc) (if_then_else
6191 (ltu (reg:CCC FLAGS_REG) (const_int 0))
6192 (label_ref (match_operand 3))
6195 "ix86_fixup_binary_operands_no_copy (PLUS, <MODE>mode, operands);")
6197 ;; The lea patterns for modes less than 32 bits need to be matched by
6198 ;; several insns converted to real lea by splitters.
6200 (define_insn_and_split "*lea<mode>_general_1"
6201 [(set (match_operand:SWI12 0 "register_operand" "=r")
6203 (plus:SWI12 (match_operand:SWI12 1 "index_register_operand" "l")
6204 (match_operand:SWI12 2 "register_operand" "r"))
6205 (match_operand:SWI12 3 "immediate_operand" "i")))]
6206 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
6208 "&& reload_completed"
6211 (plus:SI (match_dup 1) (match_dup 2))
6214 operands[0] = gen_lowpart (SImode, operands[0]);
6215 operands[1] = gen_lowpart (SImode, operands[1]);
6216 operands[2] = gen_lowpart (SImode, operands[2]);
6217 operands[3] = gen_lowpart (SImode, operands[3]);
6219 [(set_attr "type" "lea")
6220 (set_attr "mode" "SI")])
6222 (define_insn_and_split "*lea<mode>_general_2"
6223 [(set (match_operand:SWI12 0 "register_operand" "=r")
6225 (mult:SWI12 (match_operand:SWI12 1 "index_register_operand" "l")
6226 (match_operand 2 "const248_operand" "n"))
6227 (match_operand:SWI12 3 "nonmemory_operand" "ri")))]
6228 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
6230 "&& reload_completed"
6233 (mult:SI (match_dup 1) (match_dup 2))
6236 operands[0] = gen_lowpart (SImode, operands[0]);
6237 operands[1] = gen_lowpart (SImode, operands[1]);
6238 operands[3] = gen_lowpart (SImode, operands[3]);
6240 [(set_attr "type" "lea")
6241 (set_attr "mode" "SI")])
6243 (define_insn_and_split "*lea<mode>_general_2b"
6244 [(set (match_operand:SWI12 0 "register_operand" "=r")
6246 (ashift:SWI12 (match_operand:SWI12 1 "index_register_operand" "l")
6247 (match_operand 2 "const123_operand" "n"))
6248 (match_operand:SWI12 3 "nonmemory_operand" "ri")))]
6249 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
6251 "&& reload_completed"
6254 (ashift:SI (match_dup 1) (match_dup 2))
6257 operands[0] = gen_lowpart (SImode, operands[0]);
6258 operands[1] = gen_lowpart (SImode, operands[1]);
6259 operands[3] = gen_lowpart (SImode, operands[3]);
6261 [(set_attr "type" "lea")
6262 (set_attr "mode" "SI")])
6264 (define_insn_and_split "*lea<mode>_general_3"
6265 [(set (match_operand:SWI12 0 "register_operand" "=r")
6268 (mult:SWI12 (match_operand:SWI12 1 "index_register_operand" "l")
6269 (match_operand 2 "const248_operand" "n"))
6270 (match_operand:SWI12 3 "register_operand" "r"))
6271 (match_operand:SWI12 4 "immediate_operand" "i")))]
6272 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
6274 "&& reload_completed"
6278 (mult:SI (match_dup 1) (match_dup 2))
6282 operands[0] = gen_lowpart (SImode, operands[0]);
6283 operands[1] = gen_lowpart (SImode, operands[1]);
6284 operands[3] = gen_lowpart (SImode, operands[3]);
6285 operands[4] = gen_lowpart (SImode, operands[4]);
6287 [(set_attr "type" "lea")
6288 (set_attr "mode" "SI")])
6290 (define_insn_and_split "*lea<mode>_general_3b"
6291 [(set (match_operand:SWI12 0 "register_operand" "=r")
6294 (ashift:SWI12 (match_operand:SWI12 1 "index_register_operand" "l")
6295 (match_operand 2 "const123_operand" "n"))
6296 (match_operand:SWI12 3 "register_operand" "r"))
6297 (match_operand:SWI12 4 "immediate_operand" "i")))]
6298 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
6300 "&& reload_completed"
6304 (ashift:SI (match_dup 1) (match_dup 2))
6308 operands[0] = gen_lowpart (SImode, operands[0]);
6309 operands[1] = gen_lowpart (SImode, operands[1]);
6310 operands[3] = gen_lowpart (SImode, operands[3]);
6311 operands[4] = gen_lowpart (SImode, operands[4]);
6313 [(set_attr "type" "lea")
6314 (set_attr "mode" "SI")])
6316 (define_insn_and_split "*lea<mode>_general_4"
6317 [(set (match_operand:SWI12 0 "register_operand" "=r")
6320 (match_operand:SWI12 1 "index_register_operand" "l")
6321 (match_operand 2 "const_0_to_3_operand" "n"))
6322 (match_operand 3 "const_int_operand" "n")))]
6323 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6324 && ((unsigned HOST_WIDE_INT) INTVAL (operands[3])
6325 < (HOST_WIDE_INT_1U << INTVAL (operands[2])))"
6327 "&& reload_completed"
6330 (mult:SI (match_dup 1) (match_dup 2))
6333 operands[0] = gen_lowpart (SImode, operands[0]);
6334 operands[1] = gen_lowpart (SImode, operands[1]);
6335 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
6337 [(set_attr "type" "lea")
6338 (set_attr "mode" "SI")])
6340 (define_insn_and_split "*lea<mode>_general_4"
6341 [(set (match_operand:SWI48 0 "register_operand" "=r")
6344 (match_operand:SWI48 1 "index_register_operand" "l")
6345 (match_operand 2 "const_0_to_3_operand" "n"))
6346 (match_operand 3 "const_int_operand" "n")))]
6347 "(unsigned HOST_WIDE_INT) INTVAL (operands[3])
6348 < (HOST_WIDE_INT_1U << INTVAL (operands[2]))"
6350 "&& reload_completed"
6353 (mult:SWI48 (match_dup 1) (match_dup 2))
6355 "operands[2] = GEN_INT (1 << INTVAL (operands[2]));"
6356 [(set_attr "type" "lea")
6357 (set_attr "mode" "<MODE>")])
6359 ;; Subtract instructions
6361 (define_expand "sub<mode>3"
6362 [(set (match_operand:SDWIM 0 "nonimmediate_operand")
6363 (minus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")
6364 (match_operand:SDWIM 2 "<general_hilo_operand>")))]
6366 "ix86_expand_binary_operator (MINUS, <MODE>mode, operands); DONE;")
6368 (define_insn_and_split "*sub<dwi>3_doubleword"
6369 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro,r")
6371 (match_operand:<DWI> 1 "nonimmediate_operand" "0,0")
6372 (match_operand:<DWI> 2 "x86_64_hilo_general_operand" "r<di>,o")))
6373 (clobber (reg:CC FLAGS_REG))]
6374 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6377 [(parallel [(set (reg:CC FLAGS_REG)
6378 (compare:CC (match_dup 1) (match_dup 2)))
6380 (minus:DWIH (match_dup 1) (match_dup 2)))])
6381 (parallel [(set (match_dup 3)
6385 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0)))
6387 (clobber (reg:CC FLAGS_REG))])]
6389 split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
6390 if (operands[2] == const0_rtx)
6392 ix86_expand_binary_operator (MINUS, <MODE>mode, &operands[3]);
6397 (define_insn "*sub<mode>_1"
6398 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6400 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6401 (match_operand:SWI 2 "<general_operand>" "<r><i>,m")))
6402 (clobber (reg:CC FLAGS_REG))]
6403 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6404 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6405 [(set_attr "type" "alu")
6406 (set_attr "mode" "<MODE>")])
6408 (define_insn "*subsi_1_zext"
6409 [(set (match_operand:DI 0 "register_operand" "=r")
6411 (minus:SI (match_operand:SI 1 "register_operand" "0")
6412 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
6413 (clobber (reg:CC FLAGS_REG))]
6414 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6415 "sub{l}\t{%2, %k0|%k0, %2}"
6416 [(set_attr "type" "alu")
6417 (set_attr "mode" "SI")])
6419 (define_insn "*sub<mode>_1_slp"
6420 [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>"))
6421 (minus:SWI12 (match_operand:SWI12 1 "register_operand" "0")
6422 (match_operand:SWI12 2 "general_operand" "<r>mn")))
6423 (clobber (reg:CC FLAGS_REG))]
6424 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6425 /* FIXME: without this LRA can't reload this pattern, see PR82524. */
6426 && rtx_equal_p (operands[0], operands[1])"
6427 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6428 [(set_attr "type" "alu")
6429 (set_attr "mode" "<MODE>")])
6431 (define_insn "*sub<mode>_2"
6432 [(set (reg FLAGS_REG)
6435 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6436 (match_operand:SWI 2 "<general_operand>" "<r><i>,m"))
6438 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6439 (minus:SWI (match_dup 1) (match_dup 2)))]
6440 "ix86_match_ccmode (insn, CCGOCmode)
6441 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6442 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6443 [(set_attr "type" "alu")
6444 (set_attr "mode" "<MODE>")])
6446 (define_insn "*subsi_2_zext"
6447 [(set (reg FLAGS_REG)
6449 (minus:SI (match_operand:SI 1 "register_operand" "0")
6450 (match_operand:SI 2 "x86_64_general_operand" "rme"))
6452 (set (match_operand:DI 0 "register_operand" "=r")
6454 (minus:SI (match_dup 1)
6456 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6457 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6458 "sub{l}\t{%2, %k0|%k0, %2}"
6459 [(set_attr "type" "alu")
6460 (set_attr "mode" "SI")])
6462 ;; Subtract with jump on overflow.
6463 (define_expand "subv<mode>4"
6464 [(parallel [(set (reg:CCO FLAGS_REG)
6468 (match_operand:SWIDWI 1 "nonimmediate_operand"))
6471 (minus:SWIDWI (match_dup 1)
6472 (match_operand:SWIDWI 2
6473 "<general_hilo_operand>")))))
6474 (set (match_operand:SWIDWI 0 "register_operand")
6475 (minus:SWIDWI (match_dup 1) (match_dup 2)))])
6476 (set (pc) (if_then_else
6477 (eq (reg:CCO FLAGS_REG) (const_int 0))
6478 (label_ref (match_operand 3))
6482 ix86_fixup_binary_operands_no_copy (MINUS, <MODE>mode, operands);
6483 if (CONST_SCALAR_INT_P (operands[2]))
6484 operands[4] = operands[2];
6486 operands[4] = gen_rtx_SIGN_EXTEND (<DPWI>mode, operands[2]);
6489 (define_insn "*subv<mode>4"
6490 [(set (reg:CCO FLAGS_REG)
6491 (eq:CCO (minus:<DWI>
6493 (match_operand:SWI 1 "nonimmediate_operand" "0,0"))
6495 (match_operand:SWI 2 "<general_sext_operand>" "<r>We,m")))
6497 (minus:SWI (match_dup 1) (match_dup 2)))))
6498 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6499 (minus:SWI (match_dup 1) (match_dup 2)))]
6500 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6501 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6502 [(set_attr "type" "alu")
6503 (set_attr "mode" "<MODE>")])
6505 (define_insn "subv<mode>4_1"
6506 [(set (reg:CCO FLAGS_REG)
6507 (eq:CCO (minus:<DWI>
6509 (match_operand:SWI 1 "nonimmediate_operand" "0"))
6510 (match_operand:<DWI> 3 "const_int_operand" "i"))
6514 (match_operand:SWI 2 "x86_64_immediate_operand" "<i>")))))
6515 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
6516 (minus:SWI (match_dup 1) (match_dup 2)))]
6517 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)
6518 && CONST_INT_P (operands[2])
6519 && INTVAL (operands[2]) == INTVAL (operands[3])"
6520 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6521 [(set_attr "type" "alu")
6522 (set_attr "mode" "<MODE>")
6523 (set (attr "length_immediate")
6524 (cond [(match_test "IN_RANGE (INTVAL (operands[2]), -128, 127)")
6526 (match_test "<MODE_SIZE> == 8")
6528 (const_string "<MODE_SIZE>")))])
6530 (define_insn_and_split "*subv<dwi>4_doubleword"
6531 [(set (reg:CCO FLAGS_REG)
6535 (match_operand:<DWI> 1 "nonimmediate_operand" "0,0"))
6537 (match_operand:<DWI> 2 "nonimmediate_operand" "r,o")))
6539 (minus:<DWI> (match_dup 1) (match_dup 2)))))
6540 (set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro,r")
6541 (minus:<DWI> (match_dup 1) (match_dup 2)))]
6542 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6545 [(parallel [(set (reg:CC FLAGS_REG)
6546 (compare:CC (match_dup 1) (match_dup 2)))
6548 (minus:DWIH (match_dup 1) (match_dup 2)))])
6549 (parallel [(set (reg:CCO FLAGS_REG)
6553 (sign_extend:<DWI> (match_dup 4))
6554 (ltu:<DWI> (reg:CC FLAGS_REG) (const_int 0)))
6555 (sign_extend:<DWI> (match_dup 5)))
6560 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0)))
6566 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0)))
6569 split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
6572 (define_insn_and_split "*subv<dwi>4_doubleword_1"
6573 [(set (reg:CCO FLAGS_REG)
6577 (match_operand:<DWI> 1 "nonimmediate_operand" "0"))
6578 (match_operand:<QPWI> 3 "const_scalar_int_operand" ""))
6582 (match_operand:<DWI> 2 "x86_64_hilo_general_operand" "<di>")))))
6583 (set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro")
6584 (minus:<DWI> (match_dup 1) (match_dup 2)))]
6585 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)
6586 && CONST_SCALAR_INT_P (operands[2])
6587 && rtx_equal_p (operands[2], operands[3])"
6590 [(parallel [(set (reg:CC FLAGS_REG)
6591 (compare:CC (match_dup 1) (match_dup 2)))
6593 (minus:DWIH (match_dup 1) (match_dup 2)))])
6594 (parallel [(set (reg:CCO FLAGS_REG)
6598 (sign_extend:<DWI> (match_dup 4))
6599 (ltu:<DWI> (reg:CC FLAGS_REG) (const_int 0)))
6605 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0)))
6611 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0)))
6614 split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
6615 if (operands[2] == const0_rtx)
6617 emit_insn (gen_subv<mode>4_1 (operands[3], operands[4], operands[5],
6623 (define_insn "*subv<mode>4_overflow_1"
6624 [(set (reg:CCO FLAGS_REG)
6629 (match_operand:SWI 1 "nonimmediate_operand" "%0,0"))
6630 (match_operator:<DWI> 4 "ix86_carry_flag_operator"
6631 [(match_operand 3 "flags_reg_operand") (const_int 0)]))
6633 (match_operand:SWI 2 "<general_sext_operand>" "rWe,m")))
6638 (match_operator:SWI 5 "ix86_carry_flag_operator"
6639 [(match_dup 3) (const_int 0)]))
6641 (set (match_operand:SWI 0 "nonimmediate_operand" "=rm,r")
6645 (match_op_dup 5 [(match_dup 3) (const_int 0)]))
6647 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6648 "sbb{<imodesuffix>}\t{%2, %0|%0, %2}"
6649 [(set_attr "type" "alu")
6650 (set_attr "mode" "<MODE>")])
6652 (define_insn "*subv<mode>4_overflow_2"
6653 [(set (reg:CCO FLAGS_REG)
6658 (match_operand:SWI 1 "nonimmediate_operand" "%0"))
6659 (match_operator:<DWI> 4 "ix86_carry_flag_operator"
6660 [(match_operand 3 "flags_reg_operand") (const_int 0)]))
6661 (match_operand:<DWI> 6 "const_int_operand" ""))
6666 (match_operator:SWI 5 "ix86_carry_flag_operator"
6667 [(match_dup 3) (const_int 0)]))
6668 (match_operand:SWI 2 "x86_64_immediate_operand" "e")))))
6669 (set (match_operand:SWI 0 "nonimmediate_operand" "=rm")
6673 (match_op_dup 5 [(match_dup 3) (const_int 0)]))
6675 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)
6676 && CONST_INT_P (operands[2])
6677 && INTVAL (operands[2]) == INTVAL (operands[6])"
6678 "sbb{<imodesuffix>}\t{%2, %0|%0, %2}"
6679 [(set_attr "type" "alu")
6680 (set_attr "mode" "<MODE>")
6681 (set (attr "length_immediate")
6682 (if_then_else (match_test "IN_RANGE (INTVAL (operands[2]), -128, 127)")
6684 (const_string "4")))])
6686 (define_expand "usubv<mode>4"
6687 [(parallel [(set (reg:CC FLAGS_REG)
6689 (match_operand:SWI 1 "nonimmediate_operand")
6690 (match_operand:SWI 2 "<general_operand>")))
6691 (set (match_operand:SWI 0 "register_operand")
6692 (minus:SWI (match_dup 1) (match_dup 2)))])
6693 (set (pc) (if_then_else
6694 (ltu (reg:CC FLAGS_REG) (const_int 0))
6695 (label_ref (match_operand 3))
6698 "ix86_fixup_binary_operands_no_copy (MINUS, <MODE>mode, operands);")
6700 (define_insn "*sub<mode>_3"
6701 [(set (reg FLAGS_REG)
6702 (compare (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6703 (match_operand:SWI 2 "<general_operand>" "<r><i>,m")))
6704 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6705 (minus:SWI (match_dup 1) (match_dup 2)))]
6706 "ix86_match_ccmode (insn, CCmode)
6707 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6708 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6709 [(set_attr "type" "alu")
6710 (set_attr "mode" "<MODE>")])
6714 [(set (reg:CC FLAGS_REG)
6715 (compare:CC (match_operand:SWI 0 "general_reg_operand")
6716 (match_operand:SWI 1 "general_gr_operand")))
6718 (minus:SWI (match_dup 0) (match_dup 1)))])]
6719 "find_regno_note (peep2_next_insn (0), REG_UNUSED, REGNO (operands[0])) != 0"
6720 [(set (reg:CC FLAGS_REG)
6721 (compare:CC (match_dup 0) (match_dup 1)))])
6723 ;; decl %eax; cmpl $-1, %eax; jne .Lxx; can be optimized into
6724 ;; subl $1, %eax; jnc .Lxx;
6727 [(set (match_operand:SWI 0 "general_reg_operand")
6728 (plus:SWI (match_dup 0) (const_int -1)))
6729 (clobber (reg FLAGS_REG))])
6730 (set (reg:CCZ FLAGS_REG)
6731 (compare:CCZ (match_dup 0) (const_int -1)))
6733 (if_then_else (match_operator 1 "bt_comparison_operator"
6734 [(reg:CCZ FLAGS_REG) (const_int 0)])
6737 "peep2_regno_dead_p (3, FLAGS_REG)"
6739 [(set (reg:CC FLAGS_REG)
6740 (compare:CC (match_dup 0) (const_int 1)))
6742 (minus:SWI (match_dup 0) (const_int 1)))])
6744 (if_then_else (match_dup 3)
6748 rtx cc = gen_rtx_REG (CCmode, FLAGS_REG);
6749 operands[3] = gen_rtx_fmt_ee (GET_CODE (operands[1]) == NE
6750 ? GEU : LTU, VOIDmode, cc, const0_rtx);
6753 (define_insn "*subsi_3_zext"
6754 [(set (reg FLAGS_REG)
6755 (compare (match_operand:SI 1 "register_operand" "0")
6756 (match_operand:SI 2 "x86_64_general_operand" "rme")))
6757 (set (match_operand:DI 0 "register_operand" "=r")
6759 (minus:SI (match_dup 1)
6761 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6762 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6763 "sub{l}\t{%2, %1|%1, %2}"
6764 [(set_attr "type" "alu")
6765 (set_attr "mode" "SI")])
6767 ;; Add with carry and subtract with borrow
6769 (define_insn "@add<mode>3_carry"
6770 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6773 (match_operator:SWI 4 "ix86_carry_flag_operator"
6774 [(match_operand 3 "flags_reg_operand") (const_int 0)])
6775 (match_operand:SWI 1 "nonimmediate_operand" "%0,0"))
6776 (match_operand:SWI 2 "<general_operand>" "<r><i>,m")))
6777 (clobber (reg:CC FLAGS_REG))]
6778 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6779 "adc{<imodesuffix>}\t{%2, %0|%0, %2}"
6780 [(set_attr "type" "alu")
6781 (set_attr "use_carry" "1")
6782 (set_attr "pent_pair" "pu")
6783 (set_attr "mode" "<MODE>")])
6785 (define_insn "*add<mode>3_carry_0"
6786 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
6788 (match_operator:SWI 3 "ix86_carry_flag_operator"
6789 [(match_operand 2 "flags_reg_operand") (const_int 0)])
6790 (match_operand:SWI 1 "nonimmediate_operand" "0")))
6791 (clobber (reg:CC FLAGS_REG))]
6792 "ix86_unary_operator_ok (PLUS, <MODE>mode, operands)"
6793 "adc{<imodesuffix>}\t{$0, %0|%0, 0}"
6794 [(set_attr "type" "alu")
6795 (set_attr "use_carry" "1")
6796 (set_attr "pent_pair" "pu")
6797 (set_attr "mode" "<MODE>")])
6799 (define_insn "*addsi3_carry_zext"
6800 [(set (match_operand:DI 0 "register_operand" "=r")
6803 (plus:SI (match_operator:SI 3 "ix86_carry_flag_operator"
6804 [(reg FLAGS_REG) (const_int 0)])
6805 (match_operand:SI 1 "register_operand" "%0"))
6806 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
6807 (clobber (reg:CC FLAGS_REG))]
6808 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6809 "adc{l}\t{%2, %k0|%k0, %2}"
6810 [(set_attr "type" "alu")
6811 (set_attr "use_carry" "1")
6812 (set_attr "pent_pair" "pu")
6813 (set_attr "mode" "SI")])
6815 (define_insn "*addsi3_carry_zext_0"
6816 [(set (match_operand:DI 0 "register_operand" "=r")
6818 (plus:SI (match_operator:SI 2 "ix86_carry_flag_operator"
6819 [(reg FLAGS_REG) (const_int 0)])
6820 (match_operand:SI 1 "register_operand" "0"))))
6821 (clobber (reg:CC FLAGS_REG))]
6823 "adc{l}\t{$0, %k0|%k0, 0}"
6824 [(set_attr "type" "alu")
6825 (set_attr "use_carry" "1")
6826 (set_attr "pent_pair" "pu")
6827 (set_attr "mode" "SI")])
6829 ;; There is no point to generate ADCX instruction. ADC is shorter and faster.
6831 (define_insn "addcarry<mode>"
6832 [(set (reg:CCC FLAGS_REG)
6837 (match_operator:SWI48 5 "ix86_carry_flag_operator"
6838 [(match_operand 3 "flags_reg_operand") (const_int 0)])
6839 (match_operand:SWI48 1 "nonimmediate_operand" "%0,0"))
6840 (match_operand:SWI48 2 "nonimmediate_operand" "r,rm")))
6842 (zero_extend:<DWI> (match_dup 2))
6843 (match_operator:<DWI> 4 "ix86_carry_flag_operator"
6844 [(match_dup 3) (const_int 0)]))))
6845 (set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
6846 (plus:SWI48 (plus:SWI48 (match_op_dup 5
6847 [(match_dup 3) (const_int 0)])
6850 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6851 "adc{<imodesuffix>}\t{%2, %0|%0, %2}"
6852 [(set_attr "type" "alu")
6853 (set_attr "use_carry" "1")
6854 (set_attr "pent_pair" "pu")
6855 (set_attr "mode" "<MODE>")])
6857 (define_expand "addcarry<mode>_0"
6859 [(set (reg:CCC FLAGS_REG)
6862 (match_operand:SWI48 1 "nonimmediate_operand")
6863 (match_operand:SWI48 2 "x86_64_general_operand"))
6865 (set (match_operand:SWI48 0 "nonimmediate_operand")
6866 (plus:SWI48 (match_dup 1) (match_dup 2)))])]
6867 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)")
6869 (define_insn "*addcarry<mode>_1"
6870 [(set (reg:CCC FLAGS_REG)
6875 (match_operator:SWI48 5 "ix86_carry_flag_operator"
6876 [(match_operand 3 "flags_reg_operand") (const_int 0)])
6877 (match_operand:SWI48 1 "nonimmediate_operand" "%0"))
6878 (match_operand:SWI48 2 "x86_64_immediate_operand" "e")))
6880 (match_operand:<DWI> 6 "const_scalar_int_operand" "")
6881 (match_operator:<DWI> 4 "ix86_carry_flag_operator"
6882 [(match_dup 3) (const_int 0)]))))
6883 (set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
6884 (plus:SWI48 (plus:SWI48 (match_op_dup 5
6885 [(match_dup 3) (const_int 0)])
6888 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)
6889 && CONST_INT_P (operands[2])
6890 /* Check that operands[6] is operands[2] zero extended from
6891 <MODE>mode to <DWI>mode. */
6892 && ((<MODE>mode == SImode || INTVAL (operands[2]) >= 0)
6893 ? (CONST_INT_P (operands[6])
6894 && UINTVAL (operands[6]) == (UINTVAL (operands[2])
6895 & GET_MODE_MASK (<MODE>mode)))
6896 : (CONST_WIDE_INT_P (operands[6])
6897 && CONST_WIDE_INT_NUNITS (operands[6]) == 2
6898 && ((unsigned HOST_WIDE_INT) CONST_WIDE_INT_ELT (operands[6], 0)
6899 == UINTVAL (operands[2]))
6900 && CONST_WIDE_INT_ELT (operands[6], 1) == 0))"
6901 "adc{<imodesuffix>}\t{%2, %0|%0, %2}"
6902 [(set_attr "type" "alu")
6903 (set_attr "use_carry" "1")
6904 (set_attr "pent_pair" "pu")
6905 (set_attr "mode" "<MODE>")
6906 (set (attr "length_immediate")
6907 (if_then_else (match_test "IN_RANGE (INTVAL (operands[2]), -128, 127)")
6909 (const_string "4")))])
6911 (define_insn "@sub<mode>3_carry"
6912 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6915 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6916 (match_operator:SWI 4 "ix86_carry_flag_operator"
6917 [(match_operand 3 "flags_reg_operand") (const_int 0)]))
6918 (match_operand:SWI 2 "<general_operand>" "<r><i>,m")))
6919 (clobber (reg:CC FLAGS_REG))]
6920 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6921 "sbb{<imodesuffix>}\t{%2, %0|%0, %2}"
6922 [(set_attr "type" "alu")
6923 (set_attr "use_carry" "1")
6924 (set_attr "pent_pair" "pu")
6925 (set_attr "mode" "<MODE>")])
6927 (define_insn "*sub<mode>3_carry_0"
6928 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
6930 (match_operand:SWI 1 "nonimmediate_operand" "0")
6931 (match_operator:SWI 3 "ix86_carry_flag_operator"
6932 [(match_operand 2 "flags_reg_operand") (const_int 0)])))
6933 (clobber (reg:CC FLAGS_REG))]
6934 "ix86_unary_operator_ok (MINUS, <MODE>mode, operands)"
6935 "sbb{<imodesuffix>}\t{$0, %0|%0, 0}"
6936 [(set_attr "type" "alu")
6937 (set_attr "use_carry" "1")
6938 (set_attr "pent_pair" "pu")
6939 (set_attr "mode" "<MODE>")])
6941 (define_insn "*subsi3_carry_zext"
6942 [(set (match_operand:DI 0 "register_operand" "=r")
6946 (match_operand:SI 1 "register_operand" "0")
6947 (match_operator:SI 3 "ix86_carry_flag_operator"
6948 [(reg FLAGS_REG) (const_int 0)]))
6949 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
6950 (clobber (reg:CC FLAGS_REG))]
6951 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6952 "sbb{l}\t{%2, %k0|%k0, %2}"
6953 [(set_attr "type" "alu")
6954 (set_attr "use_carry" "1")
6955 (set_attr "pent_pair" "pu")
6956 (set_attr "mode" "SI")])
6958 (define_insn "*subsi3_carry_zext_0"
6959 [(set (match_operand:DI 0 "register_operand" "=r")
6962 (match_operand:SI 1 "register_operand" "0")
6963 (match_operator:SI 2 "ix86_carry_flag_operator"
6964 [(reg FLAGS_REG) (const_int 0)]))))
6965 (clobber (reg:CC FLAGS_REG))]
6967 "sbb{l}\t{$0, %k0|%k0, 0}"
6968 [(set_attr "type" "alu")
6969 (set_attr "use_carry" "1")
6970 (set_attr "pent_pair" "pu")
6971 (set_attr "mode" "SI")])
6973 (define_insn "@sub<mode>3_carry_ccc"
6974 [(set (reg:CCC FLAGS_REG)
6976 (zero_extend:<DWI> (match_operand:DWIH 1 "register_operand" "0"))
6978 (ltu:<DWI> (reg:CC FLAGS_REG) (const_int 0))
6980 (match_operand:DWIH 2 "x86_64_sext_operand" "rmWe")))))
6981 (clobber (match_scratch:DWIH 0 "=r"))]
6983 "sbb{<imodesuffix>}\t{%2, %0|%0, %2}"
6984 [(set_attr "type" "alu")
6985 (set_attr "mode" "<MODE>")])
6987 (define_insn "*sub<mode>3_carry_ccc_1"
6988 [(set (reg:CCC FLAGS_REG)
6990 (zero_extend:<DWI> (match_operand:DWIH 1 "register_operand" "0"))
6992 (ltu:<DWI> (reg:CC FLAGS_REG) (const_int 0))
6993 (match_operand:<DWI> 2 "x86_64_dwzext_immediate_operand" "Wf"))))
6994 (clobber (match_scratch:DWIH 0 "=r"))]
6997 operands[3] = simplify_subreg (<MODE>mode, operands[2], <DWI>mode, 0);
6998 return "sbb{<imodesuffix>}\t{%3, %0|%0, %3}";
7000 [(set_attr "type" "alu")
7001 (set_attr "mode" "<MODE>")])
7003 ;; The sign flag is set from the
7004 ;; (compare (match_dup 1) (plus:DWIH (ltu:DWIH ...) (match_dup 2)))
7005 ;; result, the overflow flag likewise, but the overflow flag is also
7006 ;; set if the (plus:DWIH (ltu:DWIH ...) (match_dup 2)) overflows.
7007 (define_insn "@sub<mode>3_carry_ccgz"
7008 [(set (reg:CCGZ FLAGS_REG)
7009 (unspec:CCGZ [(match_operand:DWIH 1 "register_operand" "0")
7010 (match_operand:DWIH 2 "x86_64_general_operand" "rme")
7011 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))]
7013 (clobber (match_scratch:DWIH 0 "=r"))]
7015 "sbb{<imodesuffix>}\t{%2, %0|%0, %2}"
7016 [(set_attr "type" "alu")
7017 (set_attr "mode" "<MODE>")])
7019 (define_insn "subborrow<mode>"
7020 [(set (reg:CCC FLAGS_REG)
7023 (match_operand:SWI48 1 "nonimmediate_operand" "0"))
7025 (match_operator:<DWI> 4 "ix86_carry_flag_operator"
7026 [(match_operand 3 "flags_reg_operand") (const_int 0)])
7028 (match_operand:SWI48 2 "nonimmediate_operand" "rm")))))
7029 (set (match_operand:SWI48 0 "register_operand" "=r")
7030 (minus:SWI48 (minus:SWI48
7032 (match_operator:SWI48 5 "ix86_carry_flag_operator"
7033 [(match_dup 3) (const_int 0)]))
7035 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
7036 "sbb{<imodesuffix>}\t{%2, %0|%0, %2}"
7037 [(set_attr "type" "alu")
7038 (set_attr "use_carry" "1")
7039 (set_attr "pent_pair" "pu")
7040 (set_attr "mode" "<MODE>")])
7042 (define_expand "subborrow<mode>_0"
7044 [(set (reg:CC FLAGS_REG)
7046 (match_operand:SWI48 1 "nonimmediate_operand")
7047 (match_operand:SWI48 2 "<general_operand>")))
7048 (set (match_operand:SWI48 0 "register_operand")
7049 (minus:SWI48 (match_dup 1) (match_dup 2)))])]
7050 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)")
7052 (define_mode_iterator CC_CCC [CC CCC])
7054 ;; Pre-reload splitter to optimize
7055 ;; *setcc_qi followed by *addqi3_cconly_overflow_1 with the same QI
7056 ;; operand and no intervening flags modifications into nothing.
7057 (define_insn_and_split "*setcc_qi_addqi3_cconly_overflow_1_<mode>"
7058 [(set (reg:CCC FLAGS_REG)
7059 (compare:CCC (neg:QI (geu:QI (reg:CC_CCC FLAGS_REG) (const_int 0)))
7060 (ltu:QI (reg:CC_CCC FLAGS_REG) (const_int 0))))]
7061 "ix86_pre_reload_split ()"
7066 ;; Overflow setting add instructions
7068 (define_expand "addqi3_cconly_overflow"
7070 [(set (reg:CCC FLAGS_REG)
7073 (match_operand:QI 0 "nonimmediate_operand")
7074 (match_operand:QI 1 "general_operand"))
7076 (clobber (scratch:QI))])]
7077 "!(MEM_P (operands[0]) && MEM_P (operands[1]))")
7079 (define_insn "*add<mode>3_cconly_overflow_1"
7080 [(set (reg:CCC FLAGS_REG)
7083 (match_operand:SWI 1 "nonimmediate_operand" "%0")
7084 (match_operand:SWI 2 "<general_operand>" "<g>"))
7086 (clobber (match_scratch:SWI 0 "=<r>"))]
7087 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7088 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
7089 [(set_attr "type" "alu")
7090 (set_attr "mode" "<MODE>")])
7092 (define_insn "*add<mode>3_cc_overflow_1"
7093 [(set (reg:CCC FLAGS_REG)
7096 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
7097 (match_operand:SWI 2 "<general_operand>" "<r><i>,m"))
7099 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
7100 (plus:SWI (match_dup 1) (match_dup 2)))]
7101 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
7102 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
7103 [(set_attr "type" "alu")
7104 (set_attr "mode" "<MODE>")])
7107 [(parallel [(set (reg:CCC FLAGS_REG)
7109 (plus:SWI (match_operand:SWI 0 "general_reg_operand")
7110 (match_operand:SWI 1 "memory_operand"))
7112 (set (match_dup 0) (plus:SWI (match_dup 0) (match_dup 1)))])
7113 (set (match_dup 1) (match_dup 0))]
7114 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
7115 && peep2_reg_dead_p (2, operands[0])
7116 && !reg_overlap_mentioned_p (operands[0], operands[1])"
7117 [(parallel [(set (reg:CCC FLAGS_REG)
7119 (plus:SWI (match_dup 1) (match_dup 0))
7121 (set (match_dup 1) (plus:SWI (match_dup 1) (match_dup 0)))])])
7123 (define_insn "*addsi3_zext_cc_overflow_1"
7124 [(set (reg:CCC FLAGS_REG)
7127 (match_operand:SI 1 "nonimmediate_operand" "%0")
7128 (match_operand:SI 2 "x86_64_general_operand" "rme"))
7130 (set (match_operand:DI 0 "register_operand" "=r")
7131 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
7132 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
7133 "add{l}\t{%2, %k0|%k0, %2}"
7134 [(set_attr "type" "alu")
7135 (set_attr "mode" "SI")])
7137 (define_insn "*add<mode>3_cconly_overflow_2"
7138 [(set (reg:CCC FLAGS_REG)
7141 (match_operand:SWI 1 "nonimmediate_operand" "%0")
7142 (match_operand:SWI 2 "<general_operand>" "<g>"))
7144 (clobber (match_scratch:SWI 0 "=<r>"))]
7145 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7146 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
7147 [(set_attr "type" "alu")
7148 (set_attr "mode" "<MODE>")])
7150 (define_insn "*add<mode>3_cc_overflow_2"
7151 [(set (reg:CCC FLAGS_REG)
7154 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
7155 (match_operand:SWI 2 "<general_operand>" "<r><i>,m"))
7157 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
7158 (plus:SWI (match_dup 1) (match_dup 2)))]
7159 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
7160 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
7161 [(set_attr "type" "alu")
7162 (set_attr "mode" "<MODE>")])
7164 (define_insn "*addsi3_zext_cc_overflow_2"
7165 [(set (reg:CCC FLAGS_REG)
7168 (match_operand:SI 1 "nonimmediate_operand" "%0")
7169 (match_operand:SI 2 "x86_64_general_operand" "rme"))
7171 (set (match_operand:DI 0 "register_operand" "=r")
7172 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
7173 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
7174 "add{l}\t{%2, %k0|%k0, %2}"
7175 [(set_attr "type" "alu")
7176 (set_attr "mode" "SI")])
7178 (define_insn_and_split "*add<dwi>3_doubleword_cc_overflow_1"
7179 [(set (reg:CCC FLAGS_REG)
7182 (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0")
7183 (match_operand:<DWI> 2 "x86_64_hilo_general_operand" "r<di>,o"))
7185 (set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro,r")
7186 (plus:<DWI> (match_dup 1) (match_dup 2)))]
7187 "ix86_binary_operator_ok (PLUS, <DWI>mode, operands)"
7190 [(parallel [(set (reg:CCC FLAGS_REG)
7192 (plus:DWIH (match_dup 1) (match_dup 2))
7195 (plus:DWIH (match_dup 1) (match_dup 2)))])
7196 (parallel [(set (reg:CCC FLAGS_REG)
7201 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
7206 (ltu:<DWI> (reg:CC FLAGS_REG) (const_int 0)))))
7209 (plus:DWIH (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
7213 split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
7214 if (operands[2] == const0_rtx)
7216 emit_insn (gen_addcarry<mode>_0 (operands[3], operands[4], operands[5]));
7219 if (CONST_INT_P (operands[5]))
7220 operands[6] = simplify_unary_operation (ZERO_EXTEND, <DWI>mode,
7221 operands[5], <MODE>mode);
7223 operands[6] = gen_rtx_ZERO_EXTEND (<DWI>mode, operands[5]);
7226 ;; x == 0 with zero flag test can be done also as x < 1U with carry flag
7227 ;; test, where the latter is preferrable if we have some carry consuming
7229 ;; For x != 0, we need to use x < 1U with negation of carry, i.e.
7231 (define_insn_and_split "*add<mode>3_eq"
7232 [(set (match_operand:SWI 0 "nonimmediate_operand")
7235 (eq:SWI (match_operand 3 "int_nonimmediate_operand") (const_int 0))
7236 (match_operand:SWI 1 "nonimmediate_operand"))
7237 (match_operand:SWI 2 "<general_operand>")))
7238 (clobber (reg:CC FLAGS_REG))]
7239 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)
7240 && ix86_pre_reload_split ()"
7243 [(set (reg:CC FLAGS_REG)
7244 (compare:CC (match_dup 3) (const_int 1)))
7245 (parallel [(set (match_dup 0)
7247 (plus:SWI (ltu:SWI (reg:CC FLAGS_REG) (const_int 0))
7250 (clobber (reg:CC FLAGS_REG))])])
7252 (define_insn_and_split "*add<mode>3_ne"
7253 [(set (match_operand:SWI 0 "nonimmediate_operand")
7256 (ne:SWI (match_operand 3 "int_nonimmediate_operand") (const_int 0))
7257 (match_operand:SWI 1 "nonimmediate_operand"))
7258 (match_operand:SWI 2 "<immediate_operand>")))
7259 (clobber (reg:CC FLAGS_REG))]
7260 "CONST_INT_P (operands[2])
7261 && (<MODE>mode != DImode
7262 || INTVAL (operands[2]) != HOST_WIDE_INT_C (-0x80000000))
7263 && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)
7264 && ix86_pre_reload_split ()"
7267 [(set (reg:CC FLAGS_REG)
7268 (compare:CC (match_dup 3) (const_int 1)))
7269 (parallel [(set (match_dup 0)
7271 (minus:SWI (match_dup 1)
7272 (ltu:SWI (reg:CC FLAGS_REG) (const_int 0)))
7274 (clobber (reg:CC FLAGS_REG))])]
7276 operands[2] = gen_int_mode (~INTVAL (operands[2]),
7277 <MODE>mode == DImode ? SImode : <MODE>mode);
7280 (define_insn_and_split "*add<mode>3_eq_0"
7281 [(set (match_operand:SWI 0 "nonimmediate_operand")
7283 (eq:SWI (match_operand 2 "int_nonimmediate_operand") (const_int 0))
7284 (match_operand:SWI 1 "<general_operand>")))
7285 (clobber (reg:CC FLAGS_REG))]
7286 "ix86_unary_operator_ok (PLUS, <MODE>mode, operands)
7287 && ix86_pre_reload_split ()"
7290 [(set (reg:CC FLAGS_REG)
7291 (compare:CC (match_dup 2) (const_int 1)))
7292 (parallel [(set (match_dup 0)
7293 (plus:SWI (ltu:SWI (reg:CC FLAGS_REG) (const_int 0))
7295 (clobber (reg:CC FLAGS_REG))])]
7297 if (!nonimmediate_operand (operands[1], <MODE>mode))
7298 operands[1] = force_reg (<MODE>mode, operands[1]);
7301 (define_insn_and_split "*add<mode>3_ne_0"
7302 [(set (match_operand:SWI 0 "nonimmediate_operand")
7304 (ne:SWI (match_operand 2 "int_nonimmediate_operand") (const_int 0))
7305 (match_operand:SWI 1 "<general_operand>")))
7306 (clobber (reg:CC FLAGS_REG))]
7307 "ix86_unary_operator_ok (PLUS, <MODE>mode, operands)
7308 && ix86_pre_reload_split ()"
7311 [(set (reg:CC FLAGS_REG)
7312 (compare:CC (match_dup 2) (const_int 1)))
7313 (parallel [(set (match_dup 0)
7314 (minus:SWI (minus:SWI
7316 (ltu:SWI (reg:CC FLAGS_REG) (const_int 0)))
7318 (clobber (reg:CC FLAGS_REG))])]
7320 if (!nonimmediate_operand (operands[1], <MODE>mode))
7321 operands[1] = force_reg (<MODE>mode, operands[1]);
7324 (define_insn_and_split "*sub<mode>3_eq"
7325 [(set (match_operand:SWI 0 "nonimmediate_operand")
7328 (match_operand:SWI 1 "nonimmediate_operand")
7329 (eq:SWI (match_operand 3 "int_nonimmediate_operand")
7331 (match_operand:SWI 2 "<general_operand>")))
7332 (clobber (reg:CC FLAGS_REG))]
7333 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)
7334 && ix86_pre_reload_split ()"
7337 [(set (reg:CC FLAGS_REG)
7338 (compare:CC (match_dup 3) (const_int 1)))
7339 (parallel [(set (match_dup 0)
7341 (minus:SWI (match_dup 1)
7342 (ltu:SWI (reg:CC FLAGS_REG) (const_int 0)))
7344 (clobber (reg:CC FLAGS_REG))])])
7346 (define_insn_and_split "*sub<mode>3_ne"
7347 [(set (match_operand:SWI 0 "nonimmediate_operand")
7350 (match_operand:SWI 1 "nonimmediate_operand")
7351 (ne:SWI (match_operand 3 "int_nonimmediate_operand")
7353 (match_operand:SWI 2 "<immediate_operand>")))
7354 (clobber (reg:CC FLAGS_REG))]
7355 "CONST_INT_P (operands[2])
7356 && (<MODE>mode != DImode
7357 || INTVAL (operands[2]) != HOST_WIDE_INT_C (-0x80000000))
7358 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)
7359 && ix86_pre_reload_split ()"
7362 [(set (reg:CC FLAGS_REG)
7363 (compare:CC (match_dup 3) (const_int 1)))
7364 (parallel [(set (match_dup 0)
7366 (plus:SWI (ltu:SWI (reg:CC FLAGS_REG) (const_int 0))
7369 (clobber (reg:CC FLAGS_REG))])]
7371 operands[2] = gen_int_mode (INTVAL (operands[2]) - 1,
7372 <MODE>mode == DImode ? SImode : <MODE>mode);
7375 (define_insn_and_split "*sub<mode>3_eq_1"
7376 [(set (match_operand:SWI 0 "nonimmediate_operand")
7379 (match_operand:SWI 1 "nonimmediate_operand")
7380 (eq:SWI (match_operand 3 "int_nonimmediate_operand")
7382 (match_operand:SWI 2 "<immediate_operand>")))
7383 (clobber (reg:CC FLAGS_REG))]
7384 "CONST_INT_P (operands[2])
7385 && (<MODE>mode != DImode
7386 || INTVAL (operands[2]) != HOST_WIDE_INT_C (-0x80000000))
7387 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)
7388 && ix86_pre_reload_split ()"
7391 [(set (reg:CC FLAGS_REG)
7392 (compare:CC (match_dup 3) (const_int 1)))
7393 (parallel [(set (match_dup 0)
7395 (minus:SWI (match_dup 1)
7396 (ltu:SWI (reg:CC FLAGS_REG) (const_int 0)))
7398 (clobber (reg:CC FLAGS_REG))])]
7400 operands[2] = gen_int_mode (-INTVAL (operands[2]),
7401 <MODE>mode == DImode ? SImode : <MODE>mode);
7404 (define_insn_and_split "*sub<mode>3_eq_0"
7405 [(set (match_operand:SWI 0 "nonimmediate_operand")
7407 (match_operand:SWI 1 "<general_operand>")
7408 (eq:SWI (match_operand 2 "int_nonimmediate_operand") (const_int 0))))
7409 (clobber (reg:CC FLAGS_REG))]
7410 "ix86_unary_operator_ok (MINUS, <MODE>mode, operands)
7411 && ix86_pre_reload_split ()"
7414 [(set (reg:CC FLAGS_REG)
7415 (compare:CC (match_dup 2) (const_int 1)))
7416 (parallel [(set (match_dup 0)
7417 (minus:SWI (match_dup 1)
7418 (ltu:SWI (reg:CC FLAGS_REG) (const_int 0))))
7419 (clobber (reg:CC FLAGS_REG))])]
7421 if (!nonimmediate_operand (operands[1], <MODE>mode))
7422 operands[1] = force_reg (<MODE>mode, operands[1]);
7425 (define_insn_and_split "*sub<mode>3_ne_0"
7426 [(set (match_operand:SWI 0 "nonimmediate_operand")
7428 (match_operand:SWI 1 "<general_operand>")
7429 (ne:SWI (match_operand 2 "int_nonimmediate_operand") (const_int 0))))
7430 (clobber (reg:CC FLAGS_REG))]
7431 "ix86_unary_operator_ok (MINUS, <MODE>mode, operands)
7432 && ix86_pre_reload_split ()"
7435 [(set (reg:CC FLAGS_REG)
7436 (compare:CC (match_dup 2) (const_int 1)))
7437 (parallel [(set (match_dup 0)
7439 (ltu:SWI (reg:CC FLAGS_REG) (const_int 0))
7442 (clobber (reg:CC FLAGS_REG))])]
7444 if (!nonimmediate_operand (operands[1], <MODE>mode))
7445 operands[1] = force_reg (<MODE>mode, operands[1]);
7448 ;; The patterns that match these are at the end of this file.
7450 (define_expand "<plusminus_insn>xf3"
7451 [(set (match_operand:XF 0 "register_operand")
7453 (match_operand:XF 1 "register_operand")
7454 (match_operand:XF 2 "register_operand")))]
7457 (define_expand "<plusminus_insn><mode>3"
7458 [(set (match_operand:MODEF 0 "register_operand")
7460 (match_operand:MODEF 1 "register_operand")
7461 (match_operand:MODEF 2 "nonimmediate_operand")))]
7462 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
7463 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
7465 ;; Multiply instructions
7467 (define_expand "mul<mode>3"
7468 [(parallel [(set (match_operand:SWIM248 0 "register_operand")
7470 (match_operand:SWIM248 1 "register_operand")
7471 (match_operand:SWIM248 2 "<general_operand>")))
7472 (clobber (reg:CC FLAGS_REG))])])
7474 (define_expand "mulqi3"
7475 [(parallel [(set (match_operand:QI 0 "register_operand")
7477 (match_operand:QI 1 "register_operand")
7478 (match_operand:QI 2 "nonimmediate_operand")))
7479 (clobber (reg:CC FLAGS_REG))])]
7480 "TARGET_QIMODE_MATH")
7483 ;; IMUL reg32/64, reg32/64, imm8 Direct
7484 ;; IMUL reg32/64, mem32/64, imm8 VectorPath
7485 ;; IMUL reg32/64, reg32/64, imm32 Direct
7486 ;; IMUL reg32/64, mem32/64, imm32 VectorPath
7487 ;; IMUL reg32/64, reg32/64 Direct
7488 ;; IMUL reg32/64, mem32/64 Direct
7490 ;; On BDVER1, all above IMULs use DirectPath
7493 ;; IMUL reg16, reg16, imm8 VectorPath
7494 ;; IMUL reg16, mem16, imm8 VectorPath
7495 ;; IMUL reg16, reg16, imm16 VectorPath
7496 ;; IMUL reg16, mem16, imm16 VectorPath
7497 ;; IMUL reg16, reg16 Direct
7498 ;; IMUL reg16, mem16 Direct
7500 ;; On BDVER1, all HI MULs use DoublePath
7502 (define_insn "*mul<mode>3_1"
7503 [(set (match_operand:SWIM248 0 "register_operand" "=r,r,r")
7505 (match_operand:SWIM248 1 "nonimmediate_operand" "%rm,rm,0")
7506 (match_operand:SWIM248 2 "<general_operand>" "K,<i>,mr")))
7507 (clobber (reg:CC FLAGS_REG))]
7508 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7510 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
7511 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
7512 imul{<imodesuffix>}\t{%2, %0|%0, %2}"
7513 [(set_attr "type" "imul")
7514 (set_attr "prefix_0f" "0,0,1")
7515 (set (attr "athlon_decode")
7516 (cond [(eq_attr "cpu" "athlon")
7517 (const_string "vector")
7518 (eq_attr "alternative" "1")
7519 (const_string "vector")
7520 (and (eq_attr "alternative" "2")
7521 (ior (match_test "<MODE>mode == HImode")
7522 (match_operand 1 "memory_operand")))
7523 (const_string "vector")]
7524 (const_string "direct")))
7525 (set (attr "amdfam10_decode")
7526 (cond [(and (eq_attr "alternative" "0,1")
7527 (ior (match_test "<MODE>mode == HImode")
7528 (match_operand 1 "memory_operand")))
7529 (const_string "vector")]
7530 (const_string "direct")))
7531 (set (attr "bdver1_decode")
7533 (match_test "<MODE>mode == HImode")
7534 (const_string "double")
7535 (const_string "direct")))
7536 (set_attr "mode" "<MODE>")])
7538 (define_insn "*mulsi3_1_zext"
7539 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
7541 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
7542 (match_operand:SI 2 "x86_64_general_operand" "K,e,mr"))))
7543 (clobber (reg:CC FLAGS_REG))]
7545 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7547 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7548 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7549 imul{l}\t{%2, %k0|%k0, %2}"
7550 [(set_attr "type" "imul")
7551 (set_attr "prefix_0f" "0,0,1")
7552 (set (attr "athlon_decode")
7553 (cond [(eq_attr "cpu" "athlon")
7554 (const_string "vector")
7555 (eq_attr "alternative" "1")
7556 (const_string "vector")
7557 (and (eq_attr "alternative" "2")
7558 (match_operand 1 "memory_operand"))
7559 (const_string "vector")]
7560 (const_string "direct")))
7561 (set (attr "amdfam10_decode")
7562 (cond [(and (eq_attr "alternative" "0,1")
7563 (match_operand 1 "memory_operand"))
7564 (const_string "vector")]
7565 (const_string "direct")))
7566 (set_attr "bdver1_decode" "direct")
7567 (set_attr "mode" "SI")])
7569 ;;On AMDFAM10 and BDVER1
7573 (define_insn "*mulqi3_1"
7574 [(set (match_operand:QI 0 "register_operand" "=a")
7575 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
7576 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7577 (clobber (reg:CC FLAGS_REG))]
7579 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7581 [(set_attr "type" "imul")
7582 (set_attr "length_immediate" "0")
7583 (set (attr "athlon_decode")
7584 (if_then_else (eq_attr "cpu" "athlon")
7585 (const_string "vector")
7586 (const_string "direct")))
7587 (set_attr "amdfam10_decode" "direct")
7588 (set_attr "bdver1_decode" "direct")
7589 (set_attr "mode" "QI")])
7591 ;; Multiply with jump on overflow.
7592 (define_expand "mulv<mode>4"
7593 [(parallel [(set (reg:CCO FLAGS_REG)
7596 (match_operand:SWI248 1 "register_operand"))
7599 (mult:SWI248 (match_dup 1)
7600 (match_operand:SWI248 2
7601 "<general_operand>")))))
7602 (set (match_operand:SWI248 0 "register_operand")
7603 (mult:SWI248 (match_dup 1) (match_dup 2)))])
7604 (set (pc) (if_then_else
7605 (eq (reg:CCO FLAGS_REG) (const_int 0))
7606 (label_ref (match_operand 3))
7610 if (CONST_INT_P (operands[2]))
7611 operands[4] = operands[2];
7613 operands[4] = gen_rtx_SIGN_EXTEND (<DWI>mode, operands[2]);
7616 (define_insn "*mulv<mode>4"
7617 [(set (reg:CCO FLAGS_REG)
7620 (match_operand:SWI48 1 "nonimmediate_operand" "%rm,0"))
7622 (match_operand:SWI48 2 "x86_64_sext_operand" "We,mr")))
7624 (mult:SWI48 (match_dup 1) (match_dup 2)))))
7625 (set (match_operand:SWI48 0 "register_operand" "=r,r")
7626 (mult:SWI48 (match_dup 1) (match_dup 2)))]
7627 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7629 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
7630 imul{<imodesuffix>}\t{%2, %0|%0, %2}"
7631 [(set_attr "type" "imul")
7632 (set_attr "prefix_0f" "0,1")
7633 (set (attr "athlon_decode")
7634 (cond [(eq_attr "cpu" "athlon")
7635 (const_string "vector")
7636 (eq_attr "alternative" "0")
7637 (const_string "vector")
7638 (and (eq_attr "alternative" "1")
7639 (match_operand 1 "memory_operand"))
7640 (const_string "vector")]
7641 (const_string "direct")))
7642 (set (attr "amdfam10_decode")
7643 (cond [(and (eq_attr "alternative" "1")
7644 (match_operand 1 "memory_operand"))
7645 (const_string "vector")]
7646 (const_string "direct")))
7647 (set_attr "bdver1_decode" "direct")
7648 (set_attr "mode" "<MODE>")])
7650 (define_insn "*mulvhi4"
7651 [(set (reg:CCO FLAGS_REG)
7654 (match_operand:HI 1 "nonimmediate_operand" "%0"))
7656 (match_operand:HI 2 "nonimmediate_operand" "mr")))
7658 (mult:HI (match_dup 1) (match_dup 2)))))
7659 (set (match_operand:HI 0 "register_operand" "=r")
7660 (mult:HI (match_dup 1) (match_dup 2)))]
7661 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7662 "imul{w}\t{%2, %0|%0, %2}"
7663 [(set_attr "type" "imul")
7664 (set_attr "prefix_0f" "1")
7665 (set_attr "athlon_decode" "vector")
7666 (set_attr "amdfam10_decode" "direct")
7667 (set_attr "bdver1_decode" "double")
7668 (set_attr "mode" "HI")])
7670 (define_insn "*mulv<mode>4_1"
7671 [(set (reg:CCO FLAGS_REG)
7674 (match_operand:SWI248 1 "nonimmediate_operand" "rm,rm"))
7675 (match_operand:<DWI> 3 "const_int_operand" "K,i"))
7677 (mult:SWI248 (match_dup 1)
7678 (match_operand:SWI248 2
7679 "<immediate_operand>" "K,<i>")))))
7680 (set (match_operand:SWI248 0 "register_operand" "=r,r")
7681 (mult:SWI248 (match_dup 1) (match_dup 2)))]
7682 "!(MEM_P (operands[1]) && MEM_P (operands[2]))
7683 && CONST_INT_P (operands[2])
7684 && INTVAL (operands[2]) == INTVAL (operands[3])"
7685 "imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}"
7686 [(set_attr "type" "imul")
7687 (set (attr "prefix_0f")
7689 (match_test "<MODE>mode == HImode")
7691 (const_string "*")))
7692 (set (attr "athlon_decode")
7693 (cond [(eq_attr "cpu" "athlon")
7694 (const_string "vector")
7695 (eq_attr "alternative" "1")
7696 (const_string "vector")]
7697 (const_string "direct")))
7698 (set (attr "amdfam10_decode")
7699 (cond [(ior (match_test "<MODE>mode == HImode")
7700 (match_operand 1 "memory_operand"))
7701 (const_string "vector")]
7702 (const_string "direct")))
7703 (set (attr "bdver1_decode")
7705 (match_test "<MODE>mode == HImode")
7706 (const_string "double")
7707 (const_string "direct")))
7708 (set_attr "mode" "<MODE>")
7709 (set (attr "length_immediate")
7710 (cond [(eq_attr "alternative" "0")
7712 (match_test "<MODE_SIZE> == 8")
7714 (const_string "<MODE_SIZE>")))])
7716 (define_expand "umulv<mode>4"
7717 [(parallel [(set (reg:CCO FLAGS_REG)
7720 (match_operand:SWI248 1
7721 "nonimmediate_operand"))
7723 (match_operand:SWI248 2
7724 "nonimmediate_operand")))
7726 (mult:SWI248 (match_dup 1) (match_dup 2)))))
7727 (set (match_operand:SWI248 0 "register_operand")
7728 (mult:SWI248 (match_dup 1) (match_dup 2)))
7729 (clobber (scratch:SWI248))])
7730 (set (pc) (if_then_else
7731 (eq (reg:CCO FLAGS_REG) (const_int 0))
7732 (label_ref (match_operand 3))
7736 if (MEM_P (operands[1]) && MEM_P (operands[2]))
7737 operands[1] = force_reg (<MODE>mode, operands[1]);
7740 (define_insn "*umulv<mode>4"
7741 [(set (reg:CCO FLAGS_REG)
7744 (match_operand:SWI248 1 "nonimmediate_operand" "%0"))
7746 (match_operand:SWI248 2 "nonimmediate_operand" "rm")))
7748 (mult:SWI248 (match_dup 1) (match_dup 2)))))
7749 (set (match_operand:SWI248 0 "register_operand" "=a")
7750 (mult:SWI248 (match_dup 1) (match_dup 2)))
7751 (clobber (match_scratch:SWI248 3 "=d"))]
7752 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7753 "mul{<imodesuffix>}\t%2"
7754 [(set_attr "type" "imul")
7755 (set_attr "length_immediate" "0")
7756 (set (attr "athlon_decode")
7757 (if_then_else (eq_attr "cpu" "athlon")
7758 (const_string "vector")
7759 (const_string "double")))
7760 (set_attr "amdfam10_decode" "double")
7761 (set_attr "bdver1_decode" "direct")
7762 (set_attr "mode" "<MODE>")])
7764 (define_expand "<u>mulvqi4"
7765 [(parallel [(set (reg:CCO FLAGS_REG)
7768 (match_operand:QI 1 "nonimmediate_operand"))
7770 (match_operand:QI 2 "nonimmediate_operand")))
7772 (mult:QI (match_dup 1) (match_dup 2)))))
7773 (set (match_operand:QI 0 "register_operand")
7774 (mult:QI (match_dup 1) (match_dup 2)))])
7775 (set (pc) (if_then_else
7776 (eq (reg:CCO FLAGS_REG) (const_int 0))
7777 (label_ref (match_operand 3))
7779 "TARGET_QIMODE_MATH"
7781 if (MEM_P (operands[1]) && MEM_P (operands[2]))
7782 operands[1] = force_reg (QImode, operands[1]);
7785 (define_insn "*<u>mulvqi4"
7786 [(set (reg:CCO FLAGS_REG)
7789 (match_operand:QI 1 "nonimmediate_operand" "%0"))
7791 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7793 (mult:QI (match_dup 1) (match_dup 2)))))
7794 (set (match_operand:QI 0 "register_operand" "=a")
7795 (mult:QI (match_dup 1) (match_dup 2)))]
7797 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7798 "<sgnprefix>mul{b}\t%2"
7799 [(set_attr "type" "imul")
7800 (set_attr "length_immediate" "0")
7801 (set (attr "athlon_decode")
7802 (if_then_else (eq_attr "cpu" "athlon")
7803 (const_string "vector")
7804 (const_string "direct")))
7805 (set_attr "amdfam10_decode" "direct")
7806 (set_attr "bdver1_decode" "direct")
7807 (set_attr "mode" "QI")])
7809 (define_expand "<u>mul<mode><dwi>3"
7810 [(parallel [(set (match_operand:<DWI> 0 "register_operand")
7813 (match_operand:DWIH 1 "nonimmediate_operand"))
7815 (match_operand:DWIH 2 "register_operand"))))
7816 (clobber (reg:CC FLAGS_REG))])])
7818 (define_expand "<u>mulqihi3"
7819 [(parallel [(set (match_operand:HI 0 "register_operand")
7822 (match_operand:QI 1 "nonimmediate_operand"))
7824 (match_operand:QI 2 "register_operand"))))
7825 (clobber (reg:CC FLAGS_REG))])]
7826 "TARGET_QIMODE_MATH")
7828 (define_insn "*bmi2_umul<mode><dwi>3_1"
7829 [(set (match_operand:DWIH 0 "register_operand" "=r")
7831 (match_operand:DWIH 2 "nonimmediate_operand" "%d")
7832 (match_operand:DWIH 3 "nonimmediate_operand" "rm")))
7833 (set (match_operand:DWIH 1 "register_operand" "=r")
7836 (mult:<DWI> (zero_extend:<DWI> (match_dup 2))
7837 (zero_extend:<DWI> (match_dup 3)))
7838 (match_operand:QI 4 "const_int_operand" "n"))))]
7839 "TARGET_BMI2 && INTVAL (operands[4]) == <MODE_SIZE> * BITS_PER_UNIT
7840 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7841 "mulx\t{%3, %0, %1|%1, %0, %3}"
7842 [(set_attr "type" "imulx")
7843 (set_attr "prefix" "vex")
7844 (set_attr "mode" "<MODE>")])
7846 (define_insn "*umul<mode><dwi>3_1"
7847 [(set (match_operand:<DWI> 0 "register_operand" "=r,A")
7850 (match_operand:DWIH 1 "nonimmediate_operand" "%d,0"))
7852 (match_operand:DWIH 2 "nonimmediate_operand" "rm,rm"))))
7853 (clobber (reg:CC FLAGS_REG))]
7854 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7857 mul{<imodesuffix>}\t%2"
7858 [(set_attr "isa" "bmi2,*")
7859 (set_attr "type" "imulx,imul")
7860 (set_attr "length_immediate" "*,0")
7861 (set (attr "athlon_decode")
7862 (cond [(eq_attr "alternative" "1")
7863 (if_then_else (eq_attr "cpu" "athlon")
7864 (const_string "vector")
7865 (const_string "double"))]
7866 (const_string "*")))
7867 (set_attr "amdfam10_decode" "*,double")
7868 (set_attr "bdver1_decode" "*,direct")
7869 (set_attr "prefix" "vex,orig")
7870 (set_attr "mode" "<MODE>")])
7872 ;; Convert mul to the mulx pattern to avoid flags dependency.
7874 [(set (match_operand:<DWI> 0 "register_operand")
7877 (match_operand:DWIH 1 "register_operand"))
7879 (match_operand:DWIH 2 "nonimmediate_operand"))))
7880 (clobber (reg:CC FLAGS_REG))]
7881 "TARGET_BMI2 && reload_completed
7882 && REGNO (operands[1]) == DX_REG"
7883 [(parallel [(set (match_dup 3)
7884 (mult:DWIH (match_dup 1) (match_dup 2)))
7888 (mult:<DWI> (zero_extend:<DWI> (match_dup 1))
7889 (zero_extend:<DWI> (match_dup 2)))
7892 split_double_mode (<DWI>mode, &operands[0], 1, &operands[3], &operands[4]);
7894 operands[5] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT);
7897 (define_insn "*mul<mode><dwi>3_1"
7898 [(set (match_operand:<DWI> 0 "register_operand" "=A")
7901 (match_operand:DWIH 1 "nonimmediate_operand" "%0"))
7903 (match_operand:DWIH 2 "nonimmediate_operand" "rm"))))
7904 (clobber (reg:CC FLAGS_REG))]
7905 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7906 "imul{<imodesuffix>}\t%2"
7907 [(set_attr "type" "imul")
7908 (set_attr "length_immediate" "0")
7909 (set (attr "athlon_decode")
7910 (if_then_else (eq_attr "cpu" "athlon")
7911 (const_string "vector")
7912 (const_string "double")))
7913 (set_attr "amdfam10_decode" "double")
7914 (set_attr "bdver1_decode" "direct")
7915 (set_attr "mode" "<MODE>")])
7917 (define_insn "*<u>mulqihi3_1"
7918 [(set (match_operand:HI 0 "register_operand" "=a")
7921 (match_operand:QI 1 "nonimmediate_operand" "%0"))
7923 (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7924 (clobber (reg:CC FLAGS_REG))]
7926 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7927 "<sgnprefix>mul{b}\t%2"
7928 [(set_attr "type" "imul")
7929 (set_attr "length_immediate" "0")
7930 (set (attr "athlon_decode")
7931 (if_then_else (eq_attr "cpu" "athlon")
7932 (const_string "vector")
7933 (const_string "direct")))
7934 (set_attr "amdfam10_decode" "direct")
7935 (set_attr "bdver1_decode" "direct")
7936 (set_attr "mode" "QI")])
7938 (define_expand "<s>mul<mode>3_highpart"
7939 [(parallel [(set (match_operand:DWIH 0 "register_operand")
7944 (match_operand:DWIH 1 "nonimmediate_operand"))
7946 (match_operand:DWIH 2 "register_operand")))
7948 (clobber (scratch:DWIH))
7949 (clobber (reg:CC FLAGS_REG))])]
7951 "operands[3] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
7953 (define_insn "*<s>muldi3_highpart_1"
7954 [(set (match_operand:DI 0 "register_operand" "=d")
7959 (match_operand:DI 1 "nonimmediate_operand" "%a"))
7961 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7963 (clobber (match_scratch:DI 3 "=1"))
7964 (clobber (reg:CC FLAGS_REG))]
7966 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7967 "<sgnprefix>mul{q}\t%2"
7968 [(set_attr "type" "imul")
7969 (set_attr "length_immediate" "0")
7970 (set (attr "athlon_decode")
7971 (if_then_else (eq_attr "cpu" "athlon")
7972 (const_string "vector")
7973 (const_string "double")))
7974 (set_attr "amdfam10_decode" "double")
7975 (set_attr "bdver1_decode" "direct")
7976 (set_attr "mode" "DI")])
7978 (define_insn "*<s>mulsi3_highpart_zext"
7979 [(set (match_operand:DI 0 "register_operand" "=d")
7980 (zero_extend:DI (truncate:SI
7982 (mult:DI (any_extend:DI
7983 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7985 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7987 (clobber (match_scratch:SI 3 "=1"))
7988 (clobber (reg:CC FLAGS_REG))]
7990 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7991 "<sgnprefix>mul{l}\t%2"
7992 [(set_attr "type" "imul")
7993 (set_attr "length_immediate" "0")
7994 (set (attr "athlon_decode")
7995 (if_then_else (eq_attr "cpu" "athlon")
7996 (const_string "vector")
7997 (const_string "double")))
7998 (set_attr "amdfam10_decode" "double")
7999 (set_attr "bdver1_decode" "direct")
8000 (set_attr "mode" "SI")])
8002 (define_insn "*<s>mulsi3_highpart_1"
8003 [(set (match_operand:SI 0 "register_operand" "=d")
8008 (match_operand:SI 1 "nonimmediate_operand" "%a"))
8010 (match_operand:SI 2 "nonimmediate_operand" "rm")))
8012 (clobber (match_scratch:SI 3 "=1"))
8013 (clobber (reg:CC FLAGS_REG))]
8014 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
8015 "<sgnprefix>mul{l}\t%2"
8016 [(set_attr "type" "imul")
8017 (set_attr "length_immediate" "0")
8018 (set (attr "athlon_decode")
8019 (if_then_else (eq_attr "cpu" "athlon")
8020 (const_string "vector")
8021 (const_string "double")))
8022 (set_attr "amdfam10_decode" "double")
8023 (set_attr "bdver1_decode" "direct")
8024 (set_attr "mode" "SI")])
8026 ;; The patterns that match these are at the end of this file.
8028 (define_expand "mulxf3"
8029 [(set (match_operand:XF 0 "register_operand")
8030 (mult:XF (match_operand:XF 1 "register_operand")
8031 (match_operand:XF 2 "register_operand")))]
8034 (define_expand "mul<mode>3"
8035 [(set (match_operand:MODEF 0 "register_operand")
8036 (mult:MODEF (match_operand:MODEF 1 "register_operand")
8037 (match_operand:MODEF 2 "nonimmediate_operand")))]
8038 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
8039 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
8041 ;; Divide instructions
8043 ;; The patterns that match these are at the end of this file.
8045 (define_expand "divxf3"
8046 [(set (match_operand:XF 0 "register_operand")
8047 (div:XF (match_operand:XF 1 "register_operand")
8048 (match_operand:XF 2 "register_operand")))]
8051 (define_expand "div<mode>3"
8052 [(set (match_operand:MODEF 0 "register_operand")
8053 (div:MODEF (match_operand:MODEF 1 "register_operand")
8054 (match_operand:MODEF 2 "nonimmediate_operand")))]
8055 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
8056 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8058 if (<MODE>mode == SFmode
8059 && TARGET_SSE && TARGET_SSE_MATH
8061 && optimize_insn_for_speed_p ()
8062 && flag_finite_math_only && !flag_trapping_math
8063 && flag_unsafe_math_optimizations)
8065 ix86_emit_swdivsf (operands[0], operands[1],
8066 operands[2], SFmode);
8071 ;; Divmod instructions.
8073 (define_code_iterator any_div [div udiv])
8074 (define_code_attr paired_mod [(div "mod") (udiv "umod")])
8076 (define_expand "<u>divmod<mode>4"
8077 [(parallel [(set (match_operand:SWIM248 0 "register_operand")
8079 (match_operand:SWIM248 1 "register_operand")
8080 (match_operand:SWIM248 2 "nonimmediate_operand")))
8081 (set (match_operand:SWIM248 3 "register_operand")
8082 (<paired_mod>:SWIM248 (match_dup 1) (match_dup 2)))
8083 (clobber (reg:CC FLAGS_REG))])])
8085 ;; Split with 8bit unsigned divide:
8086 ;; if (dividend an divisor are in [0-255])
8087 ;; use 8bit unsigned integer divide
8089 ;; use original integer divide
8091 [(set (match_operand:SWI48 0 "register_operand")
8092 (any_div:SWI48 (match_operand:SWI48 2 "register_operand")
8093 (match_operand:SWI48 3 "nonimmediate_operand")))
8094 (set (match_operand:SWI48 1 "register_operand")
8095 (<paired_mod>:SWI48 (match_dup 2) (match_dup 3)))
8096 (clobber (reg:CC FLAGS_REG))]
8097 "TARGET_USE_8BIT_IDIV
8098 && TARGET_QIMODE_MATH
8099 && can_create_pseudo_p ()
8100 && !optimize_insn_for_size_p ()"
8102 "ix86_split_idivmod (<MODE>mode, operands, <u_bool>); DONE;")
8105 [(set (match_operand:DI 0 "register_operand")
8107 (any_div:SI (match_operand:SI 2 "register_operand")
8108 (match_operand:SI 3 "nonimmediate_operand"))))
8109 (set (match_operand:SI 1 "register_operand")
8110 (<paired_mod>:SI (match_dup 2) (match_dup 3)))
8111 (clobber (reg:CC FLAGS_REG))]
8113 && TARGET_USE_8BIT_IDIV
8114 && TARGET_QIMODE_MATH
8115 && can_create_pseudo_p ()
8116 && !optimize_insn_for_size_p ()"
8118 "ix86_split_idivmod (SImode, operands, <u_bool>); DONE;")
8121 [(set (match_operand:DI 1 "register_operand")
8123 (<paired_mod>:SI (match_operand:SI 2 "register_operand")
8124 (match_operand:SI 3 "nonimmediate_operand"))))
8125 (set (match_operand:SI 0 "register_operand")
8126 (any_div:SI (match_dup 2) (match_dup 3)))
8127 (clobber (reg:CC FLAGS_REG))]
8129 && TARGET_USE_8BIT_IDIV
8130 && TARGET_QIMODE_MATH
8131 && can_create_pseudo_p ()
8132 && !optimize_insn_for_size_p ()"
8134 "ix86_split_idivmod (SImode, operands, <u_bool>); DONE;")
8136 (define_insn_and_split "divmod<mode>4_1"
8137 [(set (match_operand:SWI48 0 "register_operand" "=a")
8138 (div:SWI48 (match_operand:SWI48 2 "register_operand" "0")
8139 (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
8140 (set (match_operand:SWI48 1 "register_operand" "=&d")
8141 (mod:SWI48 (match_dup 2) (match_dup 3)))
8142 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
8143 (clobber (reg:CC FLAGS_REG))]
8147 [(parallel [(set (match_dup 1)
8148 (ashiftrt:SWI48 (match_dup 4) (match_dup 5)))
8149 (clobber (reg:CC FLAGS_REG))])
8150 (parallel [(set (match_dup 0)
8151 (div:SWI48 (match_dup 2) (match_dup 3)))
8153 (mod:SWI48 (match_dup 2) (match_dup 3)))
8155 (clobber (reg:CC FLAGS_REG))])]
8157 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
8159 if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
8160 operands[4] = operands[2];
8163 /* Avoid use of cltd in favor of a mov+shift. */
8164 emit_move_insn (operands[1], operands[2]);
8165 operands[4] = operands[1];
8168 [(set_attr "type" "multi")
8169 (set_attr "mode" "<MODE>")])
8171 (define_insn_and_split "udivmod<mode>4_1"
8172 [(set (match_operand:SWI48 0 "register_operand" "=a")
8173 (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "0")
8174 (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
8175 (set (match_operand:SWI48 1 "register_operand" "=&d")
8176 (umod:SWI48 (match_dup 2) (match_dup 3)))
8177 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
8178 (clobber (reg:CC FLAGS_REG))]
8182 [(set (match_dup 1) (const_int 0))
8183 (parallel [(set (match_dup 0)
8184 (udiv:SWI48 (match_dup 2) (match_dup 3)))
8186 (umod:SWI48 (match_dup 2) (match_dup 3)))
8188 (clobber (reg:CC FLAGS_REG))])]
8190 [(set_attr "type" "multi")
8191 (set_attr "mode" "<MODE>")])
8193 (define_insn_and_split "divmodsi4_zext_1"
8194 [(set (match_operand:DI 0 "register_operand" "=a")
8196 (div:SI (match_operand:SI 2 "register_operand" "0")
8197 (match_operand:SI 3 "nonimmediate_operand" "rm"))))
8198 (set (match_operand:SI 1 "register_operand" "=&d")
8199 (mod:SI (match_dup 2) (match_dup 3)))
8200 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
8201 (clobber (reg:CC FLAGS_REG))]
8204 "&& reload_completed"
8205 [(parallel [(set (match_dup 1)
8206 (ashiftrt:SI (match_dup 4) (match_dup 5)))
8207 (clobber (reg:CC FLAGS_REG))])
8208 (parallel [(set (match_dup 0)
8209 (zero_extend:DI (div:SI (match_dup 2) (match_dup 3))))
8211 (mod:SI (match_dup 2) (match_dup 3)))
8213 (clobber (reg:CC FLAGS_REG))])]
8215 operands[5] = GEN_INT (GET_MODE_BITSIZE (SImode)-1);
8217 if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
8218 operands[4] = operands[2];
8221 /* Avoid use of cltd in favor of a mov+shift. */
8222 emit_move_insn (operands[1], operands[2]);
8223 operands[4] = operands[1];
8226 [(set_attr "type" "multi")
8227 (set_attr "mode" "SI")])
8229 (define_insn_and_split "udivmodsi4_zext_1"
8230 [(set (match_operand:DI 0 "register_operand" "=a")
8232 (udiv:SI (match_operand:SI 2 "register_operand" "0")
8233 (match_operand:SI 3 "nonimmediate_operand" "rm"))))
8234 (set (match_operand:SI 1 "register_operand" "=&d")
8235 (umod:SI (match_dup 2) (match_dup 3)))
8236 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
8237 (clobber (reg:CC FLAGS_REG))]
8240 "&& reload_completed"
8241 [(set (match_dup 1) (const_int 0))
8242 (parallel [(set (match_dup 0)
8243 (zero_extend:DI (udiv:SI (match_dup 2) (match_dup 3))))
8245 (umod:SI (match_dup 2) (match_dup 3)))
8247 (clobber (reg:CC FLAGS_REG))])]
8249 [(set_attr "type" "multi")
8250 (set_attr "mode" "SI")])
8252 (define_insn_and_split "divmodsi4_zext_2"
8253 [(set (match_operand:DI 1 "register_operand" "=&d")
8255 (mod:SI (match_operand:SI 2 "register_operand" "0")
8256 (match_operand:SI 3 "nonimmediate_operand" "rm"))))
8257 (set (match_operand:SI 0 "register_operand" "=a")
8258 (div:SI (match_dup 2) (match_dup 3)))
8259 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
8260 (clobber (reg:CC FLAGS_REG))]
8263 "&& reload_completed"
8264 [(parallel [(set (match_dup 6)
8265 (ashiftrt:SI (match_dup 4) (match_dup 5)))
8266 (clobber (reg:CC FLAGS_REG))])
8267 (parallel [(set (match_dup 1)
8268 (zero_extend:DI (mod:SI (match_dup 2) (match_dup 3))))
8270 (div:SI (match_dup 2) (match_dup 3)))
8272 (clobber (reg:CC FLAGS_REG))])]
8274 operands[5] = GEN_INT (GET_MODE_BITSIZE (SImode)-1);
8275 operands[6] = gen_lowpart (SImode, operands[1]);
8277 if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
8278 operands[4] = operands[2];
8281 /* Avoid use of cltd in favor of a mov+shift. */
8282 emit_move_insn (operands[6], operands[2]);
8283 operands[4] = operands[6];
8286 [(set_attr "type" "multi")
8287 (set_attr "mode" "SI")])
8289 (define_insn_and_split "udivmodsi4_zext_2"
8290 [(set (match_operand:DI 1 "register_operand" "=&d")
8292 (umod:SI (match_operand:SI 2 "register_operand" "0")
8293 (match_operand:SI 3 "nonimmediate_operand" "rm"))))
8294 (set (match_operand:SI 0 "register_operand" "=a")
8295 (udiv:SI (match_dup 2) (match_dup 3)))
8296 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
8297 (clobber (reg:CC FLAGS_REG))]
8300 "&& reload_completed"
8301 [(set (match_dup 4) (const_int 0))
8302 (parallel [(set (match_dup 1)
8303 (zero_extend:DI (umod:SI (match_dup 2) (match_dup 3))))
8305 (udiv:SI (match_dup 2) (match_dup 3)))
8307 (clobber (reg:CC FLAGS_REG))])]
8308 "operands[4] = gen_lowpart (SImode, operands[1]);"
8309 [(set_attr "type" "multi")
8310 (set_attr "mode" "SI")])
8312 (define_insn_and_split "*divmod<mode>4"
8313 [(set (match_operand:SWIM248 0 "register_operand" "=a")
8314 (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
8315 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
8316 (set (match_operand:SWIM248 1 "register_operand" "=&d")
8317 (mod:SWIM248 (match_dup 2) (match_dup 3)))
8318 (clobber (reg:CC FLAGS_REG))]
8322 [(parallel [(set (match_dup 1)
8323 (ashiftrt:SWIM248 (match_dup 4) (match_dup 5)))
8324 (clobber (reg:CC FLAGS_REG))])
8325 (parallel [(set (match_dup 0)
8326 (div:SWIM248 (match_dup 2) (match_dup 3)))
8328 (mod:SWIM248 (match_dup 2) (match_dup 3)))
8330 (clobber (reg:CC FLAGS_REG))])]
8332 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
8334 if (<MODE>mode != HImode
8335 && (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD))
8336 operands[4] = operands[2];
8339 /* Avoid use of cltd in favor of a mov+shift. */
8340 emit_move_insn (operands[1], operands[2]);
8341 operands[4] = operands[1];
8344 [(set_attr "type" "multi")
8345 (set_attr "mode" "<MODE>")])
8347 (define_insn_and_split "*udivmod<mode>4"
8348 [(set (match_operand:SWIM248 0 "register_operand" "=a")
8349 (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
8350 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
8351 (set (match_operand:SWIM248 1 "register_operand" "=&d")
8352 (umod:SWIM248 (match_dup 2) (match_dup 3)))
8353 (clobber (reg:CC FLAGS_REG))]
8357 [(set (match_dup 1) (const_int 0))
8358 (parallel [(set (match_dup 0)
8359 (udiv:SWIM248 (match_dup 2) (match_dup 3)))
8361 (umod:SWIM248 (match_dup 2) (match_dup 3)))
8363 (clobber (reg:CC FLAGS_REG))])]
8365 [(set_attr "type" "multi")
8366 (set_attr "mode" "<MODE>")])
8368 ;; Optimize division or modulo by constant power of 2, if the constant
8369 ;; materializes only after expansion.
8370 (define_insn_and_split "*udivmod<mode>4_pow2"
8371 [(set (match_operand:SWI48 0 "register_operand" "=r")
8372 (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "0")
8373 (match_operand:SWI48 3 "const_int_operand" "n")))
8374 (set (match_operand:SWI48 1 "register_operand" "=r")
8375 (umod:SWI48 (match_dup 2) (match_dup 3)))
8376 (clobber (reg:CC FLAGS_REG))]
8377 "IN_RANGE (exact_log2 (UINTVAL (operands[3])), 1, 31)"
8379 "&& reload_completed"
8380 [(set (match_dup 1) (match_dup 2))
8381 (parallel [(set (match_dup 0) (lshiftrt:<MODE> (match_dup 2) (match_dup 4)))
8382 (clobber (reg:CC FLAGS_REG))])
8383 (parallel [(set (match_dup 1) (and:<MODE> (match_dup 1) (match_dup 5)))
8384 (clobber (reg:CC FLAGS_REG))])]
8386 int v = exact_log2 (UINTVAL (operands[3]));
8387 operands[4] = GEN_INT (v);
8388 operands[5] = GEN_INT ((HOST_WIDE_INT_1U << v) - 1);
8390 [(set_attr "type" "multi")
8391 (set_attr "mode" "<MODE>")])
8393 (define_insn_and_split "*divmodsi4_zext_1"
8394 [(set (match_operand:DI 0 "register_operand" "=a")
8396 (div:SI (match_operand:SI 2 "register_operand" "0")
8397 (match_operand:SI 3 "nonimmediate_operand" "rm"))))
8398 (set (match_operand:SI 1 "register_operand" "=&d")
8399 (mod:SI (match_dup 2) (match_dup 3)))
8400 (clobber (reg:CC FLAGS_REG))]
8403 "&& reload_completed"
8404 [(parallel [(set (match_dup 1)
8405 (ashiftrt:SI (match_dup 4) (match_dup 5)))
8406 (clobber (reg:CC FLAGS_REG))])
8407 (parallel [(set (match_dup 0)
8408 (zero_extend:DI (div:SI (match_dup 2) (match_dup 3))))
8410 (mod:SI (match_dup 2) (match_dup 3)))
8412 (clobber (reg:CC FLAGS_REG))])]
8414 operands[5] = GEN_INT (GET_MODE_BITSIZE (SImode)-1);
8416 if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
8417 operands[4] = operands[2];
8420 /* Avoid use of cltd in favor of a mov+shift. */
8421 emit_move_insn (operands[1], operands[2]);
8422 operands[4] = operands[1];
8425 [(set_attr "type" "multi")
8426 (set_attr "mode" "SI")])
8428 (define_insn_and_split "*udivmodsi4_zext_1"
8429 [(set (match_operand:DI 0 "register_operand" "=a")
8431 (udiv:SI (match_operand:SI 2 "register_operand" "0")
8432 (match_operand:SI 3 "nonimmediate_operand" "rm"))))
8433 (set (match_operand:SI 1 "register_operand" "=&d")
8434 (umod:SI (match_dup 2) (match_dup 3)))
8435 (clobber (reg:CC FLAGS_REG))]
8438 "&& reload_completed"
8439 [(set (match_dup 1) (const_int 0))
8440 (parallel [(set (match_dup 0)
8441 (zero_extend:DI (udiv:SI (match_dup 2) (match_dup 3))))
8443 (umod:SI (match_dup 2) (match_dup 3)))
8445 (clobber (reg:CC FLAGS_REG))])]
8447 [(set_attr "type" "multi")
8448 (set_attr "mode" "SI")])
8450 (define_insn_and_split "*udivmodsi4_pow2_zext_1"
8451 [(set (match_operand:DI 0 "register_operand" "=r")
8453 (udiv:SI (match_operand:SI 2 "register_operand" "0")
8454 (match_operand:SI 3 "const_int_operand" "n"))))
8455 (set (match_operand:SI 1 "register_operand" "=r")
8456 (umod:SI (match_dup 2) (match_dup 3)))
8457 (clobber (reg:CC FLAGS_REG))]
8459 && exact_log2 (UINTVAL (operands[3])) > 0"
8461 "&& reload_completed"
8462 [(set (match_dup 1) (match_dup 2))
8463 (parallel [(set (match_dup 0)
8464 (zero_extend:DI (lshiftrt:SI (match_dup 2) (match_dup 4))))
8465 (clobber (reg:CC FLAGS_REG))])
8466 (parallel [(set (match_dup 1) (and:SI (match_dup 1) (match_dup 5)))
8467 (clobber (reg:CC FLAGS_REG))])]
8469 int v = exact_log2 (UINTVAL (operands[3]));
8470 operands[4] = GEN_INT (v);
8471 operands[5] = GEN_INT ((HOST_WIDE_INT_1U << v) - 1);
8473 [(set_attr "type" "multi")
8474 (set_attr "mode" "SI")])
8476 (define_insn_and_split "*divmodsi4_zext_2"
8477 [(set (match_operand:DI 1 "register_operand" "=&d")
8479 (mod:SI (match_operand:SI 2 "register_operand" "0")
8480 (match_operand:SI 3 "nonimmediate_operand" "rm"))))
8481 (set (match_operand:SI 0 "register_operand" "=a")
8482 (div:SI (match_dup 2) (match_dup 3)))
8483 (clobber (reg:CC FLAGS_REG))]
8486 "&& reload_completed"
8487 [(parallel [(set (match_dup 6)
8488 (ashiftrt:SI (match_dup 4) (match_dup 5)))
8489 (clobber (reg:CC FLAGS_REG))])
8490 (parallel [(set (match_dup 1)
8491 (zero_extend:DI (mod:SI (match_dup 2) (match_dup 3))))
8493 (div:SI (match_dup 2) (match_dup 3)))
8495 (clobber (reg:CC FLAGS_REG))])]
8497 operands[5] = GEN_INT (GET_MODE_BITSIZE (SImode)-1);
8498 operands[6] = gen_lowpart (SImode, operands[1]);
8500 if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
8501 operands[4] = operands[2];
8504 /* Avoid use of cltd in favor of a mov+shift. */
8505 emit_move_insn (operands[6], operands[2]);
8506 operands[4] = operands[6];
8509 [(set_attr "type" "multi")
8510 (set_attr "mode" "SI")])
8512 (define_insn_and_split "*udivmodsi4_zext_2"
8513 [(set (match_operand:DI 1 "register_operand" "=&d")
8515 (umod:SI (match_operand:SI 2 "register_operand" "0")
8516 (match_operand:SI 3 "nonimmediate_operand" "rm"))))
8517 (set (match_operand:SI 0 "register_operand" "=a")
8518 (udiv:SI (match_dup 2) (match_dup 3)))
8519 (clobber (reg:CC FLAGS_REG))]
8522 "&& reload_completed"
8523 [(set (match_dup 4) (const_int 0))
8524 (parallel [(set (match_dup 1)
8525 (zero_extend:DI (umod:SI (match_dup 2) (match_dup 3))))
8527 (udiv:SI (match_dup 2) (match_dup 3)))
8529 (clobber (reg:CC FLAGS_REG))])]
8530 "operands[4] = gen_lowpart (SImode, operands[1]);"
8531 [(set_attr "type" "multi")
8532 (set_attr "mode" "SI")])
8534 (define_insn_and_split "*udivmodsi4_pow2_zext_2"
8535 [(set (match_operand:DI 1 "register_operand" "=r")
8537 (umod:SI (match_operand:SI 2 "register_operand" "0")
8538 (match_operand:SI 3 "const_int_operand" "n"))))
8539 (set (match_operand:SI 0 "register_operand" "=r")
8540 (umod:SI (match_dup 2) (match_dup 3)))
8541 (clobber (reg:CC FLAGS_REG))]
8543 && exact_log2 (UINTVAL (operands[3])) > 0"
8545 "&& reload_completed"
8546 [(set (match_dup 1) (match_dup 2))
8547 (parallel [(set (match_dup 0) (lshiftrt:SI (match_dup 2) (match_dup 4)))
8548 (clobber (reg:CC FLAGS_REG))])
8549 (parallel [(set (match_dup 1)
8550 (zero_extend:DI (and:SI (match_dup 1) (match_dup 5))))
8551 (clobber (reg:CC FLAGS_REG))])]
8553 int v = exact_log2 (UINTVAL (operands[3]));
8554 operands[4] = GEN_INT (v);
8555 operands[5] = GEN_INT ((HOST_WIDE_INT_1U << v) - 1);
8557 [(set_attr "type" "multi")
8558 (set_attr "mode" "SI")])
8560 (define_insn "*<u>divmod<mode>4_noext"
8561 [(set (match_operand:SWIM248 0 "register_operand" "=a")
8563 (match_operand:SWIM248 2 "register_operand" "0")
8564 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
8565 (set (match_operand:SWIM248 1 "register_operand" "=d")
8566 (<paired_mod>:SWIM248 (match_dup 2) (match_dup 3)))
8567 (use (match_operand:SWIM248 4 "register_operand" "1"))
8568 (clobber (reg:CC FLAGS_REG))]
8570 "<sgnprefix>div{<imodesuffix>}\t%3"
8571 [(set_attr "type" "idiv")
8572 (set_attr "mode" "<MODE>")])
8574 (define_insn "*<u>divmodsi4_noext_zext_1"
8575 [(set (match_operand:DI 0 "register_operand" "=a")
8577 (any_div:SI (match_operand:SI 2 "register_operand" "0")
8578 (match_operand:SI 3 "nonimmediate_operand" "rm"))))
8579 (set (match_operand:SI 1 "register_operand" "=d")
8580 (<paired_mod>:SI (match_dup 2) (match_dup 3)))
8581 (use (match_operand:SI 4 "register_operand" "1"))
8582 (clobber (reg:CC FLAGS_REG))]
8584 "<sgnprefix>div{l}\t%3"
8585 [(set_attr "type" "idiv")
8586 (set_attr "mode" "SI")])
8588 (define_insn "*<u>divmodsi4_noext_zext_2"
8589 [(set (match_operand:DI 1 "register_operand" "=d")
8591 (<paired_mod>:SI (match_operand:SI 2 "register_operand" "0")
8592 (match_operand:SI 3 "nonimmediate_operand" "rm"))))
8593 (set (match_operand:SI 0 "register_operand" "=a")
8594 (any_div:SI (match_dup 2) (match_dup 3)))
8595 (use (match_operand:SI 4 "register_operand" "1"))
8596 (clobber (reg:CC FLAGS_REG))]
8598 "<sgnprefix>div{l}\t%3"
8599 [(set_attr "type" "idiv")
8600 (set_attr "mode" "SI")])
8602 (define_expand "divmodqi4"
8603 [(parallel [(set (match_operand:QI 0 "register_operand")
8605 (match_operand:QI 1 "register_operand")
8606 (match_operand:QI 2 "nonimmediate_operand")))
8607 (set (match_operand:QI 3 "register_operand")
8608 (mod:QI (match_dup 1) (match_dup 2)))
8609 (clobber (reg:CC FLAGS_REG))])]
8610 "TARGET_QIMODE_MATH"
8615 tmp0 = gen_reg_rtx (HImode);
8616 tmp1 = gen_reg_rtx (HImode);
8618 /* Extend operands[1] to HImode. Generate 8bit divide. Result is in AX. */
8619 emit_insn (gen_extendqihi2 (tmp1, operands[1]));
8620 emit_insn (gen_divmodhiqi3 (tmp0, tmp1, operands[2]));
8622 /* Extract remainder from AH. */
8623 tmp1 = gen_rtx_ZERO_EXTRACT (HImode, tmp0, GEN_INT (8), GEN_INT (8));
8624 tmp1 = lowpart_subreg (QImode, tmp1, HImode);
8625 rtx_insn *insn = emit_move_insn (operands[3], tmp1);
8627 mod = gen_rtx_MOD (QImode, operands[1], operands[2]);
8628 set_unique_reg_note (insn, REG_EQUAL, mod);
8630 /* Extract quotient from AL. */
8631 insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
8633 div = gen_rtx_DIV (QImode, operands[1], operands[2]);
8634 set_unique_reg_note (insn, REG_EQUAL, div);
8639 (define_expand "udivmodqi4"
8640 [(parallel [(set (match_operand:QI 0 "register_operand")
8642 (match_operand:QI 1 "register_operand")
8643 (match_operand:QI 2 "nonimmediate_operand")))
8644 (set (match_operand:QI 3 "register_operand")
8645 (umod:QI (match_dup 1) (match_dup 2)))
8646 (clobber (reg:CC FLAGS_REG))])]
8647 "TARGET_QIMODE_MATH"
8652 tmp0 = gen_reg_rtx (HImode);
8653 tmp1 = gen_reg_rtx (HImode);
8655 /* Extend operands[1] to HImode. Generate 8bit divide. Result is in AX. */
8656 emit_insn (gen_zero_extendqihi2 (tmp1, operands[1]));
8657 emit_insn (gen_udivmodhiqi3 (tmp0, tmp1, operands[2]));
8659 /* Extract remainder from AH. */
8660 tmp1 = gen_rtx_ZERO_EXTRACT (HImode, tmp0, GEN_INT (8), GEN_INT (8));
8661 tmp1 = lowpart_subreg (QImode, tmp1, HImode);
8662 rtx_insn *insn = emit_move_insn (operands[3], tmp1);
8664 mod = gen_rtx_UMOD (QImode, operands[1], operands[2]);
8665 set_unique_reg_note (insn, REG_EQUAL, mod);
8667 /* Extract quotient from AL. */
8668 insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
8670 div = gen_rtx_UDIV (QImode, operands[1], operands[2]);
8671 set_unique_reg_note (insn, REG_EQUAL, div);
8676 ;; Divide AX by r/m8, with result stored in
8679 ;; Change div/mod to HImode and extend the second argument to HImode
8680 ;; so that mode of div/mod matches with mode of arguments. Otherwise
8681 ;; combine may fail.
8682 (define_insn "<u>divmodhiqi3"
8683 [(set (match_operand:HI 0 "register_operand" "=a")
8688 (mod:HI (match_operand:HI 1 "register_operand" "0")
8690 (match_operand:QI 2 "nonimmediate_operand" "qm")))))
8694 (div:HI (match_dup 1) (any_extend:HI (match_dup 2)))))))
8695 (clobber (reg:CC FLAGS_REG))]
8696 "TARGET_QIMODE_MATH"
8697 "<sgnprefix>div{b}\t%2"
8698 [(set_attr "type" "idiv")
8699 (set_attr "mode" "QI")])
8701 ;; We cannot use div/idiv for double division, because it causes
8702 ;; "division by zero" on the overflow and that's not what we expect
8703 ;; from truncate. Because true (non truncating) double division is
8704 ;; never generated, we can't create this insn anyway.
8707 ; [(set (match_operand:SI 0 "register_operand" "=a")
8709 ; (udiv:DI (match_operand:DI 1 "register_operand" "A")
8711 ; (match_operand:SI 2 "nonimmediate_operand" "rm")))))
8712 ; (set (match_operand:SI 3 "register_operand" "=d")
8714 ; (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
8715 ; (clobber (reg:CC FLAGS_REG))]
8717 ; "div{l}\t{%2, %0|%0, %2}"
8718 ; [(set_attr "type" "idiv")])
8720 ;;- Logical AND instructions
8722 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
8723 ;; Note that this excludes ah.
8725 (define_expand "@test<mode>_ccno_1"
8726 [(set (reg:CCNO FLAGS_REG)
8729 (match_operand:SWI48 0 "nonimmediate_operand")
8730 (match_operand:SWI48 1 "<nonmemory_szext_operand>"))
8733 (define_expand "testqi_ccz_1"
8734 [(set (reg:CCZ FLAGS_REG)
8737 (match_operand:QI 0 "nonimmediate_operand")
8738 (match_operand:QI 1 "nonmemory_operand"))
8741 (define_insn "*testdi_1"
8742 [(set (reg FLAGS_REG)
8745 (match_operand:DI 0 "nonimmediate_operand" "%r,rm")
8746 (match_operand:DI 1 "x86_64_szext_nonmemory_operand" "Z,re"))
8749 && ix86_match_ccmode
8751 /* If we are going to emit testl instead of testq, and the operands[1]
8752 constant might have the SImode sign bit set, make sure the sign
8753 flag isn't tested, because the instruction will set the sign flag
8754 based on bit 31 rather than bit 63. If it isn't CONST_INT,
8755 conservatively assume it might have bit 31 set. */
8756 (satisfies_constraint_Z (operands[1])
8757 && (!CONST_INT_P (operands[1])
8758 || val_signbit_known_set_p (SImode, INTVAL (operands[1]))))
8759 ? CCZmode : CCNOmode)"
8761 test{l}\t{%k1, %k0|%k0, %k1}
8762 test{q}\t{%1, %0|%0, %1}"
8763 [(set_attr "type" "test")
8764 (set_attr "mode" "SI,DI")])
8766 (define_insn "*testqi_1_maybe_si"
8767 [(set (reg FLAGS_REG)
8770 (match_operand:QI 0 "nonimmediate_operand" "%qm,*a,qm,r")
8771 (match_operand:QI 1 "nonmemory_operand" "q,n,n,n"))
8773 "ix86_match_ccmode (insn,
8774 CONST_INT_P (operands[1])
8775 && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
8777 if (which_alternative == 3)
8779 if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
8780 operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
8781 return "test{l}\t{%1, %k0|%k0, %1}";
8783 return "test{b}\t{%1, %0|%0, %1}";
8785 [(set_attr "type" "test")
8786 (set_attr "mode" "QI,QI,QI,SI")
8787 (set_attr "pent_pair" "uv,uv,np,np")])
8789 (define_insn "*test<mode>_1"
8790 [(set (reg FLAGS_REG)
8793 (match_operand:SWI124 0 "nonimmediate_operand" "%<r>m,*a,<r>m")
8794 (match_operand:SWI124 1 "<nonmemory_szext_operand>" "<r>,<i>,<i>"))
8796 "ix86_match_ccmode (insn, CCNOmode)"
8797 "test{<imodesuffix>}\t{%1, %0|%0, %1}"
8798 [(set_attr "type" "test")
8799 (set_attr "mode" "<MODE>")
8800 (set_attr "pent_pair" "uv,uv,np")])
8802 (define_expand "testqi_ext_1_ccno"
8803 [(set (reg:CCNO FLAGS_REG)
8808 (match_operand:HI 0 "register_operand")
8811 (match_operand:QI 1 "const_int_operand"))
8814 (define_insn "*testqi_ext<mode>_1"
8815 [(set (reg FLAGS_REG)
8819 (zero_extract:SWI248
8820 (match_operand:SWI248 0 "register_operand" "Q,Q")
8823 (match_operand:QI 1 "general_operand" "QnBc,m"))
8825 "ix86_match_ccmode (insn, CCNOmode)"
8826 "test{b}\t{%1, %h0|%h0, %1}"
8827 [(set_attr "isa" "*,nox64")
8828 (set_attr "type" "test")
8829 (set_attr "mode" "QI")])
8831 (define_insn "*testqi_ext<mode>_2"
8832 [(set (reg FLAGS_REG)
8836 (zero_extract:SWI248
8837 (match_operand:SWI248 0 "register_operand" "Q")
8841 (zero_extract:SWI248
8842 (match_operand:SWI248 1 "register_operand" "Q")
8846 "ix86_match_ccmode (insn, CCNOmode)"
8847 "test{b}\t{%h1, %h0|%h0, %h1}"
8848 [(set_attr "type" "test")
8849 (set_attr "mode" "QI")])
8851 ;; Combine likes to form bit extractions for some tests. Humor it.
8852 (define_insn_and_split "*testqi_ext_3"
8853 [(set (match_operand 0 "flags_reg_operand")
8854 (match_operator 1 "compare_operator"
8855 [(zero_extract:SWI248
8856 (match_operand 2 "int_nonimmediate_operand" "rm")
8857 (match_operand 3 "const_int_operand" "n")
8858 (match_operand 4 "const_int_operand" "n"))
8860 "/* Ensure that resulting mask is zero or sign extended operand. */
8861 INTVAL (operands[4]) >= 0
8862 && ((INTVAL (operands[3]) > 0
8863 && INTVAL (operands[3]) + INTVAL (operands[4]) <= 32)
8864 || (<MODE>mode == DImode
8865 && INTVAL (operands[3]) > 32
8866 && INTVAL (operands[3]) + INTVAL (operands[4]) == 64))
8867 && ix86_match_ccmode (insn,
8868 /* If zero_extract mode precision is the same
8869 as len, the SF of the zero_extract
8870 comparison will be the most significant
8871 extracted bit, but this could be matched
8872 after splitting only for pos 0 len all bits
8873 trivial extractions. Require CCZmode. */
8874 (GET_MODE_PRECISION (<MODE>mode)
8875 == INTVAL (operands[3]))
8876 /* Otherwise, require CCZmode if we'd use a mask
8877 with the most significant bit set and can't
8878 widen it to wider mode. *testdi_1 also
8879 requires CCZmode if the mask has bit
8880 31 set and all bits above it clear. */
8881 || (INTVAL (operands[3]) + INTVAL (operands[4])
8883 /* We can't widen also if val is not a REG. */
8884 || (INTVAL (operands[3]) + INTVAL (operands[4])
8885 == GET_MODE_PRECISION (GET_MODE (operands[2]))
8886 && !register_operand (operands[2],
8887 GET_MODE (operands[2])))
8888 /* And we shouldn't widen if
8889 TARGET_PARTIAL_REG_STALL. */
8890 || (TARGET_PARTIAL_REG_STALL
8891 && (INTVAL (operands[3]) + INTVAL (operands[4])
8892 >= (paradoxical_subreg_p (operands[2])
8894 (GET_MODE (SUBREG_REG (operands[2])))
8896 ? GET_MODE_PRECISION
8897 (GET_MODE (SUBREG_REG (operands[2])))
8898 : GET_MODE_PRECISION
8899 (GET_MODE (operands[2])))))
8900 ? CCZmode : CCNOmode)"
8903 [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
8905 rtx val = operands[2];
8906 HOST_WIDE_INT len = INTVAL (operands[3]);
8907 HOST_WIDE_INT pos = INTVAL (operands[4]);
8908 machine_mode mode = GET_MODE (val);
8912 machine_mode submode = GET_MODE (SUBREG_REG (val));
8914 /* Narrow paradoxical subregs to prevent partial register stalls. */
8915 if (GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode)
8916 && GET_MODE_CLASS (submode) == MODE_INT
8917 && (GET_MODE (operands[0]) == CCZmode
8918 || pos + len < GET_MODE_PRECISION (submode)
8919 || REG_P (SUBREG_REG (val))))
8921 val = SUBREG_REG (val);
8926 /* Small HImode tests can be converted to QImode. */
8928 && register_operand (val, HImode))
8930 rtx nval = gen_lowpart (QImode, val);
8932 || GET_MODE (operands[0]) == CCZmode
8940 gcc_assert (pos + len <= GET_MODE_PRECISION (mode));
8942 /* If the mask is going to have the sign bit set in the mode
8943 we want to do the comparison in and user isn't interested just
8944 in the zero flag, then we must widen the target mode. */
8945 if (pos + len == GET_MODE_PRECISION (mode)
8946 && GET_MODE (operands[0]) != CCZmode)
8948 gcc_assert (pos + len < 32 && !MEM_P (val));
8950 val = gen_lowpart (mode, val);
8954 = wi::shifted_mask (pos, len, false, GET_MODE_PRECISION (mode));
8956 operands[2] = gen_rtx_AND (mode, val, immed_wide_int_const (mask, mode));
8959 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
8960 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
8961 ;; this is relatively important trick.
8962 ;; Do the conversion only post-reload to avoid limiting of the register class
8965 [(set (match_operand 0 "flags_reg_operand")
8966 (match_operator 1 "compare_operator"
8967 [(and (match_operand 2 "QIreg_operand")
8968 (match_operand 3 "const_int_operand"))
8971 && GET_MODE (operands[2]) != QImode
8972 && ((ix86_match_ccmode (insn, CCZmode)
8973 && !(INTVAL (operands[3]) & ~(255 << 8)))
8974 || (ix86_match_ccmode (insn, CCNOmode)
8975 && !(INTVAL (operands[3]) & ~(127 << 8))))"
8980 (zero_extract:SI (match_dup 2)
8986 operands[2] = gen_lowpart (SImode, operands[2]);
8987 operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, QImode);
8991 [(set (match_operand 0 "flags_reg_operand")
8992 (match_operator 1 "compare_operator"
8993 [(and (match_operand 2 "nonimmediate_operand")
8994 (match_operand 3 "const_int_operand"))
8997 && GET_MODE (operands[2]) != QImode
8998 && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
8999 && ((ix86_match_ccmode (insn, CCZmode)
9000 && !(INTVAL (operands[3]) & ~255))
9001 || (ix86_match_ccmode (insn, CCNOmode)
9002 && !(INTVAL (operands[3]) & ~127)))"
9004 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
9007 operands[2] = gen_lowpart (QImode, operands[2]);
9008 operands[3] = gen_int_mode (INTVAL (operands[3]), QImode);
9011 ;; %%% This used to optimize known byte-wide and operations to memory,
9012 ;; and sometimes to QImode registers. If this is considered useful,
9013 ;; it should be done with splitters.
9015 (define_expand "and<mode>3"
9016 [(set (match_operand:SWIM1248s 0 "nonimmediate_operand")
9017 (and:SWIM1248s (match_operand:SWIM1248s 1 "nonimmediate_operand")
9018 (match_operand:SWIM1248s 2 "<general_szext_operand>")))]
9021 machine_mode mode = <MODE>mode;
9023 if (<MODE>mode == DImode && !TARGET_64BIT)
9025 else if (const_int_operand (operands[2], <MODE>mode)
9026 && register_operand (operands[0], <MODE>mode)
9027 && !(TARGET_ZERO_EXTEND_WITH_AND
9028 && optimize_function_for_speed_p (cfun)))
9030 unsigned HOST_WIDE_INT ival = UINTVAL (operands[2]);
9032 if (ival == GET_MODE_MASK (SImode))
9034 else if (ival == GET_MODE_MASK (HImode))
9036 else if (ival == GET_MODE_MASK (QImode))
9040 if (mode != <MODE>mode)
9041 emit_insn (gen_extend_insn
9042 (operands[0], gen_lowpart (mode, operands[1]),
9043 <MODE>mode, mode, 1));
9045 ix86_expand_binary_operator (AND, <MODE>mode, operands);
9050 (define_insn_and_split "*anddi3_doubleword"
9051 [(set (match_operand:DI 0 "nonimmediate_operand")
9053 (match_operand:DI 1 "nonimmediate_operand")
9054 (match_operand:DI 2 "x86_64_szext_general_operand")))
9055 (clobber (reg:CC FLAGS_REG))]
9056 "!TARGET_64BIT && TARGET_STV && TARGET_SSE2
9057 && ix86_binary_operator_ok (AND, DImode, operands)
9058 && ix86_pre_reload_split ()"
9063 split_double_mode (DImode, &operands[0], 3, &operands[0], &operands[3]);
9065 if (operands[2] == const0_rtx)
9066 emit_move_insn (operands[0], const0_rtx);
9067 else if (operands[2] == constm1_rtx)
9068 emit_move_insn (operands[0], operands[1]);
9070 emit_insn (gen_andsi3 (operands[0], operands[1], operands[2]));
9072 if (operands[5] == const0_rtx)
9073 emit_move_insn (operands[3], const0_rtx);
9074 else if (operands[5] == constm1_rtx)
9075 emit_move_insn (operands[3], operands[4]);
9077 emit_insn (gen_andsi3 (operands[3], operands[4], operands[5]));
9082 (define_insn "*anddi_1"
9083 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r,k")
9085 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm,k")
9086 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,m,L,k")))
9087 (clobber (reg:CC FLAGS_REG))]
9088 "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
9090 and{l}\t{%k2, %k0|%k0, %k2}
9091 and{q}\t{%2, %0|%0, %2}
9092 and{q}\t{%2, %0|%0, %2}
9095 [(set_attr "isa" "x64,x64,x64,x64,avx512bw")
9096 (set_attr "type" "alu,alu,alu,imovx,msklog")
9097 (set_attr "length_immediate" "*,*,*,0,*")
9098 (set (attr "prefix_rex")
9100 (and (eq_attr "type" "imovx")
9101 (and (match_test "INTVAL (operands[2]) == 0xff")
9102 (match_operand 1 "ext_QIreg_operand")))
9104 (const_string "*")))
9105 (set_attr "mode" "SI,DI,DI,SI,DI")])
9107 (define_insn_and_split "*anddi_1_btr"
9108 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9110 (match_operand:DI 1 "nonimmediate_operand" "%0")
9111 (match_operand:DI 2 "const_int_operand" "n")))
9112 (clobber (reg:CC FLAGS_REG))]
9113 "TARGET_64BIT && TARGET_USE_BT
9114 && ix86_binary_operator_ok (AND, DImode, operands)
9115 && IN_RANGE (exact_log2 (~INTVAL (operands[2])), 31, 63)"
9117 "&& reload_completed"
9118 [(parallel [(set (zero_extract:DI (match_dup 0)
9122 (clobber (reg:CC FLAGS_REG))])]
9123 "operands[3] = GEN_INT (exact_log2 (~INTVAL (operands[2])));"
9124 [(set_attr "type" "alu1")
9125 (set_attr "prefix_0f" "1")
9126 (set_attr "znver1_decode" "double")
9127 (set_attr "mode" "DI")])
9129 ;; Turn *anddi_1 into *andsi_1_zext if possible.
9131 [(set (match_operand:DI 0 "register_operand")
9132 (and:DI (subreg:DI (match_operand:SI 1 "register_operand") 0)
9133 (match_operand:DI 2 "x86_64_zext_immediate_operand")))
9134 (clobber (reg:CC FLAGS_REG))]
9136 [(parallel [(set (match_dup 0)
9137 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))
9138 (clobber (reg:CC FLAGS_REG))])]
9140 if (GET_CODE (operands[2]) == SYMBOL_REF
9141 || GET_CODE (operands[2]) == LABEL_REF)
9143 operands[2] = shallow_copy_rtx (operands[2]);
9144 PUT_MODE (operands[2], SImode);
9146 else if (GET_CODE (operands[2]) == CONST)
9148 /* (const:DI (plus:DI (symbol_ref:DI ("...")) (const_int N))) */
9149 operands[2] = copy_rtx (operands[2]);
9150 PUT_MODE (operands[2], SImode);
9151 PUT_MODE (XEXP (operands[2], 0), SImode);
9152 PUT_MODE (XEXP (XEXP (operands[2], 0), 0), SImode);
9155 operands[2] = gen_lowpart (SImode, operands[2]);
9158 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9159 (define_insn "*andsi_1_zext"
9160 [(set (match_operand:DI 0 "register_operand" "=r")
9162 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9163 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
9164 (clobber (reg:CC FLAGS_REG))]
9165 "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
9166 "and{l}\t{%2, %k0|%k0, %2}"
9167 [(set_attr "type" "alu")
9168 (set_attr "mode" "SI")])
9170 (define_insn "*and<mode>_1"
9171 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=rm,r,Ya,k")
9172 (and:SWI24 (match_operand:SWI24 1 "nonimmediate_operand" "%0,0,qm,k")
9173 (match_operand:SWI24 2 "<general_operand>" "r<i>,m,L,k")))
9174 (clobber (reg:CC FLAGS_REG))]
9175 "ix86_binary_operator_ok (AND, <MODE>mode, operands)"
9177 and{<imodesuffix>}\t{%2, %0|%0, %2}
9178 and{<imodesuffix>}\t{%2, %0|%0, %2}
9182 (cond [(eq_attr "alternative" "3")
9183 (if_then_else (eq_attr "mode" "SI")
9184 (const_string "avx512bw")
9185 (const_string "avx512f"))
9187 (const_string "*")))
9188 (set_attr "type" "alu,alu,imovx,msklog")
9189 (set_attr "length_immediate" "*,*,0,*")
9190 (set (attr "prefix_rex")
9192 (and (eq_attr "type" "imovx")
9193 (and (match_test "INTVAL (operands[2]) == 0xff")
9194 (match_operand 1 "ext_QIreg_operand")))
9196 (const_string "*")))
9197 (set_attr "mode" "<MODE>,<MODE>,SI,<MODE>")])
9199 (define_insn "*andqi_1"
9200 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,k")
9201 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,k")
9202 (match_operand:QI 2 "general_operand" "qn,m,rn,k")))
9203 (clobber (reg:CC FLAGS_REG))]
9204 "ix86_binary_operator_ok (AND, QImode, operands)"
9206 and{b}\t{%2, %0|%0, %2}
9207 and{b}\t{%2, %0|%0, %2}
9208 and{l}\t{%k2, %k0|%k0, %k2}
9210 [(set_attr "type" "alu,alu,alu,msklog")
9212 (cond [(eq_attr "alternative" "2")
9214 (and (eq_attr "alternative" "3")
9215 (match_test "!TARGET_AVX512DQ"))
9218 (const_string "QI")))
9219 ;; Potential partial reg stall on alternative 2.
9220 (set (attr "preferred_for_speed")
9221 (cond [(eq_attr "alternative" "2")
9222 (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
9223 (symbol_ref "true")))])
9225 (define_insn "*and<mode>_1_slp"
9226 [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>"))
9227 (and:SWI12 (match_operand:SWI12 1 "nonimmediate_operand" "%0")
9228 (match_operand:SWI12 2 "general_operand" "<r>mn")))
9229 (clobber (reg:CC FLAGS_REG))]
9230 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9231 /* FIXME: without this LRA can't reload this pattern, see PR82524. */
9232 && (rtx_equal_p (operands[0], operands[1])
9233 || rtx_equal_p (operands[0], operands[2]))"
9234 "and{<imodesuffix>}\t{%2, %0|%0, %2}"
9235 [(set_attr "type" "alu")
9236 (set_attr "mode" "<MODE>")])
9239 [(set (match_operand:SWI248 0 "register_operand")
9240 (and:SWI248 (match_operand:SWI248 1 "nonimmediate_operand")
9241 (match_operand:SWI248 2 "const_int_operand")))
9242 (clobber (reg:CC FLAGS_REG))]
9244 && (!REG_P (operands[1])
9245 || REGNO (operands[0]) != REGNO (operands[1]))"
9248 unsigned HOST_WIDE_INT ival = UINTVAL (operands[2]);
9251 if (ival == GET_MODE_MASK (SImode))
9253 else if (ival == GET_MODE_MASK (HImode))
9255 else if (ival == GET_MODE_MASK (QImode))
9260 /* Zero extend to SImode to avoid partial register stalls. */
9261 if (<MODE_SIZE> < GET_MODE_SIZE (SImode))
9262 operands[0] = gen_lowpart (SImode, operands[0]);
9264 emit_insn (gen_extend_insn
9265 (operands[0], gen_lowpart (mode, operands[1]),
9266 GET_MODE (operands[0]), mode, 1));
9271 [(set (match_operand:SWI48 0 "register_operand")
9272 (and:SWI48 (match_dup 0)
9273 (const_int -65536)))
9274 (clobber (reg:CC FLAGS_REG))]
9275 "(TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)
9276 || optimize_function_for_size_p (cfun)"
9277 [(set (strict_low_part (match_dup 1)) (const_int 0))]
9278 "operands[1] = gen_lowpart (HImode, operands[0]);")
9281 [(set (match_operand:SWI248 0 "any_QIreg_operand")
9282 (and:SWI248 (match_dup 0)
9284 (clobber (reg:CC FLAGS_REG))]
9285 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9286 && reload_completed"
9287 [(set (strict_low_part (match_dup 1)) (const_int 0))]
9288 "operands[1] = gen_lowpart (QImode, operands[0]);")
9291 [(set (match_operand:SWI248 0 "QIreg_operand")
9292 (and:SWI248 (match_dup 0)
9293 (const_int -65281)))
9294 (clobber (reg:CC FLAGS_REG))]
9295 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9296 && reload_completed"
9298 [(set (zero_extract:SI (match_dup 0)
9304 (zero_extract:SI (match_dup 0)
9308 (zero_extract:SI (match_dup 0)
9310 (const_int 8)) 0)) 0))
9311 (clobber (reg:CC FLAGS_REG))])]
9312 "operands[0] = gen_lowpart (SImode, operands[0]);")
9314 (define_insn "*anddi_2"
9315 [(set (reg FLAGS_REG)
9318 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
9319 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,m"))
9321 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r")
9322 (and:DI (match_dup 1) (match_dup 2)))]
9324 && ix86_match_ccmode
9326 /* If we are going to emit andl instead of andq, and the operands[2]
9327 constant might have the SImode sign bit set, make sure the sign
9328 flag isn't tested, because the instruction will set the sign flag
9329 based on bit 31 rather than bit 63. If it isn't CONST_INT,
9330 conservatively assume it might have bit 31 set. */
9331 (satisfies_constraint_Z (operands[2])
9332 && (!CONST_INT_P (operands[2])
9333 || val_signbit_known_set_p (SImode, INTVAL (operands[2]))))
9334 ? CCZmode : CCNOmode)
9335 && ix86_binary_operator_ok (AND, DImode, operands)"
9337 and{l}\t{%k2, %k0|%k0, %k2}
9338 and{q}\t{%2, %0|%0, %2}
9339 and{q}\t{%2, %0|%0, %2}"
9340 [(set_attr "type" "alu")
9341 (set_attr "mode" "SI,DI,DI")])
9343 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9344 (define_insn "*andsi_2_zext"
9345 [(set (reg FLAGS_REG)
9347 (match_operand:SI 1 "nonimmediate_operand" "%0")
9348 (match_operand:SI 2 "x86_64_general_operand" "rme"))
9350 (set (match_operand:DI 0 "register_operand" "=r")
9351 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
9352 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9353 && ix86_binary_operator_ok (AND, SImode, operands)"
9354 "and{l}\t{%2, %k0|%k0, %2}"
9355 [(set_attr "type" "alu")
9356 (set_attr "mode" "SI")])
9358 (define_insn "*andqi_2_maybe_si"
9359 [(set (reg FLAGS_REG)
9361 (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9362 (match_operand:QI 2 "general_operand" "qn,m,n"))
9364 (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
9365 (and:QI (match_dup 1) (match_dup 2)))]
9366 "ix86_binary_operator_ok (AND, QImode, operands)
9367 && ix86_match_ccmode (insn,
9368 CONST_INT_P (operands[2])
9369 && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
9371 if (which_alternative == 2)
9373 if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
9374 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
9375 return "and{l}\t{%2, %k0|%k0, %2}";
9377 return "and{b}\t{%2, %0|%0, %2}";
9379 [(set_attr "type" "alu")
9380 (set_attr "mode" "QI,QI,SI")
9381 ;; Potential partial reg stall on alternative 2.
9382 (set (attr "preferred_for_speed")
9383 (cond [(eq_attr "alternative" "2")
9384 (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
9385 (symbol_ref "true")))])
9387 (define_insn "*and<mode>_2"
9388 [(set (reg FLAGS_REG)
9389 (compare (and:SWI124
9390 (match_operand:SWI124 1 "nonimmediate_operand" "%0,0")
9391 (match_operand:SWI124 2 "<general_operand>" "<r><i>,m"))
9393 (set (match_operand:SWI124 0 "nonimmediate_operand" "=<r>m,<r>")
9394 (and:SWI124 (match_dup 1) (match_dup 2)))]
9395 "ix86_match_ccmode (insn, CCNOmode)
9396 && ix86_binary_operator_ok (AND, <MODE>mode, operands)"
9397 "and{<imodesuffix>}\t{%2, %0|%0, %2}"
9398 [(set_attr "type" "alu")
9399 (set_attr "mode" "<MODE>")])
9401 (define_expand "andqi_ext_1"
9403 [(set (zero_extract:HI (match_operand:HI 0 "register_operand")
9409 (zero_extract:HI (match_operand:HI 1 "register_operand")
9412 (match_operand:QI 2 "const_int_operand")) 0))
9413 (clobber (reg:CC FLAGS_REG))])])
9415 (define_insn "*andqi_ext<mode>_1"
9416 [(set (zero_extract:SWI248
9417 (match_operand:SWI248 0 "register_operand" "+Q,Q")
9423 (zero_extract:SWI248
9424 (match_operand:SWI248 1 "register_operand" "0,0")
9427 (match_operand:QI 2 "general_operand" "QnBc,m")) 0))
9428 (clobber (reg:CC FLAGS_REG))]
9429 "/* FIXME: without this LRA can't reload this pattern, see PR82524. */
9430 rtx_equal_p (operands[0], operands[1])"
9431 "and{b}\t{%2, %h0|%h0, %2}"
9432 [(set_attr "isa" "*,nox64")
9433 (set_attr "type" "alu")
9434 (set_attr "mode" "QI")])
9436 ;; Generated by peephole translating test to and. This shows up
9437 ;; often in fp comparisons.
9438 (define_insn "*andqi_ext<mode>_1_cc"
9439 [(set (reg FLAGS_REG)
9443 (zero_extract:SWI248
9444 (match_operand:SWI248 1 "register_operand" "0,0")
9447 (match_operand:QI 2 "general_operand" "QnBc,m"))
9449 (set (zero_extract:SWI248
9450 (match_operand:SWI248 0 "register_operand" "+Q,Q")
9456 (zero_extract:SWI248
9461 "ix86_match_ccmode (insn, CCNOmode)
9462 /* FIXME: without this LRA can't reload this pattern, see PR82524. */
9463 && rtx_equal_p (operands[0], operands[1])"
9464 "and{b}\t{%2, %h0|%h0, %2}"
9465 [(set_attr "isa" "*,nox64")
9466 (set_attr "type" "alu")
9467 (set_attr "mode" "QI")])
9469 (define_insn "*andqi_ext<mode>_2"
9470 [(set (zero_extract:SWI248
9471 (match_operand:SWI248 0 "register_operand" "+Q")
9477 (zero_extract:SWI248
9478 (match_operand:SWI248 1 "register_operand" "%0")
9482 (zero_extract:SWI248
9483 (match_operand:SWI248 2 "register_operand" "Q")
9485 (const_int 8)) 0)) 0))
9486 (clobber (reg:CC FLAGS_REG))]
9487 "/* FIXME: without this LRA can't reload this pattern, see PR82524. */
9488 rtx_equal_p (operands[0], operands[1])
9489 || rtx_equal_p (operands[0], operands[2])"
9490 "and{b}\t{%h2, %h0|%h0, %h2}"
9491 [(set_attr "type" "alu")
9492 (set_attr "mode" "QI")])
9494 ;; Convert wide AND instructions with immediate operand to shorter QImode
9495 ;; equivalents when possible.
9496 ;; Don't do the splitting with memory operands, since it introduces risk
9497 ;; of memory mismatch stalls. We may want to do the splitting for optimizing
9498 ;; for size, but that can (should?) be handled by generic code instead.
9500 [(set (match_operand:SWI248 0 "QIreg_operand")
9501 (and:SWI248 (match_operand:SWI248 1 "register_operand")
9502 (match_operand:SWI248 2 "const_int_operand")))
9503 (clobber (reg:CC FLAGS_REG))]
9505 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9506 && !(~INTVAL (operands[2]) & ~(255 << 8))"
9508 [(set (zero_extract:SI (match_dup 0)
9514 (zero_extract:SI (match_dup 1)
9518 (clobber (reg:CC FLAGS_REG))])]
9520 operands[0] = gen_lowpart (SImode, operands[0]);
9521 operands[1] = gen_lowpart (SImode, operands[1]);
9522 operands[2] = gen_int_mode (INTVAL (operands[2]) >> 8, QImode);
9525 ;; Since AND can be encoded with sign extended immediate, this is only
9526 ;; profitable when 7th bit is not set.
9528 [(set (match_operand:SWI248 0 "any_QIreg_operand")
9529 (and:SWI248 (match_operand:SWI248 1 "general_operand")
9530 (match_operand:SWI248 2 "const_int_operand")))
9531 (clobber (reg:CC FLAGS_REG))]
9533 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9534 && !(~INTVAL (operands[2]) & ~255)
9535 && !(INTVAL (operands[2]) & 128)"
9536 [(parallel [(set (strict_low_part (match_dup 0))
9537 (and:QI (match_dup 1)
9539 (clobber (reg:CC FLAGS_REG))])]
9541 operands[0] = gen_lowpart (QImode, operands[0]);
9542 operands[1] = gen_lowpart (QImode, operands[1]);
9543 operands[2] = gen_int_mode (INTVAL (operands[2]), QImode);
9546 (define_insn "*andndi3_doubleword"
9547 [(set (match_operand:DI 0 "register_operand")
9549 (not:DI (match_operand:DI 1 "register_operand"))
9550 (match_operand:DI 2 "nonimmediate_operand")))
9551 (clobber (reg:CC FLAGS_REG))]
9552 "!TARGET_64BIT && TARGET_STV && TARGET_SSE2
9553 && ix86_pre_reload_split ()"
9557 [(set (match_operand:DI 0 "register_operand")
9559 (not:DI (match_operand:DI 1 "register_operand"))
9560 (match_operand:DI 2 "nonimmediate_operand")))
9561 (clobber (reg:CC FLAGS_REG))]
9562 "!TARGET_64BIT && TARGET_BMI && TARGET_STV && TARGET_SSE2
9563 && can_create_pseudo_p ()"
9564 [(parallel [(set (match_dup 0)
9565 (and:SI (not:SI (match_dup 1)) (match_dup 2)))
9566 (clobber (reg:CC FLAGS_REG))])
9567 (parallel [(set (match_dup 3)
9568 (and:SI (not:SI (match_dup 4)) (match_dup 5)))
9569 (clobber (reg:CC FLAGS_REG))])]
9570 "split_double_mode (DImode, &operands[0], 3, &operands[0], &operands[3]);")
9573 [(set (match_operand:DI 0 "register_operand")
9575 (not:DI (match_operand:DI 1 "register_operand"))
9576 (match_operand:DI 2 "nonimmediate_operand")))
9577 (clobber (reg:CC FLAGS_REG))]
9578 "!TARGET_64BIT && !TARGET_BMI && TARGET_STV && TARGET_SSE2
9579 && can_create_pseudo_p ()"
9580 [(set (match_dup 6) (not:SI (match_dup 1)))
9581 (parallel [(set (match_dup 0)
9582 (and:SI (match_dup 6) (match_dup 2)))
9583 (clobber (reg:CC FLAGS_REG))])
9584 (set (match_dup 7) (not:SI (match_dup 4)))
9585 (parallel [(set (match_dup 3)
9586 (and:SI (match_dup 7) (match_dup 5)))
9587 (clobber (reg:CC FLAGS_REG))])]
9589 operands[6] = gen_reg_rtx (SImode);
9590 operands[7] = gen_reg_rtx (SImode);
9592 split_double_mode (DImode, &operands[0], 3, &operands[0], &operands[3]);
9595 (define_insn "*andn<mode>_1"
9596 [(set (match_operand:SWI48 0 "register_operand" "=r,r,k")
9598 (not:SWI48 (match_operand:SWI48 1 "register_operand" "r,r,k"))
9599 (match_operand:SWI48 2 "nonimmediate_operand" "r,m,k")))
9600 (clobber (reg:CC FLAGS_REG))]
9601 "TARGET_BMI || TARGET_AVX512BW"
9603 andn\t{%2, %1, %0|%0, %1, %2}
9604 andn\t{%2, %1, %0|%0, %1, %2}
9606 [(set_attr "isa" "bmi,bmi,avx512bw")
9607 (set_attr "type" "bitmanip,bitmanip,msklog")
9608 (set_attr "btver2_decode" "direct, double,*")
9609 (set_attr "mode" "<MODE>")])
9611 (define_insn "*andn<mode>_1"
9612 [(set (match_operand:SWI12 0 "register_operand" "=r,k")
9614 (not:SWI12 (match_operand:SWI12 1 "register_operand" "r,k"))
9615 (match_operand:SWI12 2 "register_operand" "r,k")))
9616 (clobber (reg:CC FLAGS_REG))]
9617 "TARGET_BMI || TARGET_AVX512BW"
9619 andn\t{%k2, %k1, %k0|%k0, %k1, %k2}
9621 [(set_attr "isa" "bmi,avx512f")
9622 (set_attr "type" "bitmanip,msklog")
9623 (set_attr "btver2_decode" "direct,*")
9625 (cond [(eq_attr "alternative" "0")
9627 (and (eq_attr "alternative" "1")
9628 (match_test "!TARGET_AVX512DQ"))
9631 (const_string "<MODE>")))])
9633 (define_insn "*andn_<mode>_ccno"
9634 [(set (reg FLAGS_REG)
9637 (not:SWI48 (match_operand:SWI48 1 "register_operand" "r,r"))
9638 (match_operand:SWI48 2 "nonimmediate_operand" "r,m"))
9640 (clobber (match_scratch:SWI48 0 "=r,r"))]
9641 "TARGET_BMI && ix86_match_ccmode (insn, CCNOmode)"
9642 "andn\t{%2, %1, %0|%0, %1, %2}"
9643 [(set_attr "type" "bitmanip")
9644 (set_attr "btver2_decode" "direct, double")
9645 (set_attr "mode" "<MODE>")])
9647 ;; Logical inclusive and exclusive OR instructions
9649 ;; %%% This used to optimize known byte-wide and operations to memory.
9650 ;; If this is considered useful, it should be done with splitters.
9652 (define_expand "<code><mode>3"
9653 [(set (match_operand:SWIM1248s 0 "nonimmediate_operand")
9654 (any_or:SWIM1248s (match_operand:SWIM1248s 1 "nonimmediate_operand")
9655 (match_operand:SWIM1248s 2 "<general_operand>")))]
9657 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
9659 (define_insn_and_split "*<code>di3_doubleword"
9660 [(set (match_operand:DI 0 "nonimmediate_operand")
9662 (match_operand:DI 1 "nonimmediate_operand")
9663 (match_operand:DI 2 "x86_64_szext_general_operand")))
9664 (clobber (reg:CC FLAGS_REG))]
9665 "!TARGET_64BIT && TARGET_STV && TARGET_SSE2
9666 && ix86_binary_operator_ok (<CODE>, DImode, operands)
9667 && ix86_pre_reload_split ()"
9672 split_double_mode (DImode, &operands[0], 3, &operands[0], &operands[3]);
9674 if (operands[2] == const0_rtx)
9675 emit_move_insn (operands[0], operands[1]);
9676 else if (operands[2] == constm1_rtx)
9679 emit_move_insn (operands[0], constm1_rtx);
9681 ix86_expand_unary_operator (NOT, SImode, &operands[0]);
9684 ix86_expand_binary_operator (<CODE>, SImode, &operands[0]);
9686 if (operands[5] == const0_rtx)
9687 emit_move_insn (operands[3], operands[4]);
9688 else if (operands[5] == constm1_rtx)
9691 emit_move_insn (operands[3], constm1_rtx);
9693 ix86_expand_unary_operator (NOT, SImode, &operands[3]);
9696 ix86_expand_binary_operator (<CODE>, SImode, &operands[3]);
9701 (define_insn "*<code><mode>_1"
9702 [(set (match_operand:SWI248 0 "nonimmediate_operand" "=rm,r,k")
9704 (match_operand:SWI248 1 "nonimmediate_operand" "%0,0,k")
9705 (match_operand:SWI248 2 "<general_operand>" "r<i>,m,k")))
9706 (clobber (reg:CC FLAGS_REG))]
9707 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9709 <logic>{<imodesuffix>}\t{%2, %0|%0, %2}
9710 <logic>{<imodesuffix>}\t{%2, %0|%0, %2}
9713 (cond [(eq_attr "alternative" "2")
9714 (if_then_else (eq_attr "mode" "SI,DI")
9715 (const_string "avx512bw")
9716 (const_string "avx512f"))
9718 (const_string "*")))
9719 (set_attr "type" "alu, alu, msklog")
9720 (set_attr "mode" "<MODE>")])
9722 (define_insn_and_split "*iordi_1_bts"
9723 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9725 (match_operand:DI 1 "nonimmediate_operand" "%0")
9726 (match_operand:DI 2 "const_int_operand" "n")))
9727 (clobber (reg:CC FLAGS_REG))]
9728 "TARGET_64BIT && TARGET_USE_BT
9729 && ix86_binary_operator_ok (IOR, DImode, operands)
9730 && IN_RANGE (exact_log2 (INTVAL (operands[2])), 31, 63)"
9732 "&& reload_completed"
9733 [(parallel [(set (zero_extract:DI (match_dup 0)
9737 (clobber (reg:CC FLAGS_REG))])]
9738 "operands[3] = GEN_INT (exact_log2 (INTVAL (operands[2])));"
9739 [(set_attr "type" "alu1")
9740 (set_attr "prefix_0f" "1")
9741 (set_attr "znver1_decode" "double")
9742 (set_attr "mode" "DI")])
9744 (define_insn_and_split "*xordi_1_btc"
9745 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9747 (match_operand:DI 1 "nonimmediate_operand" "%0")
9748 (match_operand:DI 2 "const_int_operand" "n")))
9749 (clobber (reg:CC FLAGS_REG))]
9750 "TARGET_64BIT && TARGET_USE_BT
9751 && ix86_binary_operator_ok (XOR, DImode, operands)
9752 && IN_RANGE (exact_log2 (INTVAL (operands[2])), 31, 63)"
9754 "&& reload_completed"
9755 [(parallel [(set (zero_extract:DI (match_dup 0)
9758 (not:DI (zero_extract:DI (match_dup 0)
9761 (clobber (reg:CC FLAGS_REG))])]
9762 "operands[3] = GEN_INT (exact_log2 (INTVAL (operands[2])));"
9763 [(set_attr "type" "alu1")
9764 (set_attr "prefix_0f" "1")
9765 (set_attr "znver1_decode" "double")
9766 (set_attr "mode" "DI")])
9768 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9769 (define_insn "*<code>si_1_zext"
9770 [(set (match_operand:DI 0 "register_operand" "=r")
9772 (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9773 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
9774 (clobber (reg:CC FLAGS_REG))]
9775 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
9776 "<logic>{l}\t{%2, %k0|%k0, %2}"
9777 [(set_attr "type" "alu")
9778 (set_attr "mode" "SI")])
9780 (define_insn "*<code>si_1_zext_imm"
9781 [(set (match_operand:DI 0 "register_operand" "=r")
9783 (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
9784 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
9785 (clobber (reg:CC FLAGS_REG))]
9786 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
9787 "<logic>{l}\t{%2, %k0|%k0, %2}"
9788 [(set_attr "type" "alu")
9789 (set_attr "mode" "SI")])
9791 (define_insn "*<code>qi_1"
9792 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,k")
9793 (any_or:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,k")
9794 (match_operand:QI 2 "general_operand" "qn,m,rn,k")))
9795 (clobber (reg:CC FLAGS_REG))]
9796 "ix86_binary_operator_ok (<CODE>, QImode, operands)"
9798 <logic>{b}\t{%2, %0|%0, %2}
9799 <logic>{b}\t{%2, %0|%0, %2}
9800 <logic>{l}\t{%k2, %k0|%k0, %k2}
9802 [(set_attr "isa" "*,*,*,avx512f")
9803 (set_attr "type" "alu,alu,alu,msklog")
9805 (cond [(eq_attr "alternative" "2")
9807 (and (eq_attr "alternative" "3")
9808 (match_test "!TARGET_AVX512DQ"))
9811 (const_string "QI")))
9812 ;; Potential partial reg stall on alternative 2.
9813 (set (attr "preferred_for_speed")
9814 (cond [(eq_attr "alternative" "2")
9815 (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
9816 (symbol_ref "true")))])
9818 (define_insn "*<code><mode>_1_slp"
9819 [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>"))
9820 (any_or:SWI12 (match_operand:SWI12 1 "nonimmediate_operand" "%0")
9821 (match_operand:SWI12 2 "general_operand" "<r>mn")))
9822 (clobber (reg:CC FLAGS_REG))]
9823 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9824 /* FIXME: without this LRA can't reload this pattern, see PR82524. */
9825 && (rtx_equal_p (operands[0], operands[1])
9826 || rtx_equal_p (operands[0], operands[2]))"
9827 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
9828 [(set_attr "type" "alu")
9829 (set_attr "mode" "<MODE>")])
9831 (define_insn "*<code><mode>_2"
9832 [(set (reg FLAGS_REG)
9833 (compare (any_or:SWI
9834 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
9835 (match_operand:SWI 2 "<general_operand>" "<r><i>,m"))
9837 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
9838 (any_or:SWI (match_dup 1) (match_dup 2)))]
9839 "ix86_match_ccmode (insn, CCNOmode)
9840 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9841 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
9842 [(set_attr "type" "alu")
9843 (set_attr "mode" "<MODE>")])
9845 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9846 ;; ??? Special case for immediate operand is missing - it is tricky.
9847 (define_insn "*<code>si_2_zext"
9848 [(set (reg FLAGS_REG)
9849 (compare (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9850 (match_operand:SI 2 "x86_64_general_operand" "rme"))
9852 (set (match_operand:DI 0 "register_operand" "=r")
9853 (zero_extend:DI (any_or:SI (match_dup 1) (match_dup 2))))]
9854 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9855 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
9856 "<logic>{l}\t{%2, %k0|%k0, %2}"
9857 [(set_attr "type" "alu")
9858 (set_attr "mode" "SI")])
9860 (define_insn "*<code>si_2_zext_imm"
9861 [(set (reg FLAGS_REG)
9863 (match_operand:SI 1 "nonimmediate_operand" "%0")
9864 (match_operand:SI 2 "x86_64_zext_immediate_operand" "Z"))
9866 (set (match_operand:DI 0 "register_operand" "=r")
9867 (any_or:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
9868 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9869 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
9870 "<logic>{l}\t{%2, %k0|%k0, %2}"
9871 [(set_attr "type" "alu")
9872 (set_attr "mode" "SI")])
9874 (define_insn "*<code><mode>_3"
9875 [(set (reg FLAGS_REG)
9876 (compare (any_or:SWI
9877 (match_operand:SWI 1 "nonimmediate_operand" "%0")
9878 (match_operand:SWI 2 "<general_operand>" "<g>"))
9880 (clobber (match_scratch:SWI 0 "=<r>"))]
9881 "ix86_match_ccmode (insn, CCNOmode)
9882 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9883 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
9884 [(set_attr "type" "alu")
9885 (set_attr "mode" "<MODE>")])
9887 (define_insn "*<code>qi_ext<mode>_1"
9888 [(set (zero_extract:SWI248
9889 (match_operand:SWI248 0 "register_operand" "+Q,Q")
9895 (zero_extract:SWI248
9896 (match_operand:SWI248 1 "register_operand" "0,0")
9899 (match_operand:QI 2 "general_operand" "QnBc,m")) 0))
9900 (clobber (reg:CC FLAGS_REG))]
9901 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9902 /* FIXME: without this LRA can't reload this pattern, see PR82524. */
9903 && rtx_equal_p (operands[0], operands[1])"
9904 "<logic>{b}\t{%2, %h0|%h0, %2}"
9905 [(set_attr "isa" "*,nox64")
9906 (set_attr "type" "alu")
9907 (set_attr "mode" "QI")])
9909 (define_insn "*<code>qi_ext<mode>_2"
9910 [(set (zero_extract:SWI248
9911 (match_operand:SWI248 0 "register_operand" "+Q")
9917 (zero_extract:SWI248
9918 (match_operand:SWI248 1 "register_operand" "%0")
9922 (zero_extract:SWI248
9923 (match_operand:SWI248 2 "register_operand" "Q")
9925 (const_int 8)) 0)) 0))
9926 (clobber (reg:CC FLAGS_REG))]
9927 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9928 /* FIXME: without this LRA can't reload this pattern, see PR82524. */
9929 && (rtx_equal_p (operands[0], operands[1])
9930 || rtx_equal_p (operands[0], operands[2]))"
9931 "<logic>{b}\t{%h2, %h0|%h0, %h2}"
9932 [(set_attr "type" "alu")
9933 (set_attr "mode" "QI")])
9935 ;; Convert wide OR instructions with immediate operand to shorter QImode
9936 ;; equivalents when possible.
9937 ;; Don't do the splitting with memory operands, since it introduces risk
9938 ;; of memory mismatch stalls. We may want to do the splitting for optimizing
9939 ;; for size, but that can (should?) be handled by generic code instead.
9941 [(set (match_operand:SWI248 0 "QIreg_operand")
9942 (any_or:SWI248 (match_operand:SWI248 1 "register_operand")
9943 (match_operand:SWI248 2 "const_int_operand")))
9944 (clobber (reg:CC FLAGS_REG))]
9946 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9947 && !(INTVAL (operands[2]) & ~(255 << 8))"
9949 [(set (zero_extract:SI (match_dup 0)
9955 (zero_extract:SI (match_dup 1)
9959 (clobber (reg:CC FLAGS_REG))])]
9961 operands[0] = gen_lowpart (SImode, operands[0]);
9962 operands[1] = gen_lowpart (SImode, operands[1]);
9963 operands[2] = gen_int_mode (INTVAL (operands[2]) >> 8, QImode);
9966 ;; Since OR can be encoded with sign extended immediate, this is only
9967 ;; profitable when 7th bit is set.
9969 [(set (match_operand:SWI248 0 "any_QIreg_operand")
9970 (any_or:SWI248 (match_operand:SWI248 1 "general_operand")
9971 (match_operand:SWI248 2 "const_int_operand")))
9972 (clobber (reg:CC FLAGS_REG))]
9974 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9975 && !(INTVAL (operands[2]) & ~255)
9976 && (INTVAL (operands[2]) & 128)"
9977 [(parallel [(set (strict_low_part (match_dup 0))
9978 (any_or:QI (match_dup 1)
9980 (clobber (reg:CC FLAGS_REG))])]
9982 operands[0] = gen_lowpart (QImode, operands[0]);
9983 operands[1] = gen_lowpart (QImode, operands[1]);
9984 operands[2] = gen_int_mode (INTVAL (operands[2]), QImode);
9987 (define_expand "xorqi_ext_1_cc"
9989 [(set (reg:CCNO FLAGS_REG)
9993 (zero_extract:HI (match_operand:HI 1 "register_operand")
9996 (match_operand:QI 2 "const_int_operand"))
9998 (set (zero_extract:HI (match_operand:HI 0 "register_operand")
10004 (zero_extract:HI (match_dup 1)
10007 (match_dup 2)) 0))])])
10009 (define_insn "*xorqi_ext<mode>_1_cc"
10010 [(set (reg FLAGS_REG)
10014 (zero_extract:SWI248
10015 (match_operand:SWI248 1 "register_operand" "0,0")
10018 (match_operand:QI 2 "general_operand" "QnBc,m"))
10020 (set (zero_extract:SWI248
10021 (match_operand:SWI248 0 "register_operand" "+Q,Q")
10027 (zero_extract:SWI248
10031 (match_dup 2)) 0))]
10032 "ix86_match_ccmode (insn, CCNOmode)
10033 /* FIXME: without this LRA can't reload this pattern, see PR82524. */
10034 && rtx_equal_p (operands[0], operands[1])"
10035 "xor{b}\t{%2, %h0|%h0, %2}"
10036 [(set_attr "isa" "*,nox64")
10037 (set_attr "type" "alu")
10038 (set_attr "mode" "QI")])
10040 ;; Negation instructions
10042 (define_expand "neg<mode>2"
10043 [(set (match_operand:SDWIM 0 "nonimmediate_operand")
10044 (neg:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")))]
10046 "ix86_expand_unary_operator (NEG, <MODE>mode, operands); DONE;")
10048 (define_insn_and_split "*neg<dwi>2_doubleword"
10049 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro")
10050 (neg:<DWI> (match_operand:<DWI> 1 "nonimmediate_operand" "0")))
10051 (clobber (reg:CC FLAGS_REG))]
10052 "ix86_unary_operator_ok (NEG, <DWI>mode, operands)"
10056 [(set (reg:CCZ FLAGS_REG)
10057 (compare:CCZ (neg:DWIH (match_dup 1)) (const_int 0)))
10058 (set (match_dup 0) (neg:DWIH (match_dup 1)))])
10060 [(set (match_dup 2)
10061 (plus:DWIH (plus:DWIH (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
10064 (clobber (reg:CC FLAGS_REG))])
10066 [(set (match_dup 2)
10067 (neg:DWIH (match_dup 2)))
10068 (clobber (reg:CC FLAGS_REG))])]
10069 "split_double_mode (<DWI>mode, &operands[0], 2, &operands[0], &operands[2]);")
10071 (define_insn "*neg<mode>2_1"
10072 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
10073 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")))
10074 (clobber (reg:CC FLAGS_REG))]
10075 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
10076 "neg{<imodesuffix>}\t%0"
10077 [(set_attr "type" "negnot")
10078 (set_attr "mode" "<MODE>")])
10080 (define_insn "*negsi2_1_zext"
10081 [(set (match_operand:DI 0 "register_operand" "=r")
10083 (neg:SI (match_operand:SI 1 "register_operand" "0"))))
10084 (clobber (reg:CC FLAGS_REG))]
10085 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
10087 [(set_attr "type" "negnot")
10088 (set_attr "mode" "SI")])
10090 ;; The problem with neg is that it does not perform (compare x 0),
10091 ;; it really performs (compare 0 x), which leaves us with the zero
10092 ;; flag being the only useful item.
10094 (define_insn "*neg<mode>2_cmpz"
10095 [(set (reg:CCZ FLAGS_REG)
10097 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
10099 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
10100 (neg:SWI (match_dup 1)))]
10101 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
10102 "neg{<imodesuffix>}\t%0"
10103 [(set_attr "type" "negnot")
10104 (set_attr "mode" "<MODE>")])
10106 (define_insn "*negsi2_cmpz_zext"
10107 [(set (reg:CCZ FLAGS_REG)
10109 (neg:SI (match_operand:SI 1 "register_operand" "0"))
10111 (set (match_operand:DI 0 "register_operand" "=r")
10113 (neg:SI (match_dup 1))))]
10114 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
10116 [(set_attr "type" "negnot")
10117 (set_attr "mode" "SI")])
10119 (define_insn "*neg<mode>_ccc"
10120 [(set (reg:CCC FLAGS_REG)
10122 (match_operand:SWI 1 "nonimmediate_operand" "0")
10124 (clobber (match_scratch:SWI 0 "=<r>"))]
10126 "neg{<imodesuffix>}\t%0"
10127 [(set_attr "type" "negnot")
10128 (set_attr "mode" "<MODE>")])
10130 ;; Negate with jump on overflow.
10131 (define_expand "negv<mode>3"
10132 [(parallel [(set (reg:CCO FLAGS_REG)
10133 (ne:CCO (match_operand:SWI 1 "register_operand")
10135 (set (match_operand:SWI 0 "register_operand")
10136 (neg:SWI (match_dup 1)))])
10137 (set (pc) (if_then_else
10138 (eq (reg:CCO FLAGS_REG) (const_int 0))
10139 (label_ref (match_operand 2))
10144 = gen_int_mode (HOST_WIDE_INT_1U << (GET_MODE_BITSIZE (<MODE>mode) - 1),
10148 (define_insn "*negv<mode>3"
10149 [(set (reg:CCO FLAGS_REG)
10150 (ne:CCO (match_operand:SWI 1 "nonimmediate_operand" "0")
10151 (match_operand:SWI 2 "const_int_operand")))
10152 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
10153 (neg:SWI (match_dup 1)))]
10154 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)
10155 && mode_signbit_p (<MODE>mode, operands[2])"
10156 "neg{<imodesuffix>}\t%0"
10157 [(set_attr "type" "negnot")
10158 (set_attr "mode" "<MODE>")])
10160 ;; Special expand pattern to handle integer mode abs
10162 (define_expand "abs<mode>2"
10163 [(set (match_operand:SWI48x 0 "register_operand")
10165 (match_operand:SWI48x 1 "register_operand")))]
10166 "TARGET_EXPAND_ABS"
10168 machine_mode mode = <MODE>mode;
10170 /* Generate rtx abs using abs (x) = (((signed) x >> (W-1)) ^ x) -
10171 ((signed) x >> (W-1)) */
10172 rtx shift_amount = gen_int_mode (GET_MODE_PRECISION (mode) - 1, QImode);
10173 rtx shift_dst = expand_simple_binop (mode, ASHIFTRT, operands[1],
10174 shift_amount, NULL_RTX,
10176 rtx xor_dst = expand_simple_binop (mode, XOR, shift_dst, operands[1],
10177 operands[0], 0, OPTAB_DIRECT);
10178 rtx minus_dst = expand_simple_binop (mode, MINUS, xor_dst, shift_dst,
10179 operands[0], 0, OPTAB_DIRECT);
10180 if (!rtx_equal_p (minus_dst, operands[0]))
10181 emit_move_insn (operands[0], minus_dst);
10185 (define_expand "<code>tf2"
10186 [(set (match_operand:TF 0 "register_operand")
10187 (absneg:TF (match_operand:TF 1 "register_operand")))]
10189 "ix86_expand_fp_absneg_operator (<CODE>, TFmode, operands); DONE;")
10191 (define_insn_and_split "*<code>tf2_1"
10192 [(set (match_operand:TF 0 "register_operand" "=x,x,Yv,Yv")
10194 (match_operand:TF 1 "vector_operand" "0,xBm,Yv,m")))
10195 (use (match_operand:TF 2 "vector_operand" "xBm,0,Yvm,Yv"))]
10198 "&& reload_completed"
10199 [(set (match_dup 0)
10200 (<absneg_op>:TF (match_dup 1) (match_dup 2)))]
10204 if (MEM_P (operands[1]))
10205 std::swap (operands[1], operands[2]);
10209 if (operands_match_p (operands[0], operands[2]))
10210 std::swap (operands[1], operands[2]);
10213 [(set_attr "isa" "noavx,noavx,avx,avx")])
10215 (define_insn_and_split "*nabstf2_1"
10216 [(set (match_operand:TF 0 "register_operand" "=x,x,Yv,Yv")
10219 (match_operand:TF 1 "vector_operand" "0,xBm,Yv,m"))))
10220 (use (match_operand:TF 2 "vector_operand" "xBm,0,Yvm,Yv"))]
10223 "&& reload_completed"
10224 [(set (match_dup 0)
10225 (ior:TF (match_dup 1) (match_dup 2)))]
10229 if (MEM_P (operands[1]))
10230 std::swap (operands[1], operands[2]);
10234 if (operands_match_p (operands[0], operands[2]))
10235 std::swap (operands[1], operands[2]);
10238 [(set_attr "isa" "noavx,noavx,avx,avx")])
10240 (define_expand "<code><mode>2"
10241 [(set (match_operand:X87MODEF 0 "register_operand")
10242 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand")))]
10243 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
10244 "ix86_expand_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
10246 ;; Changing of sign for FP values is doable using integer unit too.
10247 (define_insn "*<code><mode>2_i387_1"
10248 [(set (match_operand:X87MODEF 0 "register_operand" "=f,!r")
10250 (match_operand:X87MODEF 1 "register_operand" "0,0")))
10251 (clobber (reg:CC FLAGS_REG))]
10256 [(set (match_operand:X87MODEF 0 "fp_register_operand")
10257 (absneg:X87MODEF (match_operand:X87MODEF 1 "fp_register_operand")))
10258 (clobber (reg:CC FLAGS_REG))]
10259 "TARGET_80387 && reload_completed"
10260 [(set (match_dup 0) (absneg:X87MODEF (match_dup 1)))])
10263 [(set (match_operand:X87MODEF 0 "general_reg_operand")
10264 (absneg:X87MODEF (match_operand:X87MODEF 1 "general_reg_operand")))
10265 (clobber (reg:CC FLAGS_REG))]
10266 "TARGET_80387 && reload_completed"
10268 "ix86_split_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
10270 (define_insn "*<code><mode>2_1"
10271 [(set (match_operand:MODEF 0 "register_operand" "=x,x,Yv,f,!r")
10273 (match_operand:MODEF 1 "register_operand" "0,x,Yv,0,0")))
10274 (use (match_operand:<ssevecmode> 2 "vector_operand" "xBm,0,Yvm,X,X"))
10275 (clobber (reg:CC FLAGS_REG))]
10276 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
10278 [(set_attr "isa" "noavx,noavx,avx,*,*")
10279 (set (attr "enabled")
10281 (match_test ("SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"))
10283 (eq_attr "alternative" "3,4")
10284 (symbol_ref "TARGET_MIX_SSE_I387")
10285 (const_string "*"))
10287 (eq_attr "alternative" "3,4")
10288 (symbol_ref "true")
10289 (symbol_ref "false"))))])
10292 [(set (match_operand:MODEF 0 "sse_reg_operand")
10294 (match_operand:MODEF 1 "sse_reg_operand")))
10295 (use (match_operand:<ssevecmodef> 2 "vector_operand"))
10296 (clobber (reg:CC FLAGS_REG))]
10297 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
10298 && reload_completed"
10299 [(set (match_dup 0)
10300 (<absneg_op>:<ssevecmodef> (match_dup 1) (match_dup 2)))]
10302 machine_mode mode = <MODE>mode;
10303 machine_mode vmode = <ssevecmodef>mode;
10305 operands[0] = lowpart_subreg (vmode, operands[0], mode);
10306 operands[1] = lowpart_subreg (vmode, operands[1], mode);
10308 if (!TARGET_AVX && operands_match_p (operands[0], operands[2]))
10309 std::swap (operands[1], operands[2]);
10313 [(set (match_operand:MODEF 0 "fp_register_operand")
10314 (absneg:MODEF (match_operand:MODEF 1 "fp_register_operand")))
10315 (use (match_operand 2))
10316 (clobber (reg:CC FLAGS_REG))]
10317 "TARGET_80387 && reload_completed"
10318 [(set (match_dup 0) (absneg:MODEF (match_dup 1)))])
10321 [(set (match_operand:MODEF 0 "general_reg_operand")
10322 (absneg:MODEF (match_operand:MODEF 1 "general_reg_operand")))
10323 (use (match_operand 2))
10324 (clobber (reg:CC FLAGS_REG))]
10325 "TARGET_80387 && reload_completed"
10327 "ix86_split_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
10329 (define_insn_and_split "*nabs<mode>2_1"
10330 [(set (match_operand:MODEF 0 "register_operand" "=x,x,Yv")
10333 (match_operand:MODEF 1 "register_operand" "0,x,Yv"))))
10334 (use (match_operand:<ssevecmode> 2 "vector_operand" "xBm,0,Yvm"))]
10335 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
10337 "&& reload_completed"
10338 [(set (match_dup 0)
10339 (ior:<ssevecmodef> (match_dup 1) (match_dup 2)))]
10341 machine_mode mode = <MODE>mode;
10342 machine_mode vmode = <ssevecmodef>mode;
10344 operands[0] = lowpart_subreg (vmode, operands[0], mode);
10345 operands[1] = lowpart_subreg (vmode, operands[1], mode);
10347 if (!TARGET_AVX && operands_match_p (operands[0], operands[2]))
10348 std::swap (operands[1], operands[2]);
10350 [(set_attr "isa" "noavx,noavx,avx")])
10352 ;; Conditionalize these after reload. If they match before reload, we
10353 ;; lose the clobber and ability to use integer instructions.
10355 (define_insn "*<code><mode>2_i387"
10356 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
10357 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "0")))]
10358 "TARGET_80387 && reload_completed"
10359 "<absneg_mnemonic>"
10360 [(set_attr "type" "fsgn")
10361 (set_attr "mode" "<MODE>")])
10363 ;; Copysign instructions
10365 (define_expand "copysign<mode>3"
10366 [(match_operand:SSEMODEF 0 "register_operand")
10367 (match_operand:SSEMODEF 1 "nonmemory_operand")
10368 (match_operand:SSEMODEF 2 "register_operand")]
10369 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10370 || (TARGET_SSE && (<MODE>mode == TFmode))"
10371 "ix86_expand_copysign (operands); DONE;")
10373 (define_insn_and_split "@copysign<mode>3_const"
10374 [(set (match_operand:SSEMODEF 0 "register_operand" "=Yv")
10376 [(match_operand:<ssevecmodef> 1 "nonimm_or_0_operand" "YvmC")
10377 (match_operand:SSEMODEF 2 "register_operand" "0")
10378 (match_operand:<ssevecmodef> 3 "nonimmediate_operand" "Yvm")]
10380 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10381 || (TARGET_SSE && (<MODE>mode == TFmode))"
10383 "&& reload_completed"
10385 "ix86_split_copysign_const (operands); DONE;")
10387 (define_insn "@copysign<mode>3_var"
10388 [(set (match_operand:SSEMODEF 0 "register_operand" "=Yv,Yv,Yv,Yv,Yv")
10390 [(match_operand:SSEMODEF 2 "register_operand" "Yv,0,0,Yv,Yv")
10391 (match_operand:SSEMODEF 3 "register_operand" "1,1,Yv,1,Yv")
10392 (match_operand:<ssevecmodef> 4
10393 "nonimmediate_operand" "X,Yvm,Yvm,0,0")
10394 (match_operand:<ssevecmodef> 5
10395 "nonimmediate_operand" "0,Yvm,1,Yvm,1")]
10397 (clobber (match_scratch:<ssevecmodef> 1 "=Yv,Yv,Yv,Yv,Yv"))]
10398 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10399 || (TARGET_SSE && (<MODE>mode == TFmode))"
10403 [(set (match_operand:SSEMODEF 0 "register_operand")
10405 [(match_operand:SSEMODEF 2 "register_operand")
10406 (match_operand:SSEMODEF 3 "register_operand")
10407 (match_operand:<ssevecmodef> 4)
10408 (match_operand:<ssevecmodef> 5)]
10410 (clobber (match_scratch:<ssevecmodef> 1))]
10411 "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10412 || (TARGET_SSE && (<MODE>mode == TFmode)))
10413 && reload_completed"
10415 "ix86_split_copysign_var (operands); DONE;")
10417 (define_expand "xorsign<mode>3"
10418 [(match_operand:MODEF 0 "register_operand")
10419 (match_operand:MODEF 1 "register_operand")
10420 (match_operand:MODEF 2 "register_operand")]
10421 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
10422 "ix86_expand_xorsign (operands); DONE;")
10424 (define_insn_and_split "@xorsign<mode>3_1"
10425 [(set (match_operand:MODEF 0 "register_operand" "=Yv")
10427 [(match_operand:MODEF 1 "register_operand" "Yv")
10428 (match_operand:MODEF 2 "register_operand" "0")
10429 (match_operand:<ssevecmode> 3 "nonimmediate_operand" "Yvm")]
10431 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
10433 "&& reload_completed"
10435 "ix86_split_xorsign (operands); DONE;")
10437 ;; One complement instructions
10439 (define_expand "one_cmpl<mode>2"
10440 [(set (match_operand:SWIM1248s 0 "nonimmediate_operand")
10441 (not:SWIM1248s (match_operand:SWIM1248s 1 "nonimmediate_operand")))]
10443 "ix86_expand_unary_operator (NOT, <MODE>mode, operands); DONE;")
10445 (define_insn_and_split "*one_cmpldi2_doubleword"
10446 [(set (match_operand:DI 0 "nonimmediate_operand")
10447 (not:DI (match_operand:DI 1 "nonimmediate_operand")))]
10448 "!TARGET_64BIT && TARGET_STV && TARGET_SSE2
10449 && ix86_unary_operator_ok (NOT, DImode, operands)
10450 && ix86_pre_reload_split ()"
10453 [(set (match_dup 0)
10454 (not:SI (match_dup 1)))
10456 (not:SI (match_dup 3)))]
10457 "split_double_mode (DImode, &operands[0], 2, &operands[0], &operands[2]);")
10459 (define_insn "*one_cmpl<mode>2_1"
10460 [(set (match_operand:SWI248 0 "nonimmediate_operand" "=rm,k")
10461 (not:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "0,k")))]
10462 "ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
10464 not{<imodesuffix>}\t%0
10467 (cond [(eq_attr "alternative" "2")
10468 (if_then_else (eq_attr "mode" "SI,DI")
10469 (const_string "avx512bw")
10470 (const_string "avx512f"))
10472 (const_string "*")))
10473 (set_attr "type" "negnot,msklog")
10474 (set_attr "mode" "<MODE>")])
10476 (define_insn "*one_cmplsi2_1_zext"
10477 [(set (match_operand:DI 0 "register_operand" "=r,k")
10479 (not:SI (match_operand:SI 1 "register_operand" "0,k"))))]
10480 "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
10484 [(set_attr "isa" "x64,avx512bw")
10485 (set_attr "type" "negnot,msklog")
10486 (set_attr "mode" "SI,SI")])
10488 (define_insn "*one_cmplqi2_1"
10489 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,k")
10490 (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,k")))]
10491 "ix86_unary_operator_ok (NOT, QImode, operands)"
10496 [(set_attr "isa" "*,*,avx512f")
10497 (set_attr "type" "negnot,negnot,msklog")
10499 (cond [(eq_attr "alternative" "1")
10500 (const_string "SI")
10501 (and (eq_attr "alternative" "2")
10502 (match_test "!TARGET_AVX512DQ"))
10503 (const_string "HI")
10505 (const_string "QI")))
10506 ;; Potential partial reg stall on alternative 1.
10507 (set (attr "preferred_for_speed")
10508 (cond [(eq_attr "alternative" "1")
10509 (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
10510 (symbol_ref "true")))])
10512 (define_insn "*one_cmpl<mode>2_2"
10513 [(set (reg FLAGS_REG)
10514 (compare (not:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
10516 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
10517 (not:SWI (match_dup 1)))]
10518 "ix86_match_ccmode (insn, CCNOmode)
10519 && ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
10521 [(set_attr "type" "alu1")
10522 (set_attr "mode" "<MODE>")])
10525 [(set (match_operand 0 "flags_reg_operand")
10526 (match_operator 2 "compare_operator"
10527 [(not:SWI (match_operand:SWI 3 "nonimmediate_operand"))
10529 (set (match_operand:SWI 1 "nonimmediate_operand")
10530 (not:SWI (match_dup 3)))]
10531 "ix86_match_ccmode (insn, CCNOmode)"
10532 [(parallel [(set (match_dup 0)
10533 (match_op_dup 2 [(xor:SWI (match_dup 3) (const_int -1))
10536 (xor:SWI (match_dup 3) (const_int -1)))])])
10538 (define_insn "*one_cmplsi2_2_zext"
10539 [(set (reg FLAGS_REG)
10540 (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
10542 (set (match_operand:DI 0 "register_operand" "=r")
10543 (zero_extend:DI (not:SI (match_dup 1))))]
10544 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10545 && ix86_unary_operator_ok (NOT, SImode, operands)"
10547 [(set_attr "type" "alu1")
10548 (set_attr "mode" "SI")])
10551 [(set (match_operand 0 "flags_reg_operand")
10552 (match_operator 2 "compare_operator"
10553 [(not:SI (match_operand:SI 3 "register_operand"))
10555 (set (match_operand:DI 1 "register_operand")
10556 (zero_extend:DI (not:SI (match_dup 3))))]
10557 "ix86_match_ccmode (insn, CCNOmode)"
10558 [(parallel [(set (match_dup 0)
10559 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10562 (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])])
10564 ;; Shift instructions
10566 ;; DImode shifts are implemented using the i386 "shift double" opcode,
10567 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem". If the shift count
10568 ;; is variable, then the count is in %cl and the "imm" operand is dropped
10569 ;; from the assembler input.
10571 ;; This instruction shifts the target reg/mem as usual, but instead of
10572 ;; shifting in zeros, bits are shifted in from reg operand. If the insn
10573 ;; is a left shift double, bits are taken from the high order bits of
10574 ;; reg, else if the insn is a shift right double, bits are taken from the
10575 ;; low order bits of reg. So if %eax is "1234" and %edx is "5678",
10576 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
10578 ;; Since sh[lr]d does not change the `reg' operand, that is done
10579 ;; separately, making all shifts emit pairs of shift double and normal
10580 ;; shift. Since sh[lr]d does not shift more than 31 bits, and we wish to
10581 ;; support a 63 bit shift, each shift where the count is in a reg expands
10582 ;; to a pair of shifts, a branch, a shift by 32 and a label.
10584 ;; If the shift count is a constant, we need never emit more than one
10585 ;; shift pair, instead using moves and sign extension for counts greater
10588 (define_expand "ashl<mode>3"
10589 [(set (match_operand:SDWIM 0 "<shift_operand>")
10590 (ashift:SDWIM (match_operand:SDWIM 1 "<ashl_input_operand>")
10591 (match_operand:QI 2 "nonmemory_operand")))]
10593 "ix86_expand_binary_operator (ASHIFT, <MODE>mode, operands); DONE;")
10595 (define_insn_and_split "*ashl<dwi>3_doubleword_mask"
10596 [(set (match_operand:<DWI> 0 "register_operand")
10598 (match_operand:<DWI> 1 "register_operand")
10601 (match_operand:SI 2 "register_operand" "c")
10602 (match_operand:SI 3 "const_int_operand")) 0)))
10603 (clobber (reg:CC FLAGS_REG))]
10604 "(INTVAL (operands[3]) & (<MODE_SIZE> * BITS_PER_UNIT)) == 0
10605 && ix86_pre_reload_split ()"
10609 [(set (match_dup 6)
10610 (ior:DWIH (ashift:DWIH (match_dup 6) (match_dup 2))
10611 (lshiftrt:DWIH (match_dup 5)
10612 (minus:QI (match_dup 8) (match_dup 2)))))
10613 (clobber (reg:CC FLAGS_REG))])
10615 [(set (match_dup 4)
10616 (ashift:DWIH (match_dup 5) (match_dup 2)))
10617 (clobber (reg:CC FLAGS_REG))])]
10619 split_double_mode (<DWI>mode, &operands[0], 2, &operands[4], &operands[6]);
10621 operands[8] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT);
10623 if ((INTVAL (operands[3]) & ((<MODE_SIZE> * BITS_PER_UNIT) - 1))
10624 != ((<MODE_SIZE> * BITS_PER_UNIT) - 1))
10626 rtx tem = gen_reg_rtx (SImode);
10627 emit_insn (gen_andsi3 (tem, operands[2], operands[3]));
10631 operands[2] = gen_lowpart (QImode, operands[2]);
10633 if (!rtx_equal_p (operands[6], operands[7]))
10634 emit_move_insn (operands[6], operands[7]);
10637 (define_insn_and_split "*ashl<dwi>3_doubleword_mask_1"
10638 [(set (match_operand:<DWI> 0 "register_operand")
10640 (match_operand:<DWI> 1 "register_operand")
10642 (match_operand:QI 2 "register_operand" "c")
10643 (match_operand:QI 3 "const_int_operand"))))
10644 (clobber (reg:CC FLAGS_REG))]
10645 "(INTVAL (operands[3]) & (<MODE_SIZE> * BITS_PER_UNIT)) == 0
10646 && ix86_pre_reload_split ()"
10650 [(set (match_dup 6)
10651 (ior:DWIH (ashift:DWIH (match_dup 6) (match_dup 2))
10652 (lshiftrt:DWIH (match_dup 5)
10653 (minus:QI (match_dup 8) (match_dup 2)))))
10654 (clobber (reg:CC FLAGS_REG))])
10656 [(set (match_dup 4)
10657 (ashift:DWIH (match_dup 5) (match_dup 2)))
10658 (clobber (reg:CC FLAGS_REG))])]
10660 split_double_mode (<DWI>mode, &operands[0], 2, &operands[4], &operands[6]);
10662 operands[8] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT);
10664 if ((INTVAL (operands[3]) & ((<MODE_SIZE> * BITS_PER_UNIT) - 1))
10665 != ((<MODE_SIZE> * BITS_PER_UNIT) - 1))
10667 rtx tem = gen_reg_rtx (QImode);
10668 emit_insn (gen_andqi3 (tem, operands[2], operands[3]));
10672 if (!rtx_equal_p (operands[6], operands[7]))
10673 emit_move_insn (operands[6], operands[7]);
10676 (define_insn "*ashl<mode>3_doubleword"
10677 [(set (match_operand:DWI 0 "register_operand" "=&r")
10678 (ashift:DWI (match_operand:DWI 1 "reg_or_pm1_operand" "0n")
10679 (match_operand:QI 2 "nonmemory_operand" "<S>c")))
10680 (clobber (reg:CC FLAGS_REG))]
10683 [(set_attr "type" "multi")])
10686 [(set (match_operand:DWI 0 "register_operand")
10687 (ashift:DWI (match_operand:DWI 1 "nonmemory_operand")
10688 (match_operand:QI 2 "nonmemory_operand")))
10689 (clobber (reg:CC FLAGS_REG))]
10690 "epilogue_completed"
10692 "ix86_split_ashl (operands, NULL_RTX, <MODE>mode); DONE;")
10694 ;; By default we don't ask for a scratch register, because when DWImode
10695 ;; values are manipulated, registers are already at a premium. But if
10696 ;; we have one handy, we won't turn it away.
10699 [(match_scratch:DWIH 3 "r")
10700 (parallel [(set (match_operand:<DWI> 0 "register_operand")
10702 (match_operand:<DWI> 1 "nonmemory_operand")
10703 (match_operand:QI 2 "nonmemory_operand")))
10704 (clobber (reg:CC FLAGS_REG))])
10708 "ix86_split_ashl (operands, operands[3], <DWI>mode); DONE;")
10710 (define_insn "x86_64_shld"
10711 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
10712 (ior:DI (ashift:DI (match_dup 0)
10713 (match_operand:QI 2 "nonmemory_operand" "Jc"))
10714 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
10715 (minus:QI (const_int 64) (match_dup 2)))))
10716 (clobber (reg:CC FLAGS_REG))]
10718 "shld{q}\t{%s2%1, %0|%0, %1, %2}"
10719 [(set_attr "type" "ishift")
10720 (set_attr "prefix_0f" "1")
10721 (set_attr "mode" "DI")
10722 (set_attr "athlon_decode" "vector")
10723 (set_attr "amdfam10_decode" "vector")
10724 (set_attr "bdver1_decode" "vector")])
10726 (define_insn "x86_shld"
10727 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
10728 (ior:SI (ashift:SI (match_dup 0)
10729 (match_operand:QI 2 "nonmemory_operand" "Ic"))
10730 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
10731 (minus:QI (const_int 32) (match_dup 2)))))
10732 (clobber (reg:CC FLAGS_REG))]
10734 "shld{l}\t{%s2%1, %0|%0, %1, %2}"
10735 [(set_attr "type" "ishift")
10736 (set_attr "prefix_0f" "1")
10737 (set_attr "mode" "SI")
10738 (set_attr "pent_pair" "np")
10739 (set_attr "athlon_decode" "vector")
10740 (set_attr "amdfam10_decode" "vector")
10741 (set_attr "bdver1_decode" "vector")])
10743 (define_expand "@x86_shift<mode>_adj_1"
10744 [(set (reg:CCZ FLAGS_REG)
10745 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand")
10748 (set (match_operand:SWI48 0 "register_operand")
10749 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
10750 (match_operand:SWI48 1 "register_operand")
10753 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
10754 (match_operand:SWI48 3 "register_operand")
10757 "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
10759 (define_expand "@x86_shift<mode>_adj_2"
10760 [(use (match_operand:SWI48 0 "register_operand"))
10761 (use (match_operand:SWI48 1 "register_operand"))
10762 (use (match_operand:QI 2 "register_operand"))]
10765 rtx_code_label *label = gen_label_rtx ();
10768 emit_insn (gen_testqi_ccz_1 (operands[2],
10769 GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
10771 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
10772 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
10773 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
10774 gen_rtx_LABEL_REF (VOIDmode, label),
10776 tmp = emit_jump_insn (gen_rtx_SET (pc_rtx, tmp));
10777 JUMP_LABEL (tmp) = label;
10779 emit_move_insn (operands[0], operands[1]);
10780 ix86_expand_clear (operands[1]);
10782 emit_label (label);
10783 LABEL_NUSES (label) = 1;
10788 ;; Avoid useless masking of count operand.
10789 (define_insn_and_split "*ashl<mode>3_mask"
10790 [(set (match_operand:SWI48 0 "nonimmediate_operand")
10792 (match_operand:SWI48 1 "nonimmediate_operand")
10795 (match_operand:SI 2 "register_operand" "c,r")
10796 (match_operand:SI 3 "const_int_operand")) 0)))
10797 (clobber (reg:CC FLAGS_REG))]
10798 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)
10799 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10800 == GET_MODE_BITSIZE (<MODE>mode)-1
10801 && ix86_pre_reload_split ()"
10805 [(set (match_dup 0)
10806 (ashift:SWI48 (match_dup 1)
10808 (clobber (reg:CC FLAGS_REG))])]
10809 "operands[2] = gen_lowpart (QImode, operands[2]);"
10810 [(set_attr "isa" "*,bmi2")])
10812 (define_insn_and_split "*ashl<mode>3_mask_1"
10813 [(set (match_operand:SWI48 0 "nonimmediate_operand")
10815 (match_operand:SWI48 1 "nonimmediate_operand")
10817 (match_operand:QI 2 "register_operand" "c,r")
10818 (match_operand:QI 3 "const_int_operand"))))
10819 (clobber (reg:CC FLAGS_REG))]
10820 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)
10821 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10822 == GET_MODE_BITSIZE (<MODE>mode)-1
10823 && ix86_pre_reload_split ()"
10827 [(set (match_dup 0)
10828 (ashift:SWI48 (match_dup 1)
10830 (clobber (reg:CC FLAGS_REG))])]
10832 [(set_attr "isa" "*,bmi2")])
10834 (define_insn "*bmi2_ashl<mode>3_1"
10835 [(set (match_operand:SWI48 0 "register_operand" "=r")
10836 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
10837 (match_operand:SWI48 2 "register_operand" "r")))]
10839 "shlx\t{%2, %1, %0|%0, %1, %2}"
10840 [(set_attr "type" "ishiftx")
10841 (set_attr "mode" "<MODE>")])
10843 (define_insn "*ashl<mode>3_1"
10844 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r,r")
10845 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,l,rm")
10846 (match_operand:QI 2 "nonmemory_operand" "c<S>,M,r")))
10847 (clobber (reg:CC FLAGS_REG))]
10848 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
10850 switch (get_attr_type (insn))
10857 gcc_assert (operands[2] == const1_rtx);
10858 gcc_assert (rtx_equal_p (operands[0], operands[1]));
10859 return "add{<imodesuffix>}\t%0, %0";
10862 if (operands[2] == const1_rtx
10863 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10864 return "sal{<imodesuffix>}\t%0";
10866 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
10869 [(set_attr "isa" "*,*,bmi2")
10871 (cond [(eq_attr "alternative" "1")
10872 (const_string "lea")
10873 (eq_attr "alternative" "2")
10874 (const_string "ishiftx")
10875 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
10876 (match_operand 0 "register_operand"))
10877 (match_operand 2 "const1_operand"))
10878 (const_string "alu")
10880 (const_string "ishift")))
10881 (set (attr "length_immediate")
10883 (ior (eq_attr "type" "alu")
10884 (and (eq_attr "type" "ishift")
10885 (and (match_operand 2 "const1_operand")
10886 (ior (match_test "TARGET_SHIFT1")
10887 (match_test "optimize_function_for_size_p (cfun)")))))
10889 (const_string "*")))
10890 (set_attr "mode" "<MODE>")])
10892 ;; Convert shift to the shiftx pattern to avoid flags dependency.
10894 [(set (match_operand:SWI48 0 "register_operand")
10895 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
10896 (match_operand:QI 2 "register_operand")))
10897 (clobber (reg:CC FLAGS_REG))]
10898 "TARGET_BMI2 && reload_completed"
10899 [(set (match_dup 0)
10900 (ashift:SWI48 (match_dup 1) (match_dup 2)))]
10901 "operands[2] = gen_lowpart (<MODE>mode, operands[2]);")
10903 (define_insn "*bmi2_ashlsi3_1_zext"
10904 [(set (match_operand:DI 0 "register_operand" "=r")
10906 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
10907 (match_operand:SI 2 "register_operand" "r"))))]
10908 "TARGET_64BIT && TARGET_BMI2"
10909 "shlx\t{%2, %1, %k0|%k0, %1, %2}"
10910 [(set_attr "type" "ishiftx")
10911 (set_attr "mode" "SI")])
10913 (define_insn "*ashlsi3_1_zext"
10914 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
10916 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l,rm")
10917 (match_operand:QI 2 "nonmemory_operand" "cI,M,r"))))
10918 (clobber (reg:CC FLAGS_REG))]
10919 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10921 switch (get_attr_type (insn))
10928 gcc_assert (operands[2] == const1_rtx);
10929 return "add{l}\t%k0, %k0";
10932 if (operands[2] == const1_rtx
10933 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10934 return "sal{l}\t%k0";
10936 return "sal{l}\t{%2, %k0|%k0, %2}";
10939 [(set_attr "isa" "*,*,bmi2")
10941 (cond [(eq_attr "alternative" "1")
10942 (const_string "lea")
10943 (eq_attr "alternative" "2")
10944 (const_string "ishiftx")
10945 (and (match_test "TARGET_DOUBLE_WITH_ADD")
10946 (match_operand 2 "const1_operand"))
10947 (const_string "alu")
10949 (const_string "ishift")))
10950 (set (attr "length_immediate")
10952 (ior (eq_attr "type" "alu")
10953 (and (eq_attr "type" "ishift")
10954 (and (match_operand 2 "const1_operand")
10955 (ior (match_test "TARGET_SHIFT1")
10956 (match_test "optimize_function_for_size_p (cfun)")))))
10958 (const_string "*")))
10959 (set_attr "mode" "SI")])
10961 ;; Convert shift to the shiftx pattern to avoid flags dependency.
10963 [(set (match_operand:DI 0 "register_operand")
10965 (ashift:SI (match_operand:SI 1 "nonimmediate_operand")
10966 (match_operand:QI 2 "register_operand"))))
10967 (clobber (reg:CC FLAGS_REG))]
10968 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
10969 [(set (match_dup 0)
10970 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
10971 "operands[2] = gen_lowpart (SImode, operands[2]);")
10973 (define_insn "*ashlhi3_1"
10974 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,Yp")
10975 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
10976 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10977 (clobber (reg:CC FLAGS_REG))]
10978 "ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10980 switch (get_attr_type (insn))
10986 gcc_assert (operands[2] == const1_rtx);
10987 return "add{w}\t%0, %0";
10990 if (operands[2] == const1_rtx
10991 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10992 return "sal{w}\t%0";
10994 return "sal{w}\t{%2, %0|%0, %2}";
10997 [(set (attr "type")
10998 (cond [(eq_attr "alternative" "1")
10999 (const_string "lea")
11000 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
11001 (match_operand 0 "register_operand"))
11002 (match_operand 2 "const1_operand"))
11003 (const_string "alu")
11005 (const_string "ishift")))
11006 (set (attr "length_immediate")
11008 (ior (eq_attr "type" "alu")
11009 (and (eq_attr "type" "ishift")
11010 (and (match_operand 2 "const1_operand")
11011 (ior (match_test "TARGET_SHIFT1")
11012 (match_test "optimize_function_for_size_p (cfun)")))))
11014 (const_string "*")))
11015 (set_attr "mode" "HI,SI")])
11017 (define_insn "*ashlqi3_1"
11018 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,Yp")
11019 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
11020 (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
11021 (clobber (reg:CC FLAGS_REG))]
11022 "ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11024 switch (get_attr_type (insn))
11030 gcc_assert (operands[2] == const1_rtx);
11031 if (REG_P (operands[1]) && !ANY_QI_REGNO_P (REGNO (operands[1])))
11032 return "add{l}\t%k0, %k0";
11034 return "add{b}\t%0, %0";
11037 if (operands[2] == const1_rtx
11038 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11040 if (get_attr_mode (insn) == MODE_SI)
11041 return "sal{l}\t%k0";
11043 return "sal{b}\t%0";
11047 if (get_attr_mode (insn) == MODE_SI)
11048 return "sal{l}\t{%2, %k0|%k0, %2}";
11050 return "sal{b}\t{%2, %0|%0, %2}";
11054 [(set (attr "type")
11055 (cond [(eq_attr "alternative" "2")
11056 (const_string "lea")
11057 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
11058 (match_operand 0 "register_operand"))
11059 (match_operand 2 "const1_operand"))
11060 (const_string "alu")
11062 (const_string "ishift")))
11063 (set (attr "length_immediate")
11065 (ior (eq_attr "type" "alu")
11066 (and (eq_attr "type" "ishift")
11067 (and (match_operand 2 "const1_operand")
11068 (ior (match_test "TARGET_SHIFT1")
11069 (match_test "optimize_function_for_size_p (cfun)")))))
11071 (const_string "*")))
11072 (set_attr "mode" "QI,SI,SI")
11073 ;; Potential partial reg stall on alternative 1.
11074 (set (attr "preferred_for_speed")
11075 (cond [(eq_attr "alternative" "1")
11076 (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
11077 (symbol_ref "true")))])
11079 (define_insn "*ashl<mode>3_1_slp"
11080 [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>"))
11081 (ashift:SWI12 (match_operand:SWI12 1 "register_operand" "0")
11082 (match_operand:QI 2 "nonmemory_operand" "cI")))
11083 (clobber (reg:CC FLAGS_REG))]
11084 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
11085 /* FIXME: without this LRA can't reload this pattern, see PR82524. */
11086 && rtx_equal_p (operands[0], operands[1])"
11088 switch (get_attr_type (insn))
11091 gcc_assert (operands[2] == const1_rtx);
11092 return "add{<imodesuffix>}\t%0, %0";
11095 if (operands[2] == const1_rtx
11096 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11097 return "sal{<imodesuffix>}\t%0";
11099 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
11102 [(set (attr "type")
11103 (cond [(and (match_test "TARGET_DOUBLE_WITH_ADD")
11104 (match_operand 2 "const1_operand"))
11105 (const_string "alu")
11107 (const_string "ishift")))
11108 (set (attr "length_immediate")
11110 (ior (eq_attr "type" "alu")
11111 (and (eq_attr "type" "ishift")
11112 (and (match_operand 2 "const1_operand")
11113 (ior (match_test "TARGET_SHIFT1")
11114 (match_test "optimize_function_for_size_p (cfun)")))))
11116 (const_string "*")))
11117 (set_attr "mode" "<MODE>")])
11119 ;; Convert ashift to the lea pattern to avoid flags dependency.
11121 [(set (match_operand:SWI 0 "register_operand")
11122 (ashift:SWI (match_operand:SWI 1 "index_register_operand")
11123 (match_operand 2 "const_0_to_3_operand")))
11124 (clobber (reg:CC FLAGS_REG))]
11126 && REGNO (operands[0]) != REGNO (operands[1])"
11127 [(set (match_dup 0)
11128 (mult:<LEAMODE> (match_dup 1) (match_dup 2)))]
11130 if (<MODE>mode != <LEAMODE>mode)
11132 operands[0] = gen_lowpart (<LEAMODE>mode, operands[0]);
11133 operands[1] = gen_lowpart (<LEAMODE>mode, operands[1]);
11135 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
11138 ;; Convert ashift to the lea pattern to avoid flags dependency.
11140 [(set (match_operand:DI 0 "register_operand")
11142 (ashift:SI (match_operand:SI 1 "index_register_operand")
11143 (match_operand 2 "const_0_to_3_operand"))))
11144 (clobber (reg:CC FLAGS_REG))]
11145 "TARGET_64BIT && reload_completed
11146 && REGNO (operands[0]) != REGNO (operands[1])"
11147 [(set (match_dup 0)
11148 (zero_extend:DI (mult:SI (match_dup 1) (match_dup 2))))]
11150 operands[1] = gen_lowpart (SImode, operands[1]);
11151 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
11154 ;; This pattern can't accept a variable shift count, since shifts by
11155 ;; zero don't affect the flags. We assume that shifts by constant
11156 ;; zero are optimized away.
11157 (define_insn "*ashl<mode>3_cmp"
11158 [(set (reg FLAGS_REG)
11160 (ashift:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
11161 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
11163 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
11164 (ashift:SWI (match_dup 1) (match_dup 2)))]
11165 "(optimize_function_for_size_p (cfun)
11166 || !TARGET_PARTIAL_FLAG_REG_STALL
11167 || (operands[2] == const1_rtx
11169 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
11170 && ix86_match_ccmode (insn, CCGOCmode)
11171 && ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
11173 switch (get_attr_type (insn))
11176 gcc_assert (operands[2] == const1_rtx);
11177 return "add{<imodesuffix>}\t%0, %0";
11180 if (operands[2] == const1_rtx
11181 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11182 return "sal{<imodesuffix>}\t%0";
11184 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
11187 [(set (attr "type")
11188 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
11189 (match_operand 0 "register_operand"))
11190 (match_operand 2 "const1_operand"))
11191 (const_string "alu")
11193 (const_string "ishift")))
11194 (set (attr "length_immediate")
11196 (ior (eq_attr "type" "alu")
11197 (and (eq_attr "type" "ishift")
11198 (and (match_operand 2 "const1_operand")
11199 (ior (match_test "TARGET_SHIFT1")
11200 (match_test "optimize_function_for_size_p (cfun)")))))
11202 (const_string "*")))
11203 (set_attr "mode" "<MODE>")])
11205 (define_insn "*ashlsi3_cmp_zext"
11206 [(set (reg FLAGS_REG)
11208 (ashift:SI (match_operand:SI 1 "register_operand" "0")
11209 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11211 (set (match_operand:DI 0 "register_operand" "=r")
11212 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
11214 && (optimize_function_for_size_p (cfun)
11215 || !TARGET_PARTIAL_FLAG_REG_STALL
11216 || (operands[2] == const1_rtx
11218 || TARGET_DOUBLE_WITH_ADD)))
11219 && ix86_match_ccmode (insn, CCGOCmode)
11220 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11222 switch (get_attr_type (insn))
11225 gcc_assert (operands[2] == const1_rtx);
11226 return "add{l}\t%k0, %k0";
11229 if (operands[2] == const1_rtx
11230 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11231 return "sal{l}\t%k0";
11233 return "sal{l}\t{%2, %k0|%k0, %2}";
11236 [(set (attr "type")
11237 (cond [(and (match_test "TARGET_DOUBLE_WITH_ADD")
11238 (match_operand 2 "const1_operand"))
11239 (const_string "alu")
11241 (const_string "ishift")))
11242 (set (attr "length_immediate")
11244 (ior (eq_attr "type" "alu")
11245 (and (eq_attr "type" "ishift")
11246 (and (match_operand 2 "const1_operand")
11247 (ior (match_test "TARGET_SHIFT1")
11248 (match_test "optimize_function_for_size_p (cfun)")))))
11250 (const_string "*")))
11251 (set_attr "mode" "SI")])
11253 (define_insn "*ashl<mode>3_cconly"
11254 [(set (reg FLAGS_REG)
11256 (ashift:SWI (match_operand:SWI 1 "register_operand" "0")
11257 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
11259 (clobber (match_scratch:SWI 0 "=<r>"))]
11260 "(optimize_function_for_size_p (cfun)
11261 || !TARGET_PARTIAL_FLAG_REG_STALL
11262 || (operands[2] == const1_rtx
11264 || TARGET_DOUBLE_WITH_ADD)))
11265 && ix86_match_ccmode (insn, CCGOCmode)"
11267 switch (get_attr_type (insn))
11270 gcc_assert (operands[2] == const1_rtx);
11271 return "add{<imodesuffix>}\t%0, %0";
11274 if (operands[2] == const1_rtx
11275 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11276 return "sal{<imodesuffix>}\t%0";
11278 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
11281 [(set (attr "type")
11282 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
11283 (match_operand 0 "register_operand"))
11284 (match_operand 2 "const1_operand"))
11285 (const_string "alu")
11287 (const_string "ishift")))
11288 (set (attr "length_immediate")
11290 (ior (eq_attr "type" "alu")
11291 (and (eq_attr "type" "ishift")
11292 (and (match_operand 2 "const1_operand")
11293 (ior (match_test "TARGET_SHIFT1")
11294 (match_test "optimize_function_for_size_p (cfun)")))))
11296 (const_string "*")))
11297 (set_attr "mode" "<MODE>")])
11299 ;; See comment above `ashl<mode>3' about how this works.
11301 (define_expand "<shift_insn><mode>3"
11302 [(set (match_operand:SDWIM 0 "<shift_operand>")
11303 (any_shiftrt:SDWIM (match_operand:SDWIM 1 "<shift_operand>")
11304 (match_operand:QI 2 "nonmemory_operand")))]
11306 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
11308 ;; Avoid useless masking of count operand.
11309 (define_insn_and_split "*<shift_insn><mode>3_mask"
11310 [(set (match_operand:SWI48 0 "nonimmediate_operand")
11312 (match_operand:SWI48 1 "nonimmediate_operand")
11315 (match_operand:SI 2 "register_operand" "c,r")
11316 (match_operand:SI 3 "const_int_operand")) 0)))
11317 (clobber (reg:CC FLAGS_REG))]
11318 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
11319 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
11320 == GET_MODE_BITSIZE (<MODE>mode)-1
11321 && ix86_pre_reload_split ()"
11325 [(set (match_dup 0)
11326 (any_shiftrt:SWI48 (match_dup 1)
11328 (clobber (reg:CC FLAGS_REG))])]
11329 "operands[2] = gen_lowpart (QImode, operands[2]);"
11330 [(set_attr "isa" "*,bmi2")])
11332 (define_insn_and_split "*<shift_insn><mode>3_mask_1"
11333 [(set (match_operand:SWI48 0 "nonimmediate_operand")
11335 (match_operand:SWI48 1 "nonimmediate_operand")
11337 (match_operand:QI 2 "register_operand" "c,r")
11338 (match_operand:QI 3 "const_int_operand"))))
11339 (clobber (reg:CC FLAGS_REG))]
11340 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
11341 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
11342 == GET_MODE_BITSIZE (<MODE>mode)-1
11343 && ix86_pre_reload_split ()"
11347 [(set (match_dup 0)
11348 (any_shiftrt:SWI48 (match_dup 1)
11350 (clobber (reg:CC FLAGS_REG))])]
11352 [(set_attr "isa" "*,bmi2")])
11354 (define_insn_and_split "*<shift_insn><dwi>3_doubleword_mask"
11355 [(set (match_operand:<DWI> 0 "register_operand")
11357 (match_operand:<DWI> 1 "register_operand")
11360 (match_operand:SI 2 "register_operand" "c")
11361 (match_operand:SI 3 "const_int_operand")) 0)))
11362 (clobber (reg:CC FLAGS_REG))]
11363 "(INTVAL (operands[3]) & (<MODE_SIZE> * BITS_PER_UNIT)) == 0
11364 && ix86_pre_reload_split ()"
11368 [(set (match_dup 4)
11369 (ior:DWIH (lshiftrt:DWIH (match_dup 4) (match_dup 2))
11370 (ashift:DWIH (match_dup 7)
11371 (minus:QI (match_dup 8) (match_dup 2)))))
11372 (clobber (reg:CC FLAGS_REG))])
11374 [(set (match_dup 6)
11375 (any_shiftrt:DWIH (match_dup 7) (match_dup 2)))
11376 (clobber (reg:CC FLAGS_REG))])]
11378 split_double_mode (<DWI>mode, &operands[0], 2, &operands[4], &operands[6]);
11380 operands[8] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT);
11382 if ((INTVAL (operands[3]) & ((<MODE_SIZE> * BITS_PER_UNIT) - 1))
11383 != ((<MODE_SIZE> * BITS_PER_UNIT) - 1))
11385 rtx tem = gen_reg_rtx (SImode);
11386 emit_insn (gen_andsi3 (tem, operands[2], operands[3]));
11390 operands[2] = gen_lowpart (QImode, operands[2]);
11392 if (!rtx_equal_p (operands[4], operands[5]))
11393 emit_move_insn (operands[4], operands[5]);
11396 (define_insn_and_split "*<shift_insn><dwi>3_doubleword_mask_1"
11397 [(set (match_operand:<DWI> 0 "register_operand")
11399 (match_operand:<DWI> 1 "register_operand")
11401 (match_operand:QI 2 "register_operand" "c")
11402 (match_operand:QI 3 "const_int_operand"))))
11403 (clobber (reg:CC FLAGS_REG))]
11404 "(INTVAL (operands[3]) & (<MODE_SIZE> * BITS_PER_UNIT)) == 0
11405 && ix86_pre_reload_split ()"
11409 [(set (match_dup 4)
11410 (ior:DWIH (lshiftrt:DWIH (match_dup 4) (match_dup 2))
11411 (ashift:DWIH (match_dup 7)
11412 (minus:QI (match_dup 8) (match_dup 2)))))
11413 (clobber (reg:CC FLAGS_REG))])
11415 [(set (match_dup 6)
11416 (any_shiftrt:DWIH (match_dup 7) (match_dup 2)))
11417 (clobber (reg:CC FLAGS_REG))])]
11419 split_double_mode (<DWI>mode, &operands[0], 2, &operands[4], &operands[6]);
11421 operands[8] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT);
11423 if ((INTVAL (operands[3]) & ((<MODE_SIZE> * BITS_PER_UNIT) - 1))
11424 != ((<MODE_SIZE> * BITS_PER_UNIT) - 1))
11426 rtx tem = gen_reg_rtx (QImode);
11427 emit_insn (gen_andqi3 (tem, operands[2], operands[3]));
11431 if (!rtx_equal_p (operands[4], operands[5]))
11432 emit_move_insn (operands[4], operands[5]);
11435 (define_insn_and_split "*<shift_insn><mode>3_doubleword"
11436 [(set (match_operand:DWI 0 "register_operand" "=&r")
11437 (any_shiftrt:DWI (match_operand:DWI 1 "register_operand" "0")
11438 (match_operand:QI 2 "nonmemory_operand" "<S>c")))
11439 (clobber (reg:CC FLAGS_REG))]
11442 "epilogue_completed"
11444 "ix86_split_<shift_insn> (operands, NULL_RTX, <MODE>mode); DONE;"
11445 [(set_attr "type" "multi")])
11447 ;; By default we don't ask for a scratch register, because when DWImode
11448 ;; values are manipulated, registers are already at a premium. But if
11449 ;; we have one handy, we won't turn it away.
11452 [(match_scratch:DWIH 3 "r")
11453 (parallel [(set (match_operand:<DWI> 0 "register_operand")
11455 (match_operand:<DWI> 1 "register_operand")
11456 (match_operand:QI 2 "nonmemory_operand")))
11457 (clobber (reg:CC FLAGS_REG))])
11461 "ix86_split_<shift_insn> (operands, operands[3], <DWI>mode); DONE;")
11463 (define_insn "x86_64_shrd"
11464 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
11465 (ior:DI (lshiftrt:DI (match_dup 0)
11466 (match_operand:QI 2 "nonmemory_operand" "Jc"))
11467 (ashift:DI (match_operand:DI 1 "register_operand" "r")
11468 (minus:QI (const_int 64) (match_dup 2)))))
11469 (clobber (reg:CC FLAGS_REG))]
11471 "shrd{q}\t{%s2%1, %0|%0, %1, %2}"
11472 [(set_attr "type" "ishift")
11473 (set_attr "prefix_0f" "1")
11474 (set_attr "mode" "DI")
11475 (set_attr "athlon_decode" "vector")
11476 (set_attr "amdfam10_decode" "vector")
11477 (set_attr "bdver1_decode" "vector")])
11479 (define_insn "x86_shrd"
11480 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
11481 (ior:SI (lshiftrt:SI (match_dup 0)
11482 (match_operand:QI 2 "nonmemory_operand" "Ic"))
11483 (ashift:SI (match_operand:SI 1 "register_operand" "r")
11484 (minus:QI (const_int 32) (match_dup 2)))))
11485 (clobber (reg:CC FLAGS_REG))]
11487 "shrd{l}\t{%s2%1, %0|%0, %1, %2}"
11488 [(set_attr "type" "ishift")
11489 (set_attr "prefix_0f" "1")
11490 (set_attr "mode" "SI")
11491 (set_attr "pent_pair" "np")
11492 (set_attr "athlon_decode" "vector")
11493 (set_attr "amdfam10_decode" "vector")
11494 (set_attr "bdver1_decode" "vector")])
11496 ;; Base name for insn mnemonic.
11497 (define_mode_attr cvt_mnemonic
11498 [(SI "{cltd|cdq}") (DI "{cqto|cqo}")])
11500 (define_insn "ashr<mode>3_cvt"
11501 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=*d,rm")
11503 (match_operand:SWI48 1 "nonimmediate_operand" "*a,0")
11504 (match_operand:QI 2 "const_int_operand")))
11505 (clobber (reg:CC FLAGS_REG))]
11506 "INTVAL (operands[2]) == GET_MODE_BITSIZE (<MODE>mode)-1
11507 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
11508 && ix86_binary_operator_ok (ASHIFTRT, <MODE>mode, operands)"
11511 sar{<imodesuffix>}\t{%2, %0|%0, %2}"
11512 [(set_attr "type" "imovx,ishift")
11513 (set_attr "prefix_0f" "0,*")
11514 (set_attr "length_immediate" "0,*")
11515 (set_attr "modrm" "0,1")
11516 (set_attr "mode" "<MODE>")])
11518 (define_insn "*ashrsi3_cvt_zext"
11519 [(set (match_operand:DI 0 "register_operand" "=*d,r")
11521 (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
11522 (match_operand:QI 2 "const_int_operand"))))
11523 (clobber (reg:CC FLAGS_REG))]
11524 "TARGET_64BIT && INTVAL (operands[2]) == 31
11525 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
11526 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11529 sar{l}\t{%2, %k0|%k0, %2}"
11530 [(set_attr "type" "imovx,ishift")
11531 (set_attr "prefix_0f" "0,*")
11532 (set_attr "length_immediate" "0,*")
11533 (set_attr "modrm" "0,1")
11534 (set_attr "mode" "SI")])
11536 (define_expand "@x86_shift<mode>_adj_3"
11537 [(use (match_operand:SWI48 0 "register_operand"))
11538 (use (match_operand:SWI48 1 "register_operand"))
11539 (use (match_operand:QI 2 "register_operand"))]
11542 rtx_code_label *label = gen_label_rtx ();
11545 emit_insn (gen_testqi_ccz_1 (operands[2],
11546 GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
11548 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
11549 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
11550 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
11551 gen_rtx_LABEL_REF (VOIDmode, label),
11553 tmp = emit_jump_insn (gen_rtx_SET (pc_rtx, tmp));
11554 JUMP_LABEL (tmp) = label;
11556 emit_move_insn (operands[0], operands[1]);
11557 emit_insn (gen_ashr<mode>3_cvt (operands[1], operands[1],
11558 GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1)));
11559 emit_label (label);
11560 LABEL_NUSES (label) = 1;
11565 (define_insn "*bmi2_<shift_insn><mode>3_1"
11566 [(set (match_operand:SWI48 0 "register_operand" "=r")
11567 (any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11568 (match_operand:SWI48 2 "register_operand" "r")))]
11570 "<shift>x\t{%2, %1, %0|%0, %1, %2}"
11571 [(set_attr "type" "ishiftx")
11572 (set_attr "mode" "<MODE>")])
11574 (define_insn "*<shift_insn><mode>3_1"
11575 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
11577 (match_operand:SWI48 1 "nonimmediate_operand" "0,rm")
11578 (match_operand:QI 2 "nonmemory_operand" "c<S>,r")))
11579 (clobber (reg:CC FLAGS_REG))]
11580 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
11582 switch (get_attr_type (insn))
11588 if (operands[2] == const1_rtx
11589 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11590 return "<shift>{<imodesuffix>}\t%0";
11592 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
11595 [(set_attr "isa" "*,bmi2")
11596 (set_attr "type" "ishift,ishiftx")
11597 (set (attr "length_immediate")
11599 (and (match_operand 2 "const1_operand")
11600 (ior (match_test "TARGET_SHIFT1")
11601 (match_test "optimize_function_for_size_p (cfun)")))
11603 (const_string "*")))
11604 (set_attr "mode" "<MODE>")])
11606 ;; Convert shift to the shiftx pattern to avoid flags dependency.
11608 [(set (match_operand:SWI48 0 "register_operand")
11609 (any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
11610 (match_operand:QI 2 "register_operand")))
11611 (clobber (reg:CC FLAGS_REG))]
11612 "TARGET_BMI2 && reload_completed"
11613 [(set (match_dup 0)
11614 (any_shiftrt:SWI48 (match_dup 1) (match_dup 2)))]
11615 "operands[2] = gen_lowpart (<MODE>mode, operands[2]);")
11617 (define_insn "*bmi2_<shift_insn>si3_1_zext"
11618 [(set (match_operand:DI 0 "register_operand" "=r")
11620 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
11621 (match_operand:SI 2 "register_operand" "r"))))]
11622 "TARGET_64BIT && TARGET_BMI2"
11623 "<shift>x\t{%2, %1, %k0|%k0, %1, %2}"
11624 [(set_attr "type" "ishiftx")
11625 (set_attr "mode" "SI")])
11627 (define_insn "*<shift_insn>si3_1_zext"
11628 [(set (match_operand:DI 0 "register_operand" "=r,r")
11630 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm")
11631 (match_operand:QI 2 "nonmemory_operand" "cI,r"))))
11632 (clobber (reg:CC FLAGS_REG))]
11633 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
11635 switch (get_attr_type (insn))
11641 if (operands[2] == const1_rtx
11642 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11643 return "<shift>{l}\t%k0";
11645 return "<shift>{l}\t{%2, %k0|%k0, %2}";
11648 [(set_attr "isa" "*,bmi2")
11649 (set_attr "type" "ishift,ishiftx")
11650 (set (attr "length_immediate")
11652 (and (match_operand 2 "const1_operand")
11653 (ior (match_test "TARGET_SHIFT1")
11654 (match_test "optimize_function_for_size_p (cfun)")))
11656 (const_string "*")))
11657 (set_attr "mode" "SI")])
11659 ;; Convert shift to the shiftx pattern to avoid flags dependency.
11661 [(set (match_operand:DI 0 "register_operand")
11663 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand")
11664 (match_operand:QI 2 "register_operand"))))
11665 (clobber (reg:CC FLAGS_REG))]
11666 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
11667 [(set (match_dup 0)
11668 (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
11669 "operands[2] = gen_lowpart (SImode, operands[2]);")
11671 (define_insn "*<shift_insn><mode>3_1"
11672 [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m")
11674 (match_operand:SWI12 1 "nonimmediate_operand" "0")
11675 (match_operand:QI 2 "nonmemory_operand" "c<S>")))
11676 (clobber (reg:CC FLAGS_REG))]
11677 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
11679 if (operands[2] == const1_rtx
11680 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11681 return "<shift>{<imodesuffix>}\t%0";
11683 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
11685 [(set_attr "type" "ishift")
11686 (set (attr "length_immediate")
11688 (and (match_operand 2 "const1_operand")
11689 (ior (match_test "TARGET_SHIFT1")
11690 (match_test "optimize_function_for_size_p (cfun)")))
11692 (const_string "*")))
11693 (set_attr "mode" "<MODE>")])
11695 (define_insn "*<shift_insn><mode>3_1_slp"
11696 [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>"))
11697 (any_shiftrt:SWI12 (match_operand:SWI12 1 "register_operand" "0")
11698 (match_operand:QI 2 "nonmemory_operand" "cI")))
11699 (clobber (reg:CC FLAGS_REG))]
11700 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
11701 /* FIXME: without this LRA can't reload this pattern, see PR82524. */
11702 && rtx_equal_p (operands[0], operands[1])"
11704 if (operands[2] == const1_rtx
11705 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11706 return "<shift>{<imodesuffix>}\t%0";
11708 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
11710 [(set_attr "type" "ishift")
11711 (set (attr "length_immediate")
11713 (and (match_operand 2 "const1_operand")
11714 (ior (match_test "TARGET_SHIFT1")
11715 (match_test "optimize_function_for_size_p (cfun)")))
11717 (const_string "*")))
11718 (set_attr "mode" "<MODE>")])
11720 ;; This pattern can't accept a variable shift count, since shifts by
11721 ;; zero don't affect the flags. We assume that shifts by constant
11722 ;; zero are optimized away.
11723 (define_insn "*<shift_insn><mode>3_cmp"
11724 [(set (reg FLAGS_REG)
11727 (match_operand:SWI 1 "nonimmediate_operand" "0")
11728 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
11730 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
11731 (any_shiftrt:SWI (match_dup 1) (match_dup 2)))]
11732 "(optimize_function_for_size_p (cfun)
11733 || !TARGET_PARTIAL_FLAG_REG_STALL
11734 || (operands[2] == const1_rtx
11736 && ix86_match_ccmode (insn, CCGOCmode)
11737 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
11739 if (operands[2] == const1_rtx
11740 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11741 return "<shift>{<imodesuffix>}\t%0";
11743 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
11745 [(set_attr "type" "ishift")
11746 (set (attr "length_immediate")
11748 (and (match_operand 2 "const1_operand")
11749 (ior (match_test "TARGET_SHIFT1")
11750 (match_test "optimize_function_for_size_p (cfun)")))
11752 (const_string "*")))
11753 (set_attr "mode" "<MODE>")])
11755 (define_insn "*<shift_insn>si3_cmp_zext"
11756 [(set (reg FLAGS_REG)
11758 (any_shiftrt:SI (match_operand:SI 1 "register_operand" "0")
11759 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11761 (set (match_operand:DI 0 "register_operand" "=r")
11762 (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
11764 && (optimize_function_for_size_p (cfun)
11765 || !TARGET_PARTIAL_FLAG_REG_STALL
11766 || (operands[2] == const1_rtx
11768 && ix86_match_ccmode (insn, CCGOCmode)
11769 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
11771 if (operands[2] == const1_rtx
11772 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11773 return "<shift>{l}\t%k0";
11775 return "<shift>{l}\t{%2, %k0|%k0, %2}";
11777 [(set_attr "type" "ishift")
11778 (set (attr "length_immediate")
11780 (and (match_operand 2 "const1_operand")
11781 (ior (match_test "TARGET_SHIFT1")
11782 (match_test "optimize_function_for_size_p (cfun)")))
11784 (const_string "*")))
11785 (set_attr "mode" "SI")])
11787 (define_insn "*<shift_insn><mode>3_cconly"
11788 [(set (reg FLAGS_REG)
11791 (match_operand:SWI 1 "register_operand" "0")
11792 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
11794 (clobber (match_scratch:SWI 0 "=<r>"))]
11795 "(optimize_function_for_size_p (cfun)
11796 || !TARGET_PARTIAL_FLAG_REG_STALL
11797 || (operands[2] == const1_rtx
11799 && ix86_match_ccmode (insn, CCGOCmode)"
11801 if (operands[2] == const1_rtx
11802 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11803 return "<shift>{<imodesuffix>}\t%0";
11805 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
11807 [(set_attr "type" "ishift")
11808 (set (attr "length_immediate")
11810 (and (match_operand 2 "const1_operand")
11811 (ior (match_test "TARGET_SHIFT1")
11812 (match_test "optimize_function_for_size_p (cfun)")))
11814 (const_string "*")))
11815 (set_attr "mode" "<MODE>")])
11817 ;; Rotate instructions
11819 (define_expand "<rotate_insn>ti3"
11820 [(set (match_operand:TI 0 "register_operand")
11821 (any_rotate:TI (match_operand:TI 1 "register_operand")
11822 (match_operand:QI 2 "nonmemory_operand")))]
11825 if (const_1_to_63_operand (operands[2], VOIDmode))
11826 emit_insn (gen_ix86_<rotate_insn>ti3_doubleword
11827 (operands[0], operands[1], operands[2]));
11834 (define_expand "<rotate_insn>di3"
11835 [(set (match_operand:DI 0 "shiftdi_operand")
11836 (any_rotate:DI (match_operand:DI 1 "shiftdi_operand")
11837 (match_operand:QI 2 "nonmemory_operand")))]
11841 ix86_expand_binary_operator (<CODE>, DImode, operands);
11842 else if (const_1_to_31_operand (operands[2], VOIDmode))
11843 emit_insn (gen_ix86_<rotate_insn>di3_doubleword
11844 (operands[0], operands[1], operands[2]));
11851 (define_expand "<rotate_insn><mode>3"
11852 [(set (match_operand:SWIM124 0 "nonimmediate_operand")
11853 (any_rotate:SWIM124 (match_operand:SWIM124 1 "nonimmediate_operand")
11854 (match_operand:QI 2 "nonmemory_operand")))]
11856 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
11858 ;; Avoid useless masking of count operand.
11859 (define_insn_and_split "*<rotate_insn><mode>3_mask"
11860 [(set (match_operand:SWI48 0 "nonimmediate_operand")
11862 (match_operand:SWI48 1 "nonimmediate_operand")
11865 (match_operand:SI 2 "register_operand" "c")
11866 (match_operand:SI 3 "const_int_operand")) 0)))
11867 (clobber (reg:CC FLAGS_REG))]
11868 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
11869 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
11870 == GET_MODE_BITSIZE (<MODE>mode)-1
11871 && ix86_pre_reload_split ()"
11875 [(set (match_dup 0)
11876 (any_rotate:SWI48 (match_dup 1)
11878 (clobber (reg:CC FLAGS_REG))])]
11879 "operands[2] = gen_lowpart (QImode, operands[2]);")
11881 (define_insn_and_split "*<rotate_insn><mode>3_mask_1"
11882 [(set (match_operand:SWI48 0 "nonimmediate_operand")
11884 (match_operand:SWI48 1 "nonimmediate_operand")
11886 (match_operand:QI 2 "register_operand" "c")
11887 (match_operand:QI 3 "const_int_operand"))))
11888 (clobber (reg:CC FLAGS_REG))]
11889 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
11890 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
11891 == GET_MODE_BITSIZE (<MODE>mode)-1
11892 && ix86_pre_reload_split ()"
11896 [(set (match_dup 0)
11897 (any_rotate:SWI48 (match_dup 1)
11899 (clobber (reg:CC FLAGS_REG))])])
11901 ;; Implement rotation using two double-precision
11902 ;; shift instructions and a scratch register.
11904 (define_insn_and_split "ix86_rotl<dwi>3_doubleword"
11905 [(set (match_operand:<DWI> 0 "register_operand" "=r")
11906 (rotate:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
11907 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
11908 (clobber (reg:CC FLAGS_REG))
11909 (clobber (match_scratch:DWIH 3 "=&r"))]
11913 [(set (match_dup 3) (match_dup 4))
11915 [(set (match_dup 4)
11916 (ior:DWIH (ashift:DWIH (match_dup 4) (match_dup 2))
11917 (lshiftrt:DWIH (match_dup 5)
11918 (minus:QI (match_dup 6) (match_dup 2)))))
11919 (clobber (reg:CC FLAGS_REG))])
11921 [(set (match_dup 5)
11922 (ior:DWIH (ashift:DWIH (match_dup 5) (match_dup 2))
11923 (lshiftrt:DWIH (match_dup 3)
11924 (minus:QI (match_dup 6) (match_dup 2)))))
11925 (clobber (reg:CC FLAGS_REG))])]
11927 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
11929 split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
11932 (define_insn_and_split "ix86_rotr<dwi>3_doubleword"
11933 [(set (match_operand:<DWI> 0 "register_operand" "=r")
11934 (rotatert:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
11935 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
11936 (clobber (reg:CC FLAGS_REG))
11937 (clobber (match_scratch:DWIH 3 "=&r"))]
11941 [(set (match_dup 3) (match_dup 4))
11943 [(set (match_dup 4)
11944 (ior:DWIH (lshiftrt:DWIH (match_dup 4) (match_dup 2))
11945 (ashift:DWIH (match_dup 5)
11946 (minus:QI (match_dup 6) (match_dup 2)))))
11947 (clobber (reg:CC FLAGS_REG))])
11949 [(set (match_dup 5)
11950 (ior:DWIH (lshiftrt:DWIH (match_dup 5) (match_dup 2))
11951 (ashift:DWIH (match_dup 3)
11952 (minus:QI (match_dup 6) (match_dup 2)))))
11953 (clobber (reg:CC FLAGS_REG))])]
11955 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
11957 split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
11960 (define_mode_attr rorx_immediate_operand
11961 [(SI "const_0_to_31_operand")
11962 (DI "const_0_to_63_operand")])
11964 (define_insn "*bmi2_rorx<mode>3_1"
11965 [(set (match_operand:SWI48 0 "register_operand" "=r")
11967 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11968 (match_operand:QI 2 "<rorx_immediate_operand>" "<S>")))]
11970 "rorx\t{%2, %1, %0|%0, %1, %2}"
11971 [(set_attr "type" "rotatex")
11972 (set_attr "mode" "<MODE>")])
11974 (define_insn "*<rotate_insn><mode>3_1"
11975 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
11977 (match_operand:SWI48 1 "nonimmediate_operand" "0,rm")
11978 (match_operand:QI 2 "nonmemory_operand" "c<S>,<S>")))
11979 (clobber (reg:CC FLAGS_REG))]
11980 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
11982 switch (get_attr_type (insn))
11988 if (operands[2] == const1_rtx
11989 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11990 return "<rotate>{<imodesuffix>}\t%0";
11992 return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
11995 [(set_attr "isa" "*,bmi2")
11996 (set_attr "type" "rotate,rotatex")
11997 (set (attr "length_immediate")
11999 (and (eq_attr "type" "rotate")
12000 (and (match_operand 2 "const1_operand")
12001 (ior (match_test "TARGET_SHIFT1")
12002 (match_test "optimize_function_for_size_p (cfun)"))))
12004 (const_string "*")))
12005 (set_attr "mode" "<MODE>")])
12007 ;; Convert rotate to the rotatex pattern to avoid flags dependency.
12009 [(set (match_operand:SWI48 0 "register_operand")
12010 (rotate:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
12011 (match_operand:QI 2 "const_int_operand")))
12012 (clobber (reg:CC FLAGS_REG))]
12013 "TARGET_BMI2 && reload_completed"
12014 [(set (match_dup 0)
12015 (rotatert:SWI48 (match_dup 1) (match_dup 2)))]
12017 int bitsize = GET_MODE_BITSIZE (<MODE>mode);
12019 operands[2] = GEN_INT ((bitsize - INTVAL (operands[2])) % bitsize);
12023 [(set (match_operand:SWI48 0 "register_operand")
12024 (rotatert:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
12025 (match_operand:QI 2 "const_int_operand")))
12026 (clobber (reg:CC FLAGS_REG))]
12027 "TARGET_BMI2 && reload_completed"
12028 [(set (match_dup 0)
12029 (rotatert:SWI48 (match_dup 1) (match_dup 2)))])
12031 (define_insn "*bmi2_rorxsi3_1_zext"
12032 [(set (match_operand:DI 0 "register_operand" "=r")
12034 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
12035 (match_operand:QI 2 "const_0_to_31_operand" "I"))))]
12036 "TARGET_64BIT && TARGET_BMI2"
12037 "rorx\t{%2, %1, %k0|%k0, %1, %2}"
12038 [(set_attr "type" "rotatex")
12039 (set_attr "mode" "SI")])
12041 (define_insn "*<rotate_insn>si3_1_zext"
12042 [(set (match_operand:DI 0 "register_operand" "=r,r")
12044 (any_rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm")
12045 (match_operand:QI 2 "nonmemory_operand" "cI,I"))))
12046 (clobber (reg:CC FLAGS_REG))]
12047 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
12049 switch (get_attr_type (insn))
12055 if (operands[2] == const1_rtx
12056 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
12057 return "<rotate>{l}\t%k0";
12059 return "<rotate>{l}\t{%2, %k0|%k0, %2}";
12062 [(set_attr "isa" "*,bmi2")
12063 (set_attr "type" "rotate,rotatex")
12064 (set (attr "length_immediate")
12066 (and (eq_attr "type" "rotate")
12067 (and (match_operand 2 "const1_operand")
12068 (ior (match_test "TARGET_SHIFT1")
12069 (match_test "optimize_function_for_size_p (cfun)"))))
12071 (const_string "*")))
12072 (set_attr "mode" "SI")])
12074 ;; Convert rotate to the rotatex pattern to avoid flags dependency.
12076 [(set (match_operand:DI 0 "register_operand")
12078 (rotate:SI (match_operand:SI 1 "nonimmediate_operand")
12079 (match_operand:QI 2 "const_int_operand"))))
12080 (clobber (reg:CC FLAGS_REG))]
12081 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
12082 [(set (match_dup 0)
12083 (zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))]
12085 int bitsize = GET_MODE_BITSIZE (SImode);
12087 operands[2] = GEN_INT ((bitsize - INTVAL (operands[2])) % bitsize);
12091 [(set (match_operand:DI 0 "register_operand")
12093 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand")
12094 (match_operand:QI 2 "const_int_operand"))))
12095 (clobber (reg:CC FLAGS_REG))]
12096 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
12097 [(set (match_dup 0)
12098 (zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))])
12100 (define_insn "*<rotate_insn><mode>3_1"
12101 [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m")
12102 (any_rotate:SWI12 (match_operand:SWI12 1 "nonimmediate_operand" "0")
12103 (match_operand:QI 2 "nonmemory_operand" "c<S>")))
12104 (clobber (reg:CC FLAGS_REG))]
12105 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
12107 if (operands[2] == const1_rtx
12108 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
12109 return "<rotate>{<imodesuffix>}\t%0";
12111 return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
12113 [(set_attr "type" "rotate")
12114 (set (attr "length_immediate")
12116 (and (match_operand 2 "const1_operand")
12117 (ior (match_test "TARGET_SHIFT1")
12118 (match_test "optimize_function_for_size_p (cfun)")))
12120 (const_string "*")))
12121 (set_attr "mode" "<MODE>")])
12123 (define_insn "*<rotate_insn><mode>3_1_slp"
12124 [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>"))
12125 (any_rotate:SWI12 (match_operand:SWI12 1 "register_operand" "0")
12126 (match_operand:QI 2 "nonmemory_operand" "cI")))
12127 (clobber (reg:CC FLAGS_REG))]
12128 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
12129 /* FIXME: without this LRA can't reload this pattern, see PR82524. */
12130 && rtx_equal_p (operands[0], operands[1])"
12132 if (operands[2] == const1_rtx
12133 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
12134 return "<rotate>{<imodesuffix>}\t%0";
12136 return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
12138 [(set_attr "type" "rotate")
12139 (set (attr "length_immediate")
12141 (and (match_operand 2 "const1_operand")
12142 (ior (match_test "TARGET_SHIFT1")
12143 (match_test "optimize_function_for_size_p (cfun)")))
12145 (const_string "*")))
12146 (set_attr "mode" "<MODE>")])
12149 [(set (match_operand:HI 0 "QIreg_operand")
12150 (any_rotate:HI (match_dup 0) (const_int 8)))
12151 (clobber (reg:CC FLAGS_REG))]
12153 && (TARGET_USE_XCHGB || optimize_function_for_size_p (cfun))"
12154 [(parallel [(set (strict_low_part (match_dup 0))
12155 (bswap:HI (match_dup 0)))
12156 (clobber (reg:CC FLAGS_REG))])])
12158 ;; Bit set / bit test instructions
12160 ;; %%% bts, btr, btc
12162 ;; These instructions are *slow* when applied to memory.
12164 (define_code_attr btsc [(ior "bts") (xor "btc")])
12166 (define_insn "*<btsc><mode>"
12167 [(set (match_operand:SWI48 0 "register_operand" "=r")
12169 (ashift:SWI48 (const_int 1)
12170 (match_operand:QI 2 "register_operand" "r"))
12171 (match_operand:SWI48 1 "register_operand" "0")))
12172 (clobber (reg:CC FLAGS_REG))]
12174 "<btsc>{<imodesuffix>}\t{%<k>2, %0|%0, %<k>2}"
12175 [(set_attr "type" "alu1")
12176 (set_attr "prefix_0f" "1")
12177 (set_attr "znver1_decode" "double")
12178 (set_attr "mode" "<MODE>")])
12180 ;; Avoid useless masking of count operand.
12181 (define_insn_and_split "*<btsc><mode>_mask"
12182 [(set (match_operand:SWI48 0 "register_operand")
12188 (match_operand:SI 1 "register_operand")
12189 (match_operand:SI 2 "const_int_operand")) 0))
12190 (match_operand:SWI48 3 "register_operand")))
12191 (clobber (reg:CC FLAGS_REG))]
12193 && (INTVAL (operands[2]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
12194 == GET_MODE_BITSIZE (<MODE>mode)-1
12195 && ix86_pre_reload_split ()"
12199 [(set (match_dup 0)
12201 (ashift:SWI48 (const_int 1)
12204 (clobber (reg:CC FLAGS_REG))])]
12205 "operands[1] = gen_lowpart (QImode, operands[1]);")
12207 (define_insn_and_split "*<btsc><mode>_mask_1"
12208 [(set (match_operand:SWI48 0 "register_operand")
12213 (match_operand:QI 1 "register_operand")
12214 (match_operand:QI 2 "const_int_operand")))
12215 (match_operand:SWI48 3 "register_operand")))
12216 (clobber (reg:CC FLAGS_REG))]
12218 && (INTVAL (operands[2]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
12219 == GET_MODE_BITSIZE (<MODE>mode)-1
12220 && ix86_pre_reload_split ()"
12224 [(set (match_dup 0)
12226 (ashift:SWI48 (const_int 1)
12229 (clobber (reg:CC FLAGS_REG))])])
12231 (define_insn "*btr<mode>"
12232 [(set (match_operand:SWI48 0 "register_operand" "=r")
12234 (rotate:SWI48 (const_int -2)
12235 (match_operand:QI 2 "register_operand" "r"))
12236 (match_operand:SWI48 1 "register_operand" "0")))
12237 (clobber (reg:CC FLAGS_REG))]
12239 "btr{<imodesuffix>}\t{%<k>2, %0|%0, %<k>2}"
12240 [(set_attr "type" "alu1")
12241 (set_attr "prefix_0f" "1")
12242 (set_attr "znver1_decode" "double")
12243 (set_attr "mode" "<MODE>")])
12245 ;; Avoid useless masking of count operand.
12246 (define_insn_and_split "*btr<mode>_mask"
12247 [(set (match_operand:SWI48 0 "register_operand")
12253 (match_operand:SI 1 "register_operand")
12254 (match_operand:SI 2 "const_int_operand")) 0))
12255 (match_operand:SWI48 3 "register_operand")))
12256 (clobber (reg:CC FLAGS_REG))]
12258 && (INTVAL (operands[2]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
12259 == GET_MODE_BITSIZE (<MODE>mode)-1
12260 && ix86_pre_reload_split ()"
12264 [(set (match_dup 0)
12266 (rotate:SWI48 (const_int -2)
12269 (clobber (reg:CC FLAGS_REG))])]
12270 "operands[1] = gen_lowpart (QImode, operands[1]);")
12272 (define_insn_and_split "*btr<mode>_mask_1"
12273 [(set (match_operand:SWI48 0 "register_operand")
12278 (match_operand:QI 1 "register_operand")
12279 (match_operand:QI 2 "const_int_operand")))
12280 (match_operand:SWI48 3 "register_operand")))
12281 (clobber (reg:CC FLAGS_REG))]
12283 && (INTVAL (operands[2]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
12284 == GET_MODE_BITSIZE (<MODE>mode)-1
12285 && ix86_pre_reload_split ()"
12289 [(set (match_dup 0)
12291 (rotate:SWI48 (const_int -2)
12294 (clobber (reg:CC FLAGS_REG))])])
12296 ;; These instructions are never faster than the corresponding
12297 ;; and/ior/xor operations when using immediate operand, so with
12298 ;; 32-bit there's no point. But in 64-bit, we can't hold the
12299 ;; relevant immediates within the instruction itself, so operating
12300 ;; on bits in the high 32-bits of a register becomes easier.
12302 ;; These are slow on Nocona, but fast on Athlon64. We do require the use
12303 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
12304 ;; negdf respectively, so they can never be disabled entirely.
12306 (define_insn "*btsq_imm"
12307 [(set (zero_extract:DI (match_operand:DI 0 "nonimmediate_operand" "+rm")
12309 (match_operand 1 "const_0_to_63_operand" "J"))
12311 (clobber (reg:CC FLAGS_REG))]
12312 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
12313 "bts{q}\t{%1, %0|%0, %1}"
12314 [(set_attr "type" "alu1")
12315 (set_attr "prefix_0f" "1")
12316 (set_attr "znver1_decode" "double")
12317 (set_attr "mode" "DI")])
12319 (define_insn "*btrq_imm"
12320 [(set (zero_extract:DI (match_operand:DI 0 "nonimmediate_operand" "+rm")
12322 (match_operand 1 "const_0_to_63_operand" "J"))
12324 (clobber (reg:CC FLAGS_REG))]
12325 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
12326 "btr{q}\t{%1, %0|%0, %1}"
12327 [(set_attr "type" "alu1")
12328 (set_attr "prefix_0f" "1")
12329 (set_attr "znver1_decode" "double")
12330 (set_attr "mode" "DI")])
12332 (define_insn "*btcq_imm"
12333 [(set (zero_extract:DI (match_operand:DI 0 "nonimmediate_operand" "+rm")
12335 (match_operand 1 "const_0_to_63_operand" "J"))
12336 (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
12337 (clobber (reg:CC FLAGS_REG))]
12338 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
12339 "btc{q}\t{%1, %0|%0, %1}"
12340 [(set_attr "type" "alu1")
12341 (set_attr "prefix_0f" "1")
12342 (set_attr "znver1_decode" "double")
12343 (set_attr "mode" "DI")])
12345 ;; Allow Nocona to avoid these instructions if a register is available.
12348 [(match_scratch:DI 2 "r")
12349 (parallel [(set (zero_extract:DI
12350 (match_operand:DI 0 "nonimmediate_operand")
12352 (match_operand 1 "const_0_to_63_operand"))
12354 (clobber (reg:CC FLAGS_REG))])]
12355 "TARGET_64BIT && !TARGET_USE_BT"
12356 [(parallel [(set (match_dup 0)
12357 (ior:DI (match_dup 0) (match_dup 3)))
12358 (clobber (reg:CC FLAGS_REG))])]
12360 int i = INTVAL (operands[1]);
12362 operands[3] = gen_int_mode (HOST_WIDE_INT_1U << i, DImode);
12364 if (!x86_64_immediate_operand (operands[3], DImode))
12366 emit_move_insn (operands[2], operands[3]);
12367 operands[3] = operands[2];
12372 [(match_scratch:DI 2 "r")
12373 (parallel [(set (zero_extract:DI
12374 (match_operand:DI 0 "nonimmediate_operand")
12376 (match_operand 1 "const_0_to_63_operand"))
12378 (clobber (reg:CC FLAGS_REG))])]
12379 "TARGET_64BIT && !TARGET_USE_BT"
12380 [(parallel [(set (match_dup 0)
12381 (and:DI (match_dup 0) (match_dup 3)))
12382 (clobber (reg:CC FLAGS_REG))])]
12384 int i = INTVAL (operands[1]);
12386 operands[3] = gen_int_mode (~(HOST_WIDE_INT_1U << i), DImode);
12388 if (!x86_64_immediate_operand (operands[3], DImode))
12390 emit_move_insn (operands[2], operands[3]);
12391 operands[3] = operands[2];
12396 [(match_scratch:DI 2 "r")
12397 (parallel [(set (zero_extract:DI
12398 (match_operand:DI 0 "nonimmediate_operand")
12400 (match_operand 1 "const_0_to_63_operand"))
12401 (not:DI (zero_extract:DI
12402 (match_dup 0) (const_int 1) (match_dup 1))))
12403 (clobber (reg:CC FLAGS_REG))])]
12404 "TARGET_64BIT && !TARGET_USE_BT"
12405 [(parallel [(set (match_dup 0)
12406 (xor:DI (match_dup 0) (match_dup 3)))
12407 (clobber (reg:CC FLAGS_REG))])]
12409 int i = INTVAL (operands[1]);
12411 operands[3] = gen_int_mode (HOST_WIDE_INT_1U << i, DImode);
12413 if (!x86_64_immediate_operand (operands[3], DImode))
12415 emit_move_insn (operands[2], operands[3]);
12416 operands[3] = operands[2];
12422 (define_insn "*bt<mode>"
12423 [(set (reg:CCC FLAGS_REG)
12425 (zero_extract:SWI48
12426 (match_operand:SWI48 0 "nonimmediate_operand" "r,m")
12428 (match_operand:SI 1 "nonmemory_operand" "r<S>,<S>"))
12432 switch (get_attr_mode (insn))
12435 return "bt{l}\t{%1, %k0|%k0, %1}";
12438 return "bt{q}\t{%q1, %0|%0, %q1}";
12441 gcc_unreachable ();
12444 [(set_attr "type" "alu1")
12445 (set_attr "prefix_0f" "1")
12448 (and (match_test "CONST_INT_P (operands[1])")
12449 (match_test "INTVAL (operands[1]) < 32"))
12450 (const_string "SI")
12451 (const_string "<MODE>")))])
12453 (define_insn_and_split "*jcc_bt<mode>"
12455 (if_then_else (match_operator 0 "bt_comparison_operator"
12456 [(zero_extract:SWI48
12457 (match_operand:SWI48 1 "nonimmediate_operand")
12459 (match_operand:SI 2 "nonmemory_operand"))
12461 (label_ref (match_operand 3))
12463 (clobber (reg:CC FLAGS_REG))]
12464 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
12465 && (CONST_INT_P (operands[2])
12466 ? (INTVAL (operands[2]) < GET_MODE_BITSIZE (<MODE>mode)
12467 && INTVAL (operands[2])
12468 >= (optimize_function_for_size_p (cfun) ? 8 : 32))
12469 : !memory_operand (operands[1], <MODE>mode))
12470 && ix86_pre_reload_split ()"
12473 [(set (reg:CCC FLAGS_REG)
12475 (zero_extract:SWI48
12481 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
12482 (label_ref (match_dup 3))
12485 operands[0] = shallow_copy_rtx (operands[0]);
12486 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
12489 (define_insn_and_split "*jcc_bt<mode>_1"
12491 (if_then_else (match_operator 0 "bt_comparison_operator"
12492 [(zero_extract:SWI48
12493 (match_operand:SWI48 1 "register_operand")
12496 (match_operand:QI 2 "register_operand")))
12498 (label_ref (match_operand 3))
12500 (clobber (reg:CC FLAGS_REG))]
12501 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
12502 && ix86_pre_reload_split ()"
12505 [(set (reg:CCC FLAGS_REG)
12507 (zero_extract:SWI48
12513 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
12514 (label_ref (match_dup 3))
12517 operands[2] = lowpart_subreg (SImode, operands[2], QImode);
12518 operands[0] = shallow_copy_rtx (operands[0]);
12519 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
12522 ;; Avoid useless masking of bit offset operand.
12523 (define_insn_and_split "*jcc_bt<mode>_mask"
12525 (if_then_else (match_operator 0 "bt_comparison_operator"
12526 [(zero_extract:SWI48
12527 (match_operand:SWI48 1 "register_operand")
12530 (match_operand:SI 2 "register_operand")
12531 (match_operand 3 "const_int_operand")))])
12532 (label_ref (match_operand 4))
12534 (clobber (reg:CC FLAGS_REG))]
12535 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
12536 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
12537 == GET_MODE_BITSIZE (<MODE>mode)-1
12538 && ix86_pre_reload_split ()"
12541 [(set (reg:CCC FLAGS_REG)
12543 (zero_extract:SWI48
12549 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
12550 (label_ref (match_dup 4))
12553 operands[0] = shallow_copy_rtx (operands[0]);
12554 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
12557 ;; Store-flag instructions.
12560 [(set (match_operand:QI 0 "nonimmediate_operand")
12561 (match_operator:QI 1 "add_comparison_operator"
12562 [(not:SWI (match_operand:SWI 2 "register_operand"))
12563 (match_operand:SWI 3 "nonimmediate_operand")]))]
12566 [(set (reg:CCC FLAGS_REG)
12568 (plus:SWI (match_dup 2) (match_dup 3))
12570 (clobber (scratch:SWI))])
12572 (match_op_dup 1 [(reg:CCC FLAGS_REG) (const_int 0)]))])
12575 [(set (match_operand:QI 0 "nonimmediate_operand")
12576 (match_operator:QI 1 "shr_comparison_operator"
12577 [(match_operand:DI 2 "register_operand")
12578 (match_operand 3 "const_int_operand")]))]
12580 && IN_RANGE (exact_log2 (UINTVAL (operands[3]) + 1), 32, 63)"
12582 [(set (reg:CCZ FLAGS_REG)
12584 (lshiftrt:DI (match_dup 2) (match_dup 4))
12586 (clobber (scratch:DI))])
12588 (match_op_dup 1 [(reg:CCZ FLAGS_REG) (const_int 0)]))]
12590 enum rtx_code new_code;
12592 operands[1] = shallow_copy_rtx (operands[1]);
12593 switch (GET_CODE (operands[1]))
12595 case GTU: new_code = NE; break;
12596 case LEU: new_code = EQ; break;
12597 default: gcc_unreachable ();
12599 PUT_CODE (operands[1], new_code);
12601 operands[4] = GEN_INT (exact_log2 (UINTVAL (operands[3]) + 1));
12604 ;; For all sCOND expanders, also expand the compare or test insn that
12605 ;; generates cc0. Generate an equality comparison if `seq' or `sne'.
12607 (define_insn_and_split "*setcc_di_1"
12608 [(set (match_operand:DI 0 "register_operand" "=q")
12609 (match_operator:DI 1 "ix86_comparison_operator"
12610 [(reg FLAGS_REG) (const_int 0)]))]
12611 "TARGET_64BIT && !TARGET_PARTIAL_REG_STALL"
12613 "&& reload_completed"
12614 [(set (match_dup 2) (match_dup 1))
12615 (set (match_dup 0) (zero_extend:DI (match_dup 2)))]
12617 operands[1] = shallow_copy_rtx (operands[1]);
12618 PUT_MODE (operands[1], QImode);
12619 operands[2] = gen_lowpart (QImode, operands[0]);
12622 (define_insn_and_split "*setcc_si_1_and"
12623 [(set (match_operand:SI 0 "register_operand" "=q")
12624 (match_operator:SI 1 "ix86_comparison_operator"
12625 [(reg FLAGS_REG) (const_int 0)]))
12626 (clobber (reg:CC FLAGS_REG))]
12627 "!TARGET_PARTIAL_REG_STALL
12628 && TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
12630 "&& reload_completed"
12631 [(set (match_dup 2) (match_dup 1))
12632 (parallel [(set (match_dup 0) (zero_extend:SI (match_dup 2)))
12633 (clobber (reg:CC FLAGS_REG))])]
12635 operands[1] = shallow_copy_rtx (operands[1]);
12636 PUT_MODE (operands[1], QImode);
12637 operands[2] = gen_lowpart (QImode, operands[0]);
12640 (define_insn_and_split "*setcc_si_1_movzbl"
12641 [(set (match_operand:SI 0 "register_operand" "=q")
12642 (match_operator:SI 1 "ix86_comparison_operator"
12643 [(reg FLAGS_REG) (const_int 0)]))]
12644 "!TARGET_PARTIAL_REG_STALL
12645 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
12647 "&& reload_completed"
12648 [(set (match_dup 2) (match_dup 1))
12649 (set (match_dup 0) (zero_extend:SI (match_dup 2)))]
12651 operands[1] = shallow_copy_rtx (operands[1]);
12652 PUT_MODE (operands[1], QImode);
12653 operands[2] = gen_lowpart (QImode, operands[0]);
12656 (define_insn "*setcc_qi"
12657 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12658 (match_operator:QI 1 "ix86_comparison_operator"
12659 [(reg FLAGS_REG) (const_int 0)]))]
12662 [(set_attr "type" "setcc")
12663 (set_attr "mode" "QI")])
12665 (define_insn "*setcc_qi_slp"
12666 [(set (strict_low_part (match_operand:QI 0 "register_operand" "+q"))
12667 (match_operator:QI 1 "ix86_comparison_operator"
12668 [(reg FLAGS_REG) (const_int 0)]))]
12671 [(set_attr "type" "setcc")
12672 (set_attr "mode" "QI")])
12674 ;; In general it is not safe to assume too much about CCmode registers,
12675 ;; so simplify-rtx stops when it sees a second one. Under certain
12676 ;; conditions this is safe on x86, so help combine not create
12683 [(set (match_operand:QI 0 "nonimmediate_operand")
12684 (ne:QI (match_operator 1 "ix86_comparison_operator"
12685 [(reg FLAGS_REG) (const_int 0)])
12688 [(set (match_dup 0) (match_dup 1))]
12690 operands[1] = shallow_copy_rtx (operands[1]);
12691 PUT_MODE (operands[1], QImode);
12695 [(set (strict_low_part (match_operand:QI 0 "register_operand"))
12696 (ne:QI (match_operator 1 "ix86_comparison_operator"
12697 [(reg FLAGS_REG) (const_int 0)])
12700 [(set (match_dup 0) (match_dup 1))]
12702 operands[1] = shallow_copy_rtx (operands[1]);
12703 PUT_MODE (operands[1], QImode);
12707 [(set (match_operand:QI 0 "nonimmediate_operand")
12708 (eq:QI (match_operator 1 "ix86_comparison_operator"
12709 [(reg FLAGS_REG) (const_int 0)])
12712 [(set (match_dup 0) (match_dup 1))]
12714 operands[1] = shallow_copy_rtx (operands[1]);
12715 PUT_MODE (operands[1], QImode);
12716 PUT_CODE (operands[1],
12717 ix86_reverse_condition (GET_CODE (operands[1]),
12718 GET_MODE (XEXP (operands[1], 0))));
12720 /* Make sure that (a) the CCmode we have for the flags is strong
12721 enough for the reversed compare or (b) we have a valid FP compare. */
12722 if (! ix86_comparison_operator (operands[1], VOIDmode))
12727 [(set (strict_low_part (match_operand:QI 0 "register_operand"))
12728 (eq:QI (match_operator 1 "ix86_comparison_operator"
12729 [(reg FLAGS_REG) (const_int 0)])
12732 [(set (match_dup 0) (match_dup 1))]
12734 operands[1] = shallow_copy_rtx (operands[1]);
12735 PUT_MODE (operands[1], QImode);
12736 PUT_CODE (operands[1],
12737 ix86_reverse_condition (GET_CODE (operands[1]),
12738 GET_MODE (XEXP (operands[1], 0))));
12740 /* Make sure that (a) the CCmode we have for the flags is strong
12741 enough for the reversed compare or (b) we have a valid FP compare. */
12742 if (! ix86_comparison_operator (operands[1], VOIDmode))
12746 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
12747 ;; subsequent logical operations are used to imitate conditional moves.
12748 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
12751 (define_insn "setcc_<mode>_sse"
12752 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
12753 (match_operator:MODEF 3 "sse_comparison_operator"
12754 [(match_operand:MODEF 1 "register_operand" "0,x")
12755 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
12756 "SSE_FLOAT_MODE_P (<MODE>mode)"
12758 cmp%D3<ssemodesuffix>\t{%2, %0|%0, %2}
12759 vcmp%D3<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
12760 [(set_attr "isa" "noavx,avx")
12761 (set_attr "type" "ssecmp")
12762 (set_attr "length_immediate" "1")
12763 (set_attr "prefix" "orig,vex")
12764 (set_attr "mode" "<MODE>")])
12766 ;; Basic conditional jump instructions.
12771 (match_operator 1 "add_comparison_operator"
12772 [(not:SWI (match_operand:SWI 2 "register_operand"))
12773 (match_operand:SWI 3 "nonimmediate_operand")])
12774 (label_ref (match_operand 0))
12778 [(set (reg:CCC FLAGS_REG)
12780 (plus:SWI (match_dup 2) (match_dup 3))
12782 (clobber (scratch:SWI))])
12784 (if_then_else (match_op_dup 1 [(reg:CCC FLAGS_REG) (const_int 0)])
12785 (label_ref (match_operand 0))
12791 (match_operator 1 "shr_comparison_operator"
12792 [(match_operand:DI 2 "register_operand")
12793 (match_operand 3 "const_int_operand")])
12794 (label_ref (match_operand 0))
12797 && IN_RANGE (exact_log2 (UINTVAL (operands[3]) + 1), 32, 63)"
12799 [(set (reg:CCZ FLAGS_REG)
12801 (lshiftrt:DI (match_dup 2) (match_dup 4))
12803 (clobber (scratch:DI))])
12805 (if_then_else (match_op_dup 1 [(reg:CCZ FLAGS_REG) (const_int 0)])
12806 (label_ref (match_operand 0))
12809 enum rtx_code new_code;
12811 operands[1] = shallow_copy_rtx (operands[1]);
12812 switch (GET_CODE (operands[1]))
12814 case GTU: new_code = NE; break;
12815 case LEU: new_code = EQ; break;
12816 default: gcc_unreachable ();
12818 PUT_CODE (operands[1], new_code);
12820 operands[4] = GEN_INT (exact_log2 (UINTVAL (operands[3]) + 1));
12823 ;; We ignore the overflow flag for signed branch instructions.
12825 (define_insn "*jcc"
12827 (if_then_else (match_operator 1 "ix86_comparison_operator"
12828 [(reg FLAGS_REG) (const_int 0)])
12829 (label_ref (match_operand 0))
12833 [(set_attr "type" "ibr")
12834 (set_attr "modrm" "0")
12835 (set (attr "length")
12837 (and (ge (minus (match_dup 0) (pc))
12839 (lt (minus (match_dup 0) (pc))
12844 ;; In general it is not safe to assume too much about CCmode registers,
12845 ;; so simplify-rtx stops when it sees a second one. Under certain
12846 ;; conditions this is safe on x86, so help combine not create
12854 (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
12855 [(reg FLAGS_REG) (const_int 0)])
12857 (label_ref (match_operand 1))
12861 (if_then_else (match_dup 0)
12862 (label_ref (match_dup 1))
12865 operands[0] = shallow_copy_rtx (operands[0]);
12866 PUT_MODE (operands[0], VOIDmode);
12871 (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
12872 [(reg FLAGS_REG) (const_int 0)])
12874 (label_ref (match_operand 1))
12878 (if_then_else (match_dup 0)
12879 (label_ref (match_dup 1))
12882 operands[0] = shallow_copy_rtx (operands[0]);
12883 PUT_MODE (operands[0], VOIDmode);
12884 PUT_CODE (operands[0],
12885 ix86_reverse_condition (GET_CODE (operands[0]),
12886 GET_MODE (XEXP (operands[0], 0))));
12888 /* Make sure that (a) the CCmode we have for the flags is strong
12889 enough for the reversed compare or (b) we have a valid FP compare. */
12890 if (! ix86_comparison_operator (operands[0], VOIDmode))
12894 ;; Unconditional and other jump instructions
12896 (define_insn "jump"
12898 (label_ref (match_operand 0)))]
12901 [(set_attr "type" "ibr")
12902 (set_attr "modrm" "0")
12903 (set (attr "length")
12905 (and (ge (minus (match_dup 0) (pc))
12907 (lt (minus (match_dup 0) (pc))
12912 (define_expand "indirect_jump"
12913 [(set (pc) (match_operand 0 "indirect_branch_operand"))]
12916 if (TARGET_X32 || TARGET_INDIRECT_BRANCH_REGISTER)
12917 operands[0] = convert_memory_address (word_mode, operands[0]);
12918 cfun->machine->has_local_indirect_jump = true;
12921 (define_insn "*indirect_jump"
12922 [(set (pc) (match_operand:W 0 "indirect_branch_operand" "rBw"))]
12924 "* return ix86_output_indirect_jmp (operands[0]);"
12925 [(set (attr "type")
12926 (if_then_else (match_test "(cfun->machine->indirect_branch_type
12927 != indirect_branch_keep)")
12928 (const_string "multi")
12929 (const_string "ibr")))
12930 (set_attr "length_immediate" "0")])
12932 (define_expand "tablejump"
12933 [(parallel [(set (pc) (match_operand 0 "indirect_branch_operand"))
12934 (use (label_ref (match_operand 1)))])]
12937 /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
12938 relative. Convert the relative address to an absolute address. */
12942 enum rtx_code code;
12944 /* We can't use @GOTOFF for text labels on VxWorks;
12945 see gotoff_operand. */
12946 if (TARGET_64BIT || TARGET_VXWORKS_RTP)
12950 op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
12952 else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
12956 op1 = pic_offset_table_rtx;
12961 op0 = pic_offset_table_rtx;
12965 operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
12969 if (TARGET_X32 || TARGET_INDIRECT_BRANCH_REGISTER)
12970 operands[0] = convert_memory_address (word_mode, operands[0]);
12971 cfun->machine->has_local_indirect_jump = true;
12974 (define_insn "*tablejump_1"
12975 [(set (pc) (match_operand:W 0 "indirect_branch_operand" "rBw"))
12976 (use (label_ref (match_operand 1)))]
12978 "* return ix86_output_indirect_jmp (operands[0]);"
12979 [(set (attr "type")
12980 (if_then_else (match_test "(cfun->machine->indirect_branch_type
12981 != indirect_branch_keep)")
12982 (const_string "multi")
12983 (const_string "ibr")))
12984 (set_attr "length_immediate" "0")])
12986 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
12989 [(set (reg FLAGS_REG) (match_operand 0))
12990 (set (match_operand:QI 1 "register_operand")
12991 (match_operator:QI 2 "ix86_comparison_operator"
12992 [(reg FLAGS_REG) (const_int 0)]))
12993 (set (match_operand 3 "any_QIreg_operand")
12994 (zero_extend (match_dup 1)))]
12995 "(peep2_reg_dead_p (3, operands[1])
12996 || operands_match_p (operands[1], operands[3]))
12997 && ! reg_overlap_mentioned_p (operands[3], operands[0])
12998 && peep2_regno_dead_p (0, FLAGS_REG)"
12999 [(set (match_dup 4) (match_dup 0))
13000 (set (strict_low_part (match_dup 5))
13003 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
13004 operands[5] = gen_lowpart (QImode, operands[3]);
13005 ix86_expand_clear (operands[3]);
13009 [(parallel [(set (reg FLAGS_REG) (match_operand 0))
13010 (match_operand 4)])
13011 (set (match_operand:QI 1 "register_operand")
13012 (match_operator:QI 2 "ix86_comparison_operator"
13013 [(reg FLAGS_REG) (const_int 0)]))
13014 (set (match_operand 3 "any_QIreg_operand")
13015 (zero_extend (match_dup 1)))]
13016 "(peep2_reg_dead_p (3, operands[1])
13017 || operands_match_p (operands[1], operands[3]))
13018 && ! reg_overlap_mentioned_p (operands[3], operands[0])
13019 && ! reg_overlap_mentioned_p (operands[3], operands[4])
13020 && ! reg_set_p (operands[3], operands[4])
13021 && peep2_regno_dead_p (0, FLAGS_REG)"
13022 [(parallel [(set (match_dup 5) (match_dup 0))
13024 (set (strict_low_part (match_dup 6))
13027 operands[5] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
13028 operands[6] = gen_lowpart (QImode, operands[3]);
13029 ix86_expand_clear (operands[3]);
13033 [(set (reg FLAGS_REG) (match_operand 0))
13034 (parallel [(set (reg FLAGS_REG) (match_operand 1))
13035 (match_operand 5)])
13036 (set (match_operand:QI 2 "register_operand")
13037 (match_operator:QI 3 "ix86_comparison_operator"
13038 [(reg FLAGS_REG) (const_int 0)]))
13039 (set (match_operand 4 "any_QIreg_operand")
13040 (zero_extend (match_dup 2)))]
13041 "(peep2_reg_dead_p (4, operands[2])
13042 || operands_match_p (operands[2], operands[4]))
13043 && ! reg_overlap_mentioned_p (operands[4], operands[0])
13044 && ! reg_overlap_mentioned_p (operands[4], operands[1])
13045 && ! reg_overlap_mentioned_p (operands[4], operands[5])
13046 && ! reg_set_p (operands[4], operands[5])
13047 && refers_to_regno_p (FLAGS_REG, operands[1], (rtx *)NULL)
13048 && peep2_regno_dead_p (0, FLAGS_REG)"
13049 [(set (match_dup 6) (match_dup 0))
13050 (parallel [(set (match_dup 7) (match_dup 1))
13052 (set (strict_low_part (match_dup 8))
13055 operands[6] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
13056 operands[7] = gen_rtx_REG (GET_MODE (operands[1]), FLAGS_REG);
13057 operands[8] = gen_lowpart (QImode, operands[4]);
13058 ix86_expand_clear (operands[4]);
13061 ;; Similar, but match zero extend with andsi3.
13064 [(set (reg FLAGS_REG) (match_operand 0))
13065 (set (match_operand:QI 1 "register_operand")
13066 (match_operator:QI 2 "ix86_comparison_operator"
13067 [(reg FLAGS_REG) (const_int 0)]))
13068 (parallel [(set (match_operand:SI 3 "any_QIreg_operand")
13069 (and:SI (match_dup 3) (const_int 255)))
13070 (clobber (reg:CC FLAGS_REG))])]
13071 "REGNO (operands[1]) == REGNO (operands[3])
13072 && ! reg_overlap_mentioned_p (operands[3], operands[0])
13073 && peep2_regno_dead_p (0, FLAGS_REG)"
13074 [(set (match_dup 4) (match_dup 0))
13075 (set (strict_low_part (match_dup 5))
13078 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
13079 operands[5] = gen_lowpart (QImode, operands[3]);
13080 ix86_expand_clear (operands[3]);
13084 [(parallel [(set (reg FLAGS_REG) (match_operand 0))
13085 (match_operand 4)])
13086 (set (match_operand:QI 1 "register_operand")
13087 (match_operator:QI 2 "ix86_comparison_operator"
13088 [(reg FLAGS_REG) (const_int 0)]))
13089 (parallel [(set (match_operand 3 "any_QIreg_operand")
13090 (zero_extend (match_dup 1)))
13091 (clobber (reg:CC FLAGS_REG))])]
13092 "(peep2_reg_dead_p (3, operands[1])
13093 || operands_match_p (operands[1], operands[3]))
13094 && ! reg_overlap_mentioned_p (operands[3], operands[0])
13095 && ! reg_overlap_mentioned_p (operands[3], operands[4])
13096 && ! reg_set_p (operands[3], operands[4])
13097 && peep2_regno_dead_p (0, FLAGS_REG)"
13098 [(parallel [(set (match_dup 5) (match_dup 0))
13100 (set (strict_low_part (match_dup 6))
13103 operands[5] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
13104 operands[6] = gen_lowpart (QImode, operands[3]);
13105 ix86_expand_clear (operands[3]);
13109 [(set (reg FLAGS_REG) (match_operand 0))
13110 (parallel [(set (reg FLAGS_REG) (match_operand 1))
13111 (match_operand 5)])
13112 (set (match_operand:QI 2 "register_operand")
13113 (match_operator:QI 3 "ix86_comparison_operator"
13114 [(reg FLAGS_REG) (const_int 0)]))
13115 (parallel [(set (match_operand 4 "any_QIreg_operand")
13116 (zero_extend (match_dup 2)))
13117 (clobber (reg:CC FLAGS_REG))])]
13118 "(peep2_reg_dead_p (4, operands[2])
13119 || operands_match_p (operands[2], operands[4]))
13120 && ! reg_overlap_mentioned_p (operands[4], operands[0])
13121 && ! reg_overlap_mentioned_p (operands[4], operands[1])
13122 && ! reg_overlap_mentioned_p (operands[4], operands[5])
13123 && ! reg_set_p (operands[4], operands[5])
13124 && refers_to_regno_p (FLAGS_REG, operands[1], (rtx *)NULL)
13125 && peep2_regno_dead_p (0, FLAGS_REG)"
13126 [(set (match_dup 6) (match_dup 0))
13127 (parallel [(set (match_dup 7) (match_dup 1))
13129 (set (strict_low_part (match_dup 8))
13132 operands[6] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
13133 operands[7] = gen_rtx_REG (GET_MODE (operands[1]), FLAGS_REG);
13134 operands[8] = gen_lowpart (QImode, operands[4]);
13135 ix86_expand_clear (operands[4]);
13138 ;; Call instructions.
13140 ;; The predicates normally associated with named expanders are not properly
13141 ;; checked for calls. This is a bug in the generic code, but it isn't that
13142 ;; easy to fix. Ignore it for now and be prepared to fix things up.
13144 ;; P6 processors will jump to the address after the decrement when %esp
13145 ;; is used as a call operand, so they will execute return address as a code.
13146 ;; See Pentium Pro errata 70, Pentium 2 errata A33 and Pentium 3 errata E17.
13148 ;; Register constraint for call instruction.
13149 (define_mode_attr c [(SI "l") (DI "r")])
13151 ;; Call subroutine returning no value.
13153 (define_expand "call"
13154 [(call (match_operand:QI 0)
13156 (use (match_operand 2))]
13159 ix86_expand_call (NULL, operands[0], operands[1],
13160 operands[2], NULL, false);
13164 (define_expand "sibcall"
13165 [(call (match_operand:QI 0)
13167 (use (match_operand 2))]
13170 ix86_expand_call (NULL, operands[0], operands[1],
13171 operands[2], NULL, true);
13175 (define_insn "*call"
13176 [(call (mem:QI (match_operand:W 0 "call_insn_operand" "<c>BwBz"))
13177 (match_operand 1))]
13178 "!SIBLING_CALL_P (insn)"
13179 "* return ix86_output_call_insn (insn, operands[0]);"
13180 [(set_attr "type" "call")])
13182 ;; This covers both call and sibcall since only GOT slot is allowed.
13183 (define_insn "*call_got_x32"
13184 [(call (mem:QI (zero_extend:DI
13185 (match_operand:SI 0 "GOT_memory_operand" "Bg")))
13186 (match_operand 1))]
13189 rtx fnaddr = gen_const_mem (DImode, XEXP (operands[0], 0));
13190 return ix86_output_call_insn (insn, fnaddr);
13192 [(set_attr "type" "call")])
13194 ;; Since sibcall never returns, we can only use call-clobbered register
13196 (define_insn "*sibcall_GOT_32"
13199 (match_operand:SI 0 "register_no_elim_operand" "U")
13200 (match_operand:SI 1 "GOT32_symbol_operand"))))
13201 (match_operand 2))]
13204 && !TARGET_INDIRECT_BRANCH_REGISTER
13205 && SIBLING_CALL_P (insn)"
13207 rtx fnaddr = gen_rtx_PLUS (SImode, operands[0], operands[1]);
13208 fnaddr = gen_const_mem (SImode, fnaddr);
13209 return ix86_output_call_insn (insn, fnaddr);
13211 [(set_attr "type" "call")])
13213 (define_insn "*sibcall"
13214 [(call (mem:QI (match_operand:W 0 "sibcall_insn_operand" "UBsBz"))
13215 (match_operand 1))]
13216 "SIBLING_CALL_P (insn)"
13217 "* return ix86_output_call_insn (insn, operands[0]);"
13218 [(set_attr "type" "call")])
13220 (define_insn "*sibcall_memory"
13221 [(call (mem:QI (match_operand:W 0 "memory_operand" "m"))
13223 (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
13224 "!TARGET_X32 && !TARGET_INDIRECT_BRANCH_REGISTER"
13225 "* return ix86_output_call_insn (insn, operands[0]);"
13226 [(set_attr "type" "call")])
13229 [(set (match_operand:W 0 "register_operand")
13230 (match_operand:W 1 "memory_operand"))
13231 (call (mem:QI (match_dup 0))
13232 (match_operand 3))]
13234 && !TARGET_INDIRECT_BRANCH_REGISTER
13235 && SIBLING_CALL_P (peep2_next_insn (1))
13236 && !reg_mentioned_p (operands[0],
13237 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (1)))"
13238 [(parallel [(call (mem:QI (match_dup 1))
13240 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
13243 [(set (match_operand:W 0 "register_operand")
13244 (match_operand:W 1 "memory_operand"))
13245 (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
13246 (call (mem:QI (match_dup 0))
13247 (match_operand 3))]
13249 && !TARGET_INDIRECT_BRANCH_REGISTER
13250 && SIBLING_CALL_P (peep2_next_insn (2))
13251 && !reg_mentioned_p (operands[0],
13252 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (2)))"
13253 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
13254 (parallel [(call (mem:QI (match_dup 1))
13256 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
13258 (define_expand "call_pop"
13259 [(parallel [(call (match_operand:QI 0)
13260 (match_operand:SI 1))
13261 (set (reg:SI SP_REG)
13262 (plus:SI (reg:SI SP_REG)
13263 (match_operand:SI 3)))])]
13266 ix86_expand_call (NULL, operands[0], operands[1],
13267 operands[2], operands[3], false);
13271 (define_insn "*call_pop"
13272 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lBwBz"))
13274 (set (reg:SI SP_REG)
13275 (plus:SI (reg:SI SP_REG)
13276 (match_operand:SI 2 "immediate_operand" "i")))]
13277 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
13278 "* return ix86_output_call_insn (insn, operands[0]);"
13279 [(set_attr "type" "call")])
13281 (define_insn "*sibcall_pop"
13282 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "UBsBz"))
13284 (set (reg:SI SP_REG)
13285 (plus:SI (reg:SI SP_REG)
13286 (match_operand:SI 2 "immediate_operand" "i")))]
13287 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
13288 "* return ix86_output_call_insn (insn, operands[0]);"
13289 [(set_attr "type" "call")])
13291 (define_insn "*sibcall_pop_memory"
13292 [(call (mem:QI (match_operand:SI 0 "memory_operand" "Bs"))
13294 (set (reg:SI SP_REG)
13295 (plus:SI (reg:SI SP_REG)
13296 (match_operand:SI 2 "immediate_operand" "i")))
13297 (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
13299 "* return ix86_output_call_insn (insn, operands[0]);"
13300 [(set_attr "type" "call")])
13303 [(set (match_operand:SI 0 "register_operand")
13304 (match_operand:SI 1 "memory_operand"))
13305 (parallel [(call (mem:QI (match_dup 0))
13307 (set (reg:SI SP_REG)
13308 (plus:SI (reg:SI SP_REG)
13309 (match_operand:SI 4 "immediate_operand")))])]
13310 "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (1))
13311 && !reg_mentioned_p (operands[0],
13312 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (1)))"
13313 [(parallel [(call (mem:QI (match_dup 1))
13315 (set (reg:SI SP_REG)
13316 (plus:SI (reg:SI SP_REG)
13318 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
13321 [(set (match_operand:SI 0 "register_operand")
13322 (match_operand:SI 1 "memory_operand"))
13323 (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
13324 (parallel [(call (mem:QI (match_dup 0))
13326 (set (reg:SI SP_REG)
13327 (plus:SI (reg:SI SP_REG)
13328 (match_operand:SI 4 "immediate_operand")))])]
13329 "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (2))
13330 && !reg_mentioned_p (operands[0],
13331 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (2)))"
13332 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
13333 (parallel [(call (mem:QI (match_dup 1))
13335 (set (reg:SI SP_REG)
13336 (plus:SI (reg:SI SP_REG)
13338 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
13340 ;; Combining simple memory jump instruction
13343 [(set (match_operand:W 0 "register_operand")
13344 (match_operand:W 1 "memory_operand"))
13345 (set (pc) (match_dup 0))]
13347 && !TARGET_INDIRECT_BRANCH_REGISTER
13348 && peep2_reg_dead_p (2, operands[0])"
13349 [(set (pc) (match_dup 1))])
13351 ;; Call subroutine, returning value in operand 0
13353 (define_expand "call_value"
13354 [(set (match_operand 0)
13355 (call (match_operand:QI 1)
13356 (match_operand 2)))
13357 (use (match_operand 3))]
13360 ix86_expand_call (operands[0], operands[1], operands[2],
13361 operands[3], NULL, false);
13365 (define_expand "sibcall_value"
13366 [(set (match_operand 0)
13367 (call (match_operand:QI 1)
13368 (match_operand 2)))
13369 (use (match_operand 3))]
13372 ix86_expand_call (operands[0], operands[1], operands[2],
13373 operands[3], NULL, true);
13377 (define_insn "*call_value"
13378 [(set (match_operand 0)
13379 (call (mem:QI (match_operand:W 1 "call_insn_operand" "<c>BwBz"))
13380 (match_operand 2)))]
13381 "!SIBLING_CALL_P (insn)"
13382 "* return ix86_output_call_insn (insn, operands[1]);"
13383 [(set_attr "type" "callv")])
13385 ;; This covers both call and sibcall since only GOT slot is allowed.
13386 (define_insn "*call_value_got_x32"
13387 [(set (match_operand 0)
13390 (match_operand:SI 1 "GOT_memory_operand" "Bg")))
13391 (match_operand 2)))]
13394 rtx fnaddr = gen_const_mem (DImode, XEXP (operands[1], 0));
13395 return ix86_output_call_insn (insn, fnaddr);
13397 [(set_attr "type" "callv")])
13399 ;; Since sibcall never returns, we can only use call-clobbered register
13401 (define_insn "*sibcall_value_GOT_32"
13402 [(set (match_operand 0)
13405 (match_operand:SI 1 "register_no_elim_operand" "U")
13406 (match_operand:SI 2 "GOT32_symbol_operand"))))
13407 (match_operand 3)))]
13410 && !TARGET_INDIRECT_BRANCH_REGISTER
13411 && SIBLING_CALL_P (insn)"
13413 rtx fnaddr = gen_rtx_PLUS (SImode, operands[1], operands[2]);
13414 fnaddr = gen_const_mem (SImode, fnaddr);
13415 return ix86_output_call_insn (insn, fnaddr);
13417 [(set_attr "type" "callv")])
13419 (define_insn "*sibcall_value"
13420 [(set (match_operand 0)
13421 (call (mem:QI (match_operand:W 1 "sibcall_insn_operand" "UBsBz"))
13422 (match_operand 2)))]
13423 "SIBLING_CALL_P (insn)"
13424 "* return ix86_output_call_insn (insn, operands[1]);"
13425 [(set_attr "type" "callv")])
13427 (define_insn "*sibcall_value_memory"
13428 [(set (match_operand 0)
13429 (call (mem:QI (match_operand:W 1 "memory_operand" "m"))
13430 (match_operand 2)))
13431 (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
13432 "!TARGET_X32 && !TARGET_INDIRECT_BRANCH_REGISTER"
13433 "* return ix86_output_call_insn (insn, operands[1]);"
13434 [(set_attr "type" "callv")])
13437 [(set (match_operand:W 0 "register_operand")
13438 (match_operand:W 1 "memory_operand"))
13439 (set (match_operand 2)
13440 (call (mem:QI (match_dup 0))
13441 (match_operand 3)))]
13443 && !TARGET_INDIRECT_BRANCH_REGISTER
13444 && SIBLING_CALL_P (peep2_next_insn (1))
13445 && !reg_mentioned_p (operands[0],
13446 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (1)))"
13447 [(parallel [(set (match_dup 2)
13448 (call (mem:QI (match_dup 1))
13450 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
13453 [(set (match_operand:W 0 "register_operand")
13454 (match_operand:W 1 "memory_operand"))
13455 (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
13456 (set (match_operand 2)
13457 (call (mem:QI (match_dup 0))
13458 (match_operand 3)))]
13460 && !TARGET_INDIRECT_BRANCH_REGISTER
13461 && SIBLING_CALL_P (peep2_next_insn (2))
13462 && !reg_mentioned_p (operands[0],
13463 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (2)))"
13464 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
13465 (parallel [(set (match_dup 2)
13466 (call (mem:QI (match_dup 1))
13468 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
13470 (define_expand "call_value_pop"
13471 [(parallel [(set (match_operand 0)
13472 (call (match_operand:QI 1)
13473 (match_operand:SI 2)))
13474 (set (reg:SI SP_REG)
13475 (plus:SI (reg:SI SP_REG)
13476 (match_operand:SI 4)))])]
13479 ix86_expand_call (operands[0], operands[1], operands[2],
13480 operands[3], operands[4], false);
13484 (define_insn "*call_value_pop"
13485 [(set (match_operand 0)
13486 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lBwBz"))
13487 (match_operand 2)))
13488 (set (reg:SI SP_REG)
13489 (plus:SI (reg:SI SP_REG)
13490 (match_operand:SI 3 "immediate_operand" "i")))]
13491 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
13492 "* return ix86_output_call_insn (insn, operands[1]);"
13493 [(set_attr "type" "callv")])
13495 (define_insn "*sibcall_value_pop"
13496 [(set (match_operand 0)
13497 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "UBsBz"))
13498 (match_operand 2)))
13499 (set (reg:SI SP_REG)
13500 (plus:SI (reg:SI SP_REG)
13501 (match_operand:SI 3 "immediate_operand" "i")))]
13502 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
13503 "* return ix86_output_call_insn (insn, operands[1]);"
13504 [(set_attr "type" "callv")])
13506 (define_insn "*sibcall_value_pop_memory"
13507 [(set (match_operand 0)
13508 (call (mem:QI (match_operand:SI 1 "memory_operand" "m"))
13509 (match_operand 2)))
13510 (set (reg:SI SP_REG)
13511 (plus:SI (reg:SI SP_REG)
13512 (match_operand:SI 3 "immediate_operand" "i")))
13513 (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
13515 "* return ix86_output_call_insn (insn, operands[1]);"
13516 [(set_attr "type" "callv")])
13519 [(set (match_operand:SI 0 "register_operand")
13520 (match_operand:SI 1 "memory_operand"))
13521 (parallel [(set (match_operand 2)
13522 (call (mem:QI (match_dup 0))
13523 (match_operand 3)))
13524 (set (reg:SI SP_REG)
13525 (plus:SI (reg:SI SP_REG)
13526 (match_operand:SI 4 "immediate_operand")))])]
13527 "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (1))
13528 && !reg_mentioned_p (operands[0],
13529 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (1)))"
13530 [(parallel [(set (match_dup 2)
13531 (call (mem:QI (match_dup 1))
13533 (set (reg:SI SP_REG)
13534 (plus:SI (reg:SI SP_REG)
13536 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
13539 [(set (match_operand:SI 0 "register_operand")
13540 (match_operand:SI 1 "memory_operand"))
13541 (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
13542 (parallel [(set (match_operand 2)
13543 (call (mem:QI (match_dup 0))
13544 (match_operand 3)))
13545 (set (reg:SI SP_REG)
13546 (plus:SI (reg:SI SP_REG)
13547 (match_operand:SI 4 "immediate_operand")))])]
13548 "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (2))
13549 && !reg_mentioned_p (operands[0],
13550 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (2)))"
13551 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
13552 (parallel [(set (match_dup 2)
13553 (call (mem:QI (match_dup 1))
13555 (set (reg:SI SP_REG)
13556 (plus:SI (reg:SI SP_REG)
13558 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
13560 ;; Call subroutine returning any type.
13562 (define_expand "untyped_call"
13563 [(parallel [(call (match_operand 0)
13566 (match_operand 2)])]
13571 /* In order to give reg-stack an easier job in validating two
13572 coprocessor registers as containing a possible return value,
13573 simply pretend the untyped call returns a complex long double
13576 We can't use SSE_REGPARM_MAX here since callee is unprototyped
13577 and should have the default ABI. */
13579 ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
13580 ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
13581 operands[0], const0_rtx,
13582 GEN_INT ((TARGET_64BIT
13583 ? (ix86_abi == SYSV_ABI
13584 ? X86_64_SSE_REGPARM_MAX
13585 : X86_64_MS_SSE_REGPARM_MAX)
13586 : X86_32_SSE_REGPARM_MAX)
13590 for (i = 0; i < XVECLEN (operands[2], 0); i++)
13592 rtx set = XVECEXP (operands[2], 0, i);
13593 emit_move_insn (SET_DEST (set), SET_SRC (set));
13596 /* The optimizer does not know that the call sets the function value
13597 registers we stored in the result block. We avoid problems by
13598 claiming that all hard registers are used and clobbered at this
13600 emit_insn (gen_blockage ());
13605 ;; Prologue and epilogue instructions
13607 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
13608 ;; all of memory. This blocks insns from being moved across this point.
13610 (define_insn "blockage"
13611 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
13614 [(set_attr "length" "0")])
13616 ;; Do not schedule instructions accessing memory across this point.
13618 (define_expand "memory_blockage"
13619 [(set (match_dup 0)
13620 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
13623 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
13624 MEM_VOLATILE_P (operands[0]) = 1;
13627 (define_insn "*memory_blockage"
13628 [(set (match_operand:BLK 0)
13629 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
13632 [(set_attr "length" "0")])
13634 ;; As USE insns aren't meaningful after reload, this is used instead
13635 ;; to prevent deleting instructions setting registers for PIC code
13636 (define_insn "prologue_use"
13637 [(unspec_volatile [(match_operand 0)] UNSPECV_PROLOGUE_USE)]
13640 [(set_attr "length" "0")])
13642 ;; Insn emitted into the body of a function to return from a function.
13643 ;; This is only done if the function's epilogue is known to be simple.
13644 ;; See comments for ix86_can_use_return_insn_p in i386.c.
13646 (define_expand "return"
13648 "ix86_can_use_return_insn_p ()"
13650 if (crtl->args.pops_args)
13652 rtx popc = GEN_INT (crtl->args.pops_args);
13653 emit_jump_insn (gen_simple_return_pop_internal (popc));
13658 ;; We need to disable this for TARGET_SEH, as otherwise
13659 ;; shrink-wrapped prologue gets enabled too. This might exceed
13660 ;; the maximum size of prologue in unwind information.
13661 ;; Also disallow shrink-wrapping if using stack slot to pass the
13662 ;; static chain pointer - the first instruction has to be pushl %esi
13663 ;; and it can't be moved around, as we use alternate entry points
13666 (define_expand "simple_return"
13668 "!TARGET_SEH && !ix86_static_chain_on_stack"
13670 if (crtl->args.pops_args)
13672 rtx popc = GEN_INT (crtl->args.pops_args);
13673 emit_jump_insn (gen_simple_return_pop_internal (popc));
13678 (define_insn "simple_return_internal"
13681 "* return ix86_output_function_return (false);"
13682 [(set_attr "length" "1")
13683 (set_attr "atom_unit" "jeu")
13684 (set_attr "length_immediate" "0")
13685 (set_attr "modrm" "0")])
13687 (define_insn "interrupt_return"
13689 (unspec [(const_int 0)] UNSPEC_INTERRUPT_RETURN)]
13692 return TARGET_64BIT ? (TARGET_UINTR ? "uiret" : "iretq") : "iret";
13695 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
13696 ;; instruction Athlon and K8 have.
13698 (define_insn "simple_return_internal_long"
13700 (unspec [(const_int 0)] UNSPEC_REP)]
13702 "* return ix86_output_function_return (true);"
13703 [(set_attr "length" "2")
13704 (set_attr "atom_unit" "jeu")
13705 (set_attr "length_immediate" "0")
13706 (set_attr "prefix_rep" "1")
13707 (set_attr "modrm" "0")])
13709 (define_insn_and_split "simple_return_pop_internal"
13711 (use (match_operand:SI 0 "const_int_operand"))]
13714 "&& cfun->machine->function_return_type != indirect_branch_keep"
13716 "ix86_split_simple_return_pop_internal (operands[0]); DONE;"
13717 [(set_attr "length" "3")
13718 (set_attr "atom_unit" "jeu")
13719 (set_attr "length_immediate" "2")
13720 (set_attr "modrm" "0")])
13722 (define_expand "simple_return_indirect_internal"
13725 (use (match_operand 0 "register_operand"))])])
13727 (define_insn "*simple_return_indirect_internal<mode>"
13729 (use (match_operand:W 0 "register_operand" "r"))]
13731 "* return ix86_output_indirect_function_return (operands[0]);"
13732 [(set (attr "type")
13733 (if_then_else (match_test "(cfun->machine->indirect_branch_type
13734 != indirect_branch_keep)")
13735 (const_string "multi")
13736 (const_string "ibr")))
13737 (set_attr "length_immediate" "0")])
13743 [(set_attr "length" "1")
13744 (set_attr "length_immediate" "0")
13745 (set_attr "modrm" "0")])
13747 ;; Generate nops. Operand 0 is the number of nops, up to 8.
13748 (define_insn "nops"
13749 [(unspec_volatile [(match_operand 0 "const_int_operand")]
13753 int num = INTVAL (operands[0]);
13755 gcc_assert (IN_RANGE (num, 1, 8));
13758 fputs ("\tnop\n", asm_out_file);
13762 [(set (attr "length") (symbol_ref "INTVAL (operands[0])"))
13763 (set_attr "length_immediate" "0")
13764 (set_attr "modrm" "0")])
13766 ;; Pad to 16-byte boundary, max skip in op0. Used to avoid
13767 ;; branch prediction penalty for the third jump in a 16-byte
13771 [(unspec_volatile [(match_operand 0)] UNSPECV_ALIGN)]
13774 #ifdef ASM_OUTPUT_MAX_SKIP_PAD
13775 ASM_OUTPUT_MAX_SKIP_PAD (asm_out_file, 4, (int)INTVAL (operands[0]));
13777 /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
13778 The align insn is used to avoid 3 jump instructions in the row to improve
13779 branch prediction and the benefits hardly outweigh the cost of extra 8
13780 nops on the average inserted by full alignment pseudo operation. */
13784 [(set_attr "length" "16")])
13786 (define_expand "prologue"
13789 "ix86_expand_prologue (); DONE;")
13791 (define_expand "set_got"
13793 [(set (match_operand:SI 0 "register_operand")
13794 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
13795 (clobber (reg:CC FLAGS_REG))])]
13798 if (flag_pic && !TARGET_VXWORKS_RTP)
13799 ix86_pc_thunk_call_expanded = true;
13802 (define_insn "*set_got"
13803 [(set (match_operand:SI 0 "register_operand" "=r")
13804 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
13805 (clobber (reg:CC FLAGS_REG))]
13807 "* return output_set_got (operands[0], NULL_RTX);"
13808 [(set_attr "type" "multi")
13809 (set_attr "length" "12")])
13811 (define_expand "set_got_labelled"
13813 [(set (match_operand:SI 0 "register_operand")
13814 (unspec:SI [(label_ref (match_operand 1))]
13816 (clobber (reg:CC FLAGS_REG))])]
13819 if (flag_pic && !TARGET_VXWORKS_RTP)
13820 ix86_pc_thunk_call_expanded = true;
13823 (define_insn "*set_got_labelled"
13824 [(set (match_operand:SI 0 "register_operand" "=r")
13825 (unspec:SI [(label_ref (match_operand 1))]
13827 (clobber (reg:CC FLAGS_REG))]
13829 "* return output_set_got (operands[0], operands[1]);"
13830 [(set_attr "type" "multi")
13831 (set_attr "length" "12")])
13833 (define_insn "set_got_rex64"
13834 [(set (match_operand:DI 0 "register_operand" "=r")
13835 (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
13837 "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}"
13838 [(set_attr "type" "lea")
13839 (set_attr "length_address" "4")
13840 (set_attr "mode" "DI")])
13842 (define_insn "set_rip_rex64"
13843 [(set (match_operand:DI 0 "register_operand" "=r")
13844 (unspec:DI [(label_ref (match_operand 1))] UNSPEC_SET_RIP))]
13846 "lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}"
13847 [(set_attr "type" "lea")
13848 (set_attr "length_address" "4")
13849 (set_attr "mode" "DI")])
13851 (define_insn "set_got_offset_rex64"
13852 [(set (match_operand:DI 0 "register_operand" "=r")
13854 [(label_ref (match_operand 1))]
13855 UNSPEC_SET_GOT_OFFSET))]
13857 "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}"
13858 [(set_attr "type" "imov")
13859 (set_attr "length_immediate" "0")
13860 (set_attr "length_address" "8")
13861 (set_attr "mode" "DI")])
13863 (define_expand "epilogue"
13866 "ix86_expand_epilogue (1); DONE;")
13868 (define_expand "sibcall_epilogue"
13871 "ix86_expand_epilogue (0); DONE;")
13873 (define_expand "eh_return"
13874 [(use (match_operand 0 "register_operand"))]
13877 rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
13879 /* Tricky bit: we write the address of the handler to which we will
13880 be returning into someone else's stack frame, one word below the
13881 stack address we wish to restore. */
13882 tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
13883 tmp = plus_constant (Pmode, tmp, -UNITS_PER_WORD);
13884 /* Return address is always in word_mode. */
13885 tmp = gen_rtx_MEM (word_mode, tmp);
13886 if (GET_MODE (ra) != word_mode)
13887 ra = convert_to_mode (word_mode, ra, 1);
13888 emit_move_insn (tmp, ra);
13890 emit_jump_insn (gen_eh_return_internal ());
13895 (define_insn_and_split "eh_return_internal"
13899 "epilogue_completed"
13901 "ix86_expand_epilogue (2); DONE;")
13903 (define_expand "@leave_<mode>"
13905 [(set (reg:W SP_REG) (plus:W (reg:W BP_REG) (match_dup 0)))
13906 (set (reg:W BP_REG) (mem:W (reg:W BP_REG)))
13907 (clobber (mem:BLK (scratch)))])]
13909 "operands[0] = GEN_INT (<MODE_SIZE>);")
13911 (define_insn "*leave"
13912 [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
13913 (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
13914 (clobber (mem:BLK (scratch)))]
13917 [(set_attr "type" "leave")])
13919 (define_insn "*leave_rex64"
13920 [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
13921 (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
13922 (clobber (mem:BLK (scratch)))]
13925 [(set_attr "type" "leave")])
13927 ;; Handle -fsplit-stack.
13929 (define_expand "split_stack_prologue"
13933 ix86_expand_split_stack_prologue ();
13937 ;; In order to support the call/return predictor, we use a return
13938 ;; instruction which the middle-end doesn't see.
13939 (define_insn "split_stack_return"
13940 [(unspec_volatile [(match_operand:SI 0 "const_int_operand")]
13941 UNSPECV_SPLIT_STACK_RETURN)]
13944 if (operands[0] == const0_rtx)
13949 [(set_attr "atom_unit" "jeu")
13950 (set_attr "modrm" "0")
13951 (set (attr "length")
13952 (if_then_else (match_operand:SI 0 "const0_operand")
13955 (set (attr "length_immediate")
13956 (if_then_else (match_operand:SI 0 "const0_operand")
13960 ;; If there are operand 0 bytes available on the stack, jump to
13963 (define_expand "split_stack_space_check"
13964 [(set (pc) (if_then_else
13965 (ltu (minus (reg SP_REG)
13966 (match_operand 0 "register_operand"))
13968 (label_ref (match_operand 1))
13972 rtx reg = gen_reg_rtx (Pmode);
13974 emit_insn (gen_sub3_insn (reg, stack_pointer_rtx, operands[0]));
13976 operands[2] = ix86_split_stack_guard ();
13977 ix86_expand_branch (GEU, reg, operands[2], operands[1]);
13982 ;; Bit manipulation instructions.
13984 (define_expand "ffs<mode>2"
13985 [(set (match_dup 2) (const_int -1))
13986 (parallel [(set (match_dup 3) (match_dup 4))
13987 (set (match_operand:SWI48 0 "register_operand")
13989 (match_operand:SWI48 1 "nonimmediate_operand")))])
13990 (set (match_dup 0) (if_then_else:SWI48
13991 (eq (match_dup 3) (const_int 0))
13994 (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (const_int 1)))
13995 (clobber (reg:CC FLAGS_REG))])]
13998 machine_mode flags_mode;
14000 if (<MODE>mode == SImode && !TARGET_CMOVE)
14002 emit_insn (gen_ffssi2_no_cmove (operands[0], operands [1]));
14006 flags_mode = TARGET_BMI ? CCCmode : CCZmode;
14008 operands[2] = gen_reg_rtx (<MODE>mode);
14009 operands[3] = gen_rtx_REG (flags_mode, FLAGS_REG);
14010 operands[4] = gen_rtx_COMPARE (flags_mode, operands[1], const0_rtx);
14013 (define_insn_and_split "ffssi2_no_cmove"
14014 [(set (match_operand:SI 0 "register_operand" "=r")
14015 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14016 (clobber (match_scratch:SI 2 "=&q"))
14017 (clobber (reg:CC FLAGS_REG))]
14020 "&& reload_completed"
14021 [(parallel [(set (match_dup 4) (match_dup 5))
14022 (set (match_dup 0) (ctz:SI (match_dup 1)))])
14023 (set (strict_low_part (match_dup 3))
14024 (eq:QI (match_dup 4) (const_int 0)))
14025 (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
14026 (clobber (reg:CC FLAGS_REG))])
14027 (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
14028 (clobber (reg:CC FLAGS_REG))])
14029 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
14030 (clobber (reg:CC FLAGS_REG))])]
14032 machine_mode flags_mode = TARGET_BMI ? CCCmode : CCZmode;
14034 operands[3] = gen_lowpart (QImode, operands[2]);
14035 operands[4] = gen_rtx_REG (flags_mode, FLAGS_REG);
14036 operands[5] = gen_rtx_COMPARE (flags_mode, operands[1], const0_rtx);
14038 ix86_expand_clear (operands[2]);
14041 (define_insn_and_split "*tzcnt<mode>_1"
14042 [(set (reg:CCC FLAGS_REG)
14043 (compare:CCC (match_operand:SWI48 1 "nonimmediate_operand" "rm")
14045 (set (match_operand:SWI48 0 "register_operand" "=r")
14046 (ctz:SWI48 (match_dup 1)))]
14048 "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
14049 "&& TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
14050 && optimize_function_for_speed_p (cfun)
14051 && !reg_mentioned_p (operands[0], operands[1])"
14053 [(set (reg:CCC FLAGS_REG)
14054 (compare:CCC (match_dup 1) (const_int 0)))
14056 (ctz:SWI48 (match_dup 1)))
14057 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)])]
14058 "ix86_expand_clear (operands[0]);"
14059 [(set_attr "type" "alu1")
14060 (set_attr "prefix_0f" "1")
14061 (set_attr "prefix_rep" "1")
14062 (set_attr "btver2_decode" "double")
14063 (set_attr "mode" "<MODE>")])
14065 ; False dependency happens when destination is only updated by tzcnt,
14066 ; lzcnt or popcnt. There is no false dependency when destination is
14067 ; also used in source.
14068 (define_insn "*tzcnt<mode>_1_falsedep"
14069 [(set (reg:CCC FLAGS_REG)
14070 (compare:CCC (match_operand:SWI48 1 "nonimmediate_operand" "rm")
14072 (set (match_operand:SWI48 0 "register_operand" "=r")
14073 (ctz:SWI48 (match_dup 1)))
14074 (unspec [(match_operand:SWI48 2 "register_operand" "0")]
14075 UNSPEC_INSN_FALSE_DEP)]
14077 "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
14078 [(set_attr "type" "alu1")
14079 (set_attr "prefix_0f" "1")
14080 (set_attr "prefix_rep" "1")
14081 (set_attr "btver2_decode" "double")
14082 (set_attr "mode" "<MODE>")])
14084 (define_insn "*bsf<mode>_1"
14085 [(set (reg:CCZ FLAGS_REG)
14086 (compare:CCZ (match_operand:SWI48 1 "nonimmediate_operand" "rm")
14088 (set (match_operand:SWI48 0 "register_operand" "=r")
14089 (ctz:SWI48 (match_dup 1)))]
14091 "bsf{<imodesuffix>}\t{%1, %0|%0, %1}"
14092 [(set_attr "type" "alu1")
14093 (set_attr "prefix_0f" "1")
14094 (set_attr "btver2_decode" "double")
14095 (set_attr "znver1_decode" "vector")
14096 (set_attr "mode" "<MODE>")])
14098 (define_insn_and_split "ctz<mode>2"
14099 [(set (match_operand:SWI48 0 "register_operand" "=r")
14101 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
14102 (clobber (reg:CC FLAGS_REG))]
14106 return "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
14107 else if (optimize_function_for_size_p (cfun))
14109 else if (TARGET_GENERIC)
14110 /* tzcnt expands to 'rep bsf' and we can use it even if !TARGET_BMI. */
14111 return "rep%; bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
14113 return "bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
14115 "(TARGET_BMI || TARGET_GENERIC)
14116 && TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
14117 && optimize_function_for_speed_p (cfun)
14118 && !reg_mentioned_p (operands[0], operands[1])"
14120 [(set (match_dup 0)
14121 (ctz:SWI48 (match_dup 1)))
14122 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
14123 (clobber (reg:CC FLAGS_REG))])]
14124 "ix86_expand_clear (operands[0]);"
14125 [(set_attr "type" "alu1")
14126 (set_attr "prefix_0f" "1")
14127 (set (attr "prefix_rep")
14129 (ior (match_test "TARGET_BMI")
14130 (and (not (match_test "optimize_function_for_size_p (cfun)"))
14131 (match_test "TARGET_GENERIC")))
14133 (const_string "0")))
14134 (set_attr "mode" "<MODE>")])
14136 ; False dependency happens when destination is only updated by tzcnt,
14137 ; lzcnt or popcnt. There is no false dependency when destination is
14138 ; also used in source.
14139 (define_insn "*ctz<mode>2_falsedep"
14140 [(set (match_operand:SWI48 0 "register_operand" "=r")
14142 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
14143 (unspec [(match_operand:SWI48 2 "register_operand" "0")]
14144 UNSPEC_INSN_FALSE_DEP)
14145 (clobber (reg:CC FLAGS_REG))]
14149 return "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
14150 else if (TARGET_GENERIC)
14151 /* tzcnt expands to 'rep bsf' and we can use it even if !TARGET_BMI. */
14152 return "rep%; bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
14154 gcc_unreachable ();
14156 [(set_attr "type" "alu1")
14157 (set_attr "prefix_0f" "1")
14158 (set_attr "prefix_rep" "1")
14159 (set_attr "mode" "<MODE>")])
14161 (define_insn_and_split "*ctzsi2_zext"
14162 [(set (match_operand:DI 0 "register_operand" "=r")
14166 (match_operand:SI 1 "nonimmediate_operand" "rm")) 0)
14168 (clobber (reg:CC FLAGS_REG))]
14169 "TARGET_BMI && TARGET_64BIT"
14170 "tzcnt{l}\t{%1, %k0|%k0, %1}"
14171 "&& TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
14172 && optimize_function_for_speed_p (cfun)
14173 && !reg_mentioned_p (operands[0], operands[1])"
14175 [(set (match_dup 0)
14176 (and:DI (subreg:DI (ctz:SI (match_dup 1)) 0) (const_int 63)))
14177 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
14178 (clobber (reg:CC FLAGS_REG))])]
14179 "ix86_expand_clear (operands[0]);"
14180 [(set_attr "type" "alu1")
14181 (set_attr "prefix_0f" "1")
14182 (set_attr "prefix_rep" "1")
14183 (set_attr "mode" "SI")])
14185 ; False dependency happens when destination is only updated by tzcnt,
14186 ; lzcnt or popcnt. There is no false dependency when destination is
14187 ; also used in source.
14188 (define_insn "*ctzsi2_zext_falsedep"
14189 [(set (match_operand:DI 0 "register_operand" "=r")
14193 (match_operand:SI 1 "nonimmediate_operand" "rm")) 0)
14195 (unspec [(match_operand:DI 2 "register_operand" "0")]
14196 UNSPEC_INSN_FALSE_DEP)
14197 (clobber (reg:CC FLAGS_REG))]
14198 "TARGET_BMI && TARGET_64BIT"
14199 "tzcnt{l}\t{%1, %k0|%k0, %1}"
14200 [(set_attr "type" "alu1")
14201 (set_attr "prefix_0f" "1")
14202 (set_attr "prefix_rep" "1")
14203 (set_attr "mode" "SI")])
14205 (define_insn "bsr_rex64"
14206 [(set (match_operand:DI 0 "register_operand" "=r")
14207 (minus:DI (const_int 63)
14208 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
14209 (clobber (reg:CC FLAGS_REG))]
14211 "bsr{q}\t{%1, %0|%0, %1}"
14212 [(set_attr "type" "alu1")
14213 (set_attr "prefix_0f" "1")
14214 (set_attr "znver1_decode" "vector")
14215 (set_attr "mode" "DI")])
14218 [(set (match_operand:SI 0 "register_operand" "=r")
14219 (minus:SI (const_int 31)
14220 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
14221 (clobber (reg:CC FLAGS_REG))]
14223 "bsr{l}\t{%1, %0|%0, %1}"
14224 [(set_attr "type" "alu1")
14225 (set_attr "prefix_0f" "1")
14226 (set_attr "znver1_decode" "vector")
14227 (set_attr "mode" "SI")])
14229 (define_insn "*bsrhi"
14230 [(set (match_operand:HI 0 "register_operand" "=r")
14231 (minus:HI (const_int 15)
14232 (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
14233 (clobber (reg:CC FLAGS_REG))]
14235 "bsr{w}\t{%1, %0|%0, %1}"
14236 [(set_attr "type" "alu1")
14237 (set_attr "prefix_0f" "1")
14238 (set_attr "znver1_decode" "vector")
14239 (set_attr "mode" "HI")])
14241 (define_expand "clz<mode>2"
14243 [(set (match_operand:SWI48 0 "register_operand")
14246 (clz:SWI48 (match_operand:SWI48 1 "nonimmediate_operand"))))
14247 (clobber (reg:CC FLAGS_REG))])
14249 [(set (match_dup 0) (xor:SWI48 (match_dup 0) (match_dup 2)))
14250 (clobber (reg:CC FLAGS_REG))])]
14255 emit_insn (gen_clz<mode>2_lzcnt (operands[0], operands[1]));
14258 operands[2] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
14261 (define_insn_and_split "clz<mode>2_lzcnt"
14262 [(set (match_operand:SWI48 0 "register_operand" "=r")
14264 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
14265 (clobber (reg:CC FLAGS_REG))]
14267 "lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
14268 "&& TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
14269 && optimize_function_for_speed_p (cfun)
14270 && !reg_mentioned_p (operands[0], operands[1])"
14272 [(set (match_dup 0)
14273 (clz:SWI48 (match_dup 1)))
14274 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
14275 (clobber (reg:CC FLAGS_REG))])]
14276 "ix86_expand_clear (operands[0]);"
14277 [(set_attr "prefix_rep" "1")
14278 (set_attr "type" "bitmanip")
14279 (set_attr "mode" "<MODE>")])
14281 ; False dependency happens when destination is only updated by tzcnt,
14282 ; lzcnt or popcnt. There is no false dependency when destination is
14283 ; also used in source.
14284 (define_insn "*clz<mode>2_lzcnt_falsedep"
14285 [(set (match_operand:SWI48 0 "register_operand" "=r")
14287 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
14288 (unspec [(match_operand:SWI48 2 "register_operand" "0")]
14289 UNSPEC_INSN_FALSE_DEP)
14290 (clobber (reg:CC FLAGS_REG))]
14292 "lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
14293 [(set_attr "prefix_rep" "1")
14294 (set_attr "type" "bitmanip")
14295 (set_attr "mode" "<MODE>")])
14297 (define_insn_and_split "*clzsi2_lzcnt_zext"
14298 [(set (match_operand:DI 0 "register_operand" "=r")
14302 (match_operand:SI 1 "nonimmediate_operand" "rm")) 0)
14304 (clobber (reg:CC FLAGS_REG))]
14305 "TARGET_LZCNT && TARGET_64BIT"
14306 "lzcnt{l}\t{%1, %k0|%k0, %1}"
14307 "&& TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
14308 && optimize_function_for_speed_p (cfun)
14309 && !reg_mentioned_p (operands[0], operands[1])"
14311 [(set (match_dup 0)
14312 (and:DI (subreg:DI (clz:SI (match_dup 1)) 0) (const_int 63)))
14313 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
14314 (clobber (reg:CC FLAGS_REG))])]
14315 "ix86_expand_clear (operands[0]);"
14316 [(set_attr "prefix_rep" "1")
14317 (set_attr "type" "bitmanip")
14318 (set_attr "mode" "SI")])
14320 ; False dependency happens when destination is only updated by tzcnt,
14321 ; lzcnt or popcnt. There is no false dependency when destination is
14322 ; also used in source.
14323 (define_insn "*clzsi2_lzcnt_zext_falsedep"
14324 [(set (match_operand:DI 0 "register_operand" "=r")
14328 (match_operand:SWI48 1 "nonimmediate_operand" "rm")) 0)
14330 (unspec [(match_operand:DI 2 "register_operand" "0")]
14331 UNSPEC_INSN_FALSE_DEP)
14332 (clobber (reg:CC FLAGS_REG))]
14334 "lzcnt{l}\t{%1, %k0|%k0, %1}"
14335 [(set_attr "prefix_rep" "1")
14336 (set_attr "type" "bitmanip")
14337 (set_attr "mode" "SI")])
14339 (define_int_iterator LT_ZCNT
14340 [(UNSPEC_TZCNT "TARGET_BMI")
14341 (UNSPEC_LZCNT "TARGET_LZCNT")])
14343 (define_int_attr lt_zcnt
14344 [(UNSPEC_TZCNT "tzcnt")
14345 (UNSPEC_LZCNT "lzcnt")])
14347 (define_int_attr lt_zcnt_type
14348 [(UNSPEC_TZCNT "alu1")
14349 (UNSPEC_LZCNT "bitmanip")])
14351 ;; Version of lzcnt/tzcnt that is expanded from intrinsics. This version
14352 ;; provides operand size as output when source operand is zero.
14354 (define_insn_and_split "<lt_zcnt>_<mode>"
14355 [(set (match_operand:SWI48 0 "register_operand" "=r")
14357 [(match_operand:SWI48 1 "nonimmediate_operand" "rm")] LT_ZCNT))
14358 (clobber (reg:CC FLAGS_REG))]
14360 "<lt_zcnt>{<imodesuffix>}\t{%1, %0|%0, %1}"
14361 "&& TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
14362 && optimize_function_for_speed_p (cfun)
14363 && !reg_mentioned_p (operands[0], operands[1])"
14365 [(set (match_dup 0)
14366 (unspec:SWI48 [(match_dup 1)] LT_ZCNT))
14367 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
14368 (clobber (reg:CC FLAGS_REG))])]
14369 "ix86_expand_clear (operands[0]);"
14370 [(set_attr "type" "<lt_zcnt_type>")
14371 (set_attr "prefix_0f" "1")
14372 (set_attr "prefix_rep" "1")
14373 (set_attr "mode" "<MODE>")])
14375 ; False dependency happens when destination is only updated by tzcnt,
14376 ; lzcnt or popcnt. There is no false dependency when destination is
14377 ; also used in source.
14378 (define_insn "*<lt_zcnt>_<mode>_falsedep"
14379 [(set (match_operand:SWI48 0 "register_operand" "=r")
14381 [(match_operand:SWI48 1 "nonimmediate_operand" "rm")] LT_ZCNT))
14382 (unspec [(match_operand:SWI48 2 "register_operand" "0")]
14383 UNSPEC_INSN_FALSE_DEP)
14384 (clobber (reg:CC FLAGS_REG))]
14386 "<lt_zcnt>{<imodesuffix>}\t{%1, %0|%0, %1}"
14387 [(set_attr "type" "<lt_zcnt_type>")
14388 (set_attr "prefix_0f" "1")
14389 (set_attr "prefix_rep" "1")
14390 (set_attr "mode" "<MODE>")])
14392 (define_insn "<lt_zcnt>_hi"
14393 [(set (match_operand:HI 0 "register_operand" "=r")
14395 [(match_operand:HI 1 "nonimmediate_operand" "rm")] LT_ZCNT))
14396 (clobber (reg:CC FLAGS_REG))]
14398 "<lt_zcnt>{w}\t{%1, %0|%0, %1}"
14399 [(set_attr "type" "<lt_zcnt_type>")
14400 (set_attr "prefix_0f" "1")
14401 (set_attr "prefix_rep" "1")
14402 (set_attr "mode" "HI")])
14404 ;; BMI instructions.
14406 (define_insn "bmi_bextr_<mode>"
14407 [(set (match_operand:SWI48 0 "register_operand" "=r,r")
14408 (unspec:SWI48 [(match_operand:SWI48 1 "nonimmediate_operand" "r,m")
14409 (match_operand:SWI48 2 "register_operand" "r,r")]
14411 (clobber (reg:CC FLAGS_REG))]
14413 "bextr\t{%2, %1, %0|%0, %1, %2}"
14414 [(set_attr "type" "bitmanip")
14415 (set_attr "btver2_decode" "direct, double")
14416 (set_attr "mode" "<MODE>")])
14418 (define_insn "*bmi_bextr_<mode>_ccz"
14419 [(set (reg:CCZ FLAGS_REG)
14421 (unspec:SWI48 [(match_operand:SWI48 1 "nonimmediate_operand" "r,m")
14422 (match_operand:SWI48 2 "register_operand" "r,r")]
14425 (clobber (match_scratch:SWI48 0 "=r,r"))]
14427 "bextr\t{%2, %1, %0|%0, %1, %2}"
14428 [(set_attr "type" "bitmanip")
14429 (set_attr "btver2_decode" "direct, double")
14430 (set_attr "mode" "<MODE>")])
14432 (define_insn "*bmi_blsi_<mode>"
14433 [(set (match_operand:SWI48 0 "register_operand" "=r")
14436 (match_operand:SWI48 1 "nonimmediate_operand" "rm"))
14438 (clobber (reg:CC FLAGS_REG))]
14440 "blsi\t{%1, %0|%0, %1}"
14441 [(set_attr "type" "bitmanip")
14442 (set_attr "btver2_decode" "double")
14443 (set_attr "mode" "<MODE>")])
14445 (define_insn "*bmi_blsmsk_<mode>"
14446 [(set (match_operand:SWI48 0 "register_operand" "=r")
14449 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
14452 (clobber (reg:CC FLAGS_REG))]
14454 "blsmsk\t{%1, %0|%0, %1}"
14455 [(set_attr "type" "bitmanip")
14456 (set_attr "btver2_decode" "double")
14457 (set_attr "mode" "<MODE>")])
14459 (define_insn "*bmi_blsr_<mode>"
14460 [(set (match_operand:SWI48 0 "register_operand" "=r")
14463 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
14466 (clobber (reg:CC FLAGS_REG))]
14468 "blsr\t{%1, %0|%0, %1}"
14469 [(set_attr "type" "bitmanip")
14470 (set_attr "btver2_decode" "double")
14471 (set_attr "mode" "<MODE>")])
14473 (define_insn "*bmi_blsr_<mode>_cmp"
14474 [(set (reg:CCZ FLAGS_REG)
14478 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
14482 (set (match_operand:SWI48 0 "register_operand" "=r")
14489 "blsr\t{%1, %0|%0, %1}"
14490 [(set_attr "type" "bitmanip")
14491 (set_attr "btver2_decode" "double")
14492 (set_attr "mode" "<MODE>")])
14494 (define_insn "*bmi_blsr_<mode>_ccz"
14495 [(set (reg:CCZ FLAGS_REG)
14499 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
14503 (clobber (match_scratch:SWI48 0 "=r"))]
14505 "blsr\t{%1, %0|%0, %1}"
14506 [(set_attr "type" "bitmanip")
14507 (set_attr "btver2_decode" "double")
14508 (set_attr "mode" "<MODE>")])
14510 ;; BMI2 instructions.
14511 (define_expand "bmi2_bzhi_<mode>3"
14513 [(set (match_operand:SWI48 0 "register_operand")
14514 (if_then_else:SWI48
14515 (ne:QI (and:SWI48 (match_operand:SWI48 2 "register_operand")
14518 (zero_extract:SWI48
14519 (match_operand:SWI48 1 "nonimmediate_operand")
14520 (umin:SWI48 (and:SWI48 (match_dup 2) (const_int 255))
14524 (clobber (reg:CC FLAGS_REG))])]
14526 "operands[3] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT);")
14528 (define_insn "*bmi2_bzhi_<mode>3"
14529 [(set (match_operand:SWI48 0 "register_operand" "=r")
14530 (if_then_else:SWI48
14531 (ne:QI (and:SWI48 (match_operand:SWI48 2 "register_operand" "r")
14534 (zero_extract:SWI48
14535 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
14536 (umin:SWI48 (and:SWI48 (match_dup 2) (const_int 255))
14537 (match_operand:SWI48 3 "const_int_operand" "n"))
14540 (clobber (reg:CC FLAGS_REG))]
14541 "TARGET_BMI2 && INTVAL (operands[3]) == <MODE_SIZE> * BITS_PER_UNIT"
14542 "bzhi\t{%2, %1, %0|%0, %1, %2}"
14543 [(set_attr "type" "bitmanip")
14544 (set_attr "prefix" "vex")
14545 (set_attr "mode" "<MODE>")])
14547 (define_insn "*bmi2_bzhi_<mode>3_1"
14548 [(set (match_operand:SWI48 0 "register_operand" "=r")
14549 (if_then_else:SWI48
14550 (ne:QI (match_operand:QI 2 "register_operand" "r") (const_int 0))
14551 (zero_extract:SWI48
14552 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
14553 (umin:SWI48 (zero_extend:SWI48 (match_dup 2))
14554 (match_operand:SWI48 3 "const_int_operand" "n"))
14557 (clobber (reg:CC FLAGS_REG))]
14558 "TARGET_BMI2 && INTVAL (operands[3]) == <MODE_SIZE> * BITS_PER_UNIT"
14559 "bzhi\t{%<k>2, %1, %0|%0, %1, %<k>2}"
14560 [(set_attr "type" "bitmanip")
14561 (set_attr "prefix" "vex")
14562 (set_attr "mode" "<MODE>")])
14564 (define_insn "*bmi2_bzhi_<mode>3_1_ccz"
14565 [(set (reg:CCZ FLAGS_REG)
14567 (if_then_else:SWI48
14568 (ne:QI (match_operand:QI 2 "register_operand" "r") (const_int 0))
14569 (zero_extract:SWI48
14570 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
14571 (umin:SWI48 (zero_extend:SWI48 (match_dup 2))
14572 (match_operand:SWI48 3 "const_int_operand" "n"))
14576 (clobber (match_scratch:SWI48 0 "=r"))]
14577 "TARGET_BMI2 && INTVAL (operands[3]) == <MODE_SIZE> * BITS_PER_UNIT"
14578 "bzhi\t{%<k>2, %1, %0|%0, %1, %<k>2}"
14579 [(set_attr "type" "bitmanip")
14580 (set_attr "prefix" "vex")
14581 (set_attr "mode" "<MODE>")])
14583 (define_insn "*bmi2_bzhi_<mode>3_2"
14584 [(set (match_operand:SWI48 0 "register_operand" "=r")
14587 (ashift:SWI48 (const_int 1)
14588 (match_operand:QI 2 "register_operand" "r"))
14590 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
14591 (clobber (reg:CC FLAGS_REG))]
14593 "bzhi\t{%<k>2, %1, %0|%0, %1, %<k>2}"
14594 [(set_attr "type" "bitmanip")
14595 (set_attr "prefix" "vex")
14596 (set_attr "mode" "<MODE>")])
14598 (define_insn "*bmi2_bzhi_<mode>3_3"
14599 [(set (match_operand:SWI48 0 "register_operand" "=r")
14602 (ashift:SWI48 (const_int -1)
14603 (match_operand:QI 2 "register_operand" "r")))
14604 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
14605 (clobber (reg:CC FLAGS_REG))]
14607 "bzhi\t{%<k>2, %1, %0|%0, %1, %<k>2}"
14608 [(set_attr "type" "bitmanip")
14609 (set_attr "prefix" "vex")
14610 (set_attr "mode" "<MODE>")])
14612 (define_insn "bmi2_pdep_<mode>3"
14613 [(set (match_operand:SWI48 0 "register_operand" "=r")
14614 (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
14615 (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
14618 "pdep\t{%2, %1, %0|%0, %1, %2}"
14619 [(set_attr "type" "bitmanip")
14620 (set_attr "prefix" "vex")
14621 (set_attr "mode" "<MODE>")])
14623 (define_insn "bmi2_pext_<mode>3"
14624 [(set (match_operand:SWI48 0 "register_operand" "=r")
14625 (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
14626 (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
14629 "pext\t{%2, %1, %0|%0, %1, %2}"
14630 [(set_attr "type" "bitmanip")
14631 (set_attr "prefix" "vex")
14632 (set_attr "mode" "<MODE>")])
14634 ;; TBM instructions.
14635 (define_insn "@tbm_bextri_<mode>"
14636 [(set (match_operand:SWI48 0 "register_operand" "=r")
14637 (zero_extract:SWI48
14638 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
14639 (match_operand 2 "const_0_to_255_operand" "N")
14640 (match_operand 3 "const_0_to_255_operand" "N")))
14641 (clobber (reg:CC FLAGS_REG))]
14644 operands[2] = GEN_INT (INTVAL (operands[2]) << 8 | INTVAL (operands[3]));
14645 return "bextr\t{%2, %1, %0|%0, %1, %2}";
14647 [(set_attr "type" "bitmanip")
14648 (set_attr "mode" "<MODE>")])
14650 (define_insn "*tbm_blcfill_<mode>"
14651 [(set (match_operand:SWI48 0 "register_operand" "=r")
14654 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
14657 (clobber (reg:CC FLAGS_REG))]
14659 "blcfill\t{%1, %0|%0, %1}"
14660 [(set_attr "type" "bitmanip")
14661 (set_attr "mode" "<MODE>")])
14663 (define_insn "*tbm_blci_<mode>"
14664 [(set (match_operand:SWI48 0 "register_operand" "=r")
14668 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
14671 (clobber (reg:CC FLAGS_REG))]
14673 "blci\t{%1, %0|%0, %1}"
14674 [(set_attr "type" "bitmanip")
14675 (set_attr "mode" "<MODE>")])
14677 (define_insn "*tbm_blcic_<mode>"
14678 [(set (match_operand:SWI48 0 "register_operand" "=r")
14681 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
14685 (clobber (reg:CC FLAGS_REG))]
14687 "blcic\t{%1, %0|%0, %1}"
14688 [(set_attr "type" "bitmanip")
14689 (set_attr "mode" "<MODE>")])
14691 (define_insn "*tbm_blcmsk_<mode>"
14692 [(set (match_operand:SWI48 0 "register_operand" "=r")
14695 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
14698 (clobber (reg:CC FLAGS_REG))]
14700 "blcmsk\t{%1, %0|%0, %1}"
14701 [(set_attr "type" "bitmanip")
14702 (set_attr "mode" "<MODE>")])
14704 (define_insn "*tbm_blcs_<mode>"
14705 [(set (match_operand:SWI48 0 "register_operand" "=r")
14708 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
14711 (clobber (reg:CC FLAGS_REG))]
14713 "blcs\t{%1, %0|%0, %1}"
14714 [(set_attr "type" "bitmanip")
14715 (set_attr "mode" "<MODE>")])
14717 (define_insn "*tbm_blsfill_<mode>"
14718 [(set (match_operand:SWI48 0 "register_operand" "=r")
14721 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
14724 (clobber (reg:CC FLAGS_REG))]
14726 "blsfill\t{%1, %0|%0, %1}"
14727 [(set_attr "type" "bitmanip")
14728 (set_attr "mode" "<MODE>")])
14730 (define_insn "*tbm_blsic_<mode>"
14731 [(set (match_operand:SWI48 0 "register_operand" "=r")
14734 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
14738 (clobber (reg:CC FLAGS_REG))]
14740 "blsic\t{%1, %0|%0, %1}"
14741 [(set_attr "type" "bitmanip")
14742 (set_attr "mode" "<MODE>")])
14744 (define_insn "*tbm_t1mskc_<mode>"
14745 [(set (match_operand:SWI48 0 "register_operand" "=r")
14748 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
14752 (clobber (reg:CC FLAGS_REG))]
14754 "t1mskc\t{%1, %0|%0, %1}"
14755 [(set_attr "type" "bitmanip")
14756 (set_attr "mode" "<MODE>")])
14758 (define_insn "*tbm_tzmsk_<mode>"
14759 [(set (match_operand:SWI48 0 "register_operand" "=r")
14762 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
14766 (clobber (reg:CC FLAGS_REG))]
14768 "tzmsk\t{%1, %0|%0, %1}"
14769 [(set_attr "type" "bitmanip")
14770 (set_attr "mode" "<MODE>")])
14772 (define_insn_and_split "popcount<mode>2"
14773 [(set (match_operand:SWI48 0 "register_operand" "=r")
14775 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
14776 (clobber (reg:CC FLAGS_REG))]
14780 return "popcnt\t{%1, %0|%0, %1}";
14782 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
14785 "&& TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
14786 && optimize_function_for_speed_p (cfun)
14787 && !reg_mentioned_p (operands[0], operands[1])"
14789 [(set (match_dup 0)
14790 (popcount:SWI48 (match_dup 1)))
14791 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
14792 (clobber (reg:CC FLAGS_REG))])]
14793 "ix86_expand_clear (operands[0]);"
14794 [(set_attr "prefix_rep" "1")
14795 (set_attr "type" "bitmanip")
14796 (set_attr "mode" "<MODE>")])
14798 ; False dependency happens when destination is only updated by tzcnt,
14799 ; lzcnt or popcnt. There is no false dependency when destination is
14800 ; also used in source.
14801 (define_insn "*popcount<mode>2_falsedep"
14802 [(set (match_operand:SWI48 0 "register_operand" "=r")
14804 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
14805 (unspec [(match_operand:SWI48 2 "register_operand" "0")]
14806 UNSPEC_INSN_FALSE_DEP)
14807 (clobber (reg:CC FLAGS_REG))]
14811 return "popcnt\t{%1, %0|%0, %1}";
14813 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
14816 [(set_attr "prefix_rep" "1")
14817 (set_attr "type" "bitmanip")
14818 (set_attr "mode" "<MODE>")])
14820 (define_insn_and_split "*popcountsi2_zext"
14821 [(set (match_operand:DI 0 "register_operand" "=r")
14825 (match_operand:SI 1 "nonimmediate_operand" "rm")) 0)
14827 (clobber (reg:CC FLAGS_REG))]
14828 "TARGET_POPCNT && TARGET_64BIT"
14831 return "popcnt\t{%1, %k0|%k0, %1}";
14833 return "popcnt{l}\t{%1, %k0|%k0, %1}";
14836 "&& TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
14837 && optimize_function_for_speed_p (cfun)
14838 && !reg_mentioned_p (operands[0], operands[1])"
14840 [(set (match_dup 0)
14841 (and:DI (subreg:DI (popcount:SI (match_dup 1)) 0) (const_int 63)))
14842 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
14843 (clobber (reg:CC FLAGS_REG))])]
14844 "ix86_expand_clear (operands[0]);"
14845 [(set_attr "prefix_rep" "1")
14846 (set_attr "type" "bitmanip")
14847 (set_attr "mode" "SI")])
14849 ; False dependency happens when destination is only updated by tzcnt,
14850 ; lzcnt or popcnt. There is no false dependency when destination is
14851 ; also used in source.
14852 (define_insn "*popcountsi2_zext_falsedep"
14853 [(set (match_operand:DI 0 "register_operand" "=r")
14857 (match_operand:SI 1 "nonimmediate_operand" "rm")) 0)
14859 (unspec [(match_operand:DI 2 "register_operand" "0")]
14860 UNSPEC_INSN_FALSE_DEP)
14861 (clobber (reg:CC FLAGS_REG))]
14862 "TARGET_POPCNT && TARGET_64BIT"
14865 return "popcnt\t{%1, %k0|%k0, %1}";
14867 return "popcnt{l}\t{%1, %k0|%k0, %1}";
14870 [(set_attr "prefix_rep" "1")
14871 (set_attr "type" "bitmanip")
14872 (set_attr "mode" "SI")])
14874 (define_insn_and_split "*popcounthi2_1"
14875 [(set (match_operand:SI 0 "register_operand")
14877 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand"))))
14878 (clobber (reg:CC FLAGS_REG))]
14880 && ix86_pre_reload_split ()"
14885 rtx tmp = gen_reg_rtx (HImode);
14887 emit_insn (gen_popcounthi2 (tmp, operands[1]));
14888 emit_insn (gen_zero_extendhisi2 (operands[0], tmp));
14892 (define_insn "popcounthi2"
14893 [(set (match_operand:HI 0 "register_operand" "=r")
14895 (match_operand:HI 1 "nonimmediate_operand" "rm")))
14896 (clobber (reg:CC FLAGS_REG))]
14900 return "popcnt\t{%1, %0|%0, %1}";
14902 return "popcnt{w}\t{%1, %0|%0, %1}";
14905 [(set_attr "prefix_rep" "1")
14906 (set_attr "type" "bitmanip")
14907 (set_attr "mode" "HI")])
14909 (define_expand "bswapdi2"
14910 [(set (match_operand:DI 0 "register_operand")
14911 (bswap:DI (match_operand:DI 1 "nonimmediate_operand")))]
14915 operands[1] = force_reg (DImode, operands[1]);
14918 (define_expand "bswapsi2"
14919 [(set (match_operand:SI 0 "register_operand")
14920 (bswap:SI (match_operand:SI 1 "nonimmediate_operand")))]
14925 else if (TARGET_BSWAP)
14926 operands[1] = force_reg (SImode, operands[1]);
14929 rtx x = operands[0];
14931 emit_move_insn (x, operands[1]);
14932 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
14933 emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
14934 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
14939 (define_insn "*bswap<mode>2_movbe"
14940 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,r,m")
14941 (bswap:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,m,r")))]
14943 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
14946 movbe{<imodesuffix>}\t{%1, %0|%0, %1}
14947 movbe{<imodesuffix>}\t{%1, %0|%0, %1}"
14948 [(set_attr "type" "bitmanip,imov,imov")
14949 (set_attr "modrm" "0,1,1")
14950 (set_attr "prefix_0f" "*,1,1")
14951 (set_attr "prefix_extra" "*,1,1")
14952 (set_attr "mode" "<MODE>")])
14954 (define_insn "*bswap<mode>2"
14955 [(set (match_operand:SWI48 0 "register_operand" "=r")
14956 (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "0")))]
14959 [(set_attr "type" "bitmanip")
14960 (set_attr "modrm" "0")
14961 (set_attr "mode" "<MODE>")])
14963 (define_expand "bswaphi2"
14964 [(set (match_operand:HI 0 "register_operand")
14965 (bswap:HI (match_operand:HI 1 "nonimmediate_operand")))]
14968 (define_insn "*bswaphi2_movbe"
14969 [(set (match_operand:HI 0 "nonimmediate_operand" "=Q,r,m")
14970 (bswap:HI (match_operand:HI 1 "nonimmediate_operand" "0,m,r")))]
14972 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
14974 xchg{b}\t{%h0, %b0|%b0, %h0}
14975 movbe{w}\t{%1, %0|%0, %1}
14976 movbe{w}\t{%1, %0|%0, %1}"
14977 [(set_attr "type" "imov")
14978 (set_attr "modrm" "*,1,1")
14979 (set_attr "prefix_0f" "*,1,1")
14980 (set_attr "prefix_extra" "*,1,1")
14981 (set_attr "pent_pair" "np,*,*")
14982 (set_attr "athlon_decode" "vector,*,*")
14983 (set_attr "amdfam10_decode" "double,*,*")
14984 (set_attr "bdver1_decode" "double,*,*")
14985 (set_attr "mode" "QI,HI,HI")])
14988 [(set (match_operand:HI 0 "general_reg_operand")
14989 (bswap:HI (match_dup 0)))]
14991 && !(TARGET_USE_XCHGB || optimize_function_for_size_p (cfun))
14992 && peep2_regno_dead_p (0, FLAGS_REG)"
14993 [(parallel [(set (match_dup 0) (rotate:HI (match_dup 0) (const_int 8)))
14994 (clobber (reg:CC FLAGS_REG))])])
14996 (define_insn "bswaphi_lowpart"
14997 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
14998 (bswap:HI (match_dup 0)))
14999 (clobber (reg:CC FLAGS_REG))]
15002 xchg{b}\t{%h0, %b0|%b0, %h0}
15003 rol{w}\t{$8, %0|%0, 8}"
15004 [(set (attr "preferred_for_size")
15005 (cond [(eq_attr "alternative" "0")
15006 (symbol_ref "true")]
15007 (symbol_ref "false")))
15008 (set (attr "preferred_for_speed")
15009 (cond [(eq_attr "alternative" "0")
15010 (symbol_ref "TARGET_USE_XCHGB")]
15011 (symbol_ref "!TARGET_USE_XCHGB")))
15012 (set_attr "length" "2,4")
15013 (set_attr "mode" "QI,HI")])
15015 (define_expand "paritydi2"
15016 [(set (match_operand:DI 0 "register_operand")
15017 (parity:DI (match_operand:DI 1 "register_operand")))]
15020 rtx scratch = gen_reg_rtx (QImode);
15021 rtx hipart1 = gen_reg_rtx (SImode);
15022 rtx lopart1 = gen_reg_rtx (SImode);
15023 rtx xor1 = gen_reg_rtx (SImode);
15024 rtx shift2 = gen_reg_rtx (SImode);
15025 rtx hipart2 = gen_reg_rtx (HImode);
15026 rtx lopart2 = gen_reg_rtx (HImode);
15027 rtx xor2 = gen_reg_rtx (HImode);
15031 rtx shift1 = gen_reg_rtx (DImode);
15032 emit_insn (gen_lshrdi3 (shift1, operands[1], GEN_INT (32)));
15033 emit_move_insn (hipart1, gen_lowpart (SImode, shift1));
15036 emit_move_insn (hipart1, gen_highpart (SImode, operands[1]));
15038 emit_move_insn (lopart1, gen_lowpart (SImode, operands[1]));
15039 emit_insn (gen_xorsi3 (xor1, hipart1, lopart1));
15041 emit_insn (gen_lshrsi3 (shift2, xor1, GEN_INT (16)));
15042 emit_move_insn (hipart2, gen_lowpart (HImode, shift2));
15043 emit_move_insn (lopart2, gen_lowpart (HImode, xor1));
15044 emit_insn (gen_xorhi3 (xor2, hipart2, lopart2));
15046 emit_insn (gen_parityhi2_cmp (xor2));
15048 ix86_expand_setcc (scratch, ORDERED,
15049 gen_rtx_REG (CCmode, FLAGS_REG), const0_rtx);
15052 emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
15055 rtx tmp = gen_reg_rtx (SImode);
15057 emit_insn (gen_zero_extendqisi2 (tmp, scratch));
15058 emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
15063 (define_expand "paritysi2"
15064 [(set (match_operand:SI 0 "register_operand")
15065 (parity:SI (match_operand:SI 1 "register_operand")))]
15068 rtx scratch = gen_reg_rtx (QImode);
15069 rtx shift = gen_reg_rtx (SImode);
15070 rtx hipart = gen_reg_rtx (HImode);
15071 rtx lopart = gen_reg_rtx (HImode);
15072 rtx tmp = gen_reg_rtx (HImode);
15074 emit_insn (gen_lshrsi3 (shift, operands[1], GEN_INT (16)));
15075 emit_move_insn (hipart, gen_lowpart (HImode, shift));
15076 emit_move_insn (lopart, gen_lowpart (HImode, operands[1]));
15077 emit_insn (gen_xorhi3 (tmp, hipart, lopart));
15079 emit_insn (gen_parityhi2_cmp (tmp));
15081 ix86_expand_setcc (scratch, ORDERED,
15082 gen_rtx_REG (CCmode, FLAGS_REG), const0_rtx);
15084 emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
15088 (define_expand "parityhi2"
15089 [(set (match_operand:HI 0 "register_operand")
15090 (parity:HI (match_operand:HI 1 "register_operand")))]
15093 rtx scratch = gen_reg_rtx (QImode);
15095 emit_insn (gen_parityhi2_cmp (operands[1]));
15097 ix86_expand_setcc (scratch, ORDERED,
15098 gen_rtx_REG (CCmode, FLAGS_REG), const0_rtx);
15100 emit_insn (gen_zero_extendqihi2 (operands[0], scratch));
15104 (define_expand "parityqi2"
15105 [(set (match_operand:QI 0 "register_operand")
15106 (parity:QI (match_operand:QI 1 "register_operand")))]
15109 emit_insn (gen_parityqi2_cmp (operands[1]));
15111 ix86_expand_setcc (operands[0], ORDERED,
15112 gen_rtx_REG (CCmode, FLAGS_REG), const0_rtx);
15116 (define_insn "parityhi2_cmp"
15117 [(set (reg:CC FLAGS_REG)
15118 (unspec:CC [(match_operand:HI 0 "register_operand" "+Q")]
15120 (clobber (match_dup 0))]
15122 "xor{b}\t{%h0, %b0|%b0, %h0}"
15123 [(set_attr "length" "2")
15124 (set_attr "mode" "QI")])
15126 (define_insn "parityqi2_cmp"
15127 [(set (reg:CC FLAGS_REG)
15128 (unspec:CC [(match_operand:QI 0 "register_operand" "q")]
15132 [(set_attr "mode" "QI")])
15134 ;; Replace zero_extend:HI followed by parityhi2_cmp with parityqi2_cmp
15136 [(set (match_operand:HI 0 "register_operand")
15137 (zero_extend:HI (match_operand:QI 1 "general_reg_operand")))
15138 (parallel [(set (reg:CC FLAGS_REG)
15139 (unspec:CC [(match_dup 0)] UNSPEC_PARITY))
15140 (clobber (match_dup 0))])]
15142 [(set (reg:CC FLAGS_REG)
15143 (unspec:CC [(match_dup 1)] UNSPEC_PARITY))])
15145 ;; Eliminate QImode popcount&1 using parity flag
15147 [(set (match_operand:SI 0 "register_operand")
15148 (zero_extend:SI (match_operand:QI 1 "general_reg_operand")))
15149 (parallel [(set (match_operand:SI 2 "register_operand")
15150 (popcount:SI (match_dup 0)))
15151 (clobber (reg:CC FLAGS_REG))])
15152 (set (reg:CCZ FLAGS_REG)
15153 (compare:CCZ (and:QI (match_operand:QI 3 "register_operand")
15156 (set (pc) (if_then_else (match_operator 4 "bt_comparison_operator"
15157 [(reg:CCZ FLAGS_REG)
15159 (label_ref (match_operand 5))
15161 "REGNO (operands[2]) == REGNO (operands[3])
15162 && peep2_reg_dead_p (3, operands[0])
15163 && peep2_reg_dead_p (3, operands[2])
15164 && peep2_regno_dead_p (4, FLAGS_REG)"
15165 [(set (reg:CC FLAGS_REG)
15166 (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
15167 (set (pc) (if_then_else (match_op_dup 4 [(reg:CC FLAGS_REG)
15169 (label_ref (match_dup 5))
15172 operands[4] = shallow_copy_rtx (operands[4]);
15173 PUT_CODE (operands[4], GET_CODE (operands[4]) == EQ ? UNORDERED : ORDERED);
15176 ;; Eliminate HImode popcount&1 using parity flag
15178 [(match_scratch:HI 0 "Q")
15179 (parallel [(set (match_operand:HI 1 "register_operand")
15181 (match_operand:HI 2 "nonimmediate_operand")))
15182 (clobber (reg:CC FLAGS_REG))])
15183 (set (match_operand 3 "register_operand")
15184 (zero_extend (match_dup 1)))
15185 (set (reg:CCZ FLAGS_REG)
15186 (compare:CCZ (and:QI (match_operand:QI 4 "register_operand")
15189 (set (pc) (if_then_else (match_operator 5 "bt_comparison_operator"
15190 [(reg:CCZ FLAGS_REG)
15192 (label_ref (match_operand 6))
15194 "REGNO (operands[3]) == REGNO (operands[4])
15195 && peep2_reg_dead_p (3, operands[1])
15196 && peep2_reg_dead_p (3, operands[3])
15197 && peep2_regno_dead_p (4, FLAGS_REG)"
15198 [(set (match_dup 0) (match_dup 2))
15199 (parallel [(set (reg:CC FLAGS_REG)
15200 (unspec:CC [(match_dup 0)] UNSPEC_PARITY))
15201 (clobber (match_dup 0))])
15202 (set (pc) (if_then_else (match_op_dup 5 [(reg:CC FLAGS_REG)
15204 (label_ref (match_dup 6))
15207 operands[5] = shallow_copy_rtx (operands[5]);
15208 PUT_CODE (operands[5], GET_CODE (operands[5]) == EQ ? UNORDERED : ORDERED);
15212 ;; Thread-local storage patterns for ELF.
15214 ;; Note that these code sequences must appear exactly as shown
15215 ;; in order to allow linker relaxation.
15217 (define_insn "*tls_global_dynamic_32_gnu"
15218 [(set (match_operand:SI 0 "register_operand" "=a")
15220 [(match_operand:SI 1 "register_operand" "Yb")
15221 (match_operand 2 "tls_symbolic_operand")
15222 (match_operand 3 "constant_call_address_operand" "Bz")
15225 (clobber (match_scratch:SI 4 "=d"))
15226 (clobber (match_scratch:SI 5 "=c"))
15227 (clobber (reg:CC FLAGS_REG))]
15228 "!TARGET_64BIT && TARGET_GNU_TLS"
15230 if (TARGET_SUN_TLS || flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT)
15232 ("lea{l}\t{%E2@tlsgd(,%1,1), %0|%0, %E2@tlsgd[%1*1]}", operands);
15235 ("lea{l}\t{%E2@tlsgd(%1), %0|%0, %E2@tlsgd[%1]}", operands);
15236 if (TARGET_SUN_TLS)
15237 #ifdef HAVE_AS_IX86_TLSGDPLT
15238 return "call\t%a2@tlsgdplt";
15240 return "call\t%p3@plt";
15242 if (flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT)
15243 return "call\t%P3";
15244 return "call\t{*%p3@GOT(%1)|[DWORD PTR %p3@GOT[%1]]}";
15246 [(set_attr "type" "multi")
15247 (set_attr "length" "12")])
15249 (define_expand "tls_global_dynamic_32"
15251 [(set (match_operand:SI 0 "register_operand")
15252 (unspec:SI [(match_operand:SI 2 "register_operand")
15253 (match_operand 1 "tls_symbolic_operand")
15254 (match_operand 3 "constant_call_address_operand")
15257 (clobber (scratch:SI))
15258 (clobber (scratch:SI))
15259 (clobber (reg:CC FLAGS_REG))])]
15261 "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
15263 (define_insn "*tls_global_dynamic_64_<mode>"
15264 [(set (match_operand:P 0 "register_operand" "=a")
15266 (mem:QI (match_operand 2 "constant_call_address_operand" "Bz"))
15267 (match_operand 3)))
15268 (unspec:P [(match_operand 1 "tls_symbolic_operand")
15274 /* The .loc directive has effect for 'the immediately following assembly
15275 instruction'. So for a sequence:
15279 the 'immediately following assembly instruction' is insn1.
15280 We want to emit an insn prefix here, but if we use .byte (as shown in
15281 'ELF Handling For Thread-Local Storage'), a preceding .loc will point
15282 inside the insn sequence, rather than to the start. After relaxation
15283 of the sequence by the linker, the .loc might point inside an insn.
15284 Use data16 prefix instead, which doesn't have this problem. */
15285 fputs ("\tdata16", asm_out_file);
15287 ("lea{q}\t{%E1@tlsgd(%%rip), %%rdi|rdi, %E1@tlsgd[rip]}", operands);
15288 if (TARGET_SUN_TLS || flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT)
15289 fputs (ASM_SHORT "0x6666\n", asm_out_file);
15291 fputs (ASM_BYTE "0x66\n", asm_out_file);
15292 fputs ("\trex64\n", asm_out_file);
15293 if (TARGET_SUN_TLS)
15294 return "call\t%p2@plt";
15295 if (flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT)
15296 return "call\t%P2";
15297 return "call\t{*%p2@GOTPCREL(%%rip)|[QWORD PTR %p2@GOTPCREL[rip]]}";
15299 [(set_attr "type" "multi")
15300 (set (attr "length")
15301 (symbol_ref "TARGET_X32 ? 15 : 16"))])
15303 (define_insn "*tls_global_dynamic_64_largepic"
15304 [(set (match_operand:DI 0 "register_operand" "=a")
15306 (mem:QI (plus:DI (match_operand:DI 2 "register_operand" "b")
15307 (match_operand:DI 3 "immediate_operand" "i")))
15308 (match_operand 4)))
15309 (unspec:DI [(match_operand 1 "tls_symbolic_operand")
15312 "TARGET_64BIT && ix86_cmodel == CM_LARGE_PIC && !TARGET_PECOFF
15313 && GET_CODE (operands[3]) == CONST
15314 && GET_CODE (XEXP (operands[3], 0)) == UNSPEC
15315 && XINT (XEXP (operands[3], 0), 1) == UNSPEC_PLTOFF"
15318 ("lea{q}\t{%E1@tlsgd(%%rip), %%rdi|rdi, %E1@tlsgd[rip]}", operands);
15319 output_asm_insn ("movabs{q}\t{%3, %%rax|rax, %3}", operands);
15320 output_asm_insn ("add{q}\t{%2, %%rax|rax, %2}", operands);
15321 return "call\t{*%%rax|rax}";
15323 [(set_attr "type" "multi")
15324 (set_attr "length" "22")])
15326 (define_expand "@tls_global_dynamic_64_<mode>"
15328 [(set (match_operand:P 0 "register_operand")
15330 (mem:QI (match_operand 2))
15332 (unspec:P [(match_operand 1 "tls_symbolic_operand")
15336 "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
15338 (define_insn "*tls_local_dynamic_base_32_gnu"
15339 [(set (match_operand:SI 0 "register_operand" "=a")
15341 [(match_operand:SI 1 "register_operand" "Yb")
15342 (match_operand 2 "constant_call_address_operand" "Bz")
15344 UNSPEC_TLS_LD_BASE))
15345 (clobber (match_scratch:SI 3 "=d"))
15346 (clobber (match_scratch:SI 4 "=c"))
15347 (clobber (reg:CC FLAGS_REG))]
15348 "!TARGET_64BIT && TARGET_GNU_TLS"
15351 ("lea{l}\t{%&@tlsldm(%1), %0|%0, %&@tlsldm[%1]}", operands);
15352 if (TARGET_SUN_TLS)
15354 if (HAVE_AS_IX86_TLSLDMPLT)
15355 return "call\t%&@tlsldmplt";
15357 return "call\t%p2@plt";
15359 if (flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT)
15360 return "call\t%P2";
15361 return "call\t{*%p2@GOT(%1)|[DWORD PTR %p2@GOT[%1]]}";
15363 [(set_attr "type" "multi")
15364 (set_attr "length" "11")])
15366 (define_expand "tls_local_dynamic_base_32"
15368 [(set (match_operand:SI 0 "register_operand")
15370 [(match_operand:SI 1 "register_operand")
15371 (match_operand 2 "constant_call_address_operand")
15373 UNSPEC_TLS_LD_BASE))
15374 (clobber (scratch:SI))
15375 (clobber (scratch:SI))
15376 (clobber (reg:CC FLAGS_REG))])]
15378 "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
15380 (define_insn "*tls_local_dynamic_base_64_<mode>"
15381 [(set (match_operand:P 0 "register_operand" "=a")
15383 (mem:QI (match_operand 1 "constant_call_address_operand" "Bz"))
15384 (match_operand 2)))
15385 (unspec:P [(reg:P SP_REG)] UNSPEC_TLS_LD_BASE)]
15389 ("lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}", operands);
15390 if (TARGET_SUN_TLS)
15391 return "call\t%p1@plt";
15392 if (flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT)
15393 return "call\t%P1";
15394 return "call\t{*%p1@GOTPCREL(%%rip)|[QWORD PTR %p1@GOTPCREL[rip]]}";
15396 [(set_attr "type" "multi")
15397 (set_attr "length" "12")])
15399 (define_insn "*tls_local_dynamic_base_64_largepic"
15400 [(set (match_operand:DI 0 "register_operand" "=a")
15402 (mem:QI (plus:DI (match_operand:DI 1 "register_operand" "b")
15403 (match_operand:DI 2 "immediate_operand" "i")))
15404 (match_operand 3)))
15405 (unspec:DI [(reg:DI SP_REG)] UNSPEC_TLS_LD_BASE)]
15406 "TARGET_64BIT && ix86_cmodel == CM_LARGE_PIC && !TARGET_PECOFF
15407 && GET_CODE (operands[2]) == CONST
15408 && GET_CODE (XEXP (operands[2], 0)) == UNSPEC
15409 && XINT (XEXP (operands[2], 0), 1) == UNSPEC_PLTOFF"
15412 ("lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}", operands);
15413 output_asm_insn ("movabs{q}\t{%2, %%rax|rax, %2}", operands);
15414 output_asm_insn ("add{q}\t{%1, %%rax|rax, %1}", operands);
15415 return "call\t{*%%rax|rax}";
15417 [(set_attr "type" "multi")
15418 (set_attr "length" "22")])
15420 (define_expand "@tls_local_dynamic_base_64_<mode>"
15422 [(set (match_operand:P 0 "register_operand")
15424 (mem:QI (match_operand 1))
15426 (unspec:P [(reg:P SP_REG)] UNSPEC_TLS_LD_BASE)])]
15428 "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
15430 ;; Local dynamic of a single variable is a lose. Show combine how
15431 ;; to convert that back to global dynamic.
15433 (define_insn_and_split "*tls_local_dynamic_32_once"
15434 [(set (match_operand:SI 0 "register_operand" "=a")
15436 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15437 (match_operand 2 "constant_call_address_operand" "Bz")
15439 UNSPEC_TLS_LD_BASE)
15440 (const:SI (unspec:SI
15441 [(match_operand 3 "tls_symbolic_operand")]
15443 (clobber (match_scratch:SI 4 "=d"))
15444 (clobber (match_scratch:SI 5 "=c"))
15445 (clobber (reg:CC FLAGS_REG))]
15450 [(set (match_dup 0)
15451 (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)
15454 (clobber (match_dup 4))
15455 (clobber (match_dup 5))
15456 (clobber (reg:CC FLAGS_REG))])])
15458 ;; Load and add the thread base pointer from %<tp_seg>:0.
15459 (define_expand "get_thread_pointer<mode>"
15460 [(set (match_operand:PTR 0 "register_operand")
15461 (unspec:PTR [(const_int 0)] UNSPEC_TP))]
15464 /* targetm is not visible in the scope of the condition. */
15465 if (!targetm.have_tls)
15466 error ("%<__builtin_thread_pointer%> is not supported on this target");
15469 (define_insn_and_split "*load_tp_<mode>"
15470 [(set (match_operand:PTR 0 "register_operand" "=r")
15471 (unspec:PTR [(const_int 0)] UNSPEC_TP))]
15475 [(set (match_dup 0)
15478 addr_space_t as = DEFAULT_TLS_SEG_REG;
15480 operands[1] = gen_const_mem (<MODE>mode, const0_rtx);
15481 set_mem_addr_space (operands[1], as);
15484 (define_insn_and_split "*load_tp_x32_zext"
15485 [(set (match_operand:DI 0 "register_operand" "=r")
15487 (unspec:SI [(const_int 0)] UNSPEC_TP)))]
15491 [(set (match_dup 0)
15492 (zero_extend:DI (match_dup 1)))]
15494 addr_space_t as = DEFAULT_TLS_SEG_REG;
15496 operands[1] = gen_const_mem (SImode, const0_rtx);
15497 set_mem_addr_space (operands[1], as);
15500 (define_insn_and_split "*add_tp_<mode>"
15501 [(set (match_operand:PTR 0 "register_operand" "=r")
15503 (unspec:PTR [(const_int 0)] UNSPEC_TP)
15504 (match_operand:PTR 1 "register_operand" "0")))
15505 (clobber (reg:CC FLAGS_REG))]
15510 [(set (match_dup 0)
15511 (plus:PTR (match_dup 1) (match_dup 2)))
15512 (clobber (reg:CC FLAGS_REG))])]
15514 addr_space_t as = DEFAULT_TLS_SEG_REG;
15516 operands[2] = gen_const_mem (<MODE>mode, const0_rtx);
15517 set_mem_addr_space (operands[2], as);
15520 (define_insn_and_split "*add_tp_x32_zext"
15521 [(set (match_operand:DI 0 "register_operand" "=r")
15523 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
15524 (match_operand:SI 1 "register_operand" "0"))))
15525 (clobber (reg:CC FLAGS_REG))]
15530 [(set (match_dup 0)
15532 (plus:SI (match_dup 1) (match_dup 2))))
15533 (clobber (reg:CC FLAGS_REG))])]
15535 addr_space_t as = DEFAULT_TLS_SEG_REG;
15537 operands[2] = gen_const_mem (SImode, const0_rtx);
15538 set_mem_addr_space (operands[2], as);
15541 ;; The Sun linker took the AMD64 TLS spec literally and can only handle
15542 ;; %rax as destination of the initial executable code sequence.
15543 (define_insn "tls_initial_exec_64_sun"
15544 [(set (match_operand:DI 0 "register_operand" "=a")
15546 [(match_operand 1 "tls_symbolic_operand")]
15547 UNSPEC_TLS_IE_SUN))
15548 (clobber (reg:CC FLAGS_REG))]
15549 "TARGET_64BIT && TARGET_SUN_TLS"
15552 ("mov{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}", operands);
15553 return "add{q}\t{%a1@gottpoff(%%rip), %0|%0, %a1@gottpoff[rip]}";
15555 [(set_attr "type" "multi")])
15557 ;; GNU2 TLS patterns can be split.
15559 (define_expand "tls_dynamic_gnu2_32"
15560 [(set (match_dup 3)
15561 (plus:SI (match_operand:SI 2 "register_operand")
15563 (unspec:SI [(match_operand 1 "tls_symbolic_operand")]
15566 [(set (match_operand:SI 0 "register_operand")
15567 (unspec:SI [(match_dup 1) (match_dup 3)
15568 (match_dup 2) (reg:SI SP_REG)]
15570 (clobber (reg:CC FLAGS_REG))])]
15571 "!TARGET_64BIT && TARGET_GNU2_TLS"
15573 operands[3] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
15574 ix86_tls_descriptor_calls_expanded_in_cfun = true;
15577 (define_insn "*tls_dynamic_gnu2_lea_32"
15578 [(set (match_operand:SI 0 "register_operand" "=r")
15579 (plus:SI (match_operand:SI 1 "register_operand" "b")
15581 (unspec:SI [(match_operand 2 "tls_symbolic_operand")]
15582 UNSPEC_TLSDESC))))]
15583 "!TARGET_64BIT && TARGET_GNU2_TLS"
15584 "lea{l}\t{%E2@TLSDESC(%1), %0|%0, %E2@TLSDESC[%1]}"
15585 [(set_attr "type" "lea")
15586 (set_attr "mode" "SI")
15587 (set_attr "length" "6")
15588 (set_attr "length_address" "4")])
15590 (define_insn "*tls_dynamic_gnu2_call_32"
15591 [(set (match_operand:SI 0 "register_operand" "=a")
15592 (unspec:SI [(match_operand 1 "tls_symbolic_operand")
15593 (match_operand:SI 2 "register_operand" "0")
15594 ;; we have to make sure %ebx still points to the GOT
15595 (match_operand:SI 3 "register_operand" "b")
15598 (clobber (reg:CC FLAGS_REG))]
15599 "!TARGET_64BIT && TARGET_GNU2_TLS"
15600 "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
15601 [(set_attr "type" "call")
15602 (set_attr "length" "2")
15603 (set_attr "length_address" "0")])
15605 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
15606 [(set (match_operand:SI 0 "register_operand" "=&a")
15608 (unspec:SI [(match_operand 3 "tls_modbase_operand")
15609 (match_operand:SI 4)
15610 (match_operand:SI 2 "register_operand" "b")
15613 (const:SI (unspec:SI
15614 [(match_operand 1 "tls_symbolic_operand")]
15616 (clobber (reg:CC FLAGS_REG))]
15617 "!TARGET_64BIT && TARGET_GNU2_TLS"
15620 [(set (match_dup 0) (match_dup 5))]
15622 operands[5] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
15623 emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
15626 (define_expand "@tls_dynamic_gnu2_64_<mode>"
15627 [(set (match_dup 2)
15628 (unspec:PTR [(match_operand 1 "tls_symbolic_operand")]
15631 [(set (match_operand:PTR 0 "register_operand")
15632 (unspec:PTR [(match_dup 1) (match_dup 2) (reg:PTR SP_REG)]
15634 (clobber (reg:CC FLAGS_REG))])]
15635 "TARGET_64BIT && TARGET_GNU2_TLS"
15637 operands[2] = can_create_pseudo_p () ? gen_reg_rtx (ptr_mode) : operands[0];
15638 ix86_tls_descriptor_calls_expanded_in_cfun = true;
15641 (define_insn "*tls_dynamic_gnu2_lea_64_<mode>"
15642 [(set (match_operand:PTR 0 "register_operand" "=r")
15643 (unspec:PTR [(match_operand 1 "tls_symbolic_operand")]
15645 "TARGET_64BIT && TARGET_GNU2_TLS"
15646 "lea%z0\t{%E1@TLSDESC(%%rip), %0|%0, %E1@TLSDESC[rip]}"
15647 [(set_attr "type" "lea")
15648 (set_attr "mode" "<MODE>")
15649 (set_attr "length" "7")
15650 (set_attr "length_address" "4")])
15652 (define_insn "*tls_dynamic_gnu2_call_64_<mode>"
15653 [(set (match_operand:PTR 0 "register_operand" "=a")
15654 (unspec:PTR [(match_operand 1 "tls_symbolic_operand")
15655 (match_operand:PTR 2 "register_operand" "0")
15658 (clobber (reg:CC FLAGS_REG))]
15659 "TARGET_64BIT && TARGET_GNU2_TLS"
15660 "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
15661 [(set_attr "type" "call")
15662 (set_attr "length" "2")
15663 (set_attr "length_address" "0")])
15665 (define_insn_and_split "*tls_dynamic_gnu2_combine_64_<mode>"
15666 [(set (match_operand:PTR 0 "register_operand" "=&a")
15668 (unspec:PTR [(match_operand 2 "tls_modbase_operand")
15669 (match_operand:PTR 3)
15672 (const:PTR (unspec:PTR
15673 [(match_operand 1 "tls_symbolic_operand")]
15675 (clobber (reg:CC FLAGS_REG))]
15676 "TARGET_64BIT && TARGET_GNU2_TLS"
15679 [(set (match_dup 0) (match_dup 4))]
15681 operands[4] = can_create_pseudo_p () ? gen_reg_rtx (ptr_mode) : operands[0];
15682 emit_insn (gen_tls_dynamic_gnu2_64 (ptr_mode, operands[4], operands[1]));
15686 [(match_operand 0 "tls_address_pattern")]
15687 "TARGET_TLS_DIRECT_SEG_REFS"
15689 "operands[0] = ix86_rewrite_tls_address (operands[0]);")
15692 ;; These patterns match the binary 387 instructions for addM3, subM3,
15693 ;; mulM3 and divM3. There are three patterns for each of DFmode and
15694 ;; SFmode. The first is the normal insn, the second the same insn but
15695 ;; with one operand a conversion, and the third the same insn but with
15696 ;; the other operand a conversion. The conversion may be SFmode or
15697 ;; SImode if the target mode DFmode, but only SImode if the target mode
15700 ;; Gcc is slightly more smart about handling normal two address instructions
15701 ;; so use special patterns for add and mull.
15703 (define_insn "*fop_xf_comm_i387"
15704 [(set (match_operand:XF 0 "register_operand" "=f")
15705 (match_operator:XF 3 "binary_fp_operator"
15706 [(match_operand:XF 1 "register_operand" "%0")
15707 (match_operand:XF 2 "register_operand" "f")]))]
15709 && COMMUTATIVE_ARITH_P (operands[3])"
15710 "* return output_387_binary_op (insn, operands);"
15711 [(set (attr "type")
15712 (if_then_else (match_operand:XF 3 "mult_operator")
15713 (const_string "fmul")
15714 (const_string "fop")))
15715 (set_attr "mode" "XF")])
15717 (define_insn "*fop_<mode>_comm"
15718 [(set (match_operand:MODEF 0 "register_operand" "=f,x,v")
15719 (match_operator:MODEF 3 "binary_fp_operator"
15720 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,0,v")
15721 (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm,vm")]))]
15722 "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15723 || (TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)))
15724 && COMMUTATIVE_ARITH_P (operands[3])
15725 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15726 "* return output_387_binary_op (insn, operands);"
15727 [(set (attr "type")
15728 (if_then_else (eq_attr "alternative" "1,2")
15729 (if_then_else (match_operand:MODEF 3 "mult_operator")
15730 (const_string "ssemul")
15731 (const_string "sseadd"))
15732 (if_then_else (match_operand:MODEF 3 "mult_operator")
15733 (const_string "fmul")
15734 (const_string "fop"))))
15735 (set_attr "isa" "*,noavx,avx")
15736 (set_attr "prefix" "orig,orig,vex")
15737 (set_attr "mode" "<MODE>")
15738 (set (attr "enabled")
15740 (match_test ("SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"))
15742 (eq_attr "alternative" "0")
15743 (symbol_ref "TARGET_MIX_SSE_I387
15744 && X87_ENABLE_ARITH (<MODE>mode)")
15745 (const_string "*"))
15747 (eq_attr "alternative" "0")
15748 (symbol_ref "true")
15749 (symbol_ref "false"))))])
15751 (define_insn "*rcpsf2_sse"
15752 [(set (match_operand:SF 0 "register_operand" "=x,x,x")
15753 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "0,x,m")]
15755 "TARGET_SSE && TARGET_SSE_MATH"
15757 %vrcpss\t{%d1, %0|%0, %d1}
15758 %vrcpss\t{%d1, %0|%0, %d1}
15759 %vrcpss\t{%1, %d0|%d0, %1}"
15760 [(set_attr "type" "sse")
15761 (set_attr "atom_sse_attr" "rcp")
15762 (set_attr "btver2_sse_attr" "rcp")
15763 (set_attr "prefix" "maybe_vex")
15764 (set_attr "mode" "SF")
15765 (set_attr "avx_partial_xmm_update" "false,false,true")
15766 (set (attr "preferred_for_speed")
15767 (cond [(match_test "TARGET_AVX")
15768 (symbol_ref "true")
15769 (eq_attr "alternative" "1,2")
15770 (symbol_ref "!TARGET_SSE_PARTIAL_REG_DEPENDENCY")
15772 (symbol_ref "true")))])
15774 (define_insn "*fop_xf_1_i387"
15775 [(set (match_operand:XF 0 "register_operand" "=f,f")
15776 (match_operator:XF 3 "binary_fp_operator"
15777 [(match_operand:XF 1 "register_operand" "0,f")
15778 (match_operand:XF 2 "register_operand" "f,0")]))]
15780 && !COMMUTATIVE_ARITH_P (operands[3])"
15781 "* return output_387_binary_op (insn, operands);"
15782 [(set (attr "type")
15783 (if_then_else (match_operand:XF 3 "div_operator")
15784 (const_string "fdiv")
15785 (const_string "fop")))
15786 (set_attr "mode" "XF")])
15788 (define_insn "*fop_<mode>_1"
15789 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,v")
15790 (match_operator:MODEF 3 "binary_fp_operator"
15791 [(match_operand:MODEF 1
15792 "x87nonimm_ssenomem_operand" "0,fm,0,v")
15793 (match_operand:MODEF 2
15794 "nonimmediate_operand" "fm,0,xm,vm")]))]
15795 "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15796 || (TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)))
15797 && !COMMUTATIVE_ARITH_P (operands[3])
15798 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15799 "* return output_387_binary_op (insn, operands);"
15800 [(set (attr "type")
15801 (if_then_else (eq_attr "alternative" "2,3")
15802 (if_then_else (match_operand:MODEF 3 "div_operator")
15803 (const_string "ssediv")
15804 (const_string "sseadd"))
15805 (if_then_else (match_operand:MODEF 3 "div_operator")
15806 (const_string "fdiv")
15807 (const_string "fop"))))
15808 (set_attr "isa" "*,*,noavx,avx")
15809 (set_attr "prefix" "orig,orig,orig,vex")
15810 (set_attr "mode" "<MODE>")
15811 (set (attr "enabled")
15813 (match_test ("SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"))
15815 (eq_attr "alternative" "0,1")
15816 (symbol_ref "TARGET_MIX_SSE_I387
15817 && X87_ENABLE_ARITH (<MODE>mode)")
15818 (const_string "*"))
15820 (eq_attr "alternative" "0,1")
15821 (symbol_ref "true")
15822 (symbol_ref "false"))))])
15824 (define_insn "*fop_<X87MODEF:mode>_2_i387"
15825 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
15826 (match_operator:X87MODEF 3 "binary_fp_operator"
15828 (match_operand:SWI24 1 "nonimmediate_operand" "m"))
15829 (match_operand:X87MODEF 2 "register_operand" "0")]))]
15830 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI24:MODE>mode)
15831 && !(SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
15832 && (TARGET_USE_<SWI24:MODE>MODE_FIOP
15833 || optimize_function_for_size_p (cfun))"
15834 "* return output_387_binary_op (insn, operands);"
15835 [(set (attr "type")
15836 (cond [(match_operand:X87MODEF 3 "mult_operator")
15837 (const_string "fmul")
15838 (match_operand:X87MODEF 3 "div_operator")
15839 (const_string "fdiv")
15841 (const_string "fop")))
15842 (set_attr "fp_int_src" "true")
15843 (set_attr "mode" "<SWI24:MODE>")])
15845 (define_insn "*fop_<X87MODEF:mode>_3_i387"
15846 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
15847 (match_operator:X87MODEF 3 "binary_fp_operator"
15848 [(match_operand:X87MODEF 1 "register_operand" "0")
15850 (match_operand:SWI24 2 "nonimmediate_operand" "m"))]))]
15851 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI24:MODE>mode)
15852 && !(SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
15853 && (TARGET_USE_<SWI24:MODE>MODE_FIOP
15854 || optimize_function_for_size_p (cfun))"
15855 "* return output_387_binary_op (insn, operands);"
15856 [(set (attr "type")
15857 (cond [(match_operand:X87MODEF 3 "mult_operator")
15858 (const_string "fmul")
15859 (match_operand:X87MODEF 3 "div_operator")
15860 (const_string "fdiv")
15862 (const_string "fop")))
15863 (set_attr "fp_int_src" "true")
15864 (set_attr "mode" "<SWI24:MODE>")])
15866 (define_insn "*fop_xf_4_i387"
15867 [(set (match_operand:XF 0 "register_operand" "=f,f")
15868 (match_operator:XF 3 "binary_fp_operator"
15870 (match_operand:MODEF 1 "nonimmediate_operand" "fm,0"))
15871 (match_operand:XF 2 "register_operand" "0,f")]))]
15873 "* return output_387_binary_op (insn, operands);"
15874 [(set (attr "type")
15875 (cond [(match_operand:XF 3 "mult_operator")
15876 (const_string "fmul")
15877 (match_operand:XF 3 "div_operator")
15878 (const_string "fdiv")
15880 (const_string "fop")))
15881 (set_attr "mode" "<MODE>")])
15883 (define_insn "*fop_df_4_i387"
15884 [(set (match_operand:DF 0 "register_operand" "=f,f")
15885 (match_operator:DF 3 "binary_fp_operator"
15887 (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
15888 (match_operand:DF 2 "register_operand" "0,f")]))]
15889 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
15890 && !(SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
15891 "* return output_387_binary_op (insn, operands);"
15892 [(set (attr "type")
15893 (cond [(match_operand:DF 3 "mult_operator")
15894 (const_string "fmul")
15895 (match_operand:DF 3 "div_operator")
15896 (const_string "fdiv")
15898 (const_string "fop")))
15899 (set_attr "mode" "SF")])
15901 (define_insn "*fop_xf_5_i387"
15902 [(set (match_operand:XF 0 "register_operand" "=f,f")
15903 (match_operator:XF 3 "binary_fp_operator"
15904 [(match_operand:XF 1 "register_operand" "0,f")
15906 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
15908 "* return output_387_binary_op (insn, operands);"
15909 [(set (attr "type")
15910 (cond [(match_operand:XF 3 "mult_operator")
15911 (const_string "fmul")
15912 (match_operand:XF 3 "div_operator")
15913 (const_string "fdiv")
15915 (const_string "fop")))
15916 (set_attr "mode" "<MODE>")])
15918 (define_insn "*fop_df_5_i387"
15919 [(set (match_operand:DF 0 "register_operand" "=f,f")
15920 (match_operator:DF 3 "binary_fp_operator"
15921 [(match_operand:DF 1 "register_operand" "0,f")
15923 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
15924 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
15925 && !(SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
15926 "* return output_387_binary_op (insn, operands);"
15927 [(set (attr "type")
15928 (cond [(match_operand:DF 3 "mult_operator")
15929 (const_string "fmul")
15930 (match_operand:DF 3 "div_operator")
15931 (const_string "fdiv")
15933 (const_string "fop")))
15934 (set_attr "mode" "SF")])
15936 (define_insn "*fop_xf_6_i387"
15937 [(set (match_operand:XF 0 "register_operand" "=f,f")
15938 (match_operator:XF 3 "binary_fp_operator"
15940 (match_operand:MODEF 1 "register_operand" "0,f"))
15942 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
15944 "* return output_387_binary_op (insn, operands);"
15945 [(set (attr "type")
15946 (cond [(match_operand:XF 3 "mult_operator")
15947 (const_string "fmul")
15948 (match_operand:XF 3 "div_operator")
15949 (const_string "fdiv")
15951 (const_string "fop")))
15952 (set_attr "mode" "<MODE>")])
15954 (define_insn "*fop_df_6_i387"
15955 [(set (match_operand:DF 0 "register_operand" "=f,f")
15956 (match_operator:DF 3 "binary_fp_operator"
15958 (match_operand:SF 1 "register_operand" "0,f"))
15960 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
15961 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
15962 && !(SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
15963 "* return output_387_binary_op (insn, operands);"
15964 [(set (attr "type")
15965 (cond [(match_operand:DF 3 "mult_operator")
15966 (const_string "fmul")
15967 (match_operand:DF 3 "div_operator")
15968 (const_string "fdiv")
15970 (const_string "fop")))
15971 (set_attr "mode" "SF")])
15973 ;; FPU special functions.
15975 ;; This pattern implements a no-op XFmode truncation for
15976 ;; all fancy i386 XFmode math functions.
15978 (define_insn "truncxf<mode>2_i387_noop_unspec"
15979 [(set (match_operand:MODEF 0 "nonimmediate_operand" "=mf")
15980 (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")]
15981 UNSPEC_TRUNC_NOOP))]
15982 "TARGET_USE_FANCY_MATH_387"
15983 "* return output_387_reg_move (insn, operands);"
15984 [(set_attr "type" "fmov")
15985 (set_attr "mode" "<MODE>")])
15987 (define_insn "sqrtxf2"
15988 [(set (match_operand:XF 0 "register_operand" "=f")
15989 (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
15990 "TARGET_USE_FANCY_MATH_387"
15992 [(set_attr "type" "fpspc")
15993 (set_attr "mode" "XF")
15994 (set_attr "athlon_decode" "direct")
15995 (set_attr "amdfam10_decode" "direct")
15996 (set_attr "bdver1_decode" "direct")])
15998 (define_insn "*rsqrtsf2_sse"
15999 [(set (match_operand:SF 0 "register_operand" "=x,x,x")
16000 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "0,x,m")]
16002 "TARGET_SSE && TARGET_SSE_MATH"
16004 %vrsqrtss\t{%d1, %0|%0, %d1}
16005 %vrsqrtss\t{%d1, %0|%0, %d1}
16006 %vrsqrtss\t{%1, %d0|%d0, %1}"
16007 [(set_attr "type" "sse")
16008 (set_attr "atom_sse_attr" "rcp")
16009 (set_attr "btver2_sse_attr" "rcp")
16010 (set_attr "prefix" "maybe_vex")
16011 (set_attr "mode" "SF")
16012 (set_attr "avx_partial_xmm_update" "false,false,true")
16013 (set (attr "preferred_for_speed")
16014 (cond [(match_test "TARGET_AVX")
16015 (symbol_ref "true")
16016 (eq_attr "alternative" "1,2")
16017 (symbol_ref "!TARGET_SSE_PARTIAL_REG_DEPENDENCY")
16019 (symbol_ref "true")))])
16021 (define_expand "rsqrtsf2"
16022 [(set (match_operand:SF 0 "register_operand")
16023 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand")]
16025 "TARGET_SSE && TARGET_SSE_MATH"
16027 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
16031 (define_insn "*sqrt<mode>2_sse"
16032 [(set (match_operand:MODEF 0 "register_operand" "=v,v,v")
16034 (match_operand:MODEF 1 "nonimmediate_operand" "0,v,m")))]
16035 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16037 %vsqrt<ssemodesuffix>\t{%d1, %0|%0, %d1}
16038 %vsqrt<ssemodesuffix>\t{%d1, %0|%0, %d1}
16039 %vsqrt<ssemodesuffix>\t{%1, %d0|%d0, %1}"
16040 [(set_attr "type" "sse")
16041 (set_attr "atom_sse_attr" "sqrt")
16042 (set_attr "btver2_sse_attr" "sqrt")
16043 (set_attr "prefix" "maybe_vex")
16044 (set_attr "avx_partial_xmm_update" "false,false,true")
16045 (set_attr "mode" "<MODE>")
16046 (set (attr "preferred_for_speed")
16047 (cond [(match_test "TARGET_AVX")
16048 (symbol_ref "true")
16049 (eq_attr "alternative" "1,2")
16050 (symbol_ref "!TARGET_SSE_PARTIAL_REG_DEPENDENCY")
16052 (symbol_ref "true")))])
16054 (define_expand "sqrt<mode>2"
16055 [(set (match_operand:MODEF 0 "register_operand")
16057 (match_operand:MODEF 1 "nonimmediate_operand")))]
16058 "(TARGET_USE_FANCY_MATH_387 && X87_ENABLE_ARITH (<MODE>mode))
16059 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
16061 if (<MODE>mode == SFmode
16062 && TARGET_SSE && TARGET_SSE_MATH
16063 && TARGET_RECIP_SQRT
16064 && !optimize_function_for_size_p (cfun)
16065 && flag_finite_math_only && !flag_trapping_math
16066 && flag_unsafe_math_optimizations)
16068 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
16072 if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
16074 rtx op0 = gen_reg_rtx (XFmode);
16075 rtx op1 = gen_reg_rtx (XFmode);
16077 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16078 emit_insn (gen_sqrtxf2 (op0, op1));
16079 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
16084 (define_expand "hypot<mode>3"
16085 [(use (match_operand:MODEF 0 "register_operand"))
16086 (use (match_operand:MODEF 1 "general_operand"))
16087 (use (match_operand:MODEF 2 "general_operand"))]
16088 "TARGET_USE_FANCY_MATH_387
16089 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16090 || TARGET_MIX_SSE_I387)
16091 && flag_finite_math_only
16092 && flag_unsafe_math_optimizations"
16094 rtx op0 = gen_reg_rtx (XFmode);
16095 rtx op1 = gen_reg_rtx (XFmode);
16096 rtx op2 = gen_reg_rtx (XFmode);
16098 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
16099 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16101 emit_insn (gen_mulxf3 (op1, op1, op1));
16102 emit_insn (gen_mulxf3 (op2, op2, op2));
16103 emit_insn (gen_addxf3 (op0, op2, op1));
16104 emit_insn (gen_sqrtxf2 (op0, op0));
16106 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
16110 (define_insn "x86_fnstsw_1"
16111 [(set (match_operand:HI 0 "register_operand" "=a")
16112 (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
16115 [(set_attr "length" "2")
16116 (set_attr "mode" "SI")
16117 (set_attr "unit" "i387")])
16119 (define_insn "fpremxf4_i387"
16120 [(set (match_operand:XF 0 "register_operand" "=f")
16121 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16122 (match_operand:XF 3 "register_operand" "1")]
16124 (set (match_operand:XF 1 "register_operand" "=f")
16125 (unspec:XF [(match_dup 2) (match_dup 3)]
16127 (set (reg:CCFP FPSR_REG)
16128 (unspec:CCFP [(match_dup 2) (match_dup 3)]
16130 "TARGET_USE_FANCY_MATH_387
16131 && flag_finite_math_only"
16133 [(set_attr "type" "fpspc")
16134 (set_attr "znver1_decode" "vector")
16135 (set_attr "mode" "XF")])
16137 (define_expand "fmodxf3"
16138 [(use (match_operand:XF 0 "register_operand"))
16139 (use (match_operand:XF 1 "general_operand"))
16140 (use (match_operand:XF 2 "general_operand"))]
16141 "TARGET_USE_FANCY_MATH_387
16142 && flag_finite_math_only"
16144 rtx_code_label *label = gen_label_rtx ();
16146 rtx op1 = gen_reg_rtx (XFmode);
16147 rtx op2 = gen_reg_rtx (XFmode);
16149 emit_move_insn (op2, operands[2]);
16150 emit_move_insn (op1, operands[1]);
16152 emit_label (label);
16153 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
16154 ix86_emit_fp_unordered_jump (label);
16155 LABEL_NUSES (label) = 1;
16157 emit_move_insn (operands[0], op1);
16161 (define_expand "fmod<mode>3"
16162 [(use (match_operand:MODEF 0 "register_operand"))
16163 (use (match_operand:MODEF 1 "general_operand"))
16164 (use (match_operand:MODEF 2 "general_operand"))]
16165 "TARGET_USE_FANCY_MATH_387
16166 && flag_finite_math_only"
16168 rtx (*gen_truncxf) (rtx, rtx);
16170 rtx_code_label *label = gen_label_rtx ();
16172 rtx op1 = gen_reg_rtx (XFmode);
16173 rtx op2 = gen_reg_rtx (XFmode);
16175 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
16176 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16178 emit_label (label);
16179 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
16180 ix86_emit_fp_unordered_jump (label);
16181 LABEL_NUSES (label) = 1;
16183 /* Truncate the result properly for strict SSE math. */
16184 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16185 && !TARGET_MIX_SSE_I387)
16186 gen_truncxf = gen_truncxf<mode>2;
16188 gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
16190 emit_insn (gen_truncxf (operands[0], op1));
16194 (define_insn "fprem1xf4_i387"
16195 [(set (match_operand:XF 0 "register_operand" "=f")
16196 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16197 (match_operand:XF 3 "register_operand" "1")]
16199 (set (match_operand:XF 1 "register_operand" "=f")
16200 (unspec:XF [(match_dup 2) (match_dup 3)]
16202 (set (reg:CCFP FPSR_REG)
16203 (unspec:CCFP [(match_dup 2) (match_dup 3)]
16205 "TARGET_USE_FANCY_MATH_387
16206 && flag_finite_math_only"
16208 [(set_attr "type" "fpspc")
16209 (set_attr "znver1_decode" "vector")
16210 (set_attr "mode" "XF")])
16212 (define_expand "remainderxf3"
16213 [(use (match_operand:XF 0 "register_operand"))
16214 (use (match_operand:XF 1 "general_operand"))
16215 (use (match_operand:XF 2 "general_operand"))]
16216 "TARGET_USE_FANCY_MATH_387
16217 && flag_finite_math_only"
16219 rtx_code_label *label = gen_label_rtx ();
16221 rtx op1 = gen_reg_rtx (XFmode);
16222 rtx op2 = gen_reg_rtx (XFmode);
16224 emit_move_insn (op2, operands[2]);
16225 emit_move_insn (op1, operands[1]);
16227 emit_label (label);
16228 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
16229 ix86_emit_fp_unordered_jump (label);
16230 LABEL_NUSES (label) = 1;
16232 emit_move_insn (operands[0], op1);
16236 (define_expand "remainder<mode>3"
16237 [(use (match_operand:MODEF 0 "register_operand"))
16238 (use (match_operand:MODEF 1 "general_operand"))
16239 (use (match_operand:MODEF 2 "general_operand"))]
16240 "TARGET_USE_FANCY_MATH_387
16241 && flag_finite_math_only"
16243 rtx (*gen_truncxf) (rtx, rtx);
16245 rtx_code_label *label = gen_label_rtx ();
16247 rtx op1 = gen_reg_rtx (XFmode);
16248 rtx op2 = gen_reg_rtx (XFmode);
16250 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
16251 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16253 emit_label (label);
16255 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
16256 ix86_emit_fp_unordered_jump (label);
16257 LABEL_NUSES (label) = 1;
16259 /* Truncate the result properly for strict SSE math. */
16260 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16261 && !TARGET_MIX_SSE_I387)
16262 gen_truncxf = gen_truncxf<mode>2;
16264 gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
16266 emit_insn (gen_truncxf (operands[0], op1));
16270 (define_int_iterator SINCOS
16274 (define_int_attr sincos
16275 [(UNSPEC_SIN "sin")
16276 (UNSPEC_COS "cos")])
16278 (define_insn "<sincos>xf2"
16279 [(set (match_operand:XF 0 "register_operand" "=f")
16280 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16282 "TARGET_USE_FANCY_MATH_387
16283 && flag_unsafe_math_optimizations"
16285 [(set_attr "type" "fpspc")
16286 (set_attr "znver1_decode" "vector")
16287 (set_attr "mode" "XF")])
16289 (define_expand "<sincos><mode>2"
16290 [(set (match_operand:MODEF 0 "register_operand")
16291 (unspec:MODEF [(match_operand:MODEF 1 "general_operand")]
16293 "TARGET_USE_FANCY_MATH_387
16294 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16295 || TARGET_MIX_SSE_I387)
16296 && flag_unsafe_math_optimizations"
16298 rtx op0 = gen_reg_rtx (XFmode);
16299 rtx op1 = gen_reg_rtx (XFmode);
16301 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16302 emit_insn (gen_<sincos>xf2 (op0, op1));
16303 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
16307 (define_insn "sincosxf3"
16308 [(set (match_operand:XF 0 "register_operand" "=f")
16309 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16310 UNSPEC_SINCOS_COS))
16311 (set (match_operand:XF 1 "register_operand" "=f")
16312 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16313 "TARGET_USE_FANCY_MATH_387
16314 && flag_unsafe_math_optimizations"
16316 [(set_attr "type" "fpspc")
16317 (set_attr "znver1_decode" "vector")
16318 (set_attr "mode" "XF")])
16320 (define_expand "sincos<mode>3"
16321 [(use (match_operand:MODEF 0 "register_operand"))
16322 (use (match_operand:MODEF 1 "register_operand"))
16323 (use (match_operand:MODEF 2 "general_operand"))]
16324 "TARGET_USE_FANCY_MATH_387
16325 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16326 || TARGET_MIX_SSE_I387)
16327 && flag_unsafe_math_optimizations"
16329 rtx op0 = gen_reg_rtx (XFmode);
16330 rtx op1 = gen_reg_rtx (XFmode);
16331 rtx op2 = gen_reg_rtx (XFmode);
16333 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
16334 emit_insn (gen_sincosxf3 (op0, op1, op2));
16335 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
16336 emit_insn (gen_truncxf<mode>2 (operands[1], op1));
16340 (define_insn "fptanxf4_i387"
16341 [(set (match_operand:SF 0 "register_operand" "=f")
16342 (match_operand:SF 3 "const1_operand"))
16343 (set (match_operand:XF 1 "register_operand" "=f")
16344 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16346 "TARGET_USE_FANCY_MATH_387
16347 && flag_unsafe_math_optimizations"
16349 [(set_attr "type" "fpspc")
16350 (set_attr "znver1_decode" "vector")
16351 (set_attr "mode" "XF")])
16353 (define_expand "tanxf2"
16354 [(use (match_operand:XF 0 "register_operand"))
16355 (use (match_operand:XF 1 "register_operand"))]
16356 "TARGET_USE_FANCY_MATH_387
16357 && flag_unsafe_math_optimizations"
16359 rtx one = gen_reg_rtx (SFmode);
16360 emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1],
16361 CONST1_RTX (SFmode)));
16365 (define_expand "tan<mode>2"
16366 [(use (match_operand:MODEF 0 "register_operand"))
16367 (use (match_operand:MODEF 1 "general_operand"))]
16368 "TARGET_USE_FANCY_MATH_387
16369 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16370 || TARGET_MIX_SSE_I387)
16371 && flag_unsafe_math_optimizations"
16373 rtx op0 = gen_reg_rtx (XFmode);
16374 rtx op1 = gen_reg_rtx (XFmode);
16376 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16377 emit_insn (gen_tanxf2 (op0, op1));
16378 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
16382 (define_insn "atan2xf3"
16383 [(set (match_operand:XF 0 "register_operand" "=f")
16384 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16385 (match_operand:XF 1 "register_operand" "f")]
16387 (clobber (match_scratch:XF 3 "=1"))]
16388 "TARGET_USE_FANCY_MATH_387
16389 && flag_unsafe_math_optimizations"
16391 [(set_attr "type" "fpspc")
16392 (set_attr "znver1_decode" "vector")
16393 (set_attr "mode" "XF")])
16395 (define_expand "atan2<mode>3"
16396 [(use (match_operand:MODEF 0 "register_operand"))
16397 (use (match_operand:MODEF 1 "general_operand"))
16398 (use (match_operand:MODEF 2 "general_operand"))]
16399 "TARGET_USE_FANCY_MATH_387
16400 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16401 || TARGET_MIX_SSE_I387)
16402 && flag_unsafe_math_optimizations"
16404 rtx op0 = gen_reg_rtx (XFmode);
16405 rtx op1 = gen_reg_rtx (XFmode);
16406 rtx op2 = gen_reg_rtx (XFmode);
16408 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
16409 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16411 emit_insn (gen_atan2xf3 (op0, op1, op2));
16412 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
16416 (define_expand "atanxf2"
16417 [(parallel [(set (match_operand:XF 0 "register_operand")
16418 (unspec:XF [(match_dup 2)
16419 (match_operand:XF 1 "register_operand")]
16421 (clobber (scratch:XF))])]
16422 "TARGET_USE_FANCY_MATH_387
16423 && flag_unsafe_math_optimizations"
16424 "operands[2] = force_reg (XFmode, CONST1_RTX (XFmode));")
16426 (define_expand "atan<mode>2"
16427 [(use (match_operand:MODEF 0 "register_operand"))
16428 (use (match_operand:MODEF 1 "general_operand"))]
16429 "TARGET_USE_FANCY_MATH_387
16430 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16431 || TARGET_MIX_SSE_I387)
16432 && flag_unsafe_math_optimizations"
16434 rtx op0 = gen_reg_rtx (XFmode);
16435 rtx op1 = gen_reg_rtx (XFmode);
16437 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16438 emit_insn (gen_atanxf2 (op0, op1));
16439 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
16443 (define_expand "asinxf2"
16444 [(set (match_dup 2)
16445 (mult:XF (match_operand:XF 1 "register_operand")
16447 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
16448 (set (match_dup 5) (sqrt:XF (match_dup 4)))
16449 (parallel [(set (match_operand:XF 0 "register_operand")
16450 (unspec:XF [(match_dup 5) (match_dup 1)]
16452 (clobber (scratch:XF))])]
16453 "TARGET_USE_FANCY_MATH_387
16454 && flag_unsafe_math_optimizations"
16458 for (i = 2; i < 6; i++)
16459 operands[i] = gen_reg_rtx (XFmode);
16461 emit_move_insn (operands[3], CONST1_RTX (XFmode));
16464 (define_expand "asin<mode>2"
16465 [(use (match_operand:MODEF 0 "register_operand"))
16466 (use (match_operand:MODEF 1 "general_operand"))]
16467 "TARGET_USE_FANCY_MATH_387
16468 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16469 || TARGET_MIX_SSE_I387)
16470 && flag_unsafe_math_optimizations"
16472 rtx op0 = gen_reg_rtx (XFmode);
16473 rtx op1 = gen_reg_rtx (XFmode);
16475 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16476 emit_insn (gen_asinxf2 (op0, op1));
16477 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
16481 (define_expand "acosxf2"
16482 [(set (match_dup 2)
16483 (mult:XF (match_operand:XF 1 "register_operand")
16485 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
16486 (set (match_dup 5) (sqrt:XF (match_dup 4)))
16487 (parallel [(set (match_operand:XF 0 "register_operand")
16488 (unspec:XF [(match_dup 1) (match_dup 5)]
16490 (clobber (scratch:XF))])]
16491 "TARGET_USE_FANCY_MATH_387
16492 && flag_unsafe_math_optimizations"
16496 for (i = 2; i < 6; i++)
16497 operands[i] = gen_reg_rtx (XFmode);
16499 emit_move_insn (operands[3], CONST1_RTX (XFmode));
16502 (define_expand "acos<mode>2"
16503 [(use (match_operand:MODEF 0 "register_operand"))
16504 (use (match_operand:MODEF 1 "general_operand"))]
16505 "TARGET_USE_FANCY_MATH_387
16506 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16507 || TARGET_MIX_SSE_I387)
16508 && flag_unsafe_math_optimizations"
16510 rtx op0 = gen_reg_rtx (XFmode);
16511 rtx op1 = gen_reg_rtx (XFmode);
16513 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16514 emit_insn (gen_acosxf2 (op0, op1));
16515 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
16519 (define_expand "sinhxf2"
16520 [(use (match_operand:XF 0 "register_operand"))
16521 (use (match_operand:XF 1 "register_operand"))]
16522 "TARGET_USE_FANCY_MATH_387
16523 && flag_finite_math_only
16524 && flag_unsafe_math_optimizations"
16526 ix86_emit_i387_sinh (operands[0], operands[1]);
16530 (define_expand "sinh<mode>2"
16531 [(use (match_operand:MODEF 0 "register_operand"))
16532 (use (match_operand:MODEF 1 "general_operand"))]
16533 "TARGET_USE_FANCY_MATH_387
16534 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16535 || TARGET_MIX_SSE_I387)
16536 && flag_finite_math_only
16537 && flag_unsafe_math_optimizations"
16539 rtx op0 = gen_reg_rtx (XFmode);
16540 rtx op1 = gen_reg_rtx (XFmode);
16542 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16543 emit_insn (gen_sinhxf2 (op0, op1));
16544 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
16548 (define_expand "coshxf2"
16549 [(use (match_operand:XF 0 "register_operand"))
16550 (use (match_operand:XF 1 "register_operand"))]
16551 "TARGET_USE_FANCY_MATH_387
16552 && flag_unsafe_math_optimizations"
16554 ix86_emit_i387_cosh (operands[0], operands[1]);
16558 (define_expand "cosh<mode>2"
16559 [(use (match_operand:MODEF 0 "register_operand"))
16560 (use (match_operand:MODEF 1 "general_operand"))]
16561 "TARGET_USE_FANCY_MATH_387
16562 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16563 || TARGET_MIX_SSE_I387)
16564 && flag_unsafe_math_optimizations"
16566 rtx op0 = gen_reg_rtx (XFmode);
16567 rtx op1 = gen_reg_rtx (XFmode);
16569 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16570 emit_insn (gen_coshxf2 (op0, op1));
16571 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
16575 (define_expand "tanhxf2"
16576 [(use (match_operand:XF 0 "register_operand"))
16577 (use (match_operand:XF 1 "register_operand"))]
16578 "TARGET_USE_FANCY_MATH_387
16579 && flag_unsafe_math_optimizations"
16581 ix86_emit_i387_tanh (operands[0], operands[1]);
16585 (define_expand "tanh<mode>2"
16586 [(use (match_operand:MODEF 0 "register_operand"))
16587 (use (match_operand:MODEF 1 "general_operand"))]
16588 "TARGET_USE_FANCY_MATH_387
16589 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16590 || TARGET_MIX_SSE_I387)
16591 && flag_unsafe_math_optimizations"
16593 rtx op0 = gen_reg_rtx (XFmode);
16594 rtx op1 = gen_reg_rtx (XFmode);
16596 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16597 emit_insn (gen_tanhxf2 (op0, op1));
16598 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
16602 (define_expand "asinhxf2"
16603 [(use (match_operand:XF 0 "register_operand"))
16604 (use (match_operand:XF 1 "register_operand"))]
16605 "TARGET_USE_FANCY_MATH_387
16606 && flag_finite_math_only
16607 && flag_unsafe_math_optimizations"
16609 ix86_emit_i387_asinh (operands[0], operands[1]);
16613 (define_expand "asinh<mode>2"
16614 [(use (match_operand:MODEF 0 "register_operand"))
16615 (use (match_operand:MODEF 1 "general_operand"))]
16616 "TARGET_USE_FANCY_MATH_387
16617 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16618 || TARGET_MIX_SSE_I387)
16619 && flag_finite_math_only
16620 && flag_unsafe_math_optimizations"
16622 rtx op0 = gen_reg_rtx (XFmode);
16623 rtx op1 = gen_reg_rtx (XFmode);
16625 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16626 emit_insn (gen_asinhxf2 (op0, op1));
16627 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
16631 (define_expand "acoshxf2"
16632 [(use (match_operand:XF 0 "register_operand"))
16633 (use (match_operand:XF 1 "register_operand"))]
16634 "TARGET_USE_FANCY_MATH_387
16635 && flag_unsafe_math_optimizations"
16637 ix86_emit_i387_acosh (operands[0], operands[1]);
16641 (define_expand "acosh<mode>2"
16642 [(use (match_operand:MODEF 0 "register_operand"))
16643 (use (match_operand:MODEF 1 "general_operand"))]
16644 "TARGET_USE_FANCY_MATH_387
16645 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16646 || TARGET_MIX_SSE_I387)
16647 && flag_unsafe_math_optimizations"
16649 rtx op0 = gen_reg_rtx (XFmode);
16650 rtx op1 = gen_reg_rtx (XFmode);
16652 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16653 emit_insn (gen_acoshxf2 (op0, op1));
16654 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
16658 (define_expand "atanhxf2"
16659 [(use (match_operand:XF 0 "register_operand"))
16660 (use (match_operand:XF 1 "register_operand"))]
16661 "TARGET_USE_FANCY_MATH_387
16662 && flag_unsafe_math_optimizations"
16664 ix86_emit_i387_atanh (operands[0], operands[1]);
16668 (define_expand "atanh<mode>2"
16669 [(use (match_operand:MODEF 0 "register_operand"))
16670 (use (match_operand:MODEF 1 "general_operand"))]
16671 "TARGET_USE_FANCY_MATH_387
16672 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16673 || TARGET_MIX_SSE_I387)
16674 && flag_unsafe_math_optimizations"
16676 rtx op0 = gen_reg_rtx (XFmode);
16677 rtx op1 = gen_reg_rtx (XFmode);
16679 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16680 emit_insn (gen_atanhxf2 (op0, op1));
16681 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
16685 (define_insn "fyl2xxf3_i387"
16686 [(set (match_operand:XF 0 "register_operand" "=f")
16687 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
16688 (match_operand:XF 2 "register_operand" "f")]
16690 (clobber (match_scratch:XF 3 "=2"))]
16691 "TARGET_USE_FANCY_MATH_387
16692 && flag_unsafe_math_optimizations"
16694 [(set_attr "type" "fpspc")
16695 (set_attr "znver1_decode" "vector")
16696 (set_attr "mode" "XF")])
16698 (define_expand "logxf2"
16699 [(parallel [(set (match_operand:XF 0 "register_operand")
16700 (unspec:XF [(match_operand:XF 1 "register_operand")
16701 (match_dup 2)] UNSPEC_FYL2X))
16702 (clobber (scratch:XF))])]
16703 "TARGET_USE_FANCY_MATH_387
16704 && flag_unsafe_math_optimizations"
16707 = force_reg (XFmode, standard_80387_constant_rtx (4)); /* fldln2 */
16710 (define_expand "log<mode>2"
16711 [(use (match_operand:MODEF 0 "register_operand"))
16712 (use (match_operand:MODEF 1 "general_operand"))]
16713 "TARGET_USE_FANCY_MATH_387
16714 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16715 || TARGET_MIX_SSE_I387)
16716 && flag_unsafe_math_optimizations"
16718 rtx op0 = gen_reg_rtx (XFmode);
16719 rtx op1 = gen_reg_rtx (XFmode);
16721 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16722 emit_insn (gen_logxf2 (op0, op1));
16723 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
16727 (define_expand "log10xf2"
16728 [(parallel [(set (match_operand:XF 0 "register_operand")
16729 (unspec:XF [(match_operand:XF 1 "register_operand")
16730 (match_dup 2)] UNSPEC_FYL2X))
16731 (clobber (scratch:XF))])]
16732 "TARGET_USE_FANCY_MATH_387
16733 && flag_unsafe_math_optimizations"
16736 = force_reg (XFmode, standard_80387_constant_rtx (3)); /* fldlg2 */
16739 (define_expand "log10<mode>2"
16740 [(use (match_operand:MODEF 0 "register_operand"))
16741 (use (match_operand:MODEF 1 "general_operand"))]
16742 "TARGET_USE_FANCY_MATH_387
16743 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16744 || TARGET_MIX_SSE_I387)
16745 && flag_unsafe_math_optimizations"
16747 rtx op0 = gen_reg_rtx (XFmode);
16748 rtx op1 = gen_reg_rtx (XFmode);
16750 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16751 emit_insn (gen_log10xf2 (op0, op1));
16752 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
16756 (define_expand "log2xf2"
16757 [(parallel [(set (match_operand:XF 0 "register_operand")
16758 (unspec:XF [(match_operand:XF 1 "register_operand")
16759 (match_dup 2)] UNSPEC_FYL2X))
16760 (clobber (scratch:XF))])]
16761 "TARGET_USE_FANCY_MATH_387
16762 && flag_unsafe_math_optimizations"
16763 "operands[2] = force_reg (XFmode, CONST1_RTX (XFmode));")
16765 (define_expand "log2<mode>2"
16766 [(use (match_operand:MODEF 0 "register_operand"))
16767 (use (match_operand:MODEF 1 "general_operand"))]
16768 "TARGET_USE_FANCY_MATH_387
16769 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16770 || TARGET_MIX_SSE_I387)
16771 && flag_unsafe_math_optimizations"
16773 rtx op0 = gen_reg_rtx (XFmode);
16774 rtx op1 = gen_reg_rtx (XFmode);
16776 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16777 emit_insn (gen_log2xf2 (op0, op1));
16778 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
16782 (define_insn "fyl2xp1xf3_i387"
16783 [(set (match_operand:XF 0 "register_operand" "=f")
16784 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
16785 (match_operand:XF 2 "register_operand" "f")]
16787 (clobber (match_scratch:XF 3 "=2"))]
16788 "TARGET_USE_FANCY_MATH_387
16789 && flag_unsafe_math_optimizations"
16791 [(set_attr "type" "fpspc")
16792 (set_attr "znver1_decode" "vector")
16793 (set_attr "mode" "XF")])
16795 (define_expand "log1pxf2"
16796 [(use (match_operand:XF 0 "register_operand"))
16797 (use (match_operand:XF 1 "register_operand"))]
16798 "TARGET_USE_FANCY_MATH_387
16799 && flag_unsafe_math_optimizations"
16801 ix86_emit_i387_log1p (operands[0], operands[1]);
16805 (define_expand "log1p<mode>2"
16806 [(use (match_operand:MODEF 0 "register_operand"))
16807 (use (match_operand:MODEF 1 "general_operand"))]
16808 "TARGET_USE_FANCY_MATH_387
16809 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16810 || TARGET_MIX_SSE_I387)
16811 && flag_unsafe_math_optimizations"
16813 rtx op0 = gen_reg_rtx (XFmode);
16814 rtx op1 = gen_reg_rtx (XFmode);
16816 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16817 emit_insn (gen_log1pxf2 (op0, op1));
16818 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
16822 (define_insn "fxtractxf3_i387"
16823 [(set (match_operand:XF 0 "register_operand" "=f")
16824 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16825 UNSPEC_XTRACT_FRACT))
16826 (set (match_operand:XF 1 "register_operand" "=f")
16827 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
16828 "TARGET_USE_FANCY_MATH_387
16829 && flag_unsafe_math_optimizations"
16831 [(set_attr "type" "fpspc")
16832 (set_attr "znver1_decode" "vector")
16833 (set_attr "mode" "XF")])
16835 (define_expand "logbxf2"
16836 [(parallel [(set (match_dup 2)
16837 (unspec:XF [(match_operand:XF 1 "register_operand")]
16838 UNSPEC_XTRACT_FRACT))
16839 (set (match_operand:XF 0 "register_operand")
16840 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
16841 "TARGET_USE_FANCY_MATH_387
16842 && flag_unsafe_math_optimizations"
16843 "operands[2] = gen_reg_rtx (XFmode);")
16845 (define_expand "logb<mode>2"
16846 [(use (match_operand:MODEF 0 "register_operand"))
16847 (use (match_operand:MODEF 1 "general_operand"))]
16848 "TARGET_USE_FANCY_MATH_387
16849 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16850 || TARGET_MIX_SSE_I387)
16851 && flag_unsafe_math_optimizations"
16853 rtx op0 = gen_reg_rtx (XFmode);
16854 rtx op1 = gen_reg_rtx (XFmode);
16856 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16857 emit_insn (gen_logbxf2 (op0, op1));
16858 emit_insn (gen_truncxf<mode>2 (operands[0], op1));
16862 (define_expand "ilogbxf2"
16863 [(use (match_operand:SI 0 "register_operand"))
16864 (use (match_operand:XF 1 "register_operand"))]
16865 "TARGET_USE_FANCY_MATH_387
16866 && flag_unsafe_math_optimizations"
16870 if (optimize_insn_for_size_p ())
16873 op0 = gen_reg_rtx (XFmode);
16874 op1 = gen_reg_rtx (XFmode);
16876 emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
16877 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
16881 (define_expand "ilogb<mode>2"
16882 [(use (match_operand:SI 0 "register_operand"))
16883 (use (match_operand:MODEF 1 "general_operand"))]
16884 "TARGET_USE_FANCY_MATH_387
16885 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16886 || TARGET_MIX_SSE_I387)
16887 && flag_unsafe_math_optimizations"
16891 if (optimize_insn_for_size_p ())
16894 op0 = gen_reg_rtx (XFmode);
16895 op1 = gen_reg_rtx (XFmode);
16896 op2 = gen_reg_rtx (XFmode);
16898 emit_insn (gen_extend<mode>xf2 (op2, operands[1]));
16899 emit_insn (gen_fxtractxf3_i387 (op0, op1, op2));
16900 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
16904 (define_insn "*f2xm1xf2_i387"
16905 [(set (match_operand:XF 0 "register_operand" "=f")
16906 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16908 "TARGET_USE_FANCY_MATH_387
16909 && flag_unsafe_math_optimizations"
16911 [(set_attr "type" "fpspc")
16912 (set_attr "znver1_decode" "vector")
16913 (set_attr "mode" "XF")])
16915 (define_insn "fscalexf4_i387"
16916 [(set (match_operand:XF 0 "register_operand" "=f")
16917 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16918 (match_operand:XF 3 "register_operand" "1")]
16919 UNSPEC_FSCALE_FRACT))
16920 (set (match_operand:XF 1 "register_operand" "=f")
16921 (unspec:XF [(match_dup 2) (match_dup 3)]
16922 UNSPEC_FSCALE_EXP))]
16923 "TARGET_USE_FANCY_MATH_387
16924 && flag_unsafe_math_optimizations"
16926 [(set_attr "type" "fpspc")
16927 (set_attr "znver1_decode" "vector")
16928 (set_attr "mode" "XF")])
16930 (define_expand "expNcorexf3"
16931 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand")
16932 (match_operand:XF 2 "register_operand")))
16933 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16934 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16935 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16936 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
16937 (parallel [(set (match_operand:XF 0 "register_operand")
16938 (unspec:XF [(match_dup 8) (match_dup 4)]
16939 UNSPEC_FSCALE_FRACT))
16941 (unspec:XF [(match_dup 8) (match_dup 4)]
16942 UNSPEC_FSCALE_EXP))])]
16943 "TARGET_USE_FANCY_MATH_387
16944 && flag_unsafe_math_optimizations"
16948 for (i = 3; i < 10; i++)
16949 operands[i] = gen_reg_rtx (XFmode);
16951 emit_move_insn (operands[7], CONST1_RTX (XFmode));
16954 (define_expand "expxf2"
16955 [(use (match_operand:XF 0 "register_operand"))
16956 (use (match_operand:XF 1 "register_operand"))]
16957 "TARGET_USE_FANCY_MATH_387
16958 && flag_unsafe_math_optimizations"
16960 rtx op2 = force_reg (XFmode, standard_80387_constant_rtx (5)); /* fldl2e */
16962 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
16966 (define_expand "exp<mode>2"
16967 [(use (match_operand:MODEF 0 "register_operand"))
16968 (use (match_operand:MODEF 1 "general_operand"))]
16969 "TARGET_USE_FANCY_MATH_387
16970 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16971 || TARGET_MIX_SSE_I387)
16972 && flag_unsafe_math_optimizations"
16974 rtx op0 = gen_reg_rtx (XFmode);
16975 rtx op1 = gen_reg_rtx (XFmode);
16977 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16978 emit_insn (gen_expxf2 (op0, op1));
16979 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
16983 (define_expand "exp10xf2"
16984 [(use (match_operand:XF 0 "register_operand"))
16985 (use (match_operand:XF 1 "register_operand"))]
16986 "TARGET_USE_FANCY_MATH_387
16987 && flag_unsafe_math_optimizations"
16989 rtx op2 = force_reg (XFmode, standard_80387_constant_rtx (6)); /* fldl2t */
16991 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
16995 (define_expand "exp10<mode>2"
16996 [(use (match_operand:MODEF 0 "register_operand"))
16997 (use (match_operand:MODEF 1 "general_operand"))]
16998 "TARGET_USE_FANCY_MATH_387
16999 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17000 || TARGET_MIX_SSE_I387)
17001 && flag_unsafe_math_optimizations"
17003 rtx op0 = gen_reg_rtx (XFmode);
17004 rtx op1 = gen_reg_rtx (XFmode);
17006 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17007 emit_insn (gen_exp10xf2 (op0, op1));
17008 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
17012 (define_expand "exp2xf2"
17013 [(use (match_operand:XF 0 "register_operand"))
17014 (use (match_operand:XF 1 "register_operand"))]
17015 "TARGET_USE_FANCY_MATH_387
17016 && flag_unsafe_math_optimizations"
17018 rtx op2 = force_reg (XFmode, CONST1_RTX (XFmode));
17020 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
17024 (define_expand "exp2<mode>2"
17025 [(use (match_operand:MODEF 0 "register_operand"))
17026 (use (match_operand:MODEF 1 "general_operand"))]
17027 "TARGET_USE_FANCY_MATH_387
17028 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17029 || TARGET_MIX_SSE_I387)
17030 && flag_unsafe_math_optimizations"
17032 rtx op0 = gen_reg_rtx (XFmode);
17033 rtx op1 = gen_reg_rtx (XFmode);
17035 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17036 emit_insn (gen_exp2xf2 (op0, op1));
17037 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
17041 (define_expand "expm1xf2"
17042 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand")
17044 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
17045 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
17046 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
17047 (parallel [(set (match_dup 7)
17048 (unspec:XF [(match_dup 6) (match_dup 4)]
17049 UNSPEC_FSCALE_FRACT))
17051 (unspec:XF [(match_dup 6) (match_dup 4)]
17052 UNSPEC_FSCALE_EXP))])
17053 (parallel [(set (match_dup 10)
17054 (unspec:XF [(match_dup 9) (match_dup 8)]
17055 UNSPEC_FSCALE_FRACT))
17056 (set (match_dup 11)
17057 (unspec:XF [(match_dup 9) (match_dup 8)]
17058 UNSPEC_FSCALE_EXP))])
17059 (set (match_dup 12) (minus:XF (match_dup 10) (match_dup 9)))
17060 (set (match_operand:XF 0 "register_operand")
17061 (plus:XF (match_dup 12) (match_dup 7)))]
17062 "TARGET_USE_FANCY_MATH_387
17063 && flag_unsafe_math_optimizations"
17067 for (i = 2; i < 13; i++)
17068 operands[i] = gen_reg_rtx (XFmode);
17070 emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
17071 emit_move_insn (operands[9], CONST1_RTX (XFmode));
17074 (define_expand "expm1<mode>2"
17075 [(use (match_operand:MODEF 0 "register_operand"))
17076 (use (match_operand:MODEF 1 "general_operand"))]
17077 "TARGET_USE_FANCY_MATH_387
17078 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17079 || TARGET_MIX_SSE_I387)
17080 && flag_unsafe_math_optimizations"
17082 rtx op0 = gen_reg_rtx (XFmode);
17083 rtx op1 = gen_reg_rtx (XFmode);
17085 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17086 emit_insn (gen_expm1xf2 (op0, op1));
17087 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
17091 (define_expand "ldexpxf3"
17092 [(match_operand:XF 0 "register_operand")
17093 (match_operand:XF 1 "register_operand")
17094 (match_operand:SI 2 "register_operand")]
17095 "TARGET_USE_FANCY_MATH_387
17096 && flag_unsafe_math_optimizations"
17098 rtx tmp1 = gen_reg_rtx (XFmode);
17099 rtx tmp2 = gen_reg_rtx (XFmode);
17101 emit_insn (gen_floatsixf2 (tmp1, operands[2]));
17102 emit_insn (gen_fscalexf4_i387 (operands[0], tmp2,
17103 operands[1], tmp1));
17107 (define_expand "ldexp<mode>3"
17108 [(use (match_operand:MODEF 0 "register_operand"))
17109 (use (match_operand:MODEF 1 "general_operand"))
17110 (use (match_operand:SI 2 "register_operand"))]
17111 "TARGET_USE_FANCY_MATH_387
17112 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17113 || TARGET_MIX_SSE_I387)
17114 && flag_unsafe_math_optimizations"
17116 rtx op0 = gen_reg_rtx (XFmode);
17117 rtx op1 = gen_reg_rtx (XFmode);
17119 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17120 emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
17121 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
17125 (define_expand "scalbxf3"
17126 [(parallel [(set (match_operand:XF 0 " register_operand")
17127 (unspec:XF [(match_operand:XF 1 "register_operand")
17128 (match_operand:XF 2 "register_operand")]
17129 UNSPEC_FSCALE_FRACT))
17131 (unspec:XF [(match_dup 1) (match_dup 2)]
17132 UNSPEC_FSCALE_EXP))])]
17133 "TARGET_USE_FANCY_MATH_387
17134 && flag_unsafe_math_optimizations"
17135 "operands[3] = gen_reg_rtx (XFmode);")
17137 (define_expand "scalb<mode>3"
17138 [(use (match_operand:MODEF 0 "register_operand"))
17139 (use (match_operand:MODEF 1 "general_operand"))
17140 (use (match_operand:MODEF 2 "general_operand"))]
17141 "TARGET_USE_FANCY_MATH_387
17142 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17143 || TARGET_MIX_SSE_I387)
17144 && flag_unsafe_math_optimizations"
17146 rtx op0 = gen_reg_rtx (XFmode);
17147 rtx op1 = gen_reg_rtx (XFmode);
17148 rtx op2 = gen_reg_rtx (XFmode);
17150 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17151 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
17152 emit_insn (gen_scalbxf3 (op0, op1, op2));
17153 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
17157 (define_expand "significandxf2"
17158 [(parallel [(set (match_operand:XF 0 "register_operand")
17159 (unspec:XF [(match_operand:XF 1 "register_operand")]
17160 UNSPEC_XTRACT_FRACT))
17162 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
17163 "TARGET_USE_FANCY_MATH_387
17164 && flag_unsafe_math_optimizations"
17165 "operands[2] = gen_reg_rtx (XFmode);")
17167 (define_expand "significand<mode>2"
17168 [(use (match_operand:MODEF 0 "register_operand"))
17169 (use (match_operand:MODEF 1 "general_operand"))]
17170 "TARGET_USE_FANCY_MATH_387
17171 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17172 || TARGET_MIX_SSE_I387)
17173 && flag_unsafe_math_optimizations"
17175 rtx op0 = gen_reg_rtx (XFmode);
17176 rtx op1 = gen_reg_rtx (XFmode);
17178 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17179 emit_insn (gen_significandxf2 (op0, op1));
17180 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
17185 (define_insn "sse4_1_round<mode>2"
17186 [(set (match_operand:MODEF 0 "register_operand" "=x,x,x,v,v")
17188 [(match_operand:MODEF 1 "nonimmediate_operand" "0,x,m,v,m")
17189 (match_operand:SI 2 "const_0_to_15_operand" "n,n,n,n,n")]
17193 %vround<ssemodesuffix>\t{%2, %d1, %0|%0, %d1, %2}
17194 %vround<ssemodesuffix>\t{%2, %d1, %0|%0, %d1, %2}
17195 %vround<ssemodesuffix>\t{%2, %1, %d0|%d0, %1, %2}
17196 vrndscale<ssemodesuffix>\t{%2, %d1, %0|%0, %d1, %2}
17197 vrndscale<ssemodesuffix>\t{%2, %1, %d0|%d0, %1, %2}"
17198 [(set_attr "type" "ssecvt")
17199 (set_attr "prefix_extra" "1,1,1,*,*")
17200 (set_attr "length_immediate" "*,*,*,1,1")
17201 (set_attr "prefix" "maybe_vex,maybe_vex,maybe_vex,evex,evex")
17202 (set_attr "isa" "noavx512f,noavx512f,noavx512f,avx512f,avx512f")
17203 (set_attr "avx_partial_xmm_update" "false,false,true,false,true")
17204 (set_attr "mode" "<MODE>")
17205 (set (attr "preferred_for_speed")
17206 (cond [(match_test "TARGET_AVX")
17207 (symbol_ref "true")
17208 (eq_attr "alternative" "1,2")
17209 (symbol_ref "!TARGET_SSE_PARTIAL_REG_DEPENDENCY")
17211 (symbol_ref "true")))])
17213 (define_insn "rintxf2"
17214 [(set (match_operand:XF 0 "register_operand" "=f")
17215 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17217 "TARGET_USE_FANCY_MATH_387"
17219 [(set_attr "type" "fpspc")
17220 (set_attr "znver1_decode" "vector")
17221 (set_attr "mode" "XF")])
17223 (define_expand "rint<mode>2"
17224 [(use (match_operand:MODEF 0 "register_operand"))
17225 (use (match_operand:MODEF 1 "nonimmediate_operand"))]
17226 "TARGET_USE_FANCY_MATH_387
17227 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
17229 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17232 emit_insn (gen_sse4_1_round<mode>2
17233 (operands[0], operands[1], GEN_INT (ROUND_MXCSR)));
17235 ix86_expand_rint (operands[0], operands[1]);
17239 rtx op0 = gen_reg_rtx (XFmode);
17240 rtx op1 = gen_reg_rtx (XFmode);
17242 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17243 emit_insn (gen_rintxf2 (op0, op1));
17244 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
17249 (define_expand "nearbyintxf2"
17250 [(set (match_operand:XF 0 "register_operand")
17251 (unspec:XF [(match_operand:XF 1 "register_operand")]
17253 "TARGET_USE_FANCY_MATH_387
17254 && !flag_trapping_math")
17256 (define_expand "nearbyint<mode>2"
17257 [(use (match_operand:MODEF 0 "register_operand"))
17258 (use (match_operand:MODEF 1 "nonimmediate_operand"))]
17259 "(TARGET_USE_FANCY_MATH_387
17260 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17261 || TARGET_MIX_SSE_I387)
17262 && !flag_trapping_math)
17263 || (TARGET_SSE4_1 && TARGET_SSE_MATH)"
17265 if (TARGET_SSE4_1 && TARGET_SSE_MATH)
17266 emit_insn (gen_sse4_1_round<mode>2
17267 (operands[0], operands[1], GEN_INT (ROUND_MXCSR
17271 rtx op0 = gen_reg_rtx (XFmode);
17272 rtx op1 = gen_reg_rtx (XFmode);
17274 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17275 emit_insn (gen_nearbyintxf2 (op0, op1));
17276 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
17281 (define_expand "round<mode>2"
17282 [(match_operand:X87MODEF 0 "register_operand")
17283 (match_operand:X87MODEF 1 "nonimmediate_operand")]
17284 "(TARGET_USE_FANCY_MATH_387
17285 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17286 || TARGET_MIX_SSE_I387)
17287 && flag_unsafe_math_optimizations
17288 && (flag_fp_int_builtin_inexact || !flag_trapping_math))
17289 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17290 && !flag_trapping_math && !flag_rounding_math)"
17292 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17293 && !flag_trapping_math && !flag_rounding_math)
17297 operands[1] = force_reg (<MODE>mode, operands[1]);
17298 ix86_expand_round_sse4 (operands[0], operands[1]);
17300 else if (TARGET_64BIT || (<MODE>mode != DFmode))
17301 ix86_expand_round (operands[0], operands[1]);
17303 ix86_expand_rounddf_32 (operands[0], operands[1]);
17307 operands[1] = force_reg (<MODE>mode, operands[1]);
17308 ix86_emit_i387_round (operands[0], operands[1]);
17313 (define_insn "lrintxfdi2"
17314 [(set (match_operand:DI 0 "nonimmediate_operand" "=m")
17315 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17317 (clobber (match_scratch:XF 2 "=&f"))]
17318 "TARGET_USE_FANCY_MATH_387"
17319 "* return output_fix_trunc (insn, operands, false);"
17320 [(set_attr "type" "fpspc")
17321 (set_attr "mode" "DI")])
17323 (define_insn "lrintxf<mode>2"
17324 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m")
17325 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
17327 "TARGET_USE_FANCY_MATH_387"
17328 "* return output_fix_trunc (insn, operands, false);"
17329 [(set_attr "type" "fpspc")
17330 (set_attr "mode" "<MODE>")])
17332 (define_expand "lrint<MODEF:mode><SWI48:mode>2"
17333 [(set (match_operand:SWI48 0 "nonimmediate_operand")
17334 (unspec:SWI48 [(match_operand:MODEF 1 "register_operand")]
17335 UNSPEC_FIX_NOTRUNC))]
17336 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH")
17338 (define_expand "lround<X87MODEF:mode><SWI248x:mode>2"
17339 [(match_operand:SWI248x 0 "nonimmediate_operand")
17340 (match_operand:X87MODEF 1 "register_operand")]
17341 "(TARGET_USE_FANCY_MATH_387
17342 && (!(SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
17343 || TARGET_MIX_SSE_I387)
17344 && flag_unsafe_math_optimizations)
17345 || (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
17346 && <SWI248x:MODE>mode != HImode
17347 && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT)
17348 && !flag_trapping_math && !flag_rounding_math)"
17350 if (optimize_insn_for_size_p ())
17353 if (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
17354 && <SWI248x:MODE>mode != HImode
17355 && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT)
17356 && !flag_trapping_math && !flag_rounding_math)
17357 ix86_expand_lround (operands[0], operands[1]);
17359 ix86_emit_i387_round (operands[0], operands[1]);
17363 (define_int_iterator FRNDINT_ROUNDING
17364 [UNSPEC_FRNDINT_ROUNDEVEN
17365 UNSPEC_FRNDINT_FLOOR
17366 UNSPEC_FRNDINT_CEIL
17367 UNSPEC_FRNDINT_TRUNC])
17369 (define_int_iterator FIST_ROUNDING
17373 ;; Base name for define_insn
17374 (define_int_attr rounding_insn
17375 [(UNSPEC_FRNDINT_ROUNDEVEN "roundeven")
17376 (UNSPEC_FRNDINT_FLOOR "floor")
17377 (UNSPEC_FRNDINT_CEIL "ceil")
17378 (UNSPEC_FRNDINT_TRUNC "btrunc")
17379 (UNSPEC_FIST_FLOOR "floor")
17380 (UNSPEC_FIST_CEIL "ceil")])
17382 (define_int_attr rounding
17383 [(UNSPEC_FRNDINT_ROUNDEVEN "roundeven")
17384 (UNSPEC_FRNDINT_FLOOR "floor")
17385 (UNSPEC_FRNDINT_CEIL "ceil")
17386 (UNSPEC_FRNDINT_TRUNC "trunc")
17387 (UNSPEC_FIST_FLOOR "floor")
17388 (UNSPEC_FIST_CEIL "ceil")])
17390 (define_int_attr ROUNDING
17391 [(UNSPEC_FRNDINT_ROUNDEVEN "ROUNDEVEN")
17392 (UNSPEC_FRNDINT_FLOOR "FLOOR")
17393 (UNSPEC_FRNDINT_CEIL "CEIL")
17394 (UNSPEC_FRNDINT_TRUNC "TRUNC")
17395 (UNSPEC_FIST_FLOOR "FLOOR")
17396 (UNSPEC_FIST_CEIL "CEIL")])
17398 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17399 (define_insn_and_split "frndintxf2_<rounding>"
17400 [(set (match_operand:XF 0 "register_operand")
17401 (unspec:XF [(match_operand:XF 1 "register_operand")]
17403 (clobber (reg:CC FLAGS_REG))]
17404 "TARGET_USE_FANCY_MATH_387
17405 && (flag_fp_int_builtin_inexact || !flag_trapping_math)
17406 && ix86_pre_reload_split ()"
17411 ix86_optimize_mode_switching[I387_<ROUNDING>] = 1;
17413 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17414 operands[3] = assign_386_stack_local (HImode, SLOT_CW_<ROUNDING>);
17416 emit_insn (gen_frndintxf2_<rounding>_i387 (operands[0], operands[1],
17417 operands[2], operands[3]));
17420 [(set_attr "type" "frndint")
17421 (set_attr "i387_cw" "<rounding>")
17422 (set_attr "mode" "XF")])
17424 (define_insn "frndintxf2_<rounding>_i387"
17425 [(set (match_operand:XF 0 "register_operand" "=f")
17426 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17428 (use (match_operand:HI 2 "memory_operand" "m"))
17429 (use (match_operand:HI 3 "memory_operand" "m"))]
17430 "TARGET_USE_FANCY_MATH_387
17431 && (flag_fp_int_builtin_inexact || !flag_trapping_math)"
17432 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
17433 [(set_attr "type" "frndint")
17434 (set_attr "i387_cw" "<rounding>")
17435 (set_attr "mode" "XF")])
17437 (define_expand "<rounding_insn>xf2"
17438 [(parallel [(set (match_operand:XF 0 "register_operand")
17439 (unspec:XF [(match_operand:XF 1 "register_operand")]
17441 (clobber (reg:CC FLAGS_REG))])]
17442 "TARGET_USE_FANCY_MATH_387
17443 && (flag_fp_int_builtin_inexact || !flag_trapping_math)")
17445 (define_expand "<rounding_insn><mode>2"
17446 [(parallel [(set (match_operand:MODEF 0 "register_operand")
17447 (unspec:MODEF [(match_operand:MODEF 1 "register_operand")]
17449 (clobber (reg:CC FLAGS_REG))])]
17450 "(TARGET_USE_FANCY_MATH_387
17451 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17452 || TARGET_MIX_SSE_I387)
17453 && (flag_fp_int_builtin_inexact || !flag_trapping_math))
17454 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17456 || (ROUND_<ROUNDING> != ROUND_ROUNDEVEN
17457 && (flag_fp_int_builtin_inexact || !flag_trapping_math))))"
17459 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17461 || (ROUND_<ROUNDING> != ROUND_ROUNDEVEN
17462 && (flag_fp_int_builtin_inexact || !flag_trapping_math))))
17465 emit_insn (gen_sse4_1_round<mode>2
17466 (operands[0], operands[1],
17467 GEN_INT (ROUND_<ROUNDING> | ROUND_NO_EXC)));
17468 else if (TARGET_64BIT || (<MODE>mode != DFmode))
17470 if (ROUND_<ROUNDING> == ROUND_FLOOR)
17471 ix86_expand_floorceil (operands[0], operands[1], true);
17472 else if (ROUND_<ROUNDING> == ROUND_CEIL)
17473 ix86_expand_floorceil (operands[0], operands[1], false);
17474 else if (ROUND_<ROUNDING> == ROUND_TRUNC)
17475 ix86_expand_trunc (operands[0], operands[1]);
17477 gcc_unreachable ();
17481 if (ROUND_<ROUNDING> == ROUND_FLOOR)
17482 ix86_expand_floorceildf_32 (operands[0], operands[1], true);
17483 else if (ROUND_<ROUNDING> == ROUND_CEIL)
17484 ix86_expand_floorceildf_32 (operands[0], operands[1], false);
17485 else if (ROUND_<ROUNDING> == ROUND_TRUNC)
17486 ix86_expand_truncdf_32 (operands[0], operands[1]);
17488 gcc_unreachable ();
17493 rtx op0 = gen_reg_rtx (XFmode);
17494 rtx op1 = gen_reg_rtx (XFmode);
17496 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17497 emit_insn (gen_frndintxf2_<rounding> (op0, op1));
17498 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
17503 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17504 (define_insn_and_split "*fist<mode>2_<rounding>_1"
17505 [(set (match_operand:SWI248x 0 "nonimmediate_operand")
17506 (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
17508 (clobber (reg:CC FLAGS_REG))]
17509 "TARGET_USE_FANCY_MATH_387
17510 && flag_unsafe_math_optimizations
17511 && ix86_pre_reload_split ()"
17516 ix86_optimize_mode_switching[I387_<ROUNDING>] = 1;
17518 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17519 operands[3] = assign_386_stack_local (HImode, SLOT_CW_<ROUNDING>);
17521 emit_insn (gen_fist<mode>2_<rounding> (operands[0], operands[1],
17522 operands[2], operands[3]));
17525 [(set_attr "type" "fistp")
17526 (set_attr "i387_cw" "<rounding>")
17527 (set_attr "mode" "<MODE>")])
17529 (define_insn "fistdi2_<rounding>"
17530 [(set (match_operand:DI 0 "nonimmediate_operand" "=m")
17531 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17533 (use (match_operand:HI 2 "memory_operand" "m"))
17534 (use (match_operand:HI 3 "memory_operand" "m"))
17535 (clobber (match_scratch:XF 4 "=&f"))]
17536 "TARGET_USE_FANCY_MATH_387
17537 && flag_unsafe_math_optimizations"
17538 "* return output_fix_trunc (insn, operands, false);"
17539 [(set_attr "type" "fistp")
17540 (set_attr "i387_cw" "<rounding>")
17541 (set_attr "mode" "DI")])
17543 (define_insn "fist<mode>2_<rounding>"
17544 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m")
17545 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
17547 (use (match_operand:HI 2 "memory_operand" "m"))
17548 (use (match_operand:HI 3 "memory_operand" "m"))]
17549 "TARGET_USE_FANCY_MATH_387
17550 && flag_unsafe_math_optimizations"
17551 "* return output_fix_trunc (insn, operands, false);"
17552 [(set_attr "type" "fistp")
17553 (set_attr "i387_cw" "<rounding>")
17554 (set_attr "mode" "<MODE>")])
17556 (define_expand "l<rounding_insn>xf<mode>2"
17557 [(parallel [(set (match_operand:SWI248x 0 "nonimmediate_operand")
17558 (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
17560 (clobber (reg:CC FLAGS_REG))])]
17561 "TARGET_USE_FANCY_MATH_387
17562 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17563 && flag_unsafe_math_optimizations")
17565 (define_expand "l<rounding_insn><MODEF:mode><SWI48:mode>2"
17566 [(parallel [(set (match_operand:SWI48 0 "nonimmediate_operand")
17567 (unspec:SWI48 [(match_operand:MODEF 1 "register_operand")]
17569 (clobber (reg:CC FLAGS_REG))])]
17570 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
17571 && (TARGET_SSE4_1 || !flag_trapping_math)"
17575 rtx tmp = gen_reg_rtx (<MODEF:MODE>mode);
17577 emit_insn (gen_sse4_1_round<MODEF:mode>2
17578 (tmp, operands[1], GEN_INT (ROUND_<ROUNDING>
17580 emit_insn (gen_fix_trunc<MODEF:mode><SWI48:mode>2
17581 (operands[0], tmp));
17583 else if (ROUND_<ROUNDING> == ROUND_FLOOR)
17584 ix86_expand_lfloorceil (operands[0], operands[1], true);
17585 else if (ROUND_<ROUNDING> == ROUND_CEIL)
17586 ix86_expand_lfloorceil (operands[0], operands[1], false);
17588 gcc_unreachable ();
17593 (define_insn "fxam<mode>2_i387"
17594 [(set (match_operand:HI 0 "register_operand" "=a")
17596 [(match_operand:X87MODEF 1 "register_operand" "f")]
17598 "TARGET_USE_FANCY_MATH_387"
17599 "fxam\n\tfnstsw\t%0"
17600 [(set_attr "type" "multi")
17601 (set_attr "length" "4")
17602 (set_attr "unit" "i387")
17603 (set_attr "mode" "<MODE>")])
17605 (define_expand "signbittf2"
17606 [(use (match_operand:SI 0 "register_operand"))
17607 (use (match_operand:TF 1 "register_operand"))]
17612 rtx mask = ix86_build_signbit_mask (TFmode, 0, 0);
17613 rtx scratch = gen_reg_rtx (QImode);
17615 emit_insn (gen_ptesttf2 (operands[1], mask));
17616 ix86_expand_setcc (scratch, NE,
17617 gen_rtx_REG (CCZmode, FLAGS_REG), const0_rtx);
17619 emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
17623 emit_insn (gen_sse_movmskps (operands[0],
17624 gen_lowpart (V4SFmode, operands[1])));
17625 emit_insn (gen_andsi3 (operands[0], operands[0], GEN_INT (0x8)));
17630 (define_expand "signbitxf2"
17631 [(use (match_operand:SI 0 "register_operand"))
17632 (use (match_operand:XF 1 "register_operand"))]
17633 "TARGET_USE_FANCY_MATH_387"
17635 rtx scratch = gen_reg_rtx (HImode);
17637 emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
17638 emit_insn (gen_andsi3 (operands[0],
17639 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
17643 (define_insn "movmsk_df"
17644 [(set (match_operand:SI 0 "register_operand" "=r")
17646 [(match_operand:DF 1 "register_operand" "x")]
17648 "SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH"
17649 "%vmovmskpd\t{%1, %0|%0, %1}"
17650 [(set_attr "type" "ssemov")
17651 (set_attr "prefix" "maybe_vex")
17652 (set_attr "mode" "DF")])
17654 ;; Use movmskpd in SSE mode to avoid store forwarding stall
17655 ;; for 32bit targets and movq+shrq sequence for 64bit targets.
17656 (define_expand "signbitdf2"
17657 [(use (match_operand:SI 0 "register_operand"))
17658 (use (match_operand:DF 1 "register_operand"))]
17659 "TARGET_USE_FANCY_MATH_387
17660 || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
17662 if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)
17664 emit_insn (gen_movmsk_df (operands[0], operands[1]));
17665 emit_insn (gen_andsi3 (operands[0], operands[0], const1_rtx));
17669 rtx scratch = gen_reg_rtx (HImode);
17671 emit_insn (gen_fxamdf2_i387 (scratch, operands[1]));
17672 emit_insn (gen_andsi3 (operands[0],
17673 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
17678 (define_expand "signbitsf2"
17679 [(use (match_operand:SI 0 "register_operand"))
17680 (use (match_operand:SF 1 "register_operand"))]
17681 "TARGET_USE_FANCY_MATH_387
17682 && !(SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH)"
17684 rtx scratch = gen_reg_rtx (HImode);
17686 emit_insn (gen_fxamsf2_i387 (scratch, operands[1]));
17687 emit_insn (gen_andsi3 (operands[0],
17688 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
17692 ;; Block operation instructions
17695 [(unspec_volatile [(const_int 0)] UNSPECV_CLD)]
17698 [(set_attr "length" "1")
17699 (set_attr "length_immediate" "0")
17700 (set_attr "modrm" "0")])
17702 (define_expand "cpymem<mode>"
17703 [(use (match_operand:BLK 0 "memory_operand"))
17704 (use (match_operand:BLK 1 "memory_operand"))
17705 (use (match_operand:SWI48 2 "nonmemory_operand"))
17706 (use (match_operand:SWI48 3 "const_int_operand"))
17707 (use (match_operand:SI 4 "const_int_operand"))
17708 (use (match_operand:SI 5 "const_int_operand"))
17709 (use (match_operand:SI 6 ""))
17710 (use (match_operand:SI 7 ""))
17711 (use (match_operand:SI 8 ""))]
17714 if (ix86_expand_set_or_cpymem (operands[0], operands[1],
17715 operands[2], NULL, operands[3],
17716 operands[4], operands[5],
17717 operands[6], operands[7],
17718 operands[8], false))
17724 ;; Most CPUs don't like single string operations
17725 ;; Handle this case here to simplify previous expander.
17727 (define_expand "strmov"
17728 [(set (match_dup 4) (match_operand 3 "memory_operand"))
17729 (set (match_operand 1 "memory_operand") (match_dup 4))
17730 (parallel [(set (match_operand 0 "register_operand") (match_dup 5))
17731 (clobber (reg:CC FLAGS_REG))])
17732 (parallel [(set (match_operand 2 "register_operand") (match_dup 6))
17733 (clobber (reg:CC FLAGS_REG))])]
17736 /* Can't use this for non-default address spaces. */
17737 if (!ADDR_SPACE_GENERIC_P (MEM_ADDR_SPACE (operands[3])))
17740 int piece_size = GET_MODE_SIZE (GET_MODE (operands[1]));
17742 /* If .md ever supports :P for Pmode, these can be directly
17743 in the pattern above. */
17744 operands[5] = plus_constant (Pmode, operands[0], piece_size);
17745 operands[6] = plus_constant (Pmode, operands[2], piece_size);
17747 /* Can't use this if the user has appropriated esi or edi. */
17748 if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
17749 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG]))
17751 emit_insn (gen_strmov_singleop (operands[0], operands[1],
17752 operands[2], operands[3],
17753 operands[5], operands[6]));
17757 operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
17760 (define_expand "strmov_singleop"
17761 [(parallel [(set (match_operand 1 "memory_operand")
17762 (match_operand 3 "memory_operand"))
17763 (set (match_operand 0 "register_operand")
17765 (set (match_operand 2 "register_operand")
17766 (match_operand 5))])]
17770 ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
17773 (define_insn "*strmovdi_rex_1"
17774 [(set (mem:DI (match_operand:P 2 "register_operand" "0"))
17775 (mem:DI (match_operand:P 3 "register_operand" "1")))
17776 (set (match_operand:P 0 "register_operand" "=D")
17777 (plus:P (match_dup 2)
17779 (set (match_operand:P 1 "register_operand" "=S")
17780 (plus:P (match_dup 3)
17783 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG])
17784 && ix86_check_no_addr_space (insn)"
17786 [(set_attr "type" "str")
17787 (set_attr "memory" "both")
17788 (set_attr "mode" "DI")])
17790 (define_insn "*strmovsi_1"
17791 [(set (mem:SI (match_operand:P 2 "register_operand" "0"))
17792 (mem:SI (match_operand:P 3 "register_operand" "1")))
17793 (set (match_operand:P 0 "register_operand" "=D")
17794 (plus:P (match_dup 2)
17796 (set (match_operand:P 1 "register_operand" "=S")
17797 (plus:P (match_dup 3)
17799 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])
17800 && ix86_check_no_addr_space (insn)"
17802 [(set_attr "type" "str")
17803 (set_attr "memory" "both")
17804 (set_attr "mode" "SI")])
17806 (define_insn "*strmovhi_1"
17807 [(set (mem:HI (match_operand:P 2 "register_operand" "0"))
17808 (mem:HI (match_operand:P 3 "register_operand" "1")))
17809 (set (match_operand:P 0 "register_operand" "=D")
17810 (plus:P (match_dup 2)
17812 (set (match_operand:P 1 "register_operand" "=S")
17813 (plus:P (match_dup 3)
17815 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])
17816 && ix86_check_no_addr_space (insn)"
17818 [(set_attr "type" "str")
17819 (set_attr "memory" "both")
17820 (set_attr "mode" "HI")])
17822 (define_insn "*strmovqi_1"
17823 [(set (mem:QI (match_operand:P 2 "register_operand" "0"))
17824 (mem:QI (match_operand:P 3 "register_operand" "1")))
17825 (set (match_operand:P 0 "register_operand" "=D")
17826 (plus:P (match_dup 2)
17828 (set (match_operand:P 1 "register_operand" "=S")
17829 (plus:P (match_dup 3)
17831 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])
17832 && ix86_check_no_addr_space (insn)"
17834 [(set_attr "type" "str")
17835 (set_attr "memory" "both")
17836 (set (attr "prefix_rex")
17838 (match_test "<P:MODE>mode == DImode")
17840 (const_string "*")))
17841 (set_attr "mode" "QI")])
17843 (define_expand "rep_mov"
17844 [(parallel [(set (match_operand 4 "register_operand") (const_int 0))
17845 (set (match_operand 0 "register_operand")
17847 (set (match_operand 2 "register_operand")
17849 (set (match_operand 1 "memory_operand")
17850 (match_operand 3 "memory_operand"))
17851 (use (match_dup 4))])]
17855 ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
17858 (define_insn "*rep_movdi_rex64"
17859 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
17860 (set (match_operand:P 0 "register_operand" "=D")
17861 (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
17863 (match_operand:P 3 "register_operand" "0")))
17864 (set (match_operand:P 1 "register_operand" "=S")
17865 (plus:P (ashift:P (match_dup 5) (const_int 3))
17866 (match_operand:P 4 "register_operand" "1")))
17867 (set (mem:BLK (match_dup 3))
17868 (mem:BLK (match_dup 4)))
17869 (use (match_dup 5))]
17871 && !(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
17872 && ix86_check_no_addr_space (insn)"
17874 [(set_attr "type" "str")
17875 (set_attr "prefix_rep" "1")
17876 (set_attr "memory" "both")
17877 (set_attr "mode" "DI")])
17879 (define_insn "*rep_movsi"
17880 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
17881 (set (match_operand:P 0 "register_operand" "=D")
17882 (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
17884 (match_operand:P 3 "register_operand" "0")))
17885 (set (match_operand:P 1 "register_operand" "=S")
17886 (plus:P (ashift:P (match_dup 5) (const_int 2))
17887 (match_operand:P 4 "register_operand" "1")))
17888 (set (mem:BLK (match_dup 3))
17889 (mem:BLK (match_dup 4)))
17890 (use (match_dup 5))]
17891 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
17892 && ix86_check_no_addr_space (insn)"
17893 "%^rep{%;} movs{l|d}"
17894 [(set_attr "type" "str")
17895 (set_attr "prefix_rep" "1")
17896 (set_attr "memory" "both")
17897 (set_attr "mode" "SI")])
17899 (define_insn "*rep_movqi"
17900 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
17901 (set (match_operand:P 0 "register_operand" "=D")
17902 (plus:P (match_operand:P 3 "register_operand" "0")
17903 (match_operand:P 5 "register_operand" "2")))
17904 (set (match_operand:P 1 "register_operand" "=S")
17905 (plus:P (match_operand:P 4 "register_operand" "1") (match_dup 5)))
17906 (set (mem:BLK (match_dup 3))
17907 (mem:BLK (match_dup 4)))
17908 (use (match_dup 5))]
17909 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
17910 && ix86_check_no_addr_space (insn)"
17912 [(set_attr "type" "str")
17913 (set_attr "prefix_rep" "1")
17914 (set_attr "memory" "both")
17915 (set_attr "mode" "QI")])
17917 (define_expand "setmem<mode>"
17918 [(use (match_operand:BLK 0 "memory_operand"))
17919 (use (match_operand:SWI48 1 "nonmemory_operand"))
17920 (use (match_operand:QI 2 "nonmemory_operand"))
17921 (use (match_operand 3 "const_int_operand"))
17922 (use (match_operand:SI 4 "const_int_operand"))
17923 (use (match_operand:SI 5 "const_int_operand"))
17924 (use (match_operand:SI 6 ""))
17925 (use (match_operand:SI 7 ""))
17926 (use (match_operand:SI 8 ""))]
17929 if (ix86_expand_set_or_cpymem (operands[0], NULL,
17930 operands[1], operands[2],
17931 operands[3], operands[4],
17932 operands[5], operands[6],
17933 operands[7], operands[8], true))
17939 ;; Most CPUs don't like single string operations
17940 ;; Handle this case here to simplify previous expander.
17942 (define_expand "strset"
17943 [(set (match_operand 1 "memory_operand")
17944 (match_operand 2 "register_operand"))
17945 (parallel [(set (match_operand 0 "register_operand")
17947 (clobber (reg:CC FLAGS_REG))])]
17950 /* Can't use this for non-default address spaces. */
17951 if (!ADDR_SPACE_GENERIC_P (MEM_ADDR_SPACE (operands[1])))
17954 if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
17955 operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
17957 /* If .md ever supports :P for Pmode, this can be directly
17958 in the pattern above. */
17959 operands[3] = plus_constant (Pmode, operands[0],
17960 GET_MODE_SIZE (GET_MODE (operands[2])));
17962 /* Can't use this if the user has appropriated eax or edi. */
17963 if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
17964 && !(fixed_regs[AX_REG] || fixed_regs[DI_REG]))
17966 emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
17972 (define_expand "strset_singleop"
17973 [(parallel [(set (match_operand 1 "memory_operand")
17974 (match_operand 2 "register_operand"))
17975 (set (match_operand 0 "register_operand")
17977 (unspec [(const_int 0)] UNSPEC_STOS)])]
17981 ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
17984 (define_insn "*strsetdi_rex_1"
17985 [(set (mem:DI (match_operand:P 1 "register_operand" "0"))
17986 (match_operand:DI 2 "register_operand" "a"))
17987 (set (match_operand:P 0 "register_operand" "=D")
17988 (plus:P (match_dup 1)
17990 (unspec [(const_int 0)] UNSPEC_STOS)]
17992 && !(fixed_regs[AX_REG] || fixed_regs[DI_REG])
17993 && ix86_check_no_addr_space (insn)"
17995 [(set_attr "type" "str")
17996 (set_attr "memory" "store")
17997 (set_attr "mode" "DI")])
17999 (define_insn "*strsetsi_1"
18000 [(set (mem:SI (match_operand:P 1 "register_operand" "0"))
18001 (match_operand:SI 2 "register_operand" "a"))
18002 (set (match_operand:P 0 "register_operand" "=D")
18003 (plus:P (match_dup 1)
18005 (unspec [(const_int 0)] UNSPEC_STOS)]
18006 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])
18007 && ix86_check_no_addr_space (insn)"
18009 [(set_attr "type" "str")
18010 (set_attr "memory" "store")
18011 (set_attr "mode" "SI")])
18013 (define_insn "*strsethi_1"
18014 [(set (mem:HI (match_operand:P 1 "register_operand" "0"))
18015 (match_operand:HI 2 "register_operand" "a"))
18016 (set (match_operand:P 0 "register_operand" "=D")
18017 (plus:P (match_dup 1)
18019 (unspec [(const_int 0)] UNSPEC_STOS)]
18020 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])
18021 && ix86_check_no_addr_space (insn)"
18023 [(set_attr "type" "str")
18024 (set_attr "memory" "store")
18025 (set_attr "mode" "HI")])
18027 (define_insn "*strsetqi_1"
18028 [(set (mem:QI (match_operand:P 1 "register_operand" "0"))
18029 (match_operand:QI 2 "register_operand" "a"))
18030 (set (match_operand:P 0 "register_operand" "=D")
18031 (plus:P (match_dup 1)
18033 (unspec [(const_int 0)] UNSPEC_STOS)]
18034 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])
18035 && ix86_check_no_addr_space (insn)"
18037 [(set_attr "type" "str")
18038 (set_attr "memory" "store")
18039 (set (attr "prefix_rex")
18041 (match_test "<P:MODE>mode == DImode")
18043 (const_string "*")))
18044 (set_attr "mode" "QI")])
18046 (define_expand "rep_stos"
18047 [(parallel [(set (match_operand 1 "register_operand") (const_int 0))
18048 (set (match_operand 0 "register_operand")
18050 (set (match_operand 2 "memory_operand") (const_int 0))
18051 (use (match_operand 3 "register_operand"))
18052 (use (match_dup 1))])]
18056 ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
18059 (define_insn "*rep_stosdi_rex64"
18060 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
18061 (set (match_operand:P 0 "register_operand" "=D")
18062 (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
18064 (match_operand:P 3 "register_operand" "0")))
18065 (set (mem:BLK (match_dup 3))
18067 (use (match_operand:DI 2 "register_operand" "a"))
18068 (use (match_dup 4))]
18070 && !(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])
18071 && ix86_check_no_addr_space (insn)"
18073 [(set_attr "type" "str")
18074 (set_attr "prefix_rep" "1")
18075 (set_attr "memory" "store")
18076 (set_attr "mode" "DI")])
18078 (define_insn "*rep_stossi"
18079 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
18080 (set (match_operand:P 0 "register_operand" "=D")
18081 (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
18083 (match_operand:P 3 "register_operand" "0")))
18084 (set (mem:BLK (match_dup 3))
18086 (use (match_operand:SI 2 "register_operand" "a"))
18087 (use (match_dup 4))]
18088 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])
18089 && ix86_check_no_addr_space (insn)"
18090 "%^rep{%;} stos{l|d}"
18091 [(set_attr "type" "str")
18092 (set_attr "prefix_rep" "1")
18093 (set_attr "memory" "store")
18094 (set_attr "mode" "SI")])
18096 (define_insn "*rep_stosqi"
18097 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
18098 (set (match_operand:P 0 "register_operand" "=D")
18099 (plus:P (match_operand:P 3 "register_operand" "0")
18100 (match_operand:P 4 "register_operand" "1")))
18101 (set (mem:BLK (match_dup 3))
18103 (use (match_operand:QI 2 "register_operand" "a"))
18104 (use (match_dup 4))]
18105 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])
18106 && ix86_check_no_addr_space (insn)"
18108 [(set_attr "type" "str")
18109 (set_attr "prefix_rep" "1")
18110 (set_attr "memory" "store")
18111 (set (attr "prefix_rex")
18113 (match_test "<P:MODE>mode == DImode")
18115 (const_string "*")))
18116 (set_attr "mode" "QI")])
18118 (define_expand "cmpmemsi"
18119 [(set (match_operand:SI 0 "register_operand" "")
18120 (compare:SI (match_operand:BLK 1 "memory_operand" "")
18121 (match_operand:BLK 2 "memory_operand" "") ) )
18122 (use (match_operand 3 "general_operand"))
18123 (use (match_operand 4 "immediate_operand"))]
18126 if (ix86_expand_cmpstrn_or_cmpmem (operands[0], operands[1],
18127 operands[2], operands[3],
18128 operands[4], false))
18134 (define_expand "cmpstrnsi"
18135 [(set (match_operand:SI 0 "register_operand")
18136 (compare:SI (match_operand:BLK 1 "general_operand")
18137 (match_operand:BLK 2 "general_operand")))
18138 (use (match_operand 3 "general_operand"))
18139 (use (match_operand 4 "immediate_operand"))]
18142 if (ix86_expand_cmpstrn_or_cmpmem (operands[0], operands[1],
18143 operands[2], operands[3],
18144 operands[4], true))
18150 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
18152 (define_expand "cmpintqi"
18153 [(set (match_dup 1)
18154 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
18156 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
18157 (parallel [(set (match_operand:QI 0 "register_operand")
18158 (minus:QI (match_dup 1)
18160 (clobber (reg:CC FLAGS_REG))])]
18163 operands[1] = gen_reg_rtx (QImode);
18164 operands[2] = gen_reg_rtx (QImode);
18167 ;; memcmp recognizers. The `cmpsb' opcode does nothing if the count is
18168 ;; zero. Emit extra code to make sure that a zero-length compare is EQ.
18170 (define_expand "cmpstrnqi_nz_1"
18171 [(parallel [(set (reg:CC FLAGS_REG)
18172 (compare:CC (match_operand 4 "memory_operand")
18173 (match_operand 5 "memory_operand")))
18174 (use (match_operand 2 "register_operand"))
18175 (use (match_operand:SI 3 "immediate_operand"))
18176 (clobber (match_operand 0 "register_operand"))
18177 (clobber (match_operand 1 "register_operand"))
18178 (clobber (match_dup 2))])]
18182 ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
18185 (define_insn "*cmpstrnqi_nz_1"
18186 [(set (reg:CC FLAGS_REG)
18187 (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
18188 (mem:BLK (match_operand:P 5 "register_operand" "1"))))
18189 (use (match_operand:P 6 "register_operand" "2"))
18190 (use (match_operand:SI 3 "immediate_operand" "i"))
18191 (clobber (match_operand:P 0 "register_operand" "=S"))
18192 (clobber (match_operand:P 1 "register_operand" "=D"))
18193 (clobber (match_operand:P 2 "register_operand" "=c"))]
18194 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
18195 && ix86_check_no_addr_space (insn)"
18197 [(set_attr "type" "str")
18198 (set_attr "mode" "QI")
18199 (set (attr "prefix_rex")
18201 (match_test "<P:MODE>mode == DImode")
18203 (const_string "*")))
18204 (set_attr "prefix_rep" "1")])
18206 ;; The same, but the count is not known to not be zero.
18208 (define_expand "cmpstrnqi_1"
18209 [(parallel [(set (reg:CC FLAGS_REG)
18210 (if_then_else:CC (ne (match_operand 2 "register_operand")
18212 (compare:CC (match_operand 4 "memory_operand")
18213 (match_operand 5 "memory_operand"))
18215 (use (match_operand:SI 3 "immediate_operand"))
18216 (use (reg:CC FLAGS_REG))
18217 (clobber (match_operand 0 "register_operand"))
18218 (clobber (match_operand 1 "register_operand"))
18219 (clobber (match_dup 2))])]
18223 ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
18226 (define_insn "*cmpstrnqi_1"
18227 [(set (reg:CC FLAGS_REG)
18228 (if_then_else:CC (ne (match_operand:P 6 "register_operand" "2")
18230 (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
18231 (mem:BLK (match_operand:P 5 "register_operand" "1")))
18233 (use (match_operand:SI 3 "immediate_operand" "i"))
18234 (use (reg:CC FLAGS_REG))
18235 (clobber (match_operand:P 0 "register_operand" "=S"))
18236 (clobber (match_operand:P 1 "register_operand" "=D"))
18237 (clobber (match_operand:P 2 "register_operand" "=c"))]
18238 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
18239 && ix86_check_no_addr_space (insn)"
18241 [(set_attr "type" "str")
18242 (set_attr "mode" "QI")
18243 (set (attr "prefix_rex")
18245 (match_test "<P:MODE>mode == DImode")
18247 (const_string "*")))
18248 (set_attr "prefix_rep" "1")])
18250 (define_expand "strlen<mode>"
18251 [(set (match_operand:P 0 "register_operand")
18252 (unspec:P [(match_operand:BLK 1 "general_operand")
18253 (match_operand:QI 2 "immediate_operand")
18254 (match_operand 3 "immediate_operand")]
18258 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
18264 (define_expand "strlenqi_1"
18265 [(parallel [(set (match_operand 0 "register_operand")
18267 (clobber (match_operand 1 "register_operand"))
18268 (clobber (reg:CC FLAGS_REG))])]
18272 ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
18275 (define_insn "*strlenqi_1"
18276 [(set (match_operand:P 0 "register_operand" "=&c")
18277 (unspec:P [(mem:BLK (match_operand:P 5 "register_operand" "1"))
18278 (match_operand:QI 2 "register_operand" "a")
18279 (match_operand:P 3 "immediate_operand" "i")
18280 (match_operand:P 4 "register_operand" "0")] UNSPEC_SCAS))
18281 (clobber (match_operand:P 1 "register_operand" "=D"))
18282 (clobber (reg:CC FLAGS_REG))]
18283 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])
18284 && ix86_check_no_addr_space (insn)"
18285 "%^repnz{%;} scasb"
18286 [(set_attr "type" "str")
18287 (set_attr "mode" "QI")
18288 (set (attr "prefix_rex")
18290 (match_test "<P:MODE>mode == DImode")
18292 (const_string "*")))
18293 (set_attr "prefix_rep" "1")])
18295 ;; Peephole optimizations to clean up after cmpstrn*. This should be
18296 ;; handled in combine, but it is not currently up to the task.
18297 ;; When used for their truth value, the cmpstrn* expanders generate
18306 ;; The intermediate three instructions are unnecessary.
18308 ;; This one handles cmpstrn*_nz_1...
18311 (set (reg:CC FLAGS_REG)
18312 (compare:CC (mem:BLK (match_operand 4 "register_operand"))
18313 (mem:BLK (match_operand 5 "register_operand"))))
18314 (use (match_operand 6 "register_operand"))
18315 (use (match_operand:SI 3 "immediate_operand"))
18316 (clobber (match_operand 0 "register_operand"))
18317 (clobber (match_operand 1 "register_operand"))
18318 (clobber (match_operand 2 "register_operand"))])
18319 (set (match_operand:QI 7 "register_operand")
18320 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
18321 (set (match_operand:QI 8 "register_operand")
18322 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
18323 (set (reg FLAGS_REG)
18324 (compare (match_dup 7) (match_dup 8)))
18326 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
18328 (set (reg:CC FLAGS_REG)
18329 (compare:CC (mem:BLK (match_dup 4))
18330 (mem:BLK (match_dup 5))))
18331 (use (match_dup 6))
18332 (use (match_dup 3))
18333 (clobber (match_dup 0))
18334 (clobber (match_dup 1))
18335 (clobber (match_dup 2))])])
18337 ;; ...and this one handles cmpstrn*_1.
18340 (set (reg:CC FLAGS_REG)
18341 (if_then_else:CC (ne (match_operand 6 "register_operand")
18343 (compare:CC (mem:BLK (match_operand 4 "register_operand"))
18344 (mem:BLK (match_operand 5 "register_operand")))
18346 (use (match_operand:SI 3 "immediate_operand"))
18347 (use (reg:CC FLAGS_REG))
18348 (clobber (match_operand 0 "register_operand"))
18349 (clobber (match_operand 1 "register_operand"))
18350 (clobber (match_operand 2 "register_operand"))])
18351 (set (match_operand:QI 7 "register_operand")
18352 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
18353 (set (match_operand:QI 8 "register_operand")
18354 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
18355 (set (reg FLAGS_REG)
18356 (compare (match_dup 7) (match_dup 8)))
18358 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
18360 (set (reg:CC FLAGS_REG)
18361 (if_then_else:CC (ne (match_dup 6)
18363 (compare:CC (mem:BLK (match_dup 4))
18364 (mem:BLK (match_dup 5)))
18366 (use (match_dup 3))
18367 (use (reg:CC FLAGS_REG))
18368 (clobber (match_dup 0))
18369 (clobber (match_dup 1))
18370 (clobber (match_dup 2))])])
18372 ;; Conditional move instructions.
18374 (define_expand "mov<mode>cc"
18375 [(set (match_operand:SWIM 0 "register_operand")
18376 (if_then_else:SWIM (match_operand 1 "comparison_operator")
18377 (match_operand:SWIM 2 "<general_operand>")
18378 (match_operand:SWIM 3 "<general_operand>")))]
18380 "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
18382 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
18383 ;; the register first winds up with `sbbl $0,reg', which is also weird.
18384 ;; So just document what we're doing explicitly.
18386 (define_expand "x86_mov<mode>cc_0_m1"
18388 [(set (match_operand:SWI48 0 "register_operand")
18389 (if_then_else:SWI48
18390 (match_operator:SWI48 2 "ix86_carry_flag_operator"
18391 [(match_operand 1 "flags_reg_operand")
18395 (clobber (reg:CC FLAGS_REG))])])
18397 (define_insn "*x86_mov<mode>cc_0_m1"
18398 [(set (match_operand:SWI48 0 "register_operand" "=r")
18399 (if_then_else:SWI48 (match_operator 1 "ix86_carry_flag_operator"
18400 [(reg FLAGS_REG) (const_int 0)])
18403 (clobber (reg:CC FLAGS_REG))]
18405 "sbb{<imodesuffix>}\t%0, %0"
18406 [(set_attr "type" "alu1")
18407 (set_attr "use_carry" "1")
18408 (set_attr "pent_pair" "pu")
18409 (set_attr "mode" "<MODE>")
18410 (set_attr "length_immediate" "0")])
18412 (define_insn "*x86_mov<mode>cc_0_m1_se"
18413 [(set (match_operand:SWI48 0 "register_operand" "=r")
18414 (sign_extract:SWI48 (match_operator 1 "ix86_carry_flag_operator"
18415 [(reg FLAGS_REG) (const_int 0)])
18418 (clobber (reg:CC FLAGS_REG))]
18420 "sbb{<imodesuffix>}\t%0, %0"
18421 [(set_attr "type" "alu1")
18422 (set_attr "use_carry" "1")
18423 (set_attr "pent_pair" "pu")
18424 (set_attr "mode" "<MODE>")
18425 (set_attr "length_immediate" "0")])
18427 (define_insn "*x86_mov<mode>cc_0_m1_neg"
18428 [(set (match_operand:SWI 0 "register_operand" "=<r>")
18429 (neg:SWI (match_operator 1 "ix86_carry_flag_operator"
18430 [(reg FLAGS_REG) (const_int 0)])))
18431 (clobber (reg:CC FLAGS_REG))]
18433 "sbb{<imodesuffix>}\t%0, %0"
18434 [(set_attr "type" "alu1")
18435 (set_attr "use_carry" "1")
18436 (set_attr "pent_pair" "pu")
18437 (set_attr "mode" "<MODE>")
18438 (set_attr "length_immediate" "0")])
18441 [(set (match_operand:SWI48 0 "register_operand")
18444 (match_operand 1 "int_nonimmediate_operand")
18445 (match_operand 2 "const_int_operand"))))]
18446 "x86_64_immediate_operand (operands[2], VOIDmode)
18447 && INTVAL (operands[2]) != -1
18448 && INTVAL (operands[2]) != 2147483647"
18449 [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
18450 (parallel [(set (match_dup 0)
18451 (neg:SWI48 (ltu:SWI48 (reg:CC FLAGS_REG) (const_int 0))))
18452 (clobber (reg:CC FLAGS_REG))])]
18453 "operands[2] = GEN_INT (INTVAL (operands[2]) + 1);")
18456 [(set (match_operand:SWI 0 "register_operand")
18459 (match_operand 1 "int_nonimmediate_operand")
18462 [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (const_int 1)))
18463 (parallel [(set (match_dup 0)
18464 (neg:SWI (ltu:SWI (reg:CC FLAGS_REG) (const_int 0))))
18465 (clobber (reg:CC FLAGS_REG))])])
18468 [(set (match_operand:SWI 0 "register_operand")
18471 (match_operand 1 "int_nonimmediate_operand")
18474 [(parallel [(set (reg:CCC FLAGS_REG)
18475 (ne:CCC (match_dup 1) (const_int 0)))
18476 (clobber (match_dup 2))])
18477 (parallel [(set (match_dup 0)
18478 (neg:SWI (ltu:SWI (reg:CCC FLAGS_REG) (const_int 0))))
18479 (clobber (reg:CC FLAGS_REG))])]
18480 "operands[2] = gen_rtx_SCRATCH (GET_MODE (operands[1]));")
18482 (define_insn "*mov<mode>cc_noc"
18483 [(set (match_operand:SWI248 0 "register_operand" "=r,r")
18484 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
18485 [(reg FLAGS_REG) (const_int 0)])
18486 (match_operand:SWI248 2 "nonimmediate_operand" "rm,0")
18487 (match_operand:SWI248 3 "nonimmediate_operand" "0,rm")))]
18488 "TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
18490 cmov%O2%C1\t{%2, %0|%0, %2}
18491 cmov%O2%c1\t{%3, %0|%0, %3}"
18492 [(set_attr "type" "icmov")
18493 (set_attr "mode" "<MODE>")])
18495 (define_insn "*movsicc_noc_zext"
18496 [(set (match_operand:DI 0 "register_operand" "=r,r")
18497 (if_then_else:DI (match_operator 1 "ix86_comparison_operator"
18498 [(reg FLAGS_REG) (const_int 0)])
18500 (match_operand:SI 2 "nonimmediate_operand" "rm,0"))
18502 (match_operand:SI 3 "nonimmediate_operand" "0,rm"))))]
18504 && TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
18506 cmov%O2%C1\t{%2, %k0|%k0, %2}
18507 cmov%O2%c1\t{%3, %k0|%k0, %3}"
18508 [(set_attr "type" "icmov")
18509 (set_attr "mode" "SI")])
18511 ;; Don't do conditional moves with memory inputs. This splitter helps
18512 ;; register starved x86_32 by forcing inputs into registers before reload.
18514 [(set (match_operand:SWI248 0 "register_operand")
18515 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
18516 [(reg FLAGS_REG) (const_int 0)])
18517 (match_operand:SWI248 2 "nonimmediate_operand")
18518 (match_operand:SWI248 3 "nonimmediate_operand")))]
18519 "!TARGET_64BIT && TARGET_CMOVE
18520 && TARGET_AVOID_MEM_OPND_FOR_CMOVE
18521 && (MEM_P (operands[2]) || MEM_P (operands[3]))
18522 && can_create_pseudo_p ()
18523 && optimize_insn_for_speed_p ()"
18524 [(set (match_dup 0)
18525 (if_then_else:SWI248 (match_dup 1) (match_dup 2) (match_dup 3)))]
18527 if (MEM_P (operands[2]))
18528 operands[2] = force_reg (<MODE>mode, operands[2]);
18529 if (MEM_P (operands[3]))
18530 operands[3] = force_reg (<MODE>mode, operands[3]);
18533 (define_insn "*movqicc_noc"
18534 [(set (match_operand:QI 0 "register_operand" "=r,r")
18535 (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
18536 [(reg FLAGS_REG) (const_int 0)])
18537 (match_operand:QI 2 "register_operand" "r,0")
18538 (match_operand:QI 3 "register_operand" "0,r")))]
18539 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
18541 [(set_attr "type" "icmov")
18542 (set_attr "mode" "QI")])
18545 [(set (match_operand:SWI12 0 "register_operand")
18546 (if_then_else:SWI12 (match_operator 1 "ix86_comparison_operator"
18547 [(reg FLAGS_REG) (const_int 0)])
18548 (match_operand:SWI12 2 "register_operand")
18549 (match_operand:SWI12 3 "register_operand")))]
18550 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL
18551 && reload_completed"
18552 [(set (match_dup 0)
18553 (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
18555 operands[0] = gen_lowpart (SImode, operands[0]);
18556 operands[2] = gen_lowpart (SImode, operands[2]);
18557 operands[3] = gen_lowpart (SImode, operands[3]);
18560 ;; Don't do conditional moves with memory inputs
18562 [(match_scratch:SWI248 4 "r")
18563 (set (match_operand:SWI248 0 "register_operand")
18564 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
18565 [(reg FLAGS_REG) (const_int 0)])
18566 (match_operand:SWI248 2 "nonimmediate_operand")
18567 (match_operand:SWI248 3 "nonimmediate_operand")))]
18568 "TARGET_CMOVE && TARGET_AVOID_MEM_OPND_FOR_CMOVE
18569 && (MEM_P (operands[2]) || MEM_P (operands[3]))
18570 && optimize_insn_for_speed_p ()"
18571 [(set (match_dup 4) (match_dup 5))
18573 (if_then_else:SWI248 (match_dup 1) (match_dup 2) (match_dup 3)))]
18575 if (MEM_P (operands[2]))
18577 operands[5] = operands[2];
18578 operands[2] = operands[4];
18580 else if (MEM_P (operands[3]))
18582 operands[5] = operands[3];
18583 operands[3] = operands[4];
18586 gcc_unreachable ();
18590 [(match_scratch:SI 4 "r")
18591 (set (match_operand:DI 0 "register_operand")
18592 (if_then_else:DI (match_operator 1 "ix86_comparison_operator"
18593 [(reg FLAGS_REG) (const_int 0)])
18595 (match_operand:SI 2 "nonimmediate_operand"))
18597 (match_operand:SI 3 "nonimmediate_operand"))))]
18599 && TARGET_CMOVE && TARGET_AVOID_MEM_OPND_FOR_CMOVE
18600 && (MEM_P (operands[2]) || MEM_P (operands[3]))
18601 && optimize_insn_for_speed_p ()"
18602 [(set (match_dup 4) (match_dup 5))
18604 (if_then_else:DI (match_dup 1)
18605 (zero_extend:DI (match_dup 2))
18606 (zero_extend:DI (match_dup 3))))]
18608 if (MEM_P (operands[2]))
18610 operands[5] = operands[2];
18611 operands[2] = operands[4];
18613 else if (MEM_P (operands[3]))
18615 operands[5] = operands[3];
18616 operands[3] = operands[4];
18619 gcc_unreachable ();
18622 (define_expand "mov<mode>cc"
18623 [(set (match_operand:X87MODEF 0 "register_operand")
18624 (if_then_else:X87MODEF
18625 (match_operand 1 "comparison_operator")
18626 (match_operand:X87MODEF 2 "register_operand")
18627 (match_operand:X87MODEF 3 "register_operand")))]
18628 "(TARGET_80387 && TARGET_CMOVE)
18629 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
18630 "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
18632 (define_insn "*movxfcc_1"
18633 [(set (match_operand:XF 0 "register_operand" "=f,f")
18634 (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
18635 [(reg FLAGS_REG) (const_int 0)])
18636 (match_operand:XF 2 "register_operand" "f,0")
18637 (match_operand:XF 3 "register_operand" "0,f")))]
18638 "TARGET_80387 && TARGET_CMOVE"
18640 fcmov%F1\t{%2, %0|%0, %2}
18641 fcmov%f1\t{%3, %0|%0, %3}"
18642 [(set_attr "type" "fcmov")
18643 (set_attr "mode" "XF")])
18645 (define_insn "*movdfcc_1"
18646 [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r,r ,r")
18647 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
18648 [(reg FLAGS_REG) (const_int 0)])
18649 (match_operand:DF 2 "nonimmediate_operand"
18651 (match_operand:DF 3 "nonimmediate_operand"
18652 "0 ,f,0 ,rm,0, rm")))]
18653 "TARGET_80387 && TARGET_CMOVE
18654 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
18656 fcmov%F1\t{%2, %0|%0, %2}
18657 fcmov%f1\t{%3, %0|%0, %3}
18660 cmov%O2%C1\t{%2, %0|%0, %2}
18661 cmov%O2%c1\t{%3, %0|%0, %3}"
18662 [(set_attr "isa" "*,*,nox64,nox64,x64,x64")
18663 (set_attr "type" "fcmov,fcmov,multi,multi,icmov,icmov")
18664 (set_attr "mode" "DF,DF,DI,DI,DI,DI")])
18667 [(set (match_operand:DF 0 "general_reg_operand")
18668 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
18669 [(reg FLAGS_REG) (const_int 0)])
18670 (match_operand:DF 2 "nonimmediate_operand")
18671 (match_operand:DF 3 "nonimmediate_operand")))]
18672 "!TARGET_64BIT && reload_completed"
18673 [(set (match_dup 2)
18674 (if_then_else:SI (match_dup 1) (match_dup 4) (match_dup 5)))
18676 (if_then_else:SI (match_dup 1) (match_dup 6) (match_dup 7)))]
18678 split_double_mode (DImode, &operands[2], 2, &operands[4], &operands[6]);
18679 split_double_mode (DImode, &operands[0], 1, &operands[2], &operands[3]);
18682 (define_insn "*movsfcc_1_387"
18683 [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
18684 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
18685 [(reg FLAGS_REG) (const_int 0)])
18686 (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
18687 (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
18688 "TARGET_80387 && TARGET_CMOVE
18689 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
18691 fcmov%F1\t{%2, %0|%0, %2}
18692 fcmov%f1\t{%3, %0|%0, %3}
18693 cmov%O2%C1\t{%2, %0|%0, %2}
18694 cmov%O2%c1\t{%3, %0|%0, %3}"
18695 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
18696 (set_attr "mode" "SF,SF,SI,SI")])
18698 ;; Don't do conditional moves with memory inputs. This splitter helps
18699 ;; register starved x86_32 by forcing inputs into registers before reload.
18701 [(set (match_operand:MODEF 0 "register_operand")
18702 (if_then_else:MODEF (match_operator 1 "ix86_comparison_operator"
18703 [(reg FLAGS_REG) (const_int 0)])
18704 (match_operand:MODEF 2 "nonimmediate_operand")
18705 (match_operand:MODEF 3 "nonimmediate_operand")))]
18706 "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
18707 && TARGET_AVOID_MEM_OPND_FOR_CMOVE
18708 && (MEM_P (operands[2]) || MEM_P (operands[3]))
18709 && can_create_pseudo_p ()
18710 && optimize_insn_for_speed_p ()"
18711 [(set (match_dup 0)
18712 (if_then_else:MODEF (match_dup 1) (match_dup 2) (match_dup 3)))]
18714 if (MEM_P (operands[2]))
18715 operands[2] = force_reg (<MODE>mode, operands[2]);
18716 if (MEM_P (operands[3]))
18717 operands[3] = force_reg (<MODE>mode, operands[3]);
18720 ;; Don't do conditional moves with memory inputs
18722 [(match_scratch:MODEF 4 "r")
18723 (set (match_operand:MODEF 0 "general_reg_operand")
18724 (if_then_else:MODEF (match_operator 1 "fcmov_comparison_operator"
18725 [(reg FLAGS_REG) (const_int 0)])
18726 (match_operand:MODEF 2 "nonimmediate_operand")
18727 (match_operand:MODEF 3 "nonimmediate_operand")))]
18728 "(<MODE>mode != DFmode || TARGET_64BIT)
18729 && TARGET_80387 && TARGET_CMOVE
18730 && TARGET_AVOID_MEM_OPND_FOR_CMOVE
18731 && (MEM_P (operands[2]) || MEM_P (operands[3]))
18732 && optimize_insn_for_speed_p ()"
18733 [(set (match_dup 4) (match_dup 5))
18735 (if_then_else:MODEF (match_dup 1) (match_dup 2) (match_dup 3)))]
18737 if (MEM_P (operands[2]))
18739 operands[5] = operands[2];
18740 operands[2] = operands[4];
18742 else if (MEM_P (operands[3]))
18744 operands[5] = operands[3];
18745 operands[3] = operands[4];
18748 gcc_unreachable ();
18751 ;; All moves in XOP pcmov instructions are 128 bits and hence we restrict
18752 ;; the scalar versions to have only XMM registers as operands.
18754 ;; XOP conditional move
18755 (define_insn "*xop_pcmov_<mode>"
18756 [(set (match_operand:MODEF 0 "register_operand" "=x")
18757 (if_then_else:MODEF
18758 (match_operand:MODEF 1 "register_operand" "x")
18759 (match_operand:MODEF 2 "register_operand" "x")
18760 (match_operand:MODEF 3 "register_operand" "x")))]
18762 "vpcmov\t{%1, %3, %2, %0|%0, %2, %3, %1}"
18763 [(set_attr "type" "sse4arg")])
18765 ;; These versions of the min/max patterns are intentionally ignorant of
18766 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
18767 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
18768 ;; are undefined in this condition, we're certain this is correct.
18770 (define_insn "<code><mode>3"
18771 [(set (match_operand:MODEF 0 "register_operand" "=x,v")
18773 (match_operand:MODEF 1 "nonimmediate_operand" "%0,v")
18774 (match_operand:MODEF 2 "nonimmediate_operand" "xm,vm")))]
18775 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
18777 <maxmin_float><ssemodesuffix>\t{%2, %0|%0, %2}
18778 v<maxmin_float><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
18779 [(set_attr "isa" "noavx,avx")
18780 (set_attr "prefix" "orig,vex")
18781 (set_attr "type" "sseadd")
18782 (set_attr "mode" "<MODE>")])
18784 ;; These versions of the min/max patterns implement exactly the operations
18785 ;; min = (op1 < op2 ? op1 : op2)
18786 ;; max = (!(op1 < op2) ? op1 : op2)
18787 ;; Their operands are not commutative, and thus they may be used in the
18788 ;; presence of -0.0 and NaN.
18790 (define_insn "*ieee_s<ieee_maxmin><mode>3"
18791 [(set (match_operand:MODEF 0 "register_operand" "=x,v")
18793 [(match_operand:MODEF 1 "register_operand" "0,v")
18794 (match_operand:MODEF 2 "nonimmediate_operand" "xm,vm")]
18796 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
18798 <ieee_maxmin><ssemodesuffix>\t{%2, %0|%0, %2}
18799 v<ieee_maxmin><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
18800 [(set_attr "isa" "noavx,avx")
18801 (set_attr "prefix" "orig,maybe_evex")
18802 (set_attr "type" "sseadd")
18803 (set_attr "mode" "<MODE>")])
18805 ;; Make two stack loads independent:
18807 ;; fld %st(0) -> fld bb
18808 ;; fmul bb fmul %st(1), %st
18810 ;; Actually we only match the last two instructions for simplicity.
18813 [(set (match_operand 0 "fp_register_operand")
18814 (match_operand 1 "fp_register_operand"))
18816 (match_operator 2 "binary_fp_operator"
18818 (match_operand 3 "memory_operand")]))]
18819 "REGNO (operands[0]) != REGNO (operands[1])"
18820 [(set (match_dup 0) (match_dup 3))
18823 [(match_dup 5) (match_dup 4)]))]
18825 operands[4] = operands[0];
18826 operands[5] = operands[1];
18828 /* The % modifier is not operational anymore in peephole2's, so we have to
18829 swap the operands manually in the case of addition and multiplication. */
18830 if (COMMUTATIVE_ARITH_P (operands[2]))
18831 std::swap (operands[4], operands[5]);
18835 [(set (match_operand 0 "fp_register_operand")
18836 (match_operand 1 "fp_register_operand"))
18838 (match_operator 2 "binary_fp_operator"
18839 [(match_operand 3 "memory_operand")
18841 "REGNO (operands[0]) != REGNO (operands[1])"
18842 [(set (match_dup 0) (match_dup 3))
18845 [(match_dup 4) (match_dup 5)]))]
18847 operands[4] = operands[0];
18848 operands[5] = operands[1];
18850 /* The % modifier is not operational anymore in peephole2's, so we have to
18851 swap the operands manually in the case of addition and multiplication. */
18852 if (COMMUTATIVE_ARITH_P (operands[2]))
18853 std::swap (operands[4], operands[5]);
18856 ;; Conditional addition patterns
18857 (define_expand "add<mode>cc"
18858 [(match_operand:SWI 0 "register_operand")
18859 (match_operand 1 "ordered_comparison_operator")
18860 (match_operand:SWI 2 "register_operand")
18861 (match_operand:SWI 3 "const_int_operand")]
18863 "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
18865 ;; min/max patterns
18867 (define_code_attr maxmin_rel
18868 [(smax "GE") (smin "LE") (umax "GEU") (umin "LEU")])
18870 (define_expand "<code><mode>3"
18872 [(set (match_operand:SWI248 0 "register_operand")
18874 (match_operand:SWI248 1 "register_operand")
18875 (match_operand:SWI248 2 "general_operand")))
18876 (clobber (reg:CC FLAGS_REG))])]
18879 (define_insn_and_split "*<code><mode>3_1"
18880 [(set (match_operand:SWI248 0 "register_operand")
18882 (match_operand:SWI248 1 "register_operand")
18883 (match_operand:SWI248 2 "general_operand")))
18884 (clobber (reg:CC FLAGS_REG))]
18886 && ix86_pre_reload_split ()"
18889 [(set (match_dup 0)
18890 (if_then_else:SWI248 (match_dup 3)
18894 machine_mode mode = <MODE>mode;
18895 rtx cmp_op = operands[2];
18897 if (!register_operand (cmp_op, mode))
18898 operands[2] = force_reg (mode, cmp_op);
18900 enum rtx_code code = <maxmin_rel>;
18902 if (cmp_op == const1_rtx)
18904 /* Convert smax (x, 1) into (x > 0 ? x : 1).
18905 Convert umax (x, 1) into (x != 0 ? x : 1).
18906 Convert ?min (x, 1) into (x <= 0 ? x : 1). */
18907 cmp_op = const0_rtx;
18910 else if (code == GEU)
18913 /* Convert smin (x, -1) into (x < 0 ? x : -1). */
18914 else if (cmp_op == constm1_rtx && code == LE)
18916 cmp_op = const0_rtx;
18919 /* Convert smax (x, -1) into (x >= 0 ? x : -1). */
18920 else if (cmp_op == constm1_rtx && code == GE)
18921 cmp_op = const0_rtx;
18922 else if (cmp_op != const0_rtx)
18923 cmp_op = operands[2];
18925 machine_mode cmpmode = SELECT_CC_MODE (code, operands[1], cmp_op);
18926 rtx flags = gen_rtx_REG (cmpmode, FLAGS_REG);
18928 rtx tmp = gen_rtx_COMPARE (cmpmode, operands[1], cmp_op);
18929 emit_insn (gen_rtx_SET (flags, tmp));
18931 operands[3] = gen_rtx_fmt_ee (code, VOIDmode, flags, const0_rtx);
18934 (define_insn_and_split "*<code>di3_doubleword"
18935 [(set (match_operand:DI 0 "register_operand")
18936 (maxmin:DI (match_operand:DI 1 "register_operand")
18937 (match_operand:DI 2 "general_operand")))
18938 (clobber (reg:CC FLAGS_REG))]
18939 "!TARGET_64BIT && TARGET_CMOVE
18940 && ix86_pre_reload_split ()"
18943 [(set (match_dup 0)
18944 (if_then_else:SI (match_dup 6)
18948 (if_then_else:SI (match_dup 6)
18952 if (!register_operand (operands[2], DImode))
18953 operands[2] = force_reg (DImode, operands[2]);
18955 split_double_mode (DImode, &operands[0], 3, &operands[0], &operands[3]);
18957 rtx cmplo[2] = { operands[1], operands[2] };
18958 rtx cmphi[2] = { operands[4], operands[5] };
18960 enum rtx_code code = <maxmin_rel>;
18965 std::swap (cmplo[0], cmplo[1]);
18966 std::swap (cmphi[0], cmphi[1]);
18967 code = swap_condition (code);
18972 bool uns = (code == GEU);
18973 rtx (*sbb_insn) (machine_mode, rtx, rtx, rtx)
18974 = uns ? gen_sub3_carry_ccc : gen_sub3_carry_ccgz;
18976 emit_insn (gen_cmp_1 (SImode, cmplo[0], cmplo[1]));
18978 rtx tmp = gen_rtx_SCRATCH (SImode);
18979 emit_insn (sbb_insn (SImode, tmp, cmphi[0], cmphi[1]));
18981 rtx flags = gen_rtx_REG (uns ? CCCmode : CCGZmode, FLAGS_REG);
18982 operands[6] = gen_rtx_fmt_ee (code, VOIDmode, flags, const0_rtx);
18988 gcc_unreachable ();
18992 ;; Avoid clearing a register between a flags setting comparison and its use,
18993 ;; i.e. prefer "xorl %eax,%eax; test/cmp" over "test/cmp; movl $0, %eax".
18995 [(set (reg FLAGS_REG) (match_operand 0))
18996 (set (match_operand:SWI 1 "general_reg_operand") (const_int 0))]
18997 "peep2_regno_dead_p (0, FLAGS_REG)
18998 && !reg_overlap_mentioned_p (operands[1], operands[0])"
18999 [(set (match_dup 2) (match_dup 0))]
19001 operands[2] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
19002 ix86_expand_clear (operands[1]);
19005 ;; Reload dislikes loading constants directly into class_likely_spilled
19006 ;; hard registers. Try to tidy things up here.
19008 [(set (match_operand:SWI 0 "general_reg_operand")
19009 (match_operand:SWI 1 "x86_64_general_operand"))
19010 (set (match_operand:SWI 2 "general_reg_operand")
19012 "peep2_reg_dead_p (2, operands[0])"
19013 [(set (match_dup 2) (match_dup 1))])
19015 ;; Misc patterns (?)
19017 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
19018 ;; Otherwise there will be nothing to keep
19020 ;; [(set (reg ebp) (reg esp))]
19021 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
19022 ;; (clobber (eflags)]
19023 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
19025 ;; in proper program order.
19027 (define_insn "@pro_epilogue_adjust_stack_add_<mode>"
19028 [(set (match_operand:P 0 "register_operand" "=r,r")
19029 (plus:P (match_operand:P 1 "register_operand" "0,r")
19030 (match_operand:P 2 "<nonmemory_operand>" "r<i>,l<i>")))
19031 (clobber (reg:CC FLAGS_REG))
19032 (clobber (mem:BLK (scratch)))]
19035 switch (get_attr_type (insn))
19038 return "mov{<imodesuffix>}\t{%1, %0|%0, %1}";
19041 gcc_assert (rtx_equal_p (operands[0], operands[1]));
19042 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
19043 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
19045 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
19048 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
19049 return "lea{<imodesuffix>}\t{%E2, %0|%0, %E2}";
19052 [(set (attr "type")
19053 (cond [(and (eq_attr "alternative" "0")
19054 (not (match_test "TARGET_OPT_AGU")))
19055 (const_string "alu")
19056 (match_operand:<MODE> 2 "const0_operand")
19057 (const_string "imov")
19059 (const_string "lea")))
19060 (set (attr "length_immediate")
19061 (cond [(eq_attr "type" "imov")
19063 (and (eq_attr "type" "alu")
19064 (match_operand 2 "const128_operand"))
19067 (const_string "*")))
19068 (set_attr "mode" "<MODE>")])
19070 (define_insn "@pro_epilogue_adjust_stack_sub_<mode>"
19071 [(set (match_operand:P 0 "register_operand" "=r")
19072 (minus:P (match_operand:P 1 "register_operand" "0")
19073 (match_operand:P 2 "register_operand" "r")))
19074 (clobber (reg:CC FLAGS_REG))
19075 (clobber (mem:BLK (scratch)))]
19077 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
19078 [(set_attr "type" "alu")
19079 (set_attr "mode" "<MODE>")])
19081 (define_insn "@allocate_stack_worker_probe_<mode>"
19082 [(set (match_operand:P 0 "register_operand" "=a")
19083 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
19084 UNSPECV_STACK_PROBE))
19085 (clobber (reg:CC FLAGS_REG))]
19086 "ix86_target_stack_probe ()"
19087 "call\t___chkstk_ms"
19088 [(set_attr "type" "multi")
19089 (set_attr "length" "5")])
19091 (define_expand "allocate_stack"
19092 [(match_operand 0 "register_operand")
19093 (match_operand 1 "general_operand")]
19094 "ix86_target_stack_probe ()"
19098 #ifndef CHECK_STACK_LIMIT
19099 #define CHECK_STACK_LIMIT 0
19102 if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
19103 && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
19107 x = copy_to_mode_reg (Pmode, operands[1]);
19109 emit_insn (gen_allocate_stack_worker_probe (Pmode, x, x));
19112 x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, x,
19113 stack_pointer_rtx, 0, OPTAB_DIRECT);
19115 if (x != stack_pointer_rtx)
19116 emit_move_insn (stack_pointer_rtx, x);
19118 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
19122 (define_expand "probe_stack"
19123 [(match_operand 0 "memory_operand")]
19126 emit_insn (gen_probe_stack_1
19127 (word_mode, operands[0], const0_rtx));
19131 ;; Use OR for stack probes, this is shorter.
19132 (define_insn "@probe_stack_1_<mode>"
19133 [(set (match_operand:W 0 "memory_operand" "=m")
19134 (unspec:W [(match_operand:W 1 "const0_operand")]
19135 UNSPEC_PROBE_STACK))
19136 (clobber (reg:CC FLAGS_REG))]
19138 "or{<imodesuffix>}\t{%1, %0|%0, %1}"
19139 [(set_attr "type" "alu1")
19140 (set_attr "mode" "<MODE>")
19141 (set_attr "length_immediate" "1")])
19143 (define_insn "@adjust_stack_and_probe_<mode>"
19144 [(set (match_operand:P 0 "register_operand" "=r")
19145 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
19146 UNSPECV_PROBE_STACK_RANGE))
19147 (set (reg:P SP_REG)
19148 (minus:P (reg:P SP_REG) (match_operand:P 2 "const_int_operand" "n")))
19149 (clobber (reg:CC FLAGS_REG))
19150 (clobber (mem:BLK (scratch)))]
19152 "* return output_adjust_stack_and_probe (operands[0]);"
19153 [(set_attr "type" "multi")])
19155 (define_insn "@probe_stack_range_<mode>"
19156 [(set (match_operand:P 0 "register_operand" "=r")
19157 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
19158 (match_operand:P 2 "const_int_operand" "n")]
19159 UNSPECV_PROBE_STACK_RANGE))
19160 (clobber (reg:CC FLAGS_REG))]
19162 "* return output_probe_stack_range (operands[0], operands[2]);"
19163 [(set_attr "type" "multi")])
19165 (define_expand "builtin_setjmp_receiver"
19166 [(label_ref (match_operand 0))]
19167 "!TARGET_64BIT && flag_pic"
19173 rtx_code_label *label_rtx = gen_label_rtx ();
19174 emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
19175 xops[0] = xops[1] = pic_offset_table_rtx;
19176 xops[2] = machopic_gen_offset (gen_rtx_LABEL_REF (SImode, label_rtx));
19177 ix86_expand_binary_operator (MINUS, SImode, xops);
19181 emit_insn (gen_set_got (pic_offset_table_rtx));
19185 (define_expand "save_stack_nonlocal"
19186 [(set (match_operand 0 "memory_operand")
19187 (match_operand 1 "register_operand"))]
19192 if (flag_cf_protection & CF_RETURN)
19194 /* Copy shadow stack pointer to the first slot
19195 and stack pointer to the second slot. */
19196 rtx ssp_slot = adjust_address (operands[0], word_mode, 0);
19197 stack_slot = adjust_address (operands[0], Pmode, UNITS_PER_WORD);
19199 rtx reg_ssp = force_reg (word_mode, const0_rtx);
19200 emit_insn (gen_rdssp (word_mode, reg_ssp, reg_ssp));
19201 emit_move_insn (ssp_slot, reg_ssp);
19204 stack_slot = adjust_address (operands[0], Pmode, 0);
19205 emit_move_insn (stack_slot, operands[1]);
19209 (define_expand "restore_stack_nonlocal"
19210 [(set (match_operand 0 "register_operand" "")
19211 (match_operand 1 "memory_operand" ""))]
19216 if (flag_cf_protection & CF_RETURN)
19218 /* Restore shadow stack pointer from the first slot
19219 and stack pointer from the second slot. */
19220 rtx ssp_slot = adjust_address (operands[1], word_mode, 0);
19221 stack_slot = adjust_address (operands[1], Pmode, UNITS_PER_WORD);
19223 /* Get the current shadow stack pointer. The code below will check if
19224 SHSTK feature is enabled. If it is not enabled the RDSSP instruction
19226 rtx reg_ssp = force_reg (word_mode, const0_rtx);
19227 emit_insn (gen_rdssp (word_mode, reg_ssp, reg_ssp));
19229 /* Compare through subtraction the saved and the current ssp
19230 to decide if ssp has to be adjusted. */
19231 reg_ssp = expand_simple_binop (word_mode, MINUS,
19233 reg_ssp, 1, OPTAB_DIRECT);
19235 /* Compare and jump over adjustment code. */
19236 rtx noadj_label = gen_label_rtx ();
19237 emit_cmp_and_jump_insns (reg_ssp, const0_rtx, EQ, NULL_RTX,
19238 word_mode, 1, noadj_label);
19240 /* Compute the number of frames to adjust. */
19241 rtx reg_adj = gen_lowpart (ptr_mode, reg_ssp);
19242 rtx reg_adj_neg = expand_simple_unop (ptr_mode, NEG, reg_adj,
19245 reg_adj = expand_simple_binop (ptr_mode, LSHIFTRT, reg_adj_neg,
19246 GEN_INT (exact_log2 (UNITS_PER_WORD)),
19247 reg_adj, 1, OPTAB_DIRECT);
19249 /* Check if number of frames <= 255 so no loop is needed. */
19250 rtx inc_label = gen_label_rtx ();
19251 emit_cmp_and_jump_insns (reg_adj, GEN_INT (255), LEU, NULL_RTX,
19252 ptr_mode, 1, inc_label);
19254 /* Adjust the ssp in a loop. */
19255 rtx loop_label = gen_label_rtx ();
19256 emit_label (loop_label);
19257 LABEL_NUSES (loop_label) = 1;
19259 rtx reg_255 = force_reg (word_mode, GEN_INT (255));
19260 emit_insn (gen_incssp (word_mode, reg_255));
19262 reg_adj = expand_simple_binop (ptr_mode, MINUS,
19263 reg_adj, GEN_INT (255),
19264 reg_adj, 1, OPTAB_DIRECT);
19266 /* Compare and jump to the loop label. */
19267 emit_cmp_and_jump_insns (reg_adj, GEN_INT (255), GTU, NULL_RTX,
19268 ptr_mode, 1, loop_label);
19270 emit_label (inc_label);
19271 LABEL_NUSES (inc_label) = 1;
19273 emit_insn (gen_incssp (word_mode, reg_ssp));
19275 emit_label (noadj_label);
19276 LABEL_NUSES (noadj_label) = 1;
19279 stack_slot = adjust_address (operands[1], Pmode, 0);
19280 emit_move_insn (operands[0], stack_slot);
19285 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
19286 ;; Do not split instructions with mask registers.
19288 [(set (match_operand 0 "general_reg_operand")
19289 (match_operator 3 "promotable_binary_operator"
19290 [(match_operand 1 "general_reg_operand")
19291 (match_operand 2 "aligned_operand")]))
19292 (clobber (reg:CC FLAGS_REG))]
19293 "! TARGET_PARTIAL_REG_STALL && reload_completed
19294 && ((GET_MODE (operands[0]) == HImode
19295 && ((optimize_function_for_speed_p (cfun) && !TARGET_FAST_PREFIX)
19296 /* ??? next two lines just !satisfies_constraint_K (...) */
19297 || !CONST_INT_P (operands[2])
19298 || satisfies_constraint_K (operands[2])))
19299 || (GET_MODE (operands[0]) == QImode
19300 && (TARGET_PROMOTE_QImode || optimize_function_for_size_p (cfun))))"
19301 [(parallel [(set (match_dup 0)
19302 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
19303 (clobber (reg:CC FLAGS_REG))])]
19305 operands[0] = gen_lowpart (SImode, operands[0]);
19306 operands[1] = gen_lowpart (SImode, operands[1]);
19307 if (GET_CODE (operands[3]) != ASHIFT)
19308 operands[2] = gen_lowpart (SImode, operands[2]);
19309 operands[3] = shallow_copy_rtx (operands[3]);
19310 PUT_MODE (operands[3], SImode);
19313 ; Promote the QImode tests, as i386 has encoding of the AND
19314 ; instruction with 32-bit sign-extended immediate and thus the
19315 ; instruction size is unchanged, except in the %eax case for
19316 ; which it is increased by one byte, hence the ! optimize_size.
19318 [(set (match_operand 0 "flags_reg_operand")
19319 (match_operator 2 "compare_operator"
19320 [(and (match_operand 3 "aligned_operand")
19321 (match_operand 4 "const_int_operand"))
19323 (set (match_operand 1 "register_operand")
19324 (and (match_dup 3) (match_dup 4)))]
19325 "! TARGET_PARTIAL_REG_STALL && reload_completed
19326 && optimize_insn_for_speed_p ()
19327 && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
19328 || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))
19329 /* Ensure that the operand will remain sign-extended immediate. */
19330 && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)"
19331 [(parallel [(set (match_dup 0)
19332 (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
19335 (and:SI (match_dup 3) (match_dup 4)))])]
19338 = gen_int_mode (INTVAL (operands[4])
19339 & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
19340 operands[1] = gen_lowpart (SImode, operands[1]);
19341 operands[3] = gen_lowpart (SImode, operands[3]);
19344 ; Don't promote the QImode tests, as i386 doesn't have encoding of
19345 ; the TEST instruction with 32-bit sign-extended immediate and thus
19346 ; the instruction size would at least double, which is not what we
19347 ; want even with ! optimize_size.
19349 [(set (match_operand 0 "flags_reg_operand")
19350 (match_operator 1 "compare_operator"
19351 [(and (match_operand:HI 2 "aligned_operand")
19352 (match_operand:HI 3 "const_int_operand"))
19354 "! TARGET_PARTIAL_REG_STALL && reload_completed
19355 && ! TARGET_FAST_PREFIX
19356 && optimize_insn_for_speed_p ()
19357 /* Ensure that the operand will remain sign-extended immediate. */
19358 && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)"
19359 [(set (match_dup 0)
19360 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
19364 = gen_int_mode (INTVAL (operands[3])
19365 & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
19366 operands[2] = gen_lowpart (SImode, operands[2]);
19370 [(set (match_operand 0 "register_operand")
19371 (neg (match_operand 1 "register_operand")))
19372 (clobber (reg:CC FLAGS_REG))]
19373 "! TARGET_PARTIAL_REG_STALL && reload_completed
19374 && (GET_MODE (operands[0]) == HImode
19375 || (GET_MODE (operands[0]) == QImode
19376 && (TARGET_PROMOTE_QImode
19377 || optimize_insn_for_size_p ())))"
19378 [(parallel [(set (match_dup 0)
19379 (neg:SI (match_dup 1)))
19380 (clobber (reg:CC FLAGS_REG))])]
19382 operands[0] = gen_lowpart (SImode, operands[0]);
19383 operands[1] = gen_lowpart (SImode, operands[1]);
19386 ;; Do not split instructions with mask regs.
19388 [(set (match_operand 0 "general_reg_operand")
19389 (not (match_operand 1 "general_reg_operand")))]
19390 "! TARGET_PARTIAL_REG_STALL && reload_completed
19391 && (GET_MODE (operands[0]) == HImode
19392 || (GET_MODE (operands[0]) == QImode
19393 && (TARGET_PROMOTE_QImode
19394 || optimize_insn_for_size_p ())))"
19395 [(set (match_dup 0)
19396 (not:SI (match_dup 1)))]
19398 operands[0] = gen_lowpart (SImode, operands[0]);
19399 operands[1] = gen_lowpart (SImode, operands[1]);
19402 ;; RTL Peephole optimizations, run before sched2. These primarily look to
19403 ;; transform a complex memory operation into two memory to register operations.
19405 ;; Don't push memory operands
19407 [(set (match_operand:SWI 0 "push_operand")
19408 (match_operand:SWI 1 "memory_operand"))
19409 (match_scratch:SWI 2 "<r>")]
19410 "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
19411 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19412 [(set (match_dup 2) (match_dup 1))
19413 (set (match_dup 0) (match_dup 2))])
19415 ;; We need to handle SFmode only, because DFmode and XFmode are split to
19418 [(set (match_operand:SF 0 "push_operand")
19419 (match_operand:SF 1 "memory_operand"))
19420 (match_scratch:SF 2 "r")]
19421 "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
19422 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19423 [(set (match_dup 2) (match_dup 1))
19424 (set (match_dup 0) (match_dup 2))])
19426 ;; Don't move an immediate directly to memory when the instruction
19427 ;; gets too big, or if LCP stalls are a problem for 16-bit moves.
19429 [(match_scratch:SWI124 1 "<r>")
19430 (set (match_operand:SWI124 0 "memory_operand")
19432 "optimize_insn_for_speed_p ()
19433 && ((<MODE>mode == HImode
19434 && TARGET_LCP_STALL)
19435 || (!TARGET_USE_MOV0
19436 && TARGET_SPLIT_LONG_MOVES
19437 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn))
19438 && peep2_regno_dead_p (0, FLAGS_REG)"
19439 [(parallel [(set (match_dup 2) (const_int 0))
19440 (clobber (reg:CC FLAGS_REG))])
19441 (set (match_dup 0) (match_dup 1))]
19442 "operands[2] = gen_lowpart (SImode, operands[1]);")
19445 [(match_scratch:SWI124 2 "<r>")
19446 (set (match_operand:SWI124 0 "memory_operand")
19447 (match_operand:SWI124 1 "immediate_operand"))]
19448 "optimize_insn_for_speed_p ()
19449 && ((<MODE>mode == HImode
19450 && TARGET_LCP_STALL)
19451 || (TARGET_SPLIT_LONG_MOVES
19452 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn))"
19453 [(set (match_dup 2) (match_dup 1))
19454 (set (match_dup 0) (match_dup 2))])
19456 ;; Don't compare memory with zero, load and use a test instead.
19458 [(set (match_operand 0 "flags_reg_operand")
19459 (match_operator 1 "compare_operator"
19460 [(match_operand:SI 2 "memory_operand")
19462 (match_scratch:SI 3 "r")]
19463 "optimize_insn_for_speed_p () && ix86_match_ccmode (insn, CCNOmode)"
19464 [(set (match_dup 3) (match_dup 2))
19465 (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))])
19467 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
19468 ;; Don't split NOTs with a displacement operand, because resulting XOR
19469 ;; will not be pairable anyway.
19471 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
19472 ;; represented using a modRM byte. The XOR replacement is long decoded,
19473 ;; so this split helps here as well.
19475 ;; Note: Can't do this as a regular split because we can't get proper
19476 ;; lifetime information then.
19479 [(set (match_operand:SWI124 0 "nonimmediate_gr_operand")
19480 (not:SWI124 (match_operand:SWI124 1 "nonimmediate_gr_operand")))]
19481 "optimize_insn_for_speed_p ()
19482 && ((TARGET_NOT_UNPAIRABLE
19483 && (!MEM_P (operands[0])
19484 || !memory_displacement_operand (operands[0], <MODE>mode)))
19485 || (TARGET_NOT_VECTORMODE
19486 && long_memory_operand (operands[0], <MODE>mode)))
19487 && peep2_regno_dead_p (0, FLAGS_REG)"
19488 [(parallel [(set (match_dup 0)
19489 (xor:SWI124 (match_dup 1) (const_int -1)))
19490 (clobber (reg:CC FLAGS_REG))])])
19492 ;; Non pairable "test imm, reg" instructions can be translated to
19493 ;; "and imm, reg" if reg dies. The "and" form is also shorter (one
19494 ;; byte opcode instead of two, have a short form for byte operands),
19495 ;; so do it for other CPUs as well. Given that the value was dead,
19496 ;; this should not create any new dependencies. Pass on the sub-word
19497 ;; versions if we're concerned about partial register stalls.
19500 [(set (match_operand 0 "flags_reg_operand")
19501 (match_operator 1 "compare_operator"
19502 [(and:SI (match_operand:SI 2 "register_operand")
19503 (match_operand:SI 3 "immediate_operand"))
19505 "ix86_match_ccmode (insn, CCNOmode)
19506 && (REGNO (operands[2]) != AX_REG
19507 || satisfies_constraint_K (operands[3]))
19508 && peep2_reg_dead_p (1, operands[2])"
19510 [(set (match_dup 0)
19511 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
19514 (and:SI (match_dup 2) (match_dup 3)))])])
19516 ;; We don't need to handle HImode case, because it will be promoted to SImode
19517 ;; on ! TARGET_PARTIAL_REG_STALL
19520 [(set (match_operand 0 "flags_reg_operand")
19521 (match_operator 1 "compare_operator"
19522 [(and:QI (match_operand:QI 2 "register_operand")
19523 (match_operand:QI 3 "immediate_operand"))
19525 "! TARGET_PARTIAL_REG_STALL
19526 && ix86_match_ccmode (insn, CCNOmode)
19527 && REGNO (operands[2]) != AX_REG
19528 && peep2_reg_dead_p (1, operands[2])"
19530 [(set (match_dup 0)
19531 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
19534 (and:QI (match_dup 2) (match_dup 3)))])])
19537 [(set (match_operand 0 "flags_reg_operand")
19538 (match_operator 1 "compare_operator"
19541 (zero_extract:SWI248 (match_operand:SWI248 2 "QIreg_operand")
19544 (match_operand 3 "const_int_operand"))
19546 "! TARGET_PARTIAL_REG_STALL
19547 && ix86_match_ccmode (insn, CCNOmode)
19548 && REGNO (operands[2]) != AX_REG
19549 && peep2_reg_dead_p (1, operands[2])"
19551 [(set (match_dup 0)
19555 (zero_extract:SWI248 (match_dup 2)
19560 (set (zero_extract:SWI248 (match_dup 2)
19566 (zero_extract:SWI248 (match_dup 2)
19569 (match_dup 3)) 0))])])
19571 ;; Don't do logical operations with memory inputs.
19573 [(match_scratch:SWI 2 "<r>")
19574 (parallel [(set (match_operand:SWI 0 "register_operand")
19575 (match_operator:SWI 3 "arith_or_logical_operator"
19577 (match_operand:SWI 1 "memory_operand")]))
19578 (clobber (reg:CC FLAGS_REG))])]
19579 "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
19580 [(set (match_dup 2) (match_dup 1))
19581 (parallel [(set (match_dup 0)
19582 (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
19583 (clobber (reg:CC FLAGS_REG))])])
19586 [(match_scratch:SWI 2 "<r>")
19587 (parallel [(set (match_operand:SWI 0 "register_operand")
19588 (match_operator:SWI 3 "arith_or_logical_operator"
19589 [(match_operand:SWI 1 "memory_operand")
19591 (clobber (reg:CC FLAGS_REG))])]
19592 "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
19593 [(set (match_dup 2) (match_dup 1))
19594 (parallel [(set (match_dup 0)
19595 (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
19596 (clobber (reg:CC FLAGS_REG))])])
19598 ;; Prefer Load+RegOp to Mov+MemOp. Watch out for cases when
19599 ;; the memory address refers to the destination of the load!
19602 [(set (match_operand:SWI 0 "general_reg_operand")
19603 (match_operand:SWI 1 "general_reg_operand"))
19604 (parallel [(set (match_dup 0)
19605 (match_operator:SWI 3 "commutative_operator"
19607 (match_operand:SWI 2 "memory_operand")]))
19608 (clobber (reg:CC FLAGS_REG))])]
19609 "REGNO (operands[0]) != REGNO (operands[1])
19610 && (<MODE>mode != QImode
19611 || any_QIreg_operand (operands[1], QImode))"
19612 [(set (match_dup 0) (match_dup 4))
19613 (parallel [(set (match_dup 0)
19614 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))
19615 (clobber (reg:CC FLAGS_REG))])]
19616 "operands[4] = replace_rtx (operands[2], operands[0], operands[1], true);")
19619 [(set (match_operand 0 "mmx_reg_operand")
19620 (match_operand 1 "mmx_reg_operand"))
19622 (match_operator 3 "commutative_operator"
19624 (match_operand 2 "memory_operand")]))]
19625 "REGNO (operands[0]) != REGNO (operands[1])"
19626 [(set (match_dup 0) (match_dup 2))
19628 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))])
19631 [(set (match_operand 0 "sse_reg_operand")
19632 (match_operand 1 "sse_reg_operand"))
19634 (match_operator 3 "commutative_operator"
19636 (match_operand 2 "memory_operand")]))]
19637 "REGNO (operands[0]) != REGNO (operands[1])"
19638 [(set (match_dup 0) (match_dup 2))
19640 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))])
19642 ; Don't do logical operations with memory outputs
19644 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
19645 ; instruction into two 1-uop insns plus a 2-uop insn. That last has
19646 ; the same decoder scheduling characteristics as the original.
19649 [(match_scratch:SWI 2 "<r>")
19650 (parallel [(set (match_operand:SWI 0 "memory_operand")
19651 (match_operator:SWI 3 "arith_or_logical_operator"
19653 (match_operand:SWI 1 "<nonmemory_operand>")]))
19654 (clobber (reg:CC FLAGS_REG))])]
19655 "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())"
19656 [(set (match_dup 2) (match_dup 0))
19657 (parallel [(set (match_dup 2)
19658 (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
19659 (clobber (reg:CC FLAGS_REG))])
19660 (set (match_dup 0) (match_dup 2))])
19663 [(match_scratch:SWI 2 "<r>")
19664 (parallel [(set (match_operand:SWI 0 "memory_operand")
19665 (match_operator:SWI 3 "arith_or_logical_operator"
19666 [(match_operand:SWI 1 "<nonmemory_operand>")
19668 (clobber (reg:CC FLAGS_REG))])]
19669 "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())"
19670 [(set (match_dup 2) (match_dup 0))
19671 (parallel [(set (match_dup 2)
19672 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
19673 (clobber (reg:CC FLAGS_REG))])
19674 (set (match_dup 0) (match_dup 2))])
19676 ;; Attempt to use arith or logical operations with memory outputs with
19677 ;; setting of flags.
19679 [(set (match_operand:SWI 0 "register_operand")
19680 (match_operand:SWI 1 "memory_operand"))
19681 (parallel [(set (match_dup 0)
19682 (match_operator:SWI 3 "plusminuslogic_operator"
19684 (match_operand:SWI 2 "<nonmemory_operand>")]))
19685 (clobber (reg:CC FLAGS_REG))])
19686 (set (match_dup 1) (match_dup 0))
19687 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
19688 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
19689 && peep2_reg_dead_p (4, operands[0])
19690 && !reg_overlap_mentioned_p (operands[0], operands[1])
19691 && !reg_overlap_mentioned_p (operands[0], operands[2])
19692 && (<MODE>mode != QImode
19693 || immediate_operand (operands[2], QImode)
19694 || any_QIreg_operand (operands[2], QImode))
19695 && ix86_match_ccmode (peep2_next_insn (3),
19696 (GET_CODE (operands[3]) == PLUS
19697 || GET_CODE (operands[3]) == MINUS)
19698 ? CCGOCmode : CCNOmode)"
19699 [(parallel [(set (match_dup 4) (match_dup 6))
19700 (set (match_dup 1) (match_dup 5))])]
19702 operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
19704 = gen_rtx_fmt_ee (GET_CODE (operands[3]), GET_MODE (operands[3]),
19705 copy_rtx (operands[1]),
19708 = gen_rtx_COMPARE (GET_MODE (operands[4]),
19709 copy_rtx (operands[5]),
19713 ;; Likewise for cmpelim optimized pattern.
19715 [(set (match_operand:SWI 0 "register_operand")
19716 (match_operand:SWI 1 "memory_operand"))
19717 (parallel [(set (reg FLAGS_REG)
19718 (compare (match_operator:SWI 3 "plusminuslogic_operator"
19720 (match_operand:SWI 2 "<nonmemory_operand>")])
19722 (set (match_dup 0) (match_dup 3))])
19723 (set (match_dup 1) (match_dup 0))]
19724 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
19725 && peep2_reg_dead_p (3, operands[0])
19726 && !reg_overlap_mentioned_p (operands[0], operands[1])
19727 && !reg_overlap_mentioned_p (operands[0], operands[2])
19728 && ix86_match_ccmode (peep2_next_insn (1),
19729 (GET_CODE (operands[3]) == PLUS
19730 || GET_CODE (operands[3]) == MINUS)
19731 ? CCGOCmode : CCNOmode)"
19732 [(parallel [(set (match_dup 4) (match_dup 6))
19733 (set (match_dup 1) (match_dup 5))])]
19735 operands[4] = SET_DEST (XVECEXP (PATTERN (peep2_next_insn (1)), 0, 0));
19737 = gen_rtx_fmt_ee (GET_CODE (operands[3]), GET_MODE (operands[3]),
19738 copy_rtx (operands[1]), operands[2]);
19740 = gen_rtx_COMPARE (GET_MODE (operands[4]), copy_rtx (operands[5]),
19744 ;; Likewise for instances where we have a lea pattern.
19746 [(set (match_operand:SWI 0 "register_operand")
19747 (match_operand:SWI 1 "memory_operand"))
19748 (set (match_operand:<LEAMODE> 3 "register_operand")
19749 (plus:<LEAMODE> (match_operand:<LEAMODE> 4 "register_operand")
19750 (match_operand:<LEAMODE> 2 "<nonmemory_operand>")))
19751 (set (match_dup 1) (match_operand:SWI 5 "register_operand"))
19752 (set (reg FLAGS_REG) (compare (match_dup 5) (const_int 0)))]
19753 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
19754 && REGNO (operands[4]) == REGNO (operands[0])
19755 && REGNO (operands[5]) == REGNO (operands[3])
19756 && peep2_reg_dead_p (4, operands[3])
19757 && ((REGNO (operands[0]) == REGNO (operands[3]))
19758 || peep2_reg_dead_p (2, operands[0]))
19759 && !reg_overlap_mentioned_p (operands[0], operands[1])
19760 && !reg_overlap_mentioned_p (operands[3], operands[1])
19761 && !reg_overlap_mentioned_p (operands[0], operands[2])
19762 && (<MODE>mode != QImode
19763 || immediate_operand (operands[2], QImode)
19764 || any_QIreg_operand (operands[2], QImode))
19765 && ix86_match_ccmode (peep2_next_insn (3), CCGOCmode)"
19766 [(parallel [(set (match_dup 6) (match_dup 8))
19767 (set (match_dup 1) (match_dup 7))])]
19769 operands[6] = SET_DEST (PATTERN (peep2_next_insn (3)));
19771 = gen_rtx_PLUS (<MODE>mode,
19772 copy_rtx (operands[1]),
19773 gen_lowpart (<MODE>mode, operands[2]));
19775 = gen_rtx_COMPARE (GET_MODE (operands[6]),
19776 copy_rtx (operands[7]),
19781 [(parallel [(set (match_operand:SWI 0 "register_operand")
19782 (match_operator:SWI 2 "plusminuslogic_operator"
19784 (match_operand:SWI 1 "memory_operand")]))
19785 (clobber (reg:CC FLAGS_REG))])
19786 (set (match_dup 1) (match_dup 0))
19787 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
19788 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
19789 && COMMUTATIVE_ARITH_P (operands[2])
19790 && peep2_reg_dead_p (3, operands[0])
19791 && !reg_overlap_mentioned_p (operands[0], operands[1])
19792 && ix86_match_ccmode (peep2_next_insn (2),
19793 GET_CODE (operands[2]) == PLUS
19794 ? CCGOCmode : CCNOmode)"
19795 [(parallel [(set (match_dup 3) (match_dup 5))
19796 (set (match_dup 1) (match_dup 4))])]
19798 operands[3] = SET_DEST (PATTERN (peep2_next_insn (2)));
19800 = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
19801 copy_rtx (operands[1]),
19804 = gen_rtx_COMPARE (GET_MODE (operands[3]),
19805 copy_rtx (operands[4]),
19809 ;; Likewise for cmpelim optimized pattern.
19811 [(parallel [(set (reg FLAGS_REG)
19812 (compare (match_operator:SWI 2 "plusminuslogic_operator"
19813 [(match_operand:SWI 0 "register_operand")
19814 (match_operand:SWI 1 "memory_operand")])
19816 (set (match_dup 0) (match_dup 2))])
19817 (set (match_dup 1) (match_dup 0))]
19818 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
19819 && COMMUTATIVE_ARITH_P (operands[2])
19820 && peep2_reg_dead_p (2, operands[0])
19821 && !reg_overlap_mentioned_p (operands[0], operands[1])
19822 && ix86_match_ccmode (peep2_next_insn (0),
19823 GET_CODE (operands[2]) == PLUS
19824 ? CCGOCmode : CCNOmode)"
19825 [(parallel [(set (match_dup 3) (match_dup 5))
19826 (set (match_dup 1) (match_dup 4))])]
19828 operands[3] = SET_DEST (XVECEXP (PATTERN (peep2_next_insn (0)), 0, 0));
19830 = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
19831 copy_rtx (operands[1]), operands[0]);
19833 = gen_rtx_COMPARE (GET_MODE (operands[3]), copy_rtx (operands[4]),
19838 [(set (match_operand:SWI12 0 "register_operand")
19839 (match_operand:SWI12 1 "memory_operand"))
19840 (parallel [(set (match_operand:SI 4 "register_operand")
19841 (match_operator:SI 3 "plusminuslogic_operator"
19843 (match_operand:SI 2 "nonmemory_operand")]))
19844 (clobber (reg:CC FLAGS_REG))])
19845 (set (match_dup 1) (match_dup 0))
19846 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
19847 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
19848 && REGNO (operands[0]) == REGNO (operands[4])
19849 && peep2_reg_dead_p (4, operands[0])
19850 && (<MODE>mode != QImode
19851 || immediate_operand (operands[2], SImode)
19852 || any_QIreg_operand (operands[2], SImode))
19853 && !reg_overlap_mentioned_p (operands[0], operands[1])
19854 && !reg_overlap_mentioned_p (operands[0], operands[2])
19855 && ix86_match_ccmode (peep2_next_insn (3),
19856 (GET_CODE (operands[3]) == PLUS
19857 || GET_CODE (operands[3]) == MINUS)
19858 ? CCGOCmode : CCNOmode)"
19859 [(parallel [(set (match_dup 5) (match_dup 7))
19860 (set (match_dup 1) (match_dup 6))])]
19862 operands[5] = SET_DEST (PATTERN (peep2_next_insn (3)));
19864 = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
19865 copy_rtx (operands[1]),
19866 gen_lowpart (<MODE>mode, operands[2]));
19868 = gen_rtx_COMPARE (GET_MODE (operands[5]),
19869 copy_rtx (operands[6]),
19873 ;; peephole2 comes before regcprop, so deal also with a case that
19874 ;; would be cleaned up by regcprop.
19876 [(set (match_operand:SWI 0 "register_operand")
19877 (match_operand:SWI 1 "memory_operand"))
19878 (parallel [(set (match_dup 0)
19879 (match_operator:SWI 3 "plusminuslogic_operator"
19881 (match_operand:SWI 2 "<nonmemory_operand>")]))
19882 (clobber (reg:CC FLAGS_REG))])
19883 (set (match_operand:SWI 4 "register_operand") (match_dup 0))
19884 (set (match_dup 1) (match_dup 4))
19885 (set (reg FLAGS_REG) (compare (match_dup 4) (const_int 0)))]
19886 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
19887 && peep2_reg_dead_p (3, operands[0])
19888 && peep2_reg_dead_p (5, operands[4])
19889 && !reg_overlap_mentioned_p (operands[0], operands[1])
19890 && !reg_overlap_mentioned_p (operands[0], operands[2])
19891 && !reg_overlap_mentioned_p (operands[4], operands[1])
19892 && (<MODE>mode != QImode
19893 || immediate_operand (operands[2], QImode)
19894 || any_QIreg_operand (operands[2], QImode))
19895 && ix86_match_ccmode (peep2_next_insn (4),
19896 (GET_CODE (operands[3]) == PLUS
19897 || GET_CODE (operands[3]) == MINUS)
19898 ? CCGOCmode : CCNOmode)"
19899 [(parallel [(set (match_dup 5) (match_dup 7))
19900 (set (match_dup 1) (match_dup 6))])]
19902 operands[5] = SET_DEST (PATTERN (peep2_next_insn (4)));
19904 = gen_rtx_fmt_ee (GET_CODE (operands[3]), GET_MODE (operands[3]),
19905 copy_rtx (operands[1]),
19908 = gen_rtx_COMPARE (GET_MODE (operands[5]),
19909 copy_rtx (operands[6]),
19914 [(set (match_operand:SWI12 0 "register_operand")
19915 (match_operand:SWI12 1 "memory_operand"))
19916 (parallel [(set (match_operand:SI 4 "register_operand")
19917 (match_operator:SI 3 "plusminuslogic_operator"
19919 (match_operand:SI 2 "nonmemory_operand")]))
19920 (clobber (reg:CC FLAGS_REG))])
19921 (set (match_operand:SWI12 5 "register_operand") (match_dup 0))
19922 (set (match_dup 1) (match_dup 5))
19923 (set (reg FLAGS_REG) (compare (match_dup 5) (const_int 0)))]
19924 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
19925 && REGNO (operands[0]) == REGNO (operands[4])
19926 && peep2_reg_dead_p (3, operands[0])
19927 && peep2_reg_dead_p (5, operands[5])
19928 && (<MODE>mode != QImode
19929 || immediate_operand (operands[2], SImode)
19930 || any_QIreg_operand (operands[2], SImode))
19931 && !reg_overlap_mentioned_p (operands[0], operands[1])
19932 && !reg_overlap_mentioned_p (operands[0], operands[2])
19933 && !reg_overlap_mentioned_p (operands[5], operands[1])
19934 && ix86_match_ccmode (peep2_next_insn (4),
19935 (GET_CODE (operands[3]) == PLUS
19936 || GET_CODE (operands[3]) == MINUS)
19937 ? CCGOCmode : CCNOmode)"
19938 [(parallel [(set (match_dup 6) (match_dup 8))
19939 (set (match_dup 1) (match_dup 7))])]
19941 operands[6] = SET_DEST (PATTERN (peep2_next_insn (4)));
19943 = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
19944 copy_rtx (operands[1]),
19945 gen_lowpart (<MODE>mode, operands[2]));
19947 = gen_rtx_COMPARE (GET_MODE (operands[6]),
19948 copy_rtx (operands[7]),
19952 ;; Likewise for cmpelim optimized pattern.
19954 [(set (match_operand:SWI 0 "register_operand")
19955 (match_operand:SWI 1 "memory_operand"))
19956 (parallel [(set (reg FLAGS_REG)
19957 (compare (match_operator:SWI 3 "plusminuslogic_operator"
19959 (match_operand:SWI 2 "<nonmemory_operand>")])
19961 (set (match_dup 0) (match_dup 3))])
19962 (set (match_operand:SWI 4 "register_operand") (match_dup 0))
19963 (set (match_dup 1) (match_dup 4))]
19964 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
19965 && peep2_reg_dead_p (3, operands[0])
19966 && peep2_reg_dead_p (4, operands[4])
19967 && !reg_overlap_mentioned_p (operands[0], operands[1])
19968 && !reg_overlap_mentioned_p (operands[0], operands[2])
19969 && !reg_overlap_mentioned_p (operands[4], operands[1])
19970 && ix86_match_ccmode (peep2_next_insn (1),
19971 (GET_CODE (operands[3]) == PLUS
19972 || GET_CODE (operands[3]) == MINUS)
19973 ? CCGOCmode : CCNOmode)"
19974 [(parallel [(set (match_dup 5) (match_dup 7))
19975 (set (match_dup 1) (match_dup 6))])]
19977 operands[5] = SET_DEST (XVECEXP (PATTERN (peep2_next_insn (1)), 0, 0));
19979 = gen_rtx_fmt_ee (GET_CODE (operands[3]), GET_MODE (operands[3]),
19980 copy_rtx (operands[1]), operands[2]);
19982 = gen_rtx_COMPARE (GET_MODE (operands[5]), copy_rtx (operands[6]),
19986 ;; Special cases for xor, where (x ^= y) != 0 is (misoptimized)
19987 ;; into x = z; x ^= y; x != z
19989 [(set (match_operand:SWI 0 "register_operand")
19990 (match_operand:SWI 1 "memory_operand"))
19991 (set (match_operand:SWI 3 "register_operand") (match_dup 0))
19992 (parallel [(set (match_operand:SWI 4 "register_operand")
19993 (xor:SWI (match_dup 4)
19994 (match_operand:SWI 2 "<nonmemory_operand>")))
19995 (clobber (reg:CC FLAGS_REG))])
19996 (set (match_dup 1) (match_dup 4))
19997 (set (reg:CCZ FLAGS_REG)
19998 (compare:CCZ (match_operand:SWI 5 "register_operand")
19999 (match_operand:SWI 6 "<nonmemory_operand>")))]
20000 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
20001 && (REGNO (operands[4]) == REGNO (operands[0])
20002 || REGNO (operands[4]) == REGNO (operands[3]))
20003 && (rtx_equal_p (operands[REGNO (operands[4]) == REGNO (operands[0])
20004 ? 3 : 0], operands[5])
20005 ? rtx_equal_p (operands[2], operands[6])
20006 : rtx_equal_p (operands[2], operands[5])
20007 && rtx_equal_p (operands[REGNO (operands[4]) == REGNO (operands[0])
20008 ? 3 : 0], operands[6]))
20009 && peep2_reg_dead_p (4, operands[4])
20010 && peep2_reg_dead_p (5, operands[REGNO (operands[4]) == REGNO (operands[0])
20012 && !reg_overlap_mentioned_p (operands[0], operands[1])
20013 && !reg_overlap_mentioned_p (operands[0], operands[2])
20014 && !reg_overlap_mentioned_p (operands[3], operands[0])
20015 && !reg_overlap_mentioned_p (operands[3], operands[1])
20016 && !reg_overlap_mentioned_p (operands[3], operands[2])
20017 && (<MODE>mode != QImode
20018 || immediate_operand (operands[2], QImode)
20019 || any_QIreg_operand (operands[2], QImode))"
20020 [(parallel [(set (match_dup 7) (match_dup 9))
20021 (set (match_dup 1) (match_dup 8))])]
20023 operands[7] = SET_DEST (PATTERN (peep2_next_insn (4)));
20024 operands[8] = gen_rtx_XOR (<MODE>mode, copy_rtx (operands[1]),
20027 = gen_rtx_COMPARE (GET_MODE (operands[7]),
20028 copy_rtx (operands[8]),
20033 [(set (match_operand:SWI12 0 "register_operand")
20034 (match_operand:SWI12 1 "memory_operand"))
20035 (set (match_operand:SWI12 3 "register_operand") (match_dup 0))
20036 (parallel [(set (match_operand:SI 4 "register_operand")
20037 (xor:SI (match_dup 4)
20038 (match_operand:SI 2 "<nonmemory_operand>")))
20039 (clobber (reg:CC FLAGS_REG))])
20040 (set (match_dup 1) (match_operand:SWI12 5 "register_operand"))
20041 (set (reg:CCZ FLAGS_REG)
20042 (compare:CCZ (match_operand:SWI12 6 "register_operand")
20043 (match_operand:SWI12 7 "<nonmemory_operand>")))]
20044 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
20045 && (REGNO (operands[5]) == REGNO (operands[0])
20046 || REGNO (operands[5]) == REGNO (operands[3]))
20047 && REGNO (operands[5]) == REGNO (operands[4])
20048 && (rtx_equal_p (operands[REGNO (operands[5]) == REGNO (operands[0])
20049 ? 3 : 0], operands[6])
20050 ? (REG_P (operands[2])
20051 ? REG_P (operands[7]) && REGNO (operands[2]) == REGNO (operands[7])
20052 : rtx_equal_p (operands[2], operands[7]))
20053 : (rtx_equal_p (operands[REGNO (operands[5]) == REGNO (operands[0])
20054 ? 3 : 0], operands[7])
20055 && REG_P (operands[2])
20056 && REGNO (operands[2]) == REGNO (operands[6])))
20057 && peep2_reg_dead_p (4, operands[5])
20058 && peep2_reg_dead_p (5, operands[REGNO (operands[5]) == REGNO (operands[0])
20060 && !reg_overlap_mentioned_p (operands[0], operands[1])
20061 && !reg_overlap_mentioned_p (operands[0], operands[2])
20062 && !reg_overlap_mentioned_p (operands[3], operands[0])
20063 && !reg_overlap_mentioned_p (operands[3], operands[1])
20064 && !reg_overlap_mentioned_p (operands[3], operands[2])
20065 && (<MODE>mode != QImode
20066 || immediate_operand (operands[2], SImode)
20067 || any_QIreg_operand (operands[2], SImode))"
20068 [(parallel [(set (match_dup 8) (match_dup 10))
20069 (set (match_dup 1) (match_dup 9))])]
20071 operands[8] = SET_DEST (PATTERN (peep2_next_insn (4)));
20072 operands[9] = gen_rtx_XOR (<MODE>mode, copy_rtx (operands[1]),
20073 gen_lowpart (<MODE>mode, operands[2]));
20075 = gen_rtx_COMPARE (GET_MODE (operands[8]),
20076 copy_rtx (operands[9]),
20080 ;; Attempt to optimize away memory stores of values the memory already
20081 ;; has. See PR79593.
20083 [(set (match_operand 0 "register_operand")
20084 (match_operand 1 "memory_operand"))
20085 (set (match_operand 2 "memory_operand") (match_dup 0))]
20086 "!MEM_VOLATILE_P (operands[1])
20087 && !MEM_VOLATILE_P (operands[2])
20088 && rtx_equal_p (operands[1], operands[2])
20089 && !reg_overlap_mentioned_p (operands[0], operands[2])"
20090 [(set (match_dup 0) (match_dup 1))])
20092 ;; Attempt to always use XOR for zeroing registers (including FP modes).
20094 [(set (match_operand 0 "general_reg_operand")
20095 (match_operand 1 "const0_operand"))]
20096 "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
20097 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
20098 && peep2_regno_dead_p (0, FLAGS_REG)"
20099 [(parallel [(set (match_dup 0) (const_int 0))
20100 (clobber (reg:CC FLAGS_REG))])]
20101 "operands[0] = gen_lowpart (word_mode, operands[0]);")
20104 [(set (strict_low_part (match_operand:SWI12 0 "general_reg_operand"))
20106 "(! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
20107 && peep2_regno_dead_p (0, FLAGS_REG)"
20108 [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
20109 (clobber (reg:CC FLAGS_REG))])])
20111 ;; For HI, SI and DI modes, or $-1,reg is smaller than mov $-1,reg.
20113 [(set (match_operand:SWI248 0 "general_reg_operand")
20115 "(TARGET_MOVE_M1_VIA_OR || optimize_insn_for_size_p ())
20116 && peep2_regno_dead_p (0, FLAGS_REG)"
20117 [(parallel [(set (match_dup 0) (const_int -1))
20118 (clobber (reg:CC FLAGS_REG))])]
20120 if (<MODE_SIZE> < GET_MODE_SIZE (SImode))
20121 operands[0] = gen_lowpart (SImode, operands[0]);
20124 ;; Attempt to convert simple lea to add/shift.
20125 ;; These can be created by move expanders.
20126 ;; Disable PLUS peepholes on TARGET_OPT_AGU, since all
20127 ;; relevant lea instructions were already split.
20130 [(set (match_operand:SWI48 0 "register_operand")
20131 (plus:SWI48 (match_dup 0)
20132 (match_operand:SWI48 1 "<nonmemory_operand>")))]
20134 && peep2_regno_dead_p (0, FLAGS_REG)"
20135 [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1)))
20136 (clobber (reg:CC FLAGS_REG))])])
20139 [(set (match_operand:SWI48 0 "register_operand")
20140 (plus:SWI48 (match_operand:SWI48 1 "<nonmemory_operand>")
20143 && peep2_regno_dead_p (0, FLAGS_REG)"
20144 [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1)))
20145 (clobber (reg:CC FLAGS_REG))])])
20148 [(set (match_operand:DI 0 "register_operand")
20150 (plus:SI (match_operand:SI 1 "register_operand")
20151 (match_operand:SI 2 "nonmemory_operand"))))]
20152 "TARGET_64BIT && !TARGET_OPT_AGU
20153 && REGNO (operands[0]) == REGNO (operands[1])
20154 && peep2_regno_dead_p (0, FLAGS_REG)"
20155 [(parallel [(set (match_dup 0)
20156 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))
20157 (clobber (reg:CC FLAGS_REG))])])
20160 [(set (match_operand:DI 0 "register_operand")
20162 (plus:SI (match_operand:SI 1 "nonmemory_operand")
20163 (match_operand:SI 2 "register_operand"))))]
20164 "TARGET_64BIT && !TARGET_OPT_AGU
20165 && REGNO (operands[0]) == REGNO (operands[2])
20166 && peep2_regno_dead_p (0, FLAGS_REG)"
20167 [(parallel [(set (match_dup 0)
20168 (zero_extend:DI (plus:SI (match_dup 2) (match_dup 1))))
20169 (clobber (reg:CC FLAGS_REG))])])
20172 [(set (match_operand:SWI48 0 "register_operand")
20173 (mult:SWI48 (match_dup 0)
20174 (match_operand:SWI48 1 "const_int_operand")))]
20175 "pow2p_hwi (INTVAL (operands[1]))
20176 && peep2_regno_dead_p (0, FLAGS_REG)"
20177 [(parallel [(set (match_dup 0) (ashift:SWI48 (match_dup 0) (match_dup 1)))
20178 (clobber (reg:CC FLAGS_REG))])]
20179 "operands[1] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
20182 [(set (match_operand:DI 0 "register_operand")
20184 (mult:SI (match_operand:SI 1 "register_operand")
20185 (match_operand:SI 2 "const_int_operand"))))]
20187 && pow2p_hwi (INTVAL (operands[2]))
20188 && REGNO (operands[0]) == REGNO (operands[1])
20189 && peep2_regno_dead_p (0, FLAGS_REG)"
20190 [(parallel [(set (match_dup 0)
20191 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))
20192 (clobber (reg:CC FLAGS_REG))])]
20193 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
20195 ;; The ESP adjustments can be done by the push and pop instructions. Resulting
20196 ;; code is shorter, since push is only 1 byte, while add imm, %esp is 3 bytes.
20197 ;; On many CPUs it is also faster, since special hardware to avoid esp
20198 ;; dependencies is present.
20200 ;; While some of these conversions may be done using splitters, we use
20201 ;; peepholes in order to allow combine_stack_adjustments pass to see
20202 ;; nonobfuscated RTL.
20204 ;; Convert prologue esp subtractions to push.
20205 ;; We need register to push. In order to keep verify_flow_info happy we have
20207 ;; - use scratch and clobber it in order to avoid dependencies
20208 ;; - use already live register
20209 ;; We can't use the second way right now, since there is no reliable way how to
20210 ;; verify that given register is live. First choice will also most likely in
20211 ;; fewer dependencies. On the place of esp adjustments it is very likely that
20212 ;; call clobbered registers are dead. We may want to use base pointer as an
20213 ;; alternative when no register is available later.
20216 [(match_scratch:W 1 "r")
20217 (parallel [(set (reg:P SP_REG)
20218 (plus:P (reg:P SP_REG)
20219 (match_operand:P 0 "const_int_operand")))
20220 (clobber (reg:CC FLAGS_REG))
20221 (clobber (mem:BLK (scratch)))])]
20222 "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
20223 && INTVAL (operands[0]) == -GET_MODE_SIZE (word_mode)
20224 && ix86_red_zone_size == 0"
20225 [(clobber (match_dup 1))
20226 (parallel [(set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
20227 (clobber (mem:BLK (scratch)))])])
20230 [(match_scratch:W 1 "r")
20231 (parallel [(set (reg:P SP_REG)
20232 (plus:P (reg:P SP_REG)
20233 (match_operand:P 0 "const_int_operand")))
20234 (clobber (reg:CC FLAGS_REG))
20235 (clobber (mem:BLK (scratch)))])]
20236 "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
20237 && INTVAL (operands[0]) == -2*GET_MODE_SIZE (word_mode)
20238 && ix86_red_zone_size == 0"
20239 [(clobber (match_dup 1))
20240 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
20241 (parallel [(set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
20242 (clobber (mem:BLK (scratch)))])])
20244 ;; Convert esp subtractions to push.
20246 [(match_scratch:W 1 "r")
20247 (parallel [(set (reg:P SP_REG)
20248 (plus:P (reg:P SP_REG)
20249 (match_operand:P 0 "const_int_operand")))
20250 (clobber (reg:CC FLAGS_REG))])]
20251 "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
20252 && INTVAL (operands[0]) == -GET_MODE_SIZE (word_mode)
20253 && ix86_red_zone_size == 0"
20254 [(clobber (match_dup 1))
20255 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
20258 [(match_scratch:W 1 "r")
20259 (parallel [(set (reg:P SP_REG)
20260 (plus:P (reg:P SP_REG)
20261 (match_operand:P 0 "const_int_operand")))
20262 (clobber (reg:CC FLAGS_REG))])]
20263 "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
20264 && INTVAL (operands[0]) == -2*GET_MODE_SIZE (word_mode)
20265 && ix86_red_zone_size == 0"
20266 [(clobber (match_dup 1))
20267 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
20268 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
20270 ;; Convert epilogue deallocator to pop.
20272 [(match_scratch:W 1 "r")
20273 (parallel [(set (reg:P SP_REG)
20274 (plus:P (reg:P SP_REG)
20275 (match_operand:P 0 "const_int_operand")))
20276 (clobber (reg:CC FLAGS_REG))
20277 (clobber (mem:BLK (scratch)))])]
20278 "(TARGET_SINGLE_POP || optimize_insn_for_size_p ())
20279 && INTVAL (operands[0]) == GET_MODE_SIZE (word_mode)"
20280 [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
20281 (clobber (mem:BLK (scratch)))])])
20283 ;; Two pops case is tricky, since pop causes dependency
20284 ;; on destination register. We use two registers if available.
20286 [(match_scratch:W 1 "r")
20287 (match_scratch:W 2 "r")
20288 (parallel [(set (reg:P SP_REG)
20289 (plus:P (reg:P SP_REG)
20290 (match_operand:P 0 "const_int_operand")))
20291 (clobber (reg:CC FLAGS_REG))
20292 (clobber (mem:BLK (scratch)))])]
20293 "(TARGET_DOUBLE_POP || optimize_insn_for_size_p ())
20294 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
20295 [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
20296 (clobber (mem:BLK (scratch)))])
20297 (set (match_dup 2) (mem:W (post_inc:P (reg:P SP_REG))))])
20300 [(match_scratch:W 1 "r")
20301 (parallel [(set (reg:P SP_REG)
20302 (plus:P (reg:P SP_REG)
20303 (match_operand:P 0 "const_int_operand")))
20304 (clobber (reg:CC FLAGS_REG))
20305 (clobber (mem:BLK (scratch)))])]
20306 "optimize_insn_for_size_p ()
20307 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
20308 [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
20309 (clobber (mem:BLK (scratch)))])
20310 (set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
20312 ;; Convert esp additions to pop.
20314 [(match_scratch:W 1 "r")
20315 (parallel [(set (reg:P SP_REG)
20316 (plus:P (reg:P SP_REG)
20317 (match_operand:P 0 "const_int_operand")))
20318 (clobber (reg:CC FLAGS_REG))])]
20319 "INTVAL (operands[0]) == GET_MODE_SIZE (word_mode)"
20320 [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
20322 ;; Two pops case is tricky, since pop causes dependency
20323 ;; on destination register. We use two registers if available.
20325 [(match_scratch:W 1 "r")
20326 (match_scratch:W 2 "r")
20327 (parallel [(set (reg:P SP_REG)
20328 (plus:P (reg:P SP_REG)
20329 (match_operand:P 0 "const_int_operand")))
20330 (clobber (reg:CC FLAGS_REG))])]
20331 "INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
20332 [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
20333 (set (match_dup 2) (mem:W (post_inc:P (reg:P SP_REG))))])
20336 [(match_scratch:W 1 "r")
20337 (parallel [(set (reg:P SP_REG)
20338 (plus:P (reg:P SP_REG)
20339 (match_operand:P 0 "const_int_operand")))
20340 (clobber (reg:CC FLAGS_REG))])]
20341 "optimize_insn_for_size_p ()
20342 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
20343 [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
20344 (set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
20346 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
20347 ;; required and register dies. Similarly for 128 to -128.
20349 [(set (match_operand 0 "flags_reg_operand")
20350 (match_operator 1 "compare_operator"
20351 [(match_operand 2 "register_operand")
20352 (match_operand 3 "const_int_operand")]))]
20353 "(((!TARGET_FUSE_CMP_AND_BRANCH || optimize_insn_for_size_p ())
20354 && incdec_operand (operands[3], GET_MODE (operands[3])))
20355 || (!TARGET_FUSE_CMP_AND_BRANCH
20356 && INTVAL (operands[3]) == 128))
20357 && ix86_match_ccmode (insn, CCGCmode)
20358 && peep2_reg_dead_p (1, operands[2])"
20359 [(parallel [(set (match_dup 0)
20360 (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
20361 (clobber (match_dup 2))])])
20363 ;; Convert imul by three, five and nine into lea
20366 [(set (match_operand:SWI48 0 "register_operand")
20367 (mult:SWI48 (match_operand:SWI48 1 "register_operand")
20368 (match_operand:SWI48 2 "const359_operand")))
20369 (clobber (reg:CC FLAGS_REG))])]
20370 "!TARGET_PARTIAL_REG_STALL
20371 || <MODE>mode == SImode
20372 || optimize_function_for_size_p (cfun)"
20373 [(set (match_dup 0)
20374 (plus:SWI48 (mult:SWI48 (match_dup 1) (match_dup 2))
20376 "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
20380 [(set (match_operand:SWI48 0 "register_operand")
20381 (mult:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
20382 (match_operand:SWI48 2 "const359_operand")))
20383 (clobber (reg:CC FLAGS_REG))])]
20384 "optimize_insn_for_speed_p ()
20385 && (!TARGET_PARTIAL_REG_STALL || <MODE>mode == SImode)"
20386 [(set (match_dup 0) (match_dup 1))
20388 (plus:SWI48 (mult:SWI48 (match_dup 0) (match_dup 2))
20390 "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
20392 ;; imul $32bit_imm, mem, reg is vector decoded, while
20393 ;; imul $32bit_imm, reg, reg is direct decoded.
20395 [(match_scratch:SWI48 3 "r")
20396 (parallel [(set (match_operand:SWI48 0 "register_operand")
20397 (mult:SWI48 (match_operand:SWI48 1 "memory_operand")
20398 (match_operand:SWI48 2 "immediate_operand")))
20399 (clobber (reg:CC FLAGS_REG))])]
20400 "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
20401 && !satisfies_constraint_K (operands[2])"
20402 [(set (match_dup 3) (match_dup 1))
20403 (parallel [(set (match_dup 0) (mult:SWI48 (match_dup 3) (match_dup 2)))
20404 (clobber (reg:CC FLAGS_REG))])])
20407 [(match_scratch:SI 3 "r")
20408 (parallel [(set (match_operand:DI 0 "register_operand")
20410 (mult:SI (match_operand:SI 1 "memory_operand")
20411 (match_operand:SI 2 "immediate_operand"))))
20412 (clobber (reg:CC FLAGS_REG))])]
20414 && TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
20415 && !satisfies_constraint_K (operands[2])"
20416 [(set (match_dup 3) (match_dup 1))
20417 (parallel [(set (match_dup 0)
20418 (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
20419 (clobber (reg:CC FLAGS_REG))])])
20421 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
20422 ;; Convert it into imul reg, reg
20423 ;; It would be better to force assembler to encode instruction using long
20424 ;; immediate, but there is apparently no way to do so.
20426 [(parallel [(set (match_operand:SWI248 0 "register_operand")
20428 (match_operand:SWI248 1 "nonimmediate_operand")
20429 (match_operand:SWI248 2 "const_int_operand")))
20430 (clobber (reg:CC FLAGS_REG))])
20431 (match_scratch:SWI248 3 "r")]
20432 "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
20433 && satisfies_constraint_K (operands[2])"
20434 [(set (match_dup 3) (match_dup 2))
20435 (parallel [(set (match_dup 0) (mult:SWI248 (match_dup 0) (match_dup 3)))
20436 (clobber (reg:CC FLAGS_REG))])]
20438 if (!rtx_equal_p (operands[0], operands[1]))
20439 emit_move_insn (operands[0], operands[1]);
20442 ;; After splitting up read-modify operations, array accesses with memory
20443 ;; operands might end up in form:
20445 ;; movl 4(%esp), %edx
20447 ;; instead of pre-splitting:
20449 ;; addl 4(%esp), %eax
20451 ;; movl 4(%esp), %edx
20452 ;; leal (%edx,%eax,4), %eax
20455 [(match_scratch:W 5 "r")
20456 (parallel [(set (match_operand 0 "register_operand")
20457 (ashift (match_operand 1 "register_operand")
20458 (match_operand 2 "const_int_operand")))
20459 (clobber (reg:CC FLAGS_REG))])
20460 (parallel [(set (match_operand 3 "register_operand")
20461 (plus (match_dup 0)
20462 (match_operand 4 "x86_64_general_operand")))
20463 (clobber (reg:CC FLAGS_REG))])]
20464 "IN_RANGE (INTVAL (operands[2]), 1, 3)
20465 /* Validate MODE for lea. */
20466 && ((!TARGET_PARTIAL_REG_STALL
20467 && (GET_MODE (operands[0]) == QImode
20468 || GET_MODE (operands[0]) == HImode))
20469 || GET_MODE (operands[0]) == SImode
20470 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
20471 && (rtx_equal_p (operands[0], operands[3])
20472 || peep2_reg_dead_p (2, operands[0]))
20473 /* We reorder load and the shift. */
20474 && !reg_overlap_mentioned_p (operands[0], operands[4])"
20475 [(set (match_dup 5) (match_dup 4))
20476 (set (match_dup 0) (match_dup 1))]
20478 machine_mode op1mode = GET_MODE (operands[1]);
20479 machine_mode mode = op1mode == DImode ? DImode : SImode;
20480 int scale = 1 << INTVAL (operands[2]);
20481 rtx index = gen_lowpart (word_mode, operands[1]);
20482 rtx base = gen_lowpart (word_mode, operands[5]);
20483 rtx dest = gen_lowpart (mode, operands[3]);
20485 operands[1] = gen_rtx_PLUS (word_mode, base,
20486 gen_rtx_MULT (word_mode, index, GEN_INT (scale)));
20487 if (mode != word_mode)
20488 operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
20490 operands[5] = base;
20491 if (op1mode != word_mode)
20492 operands[5] = gen_lowpart (op1mode, operands[5]);
20494 operands[0] = dest;
20497 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
20498 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
20499 ;; caught for use by garbage collectors and the like. Using an insn that
20500 ;; maps to SIGILL makes it more likely the program will rightfully die.
20501 ;; Keeping with tradition, "6" is in honor of #UD.
20502 (define_insn "trap"
20503 [(trap_if (const_int 1) (const_int 6))]
20506 #ifdef HAVE_AS_IX86_UD2
20509 return ASM_SHORT "0x0b0f";
20512 [(set_attr "length" "2")])
20515 [(unspec_volatile [(const_int 0)] UNSPECV_UD2)]
20518 #ifdef HAVE_AS_IX86_UD2
20521 return ASM_SHORT "0x0b0f";
20524 [(set_attr "length" "2")])
20526 (define_expand "prefetch"
20527 [(prefetch (match_operand 0 "address_operand")
20528 (match_operand:SI 1 "const_int_operand")
20529 (match_operand:SI 2 "const_int_operand"))]
20530 "TARGET_3DNOW || TARGET_PREFETCH_SSE || TARGET_PRFCHW || TARGET_PREFETCHWT1"
20532 bool write = operands[1] != const0_rtx;
20533 int locality = INTVAL (operands[2]);
20535 gcc_assert (IN_RANGE (locality, 0, 3));
20537 /* Use 3dNOW prefetch in case we are asking for write prefetch not
20538 supported by SSE counterpart (non-SSE2 athlon machines) or the
20539 SSE prefetch is not available (K6 machines). Otherwise use SSE
20540 prefetch as it allows specifying of locality. */
20544 if (TARGET_PREFETCHWT1)
20545 operands[2] = GEN_INT (MAX (locality, 2));
20546 else if (TARGET_PRFCHW)
20547 operands[2] = GEN_INT (3);
20548 else if (TARGET_3DNOW && !TARGET_SSE2)
20549 operands[2] = GEN_INT (3);
20550 else if (TARGET_PREFETCH_SSE)
20551 operands[1] = const0_rtx;
20554 gcc_assert (TARGET_3DNOW);
20555 operands[2] = GEN_INT (3);
20560 if (TARGET_PREFETCH_SSE)
20564 gcc_assert (TARGET_3DNOW);
20565 operands[2] = GEN_INT (3);
20570 (define_insn "*prefetch_sse"
20571 [(prefetch (match_operand 0 "address_operand" "p")
20573 (match_operand:SI 1 "const_int_operand"))]
20574 "TARGET_PREFETCH_SSE"
20576 static const char * const patterns[4] = {
20577 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
20580 int locality = INTVAL (operands[1]);
20581 gcc_assert (IN_RANGE (locality, 0, 3));
20583 return patterns[locality];
20585 [(set_attr "type" "sse")
20586 (set_attr "atom_sse_attr" "prefetch")
20587 (set (attr "length_address")
20588 (symbol_ref "memory_address_length (operands[0], false)"))
20589 (set_attr "memory" "none")])
20591 (define_insn "*prefetch_3dnow"
20592 [(prefetch (match_operand 0 "address_operand" "p")
20593 (match_operand:SI 1 "const_int_operand" "n")
20595 "TARGET_3DNOW || TARGET_PRFCHW || TARGET_PREFETCHWT1"
20597 if (operands[1] == const0_rtx)
20598 return "prefetch\t%a0";
20600 return "prefetchw\t%a0";
20602 [(set_attr "type" "mmx")
20603 (set (attr "length_address")
20604 (symbol_ref "memory_address_length (operands[0], false)"))
20605 (set_attr "memory" "none")])
20607 (define_insn "*prefetch_prefetchwt1"
20608 [(prefetch (match_operand 0 "address_operand" "p")
20611 "TARGET_PREFETCHWT1"
20612 "prefetchwt1\t%a0";
20613 [(set_attr "type" "sse")
20614 (set (attr "length_address")
20615 (symbol_ref "memory_address_length (operands[0], false)"))
20616 (set_attr "memory" "none")])
20618 (define_expand "stack_protect_set"
20619 [(match_operand 0 "memory_operand")
20620 (match_operand 1 "memory_operand")]
20623 emit_insn (gen_stack_protect_set_1
20624 (ptr_mode, operands[0], operands[1]));
20628 (define_insn "@stack_protect_set_1_<mode>"
20629 [(set (match_operand:PTR 0 "memory_operand" "=m")
20630 (unspec:PTR [(match_operand:PTR 1 "memory_operand" "m")]
20632 (set (match_scratch:PTR 2 "=&r") (const_int 0))
20633 (clobber (reg:CC FLAGS_REG))]
20636 output_asm_insn ("mov{<imodesuffix>}\t{%1, %2|%2, %1}", operands);
20637 output_asm_insn ("mov{<imodesuffix>}\t{%2, %0|%0, %2}", operands);
20638 return "xor{l}\t%k2, %k2";
20640 [(set_attr "type" "multi")])
20642 ;; Patterns and peephole2s to optimize stack_protect_set_1_<mode>
20643 ;; immediately followed by *mov{s,d}i_internal to the same register,
20644 ;; where we can avoid the xor{l} above. We don't split this, so that
20645 ;; scheduling or anything else doesn't separate the *stack_protect_set*
20646 ;; pattern from the set of the register that overwrites the register
20647 ;; with a new value.
20648 (define_insn "*stack_protect_set_2_<mode>"
20649 [(set (match_operand:PTR 0 "memory_operand" "=m")
20650 (unspec:PTR [(match_operand:PTR 3 "memory_operand" "m")]
20652 (set (match_operand:SI 1 "register_operand" "=&r")
20653 (match_operand:SI 2 "general_operand" "g"))
20654 (clobber (reg:CC FLAGS_REG))]
20656 && !reg_overlap_mentioned_p (operands[1], operands[2])"
20658 output_asm_insn ("mov{<imodesuffix>}\t{%3, %<k>1|%<k>1, %3}", operands);
20659 output_asm_insn ("mov{<imodesuffix>}\t{%<k>1, %0|%0, %<k>1}", operands);
20660 if (pic_32bit_operand (operands[2], SImode)
20661 || ix86_use_lea_for_mov (insn, operands + 1))
20662 return "lea{l}\t{%E2, %1|%1, %E2}";
20664 return "mov{l}\t{%2, %1|%1, %2}";
20666 [(set_attr "type" "multi")
20667 (set_attr "length" "24")])
20670 [(parallel [(set (match_operand:PTR 0 "memory_operand")
20671 (unspec:PTR [(match_operand:PTR 1 "memory_operand")]
20673 (set (match_operand:PTR 2 "general_reg_operand") (const_int 0))
20674 (clobber (reg:CC FLAGS_REG))])
20675 (set (match_operand:SI 3 "general_reg_operand")
20676 (match_operand:SI 4))]
20677 "REGNO (operands[2]) == REGNO (operands[3])
20678 && general_operand (operands[4], SImode)
20679 && (general_reg_operand (operands[4], SImode)
20680 || memory_operand (operands[4], SImode)
20681 || immediate_operand (operands[4], SImode))
20682 && !reg_overlap_mentioned_p (operands[3], operands[4])"
20683 [(parallel [(set (match_dup 0)
20684 (unspec:PTR [(match_dup 1)] UNSPEC_SP_SET))
20685 (set (match_dup 3) (match_dup 4))
20686 (clobber (reg:CC FLAGS_REG))])])
20688 (define_insn "*stack_protect_set_3"
20689 [(set (match_operand:DI 0 "memory_operand" "=m,m,m")
20690 (unspec:DI [(match_operand:DI 3 "memory_operand" "m,m,m")]
20692 (set (match_operand:DI 1 "register_operand" "=&r,r,r")
20693 (match_operand:DI 2 "general_operand" "Z,rem,i"))
20694 (clobber (reg:CC FLAGS_REG))]
20696 && reload_completed
20697 && !reg_overlap_mentioned_p (operands[1], operands[2])"
20699 output_asm_insn ("mov{q}\t{%3, %1|%1, %3}", operands);
20700 output_asm_insn ("mov{q}\t{%1, %0|%0, %1}", operands);
20701 if (pic_32bit_operand (operands[2], DImode))
20702 return "lea{q}\t{%E2, %1|%1, %E2}";
20703 else if (which_alternative == 0)
20704 return "mov{l}\t{%k2, %k1|%k1, %k2}";
20705 else if (which_alternative == 2)
20706 return "movabs{q}\t{%2, %1|%1, %2}";
20707 else if (ix86_use_lea_for_mov (insn, operands + 1))
20708 return "lea{q}\t{%E2, %1|%1, %E2}";
20710 return "mov{q}\t{%2, %1|%1, %2}";
20712 [(set_attr "type" "multi")
20713 (set_attr "length" "24")])
20716 [(parallel [(set (match_operand:DI 0 "memory_operand")
20717 (unspec:DI [(match_operand:DI 1 "memory_operand")]
20719 (set (match_operand:DI 2 "general_reg_operand") (const_int 0))
20720 (clobber (reg:CC FLAGS_REG))])
20721 (set (match_dup 2) (match_operand:DI 3))]
20723 && general_operand (operands[3], DImode)
20724 && (general_reg_operand (operands[3], DImode)
20725 || memory_operand (operands[3], DImode)
20726 || x86_64_zext_immediate_operand (operands[3], DImode)
20727 || x86_64_immediate_operand (operands[3], DImode)
20728 || (CONSTANT_P (operands[3])
20729 && (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[3]))))
20730 && !reg_overlap_mentioned_p (operands[2], operands[3])"
20731 [(parallel [(set (match_dup 0)
20732 (unspec:PTR [(match_dup 1)] UNSPEC_SP_SET))
20733 (set (match_dup 2) (match_dup 3))
20734 (clobber (reg:CC FLAGS_REG))])])
20736 (define_expand "stack_protect_test"
20737 [(match_operand 0 "memory_operand")
20738 (match_operand 1 "memory_operand")
20742 rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
20744 emit_insn (gen_stack_protect_test_1
20745 (ptr_mode, flags, operands[0], operands[1]));
20747 emit_jump_insn (gen_cbranchcc4 (gen_rtx_EQ (VOIDmode, flags, const0_rtx),
20748 flags, const0_rtx, operands[2]));
20752 (define_insn "@stack_protect_test_1_<mode>"
20753 [(set (match_operand:CCZ 0 "flags_reg_operand")
20754 (unspec:CCZ [(match_operand:PTR 1 "memory_operand" "m")
20755 (match_operand:PTR 2 "memory_operand" "m")]
20757 (clobber (match_scratch:PTR 3 "=&r"))]
20760 output_asm_insn ("mov{<imodesuffix>}\t{%1, %3|%3, %1}", operands);
20761 return "sub{<imodesuffix>}\t{%2, %3|%3, %2}";
20763 [(set_attr "type" "multi")])
20765 (define_insn "sse4_2_crc32<mode>"
20766 [(set (match_operand:SI 0 "register_operand" "=r")
20768 [(match_operand:SI 1 "register_operand" "0")
20769 (match_operand:SWI124 2 "nonimmediate_operand" "<r>m")]
20771 "TARGET_SSE4_2 || TARGET_CRC32"
20772 "crc32{<imodesuffix>}\t{%2, %0|%0, %2}"
20773 [(set_attr "type" "sselog1")
20774 (set_attr "prefix_rep" "1")
20775 (set_attr "prefix_extra" "1")
20776 (set (attr "prefix_data16")
20777 (if_then_else (match_operand:HI 2)
20779 (const_string "*")))
20780 (set (attr "prefix_rex")
20781 (if_then_else (match_operand:QI 2 "ext_QIreg_operand")
20783 (const_string "*")))
20784 (set_attr "mode" "SI")])
20786 (define_insn "sse4_2_crc32di"
20787 [(set (match_operand:DI 0 "register_operand" "=r")
20789 [(match_operand:DI 1 "register_operand" "0")
20790 (match_operand:DI 2 "nonimmediate_operand" "rm")]
20792 "TARGET_64BIT && (TARGET_SSE4_2 || TARGET_CRC32)"
20793 "crc32{q}\t{%2, %0|%0, %2}"
20794 [(set_attr "type" "sselog1")
20795 (set_attr "prefix_rep" "1")
20796 (set_attr "prefix_extra" "1")
20797 (set_attr "mode" "DI")])
20799 (define_insn "rdpmc"
20800 [(set (match_operand:DI 0 "register_operand" "=A")
20801 (unspec_volatile:DI [(match_operand:SI 1 "register_operand" "c")]
20805 [(set_attr "type" "other")
20806 (set_attr "length" "2")])
20808 (define_insn "rdpmc_rex64"
20809 [(set (match_operand:DI 0 "register_operand" "=a")
20810 (unspec_volatile:DI [(match_operand:SI 2 "register_operand" "c")]
20812 (set (match_operand:DI 1 "register_operand" "=d")
20813 (unspec_volatile:DI [(match_dup 2)] UNSPECV_RDPMC))]
20816 [(set_attr "type" "other")
20817 (set_attr "length" "2")])
20819 (define_insn "rdtsc"
20820 [(set (match_operand:DI 0 "register_operand" "=A")
20821 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
20824 [(set_attr "type" "other")
20825 (set_attr "length" "2")])
20827 (define_insn "rdtsc_rex64"
20828 [(set (match_operand:DI 0 "register_operand" "=a")
20829 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))
20830 (set (match_operand:DI 1 "register_operand" "=d")
20831 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
20834 [(set_attr "type" "other")
20835 (set_attr "length" "2")])
20837 (define_insn "rdtscp"
20838 [(set (match_operand:DI 0 "register_operand" "=A")
20839 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
20840 (set (match_operand:SI 1 "register_operand" "=c")
20841 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
20844 [(set_attr "type" "other")
20845 (set_attr "length" "3")])
20847 (define_insn "rdtscp_rex64"
20848 [(set (match_operand:DI 0 "register_operand" "=a")
20849 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
20850 (set (match_operand:DI 1 "register_operand" "=d")
20851 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
20852 (set (match_operand:SI 2 "register_operand" "=c")
20853 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
20856 [(set_attr "type" "other")
20857 (set_attr "length" "3")])
20859 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
20861 ;; FXSR, XSAVE and XSAVEOPT instructions
20863 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
20865 (define_insn "fxsave"
20866 [(set (match_operand:BLK 0 "memory_operand" "=m")
20867 (unspec_volatile:BLK [(const_int 0)] UNSPECV_FXSAVE))]
20870 [(set_attr "type" "other")
20871 (set_attr "memory" "store")
20872 (set (attr "length")
20873 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
20875 (define_insn "fxsave64"
20876 [(set (match_operand:BLK 0 "memory_operand" "=m")
20877 (unspec_volatile:BLK [(const_int 0)] UNSPECV_FXSAVE64))]
20878 "TARGET_64BIT && TARGET_FXSR"
20880 [(set_attr "type" "other")
20881 (set_attr "memory" "store")
20882 (set (attr "length")
20883 (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
20885 (define_insn "fxrstor"
20886 [(unspec_volatile [(match_operand:BLK 0 "memory_operand" "m")]
20890 [(set_attr "type" "other")
20891 (set_attr "memory" "load")
20892 (set (attr "length")
20893 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
20895 (define_insn "fxrstor64"
20896 [(unspec_volatile [(match_operand:BLK 0 "memory_operand" "m")]
20897 UNSPECV_FXRSTOR64)]
20898 "TARGET_64BIT && TARGET_FXSR"
20900 [(set_attr "type" "other")
20901 (set_attr "memory" "load")
20902 (set (attr "length")
20903 (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
20905 (define_int_iterator ANY_XSAVE
20907 (UNSPECV_XSAVEOPT "TARGET_XSAVEOPT")
20908 (UNSPECV_XSAVEC "TARGET_XSAVEC")
20909 (UNSPECV_XSAVES "TARGET_XSAVES")])
20911 (define_int_iterator ANY_XSAVE64
20913 (UNSPECV_XSAVEOPT64 "TARGET_XSAVEOPT")
20914 (UNSPECV_XSAVEC64 "TARGET_XSAVEC")
20915 (UNSPECV_XSAVES64 "TARGET_XSAVES")])
20917 (define_int_attr xsave
20918 [(UNSPECV_XSAVE "xsave")
20919 (UNSPECV_XSAVE64 "xsave64")
20920 (UNSPECV_XSAVEOPT "xsaveopt")
20921 (UNSPECV_XSAVEOPT64 "xsaveopt64")
20922 (UNSPECV_XSAVEC "xsavec")
20923 (UNSPECV_XSAVEC64 "xsavec64")
20924 (UNSPECV_XSAVES "xsaves")
20925 (UNSPECV_XSAVES64 "xsaves64")])
20927 (define_int_iterator ANY_XRSTOR
20929 (UNSPECV_XRSTORS "TARGET_XSAVES")])
20931 (define_int_iterator ANY_XRSTOR64
20933 (UNSPECV_XRSTORS64 "TARGET_XSAVES")])
20935 (define_int_attr xrstor
20936 [(UNSPECV_XRSTOR "xrstor")
20937 (UNSPECV_XRSTOR64 "xrstor")
20938 (UNSPECV_XRSTORS "xrstors")
20939 (UNSPECV_XRSTORS64 "xrstors")])
20941 (define_insn "<xsave>"
20942 [(set (match_operand:BLK 0 "memory_operand" "=m")
20943 (unspec_volatile:BLK
20944 [(match_operand:DI 1 "register_operand" "A")]
20946 "!TARGET_64BIT && TARGET_XSAVE"
20948 [(set_attr "type" "other")
20949 (set_attr "memory" "store")
20950 (set (attr "length")
20951 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
20953 (define_insn "<xsave>_rex64"
20954 [(set (match_operand:BLK 0 "memory_operand" "=m")
20955 (unspec_volatile:BLK
20956 [(match_operand:SI 1 "register_operand" "a")
20957 (match_operand:SI 2 "register_operand" "d")]
20959 "TARGET_64BIT && TARGET_XSAVE"
20961 [(set_attr "type" "other")
20962 (set_attr "memory" "store")
20963 (set (attr "length")
20964 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
20966 (define_insn "<xsave>"
20967 [(set (match_operand:BLK 0 "memory_operand" "=m")
20968 (unspec_volatile:BLK
20969 [(match_operand:SI 1 "register_operand" "a")
20970 (match_operand:SI 2 "register_operand" "d")]
20972 "TARGET_64BIT && TARGET_XSAVE"
20974 [(set_attr "type" "other")
20975 (set_attr "memory" "store")
20976 (set (attr "length")
20977 (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
20979 (define_insn "<xrstor>"
20980 [(unspec_volatile:BLK
20981 [(match_operand:BLK 0 "memory_operand" "m")
20982 (match_operand:DI 1 "register_operand" "A")]
20984 "!TARGET_64BIT && TARGET_XSAVE"
20986 [(set_attr "type" "other")
20987 (set_attr "memory" "load")
20988 (set (attr "length")
20989 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
20991 (define_insn "<xrstor>_rex64"
20992 [(unspec_volatile:BLK
20993 [(match_operand:BLK 0 "memory_operand" "m")
20994 (match_operand:SI 1 "register_operand" "a")
20995 (match_operand:SI 2 "register_operand" "d")]
20997 "TARGET_64BIT && TARGET_XSAVE"
20999 [(set_attr "type" "other")
21000 (set_attr "memory" "load")
21001 (set (attr "length")
21002 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
21004 (define_insn "<xrstor>64"
21005 [(unspec_volatile:BLK
21006 [(match_operand:BLK 0 "memory_operand" "m")
21007 (match_operand:SI 1 "register_operand" "a")
21008 (match_operand:SI 2 "register_operand" "d")]
21010 "TARGET_64BIT && TARGET_XSAVE"
21012 [(set_attr "type" "other")
21013 (set_attr "memory" "load")
21014 (set (attr "length")
21015 (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
21017 (define_insn "xsetbv"
21018 [(unspec_volatile:SI
21019 [(match_operand:SI 0 "register_operand" "c")
21020 (match_operand:DI 1 "register_operand" "A")]
21022 "!TARGET_64BIT && TARGET_XSAVE"
21024 [(set_attr "type" "other")])
21026 (define_insn "xsetbv_rex64"
21027 [(unspec_volatile:SI
21028 [(match_operand:SI 0 "register_operand" "c")
21029 (match_operand:SI 1 "register_operand" "a")
21030 (match_operand:SI 2 "register_operand" "d")]
21032 "TARGET_64BIT && TARGET_XSAVE"
21034 [(set_attr "type" "other")])
21036 (define_insn "xgetbv"
21037 [(set (match_operand:DI 0 "register_operand" "=A")
21038 (unspec_volatile:DI [(match_operand:SI 1 "register_operand" "c")]
21040 "!TARGET_64BIT && TARGET_XSAVE"
21042 [(set_attr "type" "other")])
21044 (define_insn "xgetbv_rex64"
21045 [(set (match_operand:DI 0 "register_operand" "=a")
21046 (unspec_volatile:DI [(match_operand:SI 2 "register_operand" "c")]
21048 (set (match_operand:DI 1 "register_operand" "=d")
21049 (unspec_volatile:DI [(match_dup 2)] UNSPECV_XGETBV))]
21050 "TARGET_64BIT && TARGET_XSAVE"
21052 [(set_attr "type" "other")])
21054 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
21056 ;; Floating-point instructions for atomic compound assignments
21058 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
21060 ; Clobber all floating-point registers on environment save and restore
21061 ; to ensure that the TOS value saved at fnstenv is valid after fldenv.
21062 (define_insn "fnstenv"
21063 [(set (match_operand:BLK 0 "memory_operand" "=m")
21064 (unspec_volatile:BLK [(const_int 0)] UNSPECV_FNSTENV))
21065 (clobber (reg:XF ST0_REG))
21066 (clobber (reg:XF ST1_REG))
21067 (clobber (reg:XF ST2_REG))
21068 (clobber (reg:XF ST3_REG))
21069 (clobber (reg:XF ST4_REG))
21070 (clobber (reg:XF ST5_REG))
21071 (clobber (reg:XF ST6_REG))
21072 (clobber (reg:XF ST7_REG))]
21075 [(set_attr "type" "other")
21076 (set_attr "memory" "store")
21077 (set (attr "length")
21078 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))])
21080 (define_insn "fldenv"
21081 [(unspec_volatile [(match_operand:BLK 0 "memory_operand" "m")]
21083 (clobber (reg:XF ST0_REG))
21084 (clobber (reg:XF ST1_REG))
21085 (clobber (reg:XF ST2_REG))
21086 (clobber (reg:XF ST3_REG))
21087 (clobber (reg:XF ST4_REG))
21088 (clobber (reg:XF ST5_REG))
21089 (clobber (reg:XF ST6_REG))
21090 (clobber (reg:XF ST7_REG))]
21093 [(set_attr "type" "other")
21094 (set_attr "memory" "load")
21095 (set (attr "length")
21096 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))])
21098 (define_insn "fnstsw"
21099 [(set (match_operand:HI 0 "nonimmediate_operand" "=a,m")
21100 (unspec_volatile:HI [(const_int 0)] UNSPECV_FNSTSW))]
21103 [(set_attr "type" "other,other")
21104 (set_attr "memory" "none,store")
21105 (set (attr "length")
21106 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))])
21108 (define_insn "fnclex"
21109 [(unspec_volatile [(const_int 0)] UNSPECV_FNCLEX)]
21112 [(set_attr "type" "other")
21113 (set_attr "memory" "none")
21114 (set_attr "length" "2")])
21116 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
21118 ;; LWP instructions
21120 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
21122 (define_insn "@lwp_llwpcb<mode>"
21123 [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
21124 UNSPECV_LLWP_INTRINSIC)]
21127 [(set_attr "type" "lwp")
21128 (set_attr "mode" "<MODE>")
21129 (set_attr "length" "5")])
21131 (define_insn "@lwp_slwpcb<mode>"
21132 [(set (match_operand:P 0 "register_operand" "=r")
21133 (unspec_volatile:P [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
21136 [(set_attr "type" "lwp")
21137 (set_attr "mode" "<MODE>")
21138 (set_attr "length" "5")])
21140 (define_insn "@lwp_lwpval<mode>"
21141 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")
21142 (match_operand:SI 1 "nonimmediate_operand" "rm")
21143 (match_operand:SI 2 "const_int_operand" "i")]
21144 UNSPECV_LWPVAL_INTRINSIC)]
21146 "lwpval\t{%2, %1, %0|%0, %1, %2}"
21147 [(set_attr "type" "lwp")
21148 (set_attr "mode" "<MODE>")
21149 (set (attr "length")
21150 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
21152 (define_insn "@lwp_lwpins<mode>"
21153 [(set (reg:CCC FLAGS_REG)
21154 (unspec_volatile:CCC [(match_operand:SWI48 0 "register_operand" "r")
21155 (match_operand:SI 1 "nonimmediate_operand" "rm")
21156 (match_operand:SI 2 "const_int_operand" "i")]
21157 UNSPECV_LWPINS_INTRINSIC))]
21159 "lwpins\t{%2, %1, %0|%0, %1, %2}"
21160 [(set_attr "type" "lwp")
21161 (set_attr "mode" "<MODE>")
21162 (set (attr "length")
21163 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
21165 (define_int_iterator RDFSGSBASE
21169 (define_int_iterator WRFSGSBASE
21173 (define_int_attr fsgs
21174 [(UNSPECV_RDFSBASE "fs")
21175 (UNSPECV_RDGSBASE "gs")
21176 (UNSPECV_WRFSBASE "fs")
21177 (UNSPECV_WRGSBASE "gs")])
21179 (define_insn "rd<fsgs>base<mode>"
21180 [(set (match_operand:SWI48 0 "register_operand" "=r")
21181 (unspec_volatile:SWI48 [(const_int 0)] RDFSGSBASE))]
21182 "TARGET_64BIT && TARGET_FSGSBASE"
21184 [(set_attr "type" "other")
21185 (set_attr "prefix_extra" "2")])
21187 (define_insn "wr<fsgs>base<mode>"
21188 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
21190 "TARGET_64BIT && TARGET_FSGSBASE"
21192 [(set_attr "type" "other")
21193 (set_attr "prefix_extra" "2")])
21195 (define_insn "ptwrite<mode>"
21196 [(unspec_volatile [(match_operand:SWI48 0 "nonimmediate_operand" "rm")]
21200 [(set_attr "type" "other")
21201 (set_attr "prefix_extra" "2")])
21203 (define_insn "@rdrand<mode>"
21204 [(set (match_operand:SWI248 0 "register_operand" "=r")
21205 (unspec_volatile:SWI248 [(const_int 0)] UNSPECV_RDRAND))
21206 (set (reg:CCC FLAGS_REG)
21207 (unspec_volatile:CCC [(const_int 0)] UNSPECV_RDRAND))]
21210 [(set_attr "type" "other")
21211 (set_attr "prefix_extra" "1")])
21213 (define_insn "@rdseed<mode>"
21214 [(set (match_operand:SWI248 0 "register_operand" "=r")
21215 (unspec_volatile:SWI248 [(const_int 0)] UNSPECV_RDSEED))
21216 (set (reg:CCC FLAGS_REG)
21217 (unspec_volatile:CCC [(const_int 0)] UNSPECV_RDSEED))]
21220 [(set_attr "type" "other")
21221 (set_attr "prefix_extra" "1")])
21223 (define_expand "pause"
21224 [(set (match_dup 0)
21225 (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
21228 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
21229 MEM_VOLATILE_P (operands[0]) = 1;
21232 ;; Use "rep; nop", instead of "pause", to support older assemblers.
21233 ;; They have the same encoding.
21234 (define_insn "*pause"
21235 [(set (match_operand:BLK 0)
21236 (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
21239 [(set_attr "length" "2")
21240 (set_attr "memory" "unknown")])
21242 ;; CET instructions
21243 (define_insn "@rdssp<mode>"
21244 [(set (match_operand:SWI48 0 "register_operand" "=r")
21245 (unspec_volatile:SWI48 [(match_operand:SWI48 1 "register_operand" "0")]
21246 UNSPECV_NOP_RDSSP))]
21247 "TARGET_SHSTK || (flag_cf_protection & CF_RETURN)"
21248 "rdssp<mskmodesuffix>\t%0"
21249 [(set_attr "length" "6")
21250 (set_attr "type" "other")])
21252 (define_insn "@incssp<mode>"
21253 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
21255 "TARGET_SHSTK || (flag_cf_protection & CF_RETURN)"
21256 "incssp<mskmodesuffix>\t%0"
21257 [(set_attr "length" "4")
21258 (set_attr "type" "other")])
21260 (define_insn "saveprevssp"
21261 [(unspec_volatile [(const_int 0)] UNSPECV_SAVEPREVSSP)]
21264 [(set_attr "length" "5")
21265 (set_attr "type" "other")])
21267 (define_insn "rstorssp"
21268 [(unspec_volatile [(match_operand:DI 0 "memory_operand" "m")]
21272 [(set_attr "length" "5")
21273 (set_attr "type" "other")])
21275 (define_insn "@wrss<mode>"
21276 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")
21277 (match_operand:SWI48 1 "memory_operand" "m")]
21280 "wrss<mskmodesuffix>\t%0, %1"
21281 [(set_attr "length" "3")
21282 (set_attr "type" "other")])
21284 (define_insn "@wruss<mode>"
21285 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")
21286 (match_operand:SWI48 1 "memory_operand" "m")]
21289 "wruss<mskmodesuffix>\t%0, %1"
21290 [(set_attr "length" "4")
21291 (set_attr "type" "other")])
21293 (define_insn "setssbsy"
21294 [(unspec_volatile [(const_int 0)] UNSPECV_SETSSBSY)]
21297 [(set_attr "length" "4")
21298 (set_attr "type" "other")])
21300 (define_insn "clrssbsy"
21301 [(unspec_volatile [(match_operand:DI 0 "memory_operand" "m")]
21305 [(set_attr "length" "4")
21306 (set_attr "type" "other")])
21308 (define_insn "nop_endbr"
21309 [(unspec_volatile [(const_int 0)] UNSPECV_NOP_ENDBR)]
21310 "(flag_cf_protection & CF_BRANCH)"
21312 return TARGET_64BIT ? "endbr64" : "endbr32";
21314 [(set_attr "length" "4")
21315 (set_attr "length_immediate" "0")
21316 (set_attr "modrm" "0")])
21319 (define_expand "xbegin"
21320 [(set (match_operand:SI 0 "register_operand")
21321 (unspec_volatile:SI [(const_int 0)] UNSPECV_XBEGIN))]
21324 rtx_code_label *label = gen_label_rtx ();
21326 /* xbegin is emitted as jump_insn, so reload won't be able
21327 to reload its operand. Force the value into AX hard register. */
21328 rtx ax_reg = gen_rtx_REG (SImode, AX_REG);
21329 emit_move_insn (ax_reg, constm1_rtx);
21331 emit_jump_insn (gen_xbegin_1 (ax_reg, label));
21333 emit_label (label);
21334 LABEL_NUSES (label) = 1;
21336 emit_move_insn (operands[0], ax_reg);
21341 (define_insn "xbegin_1"
21343 (if_then_else (ne (unspec [(const_int 0)] UNSPEC_XBEGIN_ABORT)
21345 (label_ref (match_operand 1))
21347 (set (match_operand:SI 0 "register_operand" "+a")
21348 (unspec_volatile:SI [(match_dup 0)] UNSPECV_XBEGIN))]
21351 [(set_attr "type" "other")
21352 (set_attr "length" "6")])
21354 (define_insn "xend"
21355 [(unspec_volatile [(const_int 0)] UNSPECV_XEND)]
21358 [(set_attr "type" "other")
21359 (set_attr "length" "3")])
21361 (define_insn "xabort"
21362 [(unspec_volatile [(match_operand:SI 0 "const_0_to_255_operand" "n")]
21366 [(set_attr "type" "other")
21367 (set_attr "length" "3")])
21369 (define_expand "xtest"
21370 [(set (match_operand:QI 0 "register_operand")
21371 (unspec_volatile:QI [(const_int 0)] UNSPECV_XTEST))]
21374 emit_insn (gen_xtest_1 ());
21376 ix86_expand_setcc (operands[0], NE,
21377 gen_rtx_REG (CCZmode, FLAGS_REG), const0_rtx);
21381 (define_insn "xtest_1"
21382 [(set (reg:CCZ FLAGS_REG)
21383 (unspec_volatile:CCZ [(const_int 0)] UNSPECV_XTEST))]
21386 [(set_attr "type" "other")
21387 (set_attr "length" "3")])
21389 (define_insn "clwb"
21390 [(unspec_volatile [(match_operand 0 "address_operand" "p")]
21394 [(set_attr "type" "sse")
21395 (set_attr "atom_sse_attr" "fence")
21396 (set_attr "memory" "unknown")])
21398 (define_insn "clflushopt"
21399 [(unspec_volatile [(match_operand 0 "address_operand" "p")]
21400 UNSPECV_CLFLUSHOPT)]
21401 "TARGET_CLFLUSHOPT"
21403 [(set_attr "type" "sse")
21404 (set_attr "atom_sse_attr" "fence")
21405 (set_attr "memory" "unknown")])
21407 ;; MONITORX and MWAITX
21408 (define_insn "mwaitx"
21409 [(unspec_volatile [(match_operand:SI 0 "register_operand" "c")
21410 (match_operand:SI 1 "register_operand" "a")
21411 (match_operand:SI 2 "register_operand" "b")]
21414 ;; 64bit version is "mwaitx %rax,%rcx,%rbx". But only lower 32bits are used.
21415 ;; Since 32bit register operands are implicitly zero extended to 64bit,
21416 ;; we only need to set up 32bit registers.
21418 [(set_attr "length" "3")])
21420 (define_insn "@monitorx_<mode>"
21421 [(unspec_volatile [(match_operand:P 0 "register_operand" "a")
21422 (match_operand:SI 1 "register_operand" "c")
21423 (match_operand:SI 2 "register_operand" "d")]
21426 ;; 64bit version is "monitorx %rax,%rcx,%rdx". But only lower 32bits in
21427 ;; RCX and RDX are used. Since 32bit register operands are implicitly
21428 ;; zero extended to 64bit, we only need to set up 32bit registers.
21430 [(set (attr "length")
21431 (symbol_ref ("(Pmode != word_mode) + 3")))])
21434 (define_insn "@clzero_<mode>"
21435 [(unspec_volatile [(match_operand: P 0 "register_operand" "a")]
21439 [(set_attr "length" "3")
21440 (set_attr "memory" "unknown")])
21442 ;; RDPKRU and WRPKRU
21444 (define_expand "rdpkru"
21446 [(set (match_operand:SI 0 "register_operand")
21447 (unspec_volatile:SI [(match_dup 1)] UNSPECV_PKU))
21448 (set (match_dup 2) (const_int 0))])]
21451 operands[1] = force_reg (SImode, const0_rtx);
21452 operands[2] = gen_reg_rtx (SImode);
21455 (define_insn "*rdpkru"
21456 [(set (match_operand:SI 0 "register_operand" "=a")
21457 (unspec_volatile:SI [(match_operand:SI 2 "register_operand" "c")]
21459 (set (match_operand:SI 1 "register_operand" "=d")
21463 [(set_attr "type" "other")])
21465 (define_expand "wrpkru"
21466 [(unspec_volatile:SI
21467 [(match_operand:SI 0 "register_operand")
21468 (match_dup 1) (match_dup 2)] UNSPECV_PKU)]
21471 operands[1] = force_reg (SImode, const0_rtx);
21472 operands[2] = force_reg (SImode, const0_rtx);
21475 (define_insn "*wrpkru"
21476 [(unspec_volatile:SI
21477 [(match_operand:SI 0 "register_operand" "a")
21478 (match_operand:SI 1 "register_operand" "d")
21479 (match_operand:SI 2 "register_operand" "c")] UNSPECV_PKU)]
21482 [(set_attr "type" "other")])
21484 (define_insn "rdpid"
21485 [(set (match_operand:SI 0 "register_operand" "=r")
21486 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDPID))]
21487 "!TARGET_64BIT && TARGET_RDPID"
21489 [(set_attr "type" "other")])
21491 (define_insn "rdpid_rex64"
21492 [(set (match_operand:DI 0 "register_operand" "=r")
21493 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDPID))]
21494 "TARGET_64BIT && TARGET_RDPID"
21496 [(set_attr "type" "other")])
21498 ;; Intirinsics for > i486
21500 (define_insn "wbinvd"
21501 [(unspec_volatile [(const_int 0)] UNSPECV_WBINVD)]
21504 [(set_attr "type" "other")])
21506 (define_insn "wbnoinvd"
21507 [(unspec_volatile [(const_int 0)] UNSPECV_WBNOINVD)]
21510 [(set_attr "type" "other")])
21512 ;; MOVDIRI and MOVDIR64B
21514 (define_insn "movdiri<mode>"
21515 [(set (match_operand:SWI48 0 "memory_operand" "=m")
21516 (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")]
21519 "movdiri\t{%1, %0|%0, %1}"
21520 [(set_attr "type" "other")])
21522 (define_insn "@movdir64b_<mode>"
21523 [(set (mem:XI (match_operand:P 0 "register_operand" "r"))
21524 (unspec:XI [(match_operand:XI 1 "memory_operand" "m")]
21525 UNSPEC_MOVDIR64B))]
21527 "movdir64b\t{%1, %0|%0, %1}"
21528 [(set_attr "type" "other")])
21531 (define_int_iterator TSXLDTRK [UNSPECV_XSUSLDTRK UNSPECV_XRESLDTRK])
21532 (define_int_attr tsxldtrk [(UNSPECV_XSUSLDTRK "xsusldtrk")
21533 (UNSPECV_XRESLDTRK "xresldtrk")])
21534 (define_insn "<tsxldtrk>"
21535 [(unspec_volatile [(const_int 0)] TSXLDTRK)]
21538 [(set_attr "type" "other")
21539 (set_attr "length" "4")])
21541 ;; ENQCMD and ENQCMDS
21543 (define_int_iterator ENQCMD [UNSPECV_ENQCMD UNSPECV_ENQCMDS])
21544 (define_int_attr enqcmd_sfx [(UNSPECV_ENQCMD "") (UNSPECV_ENQCMDS "s")])
21546 (define_insn "@enqcmd<enqcmd_sfx>_<mode>"
21547 [(set (reg:CCZ FLAGS_REG)
21548 (unspec_volatile:CCZ [(match_operand:P 0 "register_operand" "r")
21549 (match_operand:XI 1 "memory_operand" "m")]
21552 "enqcmd<enqcmd_sfx>\t{%1, %0|%0, %1}"
21553 [(set_attr "type" "other")])
21556 (define_int_iterator UINTR [UNSPECV_CLUI UNSPECV_STUI])
21557 (define_int_attr uintr [(UNSPECV_CLUI "clui") (UNSPECV_STUI "stui")])
21559 (define_insn "<uintr>"
21560 [(unspec_volatile [(const_int 0)] UINTR)]
21561 "TARGET_UINTR && TARGET_64BIT"
21563 [(set_attr "type" "other")
21564 (set_attr "length" "4")])
21566 (define_insn "testui"
21567 [(set (reg:CCC FLAGS_REG)
21568 (unspec_volatile:CCC [(const_int 0)] UNSPECV_TESTUI))]
21569 "TARGET_UINTR && TARGET_64BIT"
21571 [(set_attr "type" "other")
21572 (set_attr "length" "4")])
21574 (define_insn "senduipi"
21576 [(match_operand:DI 0 "register_operand" "r")]
21578 "TARGET_UINTR && TARGET_64BIT"
21580 [(set_attr "type" "other")
21581 (set_attr "length" "4")])
21585 (define_insn "umwait"
21586 [(set (reg:CCC FLAGS_REG)
21587 (unspec_volatile:CCC [(match_operand:SI 0 "register_operand" "r")
21588 (match_operand:DI 1 "register_operand" "A")]
21590 "!TARGET_64BIT && TARGET_WAITPKG"
21592 [(set_attr "length" "3")])
21594 (define_insn "umwait_rex64"
21595 [(set (reg:CCC FLAGS_REG)
21596 (unspec_volatile:CCC [(match_operand:SI 0 "register_operand" "r")
21597 (match_operand:SI 1 "register_operand" "a")
21598 (match_operand:SI 2 "register_operand" "d")]
21600 "TARGET_64BIT && TARGET_WAITPKG"
21602 [(set_attr "length" "3")])
21604 (define_insn "@umonitor_<mode>"
21605 [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
21609 [(set (attr "length")
21610 (symbol_ref ("(Pmode != word_mode) + 3")))])
21612 (define_insn "tpause"
21613 [(set (reg:CCC FLAGS_REG)
21614 (unspec_volatile:CCC [(match_operand:SI 0 "register_operand" "r")
21615 (match_operand:DI 1 "register_operand" "A")]
21617 "!TARGET_64BIT && TARGET_WAITPKG"
21619 [(set_attr "length" "3")])
21621 (define_insn "tpause_rex64"
21622 [(set (reg:CCC FLAGS_REG)
21623 (unspec_volatile:CCC [(match_operand:SI 0 "register_operand" "r")
21624 (match_operand:SI 1 "register_operand" "a")
21625 (match_operand:SI 2 "register_operand" "d")]
21627 "TARGET_64BIT && TARGET_WAITPKG"
21629 [(set_attr "length" "3")])
21631 (define_insn "cldemote"
21632 [(unspec_volatile[(match_operand 0 "address_operand" "p")]
21636 [(set_attr "type" "other")
21637 (set_attr "memory" "unknown")])
21639 (define_insn "speculation_barrier"
21640 [(unspec_volatile [(const_int 0)] UNSPECV_SPECULATION_BARRIER)]
21643 [(set_attr "type" "other")
21644 (set_attr "length" "3")])
21646 (define_insn "serialize"
21647 [(unspec_volatile [(const_int 0)] UNSPECV_SERIALIZE)]
21650 [(set_attr "type" "other")
21651 (set_attr "length" "3")])
21653 (define_insn "patchable_area"
21654 [(unspec_volatile [(match_operand 0 "const_int_operand")
21655 (match_operand 1 "const_int_operand")]
21656 UNSPECV_PATCHABLE_AREA)]
21659 ix86_output_patchable_area (INTVAL (operands[0]),
21660 INTVAL (operands[1]) != 0);
21663 [(set (attr "length") (symbol_ref "INTVAL (operands[0])"))
21664 (set_attr "length_immediate" "0")
21665 (set_attr "modrm" "0")])
21667 (define_insn "hreset"
21668 [(unspec_volatile [(match_operand:SI 0 "register_operand" "a")]
21672 [(set_attr "type" "other")
21673 (set_attr "length" "4")])
21677 (include "sync.md")