1 ;; GCC machine description for IA-32 and x86-64.
2 ;; Copyright (C) 1988-2021 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,znver3"
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 avxvnni,avx512vnnivl"
823 (const_string "base"))
825 ;; Define instruction set of MMX instructions
826 (define_attr "mmx_isa" "base,native,sse,sse_noavx,avx"
827 (const_string "base"))
829 (define_attr "enabled" ""
830 (cond [(eq_attr "isa" "x64") (symbol_ref "TARGET_64BIT")
831 (eq_attr "isa" "x64_sse2")
832 (symbol_ref "TARGET_64BIT && TARGET_SSE2")
833 (eq_attr "isa" "x64_sse4")
834 (symbol_ref "TARGET_64BIT && TARGET_SSE4_1")
835 (eq_attr "isa" "x64_sse4_noavx")
836 (symbol_ref "TARGET_64BIT && TARGET_SSE4_1 && !TARGET_AVX")
837 (eq_attr "isa" "x64_avx")
838 (symbol_ref "TARGET_64BIT && TARGET_AVX")
839 (eq_attr "isa" "x64_avx512dq")
840 (symbol_ref "TARGET_64BIT && TARGET_AVX512DQ")
841 (eq_attr "isa" "x64_avx512bw")
842 (symbol_ref "TARGET_64BIT && TARGET_AVX512BW")
843 (eq_attr "isa" "nox64") (symbol_ref "!TARGET_64BIT")
844 (eq_attr "isa" "sse2") (symbol_ref "TARGET_SSE2")
845 (eq_attr "isa" "sse_noavx")
846 (symbol_ref "TARGET_SSE && !TARGET_AVX")
847 (eq_attr "isa" "sse2_noavx")
848 (symbol_ref "TARGET_SSE2 && !TARGET_AVX")
849 (eq_attr "isa" "sse3") (symbol_ref "TARGET_SSE3")
850 (eq_attr "isa" "sse3_noavx")
851 (symbol_ref "TARGET_SSE3 && !TARGET_AVX")
852 (eq_attr "isa" "sse4") (symbol_ref "TARGET_SSE4_1")
853 (eq_attr "isa" "sse4_noavx")
854 (symbol_ref "TARGET_SSE4_1 && !TARGET_AVX")
855 (eq_attr "isa" "avx") (symbol_ref "TARGET_AVX")
856 (eq_attr "isa" "noavx") (symbol_ref "!TARGET_AVX")
857 (eq_attr "isa" "avx2") (symbol_ref "TARGET_AVX2")
858 (eq_attr "isa" "noavx2") (symbol_ref "!TARGET_AVX2")
859 (eq_attr "isa" "bmi") (symbol_ref "TARGET_BMI")
860 (eq_attr "isa" "bmi2") (symbol_ref "TARGET_BMI2")
861 (eq_attr "isa" "fma4") (symbol_ref "TARGET_FMA4")
862 (eq_attr "isa" "fma") (symbol_ref "TARGET_FMA")
863 (eq_attr "isa" "avx512f") (symbol_ref "TARGET_AVX512F")
864 (eq_attr "isa" "noavx512f") (symbol_ref "!TARGET_AVX512F")
865 (eq_attr "isa" "avx512bw") (symbol_ref "TARGET_AVX512BW")
866 (eq_attr "isa" "noavx512bw") (symbol_ref "!TARGET_AVX512BW")
867 (eq_attr "isa" "avx512dq") (symbol_ref "TARGET_AVX512DQ")
868 (eq_attr "isa" "noavx512dq") (symbol_ref "!TARGET_AVX512DQ")
869 (eq_attr "isa" "avx512vl") (symbol_ref "TARGET_AVX512VL")
870 (eq_attr "isa" "noavx512vl") (symbol_ref "!TARGET_AVX512VL")
871 (eq_attr "isa" "avxvnni") (symbol_ref "TARGET_AVXVNNI")
872 (eq_attr "isa" "avx512vnnivl")
873 (symbol_ref "TARGET_AVX512VNNI && TARGET_AVX512VL")
875 (eq_attr "mmx_isa" "native")
876 (symbol_ref "!TARGET_MMX_WITH_SSE")
877 (eq_attr "mmx_isa" "sse")
878 (symbol_ref "TARGET_MMX_WITH_SSE")
879 (eq_attr "mmx_isa" "sse_noavx")
880 (symbol_ref "TARGET_MMX_WITH_SSE && !TARGET_AVX")
881 (eq_attr "mmx_isa" "avx")
882 (symbol_ref "TARGET_MMX_WITH_SSE && TARGET_AVX")
886 (define_attr "preferred_for_size" "" (const_int 1))
887 (define_attr "preferred_for_speed" "" (const_int 1))
889 ;; Describe a user's asm statement.
890 (define_asm_attributes
891 [(set_attr "length" "128")
892 (set_attr "type" "multi")])
894 (define_code_iterator plusminus [plus minus])
896 (define_code_iterator sat_plusminus [ss_plus us_plus ss_minus us_minus])
898 ;; Base name for insn mnemonic.
899 (define_code_attr plusminus_mnemonic
900 [(plus "add") (ss_plus "adds") (us_plus "addus")
901 (minus "sub") (ss_minus "subs") (us_minus "subus")])
903 (define_code_iterator multdiv [mult div])
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 insn mnemonic.
952 (define_code_attr shift [(ashift "sll") (lshiftrt "shr") (ashiftrt "sar")])
953 (define_code_attr vshift [(ashift "sll") (lshiftrt "srl") (ashiftrt "sra")])
955 ;; Mapping of rotate operators
956 (define_code_iterator any_rotate [rotate rotatert])
958 ;; Base name for insn mnemonic.
959 (define_code_attr rotate [(rotate "rol") (rotatert "ror")])
961 ;; Mapping of abs neg operators
962 (define_code_iterator absneg [abs neg])
964 ;; Mapping of abs neg operators to logic operation
965 (define_code_attr absneg_op [(abs "and") (neg "xor")])
967 ;; Base name for x87 insn mnemonic.
968 (define_code_attr absneg_mnemonic [(abs "fabs") (neg "fchs")])
970 ;; Mapping of extend operators
971 (define_code_iterator any_extend [sign_extend zero_extend])
973 ;; Prefix for insn menmonic.
974 (define_code_attr sgnprefix [(sign_extend "i") (zero_extend "")
975 (div "i") (udiv "")])
976 ;; Prefix for define_insn
977 (define_code_attr s [(sign_extend "s") (zero_extend "u")])
978 (define_code_attr u [(sign_extend "") (zero_extend "u")
979 (div "") (udiv "u")])
980 (define_code_attr u_bool [(sign_extend "false") (zero_extend "true")
981 (div "false") (udiv "true")])
983 ;; Used in signed and unsigned truncations.
984 (define_code_iterator any_truncate [ss_truncate truncate us_truncate])
985 ;; Instruction suffix for truncations.
986 (define_code_attr trunsuffix
987 [(ss_truncate "s") (truncate "") (us_truncate "us")])
989 ;; Used in signed and unsigned fix.
990 (define_code_iterator any_fix [fix unsigned_fix])
991 (define_code_attr fixsuffix [(fix "") (unsigned_fix "u")])
992 (define_code_attr fixunssuffix [(fix "") (unsigned_fix "uns")])
993 (define_code_attr fixprefix [(fix "s") (unsigned_fix "u")])
995 ;; Used in signed and unsigned float.
996 (define_code_iterator any_float [float unsigned_float])
997 (define_code_attr floatsuffix [(float "") (unsigned_float "u")])
998 (define_code_attr floatunssuffix [(float "") (unsigned_float "uns")])
999 (define_code_attr floatprefix [(float "s") (unsigned_float "u")])
1001 ;; Base name for expression
1002 (define_code_attr insn
1003 [(plus "add") (ss_plus "ssadd") (us_plus "usadd")
1004 (minus "sub") (ss_minus "sssub") (us_minus "ussub")
1005 (sign_extend "extend") (zero_extend "zero_extend")
1006 (ashift "ashl") (lshiftrt "lshr") (ashiftrt "ashr")
1007 (rotate "rotl") (rotatert "rotr")])
1009 ;; All integer modes.
1010 (define_mode_iterator SWI1248x [QI HI SI DI])
1012 ;; All integer modes without QImode.
1013 (define_mode_iterator SWI248x [HI SI DI])
1015 ;; All integer modes without QImode and HImode.
1016 (define_mode_iterator SWI48x [SI DI])
1018 ;; All integer modes without SImode and DImode.
1019 (define_mode_iterator SWI12 [QI HI])
1021 ;; All integer modes without DImode.
1022 (define_mode_iterator SWI124 [QI HI SI])
1024 ;; All integer modes without QImode and DImode.
1025 (define_mode_iterator SWI24 [HI SI])
1027 ;; Single word integer modes.
1028 (define_mode_iterator SWI [QI HI SI (DI "TARGET_64BIT")])
1030 ;; Single word integer modes without QImode.
1031 (define_mode_iterator SWI248 [HI SI (DI "TARGET_64BIT")])
1033 ;; Single word integer modes without QImode and HImode.
1034 (define_mode_iterator SWI48 [SI (DI "TARGET_64BIT")])
1036 ;; All math-dependant single and double word integer modes.
1037 (define_mode_iterator SDWIM [(QI "TARGET_QIMODE_MATH")
1038 (HI "TARGET_HIMODE_MATH")
1039 SI DI (TI "TARGET_64BIT")])
1041 ;; Math-dependant single word integer modes.
1042 (define_mode_iterator SWIM [(QI "TARGET_QIMODE_MATH")
1043 (HI "TARGET_HIMODE_MATH")
1044 SI (DI "TARGET_64BIT")])
1046 ;; Math-dependant integer modes without DImode.
1047 (define_mode_iterator SWIM124 [(QI "TARGET_QIMODE_MATH")
1048 (HI "TARGET_HIMODE_MATH")
1051 ;; Math-dependant integer modes with DImode (enabled for 32bit with STV).
1052 (define_mode_iterator SWIM1248s
1053 [(QI "TARGET_QIMODE_MATH")
1054 (HI "TARGET_HIMODE_MATH")
1055 SI (DI "TARGET_64BIT || (TARGET_STV && TARGET_SSE2)")])
1057 ;; Math-dependant single word integer modes without QImode.
1058 (define_mode_iterator SWIM248 [(HI "TARGET_HIMODE_MATH")
1059 SI (DI "TARGET_64BIT")])
1061 ;; Double word integer modes.
1062 (define_mode_iterator DWI [(DI "!TARGET_64BIT")
1063 (TI "TARGET_64BIT")])
1065 ;; SWI and DWI together.
1066 (define_mode_iterator SWIDWI [QI HI SI DI (TI "TARGET_64BIT")])
1068 ;; SWI48 and DWI together.
1069 (define_mode_iterator SWI48DWI [SI DI (TI "TARGET_64BIT")])
1071 ;; GET_MODE_SIZE for selected modes. As GET_MODE_SIZE is not
1072 ;; compile time constant, it is faster to use <MODE_SIZE> than
1073 ;; GET_MODE_SIZE (<MODE>mode). For XFmode which depends on
1074 ;; command line options just use GET_MODE_SIZE macro.
1075 (define_mode_attr MODE_SIZE [(QI "1") (HI "2") (SI "4") (DI "8") (TI "16")
1076 (SF "4") (DF "8") (XF "GET_MODE_SIZE (XFmode)")
1077 (V16QI "16") (V32QI "32") (V64QI "64")
1078 (V8HI "16") (V16HI "32") (V32HI "64")
1079 (V4SI "16") (V8SI "32") (V16SI "64")
1080 (V2DI "16") (V4DI "32") (V8DI "64")
1081 (V1TI "16") (V2TI "32") (V4TI "64")
1082 (V2DF "16") (V4DF "32") (V8DF "64")
1083 (V4SF "16") (V8SF "32") (V16SF "64")])
1085 ;; Double word integer modes as mode attribute.
1086 (define_mode_attr DWI [(QI "HI") (HI "SI") (SI "DI") (DI "TI") (TI "OI")])
1087 (define_mode_attr dwi [(QI "hi") (HI "si") (SI "di") (DI "ti") (TI "oi")])
1089 ;; LEA mode corresponding to an integer mode
1090 (define_mode_attr LEAMODE [(QI "SI") (HI "SI") (SI "SI") (DI "DI")])
1092 ;; Half mode for double word integer modes.
1093 (define_mode_iterator DWIH [(SI "!TARGET_64BIT")
1094 (DI "TARGET_64BIT")])
1096 ;; Instruction suffix for integer modes.
1097 (define_mode_attr imodesuffix [(QI "b") (HI "w") (SI "l") (DI "q")])
1099 ;; Instruction suffix for masks.
1100 (define_mode_attr mskmodesuffix [(QI "b") (HI "w") (SI "d") (DI "q")])
1102 ;; Pointer size prefix for integer modes (Intel asm dialect)
1103 (define_mode_attr iptrsize [(QI "BYTE")
1108 ;; Register class for integer modes.
1109 (define_mode_attr r [(QI "q") (HI "r") (SI "r") (DI "r")])
1111 ;; Immediate operand constraint for integer modes.
1112 (define_mode_attr i [(QI "n") (HI "n") (SI "e") (DI "e")])
1114 ;; General operand constraint for word modes.
1115 (define_mode_attr g [(QI "qmn") (HI "rmn") (SI "rme") (DI "rme")])
1117 ;; Immediate operand constraint for double integer modes.
1118 (define_mode_attr di [(SI "nF") (DI "Wd")])
1120 ;; Immediate operand constraint for shifts.
1121 (define_mode_attr S [(QI "I") (HI "I") (SI "I") (DI "J") (TI "O")])
1123 ;; Print register name in the specified mode.
1124 (define_mode_attr k [(QI "b") (HI "w") (SI "k") (DI "q")])
1126 ;; General operand predicate for integer modes.
1127 (define_mode_attr general_operand
1128 [(QI "general_operand")
1129 (HI "general_operand")
1130 (SI "x86_64_general_operand")
1131 (DI "x86_64_general_operand")
1132 (TI "x86_64_general_operand")])
1134 ;; General operand predicate for integer modes, where for TImode
1135 ;; we need both words of the operand to be general operands.
1136 (define_mode_attr general_hilo_operand
1137 [(QI "general_operand")
1138 (HI "general_operand")
1139 (SI "x86_64_general_operand")
1140 (DI "x86_64_general_operand")
1141 (TI "x86_64_hilo_general_operand")])
1143 ;; General sign extend operand predicate for integer modes,
1144 ;; which disallows VOIDmode operands and thus it is suitable
1145 ;; for use inside sign_extend.
1146 (define_mode_attr general_sext_operand
1147 [(QI "sext_operand")
1149 (SI "x86_64_sext_operand")
1150 (DI "x86_64_sext_operand")])
1152 ;; General sign/zero extend operand predicate for integer modes.
1153 (define_mode_attr general_szext_operand
1154 [(QI "general_operand")
1155 (HI "general_operand")
1156 (SI "x86_64_szext_general_operand")
1157 (DI "x86_64_szext_general_operand")])
1159 (define_mode_attr nonmemory_szext_operand
1160 [(QI "nonmemory_operand")
1161 (HI "nonmemory_operand")
1162 (SI "x86_64_szext_nonmemory_operand")
1163 (DI "x86_64_szext_nonmemory_operand")])
1165 ;; Immediate operand predicate for integer modes.
1166 (define_mode_attr immediate_operand
1167 [(QI "immediate_operand")
1168 (HI "immediate_operand")
1169 (SI "x86_64_immediate_operand")
1170 (DI "x86_64_immediate_operand")])
1172 ;; Nonmemory operand predicate for integer modes.
1173 (define_mode_attr nonmemory_operand
1174 [(QI "nonmemory_operand")
1175 (HI "nonmemory_operand")
1176 (SI "x86_64_nonmemory_operand")
1177 (DI "x86_64_nonmemory_operand")])
1179 ;; Operand predicate for shifts.
1180 (define_mode_attr shift_operand
1181 [(QI "nonimmediate_operand")
1182 (HI "nonimmediate_operand")
1183 (SI "nonimmediate_operand")
1184 (DI "shiftdi_operand")
1185 (TI "register_operand")])
1187 ;; Operand predicate for shift argument.
1188 (define_mode_attr shift_immediate_operand
1189 [(QI "const_1_to_31_operand")
1190 (HI "const_1_to_31_operand")
1191 (SI "const_1_to_31_operand")
1192 (DI "const_1_to_63_operand")])
1194 ;; Input operand predicate for arithmetic left shifts.
1195 (define_mode_attr ashl_input_operand
1196 [(QI "nonimmediate_operand")
1197 (HI "nonimmediate_operand")
1198 (SI "nonimmediate_operand")
1199 (DI "ashldi_input_operand")
1200 (TI "reg_or_pm1_operand")])
1202 ;; SSE and x87 SFmode and DFmode floating point modes
1203 (define_mode_iterator MODEF [SF DF])
1205 ;; All x87 floating point modes
1206 (define_mode_iterator X87MODEF [SF DF XF])
1208 ;; All SSE floating point modes
1209 (define_mode_iterator SSEMODEF [SF DF TF])
1210 (define_mode_attr ssevecmodef [(SF "V4SF") (DF "V2DF") (TF "TF")])
1212 ;; SSE instruction suffix for various modes
1213 (define_mode_attr ssemodesuffix
1214 [(SF "ss") (DF "sd")
1215 (V16SF "ps") (V8DF "pd")
1216 (V8SF "ps") (V4DF "pd")
1217 (V4SF "ps") (V2DF "pd")
1218 (V16QI "b") (V8HI "w") (V4SI "d") (V2DI "q")
1219 (V32QI "b") (V16HI "w") (V8SI "d") (V4DI "q")
1220 (V64QI "b") (V32HI "w") (V16SI "d") (V8DI "q")])
1222 ;; SSE vector suffix for floating point modes
1223 (define_mode_attr ssevecmodesuffix [(SF "ps") (DF "pd")])
1225 ;; SSE vector mode corresponding to a scalar mode
1226 (define_mode_attr ssevecmode
1227 [(QI "V16QI") (HI "V8HI") (SI "V4SI") (DI "V2DI") (SF "V4SF") (DF "V2DF")])
1228 (define_mode_attr ssevecmodelower
1229 [(QI "v16qi") (HI "v8hi") (SI "v4si") (DI "v2di") (SF "v4sf") (DF "v2df")])
1231 ;; AVX512F vector mode corresponding to a scalar mode
1232 (define_mode_attr avx512fvecmode
1233 [(QI "V64QI") (HI "V32HI") (SI "V16SI") (DI "V8DI") (SF "V16SF") (DF "V8DF")])
1235 ;; Instruction suffix for REX 64bit operators.
1236 (define_mode_attr rex64suffix [(SI "{l}") (DI "{q}")])
1237 (define_mode_attr rex64namesuffix [(SI "") (DI "q")])
1239 ;; This mode iterator allows :P to be used for patterns that operate on
1240 ;; pointer-sized quantities. Exactly one of the two alternatives will match.
1241 (define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
1243 ;; This mode iterator allows :W to be used for patterns that operate on
1244 ;; word_mode sized quantities.
1245 (define_mode_iterator W
1246 [(SI "word_mode == SImode") (DI "word_mode == DImode")])
1248 ;; This mode iterator allows :PTR to be used for patterns that operate on
1249 ;; ptr_mode sized quantities.
1250 (define_mode_iterator PTR
1251 [(SI "ptr_mode == SImode") (DI "ptr_mode == DImode")])
1253 ;; Scheduling descriptions
1255 (include "pentium.md")
1258 (include "athlon.md")
1259 (include "bdver1.md")
1260 (include "bdver3.md")
1261 (include "btver2.md")
1262 (include "znver1.md")
1263 (include "geode.md")
1267 (include "core2.md")
1268 (include "haswell.md")
1271 ;; Operand and operator predicates and constraints
1273 (include "predicates.md")
1274 (include "constraints.md")
1277 ;; Compare and branch/compare and store instructions.
1279 (define_expand "cbranch<mode>4"
1280 [(set (reg:CC FLAGS_REG)
1281 (compare:CC (match_operand:SDWIM 1 "nonimmediate_operand")
1282 (match_operand:SDWIM 2 "<general_operand>")))
1283 (set (pc) (if_then_else
1284 (match_operator 0 "ordered_comparison_operator"
1285 [(reg:CC FLAGS_REG) (const_int 0)])
1286 (label_ref (match_operand 3))
1290 if (MEM_P (operands[1]) && MEM_P (operands[2]))
1291 operands[1] = force_reg (<MODE>mode, operands[1]);
1292 ix86_expand_branch (GET_CODE (operands[0]),
1293 operands[1], operands[2], operands[3]);
1297 (define_expand "cstore<mode>4"
1298 [(set (reg:CC FLAGS_REG)
1299 (compare:CC (match_operand:SWIM 2 "nonimmediate_operand")
1300 (match_operand:SWIM 3 "<general_operand>")))
1301 (set (match_operand:QI 0 "register_operand")
1302 (match_operator 1 "ordered_comparison_operator"
1303 [(reg:CC FLAGS_REG) (const_int 0)]))]
1306 if (MEM_P (operands[2]) && MEM_P (operands[3]))
1307 operands[2] = force_reg (<MODE>mode, operands[2]);
1308 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1309 operands[2], operands[3]);
1313 (define_expand "@cmp<mode>_1"
1314 [(set (reg:CC FLAGS_REG)
1315 (compare:CC (match_operand:SWI48 0 "nonimmediate_operand")
1316 (match_operand:SWI48 1 "<general_operand>")))])
1318 (define_mode_iterator SWI1248_AVX512BWDQ_64
1319 [(QI "TARGET_AVX512DQ") HI
1320 (SI "TARGET_AVX512BW") (DI "TARGET_AVX512BW && TARGET_64BIT")])
1322 (define_insn "*cmp<mode>_ccz_1"
1323 [(set (reg FLAGS_REG)
1324 (compare (match_operand:SWI1248_AVX512BWDQ_64 0
1325 "nonimmediate_operand" "<r>,?m<r>,$k")
1326 (match_operand:SWI1248_AVX512BWDQ_64 1 "const0_operand")))]
1327 "TARGET_AVX512F && ix86_match_ccmode (insn, CCZmode)"
1329 test{<imodesuffix>}\t%0, %0
1330 cmp{<imodesuffix>}\t{%1, %0|%0, %1}
1331 kortest<mskmodesuffix>\t%0, %0"
1332 [(set_attr "type" "test,icmp,msklog")
1333 (set_attr "length_immediate" "0,1,*")
1334 (set_attr "prefix" "*,*,vex")
1335 (set_attr "mode" "<MODE>")])
1337 (define_insn "*cmp<mode>_ccno_1"
1338 [(set (reg FLAGS_REG)
1339 (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>,?m<r>")
1340 (match_operand:SWI 1 "const0_operand")))]
1341 "ix86_match_ccmode (insn, CCNOmode)"
1343 test{<imodesuffix>}\t%0, %0
1344 cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1345 [(set_attr "type" "test,icmp")
1346 (set_attr "length_immediate" "0,1")
1347 (set_attr "mode" "<MODE>")])
1349 (define_insn "*cmp<mode>_1"
1350 [(set (reg FLAGS_REG)
1351 (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
1352 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m")))]
1353 "ix86_match_ccmode (insn, CCmode)"
1354 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1355 [(set_attr "type" "icmp")
1356 (set_attr "mode" "<MODE>")])
1358 (define_insn "*cmp<mode>_minus_1"
1359 [(set (reg FLAGS_REG)
1361 (minus:SWI (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
1362 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
1364 "ix86_match_ccmode (insn, CCGOCmode)"
1365 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1366 [(set_attr "type" "icmp")
1367 (set_attr "mode" "<MODE>")])
1369 (define_insn "*cmpqi_ext<mode>_1"
1370 [(set (reg FLAGS_REG)
1372 (match_operand:QI 0 "nonimmediate_operand" "QBc,m")
1374 (zero_extract:SWI248
1375 (match_operand:SWI248 1 "register_operand" "Q,Q")
1377 (const_int 8)) 0)))]
1378 "ix86_match_ccmode (insn, CCmode)"
1379 "cmp{b}\t{%h1, %0|%0, %h1}"
1380 [(set_attr "isa" "*,nox64")
1381 (set_attr "type" "icmp")
1382 (set_attr "mode" "QI")])
1384 (define_insn "*cmpqi_ext<mode>_2"
1385 [(set (reg FLAGS_REG)
1388 (zero_extract:SWI248
1389 (match_operand:SWI248 0 "register_operand" "Q")
1392 (match_operand:QI 1 "const0_operand")))]
1393 "ix86_match_ccmode (insn, CCNOmode)"
1395 [(set_attr "type" "test")
1396 (set_attr "length_immediate" "0")
1397 (set_attr "mode" "QI")])
1399 (define_expand "cmpqi_ext_3"
1400 [(set (reg:CC FLAGS_REG)
1404 (match_operand:HI 0 "register_operand")
1407 (match_operand:QI 1 "const_int_operand")))])
1409 (define_insn "*cmpqi_ext<mode>_3"
1410 [(set (reg FLAGS_REG)
1413 (zero_extract:SWI248
1414 (match_operand:SWI248 0 "register_operand" "Q,Q")
1417 (match_operand:QI 1 "general_operand" "QnBc,m")))]
1418 "ix86_match_ccmode (insn, CCmode)"
1419 "cmp{b}\t{%1, %h0|%h0, %1}"
1420 [(set_attr "isa" "*,nox64")
1421 (set_attr "type" "icmp")
1422 (set_attr "mode" "QI")])
1424 (define_insn "*cmpqi_ext<mode>_4"
1425 [(set (reg FLAGS_REG)
1428 (zero_extract:SWI248
1429 (match_operand:SWI248 0 "register_operand" "Q")
1433 (zero_extract:SWI248
1434 (match_operand:SWI248 1 "register_operand" "Q")
1436 (const_int 8)) 0)))]
1437 "ix86_match_ccmode (insn, CCmode)"
1438 "cmp{b}\t{%h1, %h0|%h0, %h1}"
1439 [(set_attr "type" "icmp")
1440 (set_attr "mode" "QI")])
1442 ;; These implement float point compares.
1443 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
1444 ;; which would allow mix and match FP modes on the compares. Which is what
1445 ;; the old patterns did, but with many more of them.
1447 (define_expand "cbranchxf4"
1448 [(set (reg:CC FLAGS_REG)
1449 (compare:CC (match_operand:XF 1 "nonmemory_operand")
1450 (match_operand:XF 2 "nonmemory_operand")))
1451 (set (pc) (if_then_else
1452 (match_operator 0 "ix86_fp_comparison_operator"
1455 (label_ref (match_operand 3))
1459 ix86_expand_branch (GET_CODE (operands[0]),
1460 operands[1], operands[2], operands[3]);
1464 (define_expand "cstorexf4"
1465 [(set (reg:CC FLAGS_REG)
1466 (compare:CC (match_operand:XF 2 "nonmemory_operand")
1467 (match_operand:XF 3 "nonmemory_operand")))
1468 (set (match_operand:QI 0 "register_operand")
1469 (match_operator 1 "ix86_fp_comparison_operator"
1474 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1475 operands[2], operands[3]);
1479 (define_expand "cbranch<mode>4"
1480 [(set (reg:CC FLAGS_REG)
1481 (compare:CC (match_operand:MODEF 1 "cmp_fp_expander_operand")
1482 (match_operand:MODEF 2 "cmp_fp_expander_operand")))
1483 (set (pc) (if_then_else
1484 (match_operator 0 "ix86_fp_comparison_operator"
1487 (label_ref (match_operand 3))
1489 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1491 ix86_expand_branch (GET_CODE (operands[0]),
1492 operands[1], operands[2], operands[3]);
1496 (define_expand "cstore<mode>4"
1497 [(set (reg:CC FLAGS_REG)
1498 (compare:CC (match_operand:MODEF 2 "cmp_fp_expander_operand")
1499 (match_operand:MODEF 3 "cmp_fp_expander_operand")))
1500 (set (match_operand:QI 0 "register_operand")
1501 (match_operator 1 "ix86_fp_comparison_operator"
1504 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1506 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1507 operands[2], operands[3]);
1511 (define_expand "cbranchcc4"
1512 [(set (pc) (if_then_else
1513 (match_operator 0 "comparison_operator"
1514 [(match_operand 1 "flags_reg_operand")
1515 (match_operand 2 "const0_operand")])
1516 (label_ref (match_operand 3))
1520 ix86_expand_branch (GET_CODE (operands[0]),
1521 operands[1], operands[2], operands[3]);
1525 (define_expand "cstorecc4"
1526 [(set (match_operand:QI 0 "register_operand")
1527 (match_operator 1 "comparison_operator"
1528 [(match_operand 2 "flags_reg_operand")
1529 (match_operand 3 "const0_operand")]))]
1532 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1533 operands[2], operands[3]);
1537 ;; FP compares, step 1:
1538 ;; Set the FP condition codes and move fpsr to ax.
1540 ;; We may not use "#" to split and emit these
1541 ;; due to reg-stack pops killing fpsr.
1543 (define_insn "*cmpxf_i387"
1544 [(set (match_operand:HI 0 "register_operand" "=a")
1547 (match_operand:XF 1 "register_operand" "f")
1548 (match_operand:XF 2 "reg_or_0_operand" "fC"))]
1551 "* return output_fp_compare (insn, operands, false, false);"
1552 [(set_attr "type" "multi")
1553 (set_attr "unit" "i387")
1554 (set_attr "mode" "XF")])
1556 (define_insn "*cmp<mode>_i387"
1557 [(set (match_operand:HI 0 "register_operand" "=a")
1560 (match_operand:MODEF 1 "register_operand" "f")
1561 (match_operand:MODEF 2 "nonimm_or_0_operand" "fmC"))]
1564 "* return output_fp_compare (insn, operands, false, false);"
1565 [(set_attr "type" "multi")
1566 (set_attr "unit" "i387")
1567 (set_attr "mode" "<MODE>")])
1569 (define_insn "*cmp<X87MODEF:mode>_<SWI24:mode>_i387"
1570 [(set (match_operand:HI 0 "register_operand" "=a")
1573 (match_operand:X87MODEF 1 "register_operand" "f")
1575 (match_operand:SWI24 2 "nonimmediate_operand" "m")))]
1578 && (TARGET_USE_<SWI24:MODE>MODE_FIOP
1579 || optimize_function_for_size_p (cfun))"
1580 "* return output_fp_compare (insn, operands, false, false);"
1581 [(set_attr "type" "multi")
1582 (set_attr "unit" "i387")
1583 (set_attr "fp_int_src" "true")
1584 (set_attr "mode" "<SWI24:MODE>")])
1586 (define_insn "*cmpu<mode>_i387"
1587 [(set (match_operand:HI 0 "register_operand" "=a")
1591 (match_operand:X87MODEF 1 "register_operand" "f")
1592 (match_operand:X87MODEF 2 "register_operand" "f"))]
1596 "* return output_fp_compare (insn, operands, false, true);"
1597 [(set_attr "type" "multi")
1598 (set_attr "unit" "i387")
1599 (set_attr "mode" "<MODE>")])
1601 ;; FP compares, step 2:
1602 ;; Get ax into flags, general case.
1604 (define_insn "x86_sahf_1"
1605 [(set (reg:CC FLAGS_REG)
1606 (unspec:CC [(match_operand:HI 0 "register_operand" "a")]
1610 #ifndef HAVE_AS_IX86_SAHF
1612 return ASM_BYTE "0x9e";
1617 [(set_attr "length" "1")
1618 (set_attr "athlon_decode" "vector")
1619 (set_attr "amdfam10_decode" "direct")
1620 (set_attr "bdver1_decode" "direct")
1621 (set_attr "mode" "SI")])
1623 ;; Pentium Pro can do both steps in one go.
1624 ;; (these instructions set flags directly)
1626 (define_subst_attr "unord" "unord_subst" "" "u")
1627 (define_subst_attr "unordered" "unord_subst" "false" "true")
1629 (define_subst "unord_subst"
1630 [(set (match_operand:CCFP 0)
1631 (match_operand:CCFP 1))]
1638 (define_insn "*cmpi<unord>xf_i387"
1639 [(set (reg:CCFP FLAGS_REG)
1641 (match_operand:XF 0 "register_operand" "f")
1642 (match_operand:XF 1 "register_operand" "f")))]
1643 "TARGET_80387 && TARGET_CMOVE"
1644 "* return output_fp_compare (insn, operands, true, <unordered>);"
1645 [(set_attr "type" "fcmp")
1646 (set_attr "mode" "XF")
1647 (set_attr "athlon_decode" "vector")
1648 (set_attr "amdfam10_decode" "direct")
1649 (set_attr "bdver1_decode" "double")
1650 (set_attr "znver1_decode" "double")])
1652 (define_insn "*cmpi<unord><MODEF:mode>"
1653 [(set (reg:CCFP FLAGS_REG)
1655 (match_operand:MODEF 0 "register_operand" "f,v")
1656 (match_operand:MODEF 1 "register_ssemem_operand" "f,vm")))]
1657 "(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
1658 || (TARGET_80387 && TARGET_CMOVE)"
1660 * return output_fp_compare (insn, operands, true, <unordered>);
1661 %v<unord>comi<MODEF:ssemodesuffix>\t{%1, %0|%0, %1}"
1662 [(set_attr "type" "fcmp,ssecomi")
1663 (set_attr "prefix" "orig,maybe_vex")
1664 (set_attr "mode" "<MODEF:MODE>")
1665 (set_attr "prefix_rep" "*,0")
1666 (set (attr "prefix_data16")
1667 (cond [(eq_attr "alternative" "0")
1669 (eq_attr "mode" "DF")
1672 (const_string "0")))
1673 (set_attr "athlon_decode" "vector")
1674 (set_attr "amdfam10_decode" "direct")
1675 (set_attr "bdver1_decode" "double")
1676 (set_attr "znver1_decode" "double")
1677 (set (attr "enabled")
1679 (match_test ("SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"))
1681 (eq_attr "alternative" "0")
1682 (symbol_ref "TARGET_MIX_SSE_I387")
1683 (symbol_ref "true"))
1685 (eq_attr "alternative" "0")
1687 (symbol_ref "false"))))])
1689 ;; Push/pop instructions.
1691 (define_insn_and_split "*pushv1ti2"
1692 [(set (match_operand:V1TI 0 "push_operand" "=<")
1693 (match_operand:V1TI 1 "register_operand" "v"))]
1694 "TARGET_64BIT && TARGET_STV"
1696 "&& reload_completed"
1697 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
1698 (set (match_dup 0) (match_dup 1))]
1700 operands[2] = GEN_INT (-PUSH_ROUNDING (GET_MODE_SIZE (V1TImode)));
1701 /* Preserve memory attributes. */
1702 operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
1704 [(set_attr "type" "multi")
1705 (set_attr "mode" "TI")])
1707 (define_insn "*push<mode>2"
1708 [(set (match_operand:DWI 0 "push_operand" "=<,<")
1709 (match_operand:DWI 1 "general_no_elim_operand" "riF*o,*v"))]
1712 [(set_attr "type" "multi")
1713 (set_attr "mode" "<MODE>")])
1716 [(set (match_operand:DWI 0 "push_operand")
1717 (match_operand:DWI 1 "general_gr_operand"))]
1720 "ix86_split_long_move (operands); DONE;")
1722 (define_insn "*pushdi2_rex64"
1723 [(set (match_operand:DI 0 "push_operand" "=<,<,!<")
1724 (match_operand:DI 1 "general_no_elim_operand" "re*m,*v,n"))]
1730 [(set_attr "type" "push,multi,multi")
1731 (set_attr "mode" "DI")])
1733 ;; Convert impossible pushes of immediate to existing instructions.
1734 ;; First try to get scratch register and go through it. In case this
1735 ;; fails, push sign extended lower part first and then overwrite
1736 ;; upper part by 32bit move.
1739 [(match_scratch:DI 2 "r")
1740 (set (match_operand:DI 0 "push_operand")
1741 (match_operand:DI 1 "immediate_operand"))]
1743 && !symbolic_operand (operands[1], DImode)
1744 && !x86_64_immediate_operand (operands[1], DImode)"
1745 [(set (match_dup 2) (match_dup 1))
1746 (set (match_dup 0) (match_dup 2))])
1749 [(set (match_operand:DI 0 "push_operand")
1750 (match_operand:DI 1 "immediate_operand"))]
1751 "TARGET_64BIT && epilogue_completed
1752 && !symbolic_operand (operands[1], DImode)
1753 && !x86_64_immediate_operand (operands[1], DImode)"
1754 [(set (match_dup 0) (match_dup 1))
1755 (set (match_dup 2) (match_dup 3))]
1757 split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1759 operands[1] = gen_lowpart (DImode, operands[2]);
1760 operands[2] = gen_rtx_MEM (SImode,
1761 plus_constant (Pmode, stack_pointer_rtx, 4));
1764 ;; For TARGET_64BIT we always round up to 8 bytes.
1765 (define_insn "*pushsi2_rex64"
1766 [(set (match_operand:SI 0 "push_operand" "=X,X")
1767 (match_operand:SI 1 "nonmemory_no_elim_operand" "re,*v"))]
1772 [(set_attr "type" "push,multi")
1773 (set_attr "mode" "DI")])
1775 (define_insn "*pushsi2"
1776 [(set (match_operand:SI 0 "push_operand" "=<,<")
1777 (match_operand:SI 1 "general_no_elim_operand" "ri*m,*v"))]
1782 [(set_attr "type" "push,multi")
1783 (set_attr "mode" "SI")])
1786 [(set (match_operand:SWI48DWI 0 "push_operand")
1787 (match_operand:SWI48DWI 1 "sse_reg_operand"))]
1788 "TARGET_SSE && reload_completed"
1789 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
1790 (set (match_dup 0) (match_dup 1))]
1792 operands[2] = GEN_INT (-PUSH_ROUNDING (GET_MODE_SIZE (<SWI48DWI:MODE>mode)));
1793 /* Preserve memory attributes. */
1794 operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
1797 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1798 ;; "push a byte/word". But actually we use push{l,q}, which has
1799 ;; the effect of rounding the amount pushed up to a word.
1801 (define_insn "*push<mode>2"
1802 [(set (match_operand:SWI12 0 "push_operand" "=X")
1803 (match_operand:SWI12 1 "nonmemory_no_elim_operand" "rn"))]
1805 "* return TARGET_64BIT ? \"push{q}\t%q1\" : \"push{l}\t%k1\";"
1806 [(set_attr "type" "push")
1808 (if_then_else (match_test "TARGET_64BIT")
1810 (const_string "SI")))])
1812 (define_insn "*push<mode>2_prologue"
1813 [(set (match_operand:W 0 "push_operand" "=<")
1814 (match_operand:W 1 "general_no_elim_operand" "r<i>*m"))
1815 (clobber (mem:BLK (scratch)))]
1817 "push{<imodesuffix>}\t%1"
1818 [(set_attr "type" "push")
1819 (set_attr "mode" "<MODE>")])
1821 (define_insn "*pop<mode>1"
1822 [(set (match_operand:W 0 "nonimmediate_operand" "=r*m")
1823 (match_operand:W 1 "pop_operand" ">"))]
1825 "pop{<imodesuffix>}\t%0"
1826 [(set_attr "type" "pop")
1827 (set_attr "mode" "<MODE>")])
1829 (define_insn "*pop<mode>1_epilogue"
1830 [(set (match_operand:W 0 "nonimmediate_operand" "=r*m")
1831 (match_operand:W 1 "pop_operand" ">"))
1832 (clobber (mem:BLK (scratch)))]
1834 "pop{<imodesuffix>}\t%0"
1835 [(set_attr "type" "pop")
1836 (set_attr "mode" "<MODE>")])
1838 (define_insn "*pushfl<mode>2"
1839 [(set (match_operand:W 0 "push_operand" "=<")
1840 (match_operand:W 1 "flags_reg_operand"))]
1842 "pushf{<imodesuffix>}"
1843 [(set_attr "type" "push")
1844 (set_attr "mode" "<MODE>")])
1846 (define_insn "*popfl<mode>1"
1847 [(set (match_operand:W 0 "flags_reg_operand")
1848 (match_operand:W 1 "pop_operand" ">"))]
1850 "popf{<imodesuffix>}"
1851 [(set_attr "type" "pop")
1852 (set_attr "mode" "<MODE>")])
1855 ;; Reload patterns to support multi-word load/store
1856 ;; with non-offsetable address.
1857 (define_expand "reload_noff_store"
1858 [(parallel [(match_operand 0 "memory_operand" "=m")
1859 (match_operand 1 "register_operand" "r")
1860 (match_operand:DI 2 "register_operand" "=&r")])]
1863 rtx mem = operands[0];
1864 rtx addr = XEXP (mem, 0);
1866 emit_move_insn (operands[2], addr);
1867 mem = replace_equiv_address_nv (mem, operands[2]);
1869 emit_insn (gen_rtx_SET (mem, operands[1]));
1873 (define_expand "reload_noff_load"
1874 [(parallel [(match_operand 0 "register_operand" "=r")
1875 (match_operand 1 "memory_operand" "m")
1876 (match_operand:DI 2 "register_operand" "=r")])]
1879 rtx mem = operands[1];
1880 rtx addr = XEXP (mem, 0);
1882 emit_move_insn (operands[2], addr);
1883 mem = replace_equiv_address_nv (mem, operands[2]);
1885 emit_insn (gen_rtx_SET (operands[0], mem));
1889 ;; Move instructions.
1891 (define_expand "movxi"
1892 [(set (match_operand:XI 0 "nonimmediate_operand")
1893 (match_operand:XI 1 "general_operand"))]
1895 "ix86_expand_vector_move (XImode, operands); DONE;")
1897 (define_expand "movoi"
1898 [(set (match_operand:OI 0 "nonimmediate_operand")
1899 (match_operand:OI 1 "general_operand"))]
1901 "ix86_expand_vector_move (OImode, operands); DONE;")
1903 (define_expand "movti"
1904 [(set (match_operand:TI 0 "nonimmediate_operand")
1905 (match_operand:TI 1 "general_operand"))]
1906 "TARGET_64BIT || TARGET_SSE"
1909 ix86_expand_move (TImode, operands);
1911 ix86_expand_vector_move (TImode, operands);
1915 ;; This expands to what emit_move_complex would generate if we didn't
1916 ;; have a movti pattern. Having this avoids problems with reload on
1917 ;; 32-bit targets when SSE is present, but doesn't seem to be harmful
1918 ;; to have around all the time.
1919 (define_expand "movcdi"
1920 [(set (match_operand:CDI 0 "nonimmediate_operand")
1921 (match_operand:CDI 1 "general_operand"))]
1924 if (push_operand (operands[0], CDImode))
1925 emit_move_complex_push (CDImode, operands[0], operands[1]);
1927 emit_move_complex_parts (operands[0], operands[1]);
1931 (define_expand "mov<mode>"
1932 [(set (match_operand:SWI1248x 0 "nonimmediate_operand")
1933 (match_operand:SWI1248x 1 "general_operand"))]
1935 "ix86_expand_move (<MODE>mode, operands); DONE;")
1937 (define_insn "*mov<mode>_xor"
1938 [(set (match_operand:SWI48 0 "register_operand" "=r")
1939 (match_operand:SWI48 1 "const0_operand"))
1940 (clobber (reg:CC FLAGS_REG))]
1943 [(set_attr "type" "alu1")
1944 (set_attr "mode" "SI")
1945 (set_attr "length_immediate" "0")])
1947 (define_insn "*mov<mode>_or"
1948 [(set (match_operand:SWI48 0 "register_operand" "=r")
1949 (match_operand:SWI48 1 "constm1_operand"))
1950 (clobber (reg:CC FLAGS_REG))]
1952 "or{<imodesuffix>}\t{%1, %0|%0, %1}"
1953 [(set_attr "type" "alu1")
1954 (set_attr "mode" "<MODE>")
1955 (set_attr "length_immediate" "1")])
1957 (define_insn "*movxi_internal_avx512f"
1958 [(set (match_operand:XI 0 "nonimmediate_operand" "=v,v ,v ,m")
1959 (match_operand:XI 1 "nonimmediate_or_sse_const_operand" " C,BC,vm,v"))]
1961 && (register_operand (operands[0], XImode)
1962 || register_operand (operands[1], XImode))"
1964 switch (get_attr_type (insn))
1967 return standard_sse_constant_opcode (insn, operands);
1970 return ix86_output_ssemov (insn, operands);
1976 [(set_attr "type" "sselog1,sselog1,ssemov,ssemov")
1977 (set_attr "prefix" "evex")
1978 (set_attr "mode" "XI")])
1980 (define_insn "*movoi_internal_avx"
1981 [(set (match_operand:OI 0 "nonimmediate_operand" "=v,v ,v ,m")
1982 (match_operand:OI 1 "nonimmediate_or_sse_const_operand" " C,BC,vm,v"))]
1984 && (register_operand (operands[0], OImode)
1985 || register_operand (operands[1], OImode))"
1987 switch (get_attr_type (insn))
1990 return standard_sse_constant_opcode (insn, operands);
1993 return ix86_output_ssemov (insn, operands);
1999 [(set_attr "isa" "*,avx2,*,*")
2000 (set_attr "type" "sselog1,sselog1,ssemov,ssemov")
2001 (set_attr "prefix" "vex")
2002 (set_attr "mode" "OI")])
2004 (define_insn "*movti_internal"
2005 [(set (match_operand:TI 0 "nonimmediate_operand" "=!r ,o ,v,v ,v ,m,?r,?Yd")
2006 (match_operand:TI 1 "general_operand" "riFo,re,C,BC,vm,v,Yd,r"))]
2008 && !(MEM_P (operands[0]) && MEM_P (operands[1])))
2010 && nonimmediate_or_sse_const_operand (operands[1], TImode)
2011 && (register_operand (operands[0], TImode)
2012 || register_operand (operands[1], TImode)))"
2014 switch (get_attr_type (insn))
2020 return standard_sse_constant_opcode (insn, operands);
2023 return ix86_output_ssemov (insn, operands);
2030 (cond [(eq_attr "alternative" "0,1,6,7")
2031 (const_string "x64")
2032 (eq_attr "alternative" "3")
2033 (const_string "sse2")
2035 (const_string "*")))
2037 (cond [(eq_attr "alternative" "0,1,6,7")
2038 (const_string "multi")
2039 (eq_attr "alternative" "2,3")
2040 (const_string "sselog1")
2042 (const_string "ssemov")))
2043 (set (attr "prefix")
2044 (if_then_else (eq_attr "type" "sselog1,ssemov")
2045 (const_string "maybe_vex")
2046 (const_string "orig")))
2048 (cond [(eq_attr "alternative" "0,1")
2050 (match_test "TARGET_AVX")
2052 (ior (not (match_test "TARGET_SSE2"))
2053 (match_test "optimize_function_for_size_p (cfun)"))
2054 (const_string "V4SF")
2055 (and (eq_attr "alternative" "5")
2056 (match_test "TARGET_SSE_TYPELESS_STORES"))
2057 (const_string "V4SF")
2059 (const_string "TI")))
2060 (set (attr "preferred_for_speed")
2061 (cond [(eq_attr "alternative" "6")
2062 (symbol_ref "TARGET_INTER_UNIT_MOVES_FROM_VEC")
2063 (eq_attr "alternative" "7")
2064 (symbol_ref "TARGET_INTER_UNIT_MOVES_TO_VEC")
2066 (symbol_ref "true")))])
2069 [(set (match_operand:TI 0 "sse_reg_operand")
2070 (match_operand:TI 1 "general_reg_operand"))]
2071 "TARGET_64BIT && TARGET_SSE4_1
2072 && reload_completed"
2075 (vec_duplicate:V2DI (match_dup 3))
2079 operands[2] = lowpart_subreg (V2DImode, operands[0], TImode);
2080 operands[3] = gen_highpart (DImode, operands[1]);
2082 emit_move_insn (gen_lowpart (DImode, operands[0]),
2083 gen_lowpart (DImode, operands[1]));
2086 (define_insn "*movdi_internal"
2087 [(set (match_operand:DI 0 "nonimmediate_operand"
2088 "=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")
2089 (match_operand:DI 1 "general_operand"
2090 "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"))]
2091 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2092 && ix86_hardreg_mov_ok (operands[0], operands[1])"
2094 switch (get_attr_type (insn))
2097 return "kmovq\t{%1, %0|%0, %1}";
2100 if (operands[1] == const0_rtx)
2101 return "kxorq\t%0, %0, %0";
2102 else if (operands[1] == constm1_rtx)
2103 return "kxnorq\t%0, %0, %0";
2110 return "pxor\t%0, %0";
2113 /* Handle broken assemblers that require movd instead of movq. */
2114 if (!HAVE_AS_IX86_INTERUNIT_MOVQ
2115 && (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1])))
2116 return "movd\t{%1, %0|%0, %1}";
2117 return "movq\t{%1, %0|%0, %1}";
2120 return standard_sse_constant_opcode (insn, operands);
2123 return ix86_output_ssemov (insn, operands);
2126 if (SSE_REG_P (operands[0]))
2127 return "movq2dq\t{%1, %0|%0, %1}";
2129 return "movdq2q\t{%1, %0|%0, %1}";
2132 return "lea{q}\t{%E1, %0|%0, %E1}";
2135 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2136 if (get_attr_mode (insn) == MODE_SI)
2137 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2138 else if (which_alternative == 4)
2139 return "movabs{q}\t{%1, %0|%0, %1}";
2140 else if (ix86_use_lea_for_mov (insn, operands))
2141 return "lea{q}\t{%E1, %0|%0, %E1}";
2143 return "mov{q}\t{%1, %0|%0, %1}";
2150 (cond [(eq_attr "alternative" "0,1,17,18")
2151 (const_string "nox64")
2152 (eq_attr "alternative" "2,3,4,5,10,11,23,25")
2153 (const_string "x64")
2154 (eq_attr "alternative" "19,20")
2155 (const_string "x64_sse2")
2156 (eq_attr "alternative" "21,22")
2157 (const_string "sse2")
2159 (const_string "*")))
2161 (cond [(eq_attr "alternative" "0,1,17,18")
2162 (const_string "multi")
2163 (eq_attr "alternative" "6")
2164 (const_string "mmx")
2165 (eq_attr "alternative" "7,8,9,10,11")
2166 (const_string "mmxmov")
2167 (eq_attr "alternative" "12")
2168 (const_string "sselog1")
2169 (eq_attr "alternative" "13,14,15,16,19,20")
2170 (const_string "ssemov")
2171 (eq_attr "alternative" "21,22")
2172 (const_string "ssecvt")
2173 (eq_attr "alternative" "23,24,25,26")
2174 (const_string "mskmov")
2175 (eq_attr "alternative" "27")
2176 (const_string "msklog")
2177 (and (match_operand 0 "register_operand")
2178 (match_operand 1 "pic_32bit_operand"))
2179 (const_string "lea")
2181 (const_string "imov")))
2184 (and (eq_attr "alternative" "4") (eq_attr "type" "imov"))
2186 (const_string "*")))
2187 (set (attr "length_immediate")
2189 (and (eq_attr "alternative" "4") (eq_attr "type" "imov"))
2191 (const_string "*")))
2192 (set (attr "prefix_rex")
2194 (eq_attr "alternative" "10,11,19,20")
2196 (const_string "*")))
2197 (set (attr "prefix")
2198 (if_then_else (eq_attr "type" "sselog1,ssemov")
2199 (const_string "maybe_vex")
2200 (const_string "orig")))
2201 (set (attr "prefix_data16")
2202 (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "DI"))
2204 (const_string "*")))
2206 (cond [(eq_attr "alternative" "2")
2208 (eq_attr "alternative" "12,13")
2209 (cond [(match_test "TARGET_AVX")
2211 (ior (not (match_test "TARGET_SSE2"))
2212 (match_test "optimize_function_for_size_p (cfun)"))
2213 (const_string "V4SF")
2215 (const_string "TI"))
2217 (and (eq_attr "alternative" "14,15,16")
2218 (not (match_test "TARGET_SSE2")))
2219 (const_string "V2SF")
2221 (const_string "DI")))
2222 (set (attr "preferred_for_speed")
2223 (cond [(eq_attr "alternative" "10,17,19")
2224 (symbol_ref "TARGET_INTER_UNIT_MOVES_FROM_VEC")
2225 (eq_attr "alternative" "11,18,20")
2226 (symbol_ref "TARGET_INTER_UNIT_MOVES_TO_VEC")
2228 (symbol_ref "true")))
2229 (set (attr "enabled")
2230 (cond [(eq_attr "alternative" "15")
2232 (match_test "TARGET_STV && TARGET_SSE2")
2233 (symbol_ref "false")
2235 (eq_attr "alternative" "16")
2237 (match_test "TARGET_STV && TARGET_SSE2")
2239 (symbol_ref "false"))
2241 (const_string "*")))])
2244 [(set (match_operand:<DWI> 0 "general_reg_operand")
2245 (match_operand:<DWI> 1 "sse_reg_operand"))]
2247 && reload_completed"
2251 (parallel [(const_int 1)])))]
2253 operands[2] = gen_highpart (<MODE>mode, operands[0]);
2254 operands[3] = lowpart_subreg (<ssevecmode>mode, operands[1], <DWI>mode);
2256 emit_move_insn (gen_lowpart (<MODE>mode, operands[0]),
2257 gen_lowpart (<MODE>mode, operands[1]));
2261 [(set (match_operand:DWI 0 "nonimmediate_gr_operand")
2262 (match_operand:DWI 1 "general_gr_operand"))]
2265 "ix86_split_long_move (operands); DONE;")
2268 [(set (match_operand:DI 0 "sse_reg_operand")
2269 (match_operand:DI 1 "general_reg_operand"))]
2270 "!TARGET_64BIT && TARGET_SSE4_1
2271 && reload_completed"
2274 (vec_duplicate:V4SI (match_dup 3))
2278 operands[2] = lowpart_subreg (V4SImode, operands[0], DImode);
2279 operands[3] = gen_highpart (SImode, operands[1]);
2281 emit_move_insn (gen_lowpart (SImode, operands[0]),
2282 gen_lowpart (SImode, operands[1]));
2285 ;; movabsq $0x0012345678000000, %rax is longer
2286 ;; than movl $0x12345678, %eax; shlq $24, %rax.
2288 [(set (match_operand:DI 0 "register_operand")
2289 (match_operand:DI 1 "const_int_operand"))]
2291 && optimize_insn_for_size_p ()
2292 && LEGACY_INT_REG_P (operands[0])
2293 && !x86_64_immediate_operand (operands[1], DImode)
2294 && !x86_64_zext_immediate_operand (operands[1], DImode)
2295 && !((UINTVAL (operands[1]) >> ctz_hwi (UINTVAL (operands[1])))
2296 & ~(HOST_WIDE_INT) 0xffffffff)
2297 && peep2_regno_dead_p (0, FLAGS_REG)"
2298 [(set (match_dup 0) (match_dup 1))
2299 (parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
2300 (clobber (reg:CC FLAGS_REG))])]
2302 int shift = ctz_hwi (UINTVAL (operands[1]));
2303 operands[1] = gen_int_mode (UINTVAL (operands[1]) >> shift, DImode);
2304 operands[2] = gen_int_mode (shift, QImode);
2307 (define_insn "*movsi_internal"
2308 [(set (match_operand:SI 0 "nonimmediate_operand"
2309 "=r,m ,*y,*y,?*y,?m,?r,?*y,*v,*v,*v,m ,?r,?*v,*k,*k ,*rm,*k")
2310 (match_operand:SI 1 "general_operand"
2311 "g ,re,C ,*y,m ,*y,*y,r ,C ,*v,m ,*v,*v,r ,*r,*km,*k ,CBC"))]
2312 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2313 && ix86_hardreg_mov_ok (operands[0], operands[1])"
2315 switch (get_attr_type (insn))
2318 return standard_sse_constant_opcode (insn, operands);
2321 return "kmovd\t{%1, %0|%0, %1}";
2324 if (operands[1] == const0_rtx)
2325 return "kxord\t%0, %0, %0";
2326 else if (operands[1] == constm1_rtx)
2327 return "kxnord\t%0, %0, %0";
2331 return ix86_output_ssemov (insn, operands);
2334 return "pxor\t%0, %0";
2337 switch (get_attr_mode (insn))
2340 return "movq\t{%1, %0|%0, %1}";
2342 return "movd\t{%1, %0|%0, %1}";
2349 return "lea{l}\t{%E1, %0|%0, %E1}";
2352 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2353 if (ix86_use_lea_for_mov (insn, operands))
2354 return "lea{l}\t{%E1, %0|%0, %E1}";
2356 return "mov{l}\t{%1, %0|%0, %1}";
2363 (cond [(eq_attr "alternative" "12,13")
2364 (const_string "sse2")
2366 (const_string "*")))
2368 (cond [(eq_attr "alternative" "2")
2369 (const_string "mmx")
2370 (eq_attr "alternative" "3,4,5,6,7")
2371 (const_string "mmxmov")
2372 (eq_attr "alternative" "8")
2373 (const_string "sselog1")
2374 (eq_attr "alternative" "9,10,11,12,13")
2375 (const_string "ssemov")
2376 (eq_attr "alternative" "14,15,16")
2377 (const_string "mskmov")
2378 (eq_attr "alternative" "17")
2379 (const_string "msklog")
2380 (and (match_operand 0 "register_operand")
2381 (match_operand 1 "pic_32bit_operand"))
2382 (const_string "lea")
2384 (const_string "imov")))
2385 (set (attr "prefix")
2386 (if_then_else (eq_attr "type" "sselog1,ssemov")
2387 (const_string "maybe_vex")
2388 (const_string "orig")))
2389 (set (attr "prefix_data16")
2390 (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
2392 (const_string "*")))
2394 (cond [(eq_attr "alternative" "2,3")
2396 (eq_attr "alternative" "8,9")
2397 (cond [(match_test "TARGET_AVX")
2399 (ior (not (match_test "TARGET_SSE2"))
2400 (match_test "optimize_function_for_size_p (cfun)"))
2401 (const_string "V4SF")
2403 (const_string "TI"))
2405 (and (eq_attr "alternative" "10,11")
2406 (not (match_test "TARGET_SSE2")))
2409 (const_string "SI")))
2410 (set (attr "preferred_for_speed")
2411 (cond [(eq_attr "alternative" "6,12")
2412 (symbol_ref "TARGET_INTER_UNIT_MOVES_FROM_VEC")
2413 (eq_attr "alternative" "7,13")
2414 (symbol_ref "TARGET_INTER_UNIT_MOVES_TO_VEC")
2416 (symbol_ref "true")))])
2418 (define_insn "*movhi_internal"
2419 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r ,r ,m ,*k,*k ,*r,*m,*k")
2420 (match_operand:HI 1 "general_operand" "r ,rn,rm,rn,*r,*km,*k,*k,CBC"))]
2421 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2422 && ix86_hardreg_mov_ok (operands[0], operands[1])"
2425 switch (get_attr_type (insn))
2428 /* movzwl is faster than movw on p2 due to partial word stalls,
2429 though not as fast as an aligned movl. */
2430 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
2433 switch (which_alternative)
2436 return "kmovw\t{%k1, %0|%0, %k1}";
2438 return "kmovw\t{%1, %k0|%k0, %1}";
2441 return "kmovw\t{%1, %0|%0, %1}";
2447 if (operands[1] == const0_rtx)
2448 return "kxorw\t%0, %0, %0";
2449 else if (operands[1] == constm1_rtx)
2450 return "kxnorw\t%0, %0, %0";
2454 if (get_attr_mode (insn) == MODE_SI)
2455 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2457 return "mov{w}\t{%1, %0|%0, %1}";
2461 (cond [(eq_attr "alternative" "4,5,6,7")
2462 (const_string "mskmov")
2463 (eq_attr "alternative" "8")
2464 (const_string "msklog")
2465 (match_test "optimize_function_for_size_p (cfun)")
2466 (const_string "imov")
2467 (and (eq_attr "alternative" "0")
2468 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2469 (not (match_test "TARGET_HIMODE_MATH"))))
2470 (const_string "imov")
2471 (and (eq_attr "alternative" "1,2")
2472 (match_operand:HI 1 "aligned_operand"))
2473 (const_string "imov")
2474 (and (match_test "TARGET_MOVX")
2475 (eq_attr "alternative" "0,2"))
2476 (const_string "imovx")
2478 (const_string "imov")))
2479 (set (attr "prefix")
2480 (if_then_else (eq_attr "alternative" "4,5,6,7,8")
2481 (const_string "vex")
2482 (const_string "orig")))
2484 (cond [(eq_attr "type" "imovx")
2486 (and (eq_attr "alternative" "1,2")
2487 (match_operand:HI 1 "aligned_operand"))
2489 (and (eq_attr "alternative" "0")
2490 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2491 (not (match_test "TARGET_HIMODE_MATH"))))
2494 (const_string "HI")))])
2496 ;; Situation is quite tricky about when to choose full sized (SImode) move
2497 ;; over QImode moves. For Q_REG -> Q_REG move we use full size only for
2498 ;; partial register dependency machines (such as AMD Athlon), where QImode
2499 ;; moves issue extra dependency and for partial register stalls machines
2500 ;; that don't use QImode patterns (and QImode move cause stall on the next
2503 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
2504 ;; register stall machines with, where we use QImode instructions, since
2505 ;; partial register stall can be caused there. Then we use movzx.
2507 (define_insn "*movqi_internal"
2508 [(set (match_operand:QI 0 "nonimmediate_operand"
2509 "=Q,R,r,q,q,r,r ,?r,m ,*k,*k,*r,*m,*k,*k,*k")
2510 (match_operand:QI 1 "general_operand"
2511 "Q ,R,r,n,m,q,rn, m,qn,*r,*k,*k,*k,*m,C,BC"))]
2512 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2513 && ix86_hardreg_mov_ok (operands[0], operands[1])"
2520 switch (get_attr_type (insn))
2523 gcc_assert (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]));
2524 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
2527 switch (which_alternative)
2530 ops = "kmov%s\t{%%k1, %%0|%%0, %%k1}";
2533 ops = "kmov%s\t{%%1, %%k0|%%k0, %%1}";
2537 gcc_assert (TARGET_AVX512DQ);
2540 ops = "kmov%s\t{%%1, %%0|%%0, %%1}";
2546 suffix = (get_attr_mode (insn) == MODE_HI) ? "w" : "b";
2548 snprintf (buf, sizeof (buf), ops, suffix);
2549 output_asm_insn (buf, operands);
2553 if (operands[1] == const0_rtx)
2555 if (get_attr_mode (insn) == MODE_HI)
2556 return "kxorw\t%0, %0, %0";
2558 return "kxorb\t%0, %0, %0";
2560 else if (operands[1] == constm1_rtx)
2562 gcc_assert (TARGET_AVX512DQ);
2563 return "kxnorb\t%0, %0, %0";
2568 if (get_attr_mode (insn) == MODE_SI)
2569 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2571 return "mov{b}\t{%1, %0|%0, %1}";
2575 (cond [(eq_attr "alternative" "1,2")
2576 (const_string "x64")
2577 (eq_attr "alternative" "12,13,15")
2578 (const_string "avx512dq")
2580 (const_string "*")))
2582 (cond [(eq_attr "alternative" "9,10,11,12,13")
2583 (const_string "mskmov")
2584 (eq_attr "alternative" "14,15")
2585 (const_string "msklog")
2586 (and (eq_attr "alternative" "7")
2587 (not (match_operand:QI 1 "aligned_operand")))
2588 (const_string "imovx")
2589 (match_test "optimize_function_for_size_p (cfun)")
2590 (const_string "imov")
2591 (and (eq_attr "alternative" "5")
2592 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2593 (not (match_test "TARGET_QIMODE_MATH"))))
2594 (const_string "imov")
2595 (eq_attr "alternative" "5,7")
2596 (const_string "imovx")
2597 (and (match_test "TARGET_MOVX")
2598 (eq_attr "alternative" "4"))
2599 (const_string "imovx")
2601 (const_string "imov")))
2602 (set (attr "prefix")
2603 (if_then_else (eq_attr "alternative" "9,10,11,12,13,14,15")
2604 (const_string "vex")
2605 (const_string "orig")))
2607 (cond [(eq_attr "alternative" "5,6,7")
2609 (eq_attr "alternative" "8")
2611 (and (eq_attr "alternative" "9,10,11,14")
2612 (not (match_test "TARGET_AVX512DQ")))
2614 (eq_attr "type" "imovx")
2616 ;; For -Os, 8-bit immediates are always shorter than 32-bit
2618 (and (eq_attr "type" "imov")
2619 (and (eq_attr "alternative" "3")
2620 (match_test "optimize_function_for_size_p (cfun)")))
2622 ;; For -Os, movl where one or both operands are NON_Q_REGS
2623 ;; and both are LEGACY_REGS is shorter than movb.
2624 ;; Otherwise movb and movl sizes are the same, so decide purely
2625 ;; based on speed factors.
2626 (and (eq_attr "type" "imov")
2627 (and (eq_attr "alternative" "1")
2628 (match_test "optimize_function_for_size_p (cfun)")))
2630 (and (eq_attr "type" "imov")
2631 (and (eq_attr "alternative" "0,1,2,3")
2632 (and (match_test "TARGET_PARTIAL_REG_DEPENDENCY")
2633 (not (match_test "TARGET_PARTIAL_REG_STALL")))))
2635 ;; Avoid partial register stalls when not using QImode arithmetic
2636 (and (eq_attr "type" "imov")
2637 (and (eq_attr "alternative" "0,1,2,3")
2638 (and (match_test "TARGET_PARTIAL_REG_STALL")
2639 (not (match_test "TARGET_QIMODE_MATH")))))
2642 (const_string "QI")))])
2644 /* Reload dislikes loading 0/-1 directly into mask registers.
2645 Try to tidy things up here. */
2647 [(set (match_operand:SWI 0 "general_reg_operand")
2648 (match_operand:SWI 1 "immediate_operand"))
2649 (set (match_operand:SWI 2 "mask_reg_operand")
2651 "peep2_reg_dead_p (2, operands[0])
2652 && (const0_operand (operands[1], <MODE>mode)
2653 || (constm1_operand (operands[1], <MODE>mode)
2654 && (<MODE_SIZE> > 1 || TARGET_AVX512DQ)))"
2655 [(set (match_dup 2) (match_dup 1))])
2657 ;; Stores and loads of ax to arbitrary constant address.
2658 ;; We fake an second form of instruction to force reload to load address
2659 ;; into register when rax is not available
2660 (define_insn "*movabs<mode>_1"
2661 [(set (mem:SWI1248x (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2662 (match_operand:SWI1248x 1 "nonmemory_operand" "a,r<i>"))]
2663 "TARGET_LP64 && ix86_check_movabs (insn, 0)"
2665 /* Recover the full memory rtx. */
2666 operands[0] = SET_DEST (PATTERN (insn));
2667 switch (which_alternative)
2670 return "movabs{<imodesuffix>}\t{%1, %P0|<iptrsize> PTR [%P0], %1}";
2672 return "mov{<imodesuffix>}\t{%1, %0|%0, %1}";
2677 [(set_attr "type" "imov")
2678 (set_attr "modrm" "0,*")
2679 (set_attr "length_address" "8,0")
2680 (set_attr "length_immediate" "0,*")
2681 (set_attr "memory" "store")
2682 (set_attr "mode" "<MODE>")])
2684 (define_insn "*movabs<mode>_2"
2685 [(set (match_operand:SWI1248x 0 "register_operand" "=a,r")
2686 (mem:SWI1248x (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2687 "TARGET_LP64 && ix86_check_movabs (insn, 1)"
2689 /* Recover the full memory rtx. */
2690 operands[1] = SET_SRC (PATTERN (insn));
2691 switch (which_alternative)
2694 return "movabs{<imodesuffix>}\t{%P1, %0|%0, <iptrsize> PTR [%P1]}";
2696 return "mov{<imodesuffix>}\t{%1, %0|%0, %1}";
2701 [(set_attr "type" "imov")
2702 (set_attr "modrm" "0,*")
2703 (set_attr "length_address" "8,0")
2704 (set_attr "length_immediate" "0")
2705 (set_attr "memory" "load")
2706 (set_attr "mode" "<MODE>")])
2708 (define_insn "*swap<mode>"
2709 [(set (match_operand:SWI48 0 "register_operand" "+r")
2710 (match_operand:SWI48 1 "register_operand" "+r"))
2714 "xchg{<imodesuffix>}\t%1, %0"
2715 [(set_attr "type" "imov")
2716 (set_attr "mode" "<MODE>")
2717 (set_attr "pent_pair" "np")
2718 (set_attr "athlon_decode" "vector")
2719 (set_attr "amdfam10_decode" "double")
2720 (set_attr "bdver1_decode" "double")])
2722 (define_insn "*swap<mode>"
2723 [(set (match_operand:SWI12 0 "register_operand" "+<r>,r")
2724 (match_operand:SWI12 1 "register_operand" "+<r>,r"))
2729 xchg{<imodesuffix>}\t%1, %0
2731 [(set_attr "type" "imov")
2732 (set_attr "mode" "<MODE>,SI")
2733 (set (attr "preferred_for_size")
2734 (cond [(eq_attr "alternative" "0")
2735 (symbol_ref "false")]
2736 (symbol_ref "true")))
2737 ;; Potential partial reg stall on alternative 1.
2738 (set (attr "preferred_for_speed")
2739 (cond [(eq_attr "alternative" "1")
2740 (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
2741 (symbol_ref "true")))
2742 (set_attr "pent_pair" "np")
2743 (set_attr "athlon_decode" "vector")
2744 (set_attr "amdfam10_decode" "double")
2745 (set_attr "bdver1_decode" "double")])
2748 [(set (match_operand:SWI 0 "general_reg_operand")
2749 (match_operand:SWI 1 "general_reg_operand"))
2751 (match_operand:SWI 2 "general_reg_operand"))
2752 (set (match_dup 2) (match_dup 0))]
2753 "peep2_reg_dead_p (3, operands[0])
2754 && optimize_insn_for_size_p ()"
2755 [(parallel [(set (match_dup 1) (match_dup 2))
2756 (set (match_dup 2) (match_dup 1))])])
2758 (define_expand "movstrict<mode>"
2759 [(set (strict_low_part (match_operand:SWI12 0 "register_operand"))
2760 (match_operand:SWI12 1 "general_operand"))]
2763 gcc_assert (SUBREG_P (operands[0]));
2764 if ((TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun))
2765 || !VALID_INT_MODE_P (GET_MODE (SUBREG_REG (operands[0]))))
2769 (define_insn "*movstrict<mode>_1"
2770 [(set (strict_low_part
2771 (match_operand:SWI12 0 "register_operand" "+<r>"))
2772 (match_operand:SWI12 1 "general_operand" "<r>mn"))]
2773 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
2774 "mov{<imodesuffix>}\t{%1, %0|%0, %1}"
2775 [(set_attr "type" "imov")
2776 (set_attr "mode" "<MODE>")])
2778 (define_insn "*movstrict<mode>_xor"
2779 [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>"))
2780 (match_operand:SWI12 1 "const0_operand"))
2781 (clobber (reg:CC FLAGS_REG))]
2783 "xor{<imodesuffix>}\t%0, %0"
2784 [(set_attr "type" "alu1")
2785 (set_attr "mode" "<MODE>")
2786 (set_attr "length_immediate" "0")])
2788 (define_expand "extv<mode>"
2789 [(set (match_operand:SWI24 0 "register_operand")
2790 (sign_extract:SWI24 (match_operand:SWI24 1 "register_operand")
2791 (match_operand:SI 2 "const_int_operand")
2792 (match_operand:SI 3 "const_int_operand")))]
2795 /* Handle extractions from %ah et al. */
2796 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
2799 unsigned int regno = reg_or_subregno (operands[1]);
2801 /* Be careful to expand only with registers having upper parts. */
2802 if (regno <= LAST_VIRTUAL_REGISTER && !QI_REGNO_P (regno))
2803 operands[1] = copy_to_reg (operands[1]);
2806 (define_insn "*extv<mode>"
2807 [(set (match_operand:SWI24 0 "register_operand" "=R")
2808 (sign_extract:SWI24 (match_operand:SWI24 1 "register_operand" "Q")
2812 "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
2813 [(set_attr "type" "imovx")
2814 (set_attr "mode" "SI")])
2816 (define_expand "extzv<mode>"
2817 [(set (match_operand:SWI248 0 "register_operand")
2818 (zero_extract:SWI248 (match_operand:SWI248 1 "register_operand")
2819 (match_operand:SI 2 "const_int_operand")
2820 (match_operand:SI 3 "const_int_operand")))]
2823 if (ix86_expand_pextr (operands))
2826 /* Handle extractions from %ah et al. */
2827 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
2830 unsigned int regno = reg_or_subregno (operands[1]);
2832 /* Be careful to expand only with registers having upper parts. */
2833 if (regno <= LAST_VIRTUAL_REGISTER && !QI_REGNO_P (regno))
2834 operands[1] = copy_to_reg (operands[1]);
2837 (define_insn "*extzvqi_mem_rex64"
2838 [(set (match_operand:QI 0 "norex_memory_operand" "=Bn")
2840 (zero_extract:SWI248
2841 (match_operand:SWI248 1 "register_operand" "Q")
2844 "TARGET_64BIT && reload_completed"
2845 "mov{b}\t{%h1, %0|%0, %h1}"
2846 [(set_attr "type" "imov")
2847 (set_attr "mode" "QI")])
2849 (define_insn "*extzv<mode>"
2850 [(set (match_operand:SWI248 0 "register_operand" "=R")
2851 (zero_extract:SWI248 (match_operand:SWI248 1 "register_operand" "Q")
2855 "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
2856 [(set_attr "type" "imovx")
2857 (set_attr "mode" "SI")])
2859 (define_insn "*extzvqi"
2860 [(set (match_operand:QI 0 "nonimmediate_operand" "=QBc,?R,m")
2862 (zero_extract:SWI248
2863 (match_operand:SWI248 1 "register_operand" "Q,Q,Q")
2868 switch (get_attr_type (insn))
2871 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2873 return "mov{b}\t{%h1, %0|%0, %h1}";
2876 [(set_attr "isa" "*,*,nox64")
2878 (if_then_else (and (match_operand:QI 0 "register_operand")
2879 (ior (not (match_operand:QI 0 "QIreg_operand"))
2880 (match_test "TARGET_MOVX")))
2881 (const_string "imovx")
2882 (const_string "imov")))
2884 (if_then_else (eq_attr "type" "imovx")
2886 (const_string "QI")))])
2889 [(set (match_operand:QI 0 "register_operand")
2891 (zero_extract:SWI248 (match_operand:SWI248 1 "register_operand")
2894 (set (match_operand:QI 2 "norex_memory_operand") (match_dup 0))]
2896 && peep2_reg_dead_p (2, operands[0])"
2899 (zero_extract:SWI248 (match_dup 1)
2901 (const_int 8)) 0))])
2903 (define_expand "insv<mode>"
2904 [(set (zero_extract:SWI248 (match_operand:SWI248 0 "register_operand")
2905 (match_operand:SI 1 "const_int_operand")
2906 (match_operand:SI 2 "const_int_operand"))
2907 (match_operand:SWI248 3 "register_operand"))]
2912 if (ix86_expand_pinsr (operands))
2915 /* Handle insertions to %ah et al. */
2916 if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
2919 unsigned int regno = reg_or_subregno (operands[0]);
2921 /* Be careful to expand only with registers having upper parts. */
2922 if (regno <= LAST_VIRTUAL_REGISTER && !QI_REGNO_P (regno))
2923 dst = copy_to_reg (operands[0]);
2927 emit_insn (gen_insv_1 (<MODE>mode, dst, operands[3]));
2929 /* Fix up the destination if needed. */
2930 if (dst != operands[0])
2931 emit_move_insn (operands[0], dst);
2936 (define_insn "*insvqi_1_mem_rex64"
2937 [(set (zero_extract:SWI248
2938 (match_operand:SWI248 0 "register_operand" "+Q")
2942 (match_operand:QI 1 "norex_memory_operand" "Bn") 0))]
2943 "TARGET_64BIT && reload_completed"
2944 "mov{b}\t{%1, %h0|%h0, %1}"
2945 [(set_attr "type" "imov")
2946 (set_attr "mode" "QI")])
2948 (define_insn "@insv<mode>_1"
2949 [(set (zero_extract:SWI248
2950 (match_operand:SWI248 0 "register_operand" "+Q,Q")
2953 (match_operand:SWI248 1 "general_operand" "QnBc,m"))]
2956 if (CONST_INT_P (operands[1]))
2957 operands[1] = gen_int_mode (INTVAL (operands[1]), QImode);
2958 return "mov{b}\t{%b1, %h0|%h0, %b1}";
2960 [(set_attr "isa" "*,nox64")
2961 (set_attr "type" "imov")
2962 (set_attr "mode" "QI")])
2964 (define_insn "*insvqi_1"
2965 [(set (zero_extract:SWI248
2966 (match_operand:SWI248 0 "register_operand" "+Q,Q")
2970 (match_operand:QI 1 "general_operand" "QnBc,m") 0))]
2972 "mov{b}\t{%1, %h0|%h0, %1}"
2973 [(set_attr "isa" "*,nox64")
2974 (set_attr "type" "imov")
2975 (set_attr "mode" "QI")])
2978 [(set (match_operand:QI 0 "register_operand")
2979 (match_operand:QI 1 "norex_memory_operand"))
2980 (set (zero_extract:SWI248 (match_operand:SWI248 2 "register_operand")
2983 (subreg:SWI248 (match_dup 0) 0))]
2985 && peep2_reg_dead_p (2, operands[0])"
2986 [(set (zero_extract:SWI248 (match_dup 2)
2989 (subreg:SWI248 (match_dup 1) 0))])
2991 (define_code_iterator any_extract [sign_extract zero_extract])
2993 (define_insn "*insvqi_2"
2994 [(set (zero_extract:SWI248
2995 (match_operand:SWI248 0 "register_operand" "+Q")
2999 (match_operand:SWI248 1 "register_operand" "Q")
3003 "mov{b}\t{%h1, %h0|%h0, %h1}"
3004 [(set_attr "type" "imov")
3005 (set_attr "mode" "QI")])
3007 (define_insn "*insvqi_3"
3008 [(set (zero_extract:SWI248
3009 (match_operand:SWI248 0 "register_operand" "+Q")
3013 (match_operand:SWI248 1 "register_operand" "Q")
3016 "mov{b}\t{%h1, %h0|%h0, %h1}"
3017 [(set_attr "type" "imov")
3018 (set_attr "mode" "QI")])
3020 ;; Floating point push instructions.
3022 (define_insn "*pushtf"
3023 [(set (match_operand:TF 0 "push_operand" "=<,<")
3024 (match_operand:TF 1 "general_no_elim_operand" "v,*roC"))]
3025 "TARGET_64BIT || TARGET_SSE"
3027 /* This insn should be already split before reg-stack. */
3030 [(set_attr "isa" "*,x64")
3031 (set_attr "type" "multi")
3032 (set_attr "unit" "sse,*")
3033 (set_attr "mode" "TF,DI")])
3035 ;; %%% Kill this when call knows how to work this out.
3037 [(set (match_operand:TF 0 "push_operand")
3038 (match_operand:TF 1 "sse_reg_operand"))]
3039 "TARGET_SSE && reload_completed"
3040 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -16)))
3041 (set (match_dup 0) (match_dup 1))]
3043 /* Preserve memory attributes. */
3044 operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
3047 (define_insn_and_split "*pushxf_rounded"
3051 (plus:P (reg:P SP_REG) (const_int -16))))
3052 (match_operand:XF 0 "nonmemory_no_elim_operand" "f,r,*r,C"))]
3056 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -16)))
3057 (set (match_dup 1) (match_dup 0))]
3059 rtx pat = PATTERN (curr_insn);
3060 operands[1] = SET_DEST (pat);
3062 /* Preserve memory attributes. */
3063 operands[1] = replace_equiv_address (operands[1], stack_pointer_rtx);
3065 [(set_attr "type" "multi")
3066 (set_attr "unit" "i387,*,*,*")
3068 (cond [(eq_attr "alternative" "1,2,3")
3071 (const_string "XF")))
3072 (set (attr "preferred_for_size")
3073 (cond [(eq_attr "alternative" "1")
3074 (symbol_ref "false")]
3075 (symbol_ref "true")))])
3077 (define_insn "*pushxf"
3078 [(set (match_operand:XF 0 "push_operand" "=<,<,<,<,<")
3079 (match_operand:XF 1 "general_no_elim_operand" "f,r,*r,oF,oC"))]
3082 /* This insn should be already split before reg-stack. */
3085 [(set_attr "isa" "*,*,*,nox64,x64")
3086 (set_attr "type" "multi")
3087 (set_attr "unit" "i387,*,*,*,*")
3089 (cond [(eq_attr "alternative" "1,2,3,4")
3090 (if_then_else (match_test "TARGET_64BIT")
3092 (const_string "SI"))
3094 (const_string "XF")))
3095 (set (attr "preferred_for_size")
3096 (cond [(eq_attr "alternative" "1")
3097 (symbol_ref "false")]
3098 (symbol_ref "true")))])
3100 ;; %%% Kill this when call knows how to work this out.
3102 [(set (match_operand:XF 0 "push_operand")
3103 (match_operand:XF 1 "fp_register_operand"))]
3105 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
3106 (set (match_dup 0) (match_dup 1))]
3108 operands[2] = GEN_INT (-PUSH_ROUNDING (GET_MODE_SIZE (XFmode)));
3109 /* Preserve memory attributes. */
3110 operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
3113 (define_insn "*pushdf"
3114 [(set (match_operand:DF 0 "push_operand" "=<,<,<,<,<,<")
3115 (match_operand:DF 1 "general_no_elim_operand" "f,r,*r,oF,rmC,v"))]
3118 /* This insn should be already split before reg-stack. */
3121 [(set_attr "isa" "*,nox64,nox64,nox64,x64,sse2")
3122 (set_attr "type" "multi")
3123 (set_attr "unit" "i387,*,*,*,*,sse")
3124 (set_attr "mode" "DF,SI,SI,SI,DI,DF")
3125 (set (attr "preferred_for_size")
3126 (cond [(eq_attr "alternative" "1")
3127 (symbol_ref "false")]
3128 (symbol_ref "true")))
3129 (set (attr "preferred_for_speed")
3130 (cond [(eq_attr "alternative" "1")
3131 (symbol_ref "TARGET_INTEGER_DFMODE_MOVES")]
3132 (symbol_ref "true")))])
3134 ;; %%% Kill this when call knows how to work this out.
3136 [(set (match_operand:DF 0 "push_operand")
3137 (match_operand:DF 1 "any_fp_register_operand"))]
3139 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
3140 (set (match_dup 0) (match_dup 1))]
3142 /* Preserve memory attributes. */
3143 operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
3146 (define_insn "*pushsf_rex64"
3147 [(set (match_operand:SF 0 "push_operand" "=X,X,X")
3148 (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,v"))]
3151 /* Anything else should be already split before reg-stack. */
3152 if (which_alternative != 1)
3154 return "push{q}\t%q1";
3156 [(set_attr "type" "multi,push,multi")
3157 (set_attr "unit" "i387,*,*")
3158 (set_attr "mode" "SF,DI,SF")])
3160 (define_insn "*pushsf"
3161 [(set (match_operand:SF 0 "push_operand" "=<,<,<")
3162 (match_operand:SF 1 "general_no_elim_operand" "f,rmF,v"))]
3165 /* Anything else should be already split before reg-stack. */
3166 if (which_alternative != 1)
3168 return "push{l}\t%1";
3170 [(set_attr "type" "multi,push,multi")
3171 (set_attr "unit" "i387,*,*")
3172 (set_attr "mode" "SF,SI,SF")])
3174 ;; %%% Kill this when call knows how to work this out.
3176 [(set (match_operand:SF 0 "push_operand")
3177 (match_operand:SF 1 "any_fp_register_operand"))]
3179 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
3180 (set (match_dup 0) (match_dup 1))]
3182 rtx op = XEXP (operands[0], 0);
3183 if (GET_CODE (op) == PRE_DEC)
3185 gcc_assert (!TARGET_64BIT);
3190 op = XEXP (XEXP (op, 1), 1);
3191 gcc_assert (CONST_INT_P (op));
3194 /* Preserve memory attributes. */
3195 operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
3199 [(set (match_operand:SF 0 "push_operand")
3200 (match_operand:SF 1 "memory_operand"))]
3202 && find_constant_src (insn)"
3203 [(set (match_dup 0) (match_dup 2))]
3204 "operands[2] = find_constant_src (curr_insn);")
3207 [(set (match_operand 0 "push_operand")
3208 (match_operand 1 "general_gr_operand"))]
3210 && (GET_MODE (operands[0]) == TFmode
3211 || GET_MODE (operands[0]) == XFmode
3212 || GET_MODE (operands[0]) == DFmode)"
3214 "ix86_split_long_move (operands); DONE;")
3216 ;; Floating point move instructions.
3218 (define_expand "movtf"
3219 [(set (match_operand:TF 0 "nonimmediate_operand")
3220 (match_operand:TF 1 "nonimmediate_operand"))]
3221 "TARGET_64BIT || TARGET_SSE"
3222 "ix86_expand_move (TFmode, operands); DONE;")
3224 (define_expand "mov<mode>"
3225 [(set (match_operand:X87MODEF 0 "nonimmediate_operand")
3226 (match_operand:X87MODEF 1 "general_operand"))]
3228 "ix86_expand_move (<MODE>mode, operands); DONE;")
3230 (define_insn "*movtf_internal"
3231 [(set (match_operand:TF 0 "nonimmediate_operand" "=v,v ,m,?*r ,!o")
3232 (match_operand:TF 1 "general_operand" "C ,vm,v,*roF,*rC"))]
3233 "(TARGET_64BIT || TARGET_SSE)
3234 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3235 && (lra_in_progress || reload_completed
3236 || !CONST_DOUBLE_P (operands[1])
3237 || ((optimize_function_for_size_p (cfun)
3238 || (ix86_cmodel == CM_LARGE || ix86_cmodel == CM_LARGE_PIC))
3239 && standard_sse_constant_p (operands[1], TFmode) == 1
3240 && !memory_operand (operands[0], TFmode))
3241 || (!TARGET_MEMORY_MISMATCH_STALL
3242 && memory_operand (operands[0], TFmode)))"
3244 switch (get_attr_type (insn))
3247 return standard_sse_constant_opcode (insn, operands);
3250 return ix86_output_ssemov (insn, operands);
3259 [(set_attr "isa" "*,*,*,x64,x64")
3260 (set_attr "type" "sselog1,ssemov,ssemov,multi,multi")
3261 (set (attr "prefix")
3262 (if_then_else (eq_attr "type" "sselog1,ssemov")
3263 (const_string "maybe_vex")
3264 (const_string "orig")))
3266 (cond [(eq_attr "alternative" "3,4")
3268 (match_test "TARGET_AVX")
3270 (ior (not (match_test "TARGET_SSE2"))
3271 (match_test "optimize_function_for_size_p (cfun)"))
3272 (const_string "V4SF")
3273 (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
3274 (const_string "V4SF")
3275 (and (eq_attr "alternative" "2")
3276 (match_test "TARGET_SSE_TYPELESS_STORES"))
3277 (const_string "V4SF")
3279 (const_string "TI")))])
3282 [(set (match_operand:TF 0 "nonimmediate_gr_operand")
3283 (match_operand:TF 1 "general_gr_operand"))]
3286 "ix86_split_long_move (operands); DONE;")
3288 ;; Possible store forwarding (partial memory) stall
3289 ;; in alternatives 4, 6, 7 and 8.
3290 (define_insn "*movxf_internal"
3291 [(set (match_operand:XF 0 "nonimmediate_operand"
3292 "=f,m,f,?r ,!o,?*r ,!o,!o,!o,r ,o ,o")
3293 (match_operand:XF 1 "general_operand"
3294 "fm,f,G,roF,r ,*roF,*r,F ,C ,roF,rF,rC"))]
3295 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3296 && (lra_in_progress || reload_completed
3297 || !CONST_DOUBLE_P (operands[1])
3298 || ((optimize_function_for_size_p (cfun)
3299 || (ix86_cmodel == CM_LARGE || ix86_cmodel == CM_LARGE_PIC))
3300 && standard_80387_constant_p (operands[1]) > 0
3301 && !memory_operand (operands[0], XFmode))
3302 || (!TARGET_MEMORY_MISMATCH_STALL
3303 && memory_operand (operands[0], XFmode))
3304 || !TARGET_HARD_XF_REGS)"
3306 switch (get_attr_type (insn))
3309 if (which_alternative == 2)
3310 return standard_80387_constant_opcode (operands[1]);
3311 return output_387_reg_move (insn, operands);
3321 (cond [(eq_attr "alternative" "7,10")
3322 (const_string "nox64")
3323 (eq_attr "alternative" "8,11")
3324 (const_string "x64")
3326 (const_string "*")))
3328 (cond [(eq_attr "alternative" "3,4,5,6,7,8,9,10,11")
3329 (const_string "multi")
3331 (const_string "fmov")))
3333 (cond [(eq_attr "alternative" "3,4,5,6,7,8,9,10,11")
3334 (if_then_else (match_test "TARGET_64BIT")
3336 (const_string "SI"))
3338 (const_string "XF")))
3339 (set (attr "preferred_for_size")
3340 (cond [(eq_attr "alternative" "3,4")
3341 (symbol_ref "false")]
3342 (symbol_ref "true")))
3343 (set (attr "enabled")
3344 (cond [(eq_attr "alternative" "9,10,11")
3346 (match_test "TARGET_HARD_XF_REGS")
3347 (symbol_ref "false")
3349 (not (match_test "TARGET_HARD_XF_REGS"))
3350 (symbol_ref "false")
3352 (const_string "*")))])
3355 [(set (match_operand:XF 0 "nonimmediate_gr_operand")
3356 (match_operand:XF 1 "general_gr_operand"))]
3359 "ix86_split_long_move (operands); DONE;")
3361 ;; Possible store forwarding (partial memory) stall in alternatives 4, 6 and 7.
3362 (define_insn "*movdf_internal"
3363 [(set (match_operand:DF 0 "nonimmediate_operand"
3364 "=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")
3365 (match_operand:DF 1 "general_operand"
3366 "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"))]
3367 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3368 && (lra_in_progress || reload_completed
3369 || !CONST_DOUBLE_P (operands[1])
3370 || ((optimize_function_for_size_p (cfun)
3371 || (ix86_cmodel == CM_LARGE || ix86_cmodel == CM_LARGE_PIC))
3372 && ((IS_STACK_MODE (DFmode)
3373 && standard_80387_constant_p (operands[1]) > 0)
3374 || (TARGET_SSE2 && TARGET_SSE_MATH
3375 && standard_sse_constant_p (operands[1], DFmode) == 1))
3376 && !memory_operand (operands[0], DFmode))
3377 || ((TARGET_64BIT || !TARGET_MEMORY_MISMATCH_STALL)
3378 && memory_operand (operands[0], DFmode))
3379 || !TARGET_HARD_DF_REGS)"
3381 switch (get_attr_type (insn))
3384 if (which_alternative == 2)
3385 return standard_80387_constant_opcode (operands[1]);
3386 return output_387_reg_move (insn, operands);
3392 if (get_attr_mode (insn) == MODE_SI)
3393 return "mov{l}\t{%1, %k0|%k0, %1}";
3394 else if (which_alternative == 11)
3395 return "movabs{q}\t{%1, %0|%0, %1}";
3397 return "mov{q}\t{%1, %0|%0, %1}";
3400 return standard_sse_constant_opcode (insn, operands);
3403 return ix86_output_ssemov (insn, operands);
3410 (cond [(eq_attr "alternative" "3,4,5,6,7,22,23")
3411 (const_string "nox64")
3412 (eq_attr "alternative" "8,9,10,11,24,25")
3413 (const_string "x64")
3414 (eq_attr "alternative" "12,13,14,15")
3415 (const_string "sse2")
3416 (eq_attr "alternative" "20,21")
3417 (const_string "x64_sse2")
3419 (const_string "*")))
3421 (cond [(eq_attr "alternative" "0,1,2")
3422 (const_string "fmov")
3423 (eq_attr "alternative" "3,4,5,6,7,22,23")
3424 (const_string "multi")
3425 (eq_attr "alternative" "8,9,10,11,24,25")
3426 (const_string "imov")
3427 (eq_attr "alternative" "12,16")
3428 (const_string "sselog1")
3430 (const_string "ssemov")))
3432 (if_then_else (eq_attr "alternative" "11")
3434 (const_string "*")))
3435 (set (attr "length_immediate")
3436 (if_then_else (eq_attr "alternative" "11")
3438 (const_string "*")))
3439 (set (attr "prefix")
3440 (if_then_else (eq_attr "type" "sselog1,ssemov")
3441 (const_string "maybe_vex")
3442 (const_string "orig")))
3443 (set (attr "prefix_data16")
3445 (ior (and (eq_attr "type" "ssemov") (eq_attr "mode" "DI"))
3446 (eq_attr "mode" "V1DF"))
3448 (const_string "*")))
3450 (cond [(eq_attr "alternative" "3,4,5,6,7,10,22,23")
3452 (eq_attr "alternative" "8,9,11,20,21,24,25")
3455 /* xorps is one byte shorter for non-AVX targets. */
3456 (eq_attr "alternative" "12,16")
3457 (cond [(match_test "TARGET_AVX")
3458 (const_string "V2DF")
3459 (ior (not (match_test "TARGET_SSE2"))
3460 (match_test "optimize_function_for_size_p (cfun)"))
3461 (const_string "V4SF")
3462 (match_test "TARGET_SSE_LOAD0_BY_PXOR")
3465 (const_string "V2DF"))
3467 /* For architectures resolving dependencies on
3468 whole SSE registers use movapd to break dependency
3469 chains, otherwise use short move to avoid extra work. */
3471 /* movaps is one byte shorter for non-AVX targets. */
3472 (eq_attr "alternative" "13,17")
3473 (cond [(match_test "TARGET_AVX")
3475 (ior (not (match_test "TARGET_SSE2"))
3476 (match_test "optimize_function_for_size_p (cfun)"))
3477 (const_string "V4SF")
3478 (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
3479 (const_string "V4SF")
3480 (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3481 (const_string "V2DF")
3483 (const_string "DF"))
3485 /* For architectures resolving dependencies on register
3486 parts we may avoid extra work to zero out upper part
3488 (eq_attr "alternative" "14,18")
3489 (cond [(not (match_test "TARGET_SSE2"))
3490 (const_string "V2SF")
3491 (match_test "TARGET_AVX")
3493 (match_test "TARGET_SSE_SPLIT_REGS")
3494 (const_string "V1DF")
3496 (const_string "DF"))
3498 (and (eq_attr "alternative" "15,19")
3499 (not (match_test "TARGET_SSE2")))
3500 (const_string "V2SF")
3502 (const_string "DF")))
3503 (set (attr "preferred_for_size")
3504 (cond [(eq_attr "alternative" "3,4")
3505 (symbol_ref "false")]
3506 (symbol_ref "true")))
3507 (set (attr "preferred_for_speed")
3508 (cond [(eq_attr "alternative" "3,4")
3509 (symbol_ref "TARGET_INTEGER_DFMODE_MOVES")
3510 (eq_attr "alternative" "20")
3511 (symbol_ref "TARGET_INTER_UNIT_MOVES_FROM_VEC")
3512 (eq_attr "alternative" "21")
3513 (symbol_ref "TARGET_INTER_UNIT_MOVES_TO_VEC")
3515 (symbol_ref "true")))
3516 (set (attr "enabled")
3517 (cond [(eq_attr "alternative" "22,23,24,25")
3519 (match_test "TARGET_HARD_DF_REGS")
3520 (symbol_ref "false")
3522 (not (match_test "TARGET_HARD_DF_REGS"))
3523 (symbol_ref "false")
3525 (const_string "*")))])
3528 [(set (match_operand:DF 0 "nonimmediate_gr_operand")
3529 (match_operand:DF 1 "general_gr_operand"))]
3530 "!TARGET_64BIT && reload_completed"
3532 "ix86_split_long_move (operands); DONE;")
3534 (define_insn "*movsf_internal"
3535 [(set (match_operand:SF 0 "nonimmediate_operand"
3536 "=Yf*f,m ,Yf*f,?r ,?m,v,v,v,m,?r,?v,!*y,!*y,!m,!r,!*y,r ,m")
3537 (match_operand:SF 1 "general_operand"
3538 "Yf*fm,Yf*f,G ,rmF,rF,C,v,m,v,v ,r ,*y ,m ,*y,*y,r ,rmF,rF"))]
3539 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3540 && (lra_in_progress || reload_completed
3541 || !CONST_DOUBLE_P (operands[1])
3542 || ((optimize_function_for_size_p (cfun)
3543 || (ix86_cmodel == CM_LARGE || ix86_cmodel == CM_LARGE_PIC))
3544 && ((IS_STACK_MODE (SFmode)
3545 && standard_80387_constant_p (operands[1]) > 0)
3546 || (TARGET_SSE && TARGET_SSE_MATH
3547 && standard_sse_constant_p (operands[1], SFmode) == 1)))
3548 || memory_operand (operands[0], SFmode)
3549 || !TARGET_HARD_SF_REGS)"
3551 switch (get_attr_type (insn))
3554 if (which_alternative == 2)
3555 return standard_80387_constant_opcode (operands[1]);
3556 return output_387_reg_move (insn, operands);
3559 return "mov{l}\t{%1, %0|%0, %1}";
3562 return standard_sse_constant_opcode (insn, operands);
3565 return ix86_output_ssemov (insn, operands);
3568 switch (get_attr_mode (insn))
3571 return "movq\t{%1, %0|%0, %1}";
3573 return "movd\t{%1, %0|%0, %1}";
3584 (cond [(eq_attr "alternative" "9,10")
3585 (const_string "sse2")
3587 (const_string "*")))
3589 (cond [(eq_attr "alternative" "0,1,2")
3590 (const_string "fmov")
3591 (eq_attr "alternative" "3,4,16,17")
3592 (const_string "imov")
3593 (eq_attr "alternative" "5")
3594 (const_string "sselog1")
3595 (eq_attr "alternative" "11,12,13,14,15")
3596 (const_string "mmxmov")
3598 (const_string "ssemov")))
3599 (set (attr "prefix")
3600 (if_then_else (eq_attr "type" "sselog1,ssemov")
3601 (const_string "maybe_vex")
3602 (const_string "orig")))
3603 (set (attr "prefix_data16")
3604 (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
3606 (const_string "*")))
3608 (cond [(eq_attr "alternative" "3,4,9,10,12,13,14,15,16,17")
3610 (eq_attr "alternative" "11")
3612 (eq_attr "alternative" "5")
3613 (cond [(and (match_test "TARGET_AVX512F")
3614 (not (match_test "TARGET_PREFER_AVX256")))
3615 (const_string "V16SF")
3616 (match_test "TARGET_AVX")
3617 (const_string "V4SF")
3618 (ior (not (match_test "TARGET_SSE2"))
3619 (match_test "optimize_function_for_size_p (cfun)"))
3620 (const_string "V4SF")
3621 (match_test "TARGET_SSE_LOAD0_BY_PXOR")
3624 (const_string "V4SF"))
3626 /* For architectures resolving dependencies on
3627 whole SSE registers use APS move to break dependency
3628 chains, otherwise use short move to avoid extra work.
3630 Do the same for architectures resolving dependencies on
3631 the parts. While in DF mode it is better to always handle
3632 just register parts, the SF mode is different due to lack
3633 of instructions to load just part of the register. It is
3634 better to maintain the whole registers in single format
3635 to avoid problems on using packed logical operations. */
3636 (eq_attr "alternative" "6")
3637 (cond [(ior (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3638 (match_test "TARGET_SSE_SPLIT_REGS"))
3639 (const_string "V4SF")
3641 (const_string "SF"))
3643 (const_string "SF")))
3644 (set (attr "preferred_for_speed")
3645 (cond [(eq_attr "alternative" "9,14")
3646 (symbol_ref "TARGET_INTER_UNIT_MOVES_FROM_VEC")
3647 (eq_attr "alternative" "10,15")
3648 (symbol_ref "TARGET_INTER_UNIT_MOVES_TO_VEC")
3650 (symbol_ref "true")))
3651 (set (attr "enabled")
3652 (cond [(eq_attr "alternative" "16,17")
3654 (match_test "TARGET_HARD_SF_REGS")
3655 (symbol_ref "false")
3657 (not (match_test "TARGET_HARD_SF_REGS"))
3658 (symbol_ref "false")
3660 (const_string "*")))])
3663 [(set (match_operand 0 "any_fp_register_operand")
3664 (match_operand 1 "memory_operand"))]
3666 && (GET_MODE (operands[0]) == TFmode
3667 || GET_MODE (operands[0]) == XFmode
3668 || GET_MODE (operands[0]) == DFmode
3669 || GET_MODE (operands[0]) == SFmode)
3670 && ix86_standard_x87sse_constant_load_p (insn, operands[0])"
3671 [(set (match_dup 0) (match_dup 2))]
3672 "operands[2] = find_constant_src (curr_insn);")
3675 [(set (match_operand 0 "any_fp_register_operand")
3676 (float_extend (match_operand 1 "memory_operand")))]
3678 && (GET_MODE (operands[0]) == TFmode
3679 || GET_MODE (operands[0]) == XFmode
3680 || GET_MODE (operands[0]) == DFmode)
3681 && ix86_standard_x87sse_constant_load_p (insn, operands[0])"
3682 [(set (match_dup 0) (match_dup 2))]
3683 "operands[2] = find_constant_src (curr_insn);")
3685 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
3687 [(set (match_operand:X87MODEF 0 "fp_register_operand")
3688 (match_operand:X87MODEF 1 "immediate_operand"))]
3690 && (standard_80387_constant_p (operands[1]) == 8
3691 || standard_80387_constant_p (operands[1]) == 9)"
3692 [(set (match_dup 0)(match_dup 1))
3694 (neg:X87MODEF (match_dup 0)))]
3696 if (real_isnegzero (CONST_DOUBLE_REAL_VALUE (operands[1])))
3697 operands[1] = CONST0_RTX (<MODE>mode);
3699 operands[1] = CONST1_RTX (<MODE>mode);
3702 (define_insn "*swapxf"
3703 [(set (match_operand:XF 0 "register_operand" "+f")
3704 (match_operand:XF 1 "register_operand" "+f"))
3709 if (STACK_TOP_P (operands[0]))
3714 [(set_attr "type" "fxch")
3715 (set_attr "mode" "XF")])
3718 ;; Zero extension instructions
3720 (define_expand "zero_extendsidi2"
3721 [(set (match_operand:DI 0 "nonimmediate_operand")
3722 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand")))])
3724 (define_insn "*zero_extendsidi2"
3725 [(set (match_operand:DI 0 "nonimmediate_operand"
3726 "=r,?r,?o,r ,o,?*y,?!*y,$r,$v,$x,*x,*v,*r,*k")
3728 (match_operand:SI 1 "x86_64_zext_operand"
3729 "0 ,rm,r ,rmWz,0,r ,m ,v ,r ,m ,*x,*v,*k,*km")))]
3732 switch (get_attr_type (insn))
3735 if (ix86_use_lea_for_mov (insn, operands))
3736 return "lea{l}\t{%E1, %k0|%k0, %E1}";
3738 return "mov{l}\t{%1, %k0|%k0, %1}";
3744 return "movd\t{%1, %0|%0, %1}";
3747 if (SSE_REG_P (operands[0]) && SSE_REG_P (operands[1]))
3749 if (EXT_REX_SSE_REG_P (operands[0])
3750 || EXT_REX_SSE_REG_P (operands[1]))
3751 return "vpmovzxdq\t{%t1, %g0|%g0, %t1}";
3753 return "%vpmovzxdq\t{%1, %0|%0, %1}";
3756 if (GENERAL_REG_P (operands[0]))
3757 return "%vmovd\t{%1, %k0|%k0, %1}";
3759 return "%vmovd\t{%1, %0|%0, %1}";
3762 return "kmovd\t{%1, %k0|%k0, %1}";
3769 (cond [(eq_attr "alternative" "0,1,2")
3770 (const_string "nox64")
3771 (eq_attr "alternative" "3")
3772 (const_string "x64")
3773 (eq_attr "alternative" "7,8,9")
3774 (const_string "sse2")
3775 (eq_attr "alternative" "10")
3776 (const_string "sse4")
3777 (eq_attr "alternative" "11")
3778 (const_string "avx512f")
3779 (eq_attr "alternative" "12")
3780 (const_string "x64_avx512bw")
3781 (eq_attr "alternative" "13")
3782 (const_string "avx512bw")
3784 (const_string "*")))
3785 (set (attr "mmx_isa")
3786 (if_then_else (eq_attr "alternative" "5,6")
3787 (const_string "native")
3788 (const_string "*")))
3790 (cond [(eq_attr "alternative" "0,1,2,4")
3791 (const_string "multi")
3792 (eq_attr "alternative" "5,6")
3793 (const_string "mmxmov")
3794 (eq_attr "alternative" "7")
3795 (if_then_else (match_test "TARGET_64BIT")
3796 (const_string "ssemov")
3797 (const_string "multi"))
3798 (eq_attr "alternative" "8,9,10,11")
3799 (const_string "ssemov")
3800 (eq_attr "alternative" "12,13")
3801 (const_string "mskmov")
3803 (const_string "imovx")))
3804 (set (attr "prefix_extra")
3805 (if_then_else (eq_attr "alternative" "10,11")
3807 (const_string "*")))
3808 (set (attr "prefix")
3809 (if_then_else (eq_attr "type" "ssemov")
3810 (const_string "maybe_vex")
3811 (const_string "orig")))
3812 (set (attr "prefix_0f")
3813 (if_then_else (eq_attr "type" "imovx")
3815 (const_string "*")))
3817 (cond [(eq_attr "alternative" "5,6")
3819 (and (eq_attr "alternative" "7")
3820 (match_test "TARGET_64BIT"))
3822 (eq_attr "alternative" "8,10,11")
3825 (const_string "SI")))
3826 (set (attr "preferred_for_speed")
3827 (cond [(eq_attr "alternative" "7")
3828 (symbol_ref "TARGET_INTER_UNIT_MOVES_FROM_VEC")
3829 (eq_attr "alternative" "5,8")
3830 (symbol_ref "TARGET_INTER_UNIT_MOVES_TO_VEC")
3832 (symbol_ref "true")))])
3835 [(set (match_operand:DI 0 "memory_operand")
3836 (zero_extend:DI (match_operand:SI 1 "memory_operand")))]
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 "general_reg_operand")
3843 (zero_extend:DI (match_operand:SI 1 "general_reg_operand")))]
3844 "!TARGET_64BIT && reload_completed
3845 && REGNO (operands[0]) == REGNO (operands[1])"
3846 [(set (match_dup 4) (const_int 0))]
3847 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3850 [(set (match_operand:DI 0 "nonimmediate_gr_operand")
3851 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand")))]
3852 "!TARGET_64BIT && reload_completed
3853 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
3854 [(set (match_dup 3) (match_dup 1))
3855 (set (match_dup 4) (const_int 0))]
3856 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3858 (define_mode_attr kmov_isa
3859 [(QI "avx512dq") (HI "avx512f") (SI "avx512bw") (DI "avx512bw")])
3861 (define_insn "zero_extend<mode>di2"
3862 [(set (match_operand:DI 0 "register_operand" "=r,*r,*k")
3864 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m,*k,*km")))]
3867 movz{<imodesuffix>l|x}\t{%1, %k0|%k0, %1}
3868 kmov<mskmodesuffix>\t{%1, %k0|%k0, %1}
3869 kmov<mskmodesuffix>\t{%1, %k0|%k0, %1}"
3870 [(set_attr "isa" "*,<kmov_isa>,<kmov_isa>")
3871 (set_attr "type" "imovx,mskmov,mskmov")
3872 (set_attr "mode" "SI,<MODE>,<MODE>")])
3874 (define_expand "zero_extend<mode>si2"
3875 [(set (match_operand:SI 0 "register_operand")
3876 (zero_extend:SI (match_operand:SWI12 1 "nonimmediate_operand")))]
3879 if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3881 operands[1] = force_reg (<MODE>mode, operands[1]);
3882 emit_insn (gen_zero_extend<mode>si2_and (operands[0], operands[1]));
3887 (define_insn_and_split "zero_extend<mode>si2_and"
3888 [(set (match_operand:SI 0 "register_operand" "=r,?&<r>")
3890 (match_operand:SWI12 1 "nonimmediate_operand" "0,<r>m")))
3891 (clobber (reg:CC FLAGS_REG))]
3892 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3894 "&& reload_completed"
3895 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (match_dup 2)))
3896 (clobber (reg:CC FLAGS_REG))])]
3898 if (!REG_P (operands[1])
3899 || REGNO (operands[0]) != REGNO (operands[1]))
3901 ix86_expand_clear (operands[0]);
3903 gcc_assert (!TARGET_PARTIAL_REG_STALL);
3904 emit_insn (gen_rtx_SET
3905 (gen_rtx_STRICT_LOW_PART
3906 (VOIDmode, gen_lowpart (<MODE>mode, operands[0])),
3911 operands[2] = GEN_INT (GET_MODE_MASK (<MODE>mode));
3913 [(set_attr "type" "alu1")
3914 (set_attr "mode" "SI")])
3916 (define_insn "*zero_extend<mode>si2"
3917 [(set (match_operand:SI 0 "register_operand" "=r,*r,*k")
3919 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m,*k,*km")))]
3920 "!(TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))"
3922 movz{<imodesuffix>l|x}\t{%1, %0|%0, %1}
3923 kmov<mskmodesuffix>\t{%1, %0|%0, %1}
3924 kmov<mskmodesuffix>\t{%1, %0|%0, %1}"
3925 [(set_attr "isa" "*,<kmov_isa>,<kmov_isa>")
3926 (set_attr "type" "imovx,mskmov,mskmov")
3927 (set_attr "mode" "SI,<MODE>,<MODE>")])
3929 (define_expand "zero_extendqihi2"
3930 [(set (match_operand:HI 0 "register_operand")
3931 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand")))]
3934 if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3936 operands[1] = force_reg (QImode, operands[1]);
3937 emit_insn (gen_zero_extendqihi2_and (operands[0], operands[1]));
3942 (define_insn_and_split "zero_extendqihi2_and"
3943 [(set (match_operand:HI 0 "register_operand" "=r,?&q")
3944 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3945 (clobber (reg:CC FLAGS_REG))]
3946 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3948 "&& reload_completed"
3949 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
3950 (clobber (reg:CC FLAGS_REG))])]
3952 if (!REG_P (operands[1])
3953 || REGNO (operands[0]) != REGNO (operands[1]))
3955 ix86_expand_clear (operands[0]);
3957 gcc_assert (!TARGET_PARTIAL_REG_STALL);
3958 emit_insn (gen_rtx_SET
3959 (gen_rtx_STRICT_LOW_PART
3960 (VOIDmode, gen_lowpart (QImode, operands[0])),
3965 operands[0] = gen_lowpart (SImode, operands[0]);
3967 [(set_attr "type" "alu1")
3968 (set_attr "mode" "SI")])
3970 ; zero extend to SImode to avoid partial register stalls
3971 (define_insn "*zero_extendqihi2"
3972 [(set (match_operand:HI 0 "register_operand" "=r,*r,*k")
3973 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,*k,*km")))]
3974 "!(TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))"
3976 movz{bl|x}\t{%1, %k0|%k0, %1}
3977 kmovb\t{%1, %k0|%k0, %1}
3978 kmovb\t{%1, %0|%0, %1}"
3979 [(set_attr "isa" "*,avx512dq,avx512dq")
3980 (set_attr "type" "imovx,mskmov,mskmov")
3981 (set_attr "mode" "SI,QI,QI")])
3983 ;; Sign extension instructions
3985 (define_expand "extendsidi2"
3986 [(set (match_operand:DI 0 "register_operand")
3987 (sign_extend:DI (match_operand:SI 1 "register_operand")))]
3992 emit_insn (gen_extendsidi2_1 (operands[0], operands[1]));
3997 (define_insn "*extendsidi2_rex64"
3998 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3999 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
4003 movs{lq|x}\t{%1, %0|%0, %1}"
4004 [(set_attr "type" "imovx")
4005 (set_attr "mode" "DI")
4006 (set_attr "prefix_0f" "0")
4007 (set_attr "modrm" "0,1")])
4009 (define_insn "extendsidi2_1"
4010 [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
4011 (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
4012 (clobber (reg:CC FLAGS_REG))
4013 (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
4017 ;; Split the memory case. If the source register doesn't die, it will stay
4018 ;; this way, if it does die, following peephole2s take care of it.
4020 [(set (match_operand:DI 0 "memory_operand")
4021 (sign_extend:DI (match_operand:SI 1 "register_operand")))
4022 (clobber (reg:CC FLAGS_REG))
4023 (clobber (match_operand:SI 2 "register_operand"))]
4027 split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
4029 emit_move_insn (operands[3], operands[1]);
4031 /* Generate a cltd if possible and doing so it profitable. */
4032 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
4033 && REGNO (operands[1]) == AX_REG
4034 && REGNO (operands[2]) == DX_REG)
4036 emit_insn (gen_ashrsi3_cvt (operands[2], operands[1], GEN_INT (31)));
4040 emit_move_insn (operands[2], operands[1]);
4041 emit_insn (gen_ashrsi3_cvt (operands[2], operands[2], GEN_INT (31)));
4043 emit_move_insn (operands[4], operands[2]);
4047 ;; Peepholes for the case where the source register does die, after
4048 ;; being split with the above splitter.
4050 [(set (match_operand:SI 0 "memory_operand")
4051 (match_operand:SI 1 "general_reg_operand"))
4052 (set (match_operand:SI 2 "general_reg_operand") (match_dup 1))
4053 (parallel [(set (match_dup 2)
4054 (ashiftrt:SI (match_dup 2) (const_int 31)))
4055 (clobber (reg:CC FLAGS_REG))])
4056 (set (match_operand:SI 3 "memory_operand") (match_dup 2))]
4057 "REGNO (operands[1]) != REGNO (operands[2])
4058 && peep2_reg_dead_p (2, operands[1])
4059 && peep2_reg_dead_p (4, operands[2])
4060 && !reg_mentioned_p (operands[2], operands[3])"
4061 [(set (match_dup 0) (match_dup 1))
4062 (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
4063 (clobber (reg:CC FLAGS_REG))])
4064 (set (match_dup 3) (match_dup 1))])
4067 [(set (match_operand:SI 0 "memory_operand")
4068 (match_operand:SI 1 "general_reg_operand"))
4069 (parallel [(set (match_operand:SI 2 "general_reg_operand")
4070 (ashiftrt:SI (match_dup 1) (const_int 31)))
4071 (clobber (reg:CC FLAGS_REG))])
4072 (set (match_operand:SI 3 "memory_operand") (match_dup 2))]
4073 "/* cltd is shorter than sarl $31, %eax */
4074 !optimize_function_for_size_p (cfun)
4075 && REGNO (operands[1]) == AX_REG
4076 && REGNO (operands[2]) == DX_REG
4077 && peep2_reg_dead_p (2, operands[1])
4078 && peep2_reg_dead_p (3, operands[2])
4079 && !reg_mentioned_p (operands[2], operands[3])"
4080 [(set (match_dup 0) (match_dup 1))
4081 (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
4082 (clobber (reg:CC FLAGS_REG))])
4083 (set (match_dup 3) (match_dup 1))])
4085 ;; Extend to register case. Optimize case where source and destination
4086 ;; registers match and cases where we can use cltd.
4088 [(set (match_operand:DI 0 "register_operand")
4089 (sign_extend:DI (match_operand:SI 1 "register_operand")))
4090 (clobber (reg:CC FLAGS_REG))
4091 (clobber (match_scratch:SI 2))]
4095 split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
4097 if (REGNO (operands[3]) != REGNO (operands[1]))
4098 emit_move_insn (operands[3], operands[1]);
4100 /* Generate a cltd if possible and doing so it profitable. */
4101 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
4102 && REGNO (operands[3]) == AX_REG
4103 && REGNO (operands[4]) == DX_REG)
4105 emit_insn (gen_ashrsi3_cvt (operands[4], operands[3], GEN_INT (31)));
4109 if (REGNO (operands[4]) != REGNO (operands[1]))
4110 emit_move_insn (operands[4], operands[1]);
4112 emit_insn (gen_ashrsi3_cvt (operands[4], operands[4], GEN_INT (31)));
4116 (define_insn "extend<mode>di2"
4117 [(set (match_operand:DI 0 "register_operand" "=r")
4119 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
4121 "movs{<imodesuffix>q|x}\t{%1, %0|%0, %1}"
4122 [(set_attr "type" "imovx")
4123 (set_attr "mode" "DI")])
4125 (define_insn "extendhisi2"
4126 [(set (match_operand:SI 0 "register_operand" "=*a,r")
4127 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
4130 switch (get_attr_prefix_0f (insn))
4133 return "{cwtl|cwde}";
4135 return "movs{wl|x}\t{%1, %0|%0, %1}";
4138 [(set_attr "type" "imovx")
4139 (set_attr "mode" "SI")
4140 (set (attr "prefix_0f")
4141 ;; movsx is short decodable while cwtl is vector decoded.
4142 (if_then_else (and (eq_attr "cpu" "!k6")
4143 (eq_attr "alternative" "0"))
4145 (const_string "1")))
4146 (set (attr "znver1_decode")
4147 (if_then_else (eq_attr "prefix_0f" "0")
4148 (const_string "double")
4149 (const_string "direct")))
4151 (if_then_else (eq_attr "prefix_0f" "0")
4153 (const_string "1")))])
4155 (define_insn "*extendhisi2_zext"
4156 [(set (match_operand:DI 0 "register_operand" "=*a,r")
4159 (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
4162 switch (get_attr_prefix_0f (insn))
4165 return "{cwtl|cwde}";
4167 return "movs{wl|x}\t{%1, %k0|%k0, %1}";
4170 [(set_attr "type" "imovx")
4171 (set_attr "mode" "SI")
4172 (set (attr "prefix_0f")
4173 ;; movsx is short decodable while cwtl is vector decoded.
4174 (if_then_else (and (eq_attr "cpu" "!k6")
4175 (eq_attr "alternative" "0"))
4177 (const_string "1")))
4179 (if_then_else (eq_attr "prefix_0f" "0")
4181 (const_string "1")))])
4183 (define_insn "extendqisi2"
4184 [(set (match_operand:SI 0 "register_operand" "=r")
4185 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
4187 "movs{bl|x}\t{%1, %0|%0, %1}"
4188 [(set_attr "type" "imovx")
4189 (set_attr "mode" "SI")])
4191 (define_insn "*extendqisi2_zext"
4192 [(set (match_operand:DI 0 "register_operand" "=r")
4194 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
4196 "movs{bl|x}\t{%1, %k0|%k0, %1}"
4197 [(set_attr "type" "imovx")
4198 (set_attr "mode" "SI")])
4200 (define_insn "extendqihi2"
4201 [(set (match_operand:HI 0 "register_operand" "=*a,r")
4202 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
4205 switch (get_attr_prefix_0f (insn))
4208 return "{cbtw|cbw}";
4210 return "movs{bw|x}\t{%1, %0|%0, %1}";
4213 [(set_attr "type" "imovx")
4214 (set_attr "mode" "HI")
4215 (set (attr "prefix_0f")
4216 ;; movsx is short decodable while cwtl is vector decoded.
4217 (if_then_else (and (eq_attr "cpu" "!k6")
4218 (eq_attr "alternative" "0"))
4220 (const_string "1")))
4222 (if_then_else (eq_attr "prefix_0f" "0")
4224 (const_string "1")))])
4226 ;; Conversions between float and double.
4228 ;; These are all no-ops in the model used for the 80387.
4229 ;; So just emit moves.
4231 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
4233 [(set (match_operand:DF 0 "push_operand")
4234 (float_extend:DF (match_operand:SF 1 "fp_register_operand")))]
4236 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
4237 (set (mem:DF (reg:P SP_REG)) (float_extend:DF (match_dup 1)))])
4240 [(set (match_operand:XF 0 "push_operand")
4241 (float_extend:XF (match_operand:MODEF 1 "fp_register_operand")))]
4243 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
4244 (set (mem:XF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
4245 "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
4247 (define_expand "extendsfdf2"
4248 [(set (match_operand:DF 0 "nonimm_ssenomem_operand")
4249 (float_extend:DF (match_operand:SF 1 "general_operand")))]
4250 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4252 /* ??? Needed for compress_float_constant since all fp constants
4253 are TARGET_LEGITIMATE_CONSTANT_P. */
4254 if (CONST_DOUBLE_P (operands[1]))
4256 if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
4257 && standard_80387_constant_p (operands[1]) > 0)
4259 operands[1] = simplify_const_unary_operation
4260 (FLOAT_EXTEND, DFmode, operands[1], SFmode);
4261 emit_move_insn_1 (operands[0], operands[1]);
4264 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
4268 (define_insn "*extendsfdf2"
4269 [(set (match_operand:DF 0 "nonimm_ssenomem_operand" "=f,m,v,v")
4271 (match_operand:SF 1 "nonimmediate_operand" "fm,f,v,m")))]
4272 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4274 switch (which_alternative)
4278 return output_387_reg_move (insn, operands);
4281 return "%vcvtss2sd\t{%d1, %0|%0, %d1}";
4283 return "%vcvtss2sd\t{%1, %d0|%d0, %1}";
4289 [(set_attr "type" "fmov,fmov,ssecvt,ssecvt")
4290 (set_attr "avx_partial_xmm_update" "false,false,false,true")
4291 (set_attr "prefix" "orig,orig,maybe_vex,maybe_vex")
4292 (set_attr "mode" "SF,XF,DF,DF")
4293 (set (attr "enabled")
4295 (match_test ("TARGET_SSE2 && TARGET_SSE_MATH"))
4297 (eq_attr "alternative" "0,1")
4298 (symbol_ref "TARGET_MIX_SSE_I387")
4299 (symbol_ref "true"))
4301 (eq_attr "alternative" "0,1")
4303 (symbol_ref "false"))))])
4305 /* For converting SF(xmm2) to DF(xmm1), use the following code instead of
4307 unpcklps xmm2,xmm2 ; packed conversion might crash on signaling NaNs
4309 We do the conversion post reload to avoid producing of 128bit spills
4310 that might lead to ICE on 32bit target. The sequence unlikely combine
4313 [(set (match_operand:DF 0 "sse_reg_operand")
4315 (match_operand:SF 1 "nonimmediate_operand")))]
4316 "TARGET_USE_VECTOR_FP_CONVERTS
4317 && optimize_insn_for_speed_p ()
4319 && (!EXT_REX_SSE_REG_P (operands[0])
4320 || TARGET_AVX512VL)"
4325 (parallel [(const_int 0) (const_int 1)]))))]
4327 operands[2] = lowpart_subreg (V2DFmode, operands[0], DFmode);
4328 operands[3] = lowpart_subreg (V4SFmode, operands[0], DFmode);
4329 /* Use movss for loading from memory, unpcklps reg, reg for registers.
4330 Try to avoid move when unpacking can be done in source. */
4331 if (REG_P (operands[1]))
4333 /* If it is unsafe to overwrite upper half of source, we need
4334 to move to destination and unpack there. */
4335 if (REGNO (operands[0]) != REGNO (operands[1])
4336 || (EXT_REX_SSE_REG_P (operands[1])
4337 && !TARGET_AVX512VL))
4339 rtx tmp = lowpart_subreg (SFmode, operands[0], DFmode);
4340 emit_move_insn (tmp, operands[1]);
4343 operands[3] = lowpart_subreg (V4SFmode, operands[1], SFmode);
4344 /* FIXME: vec_interleave_lowv4sf for AVX512VL should allow
4345 =v, v, then vbroadcastss will be only needed for AVX512F without
4347 if (!EXT_REX_SSE_REGNO_P (REGNO (operands[3])))
4348 emit_insn (gen_vec_interleave_lowv4sf (operands[3], operands[3],
4352 rtx tmp = lowpart_subreg (V16SFmode, operands[3], V4SFmode);
4353 emit_insn (gen_avx512f_vec_dupv16sf_1 (tmp, tmp));
4357 emit_insn (gen_vec_setv4sf_0 (operands[3],
4358 CONST0_RTX (V4SFmode), operands[1]));
4361 ;; It's more profitable to split and then extend in the same register.
4363 [(set (match_operand:DF 0 "sse_reg_operand")
4365 (match_operand:SF 1 "memory_operand")))]
4366 "TARGET_SPLIT_MEM_OPND_FOR_FP_CONVERTS
4367 && optimize_insn_for_speed_p ()"
4368 [(set (match_dup 2) (match_dup 1))
4369 (set (match_dup 0) (float_extend:DF (match_dup 2)))]
4370 "operands[2] = lowpart_subreg (SFmode, operands[0], DFmode);")
4372 ;; Break partial SSE register dependency stall. This splitter should split
4373 ;; late in the pass sequence (after register rename pass), so allocated
4374 ;; registers won't change anymore
4377 [(set (match_operand:DF 0 "sse_reg_operand")
4379 (match_operand:SF 1 "nonimmediate_operand")))]
4381 && TARGET_SSE_PARTIAL_REG_DEPENDENCY && epilogue_completed
4382 && optimize_function_for_speed_p (cfun)
4383 && (!REG_P (operands[1])
4384 || (!TARGET_AVX && REGNO (operands[0]) != REGNO (operands[1])))
4385 && (!EXT_REX_SSE_REG_P (operands[0])
4386 || TARGET_AVX512VL)"
4395 operands[0] = lowpart_subreg (V2DFmode, operands[0], DFmode);
4396 emit_move_insn (operands[0], CONST0_RTX (V2DFmode));
4399 (define_expand "extend<mode>xf2"
4400 [(set (match_operand:XF 0 "nonimmediate_operand")
4401 (float_extend:XF (match_operand:MODEF 1 "general_operand")))]
4404 /* ??? Needed for compress_float_constant since all fp constants
4405 are TARGET_LEGITIMATE_CONSTANT_P. */
4406 if (CONST_DOUBLE_P (operands[1]))
4408 if (standard_80387_constant_p (operands[1]) > 0)
4410 operands[1] = simplify_const_unary_operation
4411 (FLOAT_EXTEND, XFmode, operands[1], <MODE>mode);
4412 emit_move_insn_1 (operands[0], operands[1]);
4415 operands[1] = validize_mem (force_const_mem (<MODE>mode, operands[1]));
4419 (define_insn "*extend<mode>xf2_i387"
4420 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
4422 (match_operand:MODEF 1 "nonimmediate_operand" "fm,f")))]
4424 "* return output_387_reg_move (insn, operands);"
4425 [(set_attr "type" "fmov")
4426 (set_attr "mode" "<MODE>,XF")])
4428 ;; %%% This seems like bad news.
4429 ;; This cannot output into an f-reg because there is no way to be sure
4430 ;; of truncating in that case. Otherwise this is just like a simple move
4431 ;; insn. So we pretend we can output to a reg in order to get better
4432 ;; register preferencing, but we really use a stack slot.
4434 ;; Conversion from DFmode to SFmode.
4436 (define_insn "truncdfsf2"
4437 [(set (match_operand:SF 0 "nonimm_ssenomem_operand" "=m,f,v,v")
4439 (match_operand:DF 1 "register_ssemem_operand" "f,f,v,m")))]
4440 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4442 switch (which_alternative)
4446 return output_387_reg_move (insn, operands);
4449 return "%vcvtsd2ss\t{%d1, %0|%0, %d1}";
4451 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4457 [(set_attr "type" "fmov,fmov,ssecvt,ssecvt")
4458 (set_attr "avx_partial_xmm_update" "false,false,false,true")
4459 (set_attr "mode" "SF")
4460 (set (attr "enabled")
4462 (match_test ("TARGET_SSE2 && TARGET_SSE_MATH"))
4463 (cond [(eq_attr "alternative" "0")
4464 (symbol_ref "TARGET_MIX_SSE_I387")
4465 (eq_attr "alternative" "1")
4466 (symbol_ref "TARGET_MIX_SSE_I387
4467 && flag_unsafe_math_optimizations")
4469 (symbol_ref "true"))
4470 (cond [(eq_attr "alternative" "0")
4472 (eq_attr "alternative" "1")
4473 (symbol_ref "flag_unsafe_math_optimizations")
4475 (symbol_ref "false"))))])
4477 /* For converting DF(xmm2) to SF(xmm1), use the following code instead of
4479 unpcklpd xmm2,xmm2 ; packed conversion might crash on signaling NaNs
4481 We do the conversion post reload to avoid producing of 128bit spills
4482 that might lead to ICE on 32bit target. The sequence unlikely combine
4485 [(set (match_operand:SF 0 "sse_reg_operand")
4487 (match_operand:DF 1 "nonimmediate_operand")))]
4488 "TARGET_USE_VECTOR_FP_CONVERTS
4489 && optimize_insn_for_speed_p ()
4491 && (!EXT_REX_SSE_REG_P (operands[0])
4492 || TARGET_AVX512VL)"
4495 (float_truncate:V2SF
4499 operands[2] = lowpart_subreg (V4SFmode, operands[0], SFmode);
4500 operands[3] = CONST0_RTX (V2SFmode);
4501 operands[4] = lowpart_subreg (V2DFmode, operands[0], SFmode);
4502 /* Use movsd for loading from memory, unpcklpd for registers.
4503 Try to avoid move when unpacking can be done in source, or SSE3
4504 movddup is available. */
4505 if (REG_P (operands[1]))
4508 && REGNO (operands[0]) != REGNO (operands[1]))
4510 rtx tmp = lowpart_subreg (DFmode, operands[0], SFmode);
4511 emit_move_insn (tmp, operands[1]);
4514 else if (!TARGET_SSE3)
4515 operands[4] = lowpart_subreg (V2DFmode, operands[1], DFmode);
4516 emit_insn (gen_vec_dupv2df (operands[4], operands[1]));
4519 emit_insn (gen_vec_concatv2df (operands[4], operands[1],
4520 CONST0_RTX (DFmode)));
4523 ;; It's more profitable to split and then truncate in the same register.
4525 [(set (match_operand:SF 0 "sse_reg_operand")
4527 (match_operand:DF 1 "memory_operand")))]
4528 "TARGET_SPLIT_MEM_OPND_FOR_FP_CONVERTS
4529 && optimize_insn_for_speed_p ()"
4530 [(set (match_dup 2) (match_dup 1))
4531 (set (match_dup 0) (float_truncate:SF (match_dup 2)))]
4532 "operands[2] = lowpart_subreg (DFmode, operands[0], SFmode);")
4534 ;; Break partial SSE register dependency stall. This splitter should split
4535 ;; late in the pass sequence (after register rename pass), so allocated
4536 ;; registers won't change anymore
4539 [(set (match_operand:SF 0 "sse_reg_operand")
4541 (match_operand:DF 1 "nonimmediate_operand")))]
4543 && TARGET_SSE_PARTIAL_REG_DEPENDENCY && epilogue_completed
4544 && optimize_function_for_speed_p (cfun)
4545 && (!REG_P (operands[1])
4546 || (!TARGET_AVX && REGNO (operands[0]) != REGNO (operands[1])))
4547 && (!EXT_REX_SSE_REG_P (operands[0])
4548 || TARGET_AVX512VL)"
4557 operands[0] = lowpart_subreg (V4SFmode, operands[0], SFmode);
4558 emit_move_insn (operands[0], CONST0_RTX (V4SFmode));
4561 ;; Conversion from XFmode to {SF,DF}mode
4563 (define_insn "truncxf<mode>2"
4564 [(set (match_operand:MODEF 0 "nonimmediate_operand" "=m,f")
4565 (float_truncate:MODEF
4566 (match_operand:XF 1 "register_operand" "f,f")))]
4568 "* return output_387_reg_move (insn, operands);"
4569 [(set_attr "type" "fmov")
4570 (set_attr "mode" "<MODE>")
4571 (set (attr "enabled")
4572 (cond [(eq_attr "alternative" "1")
4573 (symbol_ref "flag_unsafe_math_optimizations")
4575 (symbol_ref "true")))])
4577 ;; Signed conversion to DImode.
4579 (define_expand "fix_truncxfdi2"
4580 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand")
4581 (fix:DI (match_operand:XF 1 "register_operand")))
4582 (clobber (reg:CC FLAGS_REG))])]
4587 emit_insn (gen_fix_truncdi_i387_fisttp (operands[0], operands[1]));
4592 (define_expand "fix_trunc<mode>di2"
4593 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand")
4594 (fix:DI (match_operand:MODEF 1 "register_operand")))
4595 (clobber (reg:CC FLAGS_REG))])]
4596 "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4599 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4601 emit_insn (gen_fix_truncdi_i387_fisttp (operands[0], operands[1]));
4604 if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4606 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4607 emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4608 if (out != operands[0])
4609 emit_move_insn (operands[0], out);
4614 ;; Signed conversion to SImode.
4616 (define_expand "fix_truncxfsi2"
4617 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand")
4618 (fix:SI (match_operand:XF 1 "register_operand")))
4619 (clobber (reg:CC FLAGS_REG))])]
4624 emit_insn (gen_fix_truncsi_i387_fisttp (operands[0], operands[1]));
4629 (define_expand "fix_trunc<mode>si2"
4630 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand")
4631 (fix:SI (match_operand:MODEF 1 "register_operand")))
4632 (clobber (reg:CC FLAGS_REG))])]
4633 "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4636 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4638 emit_insn (gen_fix_truncsi_i387_fisttp (operands[0], operands[1]));
4641 if (SSE_FLOAT_MODE_P (<MODE>mode))
4643 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4644 emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4645 if (out != operands[0])
4646 emit_move_insn (operands[0], out);
4651 ;; Signed conversion to HImode.
4653 (define_expand "fix_trunc<mode>hi2"
4654 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand")
4655 (fix:HI (match_operand:X87MODEF 1 "register_operand")))
4656 (clobber (reg:CC FLAGS_REG))])]
4658 && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4662 emit_insn (gen_fix_trunchi_i387_fisttp (operands[0], operands[1]));
4667 ;; Unsigned conversion to DImode
4669 (define_insn "fixuns_trunc<mode>di2"
4670 [(set (match_operand:DI 0 "register_operand" "=r")
4672 (match_operand:MODEF 1 "nonimmediate_operand" "vm")))]
4673 "TARGET_64BIT && TARGET_AVX512F && TARGET_SSE_MATH"
4674 "vcvtt<ssemodesuffix>2usi\t{%1, %0|%0, %1}"
4675 [(set_attr "type" "sseicvt")
4676 (set_attr "prefix" "evex")
4677 (set_attr "mode" "DI")])
4679 ;; Unsigned conversion to SImode.
4681 (define_expand "fixuns_trunc<mode>si2"
4683 [(set (match_operand:SI 0 "register_operand")
4685 (match_operand:MODEF 1 "nonimmediate_operand")))
4687 (clobber (scratch:<ssevecmode>))
4688 (clobber (scratch:<ssevecmode>))])]
4689 "(!TARGET_64BIT || TARGET_AVX512F) && TARGET_SSE2 && TARGET_SSE_MATH"
4691 machine_mode mode = <MODE>mode;
4692 machine_mode vecmode = <ssevecmode>mode;
4693 REAL_VALUE_TYPE TWO31r;
4698 emit_insn (gen_fixuns_trunc<mode>si2_avx512f (operands[0], operands[1]));
4702 if (optimize_insn_for_size_p ())
4705 real_ldexp (&TWO31r, &dconst1, 31);
4706 two31 = const_double_from_real_value (TWO31r, mode);
4707 two31 = ix86_build_const_vector (vecmode, true, two31);
4708 operands[2] = force_reg (vecmode, two31);
4711 (define_insn "fixuns_trunc<mode>si2_avx512f"
4712 [(set (match_operand:SI 0 "register_operand" "=r")
4714 (match_operand:MODEF 1 "nonimmediate_operand" "vm")))]
4715 "TARGET_AVX512F && TARGET_SSE_MATH"
4716 "vcvtt<ssemodesuffix>2usi\t{%1, %0|%0, %1}"
4717 [(set_attr "type" "sseicvt")
4718 (set_attr "prefix" "evex")
4719 (set_attr "mode" "SI")])
4721 (define_insn "*fixuns_trunc<mode>si2_avx512f_zext"
4722 [(set (match_operand:DI 0 "register_operand" "=r")
4725 (match_operand:MODEF 1 "nonimmediate_operand" "vm"))))]
4726 "TARGET_64BIT && TARGET_AVX512F && TARGET_SSE_MATH"
4727 "vcvtt<ssemodesuffix>2usi\t{%1, %k0|%k0, %1}"
4728 [(set_attr "type" "sseicvt")
4729 (set_attr "prefix" "evex")
4730 (set_attr "mode" "SI")])
4732 (define_insn_and_split "*fixuns_trunc<mode>_1"
4733 [(set (match_operand:SI 0 "register_operand" "=&x,&x")
4735 (match_operand:MODEF 3 "nonimmediate_operand" "xm,xm")))
4736 (use (match_operand:<ssevecmode> 4 "nonimmediate_operand" "m,x"))
4737 (clobber (match_scratch:<ssevecmode> 1 "=x,&x"))
4738 (clobber (match_scratch:<ssevecmode> 2 "=x,x"))]
4739 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH
4740 && optimize_function_for_speed_p (cfun)"
4742 "&& reload_completed"
4745 ix86_split_convert_uns_si_sse (operands);
4749 ;; Unsigned conversion to HImode.
4750 ;; Without these patterns, we'll try the unsigned SI conversion which
4751 ;; is complex for SSE, rather than the signed SI conversion, which isn't.
4753 (define_expand "fixuns_trunc<mode>hi2"
4755 (fix:SI (match_operand:MODEF 1 "nonimmediate_operand")))
4756 (set (match_operand:HI 0 "nonimmediate_operand")
4757 (subreg:HI (match_dup 2) 0))]
4758 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
4759 "operands[2] = gen_reg_rtx (SImode);")
4761 ;; When SSE is available, it is always faster to use it!
4762 (define_insn "fix_trunc<MODEF:mode><SWI48:mode>_sse"
4763 [(set (match_operand:SWI48 0 "register_operand" "=r,r")
4764 (fix:SWI48 (match_operand:MODEF 1 "nonimmediate_operand" "v,m")))]
4765 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode)
4766 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4767 "%vcvtt<MODEF:ssemodesuffix>2si<SWI48:rex64suffix>\t{%1, %0|%0, %1}"
4768 [(set_attr "type" "sseicvt")
4769 (set_attr "prefix" "maybe_vex")
4770 (set (attr "prefix_rex")
4772 (match_test "<SWI48:MODE>mode == DImode")
4774 (const_string "*")))
4775 (set_attr "mode" "<MODEF:MODE>")
4776 (set_attr "athlon_decode" "double,vector")
4777 (set_attr "amdfam10_decode" "double,double")
4778 (set_attr "bdver1_decode" "double,double")])
4780 ;; Avoid vector decoded forms of the instruction.
4782 [(match_scratch:MODEF 2 "x")
4783 (set (match_operand:SWI48 0 "register_operand")
4784 (fix:SWI48 (match_operand:MODEF 1 "memory_operand")))]
4785 "TARGET_AVOID_VECTOR_DECODE
4786 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode)
4787 && optimize_insn_for_speed_p ()"
4788 [(set (match_dup 2) (match_dup 1))
4789 (set (match_dup 0) (fix:SWI48 (match_dup 2)))])
4791 (define_insn "fix_trunc<mode>_i387_fisttp"
4792 [(set (match_operand:SWI248x 0 "nonimmediate_operand" "=m")
4793 (fix:SWI248x (match_operand 1 "register_operand" "f")))
4794 (clobber (match_scratch:XF 2 "=&f"))]
4795 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4797 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4798 && (TARGET_64BIT || <MODE>mode != DImode))
4799 && TARGET_SSE_MATH)"
4800 "* return output_fix_trunc (insn, operands, true);"
4801 [(set_attr "type" "fisttp")
4802 (set_attr "mode" "<MODE>")])
4804 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4805 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4806 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4807 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4808 ;; function in i386.c.
4809 (define_insn_and_split "*fix_trunc<mode>_i387_1"
4810 [(set (match_operand:SWI248x 0 "nonimmediate_operand")
4811 (fix:SWI248x (match_operand 1 "register_operand")))
4812 (clobber (reg:CC FLAGS_REG))]
4813 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4815 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4816 && (TARGET_64BIT || <MODE>mode != DImode))
4817 && ix86_pre_reload_split ()"
4822 ix86_optimize_mode_switching[I387_TRUNC] = 1;
4824 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
4825 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
4827 emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4828 operands[2], operands[3]));
4831 [(set_attr "type" "fistp")
4832 (set_attr "i387_cw" "trunc")
4833 (set_attr "mode" "<MODE>")])
4835 (define_insn "fix_truncdi_i387"
4836 [(set (match_operand:DI 0 "nonimmediate_operand" "=m")
4837 (fix:DI (match_operand 1 "register_operand" "f")))
4838 (use (match_operand:HI 2 "memory_operand" "m"))
4839 (use (match_operand:HI 3 "memory_operand" "m"))
4840 (clobber (match_scratch:XF 4 "=&f"))]
4841 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4843 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4844 "* return output_fix_trunc (insn, operands, false);"
4845 [(set_attr "type" "fistp")
4846 (set_attr "i387_cw" "trunc")
4847 (set_attr "mode" "DI")])
4849 (define_insn "fix_trunc<mode>_i387"
4850 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m")
4851 (fix:SWI24 (match_operand 1 "register_operand" "f")))
4852 (use (match_operand:HI 2 "memory_operand" "m"))
4853 (use (match_operand:HI 3 "memory_operand" "m"))]
4854 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4856 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4857 "* return output_fix_trunc (insn, operands, false);"
4858 [(set_attr "type" "fistp")
4859 (set_attr "i387_cw" "trunc")
4860 (set_attr "mode" "<MODE>")])
4862 (define_insn "x86_fnstcw_1"
4863 [(set (match_operand:HI 0 "memory_operand" "=m")
4864 (unspec:HI [(const_int 0)] UNSPEC_FSTCW))]
4867 [(set (attr "length")
4868 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
4869 (set_attr "mode" "HI")
4870 (set_attr "unit" "i387")
4871 (set_attr "bdver1_decode" "vector")])
4873 ;; Conversion between fixed point and floating point.
4875 ;; Even though we only accept memory inputs, the backend _really_
4876 ;; wants to be able to do this between registers. Thankfully, LRA
4877 ;; will fix this up for us during register allocation.
4879 (define_insn "floathi<mode>2"
4880 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
4881 (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "m")))]
4883 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4884 || TARGET_MIX_SSE_I387)"
4886 [(set_attr "type" "fmov")
4887 (set_attr "mode" "<MODE>")
4888 (set_attr "znver1_decode" "double")
4889 (set_attr "fp_int_src" "true")])
4891 (define_insn "float<SWI48x:mode>xf2"
4892 [(set (match_operand:XF 0 "register_operand" "=f")
4893 (float:XF (match_operand:SWI48x 1 "nonimmediate_operand" "m")))]
4896 [(set_attr "type" "fmov")
4897 (set_attr "mode" "XF")
4898 (set_attr "znver1_decode" "double")
4899 (set_attr "fp_int_src" "true")])
4901 (define_expand "float<SWI48x:mode><MODEF:mode>2"
4902 [(set (match_operand:MODEF 0 "register_operand")
4903 (float:MODEF (match_operand:SWI48x 1 "nonimmediate_operand")))]
4904 "(TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI48x:MODE>mode))
4905 || (SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
4906 && ((<SWI48x:MODE>mode != DImode) || TARGET_64BIT))")
4908 (define_insn "*float<SWI48:mode><MODEF:mode>2"
4909 [(set (match_operand:MODEF 0 "register_operand" "=f,v,v")
4911 (match_operand:SWI48 1 "nonimmediate_operand" "m,r,m")))]
4912 "(TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI48:MODE>mode))
4913 || (SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)"
4916 %vcvtsi2<MODEF:ssemodesuffix><SWI48:rex64suffix>\t{%1, %d0|%d0, %1}
4917 %vcvtsi2<MODEF:ssemodesuffix><SWI48:rex64suffix>\t{%1, %d0|%d0, %1}"
4918 [(set_attr "type" "fmov,sseicvt,sseicvt")
4919 (set_attr "avx_partial_xmm_update" "false,true,true")
4920 (set_attr "prefix" "orig,maybe_vex,maybe_vex")
4921 (set_attr "mode" "<MODEF:MODE>")
4922 (set (attr "prefix_rex")
4924 (and (eq_attr "prefix" "maybe_vex")
4925 (match_test "<SWI48:MODE>mode == DImode"))
4927 (const_string "*")))
4928 (set_attr "unit" "i387,*,*")
4929 (set_attr "athlon_decode" "*,double,direct")
4930 (set_attr "amdfam10_decode" "*,vector,double")
4931 (set_attr "bdver1_decode" "*,double,direct")
4932 (set_attr "znver1_decode" "double,*,*")
4933 (set_attr "fp_int_src" "true")
4934 (set (attr "enabled")
4936 (match_test ("SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"))
4938 (eq_attr "alternative" "0")
4939 (symbol_ref "TARGET_MIX_SSE_I387
4940 && X87_ENABLE_FLOAT (<MODEF:MODE>mode,
4942 (symbol_ref "true"))
4944 (eq_attr "alternative" "0")
4946 (symbol_ref "false"))))
4947 (set (attr "preferred_for_speed")
4948 (cond [(eq_attr "alternative" "1")
4949 (symbol_ref "TARGET_INTER_UNIT_CONVERSIONS")]
4950 (symbol_ref "true")))])
4952 (define_insn "*floatdi<MODEF:mode>2_i387"
4953 [(set (match_operand:MODEF 0 "register_operand" "=f")
4954 (float:MODEF (match_operand:DI 1 "nonimmediate_operand" "m")))]
4956 && TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, DImode)"
4958 [(set_attr "type" "fmov")
4959 (set_attr "mode" "<MODEF:MODE>")
4960 (set_attr "znver1_decode" "double")
4961 (set_attr "fp_int_src" "true")])
4963 ;; Try TARGET_USE_VECTOR_CONVERTS, but not so hard as to require extra memory
4964 ;; slots when !TARGET_INTER_UNIT_MOVES_TO_VEC disables the general_regs
4965 ;; alternative in sse2_loadld.
4967 [(set (match_operand:MODEF 0 "sse_reg_operand")
4968 (float:MODEF (match_operand:SI 1 "nonimmediate_operand")))]
4970 && TARGET_USE_VECTOR_CONVERTS
4971 && optimize_function_for_speed_p (cfun)
4973 && (MEM_P (operands[1]) || TARGET_INTER_UNIT_MOVES_TO_VEC)
4974 && (!EXT_REX_SSE_REG_P (operands[0])
4975 || TARGET_AVX512VL)"
4978 operands[3] = lowpart_subreg (<ssevecmode>mode, operands[0], <MODE>mode);
4979 operands[4] = lowpart_subreg (V4SImode, operands[0], <MODE>mode);
4981 emit_insn (gen_sse2_loadld (operands[4],
4982 CONST0_RTX (V4SImode), operands[1]));
4984 if (<ssevecmode>mode == V4SFmode)
4985 emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
4987 emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
4991 ;; Avoid store forwarding (partial memory) stall penalty
4992 ;; by passing DImode value through XMM registers. */
4995 [(set (match_operand:X87MODEF 0 "register_operand")
4997 (match_operand:DI 1 "register_operand")))]
4998 "!TARGET_64BIT && TARGET_INTER_UNIT_MOVES_TO_VEC
4999 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5000 && TARGET_SSE2 && optimize_function_for_speed_p (cfun)
5001 && can_create_pseudo_p ()"
5004 emit_insn (gen_floatdi<mode>2_i387_with_xmm
5005 (operands[0], operands[1],
5006 assign_386_stack_local (DImode, SLOT_TEMP)));
5010 (define_insn_and_split "floatdi<X87MODEF:mode>2_i387_with_xmm"
5011 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5013 (match_operand:DI 1 "register_operand" "r,r")))
5014 (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
5015 (clobber (match_scratch:V4SI 3 "=x,x"))
5016 (clobber (match_scratch:V4SI 4 "=X,x"))]
5017 "!TARGET_64BIT && TARGET_INTER_UNIT_MOVES_TO_VEC
5018 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5019 && TARGET_SSE2 && optimize_function_for_speed_p (cfun)"
5021 "&& reload_completed"
5022 [(set (match_dup 2) (match_dup 3))
5023 (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5025 /* The DImode arrived in a pair of integral registers (e.g. %edx:%eax).
5026 Assemble the 64-bit DImode value in an xmm register. */
5027 emit_insn (gen_sse2_loadld (operands[3], CONST0_RTX (V4SImode),
5028 gen_lowpart (SImode, operands[1])));
5030 emit_insn (gen_sse4_1_pinsrd (operands[3], operands[3],
5031 gen_highpart (SImode, operands[1]),
5035 emit_insn (gen_sse2_loadld (operands[4], CONST0_RTX (V4SImode),
5036 gen_highpart (SImode, operands[1])));
5037 emit_insn (gen_vec_interleave_lowv4si (operands[3], operands[3],
5040 operands[3] = gen_lowpart (DImode, operands[3]);
5042 [(set_attr "isa" "sse4,*")
5043 (set_attr "type" "multi")
5044 (set_attr "mode" "<X87MODEF:MODE>")
5045 (set_attr "unit" "i387")
5046 (set_attr "fp_int_src" "true")])
5048 ;; Break partial SSE register dependency stall. This splitter should split
5049 ;; late in the pass sequence (after register rename pass), so allocated
5050 ;; registers won't change anymore
5053 [(set (match_operand:MODEF 0 "sse_reg_operand")
5054 (float:MODEF (match_operand:SWI48 1 "nonimmediate_operand")))]
5056 && TARGET_SSE_PARTIAL_REG_DEPENDENCY && epilogue_completed
5057 && optimize_function_for_speed_p (cfun)
5058 && (!EXT_REX_SSE_REG_P (operands[0])
5059 || TARGET_AVX512VL)"
5061 (vec_merge:<MODEF:ssevecmode>
5062 (vec_duplicate:<MODEF:ssevecmode>
5068 const machine_mode vmode = <MODEF:ssevecmode>mode;
5070 operands[0] = lowpart_subreg (vmode, operands[0], <MODEF:MODE>mode);
5071 emit_move_insn (operands[0], CONST0_RTX (vmode));
5074 (define_expand "floatuns<SWI12:mode><MODEF:mode>2"
5075 [(set (match_operand:MODEF 0 "register_operand")
5076 (unsigned_float:MODEF
5077 (match_operand:SWI12 1 "nonimmediate_operand")))]
5079 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
5081 operands[1] = convert_to_mode (SImode, operands[1], 1);
5082 emit_insn (gen_floatsi<MODEF:mode>2 (operands[0], operands[1]));
5086 (define_insn "*floatuns<SWI48:mode><MODEF:mode>2_avx512"
5087 [(set (match_operand:MODEF 0 "register_operand" "=v")
5088 (unsigned_float:MODEF
5089 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))]
5090 "TARGET_AVX512F && TARGET_SSE_MATH"
5091 "vcvtusi2<MODEF:ssemodesuffix><SWI48:rex64suffix>\t{%1, %0, %0|%0, %0, %1}"
5092 [(set_attr "type" "sseicvt")
5093 (set_attr "avx_partial_xmm_update" "true")
5094 (set_attr "prefix" "evex")
5095 (set_attr "mode" "<MODEF:MODE>")])
5097 ;; Avoid store forwarding (partial memory) stall penalty by extending
5098 ;; SImode value to DImode through XMM register instead of pushing two
5099 ;; SImode values to stack. Also note that fild loads from memory only.
5101 (define_insn_and_split "floatunssi<mode>2_i387_with_xmm"
5102 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5103 (unsigned_float:X87MODEF
5104 (match_operand:SI 1 "nonimmediate_operand" "rm")))
5105 (clobber (match_operand:DI 2 "memory_operand" "=m"))
5106 (clobber (match_scratch:DI 3 "=x"))]
5108 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5109 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC"
5111 "&& reload_completed"
5112 [(set (match_dup 3) (zero_extend:DI (match_dup 1)))
5113 (set (match_dup 2) (match_dup 3))
5115 (float:X87MODEF (match_dup 2)))]
5117 [(set_attr "type" "multi")
5118 (set_attr "mode" "<MODE>")])
5120 (define_expand "floatunssi<mode>2"
5121 [(set (match_operand:X87MODEF 0 "register_operand")
5122 (unsigned_float:X87MODEF
5123 (match_operand:SI 1 "nonimmediate_operand")))]
5125 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5126 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC)
5127 || ((!TARGET_64BIT || TARGET_AVX512F)
5128 && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
5130 if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
5132 emit_insn (gen_floatunssi<mode>2_i387_with_xmm
5133 (operands[0], operands[1],
5134 assign_386_stack_local (DImode, SLOT_TEMP)));
5137 if (!TARGET_AVX512F)
5139 ix86_expand_convert_uns_si<mode>_sse (operands[0], operands[1]);
5144 (define_expand "floatunsdisf2"
5145 [(set (match_operand:SF 0 "register_operand")
5147 (match_operand:DI 1 "nonimmediate_operand")))]
5148 "TARGET_64BIT && TARGET_SSE && TARGET_SSE_MATH"
5150 if (!TARGET_AVX512F)
5152 x86_emit_floatuns (operands);
5157 (define_expand "floatunsdidf2"
5158 [(set (match_operand:DF 0 "register_operand")
5160 (match_operand:DI 1 "nonimmediate_operand")))]
5161 "((TARGET_64BIT && TARGET_AVX512F)
5162 || TARGET_KEEPS_VECTOR_ALIGNED_STACK)
5163 && TARGET_SSE2 && TARGET_SSE_MATH"
5167 ix86_expand_convert_uns_didf_sse (operands[0], operands[1]);
5170 if (!TARGET_AVX512F)
5172 x86_emit_floatuns (operands);
5177 ;; Load effective address instructions
5179 (define_insn_and_split "*lea<mode>"
5180 [(set (match_operand:SWI48 0 "register_operand" "=r")
5181 (match_operand:SWI48 1 "address_no_seg_operand" "Ts"))]
5182 "ix86_hardreg_mov_ok (operands[0], operands[1])"
5184 if (SImode_address_operand (operands[1], VOIDmode))
5186 gcc_assert (TARGET_64BIT);
5187 return "lea{l}\t{%E1, %k0|%k0, %E1}";
5190 return "lea{<imodesuffix>}\t{%E1, %0|%0, %E1}";
5192 "reload_completed && ix86_avoid_lea_for_addr (insn, operands)"
5195 machine_mode mode = <MODE>mode;
5198 /* ix86_avoid_lea_for_addr re-recognizes insn and may
5199 change operands[] array behind our back. */
5200 pat = PATTERN (curr_insn);
5202 operands[0] = SET_DEST (pat);
5203 operands[1] = SET_SRC (pat);
5205 /* Emit all operations in SImode for zero-extended addresses. */
5206 if (SImode_address_operand (operands[1], VOIDmode))
5209 ix86_split_lea_for_addr (curr_insn, operands, mode);
5211 /* Zero-extend return register to DImode for zero-extended addresses. */
5212 if (mode != <MODE>mode)
5213 emit_insn (gen_zero_extendsidi2
5214 (operands[0], gen_lowpart (mode, operands[0])));
5218 [(set_attr "type" "lea")
5221 (match_operand 1 "SImode_address_operand")
5223 (const_string "<MODE>")))])
5227 (define_expand "add<mode>3"
5228 [(set (match_operand:SDWIM 0 "nonimmediate_operand")
5229 (plus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")
5230 (match_operand:SDWIM 2 "<general_hilo_operand>")))]
5232 "ix86_expand_binary_operator (PLUS, <MODE>mode, operands); DONE;")
5234 (define_insn_and_split "*add<dwi>3_doubleword"
5235 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro,r")
5237 (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0")
5238 (match_operand:<DWI> 2 "x86_64_hilo_general_operand" "r<di>,o")))
5239 (clobber (reg:CC FLAGS_REG))]
5240 "ix86_binary_operator_ok (PLUS, <DWI>mode, operands)"
5243 [(parallel [(set (reg:CCC FLAGS_REG)
5245 (plus:DWIH (match_dup 1) (match_dup 2))
5248 (plus:DWIH (match_dup 1) (match_dup 2)))])
5249 (parallel [(set (match_dup 3)
5252 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
5255 (clobber (reg:CC FLAGS_REG))])]
5257 split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
5258 if (operands[2] == const0_rtx)
5260 ix86_expand_binary_operator (PLUS, <MODE>mode, &operands[3]);
5265 (define_insn "*add<mode>_1"
5266 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r,r,r")
5268 (match_operand:SWI48 1 "nonimmediate_operand" "%0,0,r,r")
5269 (match_operand:SWI48 2 "x86_64_general_operand" "re,m,0,le")))
5270 (clobber (reg:CC FLAGS_REG))]
5271 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5273 switch (get_attr_type (insn))
5279 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5280 if (operands[2] == const1_rtx)
5281 return "inc{<imodesuffix>}\t%0";
5284 gcc_assert (operands[2] == constm1_rtx);
5285 return "dec{<imodesuffix>}\t%0";
5289 /* For most processors, ADD is faster than LEA. This alternative
5290 was added to use ADD as much as possible. */
5291 if (which_alternative == 2)
5292 std::swap (operands[1], operands[2]);
5294 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5295 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5296 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5298 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5302 (cond [(eq_attr "alternative" "3")
5303 (const_string "lea")
5304 (match_operand:SWI48 2 "incdec_operand")
5305 (const_string "incdec")
5307 (const_string "alu")))
5308 (set (attr "length_immediate")
5310 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5312 (const_string "*")))
5313 (set_attr "mode" "<MODE>")])
5315 ;; It may seem that nonimmediate operand is proper one for operand 1.
5316 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5317 ;; we take care in ix86_binary_operator_ok to not allow two memory
5318 ;; operands so proper swapping will be done in reload. This allow
5319 ;; patterns constructed from addsi_1 to match.
5321 (define_insn "addsi_1_zext"
5322 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
5324 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r,r")
5325 (match_operand:SI 2 "x86_64_general_operand" "rme,0,le"))))
5326 (clobber (reg:CC FLAGS_REG))]
5327 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5329 switch (get_attr_type (insn))
5335 if (operands[2] == const1_rtx)
5336 return "inc{l}\t%k0";
5339 gcc_assert (operands[2] == constm1_rtx);
5340 return "dec{l}\t%k0";
5344 /* For most processors, ADD is faster than LEA. This alternative
5345 was added to use ADD as much as possible. */
5346 if (which_alternative == 1)
5347 std::swap (operands[1], operands[2]);
5349 if (x86_maybe_negate_const_int (&operands[2], SImode))
5350 return "sub{l}\t{%2, %k0|%k0, %2}";
5352 return "add{l}\t{%2, %k0|%k0, %2}";
5356 (cond [(eq_attr "alternative" "2")
5357 (const_string "lea")
5358 (match_operand:SI 2 "incdec_operand")
5359 (const_string "incdec")
5361 (const_string "alu")))
5362 (set (attr "length_immediate")
5364 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5366 (const_string "*")))
5367 (set_attr "mode" "SI")])
5369 (define_insn "*addhi_1"
5370 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r,Yp")
5371 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r,Yp")
5372 (match_operand:HI 2 "general_operand" "rn,m,0,ln")))
5373 (clobber (reg:CC FLAGS_REG))]
5374 "ix86_binary_operator_ok (PLUS, HImode, operands)"
5376 switch (get_attr_type (insn))
5382 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5383 if (operands[2] == const1_rtx)
5384 return "inc{w}\t%0";
5387 gcc_assert (operands[2] == constm1_rtx);
5388 return "dec{w}\t%0";
5392 /* For most processors, ADD is faster than LEA. This alternative
5393 was added to use ADD as much as possible. */
5394 if (which_alternative == 2)
5395 std::swap (operands[1], operands[2]);
5397 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5398 if (x86_maybe_negate_const_int (&operands[2], HImode))
5399 return "sub{w}\t{%2, %0|%0, %2}";
5401 return "add{w}\t{%2, %0|%0, %2}";
5405 (cond [(eq_attr "alternative" "3")
5406 (const_string "lea")
5407 (match_operand:HI 2 "incdec_operand")
5408 (const_string "incdec")
5410 (const_string "alu")))
5411 (set (attr "length_immediate")
5413 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5415 (const_string "*")))
5416 (set_attr "mode" "HI,HI,HI,SI")])
5418 (define_insn "*addqi_1"
5419 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,q,r,r,Yp")
5420 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,q,0,r,Yp")
5421 (match_operand:QI 2 "general_operand" "qn,m,0,rn,0,ln")))
5422 (clobber (reg:CC FLAGS_REG))]
5423 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5425 bool widen = (get_attr_mode (insn) != MODE_QI);
5427 switch (get_attr_type (insn))
5433 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5434 if (operands[2] == const1_rtx)
5435 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
5438 gcc_assert (operands[2] == constm1_rtx);
5439 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
5443 /* For most processors, ADD is faster than LEA. These alternatives
5444 were added to use ADD as much as possible. */
5445 if (which_alternative == 2 || which_alternative == 4)
5446 std::swap (operands[1], operands[2]);
5448 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5449 if (x86_maybe_negate_const_int (&operands[2], QImode))
5452 return "sub{l}\t{%2, %k0|%k0, %2}";
5454 return "sub{b}\t{%2, %0|%0, %2}";
5457 return "add{l}\t{%k2, %k0|%k0, %k2}";
5459 return "add{b}\t{%2, %0|%0, %2}";
5463 (cond [(eq_attr "alternative" "5")
5464 (const_string "lea")
5465 (match_operand:QI 2 "incdec_operand")
5466 (const_string "incdec")
5468 (const_string "alu")))
5469 (set (attr "length_immediate")
5471 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5473 (const_string "*")))
5474 (set_attr "mode" "QI,QI,QI,SI,SI,SI")
5475 ;; Potential partial reg stall on alternatives 3 and 4.
5476 (set (attr "preferred_for_speed")
5477 (cond [(eq_attr "alternative" "3,4")
5478 (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
5479 (symbol_ref "true")))])
5481 (define_insn "*add<mode>_1_slp"
5482 [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>"))
5483 (plus:SWI12 (match_operand:SWI12 1 "nonimmediate_operand" "%0")
5484 (match_operand:SWI12 2 "general_operand" "<r>mn")))
5485 (clobber (reg:CC FLAGS_REG))]
5486 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
5487 /* FIXME: without this LRA can't reload this pattern, see PR82524. */
5488 && (rtx_equal_p (operands[0], operands[1])
5489 || rtx_equal_p (operands[0], operands[2]))"
5491 switch (get_attr_type (insn))
5494 if (operands[2] == const1_rtx)
5495 return "inc{<imodesuffix>}\t%0";
5498 gcc_assert (operands[2] == constm1_rtx);
5499 return "dec{<imodesuffix>}\t%0";
5503 if (x86_maybe_negate_const_int (&operands[2], QImode))
5504 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5506 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5510 (if_then_else (match_operand:QI 2 "incdec_operand")
5511 (const_string "incdec")
5512 (const_string "alu")))
5513 (set_attr "mode" "<MODE>")])
5515 ;; Split non destructive adds if we cannot use lea.
5517 [(set (match_operand:SWI48 0 "register_operand")
5518 (plus:SWI48 (match_operand:SWI48 1 "register_operand")
5519 (match_operand:SWI48 2 "x86_64_nonmemory_operand")))
5520 (clobber (reg:CC FLAGS_REG))]
5521 "reload_completed && ix86_avoid_lea_for_add (insn, operands)"
5522 [(set (match_dup 0) (match_dup 1))
5523 (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 2)))
5524 (clobber (reg:CC FLAGS_REG))])])
5526 ;; Split non destructive adds if we cannot use lea.
5528 [(set (match_operand:DI 0 "register_operand")
5530 (plus:SI (match_operand:SI 1 "register_operand")
5531 (match_operand:SI 2 "x86_64_nonmemory_operand"))))
5532 (clobber (reg:CC FLAGS_REG))]
5534 && reload_completed && ix86_avoid_lea_for_add (insn, operands)"
5535 [(set (match_dup 3) (match_dup 1))
5536 (parallel [(set (match_dup 0)
5537 (zero_extend:DI (plus:SI (match_dup 3) (match_dup 2))))
5538 (clobber (reg:CC FLAGS_REG))])]
5539 "operands[3] = gen_lowpart (SImode, operands[0]);")
5541 ;; Convert add to the lea pattern to avoid flags dependency.
5543 [(set (match_operand:SWI 0 "register_operand")
5544 (plus:SWI (match_operand:SWI 1 "register_operand")
5545 (match_operand:SWI 2 "<nonmemory_operand>")))
5546 (clobber (reg:CC FLAGS_REG))]
5547 "reload_completed && ix86_lea_for_add_ok (insn, operands)"
5549 (plus:<LEAMODE> (match_dup 1) (match_dup 2)))]
5551 if (<MODE>mode != <LEAMODE>mode)
5553 operands[0] = gen_lowpart (<LEAMODE>mode, operands[0]);
5554 operands[1] = gen_lowpart (<LEAMODE>mode, operands[1]);
5555 operands[2] = gen_lowpart (<LEAMODE>mode, operands[2]);
5559 ;; Convert add to the lea pattern to avoid flags dependency.
5561 [(set (match_operand:DI 0 "register_operand")
5563 (plus:SI (match_operand:SI 1 "register_operand")
5564 (match_operand:SI 2 "x86_64_nonmemory_operand"))))
5565 (clobber (reg:CC FLAGS_REG))]
5566 "TARGET_64BIT && reload_completed && ix86_lea_for_add_ok (insn, operands)"
5568 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))])
5570 (define_insn "*add<mode>_2"
5571 [(set (reg FLAGS_REG)
5574 (match_operand:SWI 1 "nonimmediate_operand" "%0,0,<r>")
5575 (match_operand:SWI 2 "<general_operand>" "<r><i>,m,0"))
5577 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>,<r>")
5578 (plus:SWI (match_dup 1) (match_dup 2)))]
5579 "ix86_match_ccmode (insn, CCGOCmode)
5580 && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5582 switch (get_attr_type (insn))
5585 if (operands[2] == const1_rtx)
5586 return "inc{<imodesuffix>}\t%0";
5589 gcc_assert (operands[2] == constm1_rtx);
5590 return "dec{<imodesuffix>}\t%0";
5594 if (which_alternative == 2)
5595 std::swap (operands[1], operands[2]);
5597 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5598 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5599 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5601 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5605 (if_then_else (match_operand:SWI 2 "incdec_operand")
5606 (const_string "incdec")
5607 (const_string "alu")))
5608 (set (attr "length_immediate")
5610 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5612 (const_string "*")))
5613 (set_attr "mode" "<MODE>")])
5615 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5616 (define_insn "*addsi_2_zext"
5617 [(set (reg FLAGS_REG)
5619 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
5620 (match_operand:SI 2 "x86_64_general_operand" "rme,0"))
5622 (set (match_operand:DI 0 "register_operand" "=r,r")
5623 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5624 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5625 && ix86_binary_operator_ok (PLUS, SImode, operands)"
5627 switch (get_attr_type (insn))
5630 if (operands[2] == const1_rtx)
5631 return "inc{l}\t%k0";
5634 gcc_assert (operands[2] == constm1_rtx);
5635 return "dec{l}\t%k0";
5639 if (which_alternative == 1)
5640 std::swap (operands[1], operands[2]);
5642 if (x86_maybe_negate_const_int (&operands[2], SImode))
5643 return "sub{l}\t{%2, %k0|%k0, %2}";
5645 return "add{l}\t{%2, %k0|%k0, %2}";
5649 (if_then_else (match_operand:SI 2 "incdec_operand")
5650 (const_string "incdec")
5651 (const_string "alu")))
5652 (set (attr "length_immediate")
5654 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5656 (const_string "*")))
5657 (set_attr "mode" "SI")])
5659 (define_insn "*add<mode>_3"
5660 [(set (reg FLAGS_REG)
5662 (neg:SWI (match_operand:SWI 2 "<general_operand>" "<g>,0"))
5663 (match_operand:SWI 1 "nonimmediate_operand" "%0,<r>")))
5664 (clobber (match_scratch:SWI 0 "=<r>,<r>"))]
5665 "ix86_match_ccmode (insn, CCZmode)
5666 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
5668 switch (get_attr_type (insn))
5671 if (operands[2] == const1_rtx)
5672 return "inc{<imodesuffix>}\t%0";
5675 gcc_assert (operands[2] == constm1_rtx);
5676 return "dec{<imodesuffix>}\t%0";
5680 if (which_alternative == 1)
5681 std::swap (operands[1], operands[2]);
5683 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5684 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5685 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5687 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5691 (if_then_else (match_operand:SWI 2 "incdec_operand")
5692 (const_string "incdec")
5693 (const_string "alu")))
5694 (set (attr "length_immediate")
5696 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5698 (const_string "*")))
5699 (set_attr "mode" "<MODE>")])
5701 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5702 (define_insn "*addsi_3_zext"
5703 [(set (reg FLAGS_REG)
5705 (neg:SI (match_operand:SI 2 "x86_64_general_operand" "rme,0"))
5706 (match_operand:SI 1 "nonimmediate_operand" "%0,r")))
5707 (set (match_operand:DI 0 "register_operand" "=r,r")
5708 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5709 "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
5710 && ix86_binary_operator_ok (PLUS, SImode, operands)"
5712 switch (get_attr_type (insn))
5715 if (operands[2] == const1_rtx)
5716 return "inc{l}\t%k0";
5719 gcc_assert (operands[2] == constm1_rtx);
5720 return "dec{l}\t%k0";
5724 if (which_alternative == 1)
5725 std::swap (operands[1], operands[2]);
5727 if (x86_maybe_negate_const_int (&operands[2], SImode))
5728 return "sub{l}\t{%2, %k0|%k0, %2}";
5730 return "add{l}\t{%2, %k0|%k0, %2}";
5734 (if_then_else (match_operand:SI 2 "incdec_operand")
5735 (const_string "incdec")
5736 (const_string "alu")))
5737 (set (attr "length_immediate")
5739 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5741 (const_string "*")))
5742 (set_attr "mode" "SI")])
5744 ; For comparisons against 1, -1 and 128, we may generate better code
5745 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
5746 ; is matched then. We can't accept general immediate, because for
5747 ; case of overflows, the result is messed up.
5748 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5749 ; only for comparisons not depending on it.
5751 (define_insn "*adddi_4"
5752 [(set (reg FLAGS_REG)
5754 (match_operand:DI 1 "nonimmediate_operand" "0")
5755 (match_operand:DI 2 "x86_64_immediate_operand" "e")))
5756 (clobber (match_scratch:DI 0 "=r"))]
5758 && ix86_match_ccmode (insn, CCGCmode)"
5760 switch (get_attr_type (insn))
5763 if (operands[2] == constm1_rtx)
5764 return "inc{q}\t%0";
5767 gcc_assert (operands[2] == const1_rtx);
5768 return "dec{q}\t%0";
5772 if (x86_maybe_negate_const_int (&operands[2], DImode))
5773 return "add{q}\t{%2, %0|%0, %2}";
5775 return "sub{q}\t{%2, %0|%0, %2}";
5779 (if_then_else (match_operand:DI 2 "incdec_operand")
5780 (const_string "incdec")
5781 (const_string "alu")))
5782 (set (attr "length_immediate")
5784 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5786 (const_string "*")))
5787 (set_attr "mode" "DI")])
5789 ; For comparisons against 1, -1 and 128, we may generate better code
5790 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
5791 ; is matched then. We can't accept general immediate, because for
5792 ; case of overflows, the result is messed up.
5793 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5794 ; only for comparisons not depending on it.
5796 (define_insn "*add<mode>_4"
5797 [(set (reg FLAGS_REG)
5799 (match_operand:SWI124 1 "nonimmediate_operand" "0")
5800 (match_operand:SWI124 2 "const_int_operand" "n")))
5801 (clobber (match_scratch:SWI124 0 "=<r>"))]
5802 "ix86_match_ccmode (insn, CCGCmode)"
5804 switch (get_attr_type (insn))
5807 if (operands[2] == constm1_rtx)
5808 return "inc{<imodesuffix>}\t%0";
5811 gcc_assert (operands[2] == const1_rtx);
5812 return "dec{<imodesuffix>}\t%0";
5816 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5817 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5819 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5823 (if_then_else (match_operand:<MODE> 2 "incdec_operand")
5824 (const_string "incdec")
5825 (const_string "alu")))
5826 (set (attr "length_immediate")
5828 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5830 (const_string "*")))
5831 (set_attr "mode" "<MODE>")])
5833 (define_insn "*add<mode>_5"
5834 [(set (reg FLAGS_REG)
5837 (match_operand:SWI 1 "nonimmediate_operand" "%0,<r>")
5838 (match_operand:SWI 2 "<general_operand>" "<g>,0"))
5840 (clobber (match_scratch:SWI 0 "=<r>,<r>"))]
5841 "ix86_match_ccmode (insn, CCGOCmode)
5842 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
5844 switch (get_attr_type (insn))
5847 if (operands[2] == const1_rtx)
5848 return "inc{<imodesuffix>}\t%0";
5851 gcc_assert (operands[2] == constm1_rtx);
5852 return "dec{<imodesuffix>}\t%0";
5856 if (which_alternative == 1)
5857 std::swap (operands[1], operands[2]);
5859 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5860 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5861 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5863 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5867 (if_then_else (match_operand:SWI 2 "incdec_operand")
5868 (const_string "incdec")
5869 (const_string "alu")))
5870 (set (attr "length_immediate")
5872 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5874 (const_string "*")))
5875 (set_attr "mode" "<MODE>")])
5877 (define_expand "addqi_ext_1"
5879 [(set (zero_extract:HI (match_operand:HI 0 "register_operand")
5885 (zero_extract:HI (match_operand:HI 1 "register_operand")
5888 (match_operand:QI 2 "const_int_operand")) 0))
5889 (clobber (reg:CC FLAGS_REG))])])
5891 (define_insn "*addqi_ext<mode>_1"
5892 [(set (zero_extract:SWI248
5893 (match_operand:SWI248 0 "register_operand" "+Q,Q")
5899 (zero_extract:SWI248
5900 (match_operand:SWI248 1 "register_operand" "0,0")
5903 (match_operand:QI 2 "general_operand" "QnBc,m")) 0))
5904 (clobber (reg:CC FLAGS_REG))]
5905 "/* FIXME: without this LRA can't reload this pattern, see PR82524. */
5906 rtx_equal_p (operands[0], operands[1])"
5908 switch (get_attr_type (insn))
5911 if (operands[2] == const1_rtx)
5912 return "inc{b}\t%h0";
5915 gcc_assert (operands[2] == constm1_rtx);
5916 return "dec{b}\t%h0";
5920 return "add{b}\t{%2, %h0|%h0, %2}";
5923 [(set_attr "isa" "*,nox64")
5925 (if_then_else (match_operand:QI 2 "incdec_operand")
5926 (const_string "incdec")
5927 (const_string "alu")))
5928 (set_attr "mode" "QI")])
5930 (define_insn "*addqi_ext<mode>_2"
5931 [(set (zero_extract:SWI248
5932 (match_operand:SWI248 0 "register_operand" "+Q")
5938 (zero_extract:SWI248
5939 (match_operand:SWI248 1 "register_operand" "%0")
5943 (zero_extract:SWI248
5944 (match_operand:SWI248 2 "register_operand" "Q")
5946 (const_int 8)) 0)) 0))
5947 (clobber (reg:CC FLAGS_REG))]
5948 "/* FIXME: without this LRA can't reload this pattern, see PR82524. */
5949 rtx_equal_p (operands[0], operands[1])
5950 || rtx_equal_p (operands[0], operands[2])"
5951 "add{b}\t{%h2, %h0|%h0, %h2}"
5952 [(set_attr "type" "alu")
5953 (set_attr "mode" "QI")])
5955 ;; Like DWI, but use POImode instead of OImode.
5956 (define_mode_attr DPWI [(QI "HI") (HI "SI") (SI "DI") (DI "TI") (TI "POI")])
5958 ;; Add with jump on overflow.
5959 (define_expand "addv<mode>4"
5960 [(parallel [(set (reg:CCO FLAGS_REG)
5964 (match_operand:SWIDWI 1 "nonimmediate_operand"))
5967 (plus:SWIDWI (match_dup 1)
5968 (match_operand:SWIDWI 2
5969 "<general_hilo_operand>")))))
5970 (set (match_operand:SWIDWI 0 "register_operand")
5971 (plus:SWIDWI (match_dup 1) (match_dup 2)))])
5972 (set (pc) (if_then_else
5973 (eq (reg:CCO FLAGS_REG) (const_int 0))
5974 (label_ref (match_operand 3))
5978 ix86_fixup_binary_operands_no_copy (PLUS, <MODE>mode, operands);
5979 if (CONST_SCALAR_INT_P (operands[2]))
5980 operands[4] = operands[2];
5982 operands[4] = gen_rtx_SIGN_EXTEND (<DPWI>mode, operands[2]);
5985 (define_insn "*addv<mode>4"
5986 [(set (reg:CCO FLAGS_REG)
5989 (match_operand:SWI 1 "nonimmediate_operand" "%0,0"))
5991 (match_operand:SWI 2 "<general_sext_operand>" "<r>We,m")))
5993 (plus:SWI (match_dup 1) (match_dup 2)))))
5994 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
5995 (plus:SWI (match_dup 1) (match_dup 2)))]
5996 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5997 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
5998 [(set_attr "type" "alu")
5999 (set_attr "mode" "<MODE>")])
6001 (define_insn "addv<mode>4_1"
6002 [(set (reg:CCO FLAGS_REG)
6005 (match_operand:SWI 1 "nonimmediate_operand" "0"))
6006 (match_operand:<DWI> 3 "const_int_operand" "i"))
6010 (match_operand:SWI 2 "x86_64_immediate_operand" "<i>")))))
6011 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
6012 (plus:SWI (match_dup 1) (match_dup 2)))]
6013 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)
6014 && CONST_INT_P (operands[2])
6015 && INTVAL (operands[2]) == INTVAL (operands[3])"
6016 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6017 [(set_attr "type" "alu")
6018 (set_attr "mode" "<MODE>")
6019 (set (attr "length_immediate")
6020 (cond [(match_test "IN_RANGE (INTVAL (operands[2]), -128, 127)")
6022 (match_test "<MODE_SIZE> == 8")
6024 (const_string "<MODE_SIZE>")))])
6026 ;; Quad word integer modes as mode attribute.
6027 (define_mode_attr QPWI [(SI "TI") (DI "POI")])
6029 (define_insn_and_split "*addv<dwi>4_doubleword"
6030 [(set (reg:CCO FLAGS_REG)
6034 (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0"))
6036 (match_operand:<DWI> 2 "nonimmediate_operand" "r,o")))
6038 (plus:<DWI> (match_dup 1) (match_dup 2)))))
6039 (set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro,r")
6040 (plus:<DWI> (match_dup 1) (match_dup 2)))]
6041 "ix86_binary_operator_ok (PLUS, <DWI>mode, operands)"
6044 [(parallel [(set (reg:CCC FLAGS_REG)
6046 (plus:DWIH (match_dup 1) (match_dup 2))
6049 (plus:DWIH (match_dup 1) (match_dup 2)))])
6050 (parallel [(set (reg:CCO FLAGS_REG)
6054 (ltu:<DWI> (reg:CC FLAGS_REG) (const_int 0))
6055 (sign_extend:<DWI> (match_dup 4)))
6056 (sign_extend:<DWI> (match_dup 5)))
6060 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
6066 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
6070 split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
6073 (define_insn_and_split "*addv<dwi>4_doubleword_1"
6074 [(set (reg:CCO FLAGS_REG)
6078 (match_operand:<DWI> 1 "nonimmediate_operand" "%0"))
6079 (match_operand:<QPWI> 3 "const_scalar_int_operand" ""))
6083 (match_operand:<DWI> 2 "x86_64_hilo_general_operand" "<di>")))))
6084 (set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro")
6085 (plus:<DWI> (match_dup 1) (match_dup 2)))]
6086 "ix86_binary_operator_ok (PLUS, <DWI>mode, operands)
6087 && CONST_SCALAR_INT_P (operands[2])
6088 && rtx_equal_p (operands[2], operands[3])"
6091 [(parallel [(set (reg:CCC FLAGS_REG)
6093 (plus:DWIH (match_dup 1) (match_dup 2))
6096 (plus:DWIH (match_dup 1) (match_dup 2)))])
6097 (parallel [(set (reg:CCO FLAGS_REG)
6101 (ltu:<DWI> (reg:CC FLAGS_REG) (const_int 0))
6102 (sign_extend:<DWI> (match_dup 4)))
6107 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
6113 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
6117 split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
6118 if (operands[2] == const0_rtx)
6120 emit_insn (gen_addv<mode>4_1 (operands[3], operands[4], operands[5],
6126 (define_insn "*addv<mode>4_overflow_1"
6127 [(set (reg:CCO FLAGS_REG)
6131 (match_operator:<DWI> 4 "ix86_carry_flag_operator"
6132 [(match_operand 3 "flags_reg_operand") (const_int 0)])
6134 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")))
6136 (match_operand:SWI 2 "<general_sext_operand>" "rWe,m")))
6140 (match_operator:SWI 5 "ix86_carry_flag_operator"
6141 [(match_dup 3) (const_int 0)])
6144 (set (match_operand:SWI 0 "nonimmediate_operand" "=rm,r")
6147 (match_op_dup 5 [(match_dup 3) (const_int 0)])
6150 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6151 "adc{<imodesuffix>}\t{%2, %0|%0, %2}"
6152 [(set_attr "type" "alu")
6153 (set_attr "mode" "<MODE>")])
6155 (define_insn "*addv<mode>4_overflow_2"
6156 [(set (reg:CCO FLAGS_REG)
6160 (match_operator:<DWI> 4 "ix86_carry_flag_operator"
6161 [(match_operand 3 "flags_reg_operand") (const_int 0)])
6163 (match_operand:SWI 1 "nonimmediate_operand" "%0")))
6164 (match_operand:<DWI> 6 "const_int_operand" ""))
6168 (match_operator:SWI 5 "ix86_carry_flag_operator"
6169 [(match_dup 3) (const_int 0)])
6171 (match_operand:SWI 2 "x86_64_immediate_operand" "e")))))
6172 (set (match_operand:SWI 0 "nonimmediate_operand" "=rm")
6175 (match_op_dup 5 [(match_dup 3) (const_int 0)])
6178 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)
6179 && CONST_INT_P (operands[2])
6180 && INTVAL (operands[2]) == INTVAL (operands[6])"
6181 "adc{<imodesuffix>}\t{%2, %0|%0, %2}"
6182 [(set_attr "type" "alu")
6183 (set_attr "mode" "<MODE>")
6184 (set (attr "length_immediate")
6185 (if_then_else (match_test "IN_RANGE (INTVAL (operands[2]), -128, 127)")
6187 (const_string "4")))])
6189 (define_expand "uaddv<mode>4"
6190 [(parallel [(set (reg:CCC FLAGS_REG)
6193 (match_operand:SWIDWI 1 "nonimmediate_operand")
6194 (match_operand:SWIDWI 2 "<general_hilo_operand>"))
6196 (set (match_operand:SWIDWI 0 "register_operand")
6197 (plus:SWIDWI (match_dup 1) (match_dup 2)))])
6198 (set (pc) (if_then_else
6199 (ltu (reg:CCC FLAGS_REG) (const_int 0))
6200 (label_ref (match_operand 3))
6203 "ix86_fixup_binary_operands_no_copy (PLUS, <MODE>mode, operands);")
6205 ;; The lea patterns for modes less than 32 bits need to be matched by
6206 ;; several insns converted to real lea by splitters.
6208 (define_insn_and_split "*lea<mode>_general_1"
6209 [(set (match_operand:SWI12 0 "register_operand" "=r")
6211 (plus:SWI12 (match_operand:SWI12 1 "index_register_operand" "l")
6212 (match_operand:SWI12 2 "register_operand" "r"))
6213 (match_operand:SWI12 3 "immediate_operand" "i")))]
6214 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
6216 "&& reload_completed"
6219 (plus:SI (match_dup 1) (match_dup 2))
6222 operands[0] = gen_lowpart (SImode, operands[0]);
6223 operands[1] = gen_lowpart (SImode, operands[1]);
6224 operands[2] = gen_lowpart (SImode, operands[2]);
6225 operands[3] = gen_lowpart (SImode, operands[3]);
6227 [(set_attr "type" "lea")
6228 (set_attr "mode" "SI")])
6230 (define_insn_and_split "*lea<mode>_general_2"
6231 [(set (match_operand:SWI12 0 "register_operand" "=r")
6233 (mult:SWI12 (match_operand:SWI12 1 "index_register_operand" "l")
6234 (match_operand 2 "const248_operand" "n"))
6235 (match_operand:SWI12 3 "nonmemory_operand" "ri")))]
6236 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
6238 "&& reload_completed"
6241 (mult:SI (match_dup 1) (match_dup 2))
6244 operands[0] = gen_lowpart (SImode, operands[0]);
6245 operands[1] = gen_lowpart (SImode, operands[1]);
6246 operands[3] = gen_lowpart (SImode, operands[3]);
6248 [(set_attr "type" "lea")
6249 (set_attr "mode" "SI")])
6251 (define_insn_and_split "*lea<mode>_general_2b"
6252 [(set (match_operand:SWI12 0 "register_operand" "=r")
6254 (ashift:SWI12 (match_operand:SWI12 1 "index_register_operand" "l")
6255 (match_operand 2 "const123_operand" "n"))
6256 (match_operand:SWI12 3 "nonmemory_operand" "ri")))]
6257 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
6259 "&& reload_completed"
6262 (ashift:SI (match_dup 1) (match_dup 2))
6265 operands[0] = gen_lowpart (SImode, operands[0]);
6266 operands[1] = gen_lowpart (SImode, operands[1]);
6267 operands[3] = gen_lowpart (SImode, operands[3]);
6269 [(set_attr "type" "lea")
6270 (set_attr "mode" "SI")])
6272 (define_insn_and_split "*lea<mode>_general_3"
6273 [(set (match_operand:SWI12 0 "register_operand" "=r")
6276 (mult:SWI12 (match_operand:SWI12 1 "index_register_operand" "l")
6277 (match_operand 2 "const248_operand" "n"))
6278 (match_operand:SWI12 3 "register_operand" "r"))
6279 (match_operand:SWI12 4 "immediate_operand" "i")))]
6280 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
6282 "&& reload_completed"
6286 (mult:SI (match_dup 1) (match_dup 2))
6290 operands[0] = gen_lowpart (SImode, operands[0]);
6291 operands[1] = gen_lowpart (SImode, operands[1]);
6292 operands[3] = gen_lowpart (SImode, operands[3]);
6293 operands[4] = gen_lowpart (SImode, operands[4]);
6295 [(set_attr "type" "lea")
6296 (set_attr "mode" "SI")])
6298 (define_insn_and_split "*lea<mode>_general_3b"
6299 [(set (match_operand:SWI12 0 "register_operand" "=r")
6302 (ashift:SWI12 (match_operand:SWI12 1 "index_register_operand" "l")
6303 (match_operand 2 "const123_operand" "n"))
6304 (match_operand:SWI12 3 "register_operand" "r"))
6305 (match_operand:SWI12 4 "immediate_operand" "i")))]
6306 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
6308 "&& reload_completed"
6312 (ashift:SI (match_dup 1) (match_dup 2))
6316 operands[0] = gen_lowpart (SImode, operands[0]);
6317 operands[1] = gen_lowpart (SImode, operands[1]);
6318 operands[3] = gen_lowpart (SImode, operands[3]);
6319 operands[4] = gen_lowpart (SImode, operands[4]);
6321 [(set_attr "type" "lea")
6322 (set_attr "mode" "SI")])
6324 (define_insn_and_split "*lea<mode>_general_4"
6325 [(set (match_operand:SWI12 0 "register_operand" "=r")
6328 (match_operand:SWI12 1 "index_register_operand" "l")
6329 (match_operand 2 "const_0_to_3_operand" "n"))
6330 (match_operand 3 "const_int_operand" "n")))]
6331 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6332 && ((unsigned HOST_WIDE_INT) INTVAL (operands[3])
6333 < (HOST_WIDE_INT_1U << INTVAL (operands[2])))"
6335 "&& reload_completed"
6338 (mult:SI (match_dup 1) (match_dup 2))
6341 operands[0] = gen_lowpart (SImode, operands[0]);
6342 operands[1] = gen_lowpart (SImode, operands[1]);
6343 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
6345 [(set_attr "type" "lea")
6346 (set_attr "mode" "SI")])
6348 (define_insn_and_split "*lea<mode>_general_4"
6349 [(set (match_operand:SWI48 0 "register_operand" "=r")
6352 (match_operand:SWI48 1 "index_register_operand" "l")
6353 (match_operand 2 "const_0_to_3_operand" "n"))
6354 (match_operand 3 "const_int_operand" "n")))]
6355 "(unsigned HOST_WIDE_INT) INTVAL (operands[3])
6356 < (HOST_WIDE_INT_1U << INTVAL (operands[2]))"
6358 "&& reload_completed"
6361 (mult:SWI48 (match_dup 1) (match_dup 2))
6363 "operands[2] = GEN_INT (1 << INTVAL (operands[2]));"
6364 [(set_attr "type" "lea")
6365 (set_attr "mode" "<MODE>")])
6367 ;; Subtract instructions
6369 (define_expand "sub<mode>3"
6370 [(set (match_operand:SDWIM 0 "nonimmediate_operand")
6371 (minus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")
6372 (match_operand:SDWIM 2 "<general_hilo_operand>")))]
6374 "ix86_expand_binary_operator (MINUS, <MODE>mode, operands); DONE;")
6376 (define_insn_and_split "*sub<dwi>3_doubleword"
6377 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro,r")
6379 (match_operand:<DWI> 1 "nonimmediate_operand" "0,0")
6380 (match_operand:<DWI> 2 "x86_64_hilo_general_operand" "r<di>,o")))
6381 (clobber (reg:CC FLAGS_REG))]
6382 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6385 [(parallel [(set (reg:CC FLAGS_REG)
6386 (compare:CC (match_dup 1) (match_dup 2)))
6388 (minus:DWIH (match_dup 1) (match_dup 2)))])
6389 (parallel [(set (match_dup 3)
6393 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0)))
6395 (clobber (reg:CC FLAGS_REG))])]
6397 split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
6398 if (operands[2] == const0_rtx)
6400 ix86_expand_binary_operator (MINUS, <MODE>mode, &operands[3]);
6405 (define_insn "*sub<mode>_1"
6406 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6408 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6409 (match_operand:SWI 2 "<general_operand>" "<r><i>,m")))
6410 (clobber (reg:CC FLAGS_REG))]
6411 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6412 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6413 [(set_attr "type" "alu")
6414 (set_attr "mode" "<MODE>")])
6416 (define_insn "*subsi_1_zext"
6417 [(set (match_operand:DI 0 "register_operand" "=r")
6419 (minus:SI (match_operand:SI 1 "register_operand" "0")
6420 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
6421 (clobber (reg:CC FLAGS_REG))]
6422 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6423 "sub{l}\t{%2, %k0|%k0, %2}"
6424 [(set_attr "type" "alu")
6425 (set_attr "mode" "SI")])
6427 (define_insn "*sub<mode>_1_slp"
6428 [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>"))
6429 (minus:SWI12 (match_operand:SWI12 1 "register_operand" "0")
6430 (match_operand:SWI12 2 "general_operand" "<r>mn")))
6431 (clobber (reg:CC FLAGS_REG))]
6432 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6433 /* FIXME: without this LRA can't reload this pattern, see PR82524. */
6434 && rtx_equal_p (operands[0], operands[1])"
6435 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6436 [(set_attr "type" "alu")
6437 (set_attr "mode" "<MODE>")])
6439 (define_insn "*sub<mode>_2"
6440 [(set (reg FLAGS_REG)
6443 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6444 (match_operand:SWI 2 "<general_operand>" "<r><i>,m"))
6446 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6447 (minus:SWI (match_dup 1) (match_dup 2)))]
6448 "ix86_match_ccmode (insn, CCGOCmode)
6449 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6450 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6451 [(set_attr "type" "alu")
6452 (set_attr "mode" "<MODE>")])
6454 (define_insn "*subsi_2_zext"
6455 [(set (reg FLAGS_REG)
6457 (minus:SI (match_operand:SI 1 "register_operand" "0")
6458 (match_operand:SI 2 "x86_64_general_operand" "rme"))
6460 (set (match_operand:DI 0 "register_operand" "=r")
6462 (minus:SI (match_dup 1)
6464 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6465 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6466 "sub{l}\t{%2, %k0|%k0, %2}"
6467 [(set_attr "type" "alu")
6468 (set_attr "mode" "SI")])
6470 ;; Subtract with jump on overflow.
6471 (define_expand "subv<mode>4"
6472 [(parallel [(set (reg:CCO FLAGS_REG)
6476 (match_operand:SWIDWI 1 "nonimmediate_operand"))
6479 (minus:SWIDWI (match_dup 1)
6480 (match_operand:SWIDWI 2
6481 "<general_hilo_operand>")))))
6482 (set (match_operand:SWIDWI 0 "register_operand")
6483 (minus:SWIDWI (match_dup 1) (match_dup 2)))])
6484 (set (pc) (if_then_else
6485 (eq (reg:CCO FLAGS_REG) (const_int 0))
6486 (label_ref (match_operand 3))
6490 ix86_fixup_binary_operands_no_copy (MINUS, <MODE>mode, operands);
6491 if (CONST_SCALAR_INT_P (operands[2]))
6492 operands[4] = operands[2];
6494 operands[4] = gen_rtx_SIGN_EXTEND (<DPWI>mode, operands[2]);
6497 (define_insn "*subv<mode>4"
6498 [(set (reg:CCO FLAGS_REG)
6499 (eq:CCO (minus:<DWI>
6501 (match_operand:SWI 1 "nonimmediate_operand" "0,0"))
6503 (match_operand:SWI 2 "<general_sext_operand>" "<r>We,m")))
6505 (minus:SWI (match_dup 1) (match_dup 2)))))
6506 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6507 (minus:SWI (match_dup 1) (match_dup 2)))]
6508 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6509 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6510 [(set_attr "type" "alu")
6511 (set_attr "mode" "<MODE>")])
6513 (define_insn "subv<mode>4_1"
6514 [(set (reg:CCO FLAGS_REG)
6515 (eq:CCO (minus:<DWI>
6517 (match_operand:SWI 1 "nonimmediate_operand" "0"))
6518 (match_operand:<DWI> 3 "const_int_operand" "i"))
6522 (match_operand:SWI 2 "x86_64_immediate_operand" "<i>")))))
6523 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
6524 (minus:SWI (match_dup 1) (match_dup 2)))]
6525 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)
6526 && CONST_INT_P (operands[2])
6527 && INTVAL (operands[2]) == INTVAL (operands[3])"
6528 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6529 [(set_attr "type" "alu")
6530 (set_attr "mode" "<MODE>")
6531 (set (attr "length_immediate")
6532 (cond [(match_test "IN_RANGE (INTVAL (operands[2]), -128, 127)")
6534 (match_test "<MODE_SIZE> == 8")
6536 (const_string "<MODE_SIZE>")))])
6538 (define_insn_and_split "*subv<dwi>4_doubleword"
6539 [(set (reg:CCO FLAGS_REG)
6543 (match_operand:<DWI> 1 "nonimmediate_operand" "0,0"))
6545 (match_operand:<DWI> 2 "nonimmediate_operand" "r,o")))
6547 (minus:<DWI> (match_dup 1) (match_dup 2)))))
6548 (set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro,r")
6549 (minus:<DWI> (match_dup 1) (match_dup 2)))]
6550 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6553 [(parallel [(set (reg:CC FLAGS_REG)
6554 (compare:CC (match_dup 1) (match_dup 2)))
6556 (minus:DWIH (match_dup 1) (match_dup 2)))])
6557 (parallel [(set (reg:CCO FLAGS_REG)
6561 (sign_extend:<DWI> (match_dup 4))
6562 (ltu:<DWI> (reg:CC FLAGS_REG) (const_int 0)))
6563 (sign_extend:<DWI> (match_dup 5)))
6568 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0)))
6574 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0)))
6577 split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
6580 (define_insn_and_split "*subv<dwi>4_doubleword_1"
6581 [(set (reg:CCO FLAGS_REG)
6585 (match_operand:<DWI> 1 "nonimmediate_operand" "0"))
6586 (match_operand:<QPWI> 3 "const_scalar_int_operand" ""))
6590 (match_operand:<DWI> 2 "x86_64_hilo_general_operand" "<di>")))))
6591 (set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro")
6592 (minus:<DWI> (match_dup 1) (match_dup 2)))]
6593 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)
6594 && CONST_SCALAR_INT_P (operands[2])
6595 && rtx_equal_p (operands[2], operands[3])"
6598 [(parallel [(set (reg:CC FLAGS_REG)
6599 (compare:CC (match_dup 1) (match_dup 2)))
6601 (minus:DWIH (match_dup 1) (match_dup 2)))])
6602 (parallel [(set (reg:CCO FLAGS_REG)
6606 (sign_extend:<DWI> (match_dup 4))
6607 (ltu:<DWI> (reg:CC FLAGS_REG) (const_int 0)))
6613 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0)))
6619 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0)))
6622 split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
6623 if (operands[2] == const0_rtx)
6625 emit_insn (gen_subv<mode>4_1 (operands[3], operands[4], operands[5],
6631 (define_insn "*subv<mode>4_overflow_1"
6632 [(set (reg:CCO FLAGS_REG)
6637 (match_operand:SWI 1 "nonimmediate_operand" "%0,0"))
6638 (match_operator:<DWI> 4 "ix86_carry_flag_operator"
6639 [(match_operand 3 "flags_reg_operand") (const_int 0)]))
6641 (match_operand:SWI 2 "<general_sext_operand>" "rWe,m")))
6646 (match_operator:SWI 5 "ix86_carry_flag_operator"
6647 [(match_dup 3) (const_int 0)]))
6649 (set (match_operand:SWI 0 "nonimmediate_operand" "=rm,r")
6653 (match_op_dup 5 [(match_dup 3) (const_int 0)]))
6655 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6656 "sbb{<imodesuffix>}\t{%2, %0|%0, %2}"
6657 [(set_attr "type" "alu")
6658 (set_attr "mode" "<MODE>")])
6660 (define_insn "*subv<mode>4_overflow_2"
6661 [(set (reg:CCO FLAGS_REG)
6666 (match_operand:SWI 1 "nonimmediate_operand" "%0"))
6667 (match_operator:<DWI> 4 "ix86_carry_flag_operator"
6668 [(match_operand 3 "flags_reg_operand") (const_int 0)]))
6669 (match_operand:<DWI> 6 "const_int_operand" ""))
6674 (match_operator:SWI 5 "ix86_carry_flag_operator"
6675 [(match_dup 3) (const_int 0)]))
6676 (match_operand:SWI 2 "x86_64_immediate_operand" "e")))))
6677 (set (match_operand:SWI 0 "nonimmediate_operand" "=rm")
6681 (match_op_dup 5 [(match_dup 3) (const_int 0)]))
6683 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)
6684 && CONST_INT_P (operands[2])
6685 && INTVAL (operands[2]) == INTVAL (operands[6])"
6686 "sbb{<imodesuffix>}\t{%2, %0|%0, %2}"
6687 [(set_attr "type" "alu")
6688 (set_attr "mode" "<MODE>")
6689 (set (attr "length_immediate")
6690 (if_then_else (match_test "IN_RANGE (INTVAL (operands[2]), -128, 127)")
6692 (const_string "4")))])
6694 (define_expand "usubv<mode>4"
6695 [(parallel [(set (reg:CC FLAGS_REG)
6697 (match_operand:SWI 1 "nonimmediate_operand")
6698 (match_operand:SWI 2 "<general_operand>")))
6699 (set (match_operand:SWI 0 "register_operand")
6700 (minus:SWI (match_dup 1) (match_dup 2)))])
6701 (set (pc) (if_then_else
6702 (ltu (reg:CC FLAGS_REG) (const_int 0))
6703 (label_ref (match_operand 3))
6706 "ix86_fixup_binary_operands_no_copy (MINUS, <MODE>mode, operands);")
6708 (define_insn "*sub<mode>_3"
6709 [(set (reg FLAGS_REG)
6710 (compare (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6711 (match_operand:SWI 2 "<general_operand>" "<r><i>,m")))
6712 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6713 (minus:SWI (match_dup 1) (match_dup 2)))]
6714 "ix86_match_ccmode (insn, CCmode)
6715 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6716 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6717 [(set_attr "type" "alu")
6718 (set_attr "mode" "<MODE>")])
6722 [(set (reg:CC FLAGS_REG)
6723 (compare:CC (match_operand:SWI 0 "general_reg_operand")
6724 (match_operand:SWI 1 "general_gr_operand")))
6726 (minus:SWI (match_dup 0) (match_dup 1)))])]
6727 "find_regno_note (peep2_next_insn (0), REG_UNUSED, REGNO (operands[0])) != 0"
6728 [(set (reg:CC FLAGS_REG)
6729 (compare:CC (match_dup 0) (match_dup 1)))])
6731 ;; decl %eax; cmpl $-1, %eax; jne .Lxx; can be optimized into
6732 ;; subl $1, %eax; jnc .Lxx;
6735 [(set (match_operand:SWI 0 "general_reg_operand")
6736 (plus:SWI (match_dup 0) (const_int -1)))
6737 (clobber (reg FLAGS_REG))])
6738 (set (reg:CCZ FLAGS_REG)
6739 (compare:CCZ (match_dup 0) (const_int -1)))
6741 (if_then_else (match_operator 1 "bt_comparison_operator"
6742 [(reg:CCZ FLAGS_REG) (const_int 0)])
6745 "peep2_regno_dead_p (3, FLAGS_REG)"
6747 [(set (reg:CC FLAGS_REG)
6748 (compare:CC (match_dup 0) (const_int 1)))
6750 (minus:SWI (match_dup 0) (const_int 1)))])
6752 (if_then_else (match_dup 3)
6756 rtx cc = gen_rtx_REG (CCmode, FLAGS_REG);
6757 operands[3] = gen_rtx_fmt_ee (GET_CODE (operands[1]) == NE
6758 ? GEU : LTU, VOIDmode, cc, const0_rtx);
6761 (define_insn "*subsi_3_zext"
6762 [(set (reg FLAGS_REG)
6763 (compare (match_operand:SI 1 "register_operand" "0")
6764 (match_operand:SI 2 "x86_64_general_operand" "rme")))
6765 (set (match_operand:DI 0 "register_operand" "=r")
6767 (minus:SI (match_dup 1)
6769 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6770 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6771 "sub{l}\t{%2, %1|%1, %2}"
6772 [(set_attr "type" "alu")
6773 (set_attr "mode" "SI")])
6775 ;; Add with carry and subtract with borrow
6777 (define_insn "@add<mode>3_carry"
6778 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6781 (match_operator:SWI 4 "ix86_carry_flag_operator"
6782 [(match_operand 3 "flags_reg_operand") (const_int 0)])
6783 (match_operand:SWI 1 "nonimmediate_operand" "%0,0"))
6784 (match_operand:SWI 2 "<general_operand>" "<r><i>,m")))
6785 (clobber (reg:CC FLAGS_REG))]
6786 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6787 "adc{<imodesuffix>}\t{%2, %0|%0, %2}"
6788 [(set_attr "type" "alu")
6789 (set_attr "use_carry" "1")
6790 (set_attr "pent_pair" "pu")
6791 (set_attr "mode" "<MODE>")])
6793 (define_insn "*add<mode>3_carry_0"
6794 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
6796 (match_operator:SWI 3 "ix86_carry_flag_operator"
6797 [(match_operand 2 "flags_reg_operand") (const_int 0)])
6798 (match_operand:SWI 1 "nonimmediate_operand" "0")))
6799 (clobber (reg:CC FLAGS_REG))]
6800 "ix86_unary_operator_ok (PLUS, <MODE>mode, operands)"
6801 "adc{<imodesuffix>}\t{$0, %0|%0, 0}"
6802 [(set_attr "type" "alu")
6803 (set_attr "use_carry" "1")
6804 (set_attr "pent_pair" "pu")
6805 (set_attr "mode" "<MODE>")])
6807 (define_insn "*addsi3_carry_zext"
6808 [(set (match_operand:DI 0 "register_operand" "=r")
6811 (plus:SI (match_operator:SI 3 "ix86_carry_flag_operator"
6812 [(reg FLAGS_REG) (const_int 0)])
6813 (match_operand:SI 1 "register_operand" "%0"))
6814 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
6815 (clobber (reg:CC FLAGS_REG))]
6816 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6817 "adc{l}\t{%2, %k0|%k0, %2}"
6818 [(set_attr "type" "alu")
6819 (set_attr "use_carry" "1")
6820 (set_attr "pent_pair" "pu")
6821 (set_attr "mode" "SI")])
6823 (define_insn "*addsi3_carry_zext_0"
6824 [(set (match_operand:DI 0 "register_operand" "=r")
6826 (plus:SI (match_operator:SI 2 "ix86_carry_flag_operator"
6827 [(reg FLAGS_REG) (const_int 0)])
6828 (match_operand:SI 1 "register_operand" "0"))))
6829 (clobber (reg:CC FLAGS_REG))]
6831 "adc{l}\t{$0, %k0|%k0, 0}"
6832 [(set_attr "type" "alu")
6833 (set_attr "use_carry" "1")
6834 (set_attr "pent_pair" "pu")
6835 (set_attr "mode" "SI")])
6837 ;; There is no point to generate ADCX instruction. ADC is shorter and faster.
6839 (define_insn "addcarry<mode>"
6840 [(set (reg:CCC FLAGS_REG)
6845 (match_operator:SWI48 5 "ix86_carry_flag_operator"
6846 [(match_operand 3 "flags_reg_operand") (const_int 0)])
6847 (match_operand:SWI48 1 "nonimmediate_operand" "%0,0"))
6848 (match_operand:SWI48 2 "nonimmediate_operand" "r,rm")))
6850 (zero_extend:<DWI> (match_dup 2))
6851 (match_operator:<DWI> 4 "ix86_carry_flag_operator"
6852 [(match_dup 3) (const_int 0)]))))
6853 (set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
6854 (plus:SWI48 (plus:SWI48 (match_op_dup 5
6855 [(match_dup 3) (const_int 0)])
6858 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6859 "adc{<imodesuffix>}\t{%2, %0|%0, %2}"
6860 [(set_attr "type" "alu")
6861 (set_attr "use_carry" "1")
6862 (set_attr "pent_pair" "pu")
6863 (set_attr "mode" "<MODE>")])
6865 (define_expand "addcarry<mode>_0"
6867 [(set (reg:CCC FLAGS_REG)
6870 (match_operand:SWI48 1 "nonimmediate_operand")
6871 (match_operand:SWI48 2 "x86_64_general_operand"))
6873 (set (match_operand:SWI48 0 "nonimmediate_operand")
6874 (plus:SWI48 (match_dup 1) (match_dup 2)))])]
6875 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)")
6877 (define_insn "*addcarry<mode>_1"
6878 [(set (reg:CCC FLAGS_REG)
6883 (match_operator:SWI48 5 "ix86_carry_flag_operator"
6884 [(match_operand 3 "flags_reg_operand") (const_int 0)])
6885 (match_operand:SWI48 1 "nonimmediate_operand" "%0"))
6886 (match_operand:SWI48 2 "x86_64_immediate_operand" "e")))
6888 (match_operand:<DWI> 6 "const_scalar_int_operand" "")
6889 (match_operator:<DWI> 4 "ix86_carry_flag_operator"
6890 [(match_dup 3) (const_int 0)]))))
6891 (set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
6892 (plus:SWI48 (plus:SWI48 (match_op_dup 5
6893 [(match_dup 3) (const_int 0)])
6896 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)
6897 && CONST_INT_P (operands[2])
6898 /* Check that operands[6] is operands[2] zero extended from
6899 <MODE>mode to <DWI>mode. */
6900 && ((<MODE>mode == SImode || INTVAL (operands[2]) >= 0)
6901 ? (CONST_INT_P (operands[6])
6902 && UINTVAL (operands[6]) == (UINTVAL (operands[2])
6903 & GET_MODE_MASK (<MODE>mode)))
6904 : (CONST_WIDE_INT_P (operands[6])
6905 && CONST_WIDE_INT_NUNITS (operands[6]) == 2
6906 && ((unsigned HOST_WIDE_INT) CONST_WIDE_INT_ELT (operands[6], 0)
6907 == UINTVAL (operands[2]))
6908 && CONST_WIDE_INT_ELT (operands[6], 1) == 0))"
6909 "adc{<imodesuffix>}\t{%2, %0|%0, %2}"
6910 [(set_attr "type" "alu")
6911 (set_attr "use_carry" "1")
6912 (set_attr "pent_pair" "pu")
6913 (set_attr "mode" "<MODE>")
6914 (set (attr "length_immediate")
6915 (if_then_else (match_test "IN_RANGE (INTVAL (operands[2]), -128, 127)")
6917 (const_string "4")))])
6919 (define_insn "@sub<mode>3_carry"
6920 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6923 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6924 (match_operator:SWI 4 "ix86_carry_flag_operator"
6925 [(match_operand 3 "flags_reg_operand") (const_int 0)]))
6926 (match_operand:SWI 2 "<general_operand>" "<r><i>,m")))
6927 (clobber (reg:CC FLAGS_REG))]
6928 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6929 "sbb{<imodesuffix>}\t{%2, %0|%0, %2}"
6930 [(set_attr "type" "alu")
6931 (set_attr "use_carry" "1")
6932 (set_attr "pent_pair" "pu")
6933 (set_attr "mode" "<MODE>")])
6935 (define_insn "*sub<mode>3_carry_0"
6936 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
6938 (match_operand:SWI 1 "nonimmediate_operand" "0")
6939 (match_operator:SWI 3 "ix86_carry_flag_operator"
6940 [(match_operand 2 "flags_reg_operand") (const_int 0)])))
6941 (clobber (reg:CC FLAGS_REG))]
6942 "ix86_unary_operator_ok (MINUS, <MODE>mode, operands)"
6943 "sbb{<imodesuffix>}\t{$0, %0|%0, 0}"
6944 [(set_attr "type" "alu")
6945 (set_attr "use_carry" "1")
6946 (set_attr "pent_pair" "pu")
6947 (set_attr "mode" "<MODE>")])
6949 (define_insn "*subsi3_carry_zext"
6950 [(set (match_operand:DI 0 "register_operand" "=r")
6954 (match_operand:SI 1 "register_operand" "0")
6955 (match_operator:SI 3 "ix86_carry_flag_operator"
6956 [(reg FLAGS_REG) (const_int 0)]))
6957 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
6958 (clobber (reg:CC FLAGS_REG))]
6959 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6960 "sbb{l}\t{%2, %k0|%k0, %2}"
6961 [(set_attr "type" "alu")
6962 (set_attr "use_carry" "1")
6963 (set_attr "pent_pair" "pu")
6964 (set_attr "mode" "SI")])
6966 (define_insn "*subsi3_carry_zext_0"
6967 [(set (match_operand:DI 0 "register_operand" "=r")
6970 (match_operand:SI 1 "register_operand" "0")
6971 (match_operator:SI 2 "ix86_carry_flag_operator"
6972 [(reg FLAGS_REG) (const_int 0)]))))
6973 (clobber (reg:CC FLAGS_REG))]
6975 "sbb{l}\t{$0, %k0|%k0, 0}"
6976 [(set_attr "type" "alu")
6977 (set_attr "use_carry" "1")
6978 (set_attr "pent_pair" "pu")
6979 (set_attr "mode" "SI")])
6981 (define_insn "@sub<mode>3_carry_ccc"
6982 [(set (reg:CCC FLAGS_REG)
6984 (zero_extend:<DWI> (match_operand:DWIH 1 "register_operand" "0"))
6986 (ltu:<DWI> (reg:CC FLAGS_REG) (const_int 0))
6988 (match_operand:DWIH 2 "x86_64_sext_operand" "rmWe")))))
6989 (clobber (match_scratch:DWIH 0 "=r"))]
6991 "sbb{<imodesuffix>}\t{%2, %0|%0, %2}"
6992 [(set_attr "type" "alu")
6993 (set_attr "mode" "<MODE>")])
6995 (define_insn "*sub<mode>3_carry_ccc_1"
6996 [(set (reg:CCC FLAGS_REG)
6998 (zero_extend:<DWI> (match_operand:DWIH 1 "register_operand" "0"))
7000 (ltu:<DWI> (reg:CC FLAGS_REG) (const_int 0))
7001 (match_operand:<DWI> 2 "x86_64_dwzext_immediate_operand" "Wf"))))
7002 (clobber (match_scratch:DWIH 0 "=r"))]
7005 operands[3] = simplify_subreg (<MODE>mode, operands[2], <DWI>mode, 0);
7006 return "sbb{<imodesuffix>}\t{%3, %0|%0, %3}";
7008 [(set_attr "type" "alu")
7009 (set_attr "mode" "<MODE>")])
7011 ;; The sign flag is set from the
7012 ;; (compare (match_dup 1) (plus:DWIH (ltu:DWIH ...) (match_dup 2)))
7013 ;; result, the overflow flag likewise, but the overflow flag is also
7014 ;; set if the (plus:DWIH (ltu:DWIH ...) (match_dup 2)) overflows.
7015 (define_insn "@sub<mode>3_carry_ccgz"
7016 [(set (reg:CCGZ FLAGS_REG)
7017 (unspec:CCGZ [(match_operand:DWIH 1 "register_operand" "0")
7018 (match_operand:DWIH 2 "x86_64_general_operand" "rme")
7019 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))]
7021 (clobber (match_scratch:DWIH 0 "=r"))]
7023 "sbb{<imodesuffix>}\t{%2, %0|%0, %2}"
7024 [(set_attr "type" "alu")
7025 (set_attr "mode" "<MODE>")])
7027 (define_insn "subborrow<mode>"
7028 [(set (reg:CCC FLAGS_REG)
7031 (match_operand:SWI48 1 "nonimmediate_operand" "0"))
7033 (match_operator:<DWI> 4 "ix86_carry_flag_operator"
7034 [(match_operand 3 "flags_reg_operand") (const_int 0)])
7036 (match_operand:SWI48 2 "nonimmediate_operand" "rm")))))
7037 (set (match_operand:SWI48 0 "register_operand" "=r")
7038 (minus:SWI48 (minus:SWI48
7040 (match_operator:SWI48 5 "ix86_carry_flag_operator"
7041 [(match_dup 3) (const_int 0)]))
7043 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
7044 "sbb{<imodesuffix>}\t{%2, %0|%0, %2}"
7045 [(set_attr "type" "alu")
7046 (set_attr "use_carry" "1")
7047 (set_attr "pent_pair" "pu")
7048 (set_attr "mode" "<MODE>")])
7050 (define_expand "subborrow<mode>_0"
7052 [(set (reg:CC FLAGS_REG)
7054 (match_operand:SWI48 1 "nonimmediate_operand")
7055 (match_operand:SWI48 2 "<general_operand>")))
7056 (set (match_operand:SWI48 0 "register_operand")
7057 (minus:SWI48 (match_dup 1) (match_dup 2)))])]
7058 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)")
7060 (define_mode_iterator CC_CCC [CC CCC])
7062 ;; Pre-reload splitter to optimize
7063 ;; *setcc_qi followed by *addqi3_cconly_overflow_1 with the same QI
7064 ;; operand and no intervening flags modifications into nothing.
7065 (define_insn_and_split "*setcc_qi_addqi3_cconly_overflow_1_<mode>"
7066 [(set (reg:CCC FLAGS_REG)
7067 (compare:CCC (neg:QI (geu:QI (reg:CC_CCC FLAGS_REG) (const_int 0)))
7068 (ltu:QI (reg:CC_CCC FLAGS_REG) (const_int 0))))]
7069 "ix86_pre_reload_split ()"
7074 ;; Overflow setting add instructions
7076 (define_expand "addqi3_cconly_overflow"
7078 [(set (reg:CCC FLAGS_REG)
7081 (match_operand:QI 0 "nonimmediate_operand")
7082 (match_operand:QI 1 "general_operand"))
7084 (clobber (scratch:QI))])]
7085 "!(MEM_P (operands[0]) && MEM_P (operands[1]))")
7087 (define_insn "*add<mode>3_cconly_overflow_1"
7088 [(set (reg:CCC FLAGS_REG)
7091 (match_operand:SWI 1 "nonimmediate_operand" "%0")
7092 (match_operand:SWI 2 "<general_operand>" "<g>"))
7094 (clobber (match_scratch:SWI 0 "=<r>"))]
7095 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7096 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
7097 [(set_attr "type" "alu")
7098 (set_attr "mode" "<MODE>")])
7100 (define_insn "*add<mode>3_cc_overflow_1"
7101 [(set (reg:CCC FLAGS_REG)
7104 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
7105 (match_operand:SWI 2 "<general_operand>" "<r><i>,m"))
7107 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
7108 (plus:SWI (match_dup 1) (match_dup 2)))]
7109 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
7110 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
7111 [(set_attr "type" "alu")
7112 (set_attr "mode" "<MODE>")])
7115 [(parallel [(set (reg:CCC FLAGS_REG)
7117 (plus:SWI (match_operand:SWI 0 "general_reg_operand")
7118 (match_operand:SWI 1 "memory_operand"))
7120 (set (match_dup 0) (plus:SWI (match_dup 0) (match_dup 1)))])
7121 (set (match_dup 1) (match_dup 0))]
7122 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
7123 && peep2_reg_dead_p (2, operands[0])
7124 && !reg_overlap_mentioned_p (operands[0], operands[1])"
7125 [(parallel [(set (reg:CCC FLAGS_REG)
7127 (plus:SWI (match_dup 1) (match_dup 0))
7129 (set (match_dup 1) (plus:SWI (match_dup 1) (match_dup 0)))])])
7131 (define_insn "*addsi3_zext_cc_overflow_1"
7132 [(set (reg:CCC FLAGS_REG)
7135 (match_operand:SI 1 "nonimmediate_operand" "%0")
7136 (match_operand:SI 2 "x86_64_general_operand" "rme"))
7138 (set (match_operand:DI 0 "register_operand" "=r")
7139 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
7140 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
7141 "add{l}\t{%2, %k0|%k0, %2}"
7142 [(set_attr "type" "alu")
7143 (set_attr "mode" "SI")])
7145 (define_insn "*add<mode>3_cconly_overflow_2"
7146 [(set (reg:CCC FLAGS_REG)
7149 (match_operand:SWI 1 "nonimmediate_operand" "%0")
7150 (match_operand:SWI 2 "<general_operand>" "<g>"))
7152 (clobber (match_scratch:SWI 0 "=<r>"))]
7153 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7154 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
7155 [(set_attr "type" "alu")
7156 (set_attr "mode" "<MODE>")])
7158 (define_insn "*add<mode>3_cc_overflow_2"
7159 [(set (reg:CCC FLAGS_REG)
7162 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
7163 (match_operand:SWI 2 "<general_operand>" "<r><i>,m"))
7165 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
7166 (plus:SWI (match_dup 1) (match_dup 2)))]
7167 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
7168 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
7169 [(set_attr "type" "alu")
7170 (set_attr "mode" "<MODE>")])
7172 (define_insn "*addsi3_zext_cc_overflow_2"
7173 [(set (reg:CCC FLAGS_REG)
7176 (match_operand:SI 1 "nonimmediate_operand" "%0")
7177 (match_operand:SI 2 "x86_64_general_operand" "rme"))
7179 (set (match_operand:DI 0 "register_operand" "=r")
7180 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
7181 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
7182 "add{l}\t{%2, %k0|%k0, %2}"
7183 [(set_attr "type" "alu")
7184 (set_attr "mode" "SI")])
7186 (define_insn_and_split "*add<dwi>3_doubleword_cc_overflow_1"
7187 [(set (reg:CCC FLAGS_REG)
7190 (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0")
7191 (match_operand:<DWI> 2 "x86_64_hilo_general_operand" "r<di>,o"))
7193 (set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro,r")
7194 (plus:<DWI> (match_dup 1) (match_dup 2)))]
7195 "ix86_binary_operator_ok (PLUS, <DWI>mode, operands)"
7198 [(parallel [(set (reg:CCC FLAGS_REG)
7200 (plus:DWIH (match_dup 1) (match_dup 2))
7203 (plus:DWIH (match_dup 1) (match_dup 2)))])
7204 (parallel [(set (reg:CCC FLAGS_REG)
7209 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
7214 (ltu:<DWI> (reg:CC FLAGS_REG) (const_int 0)))))
7217 (plus:DWIH (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
7221 split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
7222 if (operands[2] == const0_rtx)
7224 emit_insn (gen_addcarry<mode>_0 (operands[3], operands[4], operands[5]));
7227 if (CONST_INT_P (operands[5]))
7228 operands[6] = simplify_unary_operation (ZERO_EXTEND, <DWI>mode,
7229 operands[5], <MODE>mode);
7231 operands[6] = gen_rtx_ZERO_EXTEND (<DWI>mode, operands[5]);
7234 ;; x == 0 with zero flag test can be done also as x < 1U with carry flag
7235 ;; test, where the latter is preferrable if we have some carry consuming
7237 ;; For x != 0, we need to use x < 1U with negation of carry, i.e.
7239 (define_insn_and_split "*add<mode>3_eq"
7240 [(set (match_operand:SWI 0 "nonimmediate_operand")
7243 (eq:SWI (match_operand 3 "int_nonimmediate_operand") (const_int 0))
7244 (match_operand:SWI 1 "nonimmediate_operand"))
7245 (match_operand:SWI 2 "<general_operand>")))
7246 (clobber (reg:CC FLAGS_REG))]
7247 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)
7248 && ix86_pre_reload_split ()"
7251 [(set (reg:CC FLAGS_REG)
7252 (compare:CC (match_dup 3) (const_int 1)))
7253 (parallel [(set (match_dup 0)
7255 (plus:SWI (ltu:SWI (reg:CC FLAGS_REG) (const_int 0))
7258 (clobber (reg:CC FLAGS_REG))])])
7260 (define_insn_and_split "*add<mode>3_ne"
7261 [(set (match_operand:SWI 0 "nonimmediate_operand")
7264 (ne:SWI (match_operand 3 "int_nonimmediate_operand") (const_int 0))
7265 (match_operand:SWI 1 "nonimmediate_operand"))
7266 (match_operand:SWI 2 "<immediate_operand>")))
7267 (clobber (reg:CC FLAGS_REG))]
7268 "CONST_INT_P (operands[2])
7269 && (<MODE>mode != DImode
7270 || INTVAL (operands[2]) != HOST_WIDE_INT_C (-0x80000000))
7271 && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)
7272 && ix86_pre_reload_split ()"
7275 [(set (reg:CC FLAGS_REG)
7276 (compare:CC (match_dup 3) (const_int 1)))
7277 (parallel [(set (match_dup 0)
7279 (minus:SWI (match_dup 1)
7280 (ltu:SWI (reg:CC FLAGS_REG) (const_int 0)))
7282 (clobber (reg:CC FLAGS_REG))])]
7284 operands[2] = gen_int_mode (~INTVAL (operands[2]),
7285 <MODE>mode == DImode ? SImode : <MODE>mode);
7288 (define_insn_and_split "*add<mode>3_eq_0"
7289 [(set (match_operand:SWI 0 "nonimmediate_operand")
7291 (eq:SWI (match_operand 2 "int_nonimmediate_operand") (const_int 0))
7292 (match_operand:SWI 1 "<general_operand>")))
7293 (clobber (reg:CC FLAGS_REG))]
7294 "ix86_unary_operator_ok (PLUS, <MODE>mode, operands)
7295 && ix86_pre_reload_split ()"
7298 [(set (reg:CC FLAGS_REG)
7299 (compare:CC (match_dup 2) (const_int 1)))
7300 (parallel [(set (match_dup 0)
7301 (plus:SWI (ltu:SWI (reg:CC FLAGS_REG) (const_int 0))
7303 (clobber (reg:CC FLAGS_REG))])]
7305 if (!nonimmediate_operand (operands[1], <MODE>mode))
7306 operands[1] = force_reg (<MODE>mode, operands[1]);
7309 (define_insn_and_split "*add<mode>3_ne_0"
7310 [(set (match_operand:SWI 0 "nonimmediate_operand")
7312 (ne:SWI (match_operand 2 "int_nonimmediate_operand") (const_int 0))
7313 (match_operand:SWI 1 "<general_operand>")))
7314 (clobber (reg:CC FLAGS_REG))]
7315 "ix86_unary_operator_ok (PLUS, <MODE>mode, operands)
7316 && ix86_pre_reload_split ()"
7319 [(set (reg:CC FLAGS_REG)
7320 (compare:CC (match_dup 2) (const_int 1)))
7321 (parallel [(set (match_dup 0)
7322 (minus:SWI (minus:SWI
7324 (ltu:SWI (reg:CC FLAGS_REG) (const_int 0)))
7326 (clobber (reg:CC FLAGS_REG))])]
7328 if (!nonimmediate_operand (operands[1], <MODE>mode))
7329 operands[1] = force_reg (<MODE>mode, operands[1]);
7332 (define_insn_and_split "*sub<mode>3_eq"
7333 [(set (match_operand:SWI 0 "nonimmediate_operand")
7336 (match_operand:SWI 1 "nonimmediate_operand")
7337 (eq:SWI (match_operand 3 "int_nonimmediate_operand")
7339 (match_operand:SWI 2 "<general_operand>")))
7340 (clobber (reg:CC FLAGS_REG))]
7341 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)
7342 && ix86_pre_reload_split ()"
7345 [(set (reg:CC FLAGS_REG)
7346 (compare:CC (match_dup 3) (const_int 1)))
7347 (parallel [(set (match_dup 0)
7349 (minus:SWI (match_dup 1)
7350 (ltu:SWI (reg:CC FLAGS_REG) (const_int 0)))
7352 (clobber (reg:CC FLAGS_REG))])])
7354 (define_insn_and_split "*sub<mode>3_ne"
7355 [(set (match_operand:SWI 0 "nonimmediate_operand")
7358 (match_operand:SWI 1 "nonimmediate_operand")
7359 (ne:SWI (match_operand 3 "int_nonimmediate_operand")
7361 (match_operand:SWI 2 "<immediate_operand>")))
7362 (clobber (reg:CC FLAGS_REG))]
7363 "CONST_INT_P (operands[2])
7364 && (<MODE>mode != DImode
7365 || INTVAL (operands[2]) != HOST_WIDE_INT_C (-0x80000000))
7366 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)
7367 && ix86_pre_reload_split ()"
7370 [(set (reg:CC FLAGS_REG)
7371 (compare:CC (match_dup 3) (const_int 1)))
7372 (parallel [(set (match_dup 0)
7374 (plus:SWI (ltu:SWI (reg:CC FLAGS_REG) (const_int 0))
7377 (clobber (reg:CC FLAGS_REG))])]
7379 operands[2] = gen_int_mode (INTVAL (operands[2]) - 1,
7380 <MODE>mode == DImode ? SImode : <MODE>mode);
7383 (define_insn_and_split "*sub<mode>3_eq_1"
7384 [(set (match_operand:SWI 0 "nonimmediate_operand")
7387 (match_operand:SWI 1 "nonimmediate_operand")
7388 (eq:SWI (match_operand 3 "int_nonimmediate_operand")
7390 (match_operand:SWI 2 "<immediate_operand>")))
7391 (clobber (reg:CC FLAGS_REG))]
7392 "CONST_INT_P (operands[2])
7393 && (<MODE>mode != DImode
7394 || INTVAL (operands[2]) != HOST_WIDE_INT_C (-0x80000000))
7395 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)
7396 && ix86_pre_reload_split ()"
7399 [(set (reg:CC FLAGS_REG)
7400 (compare:CC (match_dup 3) (const_int 1)))
7401 (parallel [(set (match_dup 0)
7403 (minus:SWI (match_dup 1)
7404 (ltu:SWI (reg:CC FLAGS_REG) (const_int 0)))
7406 (clobber (reg:CC FLAGS_REG))])]
7408 operands[2] = gen_int_mode (-INTVAL (operands[2]),
7409 <MODE>mode == DImode ? SImode : <MODE>mode);
7412 (define_insn_and_split "*sub<mode>3_eq_0"
7413 [(set (match_operand:SWI 0 "nonimmediate_operand")
7415 (match_operand:SWI 1 "<general_operand>")
7416 (eq:SWI (match_operand 2 "int_nonimmediate_operand") (const_int 0))))
7417 (clobber (reg:CC FLAGS_REG))]
7418 "ix86_unary_operator_ok (MINUS, <MODE>mode, operands)
7419 && ix86_pre_reload_split ()"
7422 [(set (reg:CC FLAGS_REG)
7423 (compare:CC (match_dup 2) (const_int 1)))
7424 (parallel [(set (match_dup 0)
7425 (minus:SWI (match_dup 1)
7426 (ltu:SWI (reg:CC FLAGS_REG) (const_int 0))))
7427 (clobber (reg:CC FLAGS_REG))])]
7429 if (!nonimmediate_operand (operands[1], <MODE>mode))
7430 operands[1] = force_reg (<MODE>mode, operands[1]);
7433 (define_insn_and_split "*sub<mode>3_ne_0"
7434 [(set (match_operand:SWI 0 "nonimmediate_operand")
7436 (match_operand:SWI 1 "<general_operand>")
7437 (ne:SWI (match_operand 2 "int_nonimmediate_operand") (const_int 0))))
7438 (clobber (reg:CC FLAGS_REG))]
7439 "ix86_unary_operator_ok (MINUS, <MODE>mode, operands)
7440 && ix86_pre_reload_split ()"
7443 [(set (reg:CC FLAGS_REG)
7444 (compare:CC (match_dup 2) (const_int 1)))
7445 (parallel [(set (match_dup 0)
7447 (ltu:SWI (reg:CC FLAGS_REG) (const_int 0))
7450 (clobber (reg:CC FLAGS_REG))])]
7452 if (!nonimmediate_operand (operands[1], <MODE>mode))
7453 operands[1] = force_reg (<MODE>mode, operands[1]);
7456 ;; The patterns that match these are at the end of this file.
7458 (define_expand "<insn>xf3"
7459 [(set (match_operand:XF 0 "register_operand")
7461 (match_operand:XF 1 "register_operand")
7462 (match_operand:XF 2 "register_operand")))]
7465 (define_expand "<insn><mode>3"
7466 [(set (match_operand:MODEF 0 "register_operand")
7468 (match_operand:MODEF 1 "register_operand")
7469 (match_operand:MODEF 2 "nonimmediate_operand")))]
7470 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
7471 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
7473 ;; Multiply instructions
7475 (define_expand "mul<mode>3"
7476 [(parallel [(set (match_operand:SWIM248 0 "register_operand")
7478 (match_operand:SWIM248 1 "register_operand")
7479 (match_operand:SWIM248 2 "<general_operand>")))
7480 (clobber (reg:CC FLAGS_REG))])])
7482 (define_expand "mulqi3"
7483 [(parallel [(set (match_operand:QI 0 "register_operand")
7485 (match_operand:QI 1 "register_operand")
7486 (match_operand:QI 2 "nonimmediate_operand")))
7487 (clobber (reg:CC FLAGS_REG))])]
7488 "TARGET_QIMODE_MATH")
7491 ;; IMUL reg32/64, reg32/64, imm8 Direct
7492 ;; IMUL reg32/64, mem32/64, imm8 VectorPath
7493 ;; IMUL reg32/64, reg32/64, imm32 Direct
7494 ;; IMUL reg32/64, mem32/64, imm32 VectorPath
7495 ;; IMUL reg32/64, reg32/64 Direct
7496 ;; IMUL reg32/64, mem32/64 Direct
7498 ;; On BDVER1, all above IMULs use DirectPath
7501 ;; IMUL reg16, reg16, imm8 VectorPath
7502 ;; IMUL reg16, mem16, imm8 VectorPath
7503 ;; IMUL reg16, reg16, imm16 VectorPath
7504 ;; IMUL reg16, mem16, imm16 VectorPath
7505 ;; IMUL reg16, reg16 Direct
7506 ;; IMUL reg16, mem16 Direct
7508 ;; On BDVER1, all HI MULs use DoublePath
7510 (define_insn "*mul<mode>3_1"
7511 [(set (match_operand:SWIM248 0 "register_operand" "=r,r,r")
7513 (match_operand:SWIM248 1 "nonimmediate_operand" "%rm,rm,0")
7514 (match_operand:SWIM248 2 "<general_operand>" "K,<i>,mr")))
7515 (clobber (reg:CC FLAGS_REG))]
7516 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7518 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
7519 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
7520 imul{<imodesuffix>}\t{%2, %0|%0, %2}"
7521 [(set_attr "type" "imul")
7522 (set_attr "prefix_0f" "0,0,1")
7523 (set (attr "athlon_decode")
7524 (cond [(eq_attr "cpu" "athlon")
7525 (const_string "vector")
7526 (eq_attr "alternative" "1")
7527 (const_string "vector")
7528 (and (eq_attr "alternative" "2")
7529 (ior (match_test "<MODE>mode == HImode")
7530 (match_operand 1 "memory_operand")))
7531 (const_string "vector")]
7532 (const_string "direct")))
7533 (set (attr "amdfam10_decode")
7534 (cond [(and (eq_attr "alternative" "0,1")
7535 (ior (match_test "<MODE>mode == HImode")
7536 (match_operand 1 "memory_operand")))
7537 (const_string "vector")]
7538 (const_string "direct")))
7539 (set (attr "bdver1_decode")
7541 (match_test "<MODE>mode == HImode")
7542 (const_string "double")
7543 (const_string "direct")))
7544 (set_attr "mode" "<MODE>")])
7546 (define_insn "*mulsi3_1_zext"
7547 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
7549 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
7550 (match_operand:SI 2 "x86_64_general_operand" "K,e,mr"))))
7551 (clobber (reg:CC FLAGS_REG))]
7553 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7555 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7556 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7557 imul{l}\t{%2, %k0|%k0, %2}"
7558 [(set_attr "type" "imul")
7559 (set_attr "prefix_0f" "0,0,1")
7560 (set (attr "athlon_decode")
7561 (cond [(eq_attr "cpu" "athlon")
7562 (const_string "vector")
7563 (eq_attr "alternative" "1")
7564 (const_string "vector")
7565 (and (eq_attr "alternative" "2")
7566 (match_operand 1 "memory_operand"))
7567 (const_string "vector")]
7568 (const_string "direct")))
7569 (set (attr "amdfam10_decode")
7570 (cond [(and (eq_attr "alternative" "0,1")
7571 (match_operand 1 "memory_operand"))
7572 (const_string "vector")]
7573 (const_string "direct")))
7574 (set_attr "bdver1_decode" "direct")
7575 (set_attr "mode" "SI")])
7577 ;;On AMDFAM10 and BDVER1
7581 (define_insn "*mulqi3_1"
7582 [(set (match_operand:QI 0 "register_operand" "=a")
7583 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
7584 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7585 (clobber (reg:CC FLAGS_REG))]
7587 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7589 [(set_attr "type" "imul")
7590 (set_attr "length_immediate" "0")
7591 (set (attr "athlon_decode")
7592 (if_then_else (eq_attr "cpu" "athlon")
7593 (const_string "vector")
7594 (const_string "direct")))
7595 (set_attr "amdfam10_decode" "direct")
7596 (set_attr "bdver1_decode" "direct")
7597 (set_attr "mode" "QI")])
7599 ;; Multiply with jump on overflow.
7600 (define_expand "mulv<mode>4"
7601 [(parallel [(set (reg:CCO FLAGS_REG)
7604 (match_operand:SWI248 1 "register_operand"))
7607 (mult:SWI248 (match_dup 1)
7608 (match_operand:SWI248 2
7609 "<general_operand>")))))
7610 (set (match_operand:SWI248 0 "register_operand")
7611 (mult:SWI248 (match_dup 1) (match_dup 2)))])
7612 (set (pc) (if_then_else
7613 (eq (reg:CCO FLAGS_REG) (const_int 0))
7614 (label_ref (match_operand 3))
7618 if (CONST_INT_P (operands[2]))
7619 operands[4] = operands[2];
7621 operands[4] = gen_rtx_SIGN_EXTEND (<DWI>mode, operands[2]);
7624 (define_insn "*mulv<mode>4"
7625 [(set (reg:CCO FLAGS_REG)
7628 (match_operand:SWI48 1 "nonimmediate_operand" "%rm,0"))
7630 (match_operand:SWI48 2 "x86_64_sext_operand" "We,mr")))
7632 (mult:SWI48 (match_dup 1) (match_dup 2)))))
7633 (set (match_operand:SWI48 0 "register_operand" "=r,r")
7634 (mult:SWI48 (match_dup 1) (match_dup 2)))]
7635 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7637 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
7638 imul{<imodesuffix>}\t{%2, %0|%0, %2}"
7639 [(set_attr "type" "imul")
7640 (set_attr "prefix_0f" "0,1")
7641 (set (attr "athlon_decode")
7642 (cond [(eq_attr "cpu" "athlon")
7643 (const_string "vector")
7644 (eq_attr "alternative" "0")
7645 (const_string "vector")
7646 (and (eq_attr "alternative" "1")
7647 (match_operand 1 "memory_operand"))
7648 (const_string "vector")]
7649 (const_string "direct")))
7650 (set (attr "amdfam10_decode")
7651 (cond [(and (eq_attr "alternative" "1")
7652 (match_operand 1 "memory_operand"))
7653 (const_string "vector")]
7654 (const_string "direct")))
7655 (set_attr "bdver1_decode" "direct")
7656 (set_attr "mode" "<MODE>")])
7658 (define_insn "*mulvhi4"
7659 [(set (reg:CCO FLAGS_REG)
7662 (match_operand:HI 1 "nonimmediate_operand" "%0"))
7664 (match_operand:HI 2 "nonimmediate_operand" "mr")))
7666 (mult:HI (match_dup 1) (match_dup 2)))))
7667 (set (match_operand:HI 0 "register_operand" "=r")
7668 (mult:HI (match_dup 1) (match_dup 2)))]
7669 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7670 "imul{w}\t{%2, %0|%0, %2}"
7671 [(set_attr "type" "imul")
7672 (set_attr "prefix_0f" "1")
7673 (set_attr "athlon_decode" "vector")
7674 (set_attr "amdfam10_decode" "direct")
7675 (set_attr "bdver1_decode" "double")
7676 (set_attr "mode" "HI")])
7678 (define_insn "*mulv<mode>4_1"
7679 [(set (reg:CCO FLAGS_REG)
7682 (match_operand:SWI248 1 "nonimmediate_operand" "rm,rm"))
7683 (match_operand:<DWI> 3 "const_int_operand" "K,i"))
7685 (mult:SWI248 (match_dup 1)
7686 (match_operand:SWI248 2
7687 "<immediate_operand>" "K,<i>")))))
7688 (set (match_operand:SWI248 0 "register_operand" "=r,r")
7689 (mult:SWI248 (match_dup 1) (match_dup 2)))]
7690 "!(MEM_P (operands[1]) && MEM_P (operands[2]))
7691 && CONST_INT_P (operands[2])
7692 && INTVAL (operands[2]) == INTVAL (operands[3])"
7693 "imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}"
7694 [(set_attr "type" "imul")
7695 (set (attr "prefix_0f")
7697 (match_test "<MODE>mode == HImode")
7699 (const_string "*")))
7700 (set (attr "athlon_decode")
7701 (cond [(eq_attr "cpu" "athlon")
7702 (const_string "vector")
7703 (eq_attr "alternative" "1")
7704 (const_string "vector")]
7705 (const_string "direct")))
7706 (set (attr "amdfam10_decode")
7707 (cond [(ior (match_test "<MODE>mode == HImode")
7708 (match_operand 1 "memory_operand"))
7709 (const_string "vector")]
7710 (const_string "direct")))
7711 (set (attr "bdver1_decode")
7713 (match_test "<MODE>mode == HImode")
7714 (const_string "double")
7715 (const_string "direct")))
7716 (set_attr "mode" "<MODE>")
7717 (set (attr "length_immediate")
7718 (cond [(eq_attr "alternative" "0")
7720 (match_test "<MODE_SIZE> == 8")
7722 (const_string "<MODE_SIZE>")))])
7724 (define_expand "umulv<mode>4"
7725 [(parallel [(set (reg:CCO FLAGS_REG)
7728 (match_operand:SWI248 1
7729 "nonimmediate_operand"))
7731 (match_operand:SWI248 2
7732 "nonimmediate_operand")))
7734 (mult:SWI248 (match_dup 1) (match_dup 2)))))
7735 (set (match_operand:SWI248 0 "register_operand")
7736 (mult:SWI248 (match_dup 1) (match_dup 2)))
7737 (clobber (scratch:SWI248))])
7738 (set (pc) (if_then_else
7739 (eq (reg:CCO FLAGS_REG) (const_int 0))
7740 (label_ref (match_operand 3))
7744 if (MEM_P (operands[1]) && MEM_P (operands[2]))
7745 operands[1] = force_reg (<MODE>mode, operands[1]);
7748 (define_insn "*umulv<mode>4"
7749 [(set (reg:CCO FLAGS_REG)
7752 (match_operand:SWI248 1 "nonimmediate_operand" "%0"))
7754 (match_operand:SWI248 2 "nonimmediate_operand" "rm")))
7756 (mult:SWI248 (match_dup 1) (match_dup 2)))))
7757 (set (match_operand:SWI248 0 "register_operand" "=a")
7758 (mult:SWI248 (match_dup 1) (match_dup 2)))
7759 (clobber (match_scratch:SWI248 3 "=d"))]
7760 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7761 "mul{<imodesuffix>}\t%2"
7762 [(set_attr "type" "imul")
7763 (set_attr "length_immediate" "0")
7764 (set (attr "athlon_decode")
7765 (if_then_else (eq_attr "cpu" "athlon")
7766 (const_string "vector")
7767 (const_string "double")))
7768 (set_attr "amdfam10_decode" "double")
7769 (set_attr "bdver1_decode" "direct")
7770 (set_attr "mode" "<MODE>")])
7772 (define_expand "<u>mulvqi4"
7773 [(parallel [(set (reg:CCO FLAGS_REG)
7776 (match_operand:QI 1 "nonimmediate_operand"))
7778 (match_operand:QI 2 "nonimmediate_operand")))
7780 (mult:QI (match_dup 1) (match_dup 2)))))
7781 (set (match_operand:QI 0 "register_operand")
7782 (mult:QI (match_dup 1) (match_dup 2)))])
7783 (set (pc) (if_then_else
7784 (eq (reg:CCO FLAGS_REG) (const_int 0))
7785 (label_ref (match_operand 3))
7787 "TARGET_QIMODE_MATH"
7789 if (MEM_P (operands[1]) && MEM_P (operands[2]))
7790 operands[1] = force_reg (QImode, operands[1]);
7793 (define_insn "*<u>mulvqi4"
7794 [(set (reg:CCO FLAGS_REG)
7797 (match_operand:QI 1 "nonimmediate_operand" "%0"))
7799 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7801 (mult:QI (match_dup 1) (match_dup 2)))))
7802 (set (match_operand:QI 0 "register_operand" "=a")
7803 (mult:QI (match_dup 1) (match_dup 2)))]
7805 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7806 "<sgnprefix>mul{b}\t%2"
7807 [(set_attr "type" "imul")
7808 (set_attr "length_immediate" "0")
7809 (set (attr "athlon_decode")
7810 (if_then_else (eq_attr "cpu" "athlon")
7811 (const_string "vector")
7812 (const_string "direct")))
7813 (set_attr "amdfam10_decode" "direct")
7814 (set_attr "bdver1_decode" "direct")
7815 (set_attr "mode" "QI")])
7817 (define_expand "<u>mul<mode><dwi>3"
7818 [(parallel [(set (match_operand:<DWI> 0 "register_operand")
7821 (match_operand:DWIH 1 "nonimmediate_operand"))
7823 (match_operand:DWIH 2 "register_operand"))))
7824 (clobber (reg:CC FLAGS_REG))])])
7826 (define_expand "<u>mulqihi3"
7827 [(parallel [(set (match_operand:HI 0 "register_operand")
7830 (match_operand:QI 1 "nonimmediate_operand"))
7832 (match_operand:QI 2 "register_operand"))))
7833 (clobber (reg:CC FLAGS_REG))])]
7834 "TARGET_QIMODE_MATH")
7836 (define_insn "*bmi2_umul<mode><dwi>3_1"
7837 [(set (match_operand:DWIH 0 "register_operand" "=r")
7839 (match_operand:DWIH 2 "nonimmediate_operand" "%d")
7840 (match_operand:DWIH 3 "nonimmediate_operand" "rm")))
7841 (set (match_operand:DWIH 1 "register_operand" "=r")
7844 (mult:<DWI> (zero_extend:<DWI> (match_dup 2))
7845 (zero_extend:<DWI> (match_dup 3)))
7846 (match_operand:QI 4 "const_int_operand" "n"))))]
7847 "TARGET_BMI2 && INTVAL (operands[4]) == <MODE_SIZE> * BITS_PER_UNIT
7848 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7849 "mulx\t{%3, %0, %1|%1, %0, %3}"
7850 [(set_attr "type" "imulx")
7851 (set_attr "prefix" "vex")
7852 (set_attr "mode" "<MODE>")])
7854 (define_insn "*umul<mode><dwi>3_1"
7855 [(set (match_operand:<DWI> 0 "register_operand" "=r,A")
7858 (match_operand:DWIH 1 "nonimmediate_operand" "%d,0"))
7860 (match_operand:DWIH 2 "nonimmediate_operand" "rm,rm"))))
7861 (clobber (reg:CC FLAGS_REG))]
7862 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7865 mul{<imodesuffix>}\t%2"
7866 [(set_attr "isa" "bmi2,*")
7867 (set_attr "type" "imulx,imul")
7868 (set_attr "length_immediate" "*,0")
7869 (set (attr "athlon_decode")
7870 (cond [(eq_attr "alternative" "1")
7871 (if_then_else (eq_attr "cpu" "athlon")
7872 (const_string "vector")
7873 (const_string "double"))]
7874 (const_string "*")))
7875 (set_attr "amdfam10_decode" "*,double")
7876 (set_attr "bdver1_decode" "*,direct")
7877 (set_attr "prefix" "vex,orig")
7878 (set_attr "mode" "<MODE>")])
7880 ;; Convert mul to the mulx pattern to avoid flags dependency.
7882 [(set (match_operand:<DWI> 0 "register_operand")
7885 (match_operand:DWIH 1 "register_operand"))
7887 (match_operand:DWIH 2 "nonimmediate_operand"))))
7888 (clobber (reg:CC FLAGS_REG))]
7889 "TARGET_BMI2 && reload_completed
7890 && REGNO (operands[1]) == DX_REG"
7891 [(parallel [(set (match_dup 3)
7892 (mult:DWIH (match_dup 1) (match_dup 2)))
7896 (mult:<DWI> (zero_extend:<DWI> (match_dup 1))
7897 (zero_extend:<DWI> (match_dup 2)))
7900 split_double_mode (<DWI>mode, &operands[0], 1, &operands[3], &operands[4]);
7902 operands[5] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT);
7905 (define_insn "*mul<mode><dwi>3_1"
7906 [(set (match_operand:<DWI> 0 "register_operand" "=A")
7909 (match_operand:DWIH 1 "nonimmediate_operand" "%0"))
7911 (match_operand:DWIH 2 "nonimmediate_operand" "rm"))))
7912 (clobber (reg:CC FLAGS_REG))]
7913 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7914 "imul{<imodesuffix>}\t%2"
7915 [(set_attr "type" "imul")
7916 (set_attr "length_immediate" "0")
7917 (set (attr "athlon_decode")
7918 (if_then_else (eq_attr "cpu" "athlon")
7919 (const_string "vector")
7920 (const_string "double")))
7921 (set_attr "amdfam10_decode" "double")
7922 (set_attr "bdver1_decode" "direct")
7923 (set_attr "mode" "<MODE>")])
7925 (define_insn "*<u>mulqihi3_1"
7926 [(set (match_operand:HI 0 "register_operand" "=a")
7929 (match_operand:QI 1 "nonimmediate_operand" "%0"))
7931 (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7932 (clobber (reg:CC FLAGS_REG))]
7934 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7935 "<sgnprefix>mul{b}\t%2"
7936 [(set_attr "type" "imul")
7937 (set_attr "length_immediate" "0")
7938 (set (attr "athlon_decode")
7939 (if_then_else (eq_attr "cpu" "athlon")
7940 (const_string "vector")
7941 (const_string "direct")))
7942 (set_attr "amdfam10_decode" "direct")
7943 (set_attr "bdver1_decode" "direct")
7944 (set_attr "mode" "QI")])
7946 (define_expand "<s>mul<mode>3_highpart"
7947 [(parallel [(set (match_operand:DWIH 0 "register_operand")
7952 (match_operand:DWIH 1 "nonimmediate_operand"))
7954 (match_operand:DWIH 2 "register_operand")))
7956 (clobber (scratch:DWIH))
7957 (clobber (reg:CC FLAGS_REG))])]
7959 "operands[3] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
7961 (define_insn "*<s>muldi3_highpart_1"
7962 [(set (match_operand:DI 0 "register_operand" "=d")
7967 (match_operand:DI 1 "nonimmediate_operand" "%a"))
7969 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7971 (clobber (match_scratch:DI 3 "=1"))
7972 (clobber (reg:CC FLAGS_REG))]
7974 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7975 "<sgnprefix>mul{q}\t%2"
7976 [(set_attr "type" "imul")
7977 (set_attr "length_immediate" "0")
7978 (set (attr "athlon_decode")
7979 (if_then_else (eq_attr "cpu" "athlon")
7980 (const_string "vector")
7981 (const_string "double")))
7982 (set_attr "amdfam10_decode" "double")
7983 (set_attr "bdver1_decode" "direct")
7984 (set_attr "mode" "DI")])
7986 (define_insn "*<s>mulsi3_highpart_zext"
7987 [(set (match_operand:DI 0 "register_operand" "=d")
7988 (zero_extend:DI (truncate:SI
7990 (mult:DI (any_extend:DI
7991 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7993 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7995 (clobber (match_scratch:SI 3 "=1"))
7996 (clobber (reg:CC FLAGS_REG))]
7998 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7999 "<sgnprefix>mul{l}\t%2"
8000 [(set_attr "type" "imul")
8001 (set_attr "length_immediate" "0")
8002 (set (attr "athlon_decode")
8003 (if_then_else (eq_attr "cpu" "athlon")
8004 (const_string "vector")
8005 (const_string "double")))
8006 (set_attr "amdfam10_decode" "double")
8007 (set_attr "bdver1_decode" "direct")
8008 (set_attr "mode" "SI")])
8010 (define_insn "*<s>mulsi3_highpart_1"
8011 [(set (match_operand:SI 0 "register_operand" "=d")
8016 (match_operand:SI 1 "nonimmediate_operand" "%a"))
8018 (match_operand:SI 2 "nonimmediate_operand" "rm")))
8020 (clobber (match_scratch:SI 3 "=1"))
8021 (clobber (reg:CC FLAGS_REG))]
8022 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
8023 "<sgnprefix>mul{l}\t%2"
8024 [(set_attr "type" "imul")
8025 (set_attr "length_immediate" "0")
8026 (set (attr "athlon_decode")
8027 (if_then_else (eq_attr "cpu" "athlon")
8028 (const_string "vector")
8029 (const_string "double")))
8030 (set_attr "amdfam10_decode" "double")
8031 (set_attr "bdver1_decode" "direct")
8032 (set_attr "mode" "SI")])
8034 ;; The patterns that match these are at the end of this file.
8036 (define_expand "mulxf3"
8037 [(set (match_operand:XF 0 "register_operand")
8038 (mult:XF (match_operand:XF 1 "register_operand")
8039 (match_operand:XF 2 "register_operand")))]
8042 (define_expand "mul<mode>3"
8043 [(set (match_operand:MODEF 0 "register_operand")
8044 (mult:MODEF (match_operand:MODEF 1 "register_operand")
8045 (match_operand:MODEF 2 "nonimmediate_operand")))]
8046 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
8047 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
8049 ;; Divide instructions
8051 ;; The patterns that match these are at the end of this file.
8053 (define_expand "divxf3"
8054 [(set (match_operand:XF 0 "register_operand")
8055 (div:XF (match_operand:XF 1 "register_operand")
8056 (match_operand:XF 2 "register_operand")))]
8059 (define_expand "div<mode>3"
8060 [(set (match_operand:MODEF 0 "register_operand")
8061 (div:MODEF (match_operand:MODEF 1 "register_operand")
8062 (match_operand:MODEF 2 "nonimmediate_operand")))]
8063 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
8064 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8066 if (<MODE>mode == SFmode
8067 && TARGET_SSE && TARGET_SSE_MATH
8069 && optimize_insn_for_speed_p ()
8070 && flag_finite_math_only && !flag_trapping_math
8071 && flag_unsafe_math_optimizations)
8073 ix86_emit_swdivsf (operands[0], operands[1],
8074 operands[2], SFmode);
8079 ;; Divmod instructions.
8081 (define_code_iterator any_div [div udiv])
8082 (define_code_attr paired_mod [(div "mod") (udiv "umod")])
8084 (define_expand "<u>divmod<mode>4"
8085 [(parallel [(set (match_operand:SWIM248 0 "register_operand")
8087 (match_operand:SWIM248 1 "register_operand")
8088 (match_operand:SWIM248 2 "nonimmediate_operand")))
8089 (set (match_operand:SWIM248 3 "register_operand")
8090 (<paired_mod>:SWIM248 (match_dup 1) (match_dup 2)))
8091 (clobber (reg:CC FLAGS_REG))])])
8093 ;; Split with 8bit unsigned divide:
8094 ;; if (dividend an divisor are in [0-255])
8095 ;; use 8bit unsigned integer divide
8097 ;; use original integer divide
8099 [(set (match_operand:SWI48 0 "register_operand")
8100 (any_div:SWI48 (match_operand:SWI48 2 "register_operand")
8101 (match_operand:SWI48 3 "nonimmediate_operand")))
8102 (set (match_operand:SWI48 1 "register_operand")
8103 (<paired_mod>:SWI48 (match_dup 2) (match_dup 3)))
8104 (clobber (reg:CC FLAGS_REG))]
8105 "TARGET_USE_8BIT_IDIV
8106 && TARGET_QIMODE_MATH
8107 && can_create_pseudo_p ()
8108 && !optimize_insn_for_size_p ()"
8110 "ix86_split_idivmod (<MODE>mode, operands, <u_bool>); DONE;")
8113 [(set (match_operand:DI 0 "register_operand")
8115 (any_div:SI (match_operand:SI 2 "register_operand")
8116 (match_operand:SI 3 "nonimmediate_operand"))))
8117 (set (match_operand:SI 1 "register_operand")
8118 (<paired_mod>:SI (match_dup 2) (match_dup 3)))
8119 (clobber (reg:CC FLAGS_REG))]
8121 && TARGET_USE_8BIT_IDIV
8122 && TARGET_QIMODE_MATH
8123 && can_create_pseudo_p ()
8124 && !optimize_insn_for_size_p ()"
8126 "ix86_split_idivmod (SImode, operands, <u_bool>); DONE;")
8129 [(set (match_operand:DI 1 "register_operand")
8131 (<paired_mod>:SI (match_operand:SI 2 "register_operand")
8132 (match_operand:SI 3 "nonimmediate_operand"))))
8133 (set (match_operand:SI 0 "register_operand")
8134 (any_div:SI (match_dup 2) (match_dup 3)))
8135 (clobber (reg:CC FLAGS_REG))]
8137 && TARGET_USE_8BIT_IDIV
8138 && TARGET_QIMODE_MATH
8139 && can_create_pseudo_p ()
8140 && !optimize_insn_for_size_p ()"
8142 "ix86_split_idivmod (SImode, operands, <u_bool>); DONE;")
8144 (define_insn_and_split "divmod<mode>4_1"
8145 [(set (match_operand:SWI48 0 "register_operand" "=a")
8146 (div:SWI48 (match_operand:SWI48 2 "register_operand" "0")
8147 (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
8148 (set (match_operand:SWI48 1 "register_operand" "=&d")
8149 (mod:SWI48 (match_dup 2) (match_dup 3)))
8150 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
8151 (clobber (reg:CC FLAGS_REG))]
8155 [(parallel [(set (match_dup 1)
8156 (ashiftrt:SWI48 (match_dup 4) (match_dup 5)))
8157 (clobber (reg:CC FLAGS_REG))])
8158 (parallel [(set (match_dup 0)
8159 (div:SWI48 (match_dup 2) (match_dup 3)))
8161 (mod:SWI48 (match_dup 2) (match_dup 3)))
8163 (clobber (reg:CC FLAGS_REG))])]
8165 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
8167 if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
8168 operands[4] = operands[2];
8171 /* Avoid use of cltd in favor of a mov+shift. */
8172 emit_move_insn (operands[1], operands[2]);
8173 operands[4] = operands[1];
8176 [(set_attr "type" "multi")
8177 (set_attr "mode" "<MODE>")])
8179 (define_insn_and_split "udivmod<mode>4_1"
8180 [(set (match_operand:SWI48 0 "register_operand" "=a")
8181 (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "0")
8182 (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
8183 (set (match_operand:SWI48 1 "register_operand" "=&d")
8184 (umod:SWI48 (match_dup 2) (match_dup 3)))
8185 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
8186 (clobber (reg:CC FLAGS_REG))]
8190 [(set (match_dup 1) (const_int 0))
8191 (parallel [(set (match_dup 0)
8192 (udiv:SWI48 (match_dup 2) (match_dup 3)))
8194 (umod:SWI48 (match_dup 2) (match_dup 3)))
8196 (clobber (reg:CC FLAGS_REG))])]
8198 [(set_attr "type" "multi")
8199 (set_attr "mode" "<MODE>")])
8201 (define_insn_and_split "divmodsi4_zext_1"
8202 [(set (match_operand:DI 0 "register_operand" "=a")
8204 (div:SI (match_operand:SI 2 "register_operand" "0")
8205 (match_operand:SI 3 "nonimmediate_operand" "rm"))))
8206 (set (match_operand:SI 1 "register_operand" "=&d")
8207 (mod:SI (match_dup 2) (match_dup 3)))
8208 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
8209 (clobber (reg:CC FLAGS_REG))]
8212 "&& reload_completed"
8213 [(parallel [(set (match_dup 1)
8214 (ashiftrt:SI (match_dup 4) (match_dup 5)))
8215 (clobber (reg:CC FLAGS_REG))])
8216 (parallel [(set (match_dup 0)
8217 (zero_extend:DI (div:SI (match_dup 2) (match_dup 3))))
8219 (mod:SI (match_dup 2) (match_dup 3)))
8221 (clobber (reg:CC FLAGS_REG))])]
8223 operands[5] = GEN_INT (GET_MODE_BITSIZE (SImode)-1);
8225 if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
8226 operands[4] = operands[2];
8229 /* Avoid use of cltd in favor of a mov+shift. */
8230 emit_move_insn (operands[1], operands[2]);
8231 operands[4] = operands[1];
8234 [(set_attr "type" "multi")
8235 (set_attr "mode" "SI")])
8237 (define_insn_and_split "udivmodsi4_zext_1"
8238 [(set (match_operand:DI 0 "register_operand" "=a")
8240 (udiv:SI (match_operand:SI 2 "register_operand" "0")
8241 (match_operand:SI 3 "nonimmediate_operand" "rm"))))
8242 (set (match_operand:SI 1 "register_operand" "=&d")
8243 (umod:SI (match_dup 2) (match_dup 3)))
8244 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
8245 (clobber (reg:CC FLAGS_REG))]
8248 "&& reload_completed"
8249 [(set (match_dup 1) (const_int 0))
8250 (parallel [(set (match_dup 0)
8251 (zero_extend:DI (udiv:SI (match_dup 2) (match_dup 3))))
8253 (umod:SI (match_dup 2) (match_dup 3)))
8255 (clobber (reg:CC FLAGS_REG))])]
8257 [(set_attr "type" "multi")
8258 (set_attr "mode" "SI")])
8260 (define_insn_and_split "divmodsi4_zext_2"
8261 [(set (match_operand:DI 1 "register_operand" "=&d")
8263 (mod:SI (match_operand:SI 2 "register_operand" "0")
8264 (match_operand:SI 3 "nonimmediate_operand" "rm"))))
8265 (set (match_operand:SI 0 "register_operand" "=a")
8266 (div:SI (match_dup 2) (match_dup 3)))
8267 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
8268 (clobber (reg:CC FLAGS_REG))]
8271 "&& reload_completed"
8272 [(parallel [(set (match_dup 6)
8273 (ashiftrt:SI (match_dup 4) (match_dup 5)))
8274 (clobber (reg:CC FLAGS_REG))])
8275 (parallel [(set (match_dup 1)
8276 (zero_extend:DI (mod:SI (match_dup 2) (match_dup 3))))
8278 (div:SI (match_dup 2) (match_dup 3)))
8280 (clobber (reg:CC FLAGS_REG))])]
8282 operands[5] = GEN_INT (GET_MODE_BITSIZE (SImode)-1);
8283 operands[6] = gen_lowpart (SImode, operands[1]);
8285 if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
8286 operands[4] = operands[2];
8289 /* Avoid use of cltd in favor of a mov+shift. */
8290 emit_move_insn (operands[6], operands[2]);
8291 operands[4] = operands[6];
8294 [(set_attr "type" "multi")
8295 (set_attr "mode" "SI")])
8297 (define_insn_and_split "udivmodsi4_zext_2"
8298 [(set (match_operand:DI 1 "register_operand" "=&d")
8300 (umod:SI (match_operand:SI 2 "register_operand" "0")
8301 (match_operand:SI 3 "nonimmediate_operand" "rm"))))
8302 (set (match_operand:SI 0 "register_operand" "=a")
8303 (udiv:SI (match_dup 2) (match_dup 3)))
8304 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
8305 (clobber (reg:CC FLAGS_REG))]
8308 "&& reload_completed"
8309 [(set (match_dup 4) (const_int 0))
8310 (parallel [(set (match_dup 1)
8311 (zero_extend:DI (umod:SI (match_dup 2) (match_dup 3))))
8313 (udiv:SI (match_dup 2) (match_dup 3)))
8315 (clobber (reg:CC FLAGS_REG))])]
8316 "operands[4] = gen_lowpart (SImode, operands[1]);"
8317 [(set_attr "type" "multi")
8318 (set_attr "mode" "SI")])
8320 (define_insn_and_split "*divmod<mode>4"
8321 [(set (match_operand:SWIM248 0 "register_operand" "=a")
8322 (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
8323 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
8324 (set (match_operand:SWIM248 1 "register_operand" "=&d")
8325 (mod:SWIM248 (match_dup 2) (match_dup 3)))
8326 (clobber (reg:CC FLAGS_REG))]
8330 [(parallel [(set (match_dup 1)
8331 (ashiftrt:SWIM248 (match_dup 4) (match_dup 5)))
8332 (clobber (reg:CC FLAGS_REG))])
8333 (parallel [(set (match_dup 0)
8334 (div:SWIM248 (match_dup 2) (match_dup 3)))
8336 (mod:SWIM248 (match_dup 2) (match_dup 3)))
8338 (clobber (reg:CC FLAGS_REG))])]
8340 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
8342 if (<MODE>mode != HImode
8343 && (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD))
8344 operands[4] = operands[2];
8347 /* Avoid use of cltd in favor of a mov+shift. */
8348 emit_move_insn (operands[1], operands[2]);
8349 operands[4] = operands[1];
8352 [(set_attr "type" "multi")
8353 (set_attr "mode" "<MODE>")])
8355 (define_insn_and_split "*udivmod<mode>4"
8356 [(set (match_operand:SWIM248 0 "register_operand" "=a")
8357 (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
8358 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
8359 (set (match_operand:SWIM248 1 "register_operand" "=&d")
8360 (umod:SWIM248 (match_dup 2) (match_dup 3)))
8361 (clobber (reg:CC FLAGS_REG))]
8365 [(set (match_dup 1) (const_int 0))
8366 (parallel [(set (match_dup 0)
8367 (udiv:SWIM248 (match_dup 2) (match_dup 3)))
8369 (umod:SWIM248 (match_dup 2) (match_dup 3)))
8371 (clobber (reg:CC FLAGS_REG))])]
8373 [(set_attr "type" "multi")
8374 (set_attr "mode" "<MODE>")])
8376 ;; Optimize division or modulo by constant power of 2, if the constant
8377 ;; materializes only after expansion.
8378 (define_insn_and_split "*udivmod<mode>4_pow2"
8379 [(set (match_operand:SWI48 0 "register_operand" "=r")
8380 (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "0")
8381 (match_operand:SWI48 3 "const_int_operand" "n")))
8382 (set (match_operand:SWI48 1 "register_operand" "=r")
8383 (umod:SWI48 (match_dup 2) (match_dup 3)))
8384 (clobber (reg:CC FLAGS_REG))]
8385 "IN_RANGE (exact_log2 (UINTVAL (operands[3])), 1, 31)"
8387 "&& reload_completed"
8388 [(set (match_dup 1) (match_dup 2))
8389 (parallel [(set (match_dup 0) (lshiftrt:<MODE> (match_dup 2) (match_dup 4)))
8390 (clobber (reg:CC FLAGS_REG))])
8391 (parallel [(set (match_dup 1) (and:<MODE> (match_dup 1) (match_dup 5)))
8392 (clobber (reg:CC FLAGS_REG))])]
8394 int v = exact_log2 (UINTVAL (operands[3]));
8395 operands[4] = GEN_INT (v);
8396 operands[5] = GEN_INT ((HOST_WIDE_INT_1U << v) - 1);
8398 [(set_attr "type" "multi")
8399 (set_attr "mode" "<MODE>")])
8401 (define_insn_and_split "*divmodsi4_zext_1"
8402 [(set (match_operand:DI 0 "register_operand" "=a")
8404 (div:SI (match_operand:SI 2 "register_operand" "0")
8405 (match_operand:SI 3 "nonimmediate_operand" "rm"))))
8406 (set (match_operand:SI 1 "register_operand" "=&d")
8407 (mod:SI (match_dup 2) (match_dup 3)))
8408 (clobber (reg:CC FLAGS_REG))]
8411 "&& reload_completed"
8412 [(parallel [(set (match_dup 1)
8413 (ashiftrt:SI (match_dup 4) (match_dup 5)))
8414 (clobber (reg:CC FLAGS_REG))])
8415 (parallel [(set (match_dup 0)
8416 (zero_extend:DI (div:SI (match_dup 2) (match_dup 3))))
8418 (mod:SI (match_dup 2) (match_dup 3)))
8420 (clobber (reg:CC FLAGS_REG))])]
8422 operands[5] = GEN_INT (GET_MODE_BITSIZE (SImode)-1);
8424 if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
8425 operands[4] = operands[2];
8428 /* Avoid use of cltd in favor of a mov+shift. */
8429 emit_move_insn (operands[1], operands[2]);
8430 operands[4] = operands[1];
8433 [(set_attr "type" "multi")
8434 (set_attr "mode" "SI")])
8436 (define_insn_and_split "*udivmodsi4_zext_1"
8437 [(set (match_operand:DI 0 "register_operand" "=a")
8439 (udiv:SI (match_operand:SI 2 "register_operand" "0")
8440 (match_operand:SI 3 "nonimmediate_operand" "rm"))))
8441 (set (match_operand:SI 1 "register_operand" "=&d")
8442 (umod:SI (match_dup 2) (match_dup 3)))
8443 (clobber (reg:CC FLAGS_REG))]
8446 "&& reload_completed"
8447 [(set (match_dup 1) (const_int 0))
8448 (parallel [(set (match_dup 0)
8449 (zero_extend:DI (udiv:SI (match_dup 2) (match_dup 3))))
8451 (umod:SI (match_dup 2) (match_dup 3)))
8453 (clobber (reg:CC FLAGS_REG))])]
8455 [(set_attr "type" "multi")
8456 (set_attr "mode" "SI")])
8458 (define_insn_and_split "*udivmodsi4_pow2_zext_1"
8459 [(set (match_operand:DI 0 "register_operand" "=r")
8461 (udiv:SI (match_operand:SI 2 "register_operand" "0")
8462 (match_operand:SI 3 "const_int_operand" "n"))))
8463 (set (match_operand:SI 1 "register_operand" "=r")
8464 (umod:SI (match_dup 2) (match_dup 3)))
8465 (clobber (reg:CC FLAGS_REG))]
8467 && exact_log2 (UINTVAL (operands[3])) > 0"
8469 "&& reload_completed"
8470 [(set (match_dup 1) (match_dup 2))
8471 (parallel [(set (match_dup 0)
8472 (zero_extend:DI (lshiftrt:SI (match_dup 2) (match_dup 4))))
8473 (clobber (reg:CC FLAGS_REG))])
8474 (parallel [(set (match_dup 1) (and:SI (match_dup 1) (match_dup 5)))
8475 (clobber (reg:CC FLAGS_REG))])]
8477 int v = exact_log2 (UINTVAL (operands[3]));
8478 operands[4] = GEN_INT (v);
8479 operands[5] = GEN_INT ((HOST_WIDE_INT_1U << v) - 1);
8481 [(set_attr "type" "multi")
8482 (set_attr "mode" "SI")])
8484 (define_insn_and_split "*divmodsi4_zext_2"
8485 [(set (match_operand:DI 1 "register_operand" "=&d")
8487 (mod:SI (match_operand:SI 2 "register_operand" "0")
8488 (match_operand:SI 3 "nonimmediate_operand" "rm"))))
8489 (set (match_operand:SI 0 "register_operand" "=a")
8490 (div:SI (match_dup 2) (match_dup 3)))
8491 (clobber (reg:CC FLAGS_REG))]
8494 "&& reload_completed"
8495 [(parallel [(set (match_dup 6)
8496 (ashiftrt:SI (match_dup 4) (match_dup 5)))
8497 (clobber (reg:CC FLAGS_REG))])
8498 (parallel [(set (match_dup 1)
8499 (zero_extend:DI (mod:SI (match_dup 2) (match_dup 3))))
8501 (div:SI (match_dup 2) (match_dup 3)))
8503 (clobber (reg:CC FLAGS_REG))])]
8505 operands[5] = GEN_INT (GET_MODE_BITSIZE (SImode)-1);
8506 operands[6] = gen_lowpart (SImode, operands[1]);
8508 if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
8509 operands[4] = operands[2];
8512 /* Avoid use of cltd in favor of a mov+shift. */
8513 emit_move_insn (operands[6], operands[2]);
8514 operands[4] = operands[6];
8517 [(set_attr "type" "multi")
8518 (set_attr "mode" "SI")])
8520 (define_insn_and_split "*udivmodsi4_zext_2"
8521 [(set (match_operand:DI 1 "register_operand" "=&d")
8523 (umod:SI (match_operand:SI 2 "register_operand" "0")
8524 (match_operand:SI 3 "nonimmediate_operand" "rm"))))
8525 (set (match_operand:SI 0 "register_operand" "=a")
8526 (udiv:SI (match_dup 2) (match_dup 3)))
8527 (clobber (reg:CC FLAGS_REG))]
8530 "&& reload_completed"
8531 [(set (match_dup 4) (const_int 0))
8532 (parallel [(set (match_dup 1)
8533 (zero_extend:DI (umod:SI (match_dup 2) (match_dup 3))))
8535 (udiv:SI (match_dup 2) (match_dup 3)))
8537 (clobber (reg:CC FLAGS_REG))])]
8538 "operands[4] = gen_lowpart (SImode, operands[1]);"
8539 [(set_attr "type" "multi")
8540 (set_attr "mode" "SI")])
8542 (define_insn_and_split "*udivmodsi4_pow2_zext_2"
8543 [(set (match_operand:DI 1 "register_operand" "=r")
8545 (umod:SI (match_operand:SI 2 "register_operand" "0")
8546 (match_operand:SI 3 "const_int_operand" "n"))))
8547 (set (match_operand:SI 0 "register_operand" "=r")
8548 (umod:SI (match_dup 2) (match_dup 3)))
8549 (clobber (reg:CC FLAGS_REG))]
8551 && exact_log2 (UINTVAL (operands[3])) > 0"
8553 "&& reload_completed"
8554 [(set (match_dup 1) (match_dup 2))
8555 (parallel [(set (match_dup 0) (lshiftrt:SI (match_dup 2) (match_dup 4)))
8556 (clobber (reg:CC FLAGS_REG))])
8557 (parallel [(set (match_dup 1)
8558 (zero_extend:DI (and:SI (match_dup 1) (match_dup 5))))
8559 (clobber (reg:CC FLAGS_REG))])]
8561 int v = exact_log2 (UINTVAL (operands[3]));
8562 operands[4] = GEN_INT (v);
8563 operands[5] = GEN_INT ((HOST_WIDE_INT_1U << v) - 1);
8565 [(set_attr "type" "multi")
8566 (set_attr "mode" "SI")])
8568 (define_insn "*<u>divmod<mode>4_noext"
8569 [(set (match_operand:SWIM248 0 "register_operand" "=a")
8571 (match_operand:SWIM248 2 "register_operand" "0")
8572 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
8573 (set (match_operand:SWIM248 1 "register_operand" "=d")
8574 (<paired_mod>:SWIM248 (match_dup 2) (match_dup 3)))
8575 (use (match_operand:SWIM248 4 "register_operand" "1"))
8576 (clobber (reg:CC FLAGS_REG))]
8578 "<sgnprefix>div{<imodesuffix>}\t%3"
8579 [(set_attr "type" "idiv")
8580 (set_attr "mode" "<MODE>")])
8582 (define_insn "*<u>divmodsi4_noext_zext_1"
8583 [(set (match_operand:DI 0 "register_operand" "=a")
8585 (any_div:SI (match_operand:SI 2 "register_operand" "0")
8586 (match_operand:SI 3 "nonimmediate_operand" "rm"))))
8587 (set (match_operand:SI 1 "register_operand" "=d")
8588 (<paired_mod>:SI (match_dup 2) (match_dup 3)))
8589 (use (match_operand:SI 4 "register_operand" "1"))
8590 (clobber (reg:CC FLAGS_REG))]
8592 "<sgnprefix>div{l}\t%3"
8593 [(set_attr "type" "idiv")
8594 (set_attr "mode" "SI")])
8596 (define_insn "*<u>divmodsi4_noext_zext_2"
8597 [(set (match_operand:DI 1 "register_operand" "=d")
8599 (<paired_mod>:SI (match_operand:SI 2 "register_operand" "0")
8600 (match_operand:SI 3 "nonimmediate_operand" "rm"))))
8601 (set (match_operand:SI 0 "register_operand" "=a")
8602 (any_div:SI (match_dup 2) (match_dup 3)))
8603 (use (match_operand:SI 4 "register_operand" "1"))
8604 (clobber (reg:CC FLAGS_REG))]
8606 "<sgnprefix>div{l}\t%3"
8607 [(set_attr "type" "idiv")
8608 (set_attr "mode" "SI")])
8610 (define_expand "divmodqi4"
8611 [(parallel [(set (match_operand:QI 0 "register_operand")
8613 (match_operand:QI 1 "register_operand")
8614 (match_operand:QI 2 "nonimmediate_operand")))
8615 (set (match_operand:QI 3 "register_operand")
8616 (mod:QI (match_dup 1) (match_dup 2)))
8617 (clobber (reg:CC FLAGS_REG))])]
8618 "TARGET_QIMODE_MATH"
8623 tmp0 = gen_reg_rtx (HImode);
8624 tmp1 = gen_reg_rtx (HImode);
8626 /* Extend operands[1] to HImode. Generate 8bit divide. Result is in AX. */
8627 emit_insn (gen_extendqihi2 (tmp1, operands[1]));
8628 emit_insn (gen_divmodhiqi3 (tmp0, tmp1, operands[2]));
8630 /* Extract remainder from AH. */
8631 tmp1 = gen_rtx_ZERO_EXTRACT (HImode, tmp0, GEN_INT (8), GEN_INT (8));
8632 tmp1 = lowpart_subreg (QImode, tmp1, HImode);
8633 rtx_insn *insn = emit_move_insn (operands[3], tmp1);
8635 mod = gen_rtx_MOD (QImode, operands[1], operands[2]);
8636 set_unique_reg_note (insn, REG_EQUAL, mod);
8638 /* Extract quotient from AL. */
8639 insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
8641 div = gen_rtx_DIV (QImode, operands[1], operands[2]);
8642 set_unique_reg_note (insn, REG_EQUAL, div);
8647 (define_expand "udivmodqi4"
8648 [(parallel [(set (match_operand:QI 0 "register_operand")
8650 (match_operand:QI 1 "register_operand")
8651 (match_operand:QI 2 "nonimmediate_operand")))
8652 (set (match_operand:QI 3 "register_operand")
8653 (umod:QI (match_dup 1) (match_dup 2)))
8654 (clobber (reg:CC FLAGS_REG))])]
8655 "TARGET_QIMODE_MATH"
8660 tmp0 = gen_reg_rtx (HImode);
8661 tmp1 = gen_reg_rtx (HImode);
8663 /* Extend operands[1] to HImode. Generate 8bit divide. Result is in AX. */
8664 emit_insn (gen_zero_extendqihi2 (tmp1, operands[1]));
8665 emit_insn (gen_udivmodhiqi3 (tmp0, tmp1, operands[2]));
8667 /* Extract remainder from AH. */
8668 tmp1 = gen_rtx_ZERO_EXTRACT (HImode, tmp0, GEN_INT (8), GEN_INT (8));
8669 tmp1 = lowpart_subreg (QImode, tmp1, HImode);
8670 rtx_insn *insn = emit_move_insn (operands[3], tmp1);
8672 mod = gen_rtx_UMOD (QImode, operands[1], operands[2]);
8673 set_unique_reg_note (insn, REG_EQUAL, mod);
8675 /* Extract quotient from AL. */
8676 insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
8678 div = gen_rtx_UDIV (QImode, operands[1], operands[2]);
8679 set_unique_reg_note (insn, REG_EQUAL, div);
8684 ;; Divide AX by r/m8, with result stored in
8687 ;; Change div/mod to HImode and extend the second argument to HImode
8688 ;; so that mode of div/mod matches with mode of arguments. Otherwise
8689 ;; combine may fail.
8690 (define_insn "<u>divmodhiqi3"
8691 [(set (match_operand:HI 0 "register_operand" "=a")
8696 (mod:HI (match_operand:HI 1 "register_operand" "0")
8698 (match_operand:QI 2 "nonimmediate_operand" "qm")))))
8702 (div:HI (match_dup 1) (any_extend:HI (match_dup 2)))))))
8703 (clobber (reg:CC FLAGS_REG))]
8704 "TARGET_QIMODE_MATH"
8705 "<sgnprefix>div{b}\t%2"
8706 [(set_attr "type" "idiv")
8707 (set_attr "mode" "QI")])
8709 ;; We cannot use div/idiv for double division, because it causes
8710 ;; "division by zero" on the overflow and that's not what we expect
8711 ;; from truncate. Because true (non truncating) double division is
8712 ;; never generated, we can't create this insn anyway.
8715 ; [(set (match_operand:SI 0 "register_operand" "=a")
8717 ; (udiv:DI (match_operand:DI 1 "register_operand" "A")
8719 ; (match_operand:SI 2 "nonimmediate_operand" "rm")))))
8720 ; (set (match_operand:SI 3 "register_operand" "=d")
8722 ; (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
8723 ; (clobber (reg:CC FLAGS_REG))]
8725 ; "div{l}\t{%2, %0|%0, %2}"
8726 ; [(set_attr "type" "idiv")])
8728 ;;- Logical AND instructions
8730 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
8731 ;; Note that this excludes ah.
8733 (define_expand "@test<mode>_ccno_1"
8734 [(set (reg:CCNO FLAGS_REG)
8737 (match_operand:SWI48 0 "nonimmediate_operand")
8738 (match_operand:SWI48 1 "<nonmemory_szext_operand>"))
8741 (define_expand "testqi_ccz_1"
8742 [(set (reg:CCZ FLAGS_REG)
8745 (match_operand:QI 0 "nonimmediate_operand")
8746 (match_operand:QI 1 "nonmemory_operand"))
8749 (define_insn "*testdi_1"
8750 [(set (reg FLAGS_REG)
8753 (match_operand:DI 0 "nonimmediate_operand" "%r,rm")
8754 (match_operand:DI 1 "x86_64_szext_nonmemory_operand" "Z,re"))
8757 && ix86_match_ccmode
8759 /* If we are going to emit testl instead of testq, and the operands[1]
8760 constant might have the SImode sign bit set, make sure the sign
8761 flag isn't tested, because the instruction will set the sign flag
8762 based on bit 31 rather than bit 63. If it isn't CONST_INT,
8763 conservatively assume it might have bit 31 set. */
8764 (satisfies_constraint_Z (operands[1])
8765 && (!CONST_INT_P (operands[1])
8766 || val_signbit_known_set_p (SImode, INTVAL (operands[1]))))
8767 ? CCZmode : CCNOmode)"
8769 test{l}\t{%k1, %k0|%k0, %k1}
8770 test{q}\t{%1, %0|%0, %1}"
8771 [(set_attr "type" "test")
8772 (set_attr "mode" "SI,DI")])
8774 (define_insn "*testqi_1_maybe_si"
8775 [(set (reg FLAGS_REG)
8778 (match_operand:QI 0 "nonimmediate_operand" "%qm,*a,qm,r")
8779 (match_operand:QI 1 "nonmemory_operand" "q,n,n,n"))
8781 "ix86_match_ccmode (insn,
8782 CONST_INT_P (operands[1])
8783 && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
8785 if (which_alternative == 3)
8787 if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
8788 operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
8789 return "test{l}\t{%1, %k0|%k0, %1}";
8791 return "test{b}\t{%1, %0|%0, %1}";
8793 [(set_attr "type" "test")
8794 (set_attr "mode" "QI,QI,QI,SI")
8795 (set_attr "pent_pair" "uv,uv,np,np")])
8797 (define_insn "*test<mode>_1"
8798 [(set (reg FLAGS_REG)
8801 (match_operand:SWI124 0 "nonimmediate_operand" "%<r>m,*a,<r>m")
8802 (match_operand:SWI124 1 "<nonmemory_szext_operand>" "<r>,<i>,<i>"))
8804 "ix86_match_ccmode (insn, CCNOmode)"
8805 "test{<imodesuffix>}\t{%1, %0|%0, %1}"
8806 [(set_attr "type" "test")
8807 (set_attr "mode" "<MODE>")
8808 (set_attr "pent_pair" "uv,uv,np")])
8810 (define_expand "testqi_ext_1_ccno"
8811 [(set (reg:CCNO FLAGS_REG)
8816 (match_operand:HI 0 "register_operand")
8819 (match_operand:QI 1 "const_int_operand"))
8822 (define_insn "*testqi_ext<mode>_1"
8823 [(set (reg FLAGS_REG)
8827 (zero_extract:SWI248
8828 (match_operand:SWI248 0 "register_operand" "Q,Q")
8831 (match_operand:QI 1 "general_operand" "QnBc,m"))
8833 "ix86_match_ccmode (insn, CCNOmode)"
8834 "test{b}\t{%1, %h0|%h0, %1}"
8835 [(set_attr "isa" "*,nox64")
8836 (set_attr "type" "test")
8837 (set_attr "mode" "QI")])
8839 (define_insn "*testqi_ext<mode>_2"
8840 [(set (reg FLAGS_REG)
8844 (zero_extract:SWI248
8845 (match_operand:SWI248 0 "register_operand" "Q")
8849 (zero_extract:SWI248
8850 (match_operand:SWI248 1 "register_operand" "Q")
8854 "ix86_match_ccmode (insn, CCNOmode)"
8855 "test{b}\t{%h1, %h0|%h0, %h1}"
8856 [(set_attr "type" "test")
8857 (set_attr "mode" "QI")])
8859 ;; Combine likes to form bit extractions for some tests. Humor it.
8860 (define_insn_and_split "*testqi_ext_3"
8861 [(set (match_operand 0 "flags_reg_operand")
8862 (match_operator 1 "compare_operator"
8863 [(zero_extract:SWI248
8864 (match_operand 2 "int_nonimmediate_operand" "rm")
8865 (match_operand 3 "const_int_operand" "n")
8866 (match_operand 4 "const_int_operand" "n"))
8868 "/* Ensure that resulting mask is zero or sign extended operand. */
8869 INTVAL (operands[4]) >= 0
8870 && ((INTVAL (operands[3]) > 0
8871 && INTVAL (operands[3]) + INTVAL (operands[4]) <= 32)
8872 || (<MODE>mode == DImode
8873 && INTVAL (operands[3]) > 32
8874 && INTVAL (operands[3]) + INTVAL (operands[4]) == 64))
8875 && ix86_match_ccmode (insn,
8876 /* If zero_extract mode precision is the same
8877 as len, the SF of the zero_extract
8878 comparison will be the most significant
8879 extracted bit, but this could be matched
8880 after splitting only for pos 0 len all bits
8881 trivial extractions. Require CCZmode. */
8882 (GET_MODE_PRECISION (<MODE>mode)
8883 == INTVAL (operands[3]))
8884 /* Otherwise, require CCZmode if we'd use a mask
8885 with the most significant bit set and can't
8886 widen it to wider mode. *testdi_1 also
8887 requires CCZmode if the mask has bit
8888 31 set and all bits above it clear. */
8889 || (INTVAL (operands[3]) + INTVAL (operands[4])
8891 /* We can't widen also if val is not a REG. */
8892 || (INTVAL (operands[3]) + INTVAL (operands[4])
8893 == GET_MODE_PRECISION (GET_MODE (operands[2]))
8894 && !register_operand (operands[2],
8895 GET_MODE (operands[2])))
8896 /* And we shouldn't widen if
8897 TARGET_PARTIAL_REG_STALL. */
8898 || (TARGET_PARTIAL_REG_STALL
8899 && (INTVAL (operands[3]) + INTVAL (operands[4])
8900 >= (paradoxical_subreg_p (operands[2])
8902 (GET_MODE (SUBREG_REG (operands[2])))
8904 ? GET_MODE_PRECISION
8905 (GET_MODE (SUBREG_REG (operands[2])))
8906 : GET_MODE_PRECISION
8907 (GET_MODE (operands[2])))))
8908 ? CCZmode : CCNOmode)"
8911 [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
8913 rtx val = operands[2];
8914 HOST_WIDE_INT len = INTVAL (operands[3]);
8915 HOST_WIDE_INT pos = INTVAL (operands[4]);
8916 machine_mode mode = GET_MODE (val);
8920 machine_mode submode = GET_MODE (SUBREG_REG (val));
8922 /* Narrow paradoxical subregs to prevent partial register stalls. */
8923 if (GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode)
8924 && GET_MODE_CLASS (submode) == MODE_INT
8925 && (GET_MODE (operands[0]) == CCZmode
8926 || pos + len < GET_MODE_PRECISION (submode)
8927 || REG_P (SUBREG_REG (val))))
8929 val = SUBREG_REG (val);
8934 /* Small HImode tests can be converted to QImode. */
8936 && register_operand (val, HImode))
8938 rtx nval = gen_lowpart (QImode, val);
8940 || GET_MODE (operands[0]) == CCZmode
8948 gcc_assert (pos + len <= GET_MODE_PRECISION (mode));
8950 /* If the mask is going to have the sign bit set in the mode
8951 we want to do the comparison in and user isn't interested just
8952 in the zero flag, then we must widen the target mode. */
8953 if (pos + len == GET_MODE_PRECISION (mode)
8954 && GET_MODE (operands[0]) != CCZmode)
8956 gcc_assert (pos + len < 32 && !MEM_P (val));
8958 val = gen_lowpart (mode, val);
8962 = wi::shifted_mask (pos, len, false, GET_MODE_PRECISION (mode));
8964 operands[2] = gen_rtx_AND (mode, val, immed_wide_int_const (mask, mode));
8967 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
8968 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
8969 ;; this is relatively important trick.
8970 ;; Do the conversion only post-reload to avoid limiting of the register class
8973 [(set (match_operand 0 "flags_reg_operand")
8974 (match_operator 1 "compare_operator"
8975 [(and (match_operand 2 "QIreg_operand")
8976 (match_operand 3 "const_int_operand"))
8979 && GET_MODE (operands[2]) != QImode
8980 && ((ix86_match_ccmode (insn, CCZmode)
8981 && !(INTVAL (operands[3]) & ~(255 << 8)))
8982 || (ix86_match_ccmode (insn, CCNOmode)
8983 && !(INTVAL (operands[3]) & ~(127 << 8))))"
8988 (zero_extract:SI (match_dup 2)
8994 operands[2] = gen_lowpart (SImode, operands[2]);
8995 operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, QImode);
8999 [(set (match_operand 0 "flags_reg_operand")
9000 (match_operator 1 "compare_operator"
9001 [(and (match_operand 2 "nonimmediate_operand")
9002 (match_operand 3 "const_int_operand"))
9005 && GET_MODE (operands[2]) != QImode
9006 && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
9007 && ((ix86_match_ccmode (insn, CCZmode)
9008 && !(INTVAL (operands[3]) & ~255))
9009 || (ix86_match_ccmode (insn, CCNOmode)
9010 && !(INTVAL (operands[3]) & ~127)))"
9012 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
9015 operands[2] = gen_lowpart (QImode, operands[2]);
9016 operands[3] = gen_int_mode (INTVAL (operands[3]), QImode);
9019 ;; %%% This used to optimize known byte-wide and operations to memory,
9020 ;; and sometimes to QImode registers. If this is considered useful,
9021 ;; it should be done with splitters.
9023 (define_expand "and<mode>3"
9024 [(set (match_operand:SWIM1248s 0 "nonimmediate_operand")
9025 (and:SWIM1248s (match_operand:SWIM1248s 1 "nonimmediate_operand")
9026 (match_operand:SWIM1248s 2 "<general_szext_operand>")))]
9029 machine_mode mode = <MODE>mode;
9031 if (<MODE>mode == DImode && !TARGET_64BIT)
9033 else if (const_int_operand (operands[2], <MODE>mode)
9034 && register_operand (operands[0], <MODE>mode)
9035 && !(TARGET_ZERO_EXTEND_WITH_AND
9036 && optimize_function_for_speed_p (cfun)))
9038 unsigned HOST_WIDE_INT ival = UINTVAL (operands[2]);
9040 if (ival == GET_MODE_MASK (SImode))
9042 else if (ival == GET_MODE_MASK (HImode))
9044 else if (ival == GET_MODE_MASK (QImode))
9048 if (mode != <MODE>mode)
9049 emit_insn (gen_extend_insn
9050 (operands[0], gen_lowpart (mode, operands[1]),
9051 <MODE>mode, mode, 1));
9053 ix86_expand_binary_operator (AND, <MODE>mode, operands);
9058 (define_insn_and_split "*anddi3_doubleword"
9059 [(set (match_operand:DI 0 "nonimmediate_operand")
9061 (match_operand:DI 1 "nonimmediate_operand")
9062 (match_operand:DI 2 "x86_64_szext_general_operand")))
9063 (clobber (reg:CC FLAGS_REG))]
9064 "!TARGET_64BIT && TARGET_STV && TARGET_SSE2
9065 && ix86_binary_operator_ok (AND, DImode, operands)
9066 && ix86_pre_reload_split ()"
9071 split_double_mode (DImode, &operands[0], 3, &operands[0], &operands[3]);
9073 if (operands[2] == const0_rtx)
9074 emit_move_insn (operands[0], const0_rtx);
9075 else if (operands[2] == constm1_rtx)
9076 emit_move_insn (operands[0], operands[1]);
9078 emit_insn (gen_andsi3 (operands[0], operands[1], operands[2]));
9080 if (operands[5] == const0_rtx)
9081 emit_move_insn (operands[3], const0_rtx);
9082 else if (operands[5] == constm1_rtx)
9083 emit_move_insn (operands[3], operands[4]);
9085 emit_insn (gen_andsi3 (operands[3], operands[4], operands[5]));
9090 (define_insn "*anddi_1"
9091 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r,k")
9093 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm,k")
9094 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,m,L,k")))
9095 (clobber (reg:CC FLAGS_REG))]
9096 "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
9098 and{l}\t{%k2, %k0|%k0, %k2}
9099 and{q}\t{%2, %0|%0, %2}
9100 and{q}\t{%2, %0|%0, %2}
9103 [(set_attr "isa" "x64,x64,x64,x64,avx512bw")
9104 (set_attr "type" "alu,alu,alu,imovx,msklog")
9105 (set_attr "length_immediate" "*,*,*,0,*")
9106 (set (attr "prefix_rex")
9108 (and (eq_attr "type" "imovx")
9109 (and (match_test "INTVAL (operands[2]) == 0xff")
9110 (match_operand 1 "ext_QIreg_operand")))
9112 (const_string "*")))
9113 (set_attr "mode" "SI,DI,DI,SI,DI")])
9115 (define_insn_and_split "*anddi_1_btr"
9116 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9118 (match_operand:DI 1 "nonimmediate_operand" "%0")
9119 (match_operand:DI 2 "const_int_operand" "n")))
9120 (clobber (reg:CC FLAGS_REG))]
9121 "TARGET_64BIT && TARGET_USE_BT
9122 && ix86_binary_operator_ok (AND, DImode, operands)
9123 && IN_RANGE (exact_log2 (~INTVAL (operands[2])), 31, 63)"
9125 "&& reload_completed"
9126 [(parallel [(set (zero_extract:DI (match_dup 0)
9130 (clobber (reg:CC FLAGS_REG))])]
9131 "operands[3] = GEN_INT (exact_log2 (~INTVAL (operands[2])));"
9132 [(set_attr "type" "alu1")
9133 (set_attr "prefix_0f" "1")
9134 (set_attr "znver1_decode" "double")
9135 (set_attr "mode" "DI")])
9137 ;; Turn *anddi_1 into *andsi_1_zext if possible.
9139 [(set (match_operand:DI 0 "register_operand")
9140 (and:DI (subreg:DI (match_operand:SI 1 "register_operand") 0)
9141 (match_operand:DI 2 "x86_64_zext_immediate_operand")))
9142 (clobber (reg:CC FLAGS_REG))]
9144 [(parallel [(set (match_dup 0)
9145 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))
9146 (clobber (reg:CC FLAGS_REG))])]
9148 if (GET_CODE (operands[2]) == SYMBOL_REF
9149 || GET_CODE (operands[2]) == LABEL_REF)
9151 operands[2] = shallow_copy_rtx (operands[2]);
9152 PUT_MODE (operands[2], SImode);
9154 else if (GET_CODE (operands[2]) == CONST)
9156 /* (const:DI (plus:DI (symbol_ref:DI ("...")) (const_int N))) */
9157 operands[2] = copy_rtx (operands[2]);
9158 PUT_MODE (operands[2], SImode);
9159 PUT_MODE (XEXP (operands[2], 0), SImode);
9160 PUT_MODE (XEXP (XEXP (operands[2], 0), 0), SImode);
9163 operands[2] = gen_lowpart (SImode, operands[2]);
9166 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9167 (define_insn "*andsi_1_zext"
9168 [(set (match_operand:DI 0 "register_operand" "=r")
9170 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9171 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
9172 (clobber (reg:CC FLAGS_REG))]
9173 "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
9174 "and{l}\t{%2, %k0|%k0, %2}"
9175 [(set_attr "type" "alu")
9176 (set_attr "mode" "SI")])
9178 (define_insn "*and<mode>_1"
9179 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=rm,r,Ya,k")
9180 (and:SWI24 (match_operand:SWI24 1 "nonimmediate_operand" "%0,0,qm,k")
9181 (match_operand:SWI24 2 "<general_operand>" "r<i>,m,L,k")))
9182 (clobber (reg:CC FLAGS_REG))]
9183 "ix86_binary_operator_ok (AND, <MODE>mode, operands)"
9185 and{<imodesuffix>}\t{%2, %0|%0, %2}
9186 and{<imodesuffix>}\t{%2, %0|%0, %2}
9190 (cond [(eq_attr "alternative" "3")
9191 (if_then_else (eq_attr "mode" "SI")
9192 (const_string "avx512bw")
9193 (const_string "avx512f"))
9195 (const_string "*")))
9196 (set_attr "type" "alu,alu,imovx,msklog")
9197 (set_attr "length_immediate" "*,*,0,*")
9198 (set (attr "prefix_rex")
9200 (and (eq_attr "type" "imovx")
9201 (and (match_test "INTVAL (operands[2]) == 0xff")
9202 (match_operand 1 "ext_QIreg_operand")))
9204 (const_string "*")))
9205 (set_attr "mode" "<MODE>,<MODE>,SI,<MODE>")])
9207 (define_insn "*andqi_1"
9208 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,k")
9209 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,k")
9210 (match_operand:QI 2 "general_operand" "qn,m,rn,k")))
9211 (clobber (reg:CC FLAGS_REG))]
9212 "ix86_binary_operator_ok (AND, QImode, operands)"
9214 and{b}\t{%2, %0|%0, %2}
9215 and{b}\t{%2, %0|%0, %2}
9216 and{l}\t{%k2, %k0|%k0, %k2}
9218 [(set_attr "type" "alu,alu,alu,msklog")
9220 (cond [(eq_attr "alternative" "2")
9222 (and (eq_attr "alternative" "3")
9223 (match_test "!TARGET_AVX512DQ"))
9226 (const_string "QI")))
9227 ;; Potential partial reg stall on alternative 2.
9228 (set (attr "preferred_for_speed")
9229 (cond [(eq_attr "alternative" "2")
9230 (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
9231 (symbol_ref "true")))])
9233 (define_insn "*and<mode>_1_slp"
9234 [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>"))
9235 (and:SWI12 (match_operand:SWI12 1 "nonimmediate_operand" "%0")
9236 (match_operand:SWI12 2 "general_operand" "<r>mn")))
9237 (clobber (reg:CC FLAGS_REG))]
9238 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9239 /* FIXME: without this LRA can't reload this pattern, see PR82524. */
9240 && (rtx_equal_p (operands[0], operands[1])
9241 || rtx_equal_p (operands[0], operands[2]))"
9242 "and{<imodesuffix>}\t{%2, %0|%0, %2}"
9243 [(set_attr "type" "alu")
9244 (set_attr "mode" "<MODE>")])
9247 [(set (match_operand:SWI248 0 "register_operand")
9248 (and:SWI248 (match_operand:SWI248 1 "nonimmediate_operand")
9249 (match_operand:SWI248 2 "const_int_operand")))
9250 (clobber (reg:CC FLAGS_REG))]
9252 && (!REG_P (operands[1])
9253 || REGNO (operands[0]) != REGNO (operands[1]))"
9256 unsigned HOST_WIDE_INT ival = UINTVAL (operands[2]);
9259 if (ival == GET_MODE_MASK (SImode))
9261 else if (ival == GET_MODE_MASK (HImode))
9263 else if (ival == GET_MODE_MASK (QImode))
9268 /* Zero extend to SImode to avoid partial register stalls. */
9269 if (<MODE_SIZE> < GET_MODE_SIZE (SImode))
9270 operands[0] = gen_lowpart (SImode, operands[0]);
9272 emit_insn (gen_extend_insn
9273 (operands[0], gen_lowpart (mode, operands[1]),
9274 GET_MODE (operands[0]), mode, 1));
9279 [(set (match_operand:SWI48 0 "register_operand")
9280 (and:SWI48 (match_dup 0)
9281 (const_int -65536)))
9282 (clobber (reg:CC FLAGS_REG))]
9283 "(TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)
9284 || optimize_function_for_size_p (cfun)"
9285 [(set (strict_low_part (match_dup 1)) (const_int 0))]
9286 "operands[1] = gen_lowpart (HImode, operands[0]);")
9289 [(set (match_operand:SWI248 0 "any_QIreg_operand")
9290 (and:SWI248 (match_dup 0)
9292 (clobber (reg:CC FLAGS_REG))]
9293 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9294 && reload_completed"
9295 [(set (strict_low_part (match_dup 1)) (const_int 0))]
9296 "operands[1] = gen_lowpart (QImode, operands[0]);")
9299 [(set (match_operand:SWI248 0 "QIreg_operand")
9300 (and:SWI248 (match_dup 0)
9301 (const_int -65281)))
9302 (clobber (reg:CC FLAGS_REG))]
9303 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9304 && reload_completed"
9306 [(set (zero_extract:SI (match_dup 0)
9312 (zero_extract:SI (match_dup 0)
9316 (zero_extract:SI (match_dup 0)
9318 (const_int 8)) 0)) 0))
9319 (clobber (reg:CC FLAGS_REG))])]
9320 "operands[0] = gen_lowpart (SImode, operands[0]);")
9322 (define_insn "*anddi_2"
9323 [(set (reg FLAGS_REG)
9326 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
9327 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,m"))
9329 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r")
9330 (and:DI (match_dup 1) (match_dup 2)))]
9332 && ix86_match_ccmode
9334 /* If we are going to emit andl instead of andq, and the operands[2]
9335 constant might have the SImode sign bit set, make sure the sign
9336 flag isn't tested, because the instruction will set the sign flag
9337 based on bit 31 rather than bit 63. If it isn't CONST_INT,
9338 conservatively assume it might have bit 31 set. */
9339 (satisfies_constraint_Z (operands[2])
9340 && (!CONST_INT_P (operands[2])
9341 || val_signbit_known_set_p (SImode, INTVAL (operands[2]))))
9342 ? CCZmode : CCNOmode)
9343 && ix86_binary_operator_ok (AND, DImode, operands)"
9345 and{l}\t{%k2, %k0|%k0, %k2}
9346 and{q}\t{%2, %0|%0, %2}
9347 and{q}\t{%2, %0|%0, %2}"
9348 [(set_attr "type" "alu")
9349 (set_attr "mode" "SI,DI,DI")])
9351 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9352 (define_insn "*andsi_2_zext"
9353 [(set (reg FLAGS_REG)
9355 (match_operand:SI 1 "nonimmediate_operand" "%0")
9356 (match_operand:SI 2 "x86_64_general_operand" "rme"))
9358 (set (match_operand:DI 0 "register_operand" "=r")
9359 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
9360 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9361 && ix86_binary_operator_ok (AND, SImode, operands)"
9362 "and{l}\t{%2, %k0|%k0, %2}"
9363 [(set_attr "type" "alu")
9364 (set_attr "mode" "SI")])
9366 (define_insn "*andqi_2_maybe_si"
9367 [(set (reg FLAGS_REG)
9369 (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9370 (match_operand:QI 2 "general_operand" "qn,m,n"))
9372 (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
9373 (and:QI (match_dup 1) (match_dup 2)))]
9374 "ix86_binary_operator_ok (AND, QImode, operands)
9375 && ix86_match_ccmode (insn,
9376 CONST_INT_P (operands[2])
9377 && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
9379 if (which_alternative == 2)
9381 if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
9382 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
9383 return "and{l}\t{%2, %k0|%k0, %2}";
9385 return "and{b}\t{%2, %0|%0, %2}";
9387 [(set_attr "type" "alu")
9388 (set_attr "mode" "QI,QI,SI")
9389 ;; Potential partial reg stall on alternative 2.
9390 (set (attr "preferred_for_speed")
9391 (cond [(eq_attr "alternative" "2")
9392 (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
9393 (symbol_ref "true")))])
9395 (define_insn "*and<mode>_2"
9396 [(set (reg FLAGS_REG)
9397 (compare (and:SWI124
9398 (match_operand:SWI124 1 "nonimmediate_operand" "%0,0")
9399 (match_operand:SWI124 2 "<general_operand>" "<r><i>,m"))
9401 (set (match_operand:SWI124 0 "nonimmediate_operand" "=<r>m,<r>")
9402 (and:SWI124 (match_dup 1) (match_dup 2)))]
9403 "ix86_match_ccmode (insn, CCNOmode)
9404 && ix86_binary_operator_ok (AND, <MODE>mode, operands)"
9405 "and{<imodesuffix>}\t{%2, %0|%0, %2}"
9406 [(set_attr "type" "alu")
9407 (set_attr "mode" "<MODE>")])
9409 (define_expand "andqi_ext_1"
9411 [(set (zero_extract:HI (match_operand:HI 0 "register_operand")
9417 (zero_extract:HI (match_operand:HI 1 "register_operand")
9420 (match_operand:QI 2 "const_int_operand")) 0))
9421 (clobber (reg:CC FLAGS_REG))])])
9423 (define_insn "*andqi_ext<mode>_1"
9424 [(set (zero_extract:SWI248
9425 (match_operand:SWI248 0 "register_operand" "+Q,Q")
9431 (zero_extract:SWI248
9432 (match_operand:SWI248 1 "register_operand" "0,0")
9435 (match_operand:QI 2 "general_operand" "QnBc,m")) 0))
9436 (clobber (reg:CC FLAGS_REG))]
9437 "/* FIXME: without this LRA can't reload this pattern, see PR82524. */
9438 rtx_equal_p (operands[0], operands[1])"
9439 "and{b}\t{%2, %h0|%h0, %2}"
9440 [(set_attr "isa" "*,nox64")
9441 (set_attr "type" "alu")
9442 (set_attr "mode" "QI")])
9444 ;; Generated by peephole translating test to and. This shows up
9445 ;; often in fp comparisons.
9446 (define_insn "*andqi_ext<mode>_1_cc"
9447 [(set (reg FLAGS_REG)
9451 (zero_extract:SWI248
9452 (match_operand:SWI248 1 "register_operand" "0,0")
9455 (match_operand:QI 2 "general_operand" "QnBc,m"))
9457 (set (zero_extract:SWI248
9458 (match_operand:SWI248 0 "register_operand" "+Q,Q")
9464 (zero_extract:SWI248
9469 "ix86_match_ccmode (insn, CCNOmode)
9470 /* FIXME: without this LRA can't reload this pattern, see PR82524. */
9471 && rtx_equal_p (operands[0], operands[1])"
9472 "and{b}\t{%2, %h0|%h0, %2}"
9473 [(set_attr "isa" "*,nox64")
9474 (set_attr "type" "alu")
9475 (set_attr "mode" "QI")])
9477 (define_insn "*andqi_ext<mode>_2"
9478 [(set (zero_extract:SWI248
9479 (match_operand:SWI248 0 "register_operand" "+Q")
9485 (zero_extract:SWI248
9486 (match_operand:SWI248 1 "register_operand" "%0")
9490 (zero_extract:SWI248
9491 (match_operand:SWI248 2 "register_operand" "Q")
9493 (const_int 8)) 0)) 0))
9494 (clobber (reg:CC FLAGS_REG))]
9495 "/* FIXME: without this LRA can't reload this pattern, see PR82524. */
9496 rtx_equal_p (operands[0], operands[1])
9497 || rtx_equal_p (operands[0], operands[2])"
9498 "and{b}\t{%h2, %h0|%h0, %h2}"
9499 [(set_attr "type" "alu")
9500 (set_attr "mode" "QI")])
9502 ;; Convert wide AND instructions with immediate operand to shorter QImode
9503 ;; equivalents when possible.
9504 ;; Don't do the splitting with memory operands, since it introduces risk
9505 ;; of memory mismatch stalls. We may want to do the splitting for optimizing
9506 ;; for size, but that can (should?) be handled by generic code instead.
9508 [(set (match_operand:SWI248 0 "QIreg_operand")
9509 (and:SWI248 (match_operand:SWI248 1 "register_operand")
9510 (match_operand:SWI248 2 "const_int_operand")))
9511 (clobber (reg:CC FLAGS_REG))]
9513 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9514 && !(~INTVAL (operands[2]) & ~(255 << 8))"
9516 [(set (zero_extract:SI (match_dup 0)
9522 (zero_extract:SI (match_dup 1)
9526 (clobber (reg:CC FLAGS_REG))])]
9528 operands[0] = gen_lowpart (SImode, operands[0]);
9529 operands[1] = gen_lowpart (SImode, operands[1]);
9530 operands[2] = gen_int_mode (INTVAL (operands[2]) >> 8, QImode);
9533 ;; Since AND can be encoded with sign extended immediate, this is only
9534 ;; profitable when 7th bit is not set.
9536 [(set (match_operand:SWI248 0 "any_QIreg_operand")
9537 (and:SWI248 (match_operand:SWI248 1 "general_operand")
9538 (match_operand:SWI248 2 "const_int_operand")))
9539 (clobber (reg:CC FLAGS_REG))]
9541 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9542 && !(~INTVAL (operands[2]) & ~255)
9543 && !(INTVAL (operands[2]) & 128)"
9544 [(parallel [(set (strict_low_part (match_dup 0))
9545 (and:QI (match_dup 1)
9547 (clobber (reg:CC FLAGS_REG))])]
9549 operands[0] = gen_lowpart (QImode, operands[0]);
9550 operands[1] = gen_lowpart (QImode, operands[1]);
9551 operands[2] = gen_int_mode (INTVAL (operands[2]), QImode);
9554 (define_insn "*andndi3_doubleword"
9555 [(set (match_operand:DI 0 "register_operand")
9557 (not:DI (match_operand:DI 1 "register_operand"))
9558 (match_operand:DI 2 "nonimmediate_operand")))
9559 (clobber (reg:CC FLAGS_REG))]
9560 "!TARGET_64BIT && TARGET_STV && TARGET_SSE2
9561 && ix86_pre_reload_split ()"
9565 [(set (match_operand:DI 0 "register_operand")
9567 (not:DI (match_operand:DI 1 "register_operand"))
9568 (match_operand:DI 2 "nonimmediate_operand")))
9569 (clobber (reg:CC FLAGS_REG))]
9570 "!TARGET_64BIT && TARGET_BMI && TARGET_STV && TARGET_SSE2
9571 && can_create_pseudo_p ()"
9572 [(parallel [(set (match_dup 0)
9573 (and:SI (not:SI (match_dup 1)) (match_dup 2)))
9574 (clobber (reg:CC FLAGS_REG))])
9575 (parallel [(set (match_dup 3)
9576 (and:SI (not:SI (match_dup 4)) (match_dup 5)))
9577 (clobber (reg:CC FLAGS_REG))])]
9578 "split_double_mode (DImode, &operands[0], 3, &operands[0], &operands[3]);")
9581 [(set (match_operand:DI 0 "register_operand")
9583 (not:DI (match_operand:DI 1 "register_operand"))
9584 (match_operand:DI 2 "nonimmediate_operand")))
9585 (clobber (reg:CC FLAGS_REG))]
9586 "!TARGET_64BIT && !TARGET_BMI && TARGET_STV && TARGET_SSE2
9587 && can_create_pseudo_p ()"
9588 [(set (match_dup 6) (not:SI (match_dup 1)))
9589 (parallel [(set (match_dup 0)
9590 (and:SI (match_dup 6) (match_dup 2)))
9591 (clobber (reg:CC FLAGS_REG))])
9592 (set (match_dup 7) (not:SI (match_dup 4)))
9593 (parallel [(set (match_dup 3)
9594 (and:SI (match_dup 7) (match_dup 5)))
9595 (clobber (reg:CC FLAGS_REG))])]
9597 operands[6] = gen_reg_rtx (SImode);
9598 operands[7] = gen_reg_rtx (SImode);
9600 split_double_mode (DImode, &operands[0], 3, &operands[0], &operands[3]);
9603 (define_insn "*andn<mode>_1"
9604 [(set (match_operand:SWI48 0 "register_operand" "=r,r,k")
9606 (not:SWI48 (match_operand:SWI48 1 "register_operand" "r,r,k"))
9607 (match_operand:SWI48 2 "nonimmediate_operand" "r,m,k")))
9608 (clobber (reg:CC FLAGS_REG))]
9609 "TARGET_BMI || TARGET_AVX512BW"
9611 andn\t{%2, %1, %0|%0, %1, %2}
9612 andn\t{%2, %1, %0|%0, %1, %2}
9614 [(set_attr "isa" "bmi,bmi,avx512bw")
9615 (set_attr "type" "bitmanip,bitmanip,msklog")
9616 (set_attr "btver2_decode" "direct, double,*")
9617 (set_attr "mode" "<MODE>")])
9619 (define_insn "*andn<mode>_1"
9620 [(set (match_operand:SWI12 0 "register_operand" "=r,k")
9622 (not:SWI12 (match_operand:SWI12 1 "register_operand" "r,k"))
9623 (match_operand:SWI12 2 "register_operand" "r,k")))
9624 (clobber (reg:CC FLAGS_REG))]
9625 "TARGET_BMI || TARGET_AVX512BW"
9627 andn\t{%k2, %k1, %k0|%k0, %k1, %k2}
9629 [(set_attr "isa" "bmi,avx512f")
9630 (set_attr "type" "bitmanip,msklog")
9631 (set_attr "btver2_decode" "direct,*")
9633 (cond [(eq_attr "alternative" "0")
9635 (and (eq_attr "alternative" "1")
9636 (match_test "!TARGET_AVX512DQ"))
9639 (const_string "<MODE>")))])
9641 (define_insn "*andn_<mode>_ccno"
9642 [(set (reg FLAGS_REG)
9645 (not:SWI48 (match_operand:SWI48 1 "register_operand" "r,r"))
9646 (match_operand:SWI48 2 "nonimmediate_operand" "r,m"))
9648 (clobber (match_scratch:SWI48 0 "=r,r"))]
9649 "TARGET_BMI && ix86_match_ccmode (insn, CCNOmode)"
9650 "andn\t{%2, %1, %0|%0, %1, %2}"
9651 [(set_attr "type" "bitmanip")
9652 (set_attr "btver2_decode" "direct, double")
9653 (set_attr "mode" "<MODE>")])
9655 ;; Logical inclusive and exclusive OR instructions
9657 ;; %%% This used to optimize known byte-wide and operations to memory.
9658 ;; If this is considered useful, it should be done with splitters.
9660 (define_expand "<code><mode>3"
9661 [(set (match_operand:SWIM1248s 0 "nonimmediate_operand")
9662 (any_or:SWIM1248s (match_operand:SWIM1248s 1 "nonimmediate_operand")
9663 (match_operand:SWIM1248s 2 "<general_operand>")))]
9665 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
9667 (define_insn_and_split "*<code>di3_doubleword"
9668 [(set (match_operand:DI 0 "nonimmediate_operand")
9670 (match_operand:DI 1 "nonimmediate_operand")
9671 (match_operand:DI 2 "x86_64_szext_general_operand")))
9672 (clobber (reg:CC FLAGS_REG))]
9673 "!TARGET_64BIT && TARGET_STV && TARGET_SSE2
9674 && ix86_binary_operator_ok (<CODE>, DImode, operands)
9675 && ix86_pre_reload_split ()"
9680 split_double_mode (DImode, &operands[0], 3, &operands[0], &operands[3]);
9682 if (operands[2] == const0_rtx)
9683 emit_move_insn (operands[0], operands[1]);
9684 else if (operands[2] == constm1_rtx)
9687 emit_move_insn (operands[0], constm1_rtx);
9689 ix86_expand_unary_operator (NOT, SImode, &operands[0]);
9692 ix86_expand_binary_operator (<CODE>, SImode, &operands[0]);
9694 if (operands[5] == const0_rtx)
9695 emit_move_insn (operands[3], operands[4]);
9696 else if (operands[5] == constm1_rtx)
9699 emit_move_insn (operands[3], constm1_rtx);
9701 ix86_expand_unary_operator (NOT, SImode, &operands[3]);
9704 ix86_expand_binary_operator (<CODE>, SImode, &operands[3]);
9709 (define_insn "*<code><mode>_1"
9710 [(set (match_operand:SWI248 0 "nonimmediate_operand" "=rm,r,k")
9712 (match_operand:SWI248 1 "nonimmediate_operand" "%0,0,k")
9713 (match_operand:SWI248 2 "<general_operand>" "r<i>,m,k")))
9714 (clobber (reg:CC FLAGS_REG))]
9715 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9717 <logic>{<imodesuffix>}\t{%2, %0|%0, %2}
9718 <logic>{<imodesuffix>}\t{%2, %0|%0, %2}
9721 (cond [(eq_attr "alternative" "2")
9722 (if_then_else (eq_attr "mode" "SI,DI")
9723 (const_string "avx512bw")
9724 (const_string "avx512f"))
9726 (const_string "*")))
9727 (set_attr "type" "alu, alu, msklog")
9728 (set_attr "mode" "<MODE>")])
9730 (define_insn_and_split "*iordi_1_bts"
9731 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9733 (match_operand:DI 1 "nonimmediate_operand" "%0")
9734 (match_operand:DI 2 "const_int_operand" "n")))
9735 (clobber (reg:CC FLAGS_REG))]
9736 "TARGET_64BIT && TARGET_USE_BT
9737 && ix86_binary_operator_ok (IOR, DImode, operands)
9738 && IN_RANGE (exact_log2 (INTVAL (operands[2])), 31, 63)"
9740 "&& reload_completed"
9741 [(parallel [(set (zero_extract:DI (match_dup 0)
9745 (clobber (reg:CC FLAGS_REG))])]
9746 "operands[3] = GEN_INT (exact_log2 (INTVAL (operands[2])));"
9747 [(set_attr "type" "alu1")
9748 (set_attr "prefix_0f" "1")
9749 (set_attr "znver1_decode" "double")
9750 (set_attr "mode" "DI")])
9752 (define_insn_and_split "*xordi_1_btc"
9753 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9755 (match_operand:DI 1 "nonimmediate_operand" "%0")
9756 (match_operand:DI 2 "const_int_operand" "n")))
9757 (clobber (reg:CC FLAGS_REG))]
9758 "TARGET_64BIT && TARGET_USE_BT
9759 && ix86_binary_operator_ok (XOR, DImode, operands)
9760 && IN_RANGE (exact_log2 (INTVAL (operands[2])), 31, 63)"
9762 "&& reload_completed"
9763 [(parallel [(set (zero_extract:DI (match_dup 0)
9766 (not:DI (zero_extract:DI (match_dup 0)
9769 (clobber (reg:CC FLAGS_REG))])]
9770 "operands[3] = GEN_INT (exact_log2 (INTVAL (operands[2])));"
9771 [(set_attr "type" "alu1")
9772 (set_attr "prefix_0f" "1")
9773 (set_attr "znver1_decode" "double")
9774 (set_attr "mode" "DI")])
9776 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9777 (define_insn "*<code>si_1_zext"
9778 [(set (match_operand:DI 0 "register_operand" "=r")
9780 (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9781 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
9782 (clobber (reg:CC FLAGS_REG))]
9783 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
9784 "<logic>{l}\t{%2, %k0|%k0, %2}"
9785 [(set_attr "type" "alu")
9786 (set_attr "mode" "SI")])
9788 (define_insn "*<code>si_1_zext_imm"
9789 [(set (match_operand:DI 0 "register_operand" "=r")
9791 (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
9792 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
9793 (clobber (reg:CC FLAGS_REG))]
9794 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
9795 "<logic>{l}\t{%2, %k0|%k0, %2}"
9796 [(set_attr "type" "alu")
9797 (set_attr "mode" "SI")])
9799 (define_insn "*<code>qi_1"
9800 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,k")
9801 (any_or:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,k")
9802 (match_operand:QI 2 "general_operand" "qn,m,rn,k")))
9803 (clobber (reg:CC FLAGS_REG))]
9804 "ix86_binary_operator_ok (<CODE>, QImode, operands)"
9806 <logic>{b}\t{%2, %0|%0, %2}
9807 <logic>{b}\t{%2, %0|%0, %2}
9808 <logic>{l}\t{%k2, %k0|%k0, %k2}
9810 [(set_attr "isa" "*,*,*,avx512f")
9811 (set_attr "type" "alu,alu,alu,msklog")
9813 (cond [(eq_attr "alternative" "2")
9815 (and (eq_attr "alternative" "3")
9816 (match_test "!TARGET_AVX512DQ"))
9819 (const_string "QI")))
9820 ;; Potential partial reg stall on alternative 2.
9821 (set (attr "preferred_for_speed")
9822 (cond [(eq_attr "alternative" "2")
9823 (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
9824 (symbol_ref "true")))])
9826 (define_insn "*<code><mode>_1_slp"
9827 [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>"))
9828 (any_or:SWI12 (match_operand:SWI12 1 "nonimmediate_operand" "%0")
9829 (match_operand:SWI12 2 "general_operand" "<r>mn")))
9830 (clobber (reg:CC FLAGS_REG))]
9831 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9832 /* FIXME: without this LRA can't reload this pattern, see PR82524. */
9833 && (rtx_equal_p (operands[0], operands[1])
9834 || rtx_equal_p (operands[0], operands[2]))"
9835 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
9836 [(set_attr "type" "alu")
9837 (set_attr "mode" "<MODE>")])
9839 (define_insn "*<code><mode>_2"
9840 [(set (reg FLAGS_REG)
9841 (compare (any_or:SWI
9842 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
9843 (match_operand:SWI 2 "<general_operand>" "<r><i>,m"))
9845 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
9846 (any_or:SWI (match_dup 1) (match_dup 2)))]
9847 "ix86_match_ccmode (insn, CCNOmode)
9848 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9849 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
9850 [(set_attr "type" "alu")
9851 (set_attr "mode" "<MODE>")])
9853 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9854 ;; ??? Special case for immediate operand is missing - it is tricky.
9855 (define_insn "*<code>si_2_zext"
9856 [(set (reg FLAGS_REG)
9857 (compare (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9858 (match_operand:SI 2 "x86_64_general_operand" "rme"))
9860 (set (match_operand:DI 0 "register_operand" "=r")
9861 (zero_extend:DI (any_or:SI (match_dup 1) (match_dup 2))))]
9862 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9863 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
9864 "<logic>{l}\t{%2, %k0|%k0, %2}"
9865 [(set_attr "type" "alu")
9866 (set_attr "mode" "SI")])
9868 (define_insn "*<code>si_2_zext_imm"
9869 [(set (reg FLAGS_REG)
9871 (match_operand:SI 1 "nonimmediate_operand" "%0")
9872 (match_operand:SI 2 "x86_64_zext_immediate_operand" "Z"))
9874 (set (match_operand:DI 0 "register_operand" "=r")
9875 (any_or:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
9876 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9877 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
9878 "<logic>{l}\t{%2, %k0|%k0, %2}"
9879 [(set_attr "type" "alu")
9880 (set_attr "mode" "SI")])
9882 (define_insn "*<code><mode>_3"
9883 [(set (reg FLAGS_REG)
9884 (compare (any_or:SWI
9885 (match_operand:SWI 1 "nonimmediate_operand" "%0")
9886 (match_operand:SWI 2 "<general_operand>" "<g>"))
9888 (clobber (match_scratch:SWI 0 "=<r>"))]
9889 "ix86_match_ccmode (insn, CCNOmode)
9890 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9891 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
9892 [(set_attr "type" "alu")
9893 (set_attr "mode" "<MODE>")])
9895 (define_insn "*<code>qi_ext<mode>_1"
9896 [(set (zero_extract:SWI248
9897 (match_operand:SWI248 0 "register_operand" "+Q,Q")
9903 (zero_extract:SWI248
9904 (match_operand:SWI248 1 "register_operand" "0,0")
9907 (match_operand:QI 2 "general_operand" "QnBc,m")) 0))
9908 (clobber (reg:CC FLAGS_REG))]
9909 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9910 /* FIXME: without this LRA can't reload this pattern, see PR82524. */
9911 && rtx_equal_p (operands[0], operands[1])"
9912 "<logic>{b}\t{%2, %h0|%h0, %2}"
9913 [(set_attr "isa" "*,nox64")
9914 (set_attr "type" "alu")
9915 (set_attr "mode" "QI")])
9917 (define_insn "*<code>qi_ext<mode>_2"
9918 [(set (zero_extract:SWI248
9919 (match_operand:SWI248 0 "register_operand" "+Q")
9925 (zero_extract:SWI248
9926 (match_operand:SWI248 1 "register_operand" "%0")
9930 (zero_extract:SWI248
9931 (match_operand:SWI248 2 "register_operand" "Q")
9933 (const_int 8)) 0)) 0))
9934 (clobber (reg:CC FLAGS_REG))]
9935 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9936 /* FIXME: without this LRA can't reload this pattern, see PR82524. */
9937 && (rtx_equal_p (operands[0], operands[1])
9938 || rtx_equal_p (operands[0], operands[2]))"
9939 "<logic>{b}\t{%h2, %h0|%h0, %h2}"
9940 [(set_attr "type" "alu")
9941 (set_attr "mode" "QI")])
9943 ;; Convert wide OR instructions with immediate operand to shorter QImode
9944 ;; equivalents when possible.
9945 ;; Don't do the splitting with memory operands, since it introduces risk
9946 ;; of memory mismatch stalls. We may want to do the splitting for optimizing
9947 ;; for size, but that can (should?) be handled by generic code instead.
9949 [(set (match_operand:SWI248 0 "QIreg_operand")
9950 (any_or:SWI248 (match_operand:SWI248 1 "register_operand")
9951 (match_operand:SWI248 2 "const_int_operand")))
9952 (clobber (reg:CC FLAGS_REG))]
9954 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9955 && !(INTVAL (operands[2]) & ~(255 << 8))"
9957 [(set (zero_extract:SI (match_dup 0)
9963 (zero_extract:SI (match_dup 1)
9967 (clobber (reg:CC FLAGS_REG))])]
9969 operands[0] = gen_lowpart (SImode, operands[0]);
9970 operands[1] = gen_lowpart (SImode, operands[1]);
9971 operands[2] = gen_int_mode (INTVAL (operands[2]) >> 8, QImode);
9974 ;; Since OR can be encoded with sign extended immediate, this is only
9975 ;; profitable when 7th bit is set.
9977 [(set (match_operand:SWI248 0 "any_QIreg_operand")
9978 (any_or:SWI248 (match_operand:SWI248 1 "general_operand")
9979 (match_operand:SWI248 2 "const_int_operand")))
9980 (clobber (reg:CC FLAGS_REG))]
9982 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9983 && !(INTVAL (operands[2]) & ~255)
9984 && (INTVAL (operands[2]) & 128)"
9985 [(parallel [(set (strict_low_part (match_dup 0))
9986 (any_or:QI (match_dup 1)
9988 (clobber (reg:CC FLAGS_REG))])]
9990 operands[0] = gen_lowpart (QImode, operands[0]);
9991 operands[1] = gen_lowpart (QImode, operands[1]);
9992 operands[2] = gen_int_mode (INTVAL (operands[2]), QImode);
9995 (define_expand "xorqi_ext_1_cc"
9997 [(set (reg:CCNO FLAGS_REG)
10001 (zero_extract:HI (match_operand:HI 1 "register_operand")
10004 (match_operand:QI 2 "const_int_operand"))
10006 (set (zero_extract:HI (match_operand:HI 0 "register_operand")
10012 (zero_extract:HI (match_dup 1)
10015 (match_dup 2)) 0))])])
10017 (define_insn "*xorqi_ext<mode>_1_cc"
10018 [(set (reg FLAGS_REG)
10022 (zero_extract:SWI248
10023 (match_operand:SWI248 1 "register_operand" "0,0")
10026 (match_operand:QI 2 "general_operand" "QnBc,m"))
10028 (set (zero_extract:SWI248
10029 (match_operand:SWI248 0 "register_operand" "+Q,Q")
10035 (zero_extract:SWI248
10039 (match_dup 2)) 0))]
10040 "ix86_match_ccmode (insn, CCNOmode)
10041 /* FIXME: without this LRA can't reload this pattern, see PR82524. */
10042 && rtx_equal_p (operands[0], operands[1])"
10043 "xor{b}\t{%2, %h0|%h0, %2}"
10044 [(set_attr "isa" "*,nox64")
10045 (set_attr "type" "alu")
10046 (set_attr "mode" "QI")])
10048 ;; Negation instructions
10050 (define_expand "neg<mode>2"
10051 [(set (match_operand:SDWIM 0 "nonimmediate_operand")
10052 (neg:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")))]
10054 "ix86_expand_unary_operator (NEG, <MODE>mode, operands); DONE;")
10056 (define_insn_and_split "*neg<dwi>2_doubleword"
10057 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro")
10058 (neg:<DWI> (match_operand:<DWI> 1 "nonimmediate_operand" "0")))
10059 (clobber (reg:CC FLAGS_REG))]
10060 "ix86_unary_operator_ok (NEG, <DWI>mode, operands)"
10064 [(set (reg:CCC FLAGS_REG)
10065 (ne:CCC (match_dup 1) (const_int 0)))
10066 (set (match_dup 0) (neg:DWIH (match_dup 1)))])
10068 [(set (match_dup 2)
10069 (plus:DWIH (plus:DWIH (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
10072 (clobber (reg:CC FLAGS_REG))])
10074 [(set (match_dup 2)
10075 (neg:DWIH (match_dup 2)))
10076 (clobber (reg:CC FLAGS_REG))])]
10077 "split_double_mode (<DWI>mode, &operands[0], 2, &operands[0], &operands[2]);")
10079 (define_insn "*neg<mode>_1"
10080 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
10081 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")))
10082 (clobber (reg:CC FLAGS_REG))]
10083 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
10084 "neg{<imodesuffix>}\t%0"
10085 [(set_attr "type" "negnot")
10086 (set_attr "mode" "<MODE>")])
10088 (define_insn "*negsi_1_zext"
10089 [(set (match_operand:DI 0 "register_operand" "=r")
10091 (neg:SI (match_operand:SI 1 "register_operand" "0"))))
10092 (clobber (reg:CC FLAGS_REG))]
10093 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
10095 [(set_attr "type" "negnot")
10096 (set_attr "mode" "SI")])
10098 (define_insn "*neg<mode>_2"
10099 [(set (reg FLAGS_REG)
10101 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
10103 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
10104 (neg:SWI (match_dup 1)))]
10105 "ix86_match_ccmode (insn, CCGOCmode)
10106 && ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
10107 "neg{<imodesuffix>}\t%0"
10108 [(set_attr "type" "negnot")
10109 (set_attr "mode" "<MODE>")])
10111 (define_insn "*negsi_2_zext"
10112 [(set (reg FLAGS_REG)
10114 (neg:SI (match_operand:SI 1 "register_operand" "0"))
10116 (set (match_operand:DI 0 "register_operand" "=r")
10118 (neg:SI (match_dup 1))))]
10119 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
10120 && ix86_unary_operator_ok (NEG, SImode, operands)"
10122 [(set_attr "type" "negnot")
10123 (set_attr "mode" "SI")])
10125 (define_insn "*neg<mode>_ccc_1"
10126 [(set (reg:CCC FLAGS_REG)
10128 (match_operand:SWI 1 "nonimmediate_operand" "0")
10130 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
10131 (neg:SWI (match_dup 1)))]
10133 "neg{<imodesuffix>}\t%0"
10134 [(set_attr "type" "negnot")
10135 (set_attr "mode" "<MODE>")])
10137 (define_insn "*neg<mode>_ccc_2"
10138 [(set (reg:CCC FLAGS_REG)
10140 (match_operand:SWI 1 "nonimmediate_operand" "0")
10142 (clobber (match_scratch:SWI 0 "=<r>"))]
10144 "neg{<imodesuffix>}\t%0"
10145 [(set_attr "type" "negnot")
10146 (set_attr "mode" "<MODE>")])
10148 ;; Negate with jump on overflow.
10149 (define_expand "negv<mode>3"
10150 [(parallel [(set (reg:CCO FLAGS_REG)
10151 (ne:CCO (match_operand:SWI 1 "register_operand")
10153 (set (match_operand:SWI 0 "register_operand")
10154 (neg:SWI (match_dup 1)))])
10155 (set (pc) (if_then_else
10156 (eq (reg:CCO FLAGS_REG) (const_int 0))
10157 (label_ref (match_operand 2))
10162 = gen_int_mode (HOST_WIDE_INT_1U << (GET_MODE_BITSIZE (<MODE>mode) - 1),
10166 (define_insn "*negv<mode>3"
10167 [(set (reg:CCO FLAGS_REG)
10168 (ne:CCO (match_operand:SWI 1 "nonimmediate_operand" "0")
10169 (match_operand:SWI 2 "const_int_operand")))
10170 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
10171 (neg:SWI (match_dup 1)))]
10172 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)
10173 && mode_signbit_p (<MODE>mode, operands[2])"
10174 "neg{<imodesuffix>}\t%0"
10175 [(set_attr "type" "negnot")
10176 (set_attr "mode" "<MODE>")])
10178 ;; Special expand pattern to handle integer mode abs
10180 (define_expand "abs<mode>2"
10182 [(set (match_operand:SDWIM 0 "register_operand")
10184 (match_operand:SDWIM 1 "general_operand")))
10185 (clobber (reg:CC FLAGS_REG))])]
10187 && (<MODE>mode != QImode || !TARGET_PARTIAL_REG_STALL)"
10189 if (TARGET_EXPAND_ABS)
10191 machine_mode mode = <MODE>mode;
10192 operands[1] = force_reg (mode, operands[1]);
10194 /* Generate rtx abs using:
10195 abs (x) = (((signed) x >> (W-1)) ^ x) - ((signed) x >> (W-1)) */
10197 rtx shift_amount = gen_int_mode (GET_MODE_PRECISION (mode) - 1, QImode);
10198 rtx shift_dst = expand_simple_binop (mode, ASHIFTRT, operands[1],
10199 shift_amount, NULL_RTX,
10201 rtx xor_dst = expand_simple_binop (mode, XOR, shift_dst, operands[1],
10202 operands[0], 0, OPTAB_DIRECT);
10203 rtx minus_dst = expand_simple_binop (mode, MINUS, xor_dst, shift_dst,
10204 operands[0], 0, OPTAB_DIRECT);
10205 if (!rtx_equal_p (minus_dst, operands[0]))
10206 emit_move_insn (operands[0], minus_dst);
10211 (define_insn_and_split "*abs<dwi>2_doubleword"
10212 [(set (match_operand:<DWI> 0 "register_operand")
10214 (match_operand:<DWI> 1 "general_operand")))
10215 (clobber (reg:CC FLAGS_REG))]
10217 && ix86_pre_reload_split ()"
10221 [(set (reg:CCC FLAGS_REG)
10222 (ne:CCC (match_dup 1) (const_int 0)))
10223 (set (match_dup 2) (neg:DWIH (match_dup 1)))])
10225 [(set (match_dup 5)
10226 (plus:DWIH (plus:DWIH (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
10229 (clobber (reg:CC FLAGS_REG))])
10231 [(set (reg:CCGOC FLAGS_REG)
10233 (neg:DWIH (match_dup 5))
10236 (neg:DWIH (match_dup 5)))])
10239 (ge (reg:CCGOC FLAGS_REG) (const_int 0))
10244 (ge (reg:CCGOC FLAGS_REG) (const_int 0))
10248 operands[1] = force_reg (<DWI>mode, operands[1]);
10249 operands[2] = gen_reg_rtx (<DWI>mode);
10251 split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
10254 (define_insn_and_split "*abs<mode>2_1"
10255 [(set (match_operand:SWI 0 "register_operand")
10257 (match_operand:SWI 1 "general_operand")))
10258 (clobber (reg:CC FLAGS_REG))]
10260 && (<MODE>mode != QImode || !TARGET_PARTIAL_REG_STALL)
10261 && ix86_pre_reload_split ()"
10265 [(set (reg:CCGOC FLAGS_REG)
10267 (neg:SWI (match_dup 1))
10270 (neg:SWI (match_dup 1)))])
10273 (ge (reg:CCGOC FLAGS_REG) (const_int 0))
10277 operands[1] = force_reg (<MODE>mode, operands[1]);
10278 operands[2] = gen_reg_rtx (<MODE>mode);
10281 (define_expand "<code>tf2"
10282 [(set (match_operand:TF 0 "register_operand")
10283 (absneg:TF (match_operand:TF 1 "register_operand")))]
10285 "ix86_expand_fp_absneg_operator (<CODE>, TFmode, operands); DONE;")
10287 (define_insn_and_split "*<code>tf2_1"
10288 [(set (match_operand:TF 0 "register_operand" "=x,x,Yv,Yv")
10290 (match_operand:TF 1 "vector_operand" "0,xBm,Yv,m")))
10291 (use (match_operand:TF 2 "vector_operand" "xBm,0,Yvm,Yv"))]
10294 "&& reload_completed"
10295 [(set (match_dup 0)
10296 (<absneg_op>:TF (match_dup 1) (match_dup 2)))]
10300 if (MEM_P (operands[1]))
10301 std::swap (operands[1], operands[2]);
10305 if (operands_match_p (operands[0], operands[2]))
10306 std::swap (operands[1], operands[2]);
10309 [(set_attr "isa" "noavx,noavx,avx,avx")])
10311 (define_insn_and_split "*nabstf2_1"
10312 [(set (match_operand:TF 0 "register_operand" "=x,x,Yv,Yv")
10315 (match_operand:TF 1 "vector_operand" "0,xBm,Yv,m"))))
10316 (use (match_operand:TF 2 "vector_operand" "xBm,0,Yvm,Yv"))]
10319 "&& reload_completed"
10320 [(set (match_dup 0)
10321 (ior:TF (match_dup 1) (match_dup 2)))]
10325 if (MEM_P (operands[1]))
10326 std::swap (operands[1], operands[2]);
10330 if (operands_match_p (operands[0], operands[2]))
10331 std::swap (operands[1], operands[2]);
10334 [(set_attr "isa" "noavx,noavx,avx,avx")])
10336 (define_expand "<code><mode>2"
10337 [(set (match_operand:X87MODEF 0 "register_operand")
10338 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand")))]
10339 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
10340 "ix86_expand_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
10342 ;; Changing of sign for FP values is doable using integer unit too.
10343 (define_insn "*<code><mode>2_i387_1"
10344 [(set (match_operand:X87MODEF 0 "register_operand" "=f,!r")
10346 (match_operand:X87MODEF 1 "register_operand" "0,0")))
10347 (clobber (reg:CC FLAGS_REG))]
10348 "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
10352 [(set (match_operand:X87MODEF 0 "fp_register_operand")
10353 (absneg:X87MODEF (match_operand:X87MODEF 1 "fp_register_operand")))
10354 (clobber (reg:CC FLAGS_REG))]
10355 "TARGET_80387 && reload_completed"
10356 [(set (match_dup 0) (absneg:X87MODEF (match_dup 1)))])
10359 [(set (match_operand:X87MODEF 0 "general_reg_operand")
10360 (absneg:X87MODEF (match_operand:X87MODEF 1 "general_reg_operand")))
10361 (clobber (reg:CC FLAGS_REG))]
10362 "TARGET_80387 && reload_completed"
10364 "ix86_split_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
10366 (define_insn "*<code><mode>2_1"
10367 [(set (match_operand:MODEF 0 "register_operand" "=x,x,Yv,f,!r")
10369 (match_operand:MODEF 1 "register_operand" "0,x,Yv,0,0")))
10370 (use (match_operand:<ssevecmode> 2 "vector_operand" "xBm,0,Yvm,X,X"))
10371 (clobber (reg:CC FLAGS_REG))]
10372 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
10374 [(set_attr "isa" "noavx,noavx,avx,*,*")
10375 (set (attr "enabled")
10377 (match_test ("SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"))
10379 (eq_attr "alternative" "3,4")
10380 (symbol_ref "TARGET_MIX_SSE_I387")
10381 (const_string "*"))
10383 (eq_attr "alternative" "3,4")
10384 (symbol_ref "true")
10385 (symbol_ref "false"))))])
10388 [(set (match_operand:MODEF 0 "sse_reg_operand")
10390 (match_operand:MODEF 1 "sse_reg_operand")))
10391 (use (match_operand:<ssevecmodef> 2 "vector_operand"))
10392 (clobber (reg:CC FLAGS_REG))]
10393 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
10394 && reload_completed"
10395 [(set (match_dup 0)
10396 (<absneg_op>:<ssevecmodef> (match_dup 1) (match_dup 2)))]
10398 machine_mode mode = <MODE>mode;
10399 machine_mode vmode = <ssevecmodef>mode;
10401 operands[0] = lowpart_subreg (vmode, operands[0], mode);
10402 operands[1] = lowpart_subreg (vmode, operands[1], mode);
10404 if (!TARGET_AVX && operands_match_p (operands[0], operands[2]))
10405 std::swap (operands[1], operands[2]);
10409 [(set (match_operand:MODEF 0 "fp_register_operand")
10410 (absneg:MODEF (match_operand:MODEF 1 "fp_register_operand")))
10411 (use (match_operand 2))
10412 (clobber (reg:CC FLAGS_REG))]
10413 "TARGET_80387 && reload_completed"
10414 [(set (match_dup 0) (absneg:MODEF (match_dup 1)))])
10417 [(set (match_operand:MODEF 0 "general_reg_operand")
10418 (absneg:MODEF (match_operand:MODEF 1 "general_reg_operand")))
10419 (use (match_operand 2))
10420 (clobber (reg:CC FLAGS_REG))]
10421 "TARGET_80387 && reload_completed"
10423 "ix86_split_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
10425 (define_insn_and_split "*nabs<mode>2_1"
10426 [(set (match_operand:MODEF 0 "register_operand" "=x,x,Yv")
10429 (match_operand:MODEF 1 "register_operand" "0,x,Yv"))))
10430 (use (match_operand:<ssevecmode> 2 "vector_operand" "xBm,0,Yvm"))]
10431 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
10433 "&& reload_completed"
10434 [(set (match_dup 0)
10435 (ior:<ssevecmodef> (match_dup 1) (match_dup 2)))]
10437 machine_mode mode = <MODE>mode;
10438 machine_mode vmode = <ssevecmodef>mode;
10440 operands[0] = lowpart_subreg (vmode, operands[0], mode);
10441 operands[1] = lowpart_subreg (vmode, operands[1], mode);
10443 if (!TARGET_AVX && operands_match_p (operands[0], operands[2]))
10444 std::swap (operands[1], operands[2]);
10446 [(set_attr "isa" "noavx,noavx,avx")])
10448 ;; Conditionalize these after reload. If they match before reload, we
10449 ;; lose the clobber and ability to use integer instructions.
10451 (define_insn "*<code><mode>2_i387"
10452 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
10453 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "0")))]
10454 "TARGET_80387 && reload_completed"
10455 "<absneg_mnemonic>"
10456 [(set_attr "type" "fsgn")
10457 (set_attr "mode" "<MODE>")])
10459 ;; Copysign instructions
10461 (define_expand "copysign<mode>3"
10462 [(match_operand:SSEMODEF 0 "register_operand")
10463 (match_operand:SSEMODEF 1 "nonmemory_operand")
10464 (match_operand:SSEMODEF 2 "register_operand")]
10465 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10466 || (TARGET_SSE && (<MODE>mode == TFmode))"
10467 "ix86_expand_copysign (operands); DONE;")
10469 (define_insn_and_split "@copysign<mode>3_const"
10470 [(set (match_operand:SSEMODEF 0 "register_operand" "=Yv")
10472 [(match_operand:<ssevecmodef> 1 "nonimm_or_0_operand" "YvmC")
10473 (match_operand:SSEMODEF 2 "register_operand" "0")
10474 (match_operand:<ssevecmodef> 3 "nonimmediate_operand" "Yvm")]
10476 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10477 || (TARGET_SSE && (<MODE>mode == TFmode))"
10479 "&& reload_completed"
10481 "ix86_split_copysign_const (operands); DONE;")
10483 (define_insn "@copysign<mode>3_var"
10484 [(set (match_operand:SSEMODEF 0 "register_operand" "=Yv,Yv,Yv,Yv,Yv")
10486 [(match_operand:SSEMODEF 2 "register_operand" "Yv,0,0,Yv,Yv")
10487 (match_operand:SSEMODEF 3 "register_operand" "1,1,Yv,1,Yv")
10488 (match_operand:<ssevecmodef> 4
10489 "nonimmediate_operand" "X,Yvm,Yvm,0,0")
10490 (match_operand:<ssevecmodef> 5
10491 "nonimmediate_operand" "0,Yvm,1,Yvm,1")]
10493 (clobber (match_scratch:<ssevecmodef> 1 "=Yv,Yv,Yv,Yv,Yv"))]
10494 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10495 || (TARGET_SSE && (<MODE>mode == TFmode))"
10499 [(set (match_operand:SSEMODEF 0 "register_operand")
10501 [(match_operand:SSEMODEF 2 "register_operand")
10502 (match_operand:SSEMODEF 3 "register_operand")
10503 (match_operand:<ssevecmodef> 4)
10504 (match_operand:<ssevecmodef> 5)]
10506 (clobber (match_scratch:<ssevecmodef> 1))]
10507 "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10508 || (TARGET_SSE && (<MODE>mode == TFmode)))
10509 && reload_completed"
10511 "ix86_split_copysign_var (operands); DONE;")
10513 (define_expand "xorsign<mode>3"
10514 [(match_operand:MODEF 0 "register_operand")
10515 (match_operand:MODEF 1 "register_operand")
10516 (match_operand:MODEF 2 "register_operand")]
10517 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
10518 "ix86_expand_xorsign (operands); DONE;")
10520 (define_insn_and_split "@xorsign<mode>3_1"
10521 [(set (match_operand:MODEF 0 "register_operand" "=Yv")
10523 [(match_operand:MODEF 1 "register_operand" "Yv")
10524 (match_operand:MODEF 2 "register_operand" "0")
10525 (match_operand:<ssevecmode> 3 "nonimmediate_operand" "Yvm")]
10527 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
10529 "&& reload_completed"
10531 "ix86_split_xorsign (operands); DONE;")
10533 ;; One complement instructions
10535 (define_expand "one_cmpl<mode>2"
10536 [(set (match_operand:SWIM1248s 0 "nonimmediate_operand")
10537 (not:SWIM1248s (match_operand:SWIM1248s 1 "nonimmediate_operand")))]
10539 "ix86_expand_unary_operator (NOT, <MODE>mode, operands); DONE;")
10541 (define_insn_and_split "*one_cmpldi2_doubleword"
10542 [(set (match_operand:DI 0 "nonimmediate_operand")
10543 (not:DI (match_operand:DI 1 "nonimmediate_operand")))]
10544 "!TARGET_64BIT && TARGET_STV && TARGET_SSE2
10545 && ix86_unary_operator_ok (NOT, DImode, operands)
10546 && ix86_pre_reload_split ()"
10549 [(set (match_dup 0)
10550 (not:SI (match_dup 1)))
10552 (not:SI (match_dup 3)))]
10553 "split_double_mode (DImode, &operands[0], 2, &operands[0], &operands[2]);")
10555 (define_insn "*one_cmpl<mode>2_1"
10556 [(set (match_operand:SWI248 0 "nonimmediate_operand" "=rm,k")
10557 (not:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "0,k")))]
10558 "ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
10560 not{<imodesuffix>}\t%0
10563 (cond [(eq_attr "alternative" "1")
10564 (if_then_else (eq_attr "mode" "SI,DI")
10565 (const_string "avx512bw")
10566 (const_string "avx512f"))
10568 (const_string "*")))
10569 (set_attr "type" "negnot,msklog")
10570 (set_attr "mode" "<MODE>")])
10572 (define_insn "*one_cmplsi2_1_zext"
10573 [(set (match_operand:DI 0 "register_operand" "=r,k")
10575 (not:SI (match_operand:SI 1 "register_operand" "0,k"))))]
10576 "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
10580 [(set_attr "isa" "x64,avx512bw")
10581 (set_attr "type" "negnot,msklog")
10582 (set_attr "mode" "SI,SI")])
10584 (define_insn "*one_cmplqi2_1"
10585 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,k")
10586 (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,k")))]
10587 "ix86_unary_operator_ok (NOT, QImode, operands)"
10592 [(set_attr "isa" "*,*,avx512f")
10593 (set_attr "type" "negnot,negnot,msklog")
10595 (cond [(eq_attr "alternative" "1")
10596 (const_string "SI")
10597 (and (eq_attr "alternative" "2")
10598 (match_test "!TARGET_AVX512DQ"))
10599 (const_string "HI")
10601 (const_string "QI")))
10602 ;; Potential partial reg stall on alternative 1.
10603 (set (attr "preferred_for_speed")
10604 (cond [(eq_attr "alternative" "1")
10605 (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
10606 (symbol_ref "true")))])
10608 (define_insn "*one_cmpl<mode>2_2"
10609 [(set (reg FLAGS_REG)
10610 (compare (not:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
10612 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
10613 (not:SWI (match_dup 1)))]
10614 "ix86_match_ccmode (insn, CCNOmode)
10615 && ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
10617 [(set_attr "type" "alu1")
10618 (set_attr "mode" "<MODE>")])
10621 [(set (match_operand 0 "flags_reg_operand")
10622 (match_operator 2 "compare_operator"
10623 [(not:SWI (match_operand:SWI 3 "nonimmediate_operand"))
10625 (set (match_operand:SWI 1 "nonimmediate_operand")
10626 (not:SWI (match_dup 3)))]
10627 "ix86_match_ccmode (insn, CCNOmode)"
10628 [(parallel [(set (match_dup 0)
10629 (match_op_dup 2 [(xor:SWI (match_dup 3) (const_int -1))
10632 (xor:SWI (match_dup 3) (const_int -1)))])])
10634 (define_insn "*one_cmplsi2_2_zext"
10635 [(set (reg FLAGS_REG)
10636 (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
10638 (set (match_operand:DI 0 "register_operand" "=r")
10639 (zero_extend:DI (not:SI (match_dup 1))))]
10640 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10641 && ix86_unary_operator_ok (NOT, SImode, operands)"
10643 [(set_attr "type" "alu1")
10644 (set_attr "mode" "SI")])
10647 [(set (match_operand 0 "flags_reg_operand")
10648 (match_operator 2 "compare_operator"
10649 [(not:SI (match_operand:SI 3 "register_operand"))
10651 (set (match_operand:DI 1 "register_operand")
10652 (zero_extend:DI (not:SI (match_dup 3))))]
10653 "ix86_match_ccmode (insn, CCNOmode)"
10654 [(parallel [(set (match_dup 0)
10655 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10658 (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])])
10660 ;; Shift instructions
10662 ;; DImode shifts are implemented using the i386 "shift double" opcode,
10663 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem". If the shift count
10664 ;; is variable, then the count is in %cl and the "imm" operand is dropped
10665 ;; from the assembler input.
10667 ;; This instruction shifts the target reg/mem as usual, but instead of
10668 ;; shifting in zeros, bits are shifted in from reg operand. If the insn
10669 ;; is a left shift double, bits are taken from the high order bits of
10670 ;; reg, else if the insn is a shift right double, bits are taken from the
10671 ;; low order bits of reg. So if %eax is "1234" and %edx is "5678",
10672 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
10674 ;; Since sh[lr]d does not change the `reg' operand, that is done
10675 ;; separately, making all shifts emit pairs of shift double and normal
10676 ;; shift. Since sh[lr]d does not shift more than 31 bits, and we wish to
10677 ;; support a 63 bit shift, each shift where the count is in a reg expands
10678 ;; to a pair of shifts, a branch, a shift by 32 and a label.
10680 ;; If the shift count is a constant, we need never emit more than one
10681 ;; shift pair, instead using moves and sign extension for counts greater
10684 (define_expand "ashl<mode>3"
10685 [(set (match_operand:SDWIM 0 "<shift_operand>")
10686 (ashift:SDWIM (match_operand:SDWIM 1 "<ashl_input_operand>")
10687 (match_operand:QI 2 "nonmemory_operand")))]
10689 "ix86_expand_binary_operator (ASHIFT, <MODE>mode, operands); DONE;")
10691 (define_insn_and_split "*ashl<dwi>3_doubleword_mask"
10692 [(set (match_operand:<DWI> 0 "register_operand")
10694 (match_operand:<DWI> 1 "register_operand")
10697 (match_operand:SI 2 "register_operand" "c")
10698 (match_operand:SI 3 "const_int_operand")) 0)))
10699 (clobber (reg:CC FLAGS_REG))]
10700 "(INTVAL (operands[3]) & (<MODE_SIZE> * BITS_PER_UNIT)) == 0
10701 && ix86_pre_reload_split ()"
10705 [(set (match_dup 6)
10706 (ior:DWIH (ashift:DWIH (match_dup 6) (match_dup 2))
10707 (lshiftrt:DWIH (match_dup 5)
10708 (minus:QI (match_dup 8) (match_dup 2)))))
10709 (clobber (reg:CC FLAGS_REG))])
10711 [(set (match_dup 4)
10712 (ashift:DWIH (match_dup 5) (match_dup 2)))
10713 (clobber (reg:CC FLAGS_REG))])]
10715 split_double_mode (<DWI>mode, &operands[0], 2, &operands[4], &operands[6]);
10717 operands[8] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT);
10719 if ((INTVAL (operands[3]) & ((<MODE_SIZE> * BITS_PER_UNIT) - 1))
10720 != ((<MODE_SIZE> * BITS_PER_UNIT) - 1))
10722 rtx tem = gen_reg_rtx (SImode);
10723 emit_insn (gen_andsi3 (tem, operands[2], operands[3]));
10727 operands[2] = gen_lowpart (QImode, operands[2]);
10729 if (!rtx_equal_p (operands[6], operands[7]))
10730 emit_move_insn (operands[6], operands[7]);
10733 (define_insn_and_split "*ashl<dwi>3_doubleword_mask_1"
10734 [(set (match_operand:<DWI> 0 "register_operand")
10736 (match_operand:<DWI> 1 "register_operand")
10738 (match_operand:QI 2 "register_operand" "c")
10739 (match_operand:QI 3 "const_int_operand"))))
10740 (clobber (reg:CC FLAGS_REG))]
10741 "(INTVAL (operands[3]) & (<MODE_SIZE> * BITS_PER_UNIT)) == 0
10742 && ix86_pre_reload_split ()"
10746 [(set (match_dup 6)
10747 (ior:DWIH (ashift:DWIH (match_dup 6) (match_dup 2))
10748 (lshiftrt:DWIH (match_dup 5)
10749 (minus:QI (match_dup 8) (match_dup 2)))))
10750 (clobber (reg:CC FLAGS_REG))])
10752 [(set (match_dup 4)
10753 (ashift:DWIH (match_dup 5) (match_dup 2)))
10754 (clobber (reg:CC FLAGS_REG))])]
10756 split_double_mode (<DWI>mode, &operands[0], 2, &operands[4], &operands[6]);
10758 operands[8] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT);
10760 if ((INTVAL (operands[3]) & ((<MODE_SIZE> * BITS_PER_UNIT) - 1))
10761 != ((<MODE_SIZE> * BITS_PER_UNIT) - 1))
10763 rtx tem = gen_reg_rtx (QImode);
10764 emit_insn (gen_andqi3 (tem, operands[2], operands[3]));
10768 if (!rtx_equal_p (operands[6], operands[7]))
10769 emit_move_insn (operands[6], operands[7]);
10772 (define_insn "*ashl<mode>3_doubleword"
10773 [(set (match_operand:DWI 0 "register_operand" "=&r")
10774 (ashift:DWI (match_operand:DWI 1 "reg_or_pm1_operand" "0n")
10775 (match_operand:QI 2 "nonmemory_operand" "<S>c")))
10776 (clobber (reg:CC FLAGS_REG))]
10779 [(set_attr "type" "multi")])
10782 [(set (match_operand:DWI 0 "register_operand")
10783 (ashift:DWI (match_operand:DWI 1 "nonmemory_operand")
10784 (match_operand:QI 2 "nonmemory_operand")))
10785 (clobber (reg:CC FLAGS_REG))]
10786 "epilogue_completed"
10788 "ix86_split_ashl (operands, NULL_RTX, <MODE>mode); DONE;")
10790 ;; By default we don't ask for a scratch register, because when DWImode
10791 ;; values are manipulated, registers are already at a premium. But if
10792 ;; we have one handy, we won't turn it away.
10795 [(match_scratch:DWIH 3 "r")
10796 (parallel [(set (match_operand:<DWI> 0 "register_operand")
10798 (match_operand:<DWI> 1 "nonmemory_operand")
10799 (match_operand:QI 2 "nonmemory_operand")))
10800 (clobber (reg:CC FLAGS_REG))])
10804 "ix86_split_ashl (operands, operands[3], <DWI>mode); DONE;")
10806 (define_insn "x86_64_shld"
10807 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
10808 (ior:DI (ashift:DI (match_dup 0)
10809 (match_operand:QI 2 "nonmemory_operand" "Jc"))
10810 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
10811 (minus:QI (const_int 64) (match_dup 2)))))
10812 (clobber (reg:CC FLAGS_REG))]
10814 "shld{q}\t{%s2%1, %0|%0, %1, %2}"
10815 [(set_attr "type" "ishift")
10816 (set_attr "prefix_0f" "1")
10817 (set_attr "mode" "DI")
10818 (set_attr "athlon_decode" "vector")
10819 (set_attr "amdfam10_decode" "vector")
10820 (set_attr "bdver1_decode" "vector")])
10822 (define_insn "x86_shld"
10823 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
10824 (ior:SI (ashift:SI (match_dup 0)
10825 (match_operand:QI 2 "nonmemory_operand" "Ic"))
10826 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
10827 (minus:QI (const_int 32) (match_dup 2)))))
10828 (clobber (reg:CC FLAGS_REG))]
10830 "shld{l}\t{%s2%1, %0|%0, %1, %2}"
10831 [(set_attr "type" "ishift")
10832 (set_attr "prefix_0f" "1")
10833 (set_attr "mode" "SI")
10834 (set_attr "pent_pair" "np")
10835 (set_attr "athlon_decode" "vector")
10836 (set_attr "amdfam10_decode" "vector")
10837 (set_attr "bdver1_decode" "vector")])
10839 (define_expand "@x86_shift<mode>_adj_1"
10840 [(set (reg:CCZ FLAGS_REG)
10841 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand")
10844 (set (match_operand:SWI48 0 "register_operand")
10845 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
10846 (match_operand:SWI48 1 "register_operand")
10849 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
10850 (match_operand:SWI48 3 "register_operand")
10853 "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
10855 (define_expand "@x86_shift<mode>_adj_2"
10856 [(use (match_operand:SWI48 0 "register_operand"))
10857 (use (match_operand:SWI48 1 "register_operand"))
10858 (use (match_operand:QI 2 "register_operand"))]
10861 rtx_code_label *label = gen_label_rtx ();
10864 emit_insn (gen_testqi_ccz_1 (operands[2],
10865 GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
10867 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
10868 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
10869 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
10870 gen_rtx_LABEL_REF (VOIDmode, label),
10872 tmp = emit_jump_insn (gen_rtx_SET (pc_rtx, tmp));
10873 JUMP_LABEL (tmp) = label;
10875 emit_move_insn (operands[0], operands[1]);
10876 ix86_expand_clear (operands[1]);
10878 emit_label (label);
10879 LABEL_NUSES (label) = 1;
10884 ;; Avoid useless masking of count operand.
10885 (define_insn_and_split "*ashl<mode>3_mask"
10886 [(set (match_operand:SWI48 0 "nonimmediate_operand")
10888 (match_operand:SWI48 1 "nonimmediate_operand")
10891 (match_operand:SI 2 "register_operand" "c,r")
10892 (match_operand:SI 3 "const_int_operand")) 0)))
10893 (clobber (reg:CC FLAGS_REG))]
10894 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)
10895 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10896 == GET_MODE_BITSIZE (<MODE>mode)-1
10897 && ix86_pre_reload_split ()"
10901 [(set (match_dup 0)
10902 (ashift:SWI48 (match_dup 1)
10904 (clobber (reg:CC FLAGS_REG))])]
10905 "operands[2] = gen_lowpart (QImode, operands[2]);"
10906 [(set_attr "isa" "*,bmi2")])
10908 (define_insn_and_split "*ashl<mode>3_mask_1"
10909 [(set (match_operand:SWI48 0 "nonimmediate_operand")
10911 (match_operand:SWI48 1 "nonimmediate_operand")
10913 (match_operand:QI 2 "register_operand" "c,r")
10914 (match_operand:QI 3 "const_int_operand"))))
10915 (clobber (reg:CC FLAGS_REG))]
10916 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)
10917 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10918 == GET_MODE_BITSIZE (<MODE>mode)-1
10919 && ix86_pre_reload_split ()"
10923 [(set (match_dup 0)
10924 (ashift:SWI48 (match_dup 1)
10926 (clobber (reg:CC FLAGS_REG))])]
10928 [(set_attr "isa" "*,bmi2")])
10930 (define_insn "*bmi2_ashl<mode>3_1"
10931 [(set (match_operand:SWI48 0 "register_operand" "=r")
10932 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
10933 (match_operand:SWI48 2 "register_operand" "r")))]
10935 "shlx\t{%2, %1, %0|%0, %1, %2}"
10936 [(set_attr "type" "ishiftx")
10937 (set_attr "mode" "<MODE>")])
10939 (define_insn "*ashl<mode>3_1"
10940 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r,r")
10941 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,l,rm")
10942 (match_operand:QI 2 "nonmemory_operand" "c<S>,M,r")))
10943 (clobber (reg:CC FLAGS_REG))]
10944 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
10946 switch (get_attr_type (insn))
10953 gcc_assert (operands[2] == const1_rtx);
10954 gcc_assert (rtx_equal_p (operands[0], operands[1]));
10955 return "add{<imodesuffix>}\t%0, %0";
10958 if (operands[2] == const1_rtx
10959 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10960 return "sal{<imodesuffix>}\t%0";
10962 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
10965 [(set_attr "isa" "*,*,bmi2")
10967 (cond [(eq_attr "alternative" "1")
10968 (const_string "lea")
10969 (eq_attr "alternative" "2")
10970 (const_string "ishiftx")
10971 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
10972 (match_operand 0 "register_operand"))
10973 (match_operand 2 "const1_operand"))
10974 (const_string "alu")
10976 (const_string "ishift")))
10977 (set (attr "length_immediate")
10979 (ior (eq_attr "type" "alu")
10980 (and (eq_attr "type" "ishift")
10981 (and (match_operand 2 "const1_operand")
10982 (ior (match_test "TARGET_SHIFT1")
10983 (match_test "optimize_function_for_size_p (cfun)")))))
10985 (const_string "*")))
10986 (set_attr "mode" "<MODE>")])
10988 ;; Convert shift to the shiftx pattern to avoid flags dependency.
10990 [(set (match_operand:SWI48 0 "register_operand")
10991 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
10992 (match_operand:QI 2 "register_operand")))
10993 (clobber (reg:CC FLAGS_REG))]
10994 "TARGET_BMI2 && reload_completed"
10995 [(set (match_dup 0)
10996 (ashift:SWI48 (match_dup 1) (match_dup 2)))]
10997 "operands[2] = gen_lowpart (<MODE>mode, operands[2]);")
10999 (define_insn "*bmi2_ashlsi3_1_zext"
11000 [(set (match_operand:DI 0 "register_operand" "=r")
11002 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
11003 (match_operand:SI 2 "register_operand" "r"))))]
11004 "TARGET_64BIT && TARGET_BMI2"
11005 "shlx\t{%2, %1, %k0|%k0, %1, %2}"
11006 [(set_attr "type" "ishiftx")
11007 (set_attr "mode" "SI")])
11009 (define_insn "*ashlsi3_1_zext"
11010 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
11012 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l,rm")
11013 (match_operand:QI 2 "nonmemory_operand" "cI,M,r"))))
11014 (clobber (reg:CC FLAGS_REG))]
11015 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11017 switch (get_attr_type (insn))
11024 gcc_assert (operands[2] == const1_rtx);
11025 return "add{l}\t%k0, %k0";
11028 if (operands[2] == const1_rtx
11029 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11030 return "sal{l}\t%k0";
11032 return "sal{l}\t{%2, %k0|%k0, %2}";
11035 [(set_attr "isa" "*,*,bmi2")
11037 (cond [(eq_attr "alternative" "1")
11038 (const_string "lea")
11039 (eq_attr "alternative" "2")
11040 (const_string "ishiftx")
11041 (and (match_test "TARGET_DOUBLE_WITH_ADD")
11042 (match_operand 2 "const1_operand"))
11043 (const_string "alu")
11045 (const_string "ishift")))
11046 (set (attr "length_immediate")
11048 (ior (eq_attr "type" "alu")
11049 (and (eq_attr "type" "ishift")
11050 (and (match_operand 2 "const1_operand")
11051 (ior (match_test "TARGET_SHIFT1")
11052 (match_test "optimize_function_for_size_p (cfun)")))))
11054 (const_string "*")))
11055 (set_attr "mode" "SI")])
11057 ;; Convert shift to the shiftx pattern to avoid flags dependency.
11059 [(set (match_operand:DI 0 "register_operand")
11061 (ashift:SI (match_operand:SI 1 "nonimmediate_operand")
11062 (match_operand:QI 2 "register_operand"))))
11063 (clobber (reg:CC FLAGS_REG))]
11064 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
11065 [(set (match_dup 0)
11066 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
11067 "operands[2] = gen_lowpart (SImode, operands[2]);")
11069 (define_insn "*ashlhi3_1"
11070 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,Yp")
11071 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
11072 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
11073 (clobber (reg:CC FLAGS_REG))]
11074 "ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11076 switch (get_attr_type (insn))
11082 gcc_assert (operands[2] == const1_rtx);
11083 return "add{w}\t%0, %0";
11086 if (operands[2] == const1_rtx
11087 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11088 return "sal{w}\t%0";
11090 return "sal{w}\t{%2, %0|%0, %2}";
11093 [(set (attr "type")
11094 (cond [(eq_attr "alternative" "1")
11095 (const_string "lea")
11096 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
11097 (match_operand 0 "register_operand"))
11098 (match_operand 2 "const1_operand"))
11099 (const_string "alu")
11101 (const_string "ishift")))
11102 (set (attr "length_immediate")
11104 (ior (eq_attr "type" "alu")
11105 (and (eq_attr "type" "ishift")
11106 (and (match_operand 2 "const1_operand")
11107 (ior (match_test "TARGET_SHIFT1")
11108 (match_test "optimize_function_for_size_p (cfun)")))))
11110 (const_string "*")))
11111 (set_attr "mode" "HI,SI")])
11113 (define_insn "*ashlqi3_1"
11114 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,Yp")
11115 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
11116 (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
11117 (clobber (reg:CC FLAGS_REG))]
11118 "ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11120 switch (get_attr_type (insn))
11126 gcc_assert (operands[2] == const1_rtx);
11127 if (REG_P (operands[1]) && !ANY_QI_REGNO_P (REGNO (operands[1])))
11128 return "add{l}\t%k0, %k0";
11130 return "add{b}\t%0, %0";
11133 if (operands[2] == const1_rtx
11134 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11136 if (get_attr_mode (insn) == MODE_SI)
11137 return "sal{l}\t%k0";
11139 return "sal{b}\t%0";
11143 if (get_attr_mode (insn) == MODE_SI)
11144 return "sal{l}\t{%2, %k0|%k0, %2}";
11146 return "sal{b}\t{%2, %0|%0, %2}";
11150 [(set (attr "type")
11151 (cond [(eq_attr "alternative" "2")
11152 (const_string "lea")
11153 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
11154 (match_operand 0 "register_operand"))
11155 (match_operand 2 "const1_operand"))
11156 (const_string "alu")
11158 (const_string "ishift")))
11159 (set (attr "length_immediate")
11161 (ior (eq_attr "type" "alu")
11162 (and (eq_attr "type" "ishift")
11163 (and (match_operand 2 "const1_operand")
11164 (ior (match_test "TARGET_SHIFT1")
11165 (match_test "optimize_function_for_size_p (cfun)")))))
11167 (const_string "*")))
11168 (set_attr "mode" "QI,SI,SI")
11169 ;; Potential partial reg stall on alternative 1.
11170 (set (attr "preferred_for_speed")
11171 (cond [(eq_attr "alternative" "1")
11172 (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
11173 (symbol_ref "true")))])
11175 (define_insn "*ashl<mode>3_1_slp"
11176 [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>"))
11177 (ashift:SWI12 (match_operand:SWI12 1 "register_operand" "0")
11178 (match_operand:QI 2 "nonmemory_operand" "cI")))
11179 (clobber (reg:CC FLAGS_REG))]
11180 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
11181 /* FIXME: without this LRA can't reload this pattern, see PR82524. */
11182 && rtx_equal_p (operands[0], operands[1])"
11184 switch (get_attr_type (insn))
11187 gcc_assert (operands[2] == const1_rtx);
11188 return "add{<imodesuffix>}\t%0, %0";
11191 if (operands[2] == const1_rtx
11192 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11193 return "sal{<imodesuffix>}\t%0";
11195 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
11198 [(set (attr "type")
11199 (cond [(and (match_test "TARGET_DOUBLE_WITH_ADD")
11200 (match_operand 2 "const1_operand"))
11201 (const_string "alu")
11203 (const_string "ishift")))
11204 (set (attr "length_immediate")
11206 (ior (eq_attr "type" "alu")
11207 (and (eq_attr "type" "ishift")
11208 (and (match_operand 2 "const1_operand")
11209 (ior (match_test "TARGET_SHIFT1")
11210 (match_test "optimize_function_for_size_p (cfun)")))))
11212 (const_string "*")))
11213 (set_attr "mode" "<MODE>")])
11215 ;; Convert ashift to the lea pattern to avoid flags dependency.
11217 [(set (match_operand:SWI 0 "register_operand")
11218 (ashift:SWI (match_operand:SWI 1 "index_register_operand")
11219 (match_operand 2 "const_0_to_3_operand")))
11220 (clobber (reg:CC FLAGS_REG))]
11222 && REGNO (operands[0]) != REGNO (operands[1])"
11223 [(set (match_dup 0)
11224 (mult:<LEAMODE> (match_dup 1) (match_dup 2)))]
11226 if (<MODE>mode != <LEAMODE>mode)
11228 operands[0] = gen_lowpart (<LEAMODE>mode, operands[0]);
11229 operands[1] = gen_lowpart (<LEAMODE>mode, operands[1]);
11231 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
11234 ;; Convert ashift to the lea pattern to avoid flags dependency.
11236 [(set (match_operand:DI 0 "register_operand")
11238 (ashift:SI (match_operand:SI 1 "index_register_operand")
11239 (match_operand 2 "const_0_to_3_operand"))))
11240 (clobber (reg:CC FLAGS_REG))]
11241 "TARGET_64BIT && reload_completed
11242 && REGNO (operands[0]) != REGNO (operands[1])"
11243 [(set (match_dup 0)
11244 (zero_extend:DI (mult:SI (match_dup 1) (match_dup 2))))]
11246 operands[1] = gen_lowpart (SImode, operands[1]);
11247 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
11250 ;; This pattern can't accept a variable shift count, since shifts by
11251 ;; zero don't affect the flags. We assume that shifts by constant
11252 ;; zero are optimized away.
11253 (define_insn "*ashl<mode>3_cmp"
11254 [(set (reg FLAGS_REG)
11256 (ashift:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
11257 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
11259 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
11260 (ashift:SWI (match_dup 1) (match_dup 2)))]
11261 "(optimize_function_for_size_p (cfun)
11262 || !TARGET_PARTIAL_FLAG_REG_STALL
11263 || (operands[2] == const1_rtx
11265 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
11266 && ix86_match_ccmode (insn, CCGOCmode)
11267 && ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
11269 switch (get_attr_type (insn))
11272 gcc_assert (operands[2] == const1_rtx);
11273 return "add{<imodesuffix>}\t%0, %0";
11276 if (operands[2] == const1_rtx
11277 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11278 return "sal{<imodesuffix>}\t%0";
11280 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
11283 [(set (attr "type")
11284 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
11285 (match_operand 0 "register_operand"))
11286 (match_operand 2 "const1_operand"))
11287 (const_string "alu")
11289 (const_string "ishift")))
11290 (set (attr "length_immediate")
11292 (ior (eq_attr "type" "alu")
11293 (and (eq_attr "type" "ishift")
11294 (and (match_operand 2 "const1_operand")
11295 (ior (match_test "TARGET_SHIFT1")
11296 (match_test "optimize_function_for_size_p (cfun)")))))
11298 (const_string "*")))
11299 (set_attr "mode" "<MODE>")])
11301 (define_insn "*ashlsi3_cmp_zext"
11302 [(set (reg FLAGS_REG)
11304 (ashift:SI (match_operand:SI 1 "register_operand" "0")
11305 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11307 (set (match_operand:DI 0 "register_operand" "=r")
11308 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
11310 && (optimize_function_for_size_p (cfun)
11311 || !TARGET_PARTIAL_FLAG_REG_STALL
11312 || (operands[2] == const1_rtx
11314 || TARGET_DOUBLE_WITH_ADD)))
11315 && ix86_match_ccmode (insn, CCGOCmode)
11316 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11318 switch (get_attr_type (insn))
11321 gcc_assert (operands[2] == const1_rtx);
11322 return "add{l}\t%k0, %k0";
11325 if (operands[2] == const1_rtx
11326 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11327 return "sal{l}\t%k0";
11329 return "sal{l}\t{%2, %k0|%k0, %2}";
11332 [(set (attr "type")
11333 (cond [(and (match_test "TARGET_DOUBLE_WITH_ADD")
11334 (match_operand 2 "const1_operand"))
11335 (const_string "alu")
11337 (const_string "ishift")))
11338 (set (attr "length_immediate")
11340 (ior (eq_attr "type" "alu")
11341 (and (eq_attr "type" "ishift")
11342 (and (match_operand 2 "const1_operand")
11343 (ior (match_test "TARGET_SHIFT1")
11344 (match_test "optimize_function_for_size_p (cfun)")))))
11346 (const_string "*")))
11347 (set_attr "mode" "SI")])
11349 (define_insn "*ashl<mode>3_cconly"
11350 [(set (reg FLAGS_REG)
11352 (ashift:SWI (match_operand:SWI 1 "register_operand" "0")
11353 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
11355 (clobber (match_scratch:SWI 0 "=<r>"))]
11356 "(optimize_function_for_size_p (cfun)
11357 || !TARGET_PARTIAL_FLAG_REG_STALL
11358 || (operands[2] == const1_rtx
11360 || TARGET_DOUBLE_WITH_ADD)))
11361 && ix86_match_ccmode (insn, CCGOCmode)"
11363 switch (get_attr_type (insn))
11366 gcc_assert (operands[2] == const1_rtx);
11367 return "add{<imodesuffix>}\t%0, %0";
11370 if (operands[2] == const1_rtx
11371 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11372 return "sal{<imodesuffix>}\t%0";
11374 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
11377 [(set (attr "type")
11378 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
11379 (match_operand 0 "register_operand"))
11380 (match_operand 2 "const1_operand"))
11381 (const_string "alu")
11383 (const_string "ishift")))
11384 (set (attr "length_immediate")
11386 (ior (eq_attr "type" "alu")
11387 (and (eq_attr "type" "ishift")
11388 (and (match_operand 2 "const1_operand")
11389 (ior (match_test "TARGET_SHIFT1")
11390 (match_test "optimize_function_for_size_p (cfun)")))))
11392 (const_string "*")))
11393 (set_attr "mode" "<MODE>")])
11395 ;; See comment above `ashl<mode>3' about how this works.
11397 (define_expand "<insn><mode>3"
11398 [(set (match_operand:SDWIM 0 "<shift_operand>")
11399 (any_shiftrt:SDWIM (match_operand:SDWIM 1 "<shift_operand>")
11400 (match_operand:QI 2 "nonmemory_operand")))]
11402 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
11404 ;; Avoid useless masking of count operand.
11405 (define_insn_and_split "*<insn><mode>3_mask"
11406 [(set (match_operand:SWI48 0 "nonimmediate_operand")
11408 (match_operand:SWI48 1 "nonimmediate_operand")
11411 (match_operand:SI 2 "register_operand" "c,r")
11412 (match_operand:SI 3 "const_int_operand")) 0)))
11413 (clobber (reg:CC FLAGS_REG))]
11414 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
11415 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
11416 == GET_MODE_BITSIZE (<MODE>mode)-1
11417 && ix86_pre_reload_split ()"
11421 [(set (match_dup 0)
11422 (any_shiftrt:SWI48 (match_dup 1)
11424 (clobber (reg:CC FLAGS_REG))])]
11425 "operands[2] = gen_lowpart (QImode, operands[2]);"
11426 [(set_attr "isa" "*,bmi2")])
11428 (define_insn_and_split "*<insn><mode>3_mask_1"
11429 [(set (match_operand:SWI48 0 "nonimmediate_operand")
11431 (match_operand:SWI48 1 "nonimmediate_operand")
11433 (match_operand:QI 2 "register_operand" "c,r")
11434 (match_operand:QI 3 "const_int_operand"))))
11435 (clobber (reg:CC FLAGS_REG))]
11436 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
11437 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
11438 == GET_MODE_BITSIZE (<MODE>mode)-1
11439 && ix86_pre_reload_split ()"
11443 [(set (match_dup 0)
11444 (any_shiftrt:SWI48 (match_dup 1)
11446 (clobber (reg:CC FLAGS_REG))])]
11448 [(set_attr "isa" "*,bmi2")])
11450 (define_insn_and_split "*<insn><dwi>3_doubleword_mask"
11451 [(set (match_operand:<DWI> 0 "register_operand")
11453 (match_operand:<DWI> 1 "register_operand")
11456 (match_operand:SI 2 "register_operand" "c")
11457 (match_operand:SI 3 "const_int_operand")) 0)))
11458 (clobber (reg:CC FLAGS_REG))]
11459 "(INTVAL (operands[3]) & (<MODE_SIZE> * BITS_PER_UNIT)) == 0
11460 && ix86_pre_reload_split ()"
11464 [(set (match_dup 4)
11465 (ior:DWIH (lshiftrt:DWIH (match_dup 4) (match_dup 2))
11466 (ashift:DWIH (match_dup 7)
11467 (minus:QI (match_dup 8) (match_dup 2)))))
11468 (clobber (reg:CC FLAGS_REG))])
11470 [(set (match_dup 6)
11471 (any_shiftrt:DWIH (match_dup 7) (match_dup 2)))
11472 (clobber (reg:CC FLAGS_REG))])]
11474 split_double_mode (<DWI>mode, &operands[0], 2, &operands[4], &operands[6]);
11476 operands[8] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT);
11478 if ((INTVAL (operands[3]) & ((<MODE_SIZE> * BITS_PER_UNIT) - 1))
11479 != ((<MODE_SIZE> * BITS_PER_UNIT) - 1))
11481 rtx tem = gen_reg_rtx (SImode);
11482 emit_insn (gen_andsi3 (tem, operands[2], operands[3]));
11486 operands[2] = gen_lowpart (QImode, operands[2]);
11488 if (!rtx_equal_p (operands[4], operands[5]))
11489 emit_move_insn (operands[4], operands[5]);
11492 (define_insn_and_split "*<insn><dwi>3_doubleword_mask_1"
11493 [(set (match_operand:<DWI> 0 "register_operand")
11495 (match_operand:<DWI> 1 "register_operand")
11497 (match_operand:QI 2 "register_operand" "c")
11498 (match_operand:QI 3 "const_int_operand"))))
11499 (clobber (reg:CC FLAGS_REG))]
11500 "(INTVAL (operands[3]) & (<MODE_SIZE> * BITS_PER_UNIT)) == 0
11501 && ix86_pre_reload_split ()"
11505 [(set (match_dup 4)
11506 (ior:DWIH (lshiftrt:DWIH (match_dup 4) (match_dup 2))
11507 (ashift:DWIH (match_dup 7)
11508 (minus:QI (match_dup 8) (match_dup 2)))))
11509 (clobber (reg:CC FLAGS_REG))])
11511 [(set (match_dup 6)
11512 (any_shiftrt:DWIH (match_dup 7) (match_dup 2)))
11513 (clobber (reg:CC FLAGS_REG))])]
11515 split_double_mode (<DWI>mode, &operands[0], 2, &operands[4], &operands[6]);
11517 operands[8] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT);
11519 if ((INTVAL (operands[3]) & ((<MODE_SIZE> * BITS_PER_UNIT) - 1))
11520 != ((<MODE_SIZE> * BITS_PER_UNIT) - 1))
11522 rtx tem = gen_reg_rtx (QImode);
11523 emit_insn (gen_andqi3 (tem, operands[2], operands[3]));
11527 if (!rtx_equal_p (operands[4], operands[5]))
11528 emit_move_insn (operands[4], operands[5]);
11531 (define_insn_and_split "*<insn><mode>3_doubleword"
11532 [(set (match_operand:DWI 0 "register_operand" "=&r")
11533 (any_shiftrt:DWI (match_operand:DWI 1 "register_operand" "0")
11534 (match_operand:QI 2 "nonmemory_operand" "<S>c")))
11535 (clobber (reg:CC FLAGS_REG))]
11538 "epilogue_completed"
11540 "ix86_split_<insn> (operands, NULL_RTX, <MODE>mode); DONE;"
11541 [(set_attr "type" "multi")])
11543 ;; By default we don't ask for a scratch register, because when DWImode
11544 ;; values are manipulated, registers are already at a premium. But if
11545 ;; we have one handy, we won't turn it away.
11548 [(match_scratch:DWIH 3 "r")
11549 (parallel [(set (match_operand:<DWI> 0 "register_operand")
11551 (match_operand:<DWI> 1 "register_operand")
11552 (match_operand:QI 2 "nonmemory_operand")))
11553 (clobber (reg:CC FLAGS_REG))])
11557 "ix86_split_<insn> (operands, operands[3], <DWI>mode); DONE;")
11559 (define_insn "x86_64_shrd"
11560 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
11561 (ior:DI (lshiftrt:DI (match_dup 0)
11562 (match_operand:QI 2 "nonmemory_operand" "Jc"))
11563 (ashift:DI (match_operand:DI 1 "register_operand" "r")
11564 (minus:QI (const_int 64) (match_dup 2)))))
11565 (clobber (reg:CC FLAGS_REG))]
11567 "shrd{q}\t{%s2%1, %0|%0, %1, %2}"
11568 [(set_attr "type" "ishift")
11569 (set_attr "prefix_0f" "1")
11570 (set_attr "mode" "DI")
11571 (set_attr "athlon_decode" "vector")
11572 (set_attr "amdfam10_decode" "vector")
11573 (set_attr "bdver1_decode" "vector")])
11575 (define_insn "x86_shrd"
11576 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
11577 (ior:SI (lshiftrt:SI (match_dup 0)
11578 (match_operand:QI 2 "nonmemory_operand" "Ic"))
11579 (ashift:SI (match_operand:SI 1 "register_operand" "r")
11580 (minus:QI (const_int 32) (match_dup 2)))))
11581 (clobber (reg:CC FLAGS_REG))]
11583 "shrd{l}\t{%s2%1, %0|%0, %1, %2}"
11584 [(set_attr "type" "ishift")
11585 (set_attr "prefix_0f" "1")
11586 (set_attr "mode" "SI")
11587 (set_attr "pent_pair" "np")
11588 (set_attr "athlon_decode" "vector")
11589 (set_attr "amdfam10_decode" "vector")
11590 (set_attr "bdver1_decode" "vector")])
11592 ;; Base name for insn mnemonic.
11593 (define_mode_attr cvt_mnemonic
11594 [(SI "{cltd|cdq}") (DI "{cqto|cqo}")])
11596 (define_insn "ashr<mode>3_cvt"
11597 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=*d,rm")
11599 (match_operand:SWI48 1 "nonimmediate_operand" "*a,0")
11600 (match_operand:QI 2 "const_int_operand")))
11601 (clobber (reg:CC FLAGS_REG))]
11602 "INTVAL (operands[2]) == GET_MODE_BITSIZE (<MODE>mode)-1
11603 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
11604 && ix86_binary_operator_ok (ASHIFTRT, <MODE>mode, operands)"
11607 sar{<imodesuffix>}\t{%2, %0|%0, %2}"
11608 [(set_attr "type" "imovx,ishift")
11609 (set_attr "prefix_0f" "0,*")
11610 (set_attr "length_immediate" "0,*")
11611 (set_attr "modrm" "0,1")
11612 (set_attr "mode" "<MODE>")])
11614 (define_insn "*ashrsi3_cvt_zext"
11615 [(set (match_operand:DI 0 "register_operand" "=*d,r")
11617 (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
11618 (match_operand:QI 2 "const_int_operand"))))
11619 (clobber (reg:CC FLAGS_REG))]
11620 "TARGET_64BIT && INTVAL (operands[2]) == 31
11621 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
11622 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11625 sar{l}\t{%2, %k0|%k0, %2}"
11626 [(set_attr "type" "imovx,ishift")
11627 (set_attr "prefix_0f" "0,*")
11628 (set_attr "length_immediate" "0,*")
11629 (set_attr "modrm" "0,1")
11630 (set_attr "mode" "SI")])
11632 (define_expand "@x86_shift<mode>_adj_3"
11633 [(use (match_operand:SWI48 0 "register_operand"))
11634 (use (match_operand:SWI48 1 "register_operand"))
11635 (use (match_operand:QI 2 "register_operand"))]
11638 rtx_code_label *label = gen_label_rtx ();
11641 emit_insn (gen_testqi_ccz_1 (operands[2],
11642 GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
11644 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
11645 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
11646 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
11647 gen_rtx_LABEL_REF (VOIDmode, label),
11649 tmp = emit_jump_insn (gen_rtx_SET (pc_rtx, tmp));
11650 JUMP_LABEL (tmp) = label;
11652 emit_move_insn (operands[0], operands[1]);
11653 emit_insn (gen_ashr<mode>3_cvt (operands[1], operands[1],
11654 GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1)));
11655 emit_label (label);
11656 LABEL_NUSES (label) = 1;
11661 (define_insn "*bmi2_<insn><mode>3_1"
11662 [(set (match_operand:SWI48 0 "register_operand" "=r")
11663 (any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11664 (match_operand:SWI48 2 "register_operand" "r")))]
11666 "<shift>x\t{%2, %1, %0|%0, %1, %2}"
11667 [(set_attr "type" "ishiftx")
11668 (set_attr "mode" "<MODE>")])
11670 (define_insn "*<insn><mode>3_1"
11671 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
11673 (match_operand:SWI48 1 "nonimmediate_operand" "0,rm")
11674 (match_operand:QI 2 "nonmemory_operand" "c<S>,r")))
11675 (clobber (reg:CC FLAGS_REG))]
11676 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
11678 switch (get_attr_type (insn))
11684 if (operands[2] == const1_rtx
11685 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11686 return "<shift>{<imodesuffix>}\t%0";
11688 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
11691 [(set_attr "isa" "*,bmi2")
11692 (set_attr "type" "ishift,ishiftx")
11693 (set (attr "length_immediate")
11695 (and (match_operand 2 "const1_operand")
11696 (ior (match_test "TARGET_SHIFT1")
11697 (match_test "optimize_function_for_size_p (cfun)")))
11699 (const_string "*")))
11700 (set_attr "mode" "<MODE>")])
11702 ;; Convert shift to the shiftx pattern to avoid flags dependency.
11704 [(set (match_operand:SWI48 0 "register_operand")
11705 (any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
11706 (match_operand:QI 2 "register_operand")))
11707 (clobber (reg:CC FLAGS_REG))]
11708 "TARGET_BMI2 && reload_completed"
11709 [(set (match_dup 0)
11710 (any_shiftrt:SWI48 (match_dup 1) (match_dup 2)))]
11711 "operands[2] = gen_lowpart (<MODE>mode, operands[2]);")
11713 (define_insn "*bmi2_<insn>si3_1_zext"
11714 [(set (match_operand:DI 0 "register_operand" "=r")
11716 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
11717 (match_operand:SI 2 "register_operand" "r"))))]
11718 "TARGET_64BIT && TARGET_BMI2"
11719 "<shift>x\t{%2, %1, %k0|%k0, %1, %2}"
11720 [(set_attr "type" "ishiftx")
11721 (set_attr "mode" "SI")])
11723 (define_insn "*<insn>si3_1_zext"
11724 [(set (match_operand:DI 0 "register_operand" "=r,r")
11726 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm")
11727 (match_operand:QI 2 "nonmemory_operand" "cI,r"))))
11728 (clobber (reg:CC FLAGS_REG))]
11729 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
11731 switch (get_attr_type (insn))
11737 if (operands[2] == const1_rtx
11738 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11739 return "<shift>{l}\t%k0";
11741 return "<shift>{l}\t{%2, %k0|%k0, %2}";
11744 [(set_attr "isa" "*,bmi2")
11745 (set_attr "type" "ishift,ishiftx")
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" "SI")])
11755 ;; Convert shift to the shiftx pattern to avoid flags dependency.
11757 [(set (match_operand:DI 0 "register_operand")
11759 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand")
11760 (match_operand:QI 2 "register_operand"))))
11761 (clobber (reg:CC FLAGS_REG))]
11762 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
11763 [(set (match_dup 0)
11764 (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
11765 "operands[2] = gen_lowpart (SImode, operands[2]);")
11767 (define_insn "*<insn><mode>3_1"
11768 [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m")
11770 (match_operand:SWI12 1 "nonimmediate_operand" "0")
11771 (match_operand:QI 2 "nonmemory_operand" "c<S>")))
11772 (clobber (reg:CC FLAGS_REG))]
11773 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
11775 if (operands[2] == const1_rtx
11776 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11777 return "<shift>{<imodesuffix>}\t%0";
11779 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
11781 [(set_attr "type" "ishift")
11782 (set (attr "length_immediate")
11784 (and (match_operand 2 "const1_operand")
11785 (ior (match_test "TARGET_SHIFT1")
11786 (match_test "optimize_function_for_size_p (cfun)")))
11788 (const_string "*")))
11789 (set_attr "mode" "<MODE>")])
11791 (define_insn "*<insn><mode>3_1_slp"
11792 [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>"))
11793 (any_shiftrt:SWI12 (match_operand:SWI12 1 "register_operand" "0")
11794 (match_operand:QI 2 "nonmemory_operand" "cI")))
11795 (clobber (reg:CC FLAGS_REG))]
11796 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
11797 /* FIXME: without this LRA can't reload this pattern, see PR82524. */
11798 && rtx_equal_p (operands[0], operands[1])"
11800 if (operands[2] == const1_rtx
11801 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11802 return "<shift>{<imodesuffix>}\t%0";
11804 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
11806 [(set_attr "type" "ishift")
11807 (set (attr "length_immediate")
11809 (and (match_operand 2 "const1_operand")
11810 (ior (match_test "TARGET_SHIFT1")
11811 (match_test "optimize_function_for_size_p (cfun)")))
11813 (const_string "*")))
11814 (set_attr "mode" "<MODE>")])
11816 ;; This pattern can't accept a variable shift count, since shifts by
11817 ;; zero don't affect the flags. We assume that shifts by constant
11818 ;; zero are optimized away.
11819 (define_insn "*<insn><mode>3_cmp"
11820 [(set (reg FLAGS_REG)
11823 (match_operand:SWI 1 "nonimmediate_operand" "0")
11824 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
11826 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
11827 (any_shiftrt:SWI (match_dup 1) (match_dup 2)))]
11828 "(optimize_function_for_size_p (cfun)
11829 || !TARGET_PARTIAL_FLAG_REG_STALL
11830 || (operands[2] == const1_rtx
11832 && ix86_match_ccmode (insn, CCGOCmode)
11833 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
11835 if (operands[2] == const1_rtx
11836 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11837 return "<shift>{<imodesuffix>}\t%0";
11839 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
11841 [(set_attr "type" "ishift")
11842 (set (attr "length_immediate")
11844 (and (match_operand 2 "const1_operand")
11845 (ior (match_test "TARGET_SHIFT1")
11846 (match_test "optimize_function_for_size_p (cfun)")))
11848 (const_string "*")))
11849 (set_attr "mode" "<MODE>")])
11851 (define_insn "*<insn>si3_cmp_zext"
11852 [(set (reg FLAGS_REG)
11854 (any_shiftrt:SI (match_operand:SI 1 "register_operand" "0")
11855 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11857 (set (match_operand:DI 0 "register_operand" "=r")
11858 (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
11860 && (optimize_function_for_size_p (cfun)
11861 || !TARGET_PARTIAL_FLAG_REG_STALL
11862 || (operands[2] == const1_rtx
11864 && ix86_match_ccmode (insn, CCGOCmode)
11865 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
11867 if (operands[2] == const1_rtx
11868 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11869 return "<shift>{l}\t%k0";
11871 return "<shift>{l}\t{%2, %k0|%k0, %2}";
11873 [(set_attr "type" "ishift")
11874 (set (attr "length_immediate")
11876 (and (match_operand 2 "const1_operand")
11877 (ior (match_test "TARGET_SHIFT1")
11878 (match_test "optimize_function_for_size_p (cfun)")))
11880 (const_string "*")))
11881 (set_attr "mode" "SI")])
11883 (define_insn "*<insn><mode>3_cconly"
11884 [(set (reg FLAGS_REG)
11887 (match_operand:SWI 1 "register_operand" "0")
11888 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
11890 (clobber (match_scratch:SWI 0 "=<r>"))]
11891 "(optimize_function_for_size_p (cfun)
11892 || !TARGET_PARTIAL_FLAG_REG_STALL
11893 || (operands[2] == const1_rtx
11895 && ix86_match_ccmode (insn, CCGOCmode)"
11897 if (operands[2] == const1_rtx
11898 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11899 return "<shift>{<imodesuffix>}\t%0";
11901 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
11903 [(set_attr "type" "ishift")
11904 (set (attr "length_immediate")
11906 (and (match_operand 2 "const1_operand")
11907 (ior (match_test "TARGET_SHIFT1")
11908 (match_test "optimize_function_for_size_p (cfun)")))
11910 (const_string "*")))
11911 (set_attr "mode" "<MODE>")])
11913 ;; Rotate instructions
11915 (define_expand "<insn>ti3"
11916 [(set (match_operand:TI 0 "register_operand")
11917 (any_rotate:TI (match_operand:TI 1 "register_operand")
11918 (match_operand:QI 2 "nonmemory_operand")))]
11921 if (const_1_to_63_operand (operands[2], VOIDmode))
11922 emit_insn (gen_ix86_<insn>ti3_doubleword
11923 (operands[0], operands[1], operands[2]));
11930 (define_expand "<insn>di3"
11931 [(set (match_operand:DI 0 "shiftdi_operand")
11932 (any_rotate:DI (match_operand:DI 1 "shiftdi_operand")
11933 (match_operand:QI 2 "nonmemory_operand")))]
11937 ix86_expand_binary_operator (<CODE>, DImode, operands);
11938 else if (const_1_to_31_operand (operands[2], VOIDmode))
11939 emit_insn (gen_ix86_<insn>di3_doubleword
11940 (operands[0], operands[1], operands[2]));
11947 (define_expand "<insn><mode>3"
11948 [(set (match_operand:SWIM124 0 "nonimmediate_operand")
11949 (any_rotate:SWIM124 (match_operand:SWIM124 1 "nonimmediate_operand")
11950 (match_operand:QI 2 "nonmemory_operand")))]
11952 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
11954 ;; Avoid useless masking of count operand.
11955 (define_insn_and_split "*<insn><mode>3_mask"
11956 [(set (match_operand:SWI48 0 "nonimmediate_operand")
11958 (match_operand:SWI48 1 "nonimmediate_operand")
11961 (match_operand:SI 2 "register_operand" "c")
11962 (match_operand:SI 3 "const_int_operand")) 0)))
11963 (clobber (reg:CC FLAGS_REG))]
11964 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
11965 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
11966 == GET_MODE_BITSIZE (<MODE>mode)-1
11967 && ix86_pre_reload_split ()"
11971 [(set (match_dup 0)
11972 (any_rotate:SWI48 (match_dup 1)
11974 (clobber (reg:CC FLAGS_REG))])]
11975 "operands[2] = gen_lowpart (QImode, operands[2]);")
11978 [(set (match_operand:SWI48 0 "register_operand")
11980 (match_operand:SWI48 1 "const_int_operand")
11983 (match_operand:SI 2 "register_operand")
11984 (match_operand:SI 3 "const_int_operand")) 0)))]
11985 "(INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode) - 1))
11986 == GET_MODE_BITSIZE (<MODE>mode) - 1"
11987 [(set (match_dup 4) (match_dup 1))
11989 (any_rotate:SWI48 (match_dup 4)
11990 (subreg:QI (match_dup 2) 0)))]
11991 "operands[4] = gen_reg_rtx (<MODE>mode);")
11993 (define_insn_and_split "*<insn><mode>3_mask_1"
11994 [(set (match_operand:SWI48 0 "nonimmediate_operand")
11996 (match_operand:SWI48 1 "nonimmediate_operand")
11998 (match_operand:QI 2 "register_operand" "c")
11999 (match_operand:QI 3 "const_int_operand"))))
12000 (clobber (reg:CC FLAGS_REG))]
12001 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
12002 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
12003 == GET_MODE_BITSIZE (<MODE>mode)-1
12004 && ix86_pre_reload_split ()"
12008 [(set (match_dup 0)
12009 (any_rotate:SWI48 (match_dup 1)
12011 (clobber (reg:CC FLAGS_REG))])])
12014 [(set (match_operand:SWI48 0 "register_operand")
12016 (match_operand:SWI48 1 "const_int_operand")
12018 (match_operand:QI 2 "register_operand")
12019 (match_operand:QI 3 "const_int_operand"))))]
12020 "(INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode) - 1))
12021 == GET_MODE_BITSIZE (<MODE>mode) - 1"
12022 [(set (match_dup 4) (match_dup 1))
12024 (any_rotate:SWI48 (match_dup 4) (match_dup 2)))]
12025 "operands[4] = gen_reg_rtx (<MODE>mode);")
12027 ;; Implement rotation using two double-precision
12028 ;; shift instructions and a scratch register.
12030 (define_insn_and_split "ix86_rotl<dwi>3_doubleword"
12031 [(set (match_operand:<DWI> 0 "register_operand" "=r")
12032 (rotate:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
12033 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
12034 (clobber (reg:CC FLAGS_REG))
12035 (clobber (match_scratch:DWIH 3 "=&r"))]
12039 [(set (match_dup 3) (match_dup 4))
12041 [(set (match_dup 4)
12042 (ior:DWIH (ashift:DWIH (match_dup 4) (match_dup 2))
12043 (lshiftrt:DWIH (match_dup 5)
12044 (minus:QI (match_dup 6) (match_dup 2)))))
12045 (clobber (reg:CC FLAGS_REG))])
12047 [(set (match_dup 5)
12048 (ior:DWIH (ashift:DWIH (match_dup 5) (match_dup 2))
12049 (lshiftrt:DWIH (match_dup 3)
12050 (minus:QI (match_dup 6) (match_dup 2)))))
12051 (clobber (reg:CC FLAGS_REG))])]
12053 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
12055 split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
12058 (define_insn_and_split "ix86_rotr<dwi>3_doubleword"
12059 [(set (match_operand:<DWI> 0 "register_operand" "=r")
12060 (rotatert:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
12061 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
12062 (clobber (reg:CC FLAGS_REG))
12063 (clobber (match_scratch:DWIH 3 "=&r"))]
12067 [(set (match_dup 3) (match_dup 4))
12069 [(set (match_dup 4)
12070 (ior:DWIH (lshiftrt:DWIH (match_dup 4) (match_dup 2))
12071 (ashift:DWIH (match_dup 5)
12072 (minus:QI (match_dup 6) (match_dup 2)))))
12073 (clobber (reg:CC FLAGS_REG))])
12075 [(set (match_dup 5)
12076 (ior:DWIH (lshiftrt:DWIH (match_dup 5) (match_dup 2))
12077 (ashift:DWIH (match_dup 3)
12078 (minus:QI (match_dup 6) (match_dup 2)))))
12079 (clobber (reg:CC FLAGS_REG))])]
12081 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
12083 split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
12086 (define_mode_attr rorx_immediate_operand
12087 [(SI "const_0_to_31_operand")
12088 (DI "const_0_to_63_operand")])
12090 (define_insn "*bmi2_rorx<mode>3_1"
12091 [(set (match_operand:SWI48 0 "register_operand" "=r")
12093 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12094 (match_operand:QI 2 "<rorx_immediate_operand>" "<S>")))]
12096 "rorx\t{%2, %1, %0|%0, %1, %2}"
12097 [(set_attr "type" "rotatex")
12098 (set_attr "mode" "<MODE>")])
12100 (define_insn "*<insn><mode>3_1"
12101 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
12103 (match_operand:SWI48 1 "nonimmediate_operand" "0,rm")
12104 (match_operand:QI 2 "nonmemory_operand" "c<S>,<S>")))
12105 (clobber (reg:CC FLAGS_REG))]
12106 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
12108 switch (get_attr_type (insn))
12114 if (operands[2] == const1_rtx
12115 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
12116 return "<rotate>{<imodesuffix>}\t%0";
12118 return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
12121 [(set_attr "isa" "*,bmi2")
12122 (set_attr "type" "rotate,rotatex")
12123 (set (attr "length_immediate")
12125 (and (eq_attr "type" "rotate")
12126 (and (match_operand 2 "const1_operand")
12127 (ior (match_test "TARGET_SHIFT1")
12128 (match_test "optimize_function_for_size_p (cfun)"))))
12130 (const_string "*")))
12131 (set_attr "mode" "<MODE>")])
12133 ;; Convert rotate to the rotatex pattern to avoid flags dependency.
12135 [(set (match_operand:SWI48 0 "register_operand")
12136 (rotate:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
12137 (match_operand:QI 2 "const_int_operand")))
12138 (clobber (reg:CC FLAGS_REG))]
12139 "TARGET_BMI2 && reload_completed"
12140 [(set (match_dup 0)
12141 (rotatert:SWI48 (match_dup 1) (match_dup 2)))]
12143 int bitsize = GET_MODE_BITSIZE (<MODE>mode);
12145 operands[2] = GEN_INT ((bitsize - INTVAL (operands[2])) % bitsize);
12149 [(set (match_operand:SWI48 0 "register_operand")
12150 (rotatert:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
12151 (match_operand:QI 2 "const_int_operand")))
12152 (clobber (reg:CC FLAGS_REG))]
12153 "TARGET_BMI2 && reload_completed"
12154 [(set (match_dup 0)
12155 (rotatert:SWI48 (match_dup 1) (match_dup 2)))])
12157 (define_insn "*bmi2_rorxsi3_1_zext"
12158 [(set (match_operand:DI 0 "register_operand" "=r")
12160 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
12161 (match_operand:QI 2 "const_0_to_31_operand" "I"))))]
12162 "TARGET_64BIT && TARGET_BMI2"
12163 "rorx\t{%2, %1, %k0|%k0, %1, %2}"
12164 [(set_attr "type" "rotatex")
12165 (set_attr "mode" "SI")])
12167 (define_insn "*<insn>si3_1_zext"
12168 [(set (match_operand:DI 0 "register_operand" "=r,r")
12170 (any_rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm")
12171 (match_operand:QI 2 "nonmemory_operand" "cI,I"))))
12172 (clobber (reg:CC FLAGS_REG))]
12173 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
12175 switch (get_attr_type (insn))
12181 if (operands[2] == const1_rtx
12182 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
12183 return "<rotate>{l}\t%k0";
12185 return "<rotate>{l}\t{%2, %k0|%k0, %2}";
12188 [(set_attr "isa" "*,bmi2")
12189 (set_attr "type" "rotate,rotatex")
12190 (set (attr "length_immediate")
12192 (and (eq_attr "type" "rotate")
12193 (and (match_operand 2 "const1_operand")
12194 (ior (match_test "TARGET_SHIFT1")
12195 (match_test "optimize_function_for_size_p (cfun)"))))
12197 (const_string "*")))
12198 (set_attr "mode" "SI")])
12200 ;; Convert rotate to the rotatex pattern to avoid flags dependency.
12202 [(set (match_operand:DI 0 "register_operand")
12204 (rotate:SI (match_operand:SI 1 "nonimmediate_operand")
12205 (match_operand:QI 2 "const_int_operand"))))
12206 (clobber (reg:CC FLAGS_REG))]
12207 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
12208 [(set (match_dup 0)
12209 (zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))]
12211 int bitsize = GET_MODE_BITSIZE (SImode);
12213 operands[2] = GEN_INT ((bitsize - INTVAL (operands[2])) % bitsize);
12217 [(set (match_operand:DI 0 "register_operand")
12219 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand")
12220 (match_operand:QI 2 "const_int_operand"))))
12221 (clobber (reg:CC FLAGS_REG))]
12222 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
12223 [(set (match_dup 0)
12224 (zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))])
12226 (define_insn "*<insn><mode>3_1"
12227 [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m")
12228 (any_rotate:SWI12 (match_operand:SWI12 1 "nonimmediate_operand" "0")
12229 (match_operand:QI 2 "nonmemory_operand" "c<S>")))
12230 (clobber (reg:CC FLAGS_REG))]
12231 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
12233 if (operands[2] == const1_rtx
12234 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
12235 return "<rotate>{<imodesuffix>}\t%0";
12237 return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
12239 [(set_attr "type" "rotate")
12240 (set (attr "length_immediate")
12242 (and (match_operand 2 "const1_operand")
12243 (ior (match_test "TARGET_SHIFT1")
12244 (match_test "optimize_function_for_size_p (cfun)")))
12246 (const_string "*")))
12247 (set_attr "mode" "<MODE>")])
12249 (define_insn "*<insn><mode>3_1_slp"
12250 [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>"))
12251 (any_rotate:SWI12 (match_operand:SWI12 1 "register_operand" "0")
12252 (match_operand:QI 2 "nonmemory_operand" "cI")))
12253 (clobber (reg:CC FLAGS_REG))]
12254 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
12255 /* FIXME: without this LRA can't reload this pattern, see PR82524. */
12256 && rtx_equal_p (operands[0], operands[1])"
12258 if (operands[2] == const1_rtx
12259 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
12260 return "<rotate>{<imodesuffix>}\t%0";
12262 return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
12264 [(set_attr "type" "rotate")
12265 (set (attr "length_immediate")
12267 (and (match_operand 2 "const1_operand")
12268 (ior (match_test "TARGET_SHIFT1")
12269 (match_test "optimize_function_for_size_p (cfun)")))
12271 (const_string "*")))
12272 (set_attr "mode" "<MODE>")])
12275 [(set (match_operand:HI 0 "QIreg_operand")
12276 (any_rotate:HI (match_dup 0) (const_int 8)))
12277 (clobber (reg:CC FLAGS_REG))]
12279 && (TARGET_USE_XCHGB || optimize_function_for_size_p (cfun))"
12280 [(parallel [(set (strict_low_part (match_dup 0))
12281 (bswap:HI (match_dup 0)))
12282 (clobber (reg:CC FLAGS_REG))])])
12284 ;; Bit set / bit test instructions
12286 ;; %%% bts, btr, btc
12288 ;; These instructions are *slow* when applied to memory.
12290 (define_code_attr btsc [(ior "bts") (xor "btc")])
12292 (define_insn "*<btsc><mode>"
12293 [(set (match_operand:SWI48 0 "register_operand" "=r")
12295 (ashift:SWI48 (const_int 1)
12296 (match_operand:QI 2 "register_operand" "r"))
12297 (match_operand:SWI48 1 "register_operand" "0")))
12298 (clobber (reg:CC FLAGS_REG))]
12300 "<btsc>{<imodesuffix>}\t{%<k>2, %0|%0, %<k>2}"
12301 [(set_attr "type" "alu1")
12302 (set_attr "prefix_0f" "1")
12303 (set_attr "znver1_decode" "double")
12304 (set_attr "mode" "<MODE>")])
12306 ;; Avoid useless masking of count operand.
12307 (define_insn_and_split "*<btsc><mode>_mask"
12308 [(set (match_operand:SWI48 0 "register_operand")
12314 (match_operand:SI 1 "register_operand")
12315 (match_operand:SI 2 "const_int_operand")) 0))
12316 (match_operand:SWI48 3 "register_operand")))
12317 (clobber (reg:CC FLAGS_REG))]
12319 && (INTVAL (operands[2]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
12320 == GET_MODE_BITSIZE (<MODE>mode)-1
12321 && ix86_pre_reload_split ()"
12325 [(set (match_dup 0)
12327 (ashift:SWI48 (const_int 1)
12330 (clobber (reg:CC FLAGS_REG))])]
12331 "operands[1] = gen_lowpart (QImode, operands[1]);")
12333 (define_insn_and_split "*<btsc><mode>_mask_1"
12334 [(set (match_operand:SWI48 0 "register_operand")
12339 (match_operand:QI 1 "register_operand")
12340 (match_operand:QI 2 "const_int_operand")))
12341 (match_operand:SWI48 3 "register_operand")))
12342 (clobber (reg:CC FLAGS_REG))]
12344 && (INTVAL (operands[2]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
12345 == GET_MODE_BITSIZE (<MODE>mode)-1
12346 && ix86_pre_reload_split ()"
12350 [(set (match_dup 0)
12352 (ashift:SWI48 (const_int 1)
12355 (clobber (reg:CC FLAGS_REG))])])
12357 (define_insn "*btr<mode>"
12358 [(set (match_operand:SWI48 0 "register_operand" "=r")
12360 (rotate:SWI48 (const_int -2)
12361 (match_operand:QI 2 "register_operand" "r"))
12362 (match_operand:SWI48 1 "register_operand" "0")))
12363 (clobber (reg:CC FLAGS_REG))]
12365 "btr{<imodesuffix>}\t{%<k>2, %0|%0, %<k>2}"
12366 [(set_attr "type" "alu1")
12367 (set_attr "prefix_0f" "1")
12368 (set_attr "znver1_decode" "double")
12369 (set_attr "mode" "<MODE>")])
12371 ;; Avoid useless masking of count operand.
12372 (define_insn_and_split "*btr<mode>_mask"
12373 [(set (match_operand:SWI48 0 "register_operand")
12379 (match_operand:SI 1 "register_operand")
12380 (match_operand:SI 2 "const_int_operand")) 0))
12381 (match_operand:SWI48 3 "register_operand")))
12382 (clobber (reg:CC FLAGS_REG))]
12384 && (INTVAL (operands[2]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
12385 == GET_MODE_BITSIZE (<MODE>mode)-1
12386 && ix86_pre_reload_split ()"
12390 [(set (match_dup 0)
12392 (rotate:SWI48 (const_int -2)
12395 (clobber (reg:CC FLAGS_REG))])]
12396 "operands[1] = gen_lowpart (QImode, operands[1]);")
12398 (define_insn_and_split "*btr<mode>_mask_1"
12399 [(set (match_operand:SWI48 0 "register_operand")
12404 (match_operand:QI 1 "register_operand")
12405 (match_operand:QI 2 "const_int_operand")))
12406 (match_operand:SWI48 3 "register_operand")))
12407 (clobber (reg:CC FLAGS_REG))]
12409 && (INTVAL (operands[2]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
12410 == GET_MODE_BITSIZE (<MODE>mode)-1
12411 && ix86_pre_reload_split ()"
12415 [(set (match_dup 0)
12417 (rotate:SWI48 (const_int -2)
12420 (clobber (reg:CC FLAGS_REG))])])
12422 (define_insn_and_split "*btr<mode>_1"
12423 [(set (match_operand:SWI12 0 "register_operand")
12426 (rotate:SI (const_int -2)
12427 (match_operand:QI 2 "register_operand")) 0)
12428 (match_operand:SWI12 1 "nonimmediate_operand")))
12429 (clobber (reg:CC FLAGS_REG))]
12430 "TARGET_USE_BT && ix86_pre_reload_split ()"
12434 [(set (match_dup 0)
12435 (and:SI (rotate:SI (const_int -2) (match_dup 2))
12437 (clobber (reg:CC FLAGS_REG))])]
12439 operands[0] = lowpart_subreg (SImode, operands[0], <MODE>mode);
12440 if (MEM_P (operands[1]))
12441 operands[1] = force_reg (<MODE>mode, operands[1]);
12442 operands[1] = lowpart_subreg (SImode, operands[1], <MODE>mode);
12445 (define_insn_and_split "*btr<mode>_2"
12446 [(set (zero_extract:HI
12447 (match_operand:SWI12 0 "nonimmediate_operand")
12449 (zero_extend:SI (match_operand:QI 1 "register_operand")))
12451 (clobber (reg:CC FLAGS_REG))]
12452 "TARGET_USE_BT && ix86_pre_reload_split ()"
12454 "&& MEM_P (operands[0])"
12455 [(set (match_dup 2) (match_dup 0))
12457 [(set (match_dup 3)
12458 (and:SI (rotate:SI (const_int -2) (match_dup 1))
12460 (clobber (reg:CC FLAGS_REG))])
12461 (set (match_dup 0) (match_dup 5))]
12463 operands[2] = gen_reg_rtx (<MODE>mode);
12464 operands[5] = gen_reg_rtx (<MODE>mode);
12465 operands[3] = lowpart_subreg (SImode, operands[5], <MODE>mode);
12466 operands[4] = lowpart_subreg (SImode, operands[2], <MODE>mode);
12470 [(set (zero_extract:HI
12471 (match_operand:SWI12 0 "register_operand")
12473 (zero_extend:SI (match_operand:QI 1 "register_operand")))
12475 (clobber (reg:CC FLAGS_REG))]
12476 "TARGET_USE_BT && ix86_pre_reload_split ()"
12478 [(set (match_dup 0)
12479 (and:SI (rotate:SI (const_int -2) (match_dup 1))
12481 (clobber (reg:CC FLAGS_REG))])]
12483 operands[2] = lowpart_subreg (SImode, operands[0], <MODE>mode);
12484 operands[0] = lowpart_subreg (SImode, operands[0], <MODE>mode);
12487 ;; These instructions are never faster than the corresponding
12488 ;; and/ior/xor operations when using immediate operand, so with
12489 ;; 32-bit there's no point. But in 64-bit, we can't hold the
12490 ;; relevant immediates within the instruction itself, so operating
12491 ;; on bits in the high 32-bits of a register becomes easier.
12493 ;; These are slow on Nocona, but fast on Athlon64. We do require the use
12494 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
12495 ;; negdf respectively, so they can never be disabled entirely.
12497 (define_insn "*btsq_imm"
12498 [(set (zero_extract:DI (match_operand:DI 0 "nonimmediate_operand" "+rm")
12500 (match_operand 1 "const_0_to_63_operand" "J"))
12502 (clobber (reg:CC FLAGS_REG))]
12503 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
12504 "bts{q}\t{%1, %0|%0, %1}"
12505 [(set_attr "type" "alu1")
12506 (set_attr "prefix_0f" "1")
12507 (set_attr "znver1_decode" "double")
12508 (set_attr "mode" "DI")])
12510 (define_insn "*btrq_imm"
12511 [(set (zero_extract:DI (match_operand:DI 0 "nonimmediate_operand" "+rm")
12513 (match_operand 1 "const_0_to_63_operand" "J"))
12515 (clobber (reg:CC FLAGS_REG))]
12516 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
12517 "btr{q}\t{%1, %0|%0, %1}"
12518 [(set_attr "type" "alu1")
12519 (set_attr "prefix_0f" "1")
12520 (set_attr "znver1_decode" "double")
12521 (set_attr "mode" "DI")])
12523 (define_insn "*btcq_imm"
12524 [(set (zero_extract:DI (match_operand:DI 0 "nonimmediate_operand" "+rm")
12526 (match_operand 1 "const_0_to_63_operand" "J"))
12527 (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
12528 (clobber (reg:CC FLAGS_REG))]
12529 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
12530 "btc{q}\t{%1, %0|%0, %1}"
12531 [(set_attr "type" "alu1")
12532 (set_attr "prefix_0f" "1")
12533 (set_attr "znver1_decode" "double")
12534 (set_attr "mode" "DI")])
12536 ;; Allow Nocona to avoid these instructions if a register is available.
12539 [(match_scratch:DI 2 "r")
12540 (parallel [(set (zero_extract:DI
12541 (match_operand:DI 0 "nonimmediate_operand")
12543 (match_operand 1 "const_0_to_63_operand"))
12545 (clobber (reg:CC FLAGS_REG))])]
12546 "TARGET_64BIT && !TARGET_USE_BT"
12547 [(parallel [(set (match_dup 0)
12548 (ior:DI (match_dup 0) (match_dup 3)))
12549 (clobber (reg:CC FLAGS_REG))])]
12551 int i = INTVAL (operands[1]);
12553 operands[3] = gen_int_mode (HOST_WIDE_INT_1U << i, DImode);
12555 if (!x86_64_immediate_operand (operands[3], DImode))
12557 emit_move_insn (operands[2], operands[3]);
12558 operands[3] = operands[2];
12563 [(match_scratch:DI 2 "r")
12564 (parallel [(set (zero_extract:DI
12565 (match_operand:DI 0 "nonimmediate_operand")
12567 (match_operand 1 "const_0_to_63_operand"))
12569 (clobber (reg:CC FLAGS_REG))])]
12570 "TARGET_64BIT && !TARGET_USE_BT"
12571 [(parallel [(set (match_dup 0)
12572 (and:DI (match_dup 0) (match_dup 3)))
12573 (clobber (reg:CC FLAGS_REG))])]
12575 int i = INTVAL (operands[1]);
12577 operands[3] = gen_int_mode (~(HOST_WIDE_INT_1U << i), DImode);
12579 if (!x86_64_immediate_operand (operands[3], DImode))
12581 emit_move_insn (operands[2], operands[3]);
12582 operands[3] = operands[2];
12587 [(match_scratch:DI 2 "r")
12588 (parallel [(set (zero_extract:DI
12589 (match_operand:DI 0 "nonimmediate_operand")
12591 (match_operand 1 "const_0_to_63_operand"))
12592 (not:DI (zero_extract:DI
12593 (match_dup 0) (const_int 1) (match_dup 1))))
12594 (clobber (reg:CC FLAGS_REG))])]
12595 "TARGET_64BIT && !TARGET_USE_BT"
12596 [(parallel [(set (match_dup 0)
12597 (xor:DI (match_dup 0) (match_dup 3)))
12598 (clobber (reg:CC FLAGS_REG))])]
12600 int i = INTVAL (operands[1]);
12602 operands[3] = gen_int_mode (HOST_WIDE_INT_1U << i, DImode);
12604 if (!x86_64_immediate_operand (operands[3], DImode))
12606 emit_move_insn (operands[2], operands[3]);
12607 operands[3] = operands[2];
12613 (define_insn "*bt<mode>"
12614 [(set (reg:CCC FLAGS_REG)
12616 (zero_extract:SWI48
12617 (match_operand:SWI48 0 "nonimmediate_operand" "r,m")
12619 (match_operand:SI 1 "nonmemory_operand" "r<S>,<S>"))
12623 switch (get_attr_mode (insn))
12626 return "bt{l}\t{%1, %k0|%k0, %1}";
12629 return "bt{q}\t{%q1, %0|%0, %q1}";
12632 gcc_unreachable ();
12635 [(set_attr "type" "alu1")
12636 (set_attr "prefix_0f" "1")
12639 (and (match_test "CONST_INT_P (operands[1])")
12640 (match_test "INTVAL (operands[1]) < 32"))
12641 (const_string "SI")
12642 (const_string "<MODE>")))])
12644 (define_insn_and_split "*jcc_bt<mode>"
12646 (if_then_else (match_operator 0 "bt_comparison_operator"
12647 [(zero_extract:SWI48
12648 (match_operand:SWI48 1 "nonimmediate_operand")
12650 (match_operand:SI 2 "nonmemory_operand"))
12652 (label_ref (match_operand 3))
12654 (clobber (reg:CC FLAGS_REG))]
12655 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
12656 && (CONST_INT_P (operands[2])
12657 ? (INTVAL (operands[2]) < GET_MODE_BITSIZE (<MODE>mode)
12658 && INTVAL (operands[2])
12659 >= (optimize_function_for_size_p (cfun) ? 8 : 32))
12660 : !memory_operand (operands[1], <MODE>mode))
12661 && ix86_pre_reload_split ()"
12664 [(set (reg:CCC FLAGS_REG)
12666 (zero_extract:SWI48
12672 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
12673 (label_ref (match_dup 3))
12676 operands[0] = shallow_copy_rtx (operands[0]);
12677 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
12680 (define_insn_and_split "*jcc_bt<mode>_1"
12682 (if_then_else (match_operator 0 "bt_comparison_operator"
12683 [(zero_extract:SWI48
12684 (match_operand:SWI48 1 "register_operand")
12687 (match_operand:QI 2 "register_operand")))
12689 (label_ref (match_operand 3))
12691 (clobber (reg:CC FLAGS_REG))]
12692 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
12693 && ix86_pre_reload_split ()"
12696 [(set (reg:CCC FLAGS_REG)
12698 (zero_extract:SWI48
12704 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
12705 (label_ref (match_dup 3))
12708 operands[2] = lowpart_subreg (SImode, operands[2], QImode);
12709 operands[0] = shallow_copy_rtx (operands[0]);
12710 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
12713 ;; Avoid useless masking of bit offset operand.
12714 (define_insn_and_split "*jcc_bt<mode>_mask"
12716 (if_then_else (match_operator 0 "bt_comparison_operator"
12717 [(zero_extract:SWI48
12718 (match_operand:SWI48 1 "register_operand")
12721 (match_operand:SI 2 "register_operand")
12722 (match_operand 3 "const_int_operand")))])
12723 (label_ref (match_operand 4))
12725 (clobber (reg:CC FLAGS_REG))]
12726 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
12727 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
12728 == GET_MODE_BITSIZE (<MODE>mode)-1
12729 && ix86_pre_reload_split ()"
12732 [(set (reg:CCC FLAGS_REG)
12734 (zero_extract:SWI48
12740 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
12741 (label_ref (match_dup 4))
12744 operands[0] = shallow_copy_rtx (operands[0]);
12745 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
12748 ;; Store-flag instructions.
12751 [(set (match_operand:QI 0 "nonimmediate_operand")
12752 (match_operator:QI 1 "add_comparison_operator"
12753 [(not:SWI (match_operand:SWI 2 "register_operand"))
12754 (match_operand:SWI 3 "nonimmediate_operand")]))]
12756 [(set (reg:CCC FLAGS_REG)
12758 (plus:SWI (match_dup 2) (match_dup 3))
12761 (match_op_dup 1 [(reg:CCC FLAGS_REG) (const_int 0)]))])
12764 [(set (match_operand:QI 0 "nonimmediate_operand")
12765 (match_operator:QI 1 "shr_comparison_operator"
12766 [(match_operand:DI 2 "register_operand")
12767 (match_operand 3 "const_int_operand")]))]
12769 && IN_RANGE (exact_log2 (UINTVAL (operands[3]) + 1), 32, 63)"
12770 [(set (reg:CCZ FLAGS_REG)
12772 (lshiftrt:DI (match_dup 2) (match_dup 4))
12775 (match_op_dup 1 [(reg:CCZ FLAGS_REG) (const_int 0)]))]
12777 enum rtx_code new_code;
12779 operands[1] = shallow_copy_rtx (operands[1]);
12780 switch (GET_CODE (operands[1]))
12782 case GTU: new_code = NE; break;
12783 case LEU: new_code = EQ; break;
12784 default: gcc_unreachable ();
12786 PUT_CODE (operands[1], new_code);
12788 operands[4] = GEN_INT (exact_log2 (UINTVAL (operands[3]) + 1));
12791 ;; For all sCOND expanders, also expand the compare or test insn that
12792 ;; generates cc0. Generate an equality comparison if `seq' or `sne'.
12794 (define_insn_and_split "*setcc_di_1"
12795 [(set (match_operand:DI 0 "register_operand" "=q")
12796 (match_operator:DI 1 "ix86_comparison_operator"
12797 [(reg FLAGS_REG) (const_int 0)]))]
12798 "TARGET_64BIT && !TARGET_PARTIAL_REG_STALL"
12800 "&& reload_completed"
12801 [(set (match_dup 2) (match_dup 1))
12802 (set (match_dup 0) (zero_extend:DI (match_dup 2)))]
12804 operands[1] = shallow_copy_rtx (operands[1]);
12805 PUT_MODE (operands[1], QImode);
12806 operands[2] = gen_lowpart (QImode, operands[0]);
12809 (define_insn_and_split "*setcc_<mode>_1_and"
12810 [(set (match_operand:SWI24 0 "register_operand" "=q")
12811 (match_operator:SWI24 1 "ix86_comparison_operator"
12812 [(reg FLAGS_REG) (const_int 0)]))
12813 (clobber (reg:CC FLAGS_REG))]
12814 "!TARGET_PARTIAL_REG_STALL
12815 && TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
12817 "&& reload_completed"
12818 [(set (match_dup 2) (match_dup 1))
12819 (parallel [(set (match_dup 0) (zero_extend:SWI24 (match_dup 2)))
12820 (clobber (reg:CC FLAGS_REG))])]
12822 operands[1] = shallow_copy_rtx (operands[1]);
12823 PUT_MODE (operands[1], QImode);
12824 operands[2] = gen_lowpart (QImode, operands[0]);
12827 (define_insn_and_split "*setcc_<mode>_1_movzbl"
12828 [(set (match_operand:SWI24 0 "register_operand" "=q")
12829 (match_operator:SWI24 1 "ix86_comparison_operator"
12830 [(reg FLAGS_REG) (const_int 0)]))]
12831 "!TARGET_PARTIAL_REG_STALL
12832 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
12834 "&& reload_completed"
12835 [(set (match_dup 2) (match_dup 1))
12836 (set (match_dup 0) (zero_extend:SWI24 (match_dup 2)))]
12838 operands[1] = shallow_copy_rtx (operands[1]);
12839 PUT_MODE (operands[1], QImode);
12840 operands[2] = gen_lowpart (QImode, operands[0]);
12843 (define_insn "*setcc_qi"
12844 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12845 (match_operator:QI 1 "ix86_comparison_operator"
12846 [(reg FLAGS_REG) (const_int 0)]))]
12849 [(set_attr "type" "setcc")
12850 (set_attr "mode" "QI")])
12852 (define_insn "*setcc_qi_slp"
12853 [(set (strict_low_part (match_operand:QI 0 "register_operand" "+q"))
12854 (match_operator:QI 1 "ix86_comparison_operator"
12855 [(reg FLAGS_REG) (const_int 0)]))]
12858 [(set_attr "type" "setcc")
12859 (set_attr "mode" "QI")])
12861 ;; In general it is not safe to assume too much about CCmode registers,
12862 ;; so simplify-rtx stops when it sees a second one. Under certain
12863 ;; conditions this is safe on x86, so help combine not create
12870 [(set (match_operand:QI 0 "nonimmediate_operand")
12871 (ne:QI (match_operator 1 "ix86_comparison_operator"
12872 [(reg FLAGS_REG) (const_int 0)])
12875 [(set (match_dup 0) (match_dup 1))]
12877 operands[1] = shallow_copy_rtx (operands[1]);
12878 PUT_MODE (operands[1], QImode);
12882 [(set (strict_low_part (match_operand:QI 0 "register_operand"))
12883 (ne:QI (match_operator 1 "ix86_comparison_operator"
12884 [(reg FLAGS_REG) (const_int 0)])
12887 [(set (match_dup 0) (match_dup 1))]
12889 operands[1] = shallow_copy_rtx (operands[1]);
12890 PUT_MODE (operands[1], QImode);
12894 [(set (match_operand:QI 0 "nonimmediate_operand")
12895 (eq:QI (match_operator 1 "ix86_comparison_operator"
12896 [(reg FLAGS_REG) (const_int 0)])
12899 [(set (match_dup 0) (match_dup 1))]
12901 operands[1] = shallow_copy_rtx (operands[1]);
12902 PUT_MODE (operands[1], QImode);
12903 PUT_CODE (operands[1],
12904 ix86_reverse_condition (GET_CODE (operands[1]),
12905 GET_MODE (XEXP (operands[1], 0))));
12907 /* Make sure that (a) the CCmode we have for the flags is strong
12908 enough for the reversed compare or (b) we have a valid FP compare. */
12909 if (! ix86_comparison_operator (operands[1], VOIDmode))
12914 [(set (strict_low_part (match_operand:QI 0 "register_operand"))
12915 (eq:QI (match_operator 1 "ix86_comparison_operator"
12916 [(reg FLAGS_REG) (const_int 0)])
12919 [(set (match_dup 0) (match_dup 1))]
12921 operands[1] = shallow_copy_rtx (operands[1]);
12922 PUT_MODE (operands[1], QImode);
12923 PUT_CODE (operands[1],
12924 ix86_reverse_condition (GET_CODE (operands[1]),
12925 GET_MODE (XEXP (operands[1], 0))));
12927 /* Make sure that (a) the CCmode we have for the flags is strong
12928 enough for the reversed compare or (b) we have a valid FP compare. */
12929 if (! ix86_comparison_operator (operands[1], VOIDmode))
12933 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
12934 ;; subsequent logical operations are used to imitate conditional moves.
12935 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
12938 (define_insn "setcc_<mode>_sse"
12939 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
12940 (match_operator:MODEF 3 "sse_comparison_operator"
12941 [(match_operand:MODEF 1 "register_operand" "0,x")
12942 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
12943 "SSE_FLOAT_MODE_P (<MODE>mode)"
12945 cmp%D3<ssemodesuffix>\t{%2, %0|%0, %2}
12946 vcmp%D3<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
12947 [(set_attr "isa" "noavx,avx")
12948 (set_attr "type" "ssecmp")
12949 (set_attr "length_immediate" "1")
12950 (set_attr "prefix" "orig,vex")
12951 (set_attr "mode" "<MODE>")])
12953 ;; Basic conditional jump instructions.
12958 (match_operator 1 "add_comparison_operator"
12959 [(not:SWI (match_operand:SWI 2 "register_operand"))
12960 (match_operand:SWI 3 "nonimmediate_operand")])
12961 (label_ref (match_operand 0))
12964 [(set (reg:CCC FLAGS_REG)
12966 (plus:SWI (match_dup 2) (match_dup 3))
12969 (if_then_else (match_op_dup 1 [(reg:CCC FLAGS_REG) (const_int 0)])
12970 (label_ref (match_operand 0))
12976 (match_operator 1 "shr_comparison_operator"
12977 [(match_operand:DI 2 "register_operand")
12978 (match_operand 3 "const_int_operand")])
12979 (label_ref (match_operand 0))
12982 && IN_RANGE (exact_log2 (UINTVAL (operands[3]) + 1), 32, 63)"
12983 [(set (reg:CCZ FLAGS_REG)
12985 (lshiftrt:DI (match_dup 2) (match_dup 4))
12988 (if_then_else (match_op_dup 1 [(reg:CCZ FLAGS_REG) (const_int 0)])
12989 (label_ref (match_operand 0))
12992 enum rtx_code new_code;
12994 operands[1] = shallow_copy_rtx (operands[1]);
12995 switch (GET_CODE (operands[1]))
12997 case GTU: new_code = NE; break;
12998 case LEU: new_code = EQ; break;
12999 default: gcc_unreachable ();
13001 PUT_CODE (operands[1], new_code);
13003 operands[4] = GEN_INT (exact_log2 (UINTVAL (operands[3]) + 1));
13006 ;; We ignore the overflow flag for signed branch instructions.
13008 (define_insn "*jcc"
13010 (if_then_else (match_operator 1 "ix86_comparison_operator"
13011 [(reg FLAGS_REG) (const_int 0)])
13012 (label_ref (match_operand 0))
13016 [(set_attr "type" "ibr")
13017 (set_attr "modrm" "0")
13018 (set (attr "length")
13020 (and (ge (minus (match_dup 0) (pc))
13022 (lt (minus (match_dup 0) (pc))
13027 ;; In general it is not safe to assume too much about CCmode registers,
13028 ;; so simplify-rtx stops when it sees a second one. Under certain
13029 ;; conditions this is safe on x86, so help combine not create
13037 (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
13038 [(reg FLAGS_REG) (const_int 0)])
13040 (label_ref (match_operand 1))
13044 (if_then_else (match_dup 0)
13045 (label_ref (match_dup 1))
13048 operands[0] = shallow_copy_rtx (operands[0]);
13049 PUT_MODE (operands[0], VOIDmode);
13054 (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
13055 [(reg FLAGS_REG) (const_int 0)])
13057 (label_ref (match_operand 1))
13061 (if_then_else (match_dup 0)
13062 (label_ref (match_dup 1))
13065 operands[0] = shallow_copy_rtx (operands[0]);
13066 PUT_MODE (operands[0], VOIDmode);
13067 PUT_CODE (operands[0],
13068 ix86_reverse_condition (GET_CODE (operands[0]),
13069 GET_MODE (XEXP (operands[0], 0))));
13071 /* Make sure that (a) the CCmode we have for the flags is strong
13072 enough for the reversed compare or (b) we have a valid FP compare. */
13073 if (! ix86_comparison_operator (operands[0], VOIDmode))
13077 ;; Unconditional and other jump instructions
13079 (define_insn "jump"
13081 (label_ref (match_operand 0)))]
13084 [(set_attr "type" "ibr")
13085 (set_attr "modrm" "0")
13086 (set (attr "length")
13088 (and (ge (minus (match_dup 0) (pc))
13090 (lt (minus (match_dup 0) (pc))
13095 (define_expand "indirect_jump"
13096 [(set (pc) (match_operand 0 "indirect_branch_operand"))]
13099 if (TARGET_X32 || TARGET_INDIRECT_BRANCH_REGISTER)
13100 operands[0] = convert_memory_address (word_mode, operands[0]);
13101 cfun->machine->has_local_indirect_jump = true;
13104 (define_insn "*indirect_jump"
13105 [(set (pc) (match_operand:W 0 "indirect_branch_operand" "rBw"))]
13107 "* return ix86_output_indirect_jmp (operands[0]);"
13108 [(set (attr "type")
13109 (if_then_else (match_test "(cfun->machine->indirect_branch_type
13110 != indirect_branch_keep)")
13111 (const_string "multi")
13112 (const_string "ibr")))
13113 (set_attr "length_immediate" "0")])
13115 (define_expand "tablejump"
13116 [(parallel [(set (pc) (match_operand 0 "indirect_branch_operand"))
13117 (use (label_ref (match_operand 1)))])]
13120 /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
13121 relative. Convert the relative address to an absolute address. */
13125 enum rtx_code code;
13127 /* We can't use @GOTOFF for text labels on VxWorks;
13128 see gotoff_operand. */
13129 if (TARGET_64BIT || TARGET_VXWORKS_RTP)
13133 op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
13135 else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
13139 op1 = pic_offset_table_rtx;
13144 op0 = pic_offset_table_rtx;
13148 operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
13152 if (TARGET_X32 || TARGET_INDIRECT_BRANCH_REGISTER)
13153 operands[0] = convert_memory_address (word_mode, operands[0]);
13154 cfun->machine->has_local_indirect_jump = true;
13157 (define_insn "*tablejump_1"
13158 [(set (pc) (match_operand:W 0 "indirect_branch_operand" "rBw"))
13159 (use (label_ref (match_operand 1)))]
13161 "* return ix86_output_indirect_jmp (operands[0]);"
13162 [(set (attr "type")
13163 (if_then_else (match_test "(cfun->machine->indirect_branch_type
13164 != indirect_branch_keep)")
13165 (const_string "multi")
13166 (const_string "ibr")))
13167 (set_attr "length_immediate" "0")])
13169 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
13172 [(set (reg FLAGS_REG) (match_operand 0))
13173 (set (match_operand:QI 1 "register_operand")
13174 (match_operator:QI 2 "ix86_comparison_operator"
13175 [(reg FLAGS_REG) (const_int 0)]))
13176 (set (match_operand 3 "any_QIreg_operand")
13177 (zero_extend (match_dup 1)))]
13178 "(peep2_reg_dead_p (3, operands[1])
13179 || operands_match_p (operands[1], operands[3]))
13180 && ! reg_overlap_mentioned_p (operands[3], operands[0])
13181 && peep2_regno_dead_p (0, FLAGS_REG)"
13182 [(set (match_dup 4) (match_dup 0))
13183 (set (strict_low_part (match_dup 5))
13186 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
13187 operands[5] = gen_lowpart (QImode, operands[3]);
13188 ix86_expand_clear (operands[3]);
13192 [(parallel [(set (reg FLAGS_REG) (match_operand 0))
13193 (match_operand 4)])
13194 (set (match_operand:QI 1 "register_operand")
13195 (match_operator:QI 2 "ix86_comparison_operator"
13196 [(reg FLAGS_REG) (const_int 0)]))
13197 (set (match_operand 3 "any_QIreg_operand")
13198 (zero_extend (match_dup 1)))]
13199 "(peep2_reg_dead_p (3, operands[1])
13200 || operands_match_p (operands[1], operands[3]))
13201 && ! reg_overlap_mentioned_p (operands[3], operands[0])
13202 && ! reg_overlap_mentioned_p (operands[3], operands[4])
13203 && ! reg_set_p (operands[3], operands[4])
13204 && peep2_regno_dead_p (0, FLAGS_REG)"
13205 [(parallel [(set (match_dup 5) (match_dup 0))
13207 (set (strict_low_part (match_dup 6))
13210 operands[5] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
13211 operands[6] = gen_lowpart (QImode, operands[3]);
13212 ix86_expand_clear (operands[3]);
13216 [(set (reg FLAGS_REG) (match_operand 0))
13217 (parallel [(set (reg FLAGS_REG) (match_operand 1))
13218 (match_operand 5)])
13219 (set (match_operand:QI 2 "register_operand")
13220 (match_operator:QI 3 "ix86_comparison_operator"
13221 [(reg FLAGS_REG) (const_int 0)]))
13222 (set (match_operand 4 "any_QIreg_operand")
13223 (zero_extend (match_dup 2)))]
13224 "(peep2_reg_dead_p (4, operands[2])
13225 || operands_match_p (operands[2], operands[4]))
13226 && ! reg_overlap_mentioned_p (operands[4], operands[0])
13227 && ! reg_overlap_mentioned_p (operands[4], operands[1])
13228 && ! reg_overlap_mentioned_p (operands[4], operands[5])
13229 && ! reg_set_p (operands[4], operands[5])
13230 && refers_to_regno_p (FLAGS_REG, operands[1], (rtx *)NULL)
13231 && peep2_regno_dead_p (0, FLAGS_REG)"
13232 [(set (match_dup 6) (match_dup 0))
13233 (parallel [(set (match_dup 7) (match_dup 1))
13235 (set (strict_low_part (match_dup 8))
13238 operands[6] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
13239 operands[7] = gen_rtx_REG (GET_MODE (operands[1]), FLAGS_REG);
13240 operands[8] = gen_lowpart (QImode, operands[4]);
13241 ix86_expand_clear (operands[4]);
13244 ;; Similar, but match zero extend with andsi3.
13247 [(set (reg FLAGS_REG) (match_operand 0))
13248 (set (match_operand:QI 1 "register_operand")
13249 (match_operator:QI 2 "ix86_comparison_operator"
13250 [(reg FLAGS_REG) (const_int 0)]))
13251 (parallel [(set (match_operand:SI 3 "any_QIreg_operand")
13252 (and:SI (match_dup 3) (const_int 255)))
13253 (clobber (reg:CC FLAGS_REG))])]
13254 "REGNO (operands[1]) == REGNO (operands[3])
13255 && ! reg_overlap_mentioned_p (operands[3], operands[0])
13256 && peep2_regno_dead_p (0, FLAGS_REG)"
13257 [(set (match_dup 4) (match_dup 0))
13258 (set (strict_low_part (match_dup 5))
13261 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
13262 operands[5] = gen_lowpart (QImode, operands[3]);
13263 ix86_expand_clear (operands[3]);
13267 [(parallel [(set (reg FLAGS_REG) (match_operand 0))
13268 (match_operand 4)])
13269 (set (match_operand:QI 1 "register_operand")
13270 (match_operator:QI 2 "ix86_comparison_operator"
13271 [(reg FLAGS_REG) (const_int 0)]))
13272 (parallel [(set (match_operand 3 "any_QIreg_operand")
13273 (zero_extend (match_dup 1)))
13274 (clobber (reg:CC FLAGS_REG))])]
13275 "(peep2_reg_dead_p (3, operands[1])
13276 || operands_match_p (operands[1], operands[3]))
13277 && ! reg_overlap_mentioned_p (operands[3], operands[0])
13278 && ! reg_overlap_mentioned_p (operands[3], operands[4])
13279 && ! reg_set_p (operands[3], operands[4])
13280 && peep2_regno_dead_p (0, FLAGS_REG)"
13281 [(parallel [(set (match_dup 5) (match_dup 0))
13283 (set (strict_low_part (match_dup 6))
13286 operands[5] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
13287 operands[6] = gen_lowpart (QImode, operands[3]);
13288 ix86_expand_clear (operands[3]);
13292 [(set (reg FLAGS_REG) (match_operand 0))
13293 (parallel [(set (reg FLAGS_REG) (match_operand 1))
13294 (match_operand 5)])
13295 (set (match_operand:QI 2 "register_operand")
13296 (match_operator:QI 3 "ix86_comparison_operator"
13297 [(reg FLAGS_REG) (const_int 0)]))
13298 (parallel [(set (match_operand 4 "any_QIreg_operand")
13299 (zero_extend (match_dup 2)))
13300 (clobber (reg:CC FLAGS_REG))])]
13301 "(peep2_reg_dead_p (4, operands[2])
13302 || operands_match_p (operands[2], operands[4]))
13303 && ! reg_overlap_mentioned_p (operands[4], operands[0])
13304 && ! reg_overlap_mentioned_p (operands[4], operands[1])
13305 && ! reg_overlap_mentioned_p (operands[4], operands[5])
13306 && ! reg_set_p (operands[4], operands[5])
13307 && refers_to_regno_p (FLAGS_REG, operands[1], (rtx *)NULL)
13308 && peep2_regno_dead_p (0, FLAGS_REG)"
13309 [(set (match_dup 6) (match_dup 0))
13310 (parallel [(set (match_dup 7) (match_dup 1))
13312 (set (strict_low_part (match_dup 8))
13315 operands[6] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
13316 operands[7] = gen_rtx_REG (GET_MODE (operands[1]), FLAGS_REG);
13317 operands[8] = gen_lowpart (QImode, operands[4]);
13318 ix86_expand_clear (operands[4]);
13321 ;; Call instructions.
13323 ;; The predicates normally associated with named expanders are not properly
13324 ;; checked for calls. This is a bug in the generic code, but it isn't that
13325 ;; easy to fix. Ignore it for now and be prepared to fix things up.
13327 ;; P6 processors will jump to the address after the decrement when %esp
13328 ;; is used as a call operand, so they will execute return address as a code.
13329 ;; See Pentium Pro errata 70, Pentium 2 errata A33 and Pentium 3 errata E17.
13331 ;; Register constraint for call instruction.
13332 (define_mode_attr c [(SI "l") (DI "r")])
13334 ;; Call subroutine returning no value.
13336 (define_expand "call"
13337 [(call (match_operand:QI 0)
13339 (use (match_operand 2))]
13342 ix86_expand_call (NULL, operands[0], operands[1],
13343 operands[2], NULL, false);
13347 (define_expand "sibcall"
13348 [(call (match_operand:QI 0)
13350 (use (match_operand 2))]
13353 ix86_expand_call (NULL, operands[0], operands[1],
13354 operands[2], NULL, true);
13358 (define_insn "*call"
13359 [(call (mem:QI (match_operand:W 0 "call_insn_operand" "<c>BwBz"))
13360 (match_operand 1))]
13361 "!SIBLING_CALL_P (insn)"
13362 "* return ix86_output_call_insn (insn, operands[0]);"
13363 [(set_attr "type" "call")])
13365 ;; This covers both call and sibcall since only GOT slot is allowed.
13366 (define_insn "*call_got_x32"
13367 [(call (mem:QI (zero_extend:DI
13368 (match_operand:SI 0 "GOT_memory_operand" "Bg")))
13369 (match_operand 1))]
13372 rtx fnaddr = gen_const_mem (DImode, XEXP (operands[0], 0));
13373 return ix86_output_call_insn (insn, fnaddr);
13375 [(set_attr "type" "call")])
13377 ;; Since sibcall never returns, we can only use call-clobbered register
13379 (define_insn "*sibcall_GOT_32"
13382 (match_operand:SI 0 "register_no_elim_operand" "U")
13383 (match_operand:SI 1 "GOT32_symbol_operand"))))
13384 (match_operand 2))]
13387 && !TARGET_INDIRECT_BRANCH_REGISTER
13388 && SIBLING_CALL_P (insn)"
13390 rtx fnaddr = gen_rtx_PLUS (SImode, operands[0], operands[1]);
13391 fnaddr = gen_const_mem (SImode, fnaddr);
13392 return ix86_output_call_insn (insn, fnaddr);
13394 [(set_attr "type" "call")])
13396 (define_insn "*sibcall"
13397 [(call (mem:QI (match_operand:W 0 "sibcall_insn_operand" "UBsBz"))
13398 (match_operand 1))]
13399 "SIBLING_CALL_P (insn)"
13400 "* return ix86_output_call_insn (insn, operands[0]);"
13401 [(set_attr "type" "call")])
13403 (define_insn "*sibcall_memory"
13404 [(call (mem:QI (match_operand:W 0 "memory_operand" "m"))
13406 (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
13407 "!TARGET_X32 && !TARGET_INDIRECT_BRANCH_REGISTER"
13408 "* return ix86_output_call_insn (insn, operands[0]);"
13409 [(set_attr "type" "call")])
13412 [(set (match_operand:W 0 "register_operand")
13413 (match_operand:W 1 "memory_operand"))
13414 (call (mem:QI (match_dup 0))
13415 (match_operand 3))]
13417 && !TARGET_INDIRECT_BRANCH_REGISTER
13418 && SIBLING_CALL_P (peep2_next_insn (1))
13419 && !reg_mentioned_p (operands[0],
13420 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (1)))"
13421 [(parallel [(call (mem:QI (match_dup 1))
13423 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
13426 [(set (match_operand:W 0 "register_operand")
13427 (match_operand:W 1 "memory_operand"))
13428 (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
13429 (call (mem:QI (match_dup 0))
13430 (match_operand 3))]
13432 && !TARGET_INDIRECT_BRANCH_REGISTER
13433 && SIBLING_CALL_P (peep2_next_insn (2))
13434 && !reg_mentioned_p (operands[0],
13435 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (2)))"
13436 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
13437 (parallel [(call (mem:QI (match_dup 1))
13439 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
13441 (define_expand "call_pop"
13442 [(parallel [(call (match_operand:QI 0)
13443 (match_operand:SI 1))
13444 (set (reg:SI SP_REG)
13445 (plus:SI (reg:SI SP_REG)
13446 (match_operand:SI 3)))])]
13449 ix86_expand_call (NULL, operands[0], operands[1],
13450 operands[2], operands[3], false);
13454 (define_insn "*call_pop"
13455 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lBwBz"))
13457 (set (reg:SI SP_REG)
13458 (plus:SI (reg:SI SP_REG)
13459 (match_operand:SI 2 "immediate_operand" "i")))]
13460 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
13461 "* return ix86_output_call_insn (insn, operands[0]);"
13462 [(set_attr "type" "call")])
13464 (define_insn "*sibcall_pop"
13465 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "UBsBz"))
13467 (set (reg:SI SP_REG)
13468 (plus:SI (reg:SI SP_REG)
13469 (match_operand:SI 2 "immediate_operand" "i")))]
13470 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
13471 "* return ix86_output_call_insn (insn, operands[0]);"
13472 [(set_attr "type" "call")])
13474 (define_insn "*sibcall_pop_memory"
13475 [(call (mem:QI (match_operand:SI 0 "memory_operand" "Bs"))
13477 (set (reg:SI SP_REG)
13478 (plus:SI (reg:SI SP_REG)
13479 (match_operand:SI 2 "immediate_operand" "i")))
13480 (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
13482 "* return ix86_output_call_insn (insn, operands[0]);"
13483 [(set_attr "type" "call")])
13486 [(set (match_operand:SI 0 "register_operand")
13487 (match_operand:SI 1 "memory_operand"))
13488 (parallel [(call (mem:QI (match_dup 0))
13490 (set (reg:SI SP_REG)
13491 (plus:SI (reg:SI SP_REG)
13492 (match_operand:SI 4 "immediate_operand")))])]
13493 "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (1))
13494 && !reg_mentioned_p (operands[0],
13495 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (1)))"
13496 [(parallel [(call (mem:QI (match_dup 1))
13498 (set (reg:SI SP_REG)
13499 (plus:SI (reg:SI SP_REG)
13501 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
13504 [(set (match_operand:SI 0 "register_operand")
13505 (match_operand:SI 1 "memory_operand"))
13506 (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
13507 (parallel [(call (mem:QI (match_dup 0))
13509 (set (reg:SI SP_REG)
13510 (plus:SI (reg:SI SP_REG)
13511 (match_operand:SI 4 "immediate_operand")))])]
13512 "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (2))
13513 && !reg_mentioned_p (operands[0],
13514 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (2)))"
13515 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
13516 (parallel [(call (mem:QI (match_dup 1))
13518 (set (reg:SI SP_REG)
13519 (plus:SI (reg:SI SP_REG)
13521 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
13523 ;; Combining simple memory jump instruction
13526 [(set (match_operand:W 0 "register_operand")
13527 (match_operand:W 1 "memory_operand"))
13528 (set (pc) (match_dup 0))]
13530 && !TARGET_INDIRECT_BRANCH_REGISTER
13531 && peep2_reg_dead_p (2, operands[0])"
13532 [(set (pc) (match_dup 1))])
13534 ;; Call subroutine, returning value in operand 0
13536 (define_expand "call_value"
13537 [(set (match_operand 0)
13538 (call (match_operand:QI 1)
13539 (match_operand 2)))
13540 (use (match_operand 3))]
13543 ix86_expand_call (operands[0], operands[1], operands[2],
13544 operands[3], NULL, false);
13548 (define_expand "sibcall_value"
13549 [(set (match_operand 0)
13550 (call (match_operand:QI 1)
13551 (match_operand 2)))
13552 (use (match_operand 3))]
13555 ix86_expand_call (operands[0], operands[1], operands[2],
13556 operands[3], NULL, true);
13560 (define_insn "*call_value"
13561 [(set (match_operand 0)
13562 (call (mem:QI (match_operand:W 1 "call_insn_operand" "<c>BwBz"))
13563 (match_operand 2)))]
13564 "!SIBLING_CALL_P (insn)"
13565 "* return ix86_output_call_insn (insn, operands[1]);"
13566 [(set_attr "type" "callv")])
13568 ;; This covers both call and sibcall since only GOT slot is allowed.
13569 (define_insn "*call_value_got_x32"
13570 [(set (match_operand 0)
13573 (match_operand:SI 1 "GOT_memory_operand" "Bg")))
13574 (match_operand 2)))]
13577 rtx fnaddr = gen_const_mem (DImode, XEXP (operands[1], 0));
13578 return ix86_output_call_insn (insn, fnaddr);
13580 [(set_attr "type" "callv")])
13582 ;; Since sibcall never returns, we can only use call-clobbered register
13584 (define_insn "*sibcall_value_GOT_32"
13585 [(set (match_operand 0)
13588 (match_operand:SI 1 "register_no_elim_operand" "U")
13589 (match_operand:SI 2 "GOT32_symbol_operand"))))
13590 (match_operand 3)))]
13593 && !TARGET_INDIRECT_BRANCH_REGISTER
13594 && SIBLING_CALL_P (insn)"
13596 rtx fnaddr = gen_rtx_PLUS (SImode, operands[1], operands[2]);
13597 fnaddr = gen_const_mem (SImode, fnaddr);
13598 return ix86_output_call_insn (insn, fnaddr);
13600 [(set_attr "type" "callv")])
13602 (define_insn "*sibcall_value"
13603 [(set (match_operand 0)
13604 (call (mem:QI (match_operand:W 1 "sibcall_insn_operand" "UBsBz"))
13605 (match_operand 2)))]
13606 "SIBLING_CALL_P (insn)"
13607 "* return ix86_output_call_insn (insn, operands[1]);"
13608 [(set_attr "type" "callv")])
13610 (define_insn "*sibcall_value_memory"
13611 [(set (match_operand 0)
13612 (call (mem:QI (match_operand:W 1 "memory_operand" "m"))
13613 (match_operand 2)))
13614 (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
13615 "!TARGET_X32 && !TARGET_INDIRECT_BRANCH_REGISTER"
13616 "* return ix86_output_call_insn (insn, operands[1]);"
13617 [(set_attr "type" "callv")])
13620 [(set (match_operand:W 0 "register_operand")
13621 (match_operand:W 1 "memory_operand"))
13622 (set (match_operand 2)
13623 (call (mem:QI (match_dup 0))
13624 (match_operand 3)))]
13626 && !TARGET_INDIRECT_BRANCH_REGISTER
13627 && SIBLING_CALL_P (peep2_next_insn (1))
13628 && !reg_mentioned_p (operands[0],
13629 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (1)))"
13630 [(parallel [(set (match_dup 2)
13631 (call (mem:QI (match_dup 1))
13633 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
13636 [(set (match_operand:W 0 "register_operand")
13637 (match_operand:W 1 "memory_operand"))
13638 (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
13639 (set (match_operand 2)
13640 (call (mem:QI (match_dup 0))
13641 (match_operand 3)))]
13643 && !TARGET_INDIRECT_BRANCH_REGISTER
13644 && SIBLING_CALL_P (peep2_next_insn (2))
13645 && !reg_mentioned_p (operands[0],
13646 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (2)))"
13647 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
13648 (parallel [(set (match_dup 2)
13649 (call (mem:QI (match_dup 1))
13651 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
13653 (define_expand "call_value_pop"
13654 [(parallel [(set (match_operand 0)
13655 (call (match_operand:QI 1)
13656 (match_operand:SI 2)))
13657 (set (reg:SI SP_REG)
13658 (plus:SI (reg:SI SP_REG)
13659 (match_operand:SI 4)))])]
13662 ix86_expand_call (operands[0], operands[1], operands[2],
13663 operands[3], operands[4], false);
13667 (define_insn "*call_value_pop"
13668 [(set (match_operand 0)
13669 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lBwBz"))
13670 (match_operand 2)))
13671 (set (reg:SI SP_REG)
13672 (plus:SI (reg:SI SP_REG)
13673 (match_operand:SI 3 "immediate_operand" "i")))]
13674 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
13675 "* return ix86_output_call_insn (insn, operands[1]);"
13676 [(set_attr "type" "callv")])
13678 (define_insn "*sibcall_value_pop"
13679 [(set (match_operand 0)
13680 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "UBsBz"))
13681 (match_operand 2)))
13682 (set (reg:SI SP_REG)
13683 (plus:SI (reg:SI SP_REG)
13684 (match_operand:SI 3 "immediate_operand" "i")))]
13685 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
13686 "* return ix86_output_call_insn (insn, operands[1]);"
13687 [(set_attr "type" "callv")])
13689 (define_insn "*sibcall_value_pop_memory"
13690 [(set (match_operand 0)
13691 (call (mem:QI (match_operand:SI 1 "memory_operand" "m"))
13692 (match_operand 2)))
13693 (set (reg:SI SP_REG)
13694 (plus:SI (reg:SI SP_REG)
13695 (match_operand:SI 3 "immediate_operand" "i")))
13696 (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
13698 "* return ix86_output_call_insn (insn, operands[1]);"
13699 [(set_attr "type" "callv")])
13702 [(set (match_operand:SI 0 "register_operand")
13703 (match_operand:SI 1 "memory_operand"))
13704 (parallel [(set (match_operand 2)
13705 (call (mem:QI (match_dup 0))
13706 (match_operand 3)))
13707 (set (reg:SI SP_REG)
13708 (plus:SI (reg:SI SP_REG)
13709 (match_operand:SI 4 "immediate_operand")))])]
13710 "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (1))
13711 && !reg_mentioned_p (operands[0],
13712 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (1)))"
13713 [(parallel [(set (match_dup 2)
13714 (call (mem:QI (match_dup 1))
13716 (set (reg:SI SP_REG)
13717 (plus:SI (reg:SI SP_REG)
13719 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
13722 [(set (match_operand:SI 0 "register_operand")
13723 (match_operand:SI 1 "memory_operand"))
13724 (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
13725 (parallel [(set (match_operand 2)
13726 (call (mem:QI (match_dup 0))
13727 (match_operand 3)))
13728 (set (reg:SI SP_REG)
13729 (plus:SI (reg:SI SP_REG)
13730 (match_operand:SI 4 "immediate_operand")))])]
13731 "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (2))
13732 && !reg_mentioned_p (operands[0],
13733 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (2)))"
13734 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
13735 (parallel [(set (match_dup 2)
13736 (call (mem:QI (match_dup 1))
13738 (set (reg:SI SP_REG)
13739 (plus:SI (reg:SI SP_REG)
13741 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
13743 ;; Call subroutine returning any type.
13745 (define_expand "untyped_call"
13746 [(parallel [(call (match_operand 0)
13749 (match_operand 2)])]
13754 /* In order to give reg-stack an easier job in validating two
13755 coprocessor registers as containing a possible return value,
13756 simply pretend the untyped call returns a complex long double
13759 We can't use SSE_REGPARM_MAX here since callee is unprototyped
13760 and should have the default ABI. */
13762 ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
13763 ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
13764 operands[0], const0_rtx,
13765 GEN_INT ((TARGET_64BIT
13766 ? (ix86_abi == SYSV_ABI
13767 ? X86_64_SSE_REGPARM_MAX
13768 : X86_64_MS_SSE_REGPARM_MAX)
13769 : X86_32_SSE_REGPARM_MAX)
13773 for (i = 0; i < XVECLEN (operands[2], 0); i++)
13775 rtx set = XVECEXP (operands[2], 0, i);
13776 emit_move_insn (SET_DEST (set), SET_SRC (set));
13779 /* The optimizer does not know that the call sets the function value
13780 registers we stored in the result block. We avoid problems by
13781 claiming that all hard registers are used and clobbered at this
13783 emit_insn (gen_blockage ());
13788 ;; Prologue and epilogue instructions
13790 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
13791 ;; all of memory. This blocks insns from being moved across this point.
13793 (define_insn "blockage"
13794 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
13797 [(set_attr "length" "0")])
13799 ;; Do not schedule instructions accessing memory across this point.
13801 (define_expand "memory_blockage"
13802 [(set (match_dup 0)
13803 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
13806 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
13807 MEM_VOLATILE_P (operands[0]) = 1;
13810 (define_insn "*memory_blockage"
13811 [(set (match_operand:BLK 0)
13812 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
13815 [(set_attr "length" "0")])
13817 ;; As USE insns aren't meaningful after reload, this is used instead
13818 ;; to prevent deleting instructions setting registers for PIC code
13819 (define_insn "prologue_use"
13820 [(unspec_volatile [(match_operand 0)] UNSPECV_PROLOGUE_USE)]
13823 [(set_attr "length" "0")])
13825 ;; Insn emitted into the body of a function to return from a function.
13826 ;; This is only done if the function's epilogue is known to be simple.
13827 ;; See comments for ix86_can_use_return_insn_p in i386.c.
13829 (define_expand "return"
13831 "ix86_can_use_return_insn_p ()"
13833 if (crtl->args.pops_args)
13835 rtx popc = GEN_INT (crtl->args.pops_args);
13836 emit_jump_insn (gen_simple_return_pop_internal (popc));
13841 ;; We need to disable this for TARGET_SEH, as otherwise
13842 ;; shrink-wrapped prologue gets enabled too. This might exceed
13843 ;; the maximum size of prologue in unwind information.
13844 ;; Also disallow shrink-wrapping if using stack slot to pass the
13845 ;; static chain pointer - the first instruction has to be pushl %esi
13846 ;; and it can't be moved around, as we use alternate entry points
13848 ;; Also disallow for ms_hook_prologue functions which have frame
13849 ;; pointer set up in function label which is correctly handled in
13850 ;; ix86_expand_{prologue|epligoue}() only.
13852 (define_expand "simple_return"
13854 "!TARGET_SEH && !ix86_static_chain_on_stack && !ix86_function_ms_hook_prologue (cfun->decl)"
13856 if (crtl->args.pops_args)
13858 rtx popc = GEN_INT (crtl->args.pops_args);
13859 emit_jump_insn (gen_simple_return_pop_internal (popc));
13864 (define_insn "simple_return_internal"
13867 "* return ix86_output_function_return (false);"
13868 [(set_attr "length" "1")
13869 (set_attr "atom_unit" "jeu")
13870 (set_attr "length_immediate" "0")
13871 (set_attr "modrm" "0")])
13873 (define_insn "interrupt_return"
13875 (unspec [(const_int 0)] UNSPEC_INTERRUPT_RETURN)]
13878 return TARGET_64BIT ? (TARGET_UINTR ? "uiret" : "iretq") : "iret";
13881 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
13882 ;; instruction Athlon and K8 have.
13884 (define_insn "simple_return_internal_long"
13886 (unspec [(const_int 0)] UNSPEC_REP)]
13888 "* return ix86_output_function_return (true);"
13889 [(set_attr "length" "2")
13890 (set_attr "atom_unit" "jeu")
13891 (set_attr "length_immediate" "0")
13892 (set_attr "prefix_rep" "1")
13893 (set_attr "modrm" "0")])
13895 (define_insn_and_split "simple_return_pop_internal"
13897 (use (match_operand:SI 0 "const_int_operand"))]
13900 "&& cfun->machine->function_return_type != indirect_branch_keep"
13902 "ix86_split_simple_return_pop_internal (operands[0]); DONE;"
13903 [(set_attr "length" "3")
13904 (set_attr "atom_unit" "jeu")
13905 (set_attr "length_immediate" "2")
13906 (set_attr "modrm" "0")])
13908 (define_expand "simple_return_indirect_internal"
13911 (use (match_operand 0 "register_operand"))])])
13913 (define_insn "*simple_return_indirect_internal<mode>"
13915 (use (match_operand:W 0 "register_operand" "r"))]
13917 "* return ix86_output_indirect_function_return (operands[0]);"
13918 [(set (attr "type")
13919 (if_then_else (match_test "(cfun->machine->indirect_branch_type
13920 != indirect_branch_keep)")
13921 (const_string "multi")
13922 (const_string "ibr")))
13923 (set_attr "length_immediate" "0")])
13929 [(set_attr "length" "1")
13930 (set_attr "length_immediate" "0")
13931 (set_attr "modrm" "0")])
13933 ;; Generate nops. Operand 0 is the number of nops, up to 8.
13934 (define_insn "nops"
13935 [(unspec_volatile [(match_operand 0 "const_int_operand")]
13939 int num = INTVAL (operands[0]);
13941 gcc_assert (IN_RANGE (num, 1, 8));
13944 fputs ("\tnop\n", asm_out_file);
13948 [(set (attr "length") (symbol_ref "INTVAL (operands[0])"))
13949 (set_attr "length_immediate" "0")
13950 (set_attr "modrm" "0")])
13952 ;; Pad to 16-byte boundary, max skip in op0. Used to avoid
13953 ;; branch prediction penalty for the third jump in a 16-byte
13957 [(unspec_volatile [(match_operand 0)] UNSPECV_ALIGN)]
13960 #ifdef ASM_OUTPUT_MAX_SKIP_PAD
13961 ASM_OUTPUT_MAX_SKIP_PAD (asm_out_file, 4, (int)INTVAL (operands[0]));
13963 /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
13964 The align insn is used to avoid 3 jump instructions in the row to improve
13965 branch prediction and the benefits hardly outweigh the cost of extra 8
13966 nops on the average inserted by full alignment pseudo operation. */
13970 [(set_attr "length" "16")])
13972 (define_expand "prologue"
13975 "ix86_expand_prologue (); DONE;")
13977 (define_expand "set_got"
13979 [(set (match_operand:SI 0 "register_operand")
13980 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
13981 (clobber (reg:CC FLAGS_REG))])]
13984 if (flag_pic && !TARGET_VXWORKS_RTP)
13985 ix86_pc_thunk_call_expanded = true;
13988 (define_insn "*set_got"
13989 [(set (match_operand:SI 0 "register_operand" "=r")
13990 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
13991 (clobber (reg:CC FLAGS_REG))]
13993 "* return output_set_got (operands[0], NULL_RTX);"
13994 [(set_attr "type" "multi")
13995 (set_attr "length" "12")])
13997 (define_expand "set_got_labelled"
13999 [(set (match_operand:SI 0 "register_operand")
14000 (unspec:SI [(label_ref (match_operand 1))]
14002 (clobber (reg:CC FLAGS_REG))])]
14005 if (flag_pic && !TARGET_VXWORKS_RTP)
14006 ix86_pc_thunk_call_expanded = true;
14009 (define_insn "*set_got_labelled"
14010 [(set (match_operand:SI 0 "register_operand" "=r")
14011 (unspec:SI [(label_ref (match_operand 1))]
14013 (clobber (reg:CC FLAGS_REG))]
14015 "* return output_set_got (operands[0], operands[1]);"
14016 [(set_attr "type" "multi")
14017 (set_attr "length" "12")])
14019 (define_insn "set_got_rex64"
14020 [(set (match_operand:DI 0 "register_operand" "=r")
14021 (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
14023 "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}"
14024 [(set_attr "type" "lea")
14025 (set_attr "length_address" "4")
14026 (set_attr "mode" "DI")])
14028 (define_insn "set_rip_rex64"
14029 [(set (match_operand:DI 0 "register_operand" "=r")
14030 (unspec:DI [(label_ref (match_operand 1))] UNSPEC_SET_RIP))]
14032 "lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}"
14033 [(set_attr "type" "lea")
14034 (set_attr "length_address" "4")
14035 (set_attr "mode" "DI")])
14037 (define_insn "set_got_offset_rex64"
14038 [(set (match_operand:DI 0 "register_operand" "=r")
14040 [(label_ref (match_operand 1))]
14041 UNSPEC_SET_GOT_OFFSET))]
14043 "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}"
14044 [(set_attr "type" "imov")
14045 (set_attr "length_immediate" "0")
14046 (set_attr "length_address" "8")
14047 (set_attr "mode" "DI")])
14049 (define_expand "epilogue"
14052 "ix86_expand_epilogue (1); DONE;")
14054 (define_expand "sibcall_epilogue"
14057 "ix86_expand_epilogue (0); DONE;")
14059 (define_expand "eh_return"
14060 [(use (match_operand 0 "register_operand"))]
14063 rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
14065 /* Tricky bit: we write the address of the handler to which we will
14066 be returning into someone else's stack frame, one word below the
14067 stack address we wish to restore. */
14068 tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
14069 tmp = plus_constant (Pmode, tmp, -UNITS_PER_WORD);
14070 /* Return address is always in word_mode. */
14071 tmp = gen_rtx_MEM (word_mode, tmp);
14072 if (GET_MODE (ra) != word_mode)
14073 ra = convert_to_mode (word_mode, ra, 1);
14074 emit_move_insn (tmp, ra);
14076 emit_jump_insn (gen_eh_return_internal ());
14081 (define_insn_and_split "eh_return_internal"
14085 "epilogue_completed"
14087 "ix86_expand_epilogue (2); DONE;")
14089 (define_expand "@leave_<mode>"
14091 [(set (reg:W SP_REG) (plus:W (reg:W BP_REG) (match_dup 0)))
14092 (set (reg:W BP_REG) (mem:W (reg:W BP_REG)))
14093 (clobber (mem:BLK (scratch)))])]
14095 "operands[0] = GEN_INT (<MODE_SIZE>);")
14097 (define_insn "*leave"
14098 [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
14099 (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
14100 (clobber (mem:BLK (scratch)))]
14103 [(set_attr "type" "leave")])
14105 (define_insn "*leave_rex64"
14106 [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
14107 (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
14108 (clobber (mem:BLK (scratch)))]
14111 [(set_attr "type" "leave")])
14113 ;; Handle -fsplit-stack.
14115 (define_expand "split_stack_prologue"
14119 ix86_expand_split_stack_prologue ();
14123 ;; In order to support the call/return predictor, we use a return
14124 ;; instruction which the middle-end doesn't see.
14125 (define_insn "split_stack_return"
14126 [(unspec_volatile [(match_operand:SI 0 "const_int_operand")]
14127 UNSPECV_SPLIT_STACK_RETURN)]
14130 if (operands[0] == const0_rtx)
14135 [(set_attr "atom_unit" "jeu")
14136 (set_attr "modrm" "0")
14137 (set (attr "length")
14138 (if_then_else (match_operand:SI 0 "const0_operand")
14141 (set (attr "length_immediate")
14142 (if_then_else (match_operand:SI 0 "const0_operand")
14146 ;; If there are operand 0 bytes available on the stack, jump to
14149 (define_expand "split_stack_space_check"
14150 [(set (pc) (if_then_else
14151 (ltu (minus (reg SP_REG)
14152 (match_operand 0 "register_operand"))
14154 (label_ref (match_operand 1))
14158 rtx reg = gen_reg_rtx (Pmode);
14160 emit_insn (gen_sub3_insn (reg, stack_pointer_rtx, operands[0]));
14162 operands[2] = ix86_split_stack_guard ();
14163 ix86_expand_branch (GEU, reg, operands[2], operands[1]);
14168 ;; Bit manipulation instructions.
14170 (define_expand "ffs<mode>2"
14171 [(set (match_dup 2) (const_int -1))
14172 (parallel [(set (match_dup 3) (match_dup 4))
14173 (set (match_operand:SWI48 0 "register_operand")
14175 (match_operand:SWI48 1 "nonimmediate_operand")))])
14176 (set (match_dup 0) (if_then_else:SWI48
14177 (eq (match_dup 3) (const_int 0))
14180 (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (const_int 1)))
14181 (clobber (reg:CC FLAGS_REG))])]
14184 machine_mode flags_mode;
14186 if (<MODE>mode == SImode && !TARGET_CMOVE)
14188 emit_insn (gen_ffssi2_no_cmove (operands[0], operands [1]));
14192 flags_mode = TARGET_BMI ? CCCmode : CCZmode;
14194 operands[2] = gen_reg_rtx (<MODE>mode);
14195 operands[3] = gen_rtx_REG (flags_mode, FLAGS_REG);
14196 operands[4] = gen_rtx_COMPARE (flags_mode, operands[1], const0_rtx);
14199 (define_insn_and_split "ffssi2_no_cmove"
14200 [(set (match_operand:SI 0 "register_operand" "=r")
14201 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14202 (clobber (match_scratch:SI 2 "=&q"))
14203 (clobber (reg:CC FLAGS_REG))]
14206 "&& reload_completed"
14207 [(parallel [(set (match_dup 4) (match_dup 5))
14208 (set (match_dup 0) (ctz:SI (match_dup 1)))])
14209 (set (strict_low_part (match_dup 3))
14210 (eq:QI (match_dup 4) (const_int 0)))
14211 (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
14212 (clobber (reg:CC FLAGS_REG))])
14213 (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
14214 (clobber (reg:CC FLAGS_REG))])
14215 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
14216 (clobber (reg:CC FLAGS_REG))])]
14218 machine_mode flags_mode = TARGET_BMI ? CCCmode : CCZmode;
14220 operands[3] = gen_lowpart (QImode, operands[2]);
14221 operands[4] = gen_rtx_REG (flags_mode, FLAGS_REG);
14222 operands[5] = gen_rtx_COMPARE (flags_mode, operands[1], const0_rtx);
14224 ix86_expand_clear (operands[2]);
14227 (define_insn_and_split "*tzcnt<mode>_1"
14228 [(set (reg:CCC FLAGS_REG)
14229 (compare:CCC (match_operand:SWI48 1 "nonimmediate_operand" "rm")
14231 (set (match_operand:SWI48 0 "register_operand" "=r")
14232 (ctz:SWI48 (match_dup 1)))]
14234 "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
14235 "&& TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
14236 && optimize_function_for_speed_p (cfun)
14237 && !reg_mentioned_p (operands[0], operands[1])"
14239 [(set (reg:CCC FLAGS_REG)
14240 (compare:CCC (match_dup 1) (const_int 0)))
14242 (ctz:SWI48 (match_dup 1)))
14243 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)])]
14244 "ix86_expand_clear (operands[0]);"
14245 [(set_attr "type" "alu1")
14246 (set_attr "prefix_0f" "1")
14247 (set_attr "prefix_rep" "1")
14248 (set_attr "btver2_decode" "double")
14249 (set_attr "mode" "<MODE>")])
14251 ; False dependency happens when destination is only updated by tzcnt,
14252 ; lzcnt or popcnt. There is no false dependency when destination is
14253 ; also used in source.
14254 (define_insn "*tzcnt<mode>_1_falsedep"
14255 [(set (reg:CCC FLAGS_REG)
14256 (compare:CCC (match_operand:SWI48 1 "nonimmediate_operand" "rm")
14258 (set (match_operand:SWI48 0 "register_operand" "=r")
14259 (ctz:SWI48 (match_dup 1)))
14260 (unspec [(match_operand:SWI48 2 "register_operand" "0")]
14261 UNSPEC_INSN_FALSE_DEP)]
14263 "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
14264 [(set_attr "type" "alu1")
14265 (set_attr "prefix_0f" "1")
14266 (set_attr "prefix_rep" "1")
14267 (set_attr "btver2_decode" "double")
14268 (set_attr "mode" "<MODE>")])
14270 (define_insn "*bsf<mode>_1"
14271 [(set (reg:CCZ FLAGS_REG)
14272 (compare:CCZ (match_operand:SWI48 1 "nonimmediate_operand" "rm")
14274 (set (match_operand:SWI48 0 "register_operand" "=r")
14275 (ctz:SWI48 (match_dup 1)))]
14277 "bsf{<imodesuffix>}\t{%1, %0|%0, %1}"
14278 [(set_attr "type" "alu1")
14279 (set_attr "prefix_0f" "1")
14280 (set_attr "btver2_decode" "double")
14281 (set_attr "znver1_decode" "vector")
14282 (set_attr "mode" "<MODE>")])
14284 (define_insn_and_split "ctz<mode>2"
14285 [(set (match_operand:SWI48 0 "register_operand" "=r")
14287 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
14288 (clobber (reg:CC FLAGS_REG))]
14292 return "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
14293 else if (optimize_function_for_size_p (cfun))
14295 else if (TARGET_GENERIC)
14296 /* tzcnt expands to 'rep bsf' and we can use it even if !TARGET_BMI. */
14297 return "rep%; bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
14299 return "bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
14301 "(TARGET_BMI || TARGET_GENERIC)
14302 && TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
14303 && optimize_function_for_speed_p (cfun)
14304 && !reg_mentioned_p (operands[0], operands[1])"
14306 [(set (match_dup 0)
14307 (ctz:SWI48 (match_dup 1)))
14308 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
14309 (clobber (reg:CC FLAGS_REG))])]
14310 "ix86_expand_clear (operands[0]);"
14311 [(set_attr "type" "alu1")
14312 (set_attr "prefix_0f" "1")
14313 (set (attr "prefix_rep")
14315 (ior (match_test "TARGET_BMI")
14316 (and (not (match_test "optimize_function_for_size_p (cfun)"))
14317 (match_test "TARGET_GENERIC")))
14319 (const_string "0")))
14320 (set_attr "mode" "<MODE>")])
14322 ; False dependency happens when destination is only updated by tzcnt,
14323 ; lzcnt or popcnt. There is no false dependency when destination is
14324 ; also used in source.
14325 (define_insn "*ctz<mode>2_falsedep"
14326 [(set (match_operand:SWI48 0 "register_operand" "=r")
14328 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
14329 (unspec [(match_operand:SWI48 2 "register_operand" "0")]
14330 UNSPEC_INSN_FALSE_DEP)
14331 (clobber (reg:CC FLAGS_REG))]
14335 return "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
14336 else if (TARGET_GENERIC)
14337 /* tzcnt expands to 'rep bsf' and we can use it even if !TARGET_BMI. */
14338 return "rep%; bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
14340 gcc_unreachable ();
14342 [(set_attr "type" "alu1")
14343 (set_attr "prefix_0f" "1")
14344 (set_attr "prefix_rep" "1")
14345 (set_attr "mode" "<MODE>")])
14347 (define_insn_and_split "*ctzsi2_zext"
14348 [(set (match_operand:DI 0 "register_operand" "=r")
14352 (match_operand:SI 1 "nonimmediate_operand" "rm")) 0)
14354 (clobber (reg:CC FLAGS_REG))]
14355 "TARGET_BMI && TARGET_64BIT"
14356 "tzcnt{l}\t{%1, %k0|%k0, %1}"
14357 "&& TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
14358 && optimize_function_for_speed_p (cfun)
14359 && !reg_mentioned_p (operands[0], operands[1])"
14361 [(set (match_dup 0)
14362 (and:DI (subreg:DI (ctz:SI (match_dup 1)) 0) (const_int 63)))
14363 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
14364 (clobber (reg:CC FLAGS_REG))])]
14365 "ix86_expand_clear (operands[0]);"
14366 [(set_attr "type" "alu1")
14367 (set_attr "prefix_0f" "1")
14368 (set_attr "prefix_rep" "1")
14369 (set_attr "mode" "SI")])
14371 ; False dependency happens when destination is only updated by tzcnt,
14372 ; lzcnt or popcnt. There is no false dependency when destination is
14373 ; also used in source.
14374 (define_insn "*ctzsi2_zext_falsedep"
14375 [(set (match_operand:DI 0 "register_operand" "=r")
14379 (match_operand:SI 1 "nonimmediate_operand" "rm")) 0)
14381 (unspec [(match_operand:DI 2 "register_operand" "0")]
14382 UNSPEC_INSN_FALSE_DEP)
14383 (clobber (reg:CC FLAGS_REG))]
14384 "TARGET_BMI && TARGET_64BIT"
14385 "tzcnt{l}\t{%1, %k0|%k0, %1}"
14386 [(set_attr "type" "alu1")
14387 (set_attr "prefix_0f" "1")
14388 (set_attr "prefix_rep" "1")
14389 (set_attr "mode" "SI")])
14391 (define_insn "bsr_rex64"
14392 [(set (match_operand:DI 0 "register_operand" "=r")
14393 (minus:DI (const_int 63)
14394 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
14395 (clobber (reg:CC FLAGS_REG))]
14397 "bsr{q}\t{%1, %0|%0, %1}"
14398 [(set_attr "type" "alu1")
14399 (set_attr "prefix_0f" "1")
14400 (set_attr "znver1_decode" "vector")
14401 (set_attr "mode" "DI")])
14404 [(set (match_operand:SI 0 "register_operand" "=r")
14405 (minus:SI (const_int 31)
14406 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
14407 (clobber (reg:CC FLAGS_REG))]
14409 "bsr{l}\t{%1, %0|%0, %1}"
14410 [(set_attr "type" "alu1")
14411 (set_attr "prefix_0f" "1")
14412 (set_attr "znver1_decode" "vector")
14413 (set_attr "mode" "SI")])
14415 (define_insn "*bsrhi"
14416 [(set (match_operand:HI 0 "register_operand" "=r")
14417 (minus:HI (const_int 15)
14418 (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
14419 (clobber (reg:CC FLAGS_REG))]
14421 "bsr{w}\t{%1, %0|%0, %1}"
14422 [(set_attr "type" "alu1")
14423 (set_attr "prefix_0f" "1")
14424 (set_attr "znver1_decode" "vector")
14425 (set_attr "mode" "HI")])
14427 (define_expand "clz<mode>2"
14429 [(set (match_operand:SWI48 0 "register_operand")
14432 (clz:SWI48 (match_operand:SWI48 1 "nonimmediate_operand"))))
14433 (clobber (reg:CC FLAGS_REG))])
14435 [(set (match_dup 0) (xor:SWI48 (match_dup 0) (match_dup 2)))
14436 (clobber (reg:CC FLAGS_REG))])]
14441 emit_insn (gen_clz<mode>2_lzcnt (operands[0], operands[1]));
14444 operands[2] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
14447 (define_insn_and_split "clz<mode>2_lzcnt"
14448 [(set (match_operand:SWI48 0 "register_operand" "=r")
14450 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
14451 (clobber (reg:CC FLAGS_REG))]
14453 "lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
14454 "&& TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
14455 && optimize_function_for_speed_p (cfun)
14456 && !reg_mentioned_p (operands[0], operands[1])"
14458 [(set (match_dup 0)
14459 (clz:SWI48 (match_dup 1)))
14460 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
14461 (clobber (reg:CC FLAGS_REG))])]
14462 "ix86_expand_clear (operands[0]);"
14463 [(set_attr "prefix_rep" "1")
14464 (set_attr "type" "bitmanip")
14465 (set_attr "mode" "<MODE>")])
14467 ; False dependency happens when destination is only updated by tzcnt,
14468 ; lzcnt or popcnt. There is no false dependency when destination is
14469 ; also used in source.
14470 (define_insn "*clz<mode>2_lzcnt_falsedep"
14471 [(set (match_operand:SWI48 0 "register_operand" "=r")
14473 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
14474 (unspec [(match_operand:SWI48 2 "register_operand" "0")]
14475 UNSPEC_INSN_FALSE_DEP)
14476 (clobber (reg:CC FLAGS_REG))]
14478 "lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
14479 [(set_attr "prefix_rep" "1")
14480 (set_attr "type" "bitmanip")
14481 (set_attr "mode" "<MODE>")])
14483 (define_insn_and_split "*clzsi2_lzcnt_zext"
14484 [(set (match_operand:DI 0 "register_operand" "=r")
14488 (match_operand:SI 1 "nonimmediate_operand" "rm")) 0)
14490 (clobber (reg:CC FLAGS_REG))]
14491 "TARGET_LZCNT && TARGET_64BIT"
14492 "lzcnt{l}\t{%1, %k0|%k0, %1}"
14493 "&& TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
14494 && optimize_function_for_speed_p (cfun)
14495 && !reg_mentioned_p (operands[0], operands[1])"
14497 [(set (match_dup 0)
14498 (and:DI (subreg:DI (clz:SI (match_dup 1)) 0) (const_int 63)))
14499 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
14500 (clobber (reg:CC FLAGS_REG))])]
14501 "ix86_expand_clear (operands[0]);"
14502 [(set_attr "prefix_rep" "1")
14503 (set_attr "type" "bitmanip")
14504 (set_attr "mode" "SI")])
14506 ; False dependency happens when destination is only updated by tzcnt,
14507 ; lzcnt or popcnt. There is no false dependency when destination is
14508 ; also used in source.
14509 (define_insn "*clzsi2_lzcnt_zext_falsedep"
14510 [(set (match_operand:DI 0 "register_operand" "=r")
14514 (match_operand:SWI48 1 "nonimmediate_operand" "rm")) 0)
14516 (unspec [(match_operand:DI 2 "register_operand" "0")]
14517 UNSPEC_INSN_FALSE_DEP)
14518 (clobber (reg:CC FLAGS_REG))]
14520 "lzcnt{l}\t{%1, %k0|%k0, %1}"
14521 [(set_attr "prefix_rep" "1")
14522 (set_attr "type" "bitmanip")
14523 (set_attr "mode" "SI")])
14525 (define_int_iterator LT_ZCNT
14526 [(UNSPEC_TZCNT "TARGET_BMI")
14527 (UNSPEC_LZCNT "TARGET_LZCNT")])
14529 (define_int_attr lt_zcnt
14530 [(UNSPEC_TZCNT "tzcnt")
14531 (UNSPEC_LZCNT "lzcnt")])
14533 (define_int_attr lt_zcnt_type
14534 [(UNSPEC_TZCNT "alu1")
14535 (UNSPEC_LZCNT "bitmanip")])
14537 ;; Version of lzcnt/tzcnt that is expanded from intrinsics. This version
14538 ;; provides operand size as output when source operand is zero.
14540 (define_insn_and_split "<lt_zcnt>_<mode>"
14541 [(set (match_operand:SWI48 0 "register_operand" "=r")
14543 [(match_operand:SWI48 1 "nonimmediate_operand" "rm")] LT_ZCNT))
14544 (clobber (reg:CC FLAGS_REG))]
14546 "<lt_zcnt>{<imodesuffix>}\t{%1, %0|%0, %1}"
14547 "&& TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
14548 && optimize_function_for_speed_p (cfun)
14549 && !reg_mentioned_p (operands[0], operands[1])"
14551 [(set (match_dup 0)
14552 (unspec:SWI48 [(match_dup 1)] LT_ZCNT))
14553 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
14554 (clobber (reg:CC FLAGS_REG))])]
14555 "ix86_expand_clear (operands[0]);"
14556 [(set_attr "type" "<lt_zcnt_type>")
14557 (set_attr "prefix_0f" "1")
14558 (set_attr "prefix_rep" "1")
14559 (set_attr "mode" "<MODE>")])
14561 ; False dependency happens when destination is only updated by tzcnt,
14562 ; lzcnt or popcnt. There is no false dependency when destination is
14563 ; also used in source.
14564 (define_insn "*<lt_zcnt>_<mode>_falsedep"
14565 [(set (match_operand:SWI48 0 "register_operand" "=r")
14567 [(match_operand:SWI48 1 "nonimmediate_operand" "rm")] LT_ZCNT))
14568 (unspec [(match_operand:SWI48 2 "register_operand" "0")]
14569 UNSPEC_INSN_FALSE_DEP)
14570 (clobber (reg:CC FLAGS_REG))]
14572 "<lt_zcnt>{<imodesuffix>}\t{%1, %0|%0, %1}"
14573 [(set_attr "type" "<lt_zcnt_type>")
14574 (set_attr "prefix_0f" "1")
14575 (set_attr "prefix_rep" "1")
14576 (set_attr "mode" "<MODE>")])
14578 (define_insn "<lt_zcnt>_hi"
14579 [(set (match_operand:HI 0 "register_operand" "=r")
14581 [(match_operand:HI 1 "nonimmediate_operand" "rm")] LT_ZCNT))
14582 (clobber (reg:CC FLAGS_REG))]
14584 "<lt_zcnt>{w}\t{%1, %0|%0, %1}"
14585 [(set_attr "type" "<lt_zcnt_type>")
14586 (set_attr "prefix_0f" "1")
14587 (set_attr "prefix_rep" "1")
14588 (set_attr "mode" "HI")])
14590 ;; BMI instructions.
14592 (define_insn "bmi_bextr_<mode>"
14593 [(set (match_operand:SWI48 0 "register_operand" "=r,r")
14594 (unspec:SWI48 [(match_operand:SWI48 1 "nonimmediate_operand" "r,m")
14595 (match_operand:SWI48 2 "register_operand" "r,r")]
14597 (clobber (reg:CC FLAGS_REG))]
14599 "bextr\t{%2, %1, %0|%0, %1, %2}"
14600 [(set_attr "type" "bitmanip")
14601 (set_attr "btver2_decode" "direct, double")
14602 (set_attr "mode" "<MODE>")])
14604 (define_insn "*bmi_bextr_<mode>_ccz"
14605 [(set (reg:CCZ FLAGS_REG)
14607 (unspec:SWI48 [(match_operand:SWI48 1 "nonimmediate_operand" "r,m")
14608 (match_operand:SWI48 2 "register_operand" "r,r")]
14611 (clobber (match_scratch:SWI48 0 "=r,r"))]
14613 "bextr\t{%2, %1, %0|%0, %1, %2}"
14614 [(set_attr "type" "bitmanip")
14615 (set_attr "btver2_decode" "direct, double")
14616 (set_attr "mode" "<MODE>")])
14618 (define_insn "*bmi_blsi_<mode>"
14619 [(set (match_operand:SWI48 0 "register_operand" "=r")
14622 (match_operand:SWI48 1 "nonimmediate_operand" "rm"))
14624 (clobber (reg:CC FLAGS_REG))]
14626 "blsi\t{%1, %0|%0, %1}"
14627 [(set_attr "type" "bitmanip")
14628 (set_attr "btver2_decode" "double")
14629 (set_attr "mode" "<MODE>")])
14631 (define_insn "*bmi_blsi_<mode>_cmp"
14632 [(set (reg FLAGS_REG)
14635 (neg:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm"))
14638 (set (match_operand:SWI48 0 "register_operand" "=r")
14639 (and:SWI48 (neg:SWI48 (match_dup 1)) (match_dup 1)))]
14640 "TARGET_BMI && ix86_match_ccmode (insn, CCNOmode)"
14641 "blsi\t{%1, %0|%0, %1}"
14642 [(set_attr "type" "bitmanip")
14643 (set_attr "btver2_decode" "double")
14644 (set_attr "mode" "<MODE>")])
14646 (define_insn "*bmi_blsi_<mode>_ccno"
14647 [(set (reg FLAGS_REG)
14650 (neg:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm"))
14653 (clobber (match_scratch:SWI48 0 "=r"))]
14654 "TARGET_BMI && ix86_match_ccmode (insn, CCNOmode)"
14655 "blsi\t{%1, %0|%0, %1}"
14656 [(set_attr "type" "bitmanip")
14657 (set_attr "btver2_decode" "double")
14658 (set_attr "mode" "<MODE>")])
14660 (define_insn "*bmi_blsmsk_<mode>"
14661 [(set (match_operand:SWI48 0 "register_operand" "=r")
14664 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
14667 (clobber (reg:CC FLAGS_REG))]
14669 "blsmsk\t{%1, %0|%0, %1}"
14670 [(set_attr "type" "bitmanip")
14671 (set_attr "btver2_decode" "double")
14672 (set_attr "mode" "<MODE>")])
14674 (define_insn "*bmi_blsr_<mode>"
14675 [(set (match_operand:SWI48 0 "register_operand" "=r")
14678 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
14681 (clobber (reg:CC FLAGS_REG))]
14683 "blsr\t{%1, %0|%0, %1}"
14684 [(set_attr "type" "bitmanip")
14685 (set_attr "btver2_decode" "double")
14686 (set_attr "mode" "<MODE>")])
14688 (define_insn "*bmi_blsr_<mode>_cmp"
14689 [(set (reg:CCZ FLAGS_REG)
14693 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
14697 (set (match_operand:SWI48 0 "register_operand" "=r")
14704 "blsr\t{%1, %0|%0, %1}"
14705 [(set_attr "type" "bitmanip")
14706 (set_attr "btver2_decode" "double")
14707 (set_attr "mode" "<MODE>")])
14709 (define_insn "*bmi_blsr_<mode>_ccz"
14710 [(set (reg:CCZ FLAGS_REG)
14714 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
14718 (clobber (match_scratch:SWI48 0 "=r"))]
14720 "blsr\t{%1, %0|%0, %1}"
14721 [(set_attr "type" "bitmanip")
14722 (set_attr "btver2_decode" "double")
14723 (set_attr "mode" "<MODE>")])
14725 ;; BMI2 instructions.
14726 (define_expand "bmi2_bzhi_<mode>3"
14728 [(set (match_operand:SWI48 0 "register_operand")
14729 (if_then_else:SWI48
14730 (ne:QI (and:SWI48 (match_operand:SWI48 2 "register_operand")
14733 (zero_extract:SWI48
14734 (match_operand:SWI48 1 "nonimmediate_operand")
14735 (umin:SWI48 (and:SWI48 (match_dup 2) (const_int 255))
14739 (clobber (reg:CC FLAGS_REG))])]
14741 "operands[3] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT);")
14743 (define_insn "*bmi2_bzhi_<mode>3"
14744 [(set (match_operand:SWI48 0 "register_operand" "=r")
14745 (if_then_else:SWI48
14746 (ne:QI (and:SWI48 (match_operand:SWI48 2 "register_operand" "r")
14749 (zero_extract:SWI48
14750 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
14751 (umin:SWI48 (and:SWI48 (match_dup 2) (const_int 255))
14752 (match_operand:SWI48 3 "const_int_operand" "n"))
14755 (clobber (reg:CC FLAGS_REG))]
14756 "TARGET_BMI2 && INTVAL (operands[3]) == <MODE_SIZE> * BITS_PER_UNIT"
14757 "bzhi\t{%2, %1, %0|%0, %1, %2}"
14758 [(set_attr "type" "bitmanip")
14759 (set_attr "prefix" "vex")
14760 (set_attr "mode" "<MODE>")])
14762 (define_insn "*bmi2_bzhi_<mode>3_1"
14763 [(set (match_operand:SWI48 0 "register_operand" "=r")
14764 (if_then_else:SWI48
14765 (ne:QI (match_operand:QI 2 "register_operand" "r") (const_int 0))
14766 (zero_extract:SWI48
14767 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
14768 (umin:SWI48 (zero_extend:SWI48 (match_dup 2))
14769 (match_operand:SWI48 3 "const_int_operand" "n"))
14772 (clobber (reg:CC FLAGS_REG))]
14773 "TARGET_BMI2 && INTVAL (operands[3]) == <MODE_SIZE> * BITS_PER_UNIT"
14774 "bzhi\t{%<k>2, %1, %0|%0, %1, %<k>2}"
14775 [(set_attr "type" "bitmanip")
14776 (set_attr "prefix" "vex")
14777 (set_attr "mode" "<MODE>")])
14779 (define_insn "*bmi2_bzhi_<mode>3_1_ccz"
14780 [(set (reg:CCZ FLAGS_REG)
14782 (if_then_else:SWI48
14783 (ne:QI (match_operand:QI 2 "register_operand" "r") (const_int 0))
14784 (zero_extract:SWI48
14785 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
14786 (umin:SWI48 (zero_extend:SWI48 (match_dup 2))
14787 (match_operand:SWI48 3 "const_int_operand" "n"))
14791 (clobber (match_scratch:SWI48 0 "=r"))]
14792 "TARGET_BMI2 && INTVAL (operands[3]) == <MODE_SIZE> * BITS_PER_UNIT"
14793 "bzhi\t{%<k>2, %1, %0|%0, %1, %<k>2}"
14794 [(set_attr "type" "bitmanip")
14795 (set_attr "prefix" "vex")
14796 (set_attr "mode" "<MODE>")])
14798 (define_insn "*bmi2_bzhi_<mode>3_2"
14799 [(set (match_operand:SWI48 0 "register_operand" "=r")
14802 (ashift:SWI48 (const_int 1)
14803 (match_operand:QI 2 "register_operand" "r"))
14805 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
14806 (clobber (reg:CC FLAGS_REG))]
14808 "bzhi\t{%<k>2, %1, %0|%0, %1, %<k>2}"
14809 [(set_attr "type" "bitmanip")
14810 (set_attr "prefix" "vex")
14811 (set_attr "mode" "<MODE>")])
14813 (define_insn "*bmi2_bzhi_<mode>3_3"
14814 [(set (match_operand:SWI48 0 "register_operand" "=r")
14817 (ashift:SWI48 (const_int -1)
14818 (match_operand:QI 2 "register_operand" "r")))
14819 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
14820 (clobber (reg:CC FLAGS_REG))]
14822 "bzhi\t{%<k>2, %1, %0|%0, %1, %<k>2}"
14823 [(set_attr "type" "bitmanip")
14824 (set_attr "prefix" "vex")
14825 (set_attr "mode" "<MODE>")])
14827 (define_insn "bmi2_pdep_<mode>3"
14828 [(set (match_operand:SWI48 0 "register_operand" "=r")
14829 (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
14830 (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
14833 "pdep\t{%2, %1, %0|%0, %1, %2}"
14834 [(set_attr "type" "bitmanip")
14835 (set_attr "prefix" "vex")
14836 (set_attr "mode" "<MODE>")])
14838 (define_insn "bmi2_pext_<mode>3"
14839 [(set (match_operand:SWI48 0 "register_operand" "=r")
14840 (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
14841 (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
14844 "pext\t{%2, %1, %0|%0, %1, %2}"
14845 [(set_attr "type" "bitmanip")
14846 (set_attr "prefix" "vex")
14847 (set_attr "mode" "<MODE>")])
14849 ;; TBM instructions.
14850 (define_insn "@tbm_bextri_<mode>"
14851 [(set (match_operand:SWI48 0 "register_operand" "=r")
14852 (zero_extract:SWI48
14853 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
14854 (match_operand 2 "const_0_to_255_operand" "N")
14855 (match_operand 3 "const_0_to_255_operand" "N")))
14856 (clobber (reg:CC FLAGS_REG))]
14859 operands[2] = GEN_INT (INTVAL (operands[2]) << 8 | INTVAL (operands[3]));
14860 return "bextr\t{%2, %1, %0|%0, %1, %2}";
14862 [(set_attr "type" "bitmanip")
14863 (set_attr "mode" "<MODE>")])
14865 (define_insn "*tbm_blcfill_<mode>"
14866 [(set (match_operand:SWI48 0 "register_operand" "=r")
14869 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
14872 (clobber (reg:CC FLAGS_REG))]
14874 "blcfill\t{%1, %0|%0, %1}"
14875 [(set_attr "type" "bitmanip")
14876 (set_attr "mode" "<MODE>")])
14878 (define_insn "*tbm_blci_<mode>"
14879 [(set (match_operand:SWI48 0 "register_operand" "=r")
14883 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
14886 (clobber (reg:CC FLAGS_REG))]
14888 "blci\t{%1, %0|%0, %1}"
14889 [(set_attr "type" "bitmanip")
14890 (set_attr "mode" "<MODE>")])
14892 (define_insn "*tbm_blcic_<mode>"
14893 [(set (match_operand:SWI48 0 "register_operand" "=r")
14896 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
14900 (clobber (reg:CC FLAGS_REG))]
14902 "blcic\t{%1, %0|%0, %1}"
14903 [(set_attr "type" "bitmanip")
14904 (set_attr "mode" "<MODE>")])
14906 (define_insn "*tbm_blcmsk_<mode>"
14907 [(set (match_operand:SWI48 0 "register_operand" "=r")
14910 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
14913 (clobber (reg:CC FLAGS_REG))]
14915 "blcmsk\t{%1, %0|%0, %1}"
14916 [(set_attr "type" "bitmanip")
14917 (set_attr "mode" "<MODE>")])
14919 (define_insn "*tbm_blcs_<mode>"
14920 [(set (match_operand:SWI48 0 "register_operand" "=r")
14923 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
14926 (clobber (reg:CC FLAGS_REG))]
14928 "blcs\t{%1, %0|%0, %1}"
14929 [(set_attr "type" "bitmanip")
14930 (set_attr "mode" "<MODE>")])
14932 (define_insn "*tbm_blsfill_<mode>"
14933 [(set (match_operand:SWI48 0 "register_operand" "=r")
14936 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
14939 (clobber (reg:CC FLAGS_REG))]
14941 "blsfill\t{%1, %0|%0, %1}"
14942 [(set_attr "type" "bitmanip")
14943 (set_attr "mode" "<MODE>")])
14945 (define_insn "*tbm_blsic_<mode>"
14946 [(set (match_operand:SWI48 0 "register_operand" "=r")
14949 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
14953 (clobber (reg:CC FLAGS_REG))]
14955 "blsic\t{%1, %0|%0, %1}"
14956 [(set_attr "type" "bitmanip")
14957 (set_attr "mode" "<MODE>")])
14959 (define_insn "*tbm_t1mskc_<mode>"
14960 [(set (match_operand:SWI48 0 "register_operand" "=r")
14963 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
14967 (clobber (reg:CC FLAGS_REG))]
14969 "t1mskc\t{%1, %0|%0, %1}"
14970 [(set_attr "type" "bitmanip")
14971 (set_attr "mode" "<MODE>")])
14973 (define_insn "*tbm_tzmsk_<mode>"
14974 [(set (match_operand:SWI48 0 "register_operand" "=r")
14977 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
14981 (clobber (reg:CC FLAGS_REG))]
14983 "tzmsk\t{%1, %0|%0, %1}"
14984 [(set_attr "type" "bitmanip")
14985 (set_attr "mode" "<MODE>")])
14987 (define_insn_and_split "popcount<mode>2"
14988 [(set (match_operand:SWI48 0 "register_operand" "=r")
14990 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
14991 (clobber (reg:CC FLAGS_REG))]
14995 return "popcnt\t{%1, %0|%0, %1}";
14997 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
15000 "&& TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
15001 && optimize_function_for_speed_p (cfun)
15002 && !reg_mentioned_p (operands[0], operands[1])"
15004 [(set (match_dup 0)
15005 (popcount:SWI48 (match_dup 1)))
15006 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
15007 (clobber (reg:CC FLAGS_REG))])]
15008 "ix86_expand_clear (operands[0]);"
15009 [(set_attr "prefix_rep" "1")
15010 (set_attr "type" "bitmanip")
15011 (set_attr "mode" "<MODE>")])
15013 ; False dependency happens when destination is only updated by tzcnt,
15014 ; lzcnt or popcnt. There is no false dependency when destination is
15015 ; also used in source.
15016 (define_insn "*popcount<mode>2_falsedep"
15017 [(set (match_operand:SWI48 0 "register_operand" "=r")
15019 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
15020 (unspec [(match_operand:SWI48 2 "register_operand" "0")]
15021 UNSPEC_INSN_FALSE_DEP)
15022 (clobber (reg:CC FLAGS_REG))]
15026 return "popcnt\t{%1, %0|%0, %1}";
15028 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
15031 [(set_attr "prefix_rep" "1")
15032 (set_attr "type" "bitmanip")
15033 (set_attr "mode" "<MODE>")])
15035 (define_insn_and_split "*popcountsi2_zext"
15036 [(set (match_operand:DI 0 "register_operand" "=r")
15040 (match_operand:SI 1 "nonimmediate_operand" "rm")) 0)
15042 (clobber (reg:CC FLAGS_REG))]
15043 "TARGET_POPCNT && TARGET_64BIT"
15046 return "popcnt\t{%1, %k0|%k0, %1}";
15048 return "popcnt{l}\t{%1, %k0|%k0, %1}";
15051 "&& TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
15052 && optimize_function_for_speed_p (cfun)
15053 && !reg_mentioned_p (operands[0], operands[1])"
15055 [(set (match_dup 0)
15056 (and:DI (subreg:DI (popcount:SI (match_dup 1)) 0) (const_int 63)))
15057 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
15058 (clobber (reg:CC FLAGS_REG))])]
15059 "ix86_expand_clear (operands[0]);"
15060 [(set_attr "prefix_rep" "1")
15061 (set_attr "type" "bitmanip")
15062 (set_attr "mode" "SI")])
15064 ; False dependency happens when destination is only updated by tzcnt,
15065 ; lzcnt or popcnt. There is no false dependency when destination is
15066 ; also used in source.
15067 (define_insn "*popcountsi2_zext_falsedep"
15068 [(set (match_operand:DI 0 "register_operand" "=r")
15072 (match_operand:SI 1 "nonimmediate_operand" "rm")) 0)
15074 (unspec [(match_operand:DI 2 "register_operand" "0")]
15075 UNSPEC_INSN_FALSE_DEP)
15076 (clobber (reg:CC FLAGS_REG))]
15077 "TARGET_POPCNT && TARGET_64BIT"
15080 return "popcnt\t{%1, %k0|%k0, %1}";
15082 return "popcnt{l}\t{%1, %k0|%k0, %1}";
15085 [(set_attr "prefix_rep" "1")
15086 (set_attr "type" "bitmanip")
15087 (set_attr "mode" "SI")])
15089 (define_insn_and_split "*popcounthi2_1"
15090 [(set (match_operand:SI 0 "register_operand")
15092 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand"))))
15093 (clobber (reg:CC FLAGS_REG))]
15095 && ix86_pre_reload_split ()"
15100 rtx tmp = gen_reg_rtx (HImode);
15102 emit_insn (gen_popcounthi2 (tmp, operands[1]));
15103 emit_insn (gen_zero_extendhisi2 (operands[0], tmp));
15107 (define_insn "popcounthi2"
15108 [(set (match_operand:HI 0 "register_operand" "=r")
15110 (match_operand:HI 1 "nonimmediate_operand" "rm")))
15111 (clobber (reg:CC FLAGS_REG))]
15115 return "popcnt\t{%1, %0|%0, %1}";
15117 return "popcnt{w}\t{%1, %0|%0, %1}";
15120 [(set_attr "prefix_rep" "1")
15121 (set_attr "type" "bitmanip")
15122 (set_attr "mode" "HI")])
15124 (define_expand "bswapdi2"
15125 [(set (match_operand:DI 0 "register_operand")
15126 (bswap:DI (match_operand:DI 1 "nonimmediate_operand")))]
15130 operands[1] = force_reg (DImode, operands[1]);
15133 (define_expand "bswapsi2"
15134 [(set (match_operand:SI 0 "register_operand")
15135 (bswap:SI (match_operand:SI 1 "nonimmediate_operand")))]
15140 else if (TARGET_BSWAP)
15141 operands[1] = force_reg (SImode, operands[1]);
15144 rtx x = operands[0];
15146 emit_move_insn (x, operands[1]);
15147 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
15148 emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
15149 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
15154 (define_insn "*bswap<mode>2_movbe"
15155 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,r,m")
15156 (bswap:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,m,r")))]
15158 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
15161 movbe{<imodesuffix>}\t{%1, %0|%0, %1}
15162 movbe{<imodesuffix>}\t{%1, %0|%0, %1}"
15163 [(set_attr "type" "bitmanip,imov,imov")
15164 (set_attr "modrm" "0,1,1")
15165 (set_attr "prefix_0f" "*,1,1")
15166 (set_attr "prefix_extra" "*,1,1")
15167 (set_attr "mode" "<MODE>")])
15169 (define_insn "*bswap<mode>2"
15170 [(set (match_operand:SWI48 0 "register_operand" "=r")
15171 (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "0")))]
15174 [(set_attr "type" "bitmanip")
15175 (set_attr "modrm" "0")
15176 (set_attr "mode" "<MODE>")])
15178 (define_expand "bswaphi2"
15179 [(set (match_operand:HI 0 "register_operand")
15180 (bswap:HI (match_operand:HI 1 "nonimmediate_operand")))]
15183 (define_insn "*bswaphi2_movbe"
15184 [(set (match_operand:HI 0 "nonimmediate_operand" "=Q,r,m")
15185 (bswap:HI (match_operand:HI 1 "nonimmediate_operand" "0,m,r")))]
15187 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
15189 xchg{b}\t{%h0, %b0|%b0, %h0}
15190 movbe{w}\t{%1, %0|%0, %1}
15191 movbe{w}\t{%1, %0|%0, %1}"
15192 [(set_attr "type" "imov")
15193 (set_attr "modrm" "*,1,1")
15194 (set_attr "prefix_0f" "*,1,1")
15195 (set_attr "prefix_extra" "*,1,1")
15196 (set_attr "pent_pair" "np,*,*")
15197 (set_attr "athlon_decode" "vector,*,*")
15198 (set_attr "amdfam10_decode" "double,*,*")
15199 (set_attr "bdver1_decode" "double,*,*")
15200 (set_attr "mode" "QI,HI,HI")])
15203 [(set (match_operand:HI 0 "general_reg_operand")
15204 (bswap:HI (match_dup 0)))]
15206 && !(TARGET_USE_XCHGB || optimize_function_for_size_p (cfun))
15207 && peep2_regno_dead_p (0, FLAGS_REG)"
15208 [(parallel [(set (match_dup 0) (rotate:HI (match_dup 0) (const_int 8)))
15209 (clobber (reg:CC FLAGS_REG))])])
15211 (define_insn "bswaphi_lowpart"
15212 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
15213 (bswap:HI (match_dup 0)))
15214 (clobber (reg:CC FLAGS_REG))]
15217 xchg{b}\t{%h0, %b0|%b0, %h0}
15218 rol{w}\t{$8, %0|%0, 8}"
15219 [(set (attr "preferred_for_size")
15220 (cond [(eq_attr "alternative" "0")
15221 (symbol_ref "true")]
15222 (symbol_ref "false")))
15223 (set (attr "preferred_for_speed")
15224 (cond [(eq_attr "alternative" "0")
15225 (symbol_ref "TARGET_USE_XCHGB")]
15226 (symbol_ref "!TARGET_USE_XCHGB")))
15227 (set_attr "length" "2,4")
15228 (set_attr "mode" "QI,HI")])
15230 (define_expand "paritydi2"
15231 [(set (match_operand:DI 0 "register_operand")
15232 (parity:DI (match_operand:DI 1 "register_operand")))]
15235 rtx scratch = gen_reg_rtx (QImode);
15236 rtx hipart1 = gen_reg_rtx (SImode);
15237 rtx lopart1 = gen_reg_rtx (SImode);
15238 rtx xor1 = gen_reg_rtx (SImode);
15239 rtx shift2 = gen_reg_rtx (SImode);
15240 rtx hipart2 = gen_reg_rtx (HImode);
15241 rtx lopart2 = gen_reg_rtx (HImode);
15242 rtx xor2 = gen_reg_rtx (HImode);
15246 rtx shift1 = gen_reg_rtx (DImode);
15247 emit_insn (gen_lshrdi3 (shift1, operands[1], GEN_INT (32)));
15248 emit_move_insn (hipart1, gen_lowpart (SImode, shift1));
15251 emit_move_insn (hipart1, gen_highpart (SImode, operands[1]));
15253 emit_move_insn (lopart1, gen_lowpart (SImode, operands[1]));
15254 emit_insn (gen_xorsi3 (xor1, hipart1, lopart1));
15256 emit_insn (gen_lshrsi3 (shift2, xor1, GEN_INT (16)));
15257 emit_move_insn (hipart2, gen_lowpart (HImode, shift2));
15258 emit_move_insn (lopart2, gen_lowpart (HImode, xor1));
15259 emit_insn (gen_xorhi3 (xor2, hipart2, lopart2));
15261 emit_insn (gen_parityhi2_cmp (xor2));
15263 ix86_expand_setcc (scratch, ORDERED,
15264 gen_rtx_REG (CCmode, FLAGS_REG), const0_rtx);
15267 emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
15270 rtx tmp = gen_reg_rtx (SImode);
15272 emit_insn (gen_zero_extendqisi2 (tmp, scratch));
15273 emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
15278 (define_expand "paritysi2"
15279 [(set (match_operand:SI 0 "register_operand")
15280 (parity:SI (match_operand:SI 1 "register_operand")))]
15283 rtx scratch = gen_reg_rtx (QImode);
15284 rtx shift = gen_reg_rtx (SImode);
15285 rtx hipart = gen_reg_rtx (HImode);
15286 rtx lopart = gen_reg_rtx (HImode);
15287 rtx tmp = gen_reg_rtx (HImode);
15289 emit_insn (gen_lshrsi3 (shift, operands[1], GEN_INT (16)));
15290 emit_move_insn (hipart, gen_lowpart (HImode, shift));
15291 emit_move_insn (lopart, gen_lowpart (HImode, operands[1]));
15292 emit_insn (gen_xorhi3 (tmp, hipart, lopart));
15294 emit_insn (gen_parityhi2_cmp (tmp));
15296 ix86_expand_setcc (scratch, ORDERED,
15297 gen_rtx_REG (CCmode, FLAGS_REG), const0_rtx);
15299 emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
15303 (define_expand "parityhi2"
15304 [(set (match_operand:HI 0 "register_operand")
15305 (parity:HI (match_operand:HI 1 "register_operand")))]
15308 rtx scratch = gen_reg_rtx (QImode);
15310 emit_insn (gen_parityhi2_cmp (operands[1]));
15312 ix86_expand_setcc (scratch, ORDERED,
15313 gen_rtx_REG (CCmode, FLAGS_REG), const0_rtx);
15315 emit_insn (gen_zero_extendqihi2 (operands[0], scratch));
15319 (define_expand "parityqi2"
15320 [(set (match_operand:QI 0 "register_operand")
15321 (parity:QI (match_operand:QI 1 "register_operand")))]
15324 emit_insn (gen_parityqi2_cmp (operands[1]));
15326 ix86_expand_setcc (operands[0], ORDERED,
15327 gen_rtx_REG (CCmode, FLAGS_REG), const0_rtx);
15331 (define_insn "parityhi2_cmp"
15332 [(set (reg:CC FLAGS_REG)
15333 (unspec:CC [(match_operand:HI 0 "register_operand" "+Q")]
15335 (clobber (match_dup 0))]
15337 "xor{b}\t{%h0, %b0|%b0, %h0}"
15338 [(set_attr "length" "2")
15339 (set_attr "mode" "QI")])
15341 (define_insn "parityqi2_cmp"
15342 [(set (reg:CC FLAGS_REG)
15343 (unspec:CC [(match_operand:QI 0 "register_operand" "q")]
15347 [(set_attr "mode" "QI")])
15349 ;; Replace zero_extend:HI followed by parityhi2_cmp with parityqi2_cmp
15351 [(set (match_operand:HI 0 "register_operand")
15352 (zero_extend:HI (match_operand:QI 1 "general_reg_operand")))
15353 (parallel [(set (reg:CC FLAGS_REG)
15354 (unspec:CC [(match_dup 0)] UNSPEC_PARITY))
15355 (clobber (match_dup 0))])]
15357 [(set (reg:CC FLAGS_REG)
15358 (unspec:CC [(match_dup 1)] UNSPEC_PARITY))])
15360 ;; Eliminate QImode popcount&1 using parity flag
15362 [(set (match_operand:SI 0 "register_operand")
15363 (zero_extend:SI (match_operand:QI 1 "general_reg_operand")))
15364 (parallel [(set (match_operand:SI 2 "register_operand")
15365 (popcount:SI (match_dup 0)))
15366 (clobber (reg:CC FLAGS_REG))])
15367 (set (reg:CCZ FLAGS_REG)
15368 (compare:CCZ (and:QI (match_operand:QI 3 "register_operand")
15371 (set (pc) (if_then_else (match_operator 4 "bt_comparison_operator"
15372 [(reg:CCZ FLAGS_REG)
15374 (label_ref (match_operand 5))
15376 "REGNO (operands[2]) == REGNO (operands[3])
15377 && peep2_reg_dead_p (3, operands[0])
15378 && peep2_reg_dead_p (3, operands[2])
15379 && peep2_regno_dead_p (4, FLAGS_REG)"
15380 [(set (reg:CC FLAGS_REG)
15381 (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
15382 (set (pc) (if_then_else (match_op_dup 4 [(reg:CC FLAGS_REG)
15384 (label_ref (match_dup 5))
15387 operands[4] = shallow_copy_rtx (operands[4]);
15388 PUT_CODE (operands[4], GET_CODE (operands[4]) == EQ ? UNORDERED : ORDERED);
15391 ;; Eliminate HImode popcount&1 using parity flag
15393 [(match_scratch:HI 0 "Q")
15394 (parallel [(set (match_operand:HI 1 "register_operand")
15396 (match_operand:HI 2 "nonimmediate_operand")))
15397 (clobber (reg:CC FLAGS_REG))])
15398 (set (match_operand 3 "register_operand")
15399 (zero_extend (match_dup 1)))
15400 (set (reg:CCZ FLAGS_REG)
15401 (compare:CCZ (and:QI (match_operand:QI 4 "register_operand")
15404 (set (pc) (if_then_else (match_operator 5 "bt_comparison_operator"
15405 [(reg:CCZ FLAGS_REG)
15407 (label_ref (match_operand 6))
15409 "REGNO (operands[3]) == REGNO (operands[4])
15410 && peep2_reg_dead_p (3, operands[1])
15411 && peep2_reg_dead_p (3, operands[3])
15412 && peep2_regno_dead_p (4, FLAGS_REG)"
15413 [(set (match_dup 0) (match_dup 2))
15414 (parallel [(set (reg:CC FLAGS_REG)
15415 (unspec:CC [(match_dup 0)] UNSPEC_PARITY))
15416 (clobber (match_dup 0))])
15417 (set (pc) (if_then_else (match_op_dup 5 [(reg:CC FLAGS_REG)
15419 (label_ref (match_dup 6))
15422 operands[5] = shallow_copy_rtx (operands[5]);
15423 PUT_CODE (operands[5], GET_CODE (operands[5]) == EQ ? UNORDERED : ORDERED);
15427 ;; Thread-local storage patterns for ELF.
15429 ;; Note that these code sequences must appear exactly as shown
15430 ;; in order to allow linker relaxation.
15432 (define_insn "*tls_global_dynamic_32_gnu"
15433 [(set (match_operand:SI 0 "register_operand" "=a")
15435 [(match_operand:SI 1 "register_operand" "Yb")
15436 (match_operand 2 "tls_symbolic_operand")
15437 (match_operand 3 "constant_call_address_operand" "Bz")
15440 (clobber (match_scratch:SI 4 "=d"))
15441 (clobber (match_scratch:SI 5 "=c"))
15442 (clobber (reg:CC FLAGS_REG))]
15443 "!TARGET_64BIT && TARGET_GNU_TLS"
15445 if (TARGET_SUN_TLS || flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT)
15447 ("lea{l}\t{%E2@tlsgd(,%1,1), %0|%0, %E2@tlsgd[%1*1]}", operands);
15450 ("lea{l}\t{%E2@tlsgd(%1), %0|%0, %E2@tlsgd[%1]}", operands);
15451 if (TARGET_SUN_TLS)
15452 #ifdef HAVE_AS_IX86_TLSGDPLT
15453 return "call\t%a2@tlsgdplt";
15455 return "call\t%p3@plt";
15457 if (flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT)
15458 return "call\t%P3";
15459 return "call\t{*%p3@GOT(%1)|[DWORD PTR %p3@GOT[%1]]}";
15461 [(set_attr "type" "multi")
15462 (set_attr "length" "12")])
15464 (define_expand "tls_global_dynamic_32"
15466 [(set (match_operand:SI 0 "register_operand")
15467 (unspec:SI [(match_operand:SI 2 "register_operand")
15468 (match_operand 1 "tls_symbolic_operand")
15469 (match_operand 3 "constant_call_address_operand")
15472 (clobber (scratch:SI))
15473 (clobber (scratch:SI))
15474 (clobber (reg:CC FLAGS_REG))])]
15476 "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
15478 (define_insn "*tls_global_dynamic_64_<mode>"
15479 [(set (match_operand:P 0 "register_operand" "=a")
15481 (mem:QI (match_operand 2 "constant_call_address_operand" "Bz"))
15482 (match_operand 3)))
15483 (unspec:P [(match_operand 1 "tls_symbolic_operand")
15489 /* The .loc directive has effect for 'the immediately following assembly
15490 instruction'. So for a sequence:
15494 the 'immediately following assembly instruction' is insn1.
15495 We want to emit an insn prefix here, but if we use .byte (as shown in
15496 'ELF Handling For Thread-Local Storage'), a preceding .loc will point
15497 inside the insn sequence, rather than to the start. After relaxation
15498 of the sequence by the linker, the .loc might point inside an insn.
15499 Use data16 prefix instead, which doesn't have this problem. */
15500 fputs ("\tdata16", asm_out_file);
15502 ("lea{q}\t{%E1@tlsgd(%%rip), %%rdi|rdi, %E1@tlsgd[rip]}", operands);
15503 if (TARGET_SUN_TLS || flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT)
15504 fputs (ASM_SHORT "0x6666\n", asm_out_file);
15506 fputs (ASM_BYTE "0x66\n", asm_out_file);
15507 fputs ("\trex64\n", asm_out_file);
15508 if (TARGET_SUN_TLS)
15509 return "call\t%p2@plt";
15510 if (flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT)
15511 return "call\t%P2";
15512 return "call\t{*%p2@GOTPCREL(%%rip)|[QWORD PTR %p2@GOTPCREL[rip]]}";
15514 [(set_attr "type" "multi")
15515 (set (attr "length")
15516 (symbol_ref "TARGET_X32 ? 15 : 16"))])
15518 (define_insn "*tls_global_dynamic_64_largepic"
15519 [(set (match_operand:DI 0 "register_operand" "=a")
15521 (mem:QI (plus:DI (match_operand:DI 2 "register_operand" "b")
15522 (match_operand:DI 3 "immediate_operand" "i")))
15523 (match_operand 4)))
15524 (unspec:DI [(match_operand 1 "tls_symbolic_operand")
15527 "TARGET_64BIT && ix86_cmodel == CM_LARGE_PIC && !TARGET_PECOFF
15528 && GET_CODE (operands[3]) == CONST
15529 && GET_CODE (XEXP (operands[3], 0)) == UNSPEC
15530 && XINT (XEXP (operands[3], 0), 1) == UNSPEC_PLTOFF"
15533 ("lea{q}\t{%E1@tlsgd(%%rip), %%rdi|rdi, %E1@tlsgd[rip]}", operands);
15534 output_asm_insn ("movabs{q}\t{%3, %%rax|rax, %3}", operands);
15535 output_asm_insn ("add{q}\t{%2, %%rax|rax, %2}", operands);
15536 return "call\t{*%%rax|rax}";
15538 [(set_attr "type" "multi")
15539 (set_attr "length" "22")])
15541 (define_expand "@tls_global_dynamic_64_<mode>"
15543 [(set (match_operand:P 0 "register_operand")
15545 (mem:QI (match_operand 2))
15547 (unspec:P [(match_operand 1 "tls_symbolic_operand")
15551 "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
15553 (define_insn "*tls_local_dynamic_base_32_gnu"
15554 [(set (match_operand:SI 0 "register_operand" "=a")
15556 [(match_operand:SI 1 "register_operand" "Yb")
15557 (match_operand 2 "constant_call_address_operand" "Bz")
15559 UNSPEC_TLS_LD_BASE))
15560 (clobber (match_scratch:SI 3 "=d"))
15561 (clobber (match_scratch:SI 4 "=c"))
15562 (clobber (reg:CC FLAGS_REG))]
15563 "!TARGET_64BIT && TARGET_GNU_TLS"
15566 ("lea{l}\t{%&@tlsldm(%1), %0|%0, %&@tlsldm[%1]}", operands);
15567 if (TARGET_SUN_TLS)
15569 if (HAVE_AS_IX86_TLSLDMPLT)
15570 return "call\t%&@tlsldmplt";
15572 return "call\t%p2@plt";
15574 if (flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT)
15575 return "call\t%P2";
15576 return "call\t{*%p2@GOT(%1)|[DWORD PTR %p2@GOT[%1]]}";
15578 [(set_attr "type" "multi")
15579 (set_attr "length" "11")])
15581 (define_expand "tls_local_dynamic_base_32"
15583 [(set (match_operand:SI 0 "register_operand")
15585 [(match_operand:SI 1 "register_operand")
15586 (match_operand 2 "constant_call_address_operand")
15588 UNSPEC_TLS_LD_BASE))
15589 (clobber (scratch:SI))
15590 (clobber (scratch:SI))
15591 (clobber (reg:CC FLAGS_REG))])]
15593 "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
15595 (define_insn "*tls_local_dynamic_base_64_<mode>"
15596 [(set (match_operand:P 0 "register_operand" "=a")
15598 (mem:QI (match_operand 1 "constant_call_address_operand" "Bz"))
15599 (match_operand 2)))
15600 (unspec:P [(reg:P SP_REG)] UNSPEC_TLS_LD_BASE)]
15604 ("lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}", operands);
15605 if (TARGET_SUN_TLS)
15606 return "call\t%p1@plt";
15607 if (flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT)
15608 return "call\t%P1";
15609 return "call\t{*%p1@GOTPCREL(%%rip)|[QWORD PTR %p1@GOTPCREL[rip]]}";
15611 [(set_attr "type" "multi")
15612 (set_attr "length" "12")])
15614 (define_insn "*tls_local_dynamic_base_64_largepic"
15615 [(set (match_operand:DI 0 "register_operand" "=a")
15617 (mem:QI (plus:DI (match_operand:DI 1 "register_operand" "b")
15618 (match_operand:DI 2 "immediate_operand" "i")))
15619 (match_operand 3)))
15620 (unspec:DI [(reg:DI SP_REG)] UNSPEC_TLS_LD_BASE)]
15621 "TARGET_64BIT && ix86_cmodel == CM_LARGE_PIC && !TARGET_PECOFF
15622 && GET_CODE (operands[2]) == CONST
15623 && GET_CODE (XEXP (operands[2], 0)) == UNSPEC
15624 && XINT (XEXP (operands[2], 0), 1) == UNSPEC_PLTOFF"
15627 ("lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}", operands);
15628 output_asm_insn ("movabs{q}\t{%2, %%rax|rax, %2}", operands);
15629 output_asm_insn ("add{q}\t{%1, %%rax|rax, %1}", operands);
15630 return "call\t{*%%rax|rax}";
15632 [(set_attr "type" "multi")
15633 (set_attr "length" "22")])
15635 (define_expand "@tls_local_dynamic_base_64_<mode>"
15637 [(set (match_operand:P 0 "register_operand")
15639 (mem:QI (match_operand 1))
15641 (unspec:P [(reg:P SP_REG)] UNSPEC_TLS_LD_BASE)])]
15643 "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
15645 ;; Local dynamic of a single variable is a lose. Show combine how
15646 ;; to convert that back to global dynamic.
15648 (define_insn_and_split "*tls_local_dynamic_32_once"
15649 [(set (match_operand:SI 0 "register_operand" "=a")
15651 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15652 (match_operand 2 "constant_call_address_operand" "Bz")
15654 UNSPEC_TLS_LD_BASE)
15655 (const:SI (unspec:SI
15656 [(match_operand 3 "tls_symbolic_operand")]
15658 (clobber (match_scratch:SI 4 "=d"))
15659 (clobber (match_scratch:SI 5 "=c"))
15660 (clobber (reg:CC FLAGS_REG))]
15665 [(set (match_dup 0)
15666 (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)
15669 (clobber (match_dup 4))
15670 (clobber (match_dup 5))
15671 (clobber (reg:CC FLAGS_REG))])])
15673 ;; Load and add the thread base pointer from %<tp_seg>:0.
15674 (define_expand "get_thread_pointer<mode>"
15675 [(set (match_operand:PTR 0 "register_operand")
15676 (unspec:PTR [(const_int 0)] UNSPEC_TP))]
15679 /* targetm is not visible in the scope of the condition. */
15680 if (!targetm.have_tls)
15681 error ("%<__builtin_thread_pointer%> is not supported on this target");
15684 (define_insn_and_split "*load_tp_<mode>"
15685 [(set (match_operand:PTR 0 "register_operand" "=r")
15686 (unspec:PTR [(const_int 0)] UNSPEC_TP))]
15690 [(set (match_dup 0)
15693 addr_space_t as = DEFAULT_TLS_SEG_REG;
15695 operands[1] = gen_const_mem (<MODE>mode, const0_rtx);
15696 set_mem_addr_space (operands[1], as);
15699 (define_insn_and_split "*load_tp_x32_zext"
15700 [(set (match_operand:DI 0 "register_operand" "=r")
15702 (unspec:SI [(const_int 0)] UNSPEC_TP)))]
15706 [(set (match_dup 0)
15707 (zero_extend:DI (match_dup 1)))]
15709 addr_space_t as = DEFAULT_TLS_SEG_REG;
15711 operands[1] = gen_const_mem (SImode, const0_rtx);
15712 set_mem_addr_space (operands[1], as);
15715 (define_insn_and_split "*add_tp_<mode>"
15716 [(set (match_operand:PTR 0 "register_operand" "=r")
15718 (unspec:PTR [(const_int 0)] UNSPEC_TP)
15719 (match_operand:PTR 1 "register_operand" "0")))
15720 (clobber (reg:CC FLAGS_REG))]
15725 [(set (match_dup 0)
15726 (plus:PTR (match_dup 1) (match_dup 2)))
15727 (clobber (reg:CC FLAGS_REG))])]
15729 addr_space_t as = DEFAULT_TLS_SEG_REG;
15731 operands[2] = gen_const_mem (<MODE>mode, const0_rtx);
15732 set_mem_addr_space (operands[2], as);
15735 (define_insn_and_split "*add_tp_x32_zext"
15736 [(set (match_operand:DI 0 "register_operand" "=r")
15738 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
15739 (match_operand:SI 1 "register_operand" "0"))))
15740 (clobber (reg:CC FLAGS_REG))]
15745 [(set (match_dup 0)
15747 (plus:SI (match_dup 1) (match_dup 2))))
15748 (clobber (reg:CC FLAGS_REG))])]
15750 addr_space_t as = DEFAULT_TLS_SEG_REG;
15752 operands[2] = gen_const_mem (SImode, const0_rtx);
15753 set_mem_addr_space (operands[2], as);
15756 ;; The Sun linker took the AMD64 TLS spec literally and can only handle
15757 ;; %rax as destination of the initial executable code sequence.
15758 (define_insn "tls_initial_exec_64_sun"
15759 [(set (match_operand:DI 0 "register_operand" "=a")
15761 [(match_operand 1 "tls_symbolic_operand")]
15762 UNSPEC_TLS_IE_SUN))
15763 (clobber (reg:CC FLAGS_REG))]
15764 "TARGET_64BIT && TARGET_SUN_TLS"
15767 ("mov{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}", operands);
15768 return "add{q}\t{%a1@gottpoff(%%rip), %0|%0, %a1@gottpoff[rip]}";
15770 [(set_attr "type" "multi")])
15772 ;; GNU2 TLS patterns can be split.
15774 (define_expand "tls_dynamic_gnu2_32"
15775 [(set (match_dup 3)
15776 (plus:SI (match_operand:SI 2 "register_operand")
15778 (unspec:SI [(match_operand 1 "tls_symbolic_operand")]
15781 [(set (match_operand:SI 0 "register_operand")
15782 (unspec:SI [(match_dup 1) (match_dup 3)
15783 (match_dup 2) (reg:SI SP_REG)]
15785 (clobber (reg:CC FLAGS_REG))])]
15786 "!TARGET_64BIT && TARGET_GNU2_TLS"
15788 operands[3] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
15789 ix86_tls_descriptor_calls_expanded_in_cfun = true;
15792 (define_insn "*tls_dynamic_gnu2_lea_32"
15793 [(set (match_operand:SI 0 "register_operand" "=r")
15794 (plus:SI (match_operand:SI 1 "register_operand" "b")
15796 (unspec:SI [(match_operand 2 "tls_symbolic_operand")]
15797 UNSPEC_TLSDESC))))]
15798 "!TARGET_64BIT && TARGET_GNU2_TLS"
15799 "lea{l}\t{%E2@TLSDESC(%1), %0|%0, %E2@TLSDESC[%1]}"
15800 [(set_attr "type" "lea")
15801 (set_attr "mode" "SI")
15802 (set_attr "length" "6")
15803 (set_attr "length_address" "4")])
15805 (define_insn "*tls_dynamic_gnu2_call_32"
15806 [(set (match_operand:SI 0 "register_operand" "=a")
15807 (unspec:SI [(match_operand 1 "tls_symbolic_operand")
15808 (match_operand:SI 2 "register_operand" "0")
15809 ;; we have to make sure %ebx still points to the GOT
15810 (match_operand:SI 3 "register_operand" "b")
15813 (clobber (reg:CC FLAGS_REG))]
15814 "!TARGET_64BIT && TARGET_GNU2_TLS"
15815 "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
15816 [(set_attr "type" "call")
15817 (set_attr "length" "2")
15818 (set_attr "length_address" "0")])
15820 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
15821 [(set (match_operand:SI 0 "register_operand" "=&a")
15823 (unspec:SI [(match_operand 3 "tls_modbase_operand")
15824 (match_operand:SI 4)
15825 (match_operand:SI 2 "register_operand" "b")
15828 (const:SI (unspec:SI
15829 [(match_operand 1 "tls_symbolic_operand")]
15831 (clobber (reg:CC FLAGS_REG))]
15832 "!TARGET_64BIT && TARGET_GNU2_TLS"
15835 [(set (match_dup 0) (match_dup 5))]
15837 operands[5] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
15838 emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
15841 (define_expand "@tls_dynamic_gnu2_64_<mode>"
15842 [(set (match_dup 2)
15843 (unspec:PTR [(match_operand 1 "tls_symbolic_operand")]
15846 [(set (match_operand:PTR 0 "register_operand")
15847 (unspec:PTR [(match_dup 1) (match_dup 2) (reg:PTR SP_REG)]
15849 (clobber (reg:CC FLAGS_REG))])]
15850 "TARGET_64BIT && TARGET_GNU2_TLS"
15852 operands[2] = can_create_pseudo_p () ? gen_reg_rtx (ptr_mode) : operands[0];
15853 ix86_tls_descriptor_calls_expanded_in_cfun = true;
15856 (define_insn "*tls_dynamic_gnu2_lea_64_<mode>"
15857 [(set (match_operand:PTR 0 "register_operand" "=r")
15858 (unspec:PTR [(match_operand 1 "tls_symbolic_operand")]
15860 "TARGET_64BIT && TARGET_GNU2_TLS"
15861 "lea%z0\t{%E1@TLSDESC(%%rip), %0|%0, %E1@TLSDESC[rip]}"
15862 [(set_attr "type" "lea")
15863 (set_attr "mode" "<MODE>")
15864 (set_attr "length" "7")
15865 (set_attr "length_address" "4")])
15867 (define_insn "*tls_dynamic_gnu2_call_64_<mode>"
15868 [(set (match_operand:PTR 0 "register_operand" "=a")
15869 (unspec:PTR [(match_operand 1 "tls_symbolic_operand")
15870 (match_operand:PTR 2 "register_operand" "0")
15873 (clobber (reg:CC FLAGS_REG))]
15874 "TARGET_64BIT && TARGET_GNU2_TLS"
15875 "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
15876 [(set_attr "type" "call")
15877 (set_attr "length" "2")
15878 (set_attr "length_address" "0")])
15880 (define_insn_and_split "*tls_dynamic_gnu2_combine_64_<mode>"
15881 [(set (match_operand:PTR 0 "register_operand" "=&a")
15883 (unspec:PTR [(match_operand 2 "tls_modbase_operand")
15884 (match_operand:PTR 3)
15887 (const:PTR (unspec:PTR
15888 [(match_operand 1 "tls_symbolic_operand")]
15890 (clobber (reg:CC FLAGS_REG))]
15891 "TARGET_64BIT && TARGET_GNU2_TLS"
15894 [(set (match_dup 0) (match_dup 4))]
15896 operands[4] = can_create_pseudo_p () ? gen_reg_rtx (ptr_mode) : operands[0];
15897 emit_insn (gen_tls_dynamic_gnu2_64 (ptr_mode, operands[4], operands[1]));
15901 [(match_operand 0 "tls_address_pattern")]
15902 "TARGET_TLS_DIRECT_SEG_REFS"
15904 "operands[0] = ix86_rewrite_tls_address (operands[0]);")
15907 ;; These patterns match the binary 387 instructions for addM3, subM3,
15908 ;; mulM3 and divM3. There are three patterns for each of DFmode and
15909 ;; SFmode. The first is the normal insn, the second the same insn but
15910 ;; with one operand a conversion, and the third the same insn but with
15911 ;; the other operand a conversion. The conversion may be SFmode or
15912 ;; SImode if the target mode DFmode, but only SImode if the target mode
15915 ;; Gcc is slightly more smart about handling normal two address instructions
15916 ;; so use special patterns for add and mull.
15918 (define_insn "*fop_xf_comm_i387"
15919 [(set (match_operand:XF 0 "register_operand" "=f")
15920 (match_operator:XF 3 "binary_fp_operator"
15921 [(match_operand:XF 1 "register_operand" "%0")
15922 (match_operand:XF 2 "register_operand" "f")]))]
15924 && COMMUTATIVE_ARITH_P (operands[3])"
15925 "* return output_387_binary_op (insn, operands);"
15926 [(set (attr "type")
15927 (if_then_else (match_operand:XF 3 "mult_operator")
15928 (const_string "fmul")
15929 (const_string "fop")))
15930 (set_attr "mode" "XF")])
15932 (define_insn "*fop_<mode>_comm"
15933 [(set (match_operand:MODEF 0 "register_operand" "=f,x,v")
15934 (match_operator:MODEF 3 "binary_fp_operator"
15935 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,0,v")
15936 (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm,vm")]))]
15937 "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15938 || (TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)))
15939 && COMMUTATIVE_ARITH_P (operands[3])
15940 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15941 "* return output_387_binary_op (insn, operands);"
15942 [(set (attr "type")
15943 (if_then_else (eq_attr "alternative" "1,2")
15944 (if_then_else (match_operand:MODEF 3 "mult_operator")
15945 (const_string "ssemul")
15946 (const_string "sseadd"))
15947 (if_then_else (match_operand:MODEF 3 "mult_operator")
15948 (const_string "fmul")
15949 (const_string "fop"))))
15950 (set_attr "isa" "*,noavx,avx")
15951 (set_attr "prefix" "orig,orig,vex")
15952 (set_attr "mode" "<MODE>")
15953 (set (attr "enabled")
15955 (match_test ("SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"))
15957 (eq_attr "alternative" "0")
15958 (symbol_ref "TARGET_MIX_SSE_I387
15959 && X87_ENABLE_ARITH (<MODE>mode)")
15960 (const_string "*"))
15962 (eq_attr "alternative" "0")
15963 (symbol_ref "true")
15964 (symbol_ref "false"))))])
15966 (define_insn "*rcpsf2_sse"
15967 [(set (match_operand:SF 0 "register_operand" "=x,x,x")
15968 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "0,x,m")]
15970 "TARGET_SSE && TARGET_SSE_MATH"
15972 %vrcpss\t{%d1, %0|%0, %d1}
15973 %vrcpss\t{%d1, %0|%0, %d1}
15974 %vrcpss\t{%1, %d0|%d0, %1}"
15975 [(set_attr "type" "sse")
15976 (set_attr "atom_sse_attr" "rcp")
15977 (set_attr "btver2_sse_attr" "rcp")
15978 (set_attr "prefix" "maybe_vex")
15979 (set_attr "mode" "SF")
15980 (set_attr "avx_partial_xmm_update" "false,false,true")
15981 (set (attr "preferred_for_speed")
15982 (cond [(match_test "TARGET_AVX")
15983 (symbol_ref "true")
15984 (eq_attr "alternative" "1,2")
15985 (symbol_ref "!TARGET_SSE_PARTIAL_REG_DEPENDENCY")
15987 (symbol_ref "true")))])
15989 (define_insn "*fop_xf_1_i387"
15990 [(set (match_operand:XF 0 "register_operand" "=f,f")
15991 (match_operator:XF 3 "binary_fp_operator"
15992 [(match_operand:XF 1 "register_operand" "0,f")
15993 (match_operand:XF 2 "register_operand" "f,0")]))]
15995 && !COMMUTATIVE_ARITH_P (operands[3])"
15996 "* return output_387_binary_op (insn, operands);"
15997 [(set (attr "type")
15998 (if_then_else (match_operand:XF 3 "div_operator")
15999 (const_string "fdiv")
16000 (const_string "fop")))
16001 (set_attr "mode" "XF")])
16003 (define_insn "*fop_<mode>_1"
16004 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,v")
16005 (match_operator:MODEF 3 "binary_fp_operator"
16006 [(match_operand:MODEF 1
16007 "x87nonimm_ssenomem_operand" "0,fm,0,v")
16008 (match_operand:MODEF 2
16009 "nonimmediate_operand" "fm,0,xm,vm")]))]
16010 "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16011 || (TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)))
16012 && !COMMUTATIVE_ARITH_P (operands[3])
16013 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16014 "* return output_387_binary_op (insn, operands);"
16015 [(set (attr "type")
16016 (if_then_else (eq_attr "alternative" "2,3")
16017 (if_then_else (match_operand:MODEF 3 "div_operator")
16018 (const_string "ssediv")
16019 (const_string "sseadd"))
16020 (if_then_else (match_operand:MODEF 3 "div_operator")
16021 (const_string "fdiv")
16022 (const_string "fop"))))
16023 (set_attr "isa" "*,*,noavx,avx")
16024 (set_attr "prefix" "orig,orig,orig,vex")
16025 (set_attr "mode" "<MODE>")
16026 (set (attr "enabled")
16028 (match_test ("SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"))
16030 (eq_attr "alternative" "0,1")
16031 (symbol_ref "TARGET_MIX_SSE_I387
16032 && X87_ENABLE_ARITH (<MODE>mode)")
16033 (const_string "*"))
16035 (eq_attr "alternative" "0,1")
16036 (symbol_ref "true")
16037 (symbol_ref "false"))))])
16039 (define_insn "*fop_<X87MODEF:mode>_2_i387"
16040 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
16041 (match_operator:X87MODEF 3 "binary_fp_operator"
16043 (match_operand:SWI24 1 "nonimmediate_operand" "m"))
16044 (match_operand:X87MODEF 2 "register_operand" "0")]))]
16045 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI24:MODE>mode)
16046 && !(SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
16047 && (TARGET_USE_<SWI24:MODE>MODE_FIOP
16048 || optimize_function_for_size_p (cfun))"
16049 "* return output_387_binary_op (insn, operands);"
16050 [(set (attr "type")
16051 (cond [(match_operand:X87MODEF 3 "mult_operator")
16052 (const_string "fmul")
16053 (match_operand:X87MODEF 3 "div_operator")
16054 (const_string "fdiv")
16056 (const_string "fop")))
16057 (set_attr "fp_int_src" "true")
16058 (set_attr "mode" "<SWI24:MODE>")])
16060 (define_insn "*fop_<X87MODEF:mode>_3_i387"
16061 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
16062 (match_operator:X87MODEF 3 "binary_fp_operator"
16063 [(match_operand:X87MODEF 1 "register_operand" "0")
16065 (match_operand:SWI24 2 "nonimmediate_operand" "m"))]))]
16066 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI24:MODE>mode)
16067 && !(SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
16068 && (TARGET_USE_<SWI24:MODE>MODE_FIOP
16069 || optimize_function_for_size_p (cfun))"
16070 "* return output_387_binary_op (insn, operands);"
16071 [(set (attr "type")
16072 (cond [(match_operand:X87MODEF 3 "mult_operator")
16073 (const_string "fmul")
16074 (match_operand:X87MODEF 3 "div_operator")
16075 (const_string "fdiv")
16077 (const_string "fop")))
16078 (set_attr "fp_int_src" "true")
16079 (set_attr "mode" "<SWI24:MODE>")])
16081 (define_insn "*fop_xf_4_i387"
16082 [(set (match_operand:XF 0 "register_operand" "=f,f")
16083 (match_operator:XF 3 "binary_fp_operator"
16085 (match_operand:MODEF 1 "nonimmediate_operand" "fm,0"))
16086 (match_operand:XF 2 "register_operand" "0,f")]))]
16088 "* return output_387_binary_op (insn, operands);"
16089 [(set (attr "type")
16090 (cond [(match_operand:XF 3 "mult_operator")
16091 (const_string "fmul")
16092 (match_operand:XF 3 "div_operator")
16093 (const_string "fdiv")
16095 (const_string "fop")))
16096 (set_attr "mode" "<MODE>")])
16098 (define_insn "*fop_df_4_i387"
16099 [(set (match_operand:DF 0 "register_operand" "=f,f")
16100 (match_operator:DF 3 "binary_fp_operator"
16102 (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
16103 (match_operand:DF 2 "register_operand" "0,f")]))]
16104 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
16105 && !(SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
16106 "* return output_387_binary_op (insn, operands);"
16107 [(set (attr "type")
16108 (cond [(match_operand:DF 3 "mult_operator")
16109 (const_string "fmul")
16110 (match_operand:DF 3 "div_operator")
16111 (const_string "fdiv")
16113 (const_string "fop")))
16114 (set_attr "mode" "SF")])
16116 (define_insn "*fop_xf_5_i387"
16117 [(set (match_operand:XF 0 "register_operand" "=f,f")
16118 (match_operator:XF 3 "binary_fp_operator"
16119 [(match_operand:XF 1 "register_operand" "0,f")
16121 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
16123 "* return output_387_binary_op (insn, operands);"
16124 [(set (attr "type")
16125 (cond [(match_operand:XF 3 "mult_operator")
16126 (const_string "fmul")
16127 (match_operand:XF 3 "div_operator")
16128 (const_string "fdiv")
16130 (const_string "fop")))
16131 (set_attr "mode" "<MODE>")])
16133 (define_insn "*fop_df_5_i387"
16134 [(set (match_operand:DF 0 "register_operand" "=f,f")
16135 (match_operator:DF 3 "binary_fp_operator"
16136 [(match_operand:DF 1 "register_operand" "0,f")
16138 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
16139 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
16140 && !(SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
16141 "* return output_387_binary_op (insn, operands);"
16142 [(set (attr "type")
16143 (cond [(match_operand:DF 3 "mult_operator")
16144 (const_string "fmul")
16145 (match_operand:DF 3 "div_operator")
16146 (const_string "fdiv")
16148 (const_string "fop")))
16149 (set_attr "mode" "SF")])
16151 (define_insn "*fop_xf_6_i387"
16152 [(set (match_operand:XF 0 "register_operand" "=f,f")
16153 (match_operator:XF 3 "binary_fp_operator"
16155 (match_operand:MODEF 1 "register_operand" "0,f"))
16157 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
16159 "* return output_387_binary_op (insn, operands);"
16160 [(set (attr "type")
16161 (cond [(match_operand:XF 3 "mult_operator")
16162 (const_string "fmul")
16163 (match_operand:XF 3 "div_operator")
16164 (const_string "fdiv")
16166 (const_string "fop")))
16167 (set_attr "mode" "<MODE>")])
16169 (define_insn "*fop_df_6_i387"
16170 [(set (match_operand:DF 0 "register_operand" "=f,f")
16171 (match_operator:DF 3 "binary_fp_operator"
16173 (match_operand:SF 1 "register_operand" "0,f"))
16175 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
16176 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
16177 && !(SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
16178 "* return output_387_binary_op (insn, operands);"
16179 [(set (attr "type")
16180 (cond [(match_operand:DF 3 "mult_operator")
16181 (const_string "fmul")
16182 (match_operand:DF 3 "div_operator")
16183 (const_string "fdiv")
16185 (const_string "fop")))
16186 (set_attr "mode" "SF")])
16188 ;; FPU special functions.
16190 ;; This pattern implements a no-op XFmode truncation for
16191 ;; all fancy i386 XFmode math functions.
16193 (define_insn "truncxf<mode>2_i387_noop_unspec"
16194 [(set (match_operand:MODEF 0 "nonimmediate_operand" "=mf")
16195 (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")]
16196 UNSPEC_TRUNC_NOOP))]
16197 "TARGET_USE_FANCY_MATH_387"
16198 "* return output_387_reg_move (insn, operands);"
16199 [(set_attr "type" "fmov")
16200 (set_attr "mode" "<MODE>")])
16202 (define_insn "sqrtxf2"
16203 [(set (match_operand:XF 0 "register_operand" "=f")
16204 (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
16205 "TARGET_USE_FANCY_MATH_387"
16207 [(set_attr "type" "fpspc")
16208 (set_attr "mode" "XF")
16209 (set_attr "athlon_decode" "direct")
16210 (set_attr "amdfam10_decode" "direct")
16211 (set_attr "bdver1_decode" "direct")])
16213 (define_insn "*rsqrtsf2_sse"
16214 [(set (match_operand:SF 0 "register_operand" "=x,x,x")
16215 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "0,x,m")]
16217 "TARGET_SSE && TARGET_SSE_MATH"
16219 %vrsqrtss\t{%d1, %0|%0, %d1}
16220 %vrsqrtss\t{%d1, %0|%0, %d1}
16221 %vrsqrtss\t{%1, %d0|%d0, %1}"
16222 [(set_attr "type" "sse")
16223 (set_attr "atom_sse_attr" "rcp")
16224 (set_attr "btver2_sse_attr" "rcp")
16225 (set_attr "prefix" "maybe_vex")
16226 (set_attr "mode" "SF")
16227 (set_attr "avx_partial_xmm_update" "false,false,true")
16228 (set (attr "preferred_for_speed")
16229 (cond [(match_test "TARGET_AVX")
16230 (symbol_ref "true")
16231 (eq_attr "alternative" "1,2")
16232 (symbol_ref "!TARGET_SSE_PARTIAL_REG_DEPENDENCY")
16234 (symbol_ref "true")))])
16236 (define_expand "rsqrtsf2"
16237 [(set (match_operand:SF 0 "register_operand")
16238 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand")]
16240 "TARGET_SSE && TARGET_SSE_MATH"
16242 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
16246 (define_insn "*sqrt<mode>2_sse"
16247 [(set (match_operand:MODEF 0 "register_operand" "=v,v,v")
16249 (match_operand:MODEF 1 "nonimmediate_operand" "0,v,m")))]
16250 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16252 %vsqrt<ssemodesuffix>\t{%d1, %0|%0, %d1}
16253 %vsqrt<ssemodesuffix>\t{%d1, %0|%0, %d1}
16254 %vsqrt<ssemodesuffix>\t{%1, %d0|%d0, %1}"
16255 [(set_attr "type" "sse")
16256 (set_attr "atom_sse_attr" "sqrt")
16257 (set_attr "btver2_sse_attr" "sqrt")
16258 (set_attr "prefix" "maybe_vex")
16259 (set_attr "avx_partial_xmm_update" "false,false,true")
16260 (set_attr "mode" "<MODE>")
16261 (set (attr "preferred_for_speed")
16262 (cond [(match_test "TARGET_AVX")
16263 (symbol_ref "true")
16264 (eq_attr "alternative" "1,2")
16265 (symbol_ref "!TARGET_SSE_PARTIAL_REG_DEPENDENCY")
16267 (symbol_ref "true")))])
16269 (define_expand "sqrt<mode>2"
16270 [(set (match_operand:MODEF 0 "register_operand")
16272 (match_operand:MODEF 1 "nonimmediate_operand")))]
16273 "(TARGET_USE_FANCY_MATH_387 && X87_ENABLE_ARITH (<MODE>mode))
16274 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
16276 if (<MODE>mode == SFmode
16277 && TARGET_SSE && TARGET_SSE_MATH
16278 && TARGET_RECIP_SQRT
16279 && !optimize_function_for_size_p (cfun)
16280 && flag_finite_math_only && !flag_trapping_math
16281 && flag_unsafe_math_optimizations)
16283 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
16287 if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
16289 rtx op0 = gen_reg_rtx (XFmode);
16290 rtx op1 = gen_reg_rtx (XFmode);
16292 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16293 emit_insn (gen_sqrtxf2 (op0, op1));
16294 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
16299 (define_expand "hypot<mode>3"
16300 [(use (match_operand:MODEF 0 "register_operand"))
16301 (use (match_operand:MODEF 1 "general_operand"))
16302 (use (match_operand:MODEF 2 "general_operand"))]
16303 "TARGET_USE_FANCY_MATH_387
16304 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16305 || TARGET_MIX_SSE_I387)
16306 && flag_finite_math_only
16307 && flag_unsafe_math_optimizations"
16309 rtx op0 = gen_reg_rtx (XFmode);
16310 rtx op1 = gen_reg_rtx (XFmode);
16311 rtx op2 = gen_reg_rtx (XFmode);
16313 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
16314 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16316 emit_insn (gen_mulxf3 (op1, op1, op1));
16317 emit_insn (gen_mulxf3 (op2, op2, op2));
16318 emit_insn (gen_addxf3 (op0, op2, op1));
16319 emit_insn (gen_sqrtxf2 (op0, op0));
16321 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
16325 (define_insn "x86_fnstsw_1"
16326 [(set (match_operand:HI 0 "register_operand" "=a")
16327 (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
16330 [(set_attr "length" "2")
16331 (set_attr "mode" "SI")
16332 (set_attr "unit" "i387")])
16334 (define_insn "fpremxf4_i387"
16335 [(set (match_operand:XF 0 "register_operand" "=f")
16336 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16337 (match_operand:XF 3 "register_operand" "1")]
16339 (set (match_operand:XF 1 "register_operand" "=f")
16340 (unspec:XF [(match_dup 2) (match_dup 3)]
16342 (set (reg:CCFP FPSR_REG)
16343 (unspec:CCFP [(match_dup 2) (match_dup 3)]
16345 "TARGET_USE_FANCY_MATH_387
16346 && flag_finite_math_only"
16348 [(set_attr "type" "fpspc")
16349 (set_attr "znver1_decode" "vector")
16350 (set_attr "mode" "XF")])
16352 (define_expand "fmodxf3"
16353 [(use (match_operand:XF 0 "register_operand"))
16354 (use (match_operand:XF 1 "general_operand"))
16355 (use (match_operand:XF 2 "general_operand"))]
16356 "TARGET_USE_FANCY_MATH_387
16357 && flag_finite_math_only"
16359 rtx_code_label *label = gen_label_rtx ();
16361 rtx op1 = gen_reg_rtx (XFmode);
16362 rtx op2 = gen_reg_rtx (XFmode);
16364 emit_move_insn (op2, operands[2]);
16365 emit_move_insn (op1, operands[1]);
16367 emit_label (label);
16368 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
16369 ix86_emit_fp_unordered_jump (label);
16370 LABEL_NUSES (label) = 1;
16372 emit_move_insn (operands[0], op1);
16376 (define_expand "fmod<mode>3"
16377 [(use (match_operand:MODEF 0 "register_operand"))
16378 (use (match_operand:MODEF 1 "general_operand"))
16379 (use (match_operand:MODEF 2 "general_operand"))]
16380 "TARGET_USE_FANCY_MATH_387
16381 && flag_finite_math_only"
16383 rtx (*gen_truncxf) (rtx, rtx);
16385 rtx_code_label *label = gen_label_rtx ();
16387 rtx op1 = gen_reg_rtx (XFmode);
16388 rtx op2 = gen_reg_rtx (XFmode);
16390 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
16391 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16393 emit_label (label);
16394 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
16395 ix86_emit_fp_unordered_jump (label);
16396 LABEL_NUSES (label) = 1;
16398 /* Truncate the result properly for strict SSE math. */
16399 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16400 && !TARGET_MIX_SSE_I387)
16401 gen_truncxf = gen_truncxf<mode>2;
16403 gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
16405 emit_insn (gen_truncxf (operands[0], op1));
16409 (define_insn "fprem1xf4_i387"
16410 [(set (match_operand:XF 0 "register_operand" "=f")
16411 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16412 (match_operand:XF 3 "register_operand" "1")]
16414 (set (match_operand:XF 1 "register_operand" "=f")
16415 (unspec:XF [(match_dup 2) (match_dup 3)]
16417 (set (reg:CCFP FPSR_REG)
16418 (unspec:CCFP [(match_dup 2) (match_dup 3)]
16420 "TARGET_USE_FANCY_MATH_387
16421 && flag_finite_math_only"
16423 [(set_attr "type" "fpspc")
16424 (set_attr "znver1_decode" "vector")
16425 (set_attr "mode" "XF")])
16427 (define_expand "remainderxf3"
16428 [(use (match_operand:XF 0 "register_operand"))
16429 (use (match_operand:XF 1 "general_operand"))
16430 (use (match_operand:XF 2 "general_operand"))]
16431 "TARGET_USE_FANCY_MATH_387
16432 && flag_finite_math_only"
16434 rtx_code_label *label = gen_label_rtx ();
16436 rtx op1 = gen_reg_rtx (XFmode);
16437 rtx op2 = gen_reg_rtx (XFmode);
16439 emit_move_insn (op2, operands[2]);
16440 emit_move_insn (op1, operands[1]);
16442 emit_label (label);
16443 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
16444 ix86_emit_fp_unordered_jump (label);
16445 LABEL_NUSES (label) = 1;
16447 emit_move_insn (operands[0], op1);
16451 (define_expand "remainder<mode>3"
16452 [(use (match_operand:MODEF 0 "register_operand"))
16453 (use (match_operand:MODEF 1 "general_operand"))
16454 (use (match_operand:MODEF 2 "general_operand"))]
16455 "TARGET_USE_FANCY_MATH_387
16456 && flag_finite_math_only"
16458 rtx (*gen_truncxf) (rtx, rtx);
16460 rtx_code_label *label = gen_label_rtx ();
16462 rtx op1 = gen_reg_rtx (XFmode);
16463 rtx op2 = gen_reg_rtx (XFmode);
16465 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
16466 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16468 emit_label (label);
16470 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
16471 ix86_emit_fp_unordered_jump (label);
16472 LABEL_NUSES (label) = 1;
16474 /* Truncate the result properly for strict SSE math. */
16475 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16476 && !TARGET_MIX_SSE_I387)
16477 gen_truncxf = gen_truncxf<mode>2;
16479 gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
16481 emit_insn (gen_truncxf (operands[0], op1));
16485 (define_int_iterator SINCOS
16489 (define_int_attr sincos
16490 [(UNSPEC_SIN "sin")
16491 (UNSPEC_COS "cos")])
16493 (define_insn "<sincos>xf2"
16494 [(set (match_operand:XF 0 "register_operand" "=f")
16495 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16497 "TARGET_USE_FANCY_MATH_387
16498 && flag_unsafe_math_optimizations"
16500 [(set_attr "type" "fpspc")
16501 (set_attr "znver1_decode" "vector")
16502 (set_attr "mode" "XF")])
16504 (define_expand "<sincos><mode>2"
16505 [(set (match_operand:MODEF 0 "register_operand")
16506 (unspec:MODEF [(match_operand:MODEF 1 "general_operand")]
16508 "TARGET_USE_FANCY_MATH_387
16509 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16510 || TARGET_MIX_SSE_I387)
16511 && flag_unsafe_math_optimizations"
16513 rtx op0 = gen_reg_rtx (XFmode);
16514 rtx op1 = gen_reg_rtx (XFmode);
16516 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16517 emit_insn (gen_<sincos>xf2 (op0, op1));
16518 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
16522 (define_insn "sincosxf3"
16523 [(set (match_operand:XF 0 "register_operand" "=f")
16524 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16525 UNSPEC_SINCOS_COS))
16526 (set (match_operand:XF 1 "register_operand" "=f")
16527 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16528 "TARGET_USE_FANCY_MATH_387
16529 && flag_unsafe_math_optimizations"
16531 [(set_attr "type" "fpspc")
16532 (set_attr "znver1_decode" "vector")
16533 (set_attr "mode" "XF")])
16535 (define_expand "sincos<mode>3"
16536 [(use (match_operand:MODEF 0 "register_operand"))
16537 (use (match_operand:MODEF 1 "register_operand"))
16538 (use (match_operand:MODEF 2 "general_operand"))]
16539 "TARGET_USE_FANCY_MATH_387
16540 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16541 || TARGET_MIX_SSE_I387)
16542 && flag_unsafe_math_optimizations"
16544 rtx op0 = gen_reg_rtx (XFmode);
16545 rtx op1 = gen_reg_rtx (XFmode);
16546 rtx op2 = gen_reg_rtx (XFmode);
16548 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
16549 emit_insn (gen_sincosxf3 (op0, op1, op2));
16550 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
16551 emit_insn (gen_truncxf<mode>2 (operands[1], op1));
16555 (define_insn "fptanxf4_i387"
16556 [(set (match_operand:SF 0 "register_operand" "=f")
16557 (match_operand:SF 3 "const1_operand"))
16558 (set (match_operand:XF 1 "register_operand" "=f")
16559 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16561 "TARGET_USE_FANCY_MATH_387
16562 && flag_unsafe_math_optimizations"
16564 [(set_attr "type" "fpspc")
16565 (set_attr "znver1_decode" "vector")
16566 (set_attr "mode" "XF")])
16568 (define_expand "tanxf2"
16569 [(use (match_operand:XF 0 "register_operand"))
16570 (use (match_operand:XF 1 "register_operand"))]
16571 "TARGET_USE_FANCY_MATH_387
16572 && flag_unsafe_math_optimizations"
16574 rtx one = gen_reg_rtx (SFmode);
16575 emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1],
16576 CONST1_RTX (SFmode)));
16580 (define_expand "tan<mode>2"
16581 [(use (match_operand:MODEF 0 "register_operand"))
16582 (use (match_operand:MODEF 1 "general_operand"))]
16583 "TARGET_USE_FANCY_MATH_387
16584 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16585 || TARGET_MIX_SSE_I387)
16586 && flag_unsafe_math_optimizations"
16588 rtx op0 = gen_reg_rtx (XFmode);
16589 rtx op1 = gen_reg_rtx (XFmode);
16591 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16592 emit_insn (gen_tanxf2 (op0, op1));
16593 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
16597 (define_insn "atan2xf3"
16598 [(set (match_operand:XF 0 "register_operand" "=f")
16599 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16600 (match_operand:XF 1 "register_operand" "f")]
16602 (clobber (match_scratch:XF 3 "=1"))]
16603 "TARGET_USE_FANCY_MATH_387
16604 && flag_unsafe_math_optimizations"
16606 [(set_attr "type" "fpspc")
16607 (set_attr "znver1_decode" "vector")
16608 (set_attr "mode" "XF")])
16610 (define_expand "atan2<mode>3"
16611 [(use (match_operand:MODEF 0 "register_operand"))
16612 (use (match_operand:MODEF 1 "general_operand"))
16613 (use (match_operand:MODEF 2 "general_operand"))]
16614 "TARGET_USE_FANCY_MATH_387
16615 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16616 || TARGET_MIX_SSE_I387)
16617 && flag_unsafe_math_optimizations"
16619 rtx op0 = gen_reg_rtx (XFmode);
16620 rtx op1 = gen_reg_rtx (XFmode);
16621 rtx op2 = gen_reg_rtx (XFmode);
16623 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
16624 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16626 emit_insn (gen_atan2xf3 (op0, op1, op2));
16627 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
16631 (define_expand "atanxf2"
16632 [(parallel [(set (match_operand:XF 0 "register_operand")
16633 (unspec:XF [(match_dup 2)
16634 (match_operand:XF 1 "register_operand")]
16636 (clobber (scratch:XF))])]
16637 "TARGET_USE_FANCY_MATH_387
16638 && flag_unsafe_math_optimizations"
16639 "operands[2] = force_reg (XFmode, CONST1_RTX (XFmode));")
16641 (define_expand "atan<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_atanxf2 (op0, op1));
16654 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
16658 (define_expand "asinxf2"
16659 [(set (match_dup 2)
16660 (mult:XF (match_operand:XF 1 "register_operand")
16662 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
16663 (set (match_dup 5) (sqrt:XF (match_dup 4)))
16664 (parallel [(set (match_operand:XF 0 "register_operand")
16665 (unspec:XF [(match_dup 5) (match_dup 1)]
16667 (clobber (scratch:XF))])]
16668 "TARGET_USE_FANCY_MATH_387
16669 && flag_unsafe_math_optimizations"
16673 for (i = 2; i < 6; i++)
16674 operands[i] = gen_reg_rtx (XFmode);
16676 emit_move_insn (operands[3], CONST1_RTX (XFmode));
16679 (define_expand "asin<mode>2"
16680 [(use (match_operand:MODEF 0 "register_operand"))
16681 (use (match_operand:MODEF 1 "general_operand"))]
16682 "TARGET_USE_FANCY_MATH_387
16683 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16684 || TARGET_MIX_SSE_I387)
16685 && flag_unsafe_math_optimizations"
16687 rtx op0 = gen_reg_rtx (XFmode);
16688 rtx op1 = gen_reg_rtx (XFmode);
16690 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16691 emit_insn (gen_asinxf2 (op0, op1));
16692 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
16696 (define_expand "acosxf2"
16697 [(set (match_dup 2)
16698 (mult:XF (match_operand:XF 1 "register_operand")
16700 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
16701 (set (match_dup 5) (sqrt:XF (match_dup 4)))
16702 (parallel [(set (match_operand:XF 0 "register_operand")
16703 (unspec:XF [(match_dup 1) (match_dup 5)]
16705 (clobber (scratch:XF))])]
16706 "TARGET_USE_FANCY_MATH_387
16707 && flag_unsafe_math_optimizations"
16711 for (i = 2; i < 6; i++)
16712 operands[i] = gen_reg_rtx (XFmode);
16714 emit_move_insn (operands[3], CONST1_RTX (XFmode));
16717 (define_expand "acos<mode>2"
16718 [(use (match_operand:MODEF 0 "register_operand"))
16719 (use (match_operand:MODEF 1 "general_operand"))]
16720 "TARGET_USE_FANCY_MATH_387
16721 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16722 || TARGET_MIX_SSE_I387)
16723 && flag_unsafe_math_optimizations"
16725 rtx op0 = gen_reg_rtx (XFmode);
16726 rtx op1 = gen_reg_rtx (XFmode);
16728 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16729 emit_insn (gen_acosxf2 (op0, op1));
16730 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
16734 (define_expand "sinhxf2"
16735 [(use (match_operand:XF 0 "register_operand"))
16736 (use (match_operand:XF 1 "register_operand"))]
16737 "TARGET_USE_FANCY_MATH_387
16738 && flag_finite_math_only
16739 && flag_unsafe_math_optimizations"
16741 ix86_emit_i387_sinh (operands[0], operands[1]);
16745 (define_expand "sinh<mode>2"
16746 [(use (match_operand:MODEF 0 "register_operand"))
16747 (use (match_operand:MODEF 1 "general_operand"))]
16748 "TARGET_USE_FANCY_MATH_387
16749 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16750 || TARGET_MIX_SSE_I387)
16751 && flag_finite_math_only
16752 && flag_unsafe_math_optimizations"
16754 rtx op0 = gen_reg_rtx (XFmode);
16755 rtx op1 = gen_reg_rtx (XFmode);
16757 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16758 emit_insn (gen_sinhxf2 (op0, op1));
16759 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
16763 (define_expand "coshxf2"
16764 [(use (match_operand:XF 0 "register_operand"))
16765 (use (match_operand:XF 1 "register_operand"))]
16766 "TARGET_USE_FANCY_MATH_387
16767 && flag_unsafe_math_optimizations"
16769 ix86_emit_i387_cosh (operands[0], operands[1]);
16773 (define_expand "cosh<mode>2"
16774 [(use (match_operand:MODEF 0 "register_operand"))
16775 (use (match_operand:MODEF 1 "general_operand"))]
16776 "TARGET_USE_FANCY_MATH_387
16777 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16778 || TARGET_MIX_SSE_I387)
16779 && flag_unsafe_math_optimizations"
16781 rtx op0 = gen_reg_rtx (XFmode);
16782 rtx op1 = gen_reg_rtx (XFmode);
16784 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16785 emit_insn (gen_coshxf2 (op0, op1));
16786 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
16790 (define_expand "tanhxf2"
16791 [(use (match_operand:XF 0 "register_operand"))
16792 (use (match_operand:XF 1 "register_operand"))]
16793 "TARGET_USE_FANCY_MATH_387
16794 && flag_unsafe_math_optimizations"
16796 ix86_emit_i387_tanh (operands[0], operands[1]);
16800 (define_expand "tanh<mode>2"
16801 [(use (match_operand:MODEF 0 "register_operand"))
16802 (use (match_operand:MODEF 1 "general_operand"))]
16803 "TARGET_USE_FANCY_MATH_387
16804 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16805 || TARGET_MIX_SSE_I387)
16806 && flag_unsafe_math_optimizations"
16808 rtx op0 = gen_reg_rtx (XFmode);
16809 rtx op1 = gen_reg_rtx (XFmode);
16811 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16812 emit_insn (gen_tanhxf2 (op0, op1));
16813 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
16817 (define_expand "asinhxf2"
16818 [(use (match_operand:XF 0 "register_operand"))
16819 (use (match_operand:XF 1 "register_operand"))]
16820 "TARGET_USE_FANCY_MATH_387
16821 && flag_finite_math_only
16822 && flag_unsafe_math_optimizations"
16824 ix86_emit_i387_asinh (operands[0], operands[1]);
16828 (define_expand "asinh<mode>2"
16829 [(use (match_operand:MODEF 0 "register_operand"))
16830 (use (match_operand:MODEF 1 "general_operand"))]
16831 "TARGET_USE_FANCY_MATH_387
16832 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16833 || TARGET_MIX_SSE_I387)
16834 && flag_finite_math_only
16835 && flag_unsafe_math_optimizations"
16837 rtx op0 = gen_reg_rtx (XFmode);
16838 rtx op1 = gen_reg_rtx (XFmode);
16840 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16841 emit_insn (gen_asinhxf2 (op0, op1));
16842 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
16846 (define_expand "acoshxf2"
16847 [(use (match_operand:XF 0 "register_operand"))
16848 (use (match_operand:XF 1 "register_operand"))]
16849 "TARGET_USE_FANCY_MATH_387
16850 && flag_unsafe_math_optimizations"
16852 ix86_emit_i387_acosh (operands[0], operands[1]);
16856 (define_expand "acosh<mode>2"
16857 [(use (match_operand:MODEF 0 "register_operand"))
16858 (use (match_operand:MODEF 1 "general_operand"))]
16859 "TARGET_USE_FANCY_MATH_387
16860 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16861 || TARGET_MIX_SSE_I387)
16862 && flag_unsafe_math_optimizations"
16864 rtx op0 = gen_reg_rtx (XFmode);
16865 rtx op1 = gen_reg_rtx (XFmode);
16867 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16868 emit_insn (gen_acoshxf2 (op0, op1));
16869 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
16873 (define_expand "atanhxf2"
16874 [(use (match_operand:XF 0 "register_operand"))
16875 (use (match_operand:XF 1 "register_operand"))]
16876 "TARGET_USE_FANCY_MATH_387
16877 && flag_unsafe_math_optimizations"
16879 ix86_emit_i387_atanh (operands[0], operands[1]);
16883 (define_expand "atanh<mode>2"
16884 [(use (match_operand:MODEF 0 "register_operand"))
16885 (use (match_operand:MODEF 1 "general_operand"))]
16886 "TARGET_USE_FANCY_MATH_387
16887 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16888 || TARGET_MIX_SSE_I387)
16889 && flag_unsafe_math_optimizations"
16891 rtx op0 = gen_reg_rtx (XFmode);
16892 rtx op1 = gen_reg_rtx (XFmode);
16894 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16895 emit_insn (gen_atanhxf2 (op0, op1));
16896 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
16900 (define_insn "fyl2xxf3_i387"
16901 [(set (match_operand:XF 0 "register_operand" "=f")
16902 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
16903 (match_operand:XF 2 "register_operand" "f")]
16905 (clobber (match_scratch:XF 3 "=2"))]
16906 "TARGET_USE_FANCY_MATH_387
16907 && flag_unsafe_math_optimizations"
16909 [(set_attr "type" "fpspc")
16910 (set_attr "znver1_decode" "vector")
16911 (set_attr "mode" "XF")])
16913 (define_expand "logxf2"
16914 [(parallel [(set (match_operand:XF 0 "register_operand")
16915 (unspec:XF [(match_operand:XF 1 "register_operand")
16916 (match_dup 2)] UNSPEC_FYL2X))
16917 (clobber (scratch:XF))])]
16918 "TARGET_USE_FANCY_MATH_387
16919 && flag_unsafe_math_optimizations"
16922 = force_reg (XFmode, standard_80387_constant_rtx (4)); /* fldln2 */
16925 (define_expand "log<mode>2"
16926 [(use (match_operand:MODEF 0 "register_operand"))
16927 (use (match_operand:MODEF 1 "general_operand"))]
16928 "TARGET_USE_FANCY_MATH_387
16929 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16930 || TARGET_MIX_SSE_I387)
16931 && flag_unsafe_math_optimizations"
16933 rtx op0 = gen_reg_rtx (XFmode);
16934 rtx op1 = gen_reg_rtx (XFmode);
16936 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16937 emit_insn (gen_logxf2 (op0, op1));
16938 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
16942 (define_expand "log10xf2"
16943 [(parallel [(set (match_operand:XF 0 "register_operand")
16944 (unspec:XF [(match_operand:XF 1 "register_operand")
16945 (match_dup 2)] UNSPEC_FYL2X))
16946 (clobber (scratch:XF))])]
16947 "TARGET_USE_FANCY_MATH_387
16948 && flag_unsafe_math_optimizations"
16951 = force_reg (XFmode, standard_80387_constant_rtx (3)); /* fldlg2 */
16954 (define_expand "log10<mode>2"
16955 [(use (match_operand:MODEF 0 "register_operand"))
16956 (use (match_operand:MODEF 1 "general_operand"))]
16957 "TARGET_USE_FANCY_MATH_387
16958 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16959 || TARGET_MIX_SSE_I387)
16960 && flag_unsafe_math_optimizations"
16962 rtx op0 = gen_reg_rtx (XFmode);
16963 rtx op1 = gen_reg_rtx (XFmode);
16965 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16966 emit_insn (gen_log10xf2 (op0, op1));
16967 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
16971 (define_expand "log2xf2"
16972 [(parallel [(set (match_operand:XF 0 "register_operand")
16973 (unspec:XF [(match_operand:XF 1 "register_operand")
16974 (match_dup 2)] UNSPEC_FYL2X))
16975 (clobber (scratch:XF))])]
16976 "TARGET_USE_FANCY_MATH_387
16977 && flag_unsafe_math_optimizations"
16978 "operands[2] = force_reg (XFmode, CONST1_RTX (XFmode));")
16980 (define_expand "log2<mode>2"
16981 [(use (match_operand:MODEF 0 "register_operand"))
16982 (use (match_operand:MODEF 1 "general_operand"))]
16983 "TARGET_USE_FANCY_MATH_387
16984 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16985 || TARGET_MIX_SSE_I387)
16986 && flag_unsafe_math_optimizations"
16988 rtx op0 = gen_reg_rtx (XFmode);
16989 rtx op1 = gen_reg_rtx (XFmode);
16991 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16992 emit_insn (gen_log2xf2 (op0, op1));
16993 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
16997 (define_insn "fyl2xp1xf3_i387"
16998 [(set (match_operand:XF 0 "register_operand" "=f")
16999 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
17000 (match_operand:XF 2 "register_operand" "f")]
17002 (clobber (match_scratch:XF 3 "=2"))]
17003 "TARGET_USE_FANCY_MATH_387
17004 && flag_unsafe_math_optimizations"
17006 [(set_attr "type" "fpspc")
17007 (set_attr "znver1_decode" "vector")
17008 (set_attr "mode" "XF")])
17010 (define_expand "log1pxf2"
17011 [(use (match_operand:XF 0 "register_operand"))
17012 (use (match_operand:XF 1 "register_operand"))]
17013 "TARGET_USE_FANCY_MATH_387
17014 && flag_unsafe_math_optimizations"
17016 ix86_emit_i387_log1p (operands[0], operands[1]);
17020 (define_expand "log1p<mode>2"
17021 [(use (match_operand:MODEF 0 "register_operand"))
17022 (use (match_operand:MODEF 1 "general_operand"))]
17023 "TARGET_USE_FANCY_MATH_387
17024 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17025 || TARGET_MIX_SSE_I387)
17026 && flag_unsafe_math_optimizations"
17028 rtx op0 = gen_reg_rtx (XFmode);
17029 rtx op1 = gen_reg_rtx (XFmode);
17031 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17032 emit_insn (gen_log1pxf2 (op0, op1));
17033 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
17037 (define_insn "fxtractxf3_i387"
17038 [(set (match_operand:XF 0 "register_operand" "=f")
17039 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
17040 UNSPEC_XTRACT_FRACT))
17041 (set (match_operand:XF 1 "register_operand" "=f")
17042 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
17043 "TARGET_USE_FANCY_MATH_387
17044 && flag_unsafe_math_optimizations"
17046 [(set_attr "type" "fpspc")
17047 (set_attr "znver1_decode" "vector")
17048 (set_attr "mode" "XF")])
17050 (define_expand "logbxf2"
17051 [(parallel [(set (match_dup 2)
17052 (unspec:XF [(match_operand:XF 1 "register_operand")]
17053 UNSPEC_XTRACT_FRACT))
17054 (set (match_operand:XF 0 "register_operand")
17055 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
17056 "TARGET_USE_FANCY_MATH_387
17057 && flag_unsafe_math_optimizations"
17058 "operands[2] = gen_reg_rtx (XFmode);")
17060 (define_expand "logb<mode>2"
17061 [(use (match_operand:MODEF 0 "register_operand"))
17062 (use (match_operand:MODEF 1 "general_operand"))]
17063 "TARGET_USE_FANCY_MATH_387
17064 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17065 || TARGET_MIX_SSE_I387)
17066 && flag_unsafe_math_optimizations"
17068 rtx op0 = gen_reg_rtx (XFmode);
17069 rtx op1 = gen_reg_rtx (XFmode);
17071 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17072 emit_insn (gen_logbxf2 (op0, op1));
17073 emit_insn (gen_truncxf<mode>2 (operands[0], op1));
17077 (define_expand "ilogbxf2"
17078 [(use (match_operand:SI 0 "register_operand"))
17079 (use (match_operand:XF 1 "register_operand"))]
17080 "TARGET_USE_FANCY_MATH_387
17081 && flag_unsafe_math_optimizations"
17085 if (optimize_insn_for_size_p ())
17088 op0 = gen_reg_rtx (XFmode);
17089 op1 = gen_reg_rtx (XFmode);
17091 emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
17092 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
17096 (define_expand "ilogb<mode>2"
17097 [(use (match_operand:SI 0 "register_operand"))
17098 (use (match_operand:MODEF 1 "general_operand"))]
17099 "TARGET_USE_FANCY_MATH_387
17100 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17101 || TARGET_MIX_SSE_I387)
17102 && flag_unsafe_math_optimizations"
17106 if (optimize_insn_for_size_p ())
17109 op0 = gen_reg_rtx (XFmode);
17110 op1 = gen_reg_rtx (XFmode);
17111 op2 = gen_reg_rtx (XFmode);
17113 emit_insn (gen_extend<mode>xf2 (op2, operands[1]));
17114 emit_insn (gen_fxtractxf3_i387 (op0, op1, op2));
17115 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
17119 (define_insn "*f2xm1xf2_i387"
17120 [(set (match_operand:XF 0 "register_operand" "=f")
17121 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17123 "TARGET_USE_FANCY_MATH_387
17124 && flag_unsafe_math_optimizations"
17126 [(set_attr "type" "fpspc")
17127 (set_attr "znver1_decode" "vector")
17128 (set_attr "mode" "XF")])
17130 (define_insn "fscalexf4_i387"
17131 [(set (match_operand:XF 0 "register_operand" "=f")
17132 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
17133 (match_operand:XF 3 "register_operand" "1")]
17134 UNSPEC_FSCALE_FRACT))
17135 (set (match_operand:XF 1 "register_operand" "=f")
17136 (unspec:XF [(match_dup 2) (match_dup 3)]
17137 UNSPEC_FSCALE_EXP))]
17138 "TARGET_USE_FANCY_MATH_387
17139 && flag_unsafe_math_optimizations"
17141 [(set_attr "type" "fpspc")
17142 (set_attr "znver1_decode" "vector")
17143 (set_attr "mode" "XF")])
17145 (define_expand "expNcorexf3"
17146 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand")
17147 (match_operand:XF 2 "register_operand")))
17148 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
17149 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
17150 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
17151 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
17152 (parallel [(set (match_operand:XF 0 "register_operand")
17153 (unspec:XF [(match_dup 8) (match_dup 4)]
17154 UNSPEC_FSCALE_FRACT))
17156 (unspec:XF [(match_dup 8) (match_dup 4)]
17157 UNSPEC_FSCALE_EXP))])]
17158 "TARGET_USE_FANCY_MATH_387
17159 && flag_unsafe_math_optimizations"
17163 for (i = 3; i < 10; i++)
17164 operands[i] = gen_reg_rtx (XFmode);
17166 emit_move_insn (operands[7], CONST1_RTX (XFmode));
17169 (define_expand "expxf2"
17170 [(use (match_operand:XF 0 "register_operand"))
17171 (use (match_operand:XF 1 "register_operand"))]
17172 "TARGET_USE_FANCY_MATH_387
17173 && flag_unsafe_math_optimizations"
17175 rtx op2 = force_reg (XFmode, standard_80387_constant_rtx (5)); /* fldl2e */
17177 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
17181 (define_expand "exp<mode>2"
17182 [(use (match_operand:MODEF 0 "register_operand"))
17183 (use (match_operand:MODEF 1 "general_operand"))]
17184 "TARGET_USE_FANCY_MATH_387
17185 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17186 || TARGET_MIX_SSE_I387)
17187 && flag_unsafe_math_optimizations"
17189 rtx op0 = gen_reg_rtx (XFmode);
17190 rtx op1 = gen_reg_rtx (XFmode);
17192 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17193 emit_insn (gen_expxf2 (op0, op1));
17194 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
17198 (define_expand "exp10xf2"
17199 [(use (match_operand:XF 0 "register_operand"))
17200 (use (match_operand:XF 1 "register_operand"))]
17201 "TARGET_USE_FANCY_MATH_387
17202 && flag_unsafe_math_optimizations"
17204 rtx op2 = force_reg (XFmode, standard_80387_constant_rtx (6)); /* fldl2t */
17206 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
17210 (define_expand "exp10<mode>2"
17211 [(use (match_operand:MODEF 0 "register_operand"))
17212 (use (match_operand:MODEF 1 "general_operand"))]
17213 "TARGET_USE_FANCY_MATH_387
17214 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17215 || TARGET_MIX_SSE_I387)
17216 && flag_unsafe_math_optimizations"
17218 rtx op0 = gen_reg_rtx (XFmode);
17219 rtx op1 = gen_reg_rtx (XFmode);
17221 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17222 emit_insn (gen_exp10xf2 (op0, op1));
17223 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
17227 (define_expand "exp2xf2"
17228 [(use (match_operand:XF 0 "register_operand"))
17229 (use (match_operand:XF 1 "register_operand"))]
17230 "TARGET_USE_FANCY_MATH_387
17231 && flag_unsafe_math_optimizations"
17233 rtx op2 = force_reg (XFmode, CONST1_RTX (XFmode));
17235 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
17239 (define_expand "exp2<mode>2"
17240 [(use (match_operand:MODEF 0 "register_operand"))
17241 (use (match_operand:MODEF 1 "general_operand"))]
17242 "TARGET_USE_FANCY_MATH_387
17243 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17244 || TARGET_MIX_SSE_I387)
17245 && flag_unsafe_math_optimizations"
17247 rtx op0 = gen_reg_rtx (XFmode);
17248 rtx op1 = gen_reg_rtx (XFmode);
17250 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17251 emit_insn (gen_exp2xf2 (op0, op1));
17252 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
17256 (define_expand "expm1xf2"
17257 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand")
17259 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
17260 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
17261 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
17262 (parallel [(set (match_dup 7)
17263 (unspec:XF [(match_dup 6) (match_dup 4)]
17264 UNSPEC_FSCALE_FRACT))
17266 (unspec:XF [(match_dup 6) (match_dup 4)]
17267 UNSPEC_FSCALE_EXP))])
17268 (parallel [(set (match_dup 10)
17269 (unspec:XF [(match_dup 9) (match_dup 8)]
17270 UNSPEC_FSCALE_FRACT))
17271 (set (match_dup 11)
17272 (unspec:XF [(match_dup 9) (match_dup 8)]
17273 UNSPEC_FSCALE_EXP))])
17274 (set (match_dup 12) (minus:XF (match_dup 10) (match_dup 9)))
17275 (set (match_operand:XF 0 "register_operand")
17276 (plus:XF (match_dup 12) (match_dup 7)))]
17277 "TARGET_USE_FANCY_MATH_387
17278 && flag_unsafe_math_optimizations"
17282 for (i = 2; i < 13; i++)
17283 operands[i] = gen_reg_rtx (XFmode);
17285 emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
17286 emit_move_insn (operands[9], CONST1_RTX (XFmode));
17289 (define_expand "expm1<mode>2"
17290 [(use (match_operand:MODEF 0 "register_operand"))
17291 (use (match_operand:MODEF 1 "general_operand"))]
17292 "TARGET_USE_FANCY_MATH_387
17293 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17294 || TARGET_MIX_SSE_I387)
17295 && flag_unsafe_math_optimizations"
17297 rtx op0 = gen_reg_rtx (XFmode);
17298 rtx op1 = gen_reg_rtx (XFmode);
17300 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17301 emit_insn (gen_expm1xf2 (op0, op1));
17302 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
17306 (define_expand "ldexpxf3"
17307 [(match_operand:XF 0 "register_operand")
17308 (match_operand:XF 1 "register_operand")
17309 (match_operand:SI 2 "register_operand")]
17310 "TARGET_USE_FANCY_MATH_387
17311 && flag_unsafe_math_optimizations"
17313 rtx tmp1 = gen_reg_rtx (XFmode);
17314 rtx tmp2 = gen_reg_rtx (XFmode);
17316 emit_insn (gen_floatsixf2 (tmp1, operands[2]));
17317 emit_insn (gen_fscalexf4_i387 (operands[0], tmp2,
17318 operands[1], tmp1));
17322 (define_expand "ldexp<mode>3"
17323 [(use (match_operand:MODEF 0 "register_operand"))
17324 (use (match_operand:MODEF 1 "general_operand"))
17325 (use (match_operand:SI 2 "register_operand"))]
17326 "TARGET_USE_FANCY_MATH_387
17327 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17328 || TARGET_MIX_SSE_I387)
17329 && flag_unsafe_math_optimizations"
17331 rtx op0 = gen_reg_rtx (XFmode);
17332 rtx op1 = gen_reg_rtx (XFmode);
17334 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17335 emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
17336 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
17340 (define_expand "scalbxf3"
17341 [(parallel [(set (match_operand:XF 0 " register_operand")
17342 (unspec:XF [(match_operand:XF 1 "register_operand")
17343 (match_operand:XF 2 "register_operand")]
17344 UNSPEC_FSCALE_FRACT))
17346 (unspec:XF [(match_dup 1) (match_dup 2)]
17347 UNSPEC_FSCALE_EXP))])]
17348 "TARGET_USE_FANCY_MATH_387
17349 && flag_unsafe_math_optimizations"
17350 "operands[3] = gen_reg_rtx (XFmode);")
17352 (define_expand "scalb<mode>3"
17353 [(use (match_operand:MODEF 0 "register_operand"))
17354 (use (match_operand:MODEF 1 "general_operand"))
17355 (use (match_operand:MODEF 2 "general_operand"))]
17356 "TARGET_USE_FANCY_MATH_387
17357 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17358 || TARGET_MIX_SSE_I387)
17359 && flag_unsafe_math_optimizations"
17361 rtx op0 = gen_reg_rtx (XFmode);
17362 rtx op1 = gen_reg_rtx (XFmode);
17363 rtx op2 = gen_reg_rtx (XFmode);
17365 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17366 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
17367 emit_insn (gen_scalbxf3 (op0, op1, op2));
17368 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
17372 (define_expand "significandxf2"
17373 [(parallel [(set (match_operand:XF 0 "register_operand")
17374 (unspec:XF [(match_operand:XF 1 "register_operand")]
17375 UNSPEC_XTRACT_FRACT))
17377 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
17378 "TARGET_USE_FANCY_MATH_387
17379 && flag_unsafe_math_optimizations"
17380 "operands[2] = gen_reg_rtx (XFmode);")
17382 (define_expand "significand<mode>2"
17383 [(use (match_operand:MODEF 0 "register_operand"))
17384 (use (match_operand:MODEF 1 "general_operand"))]
17385 "TARGET_USE_FANCY_MATH_387
17386 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17387 || TARGET_MIX_SSE_I387)
17388 && flag_unsafe_math_optimizations"
17390 rtx op0 = gen_reg_rtx (XFmode);
17391 rtx op1 = gen_reg_rtx (XFmode);
17393 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17394 emit_insn (gen_significandxf2 (op0, op1));
17395 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
17400 (define_insn "sse4_1_round<mode>2"
17401 [(set (match_operand:MODEF 0 "register_operand" "=x,x,x,v,v")
17403 [(match_operand:MODEF 1 "nonimmediate_operand" "0,x,m,v,m")
17404 (match_operand:SI 2 "const_0_to_15_operand" "n,n,n,n,n")]
17408 %vround<ssemodesuffix>\t{%2, %d1, %0|%0, %d1, %2}
17409 %vround<ssemodesuffix>\t{%2, %d1, %0|%0, %d1, %2}
17410 %vround<ssemodesuffix>\t{%2, %1, %d0|%d0, %1, %2}
17411 vrndscale<ssemodesuffix>\t{%2, %d1, %0|%0, %d1, %2}
17412 vrndscale<ssemodesuffix>\t{%2, %1, %d0|%d0, %1, %2}"
17413 [(set_attr "type" "ssecvt")
17414 (set_attr "prefix_extra" "1,1,1,*,*")
17415 (set_attr "length_immediate" "*,*,*,1,1")
17416 (set_attr "prefix" "maybe_vex,maybe_vex,maybe_vex,evex,evex")
17417 (set_attr "isa" "noavx512f,noavx512f,noavx512f,avx512f,avx512f")
17418 (set_attr "avx_partial_xmm_update" "false,false,true,false,true")
17419 (set_attr "mode" "<MODE>")
17420 (set (attr "preferred_for_speed")
17421 (cond [(match_test "TARGET_AVX")
17422 (symbol_ref "true")
17423 (eq_attr "alternative" "1,2")
17424 (symbol_ref "!TARGET_SSE_PARTIAL_REG_DEPENDENCY")
17426 (symbol_ref "true")))])
17428 (define_insn "rintxf2"
17429 [(set (match_operand:XF 0 "register_operand" "=f")
17430 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17432 "TARGET_USE_FANCY_MATH_387"
17434 [(set_attr "type" "fpspc")
17435 (set_attr "znver1_decode" "vector")
17436 (set_attr "mode" "XF")])
17438 (define_expand "rint<mode>2"
17439 [(use (match_operand:MODEF 0 "register_operand"))
17440 (use (match_operand:MODEF 1 "nonimmediate_operand"))]
17441 "TARGET_USE_FANCY_MATH_387
17442 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
17444 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17447 emit_insn (gen_sse4_1_round<mode>2
17448 (operands[0], operands[1], GEN_INT (ROUND_MXCSR)));
17450 ix86_expand_rint (operands[0], operands[1]);
17454 rtx op0 = gen_reg_rtx (XFmode);
17455 rtx op1 = gen_reg_rtx (XFmode);
17457 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17458 emit_insn (gen_rintxf2 (op0, op1));
17459 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
17464 (define_expand "nearbyintxf2"
17465 [(set (match_operand:XF 0 "register_operand")
17466 (unspec:XF [(match_operand:XF 1 "register_operand")]
17468 "TARGET_USE_FANCY_MATH_387
17469 && !flag_trapping_math")
17471 (define_expand "nearbyint<mode>2"
17472 [(use (match_operand:MODEF 0 "register_operand"))
17473 (use (match_operand:MODEF 1 "nonimmediate_operand"))]
17474 "(TARGET_USE_FANCY_MATH_387
17475 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17476 || TARGET_MIX_SSE_I387)
17477 && !flag_trapping_math)
17478 || (TARGET_SSE4_1 && TARGET_SSE_MATH)"
17480 if (TARGET_SSE4_1 && TARGET_SSE_MATH)
17481 emit_insn (gen_sse4_1_round<mode>2
17482 (operands[0], operands[1], GEN_INT (ROUND_MXCSR
17486 rtx op0 = gen_reg_rtx (XFmode);
17487 rtx op1 = gen_reg_rtx (XFmode);
17489 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17490 emit_insn (gen_nearbyintxf2 (op0, op1));
17491 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
17496 (define_expand "round<mode>2"
17497 [(match_operand:X87MODEF 0 "register_operand")
17498 (match_operand:X87MODEF 1 "nonimmediate_operand")]
17499 "(TARGET_USE_FANCY_MATH_387
17500 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17501 || TARGET_MIX_SSE_I387)
17502 && flag_unsafe_math_optimizations
17503 && (flag_fp_int_builtin_inexact || !flag_trapping_math))
17504 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17505 && !flag_trapping_math && !flag_rounding_math)"
17507 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17508 && !flag_trapping_math && !flag_rounding_math)
17512 operands[1] = force_reg (<MODE>mode, operands[1]);
17513 ix86_expand_round_sse4 (operands[0], operands[1]);
17515 else if (TARGET_64BIT || (<MODE>mode != DFmode))
17516 ix86_expand_round (operands[0], operands[1]);
17518 ix86_expand_rounddf_32 (operands[0], operands[1]);
17522 operands[1] = force_reg (<MODE>mode, operands[1]);
17523 ix86_emit_i387_round (operands[0], operands[1]);
17528 (define_insn "lrintxfdi2"
17529 [(set (match_operand:DI 0 "nonimmediate_operand" "=m")
17530 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17532 (clobber (match_scratch:XF 2 "=&f"))]
17533 "TARGET_USE_FANCY_MATH_387"
17534 "* return output_fix_trunc (insn, operands, false);"
17535 [(set_attr "type" "fpspc")
17536 (set_attr "mode" "DI")])
17538 (define_insn "lrintxf<mode>2"
17539 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m")
17540 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
17542 "TARGET_USE_FANCY_MATH_387"
17543 "* return output_fix_trunc (insn, operands, false);"
17544 [(set_attr "type" "fpspc")
17545 (set_attr "mode" "<MODE>")])
17547 (define_expand "lrint<MODEF:mode><SWI48:mode>2"
17548 [(set (match_operand:SWI48 0 "nonimmediate_operand")
17549 (unspec:SWI48 [(match_operand:MODEF 1 "register_operand")]
17550 UNSPEC_FIX_NOTRUNC))]
17551 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH")
17553 (define_expand "lround<X87MODEF:mode><SWI248x:mode>2"
17554 [(match_operand:SWI248x 0 "nonimmediate_operand")
17555 (match_operand:X87MODEF 1 "register_operand")]
17556 "(TARGET_USE_FANCY_MATH_387
17557 && (!(SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
17558 || TARGET_MIX_SSE_I387)
17559 && flag_unsafe_math_optimizations)
17560 || (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
17561 && <SWI248x:MODE>mode != HImode
17562 && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT)
17563 && !flag_trapping_math && !flag_rounding_math)"
17565 if (optimize_insn_for_size_p ())
17568 if (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
17569 && <SWI248x:MODE>mode != HImode
17570 && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT)
17571 && !flag_trapping_math && !flag_rounding_math)
17572 ix86_expand_lround (operands[0], operands[1]);
17574 ix86_emit_i387_round (operands[0], operands[1]);
17578 (define_int_iterator FRNDINT_ROUNDING
17579 [UNSPEC_FRNDINT_ROUNDEVEN
17580 UNSPEC_FRNDINT_FLOOR
17581 UNSPEC_FRNDINT_CEIL
17582 UNSPEC_FRNDINT_TRUNC])
17584 (define_int_iterator FIST_ROUNDING
17588 ;; Base name for define_insn
17589 (define_int_attr rounding_insn
17590 [(UNSPEC_FRNDINT_ROUNDEVEN "roundeven")
17591 (UNSPEC_FRNDINT_FLOOR "floor")
17592 (UNSPEC_FRNDINT_CEIL "ceil")
17593 (UNSPEC_FRNDINT_TRUNC "btrunc")
17594 (UNSPEC_FIST_FLOOR "floor")
17595 (UNSPEC_FIST_CEIL "ceil")])
17597 (define_int_attr rounding
17598 [(UNSPEC_FRNDINT_ROUNDEVEN "roundeven")
17599 (UNSPEC_FRNDINT_FLOOR "floor")
17600 (UNSPEC_FRNDINT_CEIL "ceil")
17601 (UNSPEC_FRNDINT_TRUNC "trunc")
17602 (UNSPEC_FIST_FLOOR "floor")
17603 (UNSPEC_FIST_CEIL "ceil")])
17605 (define_int_attr ROUNDING
17606 [(UNSPEC_FRNDINT_ROUNDEVEN "ROUNDEVEN")
17607 (UNSPEC_FRNDINT_FLOOR "FLOOR")
17608 (UNSPEC_FRNDINT_CEIL "CEIL")
17609 (UNSPEC_FRNDINT_TRUNC "TRUNC")
17610 (UNSPEC_FIST_FLOOR "FLOOR")
17611 (UNSPEC_FIST_CEIL "CEIL")])
17613 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17614 (define_insn_and_split "frndintxf2_<rounding>"
17615 [(set (match_operand:XF 0 "register_operand")
17616 (unspec:XF [(match_operand:XF 1 "register_operand")]
17618 (clobber (reg:CC FLAGS_REG))]
17619 "TARGET_USE_FANCY_MATH_387
17620 && (flag_fp_int_builtin_inexact || !flag_trapping_math)
17621 && ix86_pre_reload_split ()"
17626 ix86_optimize_mode_switching[I387_<ROUNDING>] = 1;
17628 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17629 operands[3] = assign_386_stack_local (HImode, SLOT_CW_<ROUNDING>);
17631 emit_insn (gen_frndintxf2_<rounding>_i387 (operands[0], operands[1],
17632 operands[2], operands[3]));
17635 [(set_attr "type" "frndint")
17636 (set_attr "i387_cw" "<rounding>")
17637 (set_attr "mode" "XF")])
17639 (define_insn "frndintxf2_<rounding>_i387"
17640 [(set (match_operand:XF 0 "register_operand" "=f")
17641 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17643 (use (match_operand:HI 2 "memory_operand" "m"))
17644 (use (match_operand:HI 3 "memory_operand" "m"))]
17645 "TARGET_USE_FANCY_MATH_387
17646 && (flag_fp_int_builtin_inexact || !flag_trapping_math)"
17647 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
17648 [(set_attr "type" "frndint")
17649 (set_attr "i387_cw" "<rounding>")
17650 (set_attr "mode" "XF")])
17652 (define_expand "<rounding_insn>xf2"
17653 [(parallel [(set (match_operand:XF 0 "register_operand")
17654 (unspec:XF [(match_operand:XF 1 "register_operand")]
17656 (clobber (reg:CC FLAGS_REG))])]
17657 "TARGET_USE_FANCY_MATH_387
17658 && (flag_fp_int_builtin_inexact || !flag_trapping_math)")
17660 (define_expand "<rounding_insn><mode>2"
17661 [(parallel [(set (match_operand:MODEF 0 "register_operand")
17662 (unspec:MODEF [(match_operand:MODEF 1 "register_operand")]
17664 (clobber (reg:CC FLAGS_REG))])]
17665 "(TARGET_USE_FANCY_MATH_387
17666 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17667 || TARGET_MIX_SSE_I387)
17668 && (flag_fp_int_builtin_inexact || !flag_trapping_math))
17669 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17671 || (ROUND_<ROUNDING> != ROUND_ROUNDEVEN
17672 && (flag_fp_int_builtin_inexact || !flag_trapping_math))))"
17674 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17676 || (ROUND_<ROUNDING> != ROUND_ROUNDEVEN
17677 && (flag_fp_int_builtin_inexact || !flag_trapping_math))))
17680 emit_insn (gen_sse4_1_round<mode>2
17681 (operands[0], operands[1],
17682 GEN_INT (ROUND_<ROUNDING> | ROUND_NO_EXC)));
17683 else if (TARGET_64BIT || (<MODE>mode != DFmode))
17685 if (ROUND_<ROUNDING> == ROUND_FLOOR)
17686 ix86_expand_floorceil (operands[0], operands[1], true);
17687 else if (ROUND_<ROUNDING> == ROUND_CEIL)
17688 ix86_expand_floorceil (operands[0], operands[1], false);
17689 else if (ROUND_<ROUNDING> == ROUND_TRUNC)
17690 ix86_expand_trunc (operands[0], operands[1]);
17692 gcc_unreachable ();
17696 if (ROUND_<ROUNDING> == ROUND_FLOOR)
17697 ix86_expand_floorceildf_32 (operands[0], operands[1], true);
17698 else if (ROUND_<ROUNDING> == ROUND_CEIL)
17699 ix86_expand_floorceildf_32 (operands[0], operands[1], false);
17700 else if (ROUND_<ROUNDING> == ROUND_TRUNC)
17701 ix86_expand_truncdf_32 (operands[0], operands[1]);
17703 gcc_unreachable ();
17708 rtx op0 = gen_reg_rtx (XFmode);
17709 rtx op1 = gen_reg_rtx (XFmode);
17711 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17712 emit_insn (gen_frndintxf2_<rounding> (op0, op1));
17713 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
17718 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17719 (define_insn_and_split "*fist<mode>2_<rounding>_1"
17720 [(set (match_operand:SWI248x 0 "nonimmediate_operand")
17721 (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
17723 (clobber (reg:CC FLAGS_REG))]
17724 "TARGET_USE_FANCY_MATH_387
17725 && flag_unsafe_math_optimizations
17726 && ix86_pre_reload_split ()"
17731 ix86_optimize_mode_switching[I387_<ROUNDING>] = 1;
17733 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17734 operands[3] = assign_386_stack_local (HImode, SLOT_CW_<ROUNDING>);
17736 emit_insn (gen_fist<mode>2_<rounding> (operands[0], operands[1],
17737 operands[2], operands[3]));
17740 [(set_attr "type" "fistp")
17741 (set_attr "i387_cw" "<rounding>")
17742 (set_attr "mode" "<MODE>")])
17744 (define_insn "fistdi2_<rounding>"
17745 [(set (match_operand:DI 0 "nonimmediate_operand" "=m")
17746 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17748 (use (match_operand:HI 2 "memory_operand" "m"))
17749 (use (match_operand:HI 3 "memory_operand" "m"))
17750 (clobber (match_scratch:XF 4 "=&f"))]
17751 "TARGET_USE_FANCY_MATH_387
17752 && flag_unsafe_math_optimizations"
17753 "* return output_fix_trunc (insn, operands, false);"
17754 [(set_attr "type" "fistp")
17755 (set_attr "i387_cw" "<rounding>")
17756 (set_attr "mode" "DI")])
17758 (define_insn "fist<mode>2_<rounding>"
17759 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m")
17760 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
17762 (use (match_operand:HI 2 "memory_operand" "m"))
17763 (use (match_operand:HI 3 "memory_operand" "m"))]
17764 "TARGET_USE_FANCY_MATH_387
17765 && flag_unsafe_math_optimizations"
17766 "* return output_fix_trunc (insn, operands, false);"
17767 [(set_attr "type" "fistp")
17768 (set_attr "i387_cw" "<rounding>")
17769 (set_attr "mode" "<MODE>")])
17771 (define_expand "l<rounding_insn>xf<mode>2"
17772 [(parallel [(set (match_operand:SWI248x 0 "nonimmediate_operand")
17773 (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
17775 (clobber (reg:CC FLAGS_REG))])]
17776 "TARGET_USE_FANCY_MATH_387
17777 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17778 && flag_unsafe_math_optimizations")
17780 (define_expand "l<rounding_insn><MODEF:mode><SWI48:mode>2"
17781 [(parallel [(set (match_operand:SWI48 0 "nonimmediate_operand")
17782 (unspec:SWI48 [(match_operand:MODEF 1 "register_operand")]
17784 (clobber (reg:CC FLAGS_REG))])]
17785 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
17786 && (TARGET_SSE4_1 || !flag_trapping_math)"
17790 rtx tmp = gen_reg_rtx (<MODEF:MODE>mode);
17792 emit_insn (gen_sse4_1_round<MODEF:mode>2
17793 (tmp, operands[1], GEN_INT (ROUND_<ROUNDING>
17795 emit_insn (gen_fix_trunc<MODEF:mode><SWI48:mode>2
17796 (operands[0], tmp));
17798 else if (ROUND_<ROUNDING> == ROUND_FLOOR)
17799 ix86_expand_lfloorceil (operands[0], operands[1], true);
17800 else if (ROUND_<ROUNDING> == ROUND_CEIL)
17801 ix86_expand_lfloorceil (operands[0], operands[1], false);
17803 gcc_unreachable ();
17808 (define_insn "fxam<mode>2_i387"
17809 [(set (match_operand:HI 0 "register_operand" "=a")
17811 [(match_operand:X87MODEF 1 "register_operand" "f")]
17813 "TARGET_USE_FANCY_MATH_387"
17814 "fxam\n\tfnstsw\t%0"
17815 [(set_attr "type" "multi")
17816 (set_attr "length" "4")
17817 (set_attr "unit" "i387")
17818 (set_attr "mode" "<MODE>")])
17820 (define_expand "signbittf2"
17821 [(use (match_operand:SI 0 "register_operand"))
17822 (use (match_operand:TF 1 "register_operand"))]
17827 rtx mask = ix86_build_signbit_mask (TFmode, 0, 0);
17828 rtx scratch = gen_reg_rtx (QImode);
17830 emit_insn (gen_ptesttf2 (operands[1], mask));
17831 ix86_expand_setcc (scratch, NE,
17832 gen_rtx_REG (CCZmode, FLAGS_REG), const0_rtx);
17834 emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
17838 emit_insn (gen_sse_movmskps (operands[0],
17839 gen_lowpart (V4SFmode, operands[1])));
17840 emit_insn (gen_andsi3 (operands[0], operands[0], GEN_INT (0x8)));
17845 (define_expand "signbitxf2"
17846 [(use (match_operand:SI 0 "register_operand"))
17847 (use (match_operand:XF 1 "register_operand"))]
17848 "TARGET_USE_FANCY_MATH_387"
17850 rtx scratch = gen_reg_rtx (HImode);
17852 emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
17853 emit_insn (gen_andsi3 (operands[0],
17854 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
17858 (define_insn "movmsk_df"
17859 [(set (match_operand:SI 0 "register_operand" "=r")
17861 [(match_operand:DF 1 "register_operand" "x")]
17863 "SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH"
17864 "%vmovmskpd\t{%1, %0|%0, %1}"
17865 [(set_attr "type" "ssemov")
17866 (set_attr "prefix" "maybe_vex")
17867 (set_attr "mode" "DF")])
17869 ;; Use movmskpd in SSE mode to avoid store forwarding stall
17870 ;; for 32bit targets and movq+shrq sequence for 64bit targets.
17871 (define_expand "signbitdf2"
17872 [(use (match_operand:SI 0 "register_operand"))
17873 (use (match_operand:DF 1 "register_operand"))]
17874 "TARGET_USE_FANCY_MATH_387
17875 || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
17877 if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)
17879 emit_insn (gen_movmsk_df (operands[0], operands[1]));
17880 emit_insn (gen_andsi3 (operands[0], operands[0], const1_rtx));
17884 rtx scratch = gen_reg_rtx (HImode);
17886 emit_insn (gen_fxamdf2_i387 (scratch, operands[1]));
17887 emit_insn (gen_andsi3 (operands[0],
17888 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
17893 (define_expand "signbitsf2"
17894 [(use (match_operand:SI 0 "register_operand"))
17895 (use (match_operand:SF 1 "register_operand"))]
17896 "TARGET_USE_FANCY_MATH_387
17897 && !(SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH)"
17899 rtx scratch = gen_reg_rtx (HImode);
17901 emit_insn (gen_fxamsf2_i387 (scratch, operands[1]));
17902 emit_insn (gen_andsi3 (operands[0],
17903 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
17907 ;; Block operation instructions
17910 [(unspec_volatile [(const_int 0)] UNSPECV_CLD)]
17913 [(set_attr "length" "1")
17914 (set_attr "length_immediate" "0")
17915 (set_attr "modrm" "0")])
17917 (define_expand "cpymem<mode>"
17918 [(use (match_operand:BLK 0 "memory_operand"))
17919 (use (match_operand:BLK 1 "memory_operand"))
17920 (use (match_operand:SWI48 2 "nonmemory_operand"))
17921 (use (match_operand:SWI48 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], operands[1],
17930 operands[2], NULL, operands[3],
17931 operands[4], operands[5],
17932 operands[6], operands[7],
17933 operands[8], false))
17939 ;; Most CPUs don't like single string operations
17940 ;; Handle this case here to simplify previous expander.
17942 (define_expand "strmov"
17943 [(set (match_dup 4) (match_operand 3 "memory_operand"))
17944 (set (match_operand 1 "memory_operand") (match_dup 4))
17945 (parallel [(set (match_operand 0 "register_operand") (match_dup 5))
17946 (clobber (reg:CC FLAGS_REG))])
17947 (parallel [(set (match_operand 2 "register_operand") (match_dup 6))
17948 (clobber (reg:CC FLAGS_REG))])]
17951 /* Can't use this for non-default address spaces. */
17952 if (!ADDR_SPACE_GENERIC_P (MEM_ADDR_SPACE (operands[3])))
17955 int piece_size = GET_MODE_SIZE (GET_MODE (operands[1]));
17957 /* If .md ever supports :P for Pmode, these can be directly
17958 in the pattern above. */
17959 operands[5] = plus_constant (Pmode, operands[0], piece_size);
17960 operands[6] = plus_constant (Pmode, operands[2], piece_size);
17962 /* Can't use this if the user has appropriated esi or edi. */
17963 if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
17964 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG]))
17966 emit_insn (gen_strmov_singleop (operands[0], operands[1],
17967 operands[2], operands[3],
17968 operands[5], operands[6]));
17972 operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
17975 (define_expand "strmov_singleop"
17976 [(parallel [(set (match_operand 1 "memory_operand")
17977 (match_operand 3 "memory_operand"))
17978 (set (match_operand 0 "register_operand")
17980 (set (match_operand 2 "register_operand")
17981 (match_operand 5))])]
17985 ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
17988 (define_insn "*strmovdi_rex_1"
17989 [(set (mem:DI (match_operand:P 2 "register_operand" "0"))
17990 (mem:DI (match_operand:P 3 "register_operand" "1")))
17991 (set (match_operand:P 0 "register_operand" "=D")
17992 (plus:P (match_dup 2)
17994 (set (match_operand:P 1 "register_operand" "=S")
17995 (plus:P (match_dup 3)
17998 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG])
17999 && ix86_check_no_addr_space (insn)"
18001 [(set_attr "type" "str")
18002 (set_attr "memory" "both")
18003 (set_attr "mode" "DI")])
18005 (define_insn "*strmovsi_1"
18006 [(set (mem:SI (match_operand:P 2 "register_operand" "0"))
18007 (mem:SI (match_operand:P 3 "register_operand" "1")))
18008 (set (match_operand:P 0 "register_operand" "=D")
18009 (plus:P (match_dup 2)
18011 (set (match_operand:P 1 "register_operand" "=S")
18012 (plus:P (match_dup 3)
18014 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])
18015 && ix86_check_no_addr_space (insn)"
18017 [(set_attr "type" "str")
18018 (set_attr "memory" "both")
18019 (set_attr "mode" "SI")])
18021 (define_insn "*strmovhi_1"
18022 [(set (mem:HI (match_operand:P 2 "register_operand" "0"))
18023 (mem:HI (match_operand:P 3 "register_operand" "1")))
18024 (set (match_operand:P 0 "register_operand" "=D")
18025 (plus:P (match_dup 2)
18027 (set (match_operand:P 1 "register_operand" "=S")
18028 (plus:P (match_dup 3)
18030 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])
18031 && ix86_check_no_addr_space (insn)"
18033 [(set_attr "type" "str")
18034 (set_attr "memory" "both")
18035 (set_attr "mode" "HI")])
18037 (define_insn "*strmovqi_1"
18038 [(set (mem:QI (match_operand:P 2 "register_operand" "0"))
18039 (mem:QI (match_operand:P 3 "register_operand" "1")))
18040 (set (match_operand:P 0 "register_operand" "=D")
18041 (plus:P (match_dup 2)
18043 (set (match_operand:P 1 "register_operand" "=S")
18044 (plus:P (match_dup 3)
18046 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])
18047 && ix86_check_no_addr_space (insn)"
18049 [(set_attr "type" "str")
18050 (set_attr "memory" "both")
18051 (set (attr "prefix_rex")
18053 (match_test "<P:MODE>mode == DImode")
18055 (const_string "*")))
18056 (set_attr "mode" "QI")])
18058 (define_expand "rep_mov"
18059 [(parallel [(set (match_operand 4 "register_operand") (const_int 0))
18060 (set (match_operand 0 "register_operand")
18062 (set (match_operand 2 "register_operand")
18064 (set (match_operand 1 "memory_operand")
18065 (match_operand 3 "memory_operand"))
18066 (use (match_dup 4))])]
18070 ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
18073 (define_insn "*rep_movdi_rex64"
18074 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
18075 (set (match_operand:P 0 "register_operand" "=D")
18076 (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
18078 (match_operand:P 3 "register_operand" "0")))
18079 (set (match_operand:P 1 "register_operand" "=S")
18080 (plus:P (ashift:P (match_dup 5) (const_int 3))
18081 (match_operand:P 4 "register_operand" "1")))
18082 (set (mem:BLK (match_dup 3))
18083 (mem:BLK (match_dup 4)))
18084 (use (match_dup 5))]
18086 && !(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
18087 && ix86_check_no_addr_space (insn)"
18089 [(set_attr "type" "str")
18090 (set_attr "prefix_rep" "1")
18091 (set_attr "memory" "both")
18092 (set_attr "mode" "DI")])
18094 (define_insn "*rep_movsi"
18095 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
18096 (set (match_operand:P 0 "register_operand" "=D")
18097 (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
18099 (match_operand:P 3 "register_operand" "0")))
18100 (set (match_operand:P 1 "register_operand" "=S")
18101 (plus:P (ashift:P (match_dup 5) (const_int 2))
18102 (match_operand:P 4 "register_operand" "1")))
18103 (set (mem:BLK (match_dup 3))
18104 (mem:BLK (match_dup 4)))
18105 (use (match_dup 5))]
18106 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
18107 && ix86_check_no_addr_space (insn)"
18108 "%^rep{%;} movs{l|d}"
18109 [(set_attr "type" "str")
18110 (set_attr "prefix_rep" "1")
18111 (set_attr "memory" "both")
18112 (set_attr "mode" "SI")])
18114 (define_insn "*rep_movqi"
18115 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
18116 (set (match_operand:P 0 "register_operand" "=D")
18117 (plus:P (match_operand:P 3 "register_operand" "0")
18118 (match_operand:P 5 "register_operand" "2")))
18119 (set (match_operand:P 1 "register_operand" "=S")
18120 (plus:P (match_operand:P 4 "register_operand" "1") (match_dup 5)))
18121 (set (mem:BLK (match_dup 3))
18122 (mem:BLK (match_dup 4)))
18123 (use (match_dup 5))]
18124 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
18125 && ix86_check_no_addr_space (insn)"
18127 [(set_attr "type" "str")
18128 (set_attr "prefix_rep" "1")
18129 (set_attr "memory" "both")
18130 (set_attr "mode" "QI")])
18132 (define_expand "setmem<mode>"
18133 [(use (match_operand:BLK 0 "memory_operand"))
18134 (use (match_operand:SWI48 1 "nonmemory_operand"))
18135 (use (match_operand:QI 2 "nonmemory_operand"))
18136 (use (match_operand 3 "const_int_operand"))
18137 (use (match_operand:SI 4 "const_int_operand"))
18138 (use (match_operand:SI 5 "const_int_operand"))
18139 (use (match_operand:SI 6 ""))
18140 (use (match_operand:SI 7 ""))
18141 (use (match_operand:SI 8 ""))]
18144 if (ix86_expand_set_or_cpymem (operands[0], NULL,
18145 operands[1], operands[2],
18146 operands[3], operands[4],
18147 operands[5], operands[6],
18148 operands[7], operands[8], true))
18154 ;; Most CPUs don't like single string operations
18155 ;; Handle this case here to simplify previous expander.
18157 (define_expand "strset"
18158 [(set (match_operand 1 "memory_operand")
18159 (match_operand 2 "register_operand"))
18160 (parallel [(set (match_operand 0 "register_operand")
18162 (clobber (reg:CC FLAGS_REG))])]
18165 /* Can't use this for non-default address spaces. */
18166 if (!ADDR_SPACE_GENERIC_P (MEM_ADDR_SPACE (operands[1])))
18169 if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
18170 operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
18172 /* If .md ever supports :P for Pmode, this can be directly
18173 in the pattern above. */
18174 operands[3] = plus_constant (Pmode, operands[0],
18175 GET_MODE_SIZE (GET_MODE (operands[2])));
18177 /* Can't use this if the user has appropriated eax or edi. */
18178 if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
18179 && !(fixed_regs[AX_REG] || fixed_regs[DI_REG]))
18181 emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
18187 (define_expand "strset_singleop"
18188 [(parallel [(set (match_operand 1 "memory_operand")
18189 (match_operand 2 "register_operand"))
18190 (set (match_operand 0 "register_operand")
18192 (unspec [(const_int 0)] UNSPEC_STOS)])]
18196 ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
18199 (define_insn "*strsetdi_rex_1"
18200 [(set (mem:DI (match_operand:P 1 "register_operand" "0"))
18201 (match_operand:DI 2 "register_operand" "a"))
18202 (set (match_operand:P 0 "register_operand" "=D")
18203 (plus:P (match_dup 1)
18205 (unspec [(const_int 0)] UNSPEC_STOS)]
18207 && !(fixed_regs[AX_REG] || fixed_regs[DI_REG])
18208 && ix86_check_no_addr_space (insn)"
18210 [(set_attr "type" "str")
18211 (set_attr "memory" "store")
18212 (set_attr "mode" "DI")])
18214 (define_insn "*strsetsi_1"
18215 [(set (mem:SI (match_operand:P 1 "register_operand" "0"))
18216 (match_operand:SI 2 "register_operand" "a"))
18217 (set (match_operand:P 0 "register_operand" "=D")
18218 (plus:P (match_dup 1)
18220 (unspec [(const_int 0)] UNSPEC_STOS)]
18221 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])
18222 && ix86_check_no_addr_space (insn)"
18224 [(set_attr "type" "str")
18225 (set_attr "memory" "store")
18226 (set_attr "mode" "SI")])
18228 (define_insn "*strsethi_1"
18229 [(set (mem:HI (match_operand:P 1 "register_operand" "0"))
18230 (match_operand:HI 2 "register_operand" "a"))
18231 (set (match_operand:P 0 "register_operand" "=D")
18232 (plus:P (match_dup 1)
18234 (unspec [(const_int 0)] UNSPEC_STOS)]
18235 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])
18236 && ix86_check_no_addr_space (insn)"
18238 [(set_attr "type" "str")
18239 (set_attr "memory" "store")
18240 (set_attr "mode" "HI")])
18242 (define_insn "*strsetqi_1"
18243 [(set (mem:QI (match_operand:P 1 "register_operand" "0"))
18244 (match_operand:QI 2 "register_operand" "a"))
18245 (set (match_operand:P 0 "register_operand" "=D")
18246 (plus:P (match_dup 1)
18248 (unspec [(const_int 0)] UNSPEC_STOS)]
18249 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])
18250 && ix86_check_no_addr_space (insn)"
18252 [(set_attr "type" "str")
18253 (set_attr "memory" "store")
18254 (set (attr "prefix_rex")
18256 (match_test "<P:MODE>mode == DImode")
18258 (const_string "*")))
18259 (set_attr "mode" "QI")])
18261 (define_expand "rep_stos"
18262 [(parallel [(set (match_operand 1 "register_operand") (const_int 0))
18263 (set (match_operand 0 "register_operand")
18265 (set (match_operand 2 "memory_operand") (const_int 0))
18266 (use (match_operand 3 "register_operand"))
18267 (use (match_dup 1))])]
18271 ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
18274 (define_insn "*rep_stosdi_rex64"
18275 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
18276 (set (match_operand:P 0 "register_operand" "=D")
18277 (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
18279 (match_operand:P 3 "register_operand" "0")))
18280 (set (mem:BLK (match_dup 3))
18282 (use (match_operand:DI 2 "register_operand" "a"))
18283 (use (match_dup 4))]
18285 && !(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])
18286 && ix86_check_no_addr_space (insn)"
18288 [(set_attr "type" "str")
18289 (set_attr "prefix_rep" "1")
18290 (set_attr "memory" "store")
18291 (set_attr "mode" "DI")])
18293 (define_insn "*rep_stossi"
18294 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
18295 (set (match_operand:P 0 "register_operand" "=D")
18296 (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
18298 (match_operand:P 3 "register_operand" "0")))
18299 (set (mem:BLK (match_dup 3))
18301 (use (match_operand:SI 2 "register_operand" "a"))
18302 (use (match_dup 4))]
18303 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])
18304 && ix86_check_no_addr_space (insn)"
18305 "%^rep{%;} stos{l|d}"
18306 [(set_attr "type" "str")
18307 (set_attr "prefix_rep" "1")
18308 (set_attr "memory" "store")
18309 (set_attr "mode" "SI")])
18311 (define_insn "*rep_stosqi"
18312 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
18313 (set (match_operand:P 0 "register_operand" "=D")
18314 (plus:P (match_operand:P 3 "register_operand" "0")
18315 (match_operand:P 4 "register_operand" "1")))
18316 (set (mem:BLK (match_dup 3))
18318 (use (match_operand:QI 2 "register_operand" "a"))
18319 (use (match_dup 4))]
18320 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])
18321 && ix86_check_no_addr_space (insn)"
18323 [(set_attr "type" "str")
18324 (set_attr "prefix_rep" "1")
18325 (set_attr "memory" "store")
18326 (set (attr "prefix_rex")
18328 (match_test "<P:MODE>mode == DImode")
18330 (const_string "*")))
18331 (set_attr "mode" "QI")])
18333 (define_expand "cmpmemsi"
18334 [(set (match_operand:SI 0 "register_operand" "")
18335 (compare:SI (match_operand:BLK 1 "memory_operand" "")
18336 (match_operand:BLK 2 "memory_operand" "") ) )
18337 (use (match_operand 3 "general_operand"))
18338 (use (match_operand 4 "immediate_operand"))]
18341 if (ix86_expand_cmpstrn_or_cmpmem (operands[0], operands[1],
18342 operands[2], operands[3],
18343 operands[4], false))
18349 (define_expand "cmpstrnsi"
18350 [(set (match_operand:SI 0 "register_operand")
18351 (compare:SI (match_operand:BLK 1 "general_operand")
18352 (match_operand:BLK 2 "general_operand")))
18353 (use (match_operand 3 "general_operand"))
18354 (use (match_operand 4 "immediate_operand"))]
18357 if (ix86_expand_cmpstrn_or_cmpmem (operands[0], operands[1],
18358 operands[2], operands[3],
18359 operands[4], true))
18365 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
18367 (define_expand "cmpintqi"
18368 [(set (match_dup 1)
18369 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
18371 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
18372 (parallel [(set (match_operand:QI 0 "register_operand")
18373 (minus:QI (match_dup 1)
18375 (clobber (reg:CC FLAGS_REG))])]
18378 operands[1] = gen_reg_rtx (QImode);
18379 operands[2] = gen_reg_rtx (QImode);
18382 ;; memcmp recognizers. The `cmpsb' opcode does nothing if the count is
18383 ;; zero. Emit extra code to make sure that a zero-length compare is EQ.
18385 (define_expand "cmpstrnqi_nz_1"
18386 [(parallel [(set (reg:CC FLAGS_REG)
18387 (compare:CC (match_operand 4 "memory_operand")
18388 (match_operand 5 "memory_operand")))
18389 (use (match_operand 2 "register_operand"))
18390 (use (match_operand:SI 3 "immediate_operand"))
18391 (clobber (match_operand 0 "register_operand"))
18392 (clobber (match_operand 1 "register_operand"))
18393 (clobber (match_dup 2))])]
18397 ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
18400 (define_insn "*cmpstrnqi_nz_1"
18401 [(set (reg:CC FLAGS_REG)
18402 (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
18403 (mem:BLK (match_operand:P 5 "register_operand" "1"))))
18404 (use (match_operand:P 6 "register_operand" "2"))
18405 (use (match_operand:SI 3 "immediate_operand" "i"))
18406 (clobber (match_operand:P 0 "register_operand" "=S"))
18407 (clobber (match_operand:P 1 "register_operand" "=D"))
18408 (clobber (match_operand:P 2 "register_operand" "=c"))]
18409 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
18410 && ix86_check_no_addr_space (insn)"
18412 [(set_attr "type" "str")
18413 (set_attr "mode" "QI")
18414 (set (attr "prefix_rex")
18416 (match_test "<P:MODE>mode == DImode")
18418 (const_string "*")))
18419 (set_attr "prefix_rep" "1")])
18421 ;; The same, but the count is not known to not be zero.
18423 (define_expand "cmpstrnqi_1"
18424 [(parallel [(set (reg:CC FLAGS_REG)
18425 (if_then_else:CC (ne (match_operand 2 "register_operand")
18427 (compare:CC (match_operand 4 "memory_operand")
18428 (match_operand 5 "memory_operand"))
18430 (use (match_operand:SI 3 "immediate_operand"))
18431 (use (reg:CC FLAGS_REG))
18432 (clobber (match_operand 0 "register_operand"))
18433 (clobber (match_operand 1 "register_operand"))
18434 (clobber (match_dup 2))])]
18438 ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
18441 (define_insn "*cmpstrnqi_1"
18442 [(set (reg:CC FLAGS_REG)
18443 (if_then_else:CC (ne (match_operand:P 6 "register_operand" "2")
18445 (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
18446 (mem:BLK (match_operand:P 5 "register_operand" "1")))
18448 (use (match_operand:SI 3 "immediate_operand" "i"))
18449 (use (reg:CC FLAGS_REG))
18450 (clobber (match_operand:P 0 "register_operand" "=S"))
18451 (clobber (match_operand:P 1 "register_operand" "=D"))
18452 (clobber (match_operand:P 2 "register_operand" "=c"))]
18453 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
18454 && ix86_check_no_addr_space (insn)"
18456 [(set_attr "type" "str")
18457 (set_attr "mode" "QI")
18458 (set (attr "prefix_rex")
18460 (match_test "<P:MODE>mode == DImode")
18462 (const_string "*")))
18463 (set_attr "prefix_rep" "1")])
18465 (define_expand "strlen<mode>"
18466 [(set (match_operand:P 0 "register_operand")
18467 (unspec:P [(match_operand:BLK 1 "general_operand")
18468 (match_operand:QI 2 "immediate_operand")
18469 (match_operand 3 "immediate_operand")]
18473 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
18479 (define_expand "strlenqi_1"
18480 [(parallel [(set (match_operand 0 "register_operand")
18482 (clobber (match_operand 1 "register_operand"))
18483 (clobber (reg:CC FLAGS_REG))])]
18487 ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
18490 (define_insn "*strlenqi_1"
18491 [(set (match_operand:P 0 "register_operand" "=&c")
18492 (unspec:P [(mem:BLK (match_operand:P 5 "register_operand" "1"))
18493 (match_operand:QI 2 "register_operand" "a")
18494 (match_operand:P 3 "immediate_operand" "i")
18495 (match_operand:P 4 "register_operand" "0")] UNSPEC_SCAS))
18496 (clobber (match_operand:P 1 "register_operand" "=D"))
18497 (clobber (reg:CC FLAGS_REG))]
18498 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])
18499 && ix86_check_no_addr_space (insn)"
18500 "%^repnz{%;} scasb"
18501 [(set_attr "type" "str")
18502 (set_attr "mode" "QI")
18503 (set (attr "prefix_rex")
18505 (match_test "<P:MODE>mode == DImode")
18507 (const_string "*")))
18508 (set_attr "prefix_rep" "1")])
18510 ;; Peephole optimizations to clean up after cmpstrn*. This should be
18511 ;; handled in combine, but it is not currently up to the task.
18512 ;; When used for their truth value, the cmpstrn* expanders generate
18521 ;; The intermediate three instructions are unnecessary.
18523 ;; This one handles cmpstrn*_nz_1...
18526 (set (reg:CC FLAGS_REG)
18527 (compare:CC (mem:BLK (match_operand 4 "register_operand"))
18528 (mem:BLK (match_operand 5 "register_operand"))))
18529 (use (match_operand 6 "register_operand"))
18530 (use (match_operand:SI 3 "immediate_operand"))
18531 (clobber (match_operand 0 "register_operand"))
18532 (clobber (match_operand 1 "register_operand"))
18533 (clobber (match_operand 2 "register_operand"))])
18534 (set (match_operand:QI 7 "register_operand")
18535 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
18536 (set (match_operand:QI 8 "register_operand")
18537 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
18538 (set (reg FLAGS_REG)
18539 (compare (match_dup 7) (match_dup 8)))
18541 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
18543 (set (reg:CC FLAGS_REG)
18544 (compare:CC (mem:BLK (match_dup 4))
18545 (mem:BLK (match_dup 5))))
18546 (use (match_dup 6))
18547 (use (match_dup 3))
18548 (clobber (match_dup 0))
18549 (clobber (match_dup 1))
18550 (clobber (match_dup 2))])])
18552 ;; ...and this one handles cmpstrn*_1.
18555 (set (reg:CC FLAGS_REG)
18556 (if_then_else:CC (ne (match_operand 6 "register_operand")
18558 (compare:CC (mem:BLK (match_operand 4 "register_operand"))
18559 (mem:BLK (match_operand 5 "register_operand")))
18561 (use (match_operand:SI 3 "immediate_operand"))
18562 (use (reg:CC FLAGS_REG))
18563 (clobber (match_operand 0 "register_operand"))
18564 (clobber (match_operand 1 "register_operand"))
18565 (clobber (match_operand 2 "register_operand"))])
18566 (set (match_operand:QI 7 "register_operand")
18567 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
18568 (set (match_operand:QI 8 "register_operand")
18569 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
18570 (set (reg FLAGS_REG)
18571 (compare (match_dup 7) (match_dup 8)))
18573 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
18575 (set (reg:CC FLAGS_REG)
18576 (if_then_else:CC (ne (match_dup 6)
18578 (compare:CC (mem:BLK (match_dup 4))
18579 (mem:BLK (match_dup 5)))
18581 (use (match_dup 3))
18582 (use (reg:CC FLAGS_REG))
18583 (clobber (match_dup 0))
18584 (clobber (match_dup 1))
18585 (clobber (match_dup 2))])])
18587 ;; Conditional move instructions.
18589 (define_expand "mov<mode>cc"
18590 [(set (match_operand:SWIM 0 "register_operand")
18591 (if_then_else:SWIM (match_operand 1 "comparison_operator")
18592 (match_operand:SWIM 2 "<general_operand>")
18593 (match_operand:SWIM 3 "<general_operand>")))]
18595 "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
18597 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
18598 ;; the register first winds up with `sbbl $0,reg', which is also weird.
18599 ;; So just document what we're doing explicitly.
18601 (define_expand "x86_mov<mode>cc_0_m1"
18603 [(set (match_operand:SWI48 0 "register_operand")
18604 (if_then_else:SWI48
18605 (match_operator:SWI48 2 "ix86_carry_flag_operator"
18606 [(match_operand 1 "flags_reg_operand")
18610 (clobber (reg:CC FLAGS_REG))])])
18612 (define_insn "*x86_mov<mode>cc_0_m1"
18613 [(set (match_operand:SWI48 0 "register_operand" "=r")
18614 (if_then_else:SWI48 (match_operator 1 "ix86_carry_flag_operator"
18615 [(reg FLAGS_REG) (const_int 0)])
18618 (clobber (reg:CC FLAGS_REG))]
18620 "sbb{<imodesuffix>}\t%0, %0"
18621 [(set_attr "type" "alu1")
18622 (set_attr "use_carry" "1")
18623 (set_attr "pent_pair" "pu")
18624 (set_attr "mode" "<MODE>")
18625 (set_attr "length_immediate" "0")])
18627 (define_insn "*x86_mov<mode>cc_0_m1_se"
18628 [(set (match_operand:SWI48 0 "register_operand" "=r")
18629 (sign_extract:SWI48 (match_operator 1 "ix86_carry_flag_operator"
18630 [(reg FLAGS_REG) (const_int 0)])
18633 (clobber (reg:CC FLAGS_REG))]
18635 "sbb{<imodesuffix>}\t%0, %0"
18636 [(set_attr "type" "alu1")
18637 (set_attr "use_carry" "1")
18638 (set_attr "pent_pair" "pu")
18639 (set_attr "mode" "<MODE>")
18640 (set_attr "length_immediate" "0")])
18642 (define_insn "*x86_mov<mode>cc_0_m1_neg"
18643 [(set (match_operand:SWI 0 "register_operand" "=<r>")
18644 (neg:SWI (match_operator 1 "ix86_carry_flag_operator"
18645 [(reg FLAGS_REG) (const_int 0)])))
18646 (clobber (reg:CC FLAGS_REG))]
18648 "sbb{<imodesuffix>}\t%0, %0"
18649 [(set_attr "type" "alu1")
18650 (set_attr "use_carry" "1")
18651 (set_attr "pent_pair" "pu")
18652 (set_attr "mode" "<MODE>")
18653 (set_attr "length_immediate" "0")])
18656 [(set (match_operand:SWI48 0 "register_operand")
18659 (match_operand 1 "int_nonimmediate_operand")
18660 (match_operand 2 "const_int_operand"))))]
18661 "x86_64_immediate_operand (operands[2], VOIDmode)
18662 && INTVAL (operands[2]) != -1
18663 && INTVAL (operands[2]) != 2147483647"
18664 [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
18666 (neg:SWI48 (ltu:SWI48 (reg:CC FLAGS_REG) (const_int 0))))]
18667 "operands[2] = GEN_INT (INTVAL (operands[2]) + 1);")
18670 [(set (match_operand:SWI 0 "register_operand")
18673 (match_operand 1 "int_nonimmediate_operand")
18676 [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (const_int 1)))
18678 (neg:SWI (ltu:SWI (reg:CC FLAGS_REG) (const_int 0))))])
18681 [(set (match_operand:SWI 0 "register_operand")
18684 (match_operand 1 "int_nonimmediate_operand")
18687 [(set (reg:CCC FLAGS_REG)
18688 (ne:CCC (match_dup 1) (const_int 0)))
18690 (neg:SWI (ltu:SWI (reg:CCC FLAGS_REG) (const_int 0))))])
18692 (define_insn "*mov<mode>cc_noc"
18693 [(set (match_operand:SWI248 0 "register_operand" "=r,r")
18694 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
18695 [(reg FLAGS_REG) (const_int 0)])
18696 (match_operand:SWI248 2 "nonimmediate_operand" "rm,0")
18697 (match_operand:SWI248 3 "nonimmediate_operand" "0,rm")))]
18698 "TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
18700 cmov%O2%C1\t{%2, %0|%0, %2}
18701 cmov%O2%c1\t{%3, %0|%0, %3}"
18702 [(set_attr "type" "icmov")
18703 (set_attr "mode" "<MODE>")])
18705 (define_insn "*movsicc_noc_zext"
18706 [(set (match_operand:DI 0 "register_operand" "=r,r")
18707 (if_then_else:DI (match_operator 1 "ix86_comparison_operator"
18708 [(reg FLAGS_REG) (const_int 0)])
18710 (match_operand:SI 2 "nonimmediate_operand" "rm,0"))
18712 (match_operand:SI 3 "nonimmediate_operand" "0,rm"))))]
18714 && TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
18716 cmov%O2%C1\t{%2, %k0|%k0, %2}
18717 cmov%O2%c1\t{%3, %k0|%k0, %3}"
18718 [(set_attr "type" "icmov")
18719 (set_attr "mode" "SI")])
18721 ;; Don't do conditional moves with memory inputs. This splitter helps
18722 ;; register starved x86_32 by forcing inputs into registers before reload.
18724 [(set (match_operand:SWI248 0 "register_operand")
18725 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
18726 [(reg FLAGS_REG) (const_int 0)])
18727 (match_operand:SWI248 2 "nonimmediate_operand")
18728 (match_operand:SWI248 3 "nonimmediate_operand")))]
18729 "!TARGET_64BIT && TARGET_CMOVE
18730 && TARGET_AVOID_MEM_OPND_FOR_CMOVE
18731 && (MEM_P (operands[2]) || MEM_P (operands[3]))
18732 && can_create_pseudo_p ()
18733 && optimize_insn_for_speed_p ()"
18734 [(set (match_dup 0)
18735 (if_then_else:SWI248 (match_dup 1) (match_dup 2) (match_dup 3)))]
18737 if (MEM_P (operands[2]))
18738 operands[2] = force_reg (<MODE>mode, operands[2]);
18739 if (MEM_P (operands[3]))
18740 operands[3] = force_reg (<MODE>mode, operands[3]);
18743 (define_insn "*movqicc_noc"
18744 [(set (match_operand:QI 0 "register_operand" "=r,r")
18745 (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
18746 [(reg FLAGS_REG) (const_int 0)])
18747 (match_operand:QI 2 "register_operand" "r,0")
18748 (match_operand:QI 3 "register_operand" "0,r")))]
18749 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
18751 [(set_attr "type" "icmov")
18752 (set_attr "mode" "QI")])
18755 [(set (match_operand:SWI12 0 "register_operand")
18756 (if_then_else:SWI12 (match_operator 1 "ix86_comparison_operator"
18757 [(reg FLAGS_REG) (const_int 0)])
18758 (match_operand:SWI12 2 "register_operand")
18759 (match_operand:SWI12 3 "register_operand")))]
18760 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL
18761 && reload_completed"
18762 [(set (match_dup 0)
18763 (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
18765 operands[0] = gen_lowpart (SImode, operands[0]);
18766 operands[2] = gen_lowpart (SImode, operands[2]);
18767 operands[3] = gen_lowpart (SImode, operands[3]);
18770 ;; Don't do conditional moves with memory inputs
18772 [(match_scratch:SWI248 4 "r")
18773 (set (match_operand:SWI248 0 "register_operand")
18774 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
18775 [(reg FLAGS_REG) (const_int 0)])
18776 (match_operand:SWI248 2 "nonimmediate_operand")
18777 (match_operand:SWI248 3 "nonimmediate_operand")))]
18778 "TARGET_CMOVE && TARGET_AVOID_MEM_OPND_FOR_CMOVE
18779 && (MEM_P (operands[2]) || MEM_P (operands[3]))
18780 && optimize_insn_for_speed_p ()"
18781 [(set (match_dup 4) (match_dup 5))
18783 (if_then_else:SWI248 (match_dup 1) (match_dup 2) (match_dup 3)))]
18785 if (MEM_P (operands[2]))
18787 operands[5] = operands[2];
18788 operands[2] = operands[4];
18790 else if (MEM_P (operands[3]))
18792 operands[5] = operands[3];
18793 operands[3] = operands[4];
18796 gcc_unreachable ();
18800 [(match_scratch:SI 4 "r")
18801 (set (match_operand:DI 0 "register_operand")
18802 (if_then_else:DI (match_operator 1 "ix86_comparison_operator"
18803 [(reg FLAGS_REG) (const_int 0)])
18805 (match_operand:SI 2 "nonimmediate_operand"))
18807 (match_operand:SI 3 "nonimmediate_operand"))))]
18809 && TARGET_CMOVE && TARGET_AVOID_MEM_OPND_FOR_CMOVE
18810 && (MEM_P (operands[2]) || MEM_P (operands[3]))
18811 && optimize_insn_for_speed_p ()"
18812 [(set (match_dup 4) (match_dup 5))
18814 (if_then_else:DI (match_dup 1)
18815 (zero_extend:DI (match_dup 2))
18816 (zero_extend:DI (match_dup 3))))]
18818 if (MEM_P (operands[2]))
18820 operands[5] = operands[2];
18821 operands[2] = operands[4];
18823 else if (MEM_P (operands[3]))
18825 operands[5] = operands[3];
18826 operands[3] = operands[4];
18829 gcc_unreachable ();
18832 (define_expand "mov<mode>cc"
18833 [(set (match_operand:X87MODEF 0 "register_operand")
18834 (if_then_else:X87MODEF
18835 (match_operand 1 "comparison_operator")
18836 (match_operand:X87MODEF 2 "register_operand")
18837 (match_operand:X87MODEF 3 "register_operand")))]
18838 "(TARGET_80387 && TARGET_CMOVE)
18839 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
18840 "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
18842 (define_insn "*movxfcc_1"
18843 [(set (match_operand:XF 0 "register_operand" "=f,f")
18844 (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
18845 [(reg FLAGS_REG) (const_int 0)])
18846 (match_operand:XF 2 "register_operand" "f,0")
18847 (match_operand:XF 3 "register_operand" "0,f")))]
18848 "TARGET_80387 && TARGET_CMOVE"
18850 fcmov%F1\t{%2, %0|%0, %2}
18851 fcmov%f1\t{%3, %0|%0, %3}"
18852 [(set_attr "type" "fcmov")
18853 (set_attr "mode" "XF")])
18855 (define_insn "*movdfcc_1"
18856 [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r,r ,r")
18857 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
18858 [(reg FLAGS_REG) (const_int 0)])
18859 (match_operand:DF 2 "nonimmediate_operand"
18861 (match_operand:DF 3 "nonimmediate_operand"
18862 "0 ,f,0 ,rm,0, rm")))]
18863 "TARGET_80387 && TARGET_CMOVE
18864 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
18866 fcmov%F1\t{%2, %0|%0, %2}
18867 fcmov%f1\t{%3, %0|%0, %3}
18870 cmov%O2%C1\t{%2, %0|%0, %2}
18871 cmov%O2%c1\t{%3, %0|%0, %3}"
18872 [(set_attr "isa" "*,*,nox64,nox64,x64,x64")
18873 (set_attr "type" "fcmov,fcmov,multi,multi,icmov,icmov")
18874 (set_attr "mode" "DF,DF,DI,DI,DI,DI")])
18877 [(set (match_operand:DF 0 "general_reg_operand")
18878 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
18879 [(reg FLAGS_REG) (const_int 0)])
18880 (match_operand:DF 2 "nonimmediate_operand")
18881 (match_operand:DF 3 "nonimmediate_operand")))]
18882 "!TARGET_64BIT && reload_completed"
18883 [(set (match_dup 2)
18884 (if_then_else:SI (match_dup 1) (match_dup 4) (match_dup 5)))
18886 (if_then_else:SI (match_dup 1) (match_dup 6) (match_dup 7)))]
18888 split_double_mode (DImode, &operands[2], 2, &operands[4], &operands[6]);
18889 split_double_mode (DImode, &operands[0], 1, &operands[2], &operands[3]);
18892 (define_insn "*movsfcc_1_387"
18893 [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
18894 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
18895 [(reg FLAGS_REG) (const_int 0)])
18896 (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
18897 (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
18898 "TARGET_80387 && TARGET_CMOVE
18899 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
18901 fcmov%F1\t{%2, %0|%0, %2}
18902 fcmov%f1\t{%3, %0|%0, %3}
18903 cmov%O2%C1\t{%2, %0|%0, %2}
18904 cmov%O2%c1\t{%3, %0|%0, %3}"
18905 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
18906 (set_attr "mode" "SF,SF,SI,SI")])
18908 ;; Don't do conditional moves with memory inputs. This splitter helps
18909 ;; register starved x86_32 by forcing inputs into registers before reload.
18911 [(set (match_operand:MODEF 0 "register_operand")
18912 (if_then_else:MODEF (match_operator 1 "ix86_comparison_operator"
18913 [(reg FLAGS_REG) (const_int 0)])
18914 (match_operand:MODEF 2 "nonimmediate_operand")
18915 (match_operand:MODEF 3 "nonimmediate_operand")))]
18916 "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
18917 && TARGET_AVOID_MEM_OPND_FOR_CMOVE
18918 && (MEM_P (operands[2]) || MEM_P (operands[3]))
18919 && can_create_pseudo_p ()
18920 && optimize_insn_for_speed_p ()"
18921 [(set (match_dup 0)
18922 (if_then_else:MODEF (match_dup 1) (match_dup 2) (match_dup 3)))]
18924 if (MEM_P (operands[2]))
18925 operands[2] = force_reg (<MODE>mode, operands[2]);
18926 if (MEM_P (operands[3]))
18927 operands[3] = force_reg (<MODE>mode, operands[3]);
18930 ;; Don't do conditional moves with memory inputs
18932 [(match_scratch:MODEF 4 "r")
18933 (set (match_operand:MODEF 0 "general_reg_operand")
18934 (if_then_else:MODEF (match_operator 1 "fcmov_comparison_operator"
18935 [(reg FLAGS_REG) (const_int 0)])
18936 (match_operand:MODEF 2 "nonimmediate_operand")
18937 (match_operand:MODEF 3 "nonimmediate_operand")))]
18938 "(<MODE>mode != DFmode || TARGET_64BIT)
18939 && TARGET_80387 && TARGET_CMOVE
18940 && TARGET_AVOID_MEM_OPND_FOR_CMOVE
18941 && (MEM_P (operands[2]) || MEM_P (operands[3]))
18942 && optimize_insn_for_speed_p ()"
18943 [(set (match_dup 4) (match_dup 5))
18945 (if_then_else:MODEF (match_dup 1) (match_dup 2) (match_dup 3)))]
18947 if (MEM_P (operands[2]))
18949 operands[5] = operands[2];
18950 operands[2] = operands[4];
18952 else if (MEM_P (operands[3]))
18954 operands[5] = operands[3];
18955 operands[3] = operands[4];
18958 gcc_unreachable ();
18961 ;; All moves in XOP pcmov instructions are 128 bits and hence we restrict
18962 ;; the scalar versions to have only XMM registers as operands.
18964 ;; XOP conditional move
18965 (define_insn "*xop_pcmov_<mode>"
18966 [(set (match_operand:MODEF 0 "register_operand" "=x")
18967 (if_then_else:MODEF
18968 (match_operand:MODEF 1 "register_operand" "x")
18969 (match_operand:MODEF 2 "register_operand" "x")
18970 (match_operand:MODEF 3 "register_operand" "x")))]
18972 "vpcmov\t{%1, %3, %2, %0|%0, %2, %3, %1}"
18973 [(set_attr "type" "sse4arg")])
18975 ;; These versions of the min/max patterns are intentionally ignorant of
18976 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
18977 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
18978 ;; are undefined in this condition, we're certain this is correct.
18980 (define_insn "<code><mode>3"
18981 [(set (match_operand:MODEF 0 "register_operand" "=x,v")
18983 (match_operand:MODEF 1 "nonimmediate_operand" "%0,v")
18984 (match_operand:MODEF 2 "nonimmediate_operand" "xm,vm")))]
18985 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
18987 <maxmin_float><ssemodesuffix>\t{%2, %0|%0, %2}
18988 v<maxmin_float><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
18989 [(set_attr "isa" "noavx,avx")
18990 (set_attr "prefix" "orig,vex")
18991 (set_attr "type" "sseadd")
18992 (set_attr "mode" "<MODE>")])
18994 ;; These versions of the min/max patterns implement exactly the operations
18995 ;; min = (op1 < op2 ? op1 : op2)
18996 ;; max = (!(op1 < op2) ? op1 : op2)
18997 ;; Their operands are not commutative, and thus they may be used in the
18998 ;; presence of -0.0 and NaN.
19000 (define_insn "*ieee_s<ieee_maxmin><mode>3"
19001 [(set (match_operand:MODEF 0 "register_operand" "=x,v")
19003 [(match_operand:MODEF 1 "register_operand" "0,v")
19004 (match_operand:MODEF 2 "nonimmediate_operand" "xm,vm")]
19006 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
19008 <ieee_maxmin><ssemodesuffix>\t{%2, %0|%0, %2}
19009 v<ieee_maxmin><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
19010 [(set_attr "isa" "noavx,avx")
19011 (set_attr "prefix" "orig,maybe_evex")
19012 (set_attr "type" "sseadd")
19013 (set_attr "mode" "<MODE>")])
19015 ;; Make two stack loads independent:
19017 ;; fld %st(0) -> fld bb
19018 ;; fmul bb fmul %st(1), %st
19020 ;; Actually we only match the last two instructions for simplicity.
19023 [(set (match_operand 0 "fp_register_operand")
19024 (match_operand 1 "fp_register_operand"))
19026 (match_operator 2 "binary_fp_operator"
19028 (match_operand 3 "memory_operand")]))]
19029 "REGNO (operands[0]) != REGNO (operands[1])"
19030 [(set (match_dup 0) (match_dup 3))
19033 [(match_dup 5) (match_dup 4)]))]
19035 operands[4] = operands[0];
19036 operands[5] = operands[1];
19038 /* The % modifier is not operational anymore in peephole2's, so we have to
19039 swap the operands manually in the case of addition and multiplication. */
19040 if (COMMUTATIVE_ARITH_P (operands[2]))
19041 std::swap (operands[4], operands[5]);
19045 [(set (match_operand 0 "fp_register_operand")
19046 (match_operand 1 "fp_register_operand"))
19048 (match_operator 2 "binary_fp_operator"
19049 [(match_operand 3 "memory_operand")
19051 "REGNO (operands[0]) != REGNO (operands[1])"
19052 [(set (match_dup 0) (match_dup 3))
19055 [(match_dup 4) (match_dup 5)]))]
19057 operands[4] = operands[0];
19058 operands[5] = operands[1];
19060 /* The % modifier is not operational anymore in peephole2's, so we have to
19061 swap the operands manually in the case of addition and multiplication. */
19062 if (COMMUTATIVE_ARITH_P (operands[2]))
19063 std::swap (operands[4], operands[5]);
19066 ;; Conditional addition patterns
19067 (define_expand "add<mode>cc"
19068 [(match_operand:SWI 0 "register_operand")
19069 (match_operand 1 "ordered_comparison_operator")
19070 (match_operand:SWI 2 "register_operand")
19071 (match_operand:SWI 3 "const_int_operand")]
19073 "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
19075 ;; min/max patterns
19077 (define_code_attr maxmin_rel
19078 [(smax "GE") (smin "LE") (umax "GEU") (umin "LEU")])
19080 (define_expand "<code><mode>3"
19082 [(set (match_operand:SDWIM 0 "register_operand")
19084 (match_operand:SDWIM 1 "register_operand")
19085 (match_operand:SDWIM 2 "general_operand")))
19086 (clobber (reg:CC FLAGS_REG))])]
19088 && (<MODE>mode != QImode || !TARGET_PARTIAL_REG_STALL)")
19090 (define_insn_and_split "*<code><dwi>3_doubleword"
19091 [(set (match_operand:<DWI> 0 "register_operand")
19093 (match_operand:<DWI> 1 "register_operand")
19094 (match_operand:<DWI> 2 "general_operand")))
19095 (clobber (reg:CC FLAGS_REG))]
19097 && ix86_pre_reload_split ()"
19100 [(set (match_dup 0)
19101 (if_then_else:DWIH (match_dup 6)
19105 (if_then_else:DWIH (match_dup 6)
19109 operands[2] = force_reg (<DWI>mode, operands[2]);
19111 split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
19113 rtx cmplo[2] = { operands[1], operands[2] };
19114 rtx cmphi[2] = { operands[4], operands[5] };
19116 enum rtx_code code = <maxmin_rel>;
19121 std::swap (cmplo[0], cmplo[1]);
19122 std::swap (cmphi[0], cmphi[1]);
19123 code = swap_condition (code);
19128 bool uns = (code == GEU);
19129 rtx (*sbb_insn) (machine_mode, rtx, rtx, rtx)
19130 = uns ? gen_sub3_carry_ccc : gen_sub3_carry_ccgz;
19132 emit_insn (gen_cmp_1 (<MODE>mode, cmplo[0], cmplo[1]));
19134 rtx tmp = gen_rtx_SCRATCH (<MODE>mode);
19135 emit_insn (sbb_insn (<MODE>mode, tmp, cmphi[0], cmphi[1]));
19137 rtx flags = gen_rtx_REG (uns ? CCCmode : CCGZmode, FLAGS_REG);
19138 operands[6] = gen_rtx_fmt_ee (code, VOIDmode, flags, const0_rtx);
19144 gcc_unreachable ();
19148 (define_insn_and_split "*<code><mode>3_1"
19149 [(set (match_operand:SWI 0 "register_operand")
19151 (match_operand:SWI 1 "register_operand")
19152 (match_operand:SWI 2 "general_operand")))
19153 (clobber (reg:CC FLAGS_REG))]
19155 && (<MODE>mode != QImode || !TARGET_PARTIAL_REG_STALL)
19156 && ix86_pre_reload_split ()"
19159 [(set (match_dup 0)
19160 (if_then_else:SWI (match_dup 3)
19164 machine_mode mode = <MODE>mode;
19165 rtx cmp_op = operands[2];
19167 operands[2] = force_reg (mode, cmp_op);
19169 enum rtx_code code = <maxmin_rel>;
19171 if (cmp_op == const1_rtx)
19173 /* Convert smax (x, 1) into (x > 0 ? x : 1).
19174 Convert umax (x, 1) into (x != 0 ? x : 1).
19175 Convert ?min (x, 1) into (x <= 0 ? x : 1). */
19176 cmp_op = const0_rtx;
19179 else if (code == GEU)
19182 /* Convert smin (x, -1) into (x < 0 ? x : -1). */
19183 else if (cmp_op == constm1_rtx && code == LE)
19185 cmp_op = const0_rtx;
19188 /* Convert smax (x, -1) into (x >= 0 ? x : -1). */
19189 else if (cmp_op == constm1_rtx && code == GE)
19190 cmp_op = const0_rtx;
19191 else if (cmp_op != const0_rtx)
19192 cmp_op = operands[2];
19194 machine_mode cmpmode = SELECT_CC_MODE (code, operands[1], cmp_op);
19195 rtx flags = gen_rtx_REG (cmpmode, FLAGS_REG);
19197 rtx tmp = gen_rtx_COMPARE (cmpmode, operands[1], cmp_op);
19198 emit_insn (gen_rtx_SET (flags, tmp));
19200 operands[3] = gen_rtx_fmt_ee (code, VOIDmode, flags, const0_rtx);
19203 ;; Avoid clearing a register between a flags setting comparison and its use,
19204 ;; i.e. prefer "xorl %eax,%eax; test/cmp" over "test/cmp; movl $0, %eax".
19206 [(set (reg FLAGS_REG) (match_operand 0))
19207 (set (match_operand:SWI 1 "general_reg_operand") (const_int 0))]
19208 "peep2_regno_dead_p (0, FLAGS_REG)
19209 && !reg_overlap_mentioned_p (operands[1], operands[0])"
19210 [(set (match_dup 2) (match_dup 0))]
19212 operands[2] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
19213 ix86_expand_clear (operands[1]);
19216 ;; Reload dislikes loading constants directly into class_likely_spilled
19217 ;; hard registers. Try to tidy things up here.
19219 [(set (match_operand:SWI 0 "general_reg_operand")
19220 (match_operand:SWI 1 "x86_64_general_operand"))
19221 (set (match_operand:SWI 2 "general_reg_operand")
19223 "peep2_reg_dead_p (2, operands[0])"
19224 [(set (match_dup 2) (match_dup 1))])
19226 ;; Misc patterns (?)
19228 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
19229 ;; Otherwise there will be nothing to keep
19231 ;; [(set (reg ebp) (reg esp))]
19232 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
19233 ;; (clobber (eflags)]
19234 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
19236 ;; in proper program order.
19238 (define_insn "@pro_epilogue_adjust_stack_add_<mode>"
19239 [(set (match_operand:P 0 "register_operand" "=r,r")
19240 (plus:P (match_operand:P 1 "register_operand" "0,r")
19241 (match_operand:P 2 "<nonmemory_operand>" "r<i>,l<i>")))
19242 (clobber (reg:CC FLAGS_REG))
19243 (clobber (mem:BLK (scratch)))]
19246 switch (get_attr_type (insn))
19249 return "mov{<imodesuffix>}\t{%1, %0|%0, %1}";
19252 gcc_assert (rtx_equal_p (operands[0], operands[1]));
19253 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
19254 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
19256 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
19259 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
19260 return "lea{<imodesuffix>}\t{%E2, %0|%0, %E2}";
19263 [(set (attr "type")
19264 (cond [(and (eq_attr "alternative" "0")
19265 (not (match_test "TARGET_OPT_AGU")))
19266 (const_string "alu")
19267 (match_operand:<MODE> 2 "const0_operand")
19268 (const_string "imov")
19270 (const_string "lea")))
19271 (set (attr "length_immediate")
19272 (cond [(eq_attr "type" "imov")
19274 (and (eq_attr "type" "alu")
19275 (match_operand 2 "const128_operand"))
19278 (const_string "*")))
19279 (set_attr "mode" "<MODE>")])
19281 (define_insn "@pro_epilogue_adjust_stack_sub_<mode>"
19282 [(set (match_operand:P 0 "register_operand" "=r")
19283 (minus:P (match_operand:P 1 "register_operand" "0")
19284 (match_operand:P 2 "register_operand" "r")))
19285 (clobber (reg:CC FLAGS_REG))
19286 (clobber (mem:BLK (scratch)))]
19288 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
19289 [(set_attr "type" "alu")
19290 (set_attr "mode" "<MODE>")])
19292 (define_insn "@allocate_stack_worker_probe_<mode>"
19293 [(set (match_operand:P 0 "register_operand" "=a")
19294 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
19295 UNSPECV_STACK_PROBE))
19296 (clobber (reg:CC FLAGS_REG))]
19297 "ix86_target_stack_probe ()"
19298 "call\t___chkstk_ms"
19299 [(set_attr "type" "multi")
19300 (set_attr "length" "5")])
19302 (define_expand "allocate_stack"
19303 [(match_operand 0 "register_operand")
19304 (match_operand 1 "general_operand")]
19305 "ix86_target_stack_probe ()"
19309 #ifndef CHECK_STACK_LIMIT
19310 #define CHECK_STACK_LIMIT 0
19313 if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
19314 && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
19318 x = copy_to_mode_reg (Pmode, operands[1]);
19320 emit_insn (gen_allocate_stack_worker_probe (Pmode, x, x));
19323 x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, x,
19324 stack_pointer_rtx, 0, OPTAB_DIRECT);
19326 if (x != stack_pointer_rtx)
19327 emit_move_insn (stack_pointer_rtx, x);
19329 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
19333 (define_expand "probe_stack"
19334 [(match_operand 0 "memory_operand")]
19337 emit_insn (gen_probe_stack_1
19338 (word_mode, operands[0], const0_rtx));
19342 ;; Use OR for stack probes, this is shorter.
19343 (define_insn "@probe_stack_1_<mode>"
19344 [(set (match_operand:W 0 "memory_operand" "=m")
19345 (unspec:W [(match_operand:W 1 "const0_operand")]
19346 UNSPEC_PROBE_STACK))
19347 (clobber (reg:CC FLAGS_REG))]
19349 "or{<imodesuffix>}\t{%1, %0|%0, %1}"
19350 [(set_attr "type" "alu1")
19351 (set_attr "mode" "<MODE>")
19352 (set_attr "length_immediate" "1")])
19354 (define_insn "@adjust_stack_and_probe_<mode>"
19355 [(set (match_operand:P 0 "register_operand" "=r")
19356 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
19357 UNSPECV_PROBE_STACK_RANGE))
19358 (set (reg:P SP_REG)
19359 (minus:P (reg:P SP_REG) (match_operand:P 2 "const_int_operand" "n")))
19360 (clobber (reg:CC FLAGS_REG))
19361 (clobber (mem:BLK (scratch)))]
19363 "* return output_adjust_stack_and_probe (operands[0]);"
19364 [(set_attr "type" "multi")])
19366 (define_insn "@probe_stack_range_<mode>"
19367 [(set (match_operand:P 0 "register_operand" "=r")
19368 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
19369 (match_operand:P 2 "const_int_operand" "n")]
19370 UNSPECV_PROBE_STACK_RANGE))
19371 (clobber (reg:CC FLAGS_REG))]
19373 "* return output_probe_stack_range (operands[0], operands[2]);"
19374 [(set_attr "type" "multi")])
19376 (define_expand "builtin_setjmp_receiver"
19377 [(label_ref (match_operand 0))]
19378 "!TARGET_64BIT && flag_pic"
19384 rtx_code_label *label_rtx = gen_label_rtx ();
19385 emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
19386 xops[0] = xops[1] = pic_offset_table_rtx;
19387 xops[2] = machopic_gen_offset (gen_rtx_LABEL_REF (SImode, label_rtx));
19388 ix86_expand_binary_operator (MINUS, SImode, xops);
19392 emit_insn (gen_set_got (pic_offset_table_rtx));
19396 (define_expand "save_stack_nonlocal"
19397 [(set (match_operand 0 "memory_operand")
19398 (match_operand 1 "register_operand"))]
19403 if (flag_cf_protection & CF_RETURN)
19405 /* Copy shadow stack pointer to the first slot
19406 and stack pointer to the second slot. */
19407 rtx ssp_slot = adjust_address (operands[0], word_mode, 0);
19408 stack_slot = adjust_address (operands[0], Pmode, UNITS_PER_WORD);
19410 rtx reg_ssp = force_reg (word_mode, const0_rtx);
19411 emit_insn (gen_rdssp (word_mode, reg_ssp, reg_ssp));
19412 emit_move_insn (ssp_slot, reg_ssp);
19415 stack_slot = adjust_address (operands[0], Pmode, 0);
19416 emit_move_insn (stack_slot, operands[1]);
19420 (define_expand "restore_stack_nonlocal"
19421 [(set (match_operand 0 "register_operand" "")
19422 (match_operand 1 "memory_operand" ""))]
19427 if (flag_cf_protection & CF_RETURN)
19429 /* Restore shadow stack pointer from the first slot
19430 and stack pointer from the second slot. */
19431 rtx ssp_slot = adjust_address (operands[1], word_mode, 0);
19432 stack_slot = adjust_address (operands[1], Pmode, UNITS_PER_WORD);
19434 /* Get the current shadow stack pointer. The code below will check if
19435 SHSTK feature is enabled. If it is not enabled the RDSSP instruction
19437 rtx reg_ssp = force_reg (word_mode, const0_rtx);
19438 emit_insn (gen_rdssp (word_mode, reg_ssp, reg_ssp));
19440 /* Compare through subtraction the saved and the current ssp
19441 to decide if ssp has to be adjusted. */
19442 reg_ssp = expand_simple_binop (word_mode, MINUS,
19444 reg_ssp, 1, OPTAB_DIRECT);
19446 /* Compare and jump over adjustment code. */
19447 rtx noadj_label = gen_label_rtx ();
19448 emit_cmp_and_jump_insns (reg_ssp, const0_rtx, EQ, NULL_RTX,
19449 word_mode, 1, noadj_label);
19451 /* Compute the number of frames to adjust. */
19452 rtx reg_adj = gen_lowpart (ptr_mode, reg_ssp);
19453 rtx reg_adj_neg = expand_simple_unop (ptr_mode, NEG, reg_adj,
19456 reg_adj = expand_simple_binop (ptr_mode, LSHIFTRT, reg_adj_neg,
19457 GEN_INT (exact_log2 (UNITS_PER_WORD)),
19458 reg_adj, 1, OPTAB_DIRECT);
19460 /* Check if number of frames <= 255 so no loop is needed. */
19461 rtx inc_label = gen_label_rtx ();
19462 emit_cmp_and_jump_insns (reg_adj, GEN_INT (255), LEU, NULL_RTX,
19463 ptr_mode, 1, inc_label);
19465 /* Adjust the ssp in a loop. */
19466 rtx loop_label = gen_label_rtx ();
19467 emit_label (loop_label);
19468 LABEL_NUSES (loop_label) = 1;
19470 rtx reg_255 = force_reg (word_mode, GEN_INT (255));
19471 emit_insn (gen_incssp (word_mode, reg_255));
19473 reg_adj = expand_simple_binop (ptr_mode, MINUS,
19474 reg_adj, GEN_INT (255),
19475 reg_adj, 1, OPTAB_DIRECT);
19477 /* Compare and jump to the loop label. */
19478 emit_cmp_and_jump_insns (reg_adj, GEN_INT (255), GTU, NULL_RTX,
19479 ptr_mode, 1, loop_label);
19481 emit_label (inc_label);
19482 LABEL_NUSES (inc_label) = 1;
19484 emit_insn (gen_incssp (word_mode, reg_ssp));
19486 emit_label (noadj_label);
19487 LABEL_NUSES (noadj_label) = 1;
19490 stack_slot = adjust_address (operands[1], Pmode, 0);
19491 emit_move_insn (operands[0], stack_slot);
19496 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
19497 ;; Do not split instructions with mask registers.
19499 [(set (match_operand 0 "general_reg_operand")
19500 (match_operator 3 "promotable_binary_operator"
19501 [(match_operand 1 "general_reg_operand")
19502 (match_operand 2 "aligned_operand")]))
19503 (clobber (reg:CC FLAGS_REG))]
19504 "! TARGET_PARTIAL_REG_STALL && reload_completed
19505 && ((GET_MODE (operands[0]) == HImode
19506 && ((optimize_function_for_speed_p (cfun) && !TARGET_FAST_PREFIX)
19507 /* ??? next two lines just !satisfies_constraint_K (...) */
19508 || !CONST_INT_P (operands[2])
19509 || satisfies_constraint_K (operands[2])))
19510 || (GET_MODE (operands[0]) == QImode
19511 && (TARGET_PROMOTE_QImode || optimize_function_for_size_p (cfun))))"
19512 [(parallel [(set (match_dup 0)
19513 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
19514 (clobber (reg:CC FLAGS_REG))])]
19516 operands[0] = gen_lowpart (SImode, operands[0]);
19517 operands[1] = gen_lowpart (SImode, operands[1]);
19518 if (GET_CODE (operands[3]) != ASHIFT)
19519 operands[2] = gen_lowpart (SImode, operands[2]);
19520 operands[3] = shallow_copy_rtx (operands[3]);
19521 PUT_MODE (operands[3], SImode);
19524 ; Promote the QImode tests, as i386 has encoding of the AND
19525 ; instruction with 32-bit sign-extended immediate and thus the
19526 ; instruction size is unchanged, except in the %eax case for
19527 ; which it is increased by one byte, hence the ! optimize_size.
19529 [(set (match_operand 0 "flags_reg_operand")
19530 (match_operator 2 "compare_operator"
19531 [(and (match_operand 3 "aligned_operand")
19532 (match_operand 4 "const_int_operand"))
19534 (set (match_operand 1 "register_operand")
19535 (and (match_dup 3) (match_dup 4)))]
19536 "! TARGET_PARTIAL_REG_STALL && reload_completed
19537 && optimize_insn_for_speed_p ()
19538 && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
19539 || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))
19540 /* Ensure that the operand will remain sign-extended immediate. */
19541 && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)"
19542 [(parallel [(set (match_dup 0)
19543 (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
19546 (and:SI (match_dup 3) (match_dup 4)))])]
19549 = gen_int_mode (INTVAL (operands[4])
19550 & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
19551 operands[1] = gen_lowpart (SImode, operands[1]);
19552 operands[3] = gen_lowpart (SImode, operands[3]);
19555 ; Don't promote the QImode tests, as i386 doesn't have encoding of
19556 ; the TEST instruction with 32-bit sign-extended immediate and thus
19557 ; the instruction size would at least double, which is not what we
19558 ; want even with ! optimize_size.
19560 [(set (match_operand 0 "flags_reg_operand")
19561 (match_operator 1 "compare_operator"
19562 [(and (match_operand:HI 2 "aligned_operand")
19563 (match_operand:HI 3 "const_int_operand"))
19565 "! TARGET_PARTIAL_REG_STALL && reload_completed
19566 && ! TARGET_FAST_PREFIX
19567 && optimize_insn_for_speed_p ()
19568 /* Ensure that the operand will remain sign-extended immediate. */
19569 && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)"
19570 [(set (match_dup 0)
19571 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
19575 = gen_int_mode (INTVAL (operands[3])
19576 & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
19577 operands[2] = gen_lowpart (SImode, operands[2]);
19581 [(set (match_operand 0 "register_operand")
19582 (neg (match_operand 1 "register_operand")))
19583 (clobber (reg:CC FLAGS_REG))]
19584 "! TARGET_PARTIAL_REG_STALL && reload_completed
19585 && (GET_MODE (operands[0]) == HImode
19586 || (GET_MODE (operands[0]) == QImode
19587 && (TARGET_PROMOTE_QImode
19588 || optimize_insn_for_size_p ())))"
19589 [(parallel [(set (match_dup 0)
19590 (neg:SI (match_dup 1)))
19591 (clobber (reg:CC FLAGS_REG))])]
19593 operands[0] = gen_lowpart (SImode, operands[0]);
19594 operands[1] = gen_lowpart (SImode, operands[1]);
19597 ;; Do not split instructions with mask regs.
19599 [(set (match_operand 0 "general_reg_operand")
19600 (not (match_operand 1 "general_reg_operand")))]
19601 "! TARGET_PARTIAL_REG_STALL && reload_completed
19602 && (GET_MODE (operands[0]) == HImode
19603 || (GET_MODE (operands[0]) == QImode
19604 && (TARGET_PROMOTE_QImode
19605 || optimize_insn_for_size_p ())))"
19606 [(set (match_dup 0)
19607 (not:SI (match_dup 1)))]
19609 operands[0] = gen_lowpart (SImode, operands[0]);
19610 operands[1] = gen_lowpart (SImode, operands[1]);
19613 ;; RTL Peephole optimizations, run before sched2. These primarily look to
19614 ;; transform a complex memory operation into two memory to register operations.
19616 ;; Don't push memory operands
19618 [(set (match_operand:SWI 0 "push_operand")
19619 (match_operand:SWI 1 "memory_operand"))
19620 (match_scratch:SWI 2 "<r>")]
19621 "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
19622 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19623 [(set (match_dup 2) (match_dup 1))
19624 (set (match_dup 0) (match_dup 2))])
19626 ;; We need to handle SFmode only, because DFmode and XFmode are split to
19629 [(set (match_operand:SF 0 "push_operand")
19630 (match_operand:SF 1 "memory_operand"))
19631 (match_scratch:SF 2 "r")]
19632 "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
19633 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19634 [(set (match_dup 2) (match_dup 1))
19635 (set (match_dup 0) (match_dup 2))])
19637 ;; Don't move an immediate directly to memory when the instruction
19638 ;; gets too big, or if LCP stalls are a problem for 16-bit moves.
19640 [(match_scratch:SWI124 1 "<r>")
19641 (set (match_operand:SWI124 0 "memory_operand")
19643 "optimize_insn_for_speed_p ()
19644 && ((<MODE>mode == HImode
19645 && TARGET_LCP_STALL)
19646 || (!TARGET_USE_MOV0
19647 && TARGET_SPLIT_LONG_MOVES
19648 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn))
19649 && peep2_regno_dead_p (0, FLAGS_REG)"
19650 [(parallel [(set (match_dup 2) (const_int 0))
19651 (clobber (reg:CC FLAGS_REG))])
19652 (set (match_dup 0) (match_dup 1))]
19653 "operands[2] = gen_lowpart (SImode, operands[1]);")
19656 [(match_scratch:SWI124 2 "<r>")
19657 (set (match_operand:SWI124 0 "memory_operand")
19658 (match_operand:SWI124 1 "immediate_operand"))]
19659 "optimize_insn_for_speed_p ()
19660 && ((<MODE>mode == HImode
19661 && TARGET_LCP_STALL)
19662 || (TARGET_SPLIT_LONG_MOVES
19663 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn))"
19664 [(set (match_dup 2) (match_dup 1))
19665 (set (match_dup 0) (match_dup 2))])
19667 ;; Don't compare memory with zero, load and use a test instead.
19669 [(set (match_operand 0 "flags_reg_operand")
19670 (match_operator 1 "compare_operator"
19671 [(match_operand:SI 2 "memory_operand")
19673 (match_scratch:SI 3 "r")]
19674 "optimize_insn_for_speed_p () && ix86_match_ccmode (insn, CCNOmode)"
19675 [(set (match_dup 3) (match_dup 2))
19676 (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))])
19678 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
19679 ;; Don't split NOTs with a displacement operand, because resulting XOR
19680 ;; will not be pairable anyway.
19682 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
19683 ;; represented using a modRM byte. The XOR replacement is long decoded,
19684 ;; so this split helps here as well.
19686 ;; Note: Can't do this as a regular split because we can't get proper
19687 ;; lifetime information then.
19690 [(set (match_operand:SWI124 0 "nonimmediate_gr_operand")
19691 (not:SWI124 (match_operand:SWI124 1 "nonimmediate_gr_operand")))]
19692 "optimize_insn_for_speed_p ()
19693 && ((TARGET_NOT_UNPAIRABLE
19694 && (!MEM_P (operands[0])
19695 || !memory_displacement_operand (operands[0], <MODE>mode)))
19696 || (TARGET_NOT_VECTORMODE
19697 && long_memory_operand (operands[0], <MODE>mode)))
19698 && peep2_regno_dead_p (0, FLAGS_REG)"
19699 [(parallel [(set (match_dup 0)
19700 (xor:SWI124 (match_dup 1) (const_int -1)))
19701 (clobber (reg:CC FLAGS_REG))])])
19703 ;; Non pairable "test imm, reg" instructions can be translated to
19704 ;; "and imm, reg" if reg dies. The "and" form is also shorter (one
19705 ;; byte opcode instead of two, have a short form for byte operands),
19706 ;; so do it for other CPUs as well. Given that the value was dead,
19707 ;; this should not create any new dependencies. Pass on the sub-word
19708 ;; versions if we're concerned about partial register stalls.
19711 [(set (match_operand 0 "flags_reg_operand")
19712 (match_operator 1 "compare_operator"
19713 [(and:SI (match_operand:SI 2 "register_operand")
19714 (match_operand:SI 3 "immediate_operand"))
19716 "ix86_match_ccmode (insn, CCNOmode)
19717 && (REGNO (operands[2]) != AX_REG
19718 || satisfies_constraint_K (operands[3]))
19719 && peep2_reg_dead_p (1, operands[2])"
19721 [(set (match_dup 0)
19722 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
19725 (and:SI (match_dup 2) (match_dup 3)))])])
19727 ;; We don't need to handle HImode case, because it will be promoted to SImode
19728 ;; on ! TARGET_PARTIAL_REG_STALL
19731 [(set (match_operand 0 "flags_reg_operand")
19732 (match_operator 1 "compare_operator"
19733 [(and:QI (match_operand:QI 2 "register_operand")
19734 (match_operand:QI 3 "immediate_operand"))
19736 "! TARGET_PARTIAL_REG_STALL
19737 && ix86_match_ccmode (insn, CCNOmode)
19738 && REGNO (operands[2]) != AX_REG
19739 && peep2_reg_dead_p (1, operands[2])"
19741 [(set (match_dup 0)
19742 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
19745 (and:QI (match_dup 2) (match_dup 3)))])])
19748 [(set (match_operand 0 "flags_reg_operand")
19749 (match_operator 1 "compare_operator"
19752 (zero_extract:SWI248 (match_operand:SWI248 2 "QIreg_operand")
19755 (match_operand 3 "const_int_operand"))
19757 "! TARGET_PARTIAL_REG_STALL
19758 && ix86_match_ccmode (insn, CCNOmode)
19759 && REGNO (operands[2]) != AX_REG
19760 && peep2_reg_dead_p (1, operands[2])"
19762 [(set (match_dup 0)
19766 (zero_extract:SWI248 (match_dup 2)
19771 (set (zero_extract:SWI248 (match_dup 2)
19777 (zero_extract:SWI248 (match_dup 2)
19780 (match_dup 3)) 0))])])
19782 ;; Don't do logical operations with memory inputs.
19784 [(match_scratch:SWI 2 "<r>")
19785 (parallel [(set (match_operand:SWI 0 "register_operand")
19786 (match_operator:SWI 3 "arith_or_logical_operator"
19788 (match_operand:SWI 1 "memory_operand")]))
19789 (clobber (reg:CC FLAGS_REG))])]
19790 "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
19791 [(set (match_dup 2) (match_dup 1))
19792 (parallel [(set (match_dup 0)
19793 (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
19794 (clobber (reg:CC FLAGS_REG))])])
19797 [(match_scratch:SWI 2 "<r>")
19798 (parallel [(set (match_operand:SWI 0 "register_operand")
19799 (match_operator:SWI 3 "arith_or_logical_operator"
19800 [(match_operand:SWI 1 "memory_operand")
19802 (clobber (reg:CC FLAGS_REG))])]
19803 "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
19804 [(set (match_dup 2) (match_dup 1))
19805 (parallel [(set (match_dup 0)
19806 (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
19807 (clobber (reg:CC FLAGS_REG))])])
19809 ;; Prefer Load+RegOp to Mov+MemOp. Watch out for cases when
19810 ;; the memory address refers to the destination of the load!
19813 [(set (match_operand:SWI 0 "general_reg_operand")
19814 (match_operand:SWI 1 "general_reg_operand"))
19815 (parallel [(set (match_dup 0)
19816 (match_operator:SWI 3 "commutative_operator"
19818 (match_operand:SWI 2 "memory_operand")]))
19819 (clobber (reg:CC FLAGS_REG))])]
19820 "REGNO (operands[0]) != REGNO (operands[1])
19821 && (<MODE>mode != QImode
19822 || any_QIreg_operand (operands[1], QImode))"
19823 [(set (match_dup 0) (match_dup 4))
19824 (parallel [(set (match_dup 0)
19825 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))
19826 (clobber (reg:CC FLAGS_REG))])]
19827 "operands[4] = replace_rtx (operands[2], operands[0], operands[1], true);")
19830 [(set (match_operand 0 "mmx_reg_operand")
19831 (match_operand 1 "mmx_reg_operand"))
19833 (match_operator 3 "commutative_operator"
19835 (match_operand 2 "memory_operand")]))]
19836 "REGNO (operands[0]) != REGNO (operands[1])"
19837 [(set (match_dup 0) (match_dup 2))
19839 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))])
19842 [(set (match_operand 0 "sse_reg_operand")
19843 (match_operand 1 "sse_reg_operand"))
19845 (match_operator 3 "commutative_operator"
19847 (match_operand 2 "memory_operand")]))]
19848 "REGNO (operands[0]) != REGNO (operands[1])"
19849 [(set (match_dup 0) (match_dup 2))
19851 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))])
19853 ; Don't do logical operations with memory outputs
19855 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
19856 ; instruction into two 1-uop insns plus a 2-uop insn. That last has
19857 ; the same decoder scheduling characteristics as the original.
19860 [(match_scratch:SWI 2 "<r>")
19861 (parallel [(set (match_operand:SWI 0 "memory_operand")
19862 (match_operator:SWI 3 "arith_or_logical_operator"
19864 (match_operand:SWI 1 "<nonmemory_operand>")]))
19865 (clobber (reg:CC FLAGS_REG))])]
19866 "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())"
19867 [(set (match_dup 2) (match_dup 0))
19868 (parallel [(set (match_dup 2)
19869 (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
19870 (clobber (reg:CC FLAGS_REG))])
19871 (set (match_dup 0) (match_dup 2))])
19874 [(match_scratch:SWI 2 "<r>")
19875 (parallel [(set (match_operand:SWI 0 "memory_operand")
19876 (match_operator:SWI 3 "arith_or_logical_operator"
19877 [(match_operand:SWI 1 "<nonmemory_operand>")
19879 (clobber (reg:CC FLAGS_REG))])]
19880 "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())"
19881 [(set (match_dup 2) (match_dup 0))
19882 (parallel [(set (match_dup 2)
19883 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
19884 (clobber (reg:CC FLAGS_REG))])
19885 (set (match_dup 0) (match_dup 2))])
19887 ;; Attempt to use arith or logical operations with memory outputs with
19888 ;; setting of flags.
19890 [(set (match_operand:SWI 0 "register_operand")
19891 (match_operand:SWI 1 "memory_operand"))
19892 (parallel [(set (match_dup 0)
19893 (match_operator:SWI 3 "plusminuslogic_operator"
19895 (match_operand:SWI 2 "<nonmemory_operand>")]))
19896 (clobber (reg:CC FLAGS_REG))])
19897 (set (match_dup 1) (match_dup 0))
19898 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
19899 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
19900 && peep2_reg_dead_p (4, operands[0])
19901 && !reg_overlap_mentioned_p (operands[0], operands[1])
19902 && !reg_overlap_mentioned_p (operands[0], operands[2])
19903 && (<MODE>mode != QImode
19904 || immediate_operand (operands[2], QImode)
19905 || any_QIreg_operand (operands[2], QImode))
19906 && ix86_match_ccmode (peep2_next_insn (3),
19907 (GET_CODE (operands[3]) == PLUS
19908 || GET_CODE (operands[3]) == MINUS)
19909 ? CCGOCmode : CCNOmode)"
19910 [(parallel [(set (match_dup 4) (match_dup 6))
19911 (set (match_dup 1) (match_dup 5))])]
19913 operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
19915 = gen_rtx_fmt_ee (GET_CODE (operands[3]), GET_MODE (operands[3]),
19916 copy_rtx (operands[1]),
19919 = gen_rtx_COMPARE (GET_MODE (operands[4]),
19920 copy_rtx (operands[5]),
19924 ;; Likewise for cmpelim optimized pattern.
19926 [(set (match_operand:SWI 0 "register_operand")
19927 (match_operand:SWI 1 "memory_operand"))
19928 (parallel [(set (reg FLAGS_REG)
19929 (compare (match_operator:SWI 3 "plusminuslogic_operator"
19931 (match_operand:SWI 2 "<nonmemory_operand>")])
19933 (set (match_dup 0) (match_dup 3))])
19934 (set (match_dup 1) (match_dup 0))]
19935 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
19936 && peep2_reg_dead_p (3, operands[0])
19937 && !reg_overlap_mentioned_p (operands[0], operands[1])
19938 && !reg_overlap_mentioned_p (operands[0], operands[2])
19939 && ix86_match_ccmode (peep2_next_insn (1),
19940 (GET_CODE (operands[3]) == PLUS
19941 || GET_CODE (operands[3]) == MINUS)
19942 ? CCGOCmode : CCNOmode)"
19943 [(parallel [(set (match_dup 4) (match_dup 6))
19944 (set (match_dup 1) (match_dup 5))])]
19946 operands[4] = SET_DEST (XVECEXP (PATTERN (peep2_next_insn (1)), 0, 0));
19948 = gen_rtx_fmt_ee (GET_CODE (operands[3]), GET_MODE (operands[3]),
19949 copy_rtx (operands[1]), operands[2]);
19951 = gen_rtx_COMPARE (GET_MODE (operands[4]), copy_rtx (operands[5]),
19955 ;; Likewise for instances where we have a lea pattern.
19957 [(set (match_operand:SWI 0 "register_operand")
19958 (match_operand:SWI 1 "memory_operand"))
19959 (set (match_operand:<LEAMODE> 3 "register_operand")
19960 (plus:<LEAMODE> (match_operand:<LEAMODE> 4 "register_operand")
19961 (match_operand:<LEAMODE> 2 "<nonmemory_operand>")))
19962 (set (match_dup 1) (match_operand:SWI 5 "register_operand"))
19963 (set (reg FLAGS_REG) (compare (match_dup 5) (const_int 0)))]
19964 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
19965 && REGNO (operands[4]) == REGNO (operands[0])
19966 && REGNO (operands[5]) == REGNO (operands[3])
19967 && peep2_reg_dead_p (4, operands[3])
19968 && ((REGNO (operands[0]) == REGNO (operands[3]))
19969 || peep2_reg_dead_p (2, operands[0]))
19970 && !reg_overlap_mentioned_p (operands[0], operands[1])
19971 && !reg_overlap_mentioned_p (operands[3], operands[1])
19972 && !reg_overlap_mentioned_p (operands[0], operands[2])
19973 && (<MODE>mode != QImode
19974 || immediate_operand (operands[2], QImode)
19975 || any_QIreg_operand (operands[2], QImode))
19976 && ix86_match_ccmode (peep2_next_insn (3), CCGOCmode)"
19977 [(parallel [(set (match_dup 6) (match_dup 8))
19978 (set (match_dup 1) (match_dup 7))])]
19980 operands[6] = SET_DEST (PATTERN (peep2_next_insn (3)));
19982 = gen_rtx_PLUS (<MODE>mode,
19983 copy_rtx (operands[1]),
19984 gen_lowpart (<MODE>mode, operands[2]));
19986 = gen_rtx_COMPARE (GET_MODE (operands[6]),
19987 copy_rtx (operands[7]),
19992 [(parallel [(set (match_operand:SWI 0 "register_operand")
19993 (match_operator:SWI 2 "plusminuslogic_operator"
19995 (match_operand:SWI 1 "memory_operand")]))
19996 (clobber (reg:CC FLAGS_REG))])
19997 (set (match_dup 1) (match_dup 0))
19998 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
19999 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
20000 && COMMUTATIVE_ARITH_P (operands[2])
20001 && peep2_reg_dead_p (3, operands[0])
20002 && !reg_overlap_mentioned_p (operands[0], operands[1])
20003 && ix86_match_ccmode (peep2_next_insn (2),
20004 GET_CODE (operands[2]) == PLUS
20005 ? CCGOCmode : CCNOmode)"
20006 [(parallel [(set (match_dup 3) (match_dup 5))
20007 (set (match_dup 1) (match_dup 4))])]
20009 operands[3] = SET_DEST (PATTERN (peep2_next_insn (2)));
20011 = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
20012 copy_rtx (operands[1]),
20015 = gen_rtx_COMPARE (GET_MODE (operands[3]),
20016 copy_rtx (operands[4]),
20020 ;; Likewise for cmpelim optimized pattern.
20022 [(parallel [(set (reg FLAGS_REG)
20023 (compare (match_operator:SWI 2 "plusminuslogic_operator"
20024 [(match_operand:SWI 0 "register_operand")
20025 (match_operand:SWI 1 "memory_operand")])
20027 (set (match_dup 0) (match_dup 2))])
20028 (set (match_dup 1) (match_dup 0))]
20029 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
20030 && COMMUTATIVE_ARITH_P (operands[2])
20031 && peep2_reg_dead_p (2, operands[0])
20032 && !reg_overlap_mentioned_p (operands[0], operands[1])
20033 && ix86_match_ccmode (peep2_next_insn (0),
20034 GET_CODE (operands[2]) == PLUS
20035 ? CCGOCmode : CCNOmode)"
20036 [(parallel [(set (match_dup 3) (match_dup 5))
20037 (set (match_dup 1) (match_dup 4))])]
20039 operands[3] = SET_DEST (XVECEXP (PATTERN (peep2_next_insn (0)), 0, 0));
20041 = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
20042 copy_rtx (operands[1]), operands[0]);
20044 = gen_rtx_COMPARE (GET_MODE (operands[3]), copy_rtx (operands[4]),
20049 [(set (match_operand:SWI12 0 "register_operand")
20050 (match_operand:SWI12 1 "memory_operand"))
20051 (parallel [(set (match_operand:SI 4 "register_operand")
20052 (match_operator:SI 3 "plusminuslogic_operator"
20054 (match_operand:SI 2 "nonmemory_operand")]))
20055 (clobber (reg:CC FLAGS_REG))])
20056 (set (match_dup 1) (match_dup 0))
20057 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
20058 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
20059 && REGNO (operands[0]) == REGNO (operands[4])
20060 && peep2_reg_dead_p (4, operands[0])
20061 && (<MODE>mode != QImode
20062 || immediate_operand (operands[2], SImode)
20063 || any_QIreg_operand (operands[2], SImode))
20064 && !reg_overlap_mentioned_p (operands[0], operands[1])
20065 && !reg_overlap_mentioned_p (operands[0], operands[2])
20066 && ix86_match_ccmode (peep2_next_insn (3),
20067 (GET_CODE (operands[3]) == PLUS
20068 || GET_CODE (operands[3]) == MINUS)
20069 ? CCGOCmode : CCNOmode)"
20070 [(parallel [(set (match_dup 5) (match_dup 7))
20071 (set (match_dup 1) (match_dup 6))])]
20073 operands[5] = SET_DEST (PATTERN (peep2_next_insn (3)));
20075 = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
20076 copy_rtx (operands[1]),
20077 gen_lowpart (<MODE>mode, operands[2]));
20079 = gen_rtx_COMPARE (GET_MODE (operands[5]),
20080 copy_rtx (operands[6]),
20084 ;; peephole2 comes before regcprop, so deal also with a case that
20085 ;; would be cleaned up by regcprop.
20087 [(set (match_operand:SWI 0 "register_operand")
20088 (match_operand:SWI 1 "memory_operand"))
20089 (parallel [(set (match_dup 0)
20090 (match_operator:SWI 3 "plusminuslogic_operator"
20092 (match_operand:SWI 2 "<nonmemory_operand>")]))
20093 (clobber (reg:CC FLAGS_REG))])
20094 (set (match_operand:SWI 4 "register_operand") (match_dup 0))
20095 (set (match_dup 1) (match_dup 4))
20096 (set (reg FLAGS_REG) (compare (match_dup 4) (const_int 0)))]
20097 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
20098 && peep2_reg_dead_p (3, operands[0])
20099 && peep2_reg_dead_p (5, operands[4])
20100 && !reg_overlap_mentioned_p (operands[0], operands[1])
20101 && !reg_overlap_mentioned_p (operands[0], operands[2])
20102 && !reg_overlap_mentioned_p (operands[4], operands[1])
20103 && (<MODE>mode != QImode
20104 || immediate_operand (operands[2], QImode)
20105 || any_QIreg_operand (operands[2], QImode))
20106 && ix86_match_ccmode (peep2_next_insn (4),
20107 (GET_CODE (operands[3]) == PLUS
20108 || GET_CODE (operands[3]) == MINUS)
20109 ? CCGOCmode : CCNOmode)"
20110 [(parallel [(set (match_dup 5) (match_dup 7))
20111 (set (match_dup 1) (match_dup 6))])]
20113 operands[5] = SET_DEST (PATTERN (peep2_next_insn (4)));
20115 = gen_rtx_fmt_ee (GET_CODE (operands[3]), GET_MODE (operands[3]),
20116 copy_rtx (operands[1]),
20119 = gen_rtx_COMPARE (GET_MODE (operands[5]),
20120 copy_rtx (operands[6]),
20125 [(set (match_operand:SWI12 0 "register_operand")
20126 (match_operand:SWI12 1 "memory_operand"))
20127 (parallel [(set (match_operand:SI 4 "register_operand")
20128 (match_operator:SI 3 "plusminuslogic_operator"
20130 (match_operand:SI 2 "nonmemory_operand")]))
20131 (clobber (reg:CC FLAGS_REG))])
20132 (set (match_operand:SWI12 5 "register_operand") (match_dup 0))
20133 (set (match_dup 1) (match_dup 5))
20134 (set (reg FLAGS_REG) (compare (match_dup 5) (const_int 0)))]
20135 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
20136 && REGNO (operands[0]) == REGNO (operands[4])
20137 && peep2_reg_dead_p (3, operands[0])
20138 && peep2_reg_dead_p (5, operands[5])
20139 && (<MODE>mode != QImode
20140 || immediate_operand (operands[2], SImode)
20141 || any_QIreg_operand (operands[2], SImode))
20142 && !reg_overlap_mentioned_p (operands[0], operands[1])
20143 && !reg_overlap_mentioned_p (operands[0], operands[2])
20144 && !reg_overlap_mentioned_p (operands[5], operands[1])
20145 && ix86_match_ccmode (peep2_next_insn (4),
20146 (GET_CODE (operands[3]) == PLUS
20147 || GET_CODE (operands[3]) == MINUS)
20148 ? CCGOCmode : CCNOmode)"
20149 [(parallel [(set (match_dup 6) (match_dup 8))
20150 (set (match_dup 1) (match_dup 7))])]
20152 operands[6] = SET_DEST (PATTERN (peep2_next_insn (4)));
20154 = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
20155 copy_rtx (operands[1]),
20156 gen_lowpart (<MODE>mode, operands[2]));
20158 = gen_rtx_COMPARE (GET_MODE (operands[6]),
20159 copy_rtx (operands[7]),
20163 ;; Likewise for cmpelim optimized pattern.
20165 [(set (match_operand:SWI 0 "register_operand")
20166 (match_operand:SWI 1 "memory_operand"))
20167 (parallel [(set (reg FLAGS_REG)
20168 (compare (match_operator:SWI 3 "plusminuslogic_operator"
20170 (match_operand:SWI 2 "<nonmemory_operand>")])
20172 (set (match_dup 0) (match_dup 3))])
20173 (set (match_operand:SWI 4 "register_operand") (match_dup 0))
20174 (set (match_dup 1) (match_dup 4))]
20175 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
20176 && peep2_reg_dead_p (3, operands[0])
20177 && peep2_reg_dead_p (4, operands[4])
20178 && !reg_overlap_mentioned_p (operands[0], operands[1])
20179 && !reg_overlap_mentioned_p (operands[0], operands[2])
20180 && !reg_overlap_mentioned_p (operands[4], operands[1])
20181 && ix86_match_ccmode (peep2_next_insn (1),
20182 (GET_CODE (operands[3]) == PLUS
20183 || GET_CODE (operands[3]) == MINUS)
20184 ? CCGOCmode : CCNOmode)"
20185 [(parallel [(set (match_dup 5) (match_dup 7))
20186 (set (match_dup 1) (match_dup 6))])]
20188 operands[5] = SET_DEST (XVECEXP (PATTERN (peep2_next_insn (1)), 0, 0));
20190 = gen_rtx_fmt_ee (GET_CODE (operands[3]), GET_MODE (operands[3]),
20191 copy_rtx (operands[1]), operands[2]);
20193 = gen_rtx_COMPARE (GET_MODE (operands[5]), copy_rtx (operands[6]),
20197 ;; Special cases for xor, where (x ^= y) != 0 is (misoptimized)
20198 ;; into x = z; x ^= y; x != z
20200 [(set (match_operand:SWI 0 "register_operand")
20201 (match_operand:SWI 1 "memory_operand"))
20202 (set (match_operand:SWI 3 "register_operand") (match_dup 0))
20203 (parallel [(set (match_operand:SWI 4 "register_operand")
20204 (xor:SWI (match_dup 4)
20205 (match_operand:SWI 2 "<nonmemory_operand>")))
20206 (clobber (reg:CC FLAGS_REG))])
20207 (set (match_dup 1) (match_dup 4))
20208 (set (reg:CCZ FLAGS_REG)
20209 (compare:CCZ (match_operand:SWI 5 "register_operand")
20210 (match_operand:SWI 6 "<nonmemory_operand>")))]
20211 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
20212 && (REGNO (operands[4]) == REGNO (operands[0])
20213 || REGNO (operands[4]) == REGNO (operands[3]))
20214 && (rtx_equal_p (operands[REGNO (operands[4]) == REGNO (operands[0])
20215 ? 3 : 0], operands[5])
20216 ? rtx_equal_p (operands[2], operands[6])
20217 : rtx_equal_p (operands[2], operands[5])
20218 && rtx_equal_p (operands[REGNO (operands[4]) == REGNO (operands[0])
20219 ? 3 : 0], operands[6]))
20220 && peep2_reg_dead_p (4, operands[4])
20221 && peep2_reg_dead_p (5, operands[REGNO (operands[4]) == REGNO (operands[0])
20223 && !reg_overlap_mentioned_p (operands[0], operands[1])
20224 && !reg_overlap_mentioned_p (operands[0], operands[2])
20225 && !reg_overlap_mentioned_p (operands[3], operands[0])
20226 && !reg_overlap_mentioned_p (operands[3], operands[1])
20227 && !reg_overlap_mentioned_p (operands[3], operands[2])
20228 && (<MODE>mode != QImode
20229 || immediate_operand (operands[2], QImode)
20230 || any_QIreg_operand (operands[2], QImode))"
20231 [(parallel [(set (match_dup 7) (match_dup 9))
20232 (set (match_dup 1) (match_dup 8))])]
20234 operands[7] = SET_DEST (PATTERN (peep2_next_insn (4)));
20235 operands[8] = gen_rtx_XOR (<MODE>mode, copy_rtx (operands[1]),
20238 = gen_rtx_COMPARE (GET_MODE (operands[7]),
20239 copy_rtx (operands[8]),
20244 [(set (match_operand:SWI12 0 "register_operand")
20245 (match_operand:SWI12 1 "memory_operand"))
20246 (set (match_operand:SWI12 3 "register_operand") (match_dup 0))
20247 (parallel [(set (match_operand:SI 4 "register_operand")
20248 (xor:SI (match_dup 4)
20249 (match_operand:SI 2 "<nonmemory_operand>")))
20250 (clobber (reg:CC FLAGS_REG))])
20251 (set (match_dup 1) (match_operand:SWI12 5 "register_operand"))
20252 (set (reg:CCZ FLAGS_REG)
20253 (compare:CCZ (match_operand:SWI12 6 "register_operand")
20254 (match_operand:SWI12 7 "<nonmemory_operand>")))]
20255 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
20256 && (REGNO (operands[5]) == REGNO (operands[0])
20257 || REGNO (operands[5]) == REGNO (operands[3]))
20258 && REGNO (operands[5]) == REGNO (operands[4])
20259 && (rtx_equal_p (operands[REGNO (operands[5]) == REGNO (operands[0])
20260 ? 3 : 0], operands[6])
20261 ? (REG_P (operands[2])
20262 ? REG_P (operands[7]) && REGNO (operands[2]) == REGNO (operands[7])
20263 : rtx_equal_p (operands[2], operands[7]))
20264 : (rtx_equal_p (operands[REGNO (operands[5]) == REGNO (operands[0])
20265 ? 3 : 0], operands[7])
20266 && REG_P (operands[2])
20267 && REGNO (operands[2]) == REGNO (operands[6])))
20268 && peep2_reg_dead_p (4, operands[5])
20269 && peep2_reg_dead_p (5, operands[REGNO (operands[5]) == REGNO (operands[0])
20271 && !reg_overlap_mentioned_p (operands[0], operands[1])
20272 && !reg_overlap_mentioned_p (operands[0], operands[2])
20273 && !reg_overlap_mentioned_p (operands[3], operands[0])
20274 && !reg_overlap_mentioned_p (operands[3], operands[1])
20275 && !reg_overlap_mentioned_p (operands[3], operands[2])
20276 && (<MODE>mode != QImode
20277 || immediate_operand (operands[2], SImode)
20278 || any_QIreg_operand (operands[2], SImode))"
20279 [(parallel [(set (match_dup 8) (match_dup 10))
20280 (set (match_dup 1) (match_dup 9))])]
20282 operands[8] = SET_DEST (PATTERN (peep2_next_insn (4)));
20283 operands[9] = gen_rtx_XOR (<MODE>mode, copy_rtx (operands[1]),
20284 gen_lowpart (<MODE>mode, operands[2]));
20286 = gen_rtx_COMPARE (GET_MODE (operands[8]),
20287 copy_rtx (operands[9]),
20291 ;; Attempt to optimize away memory stores of values the memory already
20292 ;; has. See PR79593.
20294 [(set (match_operand 0 "register_operand")
20295 (match_operand 1 "memory_operand"))
20296 (set (match_operand 2 "memory_operand") (match_dup 0))]
20297 "!MEM_VOLATILE_P (operands[1])
20298 && !MEM_VOLATILE_P (operands[2])
20299 && rtx_equal_p (operands[1], operands[2])
20300 && !reg_overlap_mentioned_p (operands[0], operands[2])"
20301 [(set (match_dup 0) (match_dup 1))])
20303 ;; Attempt to always use XOR for zeroing registers (including FP modes).
20305 [(set (match_operand 0 "general_reg_operand")
20306 (match_operand 1 "const0_operand"))]
20307 "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
20308 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
20309 && peep2_regno_dead_p (0, FLAGS_REG)"
20310 [(parallel [(set (match_dup 0) (const_int 0))
20311 (clobber (reg:CC FLAGS_REG))])]
20312 "operands[0] = gen_lowpart (word_mode, operands[0]);")
20315 [(set (strict_low_part (match_operand:SWI12 0 "general_reg_operand"))
20317 "(! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
20318 && peep2_regno_dead_p (0, FLAGS_REG)"
20319 [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
20320 (clobber (reg:CC FLAGS_REG))])])
20322 ;; For HI, SI and DI modes, or $-1,reg is smaller than mov $-1,reg.
20324 [(set (match_operand:SWI248 0 "general_reg_operand")
20326 "(TARGET_MOVE_M1_VIA_OR || optimize_insn_for_size_p ())
20327 && peep2_regno_dead_p (0, FLAGS_REG)"
20328 [(parallel [(set (match_dup 0) (const_int -1))
20329 (clobber (reg:CC FLAGS_REG))])]
20331 if (<MODE_SIZE> < GET_MODE_SIZE (SImode))
20332 operands[0] = gen_lowpart (SImode, operands[0]);
20335 ;; Attempt to convert simple lea to add/shift.
20336 ;; These can be created by move expanders.
20337 ;; Disable PLUS peepholes on TARGET_OPT_AGU, since all
20338 ;; relevant lea instructions were already split.
20341 [(set (match_operand:SWI48 0 "register_operand")
20342 (plus:SWI48 (match_dup 0)
20343 (match_operand:SWI48 1 "<nonmemory_operand>")))]
20345 && peep2_regno_dead_p (0, FLAGS_REG)"
20346 [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1)))
20347 (clobber (reg:CC FLAGS_REG))])])
20350 [(set (match_operand:SWI48 0 "register_operand")
20351 (plus:SWI48 (match_operand:SWI48 1 "<nonmemory_operand>")
20354 && peep2_regno_dead_p (0, FLAGS_REG)"
20355 [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1)))
20356 (clobber (reg:CC FLAGS_REG))])])
20359 [(set (match_operand:DI 0 "register_operand")
20361 (plus:SI (match_operand:SI 1 "register_operand")
20362 (match_operand:SI 2 "nonmemory_operand"))))]
20363 "TARGET_64BIT && !TARGET_OPT_AGU
20364 && REGNO (operands[0]) == REGNO (operands[1])
20365 && peep2_regno_dead_p (0, FLAGS_REG)"
20366 [(parallel [(set (match_dup 0)
20367 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))
20368 (clobber (reg:CC FLAGS_REG))])])
20371 [(set (match_operand:DI 0 "register_operand")
20373 (plus:SI (match_operand:SI 1 "nonmemory_operand")
20374 (match_operand:SI 2 "register_operand"))))]
20375 "TARGET_64BIT && !TARGET_OPT_AGU
20376 && REGNO (operands[0]) == REGNO (operands[2])
20377 && peep2_regno_dead_p (0, FLAGS_REG)"
20378 [(parallel [(set (match_dup 0)
20379 (zero_extend:DI (plus:SI (match_dup 2) (match_dup 1))))
20380 (clobber (reg:CC FLAGS_REG))])])
20383 [(set (match_operand:SWI48 0 "register_operand")
20384 (mult:SWI48 (match_dup 0)
20385 (match_operand:SWI48 1 "const_int_operand")))]
20386 "pow2p_hwi (INTVAL (operands[1]))
20387 && peep2_regno_dead_p (0, FLAGS_REG)"
20388 [(parallel [(set (match_dup 0) (ashift:SWI48 (match_dup 0) (match_dup 1)))
20389 (clobber (reg:CC FLAGS_REG))])]
20390 "operands[1] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
20393 [(set (match_operand:DI 0 "register_operand")
20395 (mult:SI (match_operand:SI 1 "register_operand")
20396 (match_operand:SI 2 "const_int_operand"))))]
20398 && pow2p_hwi (INTVAL (operands[2]))
20399 && REGNO (operands[0]) == REGNO (operands[1])
20400 && peep2_regno_dead_p (0, FLAGS_REG)"
20401 [(parallel [(set (match_dup 0)
20402 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))
20403 (clobber (reg:CC FLAGS_REG))])]
20404 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
20406 ;; The ESP adjustments can be done by the push and pop instructions. Resulting
20407 ;; code is shorter, since push is only 1 byte, while add imm, %esp is 3 bytes.
20408 ;; On many CPUs it is also faster, since special hardware to avoid esp
20409 ;; dependencies is present.
20411 ;; While some of these conversions may be done using splitters, we use
20412 ;; peepholes in order to allow combine_stack_adjustments pass to see
20413 ;; nonobfuscated RTL.
20415 ;; Convert prologue esp subtractions to push.
20416 ;; We need register to push. In order to keep verify_flow_info happy we have
20418 ;; - use scratch and clobber it in order to avoid dependencies
20419 ;; - use already live register
20420 ;; We can't use the second way right now, since there is no reliable way how to
20421 ;; verify that given register is live. First choice will also most likely in
20422 ;; fewer dependencies. On the place of esp adjustments it is very likely that
20423 ;; call clobbered registers are dead. We may want to use base pointer as an
20424 ;; alternative when no register is available later.
20427 [(match_scratch:W 1 "r")
20428 (parallel [(set (reg:P SP_REG)
20429 (plus:P (reg:P SP_REG)
20430 (match_operand:P 0 "const_int_operand")))
20431 (clobber (reg:CC FLAGS_REG))
20432 (clobber (mem:BLK (scratch)))])]
20433 "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
20434 && INTVAL (operands[0]) == -GET_MODE_SIZE (word_mode)
20435 && ix86_red_zone_size == 0"
20436 [(clobber (match_dup 1))
20437 (parallel [(set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
20438 (clobber (mem:BLK (scratch)))])])
20441 [(match_scratch:W 1 "r")
20442 (parallel [(set (reg:P SP_REG)
20443 (plus:P (reg:P SP_REG)
20444 (match_operand:P 0 "const_int_operand")))
20445 (clobber (reg:CC FLAGS_REG))
20446 (clobber (mem:BLK (scratch)))])]
20447 "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
20448 && INTVAL (operands[0]) == -2*GET_MODE_SIZE (word_mode)
20449 && ix86_red_zone_size == 0"
20450 [(clobber (match_dup 1))
20451 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
20452 (parallel [(set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
20453 (clobber (mem:BLK (scratch)))])])
20455 ;; Convert esp subtractions to push.
20457 [(match_scratch:W 1 "r")
20458 (parallel [(set (reg:P SP_REG)
20459 (plus:P (reg:P SP_REG)
20460 (match_operand:P 0 "const_int_operand")))
20461 (clobber (reg:CC FLAGS_REG))])]
20462 "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
20463 && INTVAL (operands[0]) == -GET_MODE_SIZE (word_mode)
20464 && ix86_red_zone_size == 0"
20465 [(clobber (match_dup 1))
20466 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
20469 [(match_scratch:W 1 "r")
20470 (parallel [(set (reg:P SP_REG)
20471 (plus:P (reg:P SP_REG)
20472 (match_operand:P 0 "const_int_operand")))
20473 (clobber (reg:CC FLAGS_REG))])]
20474 "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
20475 && INTVAL (operands[0]) == -2*GET_MODE_SIZE (word_mode)
20476 && ix86_red_zone_size == 0"
20477 [(clobber (match_dup 1))
20478 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
20479 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
20481 ;; Convert epilogue deallocator to pop.
20483 [(match_scratch:W 1 "r")
20484 (parallel [(set (reg:P SP_REG)
20485 (plus:P (reg:P SP_REG)
20486 (match_operand:P 0 "const_int_operand")))
20487 (clobber (reg:CC FLAGS_REG))
20488 (clobber (mem:BLK (scratch)))])]
20489 "(TARGET_SINGLE_POP || optimize_insn_for_size_p ())
20490 && INTVAL (operands[0]) == GET_MODE_SIZE (word_mode)"
20491 [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
20492 (clobber (mem:BLK (scratch)))])])
20494 ;; Two pops case is tricky, since pop causes dependency
20495 ;; on destination register. We use two registers if available.
20497 [(match_scratch:W 1 "r")
20498 (match_scratch:W 2 "r")
20499 (parallel [(set (reg:P SP_REG)
20500 (plus:P (reg:P SP_REG)
20501 (match_operand:P 0 "const_int_operand")))
20502 (clobber (reg:CC FLAGS_REG))
20503 (clobber (mem:BLK (scratch)))])]
20504 "(TARGET_DOUBLE_POP || optimize_insn_for_size_p ())
20505 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
20506 [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
20507 (clobber (mem:BLK (scratch)))])
20508 (set (match_dup 2) (mem:W (post_inc:P (reg:P SP_REG))))])
20511 [(match_scratch:W 1 "r")
20512 (parallel [(set (reg:P SP_REG)
20513 (plus:P (reg:P SP_REG)
20514 (match_operand:P 0 "const_int_operand")))
20515 (clobber (reg:CC FLAGS_REG))
20516 (clobber (mem:BLK (scratch)))])]
20517 "optimize_insn_for_size_p ()
20518 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
20519 [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
20520 (clobber (mem:BLK (scratch)))])
20521 (set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
20523 ;; Convert esp additions to pop.
20525 [(match_scratch:W 1 "r")
20526 (parallel [(set (reg:P SP_REG)
20527 (plus:P (reg:P SP_REG)
20528 (match_operand:P 0 "const_int_operand")))
20529 (clobber (reg:CC FLAGS_REG))])]
20530 "INTVAL (operands[0]) == GET_MODE_SIZE (word_mode)"
20531 [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
20533 ;; Two pops case is tricky, since pop causes dependency
20534 ;; on destination register. We use two registers if available.
20536 [(match_scratch:W 1 "r")
20537 (match_scratch:W 2 "r")
20538 (parallel [(set (reg:P SP_REG)
20539 (plus:P (reg:P SP_REG)
20540 (match_operand:P 0 "const_int_operand")))
20541 (clobber (reg:CC FLAGS_REG))])]
20542 "INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
20543 [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
20544 (set (match_dup 2) (mem:W (post_inc:P (reg:P SP_REG))))])
20547 [(match_scratch:W 1 "r")
20548 (parallel [(set (reg:P SP_REG)
20549 (plus:P (reg:P SP_REG)
20550 (match_operand:P 0 "const_int_operand")))
20551 (clobber (reg:CC FLAGS_REG))])]
20552 "optimize_insn_for_size_p ()
20553 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
20554 [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
20555 (set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
20557 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
20558 ;; required and register dies. Similarly for 128 to -128.
20560 [(set (match_operand 0 "flags_reg_operand")
20561 (match_operator 1 "compare_operator"
20562 [(match_operand 2 "register_operand")
20563 (match_operand 3 "const_int_operand")]))]
20564 "(((!TARGET_FUSE_CMP_AND_BRANCH || optimize_insn_for_size_p ())
20565 && incdec_operand (operands[3], GET_MODE (operands[3])))
20566 || (!TARGET_FUSE_CMP_AND_BRANCH
20567 && INTVAL (operands[3]) == 128))
20568 && ix86_match_ccmode (insn, CCGCmode)
20569 && peep2_reg_dead_p (1, operands[2])"
20570 [(parallel [(set (match_dup 0)
20571 (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
20572 (clobber (match_dup 2))])])
20574 ;; Convert imul by three, five and nine into lea
20577 [(set (match_operand:SWI48 0 "register_operand")
20578 (mult:SWI48 (match_operand:SWI48 1 "register_operand")
20579 (match_operand:SWI48 2 "const359_operand")))
20580 (clobber (reg:CC FLAGS_REG))])]
20581 "!TARGET_PARTIAL_REG_STALL
20582 || <MODE>mode == SImode
20583 || optimize_function_for_size_p (cfun)"
20584 [(set (match_dup 0)
20585 (plus:SWI48 (mult:SWI48 (match_dup 1) (match_dup 2))
20587 "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
20591 [(set (match_operand:SWI48 0 "register_operand")
20592 (mult:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
20593 (match_operand:SWI48 2 "const359_operand")))
20594 (clobber (reg:CC FLAGS_REG))])]
20595 "optimize_insn_for_speed_p ()
20596 && (!TARGET_PARTIAL_REG_STALL || <MODE>mode == SImode)"
20597 [(set (match_dup 0) (match_dup 1))
20599 (plus:SWI48 (mult:SWI48 (match_dup 0) (match_dup 2))
20601 "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
20603 ;; imul $32bit_imm, mem, reg is vector decoded, while
20604 ;; imul $32bit_imm, reg, reg is direct decoded.
20606 [(match_scratch:SWI48 3 "r")
20607 (parallel [(set (match_operand:SWI48 0 "register_operand")
20608 (mult:SWI48 (match_operand:SWI48 1 "memory_operand")
20609 (match_operand:SWI48 2 "immediate_operand")))
20610 (clobber (reg:CC FLAGS_REG))])]
20611 "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
20612 && !satisfies_constraint_K (operands[2])"
20613 [(set (match_dup 3) (match_dup 1))
20614 (parallel [(set (match_dup 0) (mult:SWI48 (match_dup 3) (match_dup 2)))
20615 (clobber (reg:CC FLAGS_REG))])])
20618 [(match_scratch:SI 3 "r")
20619 (parallel [(set (match_operand:DI 0 "register_operand")
20621 (mult:SI (match_operand:SI 1 "memory_operand")
20622 (match_operand:SI 2 "immediate_operand"))))
20623 (clobber (reg:CC FLAGS_REG))])]
20625 && TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
20626 && !satisfies_constraint_K (operands[2])"
20627 [(set (match_dup 3) (match_dup 1))
20628 (parallel [(set (match_dup 0)
20629 (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
20630 (clobber (reg:CC FLAGS_REG))])])
20632 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
20633 ;; Convert it into imul reg, reg
20634 ;; It would be better to force assembler to encode instruction using long
20635 ;; immediate, but there is apparently no way to do so.
20637 [(parallel [(set (match_operand:SWI248 0 "register_operand")
20639 (match_operand:SWI248 1 "nonimmediate_operand")
20640 (match_operand:SWI248 2 "const_int_operand")))
20641 (clobber (reg:CC FLAGS_REG))])
20642 (match_scratch:SWI248 3 "r")]
20643 "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
20644 && satisfies_constraint_K (operands[2])"
20645 [(set (match_dup 3) (match_dup 2))
20646 (parallel [(set (match_dup 0) (mult:SWI248 (match_dup 0) (match_dup 3)))
20647 (clobber (reg:CC FLAGS_REG))])]
20649 if (!rtx_equal_p (operands[0], operands[1]))
20650 emit_move_insn (operands[0], operands[1]);
20653 ;; After splitting up read-modify operations, array accesses with memory
20654 ;; operands might end up in form:
20656 ;; movl 4(%esp), %edx
20658 ;; instead of pre-splitting:
20660 ;; addl 4(%esp), %eax
20662 ;; movl 4(%esp), %edx
20663 ;; leal (%edx,%eax,4), %eax
20666 [(match_scratch:W 5 "r")
20667 (parallel [(set (match_operand 0 "register_operand")
20668 (ashift (match_operand 1 "register_operand")
20669 (match_operand 2 "const_int_operand")))
20670 (clobber (reg:CC FLAGS_REG))])
20671 (parallel [(set (match_operand 3 "register_operand")
20672 (plus (match_dup 0)
20673 (match_operand 4 "x86_64_general_operand")))
20674 (clobber (reg:CC FLAGS_REG))])]
20675 "IN_RANGE (INTVAL (operands[2]), 1, 3)
20676 /* Validate MODE for lea. */
20677 && ((!TARGET_PARTIAL_REG_STALL
20678 && (GET_MODE (operands[0]) == QImode
20679 || GET_MODE (operands[0]) == HImode))
20680 || GET_MODE (operands[0]) == SImode
20681 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
20682 && (rtx_equal_p (operands[0], operands[3])
20683 || peep2_reg_dead_p (2, operands[0]))
20684 /* We reorder load and the shift. */
20685 && !reg_overlap_mentioned_p (operands[0], operands[4])"
20686 [(set (match_dup 5) (match_dup 4))
20687 (set (match_dup 0) (match_dup 1))]
20689 machine_mode op1mode = GET_MODE (operands[1]);
20690 machine_mode mode = op1mode == DImode ? DImode : SImode;
20691 int scale = 1 << INTVAL (operands[2]);
20692 rtx index = gen_lowpart (word_mode, operands[1]);
20693 rtx base = gen_lowpart (word_mode, operands[5]);
20694 rtx dest = gen_lowpart (mode, operands[3]);
20696 operands[1] = gen_rtx_PLUS (word_mode, base,
20697 gen_rtx_MULT (word_mode, index, GEN_INT (scale)));
20698 if (mode != word_mode)
20699 operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
20701 operands[5] = base;
20702 if (op1mode != word_mode)
20703 operands[5] = gen_lowpart (op1mode, operands[5]);
20705 operands[0] = dest;
20708 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
20709 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
20710 ;; caught for use by garbage collectors and the like. Using an insn that
20711 ;; maps to SIGILL makes it more likely the program will rightfully die.
20712 ;; Keeping with tradition, "6" is in honor of #UD.
20713 (define_insn "trap"
20714 [(trap_if (const_int 1) (const_int 6))]
20717 #ifdef HAVE_AS_IX86_UD2
20720 return ASM_SHORT "0x0b0f";
20723 [(set_attr "length" "2")])
20726 [(unspec_volatile [(const_int 0)] UNSPECV_UD2)]
20729 #ifdef HAVE_AS_IX86_UD2
20732 return ASM_SHORT "0x0b0f";
20735 [(set_attr "length" "2")])
20737 (define_expand "prefetch"
20738 [(prefetch (match_operand 0 "address_operand")
20739 (match_operand:SI 1 "const_int_operand")
20740 (match_operand:SI 2 "const_int_operand"))]
20741 "TARGET_3DNOW || TARGET_PREFETCH_SSE || TARGET_PRFCHW || TARGET_PREFETCHWT1"
20743 bool write = operands[1] != const0_rtx;
20744 int locality = INTVAL (operands[2]);
20746 gcc_assert (IN_RANGE (locality, 0, 3));
20748 /* Use 3dNOW prefetch in case we are asking for write prefetch not
20749 supported by SSE counterpart (non-SSE2 athlon machines) or the
20750 SSE prefetch is not available (K6 machines). Otherwise use SSE
20751 prefetch as it allows specifying of locality. */
20755 if (TARGET_PREFETCHWT1)
20756 operands[2] = GEN_INT (MAX (locality, 2));
20757 else if (TARGET_PRFCHW)
20758 operands[2] = GEN_INT (3);
20759 else if (TARGET_3DNOW && !TARGET_SSE2)
20760 operands[2] = GEN_INT (3);
20761 else if (TARGET_PREFETCH_SSE)
20762 operands[1] = const0_rtx;
20765 gcc_assert (TARGET_3DNOW);
20766 operands[2] = GEN_INT (3);
20771 if (TARGET_PREFETCH_SSE)
20775 gcc_assert (TARGET_3DNOW);
20776 operands[2] = GEN_INT (3);
20781 (define_insn "*prefetch_sse"
20782 [(prefetch (match_operand 0 "address_operand" "p")
20784 (match_operand:SI 1 "const_int_operand"))]
20785 "TARGET_PREFETCH_SSE"
20787 static const char * const patterns[4] = {
20788 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
20791 int locality = INTVAL (operands[1]);
20792 gcc_assert (IN_RANGE (locality, 0, 3));
20794 return patterns[locality];
20796 [(set_attr "type" "sse")
20797 (set_attr "atom_sse_attr" "prefetch")
20798 (set (attr "length_address")
20799 (symbol_ref "memory_address_length (operands[0], false)"))
20800 (set_attr "memory" "none")])
20802 (define_insn "*prefetch_3dnow"
20803 [(prefetch (match_operand 0 "address_operand" "p")
20804 (match_operand:SI 1 "const_int_operand" "n")
20806 "TARGET_3DNOW || TARGET_PRFCHW || TARGET_PREFETCHWT1"
20808 if (operands[1] == const0_rtx)
20809 return "prefetch\t%a0";
20811 return "prefetchw\t%a0";
20813 [(set_attr "type" "mmx")
20814 (set (attr "length_address")
20815 (symbol_ref "memory_address_length (operands[0], false)"))
20816 (set_attr "memory" "none")])
20818 (define_insn "*prefetch_prefetchwt1"
20819 [(prefetch (match_operand 0 "address_operand" "p")
20822 "TARGET_PREFETCHWT1"
20823 "prefetchwt1\t%a0";
20824 [(set_attr "type" "sse")
20825 (set (attr "length_address")
20826 (symbol_ref "memory_address_length (operands[0], false)"))
20827 (set_attr "memory" "none")])
20829 (define_expand "stack_protect_set"
20830 [(match_operand 0 "memory_operand")
20831 (match_operand 1 "memory_operand")]
20834 emit_insn (gen_stack_protect_set_1
20835 (ptr_mode, operands[0], operands[1]));
20839 (define_insn "@stack_protect_set_1_<mode>"
20840 [(set (match_operand:PTR 0 "memory_operand" "=m")
20841 (unspec:PTR [(match_operand:PTR 1 "memory_operand" "m")]
20843 (set (match_scratch:PTR 2 "=&r") (const_int 0))
20844 (clobber (reg:CC FLAGS_REG))]
20847 output_asm_insn ("mov{<imodesuffix>}\t{%1, %2|%2, %1}", operands);
20848 output_asm_insn ("mov{<imodesuffix>}\t{%2, %0|%0, %2}", operands);
20849 return "xor{l}\t%k2, %k2";
20851 [(set_attr "type" "multi")])
20853 ;; Patterns and peephole2s to optimize stack_protect_set_1_<mode>
20854 ;; immediately followed by *mov{s,d}i_internal to the same register,
20855 ;; where we can avoid the xor{l} above. We don't split this, so that
20856 ;; scheduling or anything else doesn't separate the *stack_protect_set*
20857 ;; pattern from the set of the register that overwrites the register
20858 ;; with a new value.
20859 (define_insn "*stack_protect_set_2_<mode>"
20860 [(set (match_operand:PTR 0 "memory_operand" "=m")
20861 (unspec:PTR [(match_operand:PTR 3 "memory_operand" "m")]
20863 (set (match_operand:SI 1 "register_operand" "=&r")
20864 (match_operand:SI 2 "general_operand" "g"))
20865 (clobber (reg:CC FLAGS_REG))]
20867 && !reg_overlap_mentioned_p (operands[1], operands[2])"
20869 output_asm_insn ("mov{<imodesuffix>}\t{%3, %<k>1|%<k>1, %3}", operands);
20870 output_asm_insn ("mov{<imodesuffix>}\t{%<k>1, %0|%0, %<k>1}", operands);
20871 if (pic_32bit_operand (operands[2], SImode)
20872 || ix86_use_lea_for_mov (insn, operands + 1))
20873 return "lea{l}\t{%E2, %1|%1, %E2}";
20875 return "mov{l}\t{%2, %1|%1, %2}";
20877 [(set_attr "type" "multi")
20878 (set_attr "length" "24")])
20881 [(parallel [(set (match_operand:PTR 0 "memory_operand")
20882 (unspec:PTR [(match_operand:PTR 1 "memory_operand")]
20884 (set (match_operand:PTR 2 "general_reg_operand") (const_int 0))
20885 (clobber (reg:CC FLAGS_REG))])
20886 (set (match_operand:SI 3 "general_reg_operand")
20887 (match_operand:SI 4))]
20888 "REGNO (operands[2]) == REGNO (operands[3])
20889 && general_operand (operands[4], SImode)
20890 && (general_reg_operand (operands[4], SImode)
20891 || memory_operand (operands[4], SImode)
20892 || immediate_operand (operands[4], SImode))
20893 && !reg_overlap_mentioned_p (operands[3], operands[4])"
20894 [(parallel [(set (match_dup 0)
20895 (unspec:PTR [(match_dup 1)] UNSPEC_SP_SET))
20896 (set (match_dup 3) (match_dup 4))
20897 (clobber (reg:CC FLAGS_REG))])])
20899 (define_insn "*stack_protect_set_3"
20900 [(set (match_operand:DI 0 "memory_operand" "=m,m,m")
20901 (unspec:DI [(match_operand:DI 3 "memory_operand" "m,m,m")]
20903 (set (match_operand:DI 1 "register_operand" "=&r,r,r")
20904 (match_operand:DI 2 "general_operand" "Z,rem,i"))
20905 (clobber (reg:CC FLAGS_REG))]
20907 && reload_completed
20908 && !reg_overlap_mentioned_p (operands[1], operands[2])"
20910 output_asm_insn ("mov{q}\t{%3, %1|%1, %3}", operands);
20911 output_asm_insn ("mov{q}\t{%1, %0|%0, %1}", operands);
20912 if (pic_32bit_operand (operands[2], DImode))
20913 return "lea{q}\t{%E2, %1|%1, %E2}";
20914 else if (which_alternative == 0)
20915 return "mov{l}\t{%k2, %k1|%k1, %k2}";
20916 else if (which_alternative == 2)
20917 return "movabs{q}\t{%2, %1|%1, %2}";
20918 else if (ix86_use_lea_for_mov (insn, operands + 1))
20919 return "lea{q}\t{%E2, %1|%1, %E2}";
20921 return "mov{q}\t{%2, %1|%1, %2}";
20923 [(set_attr "type" "multi")
20924 (set_attr "length" "24")])
20927 [(parallel [(set (match_operand:DI 0 "memory_operand")
20928 (unspec:DI [(match_operand:DI 1 "memory_operand")]
20930 (set (match_operand:DI 2 "general_reg_operand") (const_int 0))
20931 (clobber (reg:CC FLAGS_REG))])
20932 (set (match_dup 2) (match_operand:DI 3))]
20934 && general_operand (operands[3], DImode)
20935 && (general_reg_operand (operands[3], DImode)
20936 || memory_operand (operands[3], DImode)
20937 || x86_64_zext_immediate_operand (operands[3], DImode)
20938 || x86_64_immediate_operand (operands[3], DImode)
20939 || (CONSTANT_P (operands[3])
20940 && (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[3]))))
20941 && !reg_overlap_mentioned_p (operands[2], operands[3])"
20942 [(parallel [(set (match_dup 0)
20943 (unspec:PTR [(match_dup 1)] UNSPEC_SP_SET))
20944 (set (match_dup 2) (match_dup 3))
20945 (clobber (reg:CC FLAGS_REG))])])
20947 (define_expand "stack_protect_test"
20948 [(match_operand 0 "memory_operand")
20949 (match_operand 1 "memory_operand")
20953 rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
20955 emit_insn (gen_stack_protect_test_1
20956 (ptr_mode, flags, operands[0], operands[1]));
20958 emit_jump_insn (gen_cbranchcc4 (gen_rtx_EQ (VOIDmode, flags, const0_rtx),
20959 flags, const0_rtx, operands[2]));
20963 (define_insn "@stack_protect_test_1_<mode>"
20964 [(set (match_operand:CCZ 0 "flags_reg_operand")
20965 (unspec:CCZ [(match_operand:PTR 1 "memory_operand" "m")
20966 (match_operand:PTR 2 "memory_operand" "m")]
20968 (clobber (match_scratch:PTR 3 "=&r"))]
20971 output_asm_insn ("mov{<imodesuffix>}\t{%1, %3|%3, %1}", operands);
20972 return "sub{<imodesuffix>}\t{%2, %3|%3, %2}";
20974 [(set_attr "type" "multi")])
20976 (define_insn "sse4_2_crc32<mode>"
20977 [(set (match_operand:SI 0 "register_operand" "=r")
20979 [(match_operand:SI 1 "register_operand" "0")
20980 (match_operand:SWI124 2 "nonimmediate_operand" "<r>m")]
20982 "TARGET_SSE4_2 || TARGET_CRC32"
20983 "crc32{<imodesuffix>}\t{%2, %0|%0, %2}"
20984 [(set_attr "type" "sselog1")
20985 (set_attr "prefix_rep" "1")
20986 (set_attr "prefix_extra" "1")
20987 (set (attr "prefix_data16")
20988 (if_then_else (match_operand:HI 2)
20990 (const_string "*")))
20991 (set (attr "prefix_rex")
20992 (if_then_else (match_operand:QI 2 "ext_QIreg_operand")
20994 (const_string "*")))
20995 (set_attr "mode" "SI")])
20997 (define_insn "sse4_2_crc32di"
20998 [(set (match_operand:DI 0 "register_operand" "=r")
21000 [(match_operand:DI 1 "register_operand" "0")
21001 (match_operand:DI 2 "nonimmediate_operand" "rm")]
21003 "TARGET_64BIT && (TARGET_SSE4_2 || TARGET_CRC32)"
21004 "crc32{q}\t{%2, %0|%0, %2}"
21005 [(set_attr "type" "sselog1")
21006 (set_attr "prefix_rep" "1")
21007 (set_attr "prefix_extra" "1")
21008 (set_attr "mode" "DI")])
21010 (define_insn "rdpmc"
21011 [(set (match_operand:DI 0 "register_operand" "=A")
21012 (unspec_volatile:DI [(match_operand:SI 1 "register_operand" "c")]
21016 [(set_attr "type" "other")
21017 (set_attr "length" "2")])
21019 (define_insn "rdpmc_rex64"
21020 [(set (match_operand:DI 0 "register_operand" "=a")
21021 (unspec_volatile:DI [(match_operand:SI 2 "register_operand" "c")]
21023 (set (match_operand:DI 1 "register_operand" "=d")
21024 (unspec_volatile:DI [(match_dup 2)] UNSPECV_RDPMC))]
21027 [(set_attr "type" "other")
21028 (set_attr "length" "2")])
21030 (define_insn "rdtsc"
21031 [(set (match_operand:DI 0 "register_operand" "=A")
21032 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
21035 [(set_attr "type" "other")
21036 (set_attr "length" "2")])
21038 (define_insn "rdtsc_rex64"
21039 [(set (match_operand:DI 0 "register_operand" "=a")
21040 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))
21041 (set (match_operand:DI 1 "register_operand" "=d")
21042 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
21045 [(set_attr "type" "other")
21046 (set_attr "length" "2")])
21048 (define_insn "rdtscp"
21049 [(set (match_operand:DI 0 "register_operand" "=A")
21050 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
21051 (set (match_operand:SI 1 "register_operand" "=c")
21052 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
21055 [(set_attr "type" "other")
21056 (set_attr "length" "3")])
21058 (define_insn "rdtscp_rex64"
21059 [(set (match_operand:DI 0 "register_operand" "=a")
21060 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
21061 (set (match_operand:DI 1 "register_operand" "=d")
21062 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
21063 (set (match_operand:SI 2 "register_operand" "=c")
21064 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
21067 [(set_attr "type" "other")
21068 (set_attr "length" "3")])
21070 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
21072 ;; FXSR, XSAVE and XSAVEOPT instructions
21074 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
21076 (define_insn "fxsave"
21077 [(set (match_operand:BLK 0 "memory_operand" "=m")
21078 (unspec_volatile:BLK [(const_int 0)] UNSPECV_FXSAVE))]
21081 [(set_attr "type" "other")
21082 (set_attr "memory" "store")
21083 (set (attr "length")
21084 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
21086 (define_insn "fxsave64"
21087 [(set (match_operand:BLK 0 "memory_operand" "=m")
21088 (unspec_volatile:BLK [(const_int 0)] UNSPECV_FXSAVE64))]
21089 "TARGET_64BIT && TARGET_FXSR"
21091 [(set_attr "type" "other")
21092 (set_attr "memory" "store")
21093 (set (attr "length")
21094 (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
21096 (define_insn "fxrstor"
21097 [(unspec_volatile [(match_operand:BLK 0 "memory_operand" "m")]
21101 [(set_attr "type" "other")
21102 (set_attr "memory" "load")
21103 (set (attr "length")
21104 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
21106 (define_insn "fxrstor64"
21107 [(unspec_volatile [(match_operand:BLK 0 "memory_operand" "m")]
21108 UNSPECV_FXRSTOR64)]
21109 "TARGET_64BIT && TARGET_FXSR"
21111 [(set_attr "type" "other")
21112 (set_attr "memory" "load")
21113 (set (attr "length")
21114 (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
21116 (define_int_iterator ANY_XSAVE
21118 (UNSPECV_XSAVEOPT "TARGET_XSAVEOPT")
21119 (UNSPECV_XSAVEC "TARGET_XSAVEC")
21120 (UNSPECV_XSAVES "TARGET_XSAVES")])
21122 (define_int_iterator ANY_XSAVE64
21124 (UNSPECV_XSAVEOPT64 "TARGET_XSAVEOPT")
21125 (UNSPECV_XSAVEC64 "TARGET_XSAVEC")
21126 (UNSPECV_XSAVES64 "TARGET_XSAVES")])
21128 (define_int_attr xsave
21129 [(UNSPECV_XSAVE "xsave")
21130 (UNSPECV_XSAVE64 "xsave64")
21131 (UNSPECV_XSAVEOPT "xsaveopt")
21132 (UNSPECV_XSAVEOPT64 "xsaveopt64")
21133 (UNSPECV_XSAVEC "xsavec")
21134 (UNSPECV_XSAVEC64 "xsavec64")
21135 (UNSPECV_XSAVES "xsaves")
21136 (UNSPECV_XSAVES64 "xsaves64")])
21138 (define_int_iterator ANY_XRSTOR
21140 (UNSPECV_XRSTORS "TARGET_XSAVES")])
21142 (define_int_iterator ANY_XRSTOR64
21144 (UNSPECV_XRSTORS64 "TARGET_XSAVES")])
21146 (define_int_attr xrstor
21147 [(UNSPECV_XRSTOR "xrstor")
21148 (UNSPECV_XRSTOR64 "xrstor")
21149 (UNSPECV_XRSTORS "xrstors")
21150 (UNSPECV_XRSTORS64 "xrstors")])
21152 (define_insn "<xsave>"
21153 [(set (match_operand:BLK 0 "memory_operand" "=m")
21154 (unspec_volatile:BLK
21155 [(match_operand:DI 1 "register_operand" "A")]
21157 "!TARGET_64BIT && TARGET_XSAVE"
21159 [(set_attr "type" "other")
21160 (set_attr "memory" "store")
21161 (set (attr "length")
21162 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
21164 (define_insn "<xsave>_rex64"
21165 [(set (match_operand:BLK 0 "memory_operand" "=m")
21166 (unspec_volatile:BLK
21167 [(match_operand:SI 1 "register_operand" "a")
21168 (match_operand:SI 2 "register_operand" "d")]
21170 "TARGET_64BIT && TARGET_XSAVE"
21172 [(set_attr "type" "other")
21173 (set_attr "memory" "store")
21174 (set (attr "length")
21175 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
21177 (define_insn "<xsave>"
21178 [(set (match_operand:BLK 0 "memory_operand" "=m")
21179 (unspec_volatile:BLK
21180 [(match_operand:SI 1 "register_operand" "a")
21181 (match_operand:SI 2 "register_operand" "d")]
21183 "TARGET_64BIT && TARGET_XSAVE"
21185 [(set_attr "type" "other")
21186 (set_attr "memory" "store")
21187 (set (attr "length")
21188 (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
21190 (define_insn "<xrstor>"
21191 [(unspec_volatile:BLK
21192 [(match_operand:BLK 0 "memory_operand" "m")
21193 (match_operand:DI 1 "register_operand" "A")]
21195 "!TARGET_64BIT && TARGET_XSAVE"
21197 [(set_attr "type" "other")
21198 (set_attr "memory" "load")
21199 (set (attr "length")
21200 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
21202 (define_insn "<xrstor>_rex64"
21203 [(unspec_volatile:BLK
21204 [(match_operand:BLK 0 "memory_operand" "m")
21205 (match_operand:SI 1 "register_operand" "a")
21206 (match_operand:SI 2 "register_operand" "d")]
21208 "TARGET_64BIT && TARGET_XSAVE"
21210 [(set_attr "type" "other")
21211 (set_attr "memory" "load")
21212 (set (attr "length")
21213 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
21215 (define_insn "<xrstor>64"
21216 [(unspec_volatile:BLK
21217 [(match_operand:BLK 0 "memory_operand" "m")
21218 (match_operand:SI 1 "register_operand" "a")
21219 (match_operand:SI 2 "register_operand" "d")]
21221 "TARGET_64BIT && TARGET_XSAVE"
21223 [(set_attr "type" "other")
21224 (set_attr "memory" "load")
21225 (set (attr "length")
21226 (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
21228 (define_insn "xsetbv"
21229 [(unspec_volatile:SI
21230 [(match_operand:SI 0 "register_operand" "c")
21231 (match_operand:DI 1 "register_operand" "A")]
21233 "!TARGET_64BIT && TARGET_XSAVE"
21235 [(set_attr "type" "other")])
21237 (define_insn "xsetbv_rex64"
21238 [(unspec_volatile:SI
21239 [(match_operand:SI 0 "register_operand" "c")
21240 (match_operand:SI 1 "register_operand" "a")
21241 (match_operand:SI 2 "register_operand" "d")]
21243 "TARGET_64BIT && TARGET_XSAVE"
21245 [(set_attr "type" "other")])
21247 (define_insn "xgetbv"
21248 [(set (match_operand:DI 0 "register_operand" "=A")
21249 (unspec_volatile:DI [(match_operand:SI 1 "register_operand" "c")]
21251 "!TARGET_64BIT && TARGET_XSAVE"
21253 [(set_attr "type" "other")])
21255 (define_insn "xgetbv_rex64"
21256 [(set (match_operand:DI 0 "register_operand" "=a")
21257 (unspec_volatile:DI [(match_operand:SI 2 "register_operand" "c")]
21259 (set (match_operand:DI 1 "register_operand" "=d")
21260 (unspec_volatile:DI [(match_dup 2)] UNSPECV_XGETBV))]
21261 "TARGET_64BIT && TARGET_XSAVE"
21263 [(set_attr "type" "other")])
21265 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
21267 ;; Floating-point instructions for atomic compound assignments
21269 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
21271 ; Clobber all floating-point registers on environment save and restore
21272 ; to ensure that the TOS value saved at fnstenv is valid after fldenv.
21273 (define_insn "fnstenv"
21274 [(set (match_operand:BLK 0 "memory_operand" "=m")
21275 (unspec_volatile:BLK [(const_int 0)] UNSPECV_FNSTENV))
21276 (clobber (reg:XF ST0_REG))
21277 (clobber (reg:XF ST1_REG))
21278 (clobber (reg:XF ST2_REG))
21279 (clobber (reg:XF ST3_REG))
21280 (clobber (reg:XF ST4_REG))
21281 (clobber (reg:XF ST5_REG))
21282 (clobber (reg:XF ST6_REG))
21283 (clobber (reg:XF ST7_REG))]
21286 [(set_attr "type" "other")
21287 (set_attr "memory" "store")
21288 (set (attr "length")
21289 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))])
21291 (define_insn "fldenv"
21292 [(unspec_volatile [(match_operand:BLK 0 "memory_operand" "m")]
21294 (clobber (reg:XF ST0_REG))
21295 (clobber (reg:XF ST1_REG))
21296 (clobber (reg:XF ST2_REG))
21297 (clobber (reg:XF ST3_REG))
21298 (clobber (reg:XF ST4_REG))
21299 (clobber (reg:XF ST5_REG))
21300 (clobber (reg:XF ST6_REG))
21301 (clobber (reg:XF ST7_REG))]
21304 [(set_attr "type" "other")
21305 (set_attr "memory" "load")
21306 (set (attr "length")
21307 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))])
21309 (define_insn "fnstsw"
21310 [(set (match_operand:HI 0 "nonimmediate_operand" "=a,m")
21311 (unspec_volatile:HI [(const_int 0)] UNSPECV_FNSTSW))]
21314 [(set_attr "type" "other,other")
21315 (set_attr "memory" "none,store")
21316 (set (attr "length")
21317 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))])
21319 (define_insn "fnclex"
21320 [(unspec_volatile [(const_int 0)] UNSPECV_FNCLEX)]
21323 [(set_attr "type" "other")
21324 (set_attr "memory" "none")
21325 (set_attr "length" "2")])
21327 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
21329 ;; LWP instructions
21331 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
21333 (define_insn "@lwp_llwpcb<mode>"
21334 [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
21335 UNSPECV_LLWP_INTRINSIC)]
21338 [(set_attr "type" "lwp")
21339 (set_attr "mode" "<MODE>")
21340 (set_attr "length" "5")])
21342 (define_insn "@lwp_slwpcb<mode>"
21343 [(set (match_operand:P 0 "register_operand" "=r")
21344 (unspec_volatile:P [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
21347 [(set_attr "type" "lwp")
21348 (set_attr "mode" "<MODE>")
21349 (set_attr "length" "5")])
21351 (define_insn "@lwp_lwpval<mode>"
21352 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")
21353 (match_operand:SI 1 "nonimmediate_operand" "rm")
21354 (match_operand:SI 2 "const_int_operand" "i")]
21355 UNSPECV_LWPVAL_INTRINSIC)]
21357 "lwpval\t{%2, %1, %0|%0, %1, %2}"
21358 [(set_attr "type" "lwp")
21359 (set_attr "mode" "<MODE>")
21360 (set (attr "length")
21361 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
21363 (define_insn "@lwp_lwpins<mode>"
21364 [(set (reg:CCC FLAGS_REG)
21365 (unspec_volatile:CCC [(match_operand:SWI48 0 "register_operand" "r")
21366 (match_operand:SI 1 "nonimmediate_operand" "rm")
21367 (match_operand:SI 2 "const_int_operand" "i")]
21368 UNSPECV_LWPINS_INTRINSIC))]
21370 "lwpins\t{%2, %1, %0|%0, %1, %2}"
21371 [(set_attr "type" "lwp")
21372 (set_attr "mode" "<MODE>")
21373 (set (attr "length")
21374 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
21376 (define_int_iterator RDFSGSBASE
21380 (define_int_iterator WRFSGSBASE
21384 (define_int_attr fsgs
21385 [(UNSPECV_RDFSBASE "fs")
21386 (UNSPECV_RDGSBASE "gs")
21387 (UNSPECV_WRFSBASE "fs")
21388 (UNSPECV_WRGSBASE "gs")])
21390 (define_insn "rd<fsgs>base<mode>"
21391 [(set (match_operand:SWI48 0 "register_operand" "=r")
21392 (unspec_volatile:SWI48 [(const_int 0)] RDFSGSBASE))]
21393 "TARGET_64BIT && TARGET_FSGSBASE"
21395 [(set_attr "type" "other")
21396 (set_attr "prefix_extra" "2")])
21398 (define_insn "wr<fsgs>base<mode>"
21399 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
21401 "TARGET_64BIT && TARGET_FSGSBASE"
21403 [(set_attr "type" "other")
21404 (set_attr "prefix_extra" "2")])
21406 (define_insn "ptwrite<mode>"
21407 [(unspec_volatile [(match_operand:SWI48 0 "nonimmediate_operand" "rm")]
21411 [(set_attr "type" "other")
21412 (set_attr "prefix_extra" "2")])
21414 (define_insn "@rdrand<mode>"
21415 [(set (match_operand:SWI248 0 "register_operand" "=r")
21416 (unspec_volatile:SWI248 [(const_int 0)] UNSPECV_RDRAND))
21417 (set (reg:CCC FLAGS_REG)
21418 (unspec_volatile:CCC [(const_int 0)] UNSPECV_RDRAND))]
21421 [(set_attr "type" "other")
21422 (set_attr "prefix_extra" "1")])
21424 (define_insn "@rdseed<mode>"
21425 [(set (match_operand:SWI248 0 "register_operand" "=r")
21426 (unspec_volatile:SWI248 [(const_int 0)] UNSPECV_RDSEED))
21427 (set (reg:CCC FLAGS_REG)
21428 (unspec_volatile:CCC [(const_int 0)] UNSPECV_RDSEED))]
21431 [(set_attr "type" "other")
21432 (set_attr "prefix_extra" "1")])
21434 (define_expand "pause"
21435 [(set (match_dup 0)
21436 (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
21439 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
21440 MEM_VOLATILE_P (operands[0]) = 1;
21443 ;; Use "rep; nop", instead of "pause", to support older assemblers.
21444 ;; They have the same encoding.
21445 (define_insn "*pause"
21446 [(set (match_operand:BLK 0)
21447 (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
21450 [(set_attr "length" "2")
21451 (set_attr "memory" "unknown")])
21453 ;; CET instructions
21454 (define_insn "@rdssp<mode>"
21455 [(set (match_operand:SWI48 0 "register_operand" "=r")
21456 (unspec_volatile:SWI48 [(match_operand:SWI48 1 "register_operand" "0")]
21457 UNSPECV_NOP_RDSSP))]
21458 "TARGET_SHSTK || (flag_cf_protection & CF_RETURN)"
21459 "rdssp<mskmodesuffix>\t%0"
21460 [(set_attr "length" "6")
21461 (set_attr "type" "other")])
21463 (define_insn "@incssp<mode>"
21464 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
21466 "TARGET_SHSTK || (flag_cf_protection & CF_RETURN)"
21467 "incssp<mskmodesuffix>\t%0"
21468 [(set_attr "length" "4")
21469 (set_attr "type" "other")])
21471 (define_insn "saveprevssp"
21472 [(unspec_volatile [(const_int 0)] UNSPECV_SAVEPREVSSP)]
21475 [(set_attr "length" "5")
21476 (set_attr "type" "other")])
21478 (define_insn "rstorssp"
21479 [(unspec_volatile [(match_operand:DI 0 "memory_operand" "m")]
21483 [(set_attr "length" "5")
21484 (set_attr "type" "other")])
21486 (define_insn "@wrss<mode>"
21487 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")
21488 (match_operand:SWI48 1 "memory_operand" "m")]
21491 "wrss<mskmodesuffix>\t%0, %1"
21492 [(set_attr "length" "3")
21493 (set_attr "type" "other")])
21495 (define_insn "@wruss<mode>"
21496 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")
21497 (match_operand:SWI48 1 "memory_operand" "m")]
21500 "wruss<mskmodesuffix>\t%0, %1"
21501 [(set_attr "length" "4")
21502 (set_attr "type" "other")])
21504 (define_insn "setssbsy"
21505 [(unspec_volatile [(const_int 0)] UNSPECV_SETSSBSY)]
21508 [(set_attr "length" "4")
21509 (set_attr "type" "other")])
21511 (define_insn "clrssbsy"
21512 [(unspec_volatile [(match_operand:DI 0 "memory_operand" "m")]
21516 [(set_attr "length" "4")
21517 (set_attr "type" "other")])
21519 (define_insn "nop_endbr"
21520 [(unspec_volatile [(const_int 0)] UNSPECV_NOP_ENDBR)]
21521 "(flag_cf_protection & CF_BRANCH)"
21523 return TARGET_64BIT ? "endbr64" : "endbr32";
21525 [(set_attr "length" "4")
21526 (set_attr "length_immediate" "0")
21527 (set_attr "modrm" "0")])
21530 (define_expand "xbegin"
21531 [(set (match_operand:SI 0 "register_operand")
21532 (unspec_volatile:SI [(const_int 0)] UNSPECV_XBEGIN))]
21535 rtx_code_label *label = gen_label_rtx ();
21537 /* xbegin is emitted as jump_insn, so reload won't be able
21538 to reload its operand. Force the value into AX hard register. */
21539 rtx ax_reg = gen_rtx_REG (SImode, AX_REG);
21540 emit_move_insn (ax_reg, constm1_rtx);
21542 emit_jump_insn (gen_xbegin_1 (ax_reg, label));
21544 emit_label (label);
21545 LABEL_NUSES (label) = 1;
21547 emit_move_insn (operands[0], ax_reg);
21552 (define_insn "xbegin_1"
21554 (if_then_else (ne (unspec [(const_int 0)] UNSPEC_XBEGIN_ABORT)
21556 (label_ref (match_operand 1))
21558 (set (match_operand:SI 0 "register_operand" "+a")
21559 (unspec_volatile:SI [(match_dup 0)] UNSPECV_XBEGIN))]
21562 [(set_attr "type" "other")
21563 (set_attr "length" "6")])
21565 (define_insn "xend"
21566 [(unspec_volatile [(const_int 0)] UNSPECV_XEND)]
21569 [(set_attr "type" "other")
21570 (set_attr "length" "3")])
21572 (define_insn "xabort"
21573 [(unspec_volatile [(match_operand:SI 0 "const_0_to_255_operand" "n")]
21577 [(set_attr "type" "other")
21578 (set_attr "length" "3")])
21580 (define_expand "xtest"
21581 [(set (match_operand:QI 0 "register_operand")
21582 (unspec_volatile:QI [(const_int 0)] UNSPECV_XTEST))]
21585 emit_insn (gen_xtest_1 ());
21587 ix86_expand_setcc (operands[0], NE,
21588 gen_rtx_REG (CCZmode, FLAGS_REG), const0_rtx);
21592 (define_insn "xtest_1"
21593 [(set (reg:CCZ FLAGS_REG)
21594 (unspec_volatile:CCZ [(const_int 0)] UNSPECV_XTEST))]
21597 [(set_attr "type" "other")
21598 (set_attr "length" "3")])
21600 (define_insn "clwb"
21601 [(unspec_volatile [(match_operand 0 "address_operand" "p")]
21605 [(set_attr "type" "sse")
21606 (set_attr "atom_sse_attr" "fence")
21607 (set_attr "memory" "unknown")])
21609 (define_insn "clflushopt"
21610 [(unspec_volatile [(match_operand 0 "address_operand" "p")]
21611 UNSPECV_CLFLUSHOPT)]
21612 "TARGET_CLFLUSHOPT"
21614 [(set_attr "type" "sse")
21615 (set_attr "atom_sse_attr" "fence")
21616 (set_attr "memory" "unknown")])
21618 ;; MONITORX and MWAITX
21619 (define_insn "mwaitx"
21620 [(unspec_volatile [(match_operand:SI 0 "register_operand" "c")
21621 (match_operand:SI 1 "register_operand" "a")
21622 (match_operand:SI 2 "register_operand" "b")]
21625 ;; 64bit version is "mwaitx %rax,%rcx,%rbx". But only lower 32bits are used.
21626 ;; Since 32bit register operands are implicitly zero extended to 64bit,
21627 ;; we only need to set up 32bit registers.
21629 [(set_attr "length" "3")])
21631 (define_insn "@monitorx_<mode>"
21632 [(unspec_volatile [(match_operand:P 0 "register_operand" "a")
21633 (match_operand:SI 1 "register_operand" "c")
21634 (match_operand:SI 2 "register_operand" "d")]
21637 ;; 64bit version is "monitorx %rax,%rcx,%rdx". But only lower 32bits in
21638 ;; RCX and RDX are used. Since 32bit register operands are implicitly
21639 ;; zero extended to 64bit, we only need to set up 32bit registers.
21641 [(set (attr "length")
21642 (symbol_ref ("(Pmode != word_mode) + 3")))])
21645 (define_insn "@clzero_<mode>"
21646 [(unspec_volatile [(match_operand: P 0 "register_operand" "a")]
21650 [(set_attr "length" "3")
21651 (set_attr "memory" "unknown")])
21653 ;; RDPKRU and WRPKRU
21655 (define_expand "rdpkru"
21657 [(set (match_operand:SI 0 "register_operand")
21658 (unspec_volatile:SI [(match_dup 1)] UNSPECV_PKU))
21659 (set (match_dup 2) (const_int 0))])]
21662 operands[1] = force_reg (SImode, const0_rtx);
21663 operands[2] = gen_reg_rtx (SImode);
21666 (define_insn "*rdpkru"
21667 [(set (match_operand:SI 0 "register_operand" "=a")
21668 (unspec_volatile:SI [(match_operand:SI 2 "register_operand" "c")]
21670 (set (match_operand:SI 1 "register_operand" "=d")
21674 [(set_attr "type" "other")])
21676 (define_expand "wrpkru"
21677 [(unspec_volatile:SI
21678 [(match_operand:SI 0 "register_operand")
21679 (match_dup 1) (match_dup 2)] UNSPECV_PKU)]
21682 operands[1] = force_reg (SImode, const0_rtx);
21683 operands[2] = force_reg (SImode, const0_rtx);
21686 (define_insn "*wrpkru"
21687 [(unspec_volatile:SI
21688 [(match_operand:SI 0 "register_operand" "a")
21689 (match_operand:SI 1 "register_operand" "d")
21690 (match_operand:SI 2 "register_operand" "c")] UNSPECV_PKU)]
21693 [(set_attr "type" "other")])
21695 (define_insn "rdpid"
21696 [(set (match_operand:SI 0 "register_operand" "=r")
21697 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDPID))]
21698 "!TARGET_64BIT && TARGET_RDPID"
21700 [(set_attr "type" "other")])
21702 (define_insn "rdpid_rex64"
21703 [(set (match_operand:DI 0 "register_operand" "=r")
21704 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDPID))]
21705 "TARGET_64BIT && TARGET_RDPID"
21707 [(set_attr "type" "other")])
21709 ;; Intirinsics for > i486
21711 (define_insn "wbinvd"
21712 [(unspec_volatile [(const_int 0)] UNSPECV_WBINVD)]
21715 [(set_attr "type" "other")])
21717 (define_insn "wbnoinvd"
21718 [(unspec_volatile [(const_int 0)] UNSPECV_WBNOINVD)]
21721 [(set_attr "type" "other")])
21723 ;; MOVDIRI and MOVDIR64B
21725 (define_insn "movdiri<mode>"
21726 [(set (match_operand:SWI48 0 "memory_operand" "=m")
21727 (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")]
21730 "movdiri\t{%1, %0|%0, %1}"
21731 [(set_attr "type" "other")])
21733 (define_insn "@movdir64b_<mode>"
21734 [(set (mem:XI (match_operand:P 0 "register_operand" "r"))
21735 (unspec:XI [(match_operand:XI 1 "memory_operand" "m")]
21736 UNSPEC_MOVDIR64B))]
21738 "movdir64b\t{%1, %0|%0, %1}"
21739 [(set_attr "type" "other")])
21742 (define_int_iterator TSXLDTRK [UNSPECV_XSUSLDTRK UNSPECV_XRESLDTRK])
21743 (define_int_attr tsxldtrk [(UNSPECV_XSUSLDTRK "xsusldtrk")
21744 (UNSPECV_XRESLDTRK "xresldtrk")])
21745 (define_insn "<tsxldtrk>"
21746 [(unspec_volatile [(const_int 0)] TSXLDTRK)]
21749 [(set_attr "type" "other")
21750 (set_attr "length" "4")])
21752 ;; ENQCMD and ENQCMDS
21754 (define_int_iterator ENQCMD [UNSPECV_ENQCMD UNSPECV_ENQCMDS])
21755 (define_int_attr enqcmd_sfx [(UNSPECV_ENQCMD "") (UNSPECV_ENQCMDS "s")])
21757 (define_insn "@enqcmd<enqcmd_sfx>_<mode>"
21758 [(set (reg:CCZ FLAGS_REG)
21759 (unspec_volatile:CCZ [(match_operand:P 0 "register_operand" "r")
21760 (match_operand:XI 1 "memory_operand" "m")]
21763 "enqcmd<enqcmd_sfx>\t{%1, %0|%0, %1}"
21764 [(set_attr "type" "other")])
21767 (define_int_iterator UINTR [UNSPECV_CLUI UNSPECV_STUI])
21768 (define_int_attr uintr [(UNSPECV_CLUI "clui") (UNSPECV_STUI "stui")])
21770 (define_insn "<uintr>"
21771 [(unspec_volatile [(const_int 0)] UINTR)]
21772 "TARGET_UINTR && TARGET_64BIT"
21774 [(set_attr "type" "other")
21775 (set_attr "length" "4")])
21777 (define_insn "testui"
21778 [(set (reg:CCC FLAGS_REG)
21779 (unspec_volatile:CCC [(const_int 0)] UNSPECV_TESTUI))]
21780 "TARGET_UINTR && TARGET_64BIT"
21782 [(set_attr "type" "other")
21783 (set_attr "length" "4")])
21785 (define_insn "senduipi"
21787 [(match_operand:DI 0 "register_operand" "r")]
21789 "TARGET_UINTR && TARGET_64BIT"
21791 [(set_attr "type" "other")
21792 (set_attr "length" "4")])
21796 (define_insn "umwait"
21797 [(set (reg:CCC FLAGS_REG)
21798 (unspec_volatile:CCC [(match_operand:SI 0 "register_operand" "r")
21799 (match_operand:DI 1 "register_operand" "A")]
21801 "!TARGET_64BIT && TARGET_WAITPKG"
21803 [(set_attr "length" "3")])
21805 (define_insn "umwait_rex64"
21806 [(set (reg:CCC FLAGS_REG)
21807 (unspec_volatile:CCC [(match_operand:SI 0 "register_operand" "r")
21808 (match_operand:SI 1 "register_operand" "a")
21809 (match_operand:SI 2 "register_operand" "d")]
21811 "TARGET_64BIT && TARGET_WAITPKG"
21813 [(set_attr "length" "3")])
21815 (define_insn "@umonitor_<mode>"
21816 [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
21820 [(set (attr "length")
21821 (symbol_ref ("(Pmode != word_mode) + 3")))])
21823 (define_insn "tpause"
21824 [(set (reg:CCC FLAGS_REG)
21825 (unspec_volatile:CCC [(match_operand:SI 0 "register_operand" "r")
21826 (match_operand:DI 1 "register_operand" "A")]
21828 "!TARGET_64BIT && TARGET_WAITPKG"
21830 [(set_attr "length" "3")])
21832 (define_insn "tpause_rex64"
21833 [(set (reg:CCC FLAGS_REG)
21834 (unspec_volatile:CCC [(match_operand:SI 0 "register_operand" "r")
21835 (match_operand:SI 1 "register_operand" "a")
21836 (match_operand:SI 2 "register_operand" "d")]
21838 "TARGET_64BIT && TARGET_WAITPKG"
21840 [(set_attr "length" "3")])
21842 (define_insn "cldemote"
21843 [(unspec_volatile[(match_operand 0 "address_operand" "p")]
21847 [(set_attr "type" "other")
21848 (set_attr "memory" "unknown")])
21850 (define_insn "speculation_barrier"
21851 [(unspec_volatile [(const_int 0)] UNSPECV_SPECULATION_BARRIER)]
21854 [(set_attr "type" "other")
21855 (set_attr "length" "3")])
21857 (define_insn "serialize"
21858 [(unspec_volatile [(const_int 0)] UNSPECV_SERIALIZE)]
21861 [(set_attr "type" "other")
21862 (set_attr "length" "3")])
21864 (define_insn "patchable_area"
21865 [(unspec_volatile [(match_operand 0 "const_int_operand")
21866 (match_operand 1 "const_int_operand")]
21867 UNSPECV_PATCHABLE_AREA)]
21870 ix86_output_patchable_area (INTVAL (operands[0]),
21871 INTVAL (operands[1]) != 0);
21874 [(set (attr "length") (symbol_ref "INTVAL (operands[0])"))
21875 (set_attr "length_immediate" "0")
21876 (set_attr "modrm" "0")])
21878 (define_insn "hreset"
21879 [(unspec_volatile [(match_operand:SI 0 "register_operand" "a")]
21883 [(set_attr "type" "other")
21884 (set_attr "length" "4")])
21888 (include "sync.md")