1 ;; GCC machine description for IA-32 and x86-64.
2 ;; Copyright (C) 1988-2018 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
107 UNSPEC_LD_MPIC ; load_macho_picbase
109 UNSPEC_DIV_ALREADY_SPLIT
115 UNSPEC_INSN_FALSE_DEP
118 ;; For SSE/MMX support:
126 ;; Generic math support
128 UNSPEC_IEEE_MIN ; not commutative
129 UNSPEC_IEEE_MAX ; not commutative
131 ;; x87 Floating point
147 UNSPEC_FRNDINT_MASK_PM
151 ;; x87 Double output FP
176 ;; For LZCNT suppoprt
198 UNSPEC_INTERRUPT_RETURN
201 (define_c_enum "unspecv" [
205 UNSPECV_PROBE_STACK_RANGE
208 UNSPECV_SPLIT_STACK_RETURN
214 UNSPECV_LLWP_INTRINSIC
215 UNSPECV_SLWP_INTRINSIC
216 UNSPECV_LWPVAL_INTRINSIC
217 UNSPECV_LWPINS_INTRINSIC
243 ;; For atomic compound assignments.
249 ;; For RDRAND support
252 ;; For RDSEED support
266 ;; For CLFLUSHOPT support
269 ;; For MONITORX and MWAITX support
273 ;; For CLZERO support
276 ;; For RDPKRU and WRPKRU support
293 ;; For MOVDIRI and MOVDIR64B support
297 ;; For WAITPKG support
302 ;; For CLDEMOTE support
305 ;; For Speculation Barrier support
306 UNSPECV_SPECULATION_BARRIER
309 ;; Constants to represent rounding modes in the ROUND instruction
318 ;; Constants to represent AVX512F embeded rounding
320 [(ROUND_NEAREST_INT 0)
328 ;; Constants to represent pcomtrue/pcomfalse variants
338 ;; Constants used in the XOP pperm instruction
340 [(PPERM_SRC 0x00) /* copy source */
341 (PPERM_INVERT 0x20) /* invert source */
342 (PPERM_REVERSE 0x40) /* bit reverse source */
343 (PPERM_REV_INV 0x60) /* bit reverse & invert src */
344 (PPERM_ZERO 0x80) /* all 0's */
345 (PPERM_ONES 0xa0) /* all 1's */
346 (PPERM_SIGN 0xc0) /* propagate sign bit */
347 (PPERM_INV_SIGN 0xe0) /* invert & propagate sign */
348 (PPERM_SRC1 0x00) /* use first source byte */
349 (PPERM_SRC2 0x10) /* use second source byte */
352 ;; Registers by name.
435 (FIRST_PSEUDO_REG 81)
438 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
441 ;; In C guard expressions, put expressions which may be compile-time
442 ;; constants first. This allows for better optimization. For
443 ;; example, write "TARGET_64BIT && reload_completed", not
444 ;; "reload_completed && TARGET_64BIT".
448 (define_attr "cpu" "none,pentium,pentiumpro,geode,k6,athlon,k8,core2,nehalem,
449 atom,slm,glm,haswell,generic,amdfam10,bdver1,bdver2,bdver3,
450 bdver4,btver2,znver1"
451 (const (symbol_ref "ix86_schedule")))
453 ;; A basic instruction type. Refinements due to arguments to be
454 ;; provided in other attributes.
457 alu,alu1,negnot,imov,imovx,lea,
458 incdec,ishift,ishiftx,ishift1,rotate,rotatex,rotate1,
459 imul,imulx,idiv,icmp,test,ibr,setcc,icmov,
460 push,pop,call,callv,leave,
462 fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,
463 fxch,fistp,fisttp,frndint,
464 sse,ssemov,sseadd,sseadd1,sseiadd,sseiadd1,
465 ssemul,sseimul,ssediv,sselog,sselog1,
466 sseishft,sseishft1,ssecmp,ssecomi,
467 ssecvt,ssecvt1,sseicvt,sseins,
468 sseshuf,sseshuf1,ssemuladd,sse4arg,
470 mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft,
471 mpxmov,mpxmk,mpxchk,mpxld,mpxst"
472 (const_string "other"))
474 ;; Main data type used by the insn
476 "unknown,none,QI,HI,SI,DI,TI,OI,XI,SF,DF,XF,TF,V16SF,V8SF,V4DF,V4SF,
478 (const_string "unknown"))
480 ;; The CPU unit operations uses.
481 (define_attr "unit" "integer,i387,sse,mmx,unknown"
482 (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,
483 fxch,fistp,fisttp,frndint")
484 (const_string "i387")
485 (eq_attr "type" "sse,ssemov,sseadd,sseadd1,sseiadd,sseiadd1,
486 ssemul,sseimul,ssediv,sselog,sselog1,
487 sseishft,sseishft1,ssecmp,ssecomi,
488 ssecvt,ssecvt1,sseicvt,sseins,
489 sseshuf,sseshuf1,ssemuladd,sse4arg,mskmov")
491 (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
493 (eq_attr "type" "other")
494 (const_string "unknown")]
495 (const_string "integer")))
497 ;; The (bounding maximum) length of an instruction immediate.
498 (define_attr "length_immediate" ""
499 (cond [(eq_attr "type" "incdec,setcc,icmov,str,lea,other,multi,idiv,leave,
500 bitmanip,imulx,msklog,mskmov,mpxmk,mpxmov,mpxchk,
503 (eq_attr "unit" "i387,sse,mmx")
505 (eq_attr "type" "alu,alu1,negnot,imovx,ishift,ishiftx,ishift1,
506 rotate,rotatex,rotate1,imul,icmp,push,pop")
507 (symbol_ref "ix86_attr_length_immediate_default (insn, true)")
508 (eq_attr "type" "imov,test")
509 (symbol_ref "ix86_attr_length_immediate_default (insn, false)")
510 (eq_attr "type" "call")
511 (if_then_else (match_operand 0 "constant_call_address_operand")
514 (eq_attr "type" "callv")
515 (if_then_else (match_operand 1 "constant_call_address_operand")
518 ;; We don't know the size before shorten_branches. Expect
519 ;; the instruction to fit for better scheduling.
520 (eq_attr "type" "ibr")
523 (symbol_ref "/* Update immediate_length and other attributes! */
524 gcc_unreachable (),1")))
526 ;; The (bounding maximum) length of an instruction address.
527 (define_attr "length_address" ""
528 (cond [(eq_attr "type" "str,other,multi,fxch")
530 (and (eq_attr "type" "call")
531 (match_operand 0 "constant_call_address_operand"))
533 (and (eq_attr "type" "callv")
534 (match_operand 1 "constant_call_address_operand"))
537 (symbol_ref "ix86_attr_length_address_default (insn)")))
539 ;; Set when length prefix is used.
540 (define_attr "prefix_data16" ""
541 (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
543 (eq_attr "mode" "HI")
545 (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF,TI"))
550 ;; Set when string REP prefix is used.
551 (define_attr "prefix_rep" ""
552 (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
554 (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
559 ;; Set when 0f opcode prefix is used.
560 (define_attr "prefix_0f" ""
562 (ior (eq_attr "type" "imovx,setcc,icmov,bitmanip,msklog,mskmov,
563 mpxmk,mpxmov,mpxchk,mpxld,mpxst")
564 (eq_attr "unit" "sse,mmx"))
568 ;; Set when REX opcode prefix is used.
569 (define_attr "prefix_rex" ""
570 (cond [(not (match_test "TARGET_64BIT"))
572 (and (eq_attr "mode" "DI")
573 (and (eq_attr "type" "!push,pop,call,callv,leave,ibr")
574 (eq_attr "unit" "!mmx")))
576 (and (eq_attr "mode" "QI")
577 (match_test "x86_extended_QIreg_mentioned_p (insn)"))
579 (match_test "x86_extended_reg_mentioned_p (insn)")
581 (and (eq_attr "type" "imovx")
582 (match_operand:QI 1 "ext_QIreg_operand"))
587 ;; There are also additional prefixes in 3DNOW, SSSE3.
588 ;; ssemuladd,sse4arg default to 0f24/0f25 and DREX byte,
589 ;; sseiadd1,ssecvt1 to 0f7a with no DREX byte.
590 ;; 3DNOW has 0f0f prefix, SSSE3 and SSE4_{1,2} 0f38/0f3a.
591 (define_attr "prefix_extra" ""
592 (cond [(eq_attr "type" "ssemuladd,sse4arg")
594 (eq_attr "type" "sseiadd1,ssecvt1")
599 ;; Prefix used: original, VEX or maybe VEX.
600 (define_attr "prefix" "orig,vex,maybe_vex,evex,maybe_evex"
601 (cond [(eq_attr "mode" "OI,V8SF,V4DF")
603 (eq_attr "mode" "XI,V16SF,V8DF")
604 (const_string "evex")
606 (const_string "orig")))
608 ;; VEX W bit is used.
609 (define_attr "prefix_vex_w" "" (const_int 0))
611 ;; The length of VEX prefix
612 ;; Only instructions with 0f prefix can have 2 byte VEX prefix,
613 ;; 0f38/0f3a prefixes can't. In i386.md 0f3[8a] is
614 ;; still prefix_0f 1, with prefix_extra 1.
615 (define_attr "length_vex" ""
616 (if_then_else (and (eq_attr "prefix_0f" "1")
617 (eq_attr "prefix_extra" "0"))
618 (if_then_else (eq_attr "prefix_vex_w" "1")
619 (symbol_ref "ix86_attr_length_vex_default (insn, true, true)")
620 (symbol_ref "ix86_attr_length_vex_default (insn, true, false)"))
621 (if_then_else (eq_attr "prefix_vex_w" "1")
622 (symbol_ref "ix86_attr_length_vex_default (insn, false, true)")
623 (symbol_ref "ix86_attr_length_vex_default (insn, false, false)"))))
625 ;; 4-bytes evex prefix and 1 byte opcode.
626 (define_attr "length_evex" "" (const_int 5))
628 ;; Set when modrm byte is used.
629 (define_attr "modrm" ""
630 (cond [(eq_attr "type" "str,leave")
632 (eq_attr "unit" "i387")
634 (and (eq_attr "type" "incdec")
635 (and (not (match_test "TARGET_64BIT"))
636 (ior (match_operand:SI 1 "register_operand")
637 (match_operand:HI 1 "register_operand"))))
639 (and (eq_attr "type" "push")
640 (not (match_operand 1 "memory_operand")))
642 (and (eq_attr "type" "pop")
643 (not (match_operand 0 "memory_operand")))
645 (and (eq_attr "type" "imov")
646 (and (not (eq_attr "mode" "DI"))
647 (ior (and (match_operand 0 "register_operand")
648 (match_operand 1 "immediate_operand"))
649 (ior (and (match_operand 0 "ax_reg_operand")
650 (match_operand 1 "memory_displacement_only_operand"))
651 (and (match_operand 0 "memory_displacement_only_operand")
652 (match_operand 1 "ax_reg_operand"))))))
654 (and (eq_attr "type" "call")
655 (match_operand 0 "constant_call_address_operand"))
657 (and (eq_attr "type" "callv")
658 (match_operand 1 "constant_call_address_operand"))
660 (and (eq_attr "type" "alu,alu1,icmp,test")
661 (match_operand 0 "ax_reg_operand"))
662 (symbol_ref "(get_attr_length_immediate (insn) <= (get_attr_mode (insn) != MODE_QI))")
666 (define_attr "modrm_class" "none,incdec,op0,op01,op02,pushpop,unknown"
667 (cond [(eq_attr "modrm" "0")
668 (const_string "none")
669 (eq_attr "type" "alu,imul,ishift")
670 (const_string "op02")
671 (eq_attr "type" "imov,imovx,lea,alu1,icmp")
672 (const_string "op01")
673 (eq_attr "type" "incdec")
674 (const_string "incdec")
675 (eq_attr "type" "push,pop")
676 (const_string "pushpop")]
677 (const_string "unknown")))
679 ;; The (bounding maximum) length of an instruction in bytes.
680 ;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
681 ;; Later we may want to split them and compute proper length as for
683 (define_attr "length" ""
684 (cond [(eq_attr "type" "other,multi,fistp,frndint")
686 (eq_attr "type" "fcmp")
688 (eq_attr "unit" "i387")
690 (plus (attr "prefix_data16")
691 (attr "length_address")))
692 (ior (eq_attr "prefix" "evex")
693 (and (ior (eq_attr "prefix" "maybe_evex")
694 (eq_attr "prefix" "maybe_vex"))
695 (match_test "TARGET_AVX512F")))
696 (plus (attr "length_evex")
697 (plus (attr "length_immediate")
699 (attr "length_address"))))
700 (ior (eq_attr "prefix" "vex")
701 (and (ior (eq_attr "prefix" "maybe_vex")
702 (eq_attr "prefix" "maybe_evex"))
703 (match_test "TARGET_AVX")))
704 (plus (attr "length_vex")
705 (plus (attr "length_immediate")
707 (attr "length_address"))))]
708 (plus (plus (attr "modrm")
709 (plus (attr "prefix_0f")
710 (plus (attr "prefix_rex")
711 (plus (attr "prefix_extra")
713 (plus (attr "prefix_rep")
714 (plus (attr "prefix_data16")
715 (plus (attr "length_immediate")
716 (attr "length_address")))))))
718 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
719 ;; `store' if there is a simple memory reference therein, or `unknown'
720 ;; if the instruction is complex.
722 (define_attr "memory" "none,load,store,both,unknown"
723 (cond [(eq_attr "type" "other,multi,str,lwp")
724 (const_string "unknown")
725 (eq_attr "type" "lea,fcmov,fpspc,mpxmk,mpxchk")
726 (const_string "none")
727 (eq_attr "type" "fistp,leave")
728 (const_string "both")
729 (eq_attr "type" "frndint")
730 (const_string "load")
731 (eq_attr "type" "mpxld")
732 (const_string "load")
733 (eq_attr "type" "mpxst")
734 (const_string "store")
735 (eq_attr "type" "push")
736 (if_then_else (match_operand 1 "memory_operand")
737 (const_string "both")
738 (const_string "store"))
739 (eq_attr "type" "pop")
740 (if_then_else (match_operand 0 "memory_operand")
741 (const_string "both")
742 (const_string "load"))
743 (eq_attr "type" "setcc")
744 (if_then_else (match_operand 0 "memory_operand")
745 (const_string "store")
746 (const_string "none"))
747 (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
748 (if_then_else (ior (match_operand 0 "memory_operand")
749 (match_operand 1 "memory_operand"))
750 (const_string "load")
751 (const_string "none"))
752 (eq_attr "type" "ibr")
753 (if_then_else (match_operand 0 "memory_operand")
754 (const_string "load")
755 (const_string "none"))
756 (eq_attr "type" "call")
757 (if_then_else (match_operand 0 "constant_call_address_operand")
758 (const_string "none")
759 (const_string "load"))
760 (eq_attr "type" "callv")
761 (if_then_else (match_operand 1 "constant_call_address_operand")
762 (const_string "none")
763 (const_string "load"))
764 (and (eq_attr "type" "alu1,negnot,ishift1,rotate1,sselog1,sseshuf1")
765 (match_operand 1 "memory_operand"))
766 (const_string "both")
767 (and (match_operand 0 "memory_operand")
768 (match_operand 1 "memory_operand"))
769 (const_string "both")
770 (match_operand 0 "memory_operand")
771 (const_string "store")
772 (match_operand 1 "memory_operand")
773 (const_string "load")
775 "!alu1,negnot,ishift1,rotate1,
776 imov,imovx,icmp,test,bitmanip,
778 sse,ssemov,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,
779 sselog1,sseshuf1,sseadd1,sseiadd1,sseishft1,
780 mmx,mmxmov,mmxcmp,mmxcvt,mskmov,msklog,mpxmov")
781 (match_operand 2 "memory_operand"))
782 (const_string "load")
783 (and (eq_attr "type" "icmov,ssemuladd,sse4arg")
784 (match_operand 3 "memory_operand"))
785 (const_string "load")
787 (const_string "none")))
789 ;; Indicates if an instruction has both an immediate and a displacement.
791 (define_attr "imm_disp" "false,true,unknown"
792 (cond [(eq_attr "type" "other,multi")
793 (const_string "unknown")
794 (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
795 (and (match_operand 0 "memory_displacement_operand")
796 (match_operand 1 "immediate_operand")))
797 (const_string "true")
798 (and (eq_attr "type" "alu,ishift,ishiftx,rotate,rotatex,imul,idiv")
799 (and (match_operand 0 "memory_displacement_operand")
800 (match_operand 2 "immediate_operand")))
801 (const_string "true")
803 (const_string "false")))
805 ;; Indicates if an FP operation has an integer source.
807 (define_attr "fp_int_src" "false,true"
808 (const_string "false"))
810 ;; Defines rounding mode of an FP operation.
812 (define_attr "i387_cw" "trunc,floor,ceil,mask_pm,uninitialized,any"
813 (const_string "any"))
815 ;; Define attribute to classify add/sub insns that consumes carry flag (CF)
816 (define_attr "use_carry" "0,1" (const_string "0"))
818 ;; Define attribute to indicate unaligned ssemov insns
819 (define_attr "movu" "0,1" (const_string "0"))
821 ;; Used to control the "enabled" attribute on a per-instruction basis.
822 (define_attr "isa" "base,x64,x64_sse2,x64_sse4,x64_sse4_noavx,x64_avx,nox64,
823 sse2,sse2_noavx,sse3,sse4,sse4_noavx,avx,noavx,
824 avx2,noavx2,bmi,bmi2,fma4,fma,avx512f,noavx512f,
825 avx512bw,noavx512bw,avx512dq,noavx512dq,
826 avx512vl,noavx512vl,x64_avx512dq,x64_avx512bw"
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" "sse2_noavx")
846 (symbol_ref "TARGET_SSE2 && !TARGET_AVX")
847 (eq_attr "isa" "sse3") (symbol_ref "TARGET_SSE3")
848 (eq_attr "isa" "sse4") (symbol_ref "TARGET_SSE4_1")
849 (eq_attr "isa" "sse4_noavx")
850 (symbol_ref "TARGET_SSE4_1 && !TARGET_AVX")
851 (eq_attr "isa" "avx") (symbol_ref "TARGET_AVX")
852 (eq_attr "isa" "noavx") (symbol_ref "!TARGET_AVX")
853 (eq_attr "isa" "avx2") (symbol_ref "TARGET_AVX2")
854 (eq_attr "isa" "noavx2") (symbol_ref "!TARGET_AVX2")
855 (eq_attr "isa" "bmi") (symbol_ref "TARGET_BMI")
856 (eq_attr "isa" "bmi2") (symbol_ref "TARGET_BMI2")
857 (eq_attr "isa" "fma4") (symbol_ref "TARGET_FMA4")
858 (eq_attr "isa" "fma") (symbol_ref "TARGET_FMA")
859 (eq_attr "isa" "avx512f") (symbol_ref "TARGET_AVX512F")
860 (eq_attr "isa" "noavx512f") (symbol_ref "!TARGET_AVX512F")
861 (eq_attr "isa" "avx512bw") (symbol_ref "TARGET_AVX512BW")
862 (eq_attr "isa" "noavx512bw") (symbol_ref "!TARGET_AVX512BW")
863 (eq_attr "isa" "avx512dq") (symbol_ref "TARGET_AVX512DQ")
864 (eq_attr "isa" "noavx512dq") (symbol_ref "!TARGET_AVX512DQ")
865 (eq_attr "isa" "avx512vl") (symbol_ref "TARGET_AVX512VL")
866 (eq_attr "isa" "noavx512vl") (symbol_ref "!TARGET_AVX512VL")
870 (define_attr "preferred_for_size" "" (const_int 1))
871 (define_attr "preferred_for_speed" "" (const_int 1))
873 ;; Describe a user's asm statement.
874 (define_asm_attributes
875 [(set_attr "length" "128")
876 (set_attr "type" "multi")])
878 (define_code_iterator plusminus [plus minus])
880 (define_code_iterator sat_plusminus [ss_plus us_plus ss_minus us_minus])
882 (define_code_iterator multdiv [mult div])
884 ;; Base name for define_insn
885 (define_code_attr plusminus_insn
886 [(plus "add") (ss_plus "ssadd") (us_plus "usadd")
887 (minus "sub") (ss_minus "sssub") (us_minus "ussub")])
889 ;; Base name for insn mnemonic.
890 (define_code_attr plusminus_mnemonic
891 [(plus "add") (ss_plus "adds") (us_plus "addus")
892 (minus "sub") (ss_minus "subs") (us_minus "subus")])
893 (define_code_attr multdiv_mnemonic
894 [(mult "mul") (div "div")])
896 ;; Mark commutative operators as such in constraints.
897 (define_code_attr comm [(plus "%") (ss_plus "%") (us_plus "%")
898 (minus "") (ss_minus "") (us_minus "")])
900 ;; Mapping of max and min
901 (define_code_iterator maxmin [smax smin umax umin])
903 ;; Mapping of signed max and min
904 (define_code_iterator smaxmin [smax smin])
906 ;; Mapping of unsigned max and min
907 (define_code_iterator umaxmin [umax umin])
909 ;; Base name for integer and FP insn mnemonic
910 (define_code_attr maxmin_int [(smax "maxs") (smin "mins")
911 (umax "maxu") (umin "minu")])
912 (define_code_attr maxmin_float [(smax "max") (smin "min")])
914 (define_int_iterator IEEE_MAXMIN
918 (define_int_attr ieee_maxmin
919 [(UNSPEC_IEEE_MAX "max")
920 (UNSPEC_IEEE_MIN "min")])
922 ;; Mapping of logic operators
923 (define_code_iterator any_logic [and ior xor])
924 (define_code_iterator any_or [ior xor])
925 (define_code_iterator fpint_logic [and xor])
927 ;; Base name for insn mnemonic.
928 (define_code_attr logic [(and "and") (ior "or") (xor "xor")])
930 ;; Mapping of logic-shift operators
931 (define_code_iterator any_lshift [ashift lshiftrt])
933 ;; Mapping of shift-right operators
934 (define_code_iterator any_shiftrt [lshiftrt ashiftrt])
936 ;; Mapping of all shift operators
937 (define_code_iterator any_shift [ashift lshiftrt ashiftrt])
939 ;; Base name for define_insn
940 (define_code_attr shift_insn
941 [(ashift "ashl") (lshiftrt "lshr") (ashiftrt "ashr")])
943 ;; Base name for insn mnemonic.
944 (define_code_attr shift [(ashift "sll") (lshiftrt "shr") (ashiftrt "sar")])
945 (define_code_attr vshift [(ashift "sll") (lshiftrt "srl") (ashiftrt "sra")])
947 ;; Mapping of rotate operators
948 (define_code_iterator any_rotate [rotate rotatert])
950 ;; Base name for define_insn
951 (define_code_attr rotate_insn [(rotate "rotl") (rotatert "rotr")])
953 ;; Base name for insn mnemonic.
954 (define_code_attr rotate [(rotate "rol") (rotatert "ror")])
956 ;; Mapping of abs neg operators
957 (define_code_iterator absneg [abs neg])
959 ;; Base name for x87 insn mnemonic.
960 (define_code_attr absneg_mnemonic [(abs "abs") (neg "chs")])
962 ;; Used in signed and unsigned widening multiplications.
963 (define_code_iterator any_extend [sign_extend zero_extend])
965 ;; Prefix for insn menmonic.
966 (define_code_attr sgnprefix [(sign_extend "i") (zero_extend "")])
968 ;; Prefix for define_insn
969 (define_code_attr u [(sign_extend "") (zero_extend "u")])
970 (define_code_attr s [(sign_extend "s") (zero_extend "u")])
971 (define_code_attr u_bool [(sign_extend "false") (zero_extend "true")])
973 ;; Used in signed and unsigned truncations.
974 (define_code_iterator any_truncate [ss_truncate truncate us_truncate])
975 ;; Instruction suffix for truncations.
976 (define_code_attr trunsuffix [(ss_truncate "s") (truncate "") (us_truncate "us")])
978 ;; Used in signed and unsigned fix.
979 (define_code_iterator any_fix [fix unsigned_fix])
980 (define_code_attr fixsuffix [(fix "") (unsigned_fix "u")])
981 (define_code_attr fixunssuffix [(fix "") (unsigned_fix "uns")])
982 (define_code_attr fixprefix [(fix "s") (unsigned_fix "u")])
984 ;; Used in signed and unsigned float.
985 (define_code_iterator any_float [float unsigned_float])
986 (define_code_attr floatsuffix [(float "") (unsigned_float "u")])
987 (define_code_attr floatunssuffix [(float "") (unsigned_float "uns")])
988 (define_code_attr floatprefix [(float "s") (unsigned_float "u")])
990 ;; All integer modes.
991 (define_mode_iterator SWI1248x [QI HI SI DI])
993 ;; All integer modes without QImode.
994 (define_mode_iterator SWI248x [HI SI DI])
996 ;; All integer modes without QImode and HImode.
997 (define_mode_iterator SWI48x [SI DI])
999 ;; All integer modes without SImode and DImode.
1000 (define_mode_iterator SWI12 [QI HI])
1002 ;; All integer modes without DImode.
1003 (define_mode_iterator SWI124 [QI HI SI])
1005 ;; All integer modes without QImode and DImode.
1006 (define_mode_iterator SWI24 [HI SI])
1008 ;; Single word integer modes.
1009 (define_mode_iterator SWI [QI HI SI (DI "TARGET_64BIT")])
1011 ;; Single word integer modes without QImode.
1012 (define_mode_iterator SWI248 [HI SI (DI "TARGET_64BIT")])
1014 ;; Single word integer modes without QImode and HImode.
1015 (define_mode_iterator SWI48 [SI (DI "TARGET_64BIT")])
1017 ;; All math-dependant single and double word integer modes.
1018 (define_mode_iterator SDWIM [(QI "TARGET_QIMODE_MATH")
1019 (HI "TARGET_HIMODE_MATH")
1020 SI DI (TI "TARGET_64BIT")])
1022 ;; Math-dependant single word integer modes.
1023 (define_mode_iterator SWIM [(QI "TARGET_QIMODE_MATH")
1024 (HI "TARGET_HIMODE_MATH")
1025 SI (DI "TARGET_64BIT")])
1027 ;; Math-dependant integer modes without DImode.
1028 (define_mode_iterator SWIM124 [(QI "TARGET_QIMODE_MATH")
1029 (HI "TARGET_HIMODE_MATH")
1032 ;; Math-dependant integer modes with DImode.
1033 (define_mode_iterator SWIM1248x [(QI "TARGET_QIMODE_MATH")
1034 (HI "TARGET_HIMODE_MATH")
1035 SI (DI "(TARGET_STV && TARGET_SSE2) || TARGET_64BIT")])
1037 ;; Math-dependant single word integer modes without QImode.
1038 (define_mode_iterator SWIM248 [(HI "TARGET_HIMODE_MATH")
1039 SI (DI "TARGET_64BIT")])
1041 ;; Double word integer modes.
1042 (define_mode_iterator DWI [(DI "!TARGET_64BIT")
1043 (TI "TARGET_64BIT")])
1045 ;; GET_MODE_SIZE for selected modes. As GET_MODE_SIZE is not
1046 ;; compile time constant, it is faster to use <MODE_SIZE> than
1047 ;; GET_MODE_SIZE (<MODE>mode). For XFmode which depends on
1048 ;; command line options just use GET_MODE_SIZE macro.
1049 (define_mode_attr MODE_SIZE [(QI "1") (HI "2") (SI "4") (DI "8") (TI "16")
1050 (SF "4") (DF "8") (XF "GET_MODE_SIZE (XFmode)")
1051 (V16QI "16") (V32QI "32") (V64QI "64")
1052 (V8HI "16") (V16HI "32") (V32HI "64")
1053 (V4SI "16") (V8SI "32") (V16SI "64")
1054 (V2DI "16") (V4DI "32") (V8DI "64")
1055 (V1TI "16") (V2TI "32") (V4TI "64")
1056 (V2DF "16") (V4DF "32") (V8DF "64")
1057 (V4SF "16") (V8SF "32") (V16SF "64")])
1059 ;; Double word integer modes as mode attribute.
1060 (define_mode_attr DWI [(QI "HI") (HI "SI") (SI "DI") (DI "TI")])
1061 (define_mode_attr dwi [(QI "hi") (HI "si") (SI "di") (DI "ti")])
1063 ;; LEA mode corresponding to an integer mode
1064 (define_mode_attr LEAMODE [(QI "SI") (HI "SI") (SI "SI") (DI "DI")])
1066 ;; Half mode for double word integer modes.
1067 (define_mode_iterator DWIH [(SI "!TARGET_64BIT")
1068 (DI "TARGET_64BIT")])
1071 (define_mode_iterator BND [(BND32 "!TARGET_LP64")
1072 (BND64 "TARGET_LP64")])
1074 ;; Instruction suffix for integer modes.
1075 (define_mode_attr imodesuffix [(QI "b") (HI "w") (SI "l") (DI "q")])
1077 ;; Instruction suffix for masks.
1078 (define_mode_attr mskmodesuffix [(QI "b") (HI "w") (SI "d") (DI "q")])
1080 ;; Pointer size prefix for integer modes (Intel asm dialect)
1081 (define_mode_attr iptrsize [(QI "BYTE")
1086 ;; Register class for integer modes.
1087 (define_mode_attr r [(QI "q") (HI "r") (SI "r") (DI "r")])
1089 ;; Immediate operand constraint for integer modes.
1090 (define_mode_attr i [(QI "n") (HI "n") (SI "e") (DI "e")])
1092 ;; General operand constraint for word modes.
1093 (define_mode_attr g [(QI "qmn") (HI "rmn") (SI "rme") (DI "rme")])
1095 ;; Immediate operand constraint for double integer modes.
1096 (define_mode_attr di [(SI "nF") (DI "Wd")])
1098 ;; Immediate operand constraint for shifts.
1099 (define_mode_attr S [(QI "I") (HI "I") (SI "I") (DI "J") (TI "O")])
1101 ;; Print register name in the specified mode.
1102 (define_mode_attr k [(QI "b") (HI "w") (SI "k") (DI "q")])
1104 ;; General operand predicate for integer modes.
1105 (define_mode_attr general_operand
1106 [(QI "general_operand")
1107 (HI "general_operand")
1108 (SI "x86_64_general_operand")
1109 (DI "x86_64_general_operand")
1110 (TI "x86_64_general_operand")])
1112 ;; General operand predicate for integer modes, where for TImode
1113 ;; we need both words of the operand to be general operands.
1114 (define_mode_attr general_hilo_operand
1115 [(QI "general_operand")
1116 (HI "general_operand")
1117 (SI "x86_64_general_operand")
1118 (DI "x86_64_general_operand")
1119 (TI "x86_64_hilo_general_operand")])
1121 ;; General sign extend operand predicate for integer modes,
1122 ;; which disallows VOIDmode operands and thus it is suitable
1123 ;; for use inside sign_extend.
1124 (define_mode_attr general_sext_operand
1125 [(QI "sext_operand")
1127 (SI "x86_64_sext_operand")
1128 (DI "x86_64_sext_operand")])
1130 ;; General sign/zero extend operand predicate for integer modes.
1131 (define_mode_attr general_szext_operand
1132 [(QI "general_operand")
1133 (HI "general_operand")
1134 (SI "x86_64_szext_general_operand")
1135 (DI "x86_64_szext_general_operand")])
1137 ;; Immediate operand predicate for integer modes.
1138 (define_mode_attr immediate_operand
1139 [(QI "immediate_operand")
1140 (HI "immediate_operand")
1141 (SI "x86_64_immediate_operand")
1142 (DI "x86_64_immediate_operand")])
1144 ;; Nonmemory operand predicate for integer modes.
1145 (define_mode_attr nonmemory_operand
1146 [(QI "nonmemory_operand")
1147 (HI "nonmemory_operand")
1148 (SI "x86_64_nonmemory_operand")
1149 (DI "x86_64_nonmemory_operand")])
1151 ;; Operand predicate for shifts.
1152 (define_mode_attr shift_operand
1153 [(QI "nonimmediate_operand")
1154 (HI "nonimmediate_operand")
1155 (SI "nonimmediate_operand")
1156 (DI "shiftdi_operand")
1157 (TI "register_operand")])
1159 ;; Operand predicate for shift argument.
1160 (define_mode_attr shift_immediate_operand
1161 [(QI "const_1_to_31_operand")
1162 (HI "const_1_to_31_operand")
1163 (SI "const_1_to_31_operand")
1164 (DI "const_1_to_63_operand")])
1166 ;; Input operand predicate for arithmetic left shifts.
1167 (define_mode_attr ashl_input_operand
1168 [(QI "nonimmediate_operand")
1169 (HI "nonimmediate_operand")
1170 (SI "nonimmediate_operand")
1171 (DI "ashldi_input_operand")
1172 (TI "reg_or_pm1_operand")])
1174 ;; SSE and x87 SFmode and DFmode floating point modes
1175 (define_mode_iterator MODEF [SF DF])
1177 ;; All x87 floating point modes
1178 (define_mode_iterator X87MODEF [SF DF XF])
1180 ;; SSE instruction suffix for various modes
1181 (define_mode_attr ssemodesuffix
1182 [(SF "ss") (DF "sd")
1183 (V16SF "ps") (V8DF "pd")
1184 (V8SF "ps") (V4DF "pd")
1185 (V4SF "ps") (V2DF "pd")
1186 (V16QI "b") (V8HI "w") (V4SI "d") (V2DI "q")
1187 (V32QI "b") (V16HI "w") (V8SI "d") (V4DI "q")
1188 (V64QI "b") (V32HI "w") (V16SI "d") (V8DI "q")])
1190 ;; SSE vector suffix for floating point modes
1191 (define_mode_attr ssevecmodesuffix [(SF "ps") (DF "pd")])
1193 ;; SSE vector mode corresponding to a scalar mode
1194 (define_mode_attr ssevecmode
1195 [(QI "V16QI") (HI "V8HI") (SI "V4SI") (DI "V2DI") (SF "V4SF") (DF "V2DF")])
1196 (define_mode_attr ssevecmodelower
1197 [(QI "v16qi") (HI "v8hi") (SI "v4si") (DI "v2di") (SF "v4sf") (DF "v2df")])
1199 ;; AVX512F vector mode corresponding to a scalar mode
1200 (define_mode_attr avx512fvecmode
1201 [(QI "V64QI") (HI "V32HI") (SI "V16SI") (DI "V8DI") (SF "V16SF") (DF "V8DF")])
1203 ;; Instruction suffix for REX 64bit operators.
1204 (define_mode_attr rex64suffix [(SI "") (DI "{q}")])
1205 (define_mode_attr rex64namesuffix [(SI "") (DI "q")])
1207 ;; This mode iterator allows :P to be used for patterns that operate on
1208 ;; pointer-sized quantities. Exactly one of the two alternatives will match.
1209 (define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
1211 ;; This mode iterator allows :W to be used for patterns that operate on
1212 ;; word_mode sized quantities.
1213 (define_mode_iterator W
1214 [(SI "word_mode == SImode") (DI "word_mode == DImode")])
1216 ;; This mode iterator allows :PTR to be used for patterns that operate on
1217 ;; ptr_mode sized quantities.
1218 (define_mode_iterator PTR
1219 [(SI "ptr_mode == SImode") (DI "ptr_mode == DImode")])
1221 ;; Scheduling descriptions
1223 (include "pentium.md")
1226 (include "athlon.md")
1227 (include "bdver1.md")
1228 (include "bdver3.md")
1229 (include "btver2.md")
1230 (include "znver1.md")
1231 (include "geode.md")
1235 (include "core2.md")
1236 (include "haswell.md")
1239 ;; Operand and operator predicates and constraints
1241 (include "predicates.md")
1242 (include "constraints.md")
1245 ;; Compare and branch/compare and store instructions.
1247 (define_expand "cbranch<mode>4"
1248 [(set (reg:CC FLAGS_REG)
1249 (compare:CC (match_operand:SDWIM 1 "nonimmediate_operand")
1250 (match_operand:SDWIM 2 "<general_operand>")))
1251 (set (pc) (if_then_else
1252 (match_operator 0 "ordered_comparison_operator"
1253 [(reg:CC FLAGS_REG) (const_int 0)])
1254 (label_ref (match_operand 3))
1258 if (MEM_P (operands[1]) && MEM_P (operands[2]))
1259 operands[1] = force_reg (<MODE>mode, operands[1]);
1260 ix86_expand_branch (GET_CODE (operands[0]),
1261 operands[1], operands[2], operands[3]);
1265 (define_expand "cstore<mode>4"
1266 [(set (reg:CC FLAGS_REG)
1267 (compare:CC (match_operand:SWIM 2 "nonimmediate_operand")
1268 (match_operand:SWIM 3 "<general_operand>")))
1269 (set (match_operand:QI 0 "register_operand")
1270 (match_operator 1 "ordered_comparison_operator"
1271 [(reg:CC FLAGS_REG) (const_int 0)]))]
1274 if (MEM_P (operands[2]) && MEM_P (operands[3]))
1275 operands[2] = force_reg (<MODE>mode, operands[2]);
1276 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1277 operands[2], operands[3]);
1281 (define_expand "cmp<mode>_1"
1282 [(set (reg:CC FLAGS_REG)
1283 (compare:CC (match_operand:SWI48 0 "nonimmediate_operand")
1284 (match_operand:SWI48 1 "<general_operand>")))])
1286 (define_mode_iterator SWI1248_AVX512BWDQ2_64
1287 [(QI "TARGET_AVX512DQ") (HI "TARGET_AVX512DQ")
1288 (SI "TARGET_AVX512BW") (DI "TARGET_AVX512BW && TARGET_64BIT")])
1290 (define_insn "*cmp<mode>_ccz_1"
1291 [(set (reg FLAGS_REG)
1292 (compare (match_operand:SWI1248_AVX512BWDQ2_64 0
1293 "nonimmediate_operand" "<r>,?m<r>,$k")
1294 (match_operand:SWI1248_AVX512BWDQ2_64 1 "const0_operand")))]
1295 "ix86_match_ccmode (insn, CCZmode)"
1297 test{<imodesuffix>}\t%0, %0
1298 cmp{<imodesuffix>}\t{%1, %0|%0, %1}
1299 ktest<mskmodesuffix>\t%0, %0"
1300 [(set_attr "type" "test,icmp,msklog")
1301 (set_attr "length_immediate" "0,1,*")
1302 (set_attr "modrm_class" "op0,unknown,*")
1303 (set_attr "prefix" "*,*,vex")
1304 (set_attr "mode" "<MODE>")])
1306 (define_insn "*cmp<mode>_ccno_1"
1307 [(set (reg FLAGS_REG)
1308 (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>,?m<r>")
1309 (match_operand:SWI 1 "const0_operand")))]
1310 "ix86_match_ccmode (insn, CCNOmode)"
1312 test{<imodesuffix>}\t%0, %0
1313 cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1314 [(set_attr "type" "test,icmp")
1315 (set_attr "length_immediate" "0,1")
1316 (set_attr "modrm_class" "op0,unknown")
1317 (set_attr "mode" "<MODE>")])
1319 (define_insn "*cmp<mode>_1"
1320 [(set (reg FLAGS_REG)
1321 (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
1322 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m")))]
1323 "ix86_match_ccmode (insn, CCmode)"
1324 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1325 [(set_attr "type" "icmp")
1326 (set_attr "mode" "<MODE>")])
1328 (define_insn "*cmp<mode>_minus_1"
1329 [(set (reg FLAGS_REG)
1331 (minus:SWI (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
1332 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
1334 "ix86_match_ccmode (insn, CCGOCmode)"
1335 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1336 [(set_attr "type" "icmp")
1337 (set_attr "mode" "<MODE>")])
1339 (define_insn "*cmpqi_ext_1"
1340 [(set (reg FLAGS_REG)
1342 (match_operand:QI 0 "nonimmediate_operand" "QBc,m")
1345 (match_operand 1 "ext_register_operand" "Q,Q")
1347 (const_int 8)) 0)))]
1348 "ix86_match_ccmode (insn, CCmode)"
1349 "cmp{b}\t{%h1, %0|%0, %h1}"
1350 [(set_attr "isa" "*,nox64")
1351 (set_attr "type" "icmp")
1352 (set_attr "mode" "QI")])
1354 (define_insn "*cmpqi_ext_2"
1355 [(set (reg FLAGS_REG)
1359 (match_operand 0 "ext_register_operand" "Q")
1362 (match_operand:QI 1 "const0_operand")))]
1363 "ix86_match_ccmode (insn, CCNOmode)"
1365 [(set_attr "type" "test")
1366 (set_attr "length_immediate" "0")
1367 (set_attr "mode" "QI")])
1369 (define_expand "cmpqi_ext_3"
1370 [(set (reg:CC FLAGS_REG)
1374 (match_operand 0 "ext_register_operand")
1377 (match_operand:QI 1 "const_int_operand")))])
1379 (define_insn "*cmpqi_ext_3"
1380 [(set (reg FLAGS_REG)
1384 (match_operand 0 "ext_register_operand" "Q,Q")
1387 (match_operand:QI 1 "general_operand" "QnBc,m")))]
1388 "ix86_match_ccmode (insn, CCmode)"
1389 "cmp{b}\t{%1, %h0|%h0, %1}"
1390 [(set_attr "isa" "*,nox64")
1391 (set_attr "type" "icmp")
1392 (set_attr "mode" "QI")])
1394 (define_insn "*cmpqi_ext_4"
1395 [(set (reg FLAGS_REG)
1399 (match_operand 0 "ext_register_operand" "Q")
1404 (match_operand 1 "ext_register_operand" "Q")
1406 (const_int 8)) 0)))]
1407 "ix86_match_ccmode (insn, CCmode)"
1408 "cmp{b}\t{%h1, %h0|%h0, %h1}"
1409 [(set_attr "type" "icmp")
1410 (set_attr "mode" "QI")])
1412 ;; These implement float point compares.
1413 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
1414 ;; which would allow mix and match FP modes on the compares. Which is what
1415 ;; the old patterns did, but with many more of them.
1417 (define_expand "cbranchxf4"
1418 [(set (reg:CC FLAGS_REG)
1419 (compare:CC (match_operand:XF 1 "nonmemory_operand")
1420 (match_operand:XF 2 "nonmemory_operand")))
1421 (set (pc) (if_then_else
1422 (match_operator 0 "ix86_fp_comparison_operator"
1425 (label_ref (match_operand 3))
1429 ix86_expand_branch (GET_CODE (operands[0]),
1430 operands[1], operands[2], operands[3]);
1434 (define_expand "cstorexf4"
1435 [(set (reg:CC FLAGS_REG)
1436 (compare:CC (match_operand:XF 2 "nonmemory_operand")
1437 (match_operand:XF 3 "nonmemory_operand")))
1438 (set (match_operand:QI 0 "register_operand")
1439 (match_operator 1 "ix86_fp_comparison_operator"
1444 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1445 operands[2], operands[3]);
1449 (define_expand "cbranch<mode>4"
1450 [(set (reg:CC FLAGS_REG)
1451 (compare:CC (match_operand:MODEF 1 "cmp_fp_expander_operand")
1452 (match_operand:MODEF 2 "cmp_fp_expander_operand")))
1453 (set (pc) (if_then_else
1454 (match_operator 0 "ix86_fp_comparison_operator"
1457 (label_ref (match_operand 3))
1459 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1461 ix86_expand_branch (GET_CODE (operands[0]),
1462 operands[1], operands[2], operands[3]);
1466 (define_expand "cstore<mode>4"
1467 [(set (reg:CC FLAGS_REG)
1468 (compare:CC (match_operand:MODEF 2 "cmp_fp_expander_operand")
1469 (match_operand:MODEF 3 "cmp_fp_expander_operand")))
1470 (set (match_operand:QI 0 "register_operand")
1471 (match_operator 1 "ix86_fp_comparison_operator"
1474 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1476 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1477 operands[2], operands[3]);
1481 (define_expand "cbranchcc4"
1482 [(set (pc) (if_then_else
1483 (match_operator 0 "comparison_operator"
1484 [(match_operand 1 "flags_reg_operand")
1485 (match_operand 2 "const0_operand")])
1486 (label_ref (match_operand 3))
1490 ix86_expand_branch (GET_CODE (operands[0]),
1491 operands[1], operands[2], operands[3]);
1495 (define_expand "cstorecc4"
1496 [(set (match_operand:QI 0 "register_operand")
1497 (match_operator 1 "comparison_operator"
1498 [(match_operand 2 "flags_reg_operand")
1499 (match_operand 3 "const0_operand")]))]
1502 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1503 operands[2], operands[3]);
1508 ;; FP compares, step 1:
1509 ;; Set the FP condition codes.
1511 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
1512 ;; used to manage the reg stack popping would not be preserved.
1514 (define_insn "*cmp<mode>_0_i387"
1515 [(set (match_operand:HI 0 "register_operand" "=a")
1518 (match_operand:X87MODEF 1 "register_operand" "f")
1519 (match_operand:X87MODEF 2 "const0_operand"))]
1522 "* return output_fp_compare (insn, operands, false, false);"
1523 [(set_attr "type" "multi")
1524 (set_attr "unit" "i387")
1525 (set_attr "mode" "<MODE>")])
1527 (define_insn_and_split "*cmp<mode>_0_cc_i387"
1528 [(set (reg:CCFP FLAGS_REG)
1530 (match_operand:X87MODEF 1 "register_operand" "f")
1531 (match_operand:X87MODEF 2 "const0_operand")))
1532 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1533 "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE"
1535 "&& reload_completed"
1538 [(compare:CCFP (match_dup 1)(match_dup 2))]
1540 (set (reg:CC FLAGS_REG)
1541 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1543 [(set_attr "type" "multi")
1544 (set_attr "unit" "i387")
1545 (set_attr "mode" "<MODE>")])
1547 (define_insn "*cmpxf_i387"
1548 [(set (match_operand:HI 0 "register_operand" "=a")
1551 (match_operand:XF 1 "register_operand" "f")
1552 (match_operand:XF 2 "register_operand" "f"))]
1555 "* return output_fp_compare (insn, operands, false, false);"
1556 [(set_attr "type" "multi")
1557 (set_attr "unit" "i387")
1558 (set_attr "mode" "XF")])
1560 (define_insn_and_split "*cmpxf_cc_i387"
1561 [(set (reg:CCFP FLAGS_REG)
1563 (match_operand:XF 1 "register_operand" "f")
1564 (match_operand:XF 2 "register_operand" "f")))
1565 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1566 "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE"
1568 "&& reload_completed"
1571 [(compare:CCFP (match_dup 1)(match_dup 2))]
1573 (set (reg:CC FLAGS_REG)
1574 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1576 [(set_attr "type" "multi")
1577 (set_attr "unit" "i387")
1578 (set_attr "mode" "XF")])
1580 (define_insn "*cmp<mode>_i387"
1581 [(set (match_operand:HI 0 "register_operand" "=a")
1584 (match_operand:MODEF 1 "register_operand" "f")
1585 (match_operand:MODEF 2 "nonimmediate_operand" "fm"))]
1588 "* return output_fp_compare (insn, operands, false, false);"
1589 [(set_attr "type" "multi")
1590 (set_attr "unit" "i387")
1591 (set_attr "mode" "<MODE>")])
1593 (define_insn_and_split "*cmp<mode>_cc_i387"
1594 [(set (reg:CCFP FLAGS_REG)
1596 (match_operand:MODEF 1 "register_operand" "f")
1597 (match_operand:MODEF 2 "nonimmediate_operand" "fm")))
1598 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1599 "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE"
1601 "&& reload_completed"
1604 [(compare:CCFP (match_dup 1)(match_dup 2))]
1606 (set (reg:CC FLAGS_REG)
1607 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1609 [(set_attr "type" "multi")
1610 (set_attr "unit" "i387")
1611 (set_attr "mode" "<MODE>")])
1613 (define_insn "*cmpu<mode>_i387"
1614 [(set (match_operand:HI 0 "register_operand" "=a")
1618 (match_operand:X87MODEF 1 "register_operand" "f")
1619 (match_operand:X87MODEF 2 "register_operand" "f"))]
1623 "* return output_fp_compare (insn, operands, false, true);"
1624 [(set_attr "type" "multi")
1625 (set_attr "unit" "i387")
1626 (set_attr "mode" "<MODE>")])
1628 (define_insn_and_split "*cmpu<mode>_cc_i387"
1629 [(set (reg:CCFP FLAGS_REG)
1632 (match_operand:X87MODEF 1 "register_operand" "f")
1633 (match_operand:X87MODEF 2 "register_operand" "f"))]
1635 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1636 "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE"
1638 "&& reload_completed"
1642 [(compare:CCFP (match_dup 1)(match_dup 2))]
1645 (set (reg:CC FLAGS_REG)
1646 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1648 [(set_attr "type" "multi")
1649 (set_attr "unit" "i387")
1650 (set_attr "mode" "<MODE>")])
1652 (define_insn "*cmp<X87MODEF:mode>_<SWI24:mode>_i387"
1653 [(set (match_operand:HI 0 "register_operand" "=a")
1656 (match_operand:X87MODEF 1 "register_operand" "f")
1658 (match_operand:SWI24 2 "memory_operand" "m")))]
1661 && (TARGET_USE_<SWI24:MODE>MODE_FIOP
1662 || optimize_function_for_size_p (cfun))"
1663 "* return output_fp_compare (insn, operands, false, false);"
1664 [(set_attr "type" "multi")
1665 (set_attr "unit" "i387")
1666 (set_attr "fp_int_src" "true")
1667 (set_attr "mode" "<SWI24:MODE>")])
1669 (define_insn_and_split "*cmp<X87MODEF:mode>_<SWI24:mode>_cc_i387"
1670 [(set (reg:CCFP FLAGS_REG)
1672 (match_operand:X87MODEF 1 "register_operand" "f")
1674 (match_operand:SWI24 2 "memory_operand" "m"))))
1675 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1676 "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE
1677 && (TARGET_USE_<SWI24:MODE>MODE_FIOP
1678 || optimize_function_for_size_p (cfun))"
1680 "&& reload_completed"
1685 (float:X87MODEF (match_dup 2)))]
1687 (set (reg:CC FLAGS_REG)
1688 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1690 [(set_attr "type" "multi")
1691 (set_attr "unit" "i387")
1692 (set_attr "fp_int_src" "true")
1693 (set_attr "mode" "<SWI24:MODE>")])
1695 ;; FP compares, step 2
1696 ;; Move the fpsw to ax.
1698 (define_insn "x86_fnstsw_1"
1699 [(set (match_operand:HI 0 "register_operand" "=a")
1700 (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
1703 [(set_attr "length" "2")
1704 (set_attr "mode" "SI")
1705 (set_attr "unit" "i387")])
1707 ;; FP compares, step 3
1708 ;; Get ax into flags, general case.
1710 (define_insn "x86_sahf_1"
1711 [(set (reg:CC FLAGS_REG)
1712 (unspec:CC [(match_operand:HI 0 "register_operand" "a")]
1716 #ifndef HAVE_AS_IX86_SAHF
1718 return ASM_BYTE "0x9e";
1723 [(set_attr "length" "1")
1724 (set_attr "athlon_decode" "vector")
1725 (set_attr "amdfam10_decode" "direct")
1726 (set_attr "bdver1_decode" "direct")
1727 (set_attr "mode" "SI")])
1729 ;; Pentium Pro can do steps 1 through 3 in one go.
1730 ;; (these instructions set flags directly)
1732 (define_subst_attr "unord" "unord_subst" "" "u")
1733 (define_subst_attr "unordered" "unord_subst" "false" "true")
1735 (define_subst "unord_subst"
1736 [(set (match_operand:CCFP 0)
1737 (match_operand:CCFP 1))]
1744 (define_insn "*cmpi<unord><MODEF:mode>"
1745 [(set (reg:CCFP FLAGS_REG)
1747 (match_operand:MODEF 0 "register_operand" "f,v")
1748 (match_operand:MODEF 1 "register_ssemem_operand" "f,vm")))]
1749 "(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
1750 || (TARGET_80387 && TARGET_CMOVE)"
1752 * return output_fp_compare (insn, operands, true, <unordered>);
1753 %v<unord>comi<MODEF:ssemodesuffix>\t{%1, %0|%0, %1}"
1754 [(set_attr "type" "fcmp,ssecomi")
1755 (set_attr "prefix" "orig,maybe_vex")
1756 (set_attr "mode" "<MODEF:MODE>")
1757 (set_attr "prefix_rep" "*,0")
1758 (set (attr "prefix_data16")
1759 (cond [(eq_attr "alternative" "0")
1761 (eq_attr "mode" "DF")
1764 (const_string "0")))
1765 (set_attr "athlon_decode" "vector")
1766 (set_attr "amdfam10_decode" "direct")
1767 (set_attr "bdver1_decode" "double")
1768 (set_attr "znver1_decode" "double")
1769 (set (attr "enabled")
1771 (match_test ("SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"))
1773 (eq_attr "alternative" "0")
1774 (symbol_ref "TARGET_MIX_SSE_I387")
1775 (symbol_ref "true"))
1777 (eq_attr "alternative" "0")
1779 (symbol_ref "false"))))])
1781 (define_insn "*cmpi<unord>xf_i387"
1782 [(set (reg:CCFP FLAGS_REG)
1784 (match_operand:XF 0 "register_operand" "f")
1785 (match_operand:XF 1 "register_operand" "f")))]
1786 "TARGET_80387 && TARGET_CMOVE"
1787 "* return output_fp_compare (insn, operands, true, <unordered>);"
1788 [(set_attr "type" "fcmp")
1789 (set_attr "mode" "XF")
1790 (set_attr "athlon_decode" "vector")
1791 (set_attr "amdfam10_decode" "direct")
1792 (set_attr "bdver1_decode" "double")
1793 (set_attr "znver1_decode" "double")])
1795 ;; Push/pop instructions.
1797 (define_insn "*push<mode>2"
1798 [(set (match_operand:DWI 0 "push_operand" "=<")
1799 (match_operand:DWI 1 "general_no_elim_operand" "riF*o"))]
1802 [(set_attr "type" "multi")
1803 (set_attr "mode" "<MODE>")])
1806 [(set (match_operand:DWI 0 "push_operand")
1807 (match_operand:DWI 1 "general_gr_operand"))]
1810 "ix86_split_long_move (operands); DONE;")
1812 (define_insn "*pushdi2_rex64"
1813 [(set (match_operand:DI 0 "push_operand" "=<,!<")
1814 (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1819 [(set_attr "type" "push,multi")
1820 (set_attr "mode" "DI")])
1822 ;; Convert impossible pushes of immediate to existing instructions.
1823 ;; First try to get scratch register and go through it. In case this
1824 ;; fails, push sign extended lower part first and then overwrite
1825 ;; upper part by 32bit move.
1827 [(match_scratch:DI 2 "r")
1828 (set (match_operand:DI 0 "push_operand")
1829 (match_operand:DI 1 "immediate_operand"))]
1830 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1831 && !x86_64_immediate_operand (operands[1], DImode)"
1832 [(set (match_dup 2) (match_dup 1))
1833 (set (match_dup 0) (match_dup 2))])
1835 ;; We need to define this as both peepholer and splitter for case
1836 ;; peephole2 pass is not run.
1837 ;; "&& 1" is needed to keep it from matching the previous pattern.
1839 [(set (match_operand:DI 0 "push_operand")
1840 (match_operand:DI 1 "immediate_operand"))]
1841 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1842 && !x86_64_immediate_operand (operands[1], DImode) && 1"
1843 [(set (match_dup 0) (match_dup 1))
1844 (set (match_dup 2) (match_dup 3))]
1846 split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1848 operands[1] = gen_lowpart (DImode, operands[2]);
1849 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (Pmode, stack_pointer_rtx,
1854 [(set (match_operand:DI 0 "push_operand")
1855 (match_operand:DI 1 "immediate_operand"))]
1856 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
1857 ? epilogue_completed : reload_completed)
1858 && !symbolic_operand (operands[1], DImode)
1859 && !x86_64_immediate_operand (operands[1], DImode)"
1860 [(set (match_dup 0) (match_dup 1))
1861 (set (match_dup 2) (match_dup 3))]
1863 split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1865 operands[1] = gen_lowpart (DImode, operands[2]);
1866 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (Pmode, stack_pointer_rtx,
1870 (define_insn "*pushsi2"
1871 [(set (match_operand:SI 0 "push_operand" "=<")
1872 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1875 [(set_attr "type" "push")
1876 (set_attr "mode" "SI")])
1878 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1879 ;; "push a byte/word". But actually we use pushl, which has the effect
1880 ;; of rounding the amount pushed up to a word.
1882 ;; For TARGET_64BIT we always round up to 8 bytes.
1883 (define_insn "*push<mode>2_rex64"
1884 [(set (match_operand:SWI124 0 "push_operand" "=X")
1885 (match_operand:SWI124 1 "nonmemory_no_elim_operand" "r<i>"))]
1888 [(set_attr "type" "push")
1889 (set_attr "mode" "DI")])
1891 (define_insn "*push<mode>2"
1892 [(set (match_operand:SWI12 0 "push_operand" "=X")
1893 (match_operand:SWI12 1 "nonmemory_no_elim_operand" "rn"))]
1896 [(set_attr "type" "push")
1897 (set_attr "mode" "SI")])
1899 (define_insn "*push<mode>2_prologue"
1900 [(set (match_operand:W 0 "push_operand" "=<")
1901 (match_operand:W 1 "general_no_elim_operand" "r<i>*m"))
1902 (clobber (mem:BLK (scratch)))]
1904 "push{<imodesuffix>}\t%1"
1905 [(set_attr "type" "push")
1906 (set_attr "mode" "<MODE>")])
1908 (define_insn "*pop<mode>1"
1909 [(set (match_operand:W 0 "nonimmediate_operand" "=r*m")
1910 (match_operand:W 1 "pop_operand" ">"))]
1912 "pop{<imodesuffix>}\t%0"
1913 [(set_attr "type" "pop")
1914 (set_attr "mode" "<MODE>")])
1916 (define_insn "*pop<mode>1_epilogue"
1917 [(set (match_operand:W 0 "nonimmediate_operand" "=r*m")
1918 (match_operand:W 1 "pop_operand" ">"))
1919 (clobber (mem:BLK (scratch)))]
1921 "pop{<imodesuffix>}\t%0"
1922 [(set_attr "type" "pop")
1923 (set_attr "mode" "<MODE>")])
1925 (define_insn "*pushfl<mode>2"
1926 [(set (match_operand:W 0 "push_operand" "=<")
1927 (match_operand:W 1 "flags_reg_operand"))]
1929 "pushf{<imodesuffix>}"
1930 [(set_attr "type" "push")
1931 (set_attr "mode" "<MODE>")])
1933 (define_insn "*popfl<mode>1"
1934 [(set (match_operand:W 0 "flags_reg_operand")
1935 (match_operand:W 1 "pop_operand" ">"))]
1937 "popf{<imodesuffix>}"
1938 [(set_attr "type" "pop")
1939 (set_attr "mode" "<MODE>")])
1942 ;; Reload patterns to support multi-word load/store
1943 ;; with non-offsetable address.
1944 (define_expand "reload_noff_store"
1945 [(parallel [(match_operand 0 "memory_operand" "=m")
1946 (match_operand 1 "register_operand" "r")
1947 (match_operand:DI 2 "register_operand" "=&r")])]
1950 rtx mem = operands[0];
1951 rtx addr = XEXP (mem, 0);
1953 emit_move_insn (operands[2], addr);
1954 mem = replace_equiv_address_nv (mem, operands[2]);
1956 emit_insn (gen_rtx_SET (mem, operands[1]));
1960 (define_expand "reload_noff_load"
1961 [(parallel [(match_operand 0 "register_operand" "=r")
1962 (match_operand 1 "memory_operand" "m")
1963 (match_operand:DI 2 "register_operand" "=r")])]
1966 rtx mem = operands[1];
1967 rtx addr = XEXP (mem, 0);
1969 emit_move_insn (operands[2], addr);
1970 mem = replace_equiv_address_nv (mem, operands[2]);
1972 emit_insn (gen_rtx_SET (operands[0], mem));
1976 ;; Move instructions.
1978 (define_expand "movxi"
1979 [(set (match_operand:XI 0 "nonimmediate_operand")
1980 (match_operand:XI 1 "general_operand"))]
1982 "ix86_expand_vector_move (XImode, operands); DONE;")
1984 (define_expand "movoi"
1985 [(set (match_operand:OI 0 "nonimmediate_operand")
1986 (match_operand:OI 1 "general_operand"))]
1988 "ix86_expand_vector_move (OImode, operands); DONE;")
1990 (define_expand "movti"
1991 [(set (match_operand:TI 0 "nonimmediate_operand")
1992 (match_operand:TI 1 "general_operand"))]
1993 "TARGET_64BIT || TARGET_SSE"
1996 ix86_expand_move (TImode, operands);
1998 ix86_expand_vector_move (TImode, operands);
2002 ;; This expands to what emit_move_complex would generate if we didn't
2003 ;; have a movti pattern. Having this avoids problems with reload on
2004 ;; 32-bit targets when SSE is present, but doesn't seem to be harmful
2005 ;; to have around all the time.
2006 (define_expand "movcdi"
2007 [(set (match_operand:CDI 0 "nonimmediate_operand")
2008 (match_operand:CDI 1 "general_operand"))]
2011 if (push_operand (operands[0], CDImode))
2012 emit_move_complex_push (CDImode, operands[0], operands[1]);
2014 emit_move_complex_parts (operands[0], operands[1]);
2018 (define_expand "mov<mode>"
2019 [(set (match_operand:SWI1248x 0 "nonimmediate_operand")
2020 (match_operand:SWI1248x 1 "general_operand"))]
2022 "ix86_expand_move (<MODE>mode, operands); DONE;")
2024 (define_insn "*mov<mode>_xor"
2025 [(set (match_operand:SWI48 0 "register_operand" "=r")
2026 (match_operand:SWI48 1 "const0_operand"))
2027 (clobber (reg:CC FLAGS_REG))]
2030 [(set_attr "type" "alu1")
2031 (set_attr "modrm_class" "op0")
2032 (set_attr "mode" "SI")
2033 (set_attr "length_immediate" "0")])
2035 (define_insn "*mov<mode>_or"
2036 [(set (match_operand:SWI48 0 "register_operand" "=r")
2037 (match_operand:SWI48 1 "constm1_operand"))
2038 (clobber (reg:CC FLAGS_REG))]
2040 "or{<imodesuffix>}\t{%1, %0|%0, %1}"
2041 [(set_attr "type" "alu1")
2042 (set_attr "mode" "<MODE>")
2043 (set_attr "length_immediate" "1")])
2045 (define_insn "*movxi_internal_avx512f"
2046 [(set (match_operand:XI 0 "nonimmediate_operand" "=v,v ,v ,m")
2047 (match_operand:XI 1 "nonimmediate_or_sse_const_operand" " C,BC,vm,v"))]
2049 && (register_operand (operands[0], XImode)
2050 || register_operand (operands[1], XImode))"
2052 switch (get_attr_type (insn))
2055 return standard_sse_constant_opcode (insn, operands);
2058 if (misaligned_operand (operands[0], XImode)
2059 || misaligned_operand (operands[1], XImode))
2060 return "vmovdqu32\t{%1, %0|%0, %1}";
2062 return "vmovdqa32\t{%1, %0|%0, %1}";
2068 [(set_attr "type" "sselog1,sselog1,ssemov,ssemov")
2069 (set_attr "prefix" "evex")
2070 (set_attr "mode" "XI")])
2072 (define_insn "*movoi_internal_avx"
2073 [(set (match_operand:OI 0 "nonimmediate_operand" "=v,v ,v ,m")
2074 (match_operand:OI 1 "nonimmediate_or_sse_const_operand" " C,BC,vm,v"))]
2076 && (register_operand (operands[0], OImode)
2077 || register_operand (operands[1], OImode))"
2079 switch (get_attr_type (insn))
2082 return standard_sse_constant_opcode (insn, operands);
2085 if (misaligned_operand (operands[0], OImode)
2086 || misaligned_operand (operands[1], OImode))
2088 if (get_attr_mode (insn) == MODE_V8SF)
2089 return "vmovups\t{%1, %0|%0, %1}";
2090 else if (get_attr_mode (insn) == MODE_XI)
2091 return "vmovdqu32\t{%1, %0|%0, %1}";
2093 return "vmovdqu\t{%1, %0|%0, %1}";
2097 if (get_attr_mode (insn) == MODE_V8SF)
2098 return "vmovaps\t{%1, %0|%0, %1}";
2099 else if (get_attr_mode (insn) == MODE_XI)
2100 return "vmovdqa32\t{%1, %0|%0, %1}";
2102 return "vmovdqa\t{%1, %0|%0, %1}";
2109 [(set_attr "isa" "*,avx2,*,*")
2110 (set_attr "type" "sselog1,sselog1,ssemov,ssemov")
2111 (set_attr "prefix" "vex")
2113 (cond [(ior (match_operand 0 "ext_sse_reg_operand")
2114 (match_operand 1 "ext_sse_reg_operand"))
2116 (and (eq_attr "alternative" "1")
2117 (match_test "TARGET_AVX512VL"))
2119 (ior (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
2120 (and (eq_attr "alternative" "3")
2121 (match_test "TARGET_SSE_TYPELESS_STORES")))
2122 (const_string "V8SF")
2124 (const_string "OI")))])
2126 (define_insn "*movti_internal"
2127 [(set (match_operand:TI 0 "nonimmediate_operand" "=!r ,o ,v,v ,v ,m,?r,?Yd")
2128 (match_operand:TI 1 "general_operand" "riFo,re,C,BC,vm,v,Yd,r"))]
2130 && !(MEM_P (operands[0]) && MEM_P (operands[1])))
2132 && nonimmediate_or_sse_const_operand (operands[1], TImode)
2133 && (register_operand (operands[0], TImode)
2134 || register_operand (operands[1], TImode)))"
2136 switch (get_attr_type (insn))
2142 return standard_sse_constant_opcode (insn, operands);
2145 /* TDmode values are passed as TImode on the stack. Moving them
2146 to stack may result in unaligned memory access. */
2147 if (misaligned_operand (operands[0], TImode)
2148 || misaligned_operand (operands[1], TImode))
2150 if (get_attr_mode (insn) == MODE_V4SF)
2151 return "%vmovups\t{%1, %0|%0, %1}";
2152 else if (get_attr_mode (insn) == MODE_XI)
2153 return "vmovdqu32\t{%1, %0|%0, %1}";
2155 return "%vmovdqu\t{%1, %0|%0, %1}";
2159 if (get_attr_mode (insn) == MODE_V4SF)
2160 return "%vmovaps\t{%1, %0|%0, %1}";
2161 else if (get_attr_mode (insn) == MODE_XI)
2162 return "vmovdqa32\t{%1, %0|%0, %1}";
2164 return "%vmovdqa\t{%1, %0|%0, %1}";
2172 (cond [(eq_attr "alternative" "0,1,6,7")
2173 (const_string "x64")
2174 (eq_attr "alternative" "3")
2175 (const_string "sse2")
2177 (const_string "*")))
2179 (cond [(eq_attr "alternative" "0,1,6,7")
2180 (const_string "multi")
2181 (eq_attr "alternative" "2,3")
2182 (const_string "sselog1")
2184 (const_string "ssemov")))
2185 (set (attr "prefix")
2186 (if_then_else (eq_attr "type" "sselog1,ssemov")
2187 (const_string "maybe_vex")
2188 (const_string "orig")))
2190 (cond [(eq_attr "alternative" "0,1")
2192 (ior (match_operand 0 "ext_sse_reg_operand")
2193 (match_operand 1 "ext_sse_reg_operand"))
2195 (and (eq_attr "alternative" "3")
2196 (match_test "TARGET_AVX512VL"))
2198 (ior (not (match_test "TARGET_SSE2"))
2199 (ior (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
2200 (and (eq_attr "alternative" "5")
2201 (match_test "TARGET_SSE_TYPELESS_STORES"))))
2202 (const_string "V4SF")
2203 (match_test "TARGET_AVX")
2205 (match_test "optimize_function_for_size_p (cfun)")
2206 (const_string "V4SF")
2208 (const_string "TI")))
2209 (set (attr "preferred_for_speed")
2210 (cond [(eq_attr "alternative" "6")
2211 (symbol_ref "TARGET_INTER_UNIT_MOVES_FROM_VEC")
2212 (eq_attr "alternative" "7")
2213 (symbol_ref "TARGET_INTER_UNIT_MOVES_TO_VEC")
2215 (symbol_ref "true")))])
2218 [(set (match_operand:TI 0 "sse_reg_operand")
2219 (match_operand:TI 1 "general_reg_operand"))]
2220 "TARGET_64BIT && TARGET_SSE4_1
2221 && reload_completed"
2224 (vec_duplicate:V2DI (match_dup 3))
2228 operands[2] = lowpart_subreg (V2DImode, operands[0], TImode);
2229 operands[3] = gen_highpart (DImode, operands[1]);
2231 emit_move_insn (gen_lowpart (DImode, operands[0]),
2232 gen_lowpart (DImode, operands[1]));
2235 (define_insn "*movdi_internal"
2236 [(set (match_operand:DI 0 "nonimmediate_operand"
2237 "=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")
2238 (match_operand:DI 1 "general_operand"
2239 "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"))]
2240 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2242 switch (get_attr_type (insn))
2245 return "kmovq\t{%1, %0|%0, %1}";
2251 return "pxor\t%0, %0";
2254 /* Handle broken assemblers that require movd instead of movq. */
2255 if (!HAVE_AS_IX86_INTERUNIT_MOVQ
2256 && (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1])))
2257 return "movd\t{%1, %0|%0, %1}";
2258 return "movq\t{%1, %0|%0, %1}";
2261 return standard_sse_constant_opcode (insn, operands);
2264 switch (get_attr_mode (insn))
2267 /* Handle broken assemblers that require movd instead of movq. */
2268 if (!HAVE_AS_IX86_INTERUNIT_MOVQ
2269 && (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1])))
2270 return "%vmovd\t{%1, %0|%0, %1}";
2271 return "%vmovq\t{%1, %0|%0, %1}";
2274 /* Handle AVX512 registers set. */
2275 if (EXT_REX_SSE_REG_P (operands[0])
2276 || EXT_REX_SSE_REG_P (operands[1]))
2277 return "vmovdqa64\t{%1, %0|%0, %1}";
2278 return "%vmovdqa\t{%1, %0|%0, %1}";
2281 gcc_assert (!TARGET_AVX);
2282 return "movlps\t{%1, %0|%0, %1}";
2284 return "%vmovaps\t{%1, %0|%0, %1}";
2291 if (SSE_REG_P (operands[0]))
2292 return "movq2dq\t{%1, %0|%0, %1}";
2294 return "movdq2q\t{%1, %0|%0, %1}";
2297 return "lea{q}\t{%E1, %0|%0, %E1}";
2300 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2301 if (get_attr_mode (insn) == MODE_SI)
2302 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2303 else if (which_alternative == 4)
2304 return "movabs{q}\t{%1, %0|%0, %1}";
2305 else if (ix86_use_lea_for_mov (insn, operands))
2306 return "lea{q}\t{%E1, %0|%0, %E1}";
2308 return "mov{q}\t{%1, %0|%0, %1}";
2315 (cond [(eq_attr "alternative" "0,1,17,18")
2316 (const_string "nox64")
2317 (eq_attr "alternative" "2,3,4,5,10,11,23,25")
2318 (const_string "x64")
2319 (eq_attr "alternative" "19,20")
2320 (const_string "x64_sse2")
2321 (eq_attr "alternative" "21,22")
2322 (const_string "sse2")
2324 (const_string "*")))
2326 (cond [(eq_attr "alternative" "0,1,17,18")
2327 (const_string "multi")
2328 (eq_attr "alternative" "6")
2329 (const_string "mmx")
2330 (eq_attr "alternative" "7,8,9,10,11")
2331 (const_string "mmxmov")
2332 (eq_attr "alternative" "12")
2333 (const_string "sselog1")
2334 (eq_attr "alternative" "13,14,15,16,19,20")
2335 (const_string "ssemov")
2336 (eq_attr "alternative" "21,22")
2337 (const_string "ssecvt")
2338 (eq_attr "alternative" "23,24,25,26")
2339 (const_string "mskmov")
2340 (and (match_operand 0 "register_operand")
2341 (match_operand 1 "pic_32bit_operand"))
2342 (const_string "lea")
2344 (const_string "imov")))
2347 (and (eq_attr "alternative" "4") (eq_attr "type" "imov"))
2349 (const_string "*")))
2350 (set (attr "length_immediate")
2352 (and (eq_attr "alternative" "4") (eq_attr "type" "imov"))
2354 (const_string "*")))
2355 (set (attr "prefix_rex")
2357 (eq_attr "alternative" "10,11,19,20")
2359 (const_string "*")))
2360 (set (attr "prefix")
2361 (if_then_else (eq_attr "type" "sselog1,ssemov")
2362 (const_string "maybe_vex")
2363 (const_string "orig")))
2364 (set (attr "prefix_data16")
2365 (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "DI"))
2367 (const_string "*")))
2369 (cond [(eq_attr "alternative" "2")
2371 (eq_attr "alternative" "12,13")
2372 (cond [(ior (match_operand 0 "ext_sse_reg_operand")
2373 (match_operand 1 "ext_sse_reg_operand"))
2375 (ior (not (match_test "TARGET_SSE2"))
2376 (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL"))
2377 (const_string "V4SF")
2378 (match_test "TARGET_AVX")
2380 (match_test "optimize_function_for_size_p (cfun)")
2381 (const_string "V4SF")
2383 (const_string "TI"))
2385 (and (eq_attr "alternative" "14,15,16")
2386 (not (match_test "TARGET_SSE2")))
2387 (const_string "V2SF")
2389 (const_string "DI")))
2390 (set (attr "preferred_for_speed")
2391 (cond [(eq_attr "alternative" "10,17,19")
2392 (symbol_ref "TARGET_INTER_UNIT_MOVES_FROM_VEC")
2393 (eq_attr "alternative" "11,18,20")
2394 (symbol_ref "TARGET_INTER_UNIT_MOVES_TO_VEC")
2396 (symbol_ref "true")))
2397 (set (attr "enabled")
2398 (cond [(eq_attr "alternative" "15")
2400 (match_test "TARGET_STV && TARGET_SSE2")
2401 (symbol_ref "false")
2403 (eq_attr "alternative" "16")
2405 (match_test "TARGET_STV && TARGET_SSE2")
2407 (symbol_ref "false"))
2409 (const_string "*")))])
2412 [(set (match_operand:<DWI> 0 "general_reg_operand")
2413 (match_operand:<DWI> 1 "sse_reg_operand"))]
2415 && reload_completed"
2419 (parallel [(const_int 1)])))]
2421 operands[2] = gen_highpart (<MODE>mode, operands[0]);
2422 operands[3] = lowpart_subreg (<ssevecmode>mode, operands[1], <DWI>mode);
2424 emit_move_insn (gen_lowpart (<MODE>mode, operands[0]),
2425 gen_lowpart (<MODE>mode, operands[1]));
2429 [(set (match_operand:DWI 0 "nonimmediate_gr_operand")
2430 (match_operand:DWI 1 "general_gr_operand"))]
2433 "ix86_split_long_move (operands); DONE;")
2436 [(set (match_operand:DI 0 "sse_reg_operand")
2437 (match_operand:DI 1 "general_reg_operand"))]
2438 "!TARGET_64BIT && TARGET_SSE4_1
2439 && reload_completed"
2442 (vec_duplicate:V4SI (match_dup 3))
2446 operands[2] = lowpart_subreg (V4SImode, operands[0], DImode);
2447 operands[3] = gen_highpart (SImode, operands[1]);
2449 emit_move_insn (gen_lowpart (SImode, operands[0]),
2450 gen_lowpart (SImode, operands[1]));
2453 ;; movabsq $0x0012345678000000, %rax is longer
2454 ;; than movl $0x12345678, %eax; shlq $24, %rax.
2456 [(set (match_operand:DI 0 "register_operand")
2457 (match_operand:DI 1 "const_int_operand"))]
2459 && optimize_insn_for_size_p ()
2460 && LEGACY_INT_REG_P (operands[0])
2461 && !x86_64_immediate_operand (operands[1], DImode)
2462 && !x86_64_zext_immediate_operand (operands[1], DImode)
2463 && !((UINTVAL (operands[1]) >> ctz_hwi (UINTVAL (operands[1])))
2464 & ~(HOST_WIDE_INT) 0xffffffff)
2465 && peep2_regno_dead_p (0, FLAGS_REG)"
2466 [(set (match_dup 0) (match_dup 1))
2467 (parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
2468 (clobber (reg:CC FLAGS_REG))])]
2470 int shift = ctz_hwi (UINTVAL (operands[1]));
2471 operands[1] = gen_int_mode (UINTVAL (operands[1]) >> shift, DImode);
2472 operands[2] = gen_int_mode (shift, QImode);
2475 (define_insn "*movsi_internal"
2476 [(set (match_operand:SI 0 "nonimmediate_operand"
2477 "=r,m ,*y,*y,?*y,?m,?r,?*y,*v,*v,*v,m ,?r,?*v,*k,*k ,*rm")
2478 (match_operand:SI 1 "general_operand"
2479 "g ,re,C ,*y,m ,*y,*y,r ,C ,*v,m ,*v,*v,r ,*r,*km,*k"))]
2480 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2482 switch (get_attr_type (insn))
2485 return standard_sse_constant_opcode (insn, operands);
2488 return "kmovd\t{%1, %0|%0, %1}";
2491 switch (get_attr_mode (insn))
2494 return "%vmovd\t{%1, %0|%0, %1}";
2496 return "%vmovdqa\t{%1, %0|%0, %1}";
2498 return "vmovdqa32\t{%g1, %g0|%g0, %g1}";
2501 return "%vmovaps\t{%1, %0|%0, %1}";
2504 gcc_assert (!TARGET_AVX);
2505 return "movss\t{%1, %0|%0, %1}";
2512 return "pxor\t%0, %0";
2515 switch (get_attr_mode (insn))
2518 return "movq\t{%1, %0|%0, %1}";
2520 return "movd\t{%1, %0|%0, %1}";
2527 return "lea{l}\t{%E1, %0|%0, %E1}";
2530 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2531 if (ix86_use_lea_for_mov (insn, operands))
2532 return "lea{l}\t{%E1, %0|%0, %E1}";
2534 return "mov{l}\t{%1, %0|%0, %1}";
2541 (cond [(eq_attr "alternative" "12,13")
2542 (const_string "sse2")
2544 (const_string "*")))
2546 (cond [(eq_attr "alternative" "2")
2547 (const_string "mmx")
2548 (eq_attr "alternative" "3,4,5,6,7")
2549 (const_string "mmxmov")
2550 (eq_attr "alternative" "8")
2551 (const_string "sselog1")
2552 (eq_attr "alternative" "9,10,11,12,13")
2553 (const_string "ssemov")
2554 (eq_attr "alternative" "14,15,16")
2555 (const_string "mskmov")
2556 (and (match_operand 0 "register_operand")
2557 (match_operand 1 "pic_32bit_operand"))
2558 (const_string "lea")
2560 (const_string "imov")))
2561 (set (attr "prefix")
2562 (if_then_else (eq_attr "type" "sselog1,ssemov")
2563 (const_string "maybe_vex")
2564 (const_string "orig")))
2565 (set (attr "prefix_data16")
2566 (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
2568 (const_string "*")))
2570 (cond [(eq_attr "alternative" "2,3")
2572 (eq_attr "alternative" "8,9")
2573 (cond [(ior (match_operand 0 "ext_sse_reg_operand")
2574 (match_operand 1 "ext_sse_reg_operand"))
2576 (ior (not (match_test "TARGET_SSE2"))
2577 (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL"))
2578 (const_string "V4SF")
2579 (match_test "TARGET_AVX")
2581 (match_test "optimize_function_for_size_p (cfun)")
2582 (const_string "V4SF")
2584 (const_string "TI"))
2586 (and (eq_attr "alternative" "10,11")
2587 (not (match_test "TARGET_SSE2")))
2590 (const_string "SI")))
2591 (set (attr "preferred_for_speed")
2592 (cond [(eq_attr "alternative" "6,12")
2593 (symbol_ref "TARGET_INTER_UNIT_MOVES_FROM_VEC")
2594 (eq_attr "alternative" "7,13")
2595 (symbol_ref "TARGET_INTER_UNIT_MOVES_TO_VEC")
2597 (symbol_ref "true")))])
2599 (define_insn "*movhi_internal"
2600 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r ,r ,m ,k,k ,r,m")
2601 (match_operand:HI 1 "general_operand" "r ,rn,rm,rn,r,km,k,k"))]
2602 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2604 switch (get_attr_type (insn))
2607 /* movzwl is faster than movw on p2 due to partial word stalls,
2608 though not as fast as an aligned movl. */
2609 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
2612 switch (which_alternative)
2615 return "kmovw\t{%k1, %0|%0, %k1}";
2617 return "kmovw\t{%1, %k0|%k0, %1}";
2620 return "kmovw\t{%1, %0|%0, %1}";
2626 if (get_attr_mode (insn) == MODE_SI)
2627 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2629 return "mov{w}\t{%1, %0|%0, %1}";
2633 (cond [(eq_attr "alternative" "4,5,6,7")
2634 (const_string "mskmov")
2635 (match_test "optimize_function_for_size_p (cfun)")
2636 (const_string "imov")
2637 (and (eq_attr "alternative" "0")
2638 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2639 (not (match_test "TARGET_HIMODE_MATH"))))
2640 (const_string "imov")
2641 (and (eq_attr "alternative" "1,2")
2642 (match_operand:HI 1 "aligned_operand"))
2643 (const_string "imov")
2644 (and (match_test "TARGET_MOVX")
2645 (eq_attr "alternative" "0,2"))
2646 (const_string "imovx")
2648 (const_string "imov")))
2649 (set (attr "prefix")
2650 (if_then_else (eq_attr "alternative" "4,5,6,7")
2651 (const_string "vex")
2652 (const_string "orig")))
2654 (cond [(eq_attr "type" "imovx")
2656 (and (eq_attr "alternative" "1,2")
2657 (match_operand:HI 1 "aligned_operand"))
2659 (and (eq_attr "alternative" "0")
2660 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2661 (not (match_test "TARGET_HIMODE_MATH"))))
2664 (const_string "HI")))])
2666 ;; Situation is quite tricky about when to choose full sized (SImode) move
2667 ;; over QImode moves. For Q_REG -> Q_REG move we use full size only for
2668 ;; partial register dependency machines (such as AMD Athlon), where QImode
2669 ;; moves issue extra dependency and for partial register stalls machines
2670 ;; that don't use QImode patterns (and QImode move cause stall on the next
2673 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
2674 ;; register stall machines with, where we use QImode instructions, since
2675 ;; partial register stall can be caused there. Then we use movzx.
2677 (define_insn "*movqi_internal"
2678 [(set (match_operand:QI 0 "nonimmediate_operand"
2679 "=Q,R,r,q,q,r,r ,?r,m ,k,k,r,m,k")
2680 (match_operand:QI 1 "general_operand"
2681 "Q ,R,r,n,m,q,rn, m,qn,r,k,k,k,m"))]
2682 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2684 static char buf[128];
2688 switch (get_attr_type (insn))
2691 gcc_assert (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]));
2692 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
2695 switch (which_alternative)
2698 ops = "kmov%s\t{%%k1, %%0|%%0, %%k1}";
2701 ops = "kmov%s\t{%%1, %%k0|%%k0, %%1}";
2705 gcc_assert (TARGET_AVX512DQ);
2708 ops = "kmov%s\t{%%1, %%0|%%0, %%1}";
2714 suffix = (get_attr_mode (insn) == MODE_HI) ? "w" : "b";
2716 snprintf (buf, sizeof (buf), ops, suffix);
2720 if (get_attr_mode (insn) == MODE_SI)
2721 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2723 return "mov{b}\t{%1, %0|%0, %1}";
2727 (cond [(eq_attr "alternative" "1,2")
2728 (const_string "x64")
2729 (eq_attr "alternative" "12,13")
2730 (const_string "avx512dq")
2732 (const_string "*")))
2734 (cond [(eq_attr "alternative" "9,10,11,12,13")
2735 (const_string "mskmov")
2736 (and (eq_attr "alternative" "7")
2737 (not (match_operand:QI 1 "aligned_operand")))
2738 (const_string "imovx")
2739 (match_test "optimize_function_for_size_p (cfun)")
2740 (const_string "imov")
2741 (and (eq_attr "alternative" "5")
2742 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2743 (not (match_test "TARGET_QIMODE_MATH"))))
2744 (const_string "imov")
2745 (eq_attr "alternative" "5,7")
2746 (const_string "imovx")
2747 (and (match_test "TARGET_MOVX")
2748 (eq_attr "alternative" "4"))
2749 (const_string "imovx")
2751 (const_string "imov")))
2752 (set (attr "prefix")
2753 (if_then_else (eq_attr "alternative" "9,10,11")
2754 (const_string "vex")
2755 (const_string "orig")))
2757 (cond [(eq_attr "alternative" "5,6,7")
2759 (eq_attr "alternative" "8")
2761 (and (eq_attr "alternative" "9,10,11")
2762 (not (match_test "TARGET_AVX512DQ")))
2764 (eq_attr "type" "imovx")
2766 ;; For -Os, 8-bit immediates are always shorter than 32-bit
2768 (and (eq_attr "type" "imov")
2769 (and (eq_attr "alternative" "3")
2770 (match_test "optimize_function_for_size_p (cfun)")))
2772 ;; For -Os, movl where one or both operands are NON_Q_REGS
2773 ;; and both are LEGACY_REGS is shorter than movb.
2774 ;; Otherwise movb and movl sizes are the same, so decide purely
2775 ;; based on speed factors.
2776 (and (eq_attr "type" "imov")
2777 (and (eq_attr "alternative" "1")
2778 (match_test "optimize_function_for_size_p (cfun)")))
2780 (and (eq_attr "type" "imov")
2781 (and (eq_attr "alternative" "0,1,2,3")
2782 (and (match_test "TARGET_PARTIAL_REG_DEPENDENCY")
2783 (not (match_test "TARGET_PARTIAL_REG_STALL")))))
2785 ;; Avoid partial register stalls when not using QImode arithmetic
2786 (and (eq_attr "type" "imov")
2787 (and (eq_attr "alternative" "0,1,2,3")
2788 (and (match_test "TARGET_PARTIAL_REG_STALL")
2789 (not (match_test "TARGET_QIMODE_MATH")))))
2792 (const_string "QI")))])
2794 ;; Stores and loads of ax to arbitrary constant address.
2795 ;; We fake an second form of instruction to force reload to load address
2796 ;; into register when rax is not available
2797 (define_insn "*movabs<mode>_1"
2798 [(set (mem:SWI1248x (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2799 (match_operand:SWI1248x 1 "nonmemory_operand" "a,r<i>"))]
2800 "TARGET_LP64 && ix86_check_movabs (insn, 0)"
2802 /* Recover the full memory rtx. */
2803 operands[0] = SET_DEST (PATTERN (insn));
2804 switch (which_alternative)
2807 return "movabs{<imodesuffix>}\t{%1, %P0|<iptrsize> PTR [%P0], %1}";
2809 return "mov{<imodesuffix>}\t{%1, %0|%0, %1}";
2814 [(set_attr "type" "imov")
2815 (set_attr "modrm" "0,*")
2816 (set_attr "length_address" "8,0")
2817 (set_attr "length_immediate" "0,*")
2818 (set_attr "memory" "store")
2819 (set_attr "mode" "<MODE>")])
2821 (define_insn "*movabs<mode>_2"
2822 [(set (match_operand:SWI1248x 0 "register_operand" "=a,r")
2823 (mem:SWI1248x (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2824 "TARGET_LP64 && ix86_check_movabs (insn, 1)"
2826 /* Recover the full memory rtx. */
2827 operands[1] = SET_SRC (PATTERN (insn));
2828 switch (which_alternative)
2831 return "movabs{<imodesuffix>}\t{%P1, %0|%0, <iptrsize> PTR [%P1]}";
2833 return "mov{<imodesuffix>}\t{%1, %0|%0, %1}";
2838 [(set_attr "type" "imov")
2839 (set_attr "modrm" "0,*")
2840 (set_attr "length_address" "8,0")
2841 (set_attr "length_immediate" "0")
2842 (set_attr "memory" "load")
2843 (set_attr "mode" "<MODE>")])
2845 (define_insn "*swap<mode>"
2846 [(set (match_operand:SWI48 0 "register_operand" "+r")
2847 (match_operand:SWI48 1 "register_operand" "+r"))
2851 "xchg{<imodesuffix>}\t%1, %0"
2852 [(set_attr "type" "imov")
2853 (set_attr "mode" "<MODE>")
2854 (set_attr "pent_pair" "np")
2855 (set_attr "athlon_decode" "vector")
2856 (set_attr "amdfam10_decode" "double")
2857 (set_attr "bdver1_decode" "double")])
2859 (define_insn "*swap<mode>"
2860 [(set (match_operand:SWI12 0 "register_operand" "+<r>,r")
2861 (match_operand:SWI12 1 "register_operand" "+<r>,r"))
2866 xchg{<imodesuffix>}\t%1, %0
2868 [(set_attr "type" "imov")
2869 (set_attr "mode" "<MODE>,SI")
2870 (set (attr "preferred_for_size")
2871 (cond [(eq_attr "alternative" "0")
2872 (symbol_ref "false")]
2873 (symbol_ref "true")))
2874 ;; Potential partial reg stall on alternative 1.
2875 (set (attr "preferred_for_speed")
2876 (cond [(eq_attr "alternative" "1")
2877 (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
2878 (symbol_ref "true")))
2879 (set_attr "pent_pair" "np")
2880 (set_attr "athlon_decode" "vector")
2881 (set_attr "amdfam10_decode" "double")
2882 (set_attr "bdver1_decode" "double")])
2884 (define_expand "movstrict<mode>"
2885 [(set (strict_low_part (match_operand:SWI12 0 "nonimmediate_operand"))
2886 (match_operand:SWI12 1 "general_operand"))]
2889 if (TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun))
2891 if (SUBREG_P (operands[0])
2892 && GET_MODE_CLASS (GET_MODE (SUBREG_REG (operands[0]))) != MODE_INT)
2894 /* Don't generate memory->memory moves, go through a register */
2895 if (MEM_P (operands[0]) && MEM_P (operands[1]))
2896 operands[1] = force_reg (<MODE>mode, operands[1]);
2899 (define_insn "*movstrict<mode>_1"
2900 [(set (strict_low_part
2901 (match_operand:SWI12 0 "nonimmediate_operand" "+<r>m,<r>"))
2902 (match_operand:SWI12 1 "general_operand" "<r>n,m"))]
2903 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
2904 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2905 "mov{<imodesuffix>}\t{%1, %0|%0, %1}"
2906 [(set_attr "type" "imov")
2907 (set_attr "mode" "<MODE>")])
2909 (define_insn "*movstrict<mode>_xor"
2910 [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>"))
2911 (match_operand:SWI12 1 "const0_operand"))
2912 (clobber (reg:CC FLAGS_REG))]
2914 "xor{<imodesuffix>}\t%0, %0"
2915 [(set_attr "type" "alu1")
2916 (set_attr "modrm_class" "op0")
2917 (set_attr "mode" "<MODE>")
2918 (set_attr "length_immediate" "0")])
2920 (define_expand "extv<mode>"
2921 [(set (match_operand:SWI24 0 "register_operand")
2922 (sign_extract:SWI24 (match_operand:SWI24 1 "register_operand")
2923 (match_operand:SI 2 "const_int_operand")
2924 (match_operand:SI 3 "const_int_operand")))]
2927 /* Handle extractions from %ah et al. */
2928 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
2931 unsigned int regno = reg_or_subregno (operands[1]);
2933 /* Be careful to expand only with registers having upper parts. */
2934 if (regno <= LAST_VIRTUAL_REGISTER && !QI_REGNO_P (regno))
2935 operands[1] = copy_to_reg (operands[1]);
2938 (define_insn "*extv<mode>"
2939 [(set (match_operand:SWI24 0 "register_operand" "=R")
2940 (sign_extract:SWI24 (match_operand 1 "ext_register_operand" "Q")
2944 "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
2945 [(set_attr "type" "imovx")
2946 (set_attr "mode" "SI")])
2948 (define_expand "extzv<mode>"
2949 [(set (match_operand:SWI248 0 "register_operand")
2950 (zero_extract:SWI248 (match_operand:SWI248 1 "register_operand")
2951 (match_operand:SI 2 "const_int_operand")
2952 (match_operand:SI 3 "const_int_operand")))]
2955 if (ix86_expand_pextr (operands))
2958 /* Handle extractions from %ah et al. */
2959 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
2962 unsigned int regno = reg_or_subregno (operands[1]);
2964 /* Be careful to expand only with registers having upper parts. */
2965 if (regno <= LAST_VIRTUAL_REGISTER && !QI_REGNO_P (regno))
2966 operands[1] = copy_to_reg (operands[1]);
2969 (define_insn "*extzvqi_mem_rex64"
2970 [(set (match_operand:QI 0 "norex_memory_operand" "=Bn")
2972 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q")
2975 "TARGET_64BIT && reload_completed"
2976 "mov{b}\t{%h1, %0|%0, %h1}"
2977 [(set_attr "type" "imov")
2978 (set_attr "mode" "QI")])
2980 (define_insn "*extzv<mode>"
2981 [(set (match_operand:SWI248 0 "register_operand" "=R")
2982 (zero_extract:SWI248 (match_operand 1 "ext_register_operand" "Q")
2986 "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
2987 [(set_attr "type" "imovx")
2988 (set_attr "mode" "SI")])
2990 (define_insn "*extzvqi"
2991 [(set (match_operand:QI 0 "nonimmediate_operand" "=QBc,?R,m")
2993 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q,Q")
2998 switch (get_attr_type (insn))
3001 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
3003 return "mov{b}\t{%h1, %0|%0, %h1}";
3006 [(set_attr "isa" "*,*,nox64")
3008 (if_then_else (and (match_operand:QI 0 "register_operand")
3009 (ior (not (match_operand:QI 0 "QIreg_operand"))
3010 (match_test "TARGET_MOVX")))
3011 (const_string "imovx")
3012 (const_string "imov")))
3014 (if_then_else (eq_attr "type" "imovx")
3016 (const_string "QI")))])
3019 [(set (match_operand:QI 0 "register_operand")
3021 (zero_extract:SI (match_operand 1 "ext_register_operand")
3024 (set (match_operand:QI 2 "norex_memory_operand") (match_dup 0))]
3026 && peep2_reg_dead_p (2, operands[0])"
3029 (zero_extract:SI (match_dup 1)
3031 (const_int 8)) 0))])
3033 (define_expand "insv<mode>"
3034 [(set (zero_extract:SWI248 (match_operand:SWI248 0 "register_operand")
3035 (match_operand:SI 1 "const_int_operand")
3036 (match_operand:SI 2 "const_int_operand"))
3037 (match_operand:SWI248 3 "register_operand"))]
3042 if (ix86_expand_pinsr (operands))
3045 /* Handle insertions to %ah et al. */
3046 if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
3049 unsigned int regno = reg_or_subregno (operands[0]);
3051 /* Be careful to expand only with registers having upper parts. */
3052 if (regno <= LAST_VIRTUAL_REGISTER && !QI_REGNO_P (regno))
3053 dst = copy_to_reg (operands[0]);
3057 emit_insn (gen_insv<mode>_1 (dst, operands[3]));
3059 /* Fix up the destination if needed. */
3060 if (dst != operands[0])
3061 emit_move_insn (operands[0], dst);
3066 (define_insn "*insvqi_1_mem_rex64"
3067 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
3071 (match_operand:QI 1 "norex_memory_operand" "Bn") 0))]
3072 "TARGET_64BIT && reload_completed"
3073 "mov{b}\t{%1, %h0|%h0, %1}"
3074 [(set_attr "type" "imov")
3075 (set_attr "mode" "QI")])
3077 (define_insn "insv<mode>_1"
3078 [(set (zero_extract:SWI248 (match_operand 0 "ext_register_operand" "+Q,Q")
3081 (match_operand:SWI248 1 "general_operand" "QnBc,m"))]
3084 if (CONST_INT_P (operands[1]))
3085 operands[1] = gen_int_mode (INTVAL (operands[1]), QImode);
3086 return "mov{b}\t{%b1, %h0|%h0, %b1}";
3088 [(set_attr "isa" "*,nox64")
3089 (set_attr "type" "imov")
3090 (set_attr "mode" "QI")])
3092 (define_insn "*insvqi_1"
3093 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q,Q")
3097 (match_operand:QI 1 "general_operand" "QnBc,m") 0))]
3099 "mov{b}\t{%1, %h0|%h0, %1}"
3100 [(set_attr "isa" "*,nox64")
3101 (set_attr "type" "imov")
3102 (set_attr "mode" "QI")])
3105 [(set (match_operand:QI 0 "register_operand")
3106 (match_operand:QI 1 "norex_memory_operand"))
3107 (set (zero_extract:SI (match_operand 2 "ext_register_operand")
3110 (subreg:SI (match_dup 0) 0))]
3112 && peep2_reg_dead_p (2, operands[0])"
3113 [(set (zero_extract:SI (match_dup 2)
3116 (subreg:SI (match_dup 1) 0))])
3118 (define_code_iterator any_extract [sign_extract zero_extract])
3120 (define_insn "*insvqi_2"
3121 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
3124 (any_extract:SI (match_operand 1 "ext_register_operand" "Q")
3128 "mov{b}\t{%h1, %h0|%h0, %h1}"
3129 [(set_attr "type" "imov")
3130 (set_attr "mode" "QI")])
3132 (define_insn "*insvqi_3"
3133 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
3136 (any_shiftrt:SI (match_operand:SI 1 "register_operand" "Q")
3139 "mov{b}\t{%h1, %h0|%h0, %h1}"
3140 [(set_attr "type" "imov")
3141 (set_attr "mode" "QI")])
3143 ;; Floating point push instructions.
3145 (define_insn "*pushtf"
3146 [(set (match_operand:TF 0 "push_operand" "=<,<")
3147 (match_operand:TF 1 "general_no_elim_operand" "v,*roC"))]
3148 "TARGET_64BIT || TARGET_SSE"
3150 /* This insn should be already split before reg-stack. */
3153 [(set_attr "isa" "*,x64")
3154 (set_attr "type" "multi")
3155 (set_attr "unit" "sse,*")
3156 (set_attr "mode" "TF,DI")])
3158 ;; %%% Kill this when call knows how to work this out.
3160 [(set (match_operand:TF 0 "push_operand")
3161 (match_operand:TF 1 "sse_reg_operand"))]
3162 "TARGET_SSE && reload_completed"
3163 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -16)))
3164 (set (match_dup 0) (match_dup 1))]
3166 /* Preserve memory attributes. */
3167 operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
3170 (define_insn_and_split "*pushxf_rounded"
3174 (plus:P (reg:P SP_REG) (const_int -16))))
3175 (match_operand:XF 0 "nonmemory_no_elim_operand" "f,r,*r,C"))]
3179 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -16)))
3180 (set (match_dup 1) (match_dup 0))]
3182 rtx pat = PATTERN (curr_insn);
3183 operands[1] = SET_DEST (pat);
3185 /* Preserve memory attributes. */
3186 operands[1] = replace_equiv_address (operands[1], stack_pointer_rtx);
3188 [(set_attr "type" "multi")
3189 (set_attr "unit" "i387,*,*,*")
3191 (cond [(eq_attr "alternative" "1,2,3")
3194 (const_string "XF")))
3195 (set (attr "preferred_for_size")
3196 (cond [(eq_attr "alternative" "1")
3197 (symbol_ref "false")]
3198 (symbol_ref "true")))])
3200 (define_insn "*pushxf"
3201 [(set (match_operand:XF 0 "push_operand" "=<,<,<,<,<")
3202 (match_operand:XF 1 "general_no_elim_operand" "f,r,*r,oF,oC"))]
3205 /* This insn should be already split before reg-stack. */
3208 [(set_attr "isa" "*,*,*,nox64,x64")
3209 (set_attr "type" "multi")
3210 (set_attr "unit" "i387,*,*,*,*")
3212 (cond [(eq_attr "alternative" "1,2,3,4")
3213 (if_then_else (match_test "TARGET_64BIT")
3215 (const_string "SI"))
3217 (const_string "XF")))
3218 (set (attr "preferred_for_size")
3219 (cond [(eq_attr "alternative" "1")
3220 (symbol_ref "false")]
3221 (symbol_ref "true")))])
3223 ;; %%% Kill this when call knows how to work this out.
3225 [(set (match_operand:XF 0 "push_operand")
3226 (match_operand:XF 1 "fp_register_operand"))]
3228 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
3229 (set (match_dup 0) (match_dup 1))]
3231 operands[2] = GEN_INT (-PUSH_ROUNDING (GET_MODE_SIZE (XFmode)));
3232 /* Preserve memory attributes. */
3233 operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
3236 (define_insn "*pushdf"
3237 [(set (match_operand:DF 0 "push_operand" "=<,<,<,<,<,<")
3238 (match_operand:DF 1 "general_no_elim_operand" "f,r,*r,oF,rmC,x"))]
3241 /* This insn should be already split before reg-stack. */
3244 [(set_attr "isa" "*,nox64,nox64,nox64,x64,sse2")
3245 (set_attr "type" "multi")
3246 (set_attr "unit" "i387,*,*,*,*,sse")
3247 (set_attr "mode" "DF,SI,SI,SI,DI,DF")
3248 (set (attr "preferred_for_size")
3249 (cond [(eq_attr "alternative" "1")
3250 (symbol_ref "false")]
3251 (symbol_ref "true")))
3252 (set (attr "preferred_for_speed")
3253 (cond [(eq_attr "alternative" "1")
3254 (symbol_ref "TARGET_INTEGER_DFMODE_MOVES")]
3255 (symbol_ref "true")))])
3257 ;; %%% Kill this when call knows how to work this out.
3259 [(set (match_operand:DF 0 "push_operand")
3260 (match_operand:DF 1 "any_fp_register_operand"))]
3262 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
3263 (set (match_dup 0) (match_dup 1))]
3265 /* Preserve memory attributes. */
3266 operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
3269 (define_insn "*pushsf_rex64"
3270 [(set (match_operand:SF 0 "push_operand" "=X,X,X")
3271 (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
3274 /* Anything else should be already split before reg-stack. */
3275 gcc_assert (which_alternative == 1);
3276 return "push{q}\t%q1";
3278 [(set_attr "type" "multi,push,multi")
3279 (set_attr "unit" "i387,*,*")
3280 (set_attr "mode" "SF,DI,SF")])
3282 (define_insn "*pushsf"
3283 [(set (match_operand:SF 0 "push_operand" "=<,<,<")
3284 (match_operand:SF 1 "general_no_elim_operand" "f,rmF,x"))]
3287 /* Anything else should be already split before reg-stack. */
3288 gcc_assert (which_alternative == 1);
3289 return "push{l}\t%1";
3291 [(set_attr "type" "multi,push,multi")
3292 (set_attr "unit" "i387,*,*")
3293 (set_attr "mode" "SF,SI,SF")])
3295 ;; %%% Kill this when call knows how to work this out.
3297 [(set (match_operand:SF 0 "push_operand")
3298 (match_operand:SF 1 "any_fp_register_operand"))]
3300 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
3301 (set (match_dup 0) (match_dup 1))]
3303 rtx op = XEXP (operands[0], 0);
3304 if (GET_CODE (op) == PRE_DEC)
3306 gcc_assert (!TARGET_64BIT);
3311 op = XEXP (XEXP (op, 1), 1);
3312 gcc_assert (CONST_INT_P (op));
3315 /* Preserve memory attributes. */
3316 operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
3320 [(set (match_operand:SF 0 "push_operand")
3321 (match_operand:SF 1 "memory_operand"))]
3323 && find_constant_src (insn)"
3324 [(set (match_dup 0) (match_dup 2))]
3325 "operands[2] = find_constant_src (curr_insn);")
3328 [(set (match_operand 0 "push_operand")
3329 (match_operand 1 "general_gr_operand"))]
3331 && (GET_MODE (operands[0]) == TFmode
3332 || GET_MODE (operands[0]) == XFmode
3333 || GET_MODE (operands[0]) == DFmode)"
3335 "ix86_split_long_move (operands); DONE;")
3337 ;; Floating point move instructions.
3339 (define_expand "movtf"
3340 [(set (match_operand:TF 0 "nonimmediate_operand")
3341 (match_operand:TF 1 "nonimmediate_operand"))]
3342 "TARGET_64BIT || TARGET_SSE"
3343 "ix86_expand_move (TFmode, operands); DONE;")
3345 (define_expand "mov<mode>"
3346 [(set (match_operand:X87MODEF 0 "nonimmediate_operand")
3347 (match_operand:X87MODEF 1 "general_operand"))]
3349 "ix86_expand_move (<MODE>mode, operands); DONE;")
3351 (define_insn "*movtf_internal"
3352 [(set (match_operand:TF 0 "nonimmediate_operand" "=v,v ,m,?*r ,!o")
3353 (match_operand:TF 1 "general_operand" "C ,vm,v,*roF,*rC"))]
3354 "(TARGET_64BIT || TARGET_SSE)
3355 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3356 && (lra_in_progress || reload_completed
3357 || !CONST_DOUBLE_P (operands[1])
3358 || ((optimize_function_for_size_p (cfun)
3359 || (ix86_cmodel == CM_LARGE || ix86_cmodel == CM_LARGE_PIC))
3360 && standard_sse_constant_p (operands[1], TFmode) == 1
3361 && !memory_operand (operands[0], TFmode))
3362 || (!TARGET_MEMORY_MISMATCH_STALL
3363 && memory_operand (operands[0], TFmode)))"
3365 switch (get_attr_type (insn))
3368 return standard_sse_constant_opcode (insn, operands);
3371 /* Handle misaligned load/store since we
3372 don't have movmisaligntf pattern. */
3373 if (misaligned_operand (operands[0], TFmode)
3374 || misaligned_operand (operands[1], TFmode))
3376 if (get_attr_mode (insn) == MODE_V4SF)
3377 return "%vmovups\t{%1, %0|%0, %1}";
3378 else if (TARGET_AVX512VL
3379 && (EXT_REX_SSE_REG_P (operands[0])
3380 || EXT_REX_SSE_REG_P (operands[1])))
3381 return "vmovdqu64\t{%1, %0|%0, %1}";
3383 return "%vmovdqu\t{%1, %0|%0, %1}";
3387 if (get_attr_mode (insn) == MODE_V4SF)
3388 return "%vmovaps\t{%1, %0|%0, %1}";
3389 else if (TARGET_AVX512VL
3390 && (EXT_REX_SSE_REG_P (operands[0])
3391 || EXT_REX_SSE_REG_P (operands[1])))
3392 return "vmovdqa64\t{%1, %0|%0, %1}";
3394 return "%vmovdqa\t{%1, %0|%0, %1}";
3404 [(set_attr "isa" "*,*,*,x64,x64")
3405 (set_attr "type" "sselog1,ssemov,ssemov,multi,multi")
3406 (set (attr "prefix")
3407 (if_then_else (eq_attr "type" "sselog1,ssemov")
3408 (const_string "maybe_vex")
3409 (const_string "orig")))
3411 (cond [(eq_attr "alternative" "3,4")
3413 (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
3414 (const_string "V4SF")
3415 (and (eq_attr "alternative" "2")
3416 (match_test "TARGET_SSE_TYPELESS_STORES"))
3417 (const_string "V4SF")
3418 (match_test "TARGET_AVX")
3420 (ior (not (match_test "TARGET_SSE2"))
3421 (match_test "optimize_function_for_size_p (cfun)"))
3422 (const_string "V4SF")
3424 (const_string "TI")))])
3427 [(set (match_operand:TF 0 "nonimmediate_gr_operand")
3428 (match_operand:TF 1 "general_gr_operand"))]
3431 "ix86_split_long_move (operands); DONE;")
3433 ;; Possible store forwarding (partial memory) stall
3434 ;; in alternatives 4, 6, 7 and 8.
3435 (define_insn "*movxf_internal"
3436 [(set (match_operand:XF 0 "nonimmediate_operand"
3437 "=f,m,f,?r ,!o,?*r ,!o,!o,!o,r ,o ,o")
3438 (match_operand:XF 1 "general_operand"
3439 "fm,f,G,roF,r ,*roF,*r,F ,C ,roF,rF,rC"))]
3440 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3441 && (lra_in_progress || reload_completed
3442 || !CONST_DOUBLE_P (operands[1])
3443 || ((optimize_function_for_size_p (cfun)
3444 || (ix86_cmodel == CM_LARGE || ix86_cmodel == CM_LARGE_PIC))
3445 && standard_80387_constant_p (operands[1]) > 0
3446 && !memory_operand (operands[0], XFmode))
3447 || (!TARGET_MEMORY_MISMATCH_STALL
3448 && memory_operand (operands[0], XFmode))
3449 || !TARGET_HARD_XF_REGS)"
3451 switch (get_attr_type (insn))
3454 if (which_alternative == 2)
3455 return standard_80387_constant_opcode (operands[1]);
3456 return output_387_reg_move (insn, operands);
3466 (cond [(eq_attr "alternative" "7,10")
3467 (const_string "nox64")
3468 (eq_attr "alternative" "8,11")
3469 (const_string "x64")
3471 (const_string "*")))
3473 (cond [(eq_attr "alternative" "3,4,5,6,7,8,9,10,11")
3474 (const_string "multi")
3476 (const_string "fmov")))
3478 (cond [(eq_attr "alternative" "3,4,5,6,7,8,9,10,11")
3479 (if_then_else (match_test "TARGET_64BIT")
3481 (const_string "SI"))
3483 (const_string "XF")))
3484 (set (attr "preferred_for_size")
3485 (cond [(eq_attr "alternative" "3,4")
3486 (symbol_ref "false")]
3487 (symbol_ref "true")))
3488 (set (attr "enabled")
3489 (cond [(eq_attr "alternative" "9,10,11")
3491 (match_test "TARGET_HARD_XF_REGS")
3492 (symbol_ref "false")
3494 (not (match_test "TARGET_HARD_XF_REGS"))
3495 (symbol_ref "false")
3497 (const_string "*")))])
3500 [(set (match_operand:XF 0 "nonimmediate_gr_operand")
3501 (match_operand:XF 1 "general_gr_operand"))]
3504 "ix86_split_long_move (operands); DONE;")
3506 ;; Possible store forwarding (partial memory) stall in alternatives 4, 6 and 7.
3507 (define_insn "*movdf_internal"
3508 [(set (match_operand:DF 0 "nonimmediate_operand"
3509 "=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")
3510 (match_operand:DF 1 "general_operand"
3511 "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"))]
3512 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3513 && (lra_in_progress || reload_completed
3514 || !CONST_DOUBLE_P (operands[1])
3515 || ((optimize_function_for_size_p (cfun)
3516 || (ix86_cmodel == CM_LARGE || ix86_cmodel == CM_LARGE_PIC))
3517 && ((IS_STACK_MODE (DFmode)
3518 && standard_80387_constant_p (operands[1]) > 0)
3519 || (TARGET_SSE2 && TARGET_SSE_MATH
3520 && standard_sse_constant_p (operands[1], DFmode) == 1))
3521 && !memory_operand (operands[0], DFmode))
3522 || ((TARGET_64BIT || !TARGET_MEMORY_MISMATCH_STALL)
3523 && memory_operand (operands[0], DFmode))
3524 || !TARGET_HARD_DF_REGS)"
3526 switch (get_attr_type (insn))
3529 if (which_alternative == 2)
3530 return standard_80387_constant_opcode (operands[1]);
3531 return output_387_reg_move (insn, operands);
3537 if (get_attr_mode (insn) == MODE_SI)
3538 return "mov{l}\t{%1, %k0|%k0, %1}";
3539 else if (which_alternative == 11)
3540 return "movabs{q}\t{%1, %0|%0, %1}";
3542 return "mov{q}\t{%1, %0|%0, %1}";
3545 return standard_sse_constant_opcode (insn, operands);
3548 switch (get_attr_mode (insn))
3551 if (TARGET_AVX && REG_P (operands[0]) && REG_P (operands[1]))
3552 return "vmovsd\t{%d1, %0|%0, %d1}";
3553 return "%vmovsd\t{%1, %0|%0, %1}";
3556 return "%vmovaps\t{%1, %0|%0, %1}";
3558 return "vmovapd\t{%g1, %g0|%g0, %g1}";
3560 return "%vmovapd\t{%1, %0|%0, %1}";
3563 gcc_assert (!TARGET_AVX);
3564 return "movlps\t{%1, %0|%0, %1}";
3566 gcc_assert (!TARGET_AVX);
3567 return "movlpd\t{%1, %0|%0, %1}";
3570 /* Handle broken assemblers that require movd instead of movq. */
3571 if (!HAVE_AS_IX86_INTERUNIT_MOVQ
3572 && (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1])))
3573 return "%vmovd\t{%1, %0|%0, %1}";
3574 return "%vmovq\t{%1, %0|%0, %1}";
3585 (cond [(eq_attr "alternative" "3,4,5,6,7,22,23")
3586 (const_string "nox64")
3587 (eq_attr "alternative" "8,9,10,11,24,25")
3588 (const_string "x64")
3589 (eq_attr "alternative" "12,13,14,15")
3590 (const_string "sse2")
3591 (eq_attr "alternative" "20,21")
3592 (const_string "x64_sse2")
3594 (const_string "*")))
3596 (cond [(eq_attr "alternative" "0,1,2")
3597 (const_string "fmov")
3598 (eq_attr "alternative" "3,4,5,6,7,22,23")
3599 (const_string "multi")
3600 (eq_attr "alternative" "8,9,10,11,24,25")
3601 (const_string "imov")
3602 (eq_attr "alternative" "12,16")
3603 (const_string "sselog1")
3605 (const_string "ssemov")))
3607 (if_then_else (eq_attr "alternative" "11")
3609 (const_string "*")))
3610 (set (attr "length_immediate")
3611 (if_then_else (eq_attr "alternative" "11")
3613 (const_string "*")))
3614 (set (attr "prefix")
3615 (if_then_else (eq_attr "type" "sselog1,ssemov")
3616 (const_string "maybe_vex")
3617 (const_string "orig")))
3618 (set (attr "prefix_data16")
3620 (ior (and (eq_attr "type" "ssemov") (eq_attr "mode" "DI"))
3621 (eq_attr "mode" "V1DF"))
3623 (const_string "*")))
3625 (cond [(eq_attr "alternative" "3,4,5,6,7,10,22,23")
3627 (eq_attr "alternative" "8,9,11,20,21,24,25")
3630 /* xorps is one byte shorter for non-AVX targets. */
3631 (eq_attr "alternative" "12,16")
3632 (cond [(not (match_test "TARGET_SSE2"))
3633 (const_string "V4SF")
3634 (and (match_test "TARGET_AVX512F")
3635 (not (match_test "TARGET_PREFER_AVX256")))
3637 (match_test "TARGET_AVX")
3638 (const_string "V2DF")
3639 (match_test "optimize_function_for_size_p (cfun)")
3640 (const_string "V4SF")
3641 (match_test "TARGET_SSE_LOAD0_BY_PXOR")
3644 (const_string "V2DF"))
3646 /* For architectures resolving dependencies on
3647 whole SSE registers use movapd to break dependency
3648 chains, otherwise use short move to avoid extra work. */
3650 /* movaps is one byte shorter for non-AVX targets. */
3651 (eq_attr "alternative" "13,17")
3652 (cond [(and (ior (not (match_test "TARGET_PREFER_AVX256"))
3653 (not (match_test "TARGET_AVX512VL")))
3654 (ior (match_operand 0 "ext_sse_reg_operand")
3655 (match_operand 1 "ext_sse_reg_operand")))
3656 (const_string "V8DF")
3657 (ior (not (match_test "TARGET_SSE2"))
3658 (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL"))
3659 (const_string "V4SF")
3660 (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3661 (const_string "V2DF")
3662 (match_test "TARGET_AVX")
3664 (match_test "optimize_function_for_size_p (cfun)")
3665 (const_string "V4SF")
3667 (const_string "DF"))
3669 /* For architectures resolving dependencies on register
3670 parts we may avoid extra work to zero out upper part
3672 (eq_attr "alternative" "14,18")
3673 (cond [(not (match_test "TARGET_SSE2"))
3674 (const_string "V2SF")
3675 (match_test "TARGET_AVX")
3677 (match_test "TARGET_SSE_SPLIT_REGS")
3678 (const_string "V1DF")
3680 (const_string "DF"))
3682 (and (eq_attr "alternative" "15,19")
3683 (not (match_test "TARGET_SSE2")))
3684 (const_string "V2SF")
3686 (const_string "DF")))
3687 (set (attr "preferred_for_size")
3688 (cond [(eq_attr "alternative" "3,4")
3689 (symbol_ref "false")]
3690 (symbol_ref "true")))
3691 (set (attr "preferred_for_speed")
3692 (cond [(eq_attr "alternative" "3,4")
3693 (symbol_ref "TARGET_INTEGER_DFMODE_MOVES")
3694 (eq_attr "alternative" "20")
3695 (symbol_ref "TARGET_INTER_UNIT_MOVES_FROM_VEC")
3696 (eq_attr "alternative" "21")
3697 (symbol_ref "TARGET_INTER_UNIT_MOVES_TO_VEC")
3699 (symbol_ref "true")))
3700 (set (attr "enabled")
3701 (cond [(eq_attr "alternative" "22,23,24,25")
3703 (match_test "TARGET_HARD_DF_REGS")
3704 (symbol_ref "false")
3706 (not (match_test "TARGET_HARD_DF_REGS"))
3707 (symbol_ref "false")
3709 (const_string "*")))])
3712 [(set (match_operand:DF 0 "nonimmediate_gr_operand")
3713 (match_operand:DF 1 "general_gr_operand"))]
3714 "!TARGET_64BIT && reload_completed"
3716 "ix86_split_long_move (operands); DONE;")
3718 (define_insn "*movsf_internal"
3719 [(set (match_operand:SF 0 "nonimmediate_operand"
3720 "=Yf*f,m ,Yf*f,?r ,?m,v,v,v,m,?r,?v,!*y,!*y,!m,!r,!*y,r ,m")
3721 (match_operand:SF 1 "general_operand"
3722 "Yf*fm,Yf*f,G ,rmF,rF,C,v,m,v,v ,r ,*y ,m ,*y,*y,r ,rmF,rF"))]
3723 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3724 && (lra_in_progress || reload_completed
3725 || !CONST_DOUBLE_P (operands[1])
3726 || ((optimize_function_for_size_p (cfun)
3727 || (ix86_cmodel == CM_LARGE || ix86_cmodel == CM_LARGE_PIC))
3728 && ((IS_STACK_MODE (SFmode)
3729 && standard_80387_constant_p (operands[1]) > 0)
3730 || (TARGET_SSE && TARGET_SSE_MATH
3731 && standard_sse_constant_p (operands[1], SFmode) == 1)))
3732 || memory_operand (operands[0], SFmode)
3733 || !TARGET_HARD_SF_REGS)"
3735 switch (get_attr_type (insn))
3738 if (which_alternative == 2)
3739 return standard_80387_constant_opcode (operands[1]);
3740 return output_387_reg_move (insn, operands);
3743 return "mov{l}\t{%1, %0|%0, %1}";
3746 return standard_sse_constant_opcode (insn, operands);
3749 switch (get_attr_mode (insn))
3752 if (TARGET_AVX && REG_P (operands[0]) && REG_P (operands[1]))
3753 return "vmovss\t{%d1, %0|%0, %d1}";
3754 return "%vmovss\t{%1, %0|%0, %1}";
3757 return "vmovaps\t{%g1, %g0|%g0, %g1}";
3759 return "%vmovaps\t{%1, %0|%0, %1}";
3762 return "%vmovd\t{%1, %0|%0, %1}";
3769 switch (get_attr_mode (insn))
3772 return "movq\t{%1, %0|%0, %1}";
3774 return "movd\t{%1, %0|%0, %1}";
3785 (cond [(eq_attr "alternative" "14,15")
3786 (const_string "sse2")
3788 (const_string "*")))
3790 (cond [(eq_attr "alternative" "0,1,2")
3791 (const_string "fmov")
3792 (eq_attr "alternative" "3,4,16,17")
3793 (const_string "imov")
3794 (eq_attr "alternative" "5")
3795 (const_string "sselog1")
3796 (eq_attr "alternative" "11,12,13,14,15")
3797 (const_string "mmxmov")
3799 (const_string "ssemov")))
3800 (set (attr "prefix")
3801 (if_then_else (eq_attr "type" "sselog1,ssemov")
3802 (const_string "maybe_vex")
3803 (const_string "orig")))
3804 (set (attr "prefix_data16")
3805 (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
3807 (const_string "*")))
3809 (cond [(eq_attr "alternative" "3,4,9,10,12,13,14,15,16,17")
3811 (eq_attr "alternative" "11")
3813 (eq_attr "alternative" "5")
3814 (cond [(not (match_test "TARGET_SSE2"))
3815 (const_string "V4SF")
3816 (and (match_test "TARGET_AVX512F")
3817 (not (match_test "TARGET_PREFER_AVX256")))
3818 (const_string "V16SF")
3819 (match_test "TARGET_AVX")
3820 (const_string "V4SF")
3821 (match_test "optimize_function_for_size_p (cfun)")
3822 (const_string "V4SF")
3823 (match_test "TARGET_SSE_LOAD0_BY_PXOR")
3826 (const_string "V4SF"))
3828 /* For architectures resolving dependencies on
3829 whole SSE registers use APS move to break dependency
3830 chains, otherwise use short move to avoid extra work.
3832 Do the same for architectures resolving dependencies on
3833 the parts. While in DF mode it is better to always handle
3834 just register parts, the SF mode is different due to lack
3835 of instructions to load just part of the register. It is
3836 better to maintain the whole registers in single format
3837 to avoid problems on using packed logical operations. */
3838 (eq_attr "alternative" "6")
3839 (cond [(and (ior (not (match_test "TARGET_PREFER_AVX256"))
3840 (not (match_test "TARGET_AVX512VL")))
3841 (ior (match_operand 0 "ext_sse_reg_operand")
3842 (match_operand 1 "ext_sse_reg_operand")))
3843 (const_string "V16SF")
3844 (ior (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3845 (match_test "TARGET_SSE_SPLIT_REGS"))
3846 (const_string "V4SF")
3848 (const_string "SF"))
3850 (const_string "SF")))
3851 (set (attr "preferred_for_speed")
3852 (cond [(eq_attr "alternative" "9,14")
3853 (symbol_ref "TARGET_INTER_UNIT_MOVES_FROM_VEC")
3854 (eq_attr "alternative" "10,15")
3855 (symbol_ref "TARGET_INTER_UNIT_MOVES_TO_VEC")
3857 (symbol_ref "true")))
3858 (set (attr "enabled")
3859 (cond [(eq_attr "alternative" "16,17")
3861 (match_test "TARGET_HARD_SF_REGS")
3862 (symbol_ref "false")
3864 (not (match_test "TARGET_HARD_SF_REGS"))
3865 (symbol_ref "false")
3867 (const_string "*")))])
3870 [(set (match_operand 0 "any_fp_register_operand")
3871 (match_operand 1 "nonimmediate_operand"))]
3873 && (GET_MODE (operands[0]) == TFmode
3874 || GET_MODE (operands[0]) == XFmode
3875 || GET_MODE (operands[0]) == DFmode
3876 || GET_MODE (operands[0]) == SFmode)
3877 && ix86_standard_x87sse_constant_load_p (insn, operands[0])"
3878 [(set (match_dup 0) (match_dup 2))]
3879 "operands[2] = find_constant_src (curr_insn);")
3882 [(set (match_operand 0 "any_fp_register_operand")
3883 (float_extend (match_operand 1 "nonimmediate_operand")))]
3885 && (GET_MODE (operands[0]) == TFmode
3886 || GET_MODE (operands[0]) == XFmode
3887 || GET_MODE (operands[0]) == DFmode)
3888 && ix86_standard_x87sse_constant_load_p (insn, operands[0])"
3889 [(set (match_dup 0) (match_dup 2))]
3890 "operands[2] = find_constant_src (curr_insn);")
3892 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
3894 [(set (match_operand:X87MODEF 0 "fp_register_operand")
3895 (match_operand:X87MODEF 1 "immediate_operand"))]
3897 && (standard_80387_constant_p (operands[1]) == 8
3898 || standard_80387_constant_p (operands[1]) == 9)"
3899 [(set (match_dup 0)(match_dup 1))
3901 (neg:X87MODEF (match_dup 0)))]
3903 if (real_isnegzero (CONST_DOUBLE_REAL_VALUE (operands[1])))
3904 operands[1] = CONST0_RTX (<MODE>mode);
3906 operands[1] = CONST1_RTX (<MODE>mode);
3909 (define_insn "swapxf"
3910 [(set (match_operand:XF 0 "register_operand" "+f")
3911 (match_operand:XF 1 "register_operand" "+f"))
3916 if (STACK_TOP_P (operands[0]))
3921 [(set_attr "type" "fxch")
3922 (set_attr "mode" "XF")])
3924 (define_insn "*swap<mode>"
3925 [(set (match_operand:MODEF 0 "fp_register_operand" "+f")
3926 (match_operand:MODEF 1 "fp_register_operand" "+f"))
3929 "TARGET_80387 || reload_completed"
3931 if (STACK_TOP_P (operands[0]))
3936 [(set_attr "type" "fxch")
3937 (set_attr "mode" "<MODE>")])
3939 ;; Zero extension instructions
3941 (define_expand "zero_extendsidi2"
3942 [(set (match_operand:DI 0 "nonimmediate_operand")
3943 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand")))])
3945 (define_insn "*zero_extendsidi2"
3946 [(set (match_operand:DI 0 "nonimmediate_operand"
3947 "=r,?r,?o,r ,o,?*y,?!*y,$r,$v,$x,*x,*v,*r")
3949 (match_operand:SI 1 "x86_64_zext_operand"
3950 "0 ,rm,r ,rmWz,0,r ,m ,v ,r ,m ,*x,*v,*k")))]
3953 switch (get_attr_type (insn))
3956 if (ix86_use_lea_for_mov (insn, operands))
3957 return "lea{l}\t{%E1, %k0|%k0, %E1}";
3959 return "mov{l}\t{%1, %k0|%k0, %1}";
3965 return "movd\t{%1, %0|%0, %1}";
3968 if (SSE_REG_P (operands[0]) && SSE_REG_P (operands[1]))
3970 if (EXT_REX_SSE_REG_P (operands[0])
3971 || EXT_REX_SSE_REG_P (operands[1]))
3972 return "vpmovzxdq\t{%t1, %g0|%g0, %t1}";
3974 return "%vpmovzxdq\t{%1, %0|%0, %1}";
3977 if (GENERAL_REG_P (operands[0]))
3978 return "%vmovd\t{%1, %k0|%k0, %1}";
3980 return "%vmovd\t{%1, %0|%0, %1}";
3983 return "kmovd\t{%1, %k0|%k0, %1}";
3990 (cond [(eq_attr "alternative" "0,1,2")
3991 (const_string "nox64")
3992 (eq_attr "alternative" "3")
3993 (const_string "x64")
3994 (eq_attr "alternative" "7,8,9")
3995 (const_string "sse2")
3996 (eq_attr "alternative" "10")
3997 (const_string "sse4")
3998 (eq_attr "alternative" "11")
3999 (const_string "avx512f")
4000 (eq_attr "alternative" "12")
4001 (const_string "x64_avx512bw")
4003 (const_string "*")))
4005 (cond [(eq_attr "alternative" "0,1,2,4")
4006 (const_string "multi")
4007 (eq_attr "alternative" "5,6")
4008 (const_string "mmxmov")
4009 (eq_attr "alternative" "7")
4010 (if_then_else (match_test "TARGET_64BIT")
4011 (const_string "ssemov")
4012 (const_string "multi"))
4013 (eq_attr "alternative" "8,9,10,11")
4014 (const_string "ssemov")
4015 (eq_attr "alternative" "12")
4016 (const_string "mskmov")
4018 (const_string "imovx")))
4019 (set (attr "prefix_extra")
4020 (if_then_else (eq_attr "alternative" "10,11")
4022 (const_string "*")))
4023 (set (attr "prefix")
4024 (if_then_else (eq_attr "type" "ssemov")
4025 (const_string "maybe_vex")
4026 (const_string "orig")))
4027 (set (attr "prefix_0f")
4028 (if_then_else (eq_attr "type" "imovx")
4030 (const_string "*")))
4032 (cond [(eq_attr "alternative" "5,6")
4034 (and (eq_attr "alternative" "7")
4035 (match_test "TARGET_64BIT"))
4037 (eq_attr "alternative" "8,10,11")
4040 (const_string "SI")))
4041 (set (attr "preferred_for_speed")
4042 (cond [(eq_attr "alternative" "7")
4043 (symbol_ref "TARGET_INTER_UNIT_MOVES_FROM_VEC")
4044 (eq_attr "alternative" "5,8")
4045 (symbol_ref "TARGET_INTER_UNIT_MOVES_TO_VEC")
4047 (symbol_ref "true")))])
4050 [(set (match_operand:DI 0 "memory_operand")
4051 (zero_extend:DI (match_operand:SI 1 "memory_operand")))]
4053 [(set (match_dup 4) (const_int 0))]
4054 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
4057 [(set (match_operand:DI 0 "general_reg_operand")
4058 (zero_extend:DI (match_operand:SI 1 "general_reg_operand")))]
4059 "!TARGET_64BIT && reload_completed
4060 && REGNO (operands[0]) == REGNO (operands[1])"
4061 [(set (match_dup 4) (const_int 0))]
4062 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
4065 [(set (match_operand:DI 0 "nonimmediate_gr_operand")
4066 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand")))]
4067 "!TARGET_64BIT && reload_completed
4068 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
4069 [(set (match_dup 3) (match_dup 1))
4070 (set (match_dup 4) (const_int 0))]
4071 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
4073 (define_mode_attr kmov_isa
4074 [(QI "avx512dq") (HI "avx512f") (SI "avx512bw") (DI "avx512bw")])
4076 (define_insn "zero_extend<mode>di2"
4077 [(set (match_operand:DI 0 "register_operand" "=r,*r")
4079 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m,*k")))]
4082 movz{<imodesuffix>l|x}\t{%1, %k0|%k0, %1}
4083 kmov<mskmodesuffix>\t{%1, %k0|%k0, %1}"
4084 [(set_attr "isa" "*,<kmov_isa>")
4085 (set_attr "type" "imovx,mskmov")
4086 (set_attr "mode" "SI,<MODE>")])
4088 (define_expand "zero_extend<mode>si2"
4089 [(set (match_operand:SI 0 "register_operand")
4090 (zero_extend:SI (match_operand:SWI12 1 "nonimmediate_operand")))]
4093 if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
4095 operands[1] = force_reg (<MODE>mode, operands[1]);
4096 emit_insn (gen_zero_extend<mode>si2_and (operands[0], operands[1]));
4101 (define_insn_and_split "zero_extend<mode>si2_and"
4102 [(set (match_operand:SI 0 "register_operand" "=r,?&<r>")
4104 (match_operand:SWI12 1 "nonimmediate_operand" "0,<r>m")))
4105 (clobber (reg:CC FLAGS_REG))]
4106 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
4108 "&& reload_completed"
4109 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (match_dup 2)))
4110 (clobber (reg:CC FLAGS_REG))])]
4112 if (!REG_P (operands[1])
4113 || REGNO (operands[0]) != REGNO (operands[1]))
4115 ix86_expand_clear (operands[0]);
4117 gcc_assert (!TARGET_PARTIAL_REG_STALL);
4118 emit_insn (gen_movstrict<mode>
4119 (gen_lowpart (<MODE>mode, operands[0]), operands[1]));
4123 operands[2] = GEN_INT (GET_MODE_MASK (<MODE>mode));
4125 [(set_attr "type" "alu1")
4126 (set_attr "mode" "SI")])
4128 (define_insn "*zero_extend<mode>si2"
4129 [(set (match_operand:SI 0 "register_operand" "=r,*r")
4131 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m,*k")))]
4132 "!(TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))"
4134 movz{<imodesuffix>l|x}\t{%1, %0|%0, %1}
4135 kmov<mskmodesuffix>\t{%1, %0|%0, %1}"
4136 [(set_attr "isa" "*,<kmov_isa>")
4137 (set_attr "type" "imovx,mskmov")
4138 (set_attr "mode" "SI,<MODE>")])
4140 (define_expand "zero_extendqihi2"
4141 [(set (match_operand:HI 0 "register_operand")
4142 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand")))]
4145 if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
4147 operands[1] = force_reg (QImode, operands[1]);
4148 emit_insn (gen_zero_extendqihi2_and (operands[0], operands[1]));
4153 (define_insn_and_split "zero_extendqihi2_and"
4154 [(set (match_operand:HI 0 "register_operand" "=r,?&q")
4155 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
4156 (clobber (reg:CC FLAGS_REG))]
4157 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
4159 "&& reload_completed"
4160 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
4161 (clobber (reg:CC FLAGS_REG))])]
4163 if (!REG_P (operands[1])
4164 || REGNO (operands[0]) != REGNO (operands[1]))
4166 ix86_expand_clear (operands[0]);
4168 gcc_assert (!TARGET_PARTIAL_REG_STALL);
4169 emit_insn (gen_movstrictqi
4170 (gen_lowpart (QImode, operands[0]), operands[1]));
4174 operands[0] = gen_lowpart (SImode, operands[0]);
4176 [(set_attr "type" "alu1")
4177 (set_attr "mode" "SI")])
4179 ; zero extend to SImode to avoid partial register stalls
4180 (define_insn "*zero_extendqihi2"
4181 [(set (match_operand:HI 0 "register_operand" "=r,*r")
4182 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,*k")))]
4183 "!(TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))"
4185 movz{bl|x}\t{%1, %k0|%k0, %1}
4186 kmovb\t{%1, %k0|%k0, %1}"
4187 [(set_attr "isa" "*,avx512dq")
4188 (set_attr "type" "imovx,mskmov")
4189 (set_attr "mode" "SI,QI")])
4191 (define_insn_and_split "*zext<mode>_doubleword_and"
4192 [(set (match_operand:DI 0 "register_operand" "=&<r>")
4193 (zero_extend:DI (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
4194 "!TARGET_64BIT && TARGET_STV && TARGET_SSE2
4195 && TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
4197 "&& reload_completed && GENERAL_REG_P (operands[0])"
4198 [(set (match_dup 2) (const_int 0))]
4200 split_double_mode (DImode, &operands[0], 1, &operands[0], &operands[2]);
4202 emit_move_insn (operands[0], const0_rtx);
4204 gcc_assert (!TARGET_PARTIAL_REG_STALL);
4205 emit_insn (gen_movstrict<mode>
4206 (gen_lowpart (<MODE>mode, operands[0]), operands[1]));
4209 (define_insn_and_split "*zext<mode>_doubleword"
4210 [(set (match_operand:DI 0 "register_operand" "=r")
4211 (zero_extend:DI (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
4212 "!TARGET_64BIT && TARGET_STV && TARGET_SSE2
4213 && !(TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))"
4215 "&& reload_completed && GENERAL_REG_P (operands[0])"
4216 [(set (match_dup 0) (zero_extend:SI (match_dup 1)))
4217 (set (match_dup 2) (const_int 0))]
4218 "split_double_mode (DImode, &operands[0], 1, &operands[0], &operands[2]);")
4220 (define_insn_and_split "*zextsi_doubleword"
4221 [(set (match_operand:DI 0 "register_operand" "=r")
4222 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm")))]
4223 "!TARGET_64BIT && TARGET_STV && TARGET_SSE2"
4225 "&& reload_completed && GENERAL_REG_P (operands[0])"
4226 [(set (match_dup 0) (match_dup 1))
4227 (set (match_dup 2) (const_int 0))]
4228 "split_double_mode (DImode, &operands[0], 1, &operands[0], &operands[2]);")
4230 ;; Sign extension instructions
4232 (define_expand "extendsidi2"
4233 [(set (match_operand:DI 0 "register_operand")
4234 (sign_extend:DI (match_operand:SI 1 "register_operand")))]
4239 emit_insn (gen_extendsidi2_1 (operands[0], operands[1]));
4244 (define_insn "*extendsidi2_rex64"
4245 [(set (match_operand:DI 0 "register_operand" "=*a,r")
4246 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
4250 movs{lq|x}\t{%1, %0|%0, %1}"
4251 [(set_attr "type" "imovx")
4252 (set_attr "mode" "DI")
4253 (set_attr "prefix_0f" "0")
4254 (set_attr "modrm" "0,1")])
4256 (define_insn "extendsidi2_1"
4257 [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
4258 (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
4259 (clobber (reg:CC FLAGS_REG))
4260 (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
4264 ;; Split the memory case. If the source register doesn't die, it will stay
4265 ;; this way, if it does die, following peephole2s take care of it.
4267 [(set (match_operand:DI 0 "memory_operand")
4268 (sign_extend:DI (match_operand:SI 1 "register_operand")))
4269 (clobber (reg:CC FLAGS_REG))
4270 (clobber (match_operand:SI 2 "register_operand"))]
4274 split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
4276 emit_move_insn (operands[3], operands[1]);
4278 /* Generate a cltd if possible and doing so it profitable. */
4279 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
4280 && REGNO (operands[1]) == AX_REG
4281 && REGNO (operands[2]) == DX_REG)
4283 emit_insn (gen_ashrsi3_cvt (operands[2], operands[1], GEN_INT (31)));
4287 emit_move_insn (operands[2], operands[1]);
4288 emit_insn (gen_ashrsi3_cvt (operands[2], operands[2], GEN_INT (31)));
4290 emit_move_insn (operands[4], operands[2]);
4294 ;; Peepholes for the case where the source register does die, after
4295 ;; being split with the above splitter.
4297 [(set (match_operand:SI 0 "memory_operand")
4298 (match_operand:SI 1 "general_reg_operand"))
4299 (set (match_operand:SI 2 "general_reg_operand") (match_dup 1))
4300 (parallel [(set (match_dup 2)
4301 (ashiftrt:SI (match_dup 2) (const_int 31)))
4302 (clobber (reg:CC FLAGS_REG))])
4303 (set (match_operand:SI 3 "memory_operand") (match_dup 2))]
4304 "REGNO (operands[1]) != REGNO (operands[2])
4305 && peep2_reg_dead_p (2, operands[1])
4306 && peep2_reg_dead_p (4, operands[2])
4307 && !reg_mentioned_p (operands[2], operands[3])"
4308 [(set (match_dup 0) (match_dup 1))
4309 (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
4310 (clobber (reg:CC FLAGS_REG))])
4311 (set (match_dup 3) (match_dup 1))])
4314 [(set (match_operand:SI 0 "memory_operand")
4315 (match_operand:SI 1 "general_reg_operand"))
4316 (parallel [(set (match_operand:SI 2 "general_reg_operand")
4317 (ashiftrt:SI (match_dup 1) (const_int 31)))
4318 (clobber (reg:CC FLAGS_REG))])
4319 (set (match_operand:SI 3 "memory_operand") (match_dup 2))]
4320 "/* cltd is shorter than sarl $31, %eax */
4321 !optimize_function_for_size_p (cfun)
4322 && REGNO (operands[1]) == AX_REG
4323 && REGNO (operands[2]) == DX_REG
4324 && peep2_reg_dead_p (2, operands[1])
4325 && peep2_reg_dead_p (3, operands[2])
4326 && !reg_mentioned_p (operands[2], operands[3])"
4327 [(set (match_dup 0) (match_dup 1))
4328 (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
4329 (clobber (reg:CC FLAGS_REG))])
4330 (set (match_dup 3) (match_dup 1))])
4332 ;; Extend to register case. Optimize case where source and destination
4333 ;; registers match and cases where we can use cltd.
4335 [(set (match_operand:DI 0 "register_operand")
4336 (sign_extend:DI (match_operand:SI 1 "register_operand")))
4337 (clobber (reg:CC FLAGS_REG))
4338 (clobber (match_scratch:SI 2))]
4342 split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
4344 if (REGNO (operands[3]) != REGNO (operands[1]))
4345 emit_move_insn (operands[3], operands[1]);
4347 /* Generate a cltd if possible and doing so it profitable. */
4348 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
4349 && REGNO (operands[3]) == AX_REG
4350 && REGNO (operands[4]) == DX_REG)
4352 emit_insn (gen_ashrsi3_cvt (operands[4], operands[3], GEN_INT (31)));
4356 if (REGNO (operands[4]) != REGNO (operands[1]))
4357 emit_move_insn (operands[4], operands[1]);
4359 emit_insn (gen_ashrsi3_cvt (operands[4], operands[4], GEN_INT (31)));
4363 (define_insn "extend<mode>di2"
4364 [(set (match_operand:DI 0 "register_operand" "=r")
4366 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
4368 "movs{<imodesuffix>q|x}\t{%1, %0|%0, %1}"
4369 [(set_attr "type" "imovx")
4370 (set_attr "mode" "DI")])
4372 (define_insn "extendhisi2"
4373 [(set (match_operand:SI 0 "register_operand" "=*a,r")
4374 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
4377 switch (get_attr_prefix_0f (insn))
4380 return "{cwtl|cwde}";
4382 return "movs{wl|x}\t{%1, %0|%0, %1}";
4385 [(set_attr "type" "imovx")
4386 (set_attr "mode" "SI")
4387 (set (attr "prefix_0f")
4388 ;; movsx is short decodable while cwtl is vector decoded.
4389 (if_then_else (and (eq_attr "cpu" "!k6")
4390 (eq_attr "alternative" "0"))
4392 (const_string "1")))
4393 (set (attr "znver1_decode")
4394 (if_then_else (eq_attr "prefix_0f" "0")
4395 (const_string "double")
4396 (const_string "direct")))
4398 (if_then_else (eq_attr "prefix_0f" "0")
4400 (const_string "1")))])
4402 (define_insn "*extendhisi2_zext"
4403 [(set (match_operand:DI 0 "register_operand" "=*a,r")
4406 (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
4409 switch (get_attr_prefix_0f (insn))
4412 return "{cwtl|cwde}";
4414 return "movs{wl|x}\t{%1, %k0|%k0, %1}";
4417 [(set_attr "type" "imovx")
4418 (set_attr "mode" "SI")
4419 (set (attr "prefix_0f")
4420 ;; movsx is short decodable while cwtl is vector decoded.
4421 (if_then_else (and (eq_attr "cpu" "!k6")
4422 (eq_attr "alternative" "0"))
4424 (const_string "1")))
4426 (if_then_else (eq_attr "prefix_0f" "0")
4428 (const_string "1")))])
4430 (define_insn "extendqisi2"
4431 [(set (match_operand:SI 0 "register_operand" "=r")
4432 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
4434 "movs{bl|x}\t{%1, %0|%0, %1}"
4435 [(set_attr "type" "imovx")
4436 (set_attr "mode" "SI")])
4438 (define_insn "*extendqisi2_zext"
4439 [(set (match_operand:DI 0 "register_operand" "=r")
4441 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
4443 "movs{bl|x}\t{%1, %k0|%k0, %1}"
4444 [(set_attr "type" "imovx")
4445 (set_attr "mode" "SI")])
4447 (define_insn "extendqihi2"
4448 [(set (match_operand:HI 0 "register_operand" "=*a,r")
4449 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
4452 switch (get_attr_prefix_0f (insn))
4455 return "{cbtw|cbw}";
4457 return "movs{bw|x}\t{%1, %0|%0, %1}";
4460 [(set_attr "type" "imovx")
4461 (set_attr "mode" "HI")
4462 (set (attr "prefix_0f")
4463 ;; movsx is short decodable while cwtl is vector decoded.
4464 (if_then_else (and (eq_attr "cpu" "!k6")
4465 (eq_attr "alternative" "0"))
4467 (const_string "1")))
4469 (if_then_else (eq_attr "prefix_0f" "0")
4471 (const_string "1")))])
4473 ;; Conversions between float and double.
4475 ;; These are all no-ops in the model used for the 80387.
4476 ;; So just emit moves.
4478 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
4480 [(set (match_operand:DF 0 "push_operand")
4481 (float_extend:DF (match_operand:SF 1 "fp_register_operand")))]
4483 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
4484 (set (mem:DF (reg:P SP_REG)) (float_extend:DF (match_dup 1)))])
4487 [(set (match_operand:XF 0 "push_operand")
4488 (float_extend:XF (match_operand:MODEF 1 "fp_register_operand")))]
4490 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
4491 (set (mem:XF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
4492 "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
4494 (define_expand "extendsfdf2"
4495 [(set (match_operand:DF 0 "nonimm_ssenomem_operand")
4496 (float_extend:DF (match_operand:SF 1 "general_operand")))]
4497 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4499 /* ??? Needed for compress_float_constant since all fp constants
4500 are TARGET_LEGITIMATE_CONSTANT_P. */
4501 if (CONST_DOUBLE_P (operands[1]))
4503 if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
4504 && standard_80387_constant_p (operands[1]) > 0)
4506 operands[1] = simplify_const_unary_operation
4507 (FLOAT_EXTEND, DFmode, operands[1], SFmode);
4508 emit_move_insn_1 (operands[0], operands[1]);
4511 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
4515 /* For converting SF(xmm2) to DF(xmm1), use the following code instead of
4517 unpcklps xmm2,xmm2 ; packed conversion might crash on signaling NaNs
4519 We do the conversion post reload to avoid producing of 128bit spills
4520 that might lead to ICE on 32bit target. The sequence unlikely combine
4523 [(set (match_operand:DF 0 "sse_reg_operand")
4525 (match_operand:SF 1 "nonimmediate_operand")))]
4526 "TARGET_USE_VECTOR_FP_CONVERTS
4527 && optimize_insn_for_speed_p ()
4529 && (!EXT_REX_SSE_REG_P (operands[0])
4530 || TARGET_AVX512VL)"
4535 (parallel [(const_int 0) (const_int 1)]))))]
4537 operands[2] = lowpart_subreg (V2DFmode, operands[0], DFmode);
4538 operands[3] = lowpart_subreg (V4SFmode, operands[0], DFmode);
4539 /* Use movss for loading from memory, unpcklps reg, reg for registers.
4540 Try to avoid move when unpacking can be done in source. */
4541 if (REG_P (operands[1]))
4543 /* If it is unsafe to overwrite upper half of source, we need
4544 to move to destination and unpack there. */
4545 if (REGNO (operands[0]) != REGNO (operands[1])
4546 || (EXT_REX_SSE_REG_P (operands[1])
4547 && !TARGET_AVX512VL))
4549 rtx tmp = lowpart_subreg (SFmode, operands[0], DFmode);
4550 emit_move_insn (tmp, operands[1]);
4553 operands[3] = lowpart_subreg (V4SFmode, operands[1], SFmode);
4554 /* FIXME: vec_interleave_lowv4sf for AVX512VL should allow
4555 =v, v, then vbroadcastss will be only needed for AVX512F without
4557 if (!EXT_REX_SSE_REGNO_P (REGNO (operands[3])))
4558 emit_insn (gen_vec_interleave_lowv4sf (operands[3], operands[3],
4562 rtx tmp = lowpart_subreg (V16SFmode, operands[3], V4SFmode);
4563 emit_insn (gen_avx512f_vec_dupv16sf_1 (tmp, tmp));
4567 emit_insn (gen_vec_setv4sf_0 (operands[3],
4568 CONST0_RTX (V4SFmode), operands[1]));
4571 ;; It's more profitable to split and then extend in the same register.
4573 [(set (match_operand:DF 0 "sse_reg_operand")
4575 (match_operand:SF 1 "memory_operand")))]
4576 "TARGET_SPLIT_MEM_OPND_FOR_FP_CONVERTS
4577 && optimize_insn_for_speed_p ()"
4578 [(set (match_dup 2) (match_dup 1))
4579 (set (match_dup 0) (float_extend:DF (match_dup 2)))]
4580 "operands[2] = lowpart_subreg (SFmode, operands[0], DFmode);")
4582 (define_insn "*extendsfdf2"
4583 [(set (match_operand:DF 0 "nonimm_ssenomem_operand" "=f,m,v")
4585 (match_operand:SF 1 "nonimmediate_operand" "fm,f,vm")))]
4586 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4588 switch (which_alternative)
4592 return output_387_reg_move (insn, operands);
4595 return "%vcvtss2sd\t{%1, %d0|%d0, %1}";
4601 [(set_attr "type" "fmov,fmov,ssecvt")
4602 (set_attr "prefix" "orig,orig,maybe_vex")
4603 (set_attr "mode" "SF,XF,DF")
4604 (set (attr "enabled")
4606 (match_test ("TARGET_SSE2 && TARGET_SSE_MATH"))
4608 (eq_attr "alternative" "0,1")
4609 (symbol_ref "TARGET_MIX_SSE_I387")
4610 (symbol_ref "true"))
4612 (eq_attr "alternative" "0,1")
4614 (symbol_ref "false"))))])
4616 (define_expand "extend<mode>xf2"
4617 [(set (match_operand:XF 0 "nonimmediate_operand")
4618 (float_extend:XF (match_operand:MODEF 1 "general_operand")))]
4621 /* ??? Needed for compress_float_constant since all fp constants
4622 are TARGET_LEGITIMATE_CONSTANT_P. */
4623 if (CONST_DOUBLE_P (operands[1]))
4625 if (standard_80387_constant_p (operands[1]) > 0)
4627 operands[1] = simplify_const_unary_operation
4628 (FLOAT_EXTEND, XFmode, operands[1], <MODE>mode);
4629 emit_move_insn_1 (operands[0], operands[1]);
4632 operands[1] = validize_mem (force_const_mem (<MODE>mode, operands[1]));
4636 (define_insn "*extend<mode>xf2_i387"
4637 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
4639 (match_operand:MODEF 1 "nonimmediate_operand" "fm,f")))]
4641 "* return output_387_reg_move (insn, operands);"
4642 [(set_attr "type" "fmov")
4643 (set_attr "mode" "<MODE>,XF")])
4645 ;; %%% This seems like bad news.
4646 ;; This cannot output into an f-reg because there is no way to be sure
4647 ;; of truncating in that case. Otherwise this is just like a simple move
4648 ;; insn. So we pretend we can output to a reg in order to get better
4649 ;; register preferencing, but we really use a stack slot.
4651 ;; Conversion from DFmode to SFmode.
4653 (define_expand "truncdfsf2"
4654 [(set (match_operand:SF 0 "nonimmediate_operand")
4656 (match_operand:DF 1 "nonimmediate_operand")))]
4657 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4659 if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
4661 else if (flag_unsafe_math_optimizations)
4665 rtx temp = assign_386_stack_local (SFmode, SLOT_TEMP);
4666 emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
4671 /* For converting DF(xmm2) to SF(xmm1), use the following code instead of
4673 unpcklpd xmm2,xmm2 ; packed conversion might crash on signaling NaNs
4675 We do the conversion post reload to avoid producing of 128bit spills
4676 that might lead to ICE on 32bit target. The sequence unlikely combine
4679 [(set (match_operand:SF 0 "sse_reg_operand")
4681 (match_operand:DF 1 "nonimmediate_operand")))]
4682 "TARGET_USE_VECTOR_FP_CONVERTS
4683 && optimize_insn_for_speed_p ()
4685 && (!EXT_REX_SSE_REG_P (operands[0])
4686 || TARGET_AVX512VL)"
4689 (float_truncate:V2SF
4693 operands[2] = lowpart_subreg (V4SFmode, operands[0], SFmode);
4694 operands[3] = CONST0_RTX (V2SFmode);
4695 operands[4] = lowpart_subreg (V2DFmode, operands[0], SFmode);
4696 /* Use movsd for loading from memory, unpcklpd for registers.
4697 Try to avoid move when unpacking can be done in source, or SSE3
4698 movddup is available. */
4699 if (REG_P (operands[1]))
4702 && REGNO (operands[0]) != REGNO (operands[1]))
4704 rtx tmp = lowpart_subreg (DFmode, operands[0], SFmode);
4705 emit_move_insn (tmp, operands[1]);
4708 else if (!TARGET_SSE3)
4709 operands[4] = lowpart_subreg (V2DFmode, operands[1], DFmode);
4710 emit_insn (gen_vec_dupv2df (operands[4], operands[1]));
4713 emit_insn (gen_vec_concatv2df (operands[4], operands[1],
4714 CONST0_RTX (DFmode)));
4717 ;; It's more profitable to split and then extend in the same register.
4719 [(set (match_operand:SF 0 "sse_reg_operand")
4721 (match_operand:DF 1 "memory_operand")))]
4722 "TARGET_SPLIT_MEM_OPND_FOR_FP_CONVERTS
4723 && optimize_insn_for_speed_p ()"
4724 [(set (match_dup 2) (match_dup 1))
4725 (set (match_dup 0) (float_truncate:SF (match_dup 2)))]
4726 "operands[2] = lowpart_subreg (DFmode, operands[0], SFmode);")
4728 (define_expand "truncdfsf2_with_temp"
4729 [(parallel [(set (match_operand:SF 0)
4730 (float_truncate:SF (match_operand:DF 1)))
4731 (clobber (match_operand:SF 2))])])
4733 ;; SSE alternative doesn't depend on flag_unsafe_math_optimizations,
4734 ;; because nothing we do there is unsafe.
4735 (define_insn "*truncdfsf_fast_mixed"
4736 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm,v")
4738 (match_operand:DF 1 "nonimmediate_operand" "f ,vm")))]
4739 "TARGET_SSE2 && TARGET_SSE_MATH"
4741 switch (which_alternative)
4744 return output_387_reg_move (insn, operands);
4746 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4751 [(set_attr "type" "fmov,ssecvt")
4752 (set_attr "prefix" "orig,maybe_vex")
4753 (set_attr "mode" "SF")
4754 (set (attr "enabled")
4755 (cond [(eq_attr "alternative" "0")
4756 (symbol_ref "TARGET_MIX_SSE_I387
4757 && flag_unsafe_math_optimizations")
4759 (symbol_ref "true")))])
4761 (define_insn "*truncdfsf_fast_i387"
4762 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm")
4764 (match_operand:DF 1 "nonimmediate_operand" "f")))]
4765 "TARGET_80387 && flag_unsafe_math_optimizations"
4766 "* return output_387_reg_move (insn, operands);"
4767 [(set_attr "type" "fmov")
4768 (set_attr "mode" "SF")])
4770 (define_insn "*truncdfsf_mixed"
4771 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,v ,?f,?v,?*r")
4773 (match_operand:DF 1 "nonimmediate_operand" "f ,vm,f ,f ,f")))
4774 (clobber (match_operand:SF 2 "memory_operand" "=X,X ,m ,m ,m"))]
4775 "TARGET_MIX_SSE_I387"
4777 switch (which_alternative)
4780 return output_387_reg_move (insn, operands);
4782 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4788 [(set_attr "isa" "*,sse2,*,*,*")
4789 (set_attr "type" "fmov,ssecvt,multi,multi,multi")
4790 (set_attr "unit" "*,*,i387,i387,i387")
4791 (set_attr "prefix" "orig,maybe_vex,orig,orig,orig")
4792 (set_attr "mode" "SF")])
4794 (define_insn "*truncdfsf_i387"
4795 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?v,?*r")
4797 (match_operand:DF 1 "nonimmediate_operand" "f ,f ,f ,f")))
4798 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,m ,m"))]
4801 switch (which_alternative)
4804 return output_387_reg_move (insn, operands);
4810 [(set_attr "type" "fmov,multi,multi,multi")
4811 (set_attr "unit" "*,i387,i387,i387")
4812 (set_attr "mode" "SF")])
4814 (define_insn "*truncdfsf2_i387_1"
4815 [(set (match_operand:SF 0 "memory_operand" "=m")
4817 (match_operand:DF 1 "register_operand" "f")))]
4819 && !(TARGET_SSE2 && TARGET_SSE_MATH)
4820 && !TARGET_MIX_SSE_I387"
4821 "* return output_387_reg_move (insn, operands);"
4822 [(set_attr "type" "fmov")
4823 (set_attr "mode" "SF")])
4826 [(set (match_operand:SF 0 "register_operand")
4828 (match_operand:DF 1 "fp_register_operand")))
4829 (clobber (match_operand 2))]
4831 [(set (match_dup 2) (match_dup 1))
4832 (set (match_dup 0) (match_dup 2))]
4833 "operands[1] = gen_rtx_REG (SFmode, REGNO (operands[1]));")
4835 ;; Conversion from XFmode to {SF,DF}mode
4837 (define_expand "truncxf<mode>2"
4838 [(parallel [(set (match_operand:MODEF 0 "nonimmediate_operand")
4839 (float_truncate:MODEF
4840 (match_operand:XF 1 "register_operand")))
4841 (clobber (match_dup 2))])]
4844 if (flag_unsafe_math_optimizations)
4846 rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (<MODE>mode);
4847 emit_insn (gen_truncxf<mode>2_i387_noop (reg, operands[1]));
4848 if (reg != operands[0])
4849 emit_move_insn (operands[0], reg);
4853 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4856 (define_insn "*truncxfsf2_mixed"
4857 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?v,?*r")
4859 (match_operand:XF 1 "register_operand" "f ,f ,f ,f")))
4860 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,m ,m"))]
4863 gcc_assert (!which_alternative);
4864 return output_387_reg_move (insn, operands);
4866 [(set_attr "type" "fmov,multi,multi,multi")
4867 (set_attr "unit" "*,i387,i387,i387")
4868 (set_attr "mode" "SF")])
4870 (define_insn "*truncxfdf2_mixed"
4871 [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?v,?*r")
4873 (match_operand:XF 1 "register_operand" "f ,f ,f ,f")))
4874 (clobber (match_operand:DF 2 "memory_operand" "=X,m ,m ,m"))]
4877 gcc_assert (!which_alternative);
4878 return output_387_reg_move (insn, operands);
4880 [(set_attr "isa" "*,*,sse2,*")
4881 (set_attr "type" "fmov,multi,multi,multi")
4882 (set_attr "unit" "*,i387,i387,i387")
4883 (set_attr "mode" "DF")])
4885 (define_insn "truncxf<mode>2_i387_noop"
4886 [(set (match_operand:MODEF 0 "register_operand" "=f")
4887 (float_truncate:MODEF
4888 (match_operand:XF 1 "register_operand" "f")))]
4889 "TARGET_80387 && flag_unsafe_math_optimizations"
4890 "* return output_387_reg_move (insn, operands);"
4891 [(set_attr "type" "fmov")
4892 (set_attr "mode" "<MODE>")])
4894 (define_insn "*truncxf<mode>2_i387"
4895 [(set (match_operand:MODEF 0 "memory_operand" "=m")
4896 (float_truncate:MODEF
4897 (match_operand:XF 1 "register_operand" "f")))]
4899 "* return output_387_reg_move (insn, operands);"
4900 [(set_attr "type" "fmov")
4901 (set_attr "mode" "<MODE>")])
4904 [(set (match_operand:MODEF 0 "register_operand")
4905 (float_truncate:MODEF
4906 (match_operand:XF 1 "register_operand")))
4907 (clobber (match_operand:MODEF 2 "memory_operand"))]
4908 "TARGET_80387 && reload_completed"
4909 [(set (match_dup 2) (float_truncate:MODEF (match_dup 1)))
4910 (set (match_dup 0) (match_dup 2))])
4913 [(set (match_operand:MODEF 0 "memory_operand")
4914 (float_truncate:MODEF
4915 (match_operand:XF 1 "register_operand")))
4916 (clobber (match_operand:MODEF 2 "memory_operand"))]
4918 [(set (match_dup 0) (float_truncate:MODEF (match_dup 1)))])
4920 ;; Signed conversion to DImode.
4922 (define_expand "fix_truncxfdi2"
4923 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand")
4924 (fix:DI (match_operand:XF 1 "register_operand")))
4925 (clobber (reg:CC FLAGS_REG))])]
4930 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4935 (define_expand "fix_trunc<mode>di2"
4936 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand")
4937 (fix:DI (match_operand:MODEF 1 "register_operand")))
4938 (clobber (reg:CC FLAGS_REG))])]
4939 "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4942 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4944 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4947 if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4949 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4950 emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4951 if (out != operands[0])
4952 emit_move_insn (operands[0], out);
4957 ;; Signed conversion to SImode.
4959 (define_expand "fix_truncxfsi2"
4960 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand")
4961 (fix:SI (match_operand:XF 1 "register_operand")))
4962 (clobber (reg:CC FLAGS_REG))])]
4967 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4972 (define_expand "fix_trunc<mode>si2"
4973 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand")
4974 (fix:SI (match_operand:MODEF 1 "register_operand")))
4975 (clobber (reg:CC FLAGS_REG))])]
4976 "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4979 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4981 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4984 if (SSE_FLOAT_MODE_P (<MODE>mode))
4986 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4987 emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4988 if (out != operands[0])
4989 emit_move_insn (operands[0], out);
4994 ;; Signed conversion to HImode.
4996 (define_expand "fix_trunc<mode>hi2"
4997 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand")
4998 (fix:HI (match_operand:X87MODEF 1 "register_operand")))
4999 (clobber (reg:CC FLAGS_REG))])]
5001 && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
5005 emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
5010 ;; Unsigned conversion to DImode
5012 (define_insn "fixuns_trunc<mode>di2"
5013 [(set (match_operand:DI 0 "register_operand" "=r")
5015 (match_operand:MODEF 1 "nonimmediate_operand" "vm")))]
5016 "TARGET_64BIT && TARGET_AVX512F && TARGET_SSE_MATH"
5017 "vcvtt<ssemodesuffix>2usi\t{%1, %0|%0, %1}"
5018 [(set_attr "type" "sseicvt")
5019 (set_attr "prefix" "evex")
5020 (set_attr "mode" "DI")])
5022 ;; Unsigned conversion to SImode.
5024 (define_expand "fixuns_trunc<mode>si2"
5026 [(set (match_operand:SI 0 "register_operand")
5028 (match_operand:MODEF 1 "nonimmediate_operand")))
5030 (clobber (match_scratch:<ssevecmode> 3))
5031 (clobber (match_scratch:<ssevecmode> 4))])]
5032 "(!TARGET_64BIT || TARGET_AVX512F) && TARGET_SSE2 && TARGET_SSE_MATH"
5034 machine_mode mode = <MODE>mode;
5035 machine_mode vecmode = <ssevecmode>mode;
5036 REAL_VALUE_TYPE TWO31r;
5041 emit_insn (gen_fixuns_trunc<mode>si2_avx512f (operands[0], operands[1]));
5045 if (optimize_insn_for_size_p ())
5048 real_ldexp (&TWO31r, &dconst1, 31);
5049 two31 = const_double_from_real_value (TWO31r, mode);
5050 two31 = ix86_build_const_vector (vecmode, true, two31);
5051 operands[2] = force_reg (vecmode, two31);
5054 (define_insn "fixuns_trunc<mode>si2_avx512f"
5055 [(set (match_operand:SI 0 "register_operand" "=r")
5057 (match_operand:MODEF 1 "nonimmediate_operand" "vm")))]
5058 "TARGET_AVX512F && TARGET_SSE_MATH"
5059 "vcvtt<ssemodesuffix>2usi\t{%1, %0|%0, %1}"
5060 [(set_attr "type" "sseicvt")
5061 (set_attr "prefix" "evex")
5062 (set_attr "mode" "SI")])
5064 (define_insn "*fixuns_trunc<mode>si2_avx512f_zext"
5065 [(set (match_operand:DI 0 "register_operand" "=r")
5068 (match_operand:MODEF 1 "nonimmediate_operand" "vm"))))]
5069 "TARGET_64BIT && TARGET_AVX512F"
5070 "vcvtt<ssemodesuffix>2usi\t{%1, %k0|%k0, %1}"
5071 [(set_attr "type" "sseicvt")
5072 (set_attr "prefix" "evex")
5073 (set_attr "mode" "SI")])
5075 (define_insn_and_split "*fixuns_trunc<mode>_1"
5076 [(set (match_operand:SI 0 "register_operand" "=&x,&x")
5078 (match_operand:MODEF 3 "nonimmediate_operand" "xm,xm")))
5079 (use (match_operand:<ssevecmode> 4 "nonimmediate_operand" "m,x"))
5080 (clobber (match_scratch:<ssevecmode> 1 "=x,&x"))
5081 (clobber (match_scratch:<ssevecmode> 2 "=x,x"))]
5082 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH
5083 && optimize_function_for_speed_p (cfun)"
5085 "&& reload_completed"
5088 ix86_split_convert_uns_si_sse (operands);
5092 ;; Unsigned conversion to HImode.
5093 ;; Without these patterns, we'll try the unsigned SI conversion which
5094 ;; is complex for SSE, rather than the signed SI conversion, which isn't.
5096 (define_expand "fixuns_trunc<mode>hi2"
5098 (fix:SI (match_operand:MODEF 1 "nonimmediate_operand")))
5099 (set (match_operand:HI 0 "nonimmediate_operand")
5100 (subreg:HI (match_dup 2) 0))]
5101 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
5102 "operands[2] = gen_reg_rtx (SImode);")
5104 ;; When SSE is available, it is always faster to use it!
5105 (define_insn "fix_trunc<MODEF:mode><SWI48:mode>_sse"
5106 [(set (match_operand:SWI48 0 "register_operand" "=r,r")
5107 (fix:SWI48 (match_operand:MODEF 1 "nonimmediate_operand" "v,m")))]
5108 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode)
5109 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
5110 "%vcvtt<MODEF:ssemodesuffix>2si<SWI48:rex64suffix>\t{%1, %0|%0, %1}"
5111 [(set_attr "type" "sseicvt")
5112 (set_attr "prefix" "maybe_vex")
5113 (set (attr "prefix_rex")
5115 (match_test "<SWI48:MODE>mode == DImode")
5117 (const_string "*")))
5118 (set_attr "mode" "<MODEF:MODE>")
5119 (set_attr "athlon_decode" "double,vector")
5120 (set_attr "amdfam10_decode" "double,double")
5121 (set_attr "bdver1_decode" "double,double")])
5123 ;; Avoid vector decoded forms of the instruction.
5125 [(match_scratch:MODEF 2 "x")
5126 (set (match_operand:SWI48 0 "register_operand")
5127 (fix:SWI48 (match_operand:MODEF 1 "memory_operand")))]
5128 "TARGET_AVOID_VECTOR_DECODE
5129 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode)
5130 && optimize_insn_for_speed_p ()"
5131 [(set (match_dup 2) (match_dup 1))
5132 (set (match_dup 0) (fix:SWI48 (match_dup 2)))])
5134 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
5135 [(set (match_operand:SWI248x 0 "nonimmediate_operand")
5136 (fix:SWI248x (match_operand 1 "register_operand")))]
5137 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5139 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
5140 && (TARGET_64BIT || <MODE>mode != DImode))
5142 && can_create_pseudo_p ()"
5147 if (memory_operand (operands[0], VOIDmode))
5148 emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
5151 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
5152 emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
5158 [(set_attr "type" "fisttp")
5159 (set_attr "mode" "<MODE>")])
5161 (define_insn "fix_trunc<mode>_i387_fisttp"
5162 [(set (match_operand:SWI248x 0 "memory_operand" "=m")
5163 (fix:SWI248x (match_operand 1 "register_operand" "f")))
5164 (clobber (match_scratch:XF 2 "=&1f"))]
5165 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5167 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
5168 && (TARGET_64BIT || <MODE>mode != DImode))
5169 && TARGET_SSE_MATH)"
5170 "* return output_fix_trunc (insn, operands, true);"
5171 [(set_attr "type" "fisttp")
5172 (set_attr "mode" "<MODE>")])
5174 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
5175 [(set (match_operand:SWI248x 0 "nonimmediate_operand" "=m,?r")
5176 (fix:SWI248x (match_operand 1 "register_operand" "f,f")))
5177 (clobber (match_operand:SWI248x 2 "memory_operand" "=X,m"))
5178 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
5179 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5181 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
5182 && (TARGET_64BIT || <MODE>mode != DImode))
5183 && TARGET_SSE_MATH)"
5185 [(set_attr "type" "fisttp")
5186 (set_attr "mode" "<MODE>")])
5189 [(set (match_operand:SWI248x 0 "register_operand")
5190 (fix:SWI248x (match_operand 1 "register_operand")))
5191 (clobber (match_operand:SWI248x 2 "memory_operand"))
5192 (clobber (match_scratch 3))]
5194 [(parallel [(set (match_dup 2) (fix:SWI248x (match_dup 1)))
5195 (clobber (match_dup 3))])
5196 (set (match_dup 0) (match_dup 2))])
5199 [(set (match_operand:SWI248x 0 "memory_operand")
5200 (fix:SWI248x (match_operand 1 "register_operand")))
5201 (clobber (match_operand:SWI248x 2 "memory_operand"))
5202 (clobber (match_scratch 3))]
5204 [(parallel [(set (match_dup 0) (fix:SWI248x (match_dup 1)))
5205 (clobber (match_dup 3))])])
5207 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
5208 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
5209 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
5210 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
5211 ;; function in i386.c.
5212 (define_insn_and_split "*fix_trunc<mode>_i387_1"
5213 [(set (match_operand:SWI248x 0 "nonimmediate_operand")
5214 (fix:SWI248x (match_operand 1 "register_operand")))
5215 (clobber (reg:CC FLAGS_REG))]
5216 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5218 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
5219 && (TARGET_64BIT || <MODE>mode != DImode))
5220 && can_create_pseudo_p ()"
5225 ix86_optimize_mode_switching[I387_TRUNC] = 1;
5227 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
5228 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
5229 if (memory_operand (operands[0], VOIDmode))
5230 emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
5231 operands[2], operands[3]));
5234 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
5235 emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
5236 operands[2], operands[3],
5241 [(set_attr "type" "fistp")
5242 (set_attr "i387_cw" "trunc")
5243 (set_attr "mode" "<MODE>")])
5245 (define_insn "fix_truncdi_i387"
5246 [(set (match_operand:DI 0 "memory_operand" "=m")
5247 (fix:DI (match_operand 1 "register_operand" "f")))
5248 (use (match_operand:HI 2 "memory_operand" "m"))
5249 (use (match_operand:HI 3 "memory_operand" "m"))
5250 (clobber (match_scratch:XF 4 "=&1f"))]
5251 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5253 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
5254 "* return output_fix_trunc (insn, operands, false);"
5255 [(set_attr "type" "fistp")
5256 (set_attr "i387_cw" "trunc")
5257 (set_attr "mode" "DI")])
5259 (define_insn "fix_truncdi_i387_with_temp"
5260 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
5261 (fix:DI (match_operand 1 "register_operand" "f,f")))
5262 (use (match_operand:HI 2 "memory_operand" "m,m"))
5263 (use (match_operand:HI 3 "memory_operand" "m,m"))
5264 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
5265 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
5266 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5268 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
5270 [(set_attr "type" "fistp")
5271 (set_attr "i387_cw" "trunc")
5272 (set_attr "mode" "DI")])
5275 [(set (match_operand:DI 0 "register_operand")
5276 (fix:DI (match_operand 1 "register_operand")))
5277 (use (match_operand:HI 2 "memory_operand"))
5278 (use (match_operand:HI 3 "memory_operand"))
5279 (clobber (match_operand:DI 4 "memory_operand"))
5280 (clobber (match_scratch 5))]
5282 [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
5285 (clobber (match_dup 5))])
5286 (set (match_dup 0) (match_dup 4))])
5289 [(set (match_operand:DI 0 "memory_operand")
5290 (fix:DI (match_operand 1 "register_operand")))
5291 (use (match_operand:HI 2 "memory_operand"))
5292 (use (match_operand:HI 3 "memory_operand"))
5293 (clobber (match_operand:DI 4 "memory_operand"))
5294 (clobber (match_scratch 5))]
5296 [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
5299 (clobber (match_dup 5))])])
5301 (define_insn "fix_trunc<mode>_i387"
5302 [(set (match_operand:SWI24 0 "memory_operand" "=m")
5303 (fix:SWI24 (match_operand 1 "register_operand" "f")))
5304 (use (match_operand:HI 2 "memory_operand" "m"))
5305 (use (match_operand:HI 3 "memory_operand" "m"))]
5306 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5308 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
5309 "* return output_fix_trunc (insn, operands, false);"
5310 [(set_attr "type" "fistp")
5311 (set_attr "i387_cw" "trunc")
5312 (set_attr "mode" "<MODE>")])
5314 (define_insn "fix_trunc<mode>_i387_with_temp"
5315 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
5316 (fix:SWI24 (match_operand 1 "register_operand" "f,f")))
5317 (use (match_operand:HI 2 "memory_operand" "m,m"))
5318 (use (match_operand:HI 3 "memory_operand" "m,m"))
5319 (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
5320 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5322 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
5324 [(set_attr "type" "fistp")
5325 (set_attr "i387_cw" "trunc")
5326 (set_attr "mode" "<MODE>")])
5329 [(set (match_operand:SWI24 0 "register_operand")
5330 (fix:SWI24 (match_operand 1 "register_operand")))
5331 (use (match_operand:HI 2 "memory_operand"))
5332 (use (match_operand:HI 3 "memory_operand"))
5333 (clobber (match_operand:SWI24 4 "memory_operand"))]
5335 [(parallel [(set (match_dup 4) (fix:SWI24 (match_dup 1)))
5337 (use (match_dup 3))])
5338 (set (match_dup 0) (match_dup 4))])
5341 [(set (match_operand:SWI24 0 "memory_operand")
5342 (fix:SWI24 (match_operand 1 "register_operand")))
5343 (use (match_operand:HI 2 "memory_operand"))
5344 (use (match_operand:HI 3 "memory_operand"))
5345 (clobber (match_operand:SWI24 4 "memory_operand"))]
5347 [(parallel [(set (match_dup 0) (fix:SWI24 (match_dup 1)))
5349 (use (match_dup 3))])])
5351 (define_insn "x86_fnstcw_1"
5352 [(set (match_operand:HI 0 "memory_operand" "=m")
5353 (unspec:HI [(reg:HI FPCR_REG)] UNSPEC_FSTCW))]
5356 [(set (attr "length")
5357 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
5358 (set_attr "mode" "HI")
5359 (set_attr "unit" "i387")
5360 (set_attr "bdver1_decode" "vector")])
5362 (define_insn "x86_fldcw_1"
5363 [(set (reg:HI FPCR_REG)
5364 (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
5367 [(set (attr "length")
5368 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
5369 (set_attr "mode" "HI")
5370 (set_attr "unit" "i387")
5371 (set_attr "athlon_decode" "vector")
5372 (set_attr "amdfam10_decode" "vector")
5373 (set_attr "bdver1_decode" "vector")])
5375 ;; Conversion between fixed point and floating point.
5377 ;; Even though we only accept memory inputs, the backend _really_
5378 ;; wants to be able to do this between registers. Thankfully, LRA
5379 ;; will fix this up for us during register allocation.
5381 (define_insn "floathi<mode>2"
5382 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5383 (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "m")))]
5385 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5386 || TARGET_MIX_SSE_I387)"
5388 [(set_attr "type" "fmov")
5389 (set_attr "mode" "<MODE>")
5390 (set_attr "znver1_decode" "double")
5391 (set_attr "fp_int_src" "true")])
5393 (define_insn "float<SWI48x:mode>xf2"
5394 [(set (match_operand:XF 0 "register_operand" "=f")
5395 (float:XF (match_operand:SWI48x 1 "nonimmediate_operand" "m")))]
5398 [(set_attr "type" "fmov")
5399 (set_attr "mode" "XF")
5400 (set_attr "znver1_decode" "double")
5401 (set_attr "fp_int_src" "true")])
5403 (define_expand "float<SWI48:mode><MODEF:mode>2"
5404 [(set (match_operand:MODEF 0 "register_operand")
5405 (float:MODEF (match_operand:SWI48 1 "nonimmediate_operand")))]
5406 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)"
5408 if (!(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
5409 && !X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI48:MODE>mode))
5411 rtx reg = gen_reg_rtx (XFmode);
5412 rtx (*insn)(rtx, rtx);
5414 emit_insn (gen_float<SWI48:mode>xf2 (reg, operands[1]));
5416 if (<MODEF:MODE>mode == SFmode)
5417 insn = gen_truncxfsf2;
5418 else if (<MODEF:MODE>mode == DFmode)
5419 insn = gen_truncxfdf2;
5423 emit_insn (insn (operands[0], reg));
5428 (define_insn "*float<SWI48:mode><MODEF:mode>2_mixed"
5429 [(set (match_operand:MODEF 0 "register_operand" "=f,v,v")
5431 (match_operand:SWI48 1 "nonimmediate_operand" "m,r,m")))]
5432 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
5435 %vcvtsi2<MODEF:ssemodesuffix><SWI48:rex64suffix>\t{%1, %d0|%d0, %1}
5436 %vcvtsi2<MODEF:ssemodesuffix><SWI48:rex64suffix>\t{%1, %d0|%d0, %1}"
5437 [(set_attr "type" "fmov,sseicvt,sseicvt")
5438 (set_attr "prefix" "orig,maybe_vex,maybe_vex")
5439 (set_attr "mode" "<MODEF:MODE>")
5440 (set (attr "prefix_rex")
5442 (and (eq_attr "prefix" "maybe_vex")
5443 (match_test "<SWI48:MODE>mode == DImode"))
5445 (const_string "*")))
5446 (set_attr "unit" "i387,*,*")
5447 (set_attr "athlon_decode" "*,double,direct")
5448 (set_attr "amdfam10_decode" "*,vector,double")
5449 (set_attr "bdver1_decode" "*,double,direct")
5450 (set_attr "znver1_decode" "double,*,*")
5451 (set_attr "fp_int_src" "true")
5452 (set (attr "enabled")
5453 (cond [(eq_attr "alternative" "0")
5454 (symbol_ref "TARGET_MIX_SSE_I387
5455 && X87_ENABLE_FLOAT (<MODEF:MODE>mode,
5458 (symbol_ref "true")))
5459 (set (attr "preferred_for_speed")
5460 (cond [(eq_attr "alternative" "1")
5461 (symbol_ref "TARGET_INTER_UNIT_CONVERSIONS")]
5462 (symbol_ref "true")))])
5464 (define_insn "*float<SWI48x:mode><MODEF:mode>2_i387"
5465 [(set (match_operand:MODEF 0 "register_operand" "=f")
5466 (float:MODEF (match_operand:SWI48x 1 "nonimmediate_operand" "m")))]
5467 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI48x:MODE>mode)"
5469 [(set_attr "type" "fmov")
5470 (set_attr "mode" "<MODEF:MODE>")
5471 (set_attr "znver1_decode" "double")
5472 (set_attr "fp_int_src" "true")])
5474 ;; Try TARGET_USE_VECTOR_CONVERTS, but not so hard as to require extra memory
5475 ;; slots when !TARGET_INTER_UNIT_MOVES_TO_VEC disables the general_regs
5476 ;; alternative in sse2_loadld.
5478 [(set (match_operand:MODEF 0 "sse_reg_operand")
5479 (float:MODEF (match_operand:SI 1 "nonimmediate_operand")))]
5481 && TARGET_USE_VECTOR_CONVERTS
5482 && optimize_function_for_speed_p (cfun)
5484 && (MEM_P (operands[1]) || TARGET_INTER_UNIT_MOVES_TO_VEC)
5485 && (!EXT_REX_SSE_REG_P (operands[0])
5486 || TARGET_AVX512VL)"
5489 operands[3] = lowpart_subreg (<ssevecmode>mode, operands[0], <MODE>mode);
5490 operands[4] = lowpart_subreg (V4SImode, operands[0], <MODE>mode);
5492 emit_insn (gen_sse2_loadld (operands[4],
5493 CONST0_RTX (V4SImode), operands[1]));
5495 if (<ssevecmode>mode == V4SFmode)
5496 emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
5498 emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
5502 ;; Avoid partial SSE register dependency stalls. This splitter should split
5503 ;; late in the pass sequence (after register rename pass), so allocated
5504 ;; registers won't change anymore
5507 [(set (match_operand:MODEF 0 "sse_reg_operand")
5508 (float:MODEF (match_operand:SWI48 1 "nonimmediate_operand")))]
5509 "TARGET_SSE_PARTIAL_REG_DEPENDENCY && epilogue_completed
5510 && optimize_function_for_speed_p (cfun)
5511 && (!EXT_REX_SSE_REG_P (operands[0])
5512 || TARGET_AVX512VL)"
5514 (vec_merge:<MODEF:ssevecmode>
5515 (vec_duplicate:<MODEF:ssevecmode>
5521 const machine_mode vmode = <MODEF:ssevecmode>mode;
5523 operands[0] = lowpart_subreg (vmode, operands[0], <MODEF:MODE>mode);
5524 emit_move_insn (operands[0], CONST0_RTX (vmode));
5527 ;; Break partial reg stall for cvtsd2ss. This splitter should split
5528 ;; late in the pass sequence (after register rename pass),
5529 ;; so allocated registers won't change anymore.
5532 [(set (match_operand:SF 0 "sse_reg_operand")
5534 (match_operand:DF 1 "nonimmediate_operand")))]
5535 "TARGET_SSE_PARTIAL_REG_DEPENDENCY && epilogue_completed
5536 && optimize_function_for_speed_p (cfun)
5537 && (!REG_P (operands[1])
5538 || REGNO (operands[0]) != REGNO (operands[1]))
5539 && (!EXT_REX_SSE_REG_P (operands[0])
5540 || TARGET_AVX512VL)"
5549 operands[0] = lowpart_subreg (V4SFmode, operands[0], SFmode);
5550 emit_move_insn (operands[0], CONST0_RTX (V4SFmode));
5553 ;; Break partial reg stall for cvtss2sd. This splitter should split
5554 ;; late in the pass sequence (after register rename pass),
5555 ;; so allocated registers won't change anymore.
5558 [(set (match_operand:DF 0 "sse_reg_operand")
5560 (match_operand:SF 1 "nonimmediate_operand")))]
5561 "TARGET_SSE_PARTIAL_REG_DEPENDENCY && epilogue_completed
5562 && optimize_function_for_speed_p (cfun)
5563 && (!REG_P (operands[1])
5564 || REGNO (operands[0]) != REGNO (operands[1]))
5565 && (!EXT_REX_SSE_REG_P (operands[0])
5566 || TARGET_AVX512VL)"
5575 operands[0] = lowpart_subreg (V2DFmode, operands[0], DFmode);
5576 emit_move_insn (operands[0], CONST0_RTX (V2DFmode));
5579 ;; Avoid store forwarding (partial memory) stall penalty
5580 ;; by passing DImode value through XMM registers. */
5582 (define_insn "floatdi<X87MODEF:mode>2_i387_with_xmm"
5583 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5585 (match_operand:DI 1 "nonimmediate_operand" "m,?r")))
5586 (clobber (match_scratch:V4SI 3 "=X,x"))
5587 (clobber (match_scratch:V4SI 4 "=X,x"))
5588 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))]
5589 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5590 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC
5591 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)"
5593 [(set_attr "type" "multi")
5594 (set_attr "mode" "<X87MODEF:MODE>")
5595 (set_attr "unit" "i387")
5596 (set_attr "fp_int_src" "true")])
5599 [(set (match_operand:X87MODEF 0 "fp_register_operand")
5600 (float:X87MODEF (match_operand:DI 1 "register_operand")))
5601 (clobber (match_scratch:V4SI 3))
5602 (clobber (match_scratch:V4SI 4))
5603 (clobber (match_operand:DI 2 "memory_operand"))]
5604 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5605 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC
5606 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5607 && reload_completed"
5608 [(set (match_dup 2) (match_dup 3))
5609 (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5611 /* The DImode arrived in a pair of integral registers (e.g. %edx:%eax).
5612 Assemble the 64-bit DImode value in an xmm register. */
5613 emit_insn (gen_sse2_loadld (operands[3], CONST0_RTX (V4SImode),
5614 gen_lowpart (SImode, operands[1])));
5615 emit_insn (gen_sse2_loadld (operands[4], CONST0_RTX (V4SImode),
5616 gen_highpart (SImode, operands[1])));
5617 emit_insn (gen_vec_interleave_lowv4si (operands[3], operands[3],
5620 operands[3] = gen_lowpart (DImode, operands[3]);
5624 [(set (match_operand:X87MODEF 0 "fp_register_operand")
5625 (float:X87MODEF (match_operand:DI 1 "memory_operand")))
5626 (clobber (match_scratch:V4SI 3))
5627 (clobber (match_scratch:V4SI 4))
5628 (clobber (match_operand:DI 2 "memory_operand"))]
5629 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5630 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC
5631 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5632 && reload_completed"
5633 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
5635 (define_expand "floatuns<SWI12:mode><MODEF:mode>2"
5636 [(set (match_operand:MODEF 0 "register_operand")
5637 (unsigned_float:MODEF
5638 (match_operand:SWI12 1 "nonimmediate_operand")))]
5640 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
5642 operands[1] = convert_to_mode (SImode, operands[1], 1);
5643 emit_insn (gen_floatsi<MODEF:mode>2 (operands[0], operands[1]));
5647 (define_insn "*floatuns<SWI48:mode><MODEF:mode>2_avx512"
5648 [(set (match_operand:MODEF 0 "register_operand" "=v")
5649 (unsigned_float:MODEF
5650 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))]
5651 "TARGET_AVX512F && TARGET_SSE_MATH"
5652 "vcvtusi2<MODEF:ssemodesuffix><SWI48:rex64suffix>\t{%1, %0, %0|%0, %0, %1}"
5653 [(set_attr "type" "sseicvt")
5654 (set_attr "prefix" "evex")
5655 (set_attr "mode" "<MODEF:MODE>")])
5657 ;; Avoid store forwarding (partial memory) stall penalty by extending
5658 ;; SImode value to DImode through XMM register instead of pushing two
5659 ;; SImode values to stack. Also note that fild loads from memory only.
5661 (define_insn_and_split "floatunssi<mode>2_i387_with_xmm"
5662 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5663 (unsigned_float:X87MODEF
5664 (match_operand:SI 1 "nonimmediate_operand" "rm")))
5665 (clobber (match_operand:DI 2 "memory_operand" "=m"))
5666 (clobber (match_scratch:DI 3 "=x"))]
5668 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5669 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC"
5671 "&& reload_completed"
5672 [(set (match_dup 3) (zero_extend:DI (match_dup 1)))
5673 (set (match_dup 2) (match_dup 3))
5675 (float:X87MODEF (match_dup 2)))]
5677 [(set_attr "type" "multi")
5678 (set_attr "mode" "<MODE>")])
5680 (define_expand "floatunssi<mode>2"
5681 [(set (match_operand:X87MODEF 0 "register_operand")
5682 (unsigned_float:X87MODEF
5683 (match_operand:SI 1 "nonimmediate_operand")))]
5685 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5686 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC)
5687 || ((!TARGET_64BIT || TARGET_AVX512F)
5688 && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
5690 if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
5692 emit_insn (gen_floatunssi<mode>2_i387_with_xmm
5693 (operands[0], operands[1],
5694 assign_386_stack_local (DImode, SLOT_TEMP)));
5697 if (!TARGET_AVX512F)
5699 ix86_expand_convert_uns_si<mode>_sse (operands[0], operands[1]);
5704 (define_expand "floatunsdisf2"
5705 [(set (match_operand:SF 0 "register_operand")
5707 (match_operand:DI 1 "nonimmediate_operand")))]
5708 "TARGET_64BIT && TARGET_SSE && TARGET_SSE_MATH"
5710 if (!TARGET_AVX512F)
5712 x86_emit_floatuns (operands);
5717 (define_expand "floatunsdidf2"
5718 [(set (match_operand:DF 0 "register_operand")
5720 (match_operand:DI 1 "nonimmediate_operand")))]
5721 "(TARGET_KEEPS_VECTOR_ALIGNED_STACK || TARGET_AVX512F)
5722 && TARGET_SSE2 && TARGET_SSE_MATH"
5726 ix86_expand_convert_uns_didf_sse (operands[0], operands[1]);
5729 if (!TARGET_AVX512F)
5731 x86_emit_floatuns (operands);
5736 ;; Load effective address instructions
5738 (define_insn_and_split "*lea<mode>"
5739 [(set (match_operand:SWI48 0 "register_operand" "=r")
5740 (match_operand:SWI48 1 "address_no_seg_operand" "Ts"))]
5743 if (SImode_address_operand (operands[1], VOIDmode))
5745 gcc_assert (TARGET_64BIT);
5746 return "lea{l}\t{%E1, %k0|%k0, %E1}";
5749 return "lea{<imodesuffix>}\t{%E1, %0|%0, %E1}";
5751 "reload_completed && ix86_avoid_lea_for_addr (insn, operands)"
5754 machine_mode mode = <MODE>mode;
5757 /* ix86_avoid_lea_for_addr re-recognizes insn and may
5758 change operands[] array behind our back. */
5759 pat = PATTERN (curr_insn);
5761 operands[0] = SET_DEST (pat);
5762 operands[1] = SET_SRC (pat);
5764 /* Emit all operations in SImode for zero-extended addresses. */
5765 if (SImode_address_operand (operands[1], VOIDmode))
5768 ix86_split_lea_for_addr (curr_insn, operands, mode);
5770 /* Zero-extend return register to DImode for zero-extended addresses. */
5771 if (mode != <MODE>mode)
5772 emit_insn (gen_zero_extendsidi2
5773 (operands[0], gen_lowpart (mode, operands[0])));
5777 [(set_attr "type" "lea")
5780 (match_operand 1 "SImode_address_operand")
5782 (const_string "<MODE>")))])
5786 (define_expand "add<mode>3"
5787 [(set (match_operand:SDWIM 0 "nonimmediate_operand")
5788 (plus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")
5789 (match_operand:SDWIM 2 "<general_hilo_operand>")))]
5791 "ix86_expand_binary_operator (PLUS, <MODE>mode, operands); DONE;")
5793 (define_insn_and_split "*add<dwi>3_doubleword"
5794 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
5796 (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0")
5797 (match_operand:<DWI> 2 "x86_64_hilo_general_operand"
5799 (clobber (reg:CC FLAGS_REG))]
5800 "ix86_binary_operator_ok (PLUS, <DWI>mode, operands)"
5803 [(parallel [(set (reg:CCC FLAGS_REG)
5805 (plus:DWIH (match_dup 1) (match_dup 2))
5808 (plus:DWIH (match_dup 1) (match_dup 2)))])
5809 (parallel [(set (match_dup 3)
5812 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
5815 (clobber (reg:CC FLAGS_REG))])]
5817 split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
5818 if (operands[2] == const0_rtx)
5820 ix86_expand_binary_operator (PLUS, <MODE>mode, &operands[3]);
5825 (define_insn "*add<mode>_1"
5826 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,rm,r,r")
5828 (match_operand:SWI48 1 "nonimmediate_operand" "%0,0,r,r")
5829 (match_operand:SWI48 2 "x86_64_general_operand" "rme,re,0,le")))
5830 (clobber (reg:CC FLAGS_REG))]
5831 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5833 switch (get_attr_type (insn))
5839 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5840 if (operands[2] == const1_rtx)
5841 return "inc{<imodesuffix>}\t%0";
5844 gcc_assert (operands[2] == constm1_rtx);
5845 return "dec{<imodesuffix>}\t%0";
5849 /* For most processors, ADD is faster than LEA. This alternative
5850 was added to use ADD as much as possible. */
5851 if (which_alternative == 2)
5852 std::swap (operands[1], operands[2]);
5854 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5855 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5856 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5858 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5862 (cond [(eq_attr "alternative" "3")
5863 (const_string "lea")
5864 (match_operand:SWI48 2 "incdec_operand")
5865 (const_string "incdec")
5867 (const_string "alu")))
5868 (set (attr "length_immediate")
5870 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5872 (const_string "*")))
5873 (set_attr "mode" "<MODE>")])
5875 ;; It may seem that nonimmediate operand is proper one for operand 1.
5876 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5877 ;; we take care in ix86_binary_operator_ok to not allow two memory
5878 ;; operands so proper swapping will be done in reload. This allow
5879 ;; patterns constructed from addsi_1 to match.
5881 (define_insn "addsi_1_zext"
5882 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
5884 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r,r")
5885 (match_operand:SI 2 "x86_64_general_operand" "rme,0,le"))))
5886 (clobber (reg:CC FLAGS_REG))]
5887 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5889 switch (get_attr_type (insn))
5895 if (operands[2] == const1_rtx)
5896 return "inc{l}\t%k0";
5899 gcc_assert (operands[2] == constm1_rtx);
5900 return "dec{l}\t%k0";
5904 /* For most processors, ADD is faster than LEA. This alternative
5905 was added to use ADD as much as possible. */
5906 if (which_alternative == 1)
5907 std::swap (operands[1], operands[2]);
5909 if (x86_maybe_negate_const_int (&operands[2], SImode))
5910 return "sub{l}\t{%2, %k0|%k0, %2}";
5912 return "add{l}\t{%2, %k0|%k0, %2}";
5916 (cond [(eq_attr "alternative" "2")
5917 (const_string "lea")
5918 (match_operand:SI 2 "incdec_operand")
5919 (const_string "incdec")
5921 (const_string "alu")))
5922 (set (attr "length_immediate")
5924 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5926 (const_string "*")))
5927 (set_attr "mode" "SI")])
5929 (define_insn "*addhi_1"
5930 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r,Yp")
5931 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r,Yp")
5932 (match_operand:HI 2 "general_operand" "rn,rm,0,ln")))
5933 (clobber (reg:CC FLAGS_REG))]
5934 "ix86_binary_operator_ok (PLUS, HImode, operands)"
5936 switch (get_attr_type (insn))
5942 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5943 if (operands[2] == const1_rtx)
5944 return "inc{w}\t%0";
5947 gcc_assert (operands[2] == constm1_rtx);
5948 return "dec{w}\t%0";
5952 /* For most processors, ADD is faster than LEA. This alternative
5953 was added to use ADD as much as possible. */
5954 if (which_alternative == 2)
5955 std::swap (operands[1], operands[2]);
5957 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5958 if (x86_maybe_negate_const_int (&operands[2], HImode))
5959 return "sub{w}\t{%2, %0|%0, %2}";
5961 return "add{w}\t{%2, %0|%0, %2}";
5965 (cond [(eq_attr "alternative" "3")
5966 (const_string "lea")
5967 (match_operand:HI 2 "incdec_operand")
5968 (const_string "incdec")
5970 (const_string "alu")))
5971 (set (attr "length_immediate")
5973 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5975 (const_string "*")))
5976 (set_attr "mode" "HI,HI,HI,SI")])
5978 (define_insn "*addqi_1"
5979 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,q,r,r,Yp")
5980 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,q,0,r,Yp")
5981 (match_operand:QI 2 "general_operand" "qn,qm,0,rn,0,ln")))
5982 (clobber (reg:CC FLAGS_REG))]
5983 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5985 bool widen = (get_attr_mode (insn) != MODE_QI);
5987 switch (get_attr_type (insn))
5993 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5994 if (operands[2] == const1_rtx)
5995 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
5998 gcc_assert (operands[2] == constm1_rtx);
5999 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6003 /* For most processors, ADD is faster than LEA. These alternatives
6004 were added to use ADD as much as possible. */
6005 if (which_alternative == 2 || which_alternative == 4)
6006 std::swap (operands[1], operands[2]);
6008 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6009 if (x86_maybe_negate_const_int (&operands[2], QImode))
6012 return "sub{l}\t{%2, %k0|%k0, %2}";
6014 return "sub{b}\t{%2, %0|%0, %2}";
6017 return "add{l}\t{%k2, %k0|%k0, %k2}";
6019 return "add{b}\t{%2, %0|%0, %2}";
6023 (cond [(eq_attr "alternative" "5")
6024 (const_string "lea")
6025 (match_operand:QI 2 "incdec_operand")
6026 (const_string "incdec")
6028 (const_string "alu")))
6029 (set (attr "length_immediate")
6031 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6033 (const_string "*")))
6034 (set_attr "mode" "QI,QI,QI,SI,SI,SI")
6035 ;; Potential partial reg stall on alternatives 3 and 4.
6036 (set (attr "preferred_for_speed")
6037 (cond [(eq_attr "alternative" "3,4")
6038 (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
6039 (symbol_ref "true")))])
6041 (define_insn "*addqi_1_slp"
6042 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6043 (plus:QI (match_dup 0)
6044 (match_operand:QI 1 "general_operand" "qn,qm")))
6045 (clobber (reg:CC FLAGS_REG))]
6046 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6047 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
6049 switch (get_attr_type (insn))
6052 if (operands[1] == const1_rtx)
6053 return "inc{b}\t%0";
6056 gcc_assert (operands[1] == constm1_rtx);
6057 return "dec{b}\t%0";
6061 if (x86_maybe_negate_const_int (&operands[1], QImode))
6062 return "sub{b}\t{%1, %0|%0, %1}";
6064 return "add{b}\t{%1, %0|%0, %1}";
6068 (if_then_else (match_operand:QI 1 "incdec_operand")
6069 (const_string "incdec")
6070 (const_string "alu1")))
6071 (set (attr "memory")
6072 (if_then_else (match_operand 1 "memory_operand")
6073 (const_string "load")
6074 (const_string "none")))
6075 (set_attr "mode" "QI")])
6077 ;; Split non destructive adds if we cannot use lea.
6079 [(set (match_operand:SWI48 0 "register_operand")
6080 (plus:SWI48 (match_operand:SWI48 1 "register_operand")
6081 (match_operand:SWI48 2 "x86_64_nonmemory_operand")))
6082 (clobber (reg:CC FLAGS_REG))]
6083 "reload_completed && ix86_avoid_lea_for_add (insn, operands)"
6084 [(set (match_dup 0) (match_dup 1))
6085 (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 2)))
6086 (clobber (reg:CC FLAGS_REG))])])
6088 ;; Split non destructive adds if we cannot use lea.
6090 [(set (match_operand:DI 0 "register_operand")
6092 (plus:SI (match_operand:SI 1 "register_operand")
6093 (match_operand:SI 2 "x86_64_nonmemory_operand"))))
6094 (clobber (reg:CC FLAGS_REG))]
6096 && reload_completed && ix86_avoid_lea_for_add (insn, operands)"
6097 [(set (match_dup 3) (match_dup 1))
6098 (parallel [(set (match_dup 0)
6099 (zero_extend:DI (plus:SI (match_dup 3) (match_dup 2))))
6100 (clobber (reg:CC FLAGS_REG))])]
6101 "operands[3] = gen_lowpart (SImode, operands[0]);")
6103 ;; Convert add to the lea pattern to avoid flags dependency.
6105 [(set (match_operand:SWI 0 "register_operand")
6106 (plus:SWI (match_operand:SWI 1 "register_operand")
6107 (match_operand:SWI 2 "<nonmemory_operand>")))
6108 (clobber (reg:CC FLAGS_REG))]
6109 "reload_completed && ix86_lea_for_add_ok (insn, operands)"
6111 (plus:<LEAMODE> (match_dup 1) (match_dup 2)))]
6113 if (<MODE>mode != <LEAMODE>mode)
6115 operands[0] = gen_lowpart (<LEAMODE>mode, operands[0]);
6116 operands[1] = gen_lowpart (<LEAMODE>mode, operands[1]);
6117 operands[2] = gen_lowpart (<LEAMODE>mode, operands[2]);
6121 ;; Convert add to the lea pattern to avoid flags dependency.
6123 [(set (match_operand:DI 0 "register_operand")
6125 (plus:SI (match_operand:SI 1 "register_operand")
6126 (match_operand:SI 2 "x86_64_nonmemory_operand"))))
6127 (clobber (reg:CC FLAGS_REG))]
6128 "TARGET_64BIT && reload_completed && ix86_lea_for_add_ok (insn, operands)"
6130 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))])
6132 (define_insn "*add<mode>_2"
6133 [(set (reg FLAGS_REG)
6136 (match_operand:SWI 1 "nonimmediate_operand" "%0,0,<r>")
6137 (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>,0"))
6139 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m,<r>")
6140 (plus:SWI (match_dup 1) (match_dup 2)))]
6141 "ix86_match_ccmode (insn, CCGOCmode)
6142 && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6144 switch (get_attr_type (insn))
6147 if (operands[2] == const1_rtx)
6148 return "inc{<imodesuffix>}\t%0";
6151 gcc_assert (operands[2] == constm1_rtx);
6152 return "dec{<imodesuffix>}\t%0";
6156 if (which_alternative == 2)
6157 std::swap (operands[1], operands[2]);
6159 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6160 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6161 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6163 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6167 (if_then_else (match_operand:SWI 2 "incdec_operand")
6168 (const_string "incdec")
6169 (const_string "alu")))
6170 (set (attr "length_immediate")
6172 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6174 (const_string "*")))
6175 (set_attr "mode" "<MODE>")])
6177 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6178 (define_insn "*addsi_2_zext"
6179 [(set (reg FLAGS_REG)
6181 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
6182 (match_operand:SI 2 "x86_64_general_operand" "rme,0"))
6184 (set (match_operand:DI 0 "register_operand" "=r,r")
6185 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6186 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6187 && ix86_binary_operator_ok (PLUS, SImode, operands)"
6189 switch (get_attr_type (insn))
6192 if (operands[2] == const1_rtx)
6193 return "inc{l}\t%k0";
6196 gcc_assert (operands[2] == constm1_rtx);
6197 return "dec{l}\t%k0";
6201 if (which_alternative == 1)
6202 std::swap (operands[1], operands[2]);
6204 if (x86_maybe_negate_const_int (&operands[2], SImode))
6205 return "sub{l}\t{%2, %k0|%k0, %2}";
6207 return "add{l}\t{%2, %k0|%k0, %2}";
6211 (if_then_else (match_operand:SI 2 "incdec_operand")
6212 (const_string "incdec")
6213 (const_string "alu")))
6214 (set (attr "length_immediate")
6216 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6218 (const_string "*")))
6219 (set_attr "mode" "SI")])
6221 (define_insn "*add<mode>_3"
6222 [(set (reg FLAGS_REG)
6224 (neg:SWI (match_operand:SWI 2 "<general_operand>" "<g>,0"))
6225 (match_operand:SWI 1 "nonimmediate_operand" "%0,<r>")))
6226 (clobber (match_scratch:SWI 0 "=<r>,<r>"))]
6227 "ix86_match_ccmode (insn, CCZmode)
6228 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6230 switch (get_attr_type (insn))
6233 if (operands[2] == const1_rtx)
6234 return "inc{<imodesuffix>}\t%0";
6237 gcc_assert (operands[2] == constm1_rtx);
6238 return "dec{<imodesuffix>}\t%0";
6242 if (which_alternative == 1)
6243 std::swap (operands[1], operands[2]);
6245 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6246 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6247 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6249 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6253 (if_then_else (match_operand:SWI 2 "incdec_operand")
6254 (const_string "incdec")
6255 (const_string "alu")))
6256 (set (attr "length_immediate")
6258 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6260 (const_string "*")))
6261 (set_attr "mode" "<MODE>")])
6263 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6264 (define_insn "*addsi_3_zext"
6265 [(set (reg FLAGS_REG)
6267 (neg:SI (match_operand:SI 2 "x86_64_general_operand" "rme,0"))
6268 (match_operand:SI 1 "nonimmediate_operand" "%0,r")))
6269 (set (match_operand:DI 0 "register_operand" "=r,r")
6270 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6271 "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
6272 && ix86_binary_operator_ok (PLUS, SImode, operands)"
6274 switch (get_attr_type (insn))
6277 if (operands[2] == const1_rtx)
6278 return "inc{l}\t%k0";
6281 gcc_assert (operands[2] == constm1_rtx);
6282 return "dec{l}\t%k0";
6286 if (which_alternative == 1)
6287 std::swap (operands[1], operands[2]);
6289 if (x86_maybe_negate_const_int (&operands[2], SImode))
6290 return "sub{l}\t{%2, %k0|%k0, %2}";
6292 return "add{l}\t{%2, %k0|%k0, %2}";
6296 (if_then_else (match_operand:SI 2 "incdec_operand")
6297 (const_string "incdec")
6298 (const_string "alu")))
6299 (set (attr "length_immediate")
6301 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6303 (const_string "*")))
6304 (set_attr "mode" "SI")])
6306 ; For comparisons against 1, -1 and 128, we may generate better code
6307 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
6308 ; is matched then. We can't accept general immediate, because for
6309 ; case of overflows, the result is messed up.
6310 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6311 ; only for comparisons not depending on it.
6313 (define_insn "*adddi_4"
6314 [(set (reg FLAGS_REG)
6316 (match_operand:DI 1 "nonimmediate_operand" "0")
6317 (match_operand:DI 2 "x86_64_immediate_operand" "e")))
6318 (clobber (match_scratch:DI 0 "=rm"))]
6320 && ix86_match_ccmode (insn, CCGCmode)"
6322 switch (get_attr_type (insn))
6325 if (operands[2] == constm1_rtx)
6326 return "inc{q}\t%0";
6329 gcc_assert (operands[2] == const1_rtx);
6330 return "dec{q}\t%0";
6334 if (x86_maybe_negate_const_int (&operands[2], DImode))
6335 return "add{q}\t{%2, %0|%0, %2}";
6337 return "sub{q}\t{%2, %0|%0, %2}";
6341 (if_then_else (match_operand:DI 2 "incdec_operand")
6342 (const_string "incdec")
6343 (const_string "alu")))
6344 (set (attr "length_immediate")
6346 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6348 (const_string "*")))
6349 (set_attr "mode" "DI")])
6351 ; For comparisons against 1, -1 and 128, we may generate better code
6352 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
6353 ; is matched then. We can't accept general immediate, because for
6354 ; case of overflows, the result is messed up.
6355 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6356 ; only for comparisons not depending on it.
6358 (define_insn "*add<mode>_4"
6359 [(set (reg FLAGS_REG)
6361 (match_operand:SWI124 1 "nonimmediate_operand" "0")
6362 (match_operand:SWI124 2 "const_int_operand" "n")))
6363 (clobber (match_scratch:SWI124 0 "=<r>m"))]
6364 "ix86_match_ccmode (insn, CCGCmode)"
6366 switch (get_attr_type (insn))
6369 if (operands[2] == constm1_rtx)
6370 return "inc{<imodesuffix>}\t%0";
6373 gcc_assert (operands[2] == const1_rtx);
6374 return "dec{<imodesuffix>}\t%0";
6378 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6379 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6381 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6385 (if_then_else (match_operand:<MODE> 2 "incdec_operand")
6386 (const_string "incdec")
6387 (const_string "alu")))
6388 (set (attr "length_immediate")
6390 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6392 (const_string "*")))
6393 (set_attr "mode" "<MODE>")])
6395 (define_insn "*add<mode>_5"
6396 [(set (reg FLAGS_REG)
6399 (match_operand:SWI 1 "nonimmediate_operand" "%0,<r>")
6400 (match_operand:SWI 2 "<general_operand>" "<g>,0"))
6402 (clobber (match_scratch:SWI 0 "=<r>,<r>"))]
6403 "ix86_match_ccmode (insn, CCGOCmode)
6404 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6406 switch (get_attr_type (insn))
6409 if (operands[2] == const1_rtx)
6410 return "inc{<imodesuffix>}\t%0";
6413 gcc_assert (operands[2] == constm1_rtx);
6414 return "dec{<imodesuffix>}\t%0";
6418 if (which_alternative == 1)
6419 std::swap (operands[1], operands[2]);
6421 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6422 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6423 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6425 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6429 (if_then_else (match_operand:SWI 2 "incdec_operand")
6430 (const_string "incdec")
6431 (const_string "alu")))
6432 (set (attr "length_immediate")
6434 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6436 (const_string "*")))
6437 (set_attr "mode" "<MODE>")])
6439 (define_insn "addqi_ext_1"
6440 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q,Q")
6446 (zero_extract:SI (match_operand 1 "ext_register_operand" "0,0")
6449 (match_operand:QI 2 "general_operand" "QnBc,m")) 0))
6450 (clobber (reg:CC FLAGS_REG))]
6451 "/* FIXME: without this LRA can't reload this pattern, see PR82524. */
6452 rtx_equal_p (operands[0], operands[1])"
6454 switch (get_attr_type (insn))
6457 if (operands[2] == const1_rtx)
6458 return "inc{b}\t%h0";
6461 gcc_assert (operands[2] == constm1_rtx);
6462 return "dec{b}\t%h0";
6466 return "add{b}\t{%2, %h0|%h0, %2}";
6469 [(set_attr "isa" "*,nox64")
6471 (if_then_else (match_operand:QI 2 "incdec_operand")
6472 (const_string "incdec")
6473 (const_string "alu")))
6474 (set_attr "mode" "QI")])
6476 (define_insn "*addqi_ext_2"
6477 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
6483 (zero_extract:SI (match_operand 1 "ext_register_operand" "%0")
6487 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
6489 (const_int 8)) 0)) 0))
6490 (clobber (reg:CC FLAGS_REG))]
6491 "/* FIXME: without this LRA can't reload this pattern, see PR82524. */
6492 rtx_equal_p (operands[0], operands[1])
6493 || rtx_equal_p (operands[0], operands[2])"
6494 "add{b}\t{%h2, %h0|%h0, %h2}"
6495 [(set_attr "type" "alu")
6496 (set_attr "mode" "QI")])
6498 ;; Add with jump on overflow.
6499 (define_expand "addv<mode>4"
6500 [(parallel [(set (reg:CCO FLAGS_REG)
6503 (match_operand:SWI 1 "nonimmediate_operand"))
6506 (plus:SWI (match_dup 1)
6507 (match_operand:SWI 2
6508 "<general_operand>")))))
6509 (set (match_operand:SWI 0 "register_operand")
6510 (plus:SWI (match_dup 1) (match_dup 2)))])
6511 (set (pc) (if_then_else
6512 (eq (reg:CCO FLAGS_REG) (const_int 0))
6513 (label_ref (match_operand 3))
6517 ix86_fixup_binary_operands_no_copy (PLUS, <MODE>mode, operands);
6518 if (CONST_INT_P (operands[2]))
6519 operands[4] = operands[2];
6521 operands[4] = gen_rtx_SIGN_EXTEND (<DWI>mode, operands[2]);
6524 (define_insn "*addv<mode>4"
6525 [(set (reg:CCO FLAGS_REG)
6528 (match_operand:SWI 1 "nonimmediate_operand" "%0,0"))
6530 (match_operand:SWI 2 "<general_sext_operand>"
6533 (plus:SWI (match_dup 1) (match_dup 2)))))
6534 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
6535 (plus:SWI (match_dup 1) (match_dup 2)))]
6536 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6537 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6538 [(set_attr "type" "alu")
6539 (set_attr "mode" "<MODE>")])
6541 (define_insn "*addv<mode>4_1"
6542 [(set (reg:CCO FLAGS_REG)
6545 (match_operand:SWI 1 "nonimmediate_operand" "0"))
6546 (match_operand:<DWI> 3 "const_int_operand" "i"))
6548 (plus:SWI (match_dup 1)
6549 (match_operand:SWI 2 "x86_64_immediate_operand"
6551 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
6552 (plus:SWI (match_dup 1) (match_dup 2)))]
6553 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)
6554 && CONST_INT_P (operands[2])
6555 && INTVAL (operands[2]) == INTVAL (operands[3])"
6556 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6557 [(set_attr "type" "alu")
6558 (set_attr "mode" "<MODE>")
6559 (set (attr "length_immediate")
6560 (cond [(match_test "IN_RANGE (INTVAL (operands[2]), -128, 127)")
6562 (match_test "<MODE_SIZE> == 8")
6564 (const_string "<MODE_SIZE>")))])
6566 (define_expand "uaddv<mode>4"
6567 [(parallel [(set (reg:CCC FLAGS_REG)
6570 (match_operand:SWI 1 "nonimmediate_operand")
6571 (match_operand:SWI 2 "<general_operand>"))
6573 (set (match_operand:SWI 0 "register_operand")
6574 (plus:SWI (match_dup 1) (match_dup 2)))])
6575 (set (pc) (if_then_else
6576 (ltu (reg:CCC FLAGS_REG) (const_int 0))
6577 (label_ref (match_operand 3))
6580 "ix86_fixup_binary_operands_no_copy (PLUS, <MODE>mode, operands);")
6582 ;; The lea patterns for modes less than 32 bits need to be matched by
6583 ;; several insns converted to real lea by splitters.
6585 (define_insn_and_split "*lea<mode>_general_1"
6586 [(set (match_operand:SWI12 0 "register_operand" "=r")
6588 (plus:SWI12 (match_operand:SWI12 1 "index_register_operand" "l")
6589 (match_operand:SWI12 2 "register_operand" "r"))
6590 (match_operand:SWI12 3 "immediate_operand" "i")))]
6591 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
6593 "&& reload_completed"
6596 (plus:SI (match_dup 1) (match_dup 2))
6599 operands[0] = gen_lowpart (SImode, operands[0]);
6600 operands[1] = gen_lowpart (SImode, operands[1]);
6601 operands[2] = gen_lowpart (SImode, operands[2]);
6602 operands[3] = gen_lowpart (SImode, operands[3]);
6604 [(set_attr "type" "lea")
6605 (set_attr "mode" "SI")])
6607 (define_insn_and_split "*lea<mode>_general_2"
6608 [(set (match_operand:SWI12 0 "register_operand" "=r")
6610 (mult:SWI12 (match_operand:SWI12 1 "index_register_operand" "l")
6611 (match_operand 2 "const248_operand" "n"))
6612 (match_operand:SWI12 3 "nonmemory_operand" "ri")))]
6613 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
6615 "&& reload_completed"
6618 (mult:SI (match_dup 1) (match_dup 2))
6621 operands[0] = gen_lowpart (SImode, operands[0]);
6622 operands[1] = gen_lowpart (SImode, operands[1]);
6623 operands[3] = gen_lowpart (SImode, operands[3]);
6625 [(set_attr "type" "lea")
6626 (set_attr "mode" "SI")])
6628 (define_insn_and_split "*lea<mode>_general_2b"
6629 [(set (match_operand:SWI12 0 "register_operand" "=r")
6631 (ashift:SWI12 (match_operand:SWI12 1 "index_register_operand" "l")
6632 (match_operand 2 "const123_operand" "n"))
6633 (match_operand:SWI12 3 "nonmemory_operand" "ri")))]
6634 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
6636 "&& reload_completed"
6639 (ashift:SI (match_dup 1) (match_dup 2))
6642 operands[0] = gen_lowpart (SImode, operands[0]);
6643 operands[1] = gen_lowpart (SImode, operands[1]);
6644 operands[3] = gen_lowpart (SImode, operands[3]);
6646 [(set_attr "type" "lea")
6647 (set_attr "mode" "SI")])
6649 (define_insn_and_split "*lea<mode>_general_3"
6650 [(set (match_operand:SWI12 0 "register_operand" "=r")
6653 (mult:SWI12 (match_operand:SWI12 1 "index_register_operand" "l")
6654 (match_operand 2 "const248_operand" "n"))
6655 (match_operand:SWI12 3 "register_operand" "r"))
6656 (match_operand:SWI12 4 "immediate_operand" "i")))]
6657 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
6659 "&& reload_completed"
6663 (mult:SI (match_dup 1) (match_dup 2))
6667 operands[0] = gen_lowpart (SImode, operands[0]);
6668 operands[1] = gen_lowpart (SImode, operands[1]);
6669 operands[3] = gen_lowpart (SImode, operands[3]);
6670 operands[4] = gen_lowpart (SImode, operands[4]);
6672 [(set_attr "type" "lea")
6673 (set_attr "mode" "SI")])
6675 (define_insn_and_split "*lea<mode>_general_3b"
6676 [(set (match_operand:SWI12 0 "register_operand" "=r")
6679 (ashift:SWI12 (match_operand:SWI12 1 "index_register_operand" "l")
6680 (match_operand 2 "const123_operand" "n"))
6681 (match_operand:SWI12 3 "register_operand" "r"))
6682 (match_operand:SWI12 4 "immediate_operand" "i")))]
6683 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
6685 "&& reload_completed"
6689 (ashift:SI (match_dup 1) (match_dup 2))
6693 operands[0] = gen_lowpart (SImode, operands[0]);
6694 operands[1] = gen_lowpart (SImode, operands[1]);
6695 operands[3] = gen_lowpart (SImode, operands[3]);
6696 operands[4] = gen_lowpart (SImode, operands[4]);
6698 [(set_attr "type" "lea")
6699 (set_attr "mode" "SI")])
6701 (define_insn_and_split "*lea<mode>_general_4"
6702 [(set (match_operand:SWI12 0 "register_operand" "=r")
6705 (match_operand:SWI12 1 "index_register_operand" "l")
6706 (match_operand 2 "const_0_to_3_operand" "n"))
6707 (match_operand 3 "const_int_operand" "n")))]
6708 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6709 && ((unsigned HOST_WIDE_INT) INTVAL (operands[3])
6710 < (HOST_WIDE_INT_1U << INTVAL (operands[2])))"
6712 "&& reload_completed"
6715 (mult:SI (match_dup 1) (match_dup 2))
6718 operands[0] = gen_lowpart (SImode, operands[0]);
6719 operands[1] = gen_lowpart (SImode, operands[1]);
6720 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
6722 [(set_attr "type" "lea")
6723 (set_attr "mode" "SI")])
6725 (define_insn_and_split "*lea<mode>_general_4"
6726 [(set (match_operand:SWI48 0 "register_operand" "=r")
6729 (match_operand:SWI48 1 "index_register_operand" "l")
6730 (match_operand 2 "const_0_to_3_operand" "n"))
6731 (match_operand 3 "const_int_operand" "n")))]
6732 "(unsigned HOST_WIDE_INT) INTVAL (operands[3])
6733 < (HOST_WIDE_INT_1U << INTVAL (operands[2]))"
6735 "&& reload_completed"
6738 (mult:SWI48 (match_dup 1) (match_dup 2))
6740 "operands[2] = GEN_INT (1 << INTVAL (operands[2]));"
6741 [(set_attr "type" "lea")
6742 (set_attr "mode" "<MODE>")])
6744 ;; Subtract instructions
6746 (define_expand "sub<mode>3"
6747 [(set (match_operand:SDWIM 0 "nonimmediate_operand")
6748 (minus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")
6749 (match_operand:SDWIM 2 "<general_hilo_operand>")))]
6751 "ix86_expand_binary_operator (MINUS, <MODE>mode, operands); DONE;")
6753 (define_insn_and_split "*sub<dwi>3_doubleword"
6754 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
6756 (match_operand:<DWI> 1 "nonimmediate_operand" "0,0")
6757 (match_operand:<DWI> 2 "x86_64_hilo_general_operand"
6759 (clobber (reg:CC FLAGS_REG))]
6760 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6763 [(parallel [(set (reg:CC FLAGS_REG)
6764 (compare:CC (match_dup 1) (match_dup 2)))
6766 (minus:DWIH (match_dup 1) (match_dup 2)))])
6767 (parallel [(set (match_dup 3)
6771 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0)))
6773 (clobber (reg:CC FLAGS_REG))])]
6775 split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
6776 if (operands[2] == const0_rtx)
6778 ix86_expand_binary_operator (MINUS, <MODE>mode, &operands[3]);
6783 (define_insn "*sub<mode>_1"
6784 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6786 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6787 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6788 (clobber (reg:CC FLAGS_REG))]
6789 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6790 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6791 [(set_attr "type" "alu")
6792 (set_attr "mode" "<MODE>")])
6794 (define_insn "*subsi_1_zext"
6795 [(set (match_operand:DI 0 "register_operand" "=r")
6797 (minus:SI (match_operand:SI 1 "register_operand" "0")
6798 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
6799 (clobber (reg:CC FLAGS_REG))]
6800 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6801 "sub{l}\t{%2, %k0|%k0, %2}"
6802 [(set_attr "type" "alu")
6803 (set_attr "mode" "SI")])
6805 (define_insn "*subqi_1_slp"
6806 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6807 (minus:QI (match_dup 0)
6808 (match_operand:QI 1 "general_operand" "qn,qm")))
6809 (clobber (reg:CC FLAGS_REG))]
6810 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6811 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
6812 "sub{b}\t{%1, %0|%0, %1}"
6813 [(set_attr "type" "alu1")
6814 (set_attr "mode" "QI")])
6816 (define_insn "*sub<mode>_2"
6817 [(set (reg FLAGS_REG)
6820 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6821 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6823 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6824 (minus:SWI (match_dup 1) (match_dup 2)))]
6825 "ix86_match_ccmode (insn, CCGOCmode)
6826 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6827 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6828 [(set_attr "type" "alu")
6829 (set_attr "mode" "<MODE>")])
6831 (define_insn "*subsi_2_zext"
6832 [(set (reg FLAGS_REG)
6834 (minus:SI (match_operand:SI 1 "register_operand" "0")
6835 (match_operand:SI 2 "x86_64_general_operand" "rme"))
6837 (set (match_operand:DI 0 "register_operand" "=r")
6839 (minus:SI (match_dup 1)
6841 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6842 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6843 "sub{l}\t{%2, %k0|%k0, %2}"
6844 [(set_attr "type" "alu")
6845 (set_attr "mode" "SI")])
6847 ;; Subtract with jump on overflow.
6848 (define_expand "subv<mode>4"
6849 [(parallel [(set (reg:CCO FLAGS_REG)
6850 (eq:CCO (minus:<DWI>
6852 (match_operand:SWI 1 "nonimmediate_operand"))
6855 (minus:SWI (match_dup 1)
6856 (match_operand:SWI 2
6857 "<general_operand>")))))
6858 (set (match_operand:SWI 0 "register_operand")
6859 (minus:SWI (match_dup 1) (match_dup 2)))])
6860 (set (pc) (if_then_else
6861 (eq (reg:CCO FLAGS_REG) (const_int 0))
6862 (label_ref (match_operand 3))
6866 ix86_fixup_binary_operands_no_copy (MINUS, <MODE>mode, operands);
6867 if (CONST_INT_P (operands[2]))
6868 operands[4] = operands[2];
6870 operands[4] = gen_rtx_SIGN_EXTEND (<DWI>mode, operands[2]);
6873 (define_insn "*subv<mode>4"
6874 [(set (reg:CCO FLAGS_REG)
6875 (eq:CCO (minus:<DWI>
6877 (match_operand:SWI 1 "nonimmediate_operand" "0,0"))
6879 (match_operand:SWI 2 "<general_sext_operand>"
6882 (minus:SWI (match_dup 1) (match_dup 2)))))
6883 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6884 (minus:SWI (match_dup 1) (match_dup 2)))]
6885 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6886 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6887 [(set_attr "type" "alu")
6888 (set_attr "mode" "<MODE>")])
6890 (define_insn "*subv<mode>4_1"
6891 [(set (reg:CCO FLAGS_REG)
6892 (eq:CCO (minus:<DWI>
6894 (match_operand:SWI 1 "nonimmediate_operand" "0"))
6895 (match_operand:<DWI> 3 "const_int_operand" "i"))
6897 (minus:SWI (match_dup 1)
6898 (match_operand:SWI 2 "x86_64_immediate_operand"
6900 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
6901 (minus:SWI (match_dup 1) (match_dup 2)))]
6902 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)
6903 && CONST_INT_P (operands[2])
6904 && INTVAL (operands[2]) == INTVAL (operands[3])"
6905 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6906 [(set_attr "type" "alu")
6907 (set_attr "mode" "<MODE>")
6908 (set (attr "length_immediate")
6909 (cond [(match_test "IN_RANGE (INTVAL (operands[2]), -128, 127)")
6911 (match_test "<MODE_SIZE> == 8")
6913 (const_string "<MODE_SIZE>")))])
6915 (define_expand "usubv<mode>4"
6916 [(parallel [(set (reg:CC FLAGS_REG)
6918 (match_operand:SWI 1 "nonimmediate_operand")
6919 (match_operand:SWI 2 "<general_operand>")))
6920 (set (match_operand:SWI 0 "register_operand")
6921 (minus:SWI (match_dup 1) (match_dup 2)))])
6922 (set (pc) (if_then_else
6923 (ltu (reg:CC FLAGS_REG) (const_int 0))
6924 (label_ref (match_operand 3))
6927 "ix86_fixup_binary_operands_no_copy (MINUS, <MODE>mode, operands);")
6929 (define_insn "*sub<mode>_3"
6930 [(set (reg FLAGS_REG)
6931 (compare (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6932 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6933 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6934 (minus:SWI (match_dup 1) (match_dup 2)))]
6935 "ix86_match_ccmode (insn, CCmode)
6936 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6937 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6938 [(set_attr "type" "alu")
6939 (set_attr "mode" "<MODE>")])
6943 [(set (reg:CC FLAGS_REG)
6944 (compare:CC (match_operand:SWI 0 "general_reg_operand")
6945 (match_operand:SWI 1 "general_gr_operand")))
6947 (minus:SWI (match_dup 0) (match_dup 1)))])]
6948 "find_regno_note (peep2_next_insn (0), REG_UNUSED, REGNO (operands[0])) != 0"
6949 [(set (reg:CC FLAGS_REG)
6950 (compare:CC (match_dup 0) (match_dup 1)))])
6952 (define_insn "*subsi_3_zext"
6953 [(set (reg FLAGS_REG)
6954 (compare (match_operand:SI 1 "register_operand" "0")
6955 (match_operand:SI 2 "x86_64_general_operand" "rme")))
6956 (set (match_operand:DI 0 "register_operand" "=r")
6958 (minus:SI (match_dup 1)
6960 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6961 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6962 "sub{l}\t{%2, %1|%1, %2}"
6963 [(set_attr "type" "alu")
6964 (set_attr "mode" "SI")])
6966 ;; Add with carry and subtract with borrow
6968 (define_insn "add<mode>3_carry"
6969 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6972 (match_operator:SWI 4 "ix86_carry_flag_operator"
6973 [(match_operand 3 "flags_reg_operand") (const_int 0)])
6974 (match_operand:SWI 1 "nonimmediate_operand" "%0,0"))
6975 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6976 (clobber (reg:CC FLAGS_REG))]
6977 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6978 "adc{<imodesuffix>}\t{%2, %0|%0, %2}"
6979 [(set_attr "type" "alu")
6980 (set_attr "use_carry" "1")
6981 (set_attr "pent_pair" "pu")
6982 (set_attr "mode" "<MODE>")])
6984 (define_insn "*add<mode>3_carry_0"
6985 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
6987 (match_operator:SWI 3 "ix86_carry_flag_operator"
6988 [(match_operand 2 "flags_reg_operand") (const_int 0)])
6989 (match_operand:SWI 1 "nonimmediate_operand" "0")))
6990 (clobber (reg:CC FLAGS_REG))]
6991 "ix86_unary_operator_ok (PLUS, <MODE>mode, operands)"
6992 "adc{<imodesuffix>}\t{$0, %0|%0, 0}"
6993 [(set_attr "type" "alu")
6994 (set_attr "use_carry" "1")
6995 (set_attr "pent_pair" "pu")
6996 (set_attr "mode" "<MODE>")])
6998 (define_insn "*addsi3_carry_zext"
6999 [(set (match_operand:DI 0 "register_operand" "=r")
7002 (plus:SI (match_operator:SI 3 "ix86_carry_flag_operator"
7003 [(reg FLAGS_REG) (const_int 0)])
7004 (match_operand:SI 1 "register_operand" "%0"))
7005 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
7006 (clobber (reg:CC FLAGS_REG))]
7007 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
7008 "adc{l}\t{%2, %k0|%k0, %2}"
7009 [(set_attr "type" "alu")
7010 (set_attr "use_carry" "1")
7011 (set_attr "pent_pair" "pu")
7012 (set_attr "mode" "SI")])
7014 (define_insn "*addsi3_carry_zext_0"
7015 [(set (match_operand:DI 0 "register_operand" "=r")
7017 (plus:SI (match_operator:SI 2 "ix86_carry_flag_operator"
7018 [(reg FLAGS_REG) (const_int 0)])
7019 (match_operand:SI 1 "register_operand" "0"))))
7020 (clobber (reg:CC FLAGS_REG))]
7022 "adc{l}\t{$0, %k0|%k0, 0}"
7023 [(set_attr "type" "alu")
7024 (set_attr "use_carry" "1")
7025 (set_attr "pent_pair" "pu")
7026 (set_attr "mode" "SI")])
7028 ;; There is no point to generate ADCX instruction. ADC is shorter and faster.
7030 (define_insn "addcarry<mode>"
7031 [(set (reg:CCC FLAGS_REG)
7036 (match_operator:SWI48 5 "ix86_carry_flag_operator"
7037 [(match_operand 3 "flags_reg_operand") (const_int 0)])
7038 (match_operand:SWI48 1 "nonimmediate_operand" "%0"))
7039 (match_operand:SWI48 2 "nonimmediate_operand" "rm")))
7041 (zero_extend:<DWI> (match_dup 2))
7042 (match_operator:<DWI> 4 "ix86_carry_flag_operator"
7043 [(match_dup 3) (const_int 0)]))))
7044 (set (match_operand:SWI48 0 "register_operand" "=r")
7045 (plus:SWI48 (plus:SWI48 (match_op_dup 5
7046 [(match_dup 3) (const_int 0)])
7049 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
7050 "adc{<imodesuffix>}\t{%2, %0|%0, %2}"
7051 [(set_attr "type" "alu")
7052 (set_attr "use_carry" "1")
7053 (set_attr "pent_pair" "pu")
7054 (set_attr "mode" "<MODE>")])
7056 (define_expand "addcarry<mode>_0"
7058 [(set (reg:CCC FLAGS_REG)
7061 (match_operand:SWI48 1 "nonimmediate_operand")
7062 (match_operand:SWI48 2 "x86_64_general_operand"))
7064 (set (match_operand:SWI48 0 "register_operand")
7065 (plus:SWI48 (match_dup 1) (match_dup 2)))])]
7066 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)")
7068 (define_insn "sub<mode>3_carry"
7069 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
7072 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
7073 (match_operator:SWI 4 "ix86_carry_flag_operator"
7074 [(match_operand 3 "flags_reg_operand") (const_int 0)]))
7075 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
7076 (clobber (reg:CC FLAGS_REG))]
7077 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
7078 "sbb{<imodesuffix>}\t{%2, %0|%0, %2}"
7079 [(set_attr "type" "alu")
7080 (set_attr "use_carry" "1")
7081 (set_attr "pent_pair" "pu")
7082 (set_attr "mode" "<MODE>")])
7084 (define_insn "*sub<mode>3_carry_0"
7085 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
7087 (match_operand:SWI 1 "nonimmediate_operand" "0")
7088 (match_operator:SWI 3 "ix86_carry_flag_operator"
7089 [(match_operand 2 "flags_reg_operand") (const_int 0)])))
7090 (clobber (reg:CC FLAGS_REG))]
7091 "ix86_unary_operator_ok (MINUS, <MODE>mode, operands)"
7092 "sbb{<imodesuffix>}\t{$0, %0|%0, 0}"
7093 [(set_attr "type" "alu")
7094 (set_attr "use_carry" "1")
7095 (set_attr "pent_pair" "pu")
7096 (set_attr "mode" "<MODE>")])
7098 (define_insn "*subsi3_carry_zext"
7099 [(set (match_operand:DI 0 "register_operand" "=r")
7103 (match_operand:SI 1 "register_operand" "0")
7104 (match_operator:SI 3 "ix86_carry_flag_operator"
7105 [(reg FLAGS_REG) (const_int 0)]))
7106 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
7107 (clobber (reg:CC FLAGS_REG))]
7108 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
7109 "sbb{l}\t{%2, %k0|%k0, %2}"
7110 [(set_attr "type" "alu")
7111 (set_attr "use_carry" "1")
7112 (set_attr "pent_pair" "pu")
7113 (set_attr "mode" "SI")])
7115 (define_insn "*subsi3_carry_zext_0"
7116 [(set (match_operand:DI 0 "register_operand" "=r")
7119 (match_operand:SI 1 "register_operand" "0")
7120 (match_operator:SI 2 "ix86_carry_flag_operator"
7121 [(reg FLAGS_REG) (const_int 0)]))))
7122 (clobber (reg:CC FLAGS_REG))]
7124 "sbb{l}\t{$0, %k0|%k0, 0}"
7125 [(set_attr "type" "alu")
7126 (set_attr "use_carry" "1")
7127 (set_attr "pent_pair" "pu")
7128 (set_attr "mode" "SI")])
7130 (define_insn "sub<mode>3_carry_ccc"
7131 [(set (reg:CCC FLAGS_REG)
7133 (zero_extend:<DWI> (match_operand:DWIH 1 "register_operand" "0"))
7135 (ltu:<DWI> (reg:CC FLAGS_REG) (const_int 0))
7137 (match_operand:DWIH 2 "x86_64_sext_operand" "rmWe")))))
7138 (clobber (match_scratch:DWIH 0 "=r"))]
7140 "sbb{<imodesuffix>}\t{%2, %0|%0, %2}"
7141 [(set_attr "type" "alu")
7142 (set_attr "mode" "<MODE>")])
7144 (define_insn "*sub<mode>3_carry_ccc_1"
7145 [(set (reg:CCC FLAGS_REG)
7147 (zero_extend:<DWI> (match_operand:DWIH 1 "register_operand" "0"))
7149 (ltu:<DWI> (reg:CC FLAGS_REG) (const_int 0))
7150 (match_operand:<DWI> 2 "x86_64_dwzext_immediate_operand" "Wf"))))
7151 (clobber (match_scratch:DWIH 0 "=r"))]
7154 operands[3] = simplify_subreg (<MODE>mode, operands[2], <DWI>mode, 0);
7155 return "sbb{<imodesuffix>}\t{%3, %0|%0, %3}";
7157 [(set_attr "type" "alu")
7158 (set_attr "mode" "<MODE>")])
7160 ;; The sign flag is set from the
7161 ;; (compare (match_dup 1) (plus:DWIH (ltu:DWIH ...) (match_dup 2)))
7162 ;; result, the overflow flag likewise, but the overflow flag is also
7163 ;; set if the (plus:DWIH (ltu:DWIH ...) (match_dup 2)) overflows.
7164 (define_insn "sub<mode>3_carry_ccgz"
7165 [(set (reg:CCGZ FLAGS_REG)
7166 (unspec:CCGZ [(match_operand:DWIH 1 "register_operand" "0")
7167 (match_operand:DWIH 2 "x86_64_general_operand" "rme")
7168 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))]
7170 (clobber (match_scratch:DWIH 0 "=r"))]
7172 "sbb{<imodesuffix>}\t{%2, %0|%0, %2}"
7173 [(set_attr "type" "alu")
7174 (set_attr "mode" "<MODE>")])
7176 (define_insn "subborrow<mode>"
7177 [(set (reg:CCC FLAGS_REG)
7180 (match_operand:SWI48 1 "nonimmediate_operand" "0"))
7182 (match_operator:<DWI> 4 "ix86_carry_flag_operator"
7183 [(match_operand 3 "flags_reg_operand") (const_int 0)])
7185 (match_operand:SWI48 2 "nonimmediate_operand" "rm")))))
7186 (set (match_operand:SWI48 0 "register_operand" "=r")
7187 (minus:SWI48 (minus:SWI48
7189 (match_operator:SWI48 5 "ix86_carry_flag_operator"
7190 [(match_dup 3) (const_int 0)]))
7192 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
7193 "sbb{<imodesuffix>}\t{%2, %0|%0, %2}"
7194 [(set_attr "type" "alu")
7195 (set_attr "use_carry" "1")
7196 (set_attr "pent_pair" "pu")
7197 (set_attr "mode" "<MODE>")])
7199 (define_expand "subborrow<mode>_0"
7201 [(set (reg:CC FLAGS_REG)
7203 (match_operand:SWI48 1 "nonimmediate_operand")
7204 (match_operand:SWI48 2 "<general_operand>")))
7205 (set (match_operand:SWI48 0 "register_operand")
7206 (minus:SWI48 (match_dup 1) (match_dup 2)))])]
7207 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)")
7209 ;; Overflow setting add instructions
7211 (define_expand "addqi3_cconly_overflow"
7213 [(set (reg:CCC FLAGS_REG)
7216 (match_operand:QI 0 "nonimmediate_operand")
7217 (match_operand:QI 1 "general_operand"))
7219 (clobber (match_scratch:QI 2))])]
7220 "!(MEM_P (operands[0]) && MEM_P (operands[1]))")
7222 (define_insn "*add<mode>3_cconly_overflow_1"
7223 [(set (reg:CCC FLAGS_REG)
7226 (match_operand:SWI 1 "nonimmediate_operand" "%0")
7227 (match_operand:SWI 2 "<general_operand>" "<g>"))
7229 (clobber (match_scratch:SWI 0 "=<r>"))]
7230 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7231 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
7232 [(set_attr "type" "alu")
7233 (set_attr "mode" "<MODE>")])
7235 (define_insn "*add<mode>3_cc_overflow_1"
7236 [(set (reg:CCC FLAGS_REG)
7239 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
7240 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
7242 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
7243 (plus:SWI (match_dup 1) (match_dup 2)))]
7244 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
7245 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
7246 [(set_attr "type" "alu")
7247 (set_attr "mode" "<MODE>")])
7249 (define_insn "*addsi3_zext_cc_overflow_1"
7250 [(set (reg:CCC FLAGS_REG)
7253 (match_operand:SI 1 "nonimmediate_operand" "%0")
7254 (match_operand:SI 2 "x86_64_general_operand" "rme"))
7256 (set (match_operand:DI 0 "register_operand" "=r")
7257 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
7258 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
7259 "add{l}\t{%2, %k0|%k0, %2}"
7260 [(set_attr "type" "alu")
7261 (set_attr "mode" "SI")])
7263 (define_insn "*add<mode>3_cconly_overflow_2"
7264 [(set (reg:CCC FLAGS_REG)
7267 (match_operand:SWI 1 "nonimmediate_operand" "%0")
7268 (match_operand:SWI 2 "<general_operand>" "<g>"))
7270 (clobber (match_scratch:SWI 0 "=<r>"))]
7271 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7272 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
7273 [(set_attr "type" "alu")
7274 (set_attr "mode" "<MODE>")])
7276 (define_insn "*add<mode>3_cc_overflow_2"
7277 [(set (reg:CCC FLAGS_REG)
7280 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
7281 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
7283 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
7284 (plus:SWI (match_dup 1) (match_dup 2)))]
7285 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
7286 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
7287 [(set_attr "type" "alu")
7288 (set_attr "mode" "<MODE>")])
7290 (define_insn "*addsi3_zext_cc_overflow_2"
7291 [(set (reg:CCC FLAGS_REG)
7294 (match_operand:SI 1 "nonimmediate_operand" "%0")
7295 (match_operand:SI 2 "x86_64_general_operand" "rme"))
7297 (set (match_operand:DI 0 "register_operand" "=r")
7298 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
7299 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
7300 "add{l}\t{%2, %k0|%k0, %2}"
7301 [(set_attr "type" "alu")
7302 (set_attr "mode" "SI")])
7304 ;; The patterns that match these are at the end of this file.
7306 (define_expand "<plusminus_insn>xf3"
7307 [(set (match_operand:XF 0 "register_operand")
7309 (match_operand:XF 1 "register_operand")
7310 (match_operand:XF 2 "register_operand")))]
7313 (define_expand "<plusminus_insn><mode>3"
7314 [(set (match_operand:MODEF 0 "register_operand")
7316 (match_operand:MODEF 1 "register_operand")
7317 (match_operand:MODEF 2 "nonimmediate_operand")))]
7318 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
7319 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
7321 ;; Multiply instructions
7323 (define_expand "mul<mode>3"
7324 [(parallel [(set (match_operand:SWIM248 0 "register_operand")
7326 (match_operand:SWIM248 1 "register_operand")
7327 (match_operand:SWIM248 2 "<general_operand>")))
7328 (clobber (reg:CC FLAGS_REG))])])
7330 (define_expand "mulqi3"
7331 [(parallel [(set (match_operand:QI 0 "register_operand")
7333 (match_operand:QI 1 "register_operand")
7334 (match_operand:QI 2 "nonimmediate_operand")))
7335 (clobber (reg:CC FLAGS_REG))])]
7336 "TARGET_QIMODE_MATH")
7339 ;; IMUL reg32/64, reg32/64, imm8 Direct
7340 ;; IMUL reg32/64, mem32/64, imm8 VectorPath
7341 ;; IMUL reg32/64, reg32/64, imm32 Direct
7342 ;; IMUL reg32/64, mem32/64, imm32 VectorPath
7343 ;; IMUL reg32/64, reg32/64 Direct
7344 ;; IMUL reg32/64, mem32/64 Direct
7346 ;; On BDVER1, all above IMULs use DirectPath
7349 ;; IMUL reg16, reg16, imm8 VectorPath
7350 ;; IMUL reg16, mem16, imm8 VectorPath
7351 ;; IMUL reg16, reg16, imm16 VectorPath
7352 ;; IMUL reg16, mem16, imm16 VectorPath
7353 ;; IMUL reg16, reg16 Direct
7354 ;; IMUL reg16, mem16 Direct
7356 ;; On BDVER1, all HI MULs use DoublePath
7358 (define_insn "*mul<mode>3_1"
7359 [(set (match_operand:SWIM248 0 "register_operand" "=r,r,r")
7361 (match_operand:SWIM248 1 "nonimmediate_operand" "%rm,rm,0")
7362 (match_operand:SWIM248 2 "<general_operand>" "K,<i>,mr")))
7363 (clobber (reg:CC FLAGS_REG))]
7364 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7366 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
7367 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
7368 imul{<imodesuffix>}\t{%2, %0|%0, %2}"
7369 [(set_attr "type" "imul")
7370 (set_attr "prefix_0f" "0,0,1")
7371 (set (attr "athlon_decode")
7372 (cond [(eq_attr "cpu" "athlon")
7373 (const_string "vector")
7374 (eq_attr "alternative" "1")
7375 (const_string "vector")
7376 (and (eq_attr "alternative" "2")
7377 (ior (match_test "<MODE>mode == HImode")
7378 (match_operand 1 "memory_operand")))
7379 (const_string "vector")]
7380 (const_string "direct")))
7381 (set (attr "amdfam10_decode")
7382 (cond [(and (eq_attr "alternative" "0,1")
7383 (ior (match_test "<MODE>mode == HImode")
7384 (match_operand 1 "memory_operand")))
7385 (const_string "vector")]
7386 (const_string "direct")))
7387 (set (attr "bdver1_decode")
7389 (match_test "<MODE>mode == HImode")
7390 (const_string "double")
7391 (const_string "direct")))
7392 (set_attr "mode" "<MODE>")])
7394 (define_insn "*mulsi3_1_zext"
7395 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
7397 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
7398 (match_operand:SI 2 "x86_64_general_operand" "K,e,mr"))))
7399 (clobber (reg:CC FLAGS_REG))]
7401 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7403 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7404 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7405 imul{l}\t{%2, %k0|%k0, %2}"
7406 [(set_attr "type" "imul")
7407 (set_attr "prefix_0f" "0,0,1")
7408 (set (attr "athlon_decode")
7409 (cond [(eq_attr "cpu" "athlon")
7410 (const_string "vector")
7411 (eq_attr "alternative" "1")
7412 (const_string "vector")
7413 (and (eq_attr "alternative" "2")
7414 (match_operand 1 "memory_operand"))
7415 (const_string "vector")]
7416 (const_string "direct")))
7417 (set (attr "amdfam10_decode")
7418 (cond [(and (eq_attr "alternative" "0,1")
7419 (match_operand 1 "memory_operand"))
7420 (const_string "vector")]
7421 (const_string "direct")))
7422 (set_attr "bdver1_decode" "direct")
7423 (set_attr "mode" "SI")])
7425 ;;On AMDFAM10 and BDVER1
7429 (define_insn "*mulqi3_1"
7430 [(set (match_operand:QI 0 "register_operand" "=a")
7431 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
7432 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7433 (clobber (reg:CC FLAGS_REG))]
7435 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7437 [(set_attr "type" "imul")
7438 (set_attr "length_immediate" "0")
7439 (set (attr "athlon_decode")
7440 (if_then_else (eq_attr "cpu" "athlon")
7441 (const_string "vector")
7442 (const_string "direct")))
7443 (set_attr "amdfam10_decode" "direct")
7444 (set_attr "bdver1_decode" "direct")
7445 (set_attr "mode" "QI")])
7447 ;; Multiply with jump on overflow.
7448 (define_expand "mulv<mode>4"
7449 [(parallel [(set (reg:CCO FLAGS_REG)
7452 (match_operand:SWI248 1 "register_operand"))
7455 (mult:SWI248 (match_dup 1)
7456 (match_operand:SWI248 2
7457 "<general_operand>")))))
7458 (set (match_operand:SWI248 0 "register_operand")
7459 (mult:SWI248 (match_dup 1) (match_dup 2)))])
7460 (set (pc) (if_then_else
7461 (eq (reg:CCO FLAGS_REG) (const_int 0))
7462 (label_ref (match_operand 3))
7466 if (CONST_INT_P (operands[2]))
7467 operands[4] = operands[2];
7469 operands[4] = gen_rtx_SIGN_EXTEND (<DWI>mode, operands[2]);
7472 (define_insn "*mulv<mode>4"
7473 [(set (reg:CCO FLAGS_REG)
7476 (match_operand:SWI48 1 "nonimmediate_operand" "%rm,0"))
7478 (match_operand:SWI48 2 "x86_64_sext_operand" "We,mr")))
7480 (mult:SWI48 (match_dup 1) (match_dup 2)))))
7481 (set (match_operand:SWI48 0 "register_operand" "=r,r")
7482 (mult:SWI48 (match_dup 1) (match_dup 2)))]
7483 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7485 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
7486 imul{<imodesuffix>}\t{%2, %0|%0, %2}"
7487 [(set_attr "type" "imul")
7488 (set_attr "prefix_0f" "0,1")
7489 (set (attr "athlon_decode")
7490 (cond [(eq_attr "cpu" "athlon")
7491 (const_string "vector")
7492 (eq_attr "alternative" "0")
7493 (const_string "vector")
7494 (and (eq_attr "alternative" "1")
7495 (match_operand 1 "memory_operand"))
7496 (const_string "vector")]
7497 (const_string "direct")))
7498 (set (attr "amdfam10_decode")
7499 (cond [(and (eq_attr "alternative" "1")
7500 (match_operand 1 "memory_operand"))
7501 (const_string "vector")]
7502 (const_string "direct")))
7503 (set_attr "bdver1_decode" "direct")
7504 (set_attr "mode" "<MODE>")])
7506 (define_insn "*mulvhi4"
7507 [(set (reg:CCO FLAGS_REG)
7510 (match_operand:HI 1 "nonimmediate_operand" "%0"))
7512 (match_operand:HI 2 "nonimmediate_operand" "mr")))
7514 (mult:HI (match_dup 1) (match_dup 2)))))
7515 (set (match_operand:HI 0 "register_operand" "=r")
7516 (mult:HI (match_dup 1) (match_dup 2)))]
7517 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7518 "imul{w}\t{%2, %0|%0, %2}"
7519 [(set_attr "type" "imul")
7520 (set_attr "prefix_0f" "1")
7521 (set_attr "athlon_decode" "vector")
7522 (set_attr "amdfam10_decode" "direct")
7523 (set_attr "bdver1_decode" "double")
7524 (set_attr "mode" "HI")])
7526 (define_insn "*mulv<mode>4_1"
7527 [(set (reg:CCO FLAGS_REG)
7530 (match_operand:SWI248 1 "nonimmediate_operand" "rm,rm"))
7531 (match_operand:<DWI> 3 "const_int_operand" "K,i"))
7533 (mult:SWI248 (match_dup 1)
7534 (match_operand:SWI248 2
7535 "<immediate_operand>" "K,<i>")))))
7536 (set (match_operand:SWI248 0 "register_operand" "=r,r")
7537 (mult:SWI248 (match_dup 1) (match_dup 2)))]
7538 "!(MEM_P (operands[1]) && MEM_P (operands[2]))
7539 && CONST_INT_P (operands[2])
7540 && INTVAL (operands[2]) == INTVAL (operands[3])"
7541 "imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}"
7542 [(set_attr "type" "imul")
7543 (set (attr "prefix_0f")
7545 (match_test "<MODE>mode == HImode")
7547 (const_string "*")))
7548 (set (attr "athlon_decode")
7549 (cond [(eq_attr "cpu" "athlon")
7550 (const_string "vector")
7551 (eq_attr "alternative" "1")
7552 (const_string "vector")]
7553 (const_string "direct")))
7554 (set (attr "amdfam10_decode")
7555 (cond [(ior (match_test "<MODE>mode == HImode")
7556 (match_operand 1 "memory_operand"))
7557 (const_string "vector")]
7558 (const_string "direct")))
7559 (set (attr "bdver1_decode")
7561 (match_test "<MODE>mode == HImode")
7562 (const_string "double")
7563 (const_string "direct")))
7564 (set_attr "mode" "<MODE>")
7565 (set (attr "length_immediate")
7566 (cond [(eq_attr "alternative" "0")
7568 (match_test "<MODE_SIZE> == 8")
7570 (const_string "<MODE_SIZE>")))])
7572 (define_expand "umulv<mode>4"
7573 [(parallel [(set (reg:CCO FLAGS_REG)
7576 (match_operand:SWI248 1
7577 "nonimmediate_operand"))
7579 (match_operand:SWI248 2
7580 "nonimmediate_operand")))
7582 (mult:SWI248 (match_dup 1) (match_dup 2)))))
7583 (set (match_operand:SWI248 0 "register_operand")
7584 (mult:SWI248 (match_dup 1) (match_dup 2)))
7585 (clobber (match_scratch:SWI248 4))])
7586 (set (pc) (if_then_else
7587 (eq (reg:CCO FLAGS_REG) (const_int 0))
7588 (label_ref (match_operand 3))
7592 if (MEM_P (operands[1]) && MEM_P (operands[2]))
7593 operands[1] = force_reg (<MODE>mode, operands[1]);
7596 (define_insn "*umulv<mode>4"
7597 [(set (reg:CCO FLAGS_REG)
7600 (match_operand:SWI248 1 "nonimmediate_operand" "%0"))
7602 (match_operand:SWI248 2 "nonimmediate_operand" "rm")))
7604 (mult:SWI248 (match_dup 1) (match_dup 2)))))
7605 (set (match_operand:SWI248 0 "register_operand" "=a")
7606 (mult:SWI248 (match_dup 1) (match_dup 2)))
7607 (clobber (match_scratch:SWI248 3 "=d"))]
7608 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7609 "mul{<imodesuffix>}\t%2"
7610 [(set_attr "type" "imul")
7611 (set_attr "length_immediate" "0")
7612 (set (attr "athlon_decode")
7613 (if_then_else (eq_attr "cpu" "athlon")
7614 (const_string "vector")
7615 (const_string "double")))
7616 (set_attr "amdfam10_decode" "double")
7617 (set_attr "bdver1_decode" "direct")
7618 (set_attr "mode" "<MODE>")])
7620 (define_expand "<u>mulvqi4"
7621 [(parallel [(set (reg:CCO FLAGS_REG)
7624 (match_operand:QI 1 "nonimmediate_operand"))
7626 (match_operand:QI 2 "nonimmediate_operand")))
7628 (mult:QI (match_dup 1) (match_dup 2)))))
7629 (set (match_operand:QI 0 "register_operand")
7630 (mult:QI (match_dup 1) (match_dup 2)))])
7631 (set (pc) (if_then_else
7632 (eq (reg:CCO FLAGS_REG) (const_int 0))
7633 (label_ref (match_operand 3))
7635 "TARGET_QIMODE_MATH"
7637 if (MEM_P (operands[1]) && MEM_P (operands[2]))
7638 operands[1] = force_reg (QImode, operands[1]);
7641 (define_insn "*<u>mulvqi4"
7642 [(set (reg:CCO FLAGS_REG)
7645 (match_operand:QI 1 "nonimmediate_operand" "%0"))
7647 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7649 (mult:QI (match_dup 1) (match_dup 2)))))
7650 (set (match_operand:QI 0 "register_operand" "=a")
7651 (mult:QI (match_dup 1) (match_dup 2)))]
7653 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7654 "<sgnprefix>mul{b}\t%2"
7655 [(set_attr "type" "imul")
7656 (set_attr "length_immediate" "0")
7657 (set (attr "athlon_decode")
7658 (if_then_else (eq_attr "cpu" "athlon")
7659 (const_string "vector")
7660 (const_string "direct")))
7661 (set_attr "amdfam10_decode" "direct")
7662 (set_attr "bdver1_decode" "direct")
7663 (set_attr "mode" "QI")])
7665 (define_expand "<u>mul<mode><dwi>3"
7666 [(parallel [(set (match_operand:<DWI> 0 "register_operand")
7669 (match_operand:DWIH 1 "nonimmediate_operand"))
7671 (match_operand:DWIH 2 "register_operand"))))
7672 (clobber (reg:CC FLAGS_REG))])])
7674 (define_expand "<u>mulqihi3"
7675 [(parallel [(set (match_operand:HI 0 "register_operand")
7678 (match_operand:QI 1 "nonimmediate_operand"))
7680 (match_operand:QI 2 "register_operand"))))
7681 (clobber (reg:CC FLAGS_REG))])]
7682 "TARGET_QIMODE_MATH")
7684 (define_insn "*bmi2_umul<mode><dwi>3_1"
7685 [(set (match_operand:DWIH 0 "register_operand" "=r")
7687 (match_operand:DWIH 2 "nonimmediate_operand" "%d")
7688 (match_operand:DWIH 3 "nonimmediate_operand" "rm")))
7689 (set (match_operand:DWIH 1 "register_operand" "=r")
7692 (mult:<DWI> (zero_extend:<DWI> (match_dup 2))
7693 (zero_extend:<DWI> (match_dup 3)))
7694 (match_operand:QI 4 "const_int_operand" "n"))))]
7695 "TARGET_BMI2 && INTVAL (operands[4]) == <MODE_SIZE> * BITS_PER_UNIT
7696 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7697 "mulx\t{%3, %0, %1|%1, %0, %3}"
7698 [(set_attr "type" "imulx")
7699 (set_attr "prefix" "vex")
7700 (set_attr "mode" "<MODE>")])
7702 (define_insn "*umul<mode><dwi>3_1"
7703 [(set (match_operand:<DWI> 0 "register_operand" "=r,A")
7706 (match_operand:DWIH 1 "nonimmediate_operand" "%d,0"))
7708 (match_operand:DWIH 2 "nonimmediate_operand" "rm,rm"))))
7709 (clobber (reg:CC FLAGS_REG))]
7710 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7713 mul{<imodesuffix>}\t%2"
7714 [(set_attr "isa" "bmi2,*")
7715 (set_attr "type" "imulx,imul")
7716 (set_attr "length_immediate" "*,0")
7717 (set (attr "athlon_decode")
7718 (cond [(eq_attr "alternative" "1")
7719 (if_then_else (eq_attr "cpu" "athlon")
7720 (const_string "vector")
7721 (const_string "double"))]
7722 (const_string "*")))
7723 (set_attr "amdfam10_decode" "*,double")
7724 (set_attr "bdver1_decode" "*,direct")
7725 (set_attr "prefix" "vex,orig")
7726 (set_attr "mode" "<MODE>")])
7728 ;; Convert mul to the mulx pattern to avoid flags dependency.
7730 [(set (match_operand:<DWI> 0 "register_operand")
7733 (match_operand:DWIH 1 "register_operand"))
7735 (match_operand:DWIH 2 "nonimmediate_operand"))))
7736 (clobber (reg:CC FLAGS_REG))]
7737 "TARGET_BMI2 && reload_completed
7738 && REGNO (operands[1]) == DX_REG"
7739 [(parallel [(set (match_dup 3)
7740 (mult:DWIH (match_dup 1) (match_dup 2)))
7744 (mult:<DWI> (zero_extend:<DWI> (match_dup 1))
7745 (zero_extend:<DWI> (match_dup 2)))
7748 split_double_mode (<DWI>mode, &operands[0], 1, &operands[3], &operands[4]);
7750 operands[5] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT);
7753 (define_insn "*mul<mode><dwi>3_1"
7754 [(set (match_operand:<DWI> 0 "register_operand" "=A")
7757 (match_operand:DWIH 1 "nonimmediate_operand" "%0"))
7759 (match_operand:DWIH 2 "nonimmediate_operand" "rm"))))
7760 (clobber (reg:CC FLAGS_REG))]
7761 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7762 "imul{<imodesuffix>}\t%2"
7763 [(set_attr "type" "imul")
7764 (set_attr "length_immediate" "0")
7765 (set (attr "athlon_decode")
7766 (if_then_else (eq_attr "cpu" "athlon")
7767 (const_string "vector")
7768 (const_string "double")))
7769 (set_attr "amdfam10_decode" "double")
7770 (set_attr "bdver1_decode" "direct")
7771 (set_attr "mode" "<MODE>")])
7773 (define_insn "*<u>mulqihi3_1"
7774 [(set (match_operand:HI 0 "register_operand" "=a")
7777 (match_operand:QI 1 "nonimmediate_operand" "%0"))
7779 (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7780 (clobber (reg:CC FLAGS_REG))]
7782 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7783 "<sgnprefix>mul{b}\t%2"
7784 [(set_attr "type" "imul")
7785 (set_attr "length_immediate" "0")
7786 (set (attr "athlon_decode")
7787 (if_then_else (eq_attr "cpu" "athlon")
7788 (const_string "vector")
7789 (const_string "direct")))
7790 (set_attr "amdfam10_decode" "direct")
7791 (set_attr "bdver1_decode" "direct")
7792 (set_attr "mode" "QI")])
7794 (define_expand "<s>mul<mode>3_highpart"
7795 [(parallel [(set (match_operand:SWI48 0 "register_operand")
7800 (match_operand:SWI48 1 "nonimmediate_operand"))
7802 (match_operand:SWI48 2 "register_operand")))
7804 (clobber (match_scratch:SWI48 4))
7805 (clobber (reg:CC FLAGS_REG))])]
7807 "operands[3] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
7809 (define_insn "*<s>muldi3_highpart_1"
7810 [(set (match_operand:DI 0 "register_operand" "=d")
7815 (match_operand:DI 1 "nonimmediate_operand" "%a"))
7817 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7819 (clobber (match_scratch:DI 3 "=1"))
7820 (clobber (reg:CC FLAGS_REG))]
7822 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7823 "<sgnprefix>mul{q}\t%2"
7824 [(set_attr "type" "imul")
7825 (set_attr "length_immediate" "0")
7826 (set (attr "athlon_decode")
7827 (if_then_else (eq_attr "cpu" "athlon")
7828 (const_string "vector")
7829 (const_string "double")))
7830 (set_attr "amdfam10_decode" "double")
7831 (set_attr "bdver1_decode" "direct")
7832 (set_attr "mode" "DI")])
7834 (define_insn "*<s>mulsi3_highpart_zext"
7835 [(set (match_operand:DI 0 "register_operand" "=d")
7836 (zero_extend:DI (truncate:SI
7838 (mult:DI (any_extend:DI
7839 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7841 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7843 (clobber (match_scratch:SI 3 "=1"))
7844 (clobber (reg:CC FLAGS_REG))]
7846 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7847 "<sgnprefix>mul{l}\t%2"
7848 [(set_attr "type" "imul")
7849 (set_attr "length_immediate" "0")
7850 (set (attr "athlon_decode")
7851 (if_then_else (eq_attr "cpu" "athlon")
7852 (const_string "vector")
7853 (const_string "double")))
7854 (set_attr "amdfam10_decode" "double")
7855 (set_attr "bdver1_decode" "direct")
7856 (set_attr "mode" "SI")])
7858 (define_insn "*<s>mulsi3_highpart_1"
7859 [(set (match_operand:SI 0 "register_operand" "=d")
7864 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7866 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7868 (clobber (match_scratch:SI 3 "=1"))
7869 (clobber (reg:CC FLAGS_REG))]
7870 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7871 "<sgnprefix>mul{l}\t%2"
7872 [(set_attr "type" "imul")
7873 (set_attr "length_immediate" "0")
7874 (set (attr "athlon_decode")
7875 (if_then_else (eq_attr "cpu" "athlon")
7876 (const_string "vector")
7877 (const_string "double")))
7878 (set_attr "amdfam10_decode" "double")
7879 (set_attr "bdver1_decode" "direct")
7880 (set_attr "mode" "SI")])
7882 ;; The patterns that match these are at the end of this file.
7884 (define_expand "mulxf3"
7885 [(set (match_operand:XF 0 "register_operand")
7886 (mult:XF (match_operand:XF 1 "register_operand")
7887 (match_operand:XF 2 "register_operand")))]
7890 (define_expand "mul<mode>3"
7891 [(set (match_operand:MODEF 0 "register_operand")
7892 (mult:MODEF (match_operand:MODEF 1 "register_operand")
7893 (match_operand:MODEF 2 "nonimmediate_operand")))]
7894 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
7895 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
7897 ;; Divide instructions
7899 ;; The patterns that match these are at the end of this file.
7901 (define_expand "divxf3"
7902 [(set (match_operand:XF 0 "register_operand")
7903 (div:XF (match_operand:XF 1 "register_operand")
7904 (match_operand:XF 2 "register_operand")))]
7907 (define_expand "div<mode>3"
7908 [(set (match_operand:MODEF 0 "register_operand")
7909 (div:MODEF (match_operand:MODEF 1 "register_operand")
7910 (match_operand:MODEF 2 "nonimmediate_operand")))]
7911 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
7912 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
7914 if (<MODE>mode == SFmode
7915 && TARGET_SSE && TARGET_SSE_MATH
7917 && optimize_insn_for_speed_p ()
7918 && flag_finite_math_only && !flag_trapping_math
7919 && flag_unsafe_math_optimizations)
7921 ix86_emit_swdivsf (operands[0], operands[1],
7922 operands[2], SFmode);
7927 ;; Divmod instructions.
7929 (define_expand "divmod<mode>4"
7930 [(parallel [(set (match_operand:SWIM248 0 "register_operand")
7932 (match_operand:SWIM248 1 "register_operand")
7933 (match_operand:SWIM248 2 "nonimmediate_operand")))
7934 (set (match_operand:SWIM248 3 "register_operand")
7935 (mod:SWIM248 (match_dup 1) (match_dup 2)))
7936 (clobber (reg:CC FLAGS_REG))])])
7938 ;; Split with 8bit unsigned divide:
7939 ;; if (dividend an divisor are in [0-255])
7940 ;; use 8bit unsigned integer divide
7942 ;; use original integer divide
7944 [(set (match_operand:SWI48 0 "register_operand")
7945 (div:SWI48 (match_operand:SWI48 2 "register_operand")
7946 (match_operand:SWI48 3 "nonimmediate_operand")))
7947 (set (match_operand:SWI48 1 "register_operand")
7948 (mod:SWI48 (match_dup 2) (match_dup 3)))
7949 (clobber (reg:CC FLAGS_REG))]
7950 "TARGET_USE_8BIT_IDIV
7951 && TARGET_QIMODE_MATH
7952 && can_create_pseudo_p ()
7953 && !optimize_insn_for_size_p ()"
7955 "ix86_split_idivmod (<MODE>mode, operands, true); DONE;")
7958 [(set (match_operand:DI 0 "register_operand")
7960 (div:SI (match_operand:SI 2 "register_operand")
7961 (match_operand:SI 3 "nonimmediate_operand"))))
7962 (set (match_operand:SI 1 "register_operand")
7963 (mod:SI (match_dup 2) (match_dup 3)))
7964 (clobber (reg:CC FLAGS_REG))]
7965 "TARGET_USE_8BIT_IDIV
7966 && TARGET_QIMODE_MATH
7967 && can_create_pseudo_p ()
7968 && !optimize_insn_for_size_p ()"
7970 "ix86_split_idivmod (SImode, operands, true); DONE;")
7973 [(set (match_operand:DI 1 "register_operand")
7975 (mod:SI (match_operand:SI 2 "register_operand")
7976 (match_operand:SI 3 "nonimmediate_operand"))))
7977 (set (match_operand:SI 0 "register_operand")
7978 (div:SI (match_dup 2) (match_dup 3)))
7979 (clobber (reg:CC FLAGS_REG))]
7980 "TARGET_USE_8BIT_IDIV
7981 && TARGET_QIMODE_MATH
7982 && can_create_pseudo_p ()
7983 && !optimize_insn_for_size_p ()"
7985 "ix86_split_idivmod (SImode, operands, true); DONE;")
7987 (define_insn_and_split "divmod<mode>4_1"
7988 [(set (match_operand:SWI48 0 "register_operand" "=a")
7989 (div:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7990 (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
7991 (set (match_operand:SWI48 1 "register_operand" "=&d")
7992 (mod:SWI48 (match_dup 2) (match_dup 3)))
7993 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7994 (clobber (reg:CC FLAGS_REG))]
7998 [(parallel [(set (match_dup 1)
7999 (ashiftrt:SWI48 (match_dup 4) (match_dup 5)))
8000 (clobber (reg:CC FLAGS_REG))])
8001 (parallel [(set (match_dup 0)
8002 (div:SWI48 (match_dup 2) (match_dup 3)))
8004 (mod:SWI48 (match_dup 2) (match_dup 3)))
8006 (clobber (reg:CC FLAGS_REG))])]
8008 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
8010 if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
8011 operands[4] = operands[2];
8014 /* Avoid use of cltd in favor of a mov+shift. */
8015 emit_move_insn (operands[1], operands[2]);
8016 operands[4] = operands[1];
8019 [(set_attr "type" "multi")
8020 (set_attr "mode" "<MODE>")])
8022 (define_insn_and_split "divmodsi4_zext_1"
8023 [(set (match_operand:DI 0 "register_operand" "=a")
8025 (div:SI (match_operand:SI 2 "register_operand" "0")
8026 (match_operand:SI 3 "nonimmediate_operand" "rm"))))
8027 (set (match_operand:SI 1 "register_operand" "=&d")
8028 (mod:SI (match_dup 2) (match_dup 3)))
8029 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
8030 (clobber (reg:CC FLAGS_REG))]
8034 [(parallel [(set (match_dup 1)
8035 (ashiftrt:SI (match_dup 4) (match_dup 5)))
8036 (clobber (reg:CC FLAGS_REG))])
8037 (parallel [(set (match_dup 0)
8038 (zero_extend:DI (div:SI (match_dup 2) (match_dup 3))))
8040 (mod:SI (match_dup 2) (match_dup 3)))
8042 (clobber (reg:CC FLAGS_REG))])]
8044 operands[5] = GEN_INT (GET_MODE_BITSIZE (SImode)-1);
8046 if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
8047 operands[4] = operands[2];
8050 /* Avoid use of cltd in favor of a mov+shift. */
8051 emit_move_insn (operands[1], operands[2]);
8052 operands[4] = operands[1];
8055 [(set_attr "type" "multi")
8056 (set_attr "mode" "SI")])
8058 (define_insn_and_split "divmodsi4_zext_2"
8059 [(set (match_operand:DI 1 "register_operand" "=&d")
8061 (mod:SI (match_operand:SI 2 "register_operand" "0")
8062 (match_operand:SI 3 "nonimmediate_operand" "rm"))))
8063 (set (match_operand:SI 0 "register_operand" "=a")
8064 (div:SI (match_dup 2) (match_dup 3)))
8065 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
8066 (clobber (reg:CC FLAGS_REG))]
8070 [(parallel [(set (match_dup 6)
8071 (ashiftrt:SI (match_dup 4) (match_dup 5)))
8072 (clobber (reg:CC FLAGS_REG))])
8073 (parallel [(set (match_dup 1)
8074 (zero_extend:DI (mod:SI (match_dup 2) (match_dup 3))))
8076 (div:SI (match_dup 2) (match_dup 3)))
8078 (clobber (reg:CC FLAGS_REG))])]
8080 operands[5] = GEN_INT (GET_MODE_BITSIZE (SImode)-1);
8081 operands[6] = gen_lowpart (SImode, operands[1]);
8083 if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
8084 operands[4] = operands[2];
8087 /* Avoid use of cltd in favor of a mov+shift. */
8088 emit_move_insn (operands[6], operands[2]);
8089 operands[4] = operands[6];
8092 [(set_attr "type" "multi")
8093 (set_attr "mode" "SI")])
8095 (define_insn_and_split "*divmod<mode>4"
8096 [(set (match_operand:SWIM248 0 "register_operand" "=a")
8097 (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
8098 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
8099 (set (match_operand:SWIM248 1 "register_operand" "=&d")
8100 (mod:SWIM248 (match_dup 2) (match_dup 3)))
8101 (clobber (reg:CC FLAGS_REG))]
8105 [(parallel [(set (match_dup 1)
8106 (ashiftrt:SWIM248 (match_dup 4) (match_dup 5)))
8107 (clobber (reg:CC FLAGS_REG))])
8108 (parallel [(set (match_dup 0)
8109 (div:SWIM248 (match_dup 2) (match_dup 3)))
8111 (mod:SWIM248 (match_dup 2) (match_dup 3)))
8113 (clobber (reg:CC FLAGS_REG))])]
8115 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
8117 if (<MODE>mode != HImode
8118 && (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD))
8119 operands[4] = operands[2];
8122 /* Avoid use of cltd in favor of a mov+shift. */
8123 emit_move_insn (operands[1], operands[2]);
8124 operands[4] = operands[1];
8127 [(set_attr "type" "multi")
8128 (set_attr "mode" "<MODE>")])
8130 (define_insn_and_split "*divmodsi4_zext_1"
8131 [(set (match_operand:DI 0 "register_operand" "=a")
8133 (div:SI (match_operand:SI 2 "register_operand" "0")
8134 (match_operand:SI 3 "nonimmediate_operand" "rm"))))
8135 (set (match_operand:SI 1 "register_operand" "=&d")
8136 (mod:SI (match_dup 2) (match_dup 3)))
8137 (clobber (reg:CC FLAGS_REG))]
8141 [(parallel [(set (match_dup 1)
8142 (ashiftrt:SI (match_dup 4) (match_dup 5)))
8143 (clobber (reg:CC FLAGS_REG))])
8144 (parallel [(set (match_dup 0)
8145 (zero_extend:DI (div:SI (match_dup 2) (match_dup 3))))
8147 (mod:SI (match_dup 2) (match_dup 3)))
8149 (clobber (reg:CC FLAGS_REG))])]
8151 operands[5] = GEN_INT (GET_MODE_BITSIZE (SImode)-1);
8153 if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
8154 operands[4] = operands[2];
8157 /* Avoid use of cltd in favor of a mov+shift. */
8158 emit_move_insn (operands[1], operands[2]);
8159 operands[4] = operands[1];
8162 [(set_attr "type" "multi")
8163 (set_attr "mode" "SI")])
8165 (define_insn_and_split "*divmodsi4_zext_2"
8166 [(set (match_operand:DI 1 "register_operand" "=&d")
8168 (mod:SI (match_operand:SI 2 "register_operand" "0")
8169 (match_operand:SI 3 "nonimmediate_operand" "rm"))))
8170 (set (match_operand:SI 0 "register_operand" "=a")
8171 (div:SI (match_dup 2) (match_dup 3)))
8172 (clobber (reg:CC FLAGS_REG))]
8176 [(parallel [(set (match_dup 6)
8177 (ashiftrt:SI (match_dup 4) (match_dup 5)))
8178 (clobber (reg:CC FLAGS_REG))])
8179 (parallel [(set (match_dup 1)
8180 (zero_extend:DI (mod:SI (match_dup 2) (match_dup 3))))
8182 (div:SI (match_dup 2) (match_dup 3)))
8184 (clobber (reg:CC FLAGS_REG))])]
8186 operands[5] = GEN_INT (GET_MODE_BITSIZE (SImode)-1);
8187 operands[6] = gen_lowpart (SImode, operands[1]);
8189 if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
8190 operands[4] = operands[2];
8193 /* Avoid use of cltd in favor of a mov+shift. */
8194 emit_move_insn (operands[6], operands[2]);
8195 operands[4] = operands[6];
8198 [(set_attr "type" "multi")
8199 (set_attr "mode" "SI")])
8201 (define_insn "*divmod<mode>4_noext"
8202 [(set (match_operand:SWIM248 0 "register_operand" "=a")
8203 (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
8204 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
8205 (set (match_operand:SWIM248 1 "register_operand" "=d")
8206 (mod:SWIM248 (match_dup 2) (match_dup 3)))
8207 (use (match_operand:SWIM248 4 "register_operand" "1"))
8208 (clobber (reg:CC FLAGS_REG))]
8210 "idiv{<imodesuffix>}\t%3"
8211 [(set_attr "type" "idiv")
8212 (set_attr "mode" "<MODE>")])
8214 (define_insn "*divmodsi4_noext_zext_1"
8215 [(set (match_operand:DI 0 "register_operand" "=a")
8217 (div:SI (match_operand:SI 2 "register_operand" "0")
8218 (match_operand:SI 3 "nonimmediate_operand" "rm"))))
8219 (set (match_operand:SI 1 "register_operand" "=d")
8220 (mod:SI (match_dup 2) (match_dup 3)))
8221 (use (match_operand:SI 4 "register_operand" "1"))
8222 (clobber (reg:CC FLAGS_REG))]
8225 [(set_attr "type" "idiv")
8226 (set_attr "mode" "SI")])
8228 (define_insn "*divmodsi4_noext_zext_2"
8229 [(set (match_operand:DI 1 "register_operand" "=d")
8231 (mod:SI (match_operand:SI 2 "register_operand" "0")
8232 (match_operand:SI 3 "nonimmediate_operand" "rm"))))
8233 (set (match_operand:SI 0 "register_operand" "=a")
8234 (div:SI (match_dup 2) (match_dup 3)))
8235 (use (match_operand:SI 4 "register_operand" "1"))
8236 (clobber (reg:CC FLAGS_REG))]
8239 [(set_attr "type" "idiv")
8240 (set_attr "mode" "SI")])
8242 (define_expand "divmodqi4"
8243 [(parallel [(set (match_operand:QI 0 "register_operand")
8245 (match_operand:QI 1 "register_operand")
8246 (match_operand:QI 2 "nonimmediate_operand")))
8247 (set (match_operand:QI 3 "register_operand")
8248 (mod:QI (match_dup 1) (match_dup 2)))
8249 (clobber (reg:CC FLAGS_REG))])]
8250 "TARGET_QIMODE_MATH"
8255 tmp0 = gen_reg_rtx (HImode);
8256 tmp1 = gen_reg_rtx (HImode);
8258 /* Extend operands[1] to HImode. Generate 8bit divide. Result is in AX. */
8259 emit_insn (gen_extendqihi2 (tmp1, operands[1]));
8260 emit_insn (gen_divmodhiqi3 (tmp0, tmp1, operands[2]));
8262 /* Extract remainder from AH. */
8263 tmp1 = gen_rtx_ZERO_EXTRACT (SImode, tmp0, GEN_INT (8), GEN_INT (8));
8264 tmp1 = lowpart_subreg (QImode, tmp1, SImode);
8265 rtx_insn *insn = emit_move_insn (operands[3], tmp1);
8267 mod = gen_rtx_MOD (QImode, operands[1], operands[2]);
8268 set_unique_reg_note (insn, REG_EQUAL, mod);
8270 /* Extract quotient from AL. */
8271 insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
8273 div = gen_rtx_DIV (QImode, operands[1], operands[2]);
8274 set_unique_reg_note (insn, REG_EQUAL, div);
8279 ;; Divide AX by r/m8, with result stored in
8282 ;; Change div/mod to HImode and extend the second argument to HImode
8283 ;; so that mode of div/mod matches with mode of arguments. Otherwise
8284 ;; combine may fail.
8285 (define_insn "divmodhiqi3"
8286 [(set (match_operand:HI 0 "register_operand" "=a")
8291 (mod:HI (match_operand:HI 1 "register_operand" "0")
8293 (match_operand:QI 2 "nonimmediate_operand" "qm")))))
8297 (div:HI (match_dup 1) (sign_extend:HI (match_dup 2)))))))
8298 (clobber (reg:CC FLAGS_REG))]
8299 "TARGET_QIMODE_MATH"
8301 [(set_attr "type" "idiv")
8302 (set_attr "mode" "QI")])
8304 (define_expand "udivmod<mode>4"
8305 [(parallel [(set (match_operand:SWIM248 0 "register_operand")
8307 (match_operand:SWIM248 1 "register_operand")
8308 (match_operand:SWIM248 2 "nonimmediate_operand")))
8309 (set (match_operand:SWIM248 3 "register_operand")
8310 (umod:SWIM248 (match_dup 1) (match_dup 2)))
8311 (clobber (reg:CC FLAGS_REG))])])
8313 ;; Split with 8bit unsigned divide:
8314 ;; if (dividend an divisor are in [0-255])
8315 ;; use 8bit unsigned integer divide
8317 ;; use original integer divide
8319 [(set (match_operand:SWI48 0 "register_operand")
8320 (udiv:SWI48 (match_operand:SWI48 2 "register_operand")
8321 (match_operand:SWI48 3 "nonimmediate_operand")))
8322 (set (match_operand:SWI48 1 "register_operand")
8323 (umod:SWI48 (match_dup 2) (match_dup 3)))
8324 (clobber (reg:CC FLAGS_REG))]
8325 "TARGET_USE_8BIT_IDIV
8326 && TARGET_QIMODE_MATH
8327 && can_create_pseudo_p ()
8328 && !optimize_insn_for_size_p ()"
8330 "ix86_split_idivmod (<MODE>mode, operands, false); DONE;")
8333 [(set (match_operand:DI 0 "register_operand")
8335 (udiv:SI (match_operand:SI 2 "register_operand")
8336 (match_operand:SI 3 "nonimmediate_operand"))))
8337 (set (match_operand:SI 1 "register_operand")
8338 (umod:SI (match_dup 2) (match_dup 3)))
8339 (clobber (reg:CC FLAGS_REG))]
8341 && TARGET_USE_8BIT_IDIV
8342 && TARGET_QIMODE_MATH
8343 && can_create_pseudo_p ()
8344 && !optimize_insn_for_size_p ()"
8346 "ix86_split_idivmod (SImode, operands, false); DONE;")
8349 [(set (match_operand:DI 1 "register_operand")
8351 (umod:SI (match_operand:SI 2 "register_operand")
8352 (match_operand:SI 3 "nonimmediate_operand"))))
8353 (set (match_operand:SI 0 "register_operand")
8354 (udiv:SI (match_dup 2) (match_dup 3)))
8355 (clobber (reg:CC FLAGS_REG))]
8357 && TARGET_USE_8BIT_IDIV
8358 && TARGET_QIMODE_MATH
8359 && can_create_pseudo_p ()
8360 && !optimize_insn_for_size_p ()"
8362 "ix86_split_idivmod (SImode, operands, false); DONE;")
8364 (define_insn_and_split "udivmod<mode>4_1"
8365 [(set (match_operand:SWI48 0 "register_operand" "=a")
8366 (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "0")
8367 (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
8368 (set (match_operand:SWI48 1 "register_operand" "=&d")
8369 (umod:SWI48 (match_dup 2) (match_dup 3)))
8370 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
8371 (clobber (reg:CC FLAGS_REG))]
8375 [(set (match_dup 1) (const_int 0))
8376 (parallel [(set (match_dup 0)
8377 (udiv:SWI48 (match_dup 2) (match_dup 3)))
8379 (umod:SWI48 (match_dup 2) (match_dup 3)))
8381 (clobber (reg:CC FLAGS_REG))])]
8383 [(set_attr "type" "multi")
8384 (set_attr "mode" "<MODE>")])
8386 (define_insn_and_split "udivmodsi4_zext_1"
8387 [(set (match_operand:DI 0 "register_operand" "=a")
8389 (udiv:SI (match_operand:SI 2 "register_operand" "0")
8390 (match_operand:SI 3 "nonimmediate_operand" "rm"))))
8391 (set (match_operand:SI 1 "register_operand" "=&d")
8392 (umod:SI (match_dup 2) (match_dup 3)))
8393 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
8394 (clobber (reg:CC FLAGS_REG))]
8398 [(set (match_dup 1) (const_int 0))
8399 (parallel [(set (match_dup 0)
8400 (zero_extend:DI (udiv:SI (match_dup 2) (match_dup 3))))
8402 (umod:SI (match_dup 2) (match_dup 3)))
8404 (clobber (reg:CC FLAGS_REG))])]
8406 [(set_attr "type" "multi")
8407 (set_attr "mode" "SI")])
8409 (define_insn_and_split "udivmodsi4_zext_2"
8410 [(set (match_operand:DI 1 "register_operand" "=&d")
8412 (umod:SI (match_operand:SI 2 "register_operand" "0")
8413 (match_operand:SI 3 "nonimmediate_operand" "rm"))))
8414 (set (match_operand:SI 0 "register_operand" "=a")
8415 (udiv:SI (match_dup 2) (match_dup 3)))
8416 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
8417 (clobber (reg:CC FLAGS_REG))]
8421 [(set (match_dup 4) (const_int 0))
8422 (parallel [(set (match_dup 1)
8423 (zero_extend:DI (umod:SI (match_dup 2) (match_dup 3))))
8425 (udiv:SI (match_dup 2) (match_dup 3)))
8427 (clobber (reg:CC FLAGS_REG))])]
8428 "operands[4] = gen_lowpart (SImode, operands[1]);"
8429 [(set_attr "type" "multi")
8430 (set_attr "mode" "SI")])
8432 (define_insn_and_split "*udivmod<mode>4"
8433 [(set (match_operand:SWIM248 0 "register_operand" "=a")
8434 (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
8435 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
8436 (set (match_operand:SWIM248 1 "register_operand" "=&d")
8437 (umod:SWIM248 (match_dup 2) (match_dup 3)))
8438 (clobber (reg:CC FLAGS_REG))]
8442 [(set (match_dup 1) (const_int 0))
8443 (parallel [(set (match_dup 0)
8444 (udiv:SWIM248 (match_dup 2) (match_dup 3)))
8446 (umod:SWIM248 (match_dup 2) (match_dup 3)))
8448 (clobber (reg:CC FLAGS_REG))])]
8450 [(set_attr "type" "multi")
8451 (set_attr "mode" "<MODE>")])
8453 (define_insn_and_split "*udivmodsi4_zext_1"
8454 [(set (match_operand:DI 0 "register_operand" "=a")
8456 (udiv:SI (match_operand:SI 2 "register_operand" "0")
8457 (match_operand:SI 3 "nonimmediate_operand" "rm"))))
8458 (set (match_operand:SI 1 "register_operand" "=&d")
8459 (umod:SI (match_dup 2) (match_dup 3)))
8460 (clobber (reg:CC FLAGS_REG))]
8464 [(set (match_dup 1) (const_int 0))
8465 (parallel [(set (match_dup 0)
8466 (zero_extend:DI (udiv:SI (match_dup 2) (match_dup 3))))
8468 (umod:SI (match_dup 2) (match_dup 3)))
8470 (clobber (reg:CC FLAGS_REG))])]
8472 [(set_attr "type" "multi")
8473 (set_attr "mode" "SI")])
8475 (define_insn_and_split "*udivmodsi4_zext_2"
8476 [(set (match_operand:DI 1 "register_operand" "=&d")
8478 (umod:SI (match_operand:SI 2 "register_operand" "0")
8479 (match_operand:SI 3 "nonimmediate_operand" "rm"))))
8480 (set (match_operand:SI 0 "register_operand" "=a")
8481 (udiv:SI (match_dup 2) (match_dup 3)))
8482 (clobber (reg:CC FLAGS_REG))]
8486 [(set (match_dup 4) (const_int 0))
8487 (parallel [(set (match_dup 1)
8488 (zero_extend:DI (umod:SI (match_dup 2) (match_dup 3))))
8490 (udiv:SI (match_dup 2) (match_dup 3)))
8492 (clobber (reg:CC FLAGS_REG))])]
8493 "operands[4] = gen_lowpart (SImode, operands[1]);"
8494 [(set_attr "type" "multi")
8495 (set_attr "mode" "SI")])
8497 ;; Optimize division or modulo by constant power of 2, if the constant
8498 ;; materializes only after expansion.
8499 (define_insn_and_split "*udivmod<mode>4_pow2"
8500 [(set (match_operand:SWI48 0 "register_operand" "=r")
8501 (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "0")
8502 (match_operand:SWI48 3 "const_int_operand" "n")))
8503 (set (match_operand:SWI48 1 "register_operand" "=r")
8504 (umod:SWI48 (match_dup 2) (match_dup 3)))
8505 (clobber (reg:CC FLAGS_REG))]
8506 "IN_RANGE (INTVAL (operands[3]), 2, HOST_WIDE_INT_UC (0x80000000))
8507 && (UINTVAL (operands[3]) & (UINTVAL (operands[3]) - 1)) == 0"
8510 [(set (match_dup 1) (match_dup 2))
8511 (parallel [(set (match_dup 0) (lshiftrt:<MODE> (match_dup 2) (match_dup 4)))
8512 (clobber (reg:CC FLAGS_REG))])
8513 (parallel [(set (match_dup 1) (and:<MODE> (match_dup 1) (match_dup 5)))
8514 (clobber (reg:CC FLAGS_REG))])]
8516 int v = exact_log2 (UINTVAL (operands[3]));
8517 operands[4] = GEN_INT (v);
8518 operands[5] = GEN_INT ((HOST_WIDE_INT_1U << v) - 1);
8520 [(set_attr "type" "multi")
8521 (set_attr "mode" "<MODE>")])
8523 (define_insn_and_split "*udivmodsi4_pow2_zext_1"
8524 [(set (match_operand:DI 0 "register_operand" "=r")
8526 (udiv:SI (match_operand:SI 2 "register_operand" "0")
8527 (match_operand:SI 3 "const_int_operand" "n"))))
8528 (set (match_operand:SI 1 "register_operand" "=r")
8529 (umod:SI (match_dup 2) (match_dup 3)))
8530 (clobber (reg:CC FLAGS_REG))]
8532 && IN_RANGE (INTVAL (operands[3]), 2, HOST_WIDE_INT_UC (0x80000000))
8533 && (UINTVAL (operands[3]) & (UINTVAL (operands[3]) - 1)) == 0"
8536 [(set (match_dup 1) (match_dup 2))
8537 (parallel [(set (match_dup 0)
8538 (zero_extend:DI (lshiftrt:SI (match_dup 2) (match_dup 4))))
8539 (clobber (reg:CC FLAGS_REG))])
8540 (parallel [(set (match_dup 1) (and:SI (match_dup 1) (match_dup 5)))
8541 (clobber (reg:CC FLAGS_REG))])]
8543 int v = exact_log2 (UINTVAL (operands[3]));
8544 operands[4] = GEN_INT (v);
8545 operands[5] = GEN_INT ((HOST_WIDE_INT_1U << v) - 1);
8547 [(set_attr "type" "multi")
8548 (set_attr "mode" "SI")])
8550 (define_insn_and_split "*udivmodsi4_pow2_zext_2"
8551 [(set (match_operand:DI 1 "register_operand" "=r")
8553 (umod:SI (match_operand:SI 2 "register_operand" "0")
8554 (match_operand:SI 3 "const_int_operand" "n"))))
8555 (set (match_operand:SI 0 "register_operand" "=r")
8556 (umod:SI (match_dup 2) (match_dup 3)))
8557 (clobber (reg:CC FLAGS_REG))]
8559 && IN_RANGE (INTVAL (operands[3]), 2, HOST_WIDE_INT_UC (0x80000000))
8560 && (UINTVAL (operands[3]) & (UINTVAL (operands[3]) - 1)) == 0"
8563 [(set (match_dup 1) (match_dup 2))
8564 (parallel [(set (match_dup 0) (lshiftrt:SI (match_dup 2) (match_dup 4)))
8565 (clobber (reg:CC FLAGS_REG))])
8566 (parallel [(set (match_dup 1)
8567 (zero_extend:DI (and:SI (match_dup 1) (match_dup 5))))
8568 (clobber (reg:CC FLAGS_REG))])]
8570 int v = exact_log2 (UINTVAL (operands[3]));
8571 operands[4] = GEN_INT (v);
8572 operands[5] = GEN_INT ((HOST_WIDE_INT_1U << v) - 1);
8574 [(set_attr "type" "multi")
8575 (set_attr "mode" "SI")])
8577 (define_insn "*udivmod<mode>4_noext"
8578 [(set (match_operand:SWIM248 0 "register_operand" "=a")
8579 (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
8580 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
8581 (set (match_operand:SWIM248 1 "register_operand" "=d")
8582 (umod:SWIM248 (match_dup 2) (match_dup 3)))
8583 (use (match_operand:SWIM248 4 "register_operand" "1"))
8584 (clobber (reg:CC FLAGS_REG))]
8586 "div{<imodesuffix>}\t%3"
8587 [(set_attr "type" "idiv")
8588 (set_attr "mode" "<MODE>")])
8590 (define_insn "*udivmodsi4_noext_zext_1"
8591 [(set (match_operand:DI 0 "register_operand" "=a")
8593 (udiv:SI (match_operand:SI 2 "register_operand" "0")
8594 (match_operand:SI 3 "nonimmediate_operand" "rm"))))
8595 (set (match_operand:SI 1 "register_operand" "=d")
8596 (umod:SI (match_dup 2) (match_dup 3)))
8597 (use (match_operand:SI 4 "register_operand" "1"))
8598 (clobber (reg:CC FLAGS_REG))]
8601 [(set_attr "type" "idiv")
8602 (set_attr "mode" "SI")])
8604 (define_insn "*udivmodsi4_noext_zext_2"
8605 [(set (match_operand:DI 1 "register_operand" "=d")
8607 (umod:SI (match_operand:SI 2 "register_operand" "0")
8608 (match_operand:SI 3 "nonimmediate_operand" "rm"))))
8609 (set (match_operand:SI 0 "register_operand" "=a")
8610 (udiv:SI (match_dup 2) (match_dup 3)))
8611 (use (match_operand:SI 4 "register_operand" "1"))
8612 (clobber (reg:CC FLAGS_REG))]
8615 [(set_attr "type" "idiv")
8616 (set_attr "mode" "SI")])
8618 (define_expand "udivmodqi4"
8619 [(parallel [(set (match_operand:QI 0 "register_operand")
8621 (match_operand:QI 1 "register_operand")
8622 (match_operand:QI 2 "nonimmediate_operand")))
8623 (set (match_operand:QI 3 "register_operand")
8624 (umod:QI (match_dup 1) (match_dup 2)))
8625 (clobber (reg:CC FLAGS_REG))])]
8626 "TARGET_QIMODE_MATH"
8631 tmp0 = gen_reg_rtx (HImode);
8632 tmp1 = gen_reg_rtx (HImode);
8634 /* Extend operands[1] to HImode. Generate 8bit divide. Result is in AX. */
8635 emit_insn (gen_zero_extendqihi2 (tmp1, operands[1]));
8636 emit_insn (gen_udivmodhiqi3 (tmp0, tmp1, operands[2]));
8638 /* Extract remainder from AH. */
8639 tmp1 = gen_rtx_ZERO_EXTRACT (SImode, tmp0, GEN_INT (8), GEN_INT (8));
8640 tmp1 = lowpart_subreg (QImode, tmp1, SImode);
8641 rtx_insn *insn = emit_move_insn (operands[3], tmp1);
8643 mod = gen_rtx_UMOD (QImode, operands[1], operands[2]);
8644 set_unique_reg_note (insn, REG_EQUAL, mod);
8646 /* Extract quotient from AL. */
8647 insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
8649 div = gen_rtx_UDIV (QImode, operands[1], operands[2]);
8650 set_unique_reg_note (insn, REG_EQUAL, div);
8655 (define_insn "udivmodhiqi3"
8656 [(set (match_operand:HI 0 "register_operand" "=a")
8661 (mod:HI (match_operand:HI 1 "register_operand" "0")
8663 (match_operand:QI 2 "nonimmediate_operand" "qm")))))
8667 (div:HI (match_dup 1) (zero_extend:HI (match_dup 2)))))))
8668 (clobber (reg:CC FLAGS_REG))]
8669 "TARGET_QIMODE_MATH"
8671 [(set_attr "type" "idiv")
8672 (set_attr "mode" "QI")])
8674 ;; We cannot use div/idiv for double division, because it causes
8675 ;; "division by zero" on the overflow and that's not what we expect
8676 ;; from truncate. Because true (non truncating) double division is
8677 ;; never generated, we can't create this insn anyway.
8680 ; [(set (match_operand:SI 0 "register_operand" "=a")
8682 ; (udiv:DI (match_operand:DI 1 "register_operand" "A")
8684 ; (match_operand:SI 2 "nonimmediate_operand" "rm")))))
8685 ; (set (match_operand:SI 3 "register_operand" "=d")
8687 ; (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
8688 ; (clobber (reg:CC FLAGS_REG))]
8690 ; "div{l}\t{%2, %0|%0, %2}"
8691 ; [(set_attr "type" "idiv")])
8693 ;;- Logical AND instructions
8695 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
8696 ;; Note that this excludes ah.
8698 (define_expand "testsi_ccno_1"
8699 [(set (reg:CCNO FLAGS_REG)
8701 (and:SI (match_operand:SI 0 "nonimmediate_operand")
8702 (match_operand:SI 1 "x86_64_nonmemory_operand"))
8705 (define_expand "testqi_ccz_1"
8706 [(set (reg:CCZ FLAGS_REG)
8707 (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand")
8708 (match_operand:QI 1 "nonmemory_operand"))
8711 (define_expand "testdi_ccno_1"
8712 [(set (reg:CCNO FLAGS_REG)
8714 (and:DI (match_operand:DI 0 "nonimmediate_operand")
8715 (match_operand:DI 1 "x86_64_szext_general_operand"))
8717 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))")
8719 (define_insn "*testdi_1"
8720 [(set (reg FLAGS_REG)
8723 (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
8724 (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
8726 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8727 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8729 test{l}\t{%k1, %k0|%k0, %k1}
8730 test{l}\t{%k1, %k0|%k0, %k1}
8731 test{q}\t{%1, %0|%0, %1}
8732 test{q}\t{%1, %0|%0, %1}
8733 test{q}\t{%1, %0|%0, %1}"
8734 [(set_attr "type" "test")
8735 (set_attr "modrm" "0,1,0,1,1")
8736 (set_attr "mode" "SI,SI,DI,DI,DI")])
8738 (define_insn "*testqi_1_maybe_si"
8739 [(set (reg FLAGS_REG)
8742 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
8743 (match_operand:QI 1 "general_operand" "n,n,qn,n"))
8745 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
8746 && ix86_match_ccmode (insn,
8747 CONST_INT_P (operands[1])
8748 && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
8750 if (which_alternative == 3)
8752 if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
8753 operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
8754 return "test{l}\t{%1, %k0|%k0, %1}";
8756 return "test{b}\t{%1, %0|%0, %1}";
8758 [(set_attr "type" "test")
8759 (set_attr "modrm" "0,1,1,1")
8760 (set_attr "mode" "QI,QI,QI,SI")
8761 (set_attr "pent_pair" "uv,np,uv,np")])
8763 (define_insn "*test<mode>_1"
8764 [(set (reg FLAGS_REG)
8767 (match_operand:SWI124 0 "nonimmediate_operand" "%!*a,<r>,<r>m")
8768 (match_operand:SWI124 1 "<general_operand>" "<i>,<i>,<r><i>"))
8770 "ix86_match_ccmode (insn, CCNOmode)
8771 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8772 "test{<imodesuffix>}\t{%1, %0|%0, %1}"
8773 [(set_attr "type" "test")
8774 (set_attr "modrm" "0,1,1")
8775 (set_attr "mode" "<MODE>")
8776 (set_attr "pent_pair" "uv,np,uv")])
8778 (define_expand "testqi_ext_1_ccno"
8779 [(set (reg:CCNO FLAGS_REG)
8783 (zero_extract:SI (match_operand 0 "ext_register_operand")
8786 (match_operand 1 "const_int_operand"))
8789 (define_insn "*testqi_ext_1"
8790 [(set (reg FLAGS_REG)
8794 (zero_extract:SI (match_operand 0 "ext_register_operand" "Q,Q")
8797 (match_operand:QI 1 "general_operand" "QnBc,m"))
8799 "ix86_match_ccmode (insn, CCNOmode)"
8800 "test{b}\t{%1, %h0|%h0, %1}"
8801 [(set_attr "isa" "*,nox64")
8802 (set_attr "type" "test")
8803 (set_attr "mode" "QI")])
8805 (define_insn "*testqi_ext_2"
8806 [(set (reg FLAGS_REG)
8810 (zero_extract:SI (match_operand 0 "ext_register_operand" "Q")
8814 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q")
8818 "ix86_match_ccmode (insn, CCNOmode)"
8819 "test{b}\t{%h1, %h0|%h0, %h1}"
8820 [(set_attr "type" "test")
8821 (set_attr "mode" "QI")])
8823 ;; Combine likes to form bit extractions for some tests. Humor it.
8824 (define_insn_and_split "*testqi_ext_3"
8825 [(set (match_operand 0 "flags_reg_operand")
8826 (match_operator 1 "compare_operator"
8827 [(zero_extract:SWI248
8828 (match_operand 2 "nonimmediate_operand" "rm")
8829 (match_operand 3 "const_int_operand" "n")
8830 (match_operand 4 "const_int_operand" "n"))
8832 "ix86_match_ccmode (insn, CCNOmode)
8833 && ((TARGET_64BIT && GET_MODE (operands[2]) == DImode)
8834 || GET_MODE (operands[2]) == SImode
8835 || GET_MODE (operands[2]) == HImode
8836 || GET_MODE (operands[2]) == QImode)
8837 /* Ensure that resulting mask is zero or sign extended operand. */
8838 && INTVAL (operands[4]) >= 0
8839 && ((INTVAL (operands[3]) > 0
8840 && INTVAL (operands[3]) + INTVAL (operands[4]) <= 32)
8841 || (<MODE>mode == DImode
8842 && INTVAL (operands[3]) > 32
8843 && INTVAL (operands[3]) + INTVAL (operands[4]) == 64))"
8846 [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
8848 rtx val = operands[2];
8849 HOST_WIDE_INT len = INTVAL (operands[3]);
8850 HOST_WIDE_INT pos = INTVAL (operands[4]);
8851 machine_mode mode = GET_MODE (val);
8855 machine_mode submode = GET_MODE (SUBREG_REG (val));
8857 /* Narrow paradoxical subregs to prevent partial register stalls. */
8858 if (GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode)
8859 && GET_MODE_CLASS (submode) == MODE_INT)
8861 val = SUBREG_REG (val);
8866 /* Small HImode tests can be converted to QImode. */
8867 if (register_operand (val, HImode) && pos + len <= 8)
8869 val = gen_lowpart (QImode, val);
8873 gcc_assert (pos + len <= GET_MODE_PRECISION (mode));
8876 = wi::shifted_mask (pos, len, false, GET_MODE_PRECISION (mode));
8878 operands[2] = gen_rtx_AND (mode, val, immed_wide_int_const (mask, mode));
8881 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
8882 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
8883 ;; this is relatively important trick.
8884 ;; Do the conversion only post-reload to avoid limiting of the register class
8887 [(set (match_operand 0 "flags_reg_operand")
8888 (match_operator 1 "compare_operator"
8889 [(and (match_operand 2 "QIreg_operand")
8890 (match_operand 3 "const_int_operand"))
8893 && GET_MODE (operands[2]) != QImode
8894 && ((ix86_match_ccmode (insn, CCZmode)
8895 && !(INTVAL (operands[3]) & ~(255 << 8)))
8896 || (ix86_match_ccmode (insn, CCNOmode)
8897 && !(INTVAL (operands[3]) & ~(127 << 8))))"
8902 (zero_extract:SI (match_dup 2)
8908 operands[2] = gen_lowpart (SImode, operands[2]);
8909 operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, QImode);
8913 [(set (match_operand 0 "flags_reg_operand")
8914 (match_operator 1 "compare_operator"
8915 [(and (match_operand 2 "nonimmediate_operand")
8916 (match_operand 3 "const_int_operand"))
8919 && GET_MODE (operands[2]) != QImode
8920 && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
8921 && ((ix86_match_ccmode (insn, CCZmode)
8922 && !(INTVAL (operands[3]) & ~255))
8923 || (ix86_match_ccmode (insn, CCNOmode)
8924 && !(INTVAL (operands[3]) & ~127)))"
8926 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
8929 operands[2] = gen_lowpart (QImode, operands[2]);
8930 operands[3] = gen_int_mode (INTVAL (operands[3]), QImode);
8933 ;; %%% This used to optimize known byte-wide and operations to memory,
8934 ;; and sometimes to QImode registers. If this is considered useful,
8935 ;; it should be done with splitters.
8937 (define_expand "and<mode>3"
8938 [(set (match_operand:SWIM1248x 0 "nonimmediate_operand")
8939 (and:SWIM1248x (match_operand:SWIM1248x 1 "nonimmediate_operand")
8940 (match_operand:SWIM1248x 2 "<general_szext_operand>")))]
8943 machine_mode mode = <MODE>mode;
8944 rtx (*insn) (rtx, rtx);
8946 if (CONST_INT_P (operands[2]) && REG_P (operands[0]))
8948 HOST_WIDE_INT ival = INTVAL (operands[2]);
8950 if (ival == (HOST_WIDE_INT) 0xffffffff)
8952 else if (ival == 0xffff)
8954 else if (ival == 0xff)
8958 if (mode == <MODE>mode)
8960 ix86_expand_binary_operator (AND, <MODE>mode, operands);
8964 if (<MODE>mode == DImode)
8965 insn = (mode == SImode)
8966 ? gen_zero_extendsidi2
8968 ? gen_zero_extendhidi2
8969 : gen_zero_extendqidi2;
8970 else if (<MODE>mode == SImode)
8971 insn = (mode == HImode)
8972 ? gen_zero_extendhisi2
8973 : gen_zero_extendqisi2;
8974 else if (<MODE>mode == HImode)
8975 insn = gen_zero_extendqihi2;
8979 emit_insn (insn (operands[0], gen_lowpart (mode, operands[1])));
8983 (define_insn_and_split "*anddi3_doubleword"
8984 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r")
8986 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8987 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm")))
8988 (clobber (reg:CC FLAGS_REG))]
8989 "!TARGET_64BIT && TARGET_STV && TARGET_SSE2
8990 && ix86_binary_operator_ok (AND, DImode, operands)"
8992 "&& reload_completed"
8995 split_double_mode (DImode, &operands[0], 3, &operands[0], &operands[3]);
8996 if (operands[2] == const0_rtx)
8998 operands[1] = const0_rtx;
8999 ix86_expand_move (SImode, &operands[0]);
9001 else if (operands[2] != constm1_rtx)
9002 ix86_expand_binary_operator (AND, SImode, &operands[0]);
9003 else if (operands[5] == constm1_rtx)
9004 emit_note (NOTE_INSN_DELETED);
9005 if (operands[5] == const0_rtx)
9007 operands[4] = const0_rtx;
9008 ix86_expand_move (SImode, &operands[3]);
9010 else if (operands[5] != constm1_rtx)
9011 ix86_expand_binary_operator (AND, SImode, &operands[3]);
9015 (define_insn "*anddi_1"
9016 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
9018 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
9019 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
9020 (clobber (reg:CC FLAGS_REG))]
9021 "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
9023 and{l}\t{%k2, %k0|%k0, %k2}
9024 and{q}\t{%2, %0|%0, %2}
9025 and{q}\t{%2, %0|%0, %2}
9027 [(set_attr "type" "alu,alu,alu,imovx")
9028 (set_attr "length_immediate" "*,*,*,0")
9029 (set (attr "prefix_rex")
9031 (and (eq_attr "type" "imovx")
9032 (and (match_test "INTVAL (operands[2]) == 0xff")
9033 (match_operand 1 "ext_QIreg_operand")))
9035 (const_string "*")))
9036 (set_attr "mode" "SI,DI,DI,SI")])
9038 (define_insn_and_split "*anddi_1_btr"
9039 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9041 (match_operand:DI 1 "nonimmediate_operand" "%0")
9042 (match_operand:DI 2 "const_int_operand" "n")))
9043 (clobber (reg:CC FLAGS_REG))]
9044 "TARGET_64BIT && TARGET_USE_BT
9045 && ix86_binary_operator_ok (AND, DImode, operands)
9046 && IN_RANGE (exact_log2 (~INTVAL (operands[2])), 31, 63)"
9048 "&& reload_completed"
9049 [(parallel [(set (zero_extract:DI (match_dup 0)
9053 (clobber (reg:CC FLAGS_REG))])]
9054 "operands[3] = GEN_INT (exact_log2 (~INTVAL (operands[2])));"
9055 [(set_attr "type" "alu1")
9056 (set_attr "prefix_0f" "1")
9057 (set_attr "znver1_decode" "double")
9058 (set_attr "mode" "DI")])
9060 ;; Turn *anddi_1 into *andsi_1_zext if possible.
9062 [(set (match_operand:DI 0 "register_operand")
9063 (and:DI (subreg:DI (match_operand:SI 1 "register_operand") 0)
9064 (match_operand:DI 2 "x86_64_zext_immediate_operand")))
9065 (clobber (reg:CC FLAGS_REG))]
9067 [(parallel [(set (match_dup 0)
9068 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))
9069 (clobber (reg:CC FLAGS_REG))])]
9070 "operands[2] = gen_lowpart (SImode, operands[2]);")
9072 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9073 (define_insn "*andsi_1_zext"
9074 [(set (match_operand:DI 0 "register_operand" "=r")
9076 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9077 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
9078 (clobber (reg:CC FLAGS_REG))]
9079 "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
9080 "and{l}\t{%2, %k0|%k0, %2}"
9081 [(set_attr "type" "alu")
9082 (set_attr "mode" "SI")])
9084 (define_insn "*and<mode>_1"
9085 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=rm,r,Ya")
9086 (and:SWI24 (match_operand:SWI24 1 "nonimmediate_operand" "%0,0,qm")
9087 (match_operand:SWI24 2 "<general_operand>" "r<i>,rm,L")))
9088 (clobber (reg:CC FLAGS_REG))]
9089 "ix86_binary_operator_ok (AND, <MODE>mode, operands)"
9091 and{<imodesuffix>}\t{%2, %0|%0, %2}
9092 and{<imodesuffix>}\t{%2, %0|%0, %2}
9094 [(set_attr "type" "alu,alu,imovx")
9095 (set_attr "length_immediate" "*,*,0")
9096 (set (attr "prefix_rex")
9098 (and (eq_attr "type" "imovx")
9099 (and (match_test "INTVAL (operands[2]) == 0xff")
9100 (match_operand 1 "ext_QIreg_operand")))
9102 (const_string "*")))
9103 (set_attr "mode" "<MODE>,<MODE>,SI")])
9105 (define_insn "*andqi_1"
9106 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
9107 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9108 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
9109 (clobber (reg:CC FLAGS_REG))]
9110 "ix86_binary_operator_ok (AND, QImode, operands)"
9112 and{b}\t{%2, %0|%0, %2}
9113 and{b}\t{%2, %0|%0, %2}
9114 and{l}\t{%k2, %k0|%k0, %k2}"
9115 [(set_attr "type" "alu")
9116 (set_attr "mode" "QI,QI,SI")
9117 ;; Potential partial reg stall on alternative 2.
9118 (set (attr "preferred_for_speed")
9119 (cond [(eq_attr "alternative" "2")
9120 (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
9121 (symbol_ref "true")))])
9123 (define_insn "*andqi_1_slp"
9124 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
9125 (and:QI (match_dup 0)
9126 (match_operand:QI 1 "general_operand" "qn,qmn")))
9127 (clobber (reg:CC FLAGS_REG))]
9128 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9129 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9130 "and{b}\t{%1, %0|%0, %1}"
9131 [(set_attr "type" "alu1")
9132 (set_attr "mode" "QI")])
9135 [(set (match_operand:SWI248 0 "register_operand")
9136 (and:SWI248 (match_operand:SWI248 1 "nonimmediate_operand")
9137 (match_operand:SWI248 2 "const_int_operand")))
9138 (clobber (reg:CC FLAGS_REG))]
9140 && (!REG_P (operands[1])
9141 || REGNO (operands[0]) != REGNO (operands[1]))"
9144 HOST_WIDE_INT ival = INTVAL (operands[2]);
9146 rtx (*insn) (rtx, rtx);
9148 if (ival == (HOST_WIDE_INT) 0xffffffff)
9150 else if (ival == 0xffff)
9154 gcc_assert (ival == 0xff);
9158 if (<MODE>mode == DImode)
9159 insn = (mode == SImode)
9160 ? gen_zero_extendsidi2
9162 ? gen_zero_extendhidi2
9163 : gen_zero_extendqidi2;
9166 if (<MODE>mode != SImode)
9167 /* Zero extend to SImode to avoid partial register stalls. */
9168 operands[0] = gen_lowpart (SImode, operands[0]);
9170 insn = (mode == HImode)
9171 ? gen_zero_extendhisi2
9172 : gen_zero_extendqisi2;
9174 emit_insn (insn (operands[0], gen_lowpart (mode, operands[1])));
9179 [(set (match_operand:SWI48 0 "register_operand")
9180 (and:SWI48 (match_dup 0)
9181 (const_int -65536)))
9182 (clobber (reg:CC FLAGS_REG))]
9183 "(TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)
9184 || optimize_function_for_size_p (cfun)"
9185 [(set (strict_low_part (match_dup 1)) (const_int 0))]
9186 "operands[1] = gen_lowpart (HImode, operands[0]);")
9189 [(set (match_operand:SWI248 0 "any_QIreg_operand")
9190 (and:SWI248 (match_dup 0)
9192 (clobber (reg:CC FLAGS_REG))]
9193 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9194 && reload_completed"
9195 [(set (strict_low_part (match_dup 1)) (const_int 0))]
9196 "operands[1] = gen_lowpart (QImode, operands[0]);")
9199 [(set (match_operand:SWI248 0 "QIreg_operand")
9200 (and:SWI248 (match_dup 0)
9201 (const_int -65281)))
9202 (clobber (reg:CC FLAGS_REG))]
9203 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9204 && reload_completed"
9206 [(set (zero_extract:SI (match_dup 0)
9212 (zero_extract:SI (match_dup 0)
9216 (zero_extract:SI (match_dup 0)
9218 (const_int 8)) 0)) 0))
9219 (clobber (reg:CC FLAGS_REG))])]
9220 "operands[0] = gen_lowpart (SImode, operands[0]);")
9222 (define_insn "*anddi_2"
9223 [(set (reg FLAGS_REG)
9226 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
9227 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
9229 (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
9230 (and:DI (match_dup 1) (match_dup 2)))]
9232 && ix86_match_ccmode
9234 /* If we are going to emit andl instead of andq, and the operands[2]
9235 constant might have the SImode sign bit set, make sure the sign
9236 flag isn't tested, because the instruction will set the sign flag
9237 based on bit 31 rather than bit 63. If it isn't CONST_INT,
9238 conservatively assume it might have bit 31 set. */
9239 (satisfies_constraint_Z (operands[2])
9240 && (!CONST_INT_P (operands[2])
9241 || val_signbit_known_set_p (SImode, INTVAL (operands[2]))))
9242 ? CCZmode : CCNOmode)
9243 && ix86_binary_operator_ok (AND, DImode, operands)"
9245 and{l}\t{%k2, %k0|%k0, %k2}
9246 and{q}\t{%2, %0|%0, %2}
9247 and{q}\t{%2, %0|%0, %2}"
9248 [(set_attr "type" "alu")
9249 (set_attr "mode" "SI,DI,DI")])
9251 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9252 (define_insn "*andsi_2_zext"
9253 [(set (reg FLAGS_REG)
9255 (match_operand:SI 1 "nonimmediate_operand" "%0")
9256 (match_operand:SI 2 "x86_64_general_operand" "rme"))
9258 (set (match_operand:DI 0 "register_operand" "=r")
9259 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
9260 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9261 && ix86_binary_operator_ok (AND, SImode, operands)"
9262 "and{l}\t{%2, %k0|%k0, %2}"
9263 [(set_attr "type" "alu")
9264 (set_attr "mode" "SI")])
9266 (define_insn "*andqi_2_maybe_si"
9267 [(set (reg FLAGS_REG)
9269 (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9270 (match_operand:QI 2 "general_operand" "qmn,qn,n"))
9272 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
9273 (and:QI (match_dup 1) (match_dup 2)))]
9274 "ix86_binary_operator_ok (AND, QImode, operands)
9275 && ix86_match_ccmode (insn,
9276 CONST_INT_P (operands[2])
9277 && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
9279 if (which_alternative == 2)
9281 if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
9282 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
9283 return "and{l}\t{%2, %k0|%k0, %2}";
9285 return "and{b}\t{%2, %0|%0, %2}";
9287 [(set_attr "type" "alu")
9288 (set_attr "mode" "QI,QI,SI")])
9290 (define_insn "*and<mode>_2"
9291 [(set (reg FLAGS_REG)
9292 (compare (and:SWI124
9293 (match_operand:SWI124 1 "nonimmediate_operand" "%0,0")
9294 (match_operand:SWI124 2 "<general_operand>" "<g>,<r><i>"))
9296 (set (match_operand:SWI124 0 "nonimmediate_operand" "=<r>,<r>m")
9297 (and:SWI124 (match_dup 1) (match_dup 2)))]
9298 "ix86_match_ccmode (insn, CCNOmode)
9299 && ix86_binary_operator_ok (AND, <MODE>mode, operands)"
9300 "and{<imodesuffix>}\t{%2, %0|%0, %2}"
9301 [(set_attr "type" "alu")
9302 (set_attr "mode" "<MODE>")])
9304 (define_insn "*andqi_2_slp"
9305 [(set (reg FLAGS_REG)
9307 (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9308 (match_operand:QI 1 "nonimmediate_operand" "qmn,qn"))
9310 (set (strict_low_part (match_dup 0))
9311 (and:QI (match_dup 0) (match_dup 1)))]
9312 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9313 && ix86_match_ccmode (insn, CCNOmode)
9314 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9315 "and{b}\t{%1, %0|%0, %1}"
9316 [(set_attr "type" "alu1")
9317 (set_attr "mode" "QI")])
9319 (define_insn "andqi_ext_1"
9320 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q,Q")
9326 (zero_extract:SI (match_operand 1 "ext_register_operand" "0,0")
9329 (match_operand:QI 2 "general_operand" "QnBc,m")) 0))
9330 (clobber (reg:CC FLAGS_REG))]
9331 "/* FIXME: without this LRA can't reload this pattern, see PR82524. */
9332 rtx_equal_p (operands[0], operands[1])"
9333 "and{b}\t{%2, %h0|%h0, %2}"
9334 [(set_attr "isa" "*,nox64")
9335 (set_attr "type" "alu")
9336 (set_attr "mode" "QI")])
9338 ;; Generated by peephole translating test to and. This shows up
9339 ;; often in fp comparisons.
9340 (define_insn "*andqi_ext_1_cc"
9341 [(set (reg FLAGS_REG)
9345 (zero_extract:SI (match_operand 1 "ext_register_operand" "0,0")
9348 (match_operand:QI 2 "general_operand" "QnBc,m"))
9350 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q,Q")
9356 (zero_extract:SI (match_dup 1)
9360 "ix86_match_ccmode (insn, CCNOmode)
9361 /* FIXME: without this LRA can't reload this pattern, see PR82524. */
9362 && rtx_equal_p (operands[0], operands[1])"
9363 "and{b}\t{%2, %h0|%h0, %2}"
9364 [(set_attr "isa" "*,nox64")
9365 (set_attr "type" "alu")
9366 (set_attr "mode" "QI")])
9368 (define_insn "*andqi_ext_2"
9369 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
9375 (zero_extract:SI (match_operand 1 "ext_register_operand" "%0")
9379 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9381 (const_int 8)) 0)) 0))
9382 (clobber (reg:CC FLAGS_REG))]
9383 "/* FIXME: without this LRA can't reload this pattern, see PR82524. */
9384 rtx_equal_p (operands[0], operands[1])
9385 || rtx_equal_p (operands[0], operands[2])"
9386 "and{b}\t{%h2, %h0|%h0, %h2}"
9387 [(set_attr "type" "alu")
9388 (set_attr "mode" "QI")])
9390 ;; Convert wide AND instructions with immediate operand to shorter QImode
9391 ;; equivalents when possible.
9392 ;; Don't do the splitting with memory operands, since it introduces risk
9393 ;; of memory mismatch stalls. We may want to do the splitting for optimizing
9394 ;; for size, but that can (should?) be handled by generic code instead.
9396 [(set (match_operand:SWI248 0 "QIreg_operand")
9397 (and:SWI248 (match_operand:SWI248 1 "register_operand")
9398 (match_operand:SWI248 2 "const_int_operand")))
9399 (clobber (reg:CC FLAGS_REG))]
9401 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9402 && !(~INTVAL (operands[2]) & ~(255 << 8))"
9404 [(set (zero_extract:SI (match_dup 0)
9410 (zero_extract:SI (match_dup 1)
9414 (clobber (reg:CC FLAGS_REG))])]
9416 operands[0] = gen_lowpart (SImode, operands[0]);
9417 operands[1] = gen_lowpart (SImode, operands[1]);
9418 operands[2] = gen_int_mode (INTVAL (operands[2]) >> 8, QImode);
9421 ;; Since AND can be encoded with sign extended immediate, this is only
9422 ;; profitable when 7th bit is not set.
9424 [(set (match_operand:SWI248 0 "any_QIreg_operand")
9425 (and:SWI248 (match_operand:SWI248 1 "general_operand")
9426 (match_operand:SWI248 2 "const_int_operand")))
9427 (clobber (reg:CC FLAGS_REG))]
9429 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9430 && !(~INTVAL (operands[2]) & ~255)
9431 && !(INTVAL (operands[2]) & 128)"
9432 [(parallel [(set (strict_low_part (match_dup 0))
9433 (and:QI (match_dup 1)
9435 (clobber (reg:CC FLAGS_REG))])]
9437 operands[0] = gen_lowpart (QImode, operands[0]);
9438 operands[1] = gen_lowpart (QImode, operands[1]);
9439 operands[2] = gen_int_mode (INTVAL (operands[2]), QImode);
9442 (define_insn "*andndi3_doubleword"
9443 [(set (match_operand:DI 0 "register_operand" "=&r,r,r,&r")
9445 (not:DI (match_operand:DI 1 "register_operand" "r,0,r,0"))
9446 (match_operand:DI 2 "nonimmediate_operand" "rm,rm,0,rm")))
9447 (clobber (reg:CC FLAGS_REG))]
9448 "!TARGET_64BIT && TARGET_STV && TARGET_SSE2"
9450 [(set_attr "isa" "bmi,bmi,bmi,*")])
9453 [(set (match_operand:DI 0 "register_operand")
9455 (not:DI (match_operand:DI 1 "register_operand"))
9456 (match_operand:DI 2 "nonimmediate_operand")))
9457 (clobber (reg:CC FLAGS_REG))]
9458 "!TARGET_64BIT && TARGET_BMI && TARGET_STV && TARGET_SSE2
9459 && reload_completed"
9460 [(parallel [(set (match_dup 0)
9461 (and:SI (not:SI (match_dup 1)) (match_dup 2)))
9462 (clobber (reg:CC FLAGS_REG))])
9463 (parallel [(set (match_dup 3)
9464 (and:SI (not:SI (match_dup 4)) (match_dup 5)))
9465 (clobber (reg:CC FLAGS_REG))])]
9466 "split_double_mode (DImode, &operands[0], 3, &operands[0], &operands[3]);")
9469 [(set (match_operand:DI 0 "register_operand")
9471 (not:DI (match_dup 0))
9472 (match_operand:DI 1 "nonimmediate_operand")))
9473 (clobber (reg:CC FLAGS_REG))]
9474 "!TARGET_64BIT && !TARGET_BMI && TARGET_STV && TARGET_SSE2
9475 && reload_completed"
9476 [(set (match_dup 0) (not:SI (match_dup 0)))
9477 (parallel [(set (match_dup 0)
9478 (and:SI (match_dup 0) (match_dup 1)))
9479 (clobber (reg:CC FLAGS_REG))])
9480 (set (match_dup 2) (not:SI (match_dup 2)))
9481 (parallel [(set (match_dup 2)
9482 (and:SI (match_dup 2) (match_dup 3)))
9483 (clobber (reg:CC FLAGS_REG))])]
9484 "split_double_mode (DImode, &operands[0], 2, &operands[0], &operands[2]);")
9486 (define_insn "*andn<mode>_1"
9487 [(set (match_operand:SWI48 0 "register_operand" "=r,r")
9489 (not:SWI48 (match_operand:SWI48 1 "register_operand" "r,r"))
9490 (match_operand:SWI48 2 "nonimmediate_operand" "r,m")))
9491 (clobber (reg:CC FLAGS_REG))]
9493 "andn\t{%2, %1, %0|%0, %1, %2}"
9494 [(set_attr "type" "bitmanip")
9495 (set_attr "btver2_decode" "direct, double")
9496 (set_attr "mode" "<MODE>")])
9498 (define_insn "*andn<mode>_1"
9499 [(set (match_operand:SWI12 0 "register_operand" "=r")
9501 (not:SWI12 (match_operand:SWI12 1 "register_operand" "r"))
9502 (match_operand:SWI12 2 "register_operand" "r")))
9503 (clobber (reg:CC FLAGS_REG))]
9505 "andn\t{%k2, %k1, %k0|%k0, %k1, %k2}"
9506 [(set_attr "type" "bitmanip")
9507 (set_attr "btver2_decode" "direct")
9508 (set_attr "mode" "SI")])
9510 (define_insn "*andn_<mode>_ccno"
9511 [(set (reg FLAGS_REG)
9514 (not:SWI48 (match_operand:SWI48 1 "register_operand" "r,r"))
9515 (match_operand:SWI48 2 "nonimmediate_operand" "r,m"))
9517 (clobber (match_scratch:SWI48 0 "=r,r"))]
9518 "TARGET_BMI && ix86_match_ccmode (insn, CCNOmode)"
9519 "andn\t{%2, %1, %0|%0, %1, %2}"
9520 [(set_attr "type" "bitmanip")
9521 (set_attr "btver2_decode" "direct, double")
9522 (set_attr "mode" "<MODE>")])
9524 ;; Logical inclusive and exclusive OR instructions
9526 ;; %%% This used to optimize known byte-wide and operations to memory.
9527 ;; If this is considered useful, it should be done with splitters.
9529 (define_expand "<code><mode>3"
9530 [(set (match_operand:SWIM1248x 0 "nonimmediate_operand")
9531 (any_or:SWIM1248x (match_operand:SWIM1248x 1 "nonimmediate_operand")
9532 (match_operand:SWIM1248x 2 "<general_operand>")))]
9534 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
9536 (define_insn_and_split "*<code>di3_doubleword"
9537 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r")
9539 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
9540 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm")))
9541 (clobber (reg:CC FLAGS_REG))]
9542 "!TARGET_64BIT && TARGET_STV && TARGET_SSE2
9543 && ix86_binary_operator_ok (<CODE>, DImode, operands)"
9545 "&& reload_completed"
9548 split_double_mode (DImode, &operands[0], 3, &operands[0], &operands[3]);
9549 if (operands[2] == constm1_rtx)
9553 operands[1] = constm1_rtx;
9554 ix86_expand_move (SImode, &operands[0]);
9557 ix86_expand_unary_operator (NOT, SImode, &operands[0]);
9559 else if (operands[2] != const0_rtx)
9560 ix86_expand_binary_operator (<CODE>, SImode, &operands[0]);
9561 else if (operands[5] == const0_rtx)
9562 emit_note (NOTE_INSN_DELETED);
9563 if (operands[5] == constm1_rtx)
9567 operands[4] = constm1_rtx;
9568 ix86_expand_move (SImode, &operands[3]);
9571 ix86_expand_unary_operator (NOT, SImode, &operands[3]);
9573 else if (operands[5] != const0_rtx)
9574 ix86_expand_binary_operator (<CODE>, SImode, &operands[3]);
9578 (define_insn "*<code><mode>_1"
9579 [(set (match_operand:SWI248 0 "nonimmediate_operand" "=r,rm")
9581 (match_operand:SWI248 1 "nonimmediate_operand" "%0,0")
9582 (match_operand:SWI248 2 "<general_operand>" "<g>,r<i>")))
9583 (clobber (reg:CC FLAGS_REG))]
9584 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9585 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
9586 [(set_attr "type" "alu")
9587 (set_attr "mode" "<MODE>")])
9589 (define_insn_and_split "*iordi_1_bts"
9590 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9592 (match_operand:DI 1 "nonimmediate_operand" "%0")
9593 (match_operand:DI 2 "const_int_operand" "n")))
9594 (clobber (reg:CC FLAGS_REG))]
9595 "TARGET_64BIT && TARGET_USE_BT
9596 && ix86_binary_operator_ok (IOR, DImode, operands)
9597 && IN_RANGE (exact_log2 (INTVAL (operands[2])), 31, 63)"
9599 "&& reload_completed"
9600 [(parallel [(set (zero_extract:DI (match_dup 0)
9604 (clobber (reg:CC FLAGS_REG))])]
9605 "operands[3] = GEN_INT (exact_log2 (INTVAL (operands[2])));"
9606 [(set_attr "type" "alu1")
9607 (set_attr "prefix_0f" "1")
9608 (set_attr "znver1_decode" "double")
9609 (set_attr "mode" "DI")])
9611 (define_insn_and_split "*xordi_1_btc"
9612 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9614 (match_operand:DI 1 "nonimmediate_operand" "%0")
9615 (match_operand:DI 2 "const_int_operand" "n")))
9616 (clobber (reg:CC FLAGS_REG))]
9617 "TARGET_64BIT && TARGET_USE_BT
9618 && ix86_binary_operator_ok (XOR, DImode, operands)
9619 && IN_RANGE (exact_log2 (INTVAL (operands[2])), 31, 63)"
9621 "&& reload_completed"
9622 [(parallel [(set (zero_extract:DI (match_dup 0)
9625 (not:DI (zero_extract:DI (match_dup 0)
9628 (clobber (reg:CC FLAGS_REG))])]
9629 "operands[3] = GEN_INT (exact_log2 (INTVAL (operands[2])));"
9630 [(set_attr "type" "alu1")
9631 (set_attr "prefix_0f" "1")
9632 (set_attr "znver1_decode" "double")
9633 (set_attr "mode" "DI")])
9635 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9636 (define_insn "*<code>si_1_zext"
9637 [(set (match_operand:DI 0 "register_operand" "=r")
9639 (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9640 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
9641 (clobber (reg:CC FLAGS_REG))]
9642 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
9643 "<logic>{l}\t{%2, %k0|%k0, %2}"
9644 [(set_attr "type" "alu")
9645 (set_attr "mode" "SI")])
9647 (define_insn "*<code>si_1_zext_imm"
9648 [(set (match_operand:DI 0 "register_operand" "=r")
9650 (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
9651 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
9652 (clobber (reg:CC FLAGS_REG))]
9653 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
9654 "<logic>{l}\t{%2, %k0|%k0, %2}"
9655 [(set_attr "type" "alu")
9656 (set_attr "mode" "SI")])
9658 (define_insn "*<code>qi_1"
9659 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
9660 (any_or:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9661 (match_operand:QI 2 "general_operand" "qmn,qn,rn")))
9662 (clobber (reg:CC FLAGS_REG))]
9663 "ix86_binary_operator_ok (<CODE>, QImode, operands)"
9665 <logic>{b}\t{%2, %0|%0, %2}
9666 <logic>{b}\t{%2, %0|%0, %2}
9667 <logic>{l}\t{%k2, %k0|%k0, %k2}"
9668 [(set_attr "type" "alu")
9669 (set_attr "mode" "QI,QI,SI")
9670 ;; Potential partial reg stall on alternative 2.
9671 (set (attr "preferred_for_speed")
9672 (cond [(eq_attr "alternative" "2")
9673 (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
9674 (symbol_ref "true")))])
9676 (define_insn "*<code>qi_1_slp"
9677 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
9678 (any_or:QI (match_dup 0)
9679 (match_operand:QI 1 "general_operand" "qmn,qn")))
9680 (clobber (reg:CC FLAGS_REG))]
9681 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9682 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9683 "<logic>{b}\t{%1, %0|%0, %1}"
9684 [(set_attr "type" "alu1")
9685 (set_attr "mode" "QI")])
9687 (define_insn "*<code><mode>_2"
9688 [(set (reg FLAGS_REG)
9689 (compare (any_or:SWI
9690 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
9691 (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>"))
9693 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
9694 (any_or:SWI (match_dup 1) (match_dup 2)))]
9695 "ix86_match_ccmode (insn, CCNOmode)
9696 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9697 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
9698 [(set_attr "type" "alu")
9699 (set_attr "mode" "<MODE>")])
9701 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9702 ;; ??? Special case for immediate operand is missing - it is tricky.
9703 (define_insn "*<code>si_2_zext"
9704 [(set (reg FLAGS_REG)
9705 (compare (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9706 (match_operand:SI 2 "x86_64_general_operand" "rme"))
9708 (set (match_operand:DI 0 "register_operand" "=r")
9709 (zero_extend:DI (any_or:SI (match_dup 1) (match_dup 2))))]
9710 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9711 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
9712 "<logic>{l}\t{%2, %k0|%k0, %2}"
9713 [(set_attr "type" "alu")
9714 (set_attr "mode" "SI")])
9716 (define_insn "*<code>si_2_zext_imm"
9717 [(set (reg FLAGS_REG)
9719 (match_operand:SI 1 "nonimmediate_operand" "%0")
9720 (match_operand:SI 2 "x86_64_zext_immediate_operand" "Z"))
9722 (set (match_operand:DI 0 "register_operand" "=r")
9723 (any_or:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
9724 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9725 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
9726 "<logic>{l}\t{%2, %k0|%k0, %2}"
9727 [(set_attr "type" "alu")
9728 (set_attr "mode" "SI")])
9730 (define_insn "*<code>qi_2_slp"
9731 [(set (reg FLAGS_REG)
9732 (compare (any_or:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9733 (match_operand:QI 1 "general_operand" "qmn,qn"))
9735 (set (strict_low_part (match_dup 0))
9736 (any_or:QI (match_dup 0) (match_dup 1)))]
9737 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9738 && ix86_match_ccmode (insn, CCNOmode)
9739 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9740 "<logic>{b}\t{%1, %0|%0, %1}"
9741 [(set_attr "type" "alu1")
9742 (set_attr "mode" "QI")])
9744 (define_insn "*<code><mode>_3"
9745 [(set (reg FLAGS_REG)
9746 (compare (any_or:SWI
9747 (match_operand:SWI 1 "nonimmediate_operand" "%0")
9748 (match_operand:SWI 2 "<general_operand>" "<g>"))
9750 (clobber (match_scratch:SWI 0 "=<r>"))]
9751 "ix86_match_ccmode (insn, CCNOmode)
9752 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9753 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
9754 [(set_attr "type" "alu")
9755 (set_attr "mode" "<MODE>")])
9757 (define_insn "*<code>qi_ext_1"
9758 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q,Q")
9764 (zero_extract:SI (match_operand 1 "ext_register_operand" "0,0")
9767 (match_operand:QI 2 "general_operand" "QnBc,m")) 0))
9768 (clobber (reg:CC FLAGS_REG))]
9769 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9770 /* FIXME: without this LRA can't reload this pattern, see PR82524. */
9771 && rtx_equal_p (operands[0], operands[1])"
9772 "<logic>{b}\t{%2, %h0|%h0, %2}"
9773 [(set_attr "isa" "*,nox64")
9774 (set_attr "type" "alu")
9775 (set_attr "mode" "QI")])
9777 (define_insn "*<code>qi_ext_2"
9778 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
9784 (zero_extract:SI (match_operand 1 "ext_register_operand" "%0")
9788 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9790 (const_int 8)) 0)) 0))
9791 (clobber (reg:CC FLAGS_REG))]
9792 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9793 /* FIXME: without this LRA can't reload this pattern, see PR82524. */
9794 && (rtx_equal_p (operands[0], operands[1])
9795 || rtx_equal_p (operands[0], operands[2]))"
9796 "<logic>{b}\t{%h2, %h0|%h0, %h2}"
9797 [(set_attr "type" "alu")
9798 (set_attr "mode" "QI")])
9800 ;; Convert wide OR instructions with immediate operand to shorter QImode
9801 ;; equivalents when possible.
9802 ;; Don't do the splitting with memory operands, since it introduces risk
9803 ;; of memory mismatch stalls. We may want to do the splitting for optimizing
9804 ;; for size, but that can (should?) be handled by generic code instead.
9806 [(set (match_operand:SWI248 0 "QIreg_operand")
9807 (any_or:SWI248 (match_operand:SWI248 1 "register_operand")
9808 (match_operand:SWI248 2 "const_int_operand")))
9809 (clobber (reg:CC FLAGS_REG))]
9811 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9812 && !(INTVAL (operands[2]) & ~(255 << 8))"
9814 [(set (zero_extract:SI (match_dup 0)
9820 (zero_extract:SI (match_dup 1)
9824 (clobber (reg:CC FLAGS_REG))])]
9826 operands[0] = gen_lowpart (SImode, operands[0]);
9827 operands[1] = gen_lowpart (SImode, operands[1]);
9828 operands[2] = gen_int_mode (INTVAL (operands[2]) >> 8, QImode);
9831 ;; Since OR can be encoded with sign extended immediate, this is only
9832 ;; profitable when 7th bit is set.
9834 [(set (match_operand:SWI248 0 "any_QIreg_operand")
9835 (any_or:SWI248 (match_operand:SWI248 1 "general_operand")
9836 (match_operand:SWI248 2 "const_int_operand")))
9837 (clobber (reg:CC FLAGS_REG))]
9839 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9840 && !(INTVAL (operands[2]) & ~255)
9841 && (INTVAL (operands[2]) & 128)"
9842 [(parallel [(set (strict_low_part (match_dup 0))
9843 (any_or:QI (match_dup 1)
9845 (clobber (reg:CC FLAGS_REG))])]
9847 operands[0] = gen_lowpart (QImode, operands[0]);
9848 operands[1] = gen_lowpart (QImode, operands[1]);
9849 operands[2] = gen_int_mode (INTVAL (operands[2]), QImode);
9852 (define_expand "xorqi_ext_1_cc"
9854 (set (reg:CCNO FLAGS_REG)
9858 (zero_extract:SI (match_operand 1 "ext_register_operand")
9861 (match_operand 2 "const_int_operand"))
9863 (set (zero_extract:SI (match_operand 0 "ext_register_operand")
9869 (zero_extract:SI (match_dup 1)
9872 (match_dup 2)) 0))])])
9874 (define_insn "*xorqi_ext_1_cc"
9875 [(set (reg FLAGS_REG)
9879 (zero_extract:SI (match_operand 1 "ext_register_operand" "0,0")
9882 (match_operand:QI 2 "general_operand" "QnBc,m"))
9884 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q,Q")
9890 (zero_extract:SI (match_dup 1)
9894 "ix86_match_ccmode (insn, CCNOmode)
9895 /* FIXME: without this LRA can't reload this pattern, see PR82524. */
9896 && rtx_equal_p (operands[0], operands[1])"
9897 "xor{b}\t{%2, %h0|%h0, %2}"
9898 [(set_attr "isa" "*,nox64")
9899 (set_attr "type" "alu")
9900 (set_attr "mode" "QI")])
9902 ;; Negation instructions
9904 (define_expand "neg<mode>2"
9905 [(set (match_operand:SDWIM 0 "nonimmediate_operand")
9906 (neg:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")))]
9908 "ix86_expand_unary_operator (NEG, <MODE>mode, operands); DONE;")
9910 (define_insn_and_split "*neg<dwi>2_doubleword"
9911 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro")
9912 (neg:<DWI> (match_operand:<DWI> 1 "nonimmediate_operand" "0")))
9913 (clobber (reg:CC FLAGS_REG))]
9914 "ix86_unary_operator_ok (NEG, <DWI>mode, operands)"
9918 [(set (reg:CCZ FLAGS_REG)
9919 (compare:CCZ (neg:DWIH (match_dup 1)) (const_int 0)))
9920 (set (match_dup 0) (neg:DWIH (match_dup 1)))])
9923 (plus:DWIH (plus:DWIH (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
9926 (clobber (reg:CC FLAGS_REG))])
9929 (neg:DWIH (match_dup 2)))
9930 (clobber (reg:CC FLAGS_REG))])]
9931 "split_double_mode (<DWI>mode, &operands[0], 2, &operands[0], &operands[2]);")
9933 (define_insn "*neg<mode>2_1"
9934 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9935 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")))
9936 (clobber (reg:CC FLAGS_REG))]
9937 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
9938 "neg{<imodesuffix>}\t%0"
9939 [(set_attr "type" "negnot")
9940 (set_attr "mode" "<MODE>")])
9942 ;; Combine is quite creative about this pattern.
9943 (define_insn "*negsi2_1_zext"
9944 [(set (match_operand:DI 0 "register_operand" "=r")
9946 (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
9949 (clobber (reg:CC FLAGS_REG))]
9950 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9952 [(set_attr "type" "negnot")
9953 (set_attr "mode" "SI")])
9955 ;; The problem with neg is that it does not perform (compare x 0),
9956 ;; it really performs (compare 0 x), which leaves us with the zero
9957 ;; flag being the only useful item.
9959 (define_insn "*neg<mode>2_cmpz"
9960 [(set (reg:CCZ FLAGS_REG)
9962 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
9964 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9965 (neg:SWI (match_dup 1)))]
9966 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
9967 "neg{<imodesuffix>}\t%0"
9968 [(set_attr "type" "negnot")
9969 (set_attr "mode" "<MODE>")])
9971 (define_insn "*negsi2_cmpz_zext"
9972 [(set (reg:CCZ FLAGS_REG)
9976 (match_operand:DI 1 "register_operand" "0")
9980 (set (match_operand:DI 0 "register_operand" "=r")
9981 (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
9984 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9986 [(set_attr "type" "negnot")
9987 (set_attr "mode" "SI")])
9989 ;; Negate with jump on overflow.
9990 (define_expand "negv<mode>3"
9991 [(parallel [(set (reg:CCO FLAGS_REG)
9992 (ne:CCO (match_operand:SWI 1 "register_operand")
9994 (set (match_operand:SWI 0 "register_operand")
9995 (neg:SWI (match_dup 1)))])
9996 (set (pc) (if_then_else
9997 (eq (reg:CCO FLAGS_REG) (const_int 0))
9998 (label_ref (match_operand 2))
10003 = gen_int_mode (HOST_WIDE_INT_1U << (GET_MODE_BITSIZE (<MODE>mode) - 1),
10007 (define_insn "*negv<mode>3"
10008 [(set (reg:CCO FLAGS_REG)
10009 (ne:CCO (match_operand:SWI 1 "nonimmediate_operand" "0")
10010 (match_operand:SWI 2 "const_int_operand")))
10011 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
10012 (neg:SWI (match_dup 1)))]
10013 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)
10014 && mode_signbit_p (<MODE>mode, operands[2])"
10015 "neg{<imodesuffix>}\t%0"
10016 [(set_attr "type" "negnot")
10017 (set_attr "mode" "<MODE>")])
10019 ;; Changing of sign for FP values is doable using integer unit too.
10021 (define_expand "<code><mode>2"
10022 [(set (match_operand:X87MODEF 0 "register_operand")
10023 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand")))]
10024 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
10025 "ix86_expand_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
10027 (define_insn "*absneg<mode>2"
10028 [(set (match_operand:MODEF 0 "register_operand" "=Yv,Yv,f,!r")
10029 (match_operator:MODEF 3 "absneg_operator"
10030 [(match_operand:MODEF 1 "register_operand" "0,Yv,0,0")]))
10031 (use (match_operand:<ssevecmode> 2 "nonimmediate_operand" "Yvm,0,X,X"))
10032 (clobber (reg:CC FLAGS_REG))]
10033 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
10035 [(set (attr "enabled")
10037 (match_test ("SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"))
10039 (eq_attr "alternative" "2")
10040 (symbol_ref "TARGET_MIX_SSE_I387")
10041 (symbol_ref "true"))
10043 (eq_attr "alternative" "2,3")
10044 (symbol_ref "true")
10045 (symbol_ref "false"))))])
10047 (define_insn "*absnegxf2_i387"
10048 [(set (match_operand:XF 0 "register_operand" "=f,!r")
10049 (match_operator:XF 3 "absneg_operator"
10050 [(match_operand:XF 1 "register_operand" "0,0")]))
10051 (use (match_operand 2))
10052 (clobber (reg:CC FLAGS_REG))]
10056 (define_expand "<code>tf2"
10057 [(set (match_operand:TF 0 "register_operand")
10058 (absneg:TF (match_operand:TF 1 "register_operand")))]
10060 "ix86_expand_fp_absneg_operator (<CODE>, TFmode, operands); DONE;")
10062 (define_insn "*absnegtf2_sse"
10063 [(set (match_operand:TF 0 "register_operand" "=Yv,Yv")
10064 (match_operator:TF 3 "absneg_operator"
10065 [(match_operand:TF 1 "register_operand" "0,Yv")]))
10066 (use (match_operand:TF 2 "nonimmediate_operand" "Yvm,0"))
10067 (clobber (reg:CC FLAGS_REG))]
10071 ;; Splitters for fp abs and neg.
10074 [(set (match_operand 0 "fp_register_operand")
10075 (match_operator 1 "absneg_operator" [(match_dup 0)]))
10076 (use (match_operand 2))
10077 (clobber (reg:CC FLAGS_REG))]
10079 [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
10082 [(set (match_operand 0 "sse_reg_operand")
10083 (match_operator 3 "absneg_operator"
10084 [(match_operand 1 "register_operand")]))
10085 (use (match_operand 2 "nonimmediate_operand"))
10086 (clobber (reg:CC FLAGS_REG))]
10088 [(set (match_dup 0) (match_dup 3))]
10090 machine_mode mode = GET_MODE (operands[0]);
10091 machine_mode vmode = GET_MODE (operands[2]);
10094 operands[0] = lowpart_subreg (vmode, operands[0], mode);
10095 operands[1] = lowpart_subreg (vmode, operands[1], mode);
10096 if (operands_match_p (operands[0], operands[2]))
10097 std::swap (operands[1], operands[2]);
10098 if (GET_CODE (operands[3]) == ABS)
10099 tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
10101 tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
10106 [(set (match_operand:SF 0 "general_reg_operand")
10107 (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
10108 (use (match_operand:V4SF 2))
10109 (clobber (reg:CC FLAGS_REG))]
10111 [(parallel [(set (match_dup 0) (match_dup 1))
10112 (clobber (reg:CC FLAGS_REG))])]
10115 operands[0] = gen_lowpart (SImode, operands[0]);
10116 if (GET_CODE (operands[1]) == ABS)
10118 tmp = gen_int_mode (0x7fffffff, SImode);
10119 tmp = gen_rtx_AND (SImode, operands[0], tmp);
10123 tmp = gen_int_mode (0x80000000, SImode);
10124 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
10130 [(set (match_operand:DF 0 "general_reg_operand")
10131 (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
10132 (use (match_operand 2))
10133 (clobber (reg:CC FLAGS_REG))]
10135 [(parallel [(set (match_dup 0) (match_dup 1))
10136 (clobber (reg:CC FLAGS_REG))])]
10141 tmp = gen_lowpart (DImode, operands[0]);
10142 tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
10145 if (GET_CODE (operands[1]) == ABS)
10148 tmp = gen_rtx_NOT (DImode, tmp);
10152 operands[0] = gen_highpart (SImode, operands[0]);
10153 if (GET_CODE (operands[1]) == ABS)
10155 tmp = gen_int_mode (0x7fffffff, SImode);
10156 tmp = gen_rtx_AND (SImode, operands[0], tmp);
10160 tmp = gen_int_mode (0x80000000, SImode);
10161 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
10168 [(set (match_operand:XF 0 "general_reg_operand")
10169 (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
10170 (use (match_operand 2))
10171 (clobber (reg:CC FLAGS_REG))]
10173 [(parallel [(set (match_dup 0) (match_dup 1))
10174 (clobber (reg:CC FLAGS_REG))])]
10177 operands[0] = gen_rtx_REG (SImode,
10178 REGNO (operands[0]) + (TARGET_64BIT ? 1 : 2));
10179 if (GET_CODE (operands[1]) == ABS)
10181 tmp = GEN_INT (0x7fff);
10182 tmp = gen_rtx_AND (SImode, operands[0], tmp);
10186 tmp = GEN_INT (0x8000);
10187 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
10192 ;; Conditionalize these after reload. If they match before reload, we
10193 ;; lose the clobber and ability to use integer instructions.
10195 (define_insn "*<code><mode>2_1"
10196 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
10197 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "0")))]
10199 && (reload_completed
10200 || !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
10201 "f<absneg_mnemonic>"
10202 [(set_attr "type" "fsgn")
10203 (set_attr "mode" "<MODE>")])
10205 (define_insn "*<code>extendsfdf2"
10206 [(set (match_operand:DF 0 "register_operand" "=f")
10207 (absneg:DF (float_extend:DF
10208 (match_operand:SF 1 "register_operand" "0"))))]
10209 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
10210 "f<absneg_mnemonic>"
10211 [(set_attr "type" "fsgn")
10212 (set_attr "mode" "DF")])
10214 (define_insn "*<code>extendsfxf2"
10215 [(set (match_operand:XF 0 "register_operand" "=f")
10216 (absneg:XF (float_extend:XF
10217 (match_operand:SF 1 "register_operand" "0"))))]
10219 "f<absneg_mnemonic>"
10220 [(set_attr "type" "fsgn")
10221 (set_attr "mode" "XF")])
10223 (define_insn "*<code>extenddfxf2"
10224 [(set (match_operand:XF 0 "register_operand" "=f")
10225 (absneg:XF (float_extend:XF
10226 (match_operand:DF 1 "register_operand" "0"))))]
10228 "f<absneg_mnemonic>"
10229 [(set_attr "type" "fsgn")
10230 (set_attr "mode" "XF")])
10232 ;; Copysign instructions
10234 (define_mode_iterator CSGNMODE [SF DF TF])
10235 (define_mode_attr CSGNVMODE [(SF "V4SF") (DF "V2DF") (TF "TF")])
10237 (define_expand "copysign<mode>3"
10238 [(match_operand:CSGNMODE 0 "register_operand")
10239 (match_operand:CSGNMODE 1 "nonmemory_operand")
10240 (match_operand:CSGNMODE 2 "register_operand")]
10241 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10242 || (TARGET_SSE && (<MODE>mode == TFmode))"
10243 "ix86_expand_copysign (operands); DONE;")
10245 (define_insn_and_split "copysign<mode>3_const"
10246 [(set (match_operand:CSGNMODE 0 "register_operand" "=Yv")
10248 [(match_operand:<CSGNVMODE> 1 "vector_move_operand" "YvmC")
10249 (match_operand:CSGNMODE 2 "register_operand" "0")
10250 (match_operand:<CSGNVMODE> 3 "nonimmediate_operand" "Yvm")]
10252 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10253 || (TARGET_SSE && (<MODE>mode == TFmode))"
10255 "&& reload_completed"
10257 "ix86_split_copysign_const (operands); DONE;")
10259 (define_insn "copysign<mode>3_var"
10260 [(set (match_operand:CSGNMODE 0 "register_operand" "=Yv,Yv,Yv,Yv,Yv")
10262 [(match_operand:CSGNMODE 2 "register_operand" "Yv,0,0,Yv,Yv")
10263 (match_operand:CSGNMODE 3 "register_operand" "1,1,Yv,1,Yv")
10264 (match_operand:<CSGNVMODE> 4
10265 "nonimmediate_operand" "X,Yvm,Yvm,0,0")
10266 (match_operand:<CSGNVMODE> 5
10267 "nonimmediate_operand" "0,Yvm,1,Yvm,1")]
10269 (clobber (match_scratch:<CSGNVMODE> 1 "=Yv,Yv,Yv,Yv,Yv"))]
10270 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10271 || (TARGET_SSE && (<MODE>mode == TFmode))"
10275 [(set (match_operand:CSGNMODE 0 "register_operand")
10277 [(match_operand:CSGNMODE 2 "register_operand")
10278 (match_operand:CSGNMODE 3 "register_operand")
10279 (match_operand:<CSGNVMODE> 4)
10280 (match_operand:<CSGNVMODE> 5)]
10282 (clobber (match_scratch:<CSGNVMODE> 1))]
10283 "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10284 || (TARGET_SSE && (<MODE>mode == TFmode)))
10285 && reload_completed"
10287 "ix86_split_copysign_var (operands); DONE;")
10289 ;; One complement instructions
10291 (define_expand "one_cmpl<mode>2"
10292 [(set (match_operand:SWIM1248x 0 "nonimmediate_operand")
10293 (not:SWIM1248x (match_operand:SWIM1248x 1 "nonimmediate_operand")))]
10295 "ix86_expand_unary_operator (NOT, <MODE>mode, operands); DONE;")
10297 (define_insn_and_split "*one_cmpldi2_doubleword"
10298 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10299 (not:DI (match_operand:DI 1 "nonimmediate_operand" "0")))]
10300 "!TARGET_64BIT && TARGET_STV && TARGET_SSE2
10301 && ix86_unary_operator_ok (NOT, DImode, operands)"
10303 "&& reload_completed"
10304 [(set (match_dup 0)
10305 (not:SI (match_dup 1)))
10307 (not:SI (match_dup 3)))]
10308 "split_double_mode (DImode, &operands[0], 2, &operands[0], &operands[2]);")
10310 (define_insn "*one_cmpl<mode>2_1"
10311 [(set (match_operand:SWI248 0 "nonimmediate_operand" "=rm")
10312 (not:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "0")))]
10313 "ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
10314 "not{<imodesuffix>}\t%0"
10315 [(set_attr "type" "negnot")
10316 (set_attr "mode" "<MODE>")])
10318 ;; ??? Currently never generated - xor is used instead.
10319 (define_insn "*one_cmplsi2_1_zext"
10320 [(set (match_operand:DI 0 "register_operand" "=r")
10322 (not:SI (match_operand:SI 1 "register_operand" "0"))))]
10323 "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
10325 [(set_attr "type" "negnot")
10326 (set_attr "mode" "SI")])
10328 (define_insn "*one_cmplqi2_1"
10329 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
10330 (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
10331 "ix86_unary_operator_ok (NOT, QImode, operands)"
10335 [(set_attr "type" "negnot")
10336 (set_attr "mode" "QI,SI")
10337 ;; Potential partial reg stall on alternative 1.
10338 (set (attr "preferred_for_speed")
10339 (cond [(eq_attr "alternative" "1")
10340 (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
10341 (symbol_ref "true")))])
10343 (define_insn "*one_cmpl<mode>2_2"
10344 [(set (reg FLAGS_REG)
10345 (compare (not:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
10347 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
10348 (not:SWI (match_dup 1)))]
10349 "ix86_match_ccmode (insn, CCNOmode)
10350 && ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
10352 [(set_attr "type" "alu1")
10353 (set_attr "mode" "<MODE>")])
10356 [(set (match_operand 0 "flags_reg_operand")
10357 (match_operator 2 "compare_operator"
10358 [(not:SWI (match_operand:SWI 3 "nonimmediate_operand"))
10360 (set (match_operand:SWI 1 "nonimmediate_operand")
10361 (not:SWI (match_dup 3)))]
10362 "ix86_match_ccmode (insn, CCNOmode)"
10363 [(parallel [(set (match_dup 0)
10364 (match_op_dup 2 [(xor:SWI (match_dup 3) (const_int -1))
10367 (xor:SWI (match_dup 3) (const_int -1)))])])
10369 ;; ??? Currently never generated - xor is used instead.
10370 (define_insn "*one_cmplsi2_2_zext"
10371 [(set (reg FLAGS_REG)
10372 (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
10374 (set (match_operand:DI 0 "register_operand" "=r")
10375 (zero_extend:DI (not:SI (match_dup 1))))]
10376 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10377 && ix86_unary_operator_ok (NOT, SImode, operands)"
10379 [(set_attr "type" "alu1")
10380 (set_attr "mode" "SI")])
10383 [(set (match_operand 0 "flags_reg_operand")
10384 (match_operator 2 "compare_operator"
10385 [(not:SI (match_operand:SI 3 "register_operand"))
10387 (set (match_operand:DI 1 "register_operand")
10388 (zero_extend:DI (not:SI (match_dup 3))))]
10389 "ix86_match_ccmode (insn, CCNOmode)"
10390 [(parallel [(set (match_dup 0)
10391 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10394 (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])])
10396 ;; Shift instructions
10398 ;; DImode shifts are implemented using the i386 "shift double" opcode,
10399 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem". If the shift count
10400 ;; is variable, then the count is in %cl and the "imm" operand is dropped
10401 ;; from the assembler input.
10403 ;; This instruction shifts the target reg/mem as usual, but instead of
10404 ;; shifting in zeros, bits are shifted in from reg operand. If the insn
10405 ;; is a left shift double, bits are taken from the high order bits of
10406 ;; reg, else if the insn is a shift right double, bits are taken from the
10407 ;; low order bits of reg. So if %eax is "1234" and %edx is "5678",
10408 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
10410 ;; Since sh[lr]d does not change the `reg' operand, that is done
10411 ;; separately, making all shifts emit pairs of shift double and normal
10412 ;; shift. Since sh[lr]d does not shift more than 31 bits, and we wish to
10413 ;; support a 63 bit shift, each shift where the count is in a reg expands
10414 ;; to a pair of shifts, a branch, a shift by 32 and a label.
10416 ;; If the shift count is a constant, we need never emit more than one
10417 ;; shift pair, instead using moves and sign extension for counts greater
10420 (define_expand "ashl<mode>3"
10421 [(set (match_operand:SDWIM 0 "<shift_operand>")
10422 (ashift:SDWIM (match_operand:SDWIM 1 "<ashl_input_operand>")
10423 (match_operand:QI 2 "nonmemory_operand")))]
10425 "ix86_expand_binary_operator (ASHIFT, <MODE>mode, operands); DONE;")
10427 (define_insn_and_split "*ashl<dwi>3_doubleword_mask"
10428 [(set (match_operand:<DWI> 0 "register_operand")
10430 (match_operand:<DWI> 1 "register_operand")
10433 (match_operand:SI 2 "register_operand" "c")
10434 (match_operand:SI 3 "const_int_operand")) 0)))
10435 (clobber (reg:CC FLAGS_REG))]
10436 "(INTVAL (operands[3]) & (<MODE_SIZE> * BITS_PER_UNIT)) == 0
10437 && can_create_pseudo_p ()"
10441 [(set (match_dup 6)
10442 (ior:DWIH (ashift:DWIH (match_dup 6) (match_dup 2))
10443 (lshiftrt:DWIH (match_dup 5)
10444 (minus:QI (match_dup 8) (match_dup 2)))))
10445 (clobber (reg:CC FLAGS_REG))])
10447 [(set (match_dup 4)
10448 (ashift:DWIH (match_dup 5) (match_dup 2)))
10449 (clobber (reg:CC FLAGS_REG))])]
10451 split_double_mode (<DWI>mode, &operands[0], 2, &operands[4], &operands[6]);
10453 operands[8] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT);
10455 if ((INTVAL (operands[3]) & ((<MODE_SIZE> * BITS_PER_UNIT) - 1))
10456 != ((<MODE_SIZE> * BITS_PER_UNIT) - 1))
10458 rtx tem = gen_reg_rtx (SImode);
10459 emit_insn (gen_andsi3 (tem, operands[2], operands[3]));
10463 operands[2] = gen_lowpart (QImode, operands[2]);
10465 if (!rtx_equal_p (operands[6], operands[7]))
10466 emit_move_insn (operands[6], operands[7]);
10469 (define_insn_and_split "*ashl<dwi>3_doubleword_mask_1"
10470 [(set (match_operand:<DWI> 0 "register_operand")
10472 (match_operand:<DWI> 1 "register_operand")
10474 (match_operand:QI 2 "register_operand" "c")
10475 (match_operand:QI 3 "const_int_operand"))))
10476 (clobber (reg:CC FLAGS_REG))]
10477 "(INTVAL (operands[3]) & (<MODE_SIZE> * BITS_PER_UNIT)) == 0
10478 && can_create_pseudo_p ()"
10482 [(set (match_dup 6)
10483 (ior:DWIH (ashift:DWIH (match_dup 6) (match_dup 2))
10484 (lshiftrt:DWIH (match_dup 5)
10485 (minus:QI (match_dup 8) (match_dup 2)))))
10486 (clobber (reg:CC FLAGS_REG))])
10488 [(set (match_dup 4)
10489 (ashift:DWIH (match_dup 5) (match_dup 2)))
10490 (clobber (reg:CC FLAGS_REG))])]
10492 split_double_mode (<DWI>mode, &operands[0], 2, &operands[4], &operands[6]);
10494 operands[8] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT);
10496 if ((INTVAL (operands[3]) & ((<MODE_SIZE> * BITS_PER_UNIT) - 1))
10497 != ((<MODE_SIZE> * BITS_PER_UNIT) - 1))
10499 rtx tem = gen_reg_rtx (QImode);
10500 emit_insn (gen_andqi3 (tem, operands[2], operands[3]));
10504 if (!rtx_equal_p (operands[6], operands[7]))
10505 emit_move_insn (operands[6], operands[7]);
10508 (define_insn "*ashl<mode>3_doubleword"
10509 [(set (match_operand:DWI 0 "register_operand" "=&r")
10510 (ashift:DWI (match_operand:DWI 1 "reg_or_pm1_operand" "0n")
10511 (match_operand:QI 2 "nonmemory_operand" "<S>c")))
10512 (clobber (reg:CC FLAGS_REG))]
10515 [(set_attr "type" "multi")])
10518 [(set (match_operand:DWI 0 "register_operand")
10519 (ashift:DWI (match_operand:DWI 1 "nonmemory_operand")
10520 (match_operand:QI 2 "nonmemory_operand")))
10521 (clobber (reg:CC FLAGS_REG))]
10522 "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
10524 "ix86_split_ashl (operands, NULL_RTX, <MODE>mode); DONE;")
10526 ;; By default we don't ask for a scratch register, because when DWImode
10527 ;; values are manipulated, registers are already at a premium. But if
10528 ;; we have one handy, we won't turn it away.
10531 [(match_scratch:DWIH 3 "r")
10532 (parallel [(set (match_operand:<DWI> 0 "register_operand")
10534 (match_operand:<DWI> 1 "nonmemory_operand")
10535 (match_operand:QI 2 "nonmemory_operand")))
10536 (clobber (reg:CC FLAGS_REG))])
10540 "ix86_split_ashl (operands, operands[3], <DWI>mode); DONE;")
10542 (define_insn "x86_64_shld"
10543 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
10544 (ior:DI (ashift:DI (match_dup 0)
10545 (match_operand:QI 2 "nonmemory_operand" "Jc"))
10546 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
10547 (minus:QI (const_int 64) (match_dup 2)))))
10548 (clobber (reg:CC FLAGS_REG))]
10550 "shld{q}\t{%s2%1, %0|%0, %1, %2}"
10551 [(set_attr "type" "ishift")
10552 (set_attr "prefix_0f" "1")
10553 (set_attr "mode" "DI")
10554 (set_attr "athlon_decode" "vector")
10555 (set_attr "amdfam10_decode" "vector")
10556 (set_attr "bdver1_decode" "vector")])
10558 (define_insn "x86_shld"
10559 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
10560 (ior:SI (ashift:SI (match_dup 0)
10561 (match_operand:QI 2 "nonmemory_operand" "Ic"))
10562 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
10563 (minus:QI (const_int 32) (match_dup 2)))))
10564 (clobber (reg:CC FLAGS_REG))]
10566 "shld{l}\t{%s2%1, %0|%0, %1, %2}"
10567 [(set_attr "type" "ishift")
10568 (set_attr "prefix_0f" "1")
10569 (set_attr "mode" "SI")
10570 (set_attr "pent_pair" "np")
10571 (set_attr "athlon_decode" "vector")
10572 (set_attr "amdfam10_decode" "vector")
10573 (set_attr "bdver1_decode" "vector")])
10575 (define_expand "x86_shift<mode>_adj_1"
10576 [(set (reg:CCZ FLAGS_REG)
10577 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand")
10580 (set (match_operand:SWI48 0 "register_operand")
10581 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
10582 (match_operand:SWI48 1 "register_operand")
10585 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
10586 (match_operand:SWI48 3 "register_operand")
10589 "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
10591 (define_expand "x86_shift<mode>_adj_2"
10592 [(use (match_operand:SWI48 0 "register_operand"))
10593 (use (match_operand:SWI48 1 "register_operand"))
10594 (use (match_operand:QI 2 "register_operand"))]
10597 rtx_code_label *label = gen_label_rtx ();
10600 emit_insn (gen_testqi_ccz_1 (operands[2],
10601 GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
10603 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
10604 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
10605 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
10606 gen_rtx_LABEL_REF (VOIDmode, label),
10608 tmp = emit_jump_insn (gen_rtx_SET (pc_rtx, tmp));
10609 JUMP_LABEL (tmp) = label;
10611 emit_move_insn (operands[0], operands[1]);
10612 ix86_expand_clear (operands[1]);
10614 emit_label (label);
10615 LABEL_NUSES (label) = 1;
10620 ;; Avoid useless masking of count operand.
10621 (define_insn_and_split "*ashl<mode>3_mask"
10622 [(set (match_operand:SWI48 0 "nonimmediate_operand")
10624 (match_operand:SWI48 1 "nonimmediate_operand")
10627 (match_operand:SI 2 "register_operand" "c,r")
10628 (match_operand:SI 3 "const_int_operand")) 0)))
10629 (clobber (reg:CC FLAGS_REG))]
10630 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)
10631 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10632 == GET_MODE_BITSIZE (<MODE>mode)-1
10633 && can_create_pseudo_p ()"
10637 [(set (match_dup 0)
10638 (ashift:SWI48 (match_dup 1)
10640 (clobber (reg:CC FLAGS_REG))])]
10641 "operands[2] = gen_lowpart (QImode, operands[2]);"
10642 [(set_attr "isa" "*,bmi2")])
10644 (define_insn_and_split "*ashl<mode>3_mask_1"
10645 [(set (match_operand:SWI48 0 "nonimmediate_operand")
10647 (match_operand:SWI48 1 "nonimmediate_operand")
10649 (match_operand:QI 2 "register_operand" "c,r")
10650 (match_operand:QI 3 "const_int_operand"))))
10651 (clobber (reg:CC FLAGS_REG))]
10652 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)
10653 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10654 == GET_MODE_BITSIZE (<MODE>mode)-1
10655 && can_create_pseudo_p ()"
10659 [(set (match_dup 0)
10660 (ashift:SWI48 (match_dup 1)
10662 (clobber (reg:CC FLAGS_REG))])]
10664 [(set_attr "isa" "*,bmi2")])
10666 (define_insn "*bmi2_ashl<mode>3_1"
10667 [(set (match_operand:SWI48 0 "register_operand" "=r")
10668 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
10669 (match_operand:SWI48 2 "register_operand" "r")))]
10671 "shlx\t{%2, %1, %0|%0, %1, %2}"
10672 [(set_attr "type" "ishiftx")
10673 (set_attr "mode" "<MODE>")])
10675 (define_insn "*ashl<mode>3_1"
10676 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r,r")
10677 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,l,rm")
10678 (match_operand:QI 2 "nonmemory_operand" "c<S>,M,r")))
10679 (clobber (reg:CC FLAGS_REG))]
10680 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
10682 switch (get_attr_type (insn))
10689 gcc_assert (operands[2] == const1_rtx);
10690 gcc_assert (rtx_equal_p (operands[0], operands[1]));
10691 return "add{<imodesuffix>}\t%0, %0";
10694 if (operands[2] == const1_rtx
10695 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10696 return "sal{<imodesuffix>}\t%0";
10698 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
10701 [(set_attr "isa" "*,*,bmi2")
10703 (cond [(eq_attr "alternative" "1")
10704 (const_string "lea")
10705 (eq_attr "alternative" "2")
10706 (const_string "ishiftx")
10707 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
10708 (match_operand 0 "register_operand"))
10709 (match_operand 2 "const1_operand"))
10710 (const_string "alu")
10712 (const_string "ishift")))
10713 (set (attr "length_immediate")
10715 (ior (eq_attr "type" "alu")
10716 (and (eq_attr "type" "ishift")
10717 (and (match_operand 2 "const1_operand")
10718 (ior (match_test "TARGET_SHIFT1")
10719 (match_test "optimize_function_for_size_p (cfun)")))))
10721 (const_string "*")))
10722 (set_attr "mode" "<MODE>")])
10724 ;; Convert shift to the shiftx pattern to avoid flags dependency.
10726 [(set (match_operand:SWI48 0 "register_operand")
10727 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
10728 (match_operand:QI 2 "register_operand")))
10729 (clobber (reg:CC FLAGS_REG))]
10730 "TARGET_BMI2 && reload_completed"
10731 [(set (match_dup 0)
10732 (ashift:SWI48 (match_dup 1) (match_dup 2)))]
10733 "operands[2] = gen_lowpart (<MODE>mode, operands[2]);")
10735 (define_insn "*bmi2_ashlsi3_1_zext"
10736 [(set (match_operand:DI 0 "register_operand" "=r")
10738 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
10739 (match_operand:SI 2 "register_operand" "r"))))]
10740 "TARGET_64BIT && TARGET_BMI2"
10741 "shlx\t{%2, %1, %k0|%k0, %1, %2}"
10742 [(set_attr "type" "ishiftx")
10743 (set_attr "mode" "SI")])
10745 (define_insn "*ashlsi3_1_zext"
10746 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
10748 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l,rm")
10749 (match_operand:QI 2 "nonmemory_operand" "cI,M,r"))))
10750 (clobber (reg:CC FLAGS_REG))]
10751 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10753 switch (get_attr_type (insn))
10760 gcc_assert (operands[2] == const1_rtx);
10761 return "add{l}\t%k0, %k0";
10764 if (operands[2] == const1_rtx
10765 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10766 return "sal{l}\t%k0";
10768 return "sal{l}\t{%2, %k0|%k0, %2}";
10771 [(set_attr "isa" "*,*,bmi2")
10773 (cond [(eq_attr "alternative" "1")
10774 (const_string "lea")
10775 (eq_attr "alternative" "2")
10776 (const_string "ishiftx")
10777 (and (match_test "TARGET_DOUBLE_WITH_ADD")
10778 (match_operand 2 "const1_operand"))
10779 (const_string "alu")
10781 (const_string "ishift")))
10782 (set (attr "length_immediate")
10784 (ior (eq_attr "type" "alu")
10785 (and (eq_attr "type" "ishift")
10786 (and (match_operand 2 "const1_operand")
10787 (ior (match_test "TARGET_SHIFT1")
10788 (match_test "optimize_function_for_size_p (cfun)")))))
10790 (const_string "*")))
10791 (set_attr "mode" "SI")])
10793 ;; Convert shift to the shiftx pattern to avoid flags dependency.
10795 [(set (match_operand:DI 0 "register_operand")
10797 (ashift:SI (match_operand:SI 1 "nonimmediate_operand")
10798 (match_operand:QI 2 "register_operand"))))
10799 (clobber (reg:CC FLAGS_REG))]
10800 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
10801 [(set (match_dup 0)
10802 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
10803 "operands[2] = gen_lowpart (SImode, operands[2]);")
10805 (define_insn "*ashlhi3_1"
10806 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,Yp")
10807 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
10808 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10809 (clobber (reg:CC FLAGS_REG))]
10810 "ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10812 switch (get_attr_type (insn))
10818 gcc_assert (operands[2] == const1_rtx);
10819 return "add{w}\t%0, %0";
10822 if (operands[2] == const1_rtx
10823 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10824 return "sal{w}\t%0";
10826 return "sal{w}\t{%2, %0|%0, %2}";
10829 [(set (attr "type")
10830 (cond [(eq_attr "alternative" "1")
10831 (const_string "lea")
10832 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
10833 (match_operand 0 "register_operand"))
10834 (match_operand 2 "const1_operand"))
10835 (const_string "alu")
10837 (const_string "ishift")))
10838 (set (attr "length_immediate")
10840 (ior (eq_attr "type" "alu")
10841 (and (eq_attr "type" "ishift")
10842 (and (match_operand 2 "const1_operand")
10843 (ior (match_test "TARGET_SHIFT1")
10844 (match_test "optimize_function_for_size_p (cfun)")))))
10846 (const_string "*")))
10847 (set_attr "mode" "HI,SI")])
10849 (define_insn "*ashlqi3_1"
10850 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,Yp")
10851 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
10852 (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
10853 (clobber (reg:CC FLAGS_REG))]
10854 "ix86_binary_operator_ok (ASHIFT, QImode, operands)"
10856 switch (get_attr_type (insn))
10862 gcc_assert (operands[2] == const1_rtx);
10863 if (REG_P (operands[1]) && !ANY_QI_REGNO_P (REGNO (operands[1])))
10864 return "add{l}\t%k0, %k0";
10866 return "add{b}\t%0, %0";
10869 if (operands[2] == const1_rtx
10870 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10872 if (get_attr_mode (insn) == MODE_SI)
10873 return "sal{l}\t%k0";
10875 return "sal{b}\t%0";
10879 if (get_attr_mode (insn) == MODE_SI)
10880 return "sal{l}\t{%2, %k0|%k0, %2}";
10882 return "sal{b}\t{%2, %0|%0, %2}";
10886 [(set (attr "type")
10887 (cond [(eq_attr "alternative" "2")
10888 (const_string "lea")
10889 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
10890 (match_operand 0 "register_operand"))
10891 (match_operand 2 "const1_operand"))
10892 (const_string "alu")
10894 (const_string "ishift")))
10895 (set (attr "length_immediate")
10897 (ior (eq_attr "type" "alu")
10898 (and (eq_attr "type" "ishift")
10899 (and (match_operand 2 "const1_operand")
10900 (ior (match_test "TARGET_SHIFT1")
10901 (match_test "optimize_function_for_size_p (cfun)")))))
10903 (const_string "*")))
10904 (set_attr "mode" "QI,SI,SI")
10905 ;; Potential partial reg stall on alternative 1.
10906 (set (attr "preferred_for_speed")
10907 (cond [(eq_attr "alternative" "1")
10908 (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
10909 (symbol_ref "true")))])
10911 (define_insn "*ashlqi3_1_slp"
10912 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10913 (ashift:QI (match_dup 0)
10914 (match_operand:QI 1 "nonmemory_operand" "cI")))
10915 (clobber (reg:CC FLAGS_REG))]
10916 "(optimize_function_for_size_p (cfun)
10917 || !TARGET_PARTIAL_FLAG_REG_STALL
10918 || (operands[1] == const1_rtx
10920 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
10922 switch (get_attr_type (insn))
10925 gcc_assert (operands[1] == const1_rtx);
10926 return "add{b}\t%0, %0";
10929 if (operands[1] == const1_rtx
10930 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10931 return "sal{b}\t%0";
10933 return "sal{b}\t{%1, %0|%0, %1}";
10936 [(set (attr "type")
10937 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
10938 (match_operand 0 "register_operand"))
10939 (match_operand 1 "const1_operand"))
10940 (const_string "alu1")
10942 (const_string "ishift1")))
10943 (set (attr "length_immediate")
10945 (ior (eq_attr "type" "alu1")
10946 (and (eq_attr "type" "ishift1")
10947 (and (match_operand 1 "const1_operand")
10948 (ior (match_test "TARGET_SHIFT1")
10949 (match_test "optimize_function_for_size_p (cfun)")))))
10951 (const_string "*")))
10952 (set_attr "mode" "QI")])
10954 ;; Convert ashift to the lea pattern to avoid flags dependency.
10956 [(set (match_operand:SWI 0 "register_operand")
10957 (ashift:SWI (match_operand:SWI 1 "index_register_operand")
10958 (match_operand 2 "const_0_to_3_operand")))
10959 (clobber (reg:CC FLAGS_REG))]
10961 && REGNO (operands[0]) != REGNO (operands[1])"
10962 [(set (match_dup 0)
10963 (mult:<LEAMODE> (match_dup 1) (match_dup 2)))]
10965 if (<MODE>mode != <LEAMODE>mode)
10967 operands[0] = gen_lowpart (<LEAMODE>mode, operands[0]);
10968 operands[1] = gen_lowpart (<LEAMODE>mode, operands[1]);
10970 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
10973 ;; Convert ashift to the lea pattern to avoid flags dependency.
10975 [(set (match_operand:DI 0 "register_operand")
10977 (ashift:SI (match_operand:SI 1 "index_register_operand")
10978 (match_operand 2 "const_0_to_3_operand"))))
10979 (clobber (reg:CC FLAGS_REG))]
10980 "TARGET_64BIT && reload_completed
10981 && REGNO (operands[0]) != REGNO (operands[1])"
10982 [(set (match_dup 0)
10983 (zero_extend:DI (mult:SI (match_dup 1) (match_dup 2))))]
10985 operands[1] = gen_lowpart (SImode, operands[1]);
10986 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
10989 ;; This pattern can't accept a variable shift count, since shifts by
10990 ;; zero don't affect the flags. We assume that shifts by constant
10991 ;; zero are optimized away.
10992 (define_insn "*ashl<mode>3_cmp"
10993 [(set (reg FLAGS_REG)
10995 (ashift:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
10996 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
10998 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
10999 (ashift:SWI (match_dup 1) (match_dup 2)))]
11000 "(optimize_function_for_size_p (cfun)
11001 || !TARGET_PARTIAL_FLAG_REG_STALL
11002 || (operands[2] == const1_rtx
11004 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
11005 && ix86_match_ccmode (insn, CCGOCmode)
11006 && ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
11008 switch (get_attr_type (insn))
11011 gcc_assert (operands[2] == const1_rtx);
11012 return "add{<imodesuffix>}\t%0, %0";
11015 if (operands[2] == const1_rtx
11016 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11017 return "sal{<imodesuffix>}\t%0";
11019 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
11022 [(set (attr "type")
11023 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
11024 (match_operand 0 "register_operand"))
11025 (match_operand 2 "const1_operand"))
11026 (const_string "alu")
11028 (const_string "ishift")))
11029 (set (attr "length_immediate")
11031 (ior (eq_attr "type" "alu")
11032 (and (eq_attr "type" "ishift")
11033 (and (match_operand 2 "const1_operand")
11034 (ior (match_test "TARGET_SHIFT1")
11035 (match_test "optimize_function_for_size_p (cfun)")))))
11037 (const_string "*")))
11038 (set_attr "mode" "<MODE>")])
11040 (define_insn "*ashlsi3_cmp_zext"
11041 [(set (reg FLAGS_REG)
11043 (ashift:SI (match_operand:SI 1 "register_operand" "0")
11044 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11046 (set (match_operand:DI 0 "register_operand" "=r")
11047 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
11049 && (optimize_function_for_size_p (cfun)
11050 || !TARGET_PARTIAL_FLAG_REG_STALL
11051 || (operands[2] == const1_rtx
11053 || TARGET_DOUBLE_WITH_ADD)))
11054 && ix86_match_ccmode (insn, CCGOCmode)
11055 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11057 switch (get_attr_type (insn))
11060 gcc_assert (operands[2] == const1_rtx);
11061 return "add{l}\t%k0, %k0";
11064 if (operands[2] == const1_rtx
11065 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11066 return "sal{l}\t%k0";
11068 return "sal{l}\t{%2, %k0|%k0, %2}";
11071 [(set (attr "type")
11072 (cond [(and (match_test "TARGET_DOUBLE_WITH_ADD")
11073 (match_operand 2 "const1_operand"))
11074 (const_string "alu")
11076 (const_string "ishift")))
11077 (set (attr "length_immediate")
11079 (ior (eq_attr "type" "alu")
11080 (and (eq_attr "type" "ishift")
11081 (and (match_operand 2 "const1_operand")
11082 (ior (match_test "TARGET_SHIFT1")
11083 (match_test "optimize_function_for_size_p (cfun)")))))
11085 (const_string "*")))
11086 (set_attr "mode" "SI")])
11088 (define_insn "*ashl<mode>3_cconly"
11089 [(set (reg FLAGS_REG)
11091 (ashift:SWI (match_operand:SWI 1 "register_operand" "0")
11092 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
11094 (clobber (match_scratch:SWI 0 "=<r>"))]
11095 "(optimize_function_for_size_p (cfun)
11096 || !TARGET_PARTIAL_FLAG_REG_STALL
11097 || (operands[2] == const1_rtx
11099 || TARGET_DOUBLE_WITH_ADD)))
11100 && ix86_match_ccmode (insn, CCGOCmode)"
11102 switch (get_attr_type (insn))
11105 gcc_assert (operands[2] == const1_rtx);
11106 return "add{<imodesuffix>}\t%0, %0";
11109 if (operands[2] == const1_rtx
11110 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11111 return "sal{<imodesuffix>}\t%0";
11113 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
11116 [(set (attr "type")
11117 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
11118 (match_operand 0 "register_operand"))
11119 (match_operand 2 "const1_operand"))
11120 (const_string "alu")
11122 (const_string "ishift")))
11123 (set (attr "length_immediate")
11125 (ior (eq_attr "type" "alu")
11126 (and (eq_attr "type" "ishift")
11127 (and (match_operand 2 "const1_operand")
11128 (ior (match_test "TARGET_SHIFT1")
11129 (match_test "optimize_function_for_size_p (cfun)")))))
11131 (const_string "*")))
11132 (set_attr "mode" "<MODE>")])
11134 ;; See comment above `ashl<mode>3' about how this works.
11136 (define_expand "<shift_insn><mode>3"
11137 [(set (match_operand:SDWIM 0 "<shift_operand>")
11138 (any_shiftrt:SDWIM (match_operand:SDWIM 1 "<shift_operand>")
11139 (match_operand:QI 2 "nonmemory_operand")))]
11141 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
11143 ;; Avoid useless masking of count operand.
11144 (define_insn_and_split "*<shift_insn><mode>3_mask"
11145 [(set (match_operand:SWI48 0 "nonimmediate_operand")
11147 (match_operand:SWI48 1 "nonimmediate_operand")
11150 (match_operand:SI 2 "register_operand" "c,r")
11151 (match_operand:SI 3 "const_int_operand")) 0)))
11152 (clobber (reg:CC FLAGS_REG))]
11153 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
11154 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
11155 == GET_MODE_BITSIZE (<MODE>mode)-1
11156 && can_create_pseudo_p ()"
11160 [(set (match_dup 0)
11161 (any_shiftrt:SWI48 (match_dup 1)
11163 (clobber (reg:CC FLAGS_REG))])]
11164 "operands[2] = gen_lowpart (QImode, operands[2]);"
11165 [(set_attr "isa" "*,bmi2")])
11167 (define_insn_and_split "*<shift_insn><mode>3_mask_1"
11168 [(set (match_operand:SWI48 0 "nonimmediate_operand")
11170 (match_operand:SWI48 1 "nonimmediate_operand")
11172 (match_operand:QI 2 "register_operand" "c,r")
11173 (match_operand:QI 3 "const_int_operand"))))
11174 (clobber (reg:CC FLAGS_REG))]
11175 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
11176 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
11177 == GET_MODE_BITSIZE (<MODE>mode)-1
11178 && can_create_pseudo_p ()"
11182 [(set (match_dup 0)
11183 (any_shiftrt:SWI48 (match_dup 1)
11185 (clobber (reg:CC FLAGS_REG))])]
11187 [(set_attr "isa" "*,bmi2")])
11189 (define_insn_and_split "*<shift_insn><dwi>3_doubleword_mask"
11190 [(set (match_operand:<DWI> 0 "register_operand")
11192 (match_operand:<DWI> 1 "register_operand")
11195 (match_operand:SI 2 "register_operand" "c")
11196 (match_operand:SI 3 "const_int_operand")) 0)))
11197 (clobber (reg:CC FLAGS_REG))]
11198 "(INTVAL (operands[3]) & (<MODE_SIZE> * BITS_PER_UNIT)) == 0
11199 && can_create_pseudo_p ()"
11203 [(set (match_dup 4)
11204 (ior:DWIH (lshiftrt:DWIH (match_dup 4) (match_dup 2))
11205 (ashift:DWIH (match_dup 7)
11206 (minus:QI (match_dup 8) (match_dup 2)))))
11207 (clobber (reg:CC FLAGS_REG))])
11209 [(set (match_dup 6)
11210 (any_shiftrt:DWIH (match_dup 7) (match_dup 2)))
11211 (clobber (reg:CC FLAGS_REG))])]
11213 split_double_mode (<DWI>mode, &operands[0], 2, &operands[4], &operands[6]);
11215 operands[8] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT);
11217 if ((INTVAL (operands[3]) & ((<MODE_SIZE> * BITS_PER_UNIT) - 1))
11218 != ((<MODE_SIZE> * BITS_PER_UNIT) - 1))
11220 rtx tem = gen_reg_rtx (SImode);
11221 emit_insn (gen_andsi3 (tem, operands[2], operands[3]));
11225 operands[2] = gen_lowpart (QImode, operands[2]);
11227 if (!rtx_equal_p (operands[4], operands[5]))
11228 emit_move_insn (operands[4], operands[5]);
11231 (define_insn_and_split "*<shift_insn><dwi>3_doubleword_mask_1"
11232 [(set (match_operand:<DWI> 0 "register_operand")
11234 (match_operand:<DWI> 1 "register_operand")
11236 (match_operand:QI 2 "register_operand" "c")
11237 (match_operand:QI 3 "const_int_operand"))))
11238 (clobber (reg:CC FLAGS_REG))]
11239 "(INTVAL (operands[3]) & (<MODE_SIZE> * BITS_PER_UNIT)) == 0
11240 && can_create_pseudo_p ()"
11244 [(set (match_dup 4)
11245 (ior:DWIH (lshiftrt:DWIH (match_dup 4) (match_dup 2))
11246 (ashift:DWIH (match_dup 7)
11247 (minus:QI (match_dup 8) (match_dup 2)))))
11248 (clobber (reg:CC FLAGS_REG))])
11250 [(set (match_dup 6)
11251 (any_shiftrt:DWIH (match_dup 7) (match_dup 2)))
11252 (clobber (reg:CC FLAGS_REG))])]
11254 split_double_mode (<DWI>mode, &operands[0], 2, &operands[4], &operands[6]);
11256 operands[8] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT);
11258 if ((INTVAL (operands[3]) & ((<MODE_SIZE> * BITS_PER_UNIT) - 1))
11259 != ((<MODE_SIZE> * BITS_PER_UNIT) - 1))
11261 rtx tem = gen_reg_rtx (QImode);
11262 emit_insn (gen_andqi3 (tem, operands[2], operands[3]));
11266 if (!rtx_equal_p (operands[4], operands[5]))
11267 emit_move_insn (operands[4], operands[5]);
11270 (define_insn_and_split "*<shift_insn><mode>3_doubleword"
11271 [(set (match_operand:DWI 0 "register_operand" "=&r")
11272 (any_shiftrt:DWI (match_operand:DWI 1 "register_operand" "0")
11273 (match_operand:QI 2 "nonmemory_operand" "<S>c")))
11274 (clobber (reg:CC FLAGS_REG))]
11277 "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
11279 "ix86_split_<shift_insn> (operands, NULL_RTX, <MODE>mode); DONE;"
11280 [(set_attr "type" "multi")])
11282 ;; By default we don't ask for a scratch register, because when DWImode
11283 ;; values are manipulated, registers are already at a premium. But if
11284 ;; we have one handy, we won't turn it away.
11287 [(match_scratch:DWIH 3 "r")
11288 (parallel [(set (match_operand:<DWI> 0 "register_operand")
11290 (match_operand:<DWI> 1 "register_operand")
11291 (match_operand:QI 2 "nonmemory_operand")))
11292 (clobber (reg:CC FLAGS_REG))])
11296 "ix86_split_<shift_insn> (operands, operands[3], <DWI>mode); DONE;")
11298 (define_insn "x86_64_shrd"
11299 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
11300 (ior:DI (lshiftrt:DI (match_dup 0)
11301 (match_operand:QI 2 "nonmemory_operand" "Jc"))
11302 (ashift:DI (match_operand:DI 1 "register_operand" "r")
11303 (minus:QI (const_int 64) (match_dup 2)))))
11304 (clobber (reg:CC FLAGS_REG))]
11306 "shrd{q}\t{%s2%1, %0|%0, %1, %2}"
11307 [(set_attr "type" "ishift")
11308 (set_attr "prefix_0f" "1")
11309 (set_attr "mode" "DI")
11310 (set_attr "athlon_decode" "vector")
11311 (set_attr "amdfam10_decode" "vector")
11312 (set_attr "bdver1_decode" "vector")])
11314 (define_insn "x86_shrd"
11315 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
11316 (ior:SI (lshiftrt:SI (match_dup 0)
11317 (match_operand:QI 2 "nonmemory_operand" "Ic"))
11318 (ashift:SI (match_operand:SI 1 "register_operand" "r")
11319 (minus:QI (const_int 32) (match_dup 2)))))
11320 (clobber (reg:CC FLAGS_REG))]
11322 "shrd{l}\t{%s2%1, %0|%0, %1, %2}"
11323 [(set_attr "type" "ishift")
11324 (set_attr "prefix_0f" "1")
11325 (set_attr "mode" "SI")
11326 (set_attr "pent_pair" "np")
11327 (set_attr "athlon_decode" "vector")
11328 (set_attr "amdfam10_decode" "vector")
11329 (set_attr "bdver1_decode" "vector")])
11331 (define_insn "ashrdi3_cvt"
11332 [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
11333 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
11334 (match_operand:QI 2 "const_int_operand")))
11335 (clobber (reg:CC FLAGS_REG))]
11336 "TARGET_64BIT && INTVAL (operands[2]) == 63
11337 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
11338 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11341 sar{q}\t{%2, %0|%0, %2}"
11342 [(set_attr "type" "imovx,ishift")
11343 (set_attr "prefix_0f" "0,*")
11344 (set_attr "length_immediate" "0,*")
11345 (set_attr "modrm" "0,1")
11346 (set_attr "mode" "DI")])
11348 (define_insn "*ashrsi3_cvt_zext"
11349 [(set (match_operand:DI 0 "register_operand" "=*d,r")
11351 (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
11352 (match_operand:QI 2 "const_int_operand"))))
11353 (clobber (reg:CC FLAGS_REG))]
11354 "TARGET_64BIT && INTVAL (operands[2]) == 31
11355 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
11356 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11359 sar{l}\t{%2, %k0|%k0, %2}"
11360 [(set_attr "type" "imovx,ishift")
11361 (set_attr "prefix_0f" "0,*")
11362 (set_attr "length_immediate" "0,*")
11363 (set_attr "modrm" "0,1")
11364 (set_attr "mode" "SI")])
11366 (define_insn "ashrsi3_cvt"
11367 [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
11368 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
11369 (match_operand:QI 2 "const_int_operand")))
11370 (clobber (reg:CC FLAGS_REG))]
11371 "INTVAL (operands[2]) == 31
11372 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
11373 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11376 sar{l}\t{%2, %0|%0, %2}"
11377 [(set_attr "type" "imovx,ishift")
11378 (set_attr "prefix_0f" "0,*")
11379 (set_attr "length_immediate" "0,*")
11380 (set_attr "modrm" "0,1")
11381 (set_attr "mode" "SI")])
11383 (define_expand "x86_shift<mode>_adj_3"
11384 [(use (match_operand:SWI48 0 "register_operand"))
11385 (use (match_operand:SWI48 1 "register_operand"))
11386 (use (match_operand:QI 2 "register_operand"))]
11389 rtx_code_label *label = gen_label_rtx ();
11392 emit_insn (gen_testqi_ccz_1 (operands[2],
11393 GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
11395 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
11396 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
11397 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
11398 gen_rtx_LABEL_REF (VOIDmode, label),
11400 tmp = emit_jump_insn (gen_rtx_SET (pc_rtx, tmp));
11401 JUMP_LABEL (tmp) = label;
11403 emit_move_insn (operands[0], operands[1]);
11404 emit_insn (gen_ashr<mode>3_cvt (operands[1], operands[1],
11405 GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1)));
11406 emit_label (label);
11407 LABEL_NUSES (label) = 1;
11412 (define_insn "*bmi2_<shift_insn><mode>3_1"
11413 [(set (match_operand:SWI48 0 "register_operand" "=r")
11414 (any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11415 (match_operand:SWI48 2 "register_operand" "r")))]
11417 "<shift>x\t{%2, %1, %0|%0, %1, %2}"
11418 [(set_attr "type" "ishiftx")
11419 (set_attr "mode" "<MODE>")])
11421 (define_insn "*<shift_insn><mode>3_1"
11422 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
11424 (match_operand:SWI48 1 "nonimmediate_operand" "0,rm")
11425 (match_operand:QI 2 "nonmemory_operand" "c<S>,r")))
11426 (clobber (reg:CC FLAGS_REG))]
11427 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
11429 switch (get_attr_type (insn))
11435 if (operands[2] == const1_rtx
11436 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11437 return "<shift>{<imodesuffix>}\t%0";
11439 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
11442 [(set_attr "isa" "*,bmi2")
11443 (set_attr "type" "ishift,ishiftx")
11444 (set (attr "length_immediate")
11446 (and (match_operand 2 "const1_operand")
11447 (ior (match_test "TARGET_SHIFT1")
11448 (match_test "optimize_function_for_size_p (cfun)")))
11450 (const_string "*")))
11451 (set_attr "mode" "<MODE>")])
11453 ;; Convert shift to the shiftx pattern to avoid flags dependency.
11455 [(set (match_operand:SWI48 0 "register_operand")
11456 (any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
11457 (match_operand:QI 2 "register_operand")))
11458 (clobber (reg:CC FLAGS_REG))]
11459 "TARGET_BMI2 && reload_completed"
11460 [(set (match_dup 0)
11461 (any_shiftrt:SWI48 (match_dup 1) (match_dup 2)))]
11462 "operands[2] = gen_lowpart (<MODE>mode, operands[2]);")
11464 (define_insn "*bmi2_<shift_insn>si3_1_zext"
11465 [(set (match_operand:DI 0 "register_operand" "=r")
11467 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
11468 (match_operand:SI 2 "register_operand" "r"))))]
11469 "TARGET_64BIT && TARGET_BMI2"
11470 "<shift>x\t{%2, %1, %k0|%k0, %1, %2}"
11471 [(set_attr "type" "ishiftx")
11472 (set_attr "mode" "SI")])
11474 (define_insn "*<shift_insn>si3_1_zext"
11475 [(set (match_operand:DI 0 "register_operand" "=r,r")
11477 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm")
11478 (match_operand:QI 2 "nonmemory_operand" "cI,r"))))
11479 (clobber (reg:CC FLAGS_REG))]
11480 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
11482 switch (get_attr_type (insn))
11488 if (operands[2] == const1_rtx
11489 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11490 return "<shift>{l}\t%k0";
11492 return "<shift>{l}\t{%2, %k0|%k0, %2}";
11495 [(set_attr "isa" "*,bmi2")
11496 (set_attr "type" "ishift,ishiftx")
11497 (set (attr "length_immediate")
11499 (and (match_operand 2 "const1_operand")
11500 (ior (match_test "TARGET_SHIFT1")
11501 (match_test "optimize_function_for_size_p (cfun)")))
11503 (const_string "*")))
11504 (set_attr "mode" "SI")])
11506 ;; Convert shift to the shiftx pattern to avoid flags dependency.
11508 [(set (match_operand:DI 0 "register_operand")
11510 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand")
11511 (match_operand:QI 2 "register_operand"))))
11512 (clobber (reg:CC FLAGS_REG))]
11513 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
11514 [(set (match_dup 0)
11515 (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
11516 "operands[2] = gen_lowpart (SImode, operands[2]);")
11518 (define_insn "*<shift_insn><mode>3_1"
11519 [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m")
11521 (match_operand:SWI12 1 "nonimmediate_operand" "0")
11522 (match_operand:QI 2 "nonmemory_operand" "c<S>")))
11523 (clobber (reg:CC FLAGS_REG))]
11524 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
11526 if (operands[2] == const1_rtx
11527 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11528 return "<shift>{<imodesuffix>}\t%0";
11530 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
11532 [(set_attr "type" "ishift")
11533 (set (attr "length_immediate")
11535 (and (match_operand 2 "const1_operand")
11536 (ior (match_test "TARGET_SHIFT1")
11537 (match_test "optimize_function_for_size_p (cfun)")))
11539 (const_string "*")))
11540 (set_attr "mode" "<MODE>")])
11542 (define_insn "*<shift_insn>qi3_1_slp"
11543 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
11544 (any_shiftrt:QI (match_dup 0)
11545 (match_operand:QI 1 "nonmemory_operand" "cI")))
11546 (clobber (reg:CC FLAGS_REG))]
11547 "(optimize_function_for_size_p (cfun)
11548 || !TARGET_PARTIAL_REG_STALL
11549 || (operands[1] == const1_rtx
11550 && TARGET_SHIFT1))"
11552 if (operands[1] == const1_rtx
11553 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11554 return "<shift>{b}\t%0";
11556 return "<shift>{b}\t{%1, %0|%0, %1}";
11558 [(set_attr "type" "ishift1")
11559 (set (attr "length_immediate")
11561 (and (match_operand 1 "const1_operand")
11562 (ior (match_test "TARGET_SHIFT1")
11563 (match_test "optimize_function_for_size_p (cfun)")))
11565 (const_string "*")))
11566 (set_attr "mode" "QI")])
11568 ;; This pattern can't accept a variable shift count, since shifts by
11569 ;; zero don't affect the flags. We assume that shifts by constant
11570 ;; zero are optimized away.
11571 (define_insn "*<shift_insn><mode>3_cmp"
11572 [(set (reg FLAGS_REG)
11575 (match_operand:SWI 1 "nonimmediate_operand" "0")
11576 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
11578 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
11579 (any_shiftrt:SWI (match_dup 1) (match_dup 2)))]
11580 "(optimize_function_for_size_p (cfun)
11581 || !TARGET_PARTIAL_FLAG_REG_STALL
11582 || (operands[2] == const1_rtx
11584 && ix86_match_ccmode (insn, CCGOCmode)
11585 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
11587 if (operands[2] == const1_rtx
11588 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11589 return "<shift>{<imodesuffix>}\t%0";
11591 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
11593 [(set_attr "type" "ishift")
11594 (set (attr "length_immediate")
11596 (and (match_operand 2 "const1_operand")
11597 (ior (match_test "TARGET_SHIFT1")
11598 (match_test "optimize_function_for_size_p (cfun)")))
11600 (const_string "*")))
11601 (set_attr "mode" "<MODE>")])
11603 (define_insn "*<shift_insn>si3_cmp_zext"
11604 [(set (reg FLAGS_REG)
11606 (any_shiftrt:SI (match_operand:SI 1 "register_operand" "0")
11607 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11609 (set (match_operand:DI 0 "register_operand" "=r")
11610 (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
11612 && (optimize_function_for_size_p (cfun)
11613 || !TARGET_PARTIAL_FLAG_REG_STALL
11614 || (operands[2] == const1_rtx
11616 && ix86_match_ccmode (insn, CCGOCmode)
11617 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
11619 if (operands[2] == const1_rtx
11620 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11621 return "<shift>{l}\t%k0";
11623 return "<shift>{l}\t{%2, %k0|%k0, %2}";
11625 [(set_attr "type" "ishift")
11626 (set (attr "length_immediate")
11628 (and (match_operand 2 "const1_operand")
11629 (ior (match_test "TARGET_SHIFT1")
11630 (match_test "optimize_function_for_size_p (cfun)")))
11632 (const_string "*")))
11633 (set_attr "mode" "SI")])
11635 (define_insn "*<shift_insn><mode>3_cconly"
11636 [(set (reg FLAGS_REG)
11639 (match_operand:SWI 1 "register_operand" "0")
11640 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
11642 (clobber (match_scratch:SWI 0 "=<r>"))]
11643 "(optimize_function_for_size_p (cfun)
11644 || !TARGET_PARTIAL_FLAG_REG_STALL
11645 || (operands[2] == const1_rtx
11647 && ix86_match_ccmode (insn, CCGOCmode)"
11649 if (operands[2] == const1_rtx
11650 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11651 return "<shift>{<imodesuffix>}\t%0";
11653 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
11655 [(set_attr "type" "ishift")
11656 (set (attr "length_immediate")
11658 (and (match_operand 2 "const1_operand")
11659 (ior (match_test "TARGET_SHIFT1")
11660 (match_test "optimize_function_for_size_p (cfun)")))
11662 (const_string "*")))
11663 (set_attr "mode" "<MODE>")])
11665 ;; Rotate instructions
11667 (define_expand "<rotate_insn>ti3"
11668 [(set (match_operand:TI 0 "register_operand")
11669 (any_rotate:TI (match_operand:TI 1 "register_operand")
11670 (match_operand:QI 2 "nonmemory_operand")))]
11673 if (const_1_to_63_operand (operands[2], VOIDmode))
11674 emit_insn (gen_ix86_<rotate_insn>ti3_doubleword
11675 (operands[0], operands[1], operands[2]));
11682 (define_expand "<rotate_insn>di3"
11683 [(set (match_operand:DI 0 "shiftdi_operand")
11684 (any_rotate:DI (match_operand:DI 1 "shiftdi_operand")
11685 (match_operand:QI 2 "nonmemory_operand")))]
11689 ix86_expand_binary_operator (<CODE>, DImode, operands);
11690 else if (const_1_to_31_operand (operands[2], VOIDmode))
11691 emit_insn (gen_ix86_<rotate_insn>di3_doubleword
11692 (operands[0], operands[1], operands[2]));
11699 (define_expand "<rotate_insn><mode>3"
11700 [(set (match_operand:SWIM124 0 "nonimmediate_operand")
11701 (any_rotate:SWIM124 (match_operand:SWIM124 1 "nonimmediate_operand")
11702 (match_operand:QI 2 "nonmemory_operand")))]
11704 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
11706 ;; Avoid useless masking of count operand.
11707 (define_insn_and_split "*<rotate_insn><mode>3_mask"
11708 [(set (match_operand:SWI48 0 "nonimmediate_operand")
11710 (match_operand:SWI48 1 "nonimmediate_operand")
11713 (match_operand:SI 2 "register_operand" "c")
11714 (match_operand:SI 3 "const_int_operand")) 0)))
11715 (clobber (reg:CC FLAGS_REG))]
11716 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
11717 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
11718 == GET_MODE_BITSIZE (<MODE>mode)-1
11719 && can_create_pseudo_p ()"
11723 [(set (match_dup 0)
11724 (any_rotate:SWI48 (match_dup 1)
11726 (clobber (reg:CC FLAGS_REG))])]
11727 "operands[2] = gen_lowpart (QImode, operands[2]);")
11729 (define_insn_and_split "*<rotate_insn><mode>3_mask_1"
11730 [(set (match_operand:SWI48 0 "nonimmediate_operand")
11732 (match_operand:SWI48 1 "nonimmediate_operand")
11734 (match_operand:QI 2 "register_operand" "c")
11735 (match_operand:QI 3 "const_int_operand"))))
11736 (clobber (reg:CC FLAGS_REG))]
11737 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
11738 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
11739 == GET_MODE_BITSIZE (<MODE>mode)-1
11740 && can_create_pseudo_p ()"
11744 [(set (match_dup 0)
11745 (any_rotate:SWI48 (match_dup 1)
11747 (clobber (reg:CC FLAGS_REG))])])
11749 ;; Implement rotation using two double-precision
11750 ;; shift instructions and a scratch register.
11752 (define_insn_and_split "ix86_rotl<dwi>3_doubleword"
11753 [(set (match_operand:<DWI> 0 "register_operand" "=r")
11754 (rotate:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
11755 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
11756 (clobber (reg:CC FLAGS_REG))
11757 (clobber (match_scratch:DWIH 3 "=&r"))]
11761 [(set (match_dup 3) (match_dup 4))
11763 [(set (match_dup 4)
11764 (ior:DWIH (ashift:DWIH (match_dup 4) (match_dup 2))
11765 (lshiftrt:DWIH (match_dup 5)
11766 (minus:QI (match_dup 6) (match_dup 2)))))
11767 (clobber (reg:CC FLAGS_REG))])
11769 [(set (match_dup 5)
11770 (ior:DWIH (ashift:DWIH (match_dup 5) (match_dup 2))
11771 (lshiftrt:DWIH (match_dup 3)
11772 (minus:QI (match_dup 6) (match_dup 2)))))
11773 (clobber (reg:CC FLAGS_REG))])]
11775 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
11777 split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
11780 (define_insn_and_split "ix86_rotr<dwi>3_doubleword"
11781 [(set (match_operand:<DWI> 0 "register_operand" "=r")
11782 (rotatert:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
11783 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
11784 (clobber (reg:CC FLAGS_REG))
11785 (clobber (match_scratch:DWIH 3 "=&r"))]
11789 [(set (match_dup 3) (match_dup 4))
11791 [(set (match_dup 4)
11792 (ior:DWIH (lshiftrt:DWIH (match_dup 4) (match_dup 2))
11793 (ashift:DWIH (match_dup 5)
11794 (minus:QI (match_dup 6) (match_dup 2)))))
11795 (clobber (reg:CC FLAGS_REG))])
11797 [(set (match_dup 5)
11798 (ior:DWIH (lshiftrt:DWIH (match_dup 5) (match_dup 2))
11799 (ashift:DWIH (match_dup 3)
11800 (minus:QI (match_dup 6) (match_dup 2)))))
11801 (clobber (reg:CC FLAGS_REG))])]
11803 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
11805 split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
11808 (define_mode_attr rorx_immediate_operand
11809 [(SI "const_0_to_31_operand")
11810 (DI "const_0_to_63_operand")])
11812 (define_insn "*bmi2_rorx<mode>3_1"
11813 [(set (match_operand:SWI48 0 "register_operand" "=r")
11815 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11816 (match_operand:QI 2 "<rorx_immediate_operand>" "<S>")))]
11818 "rorx\t{%2, %1, %0|%0, %1, %2}"
11819 [(set_attr "type" "rotatex")
11820 (set_attr "mode" "<MODE>")])
11822 (define_insn "*<rotate_insn><mode>3_1"
11823 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
11825 (match_operand:SWI48 1 "nonimmediate_operand" "0,rm")
11826 (match_operand:QI 2 "nonmemory_operand" "c<S>,<S>")))
11827 (clobber (reg:CC FLAGS_REG))]
11828 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
11830 switch (get_attr_type (insn))
11836 if (operands[2] == const1_rtx
11837 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11838 return "<rotate>{<imodesuffix>}\t%0";
11840 return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
11843 [(set_attr "isa" "*,bmi2")
11844 (set_attr "type" "rotate,rotatex")
11845 (set (attr "length_immediate")
11847 (and (eq_attr "type" "rotate")
11848 (and (match_operand 2 "const1_operand")
11849 (ior (match_test "TARGET_SHIFT1")
11850 (match_test "optimize_function_for_size_p (cfun)"))))
11852 (const_string "*")))
11853 (set_attr "mode" "<MODE>")])
11855 ;; Convert rotate to the rotatex pattern to avoid flags dependency.
11857 [(set (match_operand:SWI48 0 "register_operand")
11858 (rotate:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
11859 (match_operand:QI 2 "const_int_operand")))
11860 (clobber (reg:CC FLAGS_REG))]
11861 "TARGET_BMI2 && reload_completed"
11862 [(set (match_dup 0)
11863 (rotatert:SWI48 (match_dup 1) (match_dup 2)))]
11865 int bitsize = GET_MODE_BITSIZE (<MODE>mode);
11867 operands[2] = GEN_INT ((bitsize - INTVAL (operands[2])) % bitsize);
11871 [(set (match_operand:SWI48 0 "register_operand")
11872 (rotatert:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
11873 (match_operand:QI 2 "const_int_operand")))
11874 (clobber (reg:CC FLAGS_REG))]
11875 "TARGET_BMI2 && reload_completed"
11876 [(set (match_dup 0)
11877 (rotatert:SWI48 (match_dup 1) (match_dup 2)))])
11879 (define_insn "*bmi2_rorxsi3_1_zext"
11880 [(set (match_operand:DI 0 "register_operand" "=r")
11882 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
11883 (match_operand:QI 2 "const_0_to_31_operand" "I"))))]
11884 "TARGET_64BIT && TARGET_BMI2"
11885 "rorx\t{%2, %1, %k0|%k0, %1, %2}"
11886 [(set_attr "type" "rotatex")
11887 (set_attr "mode" "SI")])
11889 (define_insn "*<rotate_insn>si3_1_zext"
11890 [(set (match_operand:DI 0 "register_operand" "=r,r")
11892 (any_rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm")
11893 (match_operand:QI 2 "nonmemory_operand" "cI,I"))))
11894 (clobber (reg:CC FLAGS_REG))]
11895 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
11897 switch (get_attr_type (insn))
11903 if (operands[2] == const1_rtx
11904 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11905 return "<rotate>{l}\t%k0";
11907 return "<rotate>{l}\t{%2, %k0|%k0, %2}";
11910 [(set_attr "isa" "*,bmi2")
11911 (set_attr "type" "rotate,rotatex")
11912 (set (attr "length_immediate")
11914 (and (eq_attr "type" "rotate")
11915 (and (match_operand 2 "const1_operand")
11916 (ior (match_test "TARGET_SHIFT1")
11917 (match_test "optimize_function_for_size_p (cfun)"))))
11919 (const_string "*")))
11920 (set_attr "mode" "SI")])
11922 ;; Convert rotate to the rotatex pattern to avoid flags dependency.
11924 [(set (match_operand:DI 0 "register_operand")
11926 (rotate:SI (match_operand:SI 1 "nonimmediate_operand")
11927 (match_operand:QI 2 "const_int_operand"))))
11928 (clobber (reg:CC FLAGS_REG))]
11929 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
11930 [(set (match_dup 0)
11931 (zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))]
11933 int bitsize = GET_MODE_BITSIZE (SImode);
11935 operands[2] = GEN_INT ((bitsize - INTVAL (operands[2])) % bitsize);
11939 [(set (match_operand:DI 0 "register_operand")
11941 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand")
11942 (match_operand:QI 2 "const_int_operand"))))
11943 (clobber (reg:CC FLAGS_REG))]
11944 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
11945 [(set (match_dup 0)
11946 (zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))])
11948 (define_insn "*<rotate_insn><mode>3_1"
11949 [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m")
11950 (any_rotate:SWI12 (match_operand:SWI12 1 "nonimmediate_operand" "0")
11951 (match_operand:QI 2 "nonmemory_operand" "c<S>")))
11952 (clobber (reg:CC FLAGS_REG))]
11953 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
11955 if (operands[2] == const1_rtx
11956 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11957 return "<rotate>{<imodesuffix>}\t%0";
11959 return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
11961 [(set_attr "type" "rotate")
11962 (set (attr "length_immediate")
11964 (and (match_operand 2 "const1_operand")
11965 (ior (match_test "TARGET_SHIFT1")
11966 (match_test "optimize_function_for_size_p (cfun)")))
11968 (const_string "*")))
11969 (set_attr "mode" "<MODE>")])
11971 (define_insn "*<rotate_insn>qi3_1_slp"
11972 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
11973 (any_rotate:QI (match_dup 0)
11974 (match_operand:QI 1 "nonmemory_operand" "cI")))
11975 (clobber (reg:CC FLAGS_REG))]
11976 "(optimize_function_for_size_p (cfun)
11977 || !TARGET_PARTIAL_REG_STALL
11978 || (operands[1] == const1_rtx
11979 && TARGET_SHIFT1))"
11981 if (operands[1] == const1_rtx
11982 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11983 return "<rotate>{b}\t%0";
11985 return "<rotate>{b}\t{%1, %0|%0, %1}";
11987 [(set_attr "type" "rotate1")
11988 (set (attr "length_immediate")
11990 (and (match_operand 1 "const1_operand")
11991 (ior (match_test "TARGET_SHIFT1")
11992 (match_test "optimize_function_for_size_p (cfun)")))
11994 (const_string "*")))
11995 (set_attr "mode" "QI")])
11998 [(set (match_operand:HI 0 "QIreg_operand")
11999 (any_rotate:HI (match_dup 0) (const_int 8)))
12000 (clobber (reg:CC FLAGS_REG))]
12002 && (TARGET_USE_XCHGB || optimize_function_for_size_p (cfun))"
12003 [(parallel [(set (strict_low_part (match_dup 0))
12004 (bswap:HI (match_dup 0)))
12005 (clobber (reg:CC FLAGS_REG))])])
12007 ;; Bit set / bit test instructions
12009 ;; %%% bts, btr, btc
12011 ;; These instructions are *slow* when applied to memory.
12013 (define_code_attr btsc [(ior "bts") (xor "btc")])
12015 (define_insn "*<btsc><mode>"
12016 [(set (match_operand:SWI48 0 "register_operand" "=r")
12018 (ashift:SWI48 (const_int 1)
12019 (match_operand:QI 2 "register_operand" "r"))
12020 (match_operand:SWI48 1 "register_operand" "0")))
12021 (clobber (reg:CC FLAGS_REG))]
12023 "<btsc>{<imodesuffix>}\t{%<k>2, %0|%0, %<k>2}"
12024 [(set_attr "type" "alu1")
12025 (set_attr "prefix_0f" "1")
12026 (set_attr "znver1_decode" "double")
12027 (set_attr "mode" "<MODE>")])
12029 ;; Avoid useless masking of count operand.
12030 (define_insn_and_split "*<btsc><mode>_mask"
12031 [(set (match_operand:SWI48 0 "register_operand")
12037 (match_operand:SI 1 "register_operand")
12038 (match_operand:SI 2 "const_int_operand")) 0))
12039 (match_operand:SWI48 3 "register_operand")))
12040 (clobber (reg:CC FLAGS_REG))]
12042 && (INTVAL (operands[2]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
12043 == GET_MODE_BITSIZE (<MODE>mode)-1
12044 && can_create_pseudo_p ()"
12048 [(set (match_dup 0)
12050 (ashift:SWI48 (const_int 1)
12053 (clobber (reg:CC FLAGS_REG))])]
12054 "operands[1] = gen_lowpart (QImode, operands[1]);")
12056 (define_insn_and_split "*<btsc><mode>_mask_1"
12057 [(set (match_operand:SWI48 0 "register_operand")
12062 (match_operand:QI 1 "register_operand")
12063 (match_operand:QI 2 "const_int_operand")))
12064 (match_operand:SWI48 3 "register_operand")))
12065 (clobber (reg:CC FLAGS_REG))]
12067 && (INTVAL (operands[2]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
12068 == GET_MODE_BITSIZE (<MODE>mode)-1
12069 && can_create_pseudo_p ()"
12073 [(set (match_dup 0)
12075 (ashift:SWI48 (const_int 1)
12078 (clobber (reg:CC FLAGS_REG))])])
12080 (define_insn "*btr<mode>"
12081 [(set (match_operand:SWI48 0 "register_operand" "=r")
12083 (rotate:SWI48 (const_int -2)
12084 (match_operand:QI 2 "register_operand" "r"))
12085 (match_operand:SWI48 1 "register_operand" "0")))
12086 (clobber (reg:CC FLAGS_REG))]
12088 "btr{<imodesuffix>}\t{%<k>2, %0|%0, %<k>2}"
12089 [(set_attr "type" "alu1")
12090 (set_attr "prefix_0f" "1")
12091 (set_attr "znver1_decode" "double")
12092 (set_attr "mode" "<MODE>")])
12094 ;; Avoid useless masking of count operand.
12095 (define_insn_and_split "*btr<mode>_mask"
12096 [(set (match_operand:SWI48 0 "register_operand")
12102 (match_operand:SI 1 "register_operand")
12103 (match_operand:SI 2 "const_int_operand")) 0))
12104 (match_operand:SWI48 3 "register_operand")))
12105 (clobber (reg:CC FLAGS_REG))]
12107 && (INTVAL (operands[2]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
12108 == GET_MODE_BITSIZE (<MODE>mode)-1
12109 && can_create_pseudo_p ()"
12113 [(set (match_dup 0)
12115 (rotate:SWI48 (const_int -2)
12118 (clobber (reg:CC FLAGS_REG))])]
12119 "operands[1] = gen_lowpart (QImode, operands[1]);")
12121 (define_insn_and_split "*btr<mode>_mask_1"
12122 [(set (match_operand:SWI48 0 "register_operand")
12127 (match_operand:QI 1 "register_operand")
12128 (match_operand:QI 2 "const_int_operand")))
12129 (match_operand:SWI48 3 "register_operand")))
12130 (clobber (reg:CC FLAGS_REG))]
12132 && (INTVAL (operands[2]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
12133 == GET_MODE_BITSIZE (<MODE>mode)-1
12134 && can_create_pseudo_p ()"
12138 [(set (match_dup 0)
12140 (rotate:SWI48 (const_int -2)
12143 (clobber (reg:CC FLAGS_REG))])])
12145 ;; These instructions are never faster than the corresponding
12146 ;; and/ior/xor operations when using immediate operand, so with
12147 ;; 32-bit there's no point. But in 64-bit, we can't hold the
12148 ;; relevant immediates within the instruction itself, so operating
12149 ;; on bits in the high 32-bits of a register becomes easier.
12151 ;; These are slow on Nocona, but fast on Athlon64. We do require the use
12152 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
12153 ;; negdf respectively, so they can never be disabled entirely.
12155 (define_insn "*btsq_imm"
12156 [(set (zero_extract:DI (match_operand:DI 0 "nonimmediate_operand" "+rm")
12158 (match_operand 1 "const_0_to_63_operand" "J"))
12160 (clobber (reg:CC FLAGS_REG))]
12161 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
12162 "bts{q}\t{%1, %0|%0, %1}"
12163 [(set_attr "type" "alu1")
12164 (set_attr "prefix_0f" "1")
12165 (set_attr "znver1_decode" "double")
12166 (set_attr "mode" "DI")])
12168 (define_insn "*btrq_imm"
12169 [(set (zero_extract:DI (match_operand:DI 0 "nonimmediate_operand" "+rm")
12171 (match_operand 1 "const_0_to_63_operand" "J"))
12173 (clobber (reg:CC FLAGS_REG))]
12174 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
12175 "btr{q}\t{%1, %0|%0, %1}"
12176 [(set_attr "type" "alu1")
12177 (set_attr "prefix_0f" "1")
12178 (set_attr "znver1_decode" "double")
12179 (set_attr "mode" "DI")])
12181 (define_insn "*btcq_imm"
12182 [(set (zero_extract:DI (match_operand:DI 0 "nonimmediate_operand" "+rm")
12184 (match_operand 1 "const_0_to_63_operand" "J"))
12185 (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
12186 (clobber (reg:CC FLAGS_REG))]
12187 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
12188 "btc{q}\t{%1, %0|%0, %1}"
12189 [(set_attr "type" "alu1")
12190 (set_attr "prefix_0f" "1")
12191 (set_attr "znver1_decode" "double")
12192 (set_attr "mode" "DI")])
12194 ;; Allow Nocona to avoid these instructions if a register is available.
12197 [(match_scratch:DI 2 "r")
12198 (parallel [(set (zero_extract:DI
12199 (match_operand:DI 0 "nonimmediate_operand")
12201 (match_operand 1 "const_0_to_63_operand"))
12203 (clobber (reg:CC FLAGS_REG))])]
12204 "TARGET_64BIT && !TARGET_USE_BT"
12205 [(parallel [(set (match_dup 0)
12206 (ior:DI (match_dup 0) (match_dup 3)))
12207 (clobber (reg:CC FLAGS_REG))])]
12209 int i = INTVAL (operands[1]);
12211 operands[3] = gen_int_mode (HOST_WIDE_INT_1U << i, DImode);
12213 if (!x86_64_immediate_operand (operands[3], DImode))
12215 emit_move_insn (operands[2], operands[3]);
12216 operands[3] = operands[2];
12221 [(match_scratch:DI 2 "r")
12222 (parallel [(set (zero_extract:DI
12223 (match_operand:DI 0 "nonimmediate_operand")
12225 (match_operand 1 "const_0_to_63_operand"))
12227 (clobber (reg:CC FLAGS_REG))])]
12228 "TARGET_64BIT && !TARGET_USE_BT"
12229 [(parallel [(set (match_dup 0)
12230 (and:DI (match_dup 0) (match_dup 3)))
12231 (clobber (reg:CC FLAGS_REG))])]
12233 int i = INTVAL (operands[1]);
12235 operands[3] = gen_int_mode (~(HOST_WIDE_INT_1U << i), DImode);
12237 if (!x86_64_immediate_operand (operands[3], DImode))
12239 emit_move_insn (operands[2], operands[3]);
12240 operands[3] = operands[2];
12245 [(match_scratch:DI 2 "r")
12246 (parallel [(set (zero_extract:DI
12247 (match_operand:DI 0 "nonimmediate_operand")
12249 (match_operand 1 "const_0_to_63_operand"))
12250 (not:DI (zero_extract:DI
12251 (match_dup 0) (const_int 1) (match_dup 1))))
12252 (clobber (reg:CC FLAGS_REG))])]
12253 "TARGET_64BIT && !TARGET_USE_BT"
12254 [(parallel [(set (match_dup 0)
12255 (xor:DI (match_dup 0) (match_dup 3)))
12256 (clobber (reg:CC FLAGS_REG))])]
12258 int i = INTVAL (operands[1]);
12260 operands[3] = gen_int_mode (HOST_WIDE_INT_1U << i, DImode);
12262 if (!x86_64_immediate_operand (operands[3], DImode))
12264 emit_move_insn (operands[2], operands[3]);
12265 operands[3] = operands[2];
12271 (define_insn "*bt<mode>"
12272 [(set (reg:CCC FLAGS_REG)
12274 (zero_extract:SWI48
12275 (match_operand:SWI48 0 "nonimmediate_operand" "r,m")
12277 (match_operand:SI 1 "nonmemory_operand" "r<S>,<S>"))
12281 switch (get_attr_mode (insn))
12284 return "bt{l}\t{%1, %k0|%k0, %1}";
12287 return "bt{q}\t{%q1, %0|%0, %q1}";
12290 gcc_unreachable ();
12293 [(set_attr "type" "alu1")
12294 (set_attr "prefix_0f" "1")
12297 (and (match_test "CONST_INT_P (operands[1])")
12298 (match_test "INTVAL (operands[1]) < 32"))
12299 (const_string "SI")
12300 (const_string "<MODE>")))])
12302 (define_insn_and_split "*jcc_bt<mode>"
12304 (if_then_else (match_operator 0 "bt_comparison_operator"
12305 [(zero_extract:SWI48
12306 (match_operand:SWI48 1 "nonimmediate_operand")
12308 (match_operand:SI 2 "nonmemory_operand"))
12310 (label_ref (match_operand 3))
12312 (clobber (reg:CC FLAGS_REG))]
12313 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
12314 && (CONST_INT_P (operands[2])
12315 ? (INTVAL (operands[2]) < GET_MODE_BITSIZE (<MODE>mode)
12316 && INTVAL (operands[2])
12317 >= (optimize_function_for_size_p (cfun) ? 8 : 32))
12318 : !memory_operand (operands[1], <MODE>mode))
12319 && can_create_pseudo_p ()"
12322 [(set (reg:CCC FLAGS_REG)
12324 (zero_extract:SWI48
12330 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
12331 (label_ref (match_dup 3))
12334 operands[0] = shallow_copy_rtx (operands[0]);
12335 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
12338 (define_insn_and_split "*jcc_bt<mode>_1"
12340 (if_then_else (match_operator 0 "bt_comparison_operator"
12341 [(zero_extract:SWI48
12342 (match_operand:SWI48 1 "register_operand")
12345 (match_operand:QI 2 "register_operand")))
12347 (label_ref (match_operand 3))
12349 (clobber (reg:CC FLAGS_REG))]
12350 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
12351 && can_create_pseudo_p ()"
12354 [(set (reg:CCC FLAGS_REG)
12356 (zero_extract:SWI48
12362 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
12363 (label_ref (match_dup 3))
12366 operands[2] = lowpart_subreg (SImode, operands[2], QImode);
12367 operands[0] = shallow_copy_rtx (operands[0]);
12368 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
12371 ;; Avoid useless masking of bit offset operand.
12372 (define_insn_and_split "*jcc_bt<mode>_mask"
12374 (if_then_else (match_operator 0 "bt_comparison_operator"
12375 [(zero_extract:SWI48
12376 (match_operand:SWI48 1 "register_operand")
12379 (match_operand:SI 2 "register_operand")
12380 (match_operand 3 "const_int_operand")))])
12381 (label_ref (match_operand 4))
12383 (clobber (reg:CC FLAGS_REG))]
12384 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
12385 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
12386 == GET_MODE_BITSIZE (<MODE>mode)-1
12387 && can_create_pseudo_p ()"
12390 [(set (reg:CCC FLAGS_REG)
12392 (zero_extract:SWI48
12398 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
12399 (label_ref (match_dup 4))
12402 operands[0] = shallow_copy_rtx (operands[0]);
12403 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
12406 ;; Store-flag instructions.
12408 ;; For all sCOND expanders, also expand the compare or test insn that
12409 ;; generates cc0. Generate an equality comparison if `seq' or `sne'.
12411 (define_insn_and_split "*setcc_di_1"
12412 [(set (match_operand:DI 0 "register_operand" "=q")
12413 (match_operator:DI 1 "ix86_comparison_operator"
12414 [(reg FLAGS_REG) (const_int 0)]))]
12415 "TARGET_64BIT && !TARGET_PARTIAL_REG_STALL"
12417 "&& reload_completed"
12418 [(set (match_dup 2) (match_dup 1))
12419 (set (match_dup 0) (zero_extend:DI (match_dup 2)))]
12421 operands[1] = shallow_copy_rtx (operands[1]);
12422 PUT_MODE (operands[1], QImode);
12423 operands[2] = gen_lowpart (QImode, operands[0]);
12426 (define_insn_and_split "*setcc_si_1_and"
12427 [(set (match_operand:SI 0 "register_operand" "=q")
12428 (match_operator:SI 1 "ix86_comparison_operator"
12429 [(reg FLAGS_REG) (const_int 0)]))
12430 (clobber (reg:CC FLAGS_REG))]
12431 "!TARGET_PARTIAL_REG_STALL
12432 && TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
12434 "&& reload_completed"
12435 [(set (match_dup 2) (match_dup 1))
12436 (parallel [(set (match_dup 0) (zero_extend:SI (match_dup 2)))
12437 (clobber (reg:CC FLAGS_REG))])]
12439 operands[1] = shallow_copy_rtx (operands[1]);
12440 PUT_MODE (operands[1], QImode);
12441 operands[2] = gen_lowpart (QImode, operands[0]);
12444 (define_insn_and_split "*setcc_si_1_movzbl"
12445 [(set (match_operand:SI 0 "register_operand" "=q")
12446 (match_operator:SI 1 "ix86_comparison_operator"
12447 [(reg FLAGS_REG) (const_int 0)]))]
12448 "!TARGET_PARTIAL_REG_STALL
12449 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
12451 "&& reload_completed"
12452 [(set (match_dup 2) (match_dup 1))
12453 (set (match_dup 0) (zero_extend:SI (match_dup 2)))]
12455 operands[1] = shallow_copy_rtx (operands[1]);
12456 PUT_MODE (operands[1], QImode);
12457 operands[2] = gen_lowpart (QImode, operands[0]);
12460 (define_insn "*setcc_qi"
12461 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12462 (match_operator:QI 1 "ix86_comparison_operator"
12463 [(reg FLAGS_REG) (const_int 0)]))]
12466 [(set_attr "type" "setcc")
12467 (set_attr "mode" "QI")])
12469 (define_insn "*setcc_qi_slp"
12470 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12471 (match_operator:QI 1 "ix86_comparison_operator"
12472 [(reg FLAGS_REG) (const_int 0)]))]
12475 [(set_attr "type" "setcc")
12476 (set_attr "mode" "QI")])
12478 ;; In general it is not safe to assume too much about CCmode registers,
12479 ;; so simplify-rtx stops when it sees a second one. Under certain
12480 ;; conditions this is safe on x86, so help combine not create
12487 [(set (match_operand:QI 0 "nonimmediate_operand")
12488 (ne:QI (match_operator 1 "ix86_comparison_operator"
12489 [(reg FLAGS_REG) (const_int 0)])
12492 [(set (match_dup 0) (match_dup 1))]
12494 operands[1] = shallow_copy_rtx (operands[1]);
12495 PUT_MODE (operands[1], QImode);
12499 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand"))
12500 (ne:QI (match_operator 1 "ix86_comparison_operator"
12501 [(reg FLAGS_REG) (const_int 0)])
12504 [(set (match_dup 0) (match_dup 1))]
12506 operands[1] = shallow_copy_rtx (operands[1]);
12507 PUT_MODE (operands[1], QImode);
12511 [(set (match_operand:QI 0 "nonimmediate_operand")
12512 (eq:QI (match_operator 1 "ix86_comparison_operator"
12513 [(reg FLAGS_REG) (const_int 0)])
12516 [(set (match_dup 0) (match_dup 1))]
12518 operands[1] = shallow_copy_rtx (operands[1]);
12519 PUT_MODE (operands[1], QImode);
12520 PUT_CODE (operands[1],
12521 ix86_reverse_condition (GET_CODE (operands[1]),
12522 GET_MODE (XEXP (operands[1], 0))));
12524 /* Make sure that (a) the CCmode we have for the flags is strong
12525 enough for the reversed compare or (b) we have a valid FP compare. */
12526 if (! ix86_comparison_operator (operands[1], VOIDmode))
12531 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand"))
12532 (eq:QI (match_operator 1 "ix86_comparison_operator"
12533 [(reg FLAGS_REG) (const_int 0)])
12536 [(set (match_dup 0) (match_dup 1))]
12538 operands[1] = shallow_copy_rtx (operands[1]);
12539 PUT_MODE (operands[1], QImode);
12540 PUT_CODE (operands[1],
12541 ix86_reverse_condition (GET_CODE (operands[1]),
12542 GET_MODE (XEXP (operands[1], 0))));
12544 /* Make sure that (a) the CCmode we have for the flags is strong
12545 enough for the reversed compare or (b) we have a valid FP compare. */
12546 if (! ix86_comparison_operator (operands[1], VOIDmode))
12550 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
12551 ;; subsequent logical operations are used to imitate conditional moves.
12552 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
12555 (define_insn "setcc_<mode>_sse"
12556 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
12557 (match_operator:MODEF 3 "sse_comparison_operator"
12558 [(match_operand:MODEF 1 "register_operand" "0,x")
12559 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
12560 "SSE_FLOAT_MODE_P (<MODE>mode)"
12562 cmp%D3<ssemodesuffix>\t{%2, %0|%0, %2}
12563 vcmp%D3<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
12564 [(set_attr "isa" "noavx,avx")
12565 (set_attr "type" "ssecmp")
12566 (set_attr "length_immediate" "1")
12567 (set_attr "prefix" "orig,vex")
12568 (set_attr "mode" "<MODE>")])
12570 ;; Basic conditional jump instructions.
12571 ;; We ignore the overflow flag for signed branch instructions.
12573 (define_insn "*jcc"
12575 (if_then_else (match_operator 1 "ix86_comparison_operator"
12576 [(reg FLAGS_REG) (const_int 0)])
12577 (label_ref (match_operand 0))
12581 [(set_attr "type" "ibr")
12582 (set_attr "modrm" "0")
12583 (set (attr "length")
12585 (and (ge (minus (match_dup 0) (pc))
12587 (lt (minus (match_dup 0) (pc))
12592 ;; In general it is not safe to assume too much about CCmode registers,
12593 ;; so simplify-rtx stops when it sees a second one. Under certain
12594 ;; conditions this is safe on x86, so help combine not create
12602 (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
12603 [(reg FLAGS_REG) (const_int 0)])
12605 (label_ref (match_operand 1))
12609 (if_then_else (match_dup 0)
12610 (label_ref (match_dup 1))
12613 operands[0] = shallow_copy_rtx (operands[0]);
12614 PUT_MODE (operands[0], VOIDmode);
12619 (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
12620 [(reg FLAGS_REG) (const_int 0)])
12622 (label_ref (match_operand 1))
12626 (if_then_else (match_dup 0)
12627 (label_ref (match_dup 1))
12630 operands[0] = shallow_copy_rtx (operands[0]);
12631 PUT_MODE (operands[0], VOIDmode);
12632 PUT_CODE (operands[0],
12633 ix86_reverse_condition (GET_CODE (operands[0]),
12634 GET_MODE (XEXP (operands[0], 0))));
12636 /* Make sure that (a) the CCmode we have for the flags is strong
12637 enough for the reversed compare or (b) we have a valid FP compare. */
12638 if (! ix86_comparison_operator (operands[0], VOIDmode))
12642 ;; Unconditional and other jump instructions
12644 (define_insn "jump"
12646 (label_ref (match_operand 0)))]
12649 [(set_attr "type" "ibr")
12650 (set_attr "modrm" "0")
12651 (set (attr "length")
12653 (and (ge (minus (match_dup 0) (pc))
12655 (lt (minus (match_dup 0) (pc))
12660 (define_expand "indirect_jump"
12661 [(set (pc) (match_operand 0 "indirect_branch_operand"))]
12664 if (TARGET_X32 || TARGET_INDIRECT_BRANCH_REGISTER)
12665 operands[0] = convert_memory_address (word_mode, operands[0]);
12666 cfun->machine->has_local_indirect_jump = true;
12669 (define_insn "*indirect_jump"
12670 [(set (pc) (match_operand:W 0 "indirect_branch_operand" "rBw"))]
12672 "* return ix86_output_indirect_jmp (operands[0]);"
12673 [(set (attr "type")
12674 (if_then_else (match_test "(cfun->machine->indirect_branch_type
12675 != indirect_branch_keep)")
12676 (const_string "multi")
12677 (const_string "ibr")))
12678 (set_attr "length_immediate" "0")])
12680 (define_expand "tablejump"
12681 [(parallel [(set (pc) (match_operand 0 "indirect_branch_operand"))
12682 (use (label_ref (match_operand 1)))])]
12685 /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
12686 relative. Convert the relative address to an absolute address. */
12690 enum rtx_code code;
12692 /* We can't use @GOTOFF for text labels on VxWorks;
12693 see gotoff_operand. */
12694 if (TARGET_64BIT || TARGET_VXWORKS_RTP)
12698 op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
12700 else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
12704 op1 = pic_offset_table_rtx;
12709 op0 = pic_offset_table_rtx;
12713 operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
12717 if (TARGET_X32 || TARGET_INDIRECT_BRANCH_REGISTER)
12718 operands[0] = convert_memory_address (word_mode, operands[0]);
12719 cfun->machine->has_local_indirect_jump = true;
12722 (define_insn "*tablejump_1"
12723 [(set (pc) (match_operand:W 0 "indirect_branch_operand" "rBw"))
12724 (use (label_ref (match_operand 1)))]
12726 "* return ix86_output_indirect_jmp (operands[0]);"
12727 [(set (attr "type")
12728 (if_then_else (match_test "(cfun->machine->indirect_branch_type
12729 != indirect_branch_keep)")
12730 (const_string "multi")
12731 (const_string "ibr")))
12732 (set_attr "length_immediate" "0")])
12734 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
12737 [(set (reg FLAGS_REG) (match_operand 0))
12738 (set (match_operand:QI 1 "register_operand")
12739 (match_operator:QI 2 "ix86_comparison_operator"
12740 [(reg FLAGS_REG) (const_int 0)]))
12741 (set (match_operand 3 "any_QIreg_operand")
12742 (zero_extend (match_dup 1)))]
12743 "(peep2_reg_dead_p (3, operands[1])
12744 || operands_match_p (operands[1], operands[3]))
12745 && ! reg_overlap_mentioned_p (operands[3], operands[0])
12746 && peep2_regno_dead_p (0, FLAGS_REG)"
12747 [(set (match_dup 4) (match_dup 0))
12748 (set (strict_low_part (match_dup 5))
12751 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
12752 operands[5] = gen_lowpart (QImode, operands[3]);
12753 ix86_expand_clear (operands[3]);
12757 [(parallel [(set (reg FLAGS_REG) (match_operand 0))
12758 (match_operand 4)])
12759 (set (match_operand:QI 1 "register_operand")
12760 (match_operator:QI 2 "ix86_comparison_operator"
12761 [(reg FLAGS_REG) (const_int 0)]))
12762 (set (match_operand 3 "any_QIreg_operand")
12763 (zero_extend (match_dup 1)))]
12764 "(peep2_reg_dead_p (3, operands[1])
12765 || operands_match_p (operands[1], operands[3]))
12766 && ! reg_overlap_mentioned_p (operands[3], operands[0])
12767 && ! reg_overlap_mentioned_p (operands[3], operands[4])
12768 && ! reg_set_p (operands[3], operands[4])
12769 && peep2_regno_dead_p (0, FLAGS_REG)"
12770 [(parallel [(set (match_dup 5) (match_dup 0))
12772 (set (strict_low_part (match_dup 6))
12775 operands[5] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
12776 operands[6] = gen_lowpart (QImode, operands[3]);
12777 ix86_expand_clear (operands[3]);
12781 [(set (reg FLAGS_REG) (match_operand 0))
12782 (parallel [(set (reg FLAGS_REG) (match_operand 1))
12783 (match_operand 5)])
12784 (set (match_operand:QI 2 "register_operand")
12785 (match_operator:QI 3 "ix86_comparison_operator"
12786 [(reg FLAGS_REG) (const_int 0)]))
12787 (set (match_operand 4 "any_QIreg_operand")
12788 (zero_extend (match_dup 2)))]
12789 "(peep2_reg_dead_p (4, operands[2])
12790 || operands_match_p (operands[2], operands[4]))
12791 && ! reg_overlap_mentioned_p (operands[4], operands[0])
12792 && ! reg_overlap_mentioned_p (operands[4], operands[1])
12793 && ! reg_overlap_mentioned_p (operands[4], operands[5])
12794 && ! reg_set_p (operands[4], operands[5])
12795 && refers_to_regno_p (FLAGS_REG, operands[1], (rtx *)NULL)
12796 && peep2_regno_dead_p (0, FLAGS_REG)"
12797 [(set (match_dup 6) (match_dup 0))
12798 (parallel [(set (match_dup 7) (match_dup 1))
12800 (set (strict_low_part (match_dup 8))
12803 operands[6] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
12804 operands[7] = gen_rtx_REG (GET_MODE (operands[1]), FLAGS_REG);
12805 operands[8] = gen_lowpart (QImode, operands[4]);
12806 ix86_expand_clear (operands[4]);
12809 ;; Similar, but match zero extend with andsi3.
12812 [(set (reg FLAGS_REG) (match_operand 0))
12813 (set (match_operand:QI 1 "register_operand")
12814 (match_operator:QI 2 "ix86_comparison_operator"
12815 [(reg FLAGS_REG) (const_int 0)]))
12816 (parallel [(set (match_operand:SI 3 "any_QIreg_operand")
12817 (and:SI (match_dup 3) (const_int 255)))
12818 (clobber (reg:CC FLAGS_REG))])]
12819 "REGNO (operands[1]) == REGNO (operands[3])
12820 && ! reg_overlap_mentioned_p (operands[3], operands[0])
12821 && peep2_regno_dead_p (0, FLAGS_REG)"
12822 [(set (match_dup 4) (match_dup 0))
12823 (set (strict_low_part (match_dup 5))
12826 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
12827 operands[5] = gen_lowpart (QImode, operands[3]);
12828 ix86_expand_clear (operands[3]);
12832 [(parallel [(set (reg FLAGS_REG) (match_operand 0))
12833 (match_operand 4)])
12834 (set (match_operand:QI 1 "register_operand")
12835 (match_operator:QI 2 "ix86_comparison_operator"
12836 [(reg FLAGS_REG) (const_int 0)]))
12837 (parallel [(set (match_operand 3 "any_QIreg_operand")
12838 (zero_extend (match_dup 1)))
12839 (clobber (reg:CC FLAGS_REG))])]
12840 "(peep2_reg_dead_p (3, operands[1])
12841 || operands_match_p (operands[1], operands[3]))
12842 && ! reg_overlap_mentioned_p (operands[3], operands[0])
12843 && ! reg_overlap_mentioned_p (operands[3], operands[4])
12844 && ! reg_set_p (operands[3], operands[4])
12845 && peep2_regno_dead_p (0, FLAGS_REG)"
12846 [(parallel [(set (match_dup 5) (match_dup 0))
12848 (set (strict_low_part (match_dup 6))
12851 operands[5] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
12852 operands[6] = gen_lowpart (QImode, operands[3]);
12853 ix86_expand_clear (operands[3]);
12857 [(set (reg FLAGS_REG) (match_operand 0))
12858 (parallel [(set (reg FLAGS_REG) (match_operand 1))
12859 (match_operand 5)])
12860 (set (match_operand:QI 2 "register_operand")
12861 (match_operator:QI 3 "ix86_comparison_operator"
12862 [(reg FLAGS_REG) (const_int 0)]))
12863 (parallel [(set (match_operand 4 "any_QIreg_operand")
12864 (zero_extend (match_dup 2)))
12865 (clobber (reg:CC FLAGS_REG))])]
12866 "(peep2_reg_dead_p (4, operands[2])
12867 || operands_match_p (operands[2], operands[4]))
12868 && ! reg_overlap_mentioned_p (operands[4], operands[0])
12869 && ! reg_overlap_mentioned_p (operands[4], operands[1])
12870 && ! reg_overlap_mentioned_p (operands[4], operands[5])
12871 && ! reg_set_p (operands[4], operands[5])
12872 && refers_to_regno_p (FLAGS_REG, operands[1], (rtx *)NULL)
12873 && peep2_regno_dead_p (0, FLAGS_REG)"
12874 [(set (match_dup 6) (match_dup 0))
12875 (parallel [(set (match_dup 7) (match_dup 1))
12877 (set (strict_low_part (match_dup 8))
12880 operands[6] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
12881 operands[7] = gen_rtx_REG (GET_MODE (operands[1]), FLAGS_REG);
12882 operands[8] = gen_lowpart (QImode, operands[4]);
12883 ix86_expand_clear (operands[4]);
12886 ;; Call instructions.
12888 ;; The predicates normally associated with named expanders are not properly
12889 ;; checked for calls. This is a bug in the generic code, but it isn't that
12890 ;; easy to fix. Ignore it for now and be prepared to fix things up.
12892 ;; P6 processors will jump to the address after the decrement when %esp
12893 ;; is used as a call operand, so they will execute return address as a code.
12894 ;; See Pentium Pro errata 70, Pentium 2 errata A33 and Pentium 3 errata E17.
12896 ;; Register constraint for call instruction.
12897 (define_mode_attr c [(SI "l") (DI "r")])
12899 ;; Call subroutine returning no value.
12901 (define_expand "call"
12902 [(call (match_operand:QI 0)
12904 (use (match_operand 2))]
12907 ix86_expand_call (NULL, operands[0], operands[1],
12908 operands[2], NULL, false);
12912 (define_expand "sibcall"
12913 [(call (match_operand:QI 0)
12915 (use (match_operand 2))]
12918 ix86_expand_call (NULL, operands[0], operands[1],
12919 operands[2], NULL, true);
12923 (define_insn "*call"
12924 [(call (mem:QI (match_operand:W 0 "call_insn_operand" "<c>BwBz"))
12925 (match_operand 1))]
12926 "!SIBLING_CALL_P (insn)"
12927 "* return ix86_output_call_insn (insn, operands[0]);"
12928 [(set_attr "type" "call")])
12930 ;; This covers both call and sibcall since only GOT slot is allowed.
12931 (define_insn "*call_got_x32"
12932 [(call (mem:QI (zero_extend:DI
12933 (match_operand:SI 0 "GOT_memory_operand" "Bg")))
12934 (match_operand 1))]
12937 rtx fnaddr = gen_const_mem (DImode, XEXP (operands[0], 0));
12938 return ix86_output_call_insn (insn, fnaddr);
12940 [(set_attr "type" "call")])
12942 ;; Since sibcall never returns, we can only use call-clobbered register
12944 (define_insn "*sibcall_GOT_32"
12947 (match_operand:SI 0 "register_no_elim_operand" "U")
12948 (match_operand:SI 1 "GOT32_symbol_operand"))))
12949 (match_operand 2))]
12952 && !TARGET_INDIRECT_BRANCH_REGISTER
12953 && SIBLING_CALL_P (insn)"
12955 rtx fnaddr = gen_rtx_PLUS (SImode, operands[0], operands[1]);
12956 fnaddr = gen_const_mem (SImode, fnaddr);
12957 return ix86_output_call_insn (insn, fnaddr);
12959 [(set_attr "type" "call")])
12961 (define_insn "*sibcall"
12962 [(call (mem:QI (match_operand:W 0 "sibcall_insn_operand" "UBsBz"))
12963 (match_operand 1))]
12964 "SIBLING_CALL_P (insn)"
12965 "* return ix86_output_call_insn (insn, operands[0]);"
12966 [(set_attr "type" "call")])
12968 (define_insn "*sibcall_memory"
12969 [(call (mem:QI (match_operand:W 0 "memory_operand" "m"))
12971 (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
12972 "!TARGET_X32 && !TARGET_INDIRECT_BRANCH_REGISTER"
12973 "* return ix86_output_call_insn (insn, operands[0]);"
12974 [(set_attr "type" "call")])
12977 [(set (match_operand:W 0 "register_operand")
12978 (match_operand:W 1 "memory_operand"))
12979 (call (mem:QI (match_dup 0))
12980 (match_operand 3))]
12982 && !TARGET_INDIRECT_BRANCH_REGISTER
12983 && SIBLING_CALL_P (peep2_next_insn (1))
12984 && !reg_mentioned_p (operands[0],
12985 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (1)))"
12986 [(parallel [(call (mem:QI (match_dup 1))
12988 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
12991 [(set (match_operand:W 0 "register_operand")
12992 (match_operand:W 1 "memory_operand"))
12993 (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
12994 (call (mem:QI (match_dup 0))
12995 (match_operand 3))]
12997 && !TARGET_INDIRECT_BRANCH_REGISTER
12998 && SIBLING_CALL_P (peep2_next_insn (2))
12999 && !reg_mentioned_p (operands[0],
13000 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (2)))"
13001 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
13002 (parallel [(call (mem:QI (match_dup 1))
13004 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
13006 (define_expand "call_pop"
13007 [(parallel [(call (match_operand:QI 0)
13008 (match_operand:SI 1))
13009 (set (reg:SI SP_REG)
13010 (plus:SI (reg:SI SP_REG)
13011 (match_operand:SI 3)))])]
13014 ix86_expand_call (NULL, operands[0], operands[1],
13015 operands[2], operands[3], false);
13019 (define_insn "*call_pop"
13020 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lBwBz"))
13022 (set (reg:SI SP_REG)
13023 (plus:SI (reg:SI SP_REG)
13024 (match_operand:SI 2 "immediate_operand" "i")))]
13025 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
13026 "* return ix86_output_call_insn (insn, operands[0]);"
13027 [(set_attr "type" "call")])
13029 (define_insn "*sibcall_pop"
13030 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "UBsBz"))
13032 (set (reg:SI SP_REG)
13033 (plus:SI (reg:SI SP_REG)
13034 (match_operand:SI 2 "immediate_operand" "i")))]
13035 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
13036 "* return ix86_output_call_insn (insn, operands[0]);"
13037 [(set_attr "type" "call")])
13039 (define_insn "*sibcall_pop_memory"
13040 [(call (mem:QI (match_operand:SI 0 "memory_operand" "Bs"))
13042 (set (reg:SI SP_REG)
13043 (plus:SI (reg:SI SP_REG)
13044 (match_operand:SI 2 "immediate_operand" "i")))
13045 (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
13047 "* return ix86_output_call_insn (insn, operands[0]);"
13048 [(set_attr "type" "call")])
13051 [(set (match_operand:SI 0 "register_operand")
13052 (match_operand:SI 1 "memory_operand"))
13053 (parallel [(call (mem:QI (match_dup 0))
13055 (set (reg:SI SP_REG)
13056 (plus:SI (reg:SI SP_REG)
13057 (match_operand:SI 4 "immediate_operand")))])]
13058 "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (1))
13059 && !reg_mentioned_p (operands[0],
13060 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (1)))"
13061 [(parallel [(call (mem:QI (match_dup 1))
13063 (set (reg:SI SP_REG)
13064 (plus:SI (reg:SI SP_REG)
13066 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
13069 [(set (match_operand:SI 0 "register_operand")
13070 (match_operand:SI 1 "memory_operand"))
13071 (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
13072 (parallel [(call (mem:QI (match_dup 0))
13074 (set (reg:SI SP_REG)
13075 (plus:SI (reg:SI SP_REG)
13076 (match_operand:SI 4 "immediate_operand")))])]
13077 "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (2))
13078 && !reg_mentioned_p (operands[0],
13079 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (2)))"
13080 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
13081 (parallel [(call (mem:QI (match_dup 1))
13083 (set (reg:SI SP_REG)
13084 (plus:SI (reg:SI SP_REG)
13086 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
13088 ;; Combining simple memory jump instruction
13091 [(set (match_operand:W 0 "register_operand")
13092 (match_operand:W 1 "memory_operand"))
13093 (set (pc) (match_dup 0))]
13095 && !TARGET_INDIRECT_BRANCH_REGISTER
13096 && peep2_reg_dead_p (2, operands[0])"
13097 [(set (pc) (match_dup 1))])
13099 ;; Call subroutine, returning value in operand 0
13101 (define_expand "call_value"
13102 [(set (match_operand 0)
13103 (call (match_operand:QI 1)
13104 (match_operand 2)))
13105 (use (match_operand 3))]
13108 ix86_expand_call (operands[0], operands[1], operands[2],
13109 operands[3], NULL, false);
13113 (define_expand "sibcall_value"
13114 [(set (match_operand 0)
13115 (call (match_operand:QI 1)
13116 (match_operand 2)))
13117 (use (match_operand 3))]
13120 ix86_expand_call (operands[0], operands[1], operands[2],
13121 operands[3], NULL, true);
13125 (define_insn "*call_value"
13126 [(set (match_operand 0)
13127 (call (mem:QI (match_operand:W 1 "call_insn_operand" "<c>BwBz"))
13128 (match_operand 2)))]
13129 "!SIBLING_CALL_P (insn)"
13130 "* return ix86_output_call_insn (insn, operands[1]);"
13131 [(set_attr "type" "callv")])
13133 ;; This covers both call and sibcall since only GOT slot is allowed.
13134 (define_insn "*call_value_got_x32"
13135 [(set (match_operand 0)
13138 (match_operand:SI 1 "GOT_memory_operand" "Bg")))
13139 (match_operand 2)))]
13142 rtx fnaddr = gen_const_mem (DImode, XEXP (operands[1], 0));
13143 return ix86_output_call_insn (insn, fnaddr);
13145 [(set_attr "type" "callv")])
13147 ;; Since sibcall never returns, we can only use call-clobbered register
13149 (define_insn "*sibcall_value_GOT_32"
13150 [(set (match_operand 0)
13153 (match_operand:SI 1 "register_no_elim_operand" "U")
13154 (match_operand:SI 2 "GOT32_symbol_operand"))))
13155 (match_operand 3)))]
13158 && !TARGET_INDIRECT_BRANCH_REGISTER
13159 && SIBLING_CALL_P (insn)"
13161 rtx fnaddr = gen_rtx_PLUS (SImode, operands[1], operands[2]);
13162 fnaddr = gen_const_mem (SImode, fnaddr);
13163 return ix86_output_call_insn (insn, fnaddr);
13165 [(set_attr "type" "callv")])
13167 (define_insn "*sibcall_value"
13168 [(set (match_operand 0)
13169 (call (mem:QI (match_operand:W 1 "sibcall_insn_operand" "UBsBz"))
13170 (match_operand 2)))]
13171 "SIBLING_CALL_P (insn)"
13172 "* return ix86_output_call_insn (insn, operands[1]);"
13173 [(set_attr "type" "callv")])
13175 (define_insn "*sibcall_value_memory"
13176 [(set (match_operand 0)
13177 (call (mem:QI (match_operand:W 1 "memory_operand" "m"))
13178 (match_operand 2)))
13179 (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
13180 "!TARGET_X32 && !TARGET_INDIRECT_BRANCH_REGISTER"
13181 "* return ix86_output_call_insn (insn, operands[1]);"
13182 [(set_attr "type" "callv")])
13185 [(set (match_operand:W 0 "register_operand")
13186 (match_operand:W 1 "memory_operand"))
13187 (set (match_operand 2)
13188 (call (mem:QI (match_dup 0))
13189 (match_operand 3)))]
13191 && !TARGET_INDIRECT_BRANCH_REGISTER
13192 && SIBLING_CALL_P (peep2_next_insn (1))
13193 && !reg_mentioned_p (operands[0],
13194 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (1)))"
13195 [(parallel [(set (match_dup 2)
13196 (call (mem:QI (match_dup 1))
13198 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
13201 [(set (match_operand:W 0 "register_operand")
13202 (match_operand:W 1 "memory_operand"))
13203 (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
13204 (set (match_operand 2)
13205 (call (mem:QI (match_dup 0))
13206 (match_operand 3)))]
13208 && !TARGET_INDIRECT_BRANCH_REGISTER
13209 && SIBLING_CALL_P (peep2_next_insn (2))
13210 && !reg_mentioned_p (operands[0],
13211 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (2)))"
13212 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
13213 (parallel [(set (match_dup 2)
13214 (call (mem:QI (match_dup 1))
13216 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
13218 (define_expand "call_value_pop"
13219 [(parallel [(set (match_operand 0)
13220 (call (match_operand:QI 1)
13221 (match_operand:SI 2)))
13222 (set (reg:SI SP_REG)
13223 (plus:SI (reg:SI SP_REG)
13224 (match_operand:SI 4)))])]
13227 ix86_expand_call (operands[0], operands[1], operands[2],
13228 operands[3], operands[4], false);
13232 (define_insn "*call_value_pop"
13233 [(set (match_operand 0)
13234 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lBwBz"))
13235 (match_operand 2)))
13236 (set (reg:SI SP_REG)
13237 (plus:SI (reg:SI SP_REG)
13238 (match_operand:SI 3 "immediate_operand" "i")))]
13239 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
13240 "* return ix86_output_call_insn (insn, operands[1]);"
13241 [(set_attr "type" "callv")])
13243 (define_insn "*sibcall_value_pop"
13244 [(set (match_operand 0)
13245 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "UBsBz"))
13246 (match_operand 2)))
13247 (set (reg:SI SP_REG)
13248 (plus:SI (reg:SI SP_REG)
13249 (match_operand:SI 3 "immediate_operand" "i")))]
13250 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
13251 "* return ix86_output_call_insn (insn, operands[1]);"
13252 [(set_attr "type" "callv")])
13254 (define_insn "*sibcall_value_pop_memory"
13255 [(set (match_operand 0)
13256 (call (mem:QI (match_operand:SI 1 "memory_operand" "m"))
13257 (match_operand 2)))
13258 (set (reg:SI SP_REG)
13259 (plus:SI (reg:SI SP_REG)
13260 (match_operand:SI 3 "immediate_operand" "i")))
13261 (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
13263 "* return ix86_output_call_insn (insn, operands[1]);"
13264 [(set_attr "type" "callv")])
13267 [(set (match_operand:SI 0 "register_operand")
13268 (match_operand:SI 1 "memory_operand"))
13269 (parallel [(set (match_operand 2)
13270 (call (mem:QI (match_dup 0))
13271 (match_operand 3)))
13272 (set (reg:SI SP_REG)
13273 (plus:SI (reg:SI SP_REG)
13274 (match_operand:SI 4 "immediate_operand")))])]
13275 "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (1))
13276 && !reg_mentioned_p (operands[0],
13277 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (1)))"
13278 [(parallel [(set (match_dup 2)
13279 (call (mem:QI (match_dup 1))
13281 (set (reg:SI SP_REG)
13282 (plus:SI (reg:SI SP_REG)
13284 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
13287 [(set (match_operand:SI 0 "register_operand")
13288 (match_operand:SI 1 "memory_operand"))
13289 (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
13290 (parallel [(set (match_operand 2)
13291 (call (mem:QI (match_dup 0))
13292 (match_operand 3)))
13293 (set (reg:SI SP_REG)
13294 (plus:SI (reg:SI SP_REG)
13295 (match_operand:SI 4 "immediate_operand")))])]
13296 "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (2))
13297 && !reg_mentioned_p (operands[0],
13298 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (2)))"
13299 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
13300 (parallel [(set (match_dup 2)
13301 (call (mem:QI (match_dup 1))
13303 (set (reg:SI SP_REG)
13304 (plus:SI (reg:SI SP_REG)
13306 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
13308 ;; Call subroutine returning any type.
13310 (define_expand "untyped_call"
13311 [(parallel [(call (match_operand 0)
13314 (match_operand 2)])]
13319 /* In order to give reg-stack an easier job in validating two
13320 coprocessor registers as containing a possible return value,
13321 simply pretend the untyped call returns a complex long double
13324 We can't use SSE_REGPARM_MAX here since callee is unprototyped
13325 and should have the default ABI. */
13327 ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
13328 ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
13329 operands[0], const0_rtx,
13330 GEN_INT ((TARGET_64BIT
13331 ? (ix86_abi == SYSV_ABI
13332 ? X86_64_SSE_REGPARM_MAX
13333 : X86_64_MS_SSE_REGPARM_MAX)
13334 : X86_32_SSE_REGPARM_MAX)
13338 for (i = 0; i < XVECLEN (operands[2], 0); i++)
13340 rtx set = XVECEXP (operands[2], 0, i);
13341 emit_move_insn (SET_DEST (set), SET_SRC (set));
13344 /* The optimizer does not know that the call sets the function value
13345 registers we stored in the result block. We avoid problems by
13346 claiming that all hard registers are used and clobbered at this
13348 emit_insn (gen_blockage ());
13353 ;; Prologue and epilogue instructions
13355 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
13356 ;; all of memory. This blocks insns from being moved across this point.
13358 (define_insn "blockage"
13359 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
13362 [(set_attr "length" "0")])
13364 ;; Do not schedule instructions accessing memory across this point.
13366 (define_expand "memory_blockage"
13367 [(set (match_dup 0)
13368 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
13371 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
13372 MEM_VOLATILE_P (operands[0]) = 1;
13375 (define_insn "*memory_blockage"
13376 [(set (match_operand:BLK 0)
13377 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
13380 [(set_attr "length" "0")])
13382 ;; As USE insns aren't meaningful after reload, this is used instead
13383 ;; to prevent deleting instructions setting registers for PIC code
13384 (define_insn "prologue_use"
13385 [(unspec_volatile [(match_operand 0)] UNSPECV_PROLOGUE_USE)]
13388 [(set_attr "length" "0")])
13390 ;; Insn emitted into the body of a function to return from a function.
13391 ;; This is only done if the function's epilogue is known to be simple.
13392 ;; See comments for ix86_can_use_return_insn_p in i386.c.
13394 (define_expand "return"
13396 "ix86_can_use_return_insn_p ()"
13398 if (crtl->args.pops_args)
13400 rtx popc = GEN_INT (crtl->args.pops_args);
13401 emit_jump_insn (gen_simple_return_pop_internal (popc));
13406 ;; We need to disable this for TARGET_SEH, as otherwise
13407 ;; shrink-wrapped prologue gets enabled too. This might exceed
13408 ;; the maximum size of prologue in unwind information.
13409 ;; Also disallow shrink-wrapping if using stack slot to pass the
13410 ;; static chain pointer - the first instruction has to be pushl %esi
13411 ;; and it can't be moved around, as we use alternate entry points
13414 (define_expand "simple_return"
13416 "!TARGET_SEH && !ix86_static_chain_on_stack"
13418 if (crtl->args.pops_args)
13420 rtx popc = GEN_INT (crtl->args.pops_args);
13421 emit_jump_insn (gen_simple_return_pop_internal (popc));
13426 (define_insn "simple_return_internal"
13429 "* return ix86_output_function_return (false);"
13430 [(set_attr "length" "1")
13431 (set_attr "atom_unit" "jeu")
13432 (set_attr "length_immediate" "0")
13433 (set_attr "modrm" "0")])
13435 (define_insn "interrupt_return"
13437 (unspec [(const_int 0)] UNSPEC_INTERRUPT_RETURN)]
13440 return TARGET_64BIT ? "iretq" : "iret";
13443 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
13444 ;; instruction Athlon and K8 have.
13446 (define_insn "simple_return_internal_long"
13448 (unspec [(const_int 0)] UNSPEC_REP)]
13450 "* return ix86_output_function_return (true);"
13451 [(set_attr "length" "2")
13452 (set_attr "atom_unit" "jeu")
13453 (set_attr "length_immediate" "0")
13454 (set_attr "prefix_rep" "1")
13455 (set_attr "modrm" "0")])
13457 (define_insn_and_split "simple_return_pop_internal"
13459 (use (match_operand:SI 0 "const_int_operand"))]
13462 "&& cfun->machine->function_return_type != indirect_branch_keep"
13464 "ix86_split_simple_return_pop_internal (operands[0]); DONE;"
13465 [(set_attr "length" "3")
13466 (set_attr "atom_unit" "jeu")
13467 (set_attr "length_immediate" "2")
13468 (set_attr "modrm" "0")])
13470 (define_expand "simple_return_indirect_internal"
13473 (use (match_operand 0 "register_operand"))])])
13475 (define_insn "*simple_return_indirect_internal<mode>"
13477 (use (match_operand:W 0 "register_operand" "r"))]
13479 "* return ix86_output_indirect_function_return (operands[0]);"
13480 [(set (attr "type")
13481 (if_then_else (match_test "(cfun->machine->indirect_branch_type
13482 != indirect_branch_keep)")
13483 (const_string "multi")
13484 (const_string "ibr")))
13485 (set_attr "length_immediate" "0")])
13491 [(set_attr "length" "1")
13492 (set_attr "length_immediate" "0")
13493 (set_attr "modrm" "0")])
13495 ;; Generate nops. Operand 0 is the number of nops, up to 8.
13496 (define_insn "nops"
13497 [(unspec_volatile [(match_operand 0 "const_int_operand")]
13501 int num = INTVAL (operands[0]);
13503 gcc_assert (IN_RANGE (num, 1, 8));
13506 fputs ("\tnop\n", asm_out_file);
13510 [(set (attr "length") (symbol_ref "INTVAL (operands[0])"))
13511 (set_attr "length_immediate" "0")
13512 (set_attr "modrm" "0")])
13514 ;; Pad to 16-byte boundary, max skip in op0. Used to avoid
13515 ;; branch prediction penalty for the third jump in a 16-byte
13519 [(unspec_volatile [(match_operand 0)] UNSPECV_ALIGN)]
13522 #ifdef ASM_OUTPUT_MAX_SKIP_PAD
13523 ASM_OUTPUT_MAX_SKIP_PAD (asm_out_file, 4, (int)INTVAL (operands[0]));
13525 /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
13526 The align insn is used to avoid 3 jump instructions in the row to improve
13527 branch prediction and the benefits hardly outweigh the cost of extra 8
13528 nops on the average inserted by full alignment pseudo operation. */
13532 [(set_attr "length" "16")])
13534 (define_expand "prologue"
13537 "ix86_expand_prologue (); DONE;")
13539 (define_expand "set_got"
13541 [(set (match_operand:SI 0 "register_operand")
13542 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
13543 (clobber (reg:CC FLAGS_REG))])]
13546 if (flag_pic && !TARGET_VXWORKS_RTP)
13547 ix86_pc_thunk_call_expanded = true;
13550 (define_insn "*set_got"
13551 [(set (match_operand:SI 0 "register_operand" "=r")
13552 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
13553 (clobber (reg:CC FLAGS_REG))]
13555 "* return output_set_got (operands[0], NULL_RTX);"
13556 [(set_attr "type" "multi")
13557 (set_attr "length" "12")])
13559 (define_expand "set_got_labelled"
13561 [(set (match_operand:SI 0 "register_operand")
13562 (unspec:SI [(label_ref (match_operand 1))]
13564 (clobber (reg:CC FLAGS_REG))])]
13567 if (flag_pic && !TARGET_VXWORKS_RTP)
13568 ix86_pc_thunk_call_expanded = true;
13571 (define_insn "*set_got_labelled"
13572 [(set (match_operand:SI 0 "register_operand" "=r")
13573 (unspec:SI [(label_ref (match_operand 1))]
13575 (clobber (reg:CC FLAGS_REG))]
13577 "* return output_set_got (operands[0], operands[1]);"
13578 [(set_attr "type" "multi")
13579 (set_attr "length" "12")])
13581 (define_insn "set_got_rex64"
13582 [(set (match_operand:DI 0 "register_operand" "=r")
13583 (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
13585 "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}"
13586 [(set_attr "type" "lea")
13587 (set_attr "length_address" "4")
13588 (set_attr "modrm_class" "unknown")
13589 (set_attr "mode" "DI")])
13591 (define_insn "set_rip_rex64"
13592 [(set (match_operand:DI 0 "register_operand" "=r")
13593 (unspec:DI [(label_ref (match_operand 1))] UNSPEC_SET_RIP))]
13595 "lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}"
13596 [(set_attr "type" "lea")
13597 (set_attr "length_address" "4")
13598 (set_attr "mode" "DI")])
13600 (define_insn "set_got_offset_rex64"
13601 [(set (match_operand:DI 0 "register_operand" "=r")
13603 [(label_ref (match_operand 1))]
13604 UNSPEC_SET_GOT_OFFSET))]
13606 "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}"
13607 [(set_attr "type" "imov")
13608 (set_attr "length_immediate" "0")
13609 (set_attr "length_address" "8")
13610 (set_attr "mode" "DI")])
13612 (define_expand "epilogue"
13615 "ix86_expand_epilogue (1); DONE;")
13617 (define_expand "sibcall_epilogue"
13620 "ix86_expand_epilogue (0); DONE;")
13622 (define_expand "eh_return"
13623 [(use (match_operand 0 "register_operand"))]
13626 rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
13628 /* Tricky bit: we write the address of the handler to which we will
13629 be returning into someone else's stack frame, one word below the
13630 stack address we wish to restore. */
13631 tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
13632 tmp = plus_constant (Pmode, tmp, -UNITS_PER_WORD);
13633 tmp = gen_rtx_MEM (Pmode, tmp);
13634 emit_move_insn (tmp, ra);
13636 emit_jump_insn (gen_eh_return_internal ());
13641 (define_insn_and_split "eh_return_internal"
13645 "epilogue_completed"
13647 "ix86_expand_epilogue (2); DONE;")
13649 (define_insn "leave"
13650 [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
13651 (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
13652 (clobber (mem:BLK (scratch)))]
13655 [(set_attr "type" "leave")])
13657 (define_insn "leave_rex64"
13658 [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
13659 (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
13660 (clobber (mem:BLK (scratch)))]
13663 [(set_attr "type" "leave")])
13665 ;; Handle -fsplit-stack.
13667 (define_expand "split_stack_prologue"
13671 ix86_expand_split_stack_prologue ();
13675 ;; In order to support the call/return predictor, we use a return
13676 ;; instruction which the middle-end doesn't see.
13677 (define_insn "split_stack_return"
13678 [(unspec_volatile [(match_operand:SI 0 "const_int_operand")]
13679 UNSPECV_SPLIT_STACK_RETURN)]
13682 if (operands[0] == const0_rtx)
13687 [(set_attr "atom_unit" "jeu")
13688 (set_attr "modrm" "0")
13689 (set (attr "length")
13690 (if_then_else (match_operand:SI 0 "const0_operand")
13693 (set (attr "length_immediate")
13694 (if_then_else (match_operand:SI 0 "const0_operand")
13698 ;; If there are operand 0 bytes available on the stack, jump to
13701 (define_expand "split_stack_space_check"
13702 [(set (pc) (if_then_else
13703 (ltu (minus (reg SP_REG)
13704 (match_operand 0 "register_operand"))
13706 (label_ref (match_operand 1))
13710 rtx reg = gen_reg_rtx (Pmode);
13712 emit_insn (gen_sub3_insn (reg, stack_pointer_rtx, operands[0]));
13714 operands[2] = ix86_split_stack_guard ();
13715 ix86_expand_branch (GEU, reg, operands[2], operands[1]);
13720 ;; Bit manipulation instructions.
13722 (define_expand "ffs<mode>2"
13723 [(set (match_dup 2) (const_int -1))
13724 (parallel [(set (match_dup 3) (match_dup 4))
13725 (set (match_operand:SWI48 0 "register_operand")
13727 (match_operand:SWI48 1 "nonimmediate_operand")))])
13728 (set (match_dup 0) (if_then_else:SWI48
13729 (eq (match_dup 3) (const_int 0))
13732 (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (const_int 1)))
13733 (clobber (reg:CC FLAGS_REG))])]
13736 machine_mode flags_mode;
13738 if (<MODE>mode == SImode && !TARGET_CMOVE)
13740 emit_insn (gen_ffssi2_no_cmove (operands[0], operands [1]));
13744 flags_mode = TARGET_BMI ? CCCmode : CCZmode;
13746 operands[2] = gen_reg_rtx (<MODE>mode);
13747 operands[3] = gen_rtx_REG (flags_mode, FLAGS_REG);
13748 operands[4] = gen_rtx_COMPARE (flags_mode, operands[1], const0_rtx);
13751 (define_insn_and_split "ffssi2_no_cmove"
13752 [(set (match_operand:SI 0 "register_operand" "=r")
13753 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
13754 (clobber (match_scratch:SI 2 "=&q"))
13755 (clobber (reg:CC FLAGS_REG))]
13758 "&& reload_completed"
13759 [(parallel [(set (match_dup 4) (match_dup 5))
13760 (set (match_dup 0) (ctz:SI (match_dup 1)))])
13761 (set (strict_low_part (match_dup 3))
13762 (eq:QI (match_dup 4) (const_int 0)))
13763 (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
13764 (clobber (reg:CC FLAGS_REG))])
13765 (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
13766 (clobber (reg:CC FLAGS_REG))])
13767 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
13768 (clobber (reg:CC FLAGS_REG))])]
13770 machine_mode flags_mode = TARGET_BMI ? CCCmode : CCZmode;
13772 operands[3] = gen_lowpart (QImode, operands[2]);
13773 operands[4] = gen_rtx_REG (flags_mode, FLAGS_REG);
13774 operands[5] = gen_rtx_COMPARE (flags_mode, operands[1], const0_rtx);
13776 ix86_expand_clear (operands[2]);
13779 (define_insn_and_split "*tzcnt<mode>_1"
13780 [(set (reg:CCC FLAGS_REG)
13781 (compare:CCC (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13783 (set (match_operand:SWI48 0 "register_operand" "=r")
13784 (ctz:SWI48 (match_dup 1)))]
13786 "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
13787 "&& TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
13788 && optimize_function_for_speed_p (cfun)
13789 && !reg_mentioned_p (operands[0], operands[1])"
13791 [(set (reg:CCC FLAGS_REG)
13792 (compare:CCC (match_dup 1) (const_int 0)))
13794 (ctz:SWI48 (match_dup 1)))
13795 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)])]
13796 "ix86_expand_clear (operands[0]);"
13797 [(set_attr "type" "alu1")
13798 (set_attr "prefix_0f" "1")
13799 (set_attr "prefix_rep" "1")
13800 (set_attr "btver2_decode" "double")
13801 (set_attr "mode" "<MODE>")])
13803 ; False dependency happens when destination is only updated by tzcnt,
13804 ; lzcnt or popcnt. There is no false dependency when destination is
13805 ; also used in source.
13806 (define_insn "*tzcnt<mode>_1_falsedep"
13807 [(set (reg:CCC FLAGS_REG)
13808 (compare:CCC (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13810 (set (match_operand:SWI48 0 "register_operand" "=r")
13811 (ctz:SWI48 (match_dup 1)))
13812 (unspec [(match_operand:SWI48 2 "register_operand" "0")]
13813 UNSPEC_INSN_FALSE_DEP)]
13815 "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
13816 [(set_attr "type" "alu1")
13817 (set_attr "prefix_0f" "1")
13818 (set_attr "prefix_rep" "1")
13819 (set_attr "btver2_decode" "double")
13820 (set_attr "mode" "<MODE>")])
13822 (define_insn "*bsf<mode>_1"
13823 [(set (reg:CCZ FLAGS_REG)
13824 (compare:CCZ (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13826 (set (match_operand:SWI48 0 "register_operand" "=r")
13827 (ctz:SWI48 (match_dup 1)))]
13829 "bsf{<imodesuffix>}\t{%1, %0|%0, %1}"
13830 [(set_attr "type" "alu1")
13831 (set_attr "prefix_0f" "1")
13832 (set_attr "btver2_decode" "double")
13833 (set_attr "znver1_decode" "vector")
13834 (set_attr "mode" "<MODE>")])
13836 (define_insn_and_split "ctz<mode>2"
13837 [(set (match_operand:SWI48 0 "register_operand" "=r")
13839 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
13840 (clobber (reg:CC FLAGS_REG))]
13844 return "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
13845 else if (optimize_function_for_size_p (cfun))
13847 else if (TARGET_GENERIC)
13848 /* tzcnt expands to 'rep bsf' and we can use it even if !TARGET_BMI. */
13849 return "rep%; bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
13851 return "bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
13853 "(TARGET_BMI || TARGET_GENERIC)
13854 && TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
13855 && optimize_function_for_speed_p (cfun)
13856 && !reg_mentioned_p (operands[0], operands[1])"
13858 [(set (match_dup 0)
13859 (ctz:SWI48 (match_dup 1)))
13860 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
13861 (clobber (reg:CC FLAGS_REG))])]
13862 "ix86_expand_clear (operands[0]);"
13863 [(set_attr "type" "alu1")
13864 (set_attr "prefix_0f" "1")
13865 (set (attr "prefix_rep")
13867 (ior (match_test "TARGET_BMI")
13868 (and (not (match_test "optimize_function_for_size_p (cfun)"))
13869 (match_test "TARGET_GENERIC")))
13871 (const_string "0")))
13872 (set_attr "mode" "<MODE>")])
13874 ; False dependency happens when destination is only updated by tzcnt,
13875 ; lzcnt or popcnt. There is no false dependency when destination is
13876 ; also used in source.
13877 (define_insn "*ctz<mode>2_falsedep"
13878 [(set (match_operand:SWI48 0 "register_operand" "=r")
13880 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
13881 (unspec [(match_operand:SWI48 2 "register_operand" "0")]
13882 UNSPEC_INSN_FALSE_DEP)
13883 (clobber (reg:CC FLAGS_REG))]
13887 return "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
13888 else if (TARGET_GENERIC)
13889 /* tzcnt expands to 'rep bsf' and we can use it even if !TARGET_BMI. */
13890 return "rep%; bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
13892 gcc_unreachable ();
13894 [(set_attr "type" "alu1")
13895 (set_attr "prefix_0f" "1")
13896 (set_attr "prefix_rep" "1")
13897 (set_attr "mode" "<MODE>")])
13899 (define_insn "bsr_rex64"
13900 [(set (match_operand:DI 0 "register_operand" "=r")
13901 (minus:DI (const_int 63)
13902 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
13903 (clobber (reg:CC FLAGS_REG))]
13905 "bsr{q}\t{%1, %0|%0, %1}"
13906 [(set_attr "type" "alu1")
13907 (set_attr "prefix_0f" "1")
13908 (set_attr "znver1_decode" "vector")
13909 (set_attr "mode" "DI")])
13912 [(set (match_operand:SI 0 "register_operand" "=r")
13913 (minus:SI (const_int 31)
13914 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
13915 (clobber (reg:CC FLAGS_REG))]
13917 "bsr{l}\t{%1, %0|%0, %1}"
13918 [(set_attr "type" "alu1")
13919 (set_attr "prefix_0f" "1")
13920 (set_attr "znver1_decode" "vector")
13921 (set_attr "mode" "SI")])
13923 (define_insn "*bsrhi"
13924 [(set (match_operand:HI 0 "register_operand" "=r")
13925 (minus:HI (const_int 15)
13926 (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
13927 (clobber (reg:CC FLAGS_REG))]
13929 "bsr{w}\t{%1, %0|%0, %1}"
13930 [(set_attr "type" "alu1")
13931 (set_attr "prefix_0f" "1")
13932 (set_attr "znver1_decode" "vector")
13933 (set_attr "mode" "HI")])
13935 (define_expand "clz<mode>2"
13937 [(set (match_operand:SWI48 0 "register_operand")
13940 (clz:SWI48 (match_operand:SWI48 1 "nonimmediate_operand"))))
13941 (clobber (reg:CC FLAGS_REG))])
13943 [(set (match_dup 0) (xor:SWI48 (match_dup 0) (match_dup 2)))
13944 (clobber (reg:CC FLAGS_REG))])]
13949 emit_insn (gen_clz<mode>2_lzcnt (operands[0], operands[1]));
13952 operands[2] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
13955 (define_insn_and_split "clz<mode>2_lzcnt"
13956 [(set (match_operand:SWI48 0 "register_operand" "=r")
13958 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
13959 (clobber (reg:CC FLAGS_REG))]
13961 "lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
13962 "&& TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
13963 && optimize_function_for_speed_p (cfun)
13964 && !reg_mentioned_p (operands[0], operands[1])"
13966 [(set (match_dup 0)
13967 (clz:SWI48 (match_dup 1)))
13968 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
13969 (clobber (reg:CC FLAGS_REG))])]
13970 "ix86_expand_clear (operands[0]);"
13971 [(set_attr "prefix_rep" "1")
13972 (set_attr "type" "bitmanip")
13973 (set_attr "mode" "<MODE>")])
13975 ; False dependency happens when destination is only updated by tzcnt,
13976 ; lzcnt or popcnt. There is no false dependency when destination is
13977 ; also used in source.
13978 (define_insn "*clz<mode>2_lzcnt_falsedep"
13979 [(set (match_operand:SWI48 0 "register_operand" "=r")
13981 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
13982 (unspec [(match_operand:SWI48 2 "register_operand" "0")]
13983 UNSPEC_INSN_FALSE_DEP)
13984 (clobber (reg:CC FLAGS_REG))]
13986 "lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
13987 [(set_attr "prefix_rep" "1")
13988 (set_attr "type" "bitmanip")
13989 (set_attr "mode" "<MODE>")])
13991 (define_int_iterator LT_ZCNT
13992 [(UNSPEC_TZCNT "TARGET_BMI")
13993 (UNSPEC_LZCNT "TARGET_LZCNT")])
13995 (define_int_attr lt_zcnt
13996 [(UNSPEC_TZCNT "tzcnt")
13997 (UNSPEC_LZCNT "lzcnt")])
13999 (define_int_attr lt_zcnt_type
14000 [(UNSPEC_TZCNT "alu1")
14001 (UNSPEC_LZCNT "bitmanip")])
14003 ;; Version of lzcnt/tzcnt that is expanded from intrinsics. This version
14004 ;; provides operand size as output when source operand is zero.
14006 (define_insn_and_split "<lt_zcnt>_<mode>"
14007 [(set (match_operand:SWI48 0 "register_operand" "=r")
14009 [(match_operand:SWI48 1 "nonimmediate_operand" "rm")] LT_ZCNT))
14010 (clobber (reg:CC FLAGS_REG))]
14012 "<lt_zcnt>{<imodesuffix>}\t{%1, %0|%0, %1}"
14013 "&& TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
14014 && optimize_function_for_speed_p (cfun)
14015 && !reg_mentioned_p (operands[0], operands[1])"
14017 [(set (match_dup 0)
14018 (unspec:SWI48 [(match_dup 1)] LT_ZCNT))
14019 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
14020 (clobber (reg:CC FLAGS_REG))])]
14021 "ix86_expand_clear (operands[0]);"
14022 [(set_attr "type" "<lt_zcnt_type>")
14023 (set_attr "prefix_0f" "1")
14024 (set_attr "prefix_rep" "1")
14025 (set_attr "mode" "<MODE>")])
14027 ; False dependency happens when destination is only updated by tzcnt,
14028 ; lzcnt or popcnt. There is no false dependency when destination is
14029 ; also used in source.
14030 (define_insn "*<lt_zcnt>_<mode>_falsedep"
14031 [(set (match_operand:SWI48 0 "register_operand" "=r")
14033 [(match_operand:SWI48 1 "nonimmediate_operand" "rm")] LT_ZCNT))
14034 (unspec [(match_operand:SWI48 2 "register_operand" "0")]
14035 UNSPEC_INSN_FALSE_DEP)
14036 (clobber (reg:CC FLAGS_REG))]
14038 "<lt_zcnt>{<imodesuffix>}\t{%1, %0|%0, %1}"
14039 [(set_attr "type" "<lt_zcnt_type>")
14040 (set_attr "prefix_0f" "1")
14041 (set_attr "prefix_rep" "1")
14042 (set_attr "mode" "<MODE>")])
14044 (define_insn "<lt_zcnt>_hi"
14045 [(set (match_operand:HI 0 "register_operand" "=r")
14047 [(match_operand:HI 1 "nonimmediate_operand" "rm")] LT_ZCNT))
14048 (clobber (reg:CC FLAGS_REG))]
14050 "<lt_zcnt>{w}\t{%1, %0|%0, %1}"
14051 [(set_attr "type" "<lt_zcnt_type>")
14052 (set_attr "prefix_0f" "1")
14053 (set_attr "prefix_rep" "1")
14054 (set_attr "mode" "HI")])
14056 ;; BMI instructions.
14058 (define_insn "bmi_bextr_<mode>"
14059 [(set (match_operand:SWI48 0 "register_operand" "=r,r")
14060 (unspec:SWI48 [(match_operand:SWI48 1 "nonimmediate_operand" "r,m")
14061 (match_operand:SWI48 2 "register_operand" "r,r")]
14063 (clobber (reg:CC FLAGS_REG))]
14065 "bextr\t{%2, %1, %0|%0, %1, %2}"
14066 [(set_attr "type" "bitmanip")
14067 (set_attr "btver2_decode" "direct, double")
14068 (set_attr "mode" "<MODE>")])
14070 (define_insn "*bmi_bextr_<mode>_ccz"
14071 [(set (reg:CCZ FLAGS_REG)
14073 (unspec:SWI48 [(match_operand:SWI48 1 "nonimmediate_operand" "r,m")
14074 (match_operand:SWI48 2 "register_operand" "r,r")]
14077 (clobber (match_scratch:SWI48 0 "=r,r"))]
14079 "bextr\t{%2, %1, %0|%0, %1, %2}"
14080 [(set_attr "type" "bitmanip")
14081 (set_attr "btver2_decode" "direct, double")
14082 (set_attr "mode" "<MODE>")])
14084 (define_insn "*bmi_blsi_<mode>"
14085 [(set (match_operand:SWI48 0 "register_operand" "=r")
14088 (match_operand:SWI48 1 "nonimmediate_operand" "rm"))
14090 (clobber (reg:CC FLAGS_REG))]
14092 "blsi\t{%1, %0|%0, %1}"
14093 [(set_attr "type" "bitmanip")
14094 (set_attr "btver2_decode" "double")
14095 (set_attr "mode" "<MODE>")])
14097 (define_insn "*bmi_blsmsk_<mode>"
14098 [(set (match_operand:SWI48 0 "register_operand" "=r")
14101 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
14104 (clobber (reg:CC FLAGS_REG))]
14106 "blsmsk\t{%1, %0|%0, %1}"
14107 [(set_attr "type" "bitmanip")
14108 (set_attr "btver2_decode" "double")
14109 (set_attr "mode" "<MODE>")])
14111 (define_insn "*bmi_blsr_<mode>"
14112 [(set (match_operand:SWI48 0 "register_operand" "=r")
14115 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
14118 (clobber (reg:CC FLAGS_REG))]
14120 "blsr\t{%1, %0|%0, %1}"
14121 [(set_attr "type" "bitmanip")
14122 (set_attr "btver2_decode" "double")
14123 (set_attr "mode" "<MODE>")])
14125 (define_insn "*bmi_blsr_<mode>_cmp"
14126 [(set (reg:CCZ FLAGS_REG)
14130 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
14134 (set (match_operand:SWI48 0 "register_operand" "=r")
14141 "blsr\t{%1, %0|%0, %1}"
14142 [(set_attr "type" "bitmanip")
14143 (set_attr "btver2_decode" "double")
14144 (set_attr "mode" "<MODE>")])
14146 (define_insn "*bmi_blsr_<mode>_ccz"
14147 [(set (reg:CCZ FLAGS_REG)
14151 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
14155 (clobber (match_scratch:SWI48 0 "=r"))]
14157 "blsr\t{%1, %0|%0, %1}"
14158 [(set_attr "type" "bitmanip")
14159 (set_attr "btver2_decode" "double")
14160 (set_attr "mode" "<MODE>")])
14162 ;; BMI2 instructions.
14163 (define_expand "bmi2_bzhi_<mode>3"
14165 [(set (match_operand:SWI48 0 "register_operand")
14166 (zero_extract:SWI48
14167 (match_operand:SWI48 1 "nonimmediate_operand")
14169 (and:SWI48 (match_operand:SWI48 2 "register_operand")
14173 (clobber (reg:CC FLAGS_REG))])]
14175 "operands[3] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT);")
14177 (define_insn "*bmi2_bzhi_<mode>3"
14178 [(set (match_operand:SWI48 0 "register_operand" "=r")
14179 (zero_extract:SWI48
14180 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
14182 (and:SWI48 (match_operand:SWI48 2 "register_operand" "r")
14184 (match_operand:SWI48 3 "const_int_operand" "n"))
14186 (clobber (reg:CC FLAGS_REG))]
14187 "TARGET_BMI2 && INTVAL (operands[3]) == <MODE_SIZE> * BITS_PER_UNIT"
14188 "bzhi\t{%2, %1, %0|%0, %1, %2}"
14189 [(set_attr "type" "bitmanip")
14190 (set_attr "prefix" "vex")
14191 (set_attr "mode" "<MODE>")])
14193 (define_insn "*bmi2_bzhi_<mode>3_1"
14194 [(set (match_operand:SWI48 0 "register_operand" "=r")
14195 (zero_extract:SWI48
14196 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
14198 (zero_extend:SWI48 (match_operand:QI 2 "register_operand" "r"))
14199 (match_operand:SWI48 3 "const_int_operand" "n"))
14201 (clobber (reg:CC FLAGS_REG))]
14202 "TARGET_BMI2 && INTVAL (operands[3]) == <MODE_SIZE> * BITS_PER_UNIT"
14203 "bzhi\t{%<k>2, %1, %0|%0, %1, %<k>2}"
14204 [(set_attr "type" "bitmanip")
14205 (set_attr "prefix" "vex")
14206 (set_attr "mode" "<MODE>")])
14208 (define_insn "*bmi2_bzhi_<mode>3_1_ccz"
14209 [(set (reg:CCZ FLAGS_REG)
14211 (zero_extract:SWI48
14212 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
14214 (zero_extend:SWI48 (match_operand:QI 2 "register_operand" "r"))
14215 (match_operand:SWI48 3 "const_int_operand" "n"))
14218 (clobber (match_scratch:SWI48 0 "=r"))]
14219 "TARGET_BMI2 && INTVAL (operands[3]) == <MODE_SIZE> * BITS_PER_UNIT"
14220 "bzhi\t{%<k>2, %1, %0|%0, %1, %<k>2}"
14221 [(set_attr "type" "bitmanip")
14222 (set_attr "prefix" "vex")
14223 (set_attr "mode" "<MODE>")])
14225 (define_insn "bmi2_pdep_<mode>3"
14226 [(set (match_operand:SWI48 0 "register_operand" "=r")
14227 (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
14228 (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
14231 "pdep\t{%2, %1, %0|%0, %1, %2}"
14232 [(set_attr "type" "bitmanip")
14233 (set_attr "prefix" "vex")
14234 (set_attr "mode" "<MODE>")])
14236 (define_insn "bmi2_pext_<mode>3"
14237 [(set (match_operand:SWI48 0 "register_operand" "=r")
14238 (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
14239 (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
14242 "pext\t{%2, %1, %0|%0, %1, %2}"
14243 [(set_attr "type" "bitmanip")
14244 (set_attr "prefix" "vex")
14245 (set_attr "mode" "<MODE>")])
14247 ;; TBM instructions.
14248 (define_insn "tbm_bextri_<mode>"
14249 [(set (match_operand:SWI48 0 "register_operand" "=r")
14250 (zero_extract:SWI48
14251 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
14252 (match_operand 2 "const_0_to_255_operand" "N")
14253 (match_operand 3 "const_0_to_255_operand" "N")))
14254 (clobber (reg:CC FLAGS_REG))]
14257 operands[2] = GEN_INT (INTVAL (operands[2]) << 8 | INTVAL (operands[3]));
14258 return "bextr\t{%2, %1, %0|%0, %1, %2}";
14260 [(set_attr "type" "bitmanip")
14261 (set_attr "mode" "<MODE>")])
14263 (define_insn "*tbm_blcfill_<mode>"
14264 [(set (match_operand:SWI48 0 "register_operand" "=r")
14267 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
14270 (clobber (reg:CC FLAGS_REG))]
14272 "blcfill\t{%1, %0|%0, %1}"
14273 [(set_attr "type" "bitmanip")
14274 (set_attr "mode" "<MODE>")])
14276 (define_insn "*tbm_blci_<mode>"
14277 [(set (match_operand:SWI48 0 "register_operand" "=r")
14281 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
14284 (clobber (reg:CC FLAGS_REG))]
14286 "blci\t{%1, %0|%0, %1}"
14287 [(set_attr "type" "bitmanip")
14288 (set_attr "mode" "<MODE>")])
14290 (define_insn "*tbm_blcic_<mode>"
14291 [(set (match_operand:SWI48 0 "register_operand" "=r")
14294 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
14298 (clobber (reg:CC FLAGS_REG))]
14300 "blcic\t{%1, %0|%0, %1}"
14301 [(set_attr "type" "bitmanip")
14302 (set_attr "mode" "<MODE>")])
14304 (define_insn "*tbm_blcmsk_<mode>"
14305 [(set (match_operand:SWI48 0 "register_operand" "=r")
14308 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
14311 (clobber (reg:CC FLAGS_REG))]
14313 "blcmsk\t{%1, %0|%0, %1}"
14314 [(set_attr "type" "bitmanip")
14315 (set_attr "mode" "<MODE>")])
14317 (define_insn "*tbm_blcs_<mode>"
14318 [(set (match_operand:SWI48 0 "register_operand" "=r")
14321 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
14324 (clobber (reg:CC FLAGS_REG))]
14326 "blcs\t{%1, %0|%0, %1}"
14327 [(set_attr "type" "bitmanip")
14328 (set_attr "mode" "<MODE>")])
14330 (define_insn "*tbm_blsfill_<mode>"
14331 [(set (match_operand:SWI48 0 "register_operand" "=r")
14334 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
14337 (clobber (reg:CC FLAGS_REG))]
14339 "blsfill\t{%1, %0|%0, %1}"
14340 [(set_attr "type" "bitmanip")
14341 (set_attr "mode" "<MODE>")])
14343 (define_insn "*tbm_blsic_<mode>"
14344 [(set (match_operand:SWI48 0 "register_operand" "=r")
14347 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
14351 (clobber (reg:CC FLAGS_REG))]
14353 "blsic\t{%1, %0|%0, %1}"
14354 [(set_attr "type" "bitmanip")
14355 (set_attr "mode" "<MODE>")])
14357 (define_insn "*tbm_t1mskc_<mode>"
14358 [(set (match_operand:SWI48 0 "register_operand" "=r")
14361 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
14365 (clobber (reg:CC FLAGS_REG))]
14367 "t1mskc\t{%1, %0|%0, %1}"
14368 [(set_attr "type" "bitmanip")
14369 (set_attr "mode" "<MODE>")])
14371 (define_insn "*tbm_tzmsk_<mode>"
14372 [(set (match_operand:SWI48 0 "register_operand" "=r")
14375 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
14379 (clobber (reg:CC FLAGS_REG))]
14381 "tzmsk\t{%1, %0|%0, %1}"
14382 [(set_attr "type" "bitmanip")
14383 (set_attr "mode" "<MODE>")])
14385 (define_insn_and_split "popcount<mode>2"
14386 [(set (match_operand:SWI48 0 "register_operand" "=r")
14388 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
14389 (clobber (reg:CC FLAGS_REG))]
14393 return "popcnt\t{%1, %0|%0, %1}";
14395 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
14398 "&& TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
14399 && optimize_function_for_speed_p (cfun)
14400 && !reg_mentioned_p (operands[0], operands[1])"
14402 [(set (match_dup 0)
14403 (popcount:SWI48 (match_dup 1)))
14404 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
14405 (clobber (reg:CC FLAGS_REG))])]
14406 "ix86_expand_clear (operands[0]);"
14407 [(set_attr "prefix_rep" "1")
14408 (set_attr "type" "bitmanip")
14409 (set_attr "mode" "<MODE>")])
14411 ; False dependency happens when destination is only updated by tzcnt,
14412 ; lzcnt or popcnt. There is no false dependency when destination is
14413 ; also used in source.
14414 (define_insn "*popcount<mode>2_falsedep"
14415 [(set (match_operand:SWI48 0 "register_operand" "=r")
14417 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
14418 (unspec [(match_operand:SWI48 2 "register_operand" "0")]
14419 UNSPEC_INSN_FALSE_DEP)
14420 (clobber (reg:CC FLAGS_REG))]
14424 return "popcnt\t{%1, %0|%0, %1}";
14426 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
14429 [(set_attr "prefix_rep" "1")
14430 (set_attr "type" "bitmanip")
14431 (set_attr "mode" "<MODE>")])
14433 (define_insn_and_split "*popcounthi2_1"
14434 [(set (match_operand:SI 0 "register_operand")
14436 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand"))))
14437 (clobber (reg:CC FLAGS_REG))]
14439 && can_create_pseudo_p ()"
14444 rtx tmp = gen_reg_rtx (HImode);
14446 emit_insn (gen_popcounthi2 (tmp, operands[1]));
14447 emit_insn (gen_zero_extendhisi2 (operands[0], tmp));
14451 (define_insn "popcounthi2"
14452 [(set (match_operand:HI 0 "register_operand" "=r")
14454 (match_operand:HI 1 "nonimmediate_operand" "rm")))
14455 (clobber (reg:CC FLAGS_REG))]
14459 return "popcnt\t{%1, %0|%0, %1}";
14461 return "popcnt{w}\t{%1, %0|%0, %1}";
14464 [(set_attr "prefix_rep" "1")
14465 (set_attr "type" "bitmanip")
14466 (set_attr "mode" "HI")])
14468 (define_expand "bswapdi2"
14469 [(set (match_operand:DI 0 "register_operand")
14470 (bswap:DI (match_operand:DI 1 "nonimmediate_operand")))]
14474 operands[1] = force_reg (DImode, operands[1]);
14477 (define_expand "bswapsi2"
14478 [(set (match_operand:SI 0 "register_operand")
14479 (bswap:SI (match_operand:SI 1 "nonimmediate_operand")))]
14484 else if (TARGET_BSWAP)
14485 operands[1] = force_reg (SImode, operands[1]);
14488 rtx x = operands[0];
14490 emit_move_insn (x, operands[1]);
14491 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
14492 emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
14493 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
14498 (define_insn "*bswap<mode>2_movbe"
14499 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,r,m")
14500 (bswap:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,m,r")))]
14502 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
14505 movbe{<imodesuffix>}\t{%1, %0|%0, %1}
14506 movbe{<imodesuffix>}\t{%1, %0|%0, %1}"
14507 [(set_attr "type" "bitmanip,imov,imov")
14508 (set_attr "modrm" "0,1,1")
14509 (set_attr "prefix_0f" "*,1,1")
14510 (set_attr "prefix_extra" "*,1,1")
14511 (set_attr "mode" "<MODE>")])
14513 (define_insn "*bswap<mode>2"
14514 [(set (match_operand:SWI48 0 "register_operand" "=r")
14515 (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "0")))]
14518 [(set_attr "type" "bitmanip")
14519 (set_attr "modrm" "0")
14520 (set_attr "mode" "<MODE>")])
14522 (define_expand "bswaphi2"
14523 [(set (match_operand:HI 0 "register_operand")
14524 (bswap:HI (match_operand:HI 1 "nonimmediate_operand")))]
14527 (define_insn "*bswaphi2_movbe"
14528 [(set (match_operand:HI 0 "nonimmediate_operand" "=Q,r,m")
14529 (bswap:HI (match_operand:HI 1 "nonimmediate_operand" "0,m,r")))]
14531 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
14533 xchg{b}\t{%h0, %b0|%b0, %h0}
14534 movbe{w}\t{%1, %0|%0, %1}
14535 movbe{w}\t{%1, %0|%0, %1}"
14536 [(set_attr "type" "imov")
14537 (set_attr "modrm" "*,1,1")
14538 (set_attr "prefix_0f" "*,1,1")
14539 (set_attr "prefix_extra" "*,1,1")
14540 (set_attr "pent_pair" "np,*,*")
14541 (set_attr "athlon_decode" "vector,*,*")
14542 (set_attr "amdfam10_decode" "double,*,*")
14543 (set_attr "bdver1_decode" "double,*,*")
14544 (set_attr "mode" "QI,HI,HI")])
14547 [(set (match_operand:HI 0 "general_reg_operand")
14548 (bswap:HI (match_dup 0)))]
14550 && !(TARGET_USE_XCHGB || optimize_function_for_size_p (cfun))
14551 && peep2_regno_dead_p (0, FLAGS_REG)"
14552 [(parallel [(set (match_dup 0) (rotate:HI (match_dup 0) (const_int 8)))
14553 (clobber (reg:CC FLAGS_REG))])])
14555 (define_insn "bswaphi_lowpart"
14556 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
14557 (bswap:HI (match_dup 0)))
14558 (clobber (reg:CC FLAGS_REG))]
14561 xchg{b}\t{%h0, %b0|%b0, %h0}
14562 rol{w}\t{$8, %0|%0, 8}"
14563 [(set (attr "preferred_for_size")
14564 (cond [(eq_attr "alternative" "0")
14565 (symbol_ref "true")]
14566 (symbol_ref "false")))
14567 (set (attr "preferred_for_speed")
14568 (cond [(eq_attr "alternative" "0")
14569 (symbol_ref "TARGET_USE_XCHGB")]
14570 (symbol_ref "!TARGET_USE_XCHGB")))
14571 (set_attr "length" "2,4")
14572 (set_attr "mode" "QI,HI")])
14574 (define_expand "paritydi2"
14575 [(set (match_operand:DI 0 "register_operand")
14576 (parity:DI (match_operand:DI 1 "register_operand")))]
14579 rtx scratch = gen_reg_rtx (QImode);
14581 emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX,
14582 NULL_RTX, operands[1]));
14584 ix86_expand_setcc (scratch, ORDERED,
14585 gen_rtx_REG (CCmode, FLAGS_REG), const0_rtx);
14588 emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
14591 rtx tmp = gen_reg_rtx (SImode);
14593 emit_insn (gen_zero_extendqisi2 (tmp, scratch));
14594 emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
14599 (define_expand "paritysi2"
14600 [(set (match_operand:SI 0 "register_operand")
14601 (parity:SI (match_operand:SI 1 "register_operand")))]
14604 rtx scratch = gen_reg_rtx (QImode);
14606 emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1]));
14608 ix86_expand_setcc (scratch, ORDERED,
14609 gen_rtx_REG (CCmode, FLAGS_REG), const0_rtx);
14611 emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
14615 (define_insn_and_split "paritydi2_cmp"
14616 [(set (reg:CC FLAGS_REG)
14617 (unspec:CC [(match_operand:DI 3 "register_operand" "0")]
14619 (clobber (match_scratch:DI 0 "=r"))
14620 (clobber (match_scratch:SI 1 "=&r"))
14621 (clobber (match_scratch:HI 2 "=Q"))]
14624 "&& reload_completed"
14626 [(set (match_dup 1)
14627 (xor:SI (match_dup 1) (match_dup 4)))
14628 (clobber (reg:CC FLAGS_REG))])
14630 [(set (reg:CC FLAGS_REG)
14631 (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
14632 (clobber (match_dup 1))
14633 (clobber (match_dup 2))])]
14635 operands[4] = gen_lowpart (SImode, operands[3]);
14639 emit_move_insn (operands[1], gen_lowpart (SImode, operands[3]));
14640 emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32)));
14643 operands[1] = gen_highpart (SImode, operands[3]);
14646 (define_insn_and_split "paritysi2_cmp"
14647 [(set (reg:CC FLAGS_REG)
14648 (unspec:CC [(match_operand:SI 2 "register_operand" "0")]
14650 (clobber (match_scratch:SI 0 "=r"))
14651 (clobber (match_scratch:HI 1 "=&Q"))]
14654 "&& reload_completed"
14656 [(set (match_dup 1)
14657 (xor:HI (match_dup 1) (match_dup 3)))
14658 (clobber (reg:CC FLAGS_REG))])
14660 [(set (reg:CC FLAGS_REG)
14661 (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
14662 (clobber (match_dup 1))])]
14664 operands[3] = gen_lowpart (HImode, operands[2]);
14666 emit_move_insn (operands[1], gen_lowpart (HImode, operands[2]));
14667 emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16)));
14670 (define_insn "*parityhi2_cmp"
14671 [(set (reg:CC FLAGS_REG)
14672 (unspec:CC [(match_operand:HI 1 "register_operand" "0")]
14674 (clobber (match_scratch:HI 0 "=Q"))]
14676 "xor{b}\t{%h0, %b0|%b0, %h0}"
14677 [(set_attr "length" "2")
14678 (set_attr "mode" "HI")])
14681 ;; Thread-local storage patterns for ELF.
14683 ;; Note that these code sequences must appear exactly as shown
14684 ;; in order to allow linker relaxation.
14686 (define_insn "*tls_global_dynamic_32_gnu"
14687 [(set (match_operand:SI 0 "register_operand" "=a")
14689 [(match_operand:SI 1 "register_operand" "Yb")
14690 (match_operand 2 "tls_symbolic_operand")
14691 (match_operand 3 "constant_call_address_operand" "Bz")
14694 (clobber (match_scratch:SI 4 "=d"))
14695 (clobber (match_scratch:SI 5 "=c"))
14696 (clobber (reg:CC FLAGS_REG))]
14697 "!TARGET_64BIT && TARGET_GNU_TLS"
14699 if (TARGET_SUN_TLS || flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT)
14701 ("lea{l}\t{%E2@tlsgd(,%1,1), %0|%0, %E2@tlsgd[%1*1]}", operands);
14704 ("lea{l}\t{%E2@tlsgd(%1), %0|%0, %E2@tlsgd[%1]}", operands);
14705 if (TARGET_SUN_TLS)
14706 #ifdef HAVE_AS_IX86_TLSGDPLT
14707 return "call\t%a2@tlsgdplt";
14709 return "call\t%p3@plt";
14711 if (flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT)
14712 return "call\t%P3";
14713 return "call\t{*%p3@GOT(%1)|[DWORD PTR %p3@GOT[%1]]}";
14715 [(set_attr "type" "multi")
14716 (set_attr "length" "12")])
14718 (define_expand "tls_global_dynamic_32"
14720 [(set (match_operand:SI 0 "register_operand")
14721 (unspec:SI [(match_operand:SI 2 "register_operand")
14722 (match_operand 1 "tls_symbolic_operand")
14723 (match_operand 3 "constant_call_address_operand")
14726 (clobber (match_scratch:SI 4))
14727 (clobber (match_scratch:SI 5))
14728 (clobber (reg:CC FLAGS_REG))])]
14730 "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
14732 (define_insn "*tls_global_dynamic_64_<mode>"
14733 [(set (match_operand:P 0 "register_operand" "=a")
14735 (mem:QI (match_operand 2 "constant_call_address_operand" "Bz"))
14736 (match_operand 3)))
14737 (unspec:P [(match_operand 1 "tls_symbolic_operand")
14743 /* The .loc directive has effect for 'the immediately following assembly
14744 instruction'. So for a sequence:
14748 the 'immediately following assembly instruction' is insn1.
14749 We want to emit an insn prefix here, but if we use .byte (as shown in
14750 'ELF Handling For Thread-Local Storage'), a preceding .loc will point
14751 inside the insn sequence, rather than to the start. After relaxation
14752 of the sequence by the linker, the .loc might point inside an insn.
14753 Use data16 prefix instead, which doesn't have this problem. */
14754 fputs ("\tdata16", asm_out_file);
14756 ("lea{q}\t{%E1@tlsgd(%%rip), %%rdi|rdi, %E1@tlsgd[rip]}", operands);
14757 if (TARGET_SUN_TLS || flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT)
14758 fputs (ASM_SHORT "0x6666\n", asm_out_file);
14760 fputs (ASM_BYTE "0x66\n", asm_out_file);
14761 fputs ("\trex64\n", asm_out_file);
14762 if (TARGET_SUN_TLS)
14763 return "call\t%p2@plt";
14764 if (flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT)
14765 return "call\t%P2";
14766 return "call\t{*%p2@GOTPCREL(%%rip)|[QWORD PTR %p2@GOTPCREL[rip]]}";
14768 [(set_attr "type" "multi")
14769 (set (attr "length")
14770 (symbol_ref "TARGET_X32 ? 15 : 16"))])
14772 (define_insn "*tls_global_dynamic_64_largepic"
14773 [(set (match_operand:DI 0 "register_operand" "=a")
14775 (mem:QI (plus:DI (match_operand:DI 2 "register_operand" "b")
14776 (match_operand:DI 3 "immediate_operand" "i")))
14777 (match_operand 4)))
14778 (unspec:DI [(match_operand 1 "tls_symbolic_operand")
14781 "TARGET_64BIT && ix86_cmodel == CM_LARGE_PIC && !TARGET_PECOFF
14782 && GET_CODE (operands[3]) == CONST
14783 && GET_CODE (XEXP (operands[3], 0)) == UNSPEC
14784 && XINT (XEXP (operands[3], 0), 1) == UNSPEC_PLTOFF"
14787 ("lea{q}\t{%E1@tlsgd(%%rip), %%rdi|rdi, %E1@tlsgd[rip]}", operands);
14788 output_asm_insn ("movabs{q}\t{%3, %%rax|rax, %3}", operands);
14789 output_asm_insn ("add{q}\t{%2, %%rax|rax, %2}", operands);
14790 return "call\t{*%%rax|rax}";
14792 [(set_attr "type" "multi")
14793 (set_attr "length" "22")])
14795 (define_expand "tls_global_dynamic_64_<mode>"
14797 [(set (match_operand:P 0 "register_operand")
14799 (mem:QI (match_operand 2))
14801 (unspec:P [(match_operand 1 "tls_symbolic_operand")
14805 "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
14807 (define_insn "*tls_local_dynamic_base_32_gnu"
14808 [(set (match_operand:SI 0 "register_operand" "=a")
14810 [(match_operand:SI 1 "register_operand" "Yb")
14811 (match_operand 2 "constant_call_address_operand" "Bz")
14813 UNSPEC_TLS_LD_BASE))
14814 (clobber (match_scratch:SI 3 "=d"))
14815 (clobber (match_scratch:SI 4 "=c"))
14816 (clobber (reg:CC FLAGS_REG))]
14817 "!TARGET_64BIT && TARGET_GNU_TLS"
14820 ("lea{l}\t{%&@tlsldm(%1), %0|%0, %&@tlsldm[%1]}", operands);
14821 if (TARGET_SUN_TLS)
14823 if (HAVE_AS_IX86_TLSLDMPLT)
14824 return "call\t%&@tlsldmplt";
14826 return "call\t%p2@plt";
14828 if (flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT)
14829 return "call\t%P2";
14830 return "call\t{*%p2@GOT(%1)|[DWORD PTR %p2@GOT[%1]]}";
14832 [(set_attr "type" "multi")
14833 (set_attr "length" "11")])
14835 (define_expand "tls_local_dynamic_base_32"
14837 [(set (match_operand:SI 0 "register_operand")
14839 [(match_operand:SI 1 "register_operand")
14840 (match_operand 2 "constant_call_address_operand")
14842 UNSPEC_TLS_LD_BASE))
14843 (clobber (match_scratch:SI 3))
14844 (clobber (match_scratch:SI 4))
14845 (clobber (reg:CC FLAGS_REG))])]
14847 "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
14849 (define_insn "*tls_local_dynamic_base_64_<mode>"
14850 [(set (match_operand:P 0 "register_operand" "=a")
14852 (mem:QI (match_operand 1 "constant_call_address_operand" "Bz"))
14853 (match_operand 2)))
14854 (unspec:P [(reg:P SP_REG)] UNSPEC_TLS_LD_BASE)]
14858 ("lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}", operands);
14859 if (TARGET_SUN_TLS)
14860 return "call\t%p1@plt";
14861 if (flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT)
14862 return "call\t%P1";
14863 return "call\t{*%p1@GOTPCREL(%%rip)|[QWORD PTR %p1@GOTPCREL[rip]]}";
14865 [(set_attr "type" "multi")
14866 (set_attr "length" "12")])
14868 (define_insn "*tls_local_dynamic_base_64_largepic"
14869 [(set (match_operand:DI 0 "register_operand" "=a")
14871 (mem:QI (plus:DI (match_operand:DI 1 "register_operand" "b")
14872 (match_operand:DI 2 "immediate_operand" "i")))
14873 (match_operand 3)))
14874 (unspec:DI [(reg:DI SP_REG)] UNSPEC_TLS_LD_BASE)]
14875 "TARGET_64BIT && ix86_cmodel == CM_LARGE_PIC && !TARGET_PECOFF
14876 && GET_CODE (operands[2]) == CONST
14877 && GET_CODE (XEXP (operands[2], 0)) == UNSPEC
14878 && XINT (XEXP (operands[2], 0), 1) == UNSPEC_PLTOFF"
14881 ("lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}", operands);
14882 output_asm_insn ("movabs{q}\t{%2, %%rax|rax, %2}", operands);
14883 output_asm_insn ("add{q}\t{%1, %%rax|rax, %1}", operands);
14884 return "call\t{*%%rax|rax}";
14886 [(set_attr "type" "multi")
14887 (set_attr "length" "22")])
14889 (define_expand "tls_local_dynamic_base_64_<mode>"
14891 [(set (match_operand:P 0 "register_operand")
14893 (mem:QI (match_operand 1))
14895 (unspec:P [(reg:P SP_REG)] UNSPEC_TLS_LD_BASE)])]
14897 "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
14899 ;; Local dynamic of a single variable is a lose. Show combine how
14900 ;; to convert that back to global dynamic.
14902 (define_insn_and_split "*tls_local_dynamic_32_once"
14903 [(set (match_operand:SI 0 "register_operand" "=a")
14905 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14906 (match_operand 2 "constant_call_address_operand" "Bz")
14908 UNSPEC_TLS_LD_BASE)
14909 (const:SI (unspec:SI
14910 [(match_operand 3 "tls_symbolic_operand")]
14912 (clobber (match_scratch:SI 4 "=d"))
14913 (clobber (match_scratch:SI 5 "=c"))
14914 (clobber (reg:CC FLAGS_REG))]
14919 [(set (match_dup 0)
14920 (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)
14923 (clobber (match_dup 4))
14924 (clobber (match_dup 5))
14925 (clobber (reg:CC FLAGS_REG))])])
14927 ;; Load and add the thread base pointer from %<tp_seg>:0.
14928 (define_insn_and_split "*load_tp_<mode>"
14929 [(set (match_operand:PTR 0 "register_operand" "=r")
14930 (unspec:PTR [(const_int 0)] UNSPEC_TP))]
14934 [(set (match_dup 0)
14937 addr_space_t as = DEFAULT_TLS_SEG_REG;
14939 operands[1] = gen_const_mem (<MODE>mode, const0_rtx);
14940 set_mem_addr_space (operands[1], as);
14943 (define_insn_and_split "*load_tp_x32_zext"
14944 [(set (match_operand:DI 0 "register_operand" "=r")
14946 (unspec:SI [(const_int 0)] UNSPEC_TP)))]
14950 [(set (match_dup 0)
14951 (zero_extend:DI (match_dup 1)))]
14953 addr_space_t as = DEFAULT_TLS_SEG_REG;
14955 operands[1] = gen_const_mem (SImode, const0_rtx);
14956 set_mem_addr_space (operands[1], as);
14959 (define_insn_and_split "*add_tp_<mode>"
14960 [(set (match_operand:PTR 0 "register_operand" "=r")
14962 (unspec:PTR [(const_int 0)] UNSPEC_TP)
14963 (match_operand:PTR 1 "register_operand" "0")))
14964 (clobber (reg:CC FLAGS_REG))]
14969 [(set (match_dup 0)
14970 (plus:PTR (match_dup 1) (match_dup 2)))
14971 (clobber (reg:CC FLAGS_REG))])]
14973 addr_space_t as = DEFAULT_TLS_SEG_REG;
14975 operands[2] = gen_const_mem (<MODE>mode, const0_rtx);
14976 set_mem_addr_space (operands[2], as);
14979 (define_insn_and_split "*add_tp_x32_zext"
14980 [(set (match_operand:DI 0 "register_operand" "=r")
14982 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
14983 (match_operand:SI 1 "register_operand" "0"))))
14984 (clobber (reg:CC FLAGS_REG))]
14989 [(set (match_dup 0)
14991 (plus:SI (match_dup 1) (match_dup 2))))
14992 (clobber (reg:CC FLAGS_REG))])]
14994 addr_space_t as = DEFAULT_TLS_SEG_REG;
14996 operands[2] = gen_const_mem (SImode, const0_rtx);
14997 set_mem_addr_space (operands[2], as);
15000 ;; The Sun linker took the AMD64 TLS spec literally and can only handle
15001 ;; %rax as destination of the initial executable code sequence.
15002 (define_insn "tls_initial_exec_64_sun"
15003 [(set (match_operand:DI 0 "register_operand" "=a")
15005 [(match_operand 1 "tls_symbolic_operand")]
15006 UNSPEC_TLS_IE_SUN))
15007 (clobber (reg:CC FLAGS_REG))]
15008 "TARGET_64BIT && TARGET_SUN_TLS"
15011 ("mov{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}", operands);
15012 return "add{q}\t{%a1@gottpoff(%%rip), %0|%0, %a1@gottpoff[rip]}";
15014 [(set_attr "type" "multi")])
15016 ;; GNU2 TLS patterns can be split.
15018 (define_expand "tls_dynamic_gnu2_32"
15019 [(set (match_dup 3)
15020 (plus:SI (match_operand:SI 2 "register_operand")
15022 (unspec:SI [(match_operand 1 "tls_symbolic_operand")]
15025 [(set (match_operand:SI 0 "register_operand")
15026 (unspec:SI [(match_dup 1) (match_dup 3)
15027 (match_dup 2) (reg:SI SP_REG)]
15029 (clobber (reg:CC FLAGS_REG))])]
15030 "!TARGET_64BIT && TARGET_GNU2_TLS"
15032 operands[3] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
15033 ix86_tls_descriptor_calls_expanded_in_cfun = true;
15036 (define_insn "*tls_dynamic_gnu2_lea_32"
15037 [(set (match_operand:SI 0 "register_operand" "=r")
15038 (plus:SI (match_operand:SI 1 "register_operand" "b")
15040 (unspec:SI [(match_operand 2 "tls_symbolic_operand")]
15041 UNSPEC_TLSDESC))))]
15042 "!TARGET_64BIT && TARGET_GNU2_TLS"
15043 "lea{l}\t{%E2@TLSDESC(%1), %0|%0, %E2@TLSDESC[%1]}"
15044 [(set_attr "type" "lea")
15045 (set_attr "mode" "SI")
15046 (set_attr "length" "6")
15047 (set_attr "length_address" "4")])
15049 (define_insn "*tls_dynamic_gnu2_call_32"
15050 [(set (match_operand:SI 0 "register_operand" "=a")
15051 (unspec:SI [(match_operand 1 "tls_symbolic_operand")
15052 (match_operand:SI 2 "register_operand" "0")
15053 ;; we have to make sure %ebx still points to the GOT
15054 (match_operand:SI 3 "register_operand" "b")
15057 (clobber (reg:CC FLAGS_REG))]
15058 "!TARGET_64BIT && TARGET_GNU2_TLS"
15059 "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
15060 [(set_attr "type" "call")
15061 (set_attr "length" "2")
15062 (set_attr "length_address" "0")])
15064 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
15065 [(set (match_operand:SI 0 "register_operand" "=&a")
15067 (unspec:SI [(match_operand 3 "tls_modbase_operand")
15068 (match_operand:SI 4)
15069 (match_operand:SI 2 "register_operand" "b")
15072 (const:SI (unspec:SI
15073 [(match_operand 1 "tls_symbolic_operand")]
15075 (clobber (reg:CC FLAGS_REG))]
15076 "!TARGET_64BIT && TARGET_GNU2_TLS"
15079 [(set (match_dup 0) (match_dup 5))]
15081 operands[5] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
15082 emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
15085 (define_expand "tls_dynamic_gnu2_64"
15086 [(set (match_dup 2)
15087 (unspec:DI [(match_operand 1 "tls_symbolic_operand")]
15090 [(set (match_operand:DI 0 "register_operand")
15091 (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
15093 (clobber (reg:CC FLAGS_REG))])]
15094 "TARGET_64BIT && TARGET_GNU2_TLS"
15096 operands[2] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
15097 ix86_tls_descriptor_calls_expanded_in_cfun = true;
15100 (define_insn "*tls_dynamic_gnu2_lea_64"
15101 [(set (match_operand:DI 0 "register_operand" "=r")
15102 (unspec:DI [(match_operand 1 "tls_symbolic_operand")]
15104 "TARGET_64BIT && TARGET_GNU2_TLS"
15105 "lea{q}\t{%E1@TLSDESC(%%rip), %0|%0, %E1@TLSDESC[rip]}"
15106 [(set_attr "type" "lea")
15107 (set_attr "mode" "DI")
15108 (set_attr "length" "7")
15109 (set_attr "length_address" "4")])
15111 (define_insn "*tls_dynamic_gnu2_call_64"
15112 [(set (match_operand:DI 0 "register_operand" "=a")
15113 (unspec:DI [(match_operand 1 "tls_symbolic_operand")
15114 (match_operand:DI 2 "register_operand" "0")
15117 (clobber (reg:CC FLAGS_REG))]
15118 "TARGET_64BIT && TARGET_GNU2_TLS"
15119 "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
15120 [(set_attr "type" "call")
15121 (set_attr "length" "2")
15122 (set_attr "length_address" "0")])
15124 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
15125 [(set (match_operand:DI 0 "register_operand" "=&a")
15127 (unspec:DI [(match_operand 2 "tls_modbase_operand")
15128 (match_operand:DI 3)
15131 (const:DI (unspec:DI
15132 [(match_operand 1 "tls_symbolic_operand")]
15134 (clobber (reg:CC FLAGS_REG))]
15135 "TARGET_64BIT && TARGET_GNU2_TLS"
15138 [(set (match_dup 0) (match_dup 4))]
15140 operands[4] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
15141 emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
15145 [(match_operand 0 "tls_address_pattern")]
15146 "TARGET_TLS_DIRECT_SEG_REFS"
15148 "operands[0] = ix86_rewrite_tls_address (operands[0]);")
15151 ;; These patterns match the binary 387 instructions for addM3, subM3,
15152 ;; mulM3 and divM3. There are three patterns for each of DFmode and
15153 ;; SFmode. The first is the normal insn, the second the same insn but
15154 ;; with one operand a conversion, and the third the same insn but with
15155 ;; the other operand a conversion. The conversion may be SFmode or
15156 ;; SImode if the target mode DFmode, but only SImode if the target mode
15159 ;; Gcc is slightly more smart about handling normal two address instructions
15160 ;; so use special patterns for add and mull.
15162 (define_insn "*fop_<mode>_comm"
15163 [(set (match_operand:MODEF 0 "register_operand" "=f,x,v")
15164 (match_operator:MODEF 3 "binary_fp_operator"
15165 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,0,v")
15166 (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm,vm")]))]
15167 "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15168 || (TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)))
15169 && COMMUTATIVE_ARITH_P (operands[3])
15170 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15171 "* return output_387_binary_op (insn, operands);"
15172 [(set (attr "type")
15173 (if_then_else (eq_attr "alternative" "1,2")
15174 (if_then_else (match_operand:MODEF 3 "mult_operator")
15175 (const_string "ssemul")
15176 (const_string "sseadd"))
15177 (if_then_else (match_operand:MODEF 3 "mult_operator")
15178 (const_string "fmul")
15179 (const_string "fop"))))
15180 (set_attr "isa" "*,noavx,avx")
15181 (set_attr "prefix" "orig,orig,vex")
15182 (set_attr "mode" "<MODE>")
15183 (set (attr "enabled")
15185 (match_test ("SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"))
15187 (eq_attr "alternative" "0")
15188 (symbol_ref "TARGET_MIX_SSE_I387
15189 && X87_ENABLE_ARITH (<MODE>mode)")
15190 (const_string "*"))
15192 (eq_attr "alternative" "0")
15193 (symbol_ref "true")
15194 (symbol_ref "false"))))])
15196 (define_insn "*rcpsf2_sse"
15197 [(set (match_operand:SF 0 "register_operand" "=x,x")
15198 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "x,m")]
15200 "TARGET_SSE && TARGET_SSE_MATH"
15202 %vrcpss\t{%d1, %0|%0, %d1}
15203 %vrcpss\t{%1, %d0|%d0, %1}"
15204 [(set_attr "type" "sse")
15205 (set_attr "atom_sse_attr" "rcp")
15206 (set_attr "btver2_sse_attr" "rcp")
15207 (set_attr "prefix" "maybe_vex")
15208 (set_attr "mode" "SF")])
15210 (define_insn "*fop_<mode>_1"
15211 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,v")
15212 (match_operator:MODEF 3 "binary_fp_operator"
15213 [(match_operand:MODEF 1
15214 "x87nonimm_ssenomem_operand" "0,fm,0,v")
15215 (match_operand:MODEF 2
15216 "nonimmediate_operand" "fm,0,xm,vm")]))]
15217 "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15218 || (TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)))
15219 && !COMMUTATIVE_ARITH_P (operands[3])
15220 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15221 "* return output_387_binary_op (insn, operands);"
15222 [(set (attr "type")
15223 (if_then_else (eq_attr "alternative" "2,3")
15224 (if_then_else (match_operand:MODEF 3 "div_operator")
15225 (const_string "ssediv")
15226 (const_string "sseadd"))
15227 (if_then_else (match_operand:MODEF 3 "div_operator")
15228 (const_string "fdiv")
15229 (const_string "fop"))))
15230 (set_attr "isa" "*,*,noavx,avx")
15231 (set_attr "prefix" "orig,orig,orig,vex")
15232 (set_attr "mode" "<MODE>")
15233 (set (attr "enabled")
15235 (match_test ("SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"))
15237 (eq_attr "alternative" "0,1")
15238 (symbol_ref "TARGET_MIX_SSE_I387
15239 && X87_ENABLE_ARITH (<MODE>mode)")
15240 (const_string "*"))
15242 (eq_attr "alternative" "0,1")
15243 (symbol_ref "true")
15244 (symbol_ref "false"))))])
15246 ;; ??? Add SSE splitters for these!
15247 (define_insn "*fop_<MODEF:mode>_2_i387"
15248 [(set (match_operand:MODEF 0 "register_operand" "=f")
15249 (match_operator:MODEF 3 "binary_fp_operator"
15251 (match_operand:SWI24 1 "nonimmediate_operand" "m"))
15252 (match_operand:MODEF 2 "register_operand" "0")]))]
15253 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI24:MODE>mode)
15254 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
15255 && (TARGET_USE_<SWI24:MODE>MODE_FIOP
15256 || optimize_function_for_size_p (cfun))"
15257 "* return output_387_binary_op (insn, operands);"
15258 [(set (attr "type")
15259 (cond [(match_operand:MODEF 3 "mult_operator")
15260 (const_string "fmul")
15261 (match_operand:MODEF 3 "div_operator")
15262 (const_string "fdiv")
15264 (const_string "fop")))
15265 (set_attr "fp_int_src" "true")
15266 (set_attr "mode" "<SWI24:MODE>")])
15268 (define_insn "*fop_<MODEF:mode>_3_i387"
15269 [(set (match_operand:MODEF 0 "register_operand" "=f")
15270 (match_operator:MODEF 3 "binary_fp_operator"
15271 [(match_operand:MODEF 1 "register_operand" "0")
15273 (match_operand:SWI24 2 "nonimmediate_operand" "m"))]))]
15274 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI24:MODE>mode)
15275 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
15276 && (TARGET_USE_<SWI24:MODE>MODE_FIOP
15277 || optimize_function_for_size_p (cfun))"
15278 "* return output_387_binary_op (insn, operands);"
15279 [(set (attr "type")
15280 (cond [(match_operand:MODEF 3 "mult_operator")
15281 (const_string "fmul")
15282 (match_operand:MODEF 3 "div_operator")
15283 (const_string "fdiv")
15285 (const_string "fop")))
15286 (set_attr "fp_int_src" "true")
15287 (set_attr "mode" "<MODE>")])
15289 (define_insn "*fop_df_4_i387"
15290 [(set (match_operand:DF 0 "register_operand" "=f,f")
15291 (match_operator:DF 3 "binary_fp_operator"
15293 (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
15294 (match_operand:DF 2 "register_operand" "0,f")]))]
15295 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
15296 && !(SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
15297 "* return output_387_binary_op (insn, operands);"
15298 [(set (attr "type")
15299 (cond [(match_operand:DF 3 "mult_operator")
15300 (const_string "fmul")
15301 (match_operand:DF 3 "div_operator")
15302 (const_string "fdiv")
15304 (const_string "fop")))
15305 (set_attr "mode" "SF")])
15307 (define_insn "*fop_df_5_i387"
15308 [(set (match_operand:DF 0 "register_operand" "=f,f")
15309 (match_operator:DF 3 "binary_fp_operator"
15310 [(match_operand:DF 1 "register_operand" "0,f")
15312 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
15313 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
15314 && !(SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
15315 "* return output_387_binary_op (insn, operands);"
15316 [(set (attr "type")
15317 (cond [(match_operand:DF 3 "mult_operator")
15318 (const_string "fmul")
15319 (match_operand:DF 3 "div_operator")
15320 (const_string "fdiv")
15322 (const_string "fop")))
15323 (set_attr "mode" "SF")])
15325 (define_insn "*fop_df_6_i387"
15326 [(set (match_operand:DF 0 "register_operand" "=f,f")
15327 (match_operator:DF 3 "binary_fp_operator"
15329 (match_operand:SF 1 "register_operand" "0,f"))
15331 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
15332 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
15333 && !(SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
15334 "* return output_387_binary_op (insn, operands);"
15335 [(set (attr "type")
15336 (cond [(match_operand:DF 3 "mult_operator")
15337 (const_string "fmul")
15338 (match_operand:DF 3 "div_operator")
15339 (const_string "fdiv")
15341 (const_string "fop")))
15342 (set_attr "mode" "SF")])
15344 (define_insn "*fop_xf_comm_i387"
15345 [(set (match_operand:XF 0 "register_operand" "=f")
15346 (match_operator:XF 3 "binary_fp_operator"
15347 [(match_operand:XF 1 "register_operand" "%0")
15348 (match_operand:XF 2 "register_operand" "f")]))]
15350 && COMMUTATIVE_ARITH_P (operands[3])"
15351 "* return output_387_binary_op (insn, operands);"
15352 [(set (attr "type")
15353 (if_then_else (match_operand:XF 3 "mult_operator")
15354 (const_string "fmul")
15355 (const_string "fop")))
15356 (set_attr "mode" "XF")])
15358 (define_insn "*fop_xf_1_i387"
15359 [(set (match_operand:XF 0 "register_operand" "=f,f")
15360 (match_operator:XF 3 "binary_fp_operator"
15361 [(match_operand:XF 1 "register_operand" "0,f")
15362 (match_operand:XF 2 "register_operand" "f,0")]))]
15364 && !COMMUTATIVE_ARITH_P (operands[3])"
15365 "* return output_387_binary_op (insn, operands);"
15366 [(set (attr "type")
15367 (if_then_else (match_operand:XF 3 "div_operator")
15368 (const_string "fdiv")
15369 (const_string "fop")))
15370 (set_attr "mode" "XF")])
15372 (define_insn "*fop_xf_2_i387"
15373 [(set (match_operand:XF 0 "register_operand" "=f")
15374 (match_operator:XF 3 "binary_fp_operator"
15376 (match_operand:SWI24 1 "nonimmediate_operand" "m"))
15377 (match_operand:XF 2 "register_operand" "0")]))]
15379 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
15380 "* return output_387_binary_op (insn, operands);"
15381 [(set (attr "type")
15382 (cond [(match_operand:XF 3 "mult_operator")
15383 (const_string "fmul")
15384 (match_operand:XF 3 "div_operator")
15385 (const_string "fdiv")
15387 (const_string "fop")))
15388 (set_attr "fp_int_src" "true")
15389 (set_attr "mode" "<MODE>")])
15391 (define_insn "*fop_xf_3_i387"
15392 [(set (match_operand:XF 0 "register_operand" "=f")
15393 (match_operator:XF 3 "binary_fp_operator"
15394 [(match_operand:XF 1 "register_operand" "0")
15396 (match_operand:SWI24 2 "nonimmediate_operand" "m"))]))]
15398 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
15399 "* return output_387_binary_op (insn, operands);"
15400 [(set (attr "type")
15401 (cond [(match_operand:XF 3 "mult_operator")
15402 (const_string "fmul")
15403 (match_operand:XF 3 "div_operator")
15404 (const_string "fdiv")
15406 (const_string "fop")))
15407 (set_attr "fp_int_src" "true")
15408 (set_attr "mode" "<MODE>")])
15410 (define_insn "*fop_xf_4_i387"
15411 [(set (match_operand:XF 0 "register_operand" "=f,f")
15412 (match_operator:XF 3 "binary_fp_operator"
15414 (match_operand:MODEF 1 "nonimmediate_operand" "fm,0"))
15415 (match_operand:XF 2 "register_operand" "0,f")]))]
15417 "* return output_387_binary_op (insn, operands);"
15418 [(set (attr "type")
15419 (cond [(match_operand:XF 3 "mult_operator")
15420 (const_string "fmul")
15421 (match_operand:XF 3 "div_operator")
15422 (const_string "fdiv")
15424 (const_string "fop")))
15425 (set_attr "mode" "<MODE>")])
15427 (define_insn "*fop_xf_5_i387"
15428 [(set (match_operand:XF 0 "register_operand" "=f,f")
15429 (match_operator:XF 3 "binary_fp_operator"
15430 [(match_operand:XF 1 "register_operand" "0,f")
15432 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
15434 "* return output_387_binary_op (insn, operands);"
15435 [(set (attr "type")
15436 (cond [(match_operand:XF 3 "mult_operator")
15437 (const_string "fmul")
15438 (match_operand:XF 3 "div_operator")
15439 (const_string "fdiv")
15441 (const_string "fop")))
15442 (set_attr "mode" "<MODE>")])
15444 (define_insn "*fop_xf_6_i387"
15445 [(set (match_operand:XF 0 "register_operand" "=f,f")
15446 (match_operator:XF 3 "binary_fp_operator"
15448 (match_operand:MODEF 1 "register_operand" "0,f"))
15450 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
15452 "* return output_387_binary_op (insn, operands);"
15453 [(set (attr "type")
15454 (cond [(match_operand:XF 3 "mult_operator")
15455 (const_string "fmul")
15456 (match_operand:XF 3 "div_operator")
15457 (const_string "fdiv")
15459 (const_string "fop")))
15460 (set_attr "mode" "<MODE>")])
15462 ;; FPU special functions.
15464 ;; This pattern implements a no-op XFmode truncation for
15465 ;; all fancy i386 XFmode math functions.
15467 (define_insn "truncxf<mode>2_i387_noop_unspec"
15468 [(set (match_operand:MODEF 0 "register_operand" "=f")
15469 (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")]
15470 UNSPEC_TRUNC_NOOP))]
15471 "TARGET_USE_FANCY_MATH_387"
15472 "* return output_387_reg_move (insn, operands);"
15473 [(set_attr "type" "fmov")
15474 (set_attr "mode" "<MODE>")])
15476 (define_insn "sqrtxf2"
15477 [(set (match_operand:XF 0 "register_operand" "=f")
15478 (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
15479 "TARGET_USE_FANCY_MATH_387"
15481 [(set_attr "type" "fpspc")
15482 (set_attr "mode" "XF")
15483 (set_attr "athlon_decode" "direct")
15484 (set_attr "amdfam10_decode" "direct")
15485 (set_attr "bdver1_decode" "direct")])
15487 (define_insn "sqrt_extend<mode>xf2_i387"
15488 [(set (match_operand:XF 0 "register_operand" "=f")
15491 (match_operand:MODEF 1 "register_operand" "0"))))]
15492 "TARGET_USE_FANCY_MATH_387"
15494 [(set_attr "type" "fpspc")
15495 (set_attr "mode" "XF")
15496 (set_attr "athlon_decode" "direct")
15497 (set_attr "amdfam10_decode" "direct")
15498 (set_attr "bdver1_decode" "direct")])
15500 (define_insn "*rsqrtsf2_sse"
15501 [(set (match_operand:SF 0 "register_operand" "=x,x")
15502 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "x,m")]
15504 "TARGET_SSE && TARGET_SSE_MATH"
15506 %vrsqrtss\t{%d1, %0|%0, %d1}
15507 %vrsqrtss\t{%1, %d0|%d0, %1}"
15508 [(set_attr "type" "sse")
15509 (set_attr "atom_sse_attr" "rcp")
15510 (set_attr "btver2_sse_attr" "rcp")
15511 (set_attr "prefix" "maybe_vex")
15512 (set_attr "mode" "SF")])
15514 (define_expand "rsqrtsf2"
15515 [(set (match_operand:SF 0 "register_operand")
15516 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand")]
15518 "TARGET_SSE && TARGET_SSE_MATH"
15520 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
15524 (define_insn "*sqrt<mode>2_sse"
15525 [(set (match_operand:MODEF 0 "register_operand" "=v,v")
15527 (match_operand:MODEF 1 "nonimmediate_operand" "v,m")))]
15528 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
15530 %vsqrt<ssemodesuffix>\t{%d1, %0|%0, %d1}
15531 %vsqrt<ssemodesuffix>\t{%1, %d0|%d0, %1}"
15532 [(set_attr "type" "sse")
15533 (set_attr "atom_sse_attr" "sqrt")
15534 (set_attr "btver2_sse_attr" "sqrt")
15535 (set_attr "prefix" "maybe_vex")
15536 (set_attr "mode" "<MODE>")
15537 (set_attr "athlon_decode" "*")
15538 (set_attr "amdfam10_decode" "*")
15539 (set_attr "bdver1_decode" "*")])
15541 (define_expand "sqrt<mode>2"
15542 [(set (match_operand:MODEF 0 "register_operand")
15544 (match_operand:MODEF 1 "nonimmediate_operand")))]
15545 "(TARGET_USE_FANCY_MATH_387 && X87_ENABLE_ARITH (<MODE>mode))
15546 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
15548 if (<MODE>mode == SFmode
15549 && TARGET_SSE && TARGET_SSE_MATH
15550 && TARGET_RECIP_SQRT
15551 && !optimize_function_for_size_p (cfun)
15552 && flag_finite_math_only && !flag_trapping_math
15553 && flag_unsafe_math_optimizations)
15555 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
15559 if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
15561 rtx op0 = gen_reg_rtx (XFmode);
15562 rtx op1 = force_reg (<MODE>mode, operands[1]);
15564 emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
15565 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
15570 (define_insn "fpremxf4_i387"
15571 [(set (match_operand:XF 0 "register_operand" "=f")
15572 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15573 (match_operand:XF 3 "register_operand" "1")]
15575 (set (match_operand:XF 1 "register_operand" "=u")
15576 (unspec:XF [(match_dup 2) (match_dup 3)]
15578 (set (reg:CCFP FPSR_REG)
15579 (unspec:CCFP [(match_dup 2) (match_dup 3)]
15581 "TARGET_USE_FANCY_MATH_387
15582 && flag_finite_math_only"
15584 [(set_attr "type" "fpspc")
15585 (set_attr "znver1_decode" "vector")
15586 (set_attr "mode" "XF")])
15588 (define_expand "fmodxf3"
15589 [(use (match_operand:XF 0 "register_operand"))
15590 (use (match_operand:XF 1 "general_operand"))
15591 (use (match_operand:XF 2 "general_operand"))]
15592 "TARGET_USE_FANCY_MATH_387
15593 && flag_finite_math_only"
15595 rtx_code_label *label = gen_label_rtx ();
15597 rtx op1 = gen_reg_rtx (XFmode);
15598 rtx op2 = gen_reg_rtx (XFmode);
15600 emit_move_insn (op2, operands[2]);
15601 emit_move_insn (op1, operands[1]);
15603 emit_label (label);
15604 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
15605 ix86_emit_fp_unordered_jump (label);
15606 LABEL_NUSES (label) = 1;
15608 emit_move_insn (operands[0], op1);
15612 (define_expand "fmod<mode>3"
15613 [(use (match_operand:MODEF 0 "register_operand"))
15614 (use (match_operand:MODEF 1 "general_operand"))
15615 (use (match_operand:MODEF 2 "general_operand"))]
15616 "TARGET_USE_FANCY_MATH_387
15617 && flag_finite_math_only"
15619 rtx (*gen_truncxf) (rtx, rtx);
15621 rtx_code_label *label = gen_label_rtx ();
15623 rtx op1 = gen_reg_rtx (XFmode);
15624 rtx op2 = gen_reg_rtx (XFmode);
15626 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
15627 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15629 emit_label (label);
15630 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
15631 ix86_emit_fp_unordered_jump (label);
15632 LABEL_NUSES (label) = 1;
15634 /* Truncate the result properly for strict SSE math. */
15635 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15636 && !TARGET_MIX_SSE_I387)
15637 gen_truncxf = gen_truncxf<mode>2;
15639 gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
15641 emit_insn (gen_truncxf (operands[0], op1));
15645 (define_insn "fprem1xf4_i387"
15646 [(set (match_operand:XF 0 "register_operand" "=f")
15647 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15648 (match_operand:XF 3 "register_operand" "1")]
15650 (set (match_operand:XF 1 "register_operand" "=u")
15651 (unspec:XF [(match_dup 2) (match_dup 3)]
15653 (set (reg:CCFP FPSR_REG)
15654 (unspec:CCFP [(match_dup 2) (match_dup 3)]
15656 "TARGET_USE_FANCY_MATH_387
15657 && flag_finite_math_only"
15659 [(set_attr "type" "fpspc")
15660 (set_attr "znver1_decode" "vector")
15661 (set_attr "mode" "XF")])
15663 (define_expand "remainderxf3"
15664 [(use (match_operand:XF 0 "register_operand"))
15665 (use (match_operand:XF 1 "general_operand"))
15666 (use (match_operand:XF 2 "general_operand"))]
15667 "TARGET_USE_FANCY_MATH_387
15668 && flag_finite_math_only"
15670 rtx_code_label *label = gen_label_rtx ();
15672 rtx op1 = gen_reg_rtx (XFmode);
15673 rtx op2 = gen_reg_rtx (XFmode);
15675 emit_move_insn (op2, operands[2]);
15676 emit_move_insn (op1, operands[1]);
15678 emit_label (label);
15679 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
15680 ix86_emit_fp_unordered_jump (label);
15681 LABEL_NUSES (label) = 1;
15683 emit_move_insn (operands[0], op1);
15687 (define_expand "remainder<mode>3"
15688 [(use (match_operand:MODEF 0 "register_operand"))
15689 (use (match_operand:MODEF 1 "general_operand"))
15690 (use (match_operand:MODEF 2 "general_operand"))]
15691 "TARGET_USE_FANCY_MATH_387
15692 && flag_finite_math_only"
15694 rtx (*gen_truncxf) (rtx, rtx);
15696 rtx_code_label *label = gen_label_rtx ();
15698 rtx op1 = gen_reg_rtx (XFmode);
15699 rtx op2 = gen_reg_rtx (XFmode);
15701 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
15702 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15704 emit_label (label);
15706 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
15707 ix86_emit_fp_unordered_jump (label);
15708 LABEL_NUSES (label) = 1;
15710 /* Truncate the result properly for strict SSE math. */
15711 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15712 && !TARGET_MIX_SSE_I387)
15713 gen_truncxf = gen_truncxf<mode>2;
15715 gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
15717 emit_insn (gen_truncxf (operands[0], op1));
15721 (define_int_iterator SINCOS
15725 (define_int_attr sincos
15726 [(UNSPEC_SIN "sin")
15727 (UNSPEC_COS "cos")])
15729 (define_insn "*<sincos>xf2_i387"
15730 [(set (match_operand:XF 0 "register_operand" "=f")
15731 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15733 "TARGET_USE_FANCY_MATH_387
15734 && flag_unsafe_math_optimizations"
15736 [(set_attr "type" "fpspc")
15737 (set_attr "znver1_decode" "vector")
15738 (set_attr "mode" "XF")])
15740 (define_insn "*<sincos>_extend<mode>xf2_i387"
15741 [(set (match_operand:XF 0 "register_operand" "=f")
15742 (unspec:XF [(float_extend:XF
15743 (match_operand:MODEF 1 "register_operand" "0"))]
15745 "TARGET_USE_FANCY_MATH_387
15746 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15747 || TARGET_MIX_SSE_I387)
15748 && flag_unsafe_math_optimizations"
15750 [(set_attr "type" "fpspc")
15751 (set_attr "znver1_decode" "vector")
15752 (set_attr "mode" "XF")])
15754 ;; When sincos pattern is defined, sin and cos builtin functions will be
15755 ;; expanded to sincos pattern with one of its outputs left unused.
15756 ;; CSE pass will figure out if two sincos patterns can be combined,
15757 ;; otherwise sincos pattern will be split back to sin or cos pattern,
15758 ;; depending on the unused output.
15760 (define_insn "sincosxf3"
15761 [(set (match_operand:XF 0 "register_operand" "=f")
15762 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15763 UNSPEC_SINCOS_COS))
15764 (set (match_operand:XF 1 "register_operand" "=u")
15765 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15766 "TARGET_USE_FANCY_MATH_387
15767 && flag_unsafe_math_optimizations"
15769 [(set_attr "type" "fpspc")
15770 (set_attr "znver1_decode" "vector")
15771 (set_attr "mode" "XF")])
15774 [(set (match_operand:XF 0 "register_operand")
15775 (unspec:XF [(match_operand:XF 2 "register_operand")]
15776 UNSPEC_SINCOS_COS))
15777 (set (match_operand:XF 1 "register_operand")
15778 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15779 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15780 && can_create_pseudo_p ()"
15781 [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))])
15784 [(set (match_operand:XF 0 "register_operand")
15785 (unspec:XF [(match_operand:XF 2 "register_operand")]
15786 UNSPEC_SINCOS_COS))
15787 (set (match_operand:XF 1 "register_operand")
15788 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15789 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15790 && can_create_pseudo_p ()"
15791 [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))])
15793 (define_insn "sincos_extend<mode>xf3_i387"
15794 [(set (match_operand:XF 0 "register_operand" "=f")
15795 (unspec:XF [(float_extend:XF
15796 (match_operand:MODEF 2 "register_operand" "0"))]
15797 UNSPEC_SINCOS_COS))
15798 (set (match_operand:XF 1 "register_operand" "=u")
15799 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
15800 "TARGET_USE_FANCY_MATH_387
15801 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15802 || TARGET_MIX_SSE_I387)
15803 && flag_unsafe_math_optimizations"
15805 [(set_attr "type" "fpspc")
15806 (set_attr "znver1_decode" "vector")
15807 (set_attr "mode" "XF")])
15810 [(set (match_operand:XF 0 "register_operand")
15811 (unspec:XF [(float_extend:XF
15812 (match_operand:MODEF 2 "register_operand"))]
15813 UNSPEC_SINCOS_COS))
15814 (set (match_operand:XF 1 "register_operand")
15815 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
15816 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15817 && can_create_pseudo_p ()"
15818 [(set (match_dup 1)
15819 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))])
15822 [(set (match_operand:XF 0 "register_operand")
15823 (unspec:XF [(float_extend:XF
15824 (match_operand:MODEF 2 "register_operand"))]
15825 UNSPEC_SINCOS_COS))
15826 (set (match_operand:XF 1 "register_operand")
15827 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
15828 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15829 && can_create_pseudo_p ()"
15830 [(set (match_dup 0)
15831 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))])
15833 (define_expand "sincos<mode>3"
15834 [(use (match_operand:MODEF 0 "register_operand"))
15835 (use (match_operand:MODEF 1 "register_operand"))
15836 (use (match_operand:MODEF 2 "register_operand"))]
15837 "TARGET_USE_FANCY_MATH_387
15838 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15839 || TARGET_MIX_SSE_I387)
15840 && flag_unsafe_math_optimizations"
15842 rtx op0 = gen_reg_rtx (XFmode);
15843 rtx op1 = gen_reg_rtx (XFmode);
15845 emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
15846 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15847 emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
15851 (define_insn "fptanxf4_i387"
15852 [(set (match_operand:XF 0 "register_operand" "=f")
15853 (match_operand:XF 3 "const_double_operand" "F"))
15854 (set (match_operand:XF 1 "register_operand" "=u")
15855 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15857 "TARGET_USE_FANCY_MATH_387
15858 && flag_unsafe_math_optimizations
15859 && standard_80387_constant_p (operands[3]) == 2"
15861 [(set_attr "type" "fpspc")
15862 (set_attr "znver1_decode" "vector")
15863 (set_attr "mode" "XF")])
15865 (define_insn "fptan_extend<mode>xf4_i387"
15866 [(set (match_operand:MODEF 0 "register_operand" "=f")
15867 (match_operand:MODEF 3 "const_double_operand" "F"))
15868 (set (match_operand:XF 1 "register_operand" "=u")
15869 (unspec:XF [(float_extend:XF
15870 (match_operand:MODEF 2 "register_operand" "0"))]
15872 "TARGET_USE_FANCY_MATH_387
15873 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15874 || TARGET_MIX_SSE_I387)
15875 && flag_unsafe_math_optimizations
15876 && standard_80387_constant_p (operands[3]) == 2"
15878 [(set_attr "type" "fpspc")
15879 (set_attr "znver1_decode" "vector")
15880 (set_attr "mode" "XF")])
15882 (define_expand "tanxf2"
15883 [(use (match_operand:XF 0 "register_operand"))
15884 (use (match_operand:XF 1 "register_operand"))]
15885 "TARGET_USE_FANCY_MATH_387
15886 && flag_unsafe_math_optimizations"
15888 rtx one = gen_reg_rtx (XFmode);
15889 rtx op2 = CONST1_RTX (XFmode); /* fld1 */
15891 emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2));
15895 (define_expand "tan<mode>2"
15896 [(use (match_operand:MODEF 0 "register_operand"))
15897 (use (match_operand:MODEF 1 "register_operand"))]
15898 "TARGET_USE_FANCY_MATH_387
15899 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15900 || TARGET_MIX_SSE_I387)
15901 && flag_unsafe_math_optimizations"
15903 rtx op0 = gen_reg_rtx (XFmode);
15905 rtx one = gen_reg_rtx (<MODE>mode);
15906 rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */
15908 emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
15909 operands[1], op2));
15910 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15914 (define_insn "*fpatanxf3_i387"
15915 [(set (match_operand:XF 0 "register_operand" "=f")
15916 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
15917 (match_operand:XF 2 "register_operand" "u")]
15919 (clobber (match_scratch:XF 3 "=2"))]
15920 "TARGET_USE_FANCY_MATH_387
15921 && flag_unsafe_math_optimizations"
15923 [(set_attr "type" "fpspc")
15924 (set_attr "znver1_decode" "vector")
15925 (set_attr "mode" "XF")])
15927 (define_insn "fpatan_extend<mode>xf3_i387"
15928 [(set (match_operand:XF 0 "register_operand" "=f")
15929 (unspec:XF [(float_extend:XF
15930 (match_operand:MODEF 1 "register_operand" "0"))
15932 (match_operand:MODEF 2 "register_operand" "u"))]
15934 (clobber (match_scratch:XF 3 "=2"))]
15935 "TARGET_USE_FANCY_MATH_387
15936 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15937 || TARGET_MIX_SSE_I387)
15938 && flag_unsafe_math_optimizations"
15940 [(set_attr "type" "fpspc")
15941 (set_attr "znver1_decode" "vector")
15942 (set_attr "mode" "XF")])
15944 (define_expand "atan2xf3"
15945 [(parallel [(set (match_operand:XF 0 "register_operand")
15946 (unspec:XF [(match_operand:XF 2 "register_operand")
15947 (match_operand:XF 1 "register_operand")]
15949 (clobber (match_scratch:XF 3))])]
15950 "TARGET_USE_FANCY_MATH_387
15951 && flag_unsafe_math_optimizations")
15953 (define_expand "atan2<mode>3"
15954 [(use (match_operand:MODEF 0 "register_operand"))
15955 (use (match_operand:MODEF 1 "register_operand"))
15956 (use (match_operand:MODEF 2 "register_operand"))]
15957 "TARGET_USE_FANCY_MATH_387
15958 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15959 || TARGET_MIX_SSE_I387)
15960 && flag_unsafe_math_optimizations"
15962 rtx op0 = gen_reg_rtx (XFmode);
15964 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
15965 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15969 (define_expand "atanxf2"
15970 [(parallel [(set (match_operand:XF 0 "register_operand")
15971 (unspec:XF [(match_dup 2)
15972 (match_operand:XF 1 "register_operand")]
15974 (clobber (match_scratch:XF 3))])]
15975 "TARGET_USE_FANCY_MATH_387
15976 && flag_unsafe_math_optimizations"
15978 operands[2] = gen_reg_rtx (XFmode);
15979 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
15982 (define_expand "atan<mode>2"
15983 [(use (match_operand:MODEF 0 "register_operand"))
15984 (use (match_operand:MODEF 1 "register_operand"))]
15985 "TARGET_USE_FANCY_MATH_387
15986 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15987 || TARGET_MIX_SSE_I387)
15988 && flag_unsafe_math_optimizations"
15990 rtx op0 = gen_reg_rtx (XFmode);
15992 rtx op2 = gen_reg_rtx (<MODE>mode);
15993 emit_move_insn (op2, CONST1_RTX (<MODE>mode)); /* fld1 */
15995 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1]));
15996 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16000 (define_expand "asinxf2"
16001 [(set (match_dup 2)
16002 (mult:XF (match_operand:XF 1 "register_operand")
16004 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
16005 (set (match_dup 5) (sqrt:XF (match_dup 4)))
16006 (parallel [(set (match_operand:XF 0 "register_operand")
16007 (unspec:XF [(match_dup 5) (match_dup 1)]
16009 (clobber (match_scratch:XF 6))])]
16010 "TARGET_USE_FANCY_MATH_387
16011 && flag_unsafe_math_optimizations"
16015 for (i = 2; i < 6; i++)
16016 operands[i] = gen_reg_rtx (XFmode);
16018 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
16021 (define_expand "asin<mode>2"
16022 [(use (match_operand:MODEF 0 "register_operand"))
16023 (use (match_operand:MODEF 1 "general_operand"))]
16024 "TARGET_USE_FANCY_MATH_387
16025 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16026 || TARGET_MIX_SSE_I387)
16027 && flag_unsafe_math_optimizations"
16029 rtx op0 = gen_reg_rtx (XFmode);
16030 rtx op1 = gen_reg_rtx (XFmode);
16032 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16033 emit_insn (gen_asinxf2 (op0, op1));
16034 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16038 (define_expand "acosxf2"
16039 [(set (match_dup 2)
16040 (mult:XF (match_operand:XF 1 "register_operand")
16042 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
16043 (set (match_dup 5) (sqrt:XF (match_dup 4)))
16044 (parallel [(set (match_operand:XF 0 "register_operand")
16045 (unspec:XF [(match_dup 1) (match_dup 5)]
16047 (clobber (match_scratch:XF 6))])]
16048 "TARGET_USE_FANCY_MATH_387
16049 && flag_unsafe_math_optimizations"
16053 for (i = 2; i < 6; i++)
16054 operands[i] = gen_reg_rtx (XFmode);
16056 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
16059 (define_expand "acos<mode>2"
16060 [(use (match_operand:MODEF 0 "register_operand"))
16061 (use (match_operand:MODEF 1 "general_operand"))]
16062 "TARGET_USE_FANCY_MATH_387
16063 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16064 || TARGET_MIX_SSE_I387)
16065 && flag_unsafe_math_optimizations"
16067 rtx op0 = gen_reg_rtx (XFmode);
16068 rtx op1 = gen_reg_rtx (XFmode);
16070 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16071 emit_insn (gen_acosxf2 (op0, op1));
16072 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16076 (define_insn "fyl2xxf3_i387"
16077 [(set (match_operand:XF 0 "register_operand" "=f")
16078 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
16079 (match_operand:XF 2 "register_operand" "u")]
16081 (clobber (match_scratch:XF 3 "=2"))]
16082 "TARGET_USE_FANCY_MATH_387
16083 && flag_unsafe_math_optimizations"
16085 [(set_attr "type" "fpspc")
16086 (set_attr "znver1_decode" "vector")
16087 (set_attr "mode" "XF")])
16089 (define_insn "fyl2x_extend<mode>xf3_i387"
16090 [(set (match_operand:XF 0 "register_operand" "=f")
16091 (unspec:XF [(float_extend:XF
16092 (match_operand:MODEF 1 "register_operand" "0"))
16093 (match_operand:XF 2 "register_operand" "u")]
16095 (clobber (match_scratch:XF 3 "=2"))]
16096 "TARGET_USE_FANCY_MATH_387
16097 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16098 || TARGET_MIX_SSE_I387)
16099 && flag_unsafe_math_optimizations"
16101 [(set_attr "type" "fpspc")
16102 (set_attr "znver1_decode" "vector")
16103 (set_attr "mode" "XF")])
16105 (define_expand "logxf2"
16106 [(parallel [(set (match_operand:XF 0 "register_operand")
16107 (unspec:XF [(match_operand:XF 1 "register_operand")
16108 (match_dup 2)] UNSPEC_FYL2X))
16109 (clobber (match_scratch:XF 3))])]
16110 "TARGET_USE_FANCY_MATH_387
16111 && flag_unsafe_math_optimizations"
16113 operands[2] = gen_reg_rtx (XFmode);
16114 emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */
16117 (define_expand "log<mode>2"
16118 [(use (match_operand:MODEF 0 "register_operand"))
16119 (use (match_operand:MODEF 1 "register_operand"))]
16120 "TARGET_USE_FANCY_MATH_387
16121 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16122 || TARGET_MIX_SSE_I387)
16123 && flag_unsafe_math_optimizations"
16125 rtx op0 = gen_reg_rtx (XFmode);
16127 rtx op2 = gen_reg_rtx (XFmode);
16128 emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */
16130 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
16131 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16135 (define_expand "log10xf2"
16136 [(parallel [(set (match_operand:XF 0 "register_operand")
16137 (unspec:XF [(match_operand:XF 1 "register_operand")
16138 (match_dup 2)] UNSPEC_FYL2X))
16139 (clobber (match_scratch:XF 3))])]
16140 "TARGET_USE_FANCY_MATH_387
16141 && flag_unsafe_math_optimizations"
16143 operands[2] = gen_reg_rtx (XFmode);
16144 emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
16147 (define_expand "log10<mode>2"
16148 [(use (match_operand:MODEF 0 "register_operand"))
16149 (use (match_operand:MODEF 1 "register_operand"))]
16150 "TARGET_USE_FANCY_MATH_387
16151 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16152 || TARGET_MIX_SSE_I387)
16153 && flag_unsafe_math_optimizations"
16155 rtx op0 = gen_reg_rtx (XFmode);
16157 rtx op2 = gen_reg_rtx (XFmode);
16158 emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */
16160 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
16161 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16165 (define_expand "log2xf2"
16166 [(parallel [(set (match_operand:XF 0 "register_operand")
16167 (unspec:XF [(match_operand:XF 1 "register_operand")
16168 (match_dup 2)] UNSPEC_FYL2X))
16169 (clobber (match_scratch:XF 3))])]
16170 "TARGET_USE_FANCY_MATH_387
16171 && flag_unsafe_math_optimizations"
16173 operands[2] = gen_reg_rtx (XFmode);
16174 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
16177 (define_expand "log2<mode>2"
16178 [(use (match_operand:MODEF 0 "register_operand"))
16179 (use (match_operand:MODEF 1 "register_operand"))]
16180 "TARGET_USE_FANCY_MATH_387
16181 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16182 || TARGET_MIX_SSE_I387)
16183 && flag_unsafe_math_optimizations"
16185 rtx op0 = gen_reg_rtx (XFmode);
16187 rtx op2 = gen_reg_rtx (XFmode);
16188 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
16190 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
16191 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16195 (define_insn "fyl2xp1xf3_i387"
16196 [(set (match_operand:XF 0 "register_operand" "=f")
16197 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
16198 (match_operand:XF 2 "register_operand" "u")]
16200 (clobber (match_scratch:XF 3 "=2"))]
16201 "TARGET_USE_FANCY_MATH_387
16202 && flag_unsafe_math_optimizations"
16204 [(set_attr "type" "fpspc")
16205 (set_attr "znver1_decode" "vector")
16206 (set_attr "mode" "XF")])
16208 (define_insn "fyl2xp1_extend<mode>xf3_i387"
16209 [(set (match_operand:XF 0 "register_operand" "=f")
16210 (unspec:XF [(float_extend:XF
16211 (match_operand:MODEF 1 "register_operand" "0"))
16212 (match_operand:XF 2 "register_operand" "u")]
16214 (clobber (match_scratch:XF 3 "=2"))]
16215 "TARGET_USE_FANCY_MATH_387
16216 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16217 || TARGET_MIX_SSE_I387)
16218 && flag_unsafe_math_optimizations"
16220 [(set_attr "type" "fpspc")
16221 (set_attr "znver1_decode" "vector")
16222 (set_attr "mode" "XF")])
16224 (define_expand "log1pxf2"
16225 [(use (match_operand:XF 0 "register_operand"))
16226 (use (match_operand:XF 1 "register_operand"))]
16227 "TARGET_USE_FANCY_MATH_387
16228 && flag_unsafe_math_optimizations"
16230 ix86_emit_i387_log1p (operands[0], operands[1]);
16234 (define_expand "log1p<mode>2"
16235 [(use (match_operand:MODEF 0 "register_operand"))
16236 (use (match_operand:MODEF 1 "register_operand"))]
16237 "TARGET_USE_FANCY_MATH_387
16238 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16239 || TARGET_MIX_SSE_I387)
16240 && flag_unsafe_math_optimizations"
16244 op0 = gen_reg_rtx (XFmode);
16246 operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
16248 ix86_emit_i387_log1p (op0, operands[1]);
16249 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16253 (define_insn "fxtractxf3_i387"
16254 [(set (match_operand:XF 0 "register_operand" "=f")
16255 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16256 UNSPEC_XTRACT_FRACT))
16257 (set (match_operand:XF 1 "register_operand" "=u")
16258 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
16259 "TARGET_USE_FANCY_MATH_387
16260 && flag_unsafe_math_optimizations"
16262 [(set_attr "type" "fpspc")
16263 (set_attr "znver1_decode" "vector")
16264 (set_attr "mode" "XF")])
16266 (define_insn "fxtract_extend<mode>xf3_i387"
16267 [(set (match_operand:XF 0 "register_operand" "=f")
16268 (unspec:XF [(float_extend:XF
16269 (match_operand:MODEF 2 "register_operand" "0"))]
16270 UNSPEC_XTRACT_FRACT))
16271 (set (match_operand:XF 1 "register_operand" "=u")
16272 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
16273 "TARGET_USE_FANCY_MATH_387
16274 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16275 || TARGET_MIX_SSE_I387)
16276 && flag_unsafe_math_optimizations"
16278 [(set_attr "type" "fpspc")
16279 (set_attr "znver1_decode" "vector")
16280 (set_attr "mode" "XF")])
16282 (define_expand "logbxf2"
16283 [(parallel [(set (match_dup 2)
16284 (unspec:XF [(match_operand:XF 1 "register_operand")]
16285 UNSPEC_XTRACT_FRACT))
16286 (set (match_operand:XF 0 "register_operand")
16287 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
16288 "TARGET_USE_FANCY_MATH_387
16289 && flag_unsafe_math_optimizations"
16290 "operands[2] = gen_reg_rtx (XFmode);")
16292 (define_expand "logb<mode>2"
16293 [(use (match_operand:MODEF 0 "register_operand"))
16294 (use (match_operand:MODEF 1 "register_operand"))]
16295 "TARGET_USE_FANCY_MATH_387
16296 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16297 || TARGET_MIX_SSE_I387)
16298 && flag_unsafe_math_optimizations"
16300 rtx op0 = gen_reg_rtx (XFmode);
16301 rtx op1 = gen_reg_rtx (XFmode);
16303 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
16304 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1));
16308 (define_expand "ilogbxf2"
16309 [(use (match_operand:SI 0 "register_operand"))
16310 (use (match_operand:XF 1 "register_operand"))]
16311 "TARGET_USE_FANCY_MATH_387
16312 && flag_unsafe_math_optimizations"
16316 if (optimize_insn_for_size_p ())
16319 op0 = gen_reg_rtx (XFmode);
16320 op1 = gen_reg_rtx (XFmode);
16322 emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
16323 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
16327 (define_expand "ilogb<mode>2"
16328 [(use (match_operand:SI 0 "register_operand"))
16329 (use (match_operand:MODEF 1 "register_operand"))]
16330 "TARGET_USE_FANCY_MATH_387
16331 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16332 || TARGET_MIX_SSE_I387)
16333 && flag_unsafe_math_optimizations"
16337 if (optimize_insn_for_size_p ())
16340 op0 = gen_reg_rtx (XFmode);
16341 op1 = gen_reg_rtx (XFmode);
16343 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
16344 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
16348 (define_insn "*f2xm1xf2_i387"
16349 [(set (match_operand:XF 0 "register_operand" "=f")
16350 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16352 "TARGET_USE_FANCY_MATH_387
16353 && flag_unsafe_math_optimizations"
16355 [(set_attr "type" "fpspc")
16356 (set_attr "znver1_decode" "vector")
16357 (set_attr "mode" "XF")])
16359 (define_insn "fscalexf4_i387"
16360 [(set (match_operand:XF 0 "register_operand" "=f")
16361 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16362 (match_operand:XF 3 "register_operand" "1")]
16363 UNSPEC_FSCALE_FRACT))
16364 (set (match_operand:XF 1 "register_operand" "=u")
16365 (unspec:XF [(match_dup 2) (match_dup 3)]
16366 UNSPEC_FSCALE_EXP))]
16367 "TARGET_USE_FANCY_MATH_387
16368 && flag_unsafe_math_optimizations"
16370 [(set_attr "type" "fpspc")
16371 (set_attr "znver1_decode" "vector")
16372 (set_attr "mode" "XF")])
16374 (define_expand "expNcorexf3"
16375 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand")
16376 (match_operand:XF 2 "register_operand")))
16377 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16378 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16379 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16380 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
16381 (parallel [(set (match_operand:XF 0 "register_operand")
16382 (unspec:XF [(match_dup 8) (match_dup 4)]
16383 UNSPEC_FSCALE_FRACT))
16385 (unspec:XF [(match_dup 8) (match_dup 4)]
16386 UNSPEC_FSCALE_EXP))])]
16387 "TARGET_USE_FANCY_MATH_387
16388 && flag_unsafe_math_optimizations"
16392 for (i = 3; i < 10; i++)
16393 operands[i] = gen_reg_rtx (XFmode);
16395 emit_move_insn (operands[7], CONST1_RTX (XFmode)); /* fld1 */
16398 (define_expand "expxf2"
16399 [(use (match_operand:XF 0 "register_operand"))
16400 (use (match_operand:XF 1 "register_operand"))]
16401 "TARGET_USE_FANCY_MATH_387
16402 && flag_unsafe_math_optimizations"
16406 op2 = gen_reg_rtx (XFmode);
16407 emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */
16409 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
16413 (define_expand "exp<mode>2"
16414 [(use (match_operand:MODEF 0 "register_operand"))
16415 (use (match_operand:MODEF 1 "general_operand"))]
16416 "TARGET_USE_FANCY_MATH_387
16417 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16418 || TARGET_MIX_SSE_I387)
16419 && flag_unsafe_math_optimizations"
16423 op0 = gen_reg_rtx (XFmode);
16424 op1 = gen_reg_rtx (XFmode);
16426 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16427 emit_insn (gen_expxf2 (op0, op1));
16428 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16432 (define_expand "exp10xf2"
16433 [(use (match_operand:XF 0 "register_operand"))
16434 (use (match_operand:XF 1 "register_operand"))]
16435 "TARGET_USE_FANCY_MATH_387
16436 && flag_unsafe_math_optimizations"
16440 op2 = gen_reg_rtx (XFmode);
16441 emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */
16443 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
16447 (define_expand "exp10<mode>2"
16448 [(use (match_operand:MODEF 0 "register_operand"))
16449 (use (match_operand:MODEF 1 "general_operand"))]
16450 "TARGET_USE_FANCY_MATH_387
16451 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16452 || TARGET_MIX_SSE_I387)
16453 && flag_unsafe_math_optimizations"
16457 op0 = gen_reg_rtx (XFmode);
16458 op1 = gen_reg_rtx (XFmode);
16460 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16461 emit_insn (gen_exp10xf2 (op0, op1));
16462 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16466 (define_expand "exp2xf2"
16467 [(use (match_operand:XF 0 "register_operand"))
16468 (use (match_operand:XF 1 "register_operand"))]
16469 "TARGET_USE_FANCY_MATH_387
16470 && flag_unsafe_math_optimizations"
16474 op2 = gen_reg_rtx (XFmode);
16475 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
16477 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
16481 (define_expand "exp2<mode>2"
16482 [(use (match_operand:MODEF 0 "register_operand"))
16483 (use (match_operand:MODEF 1 "general_operand"))]
16484 "TARGET_USE_FANCY_MATH_387
16485 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16486 || TARGET_MIX_SSE_I387)
16487 && flag_unsafe_math_optimizations"
16491 op0 = gen_reg_rtx (XFmode);
16492 op1 = gen_reg_rtx (XFmode);
16494 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16495 emit_insn (gen_exp2xf2 (op0, op1));
16496 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16500 (define_expand "expm1xf2"
16501 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand")
16503 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16504 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16505 (set (match_dup 9) (float_extend:XF (match_dup 13)))
16506 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16507 (parallel [(set (match_dup 7)
16508 (unspec:XF [(match_dup 6) (match_dup 4)]
16509 UNSPEC_FSCALE_FRACT))
16511 (unspec:XF [(match_dup 6) (match_dup 4)]
16512 UNSPEC_FSCALE_EXP))])
16513 (parallel [(set (match_dup 10)
16514 (unspec:XF [(match_dup 9) (match_dup 8)]
16515 UNSPEC_FSCALE_FRACT))
16516 (set (match_dup 11)
16517 (unspec:XF [(match_dup 9) (match_dup 8)]
16518 UNSPEC_FSCALE_EXP))])
16519 (set (match_dup 12) (minus:XF (match_dup 10)
16520 (float_extend:XF (match_dup 13))))
16521 (set (match_operand:XF 0 "register_operand")
16522 (plus:XF (match_dup 12) (match_dup 7)))]
16523 "TARGET_USE_FANCY_MATH_387
16524 && flag_unsafe_math_optimizations"
16528 for (i = 2; i < 13; i++)
16529 operands[i] = gen_reg_rtx (XFmode);
16532 = validize_mem (force_const_mem (SFmode, CONST1_RTX (SFmode))); /* fld1 */
16534 emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
16537 (define_expand "expm1<mode>2"
16538 [(use (match_operand:MODEF 0 "register_operand"))
16539 (use (match_operand:MODEF 1 "general_operand"))]
16540 "TARGET_USE_FANCY_MATH_387
16541 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16542 || TARGET_MIX_SSE_I387)
16543 && flag_unsafe_math_optimizations"
16547 op0 = gen_reg_rtx (XFmode);
16548 op1 = gen_reg_rtx (XFmode);
16550 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16551 emit_insn (gen_expm1xf2 (op0, op1));
16552 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16556 (define_expand "ldexpxf3"
16557 [(match_operand:XF 0 "register_operand")
16558 (match_operand:XF 1 "register_operand")
16559 (match_operand:SI 2 "register_operand")]
16560 "TARGET_USE_FANCY_MATH_387
16561 && flag_unsafe_math_optimizations"
16565 tmp1 = gen_reg_rtx (XFmode);
16566 tmp2 = gen_reg_rtx (XFmode);
16568 emit_insn (gen_floatsixf2 (tmp1, operands[2]));
16569 emit_insn (gen_fscalexf4_i387 (operands[0], tmp2,
16570 operands[1], tmp1));
16574 (define_expand "ldexp<mode>3"
16575 [(use (match_operand:MODEF 0 "register_operand"))
16576 (use (match_operand:MODEF 1 "general_operand"))
16577 (use (match_operand:SI 2 "register_operand"))]
16578 "TARGET_USE_FANCY_MATH_387
16579 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16580 || TARGET_MIX_SSE_I387)
16581 && flag_unsafe_math_optimizations"
16585 op0 = gen_reg_rtx (XFmode);
16586 op1 = gen_reg_rtx (XFmode);
16588 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16589 emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
16590 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16594 (define_expand "scalbxf3"
16595 [(parallel [(set (match_operand:XF 0 " register_operand")
16596 (unspec:XF [(match_operand:XF 1 "register_operand")
16597 (match_operand:XF 2 "register_operand")]
16598 UNSPEC_FSCALE_FRACT))
16600 (unspec:XF [(match_dup 1) (match_dup 2)]
16601 UNSPEC_FSCALE_EXP))])]
16602 "TARGET_USE_FANCY_MATH_387
16603 && flag_unsafe_math_optimizations"
16605 operands[3] = gen_reg_rtx (XFmode);
16608 (define_expand "scalb<mode>3"
16609 [(use (match_operand:MODEF 0 "register_operand"))
16610 (use (match_operand:MODEF 1 "general_operand"))
16611 (use (match_operand:MODEF 2 "general_operand"))]
16612 "TARGET_USE_FANCY_MATH_387
16613 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16614 || TARGET_MIX_SSE_I387)
16615 && flag_unsafe_math_optimizations"
16619 op0 = gen_reg_rtx (XFmode);
16620 op1 = gen_reg_rtx (XFmode);
16621 op2 = gen_reg_rtx (XFmode);
16623 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16624 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
16625 emit_insn (gen_scalbxf3 (op0, op1, op2));
16626 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16630 (define_expand "significandxf2"
16631 [(parallel [(set (match_operand:XF 0 "register_operand")
16632 (unspec:XF [(match_operand:XF 1 "register_operand")]
16633 UNSPEC_XTRACT_FRACT))
16635 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
16636 "TARGET_USE_FANCY_MATH_387
16637 && flag_unsafe_math_optimizations"
16638 "operands[2] = gen_reg_rtx (XFmode);")
16640 (define_expand "significand<mode>2"
16641 [(use (match_operand:MODEF 0 "register_operand"))
16642 (use (match_operand:MODEF 1 "register_operand"))]
16643 "TARGET_USE_FANCY_MATH_387
16644 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16645 || TARGET_MIX_SSE_I387)
16646 && flag_unsafe_math_optimizations"
16648 rtx op0 = gen_reg_rtx (XFmode);
16649 rtx op1 = gen_reg_rtx (XFmode);
16651 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
16652 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16657 (define_insn "sse4_1_round<mode>2"
16658 [(set (match_operand:MODEF 0 "register_operand" "=x,v")
16659 (unspec:MODEF [(match_operand:MODEF 1 "nonimmediate_operand" "xm,vm")
16660 (match_operand:SI 2 "const_0_to_15_operand" "n,n")]
16664 %vround<ssemodesuffix>\t{%2, %1, %d0|%d0, %1, %2}
16665 vrndscale<ssemodesuffix>\t{%2, %1, %d0|%d0, %1, %2}"
16666 [(set_attr "type" "ssecvt")
16667 (set_attr "prefix_extra" "1,*")
16668 (set_attr "length_immediate" "*,1")
16669 (set_attr "prefix" "maybe_vex,evex")
16670 (set_attr "isa" "noavx512f,avx512f")
16671 (set_attr "mode" "<MODE>")])
16673 (define_insn "rintxf2"
16674 [(set (match_operand:XF 0 "register_operand" "=f")
16675 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16677 "TARGET_USE_FANCY_MATH_387"
16679 [(set_attr "type" "fpspc")
16680 (set_attr "znver1_decode" "vector")
16681 (set_attr "mode" "XF")])
16683 (define_insn "rint<mode>2_frndint"
16684 [(set (match_operand:MODEF 0 "register_operand" "=f")
16685 (unspec:MODEF [(match_operand:MODEF 1 "register_operand" "0")]
16687 "TARGET_USE_FANCY_MATH_387"
16689 [(set_attr "type" "fpspc")
16690 (set_attr "znver1_decode" "vector")
16691 (set_attr "mode" "<MODE>")])
16693 (define_expand "rint<mode>2"
16694 [(use (match_operand:MODEF 0 "register_operand"))
16695 (use (match_operand:MODEF 1 "register_operand"))]
16696 "(TARGET_USE_FANCY_MATH_387
16697 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16698 || TARGET_MIX_SSE_I387))
16699 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
16701 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16704 emit_insn (gen_sse4_1_round<mode>2
16705 (operands[0], operands[1], GEN_INT (ROUND_MXCSR)));
16707 ix86_expand_rint (operands[0], operands[1]);
16710 emit_insn (gen_rint<mode>2_frndint (operands[0], operands[1]));
16714 (define_expand "round<mode>2"
16715 [(match_operand:X87MODEF 0 "register_operand")
16716 (match_operand:X87MODEF 1 "nonimmediate_operand")]
16717 "(TARGET_USE_FANCY_MATH_387
16718 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16719 || TARGET_MIX_SSE_I387)
16720 && flag_unsafe_math_optimizations
16721 && (flag_fp_int_builtin_inexact || !flag_trapping_math))
16722 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16723 && !flag_trapping_math && !flag_rounding_math)"
16725 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16726 && !flag_trapping_math && !flag_rounding_math)
16730 operands[1] = force_reg (<MODE>mode, operands[1]);
16731 ix86_expand_round_sse4 (operands[0], operands[1]);
16733 else if (TARGET_64BIT || (<MODE>mode != DFmode))
16734 ix86_expand_round (operands[0], operands[1]);
16736 ix86_expand_rounddf_32 (operands[0], operands[1]);
16740 operands[1] = force_reg (<MODE>mode, operands[1]);
16741 ix86_emit_i387_round (operands[0], operands[1]);
16746 (define_insn_and_split "*fistdi2_1"
16747 [(set (match_operand:DI 0 "nonimmediate_operand")
16748 (unspec:DI [(match_operand:XF 1 "register_operand")]
16750 "TARGET_USE_FANCY_MATH_387
16751 && can_create_pseudo_p ()"
16756 if (memory_operand (operands[0], VOIDmode))
16757 emit_insn (gen_fistdi2 (operands[0], operands[1]));
16760 operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
16761 emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
16766 [(set_attr "type" "fpspc")
16767 (set_attr "mode" "DI")])
16769 (define_insn "fistdi2"
16770 [(set (match_operand:DI 0 "memory_operand" "=m")
16771 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
16773 (clobber (match_scratch:XF 2 "=&1f"))]
16774 "TARGET_USE_FANCY_MATH_387"
16775 "* return output_fix_trunc (insn, operands, false);"
16776 [(set_attr "type" "fpspc")
16777 (set_attr "mode" "DI")])
16779 (define_insn "fistdi2_with_temp"
16780 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
16781 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
16783 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))
16784 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
16785 "TARGET_USE_FANCY_MATH_387"
16787 [(set_attr "type" "fpspc")
16788 (set_attr "mode" "DI")])
16791 [(set (match_operand:DI 0 "register_operand")
16792 (unspec:DI [(match_operand:XF 1 "register_operand")]
16794 (clobber (match_operand:DI 2 "memory_operand"))
16795 (clobber (match_scratch 3))]
16797 [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
16798 (clobber (match_dup 3))])
16799 (set (match_dup 0) (match_dup 2))])
16802 [(set (match_operand:DI 0 "memory_operand")
16803 (unspec:DI [(match_operand:XF 1 "register_operand")]
16805 (clobber (match_operand:DI 2 "memory_operand"))
16806 (clobber (match_scratch 3))]
16808 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
16809 (clobber (match_dup 3))])])
16811 (define_insn_and_split "*fist<mode>2_1"
16812 [(set (match_operand:SWI24 0 "register_operand")
16813 (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
16815 "TARGET_USE_FANCY_MATH_387
16816 && can_create_pseudo_p ()"
16821 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
16822 emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
16826 [(set_attr "type" "fpspc")
16827 (set_attr "mode" "<MODE>")])
16829 (define_insn "fist<mode>2"
16830 [(set (match_operand:SWI24 0 "memory_operand" "=m")
16831 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
16833 "TARGET_USE_FANCY_MATH_387"
16834 "* return output_fix_trunc (insn, operands, false);"
16835 [(set_attr "type" "fpspc")
16836 (set_attr "mode" "<MODE>")])
16838 (define_insn "fist<mode>2_with_temp"
16839 [(set (match_operand:SWI24 0 "register_operand" "=r")
16840 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
16842 (clobber (match_operand:SWI24 2 "memory_operand" "=m"))]
16843 "TARGET_USE_FANCY_MATH_387"
16845 [(set_attr "type" "fpspc")
16846 (set_attr "mode" "<MODE>")])
16849 [(set (match_operand:SWI24 0 "register_operand")
16850 (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
16852 (clobber (match_operand:SWI24 2 "memory_operand"))]
16854 [(set (match_dup 2) (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST))
16855 (set (match_dup 0) (match_dup 2))])
16858 [(set (match_operand:SWI24 0 "memory_operand")
16859 (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
16861 (clobber (match_operand:SWI24 2 "memory_operand"))]
16863 [(set (match_dup 0) (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST))])
16865 (define_expand "lrintxf<mode>2"
16866 [(set (match_operand:SWI248x 0 "nonimmediate_operand")
16867 (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
16869 "TARGET_USE_FANCY_MATH_387")
16871 (define_expand "lrint<MODEF:mode><SWI48:mode>2"
16872 [(set (match_operand:SWI48 0 "nonimmediate_operand")
16873 (unspec:SWI48 [(match_operand:MODEF 1 "register_operand")]
16874 UNSPEC_FIX_NOTRUNC))]
16875 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH")
16877 (define_expand "lround<X87MODEF:mode><SWI248x:mode>2"
16878 [(match_operand:SWI248x 0 "nonimmediate_operand")
16879 (match_operand:X87MODEF 1 "register_operand")]
16880 "(TARGET_USE_FANCY_MATH_387
16881 && (!(SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
16882 || TARGET_MIX_SSE_I387)
16883 && flag_unsafe_math_optimizations)
16884 || (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
16885 && <SWI248x:MODE>mode != HImode
16886 && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT)
16887 && !flag_trapping_math && !flag_rounding_math)"
16889 if (optimize_insn_for_size_p ())
16892 if (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
16893 && <SWI248x:MODE>mode != HImode
16894 && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT)
16895 && !flag_trapping_math && !flag_rounding_math)
16896 ix86_expand_lround (operands[0], operands[1]);
16898 ix86_emit_i387_round (operands[0], operands[1]);
16902 (define_int_iterator FRNDINT_ROUNDING
16903 [UNSPEC_FRNDINT_FLOOR
16904 UNSPEC_FRNDINT_CEIL
16905 UNSPEC_FRNDINT_TRUNC])
16907 (define_int_iterator FIST_ROUNDING
16911 ;; Base name for define_insn
16912 (define_int_attr rounding_insn
16913 [(UNSPEC_FRNDINT_FLOOR "floor")
16914 (UNSPEC_FRNDINT_CEIL "ceil")
16915 (UNSPEC_FRNDINT_TRUNC "btrunc")
16916 (UNSPEC_FIST_FLOOR "floor")
16917 (UNSPEC_FIST_CEIL "ceil")])
16919 (define_int_attr rounding
16920 [(UNSPEC_FRNDINT_FLOOR "floor")
16921 (UNSPEC_FRNDINT_CEIL "ceil")
16922 (UNSPEC_FRNDINT_TRUNC "trunc")
16923 (UNSPEC_FIST_FLOOR "floor")
16924 (UNSPEC_FIST_CEIL "ceil")])
16926 (define_int_attr ROUNDING
16927 [(UNSPEC_FRNDINT_FLOOR "FLOOR")
16928 (UNSPEC_FRNDINT_CEIL "CEIL")
16929 (UNSPEC_FRNDINT_TRUNC "TRUNC")
16930 (UNSPEC_FIST_FLOOR "FLOOR")
16931 (UNSPEC_FIST_CEIL "CEIL")])
16933 ;; Rounding mode control word calculation could clobber FLAGS_REG.
16934 (define_insn_and_split "frndint<mode>2_<rounding>"
16935 [(set (match_operand:X87MODEF 0 "register_operand")
16936 (unspec:X87MODEF [(match_operand:X87MODEF 1 "register_operand")]
16938 (clobber (reg:CC FLAGS_REG))]
16939 "TARGET_USE_FANCY_MATH_387
16940 && (flag_fp_int_builtin_inexact || !flag_trapping_math)
16941 && can_create_pseudo_p ()"
16946 ix86_optimize_mode_switching[I387_<ROUNDING>] = 1;
16948 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
16949 operands[3] = assign_386_stack_local (HImode, SLOT_CW_<ROUNDING>);
16951 emit_insn (gen_frndint<mode>2_<rounding>_i387 (operands[0], operands[1],
16952 operands[2], operands[3]));
16955 [(set_attr "type" "frndint")
16956 (set_attr "i387_cw" "<rounding>")
16957 (set_attr "mode" "<MODE>")])
16959 (define_insn "frndint<mode>2_<rounding>_i387"
16960 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
16961 (unspec:X87MODEF [(match_operand:X87MODEF 1 "register_operand" "0")]
16963 (use (match_operand:HI 2 "memory_operand" "m"))
16964 (use (match_operand:HI 3 "memory_operand" "m"))]
16965 "TARGET_USE_FANCY_MATH_387
16966 && (flag_fp_int_builtin_inexact || !flag_trapping_math)"
16967 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
16968 [(set_attr "type" "frndint")
16969 (set_attr "i387_cw" "<rounding>")
16970 (set_attr "mode" "<MODE>")])
16972 (define_expand "<rounding_insn>xf2"
16973 [(parallel [(set (match_operand:XF 0 "register_operand")
16974 (unspec:XF [(match_operand:XF 1 "register_operand")]
16976 (clobber (reg:CC FLAGS_REG))])]
16977 "TARGET_USE_FANCY_MATH_387
16978 && (flag_fp_int_builtin_inexact || !flag_trapping_math)")
16980 (define_expand "<rounding_insn><mode>2"
16981 [(parallel [(set (match_operand:MODEF 0 "register_operand")
16982 (unspec:MODEF [(match_operand:MODEF 1 "register_operand")]
16984 (clobber (reg:CC FLAGS_REG))])]
16985 "(TARGET_USE_FANCY_MATH_387
16986 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16987 || TARGET_MIX_SSE_I387)
16988 && (flag_fp_int_builtin_inexact || !flag_trapping_math))
16989 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16990 && (TARGET_SSE4_1 || !flag_trapping_math
16991 || flag_fp_int_builtin_inexact))"
16993 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16994 && (TARGET_SSE4_1 || !flag_trapping_math || flag_fp_int_builtin_inexact))
16997 emit_insn (gen_sse4_1_round<mode>2
16998 (operands[0], operands[1], GEN_INT (ROUND_<ROUNDING>
17000 else if (TARGET_64BIT || (<MODE>mode != DFmode))
17002 if (ROUND_<ROUNDING> == ROUND_FLOOR)
17003 ix86_expand_floorceil (operands[0], operands[1], true);
17004 else if (ROUND_<ROUNDING> == ROUND_CEIL)
17005 ix86_expand_floorceil (operands[0], operands[1], false);
17006 else if (ROUND_<ROUNDING> == ROUND_TRUNC)
17007 ix86_expand_trunc (operands[0], operands[1]);
17009 gcc_unreachable ();
17013 if (ROUND_<ROUNDING> == ROUND_FLOOR)
17014 ix86_expand_floorceildf_32 (operands[0], operands[1], true);
17015 else if (ROUND_<ROUNDING> == ROUND_CEIL)
17016 ix86_expand_floorceildf_32 (operands[0], operands[1], false);
17017 else if (ROUND_<ROUNDING> == ROUND_TRUNC)
17018 ix86_expand_truncdf_32 (operands[0], operands[1]);
17020 gcc_unreachable ();
17024 emit_insn (gen_frndint<mode>2_<rounding> (operands[0], operands[1]));
17028 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17029 (define_insn_and_split "frndintxf2_mask_pm"
17030 [(set (match_operand:XF 0 "register_operand")
17031 (unspec:XF [(match_operand:XF 1 "register_operand")]
17032 UNSPEC_FRNDINT_MASK_PM))
17033 (clobber (reg:CC FLAGS_REG))]
17034 "TARGET_USE_FANCY_MATH_387
17035 && flag_unsafe_math_optimizations
17036 && can_create_pseudo_p ()"
17041 ix86_optimize_mode_switching[I387_MASK_PM] = 1;
17043 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17044 operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
17046 emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
17047 operands[2], operands[3]));
17050 [(set_attr "type" "frndint")
17051 (set_attr "i387_cw" "mask_pm")
17052 (set_attr "mode" "XF")])
17054 (define_insn "frndintxf2_mask_pm_i387"
17055 [(set (match_operand:XF 0 "register_operand" "=f")
17056 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17057 UNSPEC_FRNDINT_MASK_PM))
17058 (use (match_operand:HI 2 "memory_operand" "m"))
17059 (use (match_operand:HI 3 "memory_operand" "m"))]
17060 "TARGET_USE_FANCY_MATH_387
17061 && flag_unsafe_math_optimizations"
17062 "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
17063 [(set_attr "type" "frndint")
17064 (set_attr "i387_cw" "mask_pm")
17065 (set_attr "mode" "XF")])
17067 (define_expand "nearbyintxf2"
17068 [(parallel [(set (match_operand:XF 0 "register_operand")
17069 (unspec:XF [(match_operand:XF 1 "register_operand")]
17070 UNSPEC_FRNDINT_MASK_PM))
17071 (clobber (reg:CC FLAGS_REG))])]
17072 "TARGET_USE_FANCY_MATH_387
17073 && flag_unsafe_math_optimizations")
17075 (define_expand "nearbyint<mode>2"
17076 [(use (match_operand:MODEF 0 "register_operand"))
17077 (use (match_operand:MODEF 1 "register_operand"))]
17078 "TARGET_USE_FANCY_MATH_387
17079 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17080 || TARGET_MIX_SSE_I387)
17081 && flag_unsafe_math_optimizations"
17083 rtx op0 = gen_reg_rtx (XFmode);
17084 rtx op1 = gen_reg_rtx (XFmode);
17086 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17087 emit_insn (gen_frndintxf2_mask_pm (op0, op1));
17089 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17093 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17094 (define_insn_and_split "*fist<mode>2_<rounding>_1"
17095 [(set (match_operand:SWI248x 0 "nonimmediate_operand")
17096 (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
17098 (clobber (reg:CC FLAGS_REG))]
17099 "TARGET_USE_FANCY_MATH_387
17100 && flag_unsafe_math_optimizations
17101 && can_create_pseudo_p ()"
17106 ix86_optimize_mode_switching[I387_<ROUNDING>] = 1;
17108 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17109 operands[3] = assign_386_stack_local (HImode, SLOT_CW_<ROUNDING>);
17110 if (memory_operand (operands[0], VOIDmode))
17111 emit_insn (gen_fist<mode>2_<rounding> (operands[0], operands[1],
17112 operands[2], operands[3]));
17115 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17116 emit_insn (gen_fist<mode>2_<rounding>_with_temp
17117 (operands[0], operands[1], operands[2],
17118 operands[3], operands[4]));
17122 [(set_attr "type" "fistp")
17123 (set_attr "i387_cw" "<rounding>")
17124 (set_attr "mode" "<MODE>")])
17126 (define_insn "fistdi2_<rounding>"
17127 [(set (match_operand:DI 0 "memory_operand" "=m")
17128 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17130 (use (match_operand:HI 2 "memory_operand" "m"))
17131 (use (match_operand:HI 3 "memory_operand" "m"))
17132 (clobber (match_scratch:XF 4 "=&1f"))]
17133 "TARGET_USE_FANCY_MATH_387
17134 && flag_unsafe_math_optimizations"
17135 "* return output_fix_trunc (insn, operands, false);"
17136 [(set_attr "type" "fistp")
17137 (set_attr "i387_cw" "<rounding>")
17138 (set_attr "mode" "DI")])
17140 (define_insn "fistdi2_<rounding>_with_temp"
17141 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17142 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17144 (use (match_operand:HI 2 "memory_operand" "m,m"))
17145 (use (match_operand:HI 3 "memory_operand" "m,m"))
17146 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
17147 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
17148 "TARGET_USE_FANCY_MATH_387
17149 && flag_unsafe_math_optimizations"
17151 [(set_attr "type" "fistp")
17152 (set_attr "i387_cw" "<rounding>")
17153 (set_attr "mode" "DI")])
17156 [(set (match_operand:DI 0 "register_operand")
17157 (unspec:DI [(match_operand:XF 1 "register_operand")]
17159 (use (match_operand:HI 2 "memory_operand"))
17160 (use (match_operand:HI 3 "memory_operand"))
17161 (clobber (match_operand:DI 4 "memory_operand"))
17162 (clobber (match_scratch 5))]
17164 [(parallel [(set (match_dup 4)
17165 (unspec:DI [(match_dup 1)] FIST_ROUNDING))
17166 (use (match_dup 2))
17167 (use (match_dup 3))
17168 (clobber (match_dup 5))])
17169 (set (match_dup 0) (match_dup 4))])
17172 [(set (match_operand:DI 0 "memory_operand")
17173 (unspec:DI [(match_operand:XF 1 "register_operand")]
17175 (use (match_operand:HI 2 "memory_operand"))
17176 (use (match_operand:HI 3 "memory_operand"))
17177 (clobber (match_operand:DI 4 "memory_operand"))
17178 (clobber (match_scratch 5))]
17180 [(parallel [(set (match_dup 0)
17181 (unspec:DI [(match_dup 1)] FIST_ROUNDING))
17182 (use (match_dup 2))
17183 (use (match_dup 3))
17184 (clobber (match_dup 5))])])
17186 (define_insn "fist<mode>2_<rounding>"
17187 [(set (match_operand:SWI24 0 "memory_operand" "=m")
17188 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
17190 (use (match_operand:HI 2 "memory_operand" "m"))
17191 (use (match_operand:HI 3 "memory_operand" "m"))]
17192 "TARGET_USE_FANCY_MATH_387
17193 && flag_unsafe_math_optimizations"
17194 "* return output_fix_trunc (insn, operands, false);"
17195 [(set_attr "type" "fistp")
17196 (set_attr "i387_cw" "<rounding>")
17197 (set_attr "mode" "<MODE>")])
17199 (define_insn "fist<mode>2_<rounding>_with_temp"
17200 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
17201 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f,f")]
17203 (use (match_operand:HI 2 "memory_operand" "m,m"))
17204 (use (match_operand:HI 3 "memory_operand" "m,m"))
17205 (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
17206 "TARGET_USE_FANCY_MATH_387
17207 && flag_unsafe_math_optimizations"
17209 [(set_attr "type" "fistp")
17210 (set_attr "i387_cw" "<rounding>")
17211 (set_attr "mode" "<MODE>")])
17214 [(set (match_operand:SWI24 0 "register_operand")
17215 (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
17217 (use (match_operand:HI 2 "memory_operand"))
17218 (use (match_operand:HI 3 "memory_operand"))
17219 (clobber (match_operand:SWI24 4 "memory_operand"))]
17221 [(parallel [(set (match_dup 4)
17222 (unspec:SWI24 [(match_dup 1)] FIST_ROUNDING))
17223 (use (match_dup 2))
17224 (use (match_dup 3))])
17225 (set (match_dup 0) (match_dup 4))])
17228 [(set (match_operand:SWI24 0 "memory_operand")
17229 (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
17231 (use (match_operand:HI 2 "memory_operand"))
17232 (use (match_operand:HI 3 "memory_operand"))
17233 (clobber (match_operand:SWI24 4 "memory_operand"))]
17235 [(parallel [(set (match_dup 0)
17236 (unspec:SWI24 [(match_dup 1)] FIST_ROUNDING))
17237 (use (match_dup 2))
17238 (use (match_dup 3))])])
17240 (define_expand "l<rounding_insn>xf<mode>2"
17241 [(parallel [(set (match_operand:SWI248x 0 "nonimmediate_operand")
17242 (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
17244 (clobber (reg:CC FLAGS_REG))])]
17245 "TARGET_USE_FANCY_MATH_387
17246 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17247 && flag_unsafe_math_optimizations")
17249 (define_expand "l<rounding_insn><MODEF:mode><SWI48:mode>2"
17250 [(parallel [(set (match_operand:SWI48 0 "nonimmediate_operand")
17251 (unspec:SWI48 [(match_operand:MODEF 1 "register_operand")]
17253 (clobber (reg:CC FLAGS_REG))])]
17254 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
17255 && (TARGET_SSE4_1 || !flag_trapping_math)"
17259 rtx tmp = gen_reg_rtx (<MODEF:MODE>mode);
17261 emit_insn (gen_sse4_1_round<mode>2
17262 (tmp, operands[1], GEN_INT (ROUND_<ROUNDING>
17264 emit_insn (gen_fix_trunc<MODEF:mode><SWI48:mode>2
17265 (operands[0], tmp));
17267 else if (ROUND_<ROUNDING> == ROUND_FLOOR)
17268 ix86_expand_lfloorceil (operands[0], operands[1], true);
17269 else if (ROUND_<ROUNDING> == ROUND_CEIL)
17270 ix86_expand_lfloorceil (operands[0], operands[1], false);
17272 gcc_unreachable ();
17277 (define_insn "fxam<mode>2_i387"
17278 [(set (match_operand:HI 0 "register_operand" "=a")
17280 [(match_operand:X87MODEF 1 "register_operand" "f")]
17282 "TARGET_USE_FANCY_MATH_387"
17283 "fxam\n\tfnstsw\t%0"
17284 [(set_attr "type" "multi")
17285 (set_attr "length" "4")
17286 (set_attr "unit" "i387")
17287 (set_attr "mode" "<MODE>")])
17289 (define_insn_and_split "fxam<mode>2_i387_with_temp"
17290 [(set (match_operand:HI 0 "register_operand")
17292 [(match_operand:MODEF 1 "memory_operand")]
17294 "TARGET_USE_FANCY_MATH_387
17295 && can_create_pseudo_p ()"
17298 [(set (match_dup 2)(match_dup 1))
17300 (unspec:HI [(match_dup 2)] UNSPEC_FXAM))]
17302 operands[2] = gen_reg_rtx (<MODE>mode);
17304 MEM_VOLATILE_P (operands[1]) = 1;
17306 [(set_attr "type" "multi")
17307 (set_attr "unit" "i387")
17308 (set_attr "mode" "<MODE>")])
17310 (define_expand "isinfxf2"
17311 [(use (match_operand:SI 0 "register_operand"))
17312 (use (match_operand:XF 1 "register_operand"))]
17313 "TARGET_USE_FANCY_MATH_387
17314 && ix86_libc_has_function (function_c99_misc)"
17316 rtx mask = GEN_INT (0x45);
17317 rtx val = GEN_INT (0x05);
17319 rtx scratch = gen_reg_rtx (HImode);
17320 rtx res = gen_reg_rtx (QImode);
17322 emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
17324 emit_insn (gen_andqi_ext_1 (scratch, scratch, mask));
17325 emit_insn (gen_cmpqi_ext_3 (scratch, val));
17326 ix86_expand_setcc (res, EQ,
17327 gen_rtx_REG (CCmode, FLAGS_REG), const0_rtx);
17328 emit_insn (gen_zero_extendqisi2 (operands[0], res));
17332 (define_expand "isinf<mode>2"
17333 [(use (match_operand:SI 0 "register_operand"))
17334 (use (match_operand:MODEF 1 "nonimmediate_operand"))]
17335 "TARGET_USE_FANCY_MATH_387
17336 && ix86_libc_has_function (function_c99_misc)
17337 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
17339 rtx mask = GEN_INT (0x45);
17340 rtx val = GEN_INT (0x05);
17342 rtx scratch = gen_reg_rtx (HImode);
17343 rtx res = gen_reg_rtx (QImode);
17345 /* Remove excess precision by forcing value through memory. */
17346 if (memory_operand (operands[1], VOIDmode))
17347 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, operands[1]));
17350 rtx temp = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17352 emit_move_insn (temp, operands[1]);
17353 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, temp));
17356 emit_insn (gen_andqi_ext_1 (scratch, scratch, mask));
17357 emit_insn (gen_cmpqi_ext_3 (scratch, val));
17358 ix86_expand_setcc (res, EQ,
17359 gen_rtx_REG (CCmode, FLAGS_REG), const0_rtx);
17360 emit_insn (gen_zero_extendqisi2 (operands[0], res));
17364 (define_expand "signbittf2"
17365 [(use (match_operand:SI 0 "register_operand"))
17366 (use (match_operand:TF 1 "register_operand"))]
17371 rtx mask = ix86_build_signbit_mask (TFmode, 0, 0);
17372 rtx scratch = gen_reg_rtx (QImode);
17374 emit_insn (gen_ptesttf2 (operands[1], mask));
17375 ix86_expand_setcc (scratch, NE,
17376 gen_rtx_REG (CCZmode, FLAGS_REG), const0_rtx);
17378 emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
17382 emit_insn (gen_sse_movmskps (operands[0],
17383 gen_lowpart (V4SFmode, operands[1])));
17384 emit_insn (gen_andsi3 (operands[0], operands[0], GEN_INT (0x8)));
17389 (define_expand "signbitxf2"
17390 [(use (match_operand:SI 0 "register_operand"))
17391 (use (match_operand:XF 1 "register_operand"))]
17392 "TARGET_USE_FANCY_MATH_387"
17394 rtx scratch = gen_reg_rtx (HImode);
17396 emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
17397 emit_insn (gen_andsi3 (operands[0],
17398 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
17402 (define_insn "movmsk_df"
17403 [(set (match_operand:SI 0 "register_operand" "=r")
17405 [(match_operand:DF 1 "register_operand" "x")]
17407 "SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH"
17408 "%vmovmskpd\t{%1, %0|%0, %1}"
17409 [(set_attr "type" "ssemov")
17410 (set_attr "prefix" "maybe_vex")
17411 (set_attr "mode" "DF")])
17413 ;; Use movmskpd in SSE mode to avoid store forwarding stall
17414 ;; for 32bit targets and movq+shrq sequence for 64bit targets.
17415 (define_expand "signbitdf2"
17416 [(use (match_operand:SI 0 "register_operand"))
17417 (use (match_operand:DF 1 "register_operand"))]
17418 "TARGET_USE_FANCY_MATH_387
17419 || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
17421 if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)
17423 emit_insn (gen_movmsk_df (operands[0], operands[1]));
17424 emit_insn (gen_andsi3 (operands[0], operands[0], const1_rtx));
17428 rtx scratch = gen_reg_rtx (HImode);
17430 emit_insn (gen_fxamdf2_i387 (scratch, operands[1]));
17431 emit_insn (gen_andsi3 (operands[0],
17432 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
17437 (define_expand "signbitsf2"
17438 [(use (match_operand:SI 0 "register_operand"))
17439 (use (match_operand:SF 1 "register_operand"))]
17440 "TARGET_USE_FANCY_MATH_387
17441 && !(SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH)"
17443 rtx scratch = gen_reg_rtx (HImode);
17445 emit_insn (gen_fxamsf2_i387 (scratch, operands[1]));
17446 emit_insn (gen_andsi3 (operands[0],
17447 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
17451 ;; Block operation instructions
17454 [(unspec_volatile [(const_int 0)] UNSPECV_CLD)]
17457 [(set_attr "length" "1")
17458 (set_attr "length_immediate" "0")
17459 (set_attr "modrm" "0")])
17461 (define_expand "movmem<mode>"
17462 [(use (match_operand:BLK 0 "memory_operand"))
17463 (use (match_operand:BLK 1 "memory_operand"))
17464 (use (match_operand:SWI48 2 "nonmemory_operand"))
17465 (use (match_operand:SWI48 3 "const_int_operand"))
17466 (use (match_operand:SI 4 "const_int_operand"))
17467 (use (match_operand:SI 5 "const_int_operand"))
17468 (use (match_operand:SI 6 ""))
17469 (use (match_operand:SI 7 ""))
17470 (use (match_operand:SI 8 ""))]
17473 if (ix86_expand_set_or_movmem (operands[0], operands[1],
17474 operands[2], NULL, operands[3],
17475 operands[4], operands[5],
17476 operands[6], operands[7],
17477 operands[8], false))
17483 ;; Most CPUs don't like single string operations
17484 ;; Handle this case here to simplify previous expander.
17486 (define_expand "strmov"
17487 [(set (match_dup 4) (match_operand 3 "memory_operand"))
17488 (set (match_operand 1 "memory_operand") (match_dup 4))
17489 (parallel [(set (match_operand 0 "register_operand") (match_dup 5))
17490 (clobber (reg:CC FLAGS_REG))])
17491 (parallel [(set (match_operand 2 "register_operand") (match_dup 6))
17492 (clobber (reg:CC FLAGS_REG))])]
17495 /* Can't use this for non-default address spaces. */
17496 if (!ADDR_SPACE_GENERIC_P (MEM_ADDR_SPACE (operands[3])))
17499 rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
17501 /* If .md ever supports :P for Pmode, these can be directly
17502 in the pattern above. */
17503 operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
17504 operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
17506 /* Can't use this if the user has appropriated esi or edi. */
17507 if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
17508 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG]))
17510 emit_insn (gen_strmov_singleop (operands[0], operands[1],
17511 operands[2], operands[3],
17512 operands[5], operands[6]));
17516 operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
17519 (define_expand "strmov_singleop"
17520 [(parallel [(set (match_operand 1 "memory_operand")
17521 (match_operand 3 "memory_operand"))
17522 (set (match_operand 0 "register_operand")
17524 (set (match_operand 2 "register_operand")
17525 (match_operand 5))])]
17529 ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
17532 (define_insn "*strmovdi_rex_1"
17533 [(set (mem:DI (match_operand:P 2 "register_operand" "0"))
17534 (mem:DI (match_operand:P 3 "register_operand" "1")))
17535 (set (match_operand:P 0 "register_operand" "=D")
17536 (plus:P (match_dup 2)
17538 (set (match_operand:P 1 "register_operand" "=S")
17539 (plus:P (match_dup 3)
17542 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG])
17543 && ix86_check_no_addr_space (insn)"
17545 [(set_attr "type" "str")
17546 (set_attr "memory" "both")
17547 (set_attr "mode" "DI")])
17549 (define_insn "*strmovsi_1"
17550 [(set (mem:SI (match_operand:P 2 "register_operand" "0"))
17551 (mem:SI (match_operand:P 3 "register_operand" "1")))
17552 (set (match_operand:P 0 "register_operand" "=D")
17553 (plus:P (match_dup 2)
17555 (set (match_operand:P 1 "register_operand" "=S")
17556 (plus:P (match_dup 3)
17558 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])
17559 && ix86_check_no_addr_space (insn)"
17561 [(set_attr "type" "str")
17562 (set_attr "memory" "both")
17563 (set_attr "mode" "SI")])
17565 (define_insn "*strmovhi_1"
17566 [(set (mem:HI (match_operand:P 2 "register_operand" "0"))
17567 (mem:HI (match_operand:P 3 "register_operand" "1")))
17568 (set (match_operand:P 0 "register_operand" "=D")
17569 (plus:P (match_dup 2)
17571 (set (match_operand:P 1 "register_operand" "=S")
17572 (plus:P (match_dup 3)
17574 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])
17575 && ix86_check_no_addr_space (insn)"
17577 [(set_attr "type" "str")
17578 (set_attr "memory" "both")
17579 (set_attr "mode" "HI")])
17581 (define_insn "*strmovqi_1"
17582 [(set (mem:QI (match_operand:P 2 "register_operand" "0"))
17583 (mem:QI (match_operand:P 3 "register_operand" "1")))
17584 (set (match_operand:P 0 "register_operand" "=D")
17585 (plus:P (match_dup 2)
17587 (set (match_operand:P 1 "register_operand" "=S")
17588 (plus:P (match_dup 3)
17590 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])
17591 && ix86_check_no_addr_space (insn)"
17593 [(set_attr "type" "str")
17594 (set_attr "memory" "both")
17595 (set (attr "prefix_rex")
17597 (match_test "<P:MODE>mode == DImode")
17599 (const_string "*")))
17600 (set_attr "mode" "QI")])
17602 (define_expand "rep_mov"
17603 [(parallel [(set (match_operand 4 "register_operand") (const_int 0))
17604 (set (match_operand 0 "register_operand")
17606 (set (match_operand 2 "register_operand")
17608 (set (match_operand 1 "memory_operand")
17609 (match_operand 3 "memory_operand"))
17610 (use (match_dup 4))])]
17614 ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
17617 (define_insn "*rep_movdi_rex64"
17618 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
17619 (set (match_operand:P 0 "register_operand" "=D")
17620 (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
17622 (match_operand:P 3 "register_operand" "0")))
17623 (set (match_operand:P 1 "register_operand" "=S")
17624 (plus:P (ashift:P (match_dup 5) (const_int 3))
17625 (match_operand:P 4 "register_operand" "1")))
17626 (set (mem:BLK (match_dup 3))
17627 (mem:BLK (match_dup 4)))
17628 (use (match_dup 5))]
17630 && !(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
17631 && ix86_check_no_addr_space (insn)"
17633 [(set_attr "type" "str")
17634 (set_attr "prefix_rep" "1")
17635 (set_attr "memory" "both")
17636 (set_attr "mode" "DI")])
17638 (define_insn "*rep_movsi"
17639 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
17640 (set (match_operand:P 0 "register_operand" "=D")
17641 (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
17643 (match_operand:P 3 "register_operand" "0")))
17644 (set (match_operand:P 1 "register_operand" "=S")
17645 (plus:P (ashift:P (match_dup 5) (const_int 2))
17646 (match_operand:P 4 "register_operand" "1")))
17647 (set (mem:BLK (match_dup 3))
17648 (mem:BLK (match_dup 4)))
17649 (use (match_dup 5))]
17650 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
17651 && ix86_check_no_addr_space (insn)"
17652 "%^rep{%;} movs{l|d}"
17653 [(set_attr "type" "str")
17654 (set_attr "prefix_rep" "1")
17655 (set_attr "memory" "both")
17656 (set_attr "mode" "SI")])
17658 (define_insn "*rep_movqi"
17659 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
17660 (set (match_operand:P 0 "register_operand" "=D")
17661 (plus:P (match_operand:P 3 "register_operand" "0")
17662 (match_operand:P 5 "register_operand" "2")))
17663 (set (match_operand:P 1 "register_operand" "=S")
17664 (plus:P (match_operand:P 4 "register_operand" "1") (match_dup 5)))
17665 (set (mem:BLK (match_dup 3))
17666 (mem:BLK (match_dup 4)))
17667 (use (match_dup 5))]
17668 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
17669 && ix86_check_no_addr_space (insn)"
17671 [(set_attr "type" "str")
17672 (set_attr "prefix_rep" "1")
17673 (set_attr "memory" "both")
17674 (set_attr "mode" "QI")])
17676 (define_expand "setmem<mode>"
17677 [(use (match_operand:BLK 0 "memory_operand"))
17678 (use (match_operand:SWI48 1 "nonmemory_operand"))
17679 (use (match_operand:QI 2 "nonmemory_operand"))
17680 (use (match_operand 3 "const_int_operand"))
17681 (use (match_operand:SI 4 "const_int_operand"))
17682 (use (match_operand:SI 5 "const_int_operand"))
17683 (use (match_operand:SI 6 ""))
17684 (use (match_operand:SI 7 ""))
17685 (use (match_operand:SI 8 ""))]
17688 if (ix86_expand_set_or_movmem (operands[0], NULL,
17689 operands[1], operands[2],
17690 operands[3], operands[4],
17691 operands[5], operands[6],
17692 operands[7], operands[8], true))
17698 ;; Most CPUs don't like single string operations
17699 ;; Handle this case here to simplify previous expander.
17701 (define_expand "strset"
17702 [(set (match_operand 1 "memory_operand")
17703 (match_operand 2 "register_operand"))
17704 (parallel [(set (match_operand 0 "register_operand")
17706 (clobber (reg:CC FLAGS_REG))])]
17709 /* Can't use this for non-default address spaces. */
17710 if (!ADDR_SPACE_GENERIC_P (MEM_ADDR_SPACE (operands[1])))
17713 if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
17714 operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
17716 /* If .md ever supports :P for Pmode, this can be directly
17717 in the pattern above. */
17718 operands[3] = gen_rtx_PLUS (Pmode, operands[0],
17719 GEN_INT (GET_MODE_SIZE (GET_MODE
17721 /* Can't use this if the user has appropriated eax or edi. */
17722 if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
17723 && !(fixed_regs[AX_REG] || fixed_regs[DI_REG]))
17725 emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
17731 (define_expand "strset_singleop"
17732 [(parallel [(set (match_operand 1 "memory_operand")
17733 (match_operand 2 "register_operand"))
17734 (set (match_operand 0 "register_operand")
17736 (unspec [(const_int 0)] UNSPEC_STOS)])]
17740 ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
17743 (define_insn "*strsetdi_rex_1"
17744 [(set (mem:DI (match_operand:P 1 "register_operand" "0"))
17745 (match_operand:DI 2 "register_operand" "a"))
17746 (set (match_operand:P 0 "register_operand" "=D")
17747 (plus:P (match_dup 1)
17749 (unspec [(const_int 0)] UNSPEC_STOS)]
17751 && !(fixed_regs[AX_REG] || fixed_regs[DI_REG])
17752 && ix86_check_no_addr_space (insn)"
17754 [(set_attr "type" "str")
17755 (set_attr "memory" "store")
17756 (set_attr "mode" "DI")])
17758 (define_insn "*strsetsi_1"
17759 [(set (mem:SI (match_operand:P 1 "register_operand" "0"))
17760 (match_operand:SI 2 "register_operand" "a"))
17761 (set (match_operand:P 0 "register_operand" "=D")
17762 (plus:P (match_dup 1)
17764 (unspec [(const_int 0)] UNSPEC_STOS)]
17765 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])
17766 && ix86_check_no_addr_space (insn)"
17768 [(set_attr "type" "str")
17769 (set_attr "memory" "store")
17770 (set_attr "mode" "SI")])
17772 (define_insn "*strsethi_1"
17773 [(set (mem:HI (match_operand:P 1 "register_operand" "0"))
17774 (match_operand:HI 2 "register_operand" "a"))
17775 (set (match_operand:P 0 "register_operand" "=D")
17776 (plus:P (match_dup 1)
17778 (unspec [(const_int 0)] UNSPEC_STOS)]
17779 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])
17780 && ix86_check_no_addr_space (insn)"
17782 [(set_attr "type" "str")
17783 (set_attr "memory" "store")
17784 (set_attr "mode" "HI")])
17786 (define_insn "*strsetqi_1"
17787 [(set (mem:QI (match_operand:P 1 "register_operand" "0"))
17788 (match_operand:QI 2 "register_operand" "a"))
17789 (set (match_operand:P 0 "register_operand" "=D")
17790 (plus:P (match_dup 1)
17792 (unspec [(const_int 0)] UNSPEC_STOS)]
17793 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])
17794 && ix86_check_no_addr_space (insn)"
17796 [(set_attr "type" "str")
17797 (set_attr "memory" "store")
17798 (set (attr "prefix_rex")
17800 (match_test "<P:MODE>mode == DImode")
17802 (const_string "*")))
17803 (set_attr "mode" "QI")])
17805 (define_expand "rep_stos"
17806 [(parallel [(set (match_operand 1 "register_operand") (const_int 0))
17807 (set (match_operand 0 "register_operand")
17809 (set (match_operand 2 "memory_operand") (const_int 0))
17810 (use (match_operand 3 "register_operand"))
17811 (use (match_dup 1))])]
17815 ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
17818 (define_insn "*rep_stosdi_rex64"
17819 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
17820 (set (match_operand:P 0 "register_operand" "=D")
17821 (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
17823 (match_operand:P 3 "register_operand" "0")))
17824 (set (mem:BLK (match_dup 3))
17826 (use (match_operand:DI 2 "register_operand" "a"))
17827 (use (match_dup 4))]
17829 && !(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])
17830 && ix86_check_no_addr_space (insn)"
17832 [(set_attr "type" "str")
17833 (set_attr "prefix_rep" "1")
17834 (set_attr "memory" "store")
17835 (set_attr "mode" "DI")])
17837 (define_insn "*rep_stossi"
17838 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
17839 (set (match_operand:P 0 "register_operand" "=D")
17840 (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
17842 (match_operand:P 3 "register_operand" "0")))
17843 (set (mem:BLK (match_dup 3))
17845 (use (match_operand:SI 2 "register_operand" "a"))
17846 (use (match_dup 4))]
17847 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])
17848 && ix86_check_no_addr_space (insn)"
17849 "%^rep{%;} stos{l|d}"
17850 [(set_attr "type" "str")
17851 (set_attr "prefix_rep" "1")
17852 (set_attr "memory" "store")
17853 (set_attr "mode" "SI")])
17855 (define_insn "*rep_stosqi"
17856 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
17857 (set (match_operand:P 0 "register_operand" "=D")
17858 (plus:P (match_operand:P 3 "register_operand" "0")
17859 (match_operand:P 4 "register_operand" "1")))
17860 (set (mem:BLK (match_dup 3))
17862 (use (match_operand:QI 2 "register_operand" "a"))
17863 (use (match_dup 4))]
17864 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])
17865 && ix86_check_no_addr_space (insn)"
17867 [(set_attr "type" "str")
17868 (set_attr "prefix_rep" "1")
17869 (set_attr "memory" "store")
17870 (set (attr "prefix_rex")
17872 (match_test "<P:MODE>mode == DImode")
17874 (const_string "*")))
17875 (set_attr "mode" "QI")])
17877 (define_expand "cmpstrnsi"
17878 [(set (match_operand:SI 0 "register_operand")
17879 (compare:SI (match_operand:BLK 1 "general_operand")
17880 (match_operand:BLK 2 "general_operand")))
17881 (use (match_operand 3 "general_operand"))
17882 (use (match_operand 4 "immediate_operand"))]
17885 rtx addr1, addr2, out, outlow, count, countreg, align;
17887 if (optimize_insn_for_size_p () && !TARGET_INLINE_ALL_STRINGOPS)
17890 /* Can't use this if the user has appropriated ecx, esi or edi. */
17891 if (fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
17894 /* One of the strings must be a constant. If so, expand_builtin_strncmp()
17895 will have rewritten the length arg to be the minimum of the const string
17896 length and the actual length arg. If both strings are the same and
17897 shorter than the length arg, repz cmpsb will not stop at the 0 byte and
17898 will incorrectly base the results on chars past the 0 byte. */
17899 tree t1 = MEM_EXPR (operands[1]);
17900 tree t2 = MEM_EXPR (operands[2]);
17901 if (!((t1 && TREE_CODE (t1) == MEM_REF
17902 && TREE_CODE (TREE_OPERAND (t1, 0)) == ADDR_EXPR
17903 && TREE_CODE (TREE_OPERAND (TREE_OPERAND (t1, 0), 0)) == STRING_CST)
17904 || (t2 && TREE_CODE (t2) == MEM_REF
17905 && TREE_CODE (TREE_OPERAND (t2, 0)) == ADDR_EXPR
17906 && TREE_CODE (TREE_OPERAND (TREE_OPERAND (t2, 0), 0)) == STRING_CST)))
17911 out = gen_reg_rtx (SImode);
17913 addr1 = copy_addr_to_reg (XEXP (operands[1], 0));
17914 addr2 = copy_addr_to_reg (XEXP (operands[2], 0));
17915 if (addr1 != XEXP (operands[1], 0))
17916 operands[1] = replace_equiv_address_nv (operands[1], addr1);
17917 if (addr2 != XEXP (operands[2], 0))
17918 operands[2] = replace_equiv_address_nv (operands[2], addr2);
17920 count = operands[3];
17921 countreg = ix86_zero_extend_to_Pmode (count);
17923 /* %%% Iff we are testing strict equality, we can use known alignment
17924 to good advantage. This may be possible with combine, particularly
17925 once cc0 is dead. */
17926 align = operands[4];
17928 if (CONST_INT_P (count))
17930 if (INTVAL (count) == 0)
17932 emit_move_insn (operands[0], const0_rtx);
17935 emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
17936 operands[1], operands[2]));
17940 rtx (*gen_cmp) (rtx, rtx);
17942 gen_cmp = (TARGET_64BIT
17943 ? gen_cmpdi_1 : gen_cmpsi_1);
17945 emit_insn (gen_cmp (countreg, countreg));
17946 emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
17947 operands[1], operands[2]));
17950 outlow = gen_lowpart (QImode, out);
17951 emit_insn (gen_cmpintqi (outlow));
17952 emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
17954 if (operands[0] != out)
17955 emit_move_insn (operands[0], out);
17960 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
17962 (define_expand "cmpintqi"
17963 [(set (match_dup 1)
17964 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
17966 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
17967 (parallel [(set (match_operand:QI 0 "register_operand")
17968 (minus:QI (match_dup 1)
17970 (clobber (reg:CC FLAGS_REG))])]
17973 operands[1] = gen_reg_rtx (QImode);
17974 operands[2] = gen_reg_rtx (QImode);
17977 ;; memcmp recognizers. The `cmpsb' opcode does nothing if the count is
17978 ;; zero. Emit extra code to make sure that a zero-length compare is EQ.
17980 (define_expand "cmpstrnqi_nz_1"
17981 [(parallel [(set (reg:CC FLAGS_REG)
17982 (compare:CC (match_operand 4 "memory_operand")
17983 (match_operand 5 "memory_operand")))
17984 (use (match_operand 2 "register_operand"))
17985 (use (match_operand:SI 3 "immediate_operand"))
17986 (clobber (match_operand 0 "register_operand"))
17987 (clobber (match_operand 1 "register_operand"))
17988 (clobber (match_dup 2))])]
17992 ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
17995 (define_insn "*cmpstrnqi_nz_1"
17996 [(set (reg:CC FLAGS_REG)
17997 (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
17998 (mem:BLK (match_operand:P 5 "register_operand" "1"))))
17999 (use (match_operand:P 6 "register_operand" "2"))
18000 (use (match_operand:SI 3 "immediate_operand" "i"))
18001 (clobber (match_operand:P 0 "register_operand" "=S"))
18002 (clobber (match_operand:P 1 "register_operand" "=D"))
18003 (clobber (match_operand:P 2 "register_operand" "=c"))]
18004 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
18005 && ix86_check_no_addr_space (insn)"
18007 [(set_attr "type" "str")
18008 (set_attr "mode" "QI")
18009 (set (attr "prefix_rex")
18011 (match_test "<P:MODE>mode == DImode")
18013 (const_string "*")))
18014 (set_attr "prefix_rep" "1")])
18016 ;; The same, but the count is not known to not be zero.
18018 (define_expand "cmpstrnqi_1"
18019 [(parallel [(set (reg:CC FLAGS_REG)
18020 (if_then_else:CC (ne (match_operand 2 "register_operand")
18022 (compare:CC (match_operand 4 "memory_operand")
18023 (match_operand 5 "memory_operand"))
18025 (use (match_operand:SI 3 "immediate_operand"))
18026 (use (reg:CC FLAGS_REG))
18027 (clobber (match_operand 0 "register_operand"))
18028 (clobber (match_operand 1 "register_operand"))
18029 (clobber (match_dup 2))])]
18033 ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
18036 (define_insn "*cmpstrnqi_1"
18037 [(set (reg:CC FLAGS_REG)
18038 (if_then_else:CC (ne (match_operand:P 6 "register_operand" "2")
18040 (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
18041 (mem:BLK (match_operand:P 5 "register_operand" "1")))
18043 (use (match_operand:SI 3 "immediate_operand" "i"))
18044 (use (reg:CC FLAGS_REG))
18045 (clobber (match_operand:P 0 "register_operand" "=S"))
18046 (clobber (match_operand:P 1 "register_operand" "=D"))
18047 (clobber (match_operand:P 2 "register_operand" "=c"))]
18048 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
18049 && ix86_check_no_addr_space (insn)"
18051 [(set_attr "type" "str")
18052 (set_attr "mode" "QI")
18053 (set (attr "prefix_rex")
18055 (match_test "<P:MODE>mode == DImode")
18057 (const_string "*")))
18058 (set_attr "prefix_rep" "1")])
18060 (define_expand "strlen<mode>"
18061 [(set (match_operand:P 0 "register_operand")
18062 (unspec:P [(match_operand:BLK 1 "general_operand")
18063 (match_operand:QI 2 "immediate_operand")
18064 (match_operand 3 "immediate_operand")]
18068 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
18074 (define_expand "strlenqi_1"
18075 [(parallel [(set (match_operand 0 "register_operand")
18077 (clobber (match_operand 1 "register_operand"))
18078 (clobber (reg:CC FLAGS_REG))])]
18082 ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
18085 (define_insn "*strlenqi_1"
18086 [(set (match_operand:P 0 "register_operand" "=&c")
18087 (unspec:P [(mem:BLK (match_operand:P 5 "register_operand" "1"))
18088 (match_operand:QI 2 "register_operand" "a")
18089 (match_operand:P 3 "immediate_operand" "i")
18090 (match_operand:P 4 "register_operand" "0")] UNSPEC_SCAS))
18091 (clobber (match_operand:P 1 "register_operand" "=D"))
18092 (clobber (reg:CC FLAGS_REG))]
18093 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])
18094 && ix86_check_no_addr_space (insn)"
18095 "%^repnz{%;} scasb"
18096 [(set_attr "type" "str")
18097 (set_attr "mode" "QI")
18098 (set (attr "prefix_rex")
18100 (match_test "<P:MODE>mode == DImode")
18102 (const_string "*")))
18103 (set_attr "prefix_rep" "1")])
18105 ;; Peephole optimizations to clean up after cmpstrn*. This should be
18106 ;; handled in combine, but it is not currently up to the task.
18107 ;; When used for their truth value, the cmpstrn* expanders generate
18116 ;; The intermediate three instructions are unnecessary.
18118 ;; This one handles cmpstrn*_nz_1...
18121 (set (reg:CC FLAGS_REG)
18122 (compare:CC (mem:BLK (match_operand 4 "register_operand"))
18123 (mem:BLK (match_operand 5 "register_operand"))))
18124 (use (match_operand 6 "register_operand"))
18125 (use (match_operand:SI 3 "immediate_operand"))
18126 (clobber (match_operand 0 "register_operand"))
18127 (clobber (match_operand 1 "register_operand"))
18128 (clobber (match_operand 2 "register_operand"))])
18129 (set (match_operand:QI 7 "register_operand")
18130 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
18131 (set (match_operand:QI 8 "register_operand")
18132 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
18133 (set (reg FLAGS_REG)
18134 (compare (match_dup 7) (match_dup 8)))
18136 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
18138 (set (reg:CC FLAGS_REG)
18139 (compare:CC (mem:BLK (match_dup 4))
18140 (mem:BLK (match_dup 5))))
18141 (use (match_dup 6))
18142 (use (match_dup 3))
18143 (clobber (match_dup 0))
18144 (clobber (match_dup 1))
18145 (clobber (match_dup 2))])])
18147 ;; ...and this one handles cmpstrn*_1.
18150 (set (reg:CC FLAGS_REG)
18151 (if_then_else:CC (ne (match_operand 6 "register_operand")
18153 (compare:CC (mem:BLK (match_operand 4 "register_operand"))
18154 (mem:BLK (match_operand 5 "register_operand")))
18156 (use (match_operand:SI 3 "immediate_operand"))
18157 (use (reg:CC FLAGS_REG))
18158 (clobber (match_operand 0 "register_operand"))
18159 (clobber (match_operand 1 "register_operand"))
18160 (clobber (match_operand 2 "register_operand"))])
18161 (set (match_operand:QI 7 "register_operand")
18162 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
18163 (set (match_operand:QI 8 "register_operand")
18164 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
18165 (set (reg FLAGS_REG)
18166 (compare (match_dup 7) (match_dup 8)))
18168 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
18170 (set (reg:CC FLAGS_REG)
18171 (if_then_else:CC (ne (match_dup 6)
18173 (compare:CC (mem:BLK (match_dup 4))
18174 (mem:BLK (match_dup 5)))
18176 (use (match_dup 3))
18177 (use (reg:CC FLAGS_REG))
18178 (clobber (match_dup 0))
18179 (clobber (match_dup 1))
18180 (clobber (match_dup 2))])])
18182 ;; Conditional move instructions.
18184 (define_expand "mov<mode>cc"
18185 [(set (match_operand:SWIM 0 "register_operand")
18186 (if_then_else:SWIM (match_operand 1 "comparison_operator")
18187 (match_operand:SWIM 2 "<general_operand>")
18188 (match_operand:SWIM 3 "<general_operand>")))]
18190 "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
18192 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
18193 ;; the register first winds up with `sbbl $0,reg', which is also weird.
18194 ;; So just document what we're doing explicitly.
18196 (define_expand "x86_mov<mode>cc_0_m1"
18198 [(set (match_operand:SWI48 0 "register_operand")
18199 (if_then_else:SWI48
18200 (match_operator:SWI48 2 "ix86_carry_flag_operator"
18201 [(match_operand 1 "flags_reg_operand")
18205 (clobber (reg:CC FLAGS_REG))])])
18207 (define_insn "*x86_mov<mode>cc_0_m1"
18208 [(set (match_operand:SWI48 0 "register_operand" "=r")
18209 (if_then_else:SWI48 (match_operator 1 "ix86_carry_flag_operator"
18210 [(reg FLAGS_REG) (const_int 0)])
18213 (clobber (reg:CC FLAGS_REG))]
18215 "sbb{<imodesuffix>}\t%0, %0"
18216 [(set_attr "type" "alu1")
18217 (set_attr "modrm_class" "op0")
18218 (set_attr "use_carry" "1")
18219 (set_attr "pent_pair" "pu")
18220 (set_attr "mode" "<MODE>")
18221 (set_attr "length_immediate" "0")])
18223 (define_insn "*x86_mov<mode>cc_0_m1_se"
18224 [(set (match_operand:SWI48 0 "register_operand" "=r")
18225 (sign_extract:SWI48 (match_operator 1 "ix86_carry_flag_operator"
18226 [(reg FLAGS_REG) (const_int 0)])
18229 (clobber (reg:CC FLAGS_REG))]
18231 "sbb{<imodesuffix>}\t%0, %0"
18232 [(set_attr "type" "alu1")
18233 (set_attr "modrm_class" "op0")
18234 (set_attr "use_carry" "1")
18235 (set_attr "pent_pair" "pu")
18236 (set_attr "mode" "<MODE>")
18237 (set_attr "length_immediate" "0")])
18239 (define_insn "*x86_mov<mode>cc_0_m1_neg"
18240 [(set (match_operand:SWI48 0 "register_operand" "=r")
18241 (neg:SWI48 (match_operator 1 "ix86_carry_flag_operator"
18242 [(reg FLAGS_REG) (const_int 0)])))
18243 (clobber (reg:CC FLAGS_REG))]
18245 "sbb{<imodesuffix>}\t%0, %0"
18246 [(set_attr "type" "alu1")
18247 (set_attr "modrm_class" "op0")
18248 (set_attr "use_carry" "1")
18249 (set_attr "pent_pair" "pu")
18250 (set_attr "mode" "<MODE>")
18251 (set_attr "length_immediate" "0")])
18253 (define_insn "*mov<mode>cc_noc"
18254 [(set (match_operand:SWI248 0 "register_operand" "=r,r")
18255 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
18256 [(reg FLAGS_REG) (const_int 0)])
18257 (match_operand:SWI248 2 "nonimmediate_operand" "rm,0")
18258 (match_operand:SWI248 3 "nonimmediate_operand" "0,rm")))]
18259 "TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
18261 cmov%O2%C1\t{%2, %0|%0, %2}
18262 cmov%O2%c1\t{%3, %0|%0, %3}"
18263 [(set_attr "type" "icmov")
18264 (set_attr "mode" "<MODE>")])
18266 (define_insn "*movsicc_noc_zext"
18267 [(set (match_operand:DI 0 "register_operand" "=r,r")
18268 (if_then_else:DI (match_operator 1 "ix86_comparison_operator"
18269 [(reg FLAGS_REG) (const_int 0)])
18271 (match_operand:SI 2 "nonimmediate_operand" "rm,0"))
18273 (match_operand:SI 3 "nonimmediate_operand" "0,rm"))))]
18275 && TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
18277 cmov%O2%C1\t{%2, %k0|%k0, %2}
18278 cmov%O2%c1\t{%3, %k0|%k0, %3}"
18279 [(set_attr "type" "icmov")
18280 (set_attr "mode" "SI")])
18282 ;; Don't do conditional moves with memory inputs. This splitter helps
18283 ;; register starved x86_32 by forcing inputs into registers before reload.
18285 [(set (match_operand:SWI248 0 "register_operand")
18286 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
18287 [(reg FLAGS_REG) (const_int 0)])
18288 (match_operand:SWI248 2 "nonimmediate_operand")
18289 (match_operand:SWI248 3 "nonimmediate_operand")))]
18290 "!TARGET_64BIT && TARGET_CMOVE
18291 && TARGET_AVOID_MEM_OPND_FOR_CMOVE
18292 && (MEM_P (operands[2]) || MEM_P (operands[3]))
18293 && can_create_pseudo_p ()
18294 && optimize_insn_for_speed_p ()"
18295 [(set (match_dup 0)
18296 (if_then_else:SWI248 (match_dup 1) (match_dup 2) (match_dup 3)))]
18298 if (MEM_P (operands[2]))
18299 operands[2] = force_reg (<MODE>mode, operands[2]);
18300 if (MEM_P (operands[3]))
18301 operands[3] = force_reg (<MODE>mode, operands[3]);
18304 (define_insn "*movqicc_noc"
18305 [(set (match_operand:QI 0 "register_operand" "=r,r")
18306 (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
18307 [(reg FLAGS_REG) (const_int 0)])
18308 (match_operand:QI 2 "register_operand" "r,0")
18309 (match_operand:QI 3 "register_operand" "0,r")))]
18310 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
18312 [(set_attr "type" "icmov")
18313 (set_attr "mode" "QI")])
18316 [(set (match_operand:SWI12 0 "register_operand")
18317 (if_then_else:SWI12 (match_operator 1 "ix86_comparison_operator"
18318 [(reg FLAGS_REG) (const_int 0)])
18319 (match_operand:SWI12 2 "register_operand")
18320 (match_operand:SWI12 3 "register_operand")))]
18321 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL
18322 && reload_completed"
18323 [(set (match_dup 0)
18324 (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
18326 operands[0] = gen_lowpart (SImode, operands[0]);
18327 operands[2] = gen_lowpart (SImode, operands[2]);
18328 operands[3] = gen_lowpart (SImode, operands[3]);
18331 ;; Don't do conditional moves with memory inputs
18333 [(match_scratch:SWI248 4 "r")
18334 (set (match_operand:SWI248 0 "register_operand")
18335 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
18336 [(reg FLAGS_REG) (const_int 0)])
18337 (match_operand:SWI248 2 "nonimmediate_operand")
18338 (match_operand:SWI248 3 "nonimmediate_operand")))]
18339 "TARGET_CMOVE && TARGET_AVOID_MEM_OPND_FOR_CMOVE
18340 && (MEM_P (operands[2]) || MEM_P (operands[3]))
18341 && optimize_insn_for_speed_p ()"
18342 [(set (match_dup 4) (match_dup 5))
18344 (if_then_else:SWI248 (match_dup 1) (match_dup 2) (match_dup 3)))]
18346 if (MEM_P (operands[2]))
18348 operands[5] = operands[2];
18349 operands[2] = operands[4];
18351 else if (MEM_P (operands[3]))
18353 operands[5] = operands[3];
18354 operands[3] = operands[4];
18357 gcc_unreachable ();
18361 [(match_scratch:SI 4 "r")
18362 (set (match_operand:DI 0 "register_operand")
18363 (if_then_else:DI (match_operator 1 "ix86_comparison_operator"
18364 [(reg FLAGS_REG) (const_int 0)])
18366 (match_operand:SI 2 "nonimmediate_operand"))
18368 (match_operand:SI 3 "nonimmediate_operand"))))]
18370 && TARGET_CMOVE && TARGET_AVOID_MEM_OPND_FOR_CMOVE
18371 && (MEM_P (operands[2]) || MEM_P (operands[3]))
18372 && optimize_insn_for_speed_p ()"
18373 [(set (match_dup 4) (match_dup 5))
18375 (if_then_else:DI (match_dup 1)
18376 (zero_extend:DI (match_dup 2))
18377 (zero_extend:DI (match_dup 3))))]
18379 if (MEM_P (operands[2]))
18381 operands[5] = operands[2];
18382 operands[2] = operands[4];
18384 else if (MEM_P (operands[3]))
18386 operands[5] = operands[3];
18387 operands[3] = operands[4];
18390 gcc_unreachable ();
18393 (define_expand "mov<mode>cc"
18394 [(set (match_operand:X87MODEF 0 "register_operand")
18395 (if_then_else:X87MODEF
18396 (match_operand 1 "comparison_operator")
18397 (match_operand:X87MODEF 2 "register_operand")
18398 (match_operand:X87MODEF 3 "register_operand")))]
18399 "(TARGET_80387 && TARGET_CMOVE)
18400 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
18401 "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
18403 (define_insn "*movxfcc_1"
18404 [(set (match_operand:XF 0 "register_operand" "=f,f")
18405 (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
18406 [(reg FLAGS_REG) (const_int 0)])
18407 (match_operand:XF 2 "register_operand" "f,0")
18408 (match_operand:XF 3 "register_operand" "0,f")))]
18409 "TARGET_80387 && TARGET_CMOVE"
18411 fcmov%F1\t{%2, %0|%0, %2}
18412 fcmov%f1\t{%3, %0|%0, %3}"
18413 [(set_attr "type" "fcmov")
18414 (set_attr "mode" "XF")])
18416 (define_insn "*movdfcc_1"
18417 [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r,r ,r")
18418 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
18419 [(reg FLAGS_REG) (const_int 0)])
18420 (match_operand:DF 2 "nonimmediate_operand"
18422 (match_operand:DF 3 "nonimmediate_operand"
18423 "0 ,f,0 ,rm,0, rm")))]
18424 "TARGET_80387 && TARGET_CMOVE
18425 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
18427 fcmov%F1\t{%2, %0|%0, %2}
18428 fcmov%f1\t{%3, %0|%0, %3}
18431 cmov%O2%C1\t{%2, %0|%0, %2}
18432 cmov%O2%c1\t{%3, %0|%0, %3}"
18433 [(set_attr "isa" "*,*,nox64,nox64,x64,x64")
18434 (set_attr "type" "fcmov,fcmov,multi,multi,icmov,icmov")
18435 (set_attr "mode" "DF,DF,DI,DI,DI,DI")])
18438 [(set (match_operand:DF 0 "general_reg_operand")
18439 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
18440 [(reg FLAGS_REG) (const_int 0)])
18441 (match_operand:DF 2 "nonimmediate_operand")
18442 (match_operand:DF 3 "nonimmediate_operand")))]
18443 "!TARGET_64BIT && reload_completed"
18444 [(set (match_dup 2)
18445 (if_then_else:SI (match_dup 1) (match_dup 4) (match_dup 5)))
18447 (if_then_else:SI (match_dup 1) (match_dup 6) (match_dup 7)))]
18449 split_double_mode (DImode, &operands[2], 2, &operands[4], &operands[6]);
18450 split_double_mode (DImode, &operands[0], 1, &operands[2], &operands[3]);
18453 (define_insn "*movsfcc_1_387"
18454 [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
18455 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
18456 [(reg FLAGS_REG) (const_int 0)])
18457 (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
18458 (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
18459 "TARGET_80387 && TARGET_CMOVE
18460 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
18462 fcmov%F1\t{%2, %0|%0, %2}
18463 fcmov%f1\t{%3, %0|%0, %3}
18464 cmov%O2%C1\t{%2, %0|%0, %2}
18465 cmov%O2%c1\t{%3, %0|%0, %3}"
18466 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
18467 (set_attr "mode" "SF,SF,SI,SI")])
18469 ;; Don't do conditional moves with memory inputs. This splitter helps
18470 ;; register starved x86_32 by forcing inputs into registers before reload.
18472 [(set (match_operand:MODEF 0 "register_operand")
18473 (if_then_else:MODEF (match_operator 1 "ix86_comparison_operator"
18474 [(reg FLAGS_REG) (const_int 0)])
18475 (match_operand:MODEF 2 "nonimmediate_operand")
18476 (match_operand:MODEF 3 "nonimmediate_operand")))]
18477 "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
18478 && TARGET_AVOID_MEM_OPND_FOR_CMOVE
18479 && (MEM_P (operands[2]) || MEM_P (operands[3]))
18480 && can_create_pseudo_p ()
18481 && optimize_insn_for_speed_p ()"
18482 [(set (match_dup 0)
18483 (if_then_else:MODEF (match_dup 1) (match_dup 2) (match_dup 3)))]
18485 if (MEM_P (operands[2]))
18486 operands[2] = force_reg (<MODE>mode, operands[2]);
18487 if (MEM_P (operands[3]))
18488 operands[3] = force_reg (<MODE>mode, operands[3]);
18491 ;; Don't do conditional moves with memory inputs
18493 [(match_scratch:MODEF 4 "r")
18494 (set (match_operand:MODEF 0 "general_reg_operand")
18495 (if_then_else:MODEF (match_operator 1 "fcmov_comparison_operator"
18496 [(reg FLAGS_REG) (const_int 0)])
18497 (match_operand:MODEF 2 "nonimmediate_operand")
18498 (match_operand:MODEF 3 "nonimmediate_operand")))]
18499 "(<MODE>mode != DFmode || TARGET_64BIT)
18500 && TARGET_80387 && TARGET_CMOVE
18501 && TARGET_AVOID_MEM_OPND_FOR_CMOVE
18502 && (MEM_P (operands[2]) || MEM_P (operands[3]))
18503 && optimize_insn_for_speed_p ()"
18504 [(set (match_dup 4) (match_dup 5))
18506 (if_then_else:MODEF (match_dup 1) (match_dup 2) (match_dup 3)))]
18508 if (MEM_P (operands[2]))
18510 operands[5] = operands[2];
18511 operands[2] = operands[4];
18513 else if (MEM_P (operands[3]))
18515 operands[5] = operands[3];
18516 operands[3] = operands[4];
18519 gcc_unreachable ();
18522 ;; All moves in XOP pcmov instructions are 128 bits and hence we restrict
18523 ;; the scalar versions to have only XMM registers as operands.
18525 ;; XOP conditional move
18526 (define_insn "*xop_pcmov_<mode>"
18527 [(set (match_operand:MODEF 0 "register_operand" "=x")
18528 (if_then_else:MODEF
18529 (match_operand:MODEF 1 "register_operand" "x")
18530 (match_operand:MODEF 2 "register_operand" "x")
18531 (match_operand:MODEF 3 "register_operand" "x")))]
18533 "vpcmov\t{%1, %3, %2, %0|%0, %2, %3, %1}"
18534 [(set_attr "type" "sse4arg")])
18536 ;; These versions of the min/max patterns are intentionally ignorant of
18537 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
18538 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
18539 ;; are undefined in this condition, we're certain this is correct.
18541 (define_insn "<code><mode>3"
18542 [(set (match_operand:MODEF 0 "register_operand" "=x,v")
18544 (match_operand:MODEF 1 "nonimmediate_operand" "%0,v")
18545 (match_operand:MODEF 2 "nonimmediate_operand" "xm,vm")))]
18546 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
18548 <maxmin_float><ssemodesuffix>\t{%2, %0|%0, %2}
18549 v<maxmin_float><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
18550 [(set_attr "isa" "noavx,avx")
18551 (set_attr "prefix" "orig,vex")
18552 (set_attr "type" "sseadd")
18553 (set_attr "mode" "<MODE>")])
18555 ;; These versions of the min/max patterns implement exactly the operations
18556 ;; min = (op1 < op2 ? op1 : op2)
18557 ;; max = (!(op1 < op2) ? op1 : op2)
18558 ;; Their operands are not commutative, and thus they may be used in the
18559 ;; presence of -0.0 and NaN.
18561 (define_insn "*ieee_s<ieee_maxmin><mode>3"
18562 [(set (match_operand:MODEF 0 "register_operand" "=x,v")
18564 [(match_operand:MODEF 1 "register_operand" "0,v")
18565 (match_operand:MODEF 2 "nonimmediate_operand" "xm,vm")]
18567 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
18569 <ieee_maxmin><ssemodesuffix>\t{%2, %0|%0, %2}
18570 v<ieee_maxmin><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
18571 [(set_attr "isa" "noavx,avx")
18572 (set_attr "prefix" "orig,maybe_evex")
18573 (set_attr "type" "sseadd")
18574 (set_attr "mode" "<MODE>")])
18576 ;; Make two stack loads independent:
18578 ;; fld %st(0) -> fld bb
18579 ;; fmul bb fmul %st(1), %st
18581 ;; Actually we only match the last two instructions for simplicity.
18584 [(set (match_operand 0 "fp_register_operand")
18585 (match_operand 1 "fp_register_operand"))
18587 (match_operator 2 "binary_fp_operator"
18589 (match_operand 3 "memory_operand")]))]
18590 "REGNO (operands[0]) != REGNO (operands[1])"
18591 [(set (match_dup 0) (match_dup 3))
18594 [(match_dup 5) (match_dup 4)]))]
18596 operands[4] = operands[0];
18597 operands[5] = operands[1];
18599 /* The % modifier is not operational anymore in peephole2's, so we have to
18600 swap the operands manually in the case of addition and multiplication. */
18601 if (COMMUTATIVE_ARITH_P (operands[2]))
18602 std::swap (operands[4], operands[5]);
18606 [(set (match_operand 0 "fp_register_operand")
18607 (match_operand 1 "fp_register_operand"))
18609 (match_operator 2 "binary_fp_operator"
18610 [(match_operand 3 "memory_operand")
18612 "REGNO (operands[0]) != REGNO (operands[1])"
18613 [(set (match_dup 0) (match_dup 3))
18616 [(match_dup 4) (match_dup 5)]))]
18618 operands[4] = operands[0];
18619 operands[5] = operands[1];
18621 /* The % modifier is not operational anymore in peephole2's, so we have to
18622 swap the operands manually in the case of addition and multiplication. */
18623 if (COMMUTATIVE_ARITH_P (operands[2]))
18624 std::swap (operands[4], operands[5]);
18627 ;; Conditional addition patterns
18628 (define_expand "add<mode>cc"
18629 [(match_operand:SWI 0 "register_operand")
18630 (match_operand 1 "ordered_comparison_operator")
18631 (match_operand:SWI 2 "register_operand")
18632 (match_operand:SWI 3 "const_int_operand")]
18634 "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
18636 ;; Misc patterns (?)
18638 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
18639 ;; Otherwise there will be nothing to keep
18641 ;; [(set (reg ebp) (reg esp))]
18642 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
18643 ;; (clobber (eflags)]
18644 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
18646 ;; in proper program order.
18648 (define_insn "pro_epilogue_adjust_stack_<mode>_add"
18649 [(set (match_operand:P 0 "register_operand" "=r,r")
18650 (plus:P (match_operand:P 1 "register_operand" "0,r")
18651 (match_operand:P 2 "<nonmemory_operand>" "r<i>,l<i>")))
18652 (clobber (reg:CC FLAGS_REG))
18653 (clobber (mem:BLK (scratch)))]
18656 switch (get_attr_type (insn))
18659 return "mov{<imodesuffix>}\t{%1, %0|%0, %1}";
18662 gcc_assert (rtx_equal_p (operands[0], operands[1]));
18663 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
18664 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
18666 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
18669 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
18670 return "lea{<imodesuffix>}\t{%E2, %0|%0, %E2}";
18673 [(set (attr "type")
18674 (cond [(and (eq_attr "alternative" "0")
18675 (not (match_test "TARGET_OPT_AGU")))
18676 (const_string "alu")
18677 (match_operand:<MODE> 2 "const0_operand")
18678 (const_string "imov")
18680 (const_string "lea")))
18681 (set (attr "length_immediate")
18682 (cond [(eq_attr "type" "imov")
18684 (and (eq_attr "type" "alu")
18685 (match_operand 2 "const128_operand"))
18688 (const_string "*")))
18689 (set_attr "mode" "<MODE>")])
18691 (define_insn "pro_epilogue_adjust_stack_<mode>_sub"
18692 [(set (match_operand:P 0 "register_operand" "=r")
18693 (minus:P (match_operand:P 1 "register_operand" "0")
18694 (match_operand:P 2 "register_operand" "r")))
18695 (clobber (reg:CC FLAGS_REG))
18696 (clobber (mem:BLK (scratch)))]
18698 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
18699 [(set_attr "type" "alu")
18700 (set_attr "mode" "<MODE>")])
18702 (define_insn "allocate_stack_worker_probe_<mode>"
18703 [(set (match_operand:P 0 "register_operand" "=a")
18704 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
18705 UNSPECV_STACK_PROBE))
18706 (clobber (reg:CC FLAGS_REG))]
18707 "ix86_target_stack_probe ()"
18708 "call\t___chkstk_ms"
18709 [(set_attr "type" "multi")
18710 (set_attr "length" "5")])
18712 (define_expand "allocate_stack"
18713 [(match_operand 0 "register_operand")
18714 (match_operand 1 "general_operand")]
18715 "ix86_target_stack_probe ()"
18719 #ifndef CHECK_STACK_LIMIT
18720 #define CHECK_STACK_LIMIT 0
18723 if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
18724 && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
18728 rtx (*insn) (rtx, rtx);
18730 x = copy_to_mode_reg (Pmode, operands[1]);
18732 insn = (TARGET_64BIT
18733 ? gen_allocate_stack_worker_probe_di
18734 : gen_allocate_stack_worker_probe_si);
18736 emit_insn (insn (x, x));
18739 x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, x,
18740 stack_pointer_rtx, 0, OPTAB_DIRECT);
18742 if (x != stack_pointer_rtx)
18743 emit_move_insn (stack_pointer_rtx, x);
18745 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
18749 (define_expand "probe_stack"
18750 [(match_operand 0 "memory_operand")]
18753 rtx (*insn) (rtx, rtx)
18754 = (GET_MODE (operands[0]) == DImode
18755 ? gen_probe_stack_di : gen_probe_stack_si);
18757 emit_insn (insn (operands[0], const0_rtx));
18761 ;; Use OR for stack probes, this is shorter.
18762 (define_insn "probe_stack_<mode>"
18763 [(set (match_operand:W 0 "memory_operand" "=m")
18764 (unspec:W [(match_operand:W 1 "const0_operand")]
18765 UNSPEC_PROBE_STACK))
18766 (clobber (reg:CC FLAGS_REG))]
18768 "or{<imodesuffix>}\t{%1, %0|%0, %1}"
18769 [(set_attr "type" "alu1")
18770 (set_attr "mode" "<MODE>")
18771 (set_attr "length_immediate" "1")])
18773 (define_insn "adjust_stack_and_probe<mode>"
18774 [(set (match_operand:P 0 "register_operand" "=r")
18775 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
18776 UNSPECV_PROBE_STACK_RANGE))
18777 (set (reg:P SP_REG)
18778 (minus:P (reg:P SP_REG) (match_operand:P 2 "const_int_operand" "n")))
18779 (clobber (reg:CC FLAGS_REG))
18780 (clobber (mem:BLK (scratch)))]
18782 "* return output_adjust_stack_and_probe (operands[0]);"
18783 [(set_attr "type" "multi")])
18785 (define_insn "probe_stack_range<mode>"
18786 [(set (match_operand:P 0 "register_operand" "=r")
18787 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
18788 (match_operand:P 2 "const_int_operand" "n")]
18789 UNSPECV_PROBE_STACK_RANGE))
18790 (clobber (reg:CC FLAGS_REG))]
18792 "* return output_probe_stack_range (operands[0], operands[2]);"
18793 [(set_attr "type" "multi")])
18795 (define_expand "builtin_setjmp_receiver"
18796 [(label_ref (match_operand 0))]
18797 "!TARGET_64BIT && flag_pic"
18803 rtx_code_label *label_rtx = gen_label_rtx ();
18804 emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
18805 xops[0] = xops[1] = pic_offset_table_rtx;
18806 xops[2] = machopic_gen_offset (gen_rtx_LABEL_REF (SImode, label_rtx));
18807 ix86_expand_binary_operator (MINUS, SImode, xops);
18811 emit_insn (gen_set_got (pic_offset_table_rtx));
18815 (define_expand "save_stack_nonlocal"
18816 [(set (match_operand 0 "memory_operand")
18817 (match_operand 1 "register_operand"))]
18821 if ((flag_cf_protection & CF_RETURN))
18823 /* Copy shadow stack pointer to the first slot and stack ppointer
18824 to the second slot. */
18825 rtx ssp_slot = adjust_address (operands[0], word_mode, 0);
18826 stack_slot = adjust_address (operands[0], Pmode, UNITS_PER_WORD);
18827 rtx ssp = gen_reg_rtx (word_mode);
18828 emit_insn ((word_mode == SImode)
18829 ? gen_rdsspsi (ssp)
18830 : gen_rdsspdi (ssp));
18831 emit_move_insn (ssp_slot, ssp);
18834 stack_slot = adjust_address (operands[0], Pmode, 0);
18835 emit_move_insn (stack_slot, operands[1]);
18839 (define_expand "restore_stack_nonlocal"
18840 [(set (match_operand 0 "register_operand" "")
18841 (match_operand 1 "memory_operand" ""))]
18845 if ((flag_cf_protection & CF_RETURN))
18847 /* Restore shadow stack pointer from the first slot and stack
18848 pointer from the second slot. */
18849 rtx ssp_slot = adjust_address (operands[1], word_mode, 0);
18850 stack_slot = adjust_address (operands[1], Pmode, UNITS_PER_WORD);
18852 rtx flags, jump, noadj_label, inc_label, loop_label;
18853 rtx reg_adj, reg_ssp, tmp, clob;
18855 /* Get the current shadow stack pointer. The code below will check if
18856 SHSTK feature is enabled. If it is not enabled the RDSSP instruction
18858 reg_ssp = gen_reg_rtx (word_mode);
18859 emit_insn (gen_rtx_SET (reg_ssp, const0_rtx));
18860 emit_insn ((word_mode == SImode)
18861 ? gen_rdsspsi (reg_ssp)
18862 : gen_rdsspdi (reg_ssp));
18864 /* Compare through substraction the saved and the current ssp to decide
18865 if ssp has to be adjusted. */
18866 tmp = gen_rtx_SET (reg_ssp, gen_rtx_MINUS (word_mode, reg_ssp,
18868 clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
18869 tmp = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, tmp, clob));
18872 /* Compare and jump over adjustment code. */
18873 noadj_label = gen_label_rtx ();
18874 flags = gen_rtx_REG (CCZmode, FLAGS_REG);
18875 tmp = gen_rtx_EQ (VOIDmode, flags, const0_rtx);
18876 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
18877 gen_rtx_LABEL_REF (VOIDmode, noadj_label),
18879 jump = emit_jump_insn (gen_rtx_SET (pc_rtx, tmp));
18880 JUMP_LABEL (jump) = noadj_label;
18882 /* Compute the numebr of frames to adjust. */
18883 reg_adj = gen_lowpart (ptr_mode, reg_ssp);
18884 tmp = gen_rtx_SET (reg_adj,
18885 gen_rtx_LSHIFTRT (ptr_mode,
18886 negate_rtx (ptr_mode, reg_adj),
18887 GEN_INT ((word_mode == SImode)
18890 clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
18891 tmp = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, tmp, clob));
18894 /* Check if number of frames <= 255 so no loop is needed. */
18895 tmp = gen_rtx_COMPARE (CCmode, reg_adj, GEN_INT (255));
18896 flags = gen_rtx_REG (CCmode, FLAGS_REG);
18897 emit_insn (gen_rtx_SET (flags, tmp));
18899 inc_label = gen_label_rtx ();
18900 tmp = gen_rtx_LEU (VOIDmode, flags, const0_rtx);
18901 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
18902 gen_rtx_LABEL_REF (VOIDmode, inc_label),
18904 jump = emit_jump_insn (gen_rtx_SET (pc_rtx, tmp));
18905 JUMP_LABEL (jump) = inc_label;
18907 rtx reg_255 = gen_reg_rtx (word_mode);
18908 emit_move_insn (reg_255, GEN_INT (255));
18910 /* Adjust the ssp in a loop. */
18911 loop_label = gen_label_rtx ();
18912 emit_label (loop_label);
18913 LABEL_NUSES (loop_label) = 1;
18915 emit_insn ((word_mode == SImode)
18916 ? gen_incsspsi (reg_255)
18917 : gen_incsspdi (reg_255));
18918 tmp = gen_rtx_SET (reg_adj, gen_rtx_MINUS (ptr_mode,
18921 clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
18922 tmp = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, tmp, clob));
18925 tmp = gen_rtx_COMPARE (CCmode, reg_adj, GEN_INT (255));
18926 flags = gen_rtx_REG (CCmode, FLAGS_REG);
18927 emit_insn (gen_rtx_SET (flags, tmp));
18929 /* Jump to the loop label. */
18930 tmp = gen_rtx_GTU (VOIDmode, flags, const0_rtx);
18931 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
18932 gen_rtx_LABEL_REF (VOIDmode, loop_label),
18934 jump = emit_jump_insn (gen_rtx_SET (pc_rtx, tmp));
18935 JUMP_LABEL (jump) = loop_label;
18937 emit_label (inc_label);
18938 LABEL_NUSES (inc_label) = 1;
18939 emit_insn ((word_mode == SImode)
18940 ? gen_incsspsi (reg_ssp)
18941 : gen_incsspdi (reg_ssp));
18943 emit_label (noadj_label);
18944 LABEL_NUSES (noadj_label) = 1;
18947 stack_slot = adjust_address (operands[1], Pmode, 0);
18948 emit_move_insn (operands[0], stack_slot);
18953 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
18954 ;; Do not split instructions with mask registers.
18956 [(set (match_operand 0 "general_reg_operand")
18957 (match_operator 3 "promotable_binary_operator"
18958 [(match_operand 1 "general_reg_operand")
18959 (match_operand 2 "aligned_operand")]))
18960 (clobber (reg:CC FLAGS_REG))]
18961 "! TARGET_PARTIAL_REG_STALL && reload_completed
18962 && ((GET_MODE (operands[0]) == HImode
18963 && ((optimize_function_for_speed_p (cfun) && !TARGET_FAST_PREFIX)
18964 /* ??? next two lines just !satisfies_constraint_K (...) */
18965 || !CONST_INT_P (operands[2])
18966 || satisfies_constraint_K (operands[2])))
18967 || (GET_MODE (operands[0]) == QImode
18968 && (TARGET_PROMOTE_QImode || optimize_function_for_size_p (cfun))))"
18969 [(parallel [(set (match_dup 0)
18970 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
18971 (clobber (reg:CC FLAGS_REG))])]
18973 operands[0] = gen_lowpart (SImode, operands[0]);
18974 operands[1] = gen_lowpart (SImode, operands[1]);
18975 if (GET_CODE (operands[3]) != ASHIFT)
18976 operands[2] = gen_lowpart (SImode, operands[2]);
18977 operands[3] = shallow_copy_rtx (operands[3]);
18978 PUT_MODE (operands[3], SImode);
18981 ; Promote the QImode tests, as i386 has encoding of the AND
18982 ; instruction with 32-bit sign-extended immediate and thus the
18983 ; instruction size is unchanged, except in the %eax case for
18984 ; which it is increased by one byte, hence the ! optimize_size.
18986 [(set (match_operand 0 "flags_reg_operand")
18987 (match_operator 2 "compare_operator"
18988 [(and (match_operand 3 "aligned_operand")
18989 (match_operand 4 "const_int_operand"))
18991 (set (match_operand 1 "register_operand")
18992 (and (match_dup 3) (match_dup 4)))]
18993 "! TARGET_PARTIAL_REG_STALL && reload_completed
18994 && optimize_insn_for_speed_p ()
18995 && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
18996 || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))
18997 /* Ensure that the operand will remain sign-extended immediate. */
18998 && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)"
18999 [(parallel [(set (match_dup 0)
19000 (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
19003 (and:SI (match_dup 3) (match_dup 4)))])]
19006 = gen_int_mode (INTVAL (operands[4])
19007 & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
19008 operands[1] = gen_lowpart (SImode, operands[1]);
19009 operands[3] = gen_lowpart (SImode, operands[3]);
19012 ; Don't promote the QImode tests, as i386 doesn't have encoding of
19013 ; the TEST instruction with 32-bit sign-extended immediate and thus
19014 ; the instruction size would at least double, which is not what we
19015 ; want even with ! optimize_size.
19017 [(set (match_operand 0 "flags_reg_operand")
19018 (match_operator 1 "compare_operator"
19019 [(and (match_operand:HI 2 "aligned_operand")
19020 (match_operand:HI 3 "const_int_operand"))
19022 "! TARGET_PARTIAL_REG_STALL && reload_completed
19023 && ! TARGET_FAST_PREFIX
19024 && optimize_insn_for_speed_p ()
19025 /* Ensure that the operand will remain sign-extended immediate. */
19026 && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)"
19027 [(set (match_dup 0)
19028 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
19032 = gen_int_mode (INTVAL (operands[3])
19033 & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
19034 operands[2] = gen_lowpart (SImode, operands[2]);
19038 [(set (match_operand 0 "register_operand")
19039 (neg (match_operand 1 "register_operand")))
19040 (clobber (reg:CC FLAGS_REG))]
19041 "! TARGET_PARTIAL_REG_STALL && reload_completed
19042 && (GET_MODE (operands[0]) == HImode
19043 || (GET_MODE (operands[0]) == QImode
19044 && (TARGET_PROMOTE_QImode
19045 || optimize_insn_for_size_p ())))"
19046 [(parallel [(set (match_dup 0)
19047 (neg:SI (match_dup 1)))
19048 (clobber (reg:CC FLAGS_REG))])]
19050 operands[0] = gen_lowpart (SImode, operands[0]);
19051 operands[1] = gen_lowpart (SImode, operands[1]);
19054 ;; Do not split instructions with mask regs.
19056 [(set (match_operand 0 "general_reg_operand")
19057 (not (match_operand 1 "general_reg_operand")))]
19058 "! TARGET_PARTIAL_REG_STALL && reload_completed
19059 && (GET_MODE (operands[0]) == HImode
19060 || (GET_MODE (operands[0]) == QImode
19061 && (TARGET_PROMOTE_QImode
19062 || optimize_insn_for_size_p ())))"
19063 [(set (match_dup 0)
19064 (not:SI (match_dup 1)))]
19066 operands[0] = gen_lowpart (SImode, operands[0]);
19067 operands[1] = gen_lowpart (SImode, operands[1]);
19070 ;; RTL Peephole optimizations, run before sched2. These primarily look to
19071 ;; transform a complex memory operation into two memory to register operations.
19073 ;; Don't push memory operands
19075 [(set (match_operand:SWI 0 "push_operand")
19076 (match_operand:SWI 1 "memory_operand"))
19077 (match_scratch:SWI 2 "<r>")]
19078 "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
19079 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19080 [(set (match_dup 2) (match_dup 1))
19081 (set (match_dup 0) (match_dup 2))])
19083 ;; We need to handle SFmode only, because DFmode and XFmode are split to
19086 [(set (match_operand:SF 0 "push_operand")
19087 (match_operand:SF 1 "memory_operand"))
19088 (match_scratch:SF 2 "r")]
19089 "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
19090 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19091 [(set (match_dup 2) (match_dup 1))
19092 (set (match_dup 0) (match_dup 2))])
19094 ;; Don't move an immediate directly to memory when the instruction
19095 ;; gets too big, or if LCP stalls are a problem for 16-bit moves.
19097 [(match_scratch:SWI124 1 "<r>")
19098 (set (match_operand:SWI124 0 "memory_operand")
19100 "optimize_insn_for_speed_p ()
19101 && ((<MODE>mode == HImode
19102 && TARGET_LCP_STALL)
19103 || (!TARGET_USE_MOV0
19104 && TARGET_SPLIT_LONG_MOVES
19105 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn))
19106 && peep2_regno_dead_p (0, FLAGS_REG)"
19107 [(parallel [(set (match_dup 2) (const_int 0))
19108 (clobber (reg:CC FLAGS_REG))])
19109 (set (match_dup 0) (match_dup 1))]
19110 "operands[2] = gen_lowpart (SImode, operands[1]);")
19113 [(match_scratch:SWI124 2 "<r>")
19114 (set (match_operand:SWI124 0 "memory_operand")
19115 (match_operand:SWI124 1 "immediate_operand"))]
19116 "optimize_insn_for_speed_p ()
19117 && ((<MODE>mode == HImode
19118 && TARGET_LCP_STALL)
19119 || (TARGET_SPLIT_LONG_MOVES
19120 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn))"
19121 [(set (match_dup 2) (match_dup 1))
19122 (set (match_dup 0) (match_dup 2))])
19124 ;; Don't compare memory with zero, load and use a test instead.
19126 [(set (match_operand 0 "flags_reg_operand")
19127 (match_operator 1 "compare_operator"
19128 [(match_operand:SI 2 "memory_operand")
19130 (match_scratch:SI 3 "r")]
19131 "optimize_insn_for_speed_p () && ix86_match_ccmode (insn, CCNOmode)"
19132 [(set (match_dup 3) (match_dup 2))
19133 (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))])
19135 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
19136 ;; Don't split NOTs with a displacement operand, because resulting XOR
19137 ;; will not be pairable anyway.
19139 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
19140 ;; represented using a modRM byte. The XOR replacement is long decoded,
19141 ;; so this split helps here as well.
19143 ;; Note: Can't do this as a regular split because we can't get proper
19144 ;; lifetime information then.
19147 [(set (match_operand:SWI124 0 "nonimmediate_gr_operand")
19148 (not:SWI124 (match_operand:SWI124 1 "nonimmediate_gr_operand")))]
19149 "optimize_insn_for_speed_p ()
19150 && ((TARGET_NOT_UNPAIRABLE
19151 && (!MEM_P (operands[0])
19152 || !memory_displacement_operand (operands[0], <MODE>mode)))
19153 || (TARGET_NOT_VECTORMODE
19154 && long_memory_operand (operands[0], <MODE>mode)))
19155 && peep2_regno_dead_p (0, FLAGS_REG)"
19156 [(parallel [(set (match_dup 0)
19157 (xor:SWI124 (match_dup 1) (const_int -1)))
19158 (clobber (reg:CC FLAGS_REG))])])
19160 ;; Non pairable "test imm, reg" instructions can be translated to
19161 ;; "and imm, reg" if reg dies. The "and" form is also shorter (one
19162 ;; byte opcode instead of two, have a short form for byte operands),
19163 ;; so do it for other CPUs as well. Given that the value was dead,
19164 ;; this should not create any new dependencies. Pass on the sub-word
19165 ;; versions if we're concerned about partial register stalls.
19168 [(set (match_operand 0 "flags_reg_operand")
19169 (match_operator 1 "compare_operator"
19170 [(and:SI (match_operand:SI 2 "register_operand")
19171 (match_operand:SI 3 "immediate_operand"))
19173 "ix86_match_ccmode (insn, CCNOmode)
19174 && (REGNO (operands[2]) != AX_REG
19175 || satisfies_constraint_K (operands[3]))
19176 && peep2_reg_dead_p (1, operands[2])"
19178 [(set (match_dup 0)
19179 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
19182 (and:SI (match_dup 2) (match_dup 3)))])])
19184 ;; We don't need to handle HImode case, because it will be promoted to SImode
19185 ;; on ! TARGET_PARTIAL_REG_STALL
19188 [(set (match_operand 0 "flags_reg_operand")
19189 (match_operator 1 "compare_operator"
19190 [(and:QI (match_operand:QI 2 "register_operand")
19191 (match_operand:QI 3 "immediate_operand"))
19193 "! TARGET_PARTIAL_REG_STALL
19194 && ix86_match_ccmode (insn, CCNOmode)
19195 && REGNO (operands[2]) != AX_REG
19196 && peep2_reg_dead_p (1, operands[2])"
19198 [(set (match_dup 0)
19199 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
19202 (and:QI (match_dup 2) (match_dup 3)))])])
19205 [(set (match_operand 0 "flags_reg_operand")
19206 (match_operator 1 "compare_operator"
19209 (zero_extract:SI (match_operand 2 "QIreg_operand")
19212 (match_operand 3 "const_int_operand"))
19214 "! TARGET_PARTIAL_REG_STALL
19215 && ix86_match_ccmode (insn, CCNOmode)
19216 && REGNO (operands[2]) != AX_REG
19217 && peep2_reg_dead_p (1, operands[2])"
19219 [(set (match_dup 0)
19223 (zero_extract:SI (match_dup 2)
19228 (set (zero_extract:SI (match_dup 2)
19234 (zero_extract:SI (match_dup 2)
19237 (match_dup 3)) 0))])])
19239 ;; Don't do logical operations with memory inputs.
19241 [(match_scratch:SWI 2 "<r>")
19242 (parallel [(set (match_operand:SWI 0 "register_operand")
19243 (match_operator:SWI 3 "arith_or_logical_operator"
19245 (match_operand:SWI 1 "memory_operand")]))
19246 (clobber (reg:CC FLAGS_REG))])]
19247 "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
19248 [(set (match_dup 2) (match_dup 1))
19249 (parallel [(set (match_dup 0)
19250 (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
19251 (clobber (reg:CC FLAGS_REG))])])
19254 [(match_scratch:SWI 2 "<r>")
19255 (parallel [(set (match_operand:SWI 0 "register_operand")
19256 (match_operator:SWI 3 "arith_or_logical_operator"
19257 [(match_operand:SWI 1 "memory_operand")
19259 (clobber (reg:CC FLAGS_REG))])]
19260 "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
19261 [(set (match_dup 2) (match_dup 1))
19262 (parallel [(set (match_dup 0)
19263 (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
19264 (clobber (reg:CC FLAGS_REG))])])
19266 ;; Prefer Load+RegOp to Mov+MemOp. Watch out for cases when
19267 ;; the memory address refers to the destination of the load!
19270 [(set (match_operand:SWI 0 "general_reg_operand")
19271 (match_operand:SWI 1 "general_reg_operand"))
19272 (parallel [(set (match_dup 0)
19273 (match_operator:SWI 3 "commutative_operator"
19275 (match_operand:SWI 2 "memory_operand")]))
19276 (clobber (reg:CC FLAGS_REG))])]
19277 "REGNO (operands[0]) != REGNO (operands[1])
19278 && (<MODE>mode != QImode
19279 || any_QIreg_operand (operands[1], QImode))"
19280 [(set (match_dup 0) (match_dup 4))
19281 (parallel [(set (match_dup 0)
19282 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))
19283 (clobber (reg:CC FLAGS_REG))])]
19284 "operands[4] = replace_rtx (operands[2], operands[0], operands[1], true);")
19287 [(set (match_operand 0 "mmx_reg_operand")
19288 (match_operand 1 "mmx_reg_operand"))
19290 (match_operator 3 "commutative_operator"
19292 (match_operand 2 "memory_operand")]))]
19293 "REGNO (operands[0]) != REGNO (operands[1])"
19294 [(set (match_dup 0) (match_dup 2))
19296 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))])
19299 [(set (match_operand 0 "sse_reg_operand")
19300 (match_operand 1 "sse_reg_operand"))
19302 (match_operator 3 "commutative_operator"
19304 (match_operand 2 "memory_operand")]))]
19305 "REGNO (operands[0]) != REGNO (operands[1])"
19306 [(set (match_dup 0) (match_dup 2))
19308 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))])
19310 ; Don't do logical operations with memory outputs
19312 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
19313 ; instruction into two 1-uop insns plus a 2-uop insn. That last has
19314 ; the same decoder scheduling characteristics as the original.
19317 [(match_scratch:SWI 2 "<r>")
19318 (parallel [(set (match_operand:SWI 0 "memory_operand")
19319 (match_operator:SWI 3 "arith_or_logical_operator"
19321 (match_operand:SWI 1 "<nonmemory_operand>")]))
19322 (clobber (reg:CC FLAGS_REG))])]
19323 "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())"
19324 [(set (match_dup 2) (match_dup 0))
19325 (parallel [(set (match_dup 2)
19326 (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
19327 (clobber (reg:CC FLAGS_REG))])
19328 (set (match_dup 0) (match_dup 2))])
19331 [(match_scratch:SWI 2 "<r>")
19332 (parallel [(set (match_operand:SWI 0 "memory_operand")
19333 (match_operator:SWI 3 "arith_or_logical_operator"
19334 [(match_operand:SWI 1 "<nonmemory_operand>")
19336 (clobber (reg:CC FLAGS_REG))])]
19337 "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())"
19338 [(set (match_dup 2) (match_dup 0))
19339 (parallel [(set (match_dup 2)
19340 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
19341 (clobber (reg:CC FLAGS_REG))])
19342 (set (match_dup 0) (match_dup 2))])
19344 ;; Attempt to use arith or logical operations with memory outputs with
19345 ;; setting of flags.
19347 [(set (match_operand:SWI 0 "register_operand")
19348 (match_operand:SWI 1 "memory_operand"))
19349 (parallel [(set (match_dup 0)
19350 (match_operator:SWI 3 "plusminuslogic_operator"
19352 (match_operand:SWI 2 "<nonmemory_operand>")]))
19353 (clobber (reg:CC FLAGS_REG))])
19354 (set (match_dup 1) (match_dup 0))
19355 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
19356 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
19357 && peep2_reg_dead_p (4, operands[0])
19358 && !reg_overlap_mentioned_p (operands[0], operands[1])
19359 && !reg_overlap_mentioned_p (operands[0], operands[2])
19360 && (<MODE>mode != QImode
19361 || immediate_operand (operands[2], QImode)
19362 || any_QIreg_operand (operands[2], QImode))
19363 && ix86_match_ccmode (peep2_next_insn (3),
19364 (GET_CODE (operands[3]) == PLUS
19365 || GET_CODE (operands[3]) == MINUS)
19366 ? CCGOCmode : CCNOmode)"
19367 [(parallel [(set (match_dup 4) (match_dup 6))
19368 (set (match_dup 1) (match_dup 5))])]
19370 operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
19372 = gen_rtx_fmt_ee (GET_CODE (operands[3]), GET_MODE (operands[3]),
19373 copy_rtx (operands[1]),
19376 = gen_rtx_COMPARE (GET_MODE (operands[4]),
19377 copy_rtx (operands[5]),
19381 ;; Likewise for cmpelim optimized pattern.
19383 [(set (match_operand:SWI 0 "register_operand")
19384 (match_operand:SWI 1 "memory_operand"))
19385 (parallel [(set (reg FLAGS_REG)
19386 (compare (match_operator:SWI 3 "plusminuslogic_operator"
19388 (match_operand:SWI 2 "<nonmemory_operand>")])
19390 (set (match_dup 0) (match_dup 3))])
19391 (set (match_dup 1) (match_dup 0))]
19392 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
19393 && peep2_reg_dead_p (3, operands[0])
19394 && !reg_overlap_mentioned_p (operands[0], operands[1])
19395 && !reg_overlap_mentioned_p (operands[0], operands[2])
19396 && ix86_match_ccmode (peep2_next_insn (1),
19397 (GET_CODE (operands[3]) == PLUS
19398 || GET_CODE (operands[3]) == MINUS)
19399 ? CCGOCmode : CCNOmode)"
19400 [(parallel [(set (match_dup 4) (match_dup 6))
19401 (set (match_dup 1) (match_dup 5))])]
19403 operands[4] = SET_DEST (XVECEXP (PATTERN (peep2_next_insn (1)), 0, 0));
19405 = gen_rtx_fmt_ee (GET_CODE (operands[3]), GET_MODE (operands[3]),
19406 copy_rtx (operands[1]), operands[2]);
19408 = gen_rtx_COMPARE (GET_MODE (operands[4]), copy_rtx (operands[5]),
19412 ;; Likewise for instances where we have a lea pattern.
19414 [(set (match_operand:SWI 0 "register_operand")
19415 (match_operand:SWI 1 "memory_operand"))
19416 (set (match_operand:SWI 3 "register_operand")
19417 (plus:SWI (match_dup 0)
19418 (match_operand:SWI 2 "<nonmemory_operand>")))
19419 (set (match_dup 1) (match_dup 3))
19420 (set (reg FLAGS_REG) (compare (match_dup 3) (const_int 0)))]
19421 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
19422 && peep2_reg_dead_p (4, operands[3])
19423 && (rtx_equal_p (operands[0], operands[3])
19424 || peep2_reg_dead_p (2, operands[0]))
19425 && !reg_overlap_mentioned_p (operands[0], operands[1])
19426 && !reg_overlap_mentioned_p (operands[3], operands[1])
19427 && !reg_overlap_mentioned_p (operands[0], operands[2])
19428 && (<MODE>mode != QImode
19429 || immediate_operand (operands[2], QImode)
19430 || any_QIreg_operand (operands[2], QImode))
19431 && ix86_match_ccmode (peep2_next_insn (3), CCGOCmode)"
19432 [(parallel [(set (match_dup 4) (match_dup 6))
19433 (set (match_dup 1) (match_dup 5))])]
19435 operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
19437 = gen_rtx_PLUS (<MODE>mode,
19438 copy_rtx (operands[1]),
19441 = gen_rtx_COMPARE (GET_MODE (operands[4]),
19442 copy_rtx (operands[5]),
19447 [(parallel [(set (match_operand:SWI 0 "register_operand")
19448 (match_operator:SWI 2 "plusminuslogic_operator"
19450 (match_operand:SWI 1 "memory_operand")]))
19451 (clobber (reg:CC FLAGS_REG))])
19452 (set (match_dup 1) (match_dup 0))
19453 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
19454 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
19455 && COMMUTATIVE_ARITH_P (operands[2])
19456 && peep2_reg_dead_p (3, operands[0])
19457 && !reg_overlap_mentioned_p (operands[0], operands[1])
19458 && ix86_match_ccmode (peep2_next_insn (2),
19459 GET_CODE (operands[2]) == PLUS
19460 ? CCGOCmode : CCNOmode)"
19461 [(parallel [(set (match_dup 3) (match_dup 5))
19462 (set (match_dup 1) (match_dup 4))])]
19464 operands[3] = SET_DEST (PATTERN (peep2_next_insn (2)));
19466 = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
19467 copy_rtx (operands[1]),
19470 = gen_rtx_COMPARE (GET_MODE (operands[3]),
19471 copy_rtx (operands[4]),
19475 ;; Likewise for cmpelim optimized pattern.
19477 [(parallel [(set (reg FLAGS_REG)
19478 (compare (match_operator:SWI 2 "plusminuslogic_operator"
19479 [(match_operand:SWI 0 "register_operand")
19480 (match_operand:SWI 1 "memory_operand")])
19482 (set (match_dup 0) (match_dup 2))])
19483 (set (match_dup 1) (match_dup 0))]
19484 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
19485 && COMMUTATIVE_ARITH_P (operands[2])
19486 && peep2_reg_dead_p (2, operands[0])
19487 && !reg_overlap_mentioned_p (operands[0], operands[1])
19488 && ix86_match_ccmode (peep2_next_insn (0),
19489 GET_CODE (operands[2]) == PLUS
19490 ? CCGOCmode : CCNOmode)"
19491 [(parallel [(set (match_dup 3) (match_dup 5))
19492 (set (match_dup 1) (match_dup 4))])]
19494 operands[3] = SET_DEST (XVECEXP (PATTERN (peep2_next_insn (0)), 0, 0));
19496 = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
19497 copy_rtx (operands[1]), operands[0]);
19499 = gen_rtx_COMPARE (GET_MODE (operands[3]), copy_rtx (operands[4]),
19504 [(set (match_operand:SWI12 0 "register_operand")
19505 (match_operand:SWI12 1 "memory_operand"))
19506 (parallel [(set (match_operand:SI 4 "register_operand")
19507 (match_operator:SI 3 "plusminuslogic_operator"
19509 (match_operand:SI 2 "nonmemory_operand")]))
19510 (clobber (reg:CC FLAGS_REG))])
19511 (set (match_dup 1) (match_dup 0))
19512 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
19513 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
19514 && REGNO (operands[0]) == REGNO (operands[4])
19515 && peep2_reg_dead_p (4, operands[0])
19516 && (<MODE>mode != QImode
19517 || immediate_operand (operands[2], SImode)
19518 || any_QIreg_operand (operands[2], SImode))
19519 && !reg_overlap_mentioned_p (operands[0], operands[1])
19520 && !reg_overlap_mentioned_p (operands[0], operands[2])
19521 && ix86_match_ccmode (peep2_next_insn (3),
19522 (GET_CODE (operands[3]) == PLUS
19523 || GET_CODE (operands[3]) == MINUS)
19524 ? CCGOCmode : CCNOmode)"
19525 [(parallel [(set (match_dup 4) (match_dup 6))
19526 (set (match_dup 1) (match_dup 5))])]
19528 operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
19530 = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
19531 copy_rtx (operands[1]),
19532 gen_lowpart (<MODE>mode, operands[2]));
19534 = gen_rtx_COMPARE (GET_MODE (operands[4]),
19535 copy_rtx (operands[5]),
19539 ;; Attempt to always use XOR for zeroing registers (including FP modes).
19541 [(set (match_operand 0 "general_reg_operand")
19542 (match_operand 1 "const0_operand"))]
19543 "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
19544 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
19545 && peep2_regno_dead_p (0, FLAGS_REG)"
19546 [(parallel [(set (match_dup 0) (const_int 0))
19547 (clobber (reg:CC FLAGS_REG))])]
19548 "operands[0] = gen_lowpart (word_mode, operands[0]);")
19551 [(set (strict_low_part (match_operand:SWI12 0 "general_reg_operand"))
19553 "(! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
19554 && peep2_regno_dead_p (0, FLAGS_REG)"
19555 [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
19556 (clobber (reg:CC FLAGS_REG))])])
19558 ;; For HI, SI and DI modes, or $-1,reg is smaller than mov $-1,reg.
19560 [(set (match_operand:SWI248 0 "general_reg_operand")
19562 "(TARGET_MOVE_M1_VIA_OR || optimize_insn_for_size_p ())
19563 && peep2_regno_dead_p (0, FLAGS_REG)"
19564 [(parallel [(set (match_dup 0) (const_int -1))
19565 (clobber (reg:CC FLAGS_REG))])]
19567 if (<MODE_SIZE> < GET_MODE_SIZE (SImode))
19568 operands[0] = gen_lowpart (SImode, operands[0]);
19571 ;; Attempt to convert simple lea to add/shift.
19572 ;; These can be created by move expanders.
19573 ;; Disable PLUS peepholes on TARGET_OPT_AGU, since all
19574 ;; relevant lea instructions were already split.
19577 [(set (match_operand:SWI48 0 "register_operand")
19578 (plus:SWI48 (match_dup 0)
19579 (match_operand:SWI48 1 "<nonmemory_operand>")))]
19581 && peep2_regno_dead_p (0, FLAGS_REG)"
19582 [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1)))
19583 (clobber (reg:CC FLAGS_REG))])])
19586 [(set (match_operand:SWI48 0 "register_operand")
19587 (plus:SWI48 (match_operand:SWI48 1 "<nonmemory_operand>")
19590 && peep2_regno_dead_p (0, FLAGS_REG)"
19591 [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1)))
19592 (clobber (reg:CC FLAGS_REG))])])
19595 [(set (match_operand:DI 0 "register_operand")
19597 (plus:SI (match_operand:SI 1 "register_operand")
19598 (match_operand:SI 2 "nonmemory_operand"))))]
19599 "TARGET_64BIT && !TARGET_OPT_AGU
19600 && REGNO (operands[0]) == REGNO (operands[1])
19601 && peep2_regno_dead_p (0, FLAGS_REG)"
19602 [(parallel [(set (match_dup 0)
19603 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))
19604 (clobber (reg:CC FLAGS_REG))])])
19607 [(set (match_operand:DI 0 "register_operand")
19609 (plus:SI (match_operand:SI 1 "nonmemory_operand")
19610 (match_operand:SI 2 "register_operand"))))]
19611 "TARGET_64BIT && !TARGET_OPT_AGU
19612 && REGNO (operands[0]) == REGNO (operands[2])
19613 && peep2_regno_dead_p (0, FLAGS_REG)"
19614 [(parallel [(set (match_dup 0)
19615 (zero_extend:DI (plus:SI (match_dup 2) (match_dup 1))))
19616 (clobber (reg:CC FLAGS_REG))])])
19619 [(set (match_operand:SWI48 0 "register_operand")
19620 (mult:SWI48 (match_dup 0)
19621 (match_operand:SWI48 1 "const_int_operand")))]
19622 "pow2p_hwi (INTVAL (operands[1]))
19623 && peep2_regno_dead_p (0, FLAGS_REG)"
19624 [(parallel [(set (match_dup 0) (ashift:SWI48 (match_dup 0) (match_dup 1)))
19625 (clobber (reg:CC FLAGS_REG))])]
19626 "operands[1] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
19629 [(set (match_operand:DI 0 "register_operand")
19631 (mult:SI (match_operand:SI 1 "register_operand")
19632 (match_operand:SI 2 "const_int_operand"))))]
19634 && pow2p_hwi (INTVAL (operands[2]))
19635 && REGNO (operands[0]) == REGNO (operands[1])
19636 && peep2_regno_dead_p (0, FLAGS_REG)"
19637 [(parallel [(set (match_dup 0)
19638 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))
19639 (clobber (reg:CC FLAGS_REG))])]
19640 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
19642 ;; The ESP adjustments can be done by the push and pop instructions. Resulting
19643 ;; code is shorter, since push is only 1 byte, while add imm, %esp is 3 bytes.
19644 ;; On many CPUs it is also faster, since special hardware to avoid esp
19645 ;; dependencies is present.
19647 ;; While some of these conversions may be done using splitters, we use
19648 ;; peepholes in order to allow combine_stack_adjustments pass to see
19649 ;; nonobfuscated RTL.
19651 ;; Convert prologue esp subtractions to push.
19652 ;; We need register to push. In order to keep verify_flow_info happy we have
19654 ;; - use scratch and clobber it in order to avoid dependencies
19655 ;; - use already live register
19656 ;; We can't use the second way right now, since there is no reliable way how to
19657 ;; verify that given register is live. First choice will also most likely in
19658 ;; fewer dependencies. On the place of esp adjustments it is very likely that
19659 ;; call clobbered registers are dead. We may want to use base pointer as an
19660 ;; alternative when no register is available later.
19663 [(match_scratch:W 1 "r")
19664 (parallel [(set (reg:P SP_REG)
19665 (plus:P (reg:P SP_REG)
19666 (match_operand:P 0 "const_int_operand")))
19667 (clobber (reg:CC FLAGS_REG))
19668 (clobber (mem:BLK (scratch)))])]
19669 "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
19670 && INTVAL (operands[0]) == -GET_MODE_SIZE (word_mode)
19671 && ix86_red_zone_size == 0"
19672 [(clobber (match_dup 1))
19673 (parallel [(set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
19674 (clobber (mem:BLK (scratch)))])])
19677 [(match_scratch:W 1 "r")
19678 (parallel [(set (reg:P SP_REG)
19679 (plus:P (reg:P SP_REG)
19680 (match_operand:P 0 "const_int_operand")))
19681 (clobber (reg:CC FLAGS_REG))
19682 (clobber (mem:BLK (scratch)))])]
19683 "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
19684 && INTVAL (operands[0]) == -2*GET_MODE_SIZE (word_mode)
19685 && ix86_red_zone_size == 0"
19686 [(clobber (match_dup 1))
19687 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
19688 (parallel [(set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
19689 (clobber (mem:BLK (scratch)))])])
19691 ;; Convert esp subtractions to push.
19693 [(match_scratch:W 1 "r")
19694 (parallel [(set (reg:P SP_REG)
19695 (plus:P (reg:P SP_REG)
19696 (match_operand:P 0 "const_int_operand")))
19697 (clobber (reg:CC FLAGS_REG))])]
19698 "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
19699 && INTVAL (operands[0]) == -GET_MODE_SIZE (word_mode)
19700 && ix86_red_zone_size == 0"
19701 [(clobber (match_dup 1))
19702 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
19705 [(match_scratch:W 1 "r")
19706 (parallel [(set (reg:P SP_REG)
19707 (plus:P (reg:P SP_REG)
19708 (match_operand:P 0 "const_int_operand")))
19709 (clobber (reg:CC FLAGS_REG))])]
19710 "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
19711 && INTVAL (operands[0]) == -2*GET_MODE_SIZE (word_mode)
19712 && ix86_red_zone_size == 0"
19713 [(clobber (match_dup 1))
19714 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
19715 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
19717 ;; Convert epilogue deallocator to pop.
19719 [(match_scratch:W 1 "r")
19720 (parallel [(set (reg:P SP_REG)
19721 (plus:P (reg:P SP_REG)
19722 (match_operand:P 0 "const_int_operand")))
19723 (clobber (reg:CC FLAGS_REG))
19724 (clobber (mem:BLK (scratch)))])]
19725 "(TARGET_SINGLE_POP || optimize_insn_for_size_p ())
19726 && INTVAL (operands[0]) == GET_MODE_SIZE (word_mode)"
19727 [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
19728 (clobber (mem:BLK (scratch)))])])
19730 ;; Two pops case is tricky, since pop causes dependency
19731 ;; on destination register. We use two registers if available.
19733 [(match_scratch:W 1 "r")
19734 (match_scratch:W 2 "r")
19735 (parallel [(set (reg:P SP_REG)
19736 (plus:P (reg:P SP_REG)
19737 (match_operand:P 0 "const_int_operand")))
19738 (clobber (reg:CC FLAGS_REG))
19739 (clobber (mem:BLK (scratch)))])]
19740 "(TARGET_DOUBLE_POP || optimize_insn_for_size_p ())
19741 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
19742 [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
19743 (clobber (mem:BLK (scratch)))])
19744 (set (match_dup 2) (mem:W (post_inc:P (reg:P SP_REG))))])
19747 [(match_scratch:W 1 "r")
19748 (parallel [(set (reg:P SP_REG)
19749 (plus:P (reg:P SP_REG)
19750 (match_operand:P 0 "const_int_operand")))
19751 (clobber (reg:CC FLAGS_REG))
19752 (clobber (mem:BLK (scratch)))])]
19753 "optimize_insn_for_size_p ()
19754 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
19755 [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
19756 (clobber (mem:BLK (scratch)))])
19757 (set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
19759 ;; Convert esp additions to pop.
19761 [(match_scratch:W 1 "r")
19762 (parallel [(set (reg:P SP_REG)
19763 (plus:P (reg:P SP_REG)
19764 (match_operand:P 0 "const_int_operand")))
19765 (clobber (reg:CC FLAGS_REG))])]
19766 "INTVAL (operands[0]) == GET_MODE_SIZE (word_mode)"
19767 [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
19769 ;; Two pops case is tricky, since pop causes dependency
19770 ;; on destination register. We use two registers if available.
19772 [(match_scratch:W 1 "r")
19773 (match_scratch:W 2 "r")
19774 (parallel [(set (reg:P SP_REG)
19775 (plus:P (reg:P SP_REG)
19776 (match_operand:P 0 "const_int_operand")))
19777 (clobber (reg:CC FLAGS_REG))])]
19778 "INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
19779 [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
19780 (set (match_dup 2) (mem:W (post_inc:P (reg:P SP_REG))))])
19783 [(match_scratch:W 1 "r")
19784 (parallel [(set (reg:P SP_REG)
19785 (plus:P (reg:P SP_REG)
19786 (match_operand:P 0 "const_int_operand")))
19787 (clobber (reg:CC FLAGS_REG))])]
19788 "optimize_insn_for_size_p ()
19789 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
19790 [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
19791 (set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
19793 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
19794 ;; required and register dies. Similarly for 128 to -128.
19796 [(set (match_operand 0 "flags_reg_operand")
19797 (match_operator 1 "compare_operator"
19798 [(match_operand 2 "register_operand")
19799 (match_operand 3 "const_int_operand")]))]
19800 "(((!TARGET_FUSE_CMP_AND_BRANCH || optimize_insn_for_size_p ())
19801 && incdec_operand (operands[3], GET_MODE (operands[3])))
19802 || (!TARGET_FUSE_CMP_AND_BRANCH
19803 && INTVAL (operands[3]) == 128))
19804 && ix86_match_ccmode (insn, CCGCmode)
19805 && peep2_reg_dead_p (1, operands[2])"
19806 [(parallel [(set (match_dup 0)
19807 (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
19808 (clobber (match_dup 2))])])
19810 ;; Convert imul by three, five and nine into lea
19813 [(set (match_operand:SWI48 0 "register_operand")
19814 (mult:SWI48 (match_operand:SWI48 1 "register_operand")
19815 (match_operand:SWI48 2 "const359_operand")))
19816 (clobber (reg:CC FLAGS_REG))])]
19817 "!TARGET_PARTIAL_REG_STALL
19818 || <MODE>mode == SImode
19819 || optimize_function_for_size_p (cfun)"
19820 [(set (match_dup 0)
19821 (plus:SWI48 (mult:SWI48 (match_dup 1) (match_dup 2))
19823 "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
19827 [(set (match_operand:SWI48 0 "register_operand")
19828 (mult:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
19829 (match_operand:SWI48 2 "const359_operand")))
19830 (clobber (reg:CC FLAGS_REG))])]
19831 "optimize_insn_for_speed_p ()
19832 && (!TARGET_PARTIAL_REG_STALL || <MODE>mode == SImode)"
19833 [(set (match_dup 0) (match_dup 1))
19835 (plus:SWI48 (mult:SWI48 (match_dup 0) (match_dup 2))
19837 "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
19839 ;; imul $32bit_imm, mem, reg is vector decoded, while
19840 ;; imul $32bit_imm, reg, reg is direct decoded.
19842 [(match_scratch:SWI48 3 "r")
19843 (parallel [(set (match_operand:SWI48 0 "register_operand")
19844 (mult:SWI48 (match_operand:SWI48 1 "memory_operand")
19845 (match_operand:SWI48 2 "immediate_operand")))
19846 (clobber (reg:CC FLAGS_REG))])]
19847 "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
19848 && !satisfies_constraint_K (operands[2])"
19849 [(set (match_dup 3) (match_dup 1))
19850 (parallel [(set (match_dup 0) (mult:SWI48 (match_dup 3) (match_dup 2)))
19851 (clobber (reg:CC FLAGS_REG))])])
19854 [(match_scratch:SI 3 "r")
19855 (parallel [(set (match_operand:DI 0 "register_operand")
19857 (mult:SI (match_operand:SI 1 "memory_operand")
19858 (match_operand:SI 2 "immediate_operand"))))
19859 (clobber (reg:CC FLAGS_REG))])]
19861 && TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
19862 && !satisfies_constraint_K (operands[2])"
19863 [(set (match_dup 3) (match_dup 1))
19864 (parallel [(set (match_dup 0)
19865 (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
19866 (clobber (reg:CC FLAGS_REG))])])
19868 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
19869 ;; Convert it into imul reg, reg
19870 ;; It would be better to force assembler to encode instruction using long
19871 ;; immediate, but there is apparently no way to do so.
19873 [(parallel [(set (match_operand:SWI248 0 "register_operand")
19875 (match_operand:SWI248 1 "nonimmediate_operand")
19876 (match_operand:SWI248 2 "const_int_operand")))
19877 (clobber (reg:CC FLAGS_REG))])
19878 (match_scratch:SWI248 3 "r")]
19879 "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
19880 && satisfies_constraint_K (operands[2])"
19881 [(set (match_dup 3) (match_dup 2))
19882 (parallel [(set (match_dup 0) (mult:SWI248 (match_dup 0) (match_dup 3)))
19883 (clobber (reg:CC FLAGS_REG))])]
19885 if (!rtx_equal_p (operands[0], operands[1]))
19886 emit_move_insn (operands[0], operands[1]);
19889 ;; After splitting up read-modify operations, array accesses with memory
19890 ;; operands might end up in form:
19892 ;; movl 4(%esp), %edx
19894 ;; instead of pre-splitting:
19896 ;; addl 4(%esp), %eax
19898 ;; movl 4(%esp), %edx
19899 ;; leal (%edx,%eax,4), %eax
19902 [(match_scratch:W 5 "r")
19903 (parallel [(set (match_operand 0 "register_operand")
19904 (ashift (match_operand 1 "register_operand")
19905 (match_operand 2 "const_int_operand")))
19906 (clobber (reg:CC FLAGS_REG))])
19907 (parallel [(set (match_operand 3 "register_operand")
19908 (plus (match_dup 0)
19909 (match_operand 4 "x86_64_general_operand")))
19910 (clobber (reg:CC FLAGS_REG))])]
19911 "IN_RANGE (INTVAL (operands[2]), 1, 3)
19912 /* Validate MODE for lea. */
19913 && ((!TARGET_PARTIAL_REG_STALL
19914 && (GET_MODE (operands[0]) == QImode
19915 || GET_MODE (operands[0]) == HImode))
19916 || GET_MODE (operands[0]) == SImode
19917 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
19918 && (rtx_equal_p (operands[0], operands[3])
19919 || peep2_reg_dead_p (2, operands[0]))
19920 /* We reorder load and the shift. */
19921 && !reg_overlap_mentioned_p (operands[0], operands[4])"
19922 [(set (match_dup 5) (match_dup 4))
19923 (set (match_dup 0) (match_dup 1))]
19925 machine_mode op1mode = GET_MODE (operands[1]);
19926 machine_mode mode = op1mode == DImode ? DImode : SImode;
19927 int scale = 1 << INTVAL (operands[2]);
19928 rtx index = gen_lowpart (word_mode, operands[1]);
19929 rtx base = gen_lowpart (word_mode, operands[5]);
19930 rtx dest = gen_lowpart (mode, operands[3]);
19932 operands[1] = gen_rtx_PLUS (word_mode, base,
19933 gen_rtx_MULT (word_mode, index, GEN_INT (scale)));
19934 if (mode != word_mode)
19935 operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
19937 operands[5] = base;
19938 if (op1mode != word_mode)
19939 operands[5] = gen_lowpart (op1mode, operands[5]);
19941 operands[0] = dest;
19944 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
19945 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
19946 ;; caught for use by garbage collectors and the like. Using an insn that
19947 ;; maps to SIGILL makes it more likely the program will rightfully die.
19948 ;; Keeping with tradition, "6" is in honor of #UD.
19949 (define_insn "trap"
19950 [(trap_if (const_int 1) (const_int 6))]
19953 #ifdef HAVE_AS_IX86_UD2
19956 return ASM_SHORT "0x0b0f";
19959 [(set_attr "length" "2")])
19962 [(unspec_volatile [(const_int 0)] UNSPECV_UD2)]
19965 #ifdef HAVE_AS_IX86_UD2
19968 return ASM_SHORT "0x0b0f";
19971 [(set_attr "length" "2")])
19973 (define_expand "prefetch"
19974 [(prefetch (match_operand 0 "address_operand")
19975 (match_operand:SI 1 "const_int_operand")
19976 (match_operand:SI 2 "const_int_operand"))]
19977 "TARGET_3DNOW || TARGET_PREFETCH_SSE || TARGET_PRFCHW || TARGET_PREFETCHWT1"
19979 bool write = INTVAL (operands[1]) != 0;
19980 int locality = INTVAL (operands[2]);
19982 gcc_assert (IN_RANGE (locality, 0, 3));
19984 /* Use 3dNOW prefetch in case we are asking for write prefetch not
19985 supported by SSE counterpart (non-SSE2 athlon machines) or the
19986 SSE prefetch is not available (K6 machines). Otherwise use SSE
19987 prefetch as it allows specifying of locality. */
19991 if (TARGET_PREFETCHWT1)
19992 operands[2] = GEN_INT (MAX (locality, 2));
19993 else if (TARGET_PRFCHW)
19994 operands[2] = GEN_INT (3);
19995 else if (TARGET_3DNOW && !TARGET_SSE2)
19996 operands[2] = GEN_INT (3);
19997 else if (TARGET_PREFETCH_SSE)
19998 operands[1] = const0_rtx;
20001 gcc_assert (TARGET_3DNOW);
20002 operands[2] = GEN_INT (3);
20007 if (TARGET_PREFETCH_SSE)
20011 gcc_assert (TARGET_3DNOW);
20012 operands[2] = GEN_INT (3);
20017 (define_insn "*prefetch_sse"
20018 [(prefetch (match_operand 0 "address_operand" "p")
20020 (match_operand:SI 1 "const_int_operand"))]
20021 "TARGET_PREFETCH_SSE"
20023 static const char * const patterns[4] = {
20024 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
20027 int locality = INTVAL (operands[1]);
20028 gcc_assert (IN_RANGE (locality, 0, 3));
20030 return patterns[locality];
20032 [(set_attr "type" "sse")
20033 (set_attr "atom_sse_attr" "prefetch")
20034 (set (attr "length_address")
20035 (symbol_ref "memory_address_length (operands[0], false)"))
20036 (set_attr "memory" "none")])
20038 (define_insn "*prefetch_3dnow"
20039 [(prefetch (match_operand 0 "address_operand" "p")
20040 (match_operand:SI 1 "const_int_operand" "n")
20042 "TARGET_3DNOW || TARGET_PRFCHW || TARGET_PREFETCHWT1"
20044 if (INTVAL (operands[1]) == 0)
20045 return "prefetch\t%a0";
20047 return "prefetchw\t%a0";
20049 [(set_attr "type" "mmx")
20050 (set (attr "length_address")
20051 (symbol_ref "memory_address_length (operands[0], false)"))
20052 (set_attr "memory" "none")])
20054 (define_insn "*prefetch_prefetchwt1"
20055 [(prefetch (match_operand 0 "address_operand" "p")
20058 "TARGET_PREFETCHWT1"
20059 "prefetchwt1\t%a0";
20060 [(set_attr "type" "sse")
20061 (set (attr "length_address")
20062 (symbol_ref "memory_address_length (operands[0], false)"))
20063 (set_attr "memory" "none")])
20065 (define_expand "stack_protect_set"
20066 [(match_operand 0 "memory_operand")
20067 (match_operand 1 "memory_operand")]
20068 "TARGET_SSP_TLS_GUARD"
20070 rtx (*insn)(rtx, rtx);
20072 insn = (TARGET_LP64
20073 ? gen_stack_protect_set_di
20074 : gen_stack_protect_set_si);
20076 emit_insn (insn (operands[0], operands[1]));
20080 (define_insn "stack_protect_set_<mode>"
20081 [(set (match_operand:PTR 0 "memory_operand" "=m")
20082 (unspec:PTR [(match_operand:PTR 1 "memory_operand" "m")]
20084 (set (match_scratch:PTR 2 "=&r") (const_int 0))
20085 (clobber (reg:CC FLAGS_REG))]
20086 "TARGET_SSP_TLS_GUARD"
20087 "mov{<imodesuffix>}\t{%1, %2|%2, %1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
20088 [(set_attr "type" "multi")])
20090 (define_expand "stack_protect_test"
20091 [(match_operand 0 "memory_operand")
20092 (match_operand 1 "memory_operand")
20094 "TARGET_SSP_TLS_GUARD"
20096 rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
20098 rtx (*insn)(rtx, rtx, rtx);
20100 insn = (TARGET_LP64
20101 ? gen_stack_protect_test_di
20102 : gen_stack_protect_test_si);
20104 emit_insn (insn (flags, operands[0], operands[1]));
20106 emit_jump_insn (gen_cbranchcc4 (gen_rtx_EQ (VOIDmode, flags, const0_rtx),
20107 flags, const0_rtx, operands[2]));
20111 (define_insn "stack_protect_test_<mode>"
20112 [(set (match_operand:CCZ 0 "flags_reg_operand")
20113 (unspec:CCZ [(match_operand:PTR 1 "memory_operand" "m")
20114 (match_operand:PTR 2 "memory_operand" "m")]
20116 (clobber (match_scratch:PTR 3 "=&r"))]
20117 "TARGET_SSP_TLS_GUARD"
20118 "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%2, %3|%3, %2}"
20119 [(set_attr "type" "multi")])
20121 (define_insn "sse4_2_crc32<mode>"
20122 [(set (match_operand:SI 0 "register_operand" "=r")
20124 [(match_operand:SI 1 "register_operand" "0")
20125 (match_operand:SWI124 2 "nonimmediate_operand" "<r>m")]
20127 "TARGET_SSE4_2 || TARGET_CRC32"
20128 "crc32{<imodesuffix>}\t{%2, %0|%0, %2}"
20129 [(set_attr "type" "sselog1")
20130 (set_attr "prefix_rep" "1")
20131 (set_attr "prefix_extra" "1")
20132 (set (attr "prefix_data16")
20133 (if_then_else (match_operand:HI 2)
20135 (const_string "*")))
20136 (set (attr "prefix_rex")
20137 (if_then_else (match_operand:QI 2 "ext_QIreg_operand")
20139 (const_string "*")))
20140 (set_attr "mode" "SI")])
20142 (define_insn "sse4_2_crc32di"
20143 [(set (match_operand:DI 0 "register_operand" "=r")
20145 [(match_operand:DI 1 "register_operand" "0")
20146 (match_operand:DI 2 "nonimmediate_operand" "rm")]
20148 "TARGET_64BIT && (TARGET_SSE4_2 || TARGET_CRC32)"
20149 "crc32{q}\t{%2, %0|%0, %2}"
20150 [(set_attr "type" "sselog1")
20151 (set_attr "prefix_rep" "1")
20152 (set_attr "prefix_extra" "1")
20153 (set_attr "mode" "DI")])
20155 (define_insn "rdpmc"
20156 [(set (match_operand:DI 0 "register_operand" "=A")
20157 (unspec_volatile:DI [(match_operand:SI 1 "register_operand" "c")]
20161 [(set_attr "type" "other")
20162 (set_attr "length" "2")])
20164 (define_insn "rdpmc_rex64"
20165 [(set (match_operand:DI 0 "register_operand" "=a")
20166 (unspec_volatile:DI [(match_operand:SI 2 "register_operand" "c")]
20168 (set (match_operand:DI 1 "register_operand" "=d")
20169 (unspec_volatile:DI [(match_dup 2)] UNSPECV_RDPMC))]
20172 [(set_attr "type" "other")
20173 (set_attr "length" "2")])
20175 (define_insn "rdtsc"
20176 [(set (match_operand:DI 0 "register_operand" "=A")
20177 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
20180 [(set_attr "type" "other")
20181 (set_attr "length" "2")])
20183 (define_insn "rdtsc_rex64"
20184 [(set (match_operand:DI 0 "register_operand" "=a")
20185 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))
20186 (set (match_operand:DI 1 "register_operand" "=d")
20187 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
20190 [(set_attr "type" "other")
20191 (set_attr "length" "2")])
20193 (define_insn "rdtscp"
20194 [(set (match_operand:DI 0 "register_operand" "=A")
20195 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
20196 (set (match_operand:SI 1 "register_operand" "=c")
20197 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
20200 [(set_attr "type" "other")
20201 (set_attr "length" "3")])
20203 (define_insn "rdtscp_rex64"
20204 [(set (match_operand:DI 0 "register_operand" "=a")
20205 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
20206 (set (match_operand:DI 1 "register_operand" "=d")
20207 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
20208 (set (match_operand:SI 2 "register_operand" "=c")
20209 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
20212 [(set_attr "type" "other")
20213 (set_attr "length" "3")])
20215 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
20217 ;; FXSR, XSAVE and XSAVEOPT instructions
20219 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
20221 (define_insn "fxsave"
20222 [(set (match_operand:BLK 0 "memory_operand" "=m")
20223 (unspec_volatile:BLK [(const_int 0)] UNSPECV_FXSAVE))]
20226 [(set_attr "type" "other")
20227 (set_attr "memory" "store")
20228 (set (attr "length")
20229 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
20231 (define_insn "fxsave64"
20232 [(set (match_operand:BLK 0 "memory_operand" "=m")
20233 (unspec_volatile:BLK [(const_int 0)] UNSPECV_FXSAVE64))]
20234 "TARGET_64BIT && TARGET_FXSR"
20236 [(set_attr "type" "other")
20237 (set_attr "memory" "store")
20238 (set (attr "length")
20239 (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
20241 (define_insn "fxrstor"
20242 [(unspec_volatile [(match_operand:BLK 0 "memory_operand" "m")]
20246 [(set_attr "type" "other")
20247 (set_attr "memory" "load")
20248 (set (attr "length")
20249 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
20251 (define_insn "fxrstor64"
20252 [(unspec_volatile [(match_operand:BLK 0 "memory_operand" "m")]
20253 UNSPECV_FXRSTOR64)]
20254 "TARGET_64BIT && TARGET_FXSR"
20256 [(set_attr "type" "other")
20257 (set_attr "memory" "load")
20258 (set (attr "length")
20259 (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
20261 (define_int_iterator ANY_XSAVE
20263 (UNSPECV_XSAVEOPT "TARGET_XSAVEOPT")
20264 (UNSPECV_XSAVEC "TARGET_XSAVEC")
20265 (UNSPECV_XSAVES "TARGET_XSAVES")])
20267 (define_int_iterator ANY_XSAVE64
20269 (UNSPECV_XSAVEOPT64 "TARGET_XSAVEOPT")
20270 (UNSPECV_XSAVEC64 "TARGET_XSAVEC")
20271 (UNSPECV_XSAVES64 "TARGET_XSAVES")])
20273 (define_int_attr xsave
20274 [(UNSPECV_XSAVE "xsave")
20275 (UNSPECV_XSAVE64 "xsave64")
20276 (UNSPECV_XSAVEOPT "xsaveopt")
20277 (UNSPECV_XSAVEOPT64 "xsaveopt64")
20278 (UNSPECV_XSAVEC "xsavec")
20279 (UNSPECV_XSAVEC64 "xsavec64")
20280 (UNSPECV_XSAVES "xsaves")
20281 (UNSPECV_XSAVES64 "xsaves64")])
20283 (define_int_iterator ANY_XRSTOR
20285 (UNSPECV_XRSTORS "TARGET_XSAVES")])
20287 (define_int_iterator ANY_XRSTOR64
20289 (UNSPECV_XRSTORS64 "TARGET_XSAVES")])
20291 (define_int_attr xrstor
20292 [(UNSPECV_XRSTOR "xrstor")
20293 (UNSPECV_XRSTOR64 "xrstor")
20294 (UNSPECV_XRSTORS "xrstors")
20295 (UNSPECV_XRSTORS64 "xrstors")])
20297 (define_insn "<xsave>"
20298 [(set (match_operand:BLK 0 "memory_operand" "=m")
20299 (unspec_volatile:BLK
20300 [(match_operand:DI 1 "register_operand" "A")]
20302 "!TARGET_64BIT && TARGET_XSAVE"
20304 [(set_attr "type" "other")
20305 (set_attr "memory" "store")
20306 (set (attr "length")
20307 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
20309 (define_insn "<xsave>_rex64"
20310 [(set (match_operand:BLK 0 "memory_operand" "=m")
20311 (unspec_volatile:BLK
20312 [(match_operand:SI 1 "register_operand" "a")
20313 (match_operand:SI 2 "register_operand" "d")]
20315 "TARGET_64BIT && TARGET_XSAVE"
20317 [(set_attr "type" "other")
20318 (set_attr "memory" "store")
20319 (set (attr "length")
20320 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
20322 (define_insn "<xsave>"
20323 [(set (match_operand:BLK 0 "memory_operand" "=m")
20324 (unspec_volatile:BLK
20325 [(match_operand:SI 1 "register_operand" "a")
20326 (match_operand:SI 2 "register_operand" "d")]
20328 "TARGET_64BIT && TARGET_XSAVE"
20330 [(set_attr "type" "other")
20331 (set_attr "memory" "store")
20332 (set (attr "length")
20333 (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
20335 (define_insn "<xrstor>"
20336 [(unspec_volatile:BLK
20337 [(match_operand:BLK 0 "memory_operand" "m")
20338 (match_operand:DI 1 "register_operand" "A")]
20340 "!TARGET_64BIT && TARGET_XSAVE"
20342 [(set_attr "type" "other")
20343 (set_attr "memory" "load")
20344 (set (attr "length")
20345 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
20347 (define_insn "<xrstor>_rex64"
20348 [(unspec_volatile:BLK
20349 [(match_operand:BLK 0 "memory_operand" "m")
20350 (match_operand:SI 1 "register_operand" "a")
20351 (match_operand:SI 2 "register_operand" "d")]
20353 "TARGET_64BIT && TARGET_XSAVE"
20355 [(set_attr "type" "other")
20356 (set_attr "memory" "load")
20357 (set (attr "length")
20358 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
20360 (define_insn "<xrstor>64"
20361 [(unspec_volatile:BLK
20362 [(match_operand:BLK 0 "memory_operand" "m")
20363 (match_operand:SI 1 "register_operand" "a")
20364 (match_operand:SI 2 "register_operand" "d")]
20366 "TARGET_64BIT && TARGET_XSAVE"
20368 [(set_attr "type" "other")
20369 (set_attr "memory" "load")
20370 (set (attr "length")
20371 (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
20373 (define_insn "xsetbv"
20374 [(unspec_volatile:SI
20375 [(match_operand:SI 0 "register_operand" "c")
20376 (match_operand:DI 1 "register_operand" "A")]
20378 "!TARGET_64BIT && TARGET_XSAVE"
20380 [(set_attr "type" "other")])
20382 (define_insn "xsetbv_rex64"
20383 [(unspec_volatile:SI
20384 [(match_operand:SI 0 "register_operand" "c")
20385 (match_operand:SI 1 "register_operand" "a")
20386 (match_operand:SI 2 "register_operand" "d")]
20388 "TARGET_64BIT && TARGET_XSAVE"
20390 [(set_attr "type" "other")])
20392 (define_insn "xgetbv"
20393 [(set (match_operand:DI 0 "register_operand" "=A")
20394 (unspec_volatile:DI [(match_operand:SI 1 "register_operand" "c")]
20396 "!TARGET_64BIT && TARGET_XSAVE"
20398 [(set_attr "type" "other")])
20400 (define_insn "xgetbv_rex64"
20401 [(set (match_operand:DI 0 "register_operand" "=a")
20402 (unspec_volatile:DI [(match_operand:SI 2 "register_operand" "c")]
20404 (set (match_operand:DI 1 "register_operand" "=d")
20405 (unspec_volatile:DI [(match_dup 2)] UNSPECV_XGETBV))]
20406 "TARGET_64BIT && TARGET_XSAVE"
20408 [(set_attr "type" "other")])
20410 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
20412 ;; Floating-point instructions for atomic compound assignments
20414 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
20416 ; Clobber all floating-point registers on environment save and restore
20417 ; to ensure that the TOS value saved at fnstenv is valid after fldenv.
20418 (define_insn "fnstenv"
20419 [(set (match_operand:BLK 0 "memory_operand" "=m")
20420 (unspec_volatile:BLK [(const_int 0)] UNSPECV_FNSTENV))
20421 (clobber (reg:HI FPCR_REG))
20422 (clobber (reg:XF ST0_REG))
20423 (clobber (reg:XF ST1_REG))
20424 (clobber (reg:XF ST2_REG))
20425 (clobber (reg:XF ST3_REG))
20426 (clobber (reg:XF ST4_REG))
20427 (clobber (reg:XF ST5_REG))
20428 (clobber (reg:XF ST6_REG))
20429 (clobber (reg:XF ST7_REG))]
20432 [(set_attr "type" "other")
20433 (set_attr "memory" "store")
20434 (set (attr "length")
20435 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))])
20437 (define_insn "fldenv"
20438 [(unspec_volatile [(match_operand:BLK 0 "memory_operand" "m")]
20440 (clobber (reg:CCFP FPSR_REG))
20441 (clobber (reg:HI FPCR_REG))
20442 (clobber (reg:XF ST0_REG))
20443 (clobber (reg:XF ST1_REG))
20444 (clobber (reg:XF ST2_REG))
20445 (clobber (reg:XF ST3_REG))
20446 (clobber (reg:XF ST4_REG))
20447 (clobber (reg:XF ST5_REG))
20448 (clobber (reg:XF ST6_REG))
20449 (clobber (reg:XF ST7_REG))]
20452 [(set_attr "type" "other")
20453 (set_attr "memory" "load")
20454 (set (attr "length")
20455 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))])
20457 (define_insn "fnstsw"
20458 [(set (match_operand:HI 0 "nonimmediate_operand" "=a,m")
20459 (unspec_volatile:HI [(const_int 0)] UNSPECV_FNSTSW))]
20462 [(set_attr "type" "other,other")
20463 (set_attr "memory" "none,store")
20464 (set (attr "length")
20465 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))])
20467 (define_insn "fnclex"
20468 [(unspec_volatile [(const_int 0)] UNSPECV_FNCLEX)]
20471 [(set_attr "type" "other")
20472 (set_attr "memory" "none")
20473 (set_attr "length" "2")])
20475 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
20477 ;; LWP instructions
20479 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
20481 (define_expand "lwp_llwpcb"
20482 [(unspec_volatile [(match_operand 0 "register_operand")]
20483 UNSPECV_LLWP_INTRINSIC)]
20486 (define_insn "*lwp_llwpcb<mode>1"
20487 [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
20488 UNSPECV_LLWP_INTRINSIC)]
20491 [(set_attr "type" "lwp")
20492 (set_attr "mode" "<MODE>")
20493 (set_attr "length" "5")])
20495 (define_expand "lwp_slwpcb"
20496 [(set (match_operand 0 "register_operand")
20497 (unspec_volatile [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
20502 insn = (Pmode == DImode
20504 : gen_lwp_slwpcbsi);
20506 emit_insn (insn (operands[0]));
20510 (define_insn "lwp_slwpcb<mode>"
20511 [(set (match_operand:P 0 "register_operand" "=r")
20512 (unspec_volatile:P [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
20515 [(set_attr "type" "lwp")
20516 (set_attr "mode" "<MODE>")
20517 (set_attr "length" "5")])
20519 (define_expand "lwp_lwpval<mode>3"
20520 [(unspec_volatile [(match_operand:SWI48 1 "register_operand")
20521 (match_operand:SI 2 "nonimmediate_operand")
20522 (match_operand:SI 3 "const_int_operand")]
20523 UNSPECV_LWPVAL_INTRINSIC)]
20525 ;; Avoid unused variable warning.
20526 "(void) operands[0];")
20528 (define_insn "*lwp_lwpval<mode>3_1"
20529 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")
20530 (match_operand:SI 1 "nonimmediate_operand" "rm")
20531 (match_operand:SI 2 "const_int_operand" "i")]
20532 UNSPECV_LWPVAL_INTRINSIC)]
20534 "lwpval\t{%2, %1, %0|%0, %1, %2}"
20535 [(set_attr "type" "lwp")
20536 (set_attr "mode" "<MODE>")
20537 (set (attr "length")
20538 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
20540 (define_expand "lwp_lwpins<mode>3"
20541 [(set (reg:CCC FLAGS_REG)
20542 (unspec_volatile:CCC [(match_operand:SWI48 1 "register_operand")
20543 (match_operand:SI 2 "nonimmediate_operand")
20544 (match_operand:SI 3 "const_int_operand")]
20545 UNSPECV_LWPINS_INTRINSIC))
20546 (set (match_operand:QI 0 "nonimmediate_operand")
20547 (eq:QI (reg:CCC FLAGS_REG) (const_int 0)))]
20550 (define_insn "*lwp_lwpins<mode>3_1"
20551 [(set (reg:CCC FLAGS_REG)
20552 (unspec_volatile:CCC [(match_operand:SWI48 0 "register_operand" "r")
20553 (match_operand:SI 1 "nonimmediate_operand" "rm")
20554 (match_operand:SI 2 "const_int_operand" "i")]
20555 UNSPECV_LWPINS_INTRINSIC))]
20557 "lwpins\t{%2, %1, %0|%0, %1, %2}"
20558 [(set_attr "type" "lwp")
20559 (set_attr "mode" "<MODE>")
20560 (set (attr "length")
20561 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
20563 (define_int_iterator RDFSGSBASE
20567 (define_int_iterator WRFSGSBASE
20571 (define_int_attr fsgs
20572 [(UNSPECV_RDFSBASE "fs")
20573 (UNSPECV_RDGSBASE "gs")
20574 (UNSPECV_WRFSBASE "fs")
20575 (UNSPECV_WRGSBASE "gs")])
20577 (define_insn "rd<fsgs>base<mode>"
20578 [(set (match_operand:SWI48 0 "register_operand" "=r")
20579 (unspec_volatile:SWI48 [(const_int 0)] RDFSGSBASE))]
20580 "TARGET_64BIT && TARGET_FSGSBASE"
20582 [(set_attr "type" "other")
20583 (set_attr "prefix_extra" "2")])
20585 (define_insn "wr<fsgs>base<mode>"
20586 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
20588 "TARGET_64BIT && TARGET_FSGSBASE"
20590 [(set_attr "type" "other")
20591 (set_attr "prefix_extra" "2")])
20593 (define_insn "rdrand<mode>_1"
20594 [(set (match_operand:SWI248 0 "register_operand" "=r")
20595 (unspec_volatile:SWI248 [(const_int 0)] UNSPECV_RDRAND))
20596 (set (reg:CCC FLAGS_REG)
20597 (unspec_volatile:CCC [(const_int 0)] UNSPECV_RDRAND))]
20600 [(set_attr "type" "other")
20601 (set_attr "prefix_extra" "1")])
20603 (define_insn "rdseed<mode>_1"
20604 [(set (match_operand:SWI248 0 "register_operand" "=r")
20605 (unspec_volatile:SWI248 [(const_int 0)] UNSPECV_RDSEED))
20606 (set (reg:CCC FLAGS_REG)
20607 (unspec_volatile:CCC [(const_int 0)] UNSPECV_RDSEED))]
20610 [(set_attr "type" "other")
20611 (set_attr "prefix_extra" "1")])
20613 (define_expand "pause"
20614 [(set (match_dup 0)
20615 (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
20618 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
20619 MEM_VOLATILE_P (operands[0]) = 1;
20622 ;; Use "rep; nop", instead of "pause", to support older assemblers.
20623 ;; They have the same encoding.
20624 (define_insn "*pause"
20625 [(set (match_operand:BLK 0)
20626 (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
20629 [(set_attr "length" "2")
20630 (set_attr "memory" "unknown")])
20632 ;; CET instructions
20633 (define_insn "rdssp<mode>"
20634 [(set (match_operand:SWI48x 0 "register_operand" "=r")
20635 (unspec_volatile:SWI48x [(const_int 0)] UNSPECV_NOP_RDSSP))]
20636 "TARGET_SHSTK || (flag_cf_protection & CF_RETURN)"
20637 "xor{l}\t%k0, %k0\n\trdssp<mskmodesuffix>\t%0"
20638 [(set_attr "length" "6")
20639 (set_attr "type" "other")])
20641 (define_insn "incssp<mode>"
20642 [(unspec_volatile [(match_operand:SWI48x 0 "register_operand" "r")]
20644 "TARGET_SHSTK || (flag_cf_protection & CF_RETURN)"
20645 "incssp<mskmodesuffix>\t%0"
20646 [(set_attr "length" "4")
20647 (set_attr "type" "other")])
20649 (define_insn "saveprevssp"
20650 [(unspec_volatile [(const_int 0)] UNSPECV_SAVEPREVSSP)]
20653 [(set_attr "length" "5")
20654 (set_attr "type" "other")])
20656 (define_expand "rstorssp"
20657 [(unspec_volatile [(match_operand 0 "memory_operand")]
20661 (define_insn "*rstorssp<mode>"
20662 [(unspec_volatile [(match_operand:P 0 "memory_operand" "m")]
20666 [(set_attr "length" "5")
20667 (set_attr "type" "other")])
20669 (define_insn "wrss<mode>"
20670 [(unspec_volatile [(match_operand:SWI48x 0 "register_operand" "r")
20671 (match_operand:SWI48x 1 "memory_operand" "m")]
20674 "wrss<mskmodesuffix>\t%0, %1"
20675 [(set_attr "length" "3")
20676 (set_attr "type" "other")])
20678 (define_insn "wruss<mode>"
20679 [(unspec_volatile [(match_operand:SWI48x 0 "register_operand" "r")
20680 (match_operand:SWI48x 1 "memory_operand" "m")]
20683 "wruss<mskmodesuffix>\t%0, %1"
20684 [(set_attr "length" "4")
20685 (set_attr "type" "other")])
20687 (define_insn "setssbsy"
20688 [(unspec_volatile [(const_int 0)] UNSPECV_SETSSBSY)]
20691 [(set_attr "length" "4")
20692 (set_attr "type" "other")])
20694 (define_expand "clrssbsy"
20695 [(unspec_volatile [(match_operand 0 "memory_operand")]
20699 (define_insn "*clrssbsy<mode>"
20700 [(unspec_volatile [(match_operand:P 0 "memory_operand" "m")]
20704 [(set_attr "length" "4")
20705 (set_attr "type" "other")])
20707 (define_insn "nop_endbr"
20708 [(unspec_volatile [(const_int 0)] UNSPECV_NOP_ENDBR)]
20709 "(flag_cf_protection & CF_BRANCH)"
20711 return TARGET_64BIT ? "endbr64" : "endbr32";
20713 [(set_attr "length" "4")
20714 (set_attr "length_immediate" "0")
20715 (set_attr "modrm" "0")])
20718 (define_expand "xbegin"
20719 [(set (match_operand:SI 0 "register_operand")
20720 (unspec_volatile:SI [(const_int 0)] UNSPECV_XBEGIN))]
20723 rtx_code_label *label = gen_label_rtx ();
20725 /* xbegin is emitted as jump_insn, so reload won't be able
20726 to reload its operand. Force the value into AX hard register. */
20727 rtx ax_reg = gen_rtx_REG (SImode, AX_REG);
20728 emit_move_insn (ax_reg, constm1_rtx);
20730 emit_jump_insn (gen_xbegin_1 (ax_reg, label));
20732 emit_label (label);
20733 LABEL_NUSES (label) = 1;
20735 emit_move_insn (operands[0], ax_reg);
20740 (define_insn "xbegin_1"
20742 (if_then_else (ne (unspec [(const_int 0)] UNSPEC_XBEGIN_ABORT)
20744 (label_ref (match_operand 1))
20746 (set (match_operand:SI 0 "register_operand" "+a")
20747 (unspec_volatile:SI [(match_dup 0)] UNSPECV_XBEGIN))]
20750 [(set_attr "type" "other")
20751 (set_attr "length" "6")])
20753 (define_insn "xend"
20754 [(unspec_volatile [(const_int 0)] UNSPECV_XEND)]
20757 [(set_attr "type" "other")
20758 (set_attr "length" "3")])
20760 (define_insn "xabort"
20761 [(unspec_volatile [(match_operand:SI 0 "const_0_to_255_operand" "n")]
20765 [(set_attr "type" "other")
20766 (set_attr "length" "3")])
20768 (define_expand "xtest"
20769 [(set (match_operand:QI 0 "register_operand")
20770 (unspec_volatile:QI [(const_int 0)] UNSPECV_XTEST))]
20773 emit_insn (gen_xtest_1 ());
20775 ix86_expand_setcc (operands[0], NE,
20776 gen_rtx_REG (CCZmode, FLAGS_REG), const0_rtx);
20780 (define_insn "xtest_1"
20781 [(set (reg:CCZ FLAGS_REG)
20782 (unspec_volatile:CCZ [(const_int 0)] UNSPECV_XTEST))]
20785 [(set_attr "type" "other")
20786 (set_attr "length" "3")])
20788 (define_insn "clwb"
20789 [(unspec_volatile [(match_operand 0 "address_operand" "p")]
20793 [(set_attr "type" "sse")
20794 (set_attr "atom_sse_attr" "fence")
20795 (set_attr "memory" "unknown")])
20797 (define_insn "clflushopt"
20798 [(unspec_volatile [(match_operand 0 "address_operand" "p")]
20799 UNSPECV_CLFLUSHOPT)]
20800 "TARGET_CLFLUSHOPT"
20802 [(set_attr "type" "sse")
20803 (set_attr "atom_sse_attr" "fence")
20804 (set_attr "memory" "unknown")])
20806 ;; MONITORX and MWAITX
20807 (define_insn "mwaitx"
20808 [(unspec_volatile [(match_operand:SI 0 "register_operand" "c")
20809 (match_operand:SI 1 "register_operand" "a")
20810 (match_operand:SI 2 "register_operand" "b")]
20813 ;; 64bit version is "mwaitx %rax,%rcx,%rbx". But only lower 32bits are used.
20814 ;; Since 32bit register operands are implicitly zero extended to 64bit,
20815 ;; we only need to set up 32bit registers.
20817 [(set_attr "length" "3")])
20819 (define_insn "monitorx_<mode>"
20820 [(unspec_volatile [(match_operand:P 0 "register_operand" "a")
20821 (match_operand:SI 1 "register_operand" "c")
20822 (match_operand:SI 2 "register_operand" "d")]
20825 ;; 64bit version is "monitorx %rax,%rcx,%rdx". But only lower 32bits in
20826 ;; RCX and RDX are used. Since 32bit register operands are implicitly
20827 ;; zero extended to 64bit, we only need to set up 32bit registers.
20829 [(set (attr "length")
20830 (symbol_ref ("(Pmode != word_mode) + 3")))])
20833 (define_insn "clzero_<mode>"
20834 [(unspec_volatile [(match_operand: P 0 "register_operand" "a")]
20838 [(set_attr "length" "3")
20839 (set_attr "memory" "unknown")])
20841 ;; RDPKRU and WRPKRU
20843 (define_expand "rdpkru"
20845 [(set (match_operand:SI 0 "register_operand")
20846 (unspec_volatile:SI [(match_dup 1)] UNSPECV_PKU))
20847 (set (match_dup 2) (const_int 0))])]
20850 operands[1] = force_reg (SImode, const0_rtx);
20851 operands[2] = gen_reg_rtx (SImode);
20854 (define_insn "*rdpkru"
20855 [(set (match_operand:SI 0 "register_operand" "=a")
20856 (unspec_volatile:SI [(match_operand:SI 2 "register_operand" "c")]
20858 (set (match_operand:SI 1 "register_operand" "=d")
20862 [(set_attr "type" "other")])
20864 (define_expand "wrpkru"
20865 [(unspec_volatile:SI
20866 [(match_operand:SI 0 "register_operand")
20867 (match_dup 1) (match_dup 2)] UNSPECV_PKU)]
20870 operands[1] = force_reg (SImode, const0_rtx);
20871 operands[2] = force_reg (SImode, const0_rtx);
20874 (define_insn "*wrpkru"
20875 [(unspec_volatile:SI
20876 [(match_operand:SI 0 "register_operand" "a")
20877 (match_operand:SI 1 "register_operand" "d")
20878 (match_operand:SI 2 "register_operand" "c")] UNSPECV_PKU)]
20881 [(set_attr "type" "other")])
20883 (define_insn "rdpid"
20884 [(set (match_operand:SI 0 "register_operand" "=r")
20885 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDPID))]
20886 "!TARGET_64BIT && TARGET_RDPID"
20888 [(set_attr "type" "other")])
20890 (define_insn "rdpid_rex64"
20891 [(set (match_operand:DI 0 "register_operand" "=r")
20892 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDPID))]
20893 "TARGET_64BIT && TARGET_RDPID"
20895 [(set_attr "type" "other")])
20897 ;; Intirinsics for > i486
20899 (define_insn "wbinvd"
20900 [(unspec_volatile [(const_int 0)] UNSPECV_WBINVD)]
20903 [(set_attr "type" "other")])
20905 (define_insn "wbnoinvd"
20906 [(unspec_volatile [(const_int 0)] UNSPECV_WBNOINVD)]
20909 [(set_attr "type" "other")])
20911 ;; MOVDIRI and MOVDIR64B
20913 (define_insn "movdiri<mode>"
20914 [(unspec_volatile:SWI48 [(match_operand:SWI48 0 "memory_operand" "m")
20915 (match_operand:SWI48 1 "register_operand" "r")]
20918 "movdiri\t{%1, %0|%0, %1}"
20919 [(set_attr "type" "other")])
20921 (define_insn "movdir64b_<mode>"
20922 [(unspec_volatile:XI [(match_operand:P 0 "register_operand" "r")
20923 (match_operand:XI 1 "memory_operand")]
20924 UNSPECV_MOVDIR64B)]
20926 "movdir64b\t{%1, %0|%0, %1}"
20927 [(set_attr "type" "other")])
20931 (define_insn "umwait"
20932 [(set (reg:CCC FLAGS_REG)
20933 (unspec_volatile:CCC [(match_operand:SI 0 "register_operand" "r")
20934 (match_operand:DI 1 "register_operand" "A")]
20936 "!TARGET_64BIT && TARGET_WAITPKG"
20938 [(set_attr "length" "3")])
20940 (define_insn "umwait_rex64"
20941 [(set (reg:CCC FLAGS_REG)
20942 (unspec_volatile:CCC [(match_operand:SI 0 "register_operand" "r")
20943 (match_operand:SI 1 "register_operand" "a")
20944 (match_operand:SI 2 "register_operand" "d")]
20946 "TARGET_64BIT && TARGET_WAITPKG"
20948 [(set_attr "length" "3")])
20950 (define_insn "umonitor_<mode>"
20951 [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
20955 [(set (attr "length")
20956 (symbol_ref ("(Pmode != word_mode) + 3")))])
20958 (define_insn "tpause"
20959 [(set (reg:CCC FLAGS_REG)
20960 (unspec_volatile:CCC [(match_operand:SI 0 "register_operand" "r")
20961 (match_operand:DI 1 "register_operand" "A")]
20963 "!TARGET_64BIT && TARGET_WAITPKG"
20965 [(set_attr "length" "3")])
20967 (define_insn "tpause_rex64"
20968 [(set (reg:CCC FLAGS_REG)
20969 (unspec_volatile:CCC [(match_operand:SI 0 "register_operand" "r")
20970 (match_operand:SI 1 "register_operand" "a")
20971 (match_operand:SI 2 "register_operand" "d")]
20973 "TARGET_64BIT && TARGET_WAITPKG"
20975 [(set_attr "length" "3")])
20977 (define_insn "cldemote"
20978 [(unspec_volatile[(match_operand 0 "address_operand" "p")]
20982 [(set_attr "type" "other")
20983 (set_attr "memory" "unknown")])
20985 (define_insn "speculation_barrier"
20986 [(unspec_volatile [(const_int 0)] UNSPECV_SPECULATION_BARRIER)]
20989 [(set_attr "type" "other")
20990 (set_attr "length" "3")])
20994 (include "sync.md")