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
106 UNSPEC_LD_MPIC ; load_macho_picbase
108 UNSPEC_DIV_ALREADY_SPLIT
114 UNSPEC_INSN_FALSE_DEP
117 ;; For SSE/MMX support:
125 ;; Generic math support
127 UNSPEC_IEEE_MIN ; not commutative
128 UNSPEC_IEEE_MAX ; not commutative
130 ;; x87 Floating point
149 ;; x87 Double output FP
174 ;; For LZCNT suppoprt
186 UNSPEC_INTERRUPT_RETURN
189 (define_c_enum "unspecv" [
193 UNSPECV_PROBE_STACK_RANGE
196 UNSPECV_SPLIT_STACK_RETURN
202 UNSPECV_LLWP_INTRINSIC
203 UNSPECV_SLWP_INTRINSIC
204 UNSPECV_LWPVAL_INTRINSIC
205 UNSPECV_LWPINS_INTRINSIC
231 ;; For atomic compound assignments.
237 ;; For RDRAND support
240 ;; For RDSEED support
254 ;; For CLFLUSHOPT support
257 ;; For MONITORX and MWAITX support
261 ;; For CLZERO support
264 ;; For RDPKRU and WRPKRU support
281 ;; For MOVDIRI and MOVDIR64B support
285 ;; For WAITPKG support
290 ;; For CLDEMOTE support
293 ;; For Speculation Barrier support
294 UNSPECV_SPECULATION_BARRIER
297 ;; Constants to represent rounding modes in the ROUND instruction
306 ;; Constants to represent AVX512F embeded rounding
308 [(ROUND_NEAREST_INT 0)
316 ;; Constants to represent pcomtrue/pcomfalse variants
326 ;; Constants used in the XOP pperm instruction
328 [(PPERM_SRC 0x00) /* copy source */
329 (PPERM_INVERT 0x20) /* invert source */
330 (PPERM_REVERSE 0x40) /* bit reverse source */
331 (PPERM_REV_INV 0x60) /* bit reverse & invert src */
332 (PPERM_ZERO 0x80) /* all 0's */
333 (PPERM_ONES 0xa0) /* all 1's */
334 (PPERM_SIGN 0xc0) /* propagate sign bit */
335 (PPERM_INV_SIGN 0xe0) /* invert & propagate sign */
336 (PPERM_SRC1 0x00) /* use first source byte */
337 (PPERM_SRC2 0x10) /* use second source byte */
340 ;; Registers by name.
418 (FIRST_PSEUDO_REG 76)
421 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
424 ;; In C guard expressions, put expressions which may be compile-time
425 ;; constants first. This allows for better optimization. For
426 ;; example, write "TARGET_64BIT && reload_completed", not
427 ;; "reload_completed && TARGET_64BIT".
431 (define_attr "cpu" "none,pentium,pentiumpro,geode,k6,athlon,k8,core2,nehalem,
432 atom,slm,glm,haswell,generic,amdfam10,bdver1,bdver2,bdver3,
433 bdver4,btver2,znver1"
434 (const (symbol_ref "ix86_schedule")))
436 ;; A basic instruction type. Refinements due to arguments to be
437 ;; provided in other attributes.
440 alu,alu1,negnot,imov,imovx,lea,
441 incdec,ishift,ishiftx,ishift1,rotate,rotatex,rotate1,
442 imul,imulx,idiv,icmp,test,ibr,setcc,icmov,
443 push,pop,call,callv,leave,
445 fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,
446 fxch,fistp,fisttp,frndint,
447 sse,ssemov,sseadd,sseadd1,sseiadd,sseiadd1,
448 ssemul,sseimul,ssediv,sselog,sselog1,
449 sseishft,sseishft1,ssecmp,ssecomi,
450 ssecvt,ssecvt1,sseicvt,sseins,
451 sseshuf,sseshuf1,ssemuladd,sse4arg,
453 mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
454 (const_string "other"))
456 ;; Main data type used by the insn
458 "unknown,none,QI,HI,SI,DI,TI,OI,XI,SF,DF,XF,TF,V16SF,V8SF,V4DF,V4SF,
460 (const_string "unknown"))
462 ;; The CPU unit operations uses.
463 (define_attr "unit" "integer,i387,sse,mmx,unknown"
464 (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,
465 fxch,fistp,fisttp,frndint")
466 (const_string "i387")
467 (eq_attr "type" "sse,ssemov,sseadd,sseadd1,sseiadd,sseiadd1,
468 ssemul,sseimul,ssediv,sselog,sselog1,
469 sseishft,sseishft1,ssecmp,ssecomi,
470 ssecvt,ssecvt1,sseicvt,sseins,
471 sseshuf,sseshuf1,ssemuladd,sse4arg,mskmov")
473 (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
475 (eq_attr "type" "other")
476 (const_string "unknown")]
477 (const_string "integer")))
479 ;; The (bounding maximum) length of an instruction immediate.
480 (define_attr "length_immediate" ""
481 (cond [(eq_attr "type" "incdec,setcc,icmov,str,lea,other,multi,idiv,leave,
482 bitmanip,imulx,msklog,mskmov")
484 (eq_attr "unit" "i387,sse,mmx")
486 (eq_attr "type" "alu,alu1,negnot,imovx,ishift,ishiftx,ishift1,
487 rotate,rotatex,rotate1,imul,icmp,push,pop")
488 (symbol_ref "ix86_attr_length_immediate_default (insn, true)")
489 (eq_attr "type" "imov,test")
490 (symbol_ref "ix86_attr_length_immediate_default (insn, false)")
491 (eq_attr "type" "call")
492 (if_then_else (match_operand 0 "constant_call_address_operand")
495 (eq_attr "type" "callv")
496 (if_then_else (match_operand 1 "constant_call_address_operand")
499 ;; We don't know the size before shorten_branches. Expect
500 ;; the instruction to fit for better scheduling.
501 (eq_attr "type" "ibr")
504 (symbol_ref "/* Update immediate_length and other attributes! */
505 gcc_unreachable (),1")))
507 ;; The (bounding maximum) length of an instruction address.
508 (define_attr "length_address" ""
509 (cond [(eq_attr "type" "str,other,multi,fxch")
511 (and (eq_attr "type" "call")
512 (match_operand 0 "constant_call_address_operand"))
514 (and (eq_attr "type" "callv")
515 (match_operand 1 "constant_call_address_operand"))
518 (symbol_ref "ix86_attr_length_address_default (insn)")))
520 ;; Set when length prefix is used.
521 (define_attr "prefix_data16" ""
522 (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
524 (eq_attr "mode" "HI")
526 (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF,TI"))
531 ;; Set when string REP prefix is used.
532 (define_attr "prefix_rep" ""
533 (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
535 (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
540 ;; Set when 0f opcode prefix is used.
541 (define_attr "prefix_0f" ""
543 (ior (eq_attr "type" "imovx,setcc,icmov,bitmanip,msklog,mskmov")
544 (eq_attr "unit" "sse,mmx"))
548 ;; Set when REX opcode prefix is used.
549 (define_attr "prefix_rex" ""
550 (cond [(not (match_test "TARGET_64BIT"))
552 (and (eq_attr "mode" "DI")
553 (and (eq_attr "type" "!push,pop,call,callv,leave,ibr")
554 (eq_attr "unit" "!mmx")))
556 (and (eq_attr "mode" "QI")
557 (match_test "x86_extended_QIreg_mentioned_p (insn)"))
559 (match_test "x86_extended_reg_mentioned_p (insn)")
561 (and (eq_attr "type" "imovx")
562 (match_operand:QI 1 "ext_QIreg_operand"))
567 ;; There are also additional prefixes in 3DNOW, SSSE3.
568 ;; ssemuladd,sse4arg default to 0f24/0f25 and DREX byte,
569 ;; sseiadd1,ssecvt1 to 0f7a with no DREX byte.
570 ;; 3DNOW has 0f0f prefix, SSSE3 and SSE4_{1,2} 0f38/0f3a.
571 (define_attr "prefix_extra" ""
572 (cond [(eq_attr "type" "ssemuladd,sse4arg")
574 (eq_attr "type" "sseiadd1,ssecvt1")
579 ;; Prefix used: original, VEX or maybe VEX.
580 (define_attr "prefix" "orig,vex,maybe_vex,evex,maybe_evex"
581 (cond [(eq_attr "mode" "OI,V8SF,V4DF")
583 (eq_attr "mode" "XI,V16SF,V8DF")
584 (const_string "evex")
586 (const_string "orig")))
588 ;; VEX W bit is used.
589 (define_attr "prefix_vex_w" "" (const_int 0))
591 ;; The length of VEX prefix
592 ;; Only instructions with 0f prefix can have 2 byte VEX prefix,
593 ;; 0f38/0f3a prefixes can't. In i386.md 0f3[8a] is
594 ;; still prefix_0f 1, with prefix_extra 1.
595 (define_attr "length_vex" ""
596 (if_then_else (and (eq_attr "prefix_0f" "1")
597 (eq_attr "prefix_extra" "0"))
598 (if_then_else (eq_attr "prefix_vex_w" "1")
599 (symbol_ref "ix86_attr_length_vex_default (insn, true, true)")
600 (symbol_ref "ix86_attr_length_vex_default (insn, true, false)"))
601 (if_then_else (eq_attr "prefix_vex_w" "1")
602 (symbol_ref "ix86_attr_length_vex_default (insn, false, true)")
603 (symbol_ref "ix86_attr_length_vex_default (insn, false, false)"))))
605 ;; 4-bytes evex prefix and 1 byte opcode.
606 (define_attr "length_evex" "" (const_int 5))
608 ;; Set when modrm byte is used.
609 (define_attr "modrm" ""
610 (cond [(eq_attr "type" "str,leave")
612 (eq_attr "unit" "i387")
614 (and (eq_attr "type" "incdec")
615 (and (not (match_test "TARGET_64BIT"))
616 (ior (match_operand:SI 1 "register_operand")
617 (match_operand:HI 1 "register_operand"))))
619 (and (eq_attr "type" "push")
620 (not (match_operand 1 "memory_operand")))
622 (and (eq_attr "type" "pop")
623 (not (match_operand 0 "memory_operand")))
625 (and (eq_attr "type" "imov")
626 (and (not (eq_attr "mode" "DI"))
627 (ior (and (match_operand 0 "register_operand")
628 (match_operand 1 "immediate_operand"))
629 (ior (and (match_operand 0 "ax_reg_operand")
630 (match_operand 1 "memory_displacement_only_operand"))
631 (and (match_operand 0 "memory_displacement_only_operand")
632 (match_operand 1 "ax_reg_operand"))))))
634 (and (eq_attr "type" "call")
635 (match_operand 0 "constant_call_address_operand"))
637 (and (eq_attr "type" "callv")
638 (match_operand 1 "constant_call_address_operand"))
640 (and (eq_attr "type" "alu,alu1,icmp,test")
641 (match_operand 0 "ax_reg_operand"))
642 (symbol_ref "(get_attr_length_immediate (insn) <= (get_attr_mode (insn) != MODE_QI))")
646 ;; The (bounding maximum) length of an instruction in bytes.
647 ;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
648 ;; Later we may want to split them and compute proper length as for
650 (define_attr "length" ""
651 (cond [(eq_attr "type" "other,multi,fistp,frndint")
653 (eq_attr "type" "fcmp")
655 (eq_attr "unit" "i387")
657 (plus (attr "prefix_data16")
658 (attr "length_address")))
659 (ior (eq_attr "prefix" "evex")
660 (and (ior (eq_attr "prefix" "maybe_evex")
661 (eq_attr "prefix" "maybe_vex"))
662 (match_test "TARGET_AVX512F")))
663 (plus (attr "length_evex")
664 (plus (attr "length_immediate")
666 (attr "length_address"))))
667 (ior (eq_attr "prefix" "vex")
668 (and (ior (eq_attr "prefix" "maybe_vex")
669 (eq_attr "prefix" "maybe_evex"))
670 (match_test "TARGET_AVX")))
671 (plus (attr "length_vex")
672 (plus (attr "length_immediate")
674 (attr "length_address"))))]
675 (plus (plus (attr "modrm")
676 (plus (attr "prefix_0f")
677 (plus (attr "prefix_rex")
678 (plus (attr "prefix_extra")
680 (plus (attr "prefix_rep")
681 (plus (attr "prefix_data16")
682 (plus (attr "length_immediate")
683 (attr "length_address")))))))
685 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
686 ;; `store' if there is a simple memory reference therein, or `unknown'
687 ;; if the instruction is complex.
689 (define_attr "memory" "none,load,store,both,unknown"
690 (cond [(eq_attr "type" "other,multi,str,lwp")
691 (const_string "unknown")
692 (eq_attr "type" "lea,fcmov,fpspc")
693 (const_string "none")
694 (eq_attr "type" "fistp,leave")
695 (const_string "both")
696 (eq_attr "type" "frndint")
697 (const_string "load")
698 (eq_attr "type" "push")
699 (if_then_else (match_operand 1 "memory_operand")
700 (const_string "both")
701 (const_string "store"))
702 (eq_attr "type" "pop")
703 (if_then_else (match_operand 0 "memory_operand")
704 (const_string "both")
705 (const_string "load"))
706 (eq_attr "type" "setcc")
707 (if_then_else (match_operand 0 "memory_operand")
708 (const_string "store")
709 (const_string "none"))
710 (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
711 (if_then_else (ior (match_operand 0 "memory_operand")
712 (match_operand 1 "memory_operand"))
713 (const_string "load")
714 (const_string "none"))
715 (eq_attr "type" "ibr")
716 (if_then_else (match_operand 0 "memory_operand")
717 (const_string "load")
718 (const_string "none"))
719 (eq_attr "type" "call")
720 (if_then_else (match_operand 0 "constant_call_address_operand")
721 (const_string "none")
722 (const_string "load"))
723 (eq_attr "type" "callv")
724 (if_then_else (match_operand 1 "constant_call_address_operand")
725 (const_string "none")
726 (const_string "load"))
727 (and (eq_attr "type" "alu1,negnot,ishift1,rotate1,sselog1,sseshuf1")
728 (match_operand 1 "memory_operand"))
729 (const_string "both")
730 (and (match_operand 0 "memory_operand")
731 (match_operand 1 "memory_operand"))
732 (const_string "both")
733 (match_operand 0 "memory_operand")
734 (const_string "store")
735 (match_operand 1 "memory_operand")
736 (const_string "load")
738 "!alu1,negnot,ishift1,rotate1,
739 imov,imovx,icmp,test,bitmanip,
741 sse,ssemov,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,
742 sselog1,sseshuf1,sseadd1,sseiadd1,sseishft1,
743 mmx,mmxmov,mmxcmp,mmxcvt,mskmov,msklog")
744 (match_operand 2 "memory_operand"))
745 (const_string "load")
746 (and (eq_attr "type" "icmov,ssemuladd,sse4arg")
747 (match_operand 3 "memory_operand"))
748 (const_string "load")
750 (const_string "none")))
752 ;; Indicates if an instruction has both an immediate and a displacement.
754 (define_attr "imm_disp" "false,true,unknown"
755 (cond [(eq_attr "type" "other,multi")
756 (const_string "unknown")
757 (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
758 (and (match_operand 0 "memory_displacement_operand")
759 (match_operand 1 "immediate_operand")))
760 (const_string "true")
761 (and (eq_attr "type" "alu,ishift,ishiftx,rotate,rotatex,imul,idiv")
762 (and (match_operand 0 "memory_displacement_operand")
763 (match_operand 2 "immediate_operand")))
764 (const_string "true")
766 (const_string "false")))
768 ;; Indicates if an FP operation has an integer source.
770 (define_attr "fp_int_src" "false,true"
771 (const_string "false"))
773 ;; Defines rounding mode of an FP operation.
775 (define_attr "i387_cw" "trunc,floor,ceil,uninitialized,any"
776 (const_string "any"))
778 ;; Define attribute to classify add/sub insns that consumes carry flag (CF)
779 (define_attr "use_carry" "0,1" (const_string "0"))
781 ;; Define attribute to indicate unaligned ssemov insns
782 (define_attr "movu" "0,1" (const_string "0"))
784 ;; Used to control the "enabled" attribute on a per-instruction basis.
785 (define_attr "isa" "base,x64,x64_sse2,x64_sse4,x64_sse4_noavx,x64_avx,nox64,
786 sse2,sse2_noavx,sse3,sse4,sse4_noavx,avx,noavx,
787 avx2,noavx2,bmi,bmi2,fma4,fma,avx512f,noavx512f,
788 avx512bw,noavx512bw,avx512dq,noavx512dq,
789 avx512vl,noavx512vl,x64_avx512dq,x64_avx512bw"
790 (const_string "base"))
792 (define_attr "enabled" ""
793 (cond [(eq_attr "isa" "x64") (symbol_ref "TARGET_64BIT")
794 (eq_attr "isa" "x64_sse2")
795 (symbol_ref "TARGET_64BIT && TARGET_SSE2")
796 (eq_attr "isa" "x64_sse4")
797 (symbol_ref "TARGET_64BIT && TARGET_SSE4_1")
798 (eq_attr "isa" "x64_sse4_noavx")
799 (symbol_ref "TARGET_64BIT && TARGET_SSE4_1 && !TARGET_AVX")
800 (eq_attr "isa" "x64_avx")
801 (symbol_ref "TARGET_64BIT && TARGET_AVX")
802 (eq_attr "isa" "x64_avx512dq")
803 (symbol_ref "TARGET_64BIT && TARGET_AVX512DQ")
804 (eq_attr "isa" "x64_avx512bw")
805 (symbol_ref "TARGET_64BIT && TARGET_AVX512BW")
806 (eq_attr "isa" "nox64") (symbol_ref "!TARGET_64BIT")
807 (eq_attr "isa" "sse2") (symbol_ref "TARGET_SSE2")
808 (eq_attr "isa" "sse2_noavx")
809 (symbol_ref "TARGET_SSE2 && !TARGET_AVX")
810 (eq_attr "isa" "sse3") (symbol_ref "TARGET_SSE3")
811 (eq_attr "isa" "sse4") (symbol_ref "TARGET_SSE4_1")
812 (eq_attr "isa" "sse4_noavx")
813 (symbol_ref "TARGET_SSE4_1 && !TARGET_AVX")
814 (eq_attr "isa" "avx") (symbol_ref "TARGET_AVX")
815 (eq_attr "isa" "noavx") (symbol_ref "!TARGET_AVX")
816 (eq_attr "isa" "avx2") (symbol_ref "TARGET_AVX2")
817 (eq_attr "isa" "noavx2") (symbol_ref "!TARGET_AVX2")
818 (eq_attr "isa" "bmi") (symbol_ref "TARGET_BMI")
819 (eq_attr "isa" "bmi2") (symbol_ref "TARGET_BMI2")
820 (eq_attr "isa" "fma4") (symbol_ref "TARGET_FMA4")
821 (eq_attr "isa" "fma") (symbol_ref "TARGET_FMA")
822 (eq_attr "isa" "avx512f") (symbol_ref "TARGET_AVX512F")
823 (eq_attr "isa" "noavx512f") (symbol_ref "!TARGET_AVX512F")
824 (eq_attr "isa" "avx512bw") (symbol_ref "TARGET_AVX512BW")
825 (eq_attr "isa" "noavx512bw") (symbol_ref "!TARGET_AVX512BW")
826 (eq_attr "isa" "avx512dq") (symbol_ref "TARGET_AVX512DQ")
827 (eq_attr "isa" "noavx512dq") (symbol_ref "!TARGET_AVX512DQ")
828 (eq_attr "isa" "avx512vl") (symbol_ref "TARGET_AVX512VL")
829 (eq_attr "isa" "noavx512vl") (symbol_ref "!TARGET_AVX512VL")
833 (define_attr "preferred_for_size" "" (const_int 1))
834 (define_attr "preferred_for_speed" "" (const_int 1))
836 ;; Describe a user's asm statement.
837 (define_asm_attributes
838 [(set_attr "length" "128")
839 (set_attr "type" "multi")])
841 (define_code_iterator plusminus [plus minus])
843 (define_code_iterator sat_plusminus [ss_plus us_plus ss_minus us_minus])
845 (define_code_iterator multdiv [mult div])
847 ;; Base name for define_insn
848 (define_code_attr plusminus_insn
849 [(plus "add") (ss_plus "ssadd") (us_plus "usadd")
850 (minus "sub") (ss_minus "sssub") (us_minus "ussub")])
852 ;; Base name for insn mnemonic.
853 (define_code_attr plusminus_mnemonic
854 [(plus "add") (ss_plus "adds") (us_plus "addus")
855 (minus "sub") (ss_minus "subs") (us_minus "subus")])
856 (define_code_attr multdiv_mnemonic
857 [(mult "mul") (div "div")])
859 ;; Mark commutative operators as such in constraints.
860 (define_code_attr comm [(plus "%") (ss_plus "%") (us_plus "%")
861 (minus "") (ss_minus "") (us_minus "")])
863 ;; Mapping of max and min
864 (define_code_iterator maxmin [smax smin umax umin])
866 ;; Mapping of signed max and min
867 (define_code_iterator smaxmin [smax smin])
869 ;; Mapping of unsigned max and min
870 (define_code_iterator umaxmin [umax umin])
872 ;; Base name for integer and FP insn mnemonic
873 (define_code_attr maxmin_int [(smax "maxs") (smin "mins")
874 (umax "maxu") (umin "minu")])
875 (define_code_attr maxmin_float [(smax "max") (smin "min")])
877 (define_int_iterator IEEE_MAXMIN
881 (define_int_attr ieee_maxmin
882 [(UNSPEC_IEEE_MAX "max")
883 (UNSPEC_IEEE_MIN "min")])
885 ;; Mapping of logic operators
886 (define_code_iterator any_logic [and ior xor])
887 (define_code_iterator any_or [ior xor])
888 (define_code_iterator fpint_logic [and xor])
890 ;; Base name for insn mnemonic.
891 (define_code_attr logic [(and "and") (ior "or") (xor "xor")])
893 ;; Mapping of logic-shift operators
894 (define_code_iterator any_lshift [ashift lshiftrt])
896 ;; Mapping of shift-right operators
897 (define_code_iterator any_shiftrt [lshiftrt ashiftrt])
899 ;; Mapping of all shift operators
900 (define_code_iterator any_shift [ashift lshiftrt ashiftrt])
902 ;; Base name for define_insn
903 (define_code_attr shift_insn
904 [(ashift "ashl") (lshiftrt "lshr") (ashiftrt "ashr")])
906 ;; Base name for insn mnemonic.
907 (define_code_attr shift [(ashift "sll") (lshiftrt "shr") (ashiftrt "sar")])
908 (define_code_attr vshift [(ashift "sll") (lshiftrt "srl") (ashiftrt "sra")])
910 ;; Mapping of rotate operators
911 (define_code_iterator any_rotate [rotate rotatert])
913 ;; Base name for define_insn
914 (define_code_attr rotate_insn [(rotate "rotl") (rotatert "rotr")])
916 ;; Base name for insn mnemonic.
917 (define_code_attr rotate [(rotate "rol") (rotatert "ror")])
919 ;; Mapping of abs neg operators
920 (define_code_iterator absneg [abs neg])
922 ;; Base name for x87 insn mnemonic.
923 (define_code_attr absneg_mnemonic [(abs "fabs") (neg "fchs")])
925 ;; Used in signed and unsigned widening multiplications.
926 (define_code_iterator any_extend [sign_extend zero_extend])
928 ;; Prefix for insn menmonic.
929 (define_code_attr sgnprefix [(sign_extend "i") (zero_extend "")])
931 ;; Prefix for define_insn
932 (define_code_attr u [(sign_extend "") (zero_extend "u")])
933 (define_code_attr s [(sign_extend "s") (zero_extend "u")])
934 (define_code_attr u_bool [(sign_extend "false") (zero_extend "true")])
936 ;; Used in signed and unsigned truncations.
937 (define_code_iterator any_truncate [ss_truncate truncate us_truncate])
938 ;; Instruction suffix for truncations.
939 (define_code_attr trunsuffix [(ss_truncate "s") (truncate "") (us_truncate "us")])
941 ;; Used in signed and unsigned fix.
942 (define_code_iterator any_fix [fix unsigned_fix])
943 (define_code_attr fixsuffix [(fix "") (unsigned_fix "u")])
944 (define_code_attr fixunssuffix [(fix "") (unsigned_fix "uns")])
945 (define_code_attr fixprefix [(fix "s") (unsigned_fix "u")])
947 ;; Used in signed and unsigned float.
948 (define_code_iterator any_float [float unsigned_float])
949 (define_code_attr floatsuffix [(float "") (unsigned_float "u")])
950 (define_code_attr floatunssuffix [(float "") (unsigned_float "uns")])
951 (define_code_attr floatprefix [(float "s") (unsigned_float "u")])
953 ;; All integer modes.
954 (define_mode_iterator SWI1248x [QI HI SI DI])
956 ;; All integer modes without QImode.
957 (define_mode_iterator SWI248x [HI SI DI])
959 ;; All integer modes without QImode and HImode.
960 (define_mode_iterator SWI48x [SI DI])
962 ;; All integer modes without SImode and DImode.
963 (define_mode_iterator SWI12 [QI HI])
965 ;; All integer modes without DImode.
966 (define_mode_iterator SWI124 [QI HI SI])
968 ;; All integer modes without QImode and DImode.
969 (define_mode_iterator SWI24 [HI SI])
971 ;; Single word integer modes.
972 (define_mode_iterator SWI [QI HI SI (DI "TARGET_64BIT")])
974 ;; Single word integer modes without QImode.
975 (define_mode_iterator SWI248 [HI SI (DI "TARGET_64BIT")])
977 ;; Single word integer modes without QImode and HImode.
978 (define_mode_iterator SWI48 [SI (DI "TARGET_64BIT")])
980 ;; All math-dependant single and double word integer modes.
981 (define_mode_iterator SDWIM [(QI "TARGET_QIMODE_MATH")
982 (HI "TARGET_HIMODE_MATH")
983 SI DI (TI "TARGET_64BIT")])
985 ;; Math-dependant single word integer modes.
986 (define_mode_iterator SWIM [(QI "TARGET_QIMODE_MATH")
987 (HI "TARGET_HIMODE_MATH")
988 SI (DI "TARGET_64BIT")])
990 ;; Math-dependant integer modes without DImode.
991 (define_mode_iterator SWIM124 [(QI "TARGET_QIMODE_MATH")
992 (HI "TARGET_HIMODE_MATH")
995 ;; Math-dependant integer modes with DImode.
996 (define_mode_iterator SWIM1248x [(QI "TARGET_QIMODE_MATH")
997 (HI "TARGET_HIMODE_MATH")
998 SI (DI "(TARGET_STV && TARGET_SSE2) || TARGET_64BIT")])
1000 ;; Math-dependant single word integer modes without QImode.
1001 (define_mode_iterator SWIM248 [(HI "TARGET_HIMODE_MATH")
1002 SI (DI "TARGET_64BIT")])
1004 ;; Double word integer modes.
1005 (define_mode_iterator DWI [(DI "!TARGET_64BIT")
1006 (TI "TARGET_64BIT")])
1008 ;; GET_MODE_SIZE for selected modes. As GET_MODE_SIZE is not
1009 ;; compile time constant, it is faster to use <MODE_SIZE> than
1010 ;; GET_MODE_SIZE (<MODE>mode). For XFmode which depends on
1011 ;; command line options just use GET_MODE_SIZE macro.
1012 (define_mode_attr MODE_SIZE [(QI "1") (HI "2") (SI "4") (DI "8") (TI "16")
1013 (SF "4") (DF "8") (XF "GET_MODE_SIZE (XFmode)")
1014 (V16QI "16") (V32QI "32") (V64QI "64")
1015 (V8HI "16") (V16HI "32") (V32HI "64")
1016 (V4SI "16") (V8SI "32") (V16SI "64")
1017 (V2DI "16") (V4DI "32") (V8DI "64")
1018 (V1TI "16") (V2TI "32") (V4TI "64")
1019 (V2DF "16") (V4DF "32") (V8DF "64")
1020 (V4SF "16") (V8SF "32") (V16SF "64")])
1022 ;; Double word integer modes as mode attribute.
1023 (define_mode_attr DWI [(QI "HI") (HI "SI") (SI "DI") (DI "TI")])
1024 (define_mode_attr dwi [(QI "hi") (HI "si") (SI "di") (DI "ti")])
1026 ;; LEA mode corresponding to an integer mode
1027 (define_mode_attr LEAMODE [(QI "SI") (HI "SI") (SI "SI") (DI "DI")])
1029 ;; Half mode for double word integer modes.
1030 (define_mode_iterator DWIH [(SI "!TARGET_64BIT")
1031 (DI "TARGET_64BIT")])
1033 ;; Instruction suffix for integer modes.
1034 (define_mode_attr imodesuffix [(QI "b") (HI "w") (SI "l") (DI "q")])
1036 ;; Instruction suffix for masks.
1037 (define_mode_attr mskmodesuffix [(QI "b") (HI "w") (SI "d") (DI "q")])
1039 ;; Pointer size prefix for integer modes (Intel asm dialect)
1040 (define_mode_attr iptrsize [(QI "BYTE")
1045 ;; Register class for integer modes.
1046 (define_mode_attr r [(QI "q") (HI "r") (SI "r") (DI "r")])
1048 ;; Immediate operand constraint for integer modes.
1049 (define_mode_attr i [(QI "n") (HI "n") (SI "e") (DI "e")])
1051 ;; General operand constraint for word modes.
1052 (define_mode_attr g [(QI "qmn") (HI "rmn") (SI "rme") (DI "rme")])
1054 ;; Immediate operand constraint for double integer modes.
1055 (define_mode_attr di [(SI "nF") (DI "Wd")])
1057 ;; Immediate operand constraint for shifts.
1058 (define_mode_attr S [(QI "I") (HI "I") (SI "I") (DI "J") (TI "O")])
1060 ;; Print register name in the specified mode.
1061 (define_mode_attr k [(QI "b") (HI "w") (SI "k") (DI "q")])
1063 ;; General operand predicate for integer modes.
1064 (define_mode_attr general_operand
1065 [(QI "general_operand")
1066 (HI "general_operand")
1067 (SI "x86_64_general_operand")
1068 (DI "x86_64_general_operand")
1069 (TI "x86_64_general_operand")])
1071 ;; General operand predicate for integer modes, where for TImode
1072 ;; we need both words of the operand to be general operands.
1073 (define_mode_attr general_hilo_operand
1074 [(QI "general_operand")
1075 (HI "general_operand")
1076 (SI "x86_64_general_operand")
1077 (DI "x86_64_general_operand")
1078 (TI "x86_64_hilo_general_operand")])
1080 ;; General sign extend operand predicate for integer modes,
1081 ;; which disallows VOIDmode operands and thus it is suitable
1082 ;; for use inside sign_extend.
1083 (define_mode_attr general_sext_operand
1084 [(QI "sext_operand")
1086 (SI "x86_64_sext_operand")
1087 (DI "x86_64_sext_operand")])
1089 ;; General sign/zero extend operand predicate for integer modes.
1090 (define_mode_attr general_szext_operand
1091 [(QI "general_operand")
1092 (HI "general_operand")
1093 (SI "x86_64_szext_general_operand")
1094 (DI "x86_64_szext_general_operand")])
1096 ;; Immediate operand predicate for integer modes.
1097 (define_mode_attr immediate_operand
1098 [(QI "immediate_operand")
1099 (HI "immediate_operand")
1100 (SI "x86_64_immediate_operand")
1101 (DI "x86_64_immediate_operand")])
1103 ;; Nonmemory operand predicate for integer modes.
1104 (define_mode_attr nonmemory_operand
1105 [(QI "nonmemory_operand")
1106 (HI "nonmemory_operand")
1107 (SI "x86_64_nonmemory_operand")
1108 (DI "x86_64_nonmemory_operand")])
1110 ;; Operand predicate for shifts.
1111 (define_mode_attr shift_operand
1112 [(QI "nonimmediate_operand")
1113 (HI "nonimmediate_operand")
1114 (SI "nonimmediate_operand")
1115 (DI "shiftdi_operand")
1116 (TI "register_operand")])
1118 ;; Operand predicate for shift argument.
1119 (define_mode_attr shift_immediate_operand
1120 [(QI "const_1_to_31_operand")
1121 (HI "const_1_to_31_operand")
1122 (SI "const_1_to_31_operand")
1123 (DI "const_1_to_63_operand")])
1125 ;; Input operand predicate for arithmetic left shifts.
1126 (define_mode_attr ashl_input_operand
1127 [(QI "nonimmediate_operand")
1128 (HI "nonimmediate_operand")
1129 (SI "nonimmediate_operand")
1130 (DI "ashldi_input_operand")
1131 (TI "reg_or_pm1_operand")])
1133 ;; SSE and x87 SFmode and DFmode floating point modes
1134 (define_mode_iterator MODEF [SF DF])
1136 ;; All x87 floating point modes
1137 (define_mode_iterator X87MODEF [SF DF XF])
1139 ;; SSE instruction suffix for various modes
1140 (define_mode_attr ssemodesuffix
1141 [(SF "ss") (DF "sd")
1142 (V16SF "ps") (V8DF "pd")
1143 (V8SF "ps") (V4DF "pd")
1144 (V4SF "ps") (V2DF "pd")
1145 (V16QI "b") (V8HI "w") (V4SI "d") (V2DI "q")
1146 (V32QI "b") (V16HI "w") (V8SI "d") (V4DI "q")
1147 (V64QI "b") (V32HI "w") (V16SI "d") (V8DI "q")])
1149 ;; SSE vector suffix for floating point modes
1150 (define_mode_attr ssevecmodesuffix [(SF "ps") (DF "pd")])
1152 ;; SSE vector mode corresponding to a scalar mode
1153 (define_mode_attr ssevecmode
1154 [(QI "V16QI") (HI "V8HI") (SI "V4SI") (DI "V2DI") (SF "V4SF") (DF "V2DF")])
1155 (define_mode_attr ssevecmodelower
1156 [(QI "v16qi") (HI "v8hi") (SI "v4si") (DI "v2di") (SF "v4sf") (DF "v2df")])
1158 ;; AVX512F vector mode corresponding to a scalar mode
1159 (define_mode_attr avx512fvecmode
1160 [(QI "V64QI") (HI "V32HI") (SI "V16SI") (DI "V8DI") (SF "V16SF") (DF "V8DF")])
1162 ;; Instruction suffix for REX 64bit operators.
1163 (define_mode_attr rex64suffix [(SI "") (DI "{q}")])
1164 (define_mode_attr rex64namesuffix [(SI "") (DI "q")])
1166 ;; This mode iterator allows :P to be used for patterns that operate on
1167 ;; pointer-sized quantities. Exactly one of the two alternatives will match.
1168 (define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
1170 ;; This mode iterator allows :W to be used for patterns that operate on
1171 ;; word_mode sized quantities.
1172 (define_mode_iterator W
1173 [(SI "word_mode == SImode") (DI "word_mode == DImode")])
1175 ;; This mode iterator allows :PTR to be used for patterns that operate on
1176 ;; ptr_mode sized quantities.
1177 (define_mode_iterator PTR
1178 [(SI "ptr_mode == SImode") (DI "ptr_mode == DImode")])
1180 ;; Scheduling descriptions
1182 (include "pentium.md")
1185 (include "athlon.md")
1186 (include "bdver1.md")
1187 (include "bdver3.md")
1188 (include "btver2.md")
1189 (include "znver1.md")
1190 (include "geode.md")
1194 (include "core2.md")
1195 (include "haswell.md")
1198 ;; Operand and operator predicates and constraints
1200 (include "predicates.md")
1201 (include "constraints.md")
1204 ;; Compare and branch/compare and store instructions.
1206 (define_expand "cbranch<mode>4"
1207 [(set (reg:CC FLAGS_REG)
1208 (compare:CC (match_operand:SDWIM 1 "nonimmediate_operand")
1209 (match_operand:SDWIM 2 "<general_operand>")))
1210 (set (pc) (if_then_else
1211 (match_operator 0 "ordered_comparison_operator"
1212 [(reg:CC FLAGS_REG) (const_int 0)])
1213 (label_ref (match_operand 3))
1217 if (MEM_P (operands[1]) && MEM_P (operands[2]))
1218 operands[1] = force_reg (<MODE>mode, operands[1]);
1219 ix86_expand_branch (GET_CODE (operands[0]),
1220 operands[1], operands[2], operands[3]);
1224 (define_expand "cstore<mode>4"
1225 [(set (reg:CC FLAGS_REG)
1226 (compare:CC (match_operand:SWIM 2 "nonimmediate_operand")
1227 (match_operand:SWIM 3 "<general_operand>")))
1228 (set (match_operand:QI 0 "register_operand")
1229 (match_operator 1 "ordered_comparison_operator"
1230 [(reg:CC FLAGS_REG) (const_int 0)]))]
1233 if (MEM_P (operands[2]) && MEM_P (operands[3]))
1234 operands[2] = force_reg (<MODE>mode, operands[2]);
1235 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1236 operands[2], operands[3]);
1240 (define_expand "cmp<mode>_1"
1241 [(set (reg:CC FLAGS_REG)
1242 (compare:CC (match_operand:SWI48 0 "nonimmediate_operand")
1243 (match_operand:SWI48 1 "<general_operand>")))])
1245 (define_mode_iterator SWI1248_AVX512BWDQ2_64
1246 [(QI "TARGET_AVX512DQ") (HI "TARGET_AVX512DQ")
1247 (SI "TARGET_AVX512BW") (DI "TARGET_AVX512BW && TARGET_64BIT")])
1249 (define_insn "*cmp<mode>_ccz_1"
1250 [(set (reg FLAGS_REG)
1251 (compare (match_operand:SWI1248_AVX512BWDQ2_64 0
1252 "nonimmediate_operand" "<r>,?m<r>,$k")
1253 (match_operand:SWI1248_AVX512BWDQ2_64 1 "const0_operand")))]
1254 "ix86_match_ccmode (insn, CCZmode)"
1256 test{<imodesuffix>}\t%0, %0
1257 cmp{<imodesuffix>}\t{%1, %0|%0, %1}
1258 ktest<mskmodesuffix>\t%0, %0"
1259 [(set_attr "type" "test,icmp,msklog")
1260 (set_attr "length_immediate" "0,1,*")
1261 (set_attr "prefix" "*,*,vex")
1262 (set_attr "mode" "<MODE>")])
1264 (define_insn "*cmp<mode>_ccno_1"
1265 [(set (reg FLAGS_REG)
1266 (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>,?m<r>")
1267 (match_operand:SWI 1 "const0_operand")))]
1268 "ix86_match_ccmode (insn, CCNOmode)"
1270 test{<imodesuffix>}\t%0, %0
1271 cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1272 [(set_attr "type" "test,icmp")
1273 (set_attr "length_immediate" "0,1")
1274 (set_attr "mode" "<MODE>")])
1276 (define_insn "*cmp<mode>_1"
1277 [(set (reg FLAGS_REG)
1278 (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
1279 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m")))]
1280 "ix86_match_ccmode (insn, CCmode)"
1281 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1282 [(set_attr "type" "icmp")
1283 (set_attr "mode" "<MODE>")])
1285 (define_insn "*cmp<mode>_minus_1"
1286 [(set (reg FLAGS_REG)
1288 (minus:SWI (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
1289 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
1291 "ix86_match_ccmode (insn, CCGOCmode)"
1292 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1293 [(set_attr "type" "icmp")
1294 (set_attr "mode" "<MODE>")])
1296 (define_insn "*cmpqi_ext_1"
1297 [(set (reg FLAGS_REG)
1299 (match_operand:QI 0 "nonimmediate_operand" "QBc,m")
1302 (match_operand 1 "ext_register_operand" "Q,Q")
1304 (const_int 8)) 0)))]
1305 "ix86_match_ccmode (insn, CCmode)"
1306 "cmp{b}\t{%h1, %0|%0, %h1}"
1307 [(set_attr "isa" "*,nox64")
1308 (set_attr "type" "icmp")
1309 (set_attr "mode" "QI")])
1311 (define_insn "*cmpqi_ext_2"
1312 [(set (reg FLAGS_REG)
1316 (match_operand 0 "ext_register_operand" "Q")
1319 (match_operand:QI 1 "const0_operand")))]
1320 "ix86_match_ccmode (insn, CCNOmode)"
1322 [(set_attr "type" "test")
1323 (set_attr "length_immediate" "0")
1324 (set_attr "mode" "QI")])
1326 (define_expand "cmpqi_ext_3"
1327 [(set (reg:CC FLAGS_REG)
1331 (match_operand 0 "ext_register_operand")
1334 (match_operand:QI 1 "const_int_operand")))])
1336 (define_insn "*cmpqi_ext_3"
1337 [(set (reg FLAGS_REG)
1341 (match_operand 0 "ext_register_operand" "Q,Q")
1344 (match_operand:QI 1 "general_operand" "QnBc,m")))]
1345 "ix86_match_ccmode (insn, CCmode)"
1346 "cmp{b}\t{%1, %h0|%h0, %1}"
1347 [(set_attr "isa" "*,nox64")
1348 (set_attr "type" "icmp")
1349 (set_attr "mode" "QI")])
1351 (define_insn "*cmpqi_ext_4"
1352 [(set (reg FLAGS_REG)
1356 (match_operand 0 "ext_register_operand" "Q")
1361 (match_operand 1 "ext_register_operand" "Q")
1363 (const_int 8)) 0)))]
1364 "ix86_match_ccmode (insn, CCmode)"
1365 "cmp{b}\t{%h1, %h0|%h0, %h1}"
1366 [(set_attr "type" "icmp")
1367 (set_attr "mode" "QI")])
1369 ;; These implement float point compares.
1370 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
1371 ;; which would allow mix and match FP modes on the compares. Which is what
1372 ;; the old patterns did, but with many more of them.
1374 (define_expand "cbranchxf4"
1375 [(set (reg:CC FLAGS_REG)
1376 (compare:CC (match_operand:XF 1 "nonmemory_operand")
1377 (match_operand:XF 2 "nonmemory_operand")))
1378 (set (pc) (if_then_else
1379 (match_operator 0 "ix86_fp_comparison_operator"
1382 (label_ref (match_operand 3))
1386 ix86_expand_branch (GET_CODE (operands[0]),
1387 operands[1], operands[2], operands[3]);
1391 (define_expand "cstorexf4"
1392 [(set (reg:CC FLAGS_REG)
1393 (compare:CC (match_operand:XF 2 "nonmemory_operand")
1394 (match_operand:XF 3 "nonmemory_operand")))
1395 (set (match_operand:QI 0 "register_operand")
1396 (match_operator 1 "ix86_fp_comparison_operator"
1401 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1402 operands[2], operands[3]);
1406 (define_expand "cbranch<mode>4"
1407 [(set (reg:CC FLAGS_REG)
1408 (compare:CC (match_operand:MODEF 1 "cmp_fp_expander_operand")
1409 (match_operand:MODEF 2 "cmp_fp_expander_operand")))
1410 (set (pc) (if_then_else
1411 (match_operator 0 "ix86_fp_comparison_operator"
1414 (label_ref (match_operand 3))
1416 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1418 ix86_expand_branch (GET_CODE (operands[0]),
1419 operands[1], operands[2], operands[3]);
1423 (define_expand "cstore<mode>4"
1424 [(set (reg:CC FLAGS_REG)
1425 (compare:CC (match_operand:MODEF 2 "cmp_fp_expander_operand")
1426 (match_operand:MODEF 3 "cmp_fp_expander_operand")))
1427 (set (match_operand:QI 0 "register_operand")
1428 (match_operator 1 "ix86_fp_comparison_operator"
1431 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1433 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1434 operands[2], operands[3]);
1438 (define_expand "cbranchcc4"
1439 [(set (pc) (if_then_else
1440 (match_operator 0 "comparison_operator"
1441 [(match_operand 1 "flags_reg_operand")
1442 (match_operand 2 "const0_operand")])
1443 (label_ref (match_operand 3))
1447 ix86_expand_branch (GET_CODE (operands[0]),
1448 operands[1], operands[2], operands[3]);
1452 (define_expand "cstorecc4"
1453 [(set (match_operand:QI 0 "register_operand")
1454 (match_operator 1 "comparison_operator"
1455 [(match_operand 2 "flags_reg_operand")
1456 (match_operand 3 "const0_operand")]))]
1459 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1460 operands[2], operands[3]);
1464 ;; FP compares, step 1:
1465 ;; Set the FP condition codes and move fpsr to ax.
1467 ;; We may not use "#" to split and emit these
1468 ;; due to reg-stack pops killing fpsr.
1470 (define_insn "*cmpxf_i387"
1471 [(set (match_operand:HI 0 "register_operand" "=a")
1474 (match_operand:XF 1 "register_operand" "f")
1475 (match_operand:XF 2 "reg_or_0_operand" "fC"))]
1478 "* return output_fp_compare (insn, operands, false, false);"
1479 [(set_attr "type" "multi")
1480 (set_attr "unit" "i387")
1481 (set_attr "mode" "XF")])
1483 (define_insn "*cmp<mode>_i387"
1484 [(set (match_operand:HI 0 "register_operand" "=a")
1487 (match_operand:MODEF 1 "register_operand" "f")
1488 (match_operand:MODEF 2 "nonimm_or_0_operand" "fmC"))]
1491 "* return output_fp_compare (insn, operands, false, false);"
1492 [(set_attr "type" "multi")
1493 (set_attr "unit" "i387")
1494 (set_attr "mode" "<MODE>")])
1496 (define_insn "*cmp<X87MODEF:mode>_<SWI24:mode>_i387"
1497 [(set (match_operand:HI 0 "register_operand" "=a")
1500 (match_operand:X87MODEF 1 "register_operand" "f")
1502 (match_operand:SWI24 2 "nonimmediate_operand" "m")))]
1505 && (TARGET_USE_<SWI24:MODE>MODE_FIOP
1506 || optimize_function_for_size_p (cfun))"
1507 "* return output_fp_compare (insn, operands, false, false);"
1508 [(set_attr "type" "multi")
1509 (set_attr "unit" "i387")
1510 (set_attr "fp_int_src" "true")
1511 (set_attr "mode" "<SWI24:MODE>")])
1513 (define_insn "*cmpu<mode>_i387"
1514 [(set (match_operand:HI 0 "register_operand" "=a")
1518 (match_operand:X87MODEF 1 "register_operand" "f")
1519 (match_operand:X87MODEF 2 "register_operand" "f"))]
1523 "* return output_fp_compare (insn, operands, false, true);"
1524 [(set_attr "type" "multi")
1525 (set_attr "unit" "i387")
1526 (set_attr "mode" "<MODE>")])
1528 ;; FP compares, step 2:
1529 ;; Get ax into flags, general case.
1531 (define_insn "x86_sahf_1"
1532 [(set (reg:CC FLAGS_REG)
1533 (unspec:CC [(match_operand:HI 0 "register_operand" "a")]
1537 #ifndef HAVE_AS_IX86_SAHF
1539 return ASM_BYTE "0x9e";
1544 [(set_attr "length" "1")
1545 (set_attr "athlon_decode" "vector")
1546 (set_attr "amdfam10_decode" "direct")
1547 (set_attr "bdver1_decode" "direct")
1548 (set_attr "mode" "SI")])
1550 ;; Pentium Pro can do both steps in one go.
1551 ;; (these instructions set flags directly)
1553 (define_subst_attr "unord" "unord_subst" "" "u")
1554 (define_subst_attr "unordered" "unord_subst" "false" "true")
1556 (define_subst "unord_subst"
1557 [(set (match_operand:CCFP 0)
1558 (match_operand:CCFP 1))]
1565 (define_insn "*cmpi<unord>xf_i387"
1566 [(set (reg:CCFP FLAGS_REG)
1568 (match_operand:XF 0 "register_operand" "f")
1569 (match_operand:XF 1 "register_operand" "f")))]
1570 "TARGET_80387 && TARGET_CMOVE"
1571 "* return output_fp_compare (insn, operands, true, <unordered>);"
1572 [(set_attr "type" "fcmp")
1573 (set_attr "mode" "XF")
1574 (set_attr "athlon_decode" "vector")
1575 (set_attr "amdfam10_decode" "direct")
1576 (set_attr "bdver1_decode" "double")
1577 (set_attr "znver1_decode" "double")])
1579 (define_insn "*cmpi<unord><MODEF:mode>"
1580 [(set (reg:CCFP FLAGS_REG)
1582 (match_operand:MODEF 0 "register_operand" "f,v")
1583 (match_operand:MODEF 1 "register_ssemem_operand" "f,vm")))]
1584 "(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
1585 || (TARGET_80387 && TARGET_CMOVE)"
1587 * return output_fp_compare (insn, operands, true, <unordered>);
1588 %v<unord>comi<MODEF:ssemodesuffix>\t{%1, %0|%0, %1}"
1589 [(set_attr "type" "fcmp,ssecomi")
1590 (set_attr "prefix" "orig,maybe_vex")
1591 (set_attr "mode" "<MODEF:MODE>")
1592 (set_attr "prefix_rep" "*,0")
1593 (set (attr "prefix_data16")
1594 (cond [(eq_attr "alternative" "0")
1596 (eq_attr "mode" "DF")
1599 (const_string "0")))
1600 (set_attr "athlon_decode" "vector")
1601 (set_attr "amdfam10_decode" "direct")
1602 (set_attr "bdver1_decode" "double")
1603 (set_attr "znver1_decode" "double")
1604 (set (attr "enabled")
1606 (match_test ("SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"))
1608 (eq_attr "alternative" "0")
1609 (symbol_ref "TARGET_MIX_SSE_I387")
1610 (symbol_ref "true"))
1612 (eq_attr "alternative" "0")
1614 (symbol_ref "false"))))])
1616 ;; Push/pop instructions.
1618 (define_insn "*push<mode>2"
1619 [(set (match_operand:DWI 0 "push_operand" "=<")
1620 (match_operand:DWI 1 "general_no_elim_operand" "riF*o"))]
1623 [(set_attr "type" "multi")
1624 (set_attr "mode" "<MODE>")])
1627 [(set (match_operand:DWI 0 "push_operand")
1628 (match_operand:DWI 1 "general_gr_operand"))]
1631 "ix86_split_long_move (operands); DONE;")
1633 (define_insn "*pushdi2_rex64"
1634 [(set (match_operand:DI 0 "push_operand" "=<,!<")
1635 (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1640 [(set_attr "type" "push,multi")
1641 (set_attr "mode" "DI")])
1643 ;; Convert impossible pushes of immediate to existing instructions.
1644 ;; First try to get scratch register and go through it. In case this
1645 ;; fails, push sign extended lower part first and then overwrite
1646 ;; upper part by 32bit move.
1648 [(match_scratch:DI 2 "r")
1649 (set (match_operand:DI 0 "push_operand")
1650 (match_operand:DI 1 "immediate_operand"))]
1651 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1652 && !x86_64_immediate_operand (operands[1], DImode)"
1653 [(set (match_dup 2) (match_dup 1))
1654 (set (match_dup 0) (match_dup 2))])
1656 ;; We need to define this as both peepholer and splitter for case
1657 ;; peephole2 pass is not run.
1658 ;; "&& 1" is needed to keep it from matching the previous pattern.
1660 [(set (match_operand:DI 0 "push_operand")
1661 (match_operand:DI 1 "immediate_operand"))]
1662 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1663 && !x86_64_immediate_operand (operands[1], DImode) && 1"
1664 [(set (match_dup 0) (match_dup 1))
1665 (set (match_dup 2) (match_dup 3))]
1667 split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1669 operands[1] = gen_lowpart (DImode, operands[2]);
1670 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (Pmode, stack_pointer_rtx,
1675 [(set (match_operand:DI 0 "push_operand")
1676 (match_operand:DI 1 "immediate_operand"))]
1677 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
1678 ? epilogue_completed : reload_completed)
1679 && !symbolic_operand (operands[1], DImode)
1680 && !x86_64_immediate_operand (operands[1], DImode)"
1681 [(set (match_dup 0) (match_dup 1))
1682 (set (match_dup 2) (match_dup 3))]
1684 split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1686 operands[1] = gen_lowpart (DImode, operands[2]);
1687 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (Pmode, stack_pointer_rtx,
1691 (define_insn "*pushsi2"
1692 [(set (match_operand:SI 0 "push_operand" "=<")
1693 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1696 [(set_attr "type" "push")
1697 (set_attr "mode" "SI")])
1699 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1700 ;; "push a byte/word". But actually we use pushl, which has the effect
1701 ;; of rounding the amount pushed up to a word.
1703 ;; For TARGET_64BIT we always round up to 8 bytes.
1704 (define_insn "*push<mode>2_rex64"
1705 [(set (match_operand:SWI124 0 "push_operand" "=X")
1706 (match_operand:SWI124 1 "nonmemory_no_elim_operand" "r<i>"))]
1709 [(set_attr "type" "push")
1710 (set_attr "mode" "DI")])
1712 (define_insn "*push<mode>2"
1713 [(set (match_operand:SWI12 0 "push_operand" "=X")
1714 (match_operand:SWI12 1 "nonmemory_no_elim_operand" "rn"))]
1717 [(set_attr "type" "push")
1718 (set_attr "mode" "SI")])
1720 (define_insn "*push<mode>2_prologue"
1721 [(set (match_operand:W 0 "push_operand" "=<")
1722 (match_operand:W 1 "general_no_elim_operand" "r<i>*m"))
1723 (clobber (mem:BLK (scratch)))]
1725 "push{<imodesuffix>}\t%1"
1726 [(set_attr "type" "push")
1727 (set_attr "mode" "<MODE>")])
1729 (define_insn "*pop<mode>1"
1730 [(set (match_operand:W 0 "nonimmediate_operand" "=r*m")
1731 (match_operand:W 1 "pop_operand" ">"))]
1733 "pop{<imodesuffix>}\t%0"
1734 [(set_attr "type" "pop")
1735 (set_attr "mode" "<MODE>")])
1737 (define_insn "*pop<mode>1_epilogue"
1738 [(set (match_operand:W 0 "nonimmediate_operand" "=r*m")
1739 (match_operand:W 1 "pop_operand" ">"))
1740 (clobber (mem:BLK (scratch)))]
1742 "pop{<imodesuffix>}\t%0"
1743 [(set_attr "type" "pop")
1744 (set_attr "mode" "<MODE>")])
1746 (define_insn "*pushfl<mode>2"
1747 [(set (match_operand:W 0 "push_operand" "=<")
1748 (match_operand:W 1 "flags_reg_operand"))]
1750 "pushf{<imodesuffix>}"
1751 [(set_attr "type" "push")
1752 (set_attr "mode" "<MODE>")])
1754 (define_insn "*popfl<mode>1"
1755 [(set (match_operand:W 0 "flags_reg_operand")
1756 (match_operand:W 1 "pop_operand" ">"))]
1758 "popf{<imodesuffix>}"
1759 [(set_attr "type" "pop")
1760 (set_attr "mode" "<MODE>")])
1763 ;; Reload patterns to support multi-word load/store
1764 ;; with non-offsetable address.
1765 (define_expand "reload_noff_store"
1766 [(parallel [(match_operand 0 "memory_operand" "=m")
1767 (match_operand 1 "register_operand" "r")
1768 (match_operand:DI 2 "register_operand" "=&r")])]
1771 rtx mem = operands[0];
1772 rtx addr = XEXP (mem, 0);
1774 emit_move_insn (operands[2], addr);
1775 mem = replace_equiv_address_nv (mem, operands[2]);
1777 emit_insn (gen_rtx_SET (mem, operands[1]));
1781 (define_expand "reload_noff_load"
1782 [(parallel [(match_operand 0 "register_operand" "=r")
1783 (match_operand 1 "memory_operand" "m")
1784 (match_operand:DI 2 "register_operand" "=r")])]
1787 rtx mem = operands[1];
1788 rtx addr = XEXP (mem, 0);
1790 emit_move_insn (operands[2], addr);
1791 mem = replace_equiv_address_nv (mem, operands[2]);
1793 emit_insn (gen_rtx_SET (operands[0], mem));
1797 ;; Move instructions.
1799 (define_expand "movxi"
1800 [(set (match_operand:XI 0 "nonimmediate_operand")
1801 (match_operand:XI 1 "general_operand"))]
1803 "ix86_expand_vector_move (XImode, operands); DONE;")
1805 (define_expand "movoi"
1806 [(set (match_operand:OI 0 "nonimmediate_operand")
1807 (match_operand:OI 1 "general_operand"))]
1809 "ix86_expand_vector_move (OImode, operands); DONE;")
1811 (define_expand "movti"
1812 [(set (match_operand:TI 0 "nonimmediate_operand")
1813 (match_operand:TI 1 "general_operand"))]
1814 "TARGET_64BIT || TARGET_SSE"
1817 ix86_expand_move (TImode, operands);
1819 ix86_expand_vector_move (TImode, operands);
1823 ;; This expands to what emit_move_complex would generate if we didn't
1824 ;; have a movti pattern. Having this avoids problems with reload on
1825 ;; 32-bit targets when SSE is present, but doesn't seem to be harmful
1826 ;; to have around all the time.
1827 (define_expand "movcdi"
1828 [(set (match_operand:CDI 0 "nonimmediate_operand")
1829 (match_operand:CDI 1 "general_operand"))]
1832 if (push_operand (operands[0], CDImode))
1833 emit_move_complex_push (CDImode, operands[0], operands[1]);
1835 emit_move_complex_parts (operands[0], operands[1]);
1839 (define_expand "mov<mode>"
1840 [(set (match_operand:SWI1248x 0 "nonimmediate_operand")
1841 (match_operand:SWI1248x 1 "general_operand"))]
1843 "ix86_expand_move (<MODE>mode, operands); DONE;")
1845 (define_insn "*mov<mode>_xor"
1846 [(set (match_operand:SWI48 0 "register_operand" "=r")
1847 (match_operand:SWI48 1 "const0_operand"))
1848 (clobber (reg:CC FLAGS_REG))]
1851 [(set_attr "type" "alu1")
1852 (set_attr "mode" "SI")
1853 (set_attr "length_immediate" "0")])
1855 (define_insn "*mov<mode>_or"
1856 [(set (match_operand:SWI48 0 "register_operand" "=r")
1857 (match_operand:SWI48 1 "constm1_operand"))
1858 (clobber (reg:CC FLAGS_REG))]
1860 "or{<imodesuffix>}\t{%1, %0|%0, %1}"
1861 [(set_attr "type" "alu1")
1862 (set_attr "mode" "<MODE>")
1863 (set_attr "length_immediate" "1")])
1865 (define_insn "*movxi_internal_avx512f"
1866 [(set (match_operand:XI 0 "nonimmediate_operand" "=v,v ,v ,m")
1867 (match_operand:XI 1 "nonimmediate_or_sse_const_operand" " C,BC,vm,v"))]
1869 && (register_operand (operands[0], XImode)
1870 || register_operand (operands[1], XImode))"
1872 switch (get_attr_type (insn))
1875 return standard_sse_constant_opcode (insn, operands);
1878 if (misaligned_operand (operands[0], XImode)
1879 || misaligned_operand (operands[1], XImode))
1880 return "vmovdqu32\t{%1, %0|%0, %1}";
1882 return "vmovdqa32\t{%1, %0|%0, %1}";
1888 [(set_attr "type" "sselog1,sselog1,ssemov,ssemov")
1889 (set_attr "prefix" "evex")
1890 (set_attr "mode" "XI")])
1892 (define_insn "*movoi_internal_avx"
1893 [(set (match_operand:OI 0 "nonimmediate_operand" "=v,v ,v ,m")
1894 (match_operand:OI 1 "nonimmediate_or_sse_const_operand" " C,BC,vm,v"))]
1896 && (register_operand (operands[0], OImode)
1897 || register_operand (operands[1], OImode))"
1899 switch (get_attr_type (insn))
1902 return standard_sse_constant_opcode (insn, operands);
1905 if (misaligned_operand (operands[0], OImode)
1906 || misaligned_operand (operands[1], OImode))
1908 if (get_attr_mode (insn) == MODE_V8SF)
1909 return "vmovups\t{%1, %0|%0, %1}";
1910 else if (get_attr_mode (insn) == MODE_XI)
1911 return "vmovdqu32\t{%1, %0|%0, %1}";
1913 return "vmovdqu\t{%1, %0|%0, %1}";
1917 if (get_attr_mode (insn) == MODE_V8SF)
1918 return "vmovaps\t{%1, %0|%0, %1}";
1919 else if (get_attr_mode (insn) == MODE_XI)
1920 return "vmovdqa32\t{%1, %0|%0, %1}";
1922 return "vmovdqa\t{%1, %0|%0, %1}";
1929 [(set_attr "isa" "*,avx2,*,*")
1930 (set_attr "type" "sselog1,sselog1,ssemov,ssemov")
1931 (set_attr "prefix" "vex")
1933 (cond [(ior (match_operand 0 "ext_sse_reg_operand")
1934 (match_operand 1 "ext_sse_reg_operand"))
1936 (and (eq_attr "alternative" "1")
1937 (match_test "TARGET_AVX512VL"))
1939 (ior (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
1940 (and (eq_attr "alternative" "3")
1941 (match_test "TARGET_SSE_TYPELESS_STORES")))
1942 (const_string "V8SF")
1944 (const_string "OI")))])
1946 (define_insn "*movti_internal"
1947 [(set (match_operand:TI 0 "nonimmediate_operand" "=!r ,o ,v,v ,v ,m,?r,?Yd")
1948 (match_operand:TI 1 "general_operand" "riFo,re,C,BC,vm,v,Yd,r"))]
1950 && !(MEM_P (operands[0]) && MEM_P (operands[1])))
1952 && nonimmediate_or_sse_const_operand (operands[1], TImode)
1953 && (register_operand (operands[0], TImode)
1954 || register_operand (operands[1], TImode)))"
1956 switch (get_attr_type (insn))
1962 return standard_sse_constant_opcode (insn, operands);
1965 /* TDmode values are passed as TImode on the stack. Moving them
1966 to stack may result in unaligned memory access. */
1967 if (misaligned_operand (operands[0], TImode)
1968 || misaligned_operand (operands[1], TImode))
1970 if (get_attr_mode (insn) == MODE_V4SF)
1971 return "%vmovups\t{%1, %0|%0, %1}";
1972 else if (get_attr_mode (insn) == MODE_XI)
1973 return "vmovdqu32\t{%1, %0|%0, %1}";
1975 return "%vmovdqu\t{%1, %0|%0, %1}";
1979 if (get_attr_mode (insn) == MODE_V4SF)
1980 return "%vmovaps\t{%1, %0|%0, %1}";
1981 else if (get_attr_mode (insn) == MODE_XI)
1982 return "vmovdqa32\t{%1, %0|%0, %1}";
1984 return "%vmovdqa\t{%1, %0|%0, %1}";
1992 (cond [(eq_attr "alternative" "0,1,6,7")
1993 (const_string "x64")
1994 (eq_attr "alternative" "3")
1995 (const_string "sse2")
1997 (const_string "*")))
1999 (cond [(eq_attr "alternative" "0,1,6,7")
2000 (const_string "multi")
2001 (eq_attr "alternative" "2,3")
2002 (const_string "sselog1")
2004 (const_string "ssemov")))
2005 (set (attr "prefix")
2006 (if_then_else (eq_attr "type" "sselog1,ssemov")
2007 (const_string "maybe_vex")
2008 (const_string "orig")))
2010 (cond [(eq_attr "alternative" "0,1")
2012 (ior (match_operand 0 "ext_sse_reg_operand")
2013 (match_operand 1 "ext_sse_reg_operand"))
2015 (and (eq_attr "alternative" "3")
2016 (match_test "TARGET_AVX512VL"))
2018 (ior (not (match_test "TARGET_SSE2"))
2019 (ior (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
2020 (and (eq_attr "alternative" "5")
2021 (match_test "TARGET_SSE_TYPELESS_STORES"))))
2022 (const_string "V4SF")
2023 (match_test "TARGET_AVX")
2025 (match_test "optimize_function_for_size_p (cfun)")
2026 (const_string "V4SF")
2028 (const_string "TI")))
2029 (set (attr "preferred_for_speed")
2030 (cond [(eq_attr "alternative" "6")
2031 (symbol_ref "TARGET_INTER_UNIT_MOVES_FROM_VEC")
2032 (eq_attr "alternative" "7")
2033 (symbol_ref "TARGET_INTER_UNIT_MOVES_TO_VEC")
2035 (symbol_ref "true")))])
2038 [(set (match_operand:TI 0 "sse_reg_operand")
2039 (match_operand:TI 1 "general_reg_operand"))]
2040 "TARGET_64BIT && TARGET_SSE4_1
2041 && reload_completed"
2044 (vec_duplicate:V2DI (match_dup 3))
2048 operands[2] = lowpart_subreg (V2DImode, operands[0], TImode);
2049 operands[3] = gen_highpart (DImode, operands[1]);
2051 emit_move_insn (gen_lowpart (DImode, operands[0]),
2052 gen_lowpart (DImode, operands[1]));
2055 (define_insn "*movdi_internal"
2056 [(set (match_operand:DI 0 "nonimmediate_operand"
2057 "=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")
2058 (match_operand:DI 1 "general_operand"
2059 "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"))]
2060 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2062 switch (get_attr_type (insn))
2065 return "kmovq\t{%1, %0|%0, %1}";
2071 return "pxor\t%0, %0";
2074 /* Handle broken assemblers that require movd instead of movq. */
2075 if (!HAVE_AS_IX86_INTERUNIT_MOVQ
2076 && (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1])))
2077 return "movd\t{%1, %0|%0, %1}";
2078 return "movq\t{%1, %0|%0, %1}";
2081 return standard_sse_constant_opcode (insn, operands);
2084 switch (get_attr_mode (insn))
2087 /* Handle broken assemblers that require movd instead of movq. */
2088 if (!HAVE_AS_IX86_INTERUNIT_MOVQ
2089 && (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1])))
2090 return "%vmovd\t{%1, %0|%0, %1}";
2091 return "%vmovq\t{%1, %0|%0, %1}";
2094 /* Handle AVX512 registers set. */
2095 if (EXT_REX_SSE_REG_P (operands[0])
2096 || EXT_REX_SSE_REG_P (operands[1]))
2097 return "vmovdqa64\t{%1, %0|%0, %1}";
2098 return "%vmovdqa\t{%1, %0|%0, %1}";
2101 gcc_assert (!TARGET_AVX);
2102 return "movlps\t{%1, %0|%0, %1}";
2104 return "%vmovaps\t{%1, %0|%0, %1}";
2111 if (SSE_REG_P (operands[0]))
2112 return "movq2dq\t{%1, %0|%0, %1}";
2114 return "movdq2q\t{%1, %0|%0, %1}";
2117 return "lea{q}\t{%E1, %0|%0, %E1}";
2120 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2121 if (get_attr_mode (insn) == MODE_SI)
2122 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2123 else if (which_alternative == 4)
2124 return "movabs{q}\t{%1, %0|%0, %1}";
2125 else if (ix86_use_lea_for_mov (insn, operands))
2126 return "lea{q}\t{%E1, %0|%0, %E1}";
2128 return "mov{q}\t{%1, %0|%0, %1}";
2135 (cond [(eq_attr "alternative" "0,1,17,18")
2136 (const_string "nox64")
2137 (eq_attr "alternative" "2,3,4,5,10,11,23,25")
2138 (const_string "x64")
2139 (eq_attr "alternative" "19,20")
2140 (const_string "x64_sse2")
2141 (eq_attr "alternative" "21,22")
2142 (const_string "sse2")
2144 (const_string "*")))
2146 (cond [(eq_attr "alternative" "0,1,17,18")
2147 (const_string "multi")
2148 (eq_attr "alternative" "6")
2149 (const_string "mmx")
2150 (eq_attr "alternative" "7,8,9,10,11")
2151 (const_string "mmxmov")
2152 (eq_attr "alternative" "12")
2153 (const_string "sselog1")
2154 (eq_attr "alternative" "13,14,15,16,19,20")
2155 (const_string "ssemov")
2156 (eq_attr "alternative" "21,22")
2157 (const_string "ssecvt")
2158 (eq_attr "alternative" "23,24,25,26")
2159 (const_string "mskmov")
2160 (and (match_operand 0 "register_operand")
2161 (match_operand 1 "pic_32bit_operand"))
2162 (const_string "lea")
2164 (const_string "imov")))
2167 (and (eq_attr "alternative" "4") (eq_attr "type" "imov"))
2169 (const_string "*")))
2170 (set (attr "length_immediate")
2172 (and (eq_attr "alternative" "4") (eq_attr "type" "imov"))
2174 (const_string "*")))
2175 (set (attr "prefix_rex")
2177 (eq_attr "alternative" "10,11,19,20")
2179 (const_string "*")))
2180 (set (attr "prefix")
2181 (if_then_else (eq_attr "type" "sselog1,ssemov")
2182 (const_string "maybe_vex")
2183 (const_string "orig")))
2184 (set (attr "prefix_data16")
2185 (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "DI"))
2187 (const_string "*")))
2189 (cond [(eq_attr "alternative" "2")
2191 (eq_attr "alternative" "12,13")
2192 (cond [(ior (match_operand 0 "ext_sse_reg_operand")
2193 (match_operand 1 "ext_sse_reg_operand"))
2195 (ior (not (match_test "TARGET_SSE2"))
2196 (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL"))
2197 (const_string "V4SF")
2198 (match_test "TARGET_AVX")
2200 (match_test "optimize_function_for_size_p (cfun)")
2201 (const_string "V4SF")
2203 (const_string "TI"))
2205 (and (eq_attr "alternative" "14,15,16")
2206 (not (match_test "TARGET_SSE2")))
2207 (const_string "V2SF")
2209 (const_string "DI")))
2210 (set (attr "preferred_for_speed")
2211 (cond [(eq_attr "alternative" "10,17,19")
2212 (symbol_ref "TARGET_INTER_UNIT_MOVES_FROM_VEC")
2213 (eq_attr "alternative" "11,18,20")
2214 (symbol_ref "TARGET_INTER_UNIT_MOVES_TO_VEC")
2216 (symbol_ref "true")))
2217 (set (attr "enabled")
2218 (cond [(eq_attr "alternative" "15")
2220 (match_test "TARGET_STV && TARGET_SSE2")
2221 (symbol_ref "false")
2223 (eq_attr "alternative" "16")
2225 (match_test "TARGET_STV && TARGET_SSE2")
2227 (symbol_ref "false"))
2229 (const_string "*")))])
2232 [(set (match_operand:<DWI> 0 "general_reg_operand")
2233 (match_operand:<DWI> 1 "sse_reg_operand"))]
2235 && reload_completed"
2239 (parallel [(const_int 1)])))]
2241 operands[2] = gen_highpart (<MODE>mode, operands[0]);
2242 operands[3] = lowpart_subreg (<ssevecmode>mode, operands[1], <DWI>mode);
2244 emit_move_insn (gen_lowpart (<MODE>mode, operands[0]),
2245 gen_lowpart (<MODE>mode, operands[1]));
2249 [(set (match_operand:DWI 0 "nonimmediate_gr_operand")
2250 (match_operand:DWI 1 "general_gr_operand"))]
2253 "ix86_split_long_move (operands); DONE;")
2256 [(set (match_operand:DI 0 "sse_reg_operand")
2257 (match_operand:DI 1 "general_reg_operand"))]
2258 "!TARGET_64BIT && TARGET_SSE4_1
2259 && reload_completed"
2262 (vec_duplicate:V4SI (match_dup 3))
2266 operands[2] = lowpart_subreg (V4SImode, operands[0], DImode);
2267 operands[3] = gen_highpart (SImode, operands[1]);
2269 emit_move_insn (gen_lowpart (SImode, operands[0]),
2270 gen_lowpart (SImode, operands[1]));
2273 ;; movabsq $0x0012345678000000, %rax is longer
2274 ;; than movl $0x12345678, %eax; shlq $24, %rax.
2276 [(set (match_operand:DI 0 "register_operand")
2277 (match_operand:DI 1 "const_int_operand"))]
2279 && optimize_insn_for_size_p ()
2280 && LEGACY_INT_REG_P (operands[0])
2281 && !x86_64_immediate_operand (operands[1], DImode)
2282 && !x86_64_zext_immediate_operand (operands[1], DImode)
2283 && !((UINTVAL (operands[1]) >> ctz_hwi (UINTVAL (operands[1])))
2284 & ~(HOST_WIDE_INT) 0xffffffff)
2285 && peep2_regno_dead_p (0, FLAGS_REG)"
2286 [(set (match_dup 0) (match_dup 1))
2287 (parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
2288 (clobber (reg:CC FLAGS_REG))])]
2290 int shift = ctz_hwi (UINTVAL (operands[1]));
2291 operands[1] = gen_int_mode (UINTVAL (operands[1]) >> shift, DImode);
2292 operands[2] = gen_int_mode (shift, QImode);
2295 (define_insn "*movsi_internal"
2296 [(set (match_operand:SI 0 "nonimmediate_operand"
2297 "=r,m ,*y,*y,?*y,?m,?r,?*y,*v,*v,*v,m ,?r,?*v,*k,*k ,*rm")
2298 (match_operand:SI 1 "general_operand"
2299 "g ,re,C ,*y,m ,*y,*y,r ,C ,*v,m ,*v,*v,r ,*r,*km,*k"))]
2300 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2302 switch (get_attr_type (insn))
2305 return standard_sse_constant_opcode (insn, operands);
2308 return "kmovd\t{%1, %0|%0, %1}";
2311 switch (get_attr_mode (insn))
2314 return "%vmovd\t{%1, %0|%0, %1}";
2316 return "%vmovdqa\t{%1, %0|%0, %1}";
2318 return "vmovdqa32\t{%g1, %g0|%g0, %g1}";
2321 return "%vmovaps\t{%1, %0|%0, %1}";
2324 gcc_assert (!TARGET_AVX);
2325 return "movss\t{%1, %0|%0, %1}";
2332 return "pxor\t%0, %0";
2335 switch (get_attr_mode (insn))
2338 return "movq\t{%1, %0|%0, %1}";
2340 return "movd\t{%1, %0|%0, %1}";
2347 return "lea{l}\t{%E1, %0|%0, %E1}";
2350 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2351 if (ix86_use_lea_for_mov (insn, operands))
2352 return "lea{l}\t{%E1, %0|%0, %E1}";
2354 return "mov{l}\t{%1, %0|%0, %1}";
2361 (cond [(eq_attr "alternative" "12,13")
2362 (const_string "sse2")
2364 (const_string "*")))
2366 (cond [(eq_attr "alternative" "2")
2367 (const_string "mmx")
2368 (eq_attr "alternative" "3,4,5,6,7")
2369 (const_string "mmxmov")
2370 (eq_attr "alternative" "8")
2371 (const_string "sselog1")
2372 (eq_attr "alternative" "9,10,11,12,13")
2373 (const_string "ssemov")
2374 (eq_attr "alternative" "14,15,16")
2375 (const_string "mskmov")
2376 (and (match_operand 0 "register_operand")
2377 (match_operand 1 "pic_32bit_operand"))
2378 (const_string "lea")
2380 (const_string "imov")))
2381 (set (attr "prefix")
2382 (if_then_else (eq_attr "type" "sselog1,ssemov")
2383 (const_string "maybe_vex")
2384 (const_string "orig")))
2385 (set (attr "prefix_data16")
2386 (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
2388 (const_string "*")))
2390 (cond [(eq_attr "alternative" "2,3")
2392 (eq_attr "alternative" "8,9")
2393 (cond [(ior (match_operand 0 "ext_sse_reg_operand")
2394 (match_operand 1 "ext_sse_reg_operand"))
2396 (ior (not (match_test "TARGET_SSE2"))
2397 (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL"))
2398 (const_string "V4SF")
2399 (match_test "TARGET_AVX")
2401 (match_test "optimize_function_for_size_p (cfun)")
2402 (const_string "V4SF")
2404 (const_string "TI"))
2406 (and (eq_attr "alternative" "10,11")
2407 (not (match_test "TARGET_SSE2")))
2410 (const_string "SI")))
2411 (set (attr "preferred_for_speed")
2412 (cond [(eq_attr "alternative" "6,12")
2413 (symbol_ref "TARGET_INTER_UNIT_MOVES_FROM_VEC")
2414 (eq_attr "alternative" "7,13")
2415 (symbol_ref "TARGET_INTER_UNIT_MOVES_TO_VEC")
2417 (symbol_ref "true")))])
2419 (define_insn "*movhi_internal"
2420 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r ,r ,m ,k,k ,r,m")
2421 (match_operand:HI 1 "general_operand" "r ,rn,rm,rn,r,km,k,k"))]
2422 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2424 switch (get_attr_type (insn))
2427 /* movzwl is faster than movw on p2 due to partial word stalls,
2428 though not as fast as an aligned movl. */
2429 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
2432 switch (which_alternative)
2435 return "kmovw\t{%k1, %0|%0, %k1}";
2437 return "kmovw\t{%1, %k0|%k0, %1}";
2440 return "kmovw\t{%1, %0|%0, %1}";
2446 if (get_attr_mode (insn) == MODE_SI)
2447 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2449 return "mov{w}\t{%1, %0|%0, %1}";
2453 (cond [(eq_attr "alternative" "4,5,6,7")
2454 (const_string "mskmov")
2455 (match_test "optimize_function_for_size_p (cfun)")
2456 (const_string "imov")
2457 (and (eq_attr "alternative" "0")
2458 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2459 (not (match_test "TARGET_HIMODE_MATH"))))
2460 (const_string "imov")
2461 (and (eq_attr "alternative" "1,2")
2462 (match_operand:HI 1 "aligned_operand"))
2463 (const_string "imov")
2464 (and (match_test "TARGET_MOVX")
2465 (eq_attr "alternative" "0,2"))
2466 (const_string "imovx")
2468 (const_string "imov")))
2469 (set (attr "prefix")
2470 (if_then_else (eq_attr "alternative" "4,5,6,7")
2471 (const_string "vex")
2472 (const_string "orig")))
2474 (cond [(eq_attr "type" "imovx")
2476 (and (eq_attr "alternative" "1,2")
2477 (match_operand:HI 1 "aligned_operand"))
2479 (and (eq_attr "alternative" "0")
2480 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2481 (not (match_test "TARGET_HIMODE_MATH"))))
2484 (const_string "HI")))])
2486 ;; Situation is quite tricky about when to choose full sized (SImode) move
2487 ;; over QImode moves. For Q_REG -> Q_REG move we use full size only for
2488 ;; partial register dependency machines (such as AMD Athlon), where QImode
2489 ;; moves issue extra dependency and for partial register stalls machines
2490 ;; that don't use QImode patterns (and QImode move cause stall on the next
2493 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
2494 ;; register stall machines with, where we use QImode instructions, since
2495 ;; partial register stall can be caused there. Then we use movzx.
2497 (define_insn "*movqi_internal"
2498 [(set (match_operand:QI 0 "nonimmediate_operand"
2499 "=Q,R,r,q,q,r,r ,?r,m ,k,k,r,m,k")
2500 (match_operand:QI 1 "general_operand"
2501 "Q ,R,r,n,m,q,rn, m,qn,r,k,k,k,m"))]
2502 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2504 static char buf[128];
2508 switch (get_attr_type (insn))
2511 gcc_assert (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]));
2512 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
2515 switch (which_alternative)
2518 ops = "kmov%s\t{%%k1, %%0|%%0, %%k1}";
2521 ops = "kmov%s\t{%%1, %%k0|%%k0, %%1}";
2525 gcc_assert (TARGET_AVX512DQ);
2528 ops = "kmov%s\t{%%1, %%0|%%0, %%1}";
2534 suffix = (get_attr_mode (insn) == MODE_HI) ? "w" : "b";
2536 snprintf (buf, sizeof (buf), ops, suffix);
2540 if (get_attr_mode (insn) == MODE_SI)
2541 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2543 return "mov{b}\t{%1, %0|%0, %1}";
2547 (cond [(eq_attr "alternative" "1,2")
2548 (const_string "x64")
2549 (eq_attr "alternative" "12,13")
2550 (const_string "avx512dq")
2552 (const_string "*")))
2554 (cond [(eq_attr "alternative" "9,10,11,12,13")
2555 (const_string "mskmov")
2556 (and (eq_attr "alternative" "7")
2557 (not (match_operand:QI 1 "aligned_operand")))
2558 (const_string "imovx")
2559 (match_test "optimize_function_for_size_p (cfun)")
2560 (const_string "imov")
2561 (and (eq_attr "alternative" "5")
2562 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2563 (not (match_test "TARGET_QIMODE_MATH"))))
2564 (const_string "imov")
2565 (eq_attr "alternative" "5,7")
2566 (const_string "imovx")
2567 (and (match_test "TARGET_MOVX")
2568 (eq_attr "alternative" "4"))
2569 (const_string "imovx")
2571 (const_string "imov")))
2572 (set (attr "prefix")
2573 (if_then_else (eq_attr "alternative" "9,10,11")
2574 (const_string "vex")
2575 (const_string "orig")))
2577 (cond [(eq_attr "alternative" "5,6,7")
2579 (eq_attr "alternative" "8")
2581 (and (eq_attr "alternative" "9,10,11")
2582 (not (match_test "TARGET_AVX512DQ")))
2584 (eq_attr "type" "imovx")
2586 ;; For -Os, 8-bit immediates are always shorter than 32-bit
2588 (and (eq_attr "type" "imov")
2589 (and (eq_attr "alternative" "3")
2590 (match_test "optimize_function_for_size_p (cfun)")))
2592 ;; For -Os, movl where one or both operands are NON_Q_REGS
2593 ;; and both are LEGACY_REGS is shorter than movb.
2594 ;; Otherwise movb and movl sizes are the same, so decide purely
2595 ;; based on speed factors.
2596 (and (eq_attr "type" "imov")
2597 (and (eq_attr "alternative" "1")
2598 (match_test "optimize_function_for_size_p (cfun)")))
2600 (and (eq_attr "type" "imov")
2601 (and (eq_attr "alternative" "0,1,2,3")
2602 (and (match_test "TARGET_PARTIAL_REG_DEPENDENCY")
2603 (not (match_test "TARGET_PARTIAL_REG_STALL")))))
2605 ;; Avoid partial register stalls when not using QImode arithmetic
2606 (and (eq_attr "type" "imov")
2607 (and (eq_attr "alternative" "0,1,2,3")
2608 (and (match_test "TARGET_PARTIAL_REG_STALL")
2609 (not (match_test "TARGET_QIMODE_MATH")))))
2612 (const_string "QI")))])
2614 ;; Stores and loads of ax to arbitrary constant address.
2615 ;; We fake an second form of instruction to force reload to load address
2616 ;; into register when rax is not available
2617 (define_insn "*movabs<mode>_1"
2618 [(set (mem:SWI1248x (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2619 (match_operand:SWI1248x 1 "nonmemory_operand" "a,r<i>"))]
2620 "TARGET_LP64 && ix86_check_movabs (insn, 0)"
2622 /* Recover the full memory rtx. */
2623 operands[0] = SET_DEST (PATTERN (insn));
2624 switch (which_alternative)
2627 return "movabs{<imodesuffix>}\t{%1, %P0|<iptrsize> PTR [%P0], %1}";
2629 return "mov{<imodesuffix>}\t{%1, %0|%0, %1}";
2634 [(set_attr "type" "imov")
2635 (set_attr "modrm" "0,*")
2636 (set_attr "length_address" "8,0")
2637 (set_attr "length_immediate" "0,*")
2638 (set_attr "memory" "store")
2639 (set_attr "mode" "<MODE>")])
2641 (define_insn "*movabs<mode>_2"
2642 [(set (match_operand:SWI1248x 0 "register_operand" "=a,r")
2643 (mem:SWI1248x (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2644 "TARGET_LP64 && ix86_check_movabs (insn, 1)"
2646 /* Recover the full memory rtx. */
2647 operands[1] = SET_SRC (PATTERN (insn));
2648 switch (which_alternative)
2651 return "movabs{<imodesuffix>}\t{%P1, %0|%0, <iptrsize> PTR [%P1]}";
2653 return "mov{<imodesuffix>}\t{%1, %0|%0, %1}";
2658 [(set_attr "type" "imov")
2659 (set_attr "modrm" "0,*")
2660 (set_attr "length_address" "8,0")
2661 (set_attr "length_immediate" "0")
2662 (set_attr "memory" "load")
2663 (set_attr "mode" "<MODE>")])
2665 (define_insn "*swap<mode>"
2666 [(set (match_operand:SWI48 0 "register_operand" "+r")
2667 (match_operand:SWI48 1 "register_operand" "+r"))
2671 "xchg{<imodesuffix>}\t%1, %0"
2672 [(set_attr "type" "imov")
2673 (set_attr "mode" "<MODE>")
2674 (set_attr "pent_pair" "np")
2675 (set_attr "athlon_decode" "vector")
2676 (set_attr "amdfam10_decode" "double")
2677 (set_attr "bdver1_decode" "double")])
2679 (define_insn "*swap<mode>"
2680 [(set (match_operand:SWI12 0 "register_operand" "+<r>,r")
2681 (match_operand:SWI12 1 "register_operand" "+<r>,r"))
2686 xchg{<imodesuffix>}\t%1, %0
2688 [(set_attr "type" "imov")
2689 (set_attr "mode" "<MODE>,SI")
2690 (set (attr "preferred_for_size")
2691 (cond [(eq_attr "alternative" "0")
2692 (symbol_ref "false")]
2693 (symbol_ref "true")))
2694 ;; Potential partial reg stall on alternative 1.
2695 (set (attr "preferred_for_speed")
2696 (cond [(eq_attr "alternative" "1")
2697 (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
2698 (symbol_ref "true")))
2699 (set_attr "pent_pair" "np")
2700 (set_attr "athlon_decode" "vector")
2701 (set_attr "amdfam10_decode" "double")
2702 (set_attr "bdver1_decode" "double")])
2704 (define_expand "movstrict<mode>"
2705 [(set (strict_low_part (match_operand:SWI12 0 "nonimmediate_operand"))
2706 (match_operand:SWI12 1 "general_operand"))]
2709 if (TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun))
2711 if (SUBREG_P (operands[0])
2712 && GET_MODE_CLASS (GET_MODE (SUBREG_REG (operands[0]))) != MODE_INT)
2714 /* Don't generate memory->memory moves, go through a register */
2715 if (MEM_P (operands[0]) && MEM_P (operands[1]))
2716 operands[1] = force_reg (<MODE>mode, operands[1]);
2719 (define_insn "*movstrict<mode>_1"
2720 [(set (strict_low_part
2721 (match_operand:SWI12 0 "nonimmediate_operand" "+<r>m,<r>"))
2722 (match_operand:SWI12 1 "general_operand" "<r>n,m"))]
2723 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
2724 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2725 "mov{<imodesuffix>}\t{%1, %0|%0, %1}"
2726 [(set_attr "type" "imov")
2727 (set_attr "mode" "<MODE>")])
2729 (define_insn "*movstrict<mode>_xor"
2730 [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>"))
2731 (match_operand:SWI12 1 "const0_operand"))
2732 (clobber (reg:CC FLAGS_REG))]
2734 "xor{<imodesuffix>}\t%0, %0"
2735 [(set_attr "type" "alu1")
2736 (set_attr "mode" "<MODE>")
2737 (set_attr "length_immediate" "0")])
2739 (define_expand "extv<mode>"
2740 [(set (match_operand:SWI24 0 "register_operand")
2741 (sign_extract:SWI24 (match_operand:SWI24 1 "register_operand")
2742 (match_operand:SI 2 "const_int_operand")
2743 (match_operand:SI 3 "const_int_operand")))]
2746 /* Handle extractions from %ah et al. */
2747 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
2750 unsigned int regno = reg_or_subregno (operands[1]);
2752 /* Be careful to expand only with registers having upper parts. */
2753 if (regno <= LAST_VIRTUAL_REGISTER && !QI_REGNO_P (regno))
2754 operands[1] = copy_to_reg (operands[1]);
2757 (define_insn "*extv<mode>"
2758 [(set (match_operand:SWI24 0 "register_operand" "=R")
2759 (sign_extract:SWI24 (match_operand 1 "ext_register_operand" "Q")
2763 "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
2764 [(set_attr "type" "imovx")
2765 (set_attr "mode" "SI")])
2767 (define_expand "extzv<mode>"
2768 [(set (match_operand:SWI248 0 "register_operand")
2769 (zero_extract:SWI248 (match_operand:SWI248 1 "register_operand")
2770 (match_operand:SI 2 "const_int_operand")
2771 (match_operand:SI 3 "const_int_operand")))]
2774 if (ix86_expand_pextr (operands))
2777 /* Handle extractions from %ah et al. */
2778 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
2781 unsigned int regno = reg_or_subregno (operands[1]);
2783 /* Be careful to expand only with registers having upper parts. */
2784 if (regno <= LAST_VIRTUAL_REGISTER && !QI_REGNO_P (regno))
2785 operands[1] = copy_to_reg (operands[1]);
2788 (define_insn "*extzvqi_mem_rex64"
2789 [(set (match_operand:QI 0 "norex_memory_operand" "=Bn")
2791 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q")
2794 "TARGET_64BIT && reload_completed"
2795 "mov{b}\t{%h1, %0|%0, %h1}"
2796 [(set_attr "type" "imov")
2797 (set_attr "mode" "QI")])
2799 (define_insn "*extzv<mode>"
2800 [(set (match_operand:SWI248 0 "register_operand" "=R")
2801 (zero_extract:SWI248 (match_operand 1 "ext_register_operand" "Q")
2805 "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
2806 [(set_attr "type" "imovx")
2807 (set_attr "mode" "SI")])
2809 (define_insn "*extzvqi"
2810 [(set (match_operand:QI 0 "nonimmediate_operand" "=QBc,?R,m")
2812 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q,Q")
2817 switch (get_attr_type (insn))
2820 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2822 return "mov{b}\t{%h1, %0|%0, %h1}";
2825 [(set_attr "isa" "*,*,nox64")
2827 (if_then_else (and (match_operand:QI 0 "register_operand")
2828 (ior (not (match_operand:QI 0 "QIreg_operand"))
2829 (match_test "TARGET_MOVX")))
2830 (const_string "imovx")
2831 (const_string "imov")))
2833 (if_then_else (eq_attr "type" "imovx")
2835 (const_string "QI")))])
2838 [(set (match_operand:QI 0 "register_operand")
2840 (zero_extract:SI (match_operand 1 "ext_register_operand")
2843 (set (match_operand:QI 2 "norex_memory_operand") (match_dup 0))]
2845 && peep2_reg_dead_p (2, operands[0])"
2848 (zero_extract:SI (match_dup 1)
2850 (const_int 8)) 0))])
2852 (define_expand "insv<mode>"
2853 [(set (zero_extract:SWI248 (match_operand:SWI248 0 "register_operand")
2854 (match_operand:SI 1 "const_int_operand")
2855 (match_operand:SI 2 "const_int_operand"))
2856 (match_operand:SWI248 3 "register_operand"))]
2861 if (ix86_expand_pinsr (operands))
2864 /* Handle insertions to %ah et al. */
2865 if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
2868 unsigned int regno = reg_or_subregno (operands[0]);
2870 /* Be careful to expand only with registers having upper parts. */
2871 if (regno <= LAST_VIRTUAL_REGISTER && !QI_REGNO_P (regno))
2872 dst = copy_to_reg (operands[0]);
2876 emit_insn (gen_insv<mode>_1 (dst, operands[3]));
2878 /* Fix up the destination if needed. */
2879 if (dst != operands[0])
2880 emit_move_insn (operands[0], dst);
2885 (define_insn "*insvqi_1_mem_rex64"
2886 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2890 (match_operand:QI 1 "norex_memory_operand" "Bn") 0))]
2891 "TARGET_64BIT && reload_completed"
2892 "mov{b}\t{%1, %h0|%h0, %1}"
2893 [(set_attr "type" "imov")
2894 (set_attr "mode" "QI")])
2896 (define_insn "insv<mode>_1"
2897 [(set (zero_extract:SWI248 (match_operand 0 "ext_register_operand" "+Q,Q")
2900 (match_operand:SWI248 1 "general_operand" "QnBc,m"))]
2903 if (CONST_INT_P (operands[1]))
2904 operands[1] = gen_int_mode (INTVAL (operands[1]), QImode);
2905 return "mov{b}\t{%b1, %h0|%h0, %b1}";
2907 [(set_attr "isa" "*,nox64")
2908 (set_attr "type" "imov")
2909 (set_attr "mode" "QI")])
2911 (define_insn "*insvqi_1"
2912 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q,Q")
2916 (match_operand:QI 1 "general_operand" "QnBc,m") 0))]
2918 "mov{b}\t{%1, %h0|%h0, %1}"
2919 [(set_attr "isa" "*,nox64")
2920 (set_attr "type" "imov")
2921 (set_attr "mode" "QI")])
2924 [(set (match_operand:QI 0 "register_operand")
2925 (match_operand:QI 1 "norex_memory_operand"))
2926 (set (zero_extract:SI (match_operand 2 "ext_register_operand")
2929 (subreg:SI (match_dup 0) 0))]
2931 && peep2_reg_dead_p (2, operands[0])"
2932 [(set (zero_extract:SI (match_dup 2)
2935 (subreg:SI (match_dup 1) 0))])
2937 (define_code_iterator any_extract [sign_extract zero_extract])
2939 (define_insn "*insvqi_2"
2940 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2943 (any_extract:SI (match_operand 1 "ext_register_operand" "Q")
2947 "mov{b}\t{%h1, %h0|%h0, %h1}"
2948 [(set_attr "type" "imov")
2949 (set_attr "mode" "QI")])
2951 (define_insn "*insvqi_3"
2952 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2955 (any_shiftrt:SI (match_operand:SI 1 "register_operand" "Q")
2958 "mov{b}\t{%h1, %h0|%h0, %h1}"
2959 [(set_attr "type" "imov")
2960 (set_attr "mode" "QI")])
2962 ;; Floating point push instructions.
2964 (define_insn "*pushtf"
2965 [(set (match_operand:TF 0 "push_operand" "=<,<")
2966 (match_operand:TF 1 "general_no_elim_operand" "v,*roC"))]
2967 "TARGET_64BIT || TARGET_SSE"
2969 /* This insn should be already split before reg-stack. */
2972 [(set_attr "isa" "*,x64")
2973 (set_attr "type" "multi")
2974 (set_attr "unit" "sse,*")
2975 (set_attr "mode" "TF,DI")])
2977 ;; %%% Kill this when call knows how to work this out.
2979 [(set (match_operand:TF 0 "push_operand")
2980 (match_operand:TF 1 "sse_reg_operand"))]
2981 "TARGET_SSE && reload_completed"
2982 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -16)))
2983 (set (match_dup 0) (match_dup 1))]
2985 /* Preserve memory attributes. */
2986 operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
2989 (define_insn_and_split "*pushxf_rounded"
2993 (plus:P (reg:P SP_REG) (const_int -16))))
2994 (match_operand:XF 0 "nonmemory_no_elim_operand" "f,r,*r,C"))]
2998 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -16)))
2999 (set (match_dup 1) (match_dup 0))]
3001 rtx pat = PATTERN (curr_insn);
3002 operands[1] = SET_DEST (pat);
3004 /* Preserve memory attributes. */
3005 operands[1] = replace_equiv_address (operands[1], stack_pointer_rtx);
3007 [(set_attr "type" "multi")
3008 (set_attr "unit" "i387,*,*,*")
3010 (cond [(eq_attr "alternative" "1,2,3")
3013 (const_string "XF")))
3014 (set (attr "preferred_for_size")
3015 (cond [(eq_attr "alternative" "1")
3016 (symbol_ref "false")]
3017 (symbol_ref "true")))])
3019 (define_insn "*pushxf"
3020 [(set (match_operand:XF 0 "push_operand" "=<,<,<,<,<")
3021 (match_operand:XF 1 "general_no_elim_operand" "f,r,*r,oF,oC"))]
3024 /* This insn should be already split before reg-stack. */
3027 [(set_attr "isa" "*,*,*,nox64,x64")
3028 (set_attr "type" "multi")
3029 (set_attr "unit" "i387,*,*,*,*")
3031 (cond [(eq_attr "alternative" "1,2,3,4")
3032 (if_then_else (match_test "TARGET_64BIT")
3034 (const_string "SI"))
3036 (const_string "XF")))
3037 (set (attr "preferred_for_size")
3038 (cond [(eq_attr "alternative" "1")
3039 (symbol_ref "false")]
3040 (symbol_ref "true")))])
3042 ;; %%% Kill this when call knows how to work this out.
3044 [(set (match_operand:XF 0 "push_operand")
3045 (match_operand:XF 1 "fp_register_operand"))]
3047 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
3048 (set (match_dup 0) (match_dup 1))]
3050 operands[2] = GEN_INT (-PUSH_ROUNDING (GET_MODE_SIZE (XFmode)));
3051 /* Preserve memory attributes. */
3052 operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
3055 (define_insn "*pushdf"
3056 [(set (match_operand:DF 0 "push_operand" "=<,<,<,<,<,<")
3057 (match_operand:DF 1 "general_no_elim_operand" "f,r,*r,oF,rmC,x"))]
3060 /* This insn should be already split before reg-stack. */
3063 [(set_attr "isa" "*,nox64,nox64,nox64,x64,sse2")
3064 (set_attr "type" "multi")
3065 (set_attr "unit" "i387,*,*,*,*,sse")
3066 (set_attr "mode" "DF,SI,SI,SI,DI,DF")
3067 (set (attr "preferred_for_size")
3068 (cond [(eq_attr "alternative" "1")
3069 (symbol_ref "false")]
3070 (symbol_ref "true")))
3071 (set (attr "preferred_for_speed")
3072 (cond [(eq_attr "alternative" "1")
3073 (symbol_ref "TARGET_INTEGER_DFMODE_MOVES")]
3074 (symbol_ref "true")))])
3076 ;; %%% Kill this when call knows how to work this out.
3078 [(set (match_operand:DF 0 "push_operand")
3079 (match_operand:DF 1 "any_fp_register_operand"))]
3081 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
3082 (set (match_dup 0) (match_dup 1))]
3084 /* Preserve memory attributes. */
3085 operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
3088 (define_insn "*pushsf_rex64"
3089 [(set (match_operand:SF 0 "push_operand" "=X,X,X")
3090 (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
3093 /* Anything else should be already split before reg-stack. */
3094 gcc_assert (which_alternative == 1);
3095 return "push{q}\t%q1";
3097 [(set_attr "type" "multi,push,multi")
3098 (set_attr "unit" "i387,*,*")
3099 (set_attr "mode" "SF,DI,SF")])
3101 (define_insn "*pushsf"
3102 [(set (match_operand:SF 0 "push_operand" "=<,<,<")
3103 (match_operand:SF 1 "general_no_elim_operand" "f,rmF,x"))]
3106 /* Anything else should be already split before reg-stack. */
3107 gcc_assert (which_alternative == 1);
3108 return "push{l}\t%1";
3110 [(set_attr "type" "multi,push,multi")
3111 (set_attr "unit" "i387,*,*")
3112 (set_attr "mode" "SF,SI,SF")])
3114 ;; %%% Kill this when call knows how to work this out.
3116 [(set (match_operand:SF 0 "push_operand")
3117 (match_operand:SF 1 "any_fp_register_operand"))]
3119 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
3120 (set (match_dup 0) (match_dup 1))]
3122 rtx op = XEXP (operands[0], 0);
3123 if (GET_CODE (op) == PRE_DEC)
3125 gcc_assert (!TARGET_64BIT);
3130 op = XEXP (XEXP (op, 1), 1);
3131 gcc_assert (CONST_INT_P (op));
3134 /* Preserve memory attributes. */
3135 operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
3139 [(set (match_operand:SF 0 "push_operand")
3140 (match_operand:SF 1 "memory_operand"))]
3142 && find_constant_src (insn)"
3143 [(set (match_dup 0) (match_dup 2))]
3144 "operands[2] = find_constant_src (curr_insn);")
3147 [(set (match_operand 0 "push_operand")
3148 (match_operand 1 "general_gr_operand"))]
3150 && (GET_MODE (operands[0]) == TFmode
3151 || GET_MODE (operands[0]) == XFmode
3152 || GET_MODE (operands[0]) == DFmode)"
3154 "ix86_split_long_move (operands); DONE;")
3156 ;; Floating point move instructions.
3158 (define_expand "movtf"
3159 [(set (match_operand:TF 0 "nonimmediate_operand")
3160 (match_operand:TF 1 "nonimmediate_operand"))]
3161 "TARGET_64BIT || TARGET_SSE"
3162 "ix86_expand_move (TFmode, operands); DONE;")
3164 (define_expand "mov<mode>"
3165 [(set (match_operand:X87MODEF 0 "nonimmediate_operand")
3166 (match_operand:X87MODEF 1 "general_operand"))]
3168 "ix86_expand_move (<MODE>mode, operands); DONE;")
3170 (define_insn "*movtf_internal"
3171 [(set (match_operand:TF 0 "nonimmediate_operand" "=v,v ,m,?*r ,!o")
3172 (match_operand:TF 1 "general_operand" "C ,vm,v,*roF,*rC"))]
3173 "(TARGET_64BIT || TARGET_SSE)
3174 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3175 && (lra_in_progress || reload_completed
3176 || !CONST_DOUBLE_P (operands[1])
3177 || ((optimize_function_for_size_p (cfun)
3178 || (ix86_cmodel == CM_LARGE || ix86_cmodel == CM_LARGE_PIC))
3179 && standard_sse_constant_p (operands[1], TFmode) == 1
3180 && !memory_operand (operands[0], TFmode))
3181 || (!TARGET_MEMORY_MISMATCH_STALL
3182 && memory_operand (operands[0], TFmode)))"
3184 switch (get_attr_type (insn))
3187 return standard_sse_constant_opcode (insn, operands);
3190 /* Handle misaligned load/store since we
3191 don't have movmisaligntf pattern. */
3192 if (misaligned_operand (operands[0], TFmode)
3193 || misaligned_operand (operands[1], TFmode))
3195 if (get_attr_mode (insn) == MODE_V4SF)
3196 return "%vmovups\t{%1, %0|%0, %1}";
3197 else if (TARGET_AVX512VL
3198 && (EXT_REX_SSE_REG_P (operands[0])
3199 || EXT_REX_SSE_REG_P (operands[1])))
3200 return "vmovdqu64\t{%1, %0|%0, %1}";
3202 return "%vmovdqu\t{%1, %0|%0, %1}";
3206 if (get_attr_mode (insn) == MODE_V4SF)
3207 return "%vmovaps\t{%1, %0|%0, %1}";
3208 else if (TARGET_AVX512VL
3209 && (EXT_REX_SSE_REG_P (operands[0])
3210 || EXT_REX_SSE_REG_P (operands[1])))
3211 return "vmovdqa64\t{%1, %0|%0, %1}";
3213 return "%vmovdqa\t{%1, %0|%0, %1}";
3223 [(set_attr "isa" "*,*,*,x64,x64")
3224 (set_attr "type" "sselog1,ssemov,ssemov,multi,multi")
3225 (set (attr "prefix")
3226 (if_then_else (eq_attr "type" "sselog1,ssemov")
3227 (const_string "maybe_vex")
3228 (const_string "orig")))
3230 (cond [(eq_attr "alternative" "3,4")
3232 (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
3233 (const_string "V4SF")
3234 (and (eq_attr "alternative" "2")
3235 (match_test "TARGET_SSE_TYPELESS_STORES"))
3236 (const_string "V4SF")
3237 (match_test "TARGET_AVX")
3239 (ior (not (match_test "TARGET_SSE2"))
3240 (match_test "optimize_function_for_size_p (cfun)"))
3241 (const_string "V4SF")
3243 (const_string "TI")))])
3246 [(set (match_operand:TF 0 "nonimmediate_gr_operand")
3247 (match_operand:TF 1 "general_gr_operand"))]
3250 "ix86_split_long_move (operands); DONE;")
3252 ;; Possible store forwarding (partial memory) stall
3253 ;; in alternatives 4, 6, 7 and 8.
3254 (define_insn "*movxf_internal"
3255 [(set (match_operand:XF 0 "nonimmediate_operand"
3256 "=f,m,f,?r ,!o,?*r ,!o,!o,!o,r ,o ,o")
3257 (match_operand:XF 1 "general_operand"
3258 "fm,f,G,roF,r ,*roF,*r,F ,C ,roF,rF,rC"))]
3259 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3260 && (lra_in_progress || reload_completed
3261 || !CONST_DOUBLE_P (operands[1])
3262 || ((optimize_function_for_size_p (cfun)
3263 || (ix86_cmodel == CM_LARGE || ix86_cmodel == CM_LARGE_PIC))
3264 && standard_80387_constant_p (operands[1]) > 0
3265 && !memory_operand (operands[0], XFmode))
3266 || (!TARGET_MEMORY_MISMATCH_STALL
3267 && memory_operand (operands[0], XFmode))
3268 || !TARGET_HARD_XF_REGS)"
3270 switch (get_attr_type (insn))
3273 if (which_alternative == 2)
3274 return standard_80387_constant_opcode (operands[1]);
3275 return output_387_reg_move (insn, operands);
3285 (cond [(eq_attr "alternative" "7,10")
3286 (const_string "nox64")
3287 (eq_attr "alternative" "8,11")
3288 (const_string "x64")
3290 (const_string "*")))
3292 (cond [(eq_attr "alternative" "3,4,5,6,7,8,9,10,11")
3293 (const_string "multi")
3295 (const_string "fmov")))
3297 (cond [(eq_attr "alternative" "3,4,5,6,7,8,9,10,11")
3298 (if_then_else (match_test "TARGET_64BIT")
3300 (const_string "SI"))
3302 (const_string "XF")))
3303 (set (attr "preferred_for_size")
3304 (cond [(eq_attr "alternative" "3,4")
3305 (symbol_ref "false")]
3306 (symbol_ref "true")))
3307 (set (attr "enabled")
3308 (cond [(eq_attr "alternative" "9,10,11")
3310 (match_test "TARGET_HARD_XF_REGS")
3311 (symbol_ref "false")
3313 (not (match_test "TARGET_HARD_XF_REGS"))
3314 (symbol_ref "false")
3316 (const_string "*")))])
3319 [(set (match_operand:XF 0 "nonimmediate_gr_operand")
3320 (match_operand:XF 1 "general_gr_operand"))]
3323 "ix86_split_long_move (operands); DONE;")
3325 ;; Possible store forwarding (partial memory) stall in alternatives 4, 6 and 7.
3326 (define_insn "*movdf_internal"
3327 [(set (match_operand:DF 0 "nonimmediate_operand"
3328 "=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")
3329 (match_operand:DF 1 "general_operand"
3330 "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"))]
3331 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3332 && (lra_in_progress || reload_completed
3333 || !CONST_DOUBLE_P (operands[1])
3334 || ((optimize_function_for_size_p (cfun)
3335 || (ix86_cmodel == CM_LARGE || ix86_cmodel == CM_LARGE_PIC))
3336 && ((IS_STACK_MODE (DFmode)
3337 && standard_80387_constant_p (operands[1]) > 0)
3338 || (TARGET_SSE2 && TARGET_SSE_MATH
3339 && standard_sse_constant_p (operands[1], DFmode) == 1))
3340 && !memory_operand (operands[0], DFmode))
3341 || ((TARGET_64BIT || !TARGET_MEMORY_MISMATCH_STALL)
3342 && memory_operand (operands[0], DFmode))
3343 || !TARGET_HARD_DF_REGS)"
3345 switch (get_attr_type (insn))
3348 if (which_alternative == 2)
3349 return standard_80387_constant_opcode (operands[1]);
3350 return output_387_reg_move (insn, operands);
3356 if (get_attr_mode (insn) == MODE_SI)
3357 return "mov{l}\t{%1, %k0|%k0, %1}";
3358 else if (which_alternative == 11)
3359 return "movabs{q}\t{%1, %0|%0, %1}";
3361 return "mov{q}\t{%1, %0|%0, %1}";
3364 return standard_sse_constant_opcode (insn, operands);
3367 switch (get_attr_mode (insn))
3370 if (TARGET_AVX && REG_P (operands[0]) && REG_P (operands[1]))
3371 return "vmovsd\t{%d1, %0|%0, %d1}";
3372 return "%vmovsd\t{%1, %0|%0, %1}";
3375 return "%vmovaps\t{%1, %0|%0, %1}";
3377 return "vmovapd\t{%g1, %g0|%g0, %g1}";
3379 return "%vmovapd\t{%1, %0|%0, %1}";
3382 gcc_assert (!TARGET_AVX);
3383 return "movlps\t{%1, %0|%0, %1}";
3385 gcc_assert (!TARGET_AVX);
3386 return "movlpd\t{%1, %0|%0, %1}";
3389 /* Handle broken assemblers that require movd instead of movq. */
3390 if (!HAVE_AS_IX86_INTERUNIT_MOVQ
3391 && (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1])))
3392 return "%vmovd\t{%1, %0|%0, %1}";
3393 return "%vmovq\t{%1, %0|%0, %1}";
3404 (cond [(eq_attr "alternative" "3,4,5,6,7,22,23")
3405 (const_string "nox64")
3406 (eq_attr "alternative" "8,9,10,11,24,25")
3407 (const_string "x64")
3408 (eq_attr "alternative" "12,13,14,15")
3409 (const_string "sse2")
3410 (eq_attr "alternative" "20,21")
3411 (const_string "x64_sse2")
3413 (const_string "*")))
3415 (cond [(eq_attr "alternative" "0,1,2")
3416 (const_string "fmov")
3417 (eq_attr "alternative" "3,4,5,6,7,22,23")
3418 (const_string "multi")
3419 (eq_attr "alternative" "8,9,10,11,24,25")
3420 (const_string "imov")
3421 (eq_attr "alternative" "12,16")
3422 (const_string "sselog1")
3424 (const_string "ssemov")))
3426 (if_then_else (eq_attr "alternative" "11")
3428 (const_string "*")))
3429 (set (attr "length_immediate")
3430 (if_then_else (eq_attr "alternative" "11")
3432 (const_string "*")))
3433 (set (attr "prefix")
3434 (if_then_else (eq_attr "type" "sselog1,ssemov")
3435 (const_string "maybe_vex")
3436 (const_string "orig")))
3437 (set (attr "prefix_data16")
3439 (ior (and (eq_attr "type" "ssemov") (eq_attr "mode" "DI"))
3440 (eq_attr "mode" "V1DF"))
3442 (const_string "*")))
3444 (cond [(eq_attr "alternative" "3,4,5,6,7,10,22,23")
3446 (eq_attr "alternative" "8,9,11,20,21,24,25")
3449 /* xorps is one byte shorter for non-AVX targets. */
3450 (eq_attr "alternative" "12,16")
3451 (cond [(not (match_test "TARGET_SSE2"))
3452 (const_string "V4SF")
3453 (and (match_test "TARGET_AVX512F")
3454 (not (match_test "TARGET_PREFER_AVX256")))
3456 (match_test "TARGET_AVX")
3457 (const_string "V2DF")
3458 (match_test "optimize_function_for_size_p (cfun)")
3459 (const_string "V4SF")
3460 (match_test "TARGET_SSE_LOAD0_BY_PXOR")
3463 (const_string "V2DF"))
3465 /* For architectures resolving dependencies on
3466 whole SSE registers use movapd to break dependency
3467 chains, otherwise use short move to avoid extra work. */
3469 /* movaps is one byte shorter for non-AVX targets. */
3470 (eq_attr "alternative" "13,17")
3471 (cond [(and (ior (not (match_test "TARGET_PREFER_AVX256"))
3472 (not (match_test "TARGET_AVX512VL")))
3473 (ior (match_operand 0 "ext_sse_reg_operand")
3474 (match_operand 1 "ext_sse_reg_operand")))
3475 (const_string "V8DF")
3476 (ior (not (match_test "TARGET_SSE2"))
3477 (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL"))
3478 (const_string "V4SF")
3479 (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3480 (const_string "V2DF")
3481 (match_test "TARGET_AVX")
3483 (match_test "optimize_function_for_size_p (cfun)")
3484 (const_string "V4SF")
3486 (const_string "DF"))
3488 /* For architectures resolving dependencies on register
3489 parts we may avoid extra work to zero out upper part
3491 (eq_attr "alternative" "14,18")
3492 (cond [(not (match_test "TARGET_SSE2"))
3493 (const_string "V2SF")
3494 (match_test "TARGET_AVX")
3496 (match_test "TARGET_SSE_SPLIT_REGS")
3497 (const_string "V1DF")
3499 (const_string "DF"))
3501 (and (eq_attr "alternative" "15,19")
3502 (not (match_test "TARGET_SSE2")))
3503 (const_string "V2SF")
3505 (const_string "DF")))
3506 (set (attr "preferred_for_size")
3507 (cond [(eq_attr "alternative" "3,4")
3508 (symbol_ref "false")]
3509 (symbol_ref "true")))
3510 (set (attr "preferred_for_speed")
3511 (cond [(eq_attr "alternative" "3,4")
3512 (symbol_ref "TARGET_INTEGER_DFMODE_MOVES")
3513 (eq_attr "alternative" "20")
3514 (symbol_ref "TARGET_INTER_UNIT_MOVES_FROM_VEC")
3515 (eq_attr "alternative" "21")
3516 (symbol_ref "TARGET_INTER_UNIT_MOVES_TO_VEC")
3518 (symbol_ref "true")))
3519 (set (attr "enabled")
3520 (cond [(eq_attr "alternative" "22,23,24,25")
3522 (match_test "TARGET_HARD_DF_REGS")
3523 (symbol_ref "false")
3525 (not (match_test "TARGET_HARD_DF_REGS"))
3526 (symbol_ref "false")
3528 (const_string "*")))])
3531 [(set (match_operand:DF 0 "nonimmediate_gr_operand")
3532 (match_operand:DF 1 "general_gr_operand"))]
3533 "!TARGET_64BIT && reload_completed"
3535 "ix86_split_long_move (operands); DONE;")
3537 (define_insn "*movsf_internal"
3538 [(set (match_operand:SF 0 "nonimmediate_operand"
3539 "=Yf*f,m ,Yf*f,?r ,?m,v,v,v,m,?r,?v,!*y,!*y,!m,!r,!*y,r ,m")
3540 (match_operand:SF 1 "general_operand"
3541 "Yf*fm,Yf*f,G ,rmF,rF,C,v,m,v,v ,r ,*y ,m ,*y,*y,r ,rmF,rF"))]
3542 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3543 && (lra_in_progress || reload_completed
3544 || !CONST_DOUBLE_P (operands[1])
3545 || ((optimize_function_for_size_p (cfun)
3546 || (ix86_cmodel == CM_LARGE || ix86_cmodel == CM_LARGE_PIC))
3547 && ((IS_STACK_MODE (SFmode)
3548 && standard_80387_constant_p (operands[1]) > 0)
3549 || (TARGET_SSE && TARGET_SSE_MATH
3550 && standard_sse_constant_p (operands[1], SFmode) == 1)))
3551 || memory_operand (operands[0], SFmode)
3552 || !TARGET_HARD_SF_REGS)"
3554 switch (get_attr_type (insn))
3557 if (which_alternative == 2)
3558 return standard_80387_constant_opcode (operands[1]);
3559 return output_387_reg_move (insn, operands);
3562 return "mov{l}\t{%1, %0|%0, %1}";
3565 return standard_sse_constant_opcode (insn, operands);
3568 switch (get_attr_mode (insn))
3571 if (TARGET_AVX && REG_P (operands[0]) && REG_P (operands[1]))
3572 return "vmovss\t{%d1, %0|%0, %d1}";
3573 return "%vmovss\t{%1, %0|%0, %1}";
3576 return "vmovaps\t{%g1, %g0|%g0, %g1}";
3578 return "%vmovaps\t{%1, %0|%0, %1}";
3581 return "%vmovd\t{%1, %0|%0, %1}";
3588 switch (get_attr_mode (insn))
3591 return "movq\t{%1, %0|%0, %1}";
3593 return "movd\t{%1, %0|%0, %1}";
3604 (cond [(eq_attr "alternative" "14,15")
3605 (const_string "sse2")
3607 (const_string "*")))
3609 (cond [(eq_attr "alternative" "0,1,2")
3610 (const_string "fmov")
3611 (eq_attr "alternative" "3,4,16,17")
3612 (const_string "imov")
3613 (eq_attr "alternative" "5")
3614 (const_string "sselog1")
3615 (eq_attr "alternative" "11,12,13,14,15")
3616 (const_string "mmxmov")
3618 (const_string "ssemov")))
3619 (set (attr "prefix")
3620 (if_then_else (eq_attr "type" "sselog1,ssemov")
3621 (const_string "maybe_vex")
3622 (const_string "orig")))
3623 (set (attr "prefix_data16")
3624 (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
3626 (const_string "*")))
3628 (cond [(eq_attr "alternative" "3,4,9,10,12,13,14,15,16,17")
3630 (eq_attr "alternative" "11")
3632 (eq_attr "alternative" "5")
3633 (cond [(not (match_test "TARGET_SSE2"))
3634 (const_string "V4SF")
3635 (and (match_test "TARGET_AVX512F")
3636 (not (match_test "TARGET_PREFER_AVX256")))
3637 (const_string "V16SF")
3638 (match_test "TARGET_AVX")
3639 (const_string "V4SF")
3640 (match_test "optimize_function_for_size_p (cfun)")
3641 (const_string "V4SF")
3642 (match_test "TARGET_SSE_LOAD0_BY_PXOR")
3645 (const_string "V4SF"))
3647 /* For architectures resolving dependencies on
3648 whole SSE registers use APS move to break dependency
3649 chains, otherwise use short move to avoid extra work.
3651 Do the same for architectures resolving dependencies on
3652 the parts. While in DF mode it is better to always handle
3653 just register parts, the SF mode is different due to lack
3654 of instructions to load just part of the register. It is
3655 better to maintain the whole registers in single format
3656 to avoid problems on using packed logical operations. */
3657 (eq_attr "alternative" "6")
3658 (cond [(and (ior (not (match_test "TARGET_PREFER_AVX256"))
3659 (not (match_test "TARGET_AVX512VL")))
3660 (ior (match_operand 0 "ext_sse_reg_operand")
3661 (match_operand 1 "ext_sse_reg_operand")))
3662 (const_string "V16SF")
3663 (ior (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3664 (match_test "TARGET_SSE_SPLIT_REGS"))
3665 (const_string "V4SF")
3667 (const_string "SF"))
3669 (const_string "SF")))
3670 (set (attr "preferred_for_speed")
3671 (cond [(eq_attr "alternative" "9,14")
3672 (symbol_ref "TARGET_INTER_UNIT_MOVES_FROM_VEC")
3673 (eq_attr "alternative" "10,15")
3674 (symbol_ref "TARGET_INTER_UNIT_MOVES_TO_VEC")
3676 (symbol_ref "true")))
3677 (set (attr "enabled")
3678 (cond [(eq_attr "alternative" "16,17")
3680 (match_test "TARGET_HARD_SF_REGS")
3681 (symbol_ref "false")
3683 (not (match_test "TARGET_HARD_SF_REGS"))
3684 (symbol_ref "false")
3686 (const_string "*")))])
3689 [(set (match_operand 0 "any_fp_register_operand")
3690 (match_operand 1 "memory_operand"))]
3692 && (GET_MODE (operands[0]) == TFmode
3693 || GET_MODE (operands[0]) == XFmode
3694 || GET_MODE (operands[0]) == DFmode
3695 || GET_MODE (operands[0]) == SFmode)
3696 && ix86_standard_x87sse_constant_load_p (insn, operands[0])"
3697 [(set (match_dup 0) (match_dup 2))]
3698 "operands[2] = find_constant_src (curr_insn);")
3701 [(set (match_operand 0 "any_fp_register_operand")
3702 (float_extend (match_operand 1 "memory_operand")))]
3704 && (GET_MODE (operands[0]) == TFmode
3705 || GET_MODE (operands[0]) == XFmode
3706 || GET_MODE (operands[0]) == DFmode)
3707 && ix86_standard_x87sse_constant_load_p (insn, operands[0])"
3708 [(set (match_dup 0) (match_dup 2))]
3709 "operands[2] = find_constant_src (curr_insn);")
3711 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
3713 [(set (match_operand:X87MODEF 0 "fp_register_operand")
3714 (match_operand:X87MODEF 1 "immediate_operand"))]
3716 && (standard_80387_constant_p (operands[1]) == 8
3717 || standard_80387_constant_p (operands[1]) == 9)"
3718 [(set (match_dup 0)(match_dup 1))
3720 (neg:X87MODEF (match_dup 0)))]
3722 if (real_isnegzero (CONST_DOUBLE_REAL_VALUE (operands[1])))
3723 operands[1] = CONST0_RTX (<MODE>mode);
3725 operands[1] = CONST1_RTX (<MODE>mode);
3728 (define_insn "*swapxf"
3729 [(set (match_operand:XF 0 "register_operand" "+f")
3730 (match_operand:XF 1 "register_operand" "+f"))
3735 if (STACK_TOP_P (operands[0]))
3740 [(set_attr "type" "fxch")
3741 (set_attr "mode" "XF")])
3744 ;; Zero extension instructions
3746 (define_expand "zero_extendsidi2"
3747 [(set (match_operand:DI 0 "nonimmediate_operand")
3748 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand")))])
3750 (define_insn "*zero_extendsidi2"
3751 [(set (match_operand:DI 0 "nonimmediate_operand"
3752 "=r,?r,?o,r ,o,?*y,?!*y,$r,$v,$x,*x,*v,*r")
3754 (match_operand:SI 1 "x86_64_zext_operand"
3755 "0 ,rm,r ,rmWz,0,r ,m ,v ,r ,m ,*x,*v,*k")))]
3758 switch (get_attr_type (insn))
3761 if (ix86_use_lea_for_mov (insn, operands))
3762 return "lea{l}\t{%E1, %k0|%k0, %E1}";
3764 return "mov{l}\t{%1, %k0|%k0, %1}";
3770 return "movd\t{%1, %0|%0, %1}";
3773 if (SSE_REG_P (operands[0]) && SSE_REG_P (operands[1]))
3775 if (EXT_REX_SSE_REG_P (operands[0])
3776 || EXT_REX_SSE_REG_P (operands[1]))
3777 return "vpmovzxdq\t{%t1, %g0|%g0, %t1}";
3779 return "%vpmovzxdq\t{%1, %0|%0, %1}";
3782 if (GENERAL_REG_P (operands[0]))
3783 return "%vmovd\t{%1, %k0|%k0, %1}";
3785 return "%vmovd\t{%1, %0|%0, %1}";
3788 return "kmovd\t{%1, %k0|%k0, %1}";
3795 (cond [(eq_attr "alternative" "0,1,2")
3796 (const_string "nox64")
3797 (eq_attr "alternative" "3")
3798 (const_string "x64")
3799 (eq_attr "alternative" "7,8,9")
3800 (const_string "sse2")
3801 (eq_attr "alternative" "10")
3802 (const_string "sse4")
3803 (eq_attr "alternative" "11")
3804 (const_string "avx512f")
3805 (eq_attr "alternative" "12")
3806 (const_string "x64_avx512bw")
3808 (const_string "*")))
3810 (cond [(eq_attr "alternative" "0,1,2,4")
3811 (const_string "multi")
3812 (eq_attr "alternative" "5,6")
3813 (const_string "mmxmov")
3814 (eq_attr "alternative" "7")
3815 (if_then_else (match_test "TARGET_64BIT")
3816 (const_string "ssemov")
3817 (const_string "multi"))
3818 (eq_attr "alternative" "8,9,10,11")
3819 (const_string "ssemov")
3820 (eq_attr "alternative" "12")
3821 (const_string "mskmov")
3823 (const_string "imovx")))
3824 (set (attr "prefix_extra")
3825 (if_then_else (eq_attr "alternative" "10,11")
3827 (const_string "*")))
3828 (set (attr "prefix")
3829 (if_then_else (eq_attr "type" "ssemov")
3830 (const_string "maybe_vex")
3831 (const_string "orig")))
3832 (set (attr "prefix_0f")
3833 (if_then_else (eq_attr "type" "imovx")
3835 (const_string "*")))
3837 (cond [(eq_attr "alternative" "5,6")
3839 (and (eq_attr "alternative" "7")
3840 (match_test "TARGET_64BIT"))
3842 (eq_attr "alternative" "8,10,11")
3845 (const_string "SI")))
3846 (set (attr "preferred_for_speed")
3847 (cond [(eq_attr "alternative" "7")
3848 (symbol_ref "TARGET_INTER_UNIT_MOVES_FROM_VEC")
3849 (eq_attr "alternative" "5,8")
3850 (symbol_ref "TARGET_INTER_UNIT_MOVES_TO_VEC")
3852 (symbol_ref "true")))])
3855 [(set (match_operand:DI 0 "memory_operand")
3856 (zero_extend:DI (match_operand:SI 1 "memory_operand")))]
3858 [(set (match_dup 4) (const_int 0))]
3859 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3862 [(set (match_operand:DI 0 "general_reg_operand")
3863 (zero_extend:DI (match_operand:SI 1 "general_reg_operand")))]
3864 "!TARGET_64BIT && reload_completed
3865 && REGNO (operands[0]) == REGNO (operands[1])"
3866 [(set (match_dup 4) (const_int 0))]
3867 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3870 [(set (match_operand:DI 0 "nonimmediate_gr_operand")
3871 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand")))]
3872 "!TARGET_64BIT && reload_completed
3873 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
3874 [(set (match_dup 3) (match_dup 1))
3875 (set (match_dup 4) (const_int 0))]
3876 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3878 (define_mode_attr kmov_isa
3879 [(QI "avx512dq") (HI "avx512f") (SI "avx512bw") (DI "avx512bw")])
3881 (define_insn "zero_extend<mode>di2"
3882 [(set (match_operand:DI 0 "register_operand" "=r,*r")
3884 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m,*k")))]
3887 movz{<imodesuffix>l|x}\t{%1, %k0|%k0, %1}
3888 kmov<mskmodesuffix>\t{%1, %k0|%k0, %1}"
3889 [(set_attr "isa" "*,<kmov_isa>")
3890 (set_attr "type" "imovx,mskmov")
3891 (set_attr "mode" "SI,<MODE>")])
3893 (define_expand "zero_extend<mode>si2"
3894 [(set (match_operand:SI 0 "register_operand")
3895 (zero_extend:SI (match_operand:SWI12 1 "nonimmediate_operand")))]
3898 if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3900 operands[1] = force_reg (<MODE>mode, operands[1]);
3901 emit_insn (gen_zero_extend<mode>si2_and (operands[0], operands[1]));
3906 (define_insn_and_split "zero_extend<mode>si2_and"
3907 [(set (match_operand:SI 0 "register_operand" "=r,?&<r>")
3909 (match_operand:SWI12 1 "nonimmediate_operand" "0,<r>m")))
3910 (clobber (reg:CC FLAGS_REG))]
3911 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3913 "&& reload_completed"
3914 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (match_dup 2)))
3915 (clobber (reg:CC FLAGS_REG))])]
3917 if (!REG_P (operands[1])
3918 || REGNO (operands[0]) != REGNO (operands[1]))
3920 ix86_expand_clear (operands[0]);
3922 gcc_assert (!TARGET_PARTIAL_REG_STALL);
3923 emit_insn (gen_movstrict<mode>
3924 (gen_lowpart (<MODE>mode, operands[0]), operands[1]));
3928 operands[2] = GEN_INT (GET_MODE_MASK (<MODE>mode));
3930 [(set_attr "type" "alu1")
3931 (set_attr "mode" "SI")])
3933 (define_insn "*zero_extend<mode>si2"
3934 [(set (match_operand:SI 0 "register_operand" "=r,*r")
3936 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m,*k")))]
3937 "!(TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))"
3939 movz{<imodesuffix>l|x}\t{%1, %0|%0, %1}
3940 kmov<mskmodesuffix>\t{%1, %0|%0, %1}"
3941 [(set_attr "isa" "*,<kmov_isa>")
3942 (set_attr "type" "imovx,mskmov")
3943 (set_attr "mode" "SI,<MODE>")])
3945 (define_expand "zero_extendqihi2"
3946 [(set (match_operand:HI 0 "register_operand")
3947 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand")))]
3950 if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3952 operands[1] = force_reg (QImode, operands[1]);
3953 emit_insn (gen_zero_extendqihi2_and (operands[0], operands[1]));
3958 (define_insn_and_split "zero_extendqihi2_and"
3959 [(set (match_operand:HI 0 "register_operand" "=r,?&q")
3960 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3961 (clobber (reg:CC FLAGS_REG))]
3962 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3964 "&& reload_completed"
3965 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
3966 (clobber (reg:CC FLAGS_REG))])]
3968 if (!REG_P (operands[1])
3969 || REGNO (operands[0]) != REGNO (operands[1]))
3971 ix86_expand_clear (operands[0]);
3973 gcc_assert (!TARGET_PARTIAL_REG_STALL);
3974 emit_insn (gen_movstrictqi
3975 (gen_lowpart (QImode, operands[0]), operands[1]));
3979 operands[0] = gen_lowpart (SImode, operands[0]);
3981 [(set_attr "type" "alu1")
3982 (set_attr "mode" "SI")])
3984 ; zero extend to SImode to avoid partial register stalls
3985 (define_insn "*zero_extendqihi2"
3986 [(set (match_operand:HI 0 "register_operand" "=r,*r")
3987 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,*k")))]
3988 "!(TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))"
3990 movz{bl|x}\t{%1, %k0|%k0, %1}
3991 kmovb\t{%1, %k0|%k0, %1}"
3992 [(set_attr "isa" "*,avx512dq")
3993 (set_attr "type" "imovx,mskmov")
3994 (set_attr "mode" "SI,QI")])
3996 (define_insn_and_split "*zext<mode>_doubleword_and"
3997 [(set (match_operand:DI 0 "register_operand" "=&<r>")
3998 (zero_extend:DI (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3999 "!TARGET_64BIT && TARGET_STV && TARGET_SSE2
4000 && TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
4002 "&& reload_completed && GENERAL_REG_P (operands[0])"
4003 [(set (match_dup 2) (const_int 0))]
4005 split_double_mode (DImode, &operands[0], 1, &operands[0], &operands[2]);
4007 emit_move_insn (operands[0], const0_rtx);
4009 gcc_assert (!TARGET_PARTIAL_REG_STALL);
4010 emit_insn (gen_movstrict<mode>
4011 (gen_lowpart (<MODE>mode, operands[0]), operands[1]));
4014 (define_insn_and_split "*zext<mode>_doubleword"
4015 [(set (match_operand:DI 0 "register_operand" "=r")
4016 (zero_extend:DI (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
4017 "!TARGET_64BIT && TARGET_STV && TARGET_SSE2
4018 && !(TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))"
4020 "&& reload_completed && GENERAL_REG_P (operands[0])"
4021 [(set (match_dup 0) (zero_extend:SI (match_dup 1)))
4022 (set (match_dup 2) (const_int 0))]
4023 "split_double_mode (DImode, &operands[0], 1, &operands[0], &operands[2]);")
4025 (define_insn_and_split "*zextsi_doubleword"
4026 [(set (match_operand:DI 0 "register_operand" "=r")
4027 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm")))]
4028 "!TARGET_64BIT && TARGET_STV && TARGET_SSE2"
4030 "&& reload_completed && GENERAL_REG_P (operands[0])"
4031 [(set (match_dup 0) (match_dup 1))
4032 (set (match_dup 2) (const_int 0))]
4033 "split_double_mode (DImode, &operands[0], 1, &operands[0], &operands[2]);")
4035 ;; Sign extension instructions
4037 (define_expand "extendsidi2"
4038 [(set (match_operand:DI 0 "register_operand")
4039 (sign_extend:DI (match_operand:SI 1 "register_operand")))]
4044 emit_insn (gen_extendsidi2_1 (operands[0], operands[1]));
4049 (define_insn "*extendsidi2_rex64"
4050 [(set (match_operand:DI 0 "register_operand" "=*a,r")
4051 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
4055 movs{lq|x}\t{%1, %0|%0, %1}"
4056 [(set_attr "type" "imovx")
4057 (set_attr "mode" "DI")
4058 (set_attr "prefix_0f" "0")
4059 (set_attr "modrm" "0,1")])
4061 (define_insn "extendsidi2_1"
4062 [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
4063 (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
4064 (clobber (reg:CC FLAGS_REG))
4065 (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
4069 ;; Split the memory case. If the source register doesn't die, it will stay
4070 ;; this way, if it does die, following peephole2s take care of it.
4072 [(set (match_operand:DI 0 "memory_operand")
4073 (sign_extend:DI (match_operand:SI 1 "register_operand")))
4074 (clobber (reg:CC FLAGS_REG))
4075 (clobber (match_operand:SI 2 "register_operand"))]
4079 split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
4081 emit_move_insn (operands[3], operands[1]);
4083 /* Generate a cltd if possible and doing so it profitable. */
4084 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
4085 && REGNO (operands[1]) == AX_REG
4086 && REGNO (operands[2]) == DX_REG)
4088 emit_insn (gen_ashrsi3_cvt (operands[2], operands[1], GEN_INT (31)));
4092 emit_move_insn (operands[2], operands[1]);
4093 emit_insn (gen_ashrsi3_cvt (operands[2], operands[2], GEN_INT (31)));
4095 emit_move_insn (operands[4], operands[2]);
4099 ;; Peepholes for the case where the source register does die, after
4100 ;; being split with the above splitter.
4102 [(set (match_operand:SI 0 "memory_operand")
4103 (match_operand:SI 1 "general_reg_operand"))
4104 (set (match_operand:SI 2 "general_reg_operand") (match_dup 1))
4105 (parallel [(set (match_dup 2)
4106 (ashiftrt:SI (match_dup 2) (const_int 31)))
4107 (clobber (reg:CC FLAGS_REG))])
4108 (set (match_operand:SI 3 "memory_operand") (match_dup 2))]
4109 "REGNO (operands[1]) != REGNO (operands[2])
4110 && peep2_reg_dead_p (2, operands[1])
4111 && peep2_reg_dead_p (4, operands[2])
4112 && !reg_mentioned_p (operands[2], operands[3])"
4113 [(set (match_dup 0) (match_dup 1))
4114 (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
4115 (clobber (reg:CC FLAGS_REG))])
4116 (set (match_dup 3) (match_dup 1))])
4119 [(set (match_operand:SI 0 "memory_operand")
4120 (match_operand:SI 1 "general_reg_operand"))
4121 (parallel [(set (match_operand:SI 2 "general_reg_operand")
4122 (ashiftrt:SI (match_dup 1) (const_int 31)))
4123 (clobber (reg:CC FLAGS_REG))])
4124 (set (match_operand:SI 3 "memory_operand") (match_dup 2))]
4125 "/* cltd is shorter than sarl $31, %eax */
4126 !optimize_function_for_size_p (cfun)
4127 && REGNO (operands[1]) == AX_REG
4128 && REGNO (operands[2]) == DX_REG
4129 && peep2_reg_dead_p (2, operands[1])
4130 && peep2_reg_dead_p (3, operands[2])
4131 && !reg_mentioned_p (operands[2], operands[3])"
4132 [(set (match_dup 0) (match_dup 1))
4133 (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
4134 (clobber (reg:CC FLAGS_REG))])
4135 (set (match_dup 3) (match_dup 1))])
4137 ;; Extend to register case. Optimize case where source and destination
4138 ;; registers match and cases where we can use cltd.
4140 [(set (match_operand:DI 0 "register_operand")
4141 (sign_extend:DI (match_operand:SI 1 "register_operand")))
4142 (clobber (reg:CC FLAGS_REG))
4143 (clobber (match_scratch:SI 2))]
4147 split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
4149 if (REGNO (operands[3]) != REGNO (operands[1]))
4150 emit_move_insn (operands[3], operands[1]);
4152 /* Generate a cltd if possible and doing so it profitable. */
4153 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
4154 && REGNO (operands[3]) == AX_REG
4155 && REGNO (operands[4]) == DX_REG)
4157 emit_insn (gen_ashrsi3_cvt (operands[4], operands[3], GEN_INT (31)));
4161 if (REGNO (operands[4]) != REGNO (operands[1]))
4162 emit_move_insn (operands[4], operands[1]);
4164 emit_insn (gen_ashrsi3_cvt (operands[4], operands[4], GEN_INT (31)));
4168 (define_insn "extend<mode>di2"
4169 [(set (match_operand:DI 0 "register_operand" "=r")
4171 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
4173 "movs{<imodesuffix>q|x}\t{%1, %0|%0, %1}"
4174 [(set_attr "type" "imovx")
4175 (set_attr "mode" "DI")])
4177 (define_insn "extendhisi2"
4178 [(set (match_operand:SI 0 "register_operand" "=*a,r")
4179 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
4182 switch (get_attr_prefix_0f (insn))
4185 return "{cwtl|cwde}";
4187 return "movs{wl|x}\t{%1, %0|%0, %1}";
4190 [(set_attr "type" "imovx")
4191 (set_attr "mode" "SI")
4192 (set (attr "prefix_0f")
4193 ;; movsx is short decodable while cwtl is vector decoded.
4194 (if_then_else (and (eq_attr "cpu" "!k6")
4195 (eq_attr "alternative" "0"))
4197 (const_string "1")))
4198 (set (attr "znver1_decode")
4199 (if_then_else (eq_attr "prefix_0f" "0")
4200 (const_string "double")
4201 (const_string "direct")))
4203 (if_then_else (eq_attr "prefix_0f" "0")
4205 (const_string "1")))])
4207 (define_insn "*extendhisi2_zext"
4208 [(set (match_operand:DI 0 "register_operand" "=*a,r")
4211 (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
4214 switch (get_attr_prefix_0f (insn))
4217 return "{cwtl|cwde}";
4219 return "movs{wl|x}\t{%1, %k0|%k0, %1}";
4222 [(set_attr "type" "imovx")
4223 (set_attr "mode" "SI")
4224 (set (attr "prefix_0f")
4225 ;; movsx is short decodable while cwtl is vector decoded.
4226 (if_then_else (and (eq_attr "cpu" "!k6")
4227 (eq_attr "alternative" "0"))
4229 (const_string "1")))
4231 (if_then_else (eq_attr "prefix_0f" "0")
4233 (const_string "1")))])
4235 (define_insn "extendqisi2"
4236 [(set (match_operand:SI 0 "register_operand" "=r")
4237 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
4239 "movs{bl|x}\t{%1, %0|%0, %1}"
4240 [(set_attr "type" "imovx")
4241 (set_attr "mode" "SI")])
4243 (define_insn "*extendqisi2_zext"
4244 [(set (match_operand:DI 0 "register_operand" "=r")
4246 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
4248 "movs{bl|x}\t{%1, %k0|%k0, %1}"
4249 [(set_attr "type" "imovx")
4250 (set_attr "mode" "SI")])
4252 (define_insn "extendqihi2"
4253 [(set (match_operand:HI 0 "register_operand" "=*a,r")
4254 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
4257 switch (get_attr_prefix_0f (insn))
4260 return "{cbtw|cbw}";
4262 return "movs{bw|x}\t{%1, %0|%0, %1}";
4265 [(set_attr "type" "imovx")
4266 (set_attr "mode" "HI")
4267 (set (attr "prefix_0f")
4268 ;; movsx is short decodable while cwtl is vector decoded.
4269 (if_then_else (and (eq_attr "cpu" "!k6")
4270 (eq_attr "alternative" "0"))
4272 (const_string "1")))
4274 (if_then_else (eq_attr "prefix_0f" "0")
4276 (const_string "1")))])
4278 ;; Conversions between float and double.
4280 ;; These are all no-ops in the model used for the 80387.
4281 ;; So just emit moves.
4283 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
4285 [(set (match_operand:DF 0 "push_operand")
4286 (float_extend:DF (match_operand:SF 1 "fp_register_operand")))]
4288 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
4289 (set (mem:DF (reg:P SP_REG)) (float_extend:DF (match_dup 1)))])
4292 [(set (match_operand:XF 0 "push_operand")
4293 (float_extend:XF (match_operand:MODEF 1 "fp_register_operand")))]
4295 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
4296 (set (mem:XF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
4297 "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
4299 (define_expand "extendsfdf2"
4300 [(set (match_operand:DF 0 "nonimm_ssenomem_operand")
4301 (float_extend:DF (match_operand:SF 1 "general_operand")))]
4302 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4304 /* ??? Needed for compress_float_constant since all fp constants
4305 are TARGET_LEGITIMATE_CONSTANT_P. */
4306 if (CONST_DOUBLE_P (operands[1]))
4308 if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
4309 && standard_80387_constant_p (operands[1]) > 0)
4311 operands[1] = simplify_const_unary_operation
4312 (FLOAT_EXTEND, DFmode, operands[1], SFmode);
4313 emit_move_insn_1 (operands[0], operands[1]);
4316 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
4320 (define_insn "*extendsfdf2"
4321 [(set (match_operand:DF 0 "nonimm_ssenomem_operand" "=f,m,v")
4323 (match_operand:SF 1 "nonimmediate_operand" "fm,f,vm")))]
4324 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4326 switch (which_alternative)
4330 return output_387_reg_move (insn, operands);
4333 return "%vcvtss2sd\t{%1, %d0|%d0, %1}";
4339 [(set_attr "type" "fmov,fmov,ssecvt")
4340 (set_attr "prefix" "orig,orig,maybe_vex")
4341 (set_attr "mode" "SF,XF,DF")
4342 (set (attr "enabled")
4344 (match_test ("TARGET_SSE2 && TARGET_SSE_MATH"))
4346 (eq_attr "alternative" "0,1")
4347 (symbol_ref "TARGET_MIX_SSE_I387")
4348 (symbol_ref "true"))
4350 (eq_attr "alternative" "0,1")
4352 (symbol_ref "false"))))])
4354 /* For converting SF(xmm2) to DF(xmm1), use the following code instead of
4356 unpcklps xmm2,xmm2 ; packed conversion might crash on signaling NaNs
4358 We do the conversion post reload to avoid producing of 128bit spills
4359 that might lead to ICE on 32bit target. The sequence unlikely combine
4362 [(set (match_operand:DF 0 "sse_reg_operand")
4364 (match_operand:SF 1 "nonimmediate_operand")))]
4365 "TARGET_USE_VECTOR_FP_CONVERTS
4366 && optimize_insn_for_speed_p ()
4368 && (!EXT_REX_SSE_REG_P (operands[0])
4369 || TARGET_AVX512VL)"
4374 (parallel [(const_int 0) (const_int 1)]))))]
4376 operands[2] = lowpart_subreg (V2DFmode, operands[0], DFmode);
4377 operands[3] = lowpart_subreg (V4SFmode, operands[0], DFmode);
4378 /* Use movss for loading from memory, unpcklps reg, reg for registers.
4379 Try to avoid move when unpacking can be done in source. */
4380 if (REG_P (operands[1]))
4382 /* If it is unsafe to overwrite upper half of source, we need
4383 to move to destination and unpack there. */
4384 if (REGNO (operands[0]) != REGNO (operands[1])
4385 || (EXT_REX_SSE_REG_P (operands[1])
4386 && !TARGET_AVX512VL))
4388 rtx tmp = lowpart_subreg (SFmode, operands[0], DFmode);
4389 emit_move_insn (tmp, operands[1]);
4392 operands[3] = lowpart_subreg (V4SFmode, operands[1], SFmode);
4393 /* FIXME: vec_interleave_lowv4sf for AVX512VL should allow
4394 =v, v, then vbroadcastss will be only needed for AVX512F without
4396 if (!EXT_REX_SSE_REGNO_P (REGNO (operands[3])))
4397 emit_insn (gen_vec_interleave_lowv4sf (operands[3], operands[3],
4401 rtx tmp = lowpart_subreg (V16SFmode, operands[3], V4SFmode);
4402 emit_insn (gen_avx512f_vec_dupv16sf_1 (tmp, tmp));
4406 emit_insn (gen_vec_setv4sf_0 (operands[3],
4407 CONST0_RTX (V4SFmode), operands[1]));
4410 ;; It's more profitable to split and then extend in the same register.
4412 [(set (match_operand:DF 0 "sse_reg_operand")
4414 (match_operand:SF 1 "memory_operand")))]
4415 "TARGET_SPLIT_MEM_OPND_FOR_FP_CONVERTS
4416 && optimize_insn_for_speed_p ()"
4417 [(set (match_dup 2) (match_dup 1))
4418 (set (match_dup 0) (float_extend:DF (match_dup 2)))]
4419 "operands[2] = lowpart_subreg (SFmode, operands[0], DFmode);")
4421 ;; Break partial reg stall for cvtss2sd. This splitter should split
4422 ;; late in the pass sequence (after register rename pass),
4423 ;; so allocated registers won't change anymore.
4426 [(set (match_operand:DF 0 "sse_reg_operand")
4428 (match_operand:SF 1 "nonimmediate_operand")))]
4429 "TARGET_SSE_PARTIAL_REG_DEPENDENCY && epilogue_completed
4430 && optimize_function_for_speed_p (cfun)
4431 && (!REG_P (operands[1])
4432 || REGNO (operands[0]) != REGNO (operands[1]))
4433 && (!EXT_REX_SSE_REG_P (operands[0])
4434 || TARGET_AVX512VL)"
4443 operands[0] = lowpart_subreg (V2DFmode, operands[0], DFmode);
4444 emit_move_insn (operands[0], CONST0_RTX (V2DFmode));
4447 (define_expand "extend<mode>xf2"
4448 [(set (match_operand:XF 0 "nonimmediate_operand")
4449 (float_extend:XF (match_operand:MODEF 1 "general_operand")))]
4452 /* ??? Needed for compress_float_constant since all fp constants
4453 are TARGET_LEGITIMATE_CONSTANT_P. */
4454 if (CONST_DOUBLE_P (operands[1]))
4456 if (standard_80387_constant_p (operands[1]) > 0)
4458 operands[1] = simplify_const_unary_operation
4459 (FLOAT_EXTEND, XFmode, operands[1], <MODE>mode);
4460 emit_move_insn_1 (operands[0], operands[1]);
4463 operands[1] = validize_mem (force_const_mem (<MODE>mode, operands[1]));
4467 (define_insn "*extend<mode>xf2_i387"
4468 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
4470 (match_operand:MODEF 1 "nonimmediate_operand" "fm,f")))]
4472 "* return output_387_reg_move (insn, operands);"
4473 [(set_attr "type" "fmov")
4474 (set_attr "mode" "<MODE>,XF")])
4476 ;; %%% This seems like bad news.
4477 ;; This cannot output into an f-reg because there is no way to be sure
4478 ;; of truncating in that case. Otherwise this is just like a simple move
4479 ;; insn. So we pretend we can output to a reg in order to get better
4480 ;; register preferencing, but we really use a stack slot.
4482 ;; Conversion from DFmode to SFmode.
4484 (define_insn "truncdfsf2"
4485 [(set (match_operand:SF 0 "nonimm_ssenomem_operand" "=m,f,v")
4487 (match_operand:DF 1 "register_ssemem_operand" "f,f,vm")))]
4488 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4490 switch (which_alternative)
4494 return output_387_reg_move (insn, operands);
4497 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4503 [(set_attr "type" "fmov,fmov,ssecvt")
4504 (set_attr "mode" "SF")
4505 (set (attr "enabled")
4507 (match_test ("TARGET_SSE2 && TARGET_SSE_MATH"))
4508 (cond [(eq_attr "alternative" "0")
4509 (symbol_ref "TARGET_MIX_SSE_I387")
4510 (eq_attr "alternative" "1")
4511 (symbol_ref "TARGET_MIX_SSE_I387
4512 && flag_unsafe_math_optimizations")
4514 (symbol_ref "true"))
4515 (cond [(eq_attr "alternative" "0")
4517 (eq_attr "alternative" "1")
4518 (symbol_ref "flag_unsafe_math_optimizations")
4520 (symbol_ref "false"))))])
4522 /* For converting DF(xmm2) to SF(xmm1), use the following code instead of
4524 unpcklpd xmm2,xmm2 ; packed conversion might crash on signaling NaNs
4526 We do the conversion post reload to avoid producing of 128bit spills
4527 that might lead to ICE on 32bit target. The sequence unlikely combine
4530 [(set (match_operand:SF 0 "sse_reg_operand")
4532 (match_operand:DF 1 "nonimmediate_operand")))]
4533 "TARGET_USE_VECTOR_FP_CONVERTS
4534 && optimize_insn_for_speed_p ()
4536 && (!EXT_REX_SSE_REG_P (operands[0])
4537 || TARGET_AVX512VL)"
4540 (float_truncate:V2SF
4544 operands[2] = lowpart_subreg (V4SFmode, operands[0], SFmode);
4545 operands[3] = CONST0_RTX (V2SFmode);
4546 operands[4] = lowpart_subreg (V2DFmode, operands[0], SFmode);
4547 /* Use movsd for loading from memory, unpcklpd for registers.
4548 Try to avoid move when unpacking can be done in source, or SSE3
4549 movddup is available. */
4550 if (REG_P (operands[1]))
4553 && REGNO (operands[0]) != REGNO (operands[1]))
4555 rtx tmp = lowpart_subreg (DFmode, operands[0], SFmode);
4556 emit_move_insn (tmp, operands[1]);
4559 else if (!TARGET_SSE3)
4560 operands[4] = lowpart_subreg (V2DFmode, operands[1], DFmode);
4561 emit_insn (gen_vec_dupv2df (operands[4], operands[1]));
4564 emit_insn (gen_vec_concatv2df (operands[4], operands[1],
4565 CONST0_RTX (DFmode)));
4568 ;; It's more profitable to split and then truncate in the same register.
4570 [(set (match_operand:SF 0 "sse_reg_operand")
4572 (match_operand:DF 1 "memory_operand")))]
4573 "TARGET_SPLIT_MEM_OPND_FOR_FP_CONVERTS
4574 && optimize_insn_for_speed_p ()"
4575 [(set (match_dup 2) (match_dup 1))
4576 (set (match_dup 0) (float_truncate:SF (match_dup 2)))]
4577 "operands[2] = lowpart_subreg (DFmode, operands[0], SFmode);")
4579 ;; Break partial reg stall for cvtsd2ss. This splitter should split
4580 ;; late in the pass sequence (after register rename pass),
4581 ;; so allocated registers won't change anymore.
4584 [(set (match_operand:SF 0 "sse_reg_operand")
4586 (match_operand:DF 1 "nonimmediate_operand")))]
4587 "TARGET_SSE_PARTIAL_REG_DEPENDENCY && epilogue_completed
4588 && optimize_function_for_speed_p (cfun)
4589 && (!REG_P (operands[1])
4590 || REGNO (operands[0]) != REGNO (operands[1]))
4591 && (!EXT_REX_SSE_REG_P (operands[0])
4592 || TARGET_AVX512VL)"
4601 operands[0] = lowpart_subreg (V4SFmode, operands[0], SFmode);
4602 emit_move_insn (operands[0], CONST0_RTX (V4SFmode));
4605 ;; Conversion from XFmode to {SF,DF}mode
4607 (define_insn "truncxf<mode>2"
4608 [(set (match_operand:MODEF 0 "nonimmediate_operand" "=m,f")
4609 (float_truncate:MODEF
4610 (match_operand:XF 1 "register_operand" "f,f")))]
4612 "* return output_387_reg_move (insn, operands);"
4613 [(set_attr "type" "fmov")
4614 (set_attr "mode" "<MODE>")
4615 (set (attr "enabled")
4616 (cond [(eq_attr "alternative" "1")
4617 (symbol_ref "flag_unsafe_math_optimizations")
4619 (symbol_ref "true")))])
4621 ;; Signed conversion to DImode.
4623 (define_expand "fix_truncxfdi2"
4624 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand")
4625 (fix:DI (match_operand:XF 1 "register_operand")))
4626 (clobber (reg:CC FLAGS_REG))])]
4631 emit_insn (gen_fix_truncdi_i387_fisttp (operands[0], operands[1]));
4636 (define_expand "fix_trunc<mode>di2"
4637 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand")
4638 (fix:DI (match_operand:MODEF 1 "register_operand")))
4639 (clobber (reg:CC FLAGS_REG))])]
4640 "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4643 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4645 emit_insn (gen_fix_truncdi_i387_fisttp (operands[0], operands[1]));
4648 if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4650 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4651 emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4652 if (out != operands[0])
4653 emit_move_insn (operands[0], out);
4658 ;; Signed conversion to SImode.
4660 (define_expand "fix_truncxfsi2"
4661 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand")
4662 (fix:SI (match_operand:XF 1 "register_operand")))
4663 (clobber (reg:CC FLAGS_REG))])]
4668 emit_insn (gen_fix_truncsi_i387_fisttp (operands[0], operands[1]));
4673 (define_expand "fix_trunc<mode>si2"
4674 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand")
4675 (fix:SI (match_operand:MODEF 1 "register_operand")))
4676 (clobber (reg:CC FLAGS_REG))])]
4677 "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4680 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4682 emit_insn (gen_fix_truncsi_i387_fisttp (operands[0], operands[1]));
4685 if (SSE_FLOAT_MODE_P (<MODE>mode))
4687 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4688 emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4689 if (out != operands[0])
4690 emit_move_insn (operands[0], out);
4695 ;; Signed conversion to HImode.
4697 (define_expand "fix_trunc<mode>hi2"
4698 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand")
4699 (fix:HI (match_operand:X87MODEF 1 "register_operand")))
4700 (clobber (reg:CC FLAGS_REG))])]
4702 && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4706 emit_insn (gen_fix_trunchi_i387_fisttp (operands[0], operands[1]));
4711 ;; Unsigned conversion to DImode
4713 (define_insn "fixuns_trunc<mode>di2"
4714 [(set (match_operand:DI 0 "register_operand" "=r")
4716 (match_operand:MODEF 1 "nonimmediate_operand" "vm")))]
4717 "TARGET_64BIT && TARGET_AVX512F && TARGET_SSE_MATH"
4718 "vcvtt<ssemodesuffix>2usi\t{%1, %0|%0, %1}"
4719 [(set_attr "type" "sseicvt")
4720 (set_attr "prefix" "evex")
4721 (set_attr "mode" "DI")])
4723 ;; Unsigned conversion to SImode.
4725 (define_expand "fixuns_trunc<mode>si2"
4727 [(set (match_operand:SI 0 "register_operand")
4729 (match_operand:MODEF 1 "nonimmediate_operand")))
4731 (clobber (match_scratch:<ssevecmode> 3))
4732 (clobber (match_scratch:<ssevecmode> 4))])]
4733 "(!TARGET_64BIT || TARGET_AVX512F) && TARGET_SSE2 && TARGET_SSE_MATH"
4735 machine_mode mode = <MODE>mode;
4736 machine_mode vecmode = <ssevecmode>mode;
4737 REAL_VALUE_TYPE TWO31r;
4742 emit_insn (gen_fixuns_trunc<mode>si2_avx512f (operands[0], operands[1]));
4746 if (optimize_insn_for_size_p ())
4749 real_ldexp (&TWO31r, &dconst1, 31);
4750 two31 = const_double_from_real_value (TWO31r, mode);
4751 two31 = ix86_build_const_vector (vecmode, true, two31);
4752 operands[2] = force_reg (vecmode, two31);
4755 (define_insn "fixuns_trunc<mode>si2_avx512f"
4756 [(set (match_operand:SI 0 "register_operand" "=r")
4758 (match_operand:MODEF 1 "nonimmediate_operand" "vm")))]
4759 "TARGET_AVX512F && TARGET_SSE_MATH"
4760 "vcvtt<ssemodesuffix>2usi\t{%1, %0|%0, %1}"
4761 [(set_attr "type" "sseicvt")
4762 (set_attr "prefix" "evex")
4763 (set_attr "mode" "SI")])
4765 (define_insn "*fixuns_trunc<mode>si2_avx512f_zext"
4766 [(set (match_operand:DI 0 "register_operand" "=r")
4769 (match_operand:MODEF 1 "nonimmediate_operand" "vm"))))]
4770 "TARGET_64BIT && TARGET_AVX512F && TARGET_SSE_MATH"
4771 "vcvtt<ssemodesuffix>2usi\t{%1, %k0|%k0, %1}"
4772 [(set_attr "type" "sseicvt")
4773 (set_attr "prefix" "evex")
4774 (set_attr "mode" "SI")])
4776 (define_insn_and_split "*fixuns_trunc<mode>_1"
4777 [(set (match_operand:SI 0 "register_operand" "=&x,&x")
4779 (match_operand:MODEF 3 "nonimmediate_operand" "xm,xm")))
4780 (use (match_operand:<ssevecmode> 4 "nonimmediate_operand" "m,x"))
4781 (clobber (match_scratch:<ssevecmode> 1 "=x,&x"))
4782 (clobber (match_scratch:<ssevecmode> 2 "=x,x"))]
4783 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH
4784 && optimize_function_for_speed_p (cfun)"
4786 "&& reload_completed"
4789 ix86_split_convert_uns_si_sse (operands);
4793 ;; Unsigned conversion to HImode.
4794 ;; Without these patterns, we'll try the unsigned SI conversion which
4795 ;; is complex for SSE, rather than the signed SI conversion, which isn't.
4797 (define_expand "fixuns_trunc<mode>hi2"
4799 (fix:SI (match_operand:MODEF 1 "nonimmediate_operand")))
4800 (set (match_operand:HI 0 "nonimmediate_operand")
4801 (subreg:HI (match_dup 2) 0))]
4802 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
4803 "operands[2] = gen_reg_rtx (SImode);")
4805 ;; When SSE is available, it is always faster to use it!
4806 (define_insn "fix_trunc<MODEF:mode><SWI48:mode>_sse"
4807 [(set (match_operand:SWI48 0 "register_operand" "=r,r")
4808 (fix:SWI48 (match_operand:MODEF 1 "nonimmediate_operand" "v,m")))]
4809 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode)
4810 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4811 "%vcvtt<MODEF:ssemodesuffix>2si<SWI48:rex64suffix>\t{%1, %0|%0, %1}"
4812 [(set_attr "type" "sseicvt")
4813 (set_attr "prefix" "maybe_vex")
4814 (set (attr "prefix_rex")
4816 (match_test "<SWI48:MODE>mode == DImode")
4818 (const_string "*")))
4819 (set_attr "mode" "<MODEF:MODE>")
4820 (set_attr "athlon_decode" "double,vector")
4821 (set_attr "amdfam10_decode" "double,double")
4822 (set_attr "bdver1_decode" "double,double")])
4824 ;; Avoid vector decoded forms of the instruction.
4826 [(match_scratch:MODEF 2 "x")
4827 (set (match_operand:SWI48 0 "register_operand")
4828 (fix:SWI48 (match_operand:MODEF 1 "memory_operand")))]
4829 "TARGET_AVOID_VECTOR_DECODE
4830 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode)
4831 && optimize_insn_for_speed_p ()"
4832 [(set (match_dup 2) (match_dup 1))
4833 (set (match_dup 0) (fix:SWI48 (match_dup 2)))])
4835 (define_insn "fix_trunc<mode>_i387_fisttp"
4836 [(set (match_operand:SWI248x 0 "nonimmediate_operand" "=m")
4837 (fix:SWI248x (match_operand 1 "register_operand" "f")))
4838 (clobber (match_scratch:XF 2 "=&f"))]
4839 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4841 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4842 && (TARGET_64BIT || <MODE>mode != DImode))
4843 && TARGET_SSE_MATH)"
4844 "* return output_fix_trunc (insn, operands, true);"
4845 [(set_attr "type" "fisttp")
4846 (set_attr "mode" "<MODE>")])
4848 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4849 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4850 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4851 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4852 ;; function in i386.c.
4853 (define_insn_and_split "*fix_trunc<mode>_i387_1"
4854 [(set (match_operand:SWI248x 0 "nonimmediate_operand")
4855 (fix:SWI248x (match_operand 1 "register_operand")))
4856 (clobber (reg:CC FLAGS_REG))]
4857 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4859 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4860 && (TARGET_64BIT || <MODE>mode != DImode))
4861 && can_create_pseudo_p ()"
4866 ix86_optimize_mode_switching[I387_TRUNC] = 1;
4868 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
4869 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
4871 emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4872 operands[2], operands[3]));
4875 [(set_attr "type" "fistp")
4876 (set_attr "i387_cw" "trunc")
4877 (set_attr "mode" "<MODE>")])
4879 (define_insn "fix_truncdi_i387"
4880 [(set (match_operand:DI 0 "nonimmediate_operand" "=m")
4881 (fix:DI (match_operand 1 "register_operand" "f")))
4882 (use (match_operand:HI 2 "memory_operand" "m"))
4883 (use (match_operand:HI 3 "memory_operand" "m"))
4884 (clobber (match_scratch:XF 4 "=&f"))]
4885 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4887 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4888 "* return output_fix_trunc (insn, operands, false);"
4889 [(set_attr "type" "fistp")
4890 (set_attr "i387_cw" "trunc")
4891 (set_attr "mode" "DI")])
4893 (define_insn "fix_trunc<mode>_i387"
4894 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m")
4895 (fix:SWI24 (match_operand 1 "register_operand" "f")))
4896 (use (match_operand:HI 2 "memory_operand" "m"))
4897 (use (match_operand:HI 3 "memory_operand" "m"))]
4898 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4900 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4901 "* return output_fix_trunc (insn, operands, false);"
4902 [(set_attr "type" "fistp")
4903 (set_attr "i387_cw" "trunc")
4904 (set_attr "mode" "<MODE>")])
4906 (define_insn "x86_fnstcw_1"
4907 [(set (match_operand:HI 0 "memory_operand" "=m")
4908 (unspec:HI [(const_int 0)] UNSPEC_FSTCW))]
4911 [(set (attr "length")
4912 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
4913 (set_attr "mode" "HI")
4914 (set_attr "unit" "i387")
4915 (set_attr "bdver1_decode" "vector")])
4917 ;; Conversion between fixed point and floating point.
4919 ;; Even though we only accept memory inputs, the backend _really_
4920 ;; wants to be able to do this between registers. Thankfully, LRA
4921 ;; will fix this up for us during register allocation.
4923 (define_insn "floathi<mode>2"
4924 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
4925 (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "m")))]
4927 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4928 || TARGET_MIX_SSE_I387)"
4930 [(set_attr "type" "fmov")
4931 (set_attr "mode" "<MODE>")
4932 (set_attr "znver1_decode" "double")
4933 (set_attr "fp_int_src" "true")])
4935 (define_insn "float<SWI48x:mode>xf2"
4936 [(set (match_operand:XF 0 "register_operand" "=f")
4937 (float:XF (match_operand:SWI48x 1 "nonimmediate_operand" "m")))]
4940 [(set_attr "type" "fmov")
4941 (set_attr "mode" "XF")
4942 (set_attr "znver1_decode" "double")
4943 (set_attr "fp_int_src" "true")])
4945 (define_expand "float<SWI48x:mode><MODEF:mode>2"
4946 [(set (match_operand:MODEF 0 "register_operand")
4947 (float:MODEF (match_operand:SWI48x 1 "nonimmediate_operand")))]
4948 "(TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI48x:MODE>mode))
4949 || (SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
4950 && ((<SWI48x:MODE>mode != DImode) || TARGET_64BIT))")
4952 (define_insn "*float<SWI48:mode><MODEF:mode>2"
4953 [(set (match_operand:MODEF 0 "register_operand" "=f,v,v")
4955 (match_operand:SWI48 1 "nonimmediate_operand" "m,r,m")))]
4956 "(TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI48:MODE>mode))
4957 || (SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)"
4960 %vcvtsi2<MODEF:ssemodesuffix><SWI48:rex64suffix>\t{%1, %d0|%d0, %1}
4961 %vcvtsi2<MODEF:ssemodesuffix><SWI48:rex64suffix>\t{%1, %d0|%d0, %1}"
4962 [(set_attr "type" "fmov,sseicvt,sseicvt")
4963 (set_attr "prefix" "orig,maybe_vex,maybe_vex")
4964 (set_attr "mode" "<MODEF:MODE>")
4965 (set (attr "prefix_rex")
4967 (and (eq_attr "prefix" "maybe_vex")
4968 (match_test "<SWI48:MODE>mode == DImode"))
4970 (const_string "*")))
4971 (set_attr "unit" "i387,*,*")
4972 (set_attr "athlon_decode" "*,double,direct")
4973 (set_attr "amdfam10_decode" "*,vector,double")
4974 (set_attr "bdver1_decode" "*,double,direct")
4975 (set_attr "znver1_decode" "double,*,*")
4976 (set_attr "fp_int_src" "true")
4977 (set (attr "enabled")
4979 (match_test ("SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"))
4981 (eq_attr "alternative" "0")
4982 (symbol_ref "TARGET_MIX_SSE_I387
4983 && X87_ENABLE_FLOAT (<MODEF:MODE>mode,
4985 (symbol_ref "true"))
4987 (eq_attr "alternative" "0")
4989 (symbol_ref "false"))))
4990 (set (attr "preferred_for_speed")
4991 (cond [(eq_attr "alternative" "1")
4992 (symbol_ref "TARGET_INTER_UNIT_CONVERSIONS")]
4993 (symbol_ref "true")))])
4995 (define_insn "*floatdi<MODEF:mode>2_i387"
4996 [(set (match_operand:MODEF 0 "register_operand" "=f")
4997 (float:MODEF (match_operand:DI 1 "nonimmediate_operand" "m")))]
4999 && TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, DImode)"
5001 [(set_attr "type" "fmov")
5002 (set_attr "mode" "<MODEF:MODE>")
5003 (set_attr "znver1_decode" "double")
5004 (set_attr "fp_int_src" "true")])
5006 ;; Try TARGET_USE_VECTOR_CONVERTS, but not so hard as to require extra memory
5007 ;; slots when !TARGET_INTER_UNIT_MOVES_TO_VEC disables the general_regs
5008 ;; alternative in sse2_loadld.
5010 [(set (match_operand:MODEF 0 "sse_reg_operand")
5011 (float:MODEF (match_operand:SI 1 "nonimmediate_operand")))]
5013 && TARGET_USE_VECTOR_CONVERTS
5014 && optimize_function_for_speed_p (cfun)
5016 && (MEM_P (operands[1]) || TARGET_INTER_UNIT_MOVES_TO_VEC)
5017 && (!EXT_REX_SSE_REG_P (operands[0])
5018 || TARGET_AVX512VL)"
5021 operands[3] = lowpart_subreg (<ssevecmode>mode, operands[0], <MODE>mode);
5022 operands[4] = lowpart_subreg (V4SImode, operands[0], <MODE>mode);
5024 emit_insn (gen_sse2_loadld (operands[4],
5025 CONST0_RTX (V4SImode), operands[1]));
5027 if (<ssevecmode>mode == V4SFmode)
5028 emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
5030 emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
5034 ;; Avoid store forwarding (partial memory) stall penalty
5035 ;; by passing DImode value through XMM registers. */
5038 [(set (match_operand:X87MODEF 0 "register_operand")
5040 (match_operand:DI 1 "register_operand")))]
5041 "!TARGET_64BIT && TARGET_INTER_UNIT_MOVES_TO_VEC
5042 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5043 && TARGET_SSE2 && optimize_function_for_speed_p (cfun)
5044 && can_create_pseudo_p ()"
5047 emit_insn (gen_floatdi<mode>2_i387_with_xmm
5048 (operands[0], operands[1],
5049 assign_386_stack_local (DImode, SLOT_TEMP)));
5053 (define_insn_and_split "floatdi<X87MODEF:mode>2_i387_with_xmm"
5054 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5056 (match_operand:DI 1 "register_operand" "r")))
5057 (clobber (match_scratch:V4SI 3 "=x"))
5058 (clobber (match_scratch:V4SI 4 "=x"))
5059 (clobber (match_operand:DI 2 "memory_operand" "=m"))]
5060 "!TARGET_64BIT && TARGET_INTER_UNIT_MOVES_TO_VEC
5061 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5062 && TARGET_SSE2 && optimize_function_for_speed_p (cfun)"
5064 "&& reload_completed"
5065 [(set (match_dup 2) (match_dup 3))
5066 (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5068 /* The DImode arrived in a pair of integral registers (e.g. %edx:%eax).
5069 Assemble the 64-bit DImode value in an xmm register. */
5070 emit_insn (gen_sse2_loadld (operands[3], CONST0_RTX (V4SImode),
5071 gen_lowpart (SImode, operands[1])));
5072 emit_insn (gen_sse2_loadld (operands[4], CONST0_RTX (V4SImode),
5073 gen_highpart (SImode, operands[1])));
5074 emit_insn (gen_vec_interleave_lowv4si (operands[3], operands[3],
5077 operands[3] = gen_lowpart (DImode, operands[3]);
5079 [(set_attr "type" "multi")
5080 (set_attr "mode" "<X87MODEF:MODE>")
5081 (set_attr "unit" "i387")
5082 (set_attr "fp_int_src" "true")])
5084 ;; Avoid partial SSE register dependency stalls. This splitter should split
5085 ;; late in the pass sequence (after register rename pass), so allocated
5086 ;; registers won't change anymore
5089 [(set (match_operand:MODEF 0 "sse_reg_operand")
5090 (float:MODEF (match_operand:SWI48 1 "nonimmediate_operand")))]
5091 "TARGET_SSE_PARTIAL_REG_DEPENDENCY && epilogue_completed
5092 && optimize_function_for_speed_p (cfun)
5093 && (!EXT_REX_SSE_REG_P (operands[0])
5094 || TARGET_AVX512VL)"
5096 (vec_merge:<MODEF:ssevecmode>
5097 (vec_duplicate:<MODEF:ssevecmode>
5103 const machine_mode vmode = <MODEF:ssevecmode>mode;
5105 operands[0] = lowpart_subreg (vmode, operands[0], <MODEF:MODE>mode);
5106 emit_move_insn (operands[0], CONST0_RTX (vmode));
5109 (define_expand "floatuns<SWI12:mode><MODEF:mode>2"
5110 [(set (match_operand:MODEF 0 "register_operand")
5111 (unsigned_float:MODEF
5112 (match_operand:SWI12 1 "nonimmediate_operand")))]
5114 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
5116 operands[1] = convert_to_mode (SImode, operands[1], 1);
5117 emit_insn (gen_floatsi<MODEF:mode>2 (operands[0], operands[1]));
5121 (define_insn "*floatuns<SWI48:mode><MODEF:mode>2_avx512"
5122 [(set (match_operand:MODEF 0 "register_operand" "=v")
5123 (unsigned_float:MODEF
5124 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))]
5125 "TARGET_AVX512F && TARGET_SSE_MATH"
5126 "vcvtusi2<MODEF:ssemodesuffix><SWI48:rex64suffix>\t{%1, %0, %0|%0, %0, %1}"
5127 [(set_attr "type" "sseicvt")
5128 (set_attr "prefix" "evex")
5129 (set_attr "mode" "<MODEF:MODE>")])
5131 ;; Avoid store forwarding (partial memory) stall penalty by extending
5132 ;; SImode value to DImode through XMM register instead of pushing two
5133 ;; SImode values to stack. Also note that fild loads from memory only.
5135 (define_insn_and_split "floatunssi<mode>2_i387_with_xmm"
5136 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5137 (unsigned_float:X87MODEF
5138 (match_operand:SI 1 "nonimmediate_operand" "rm")))
5139 (clobber (match_operand:DI 2 "memory_operand" "=m"))
5140 (clobber (match_scratch:DI 3 "=x"))]
5142 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5143 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC"
5145 "&& reload_completed"
5146 [(set (match_dup 3) (zero_extend:DI (match_dup 1)))
5147 (set (match_dup 2) (match_dup 3))
5149 (float:X87MODEF (match_dup 2)))]
5151 [(set_attr "type" "multi")
5152 (set_attr "mode" "<MODE>")])
5154 (define_expand "floatunssi<mode>2"
5155 [(set (match_operand:X87MODEF 0 "register_operand")
5156 (unsigned_float:X87MODEF
5157 (match_operand:SI 1 "nonimmediate_operand")))]
5159 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5160 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC)
5161 || ((!TARGET_64BIT || TARGET_AVX512F)
5162 && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
5164 if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
5166 emit_insn (gen_floatunssi<mode>2_i387_with_xmm
5167 (operands[0], operands[1],
5168 assign_386_stack_local (DImode, SLOT_TEMP)));
5171 if (!TARGET_AVX512F)
5173 ix86_expand_convert_uns_si<mode>_sse (operands[0], operands[1]);
5178 (define_expand "floatunsdisf2"
5179 [(set (match_operand:SF 0 "register_operand")
5181 (match_operand:DI 1 "nonimmediate_operand")))]
5182 "TARGET_64BIT && TARGET_SSE && TARGET_SSE_MATH"
5184 if (!TARGET_AVX512F)
5186 x86_emit_floatuns (operands);
5191 (define_expand "floatunsdidf2"
5192 [(set (match_operand:DF 0 "register_operand")
5194 (match_operand:DI 1 "nonimmediate_operand")))]
5195 "(TARGET_KEEPS_VECTOR_ALIGNED_STACK || TARGET_AVX512F)
5196 && TARGET_SSE2 && TARGET_SSE_MATH"
5200 ix86_expand_convert_uns_didf_sse (operands[0], operands[1]);
5203 if (!TARGET_AVX512F)
5205 x86_emit_floatuns (operands);
5210 ;; Load effective address instructions
5212 (define_insn_and_split "*lea<mode>"
5213 [(set (match_operand:SWI48 0 "register_operand" "=r")
5214 (match_operand:SWI48 1 "address_no_seg_operand" "Ts"))]
5217 if (SImode_address_operand (operands[1], VOIDmode))
5219 gcc_assert (TARGET_64BIT);
5220 return "lea{l}\t{%E1, %k0|%k0, %E1}";
5223 return "lea{<imodesuffix>}\t{%E1, %0|%0, %E1}";
5225 "reload_completed && ix86_avoid_lea_for_addr (insn, operands)"
5228 machine_mode mode = <MODE>mode;
5231 /* ix86_avoid_lea_for_addr re-recognizes insn and may
5232 change operands[] array behind our back. */
5233 pat = PATTERN (curr_insn);
5235 operands[0] = SET_DEST (pat);
5236 operands[1] = SET_SRC (pat);
5238 /* Emit all operations in SImode for zero-extended addresses. */
5239 if (SImode_address_operand (operands[1], VOIDmode))
5242 ix86_split_lea_for_addr (curr_insn, operands, mode);
5244 /* Zero-extend return register to DImode for zero-extended addresses. */
5245 if (mode != <MODE>mode)
5246 emit_insn (gen_zero_extendsidi2
5247 (operands[0], gen_lowpart (mode, operands[0])));
5251 [(set_attr "type" "lea")
5254 (match_operand 1 "SImode_address_operand")
5256 (const_string "<MODE>")))])
5260 (define_expand "add<mode>3"
5261 [(set (match_operand:SDWIM 0 "nonimmediate_operand")
5262 (plus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")
5263 (match_operand:SDWIM 2 "<general_hilo_operand>")))]
5265 "ix86_expand_binary_operator (PLUS, <MODE>mode, operands); DONE;")
5267 (define_insn_and_split "*add<dwi>3_doubleword"
5268 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
5270 (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0")
5271 (match_operand:<DWI> 2 "x86_64_hilo_general_operand"
5273 (clobber (reg:CC FLAGS_REG))]
5274 "ix86_binary_operator_ok (PLUS, <DWI>mode, operands)"
5277 [(parallel [(set (reg:CCC FLAGS_REG)
5279 (plus:DWIH (match_dup 1) (match_dup 2))
5282 (plus:DWIH (match_dup 1) (match_dup 2)))])
5283 (parallel [(set (match_dup 3)
5286 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
5289 (clobber (reg:CC FLAGS_REG))])]
5291 split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
5292 if (operands[2] == const0_rtx)
5294 ix86_expand_binary_operator (PLUS, <MODE>mode, &operands[3]);
5299 (define_insn "*add<mode>_1"
5300 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,rm,r,r")
5302 (match_operand:SWI48 1 "nonimmediate_operand" "%0,0,r,r")
5303 (match_operand:SWI48 2 "x86_64_general_operand" "rme,re,0,le")))
5304 (clobber (reg:CC FLAGS_REG))]
5305 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5307 switch (get_attr_type (insn))
5313 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5314 if (operands[2] == const1_rtx)
5315 return "inc{<imodesuffix>}\t%0";
5318 gcc_assert (operands[2] == constm1_rtx);
5319 return "dec{<imodesuffix>}\t%0";
5323 /* For most processors, ADD is faster than LEA. This alternative
5324 was added to use ADD as much as possible. */
5325 if (which_alternative == 2)
5326 std::swap (operands[1], operands[2]);
5328 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5329 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5330 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5332 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5336 (cond [(eq_attr "alternative" "3")
5337 (const_string "lea")
5338 (match_operand:SWI48 2 "incdec_operand")
5339 (const_string "incdec")
5341 (const_string "alu")))
5342 (set (attr "length_immediate")
5344 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5346 (const_string "*")))
5347 (set_attr "mode" "<MODE>")])
5349 ;; It may seem that nonimmediate operand is proper one for operand 1.
5350 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5351 ;; we take care in ix86_binary_operator_ok to not allow two memory
5352 ;; operands so proper swapping will be done in reload. This allow
5353 ;; patterns constructed from addsi_1 to match.
5355 (define_insn "addsi_1_zext"
5356 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
5358 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r,r")
5359 (match_operand:SI 2 "x86_64_general_operand" "rme,0,le"))))
5360 (clobber (reg:CC FLAGS_REG))]
5361 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5363 switch (get_attr_type (insn))
5369 if (operands[2] == const1_rtx)
5370 return "inc{l}\t%k0";
5373 gcc_assert (operands[2] == constm1_rtx);
5374 return "dec{l}\t%k0";
5378 /* For most processors, ADD is faster than LEA. This alternative
5379 was added to use ADD as much as possible. */
5380 if (which_alternative == 1)
5381 std::swap (operands[1], operands[2]);
5383 if (x86_maybe_negate_const_int (&operands[2], SImode))
5384 return "sub{l}\t{%2, %k0|%k0, %2}";
5386 return "add{l}\t{%2, %k0|%k0, %2}";
5390 (cond [(eq_attr "alternative" "2")
5391 (const_string "lea")
5392 (match_operand:SI 2 "incdec_operand")
5393 (const_string "incdec")
5395 (const_string "alu")))
5396 (set (attr "length_immediate")
5398 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5400 (const_string "*")))
5401 (set_attr "mode" "SI")])
5403 (define_insn "*addhi_1"
5404 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r,Yp")
5405 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r,Yp")
5406 (match_operand:HI 2 "general_operand" "rn,rm,0,ln")))
5407 (clobber (reg:CC FLAGS_REG))]
5408 "ix86_binary_operator_ok (PLUS, HImode, operands)"
5410 switch (get_attr_type (insn))
5416 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5417 if (operands[2] == const1_rtx)
5418 return "inc{w}\t%0";
5421 gcc_assert (operands[2] == constm1_rtx);
5422 return "dec{w}\t%0";
5426 /* For most processors, ADD is faster than LEA. This alternative
5427 was added to use ADD as much as possible. */
5428 if (which_alternative == 2)
5429 std::swap (operands[1], operands[2]);
5431 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5432 if (x86_maybe_negate_const_int (&operands[2], HImode))
5433 return "sub{w}\t{%2, %0|%0, %2}";
5435 return "add{w}\t{%2, %0|%0, %2}";
5439 (cond [(eq_attr "alternative" "3")
5440 (const_string "lea")
5441 (match_operand:HI 2 "incdec_operand")
5442 (const_string "incdec")
5444 (const_string "alu")))
5445 (set (attr "length_immediate")
5447 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5449 (const_string "*")))
5450 (set_attr "mode" "HI,HI,HI,SI")])
5452 (define_insn "*addqi_1"
5453 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,q,r,r,Yp")
5454 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,q,0,r,Yp")
5455 (match_operand:QI 2 "general_operand" "qn,qm,0,rn,0,ln")))
5456 (clobber (reg:CC FLAGS_REG))]
5457 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5459 bool widen = (get_attr_mode (insn) != MODE_QI);
5461 switch (get_attr_type (insn))
5467 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5468 if (operands[2] == const1_rtx)
5469 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
5472 gcc_assert (operands[2] == constm1_rtx);
5473 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
5477 /* For most processors, ADD is faster than LEA. These alternatives
5478 were added to use ADD as much as possible. */
5479 if (which_alternative == 2 || which_alternative == 4)
5480 std::swap (operands[1], operands[2]);
5482 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5483 if (x86_maybe_negate_const_int (&operands[2], QImode))
5486 return "sub{l}\t{%2, %k0|%k0, %2}";
5488 return "sub{b}\t{%2, %0|%0, %2}";
5491 return "add{l}\t{%k2, %k0|%k0, %k2}";
5493 return "add{b}\t{%2, %0|%0, %2}";
5497 (cond [(eq_attr "alternative" "5")
5498 (const_string "lea")
5499 (match_operand:QI 2 "incdec_operand")
5500 (const_string "incdec")
5502 (const_string "alu")))
5503 (set (attr "length_immediate")
5505 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5507 (const_string "*")))
5508 (set_attr "mode" "QI,QI,QI,SI,SI,SI")
5509 ;; Potential partial reg stall on alternatives 3 and 4.
5510 (set (attr "preferred_for_speed")
5511 (cond [(eq_attr "alternative" "3,4")
5512 (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
5513 (symbol_ref "true")))])
5515 (define_insn "*addqi_1_slp"
5516 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
5517 (plus:QI (match_dup 0)
5518 (match_operand:QI 1 "general_operand" "qn,qm")))
5519 (clobber (reg:CC FLAGS_REG))]
5520 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
5521 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
5523 switch (get_attr_type (insn))
5526 if (operands[1] == const1_rtx)
5527 return "inc{b}\t%0";
5530 gcc_assert (operands[1] == constm1_rtx);
5531 return "dec{b}\t%0";
5535 if (x86_maybe_negate_const_int (&operands[1], QImode))
5536 return "sub{b}\t{%1, %0|%0, %1}";
5538 return "add{b}\t{%1, %0|%0, %1}";
5542 (if_then_else (match_operand:QI 1 "incdec_operand")
5543 (const_string "incdec")
5544 (const_string "alu1")))
5545 (set (attr "memory")
5546 (if_then_else (match_operand 1 "memory_operand")
5547 (const_string "load")
5548 (const_string "none")))
5549 (set_attr "mode" "QI")])
5551 ;; Split non destructive adds if we cannot use lea.
5553 [(set (match_operand:SWI48 0 "register_operand")
5554 (plus:SWI48 (match_operand:SWI48 1 "register_operand")
5555 (match_operand:SWI48 2 "x86_64_nonmemory_operand")))
5556 (clobber (reg:CC FLAGS_REG))]
5557 "reload_completed && ix86_avoid_lea_for_add (insn, operands)"
5558 [(set (match_dup 0) (match_dup 1))
5559 (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 2)))
5560 (clobber (reg:CC FLAGS_REG))])])
5562 ;; Split non destructive adds if we cannot use lea.
5564 [(set (match_operand:DI 0 "register_operand")
5566 (plus:SI (match_operand:SI 1 "register_operand")
5567 (match_operand:SI 2 "x86_64_nonmemory_operand"))))
5568 (clobber (reg:CC FLAGS_REG))]
5570 && reload_completed && ix86_avoid_lea_for_add (insn, operands)"
5571 [(set (match_dup 3) (match_dup 1))
5572 (parallel [(set (match_dup 0)
5573 (zero_extend:DI (plus:SI (match_dup 3) (match_dup 2))))
5574 (clobber (reg:CC FLAGS_REG))])]
5575 "operands[3] = gen_lowpart (SImode, operands[0]);")
5577 ;; Convert add to the lea pattern to avoid flags dependency.
5579 [(set (match_operand:SWI 0 "register_operand")
5580 (plus:SWI (match_operand:SWI 1 "register_operand")
5581 (match_operand:SWI 2 "<nonmemory_operand>")))
5582 (clobber (reg:CC FLAGS_REG))]
5583 "reload_completed && ix86_lea_for_add_ok (insn, operands)"
5585 (plus:<LEAMODE> (match_dup 1) (match_dup 2)))]
5587 if (<MODE>mode != <LEAMODE>mode)
5589 operands[0] = gen_lowpart (<LEAMODE>mode, operands[0]);
5590 operands[1] = gen_lowpart (<LEAMODE>mode, operands[1]);
5591 operands[2] = gen_lowpart (<LEAMODE>mode, operands[2]);
5595 ;; Convert add to the lea pattern to avoid flags dependency.
5597 [(set (match_operand:DI 0 "register_operand")
5599 (plus:SI (match_operand:SI 1 "register_operand")
5600 (match_operand:SI 2 "x86_64_nonmemory_operand"))))
5601 (clobber (reg:CC FLAGS_REG))]
5602 "TARGET_64BIT && reload_completed && ix86_lea_for_add_ok (insn, operands)"
5604 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))])
5606 (define_insn "*add<mode>_2"
5607 [(set (reg FLAGS_REG)
5610 (match_operand:SWI 1 "nonimmediate_operand" "%0,0,<r>")
5611 (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>,0"))
5613 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m,<r>")
5614 (plus:SWI (match_dup 1) (match_dup 2)))]
5615 "ix86_match_ccmode (insn, CCGOCmode)
5616 && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5618 switch (get_attr_type (insn))
5621 if (operands[2] == const1_rtx)
5622 return "inc{<imodesuffix>}\t%0";
5625 gcc_assert (operands[2] == constm1_rtx);
5626 return "dec{<imodesuffix>}\t%0";
5630 if (which_alternative == 2)
5631 std::swap (operands[1], operands[2]);
5633 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5634 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5635 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5637 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5641 (if_then_else (match_operand:SWI 2 "incdec_operand")
5642 (const_string "incdec")
5643 (const_string "alu")))
5644 (set (attr "length_immediate")
5646 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5648 (const_string "*")))
5649 (set_attr "mode" "<MODE>")])
5651 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5652 (define_insn "*addsi_2_zext"
5653 [(set (reg FLAGS_REG)
5655 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
5656 (match_operand:SI 2 "x86_64_general_operand" "rme,0"))
5658 (set (match_operand:DI 0 "register_operand" "=r,r")
5659 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5660 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5661 && ix86_binary_operator_ok (PLUS, SImode, operands)"
5663 switch (get_attr_type (insn))
5666 if (operands[2] == const1_rtx)
5667 return "inc{l}\t%k0";
5670 gcc_assert (operands[2] == constm1_rtx);
5671 return "dec{l}\t%k0";
5675 if (which_alternative == 1)
5676 std::swap (operands[1], operands[2]);
5678 if (x86_maybe_negate_const_int (&operands[2], SImode))
5679 return "sub{l}\t{%2, %k0|%k0, %2}";
5681 return "add{l}\t{%2, %k0|%k0, %2}";
5685 (if_then_else (match_operand:SI 2 "incdec_operand")
5686 (const_string "incdec")
5687 (const_string "alu")))
5688 (set (attr "length_immediate")
5690 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5692 (const_string "*")))
5693 (set_attr "mode" "SI")])
5695 (define_insn "*add<mode>_3"
5696 [(set (reg FLAGS_REG)
5698 (neg:SWI (match_operand:SWI 2 "<general_operand>" "<g>,0"))
5699 (match_operand:SWI 1 "nonimmediate_operand" "%0,<r>")))
5700 (clobber (match_scratch:SWI 0 "=<r>,<r>"))]
5701 "ix86_match_ccmode (insn, CCZmode)
5702 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
5704 switch (get_attr_type (insn))
5707 if (operands[2] == const1_rtx)
5708 return "inc{<imodesuffix>}\t%0";
5711 gcc_assert (operands[2] == constm1_rtx);
5712 return "dec{<imodesuffix>}\t%0";
5716 if (which_alternative == 1)
5717 std::swap (operands[1], operands[2]);
5719 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5720 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5721 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5723 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5727 (if_then_else (match_operand:SWI 2 "incdec_operand")
5728 (const_string "incdec")
5729 (const_string "alu")))
5730 (set (attr "length_immediate")
5732 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5734 (const_string "*")))
5735 (set_attr "mode" "<MODE>")])
5737 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5738 (define_insn "*addsi_3_zext"
5739 [(set (reg FLAGS_REG)
5741 (neg:SI (match_operand:SI 2 "x86_64_general_operand" "rme,0"))
5742 (match_operand:SI 1 "nonimmediate_operand" "%0,r")))
5743 (set (match_operand:DI 0 "register_operand" "=r,r")
5744 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5745 "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
5746 && ix86_binary_operator_ok (PLUS, SImode, operands)"
5748 switch (get_attr_type (insn))
5751 if (operands[2] == const1_rtx)
5752 return "inc{l}\t%k0";
5755 gcc_assert (operands[2] == constm1_rtx);
5756 return "dec{l}\t%k0";
5760 if (which_alternative == 1)
5761 std::swap (operands[1], operands[2]);
5763 if (x86_maybe_negate_const_int (&operands[2], SImode))
5764 return "sub{l}\t{%2, %k0|%k0, %2}";
5766 return "add{l}\t{%2, %k0|%k0, %2}";
5770 (if_then_else (match_operand:SI 2 "incdec_operand")
5771 (const_string "incdec")
5772 (const_string "alu")))
5773 (set (attr "length_immediate")
5775 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5777 (const_string "*")))
5778 (set_attr "mode" "SI")])
5780 ; For comparisons against 1, -1 and 128, we may generate better code
5781 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
5782 ; is matched then. We can't accept general immediate, because for
5783 ; case of overflows, the result is messed up.
5784 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5785 ; only for comparisons not depending on it.
5787 (define_insn "*adddi_4"
5788 [(set (reg FLAGS_REG)
5790 (match_operand:DI 1 "nonimmediate_operand" "0")
5791 (match_operand:DI 2 "x86_64_immediate_operand" "e")))
5792 (clobber (match_scratch:DI 0 "=rm"))]
5794 && ix86_match_ccmode (insn, CCGCmode)"
5796 switch (get_attr_type (insn))
5799 if (operands[2] == constm1_rtx)
5800 return "inc{q}\t%0";
5803 gcc_assert (operands[2] == const1_rtx);
5804 return "dec{q}\t%0";
5808 if (x86_maybe_negate_const_int (&operands[2], DImode))
5809 return "add{q}\t{%2, %0|%0, %2}";
5811 return "sub{q}\t{%2, %0|%0, %2}";
5815 (if_then_else (match_operand:DI 2 "incdec_operand")
5816 (const_string "incdec")
5817 (const_string "alu")))
5818 (set (attr "length_immediate")
5820 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5822 (const_string "*")))
5823 (set_attr "mode" "DI")])
5825 ; For comparisons against 1, -1 and 128, we may generate better code
5826 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
5827 ; is matched then. We can't accept general immediate, because for
5828 ; case of overflows, the result is messed up.
5829 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5830 ; only for comparisons not depending on it.
5832 (define_insn "*add<mode>_4"
5833 [(set (reg FLAGS_REG)
5835 (match_operand:SWI124 1 "nonimmediate_operand" "0")
5836 (match_operand:SWI124 2 "const_int_operand" "n")))
5837 (clobber (match_scratch:SWI124 0 "=<r>m"))]
5838 "ix86_match_ccmode (insn, CCGCmode)"
5840 switch (get_attr_type (insn))
5843 if (operands[2] == constm1_rtx)
5844 return "inc{<imodesuffix>}\t%0";
5847 gcc_assert (operands[2] == const1_rtx);
5848 return "dec{<imodesuffix>}\t%0";
5852 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5853 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5855 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5859 (if_then_else (match_operand:<MODE> 2 "incdec_operand")
5860 (const_string "incdec")
5861 (const_string "alu")))
5862 (set (attr "length_immediate")
5864 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5866 (const_string "*")))
5867 (set_attr "mode" "<MODE>")])
5869 (define_insn "*add<mode>_5"
5870 [(set (reg FLAGS_REG)
5873 (match_operand:SWI 1 "nonimmediate_operand" "%0,<r>")
5874 (match_operand:SWI 2 "<general_operand>" "<g>,0"))
5876 (clobber (match_scratch:SWI 0 "=<r>,<r>"))]
5877 "ix86_match_ccmode (insn, CCGOCmode)
5878 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
5880 switch (get_attr_type (insn))
5883 if (operands[2] == const1_rtx)
5884 return "inc{<imodesuffix>}\t%0";
5887 gcc_assert (operands[2] == constm1_rtx);
5888 return "dec{<imodesuffix>}\t%0";
5892 if (which_alternative == 1)
5893 std::swap (operands[1], operands[2]);
5895 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5896 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5897 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5899 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5903 (if_then_else (match_operand:SWI 2 "incdec_operand")
5904 (const_string "incdec")
5905 (const_string "alu")))
5906 (set (attr "length_immediate")
5908 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5910 (const_string "*")))
5911 (set_attr "mode" "<MODE>")])
5913 (define_insn "addqi_ext_1"
5914 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q,Q")
5920 (zero_extract:SI (match_operand 1 "ext_register_operand" "0,0")
5923 (match_operand:QI 2 "general_operand" "QnBc,m")) 0))
5924 (clobber (reg:CC FLAGS_REG))]
5925 "/* FIXME: without this LRA can't reload this pattern, see PR82524. */
5926 rtx_equal_p (operands[0], operands[1])"
5928 switch (get_attr_type (insn))
5931 if (operands[2] == const1_rtx)
5932 return "inc{b}\t%h0";
5935 gcc_assert (operands[2] == constm1_rtx);
5936 return "dec{b}\t%h0";
5940 return "add{b}\t{%2, %h0|%h0, %2}";
5943 [(set_attr "isa" "*,nox64")
5945 (if_then_else (match_operand:QI 2 "incdec_operand")
5946 (const_string "incdec")
5947 (const_string "alu")))
5948 (set_attr "mode" "QI")])
5950 (define_insn "*addqi_ext_2"
5951 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
5957 (zero_extract:SI (match_operand 1 "ext_register_operand" "%0")
5961 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
5963 (const_int 8)) 0)) 0))
5964 (clobber (reg:CC FLAGS_REG))]
5965 "/* FIXME: without this LRA can't reload this pattern, see PR82524. */
5966 rtx_equal_p (operands[0], operands[1])
5967 || rtx_equal_p (operands[0], operands[2])"
5968 "add{b}\t{%h2, %h0|%h0, %h2}"
5969 [(set_attr "type" "alu")
5970 (set_attr "mode" "QI")])
5972 ;; Add with jump on overflow.
5973 (define_expand "addv<mode>4"
5974 [(parallel [(set (reg:CCO FLAGS_REG)
5977 (match_operand:SWI 1 "nonimmediate_operand"))
5980 (plus:SWI (match_dup 1)
5981 (match_operand:SWI 2
5982 "<general_operand>")))))
5983 (set (match_operand:SWI 0 "register_operand")
5984 (plus:SWI (match_dup 1) (match_dup 2)))])
5985 (set (pc) (if_then_else
5986 (eq (reg:CCO FLAGS_REG) (const_int 0))
5987 (label_ref (match_operand 3))
5991 ix86_fixup_binary_operands_no_copy (PLUS, <MODE>mode, operands);
5992 if (CONST_INT_P (operands[2]))
5993 operands[4] = operands[2];
5995 operands[4] = gen_rtx_SIGN_EXTEND (<DWI>mode, operands[2]);
5998 (define_insn "*addv<mode>4"
5999 [(set (reg:CCO FLAGS_REG)
6002 (match_operand:SWI 1 "nonimmediate_operand" "%0,0"))
6004 (match_operand:SWI 2 "<general_sext_operand>"
6007 (plus:SWI (match_dup 1) (match_dup 2)))))
6008 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
6009 (plus:SWI (match_dup 1) (match_dup 2)))]
6010 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6011 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6012 [(set_attr "type" "alu")
6013 (set_attr "mode" "<MODE>")])
6015 (define_insn "*addv<mode>4_1"
6016 [(set (reg:CCO FLAGS_REG)
6019 (match_operand:SWI 1 "nonimmediate_operand" "0"))
6020 (match_operand:<DWI> 3 "const_int_operand" "i"))
6022 (plus:SWI (match_dup 1)
6023 (match_operand:SWI 2 "x86_64_immediate_operand"
6025 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
6026 (plus:SWI (match_dup 1) (match_dup 2)))]
6027 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)
6028 && CONST_INT_P (operands[2])
6029 && INTVAL (operands[2]) == INTVAL (operands[3])"
6030 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6031 [(set_attr "type" "alu")
6032 (set_attr "mode" "<MODE>")
6033 (set (attr "length_immediate")
6034 (cond [(match_test "IN_RANGE (INTVAL (operands[2]), -128, 127)")
6036 (match_test "<MODE_SIZE> == 8")
6038 (const_string "<MODE_SIZE>")))])
6040 (define_expand "uaddv<mode>4"
6041 [(parallel [(set (reg:CCC FLAGS_REG)
6044 (match_operand:SWI 1 "nonimmediate_operand")
6045 (match_operand:SWI 2 "<general_operand>"))
6047 (set (match_operand:SWI 0 "register_operand")
6048 (plus:SWI (match_dup 1) (match_dup 2)))])
6049 (set (pc) (if_then_else
6050 (ltu (reg:CCC FLAGS_REG) (const_int 0))
6051 (label_ref (match_operand 3))
6054 "ix86_fixup_binary_operands_no_copy (PLUS, <MODE>mode, operands);")
6056 ;; The lea patterns for modes less than 32 bits need to be matched by
6057 ;; several insns converted to real lea by splitters.
6059 (define_insn_and_split "*lea<mode>_general_1"
6060 [(set (match_operand:SWI12 0 "register_operand" "=r")
6062 (plus:SWI12 (match_operand:SWI12 1 "index_register_operand" "l")
6063 (match_operand:SWI12 2 "register_operand" "r"))
6064 (match_operand:SWI12 3 "immediate_operand" "i")))]
6065 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
6067 "&& reload_completed"
6070 (plus:SI (match_dup 1) (match_dup 2))
6073 operands[0] = gen_lowpart (SImode, operands[0]);
6074 operands[1] = gen_lowpart (SImode, operands[1]);
6075 operands[2] = gen_lowpart (SImode, operands[2]);
6076 operands[3] = gen_lowpart (SImode, operands[3]);
6078 [(set_attr "type" "lea")
6079 (set_attr "mode" "SI")])
6081 (define_insn_and_split "*lea<mode>_general_2"
6082 [(set (match_operand:SWI12 0 "register_operand" "=r")
6084 (mult:SWI12 (match_operand:SWI12 1 "index_register_operand" "l")
6085 (match_operand 2 "const248_operand" "n"))
6086 (match_operand:SWI12 3 "nonmemory_operand" "ri")))]
6087 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
6089 "&& reload_completed"
6092 (mult:SI (match_dup 1) (match_dup 2))
6095 operands[0] = gen_lowpart (SImode, operands[0]);
6096 operands[1] = gen_lowpart (SImode, operands[1]);
6097 operands[3] = gen_lowpart (SImode, operands[3]);
6099 [(set_attr "type" "lea")
6100 (set_attr "mode" "SI")])
6102 (define_insn_and_split "*lea<mode>_general_2b"
6103 [(set (match_operand:SWI12 0 "register_operand" "=r")
6105 (ashift:SWI12 (match_operand:SWI12 1 "index_register_operand" "l")
6106 (match_operand 2 "const123_operand" "n"))
6107 (match_operand:SWI12 3 "nonmemory_operand" "ri")))]
6108 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
6110 "&& reload_completed"
6113 (ashift:SI (match_dup 1) (match_dup 2))
6116 operands[0] = gen_lowpart (SImode, operands[0]);
6117 operands[1] = gen_lowpart (SImode, operands[1]);
6118 operands[3] = gen_lowpart (SImode, operands[3]);
6120 [(set_attr "type" "lea")
6121 (set_attr "mode" "SI")])
6123 (define_insn_and_split "*lea<mode>_general_3"
6124 [(set (match_operand:SWI12 0 "register_operand" "=r")
6127 (mult:SWI12 (match_operand:SWI12 1 "index_register_operand" "l")
6128 (match_operand 2 "const248_operand" "n"))
6129 (match_operand:SWI12 3 "register_operand" "r"))
6130 (match_operand:SWI12 4 "immediate_operand" "i")))]
6131 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
6133 "&& reload_completed"
6137 (mult:SI (match_dup 1) (match_dup 2))
6141 operands[0] = gen_lowpart (SImode, operands[0]);
6142 operands[1] = gen_lowpart (SImode, operands[1]);
6143 operands[3] = gen_lowpart (SImode, operands[3]);
6144 operands[4] = gen_lowpart (SImode, operands[4]);
6146 [(set_attr "type" "lea")
6147 (set_attr "mode" "SI")])
6149 (define_insn_and_split "*lea<mode>_general_3b"
6150 [(set (match_operand:SWI12 0 "register_operand" "=r")
6153 (ashift:SWI12 (match_operand:SWI12 1 "index_register_operand" "l")
6154 (match_operand 2 "const123_operand" "n"))
6155 (match_operand:SWI12 3 "register_operand" "r"))
6156 (match_operand:SWI12 4 "immediate_operand" "i")))]
6157 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
6159 "&& reload_completed"
6163 (ashift:SI (match_dup 1) (match_dup 2))
6167 operands[0] = gen_lowpart (SImode, operands[0]);
6168 operands[1] = gen_lowpart (SImode, operands[1]);
6169 operands[3] = gen_lowpart (SImode, operands[3]);
6170 operands[4] = gen_lowpart (SImode, operands[4]);
6172 [(set_attr "type" "lea")
6173 (set_attr "mode" "SI")])
6175 (define_insn_and_split "*lea<mode>_general_4"
6176 [(set (match_operand:SWI12 0 "register_operand" "=r")
6179 (match_operand:SWI12 1 "index_register_operand" "l")
6180 (match_operand 2 "const_0_to_3_operand" "n"))
6181 (match_operand 3 "const_int_operand" "n")))]
6182 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6183 && ((unsigned HOST_WIDE_INT) INTVAL (operands[3])
6184 < (HOST_WIDE_INT_1U << INTVAL (operands[2])))"
6186 "&& reload_completed"
6189 (mult:SI (match_dup 1) (match_dup 2))
6192 operands[0] = gen_lowpart (SImode, operands[0]);
6193 operands[1] = gen_lowpart (SImode, operands[1]);
6194 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
6196 [(set_attr "type" "lea")
6197 (set_attr "mode" "SI")])
6199 (define_insn_and_split "*lea<mode>_general_4"
6200 [(set (match_operand:SWI48 0 "register_operand" "=r")
6203 (match_operand:SWI48 1 "index_register_operand" "l")
6204 (match_operand 2 "const_0_to_3_operand" "n"))
6205 (match_operand 3 "const_int_operand" "n")))]
6206 "(unsigned HOST_WIDE_INT) INTVAL (operands[3])
6207 < (HOST_WIDE_INT_1U << INTVAL (operands[2]))"
6209 "&& reload_completed"
6212 (mult:SWI48 (match_dup 1) (match_dup 2))
6214 "operands[2] = GEN_INT (1 << INTVAL (operands[2]));"
6215 [(set_attr "type" "lea")
6216 (set_attr "mode" "<MODE>")])
6218 ;; Subtract instructions
6220 (define_expand "sub<mode>3"
6221 [(set (match_operand:SDWIM 0 "nonimmediate_operand")
6222 (minus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")
6223 (match_operand:SDWIM 2 "<general_hilo_operand>")))]
6225 "ix86_expand_binary_operator (MINUS, <MODE>mode, operands); DONE;")
6227 (define_insn_and_split "*sub<dwi>3_doubleword"
6228 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
6230 (match_operand:<DWI> 1 "nonimmediate_operand" "0,0")
6231 (match_operand:<DWI> 2 "x86_64_hilo_general_operand"
6233 (clobber (reg:CC FLAGS_REG))]
6234 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6237 [(parallel [(set (reg:CC FLAGS_REG)
6238 (compare:CC (match_dup 1) (match_dup 2)))
6240 (minus:DWIH (match_dup 1) (match_dup 2)))])
6241 (parallel [(set (match_dup 3)
6245 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0)))
6247 (clobber (reg:CC FLAGS_REG))])]
6249 split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
6250 if (operands[2] == const0_rtx)
6252 ix86_expand_binary_operator (MINUS, <MODE>mode, &operands[3]);
6257 (define_insn "*sub<mode>_1"
6258 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6260 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6261 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6262 (clobber (reg:CC FLAGS_REG))]
6263 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6264 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6265 [(set_attr "type" "alu")
6266 (set_attr "mode" "<MODE>")])
6268 (define_insn "*subsi_1_zext"
6269 [(set (match_operand:DI 0 "register_operand" "=r")
6271 (minus:SI (match_operand:SI 1 "register_operand" "0")
6272 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
6273 (clobber (reg:CC FLAGS_REG))]
6274 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6275 "sub{l}\t{%2, %k0|%k0, %2}"
6276 [(set_attr "type" "alu")
6277 (set_attr "mode" "SI")])
6279 (define_insn "*subqi_1_slp"
6280 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6281 (minus:QI (match_dup 0)
6282 (match_operand:QI 1 "general_operand" "qn,qm")))
6283 (clobber (reg:CC FLAGS_REG))]
6284 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6285 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
6286 "sub{b}\t{%1, %0|%0, %1}"
6287 [(set_attr "type" "alu1")
6288 (set_attr "mode" "QI")])
6290 (define_insn "*sub<mode>_2"
6291 [(set (reg FLAGS_REG)
6294 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6295 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6297 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6298 (minus:SWI (match_dup 1) (match_dup 2)))]
6299 "ix86_match_ccmode (insn, CCGOCmode)
6300 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6301 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6302 [(set_attr "type" "alu")
6303 (set_attr "mode" "<MODE>")])
6305 (define_insn "*subsi_2_zext"
6306 [(set (reg FLAGS_REG)
6308 (minus:SI (match_operand:SI 1 "register_operand" "0")
6309 (match_operand:SI 2 "x86_64_general_operand" "rme"))
6311 (set (match_operand:DI 0 "register_operand" "=r")
6313 (minus:SI (match_dup 1)
6315 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6316 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6317 "sub{l}\t{%2, %k0|%k0, %2}"
6318 [(set_attr "type" "alu")
6319 (set_attr "mode" "SI")])
6321 ;; Subtract with jump on overflow.
6322 (define_expand "subv<mode>4"
6323 [(parallel [(set (reg:CCO FLAGS_REG)
6324 (eq:CCO (minus:<DWI>
6326 (match_operand:SWI 1 "nonimmediate_operand"))
6329 (minus:SWI (match_dup 1)
6330 (match_operand:SWI 2
6331 "<general_operand>")))))
6332 (set (match_operand:SWI 0 "register_operand")
6333 (minus:SWI (match_dup 1) (match_dup 2)))])
6334 (set (pc) (if_then_else
6335 (eq (reg:CCO FLAGS_REG) (const_int 0))
6336 (label_ref (match_operand 3))
6340 ix86_fixup_binary_operands_no_copy (MINUS, <MODE>mode, operands);
6341 if (CONST_INT_P (operands[2]))
6342 operands[4] = operands[2];
6344 operands[4] = gen_rtx_SIGN_EXTEND (<DWI>mode, operands[2]);
6347 (define_insn "*subv<mode>4"
6348 [(set (reg:CCO FLAGS_REG)
6349 (eq:CCO (minus:<DWI>
6351 (match_operand:SWI 1 "nonimmediate_operand" "0,0"))
6353 (match_operand:SWI 2 "<general_sext_operand>"
6356 (minus:SWI (match_dup 1) (match_dup 2)))))
6357 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6358 (minus:SWI (match_dup 1) (match_dup 2)))]
6359 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6360 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6361 [(set_attr "type" "alu")
6362 (set_attr "mode" "<MODE>")])
6364 (define_insn "*subv<mode>4_1"
6365 [(set (reg:CCO FLAGS_REG)
6366 (eq:CCO (minus:<DWI>
6368 (match_operand:SWI 1 "nonimmediate_operand" "0"))
6369 (match_operand:<DWI> 3 "const_int_operand" "i"))
6371 (minus:SWI (match_dup 1)
6372 (match_operand:SWI 2 "x86_64_immediate_operand"
6374 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
6375 (minus:SWI (match_dup 1) (match_dup 2)))]
6376 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)
6377 && CONST_INT_P (operands[2])
6378 && INTVAL (operands[2]) == INTVAL (operands[3])"
6379 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6380 [(set_attr "type" "alu")
6381 (set_attr "mode" "<MODE>")
6382 (set (attr "length_immediate")
6383 (cond [(match_test "IN_RANGE (INTVAL (operands[2]), -128, 127)")
6385 (match_test "<MODE_SIZE> == 8")
6387 (const_string "<MODE_SIZE>")))])
6389 (define_expand "usubv<mode>4"
6390 [(parallel [(set (reg:CC FLAGS_REG)
6392 (match_operand:SWI 1 "nonimmediate_operand")
6393 (match_operand:SWI 2 "<general_operand>")))
6394 (set (match_operand:SWI 0 "register_operand")
6395 (minus:SWI (match_dup 1) (match_dup 2)))])
6396 (set (pc) (if_then_else
6397 (ltu (reg:CC FLAGS_REG) (const_int 0))
6398 (label_ref (match_operand 3))
6401 "ix86_fixup_binary_operands_no_copy (MINUS, <MODE>mode, operands);")
6403 (define_insn "*sub<mode>_3"
6404 [(set (reg FLAGS_REG)
6405 (compare (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6406 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6407 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6408 (minus:SWI (match_dup 1) (match_dup 2)))]
6409 "ix86_match_ccmode (insn, CCmode)
6410 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6411 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6412 [(set_attr "type" "alu")
6413 (set_attr "mode" "<MODE>")])
6417 [(set (reg:CC FLAGS_REG)
6418 (compare:CC (match_operand:SWI 0 "general_reg_operand")
6419 (match_operand:SWI 1 "general_gr_operand")))
6421 (minus:SWI (match_dup 0) (match_dup 1)))])]
6422 "find_regno_note (peep2_next_insn (0), REG_UNUSED, REGNO (operands[0])) != 0"
6423 [(set (reg:CC FLAGS_REG)
6424 (compare:CC (match_dup 0) (match_dup 1)))])
6426 (define_insn "*subsi_3_zext"
6427 [(set (reg FLAGS_REG)
6428 (compare (match_operand:SI 1 "register_operand" "0")
6429 (match_operand:SI 2 "x86_64_general_operand" "rme")))
6430 (set (match_operand:DI 0 "register_operand" "=r")
6432 (minus:SI (match_dup 1)
6434 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6435 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6436 "sub{l}\t{%2, %1|%1, %2}"
6437 [(set_attr "type" "alu")
6438 (set_attr "mode" "SI")])
6440 ;; Add with carry and subtract with borrow
6442 (define_insn "add<mode>3_carry"
6443 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6446 (match_operator:SWI 4 "ix86_carry_flag_operator"
6447 [(match_operand 3 "flags_reg_operand") (const_int 0)])
6448 (match_operand:SWI 1 "nonimmediate_operand" "%0,0"))
6449 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6450 (clobber (reg:CC FLAGS_REG))]
6451 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6452 "adc{<imodesuffix>}\t{%2, %0|%0, %2}"
6453 [(set_attr "type" "alu")
6454 (set_attr "use_carry" "1")
6455 (set_attr "pent_pair" "pu")
6456 (set_attr "mode" "<MODE>")])
6458 (define_insn "*add<mode>3_carry_0"
6459 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
6461 (match_operator:SWI 3 "ix86_carry_flag_operator"
6462 [(match_operand 2 "flags_reg_operand") (const_int 0)])
6463 (match_operand:SWI 1 "nonimmediate_operand" "0")))
6464 (clobber (reg:CC FLAGS_REG))]
6465 "ix86_unary_operator_ok (PLUS, <MODE>mode, operands)"
6466 "adc{<imodesuffix>}\t{$0, %0|%0, 0}"
6467 [(set_attr "type" "alu")
6468 (set_attr "use_carry" "1")
6469 (set_attr "pent_pair" "pu")
6470 (set_attr "mode" "<MODE>")])
6472 (define_insn "*addsi3_carry_zext"
6473 [(set (match_operand:DI 0 "register_operand" "=r")
6476 (plus:SI (match_operator:SI 3 "ix86_carry_flag_operator"
6477 [(reg FLAGS_REG) (const_int 0)])
6478 (match_operand:SI 1 "register_operand" "%0"))
6479 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
6480 (clobber (reg:CC FLAGS_REG))]
6481 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6482 "adc{l}\t{%2, %k0|%k0, %2}"
6483 [(set_attr "type" "alu")
6484 (set_attr "use_carry" "1")
6485 (set_attr "pent_pair" "pu")
6486 (set_attr "mode" "SI")])
6488 (define_insn "*addsi3_carry_zext_0"
6489 [(set (match_operand:DI 0 "register_operand" "=r")
6491 (plus:SI (match_operator:SI 2 "ix86_carry_flag_operator"
6492 [(reg FLAGS_REG) (const_int 0)])
6493 (match_operand:SI 1 "register_operand" "0"))))
6494 (clobber (reg:CC FLAGS_REG))]
6496 "adc{l}\t{$0, %k0|%k0, 0}"
6497 [(set_attr "type" "alu")
6498 (set_attr "use_carry" "1")
6499 (set_attr "pent_pair" "pu")
6500 (set_attr "mode" "SI")])
6502 ;; There is no point to generate ADCX instruction. ADC is shorter and faster.
6504 (define_insn "addcarry<mode>"
6505 [(set (reg:CCC FLAGS_REG)
6510 (match_operator:SWI48 5 "ix86_carry_flag_operator"
6511 [(match_operand 3 "flags_reg_operand") (const_int 0)])
6512 (match_operand:SWI48 1 "nonimmediate_operand" "%0"))
6513 (match_operand:SWI48 2 "nonimmediate_operand" "rm")))
6515 (zero_extend:<DWI> (match_dup 2))
6516 (match_operator:<DWI> 4 "ix86_carry_flag_operator"
6517 [(match_dup 3) (const_int 0)]))))
6518 (set (match_operand:SWI48 0 "register_operand" "=r")
6519 (plus:SWI48 (plus:SWI48 (match_op_dup 5
6520 [(match_dup 3) (const_int 0)])
6523 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6524 "adc{<imodesuffix>}\t{%2, %0|%0, %2}"
6525 [(set_attr "type" "alu")
6526 (set_attr "use_carry" "1")
6527 (set_attr "pent_pair" "pu")
6528 (set_attr "mode" "<MODE>")])
6530 (define_expand "addcarry<mode>_0"
6532 [(set (reg:CCC FLAGS_REG)
6535 (match_operand:SWI48 1 "nonimmediate_operand")
6536 (match_operand:SWI48 2 "x86_64_general_operand"))
6538 (set (match_operand:SWI48 0 "register_operand")
6539 (plus:SWI48 (match_dup 1) (match_dup 2)))])]
6540 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)")
6542 (define_insn "sub<mode>3_carry"
6543 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6546 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6547 (match_operator:SWI 4 "ix86_carry_flag_operator"
6548 [(match_operand 3 "flags_reg_operand") (const_int 0)]))
6549 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6550 (clobber (reg:CC FLAGS_REG))]
6551 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6552 "sbb{<imodesuffix>}\t{%2, %0|%0, %2}"
6553 [(set_attr "type" "alu")
6554 (set_attr "use_carry" "1")
6555 (set_attr "pent_pair" "pu")
6556 (set_attr "mode" "<MODE>")])
6558 (define_insn "*sub<mode>3_carry_0"
6559 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
6561 (match_operand:SWI 1 "nonimmediate_operand" "0")
6562 (match_operator:SWI 3 "ix86_carry_flag_operator"
6563 [(match_operand 2 "flags_reg_operand") (const_int 0)])))
6564 (clobber (reg:CC FLAGS_REG))]
6565 "ix86_unary_operator_ok (MINUS, <MODE>mode, operands)"
6566 "sbb{<imodesuffix>}\t{$0, %0|%0, 0}"
6567 [(set_attr "type" "alu")
6568 (set_attr "use_carry" "1")
6569 (set_attr "pent_pair" "pu")
6570 (set_attr "mode" "<MODE>")])
6572 (define_insn "*subsi3_carry_zext"
6573 [(set (match_operand:DI 0 "register_operand" "=r")
6577 (match_operand:SI 1 "register_operand" "0")
6578 (match_operator:SI 3 "ix86_carry_flag_operator"
6579 [(reg FLAGS_REG) (const_int 0)]))
6580 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
6581 (clobber (reg:CC FLAGS_REG))]
6582 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6583 "sbb{l}\t{%2, %k0|%k0, %2}"
6584 [(set_attr "type" "alu")
6585 (set_attr "use_carry" "1")
6586 (set_attr "pent_pair" "pu")
6587 (set_attr "mode" "SI")])
6589 (define_insn "*subsi3_carry_zext_0"
6590 [(set (match_operand:DI 0 "register_operand" "=r")
6593 (match_operand:SI 1 "register_operand" "0")
6594 (match_operator:SI 2 "ix86_carry_flag_operator"
6595 [(reg FLAGS_REG) (const_int 0)]))))
6596 (clobber (reg:CC FLAGS_REG))]
6598 "sbb{l}\t{$0, %k0|%k0, 0}"
6599 [(set_attr "type" "alu")
6600 (set_attr "use_carry" "1")
6601 (set_attr "pent_pair" "pu")
6602 (set_attr "mode" "SI")])
6604 (define_insn "sub<mode>3_carry_ccc"
6605 [(set (reg:CCC FLAGS_REG)
6607 (zero_extend:<DWI> (match_operand:DWIH 1 "register_operand" "0"))
6609 (ltu:<DWI> (reg:CC FLAGS_REG) (const_int 0))
6611 (match_operand:DWIH 2 "x86_64_sext_operand" "rmWe")))))
6612 (clobber (match_scratch:DWIH 0 "=r"))]
6614 "sbb{<imodesuffix>}\t{%2, %0|%0, %2}"
6615 [(set_attr "type" "alu")
6616 (set_attr "mode" "<MODE>")])
6618 (define_insn "*sub<mode>3_carry_ccc_1"
6619 [(set (reg:CCC FLAGS_REG)
6621 (zero_extend:<DWI> (match_operand:DWIH 1 "register_operand" "0"))
6623 (ltu:<DWI> (reg:CC FLAGS_REG) (const_int 0))
6624 (match_operand:<DWI> 2 "x86_64_dwzext_immediate_operand" "Wf"))))
6625 (clobber (match_scratch:DWIH 0 "=r"))]
6628 operands[3] = simplify_subreg (<MODE>mode, operands[2], <DWI>mode, 0);
6629 return "sbb{<imodesuffix>}\t{%3, %0|%0, %3}";
6631 [(set_attr "type" "alu")
6632 (set_attr "mode" "<MODE>")])
6634 ;; The sign flag is set from the
6635 ;; (compare (match_dup 1) (plus:DWIH (ltu:DWIH ...) (match_dup 2)))
6636 ;; result, the overflow flag likewise, but the overflow flag is also
6637 ;; set if the (plus:DWIH (ltu:DWIH ...) (match_dup 2)) overflows.
6638 (define_insn "sub<mode>3_carry_ccgz"
6639 [(set (reg:CCGZ FLAGS_REG)
6640 (unspec:CCGZ [(match_operand:DWIH 1 "register_operand" "0")
6641 (match_operand:DWIH 2 "x86_64_general_operand" "rme")
6642 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))]
6644 (clobber (match_scratch:DWIH 0 "=r"))]
6646 "sbb{<imodesuffix>}\t{%2, %0|%0, %2}"
6647 [(set_attr "type" "alu")
6648 (set_attr "mode" "<MODE>")])
6650 (define_insn "subborrow<mode>"
6651 [(set (reg:CCC FLAGS_REG)
6654 (match_operand:SWI48 1 "nonimmediate_operand" "0"))
6656 (match_operator:<DWI> 4 "ix86_carry_flag_operator"
6657 [(match_operand 3 "flags_reg_operand") (const_int 0)])
6659 (match_operand:SWI48 2 "nonimmediate_operand" "rm")))))
6660 (set (match_operand:SWI48 0 "register_operand" "=r")
6661 (minus:SWI48 (minus:SWI48
6663 (match_operator:SWI48 5 "ix86_carry_flag_operator"
6664 [(match_dup 3) (const_int 0)]))
6666 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6667 "sbb{<imodesuffix>}\t{%2, %0|%0, %2}"
6668 [(set_attr "type" "alu")
6669 (set_attr "use_carry" "1")
6670 (set_attr "pent_pair" "pu")
6671 (set_attr "mode" "<MODE>")])
6673 (define_expand "subborrow<mode>_0"
6675 [(set (reg:CC FLAGS_REG)
6677 (match_operand:SWI48 1 "nonimmediate_operand")
6678 (match_operand:SWI48 2 "<general_operand>")))
6679 (set (match_operand:SWI48 0 "register_operand")
6680 (minus:SWI48 (match_dup 1) (match_dup 2)))])]
6681 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)")
6683 ;; Overflow setting add instructions
6685 (define_expand "addqi3_cconly_overflow"
6687 [(set (reg:CCC FLAGS_REG)
6690 (match_operand:QI 0 "nonimmediate_operand")
6691 (match_operand:QI 1 "general_operand"))
6693 (clobber (match_scratch:QI 2))])]
6694 "!(MEM_P (operands[0]) && MEM_P (operands[1]))")
6696 (define_insn "*add<mode>3_cconly_overflow_1"
6697 [(set (reg:CCC FLAGS_REG)
6700 (match_operand:SWI 1 "nonimmediate_operand" "%0")
6701 (match_operand:SWI 2 "<general_operand>" "<g>"))
6703 (clobber (match_scratch:SWI 0 "=<r>"))]
6704 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6705 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6706 [(set_attr "type" "alu")
6707 (set_attr "mode" "<MODE>")])
6709 (define_insn "*add<mode>3_cc_overflow_1"
6710 [(set (reg:CCC FLAGS_REG)
6713 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
6714 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6716 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6717 (plus:SWI (match_dup 1) (match_dup 2)))]
6718 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6719 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6720 [(set_attr "type" "alu")
6721 (set_attr "mode" "<MODE>")])
6723 (define_insn "*addsi3_zext_cc_overflow_1"
6724 [(set (reg:CCC FLAGS_REG)
6727 (match_operand:SI 1 "nonimmediate_operand" "%0")
6728 (match_operand:SI 2 "x86_64_general_operand" "rme"))
6730 (set (match_operand:DI 0 "register_operand" "=r")
6731 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6732 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6733 "add{l}\t{%2, %k0|%k0, %2}"
6734 [(set_attr "type" "alu")
6735 (set_attr "mode" "SI")])
6737 (define_insn "*add<mode>3_cconly_overflow_2"
6738 [(set (reg:CCC FLAGS_REG)
6741 (match_operand:SWI 1 "nonimmediate_operand" "%0")
6742 (match_operand:SWI 2 "<general_operand>" "<g>"))
6744 (clobber (match_scratch:SWI 0 "=<r>"))]
6745 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6746 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6747 [(set_attr "type" "alu")
6748 (set_attr "mode" "<MODE>")])
6750 (define_insn "*add<mode>3_cc_overflow_2"
6751 [(set (reg:CCC FLAGS_REG)
6754 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
6755 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6757 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6758 (plus:SWI (match_dup 1) (match_dup 2)))]
6759 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6760 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6761 [(set_attr "type" "alu")
6762 (set_attr "mode" "<MODE>")])
6764 (define_insn "*addsi3_zext_cc_overflow_2"
6765 [(set (reg:CCC FLAGS_REG)
6768 (match_operand:SI 1 "nonimmediate_operand" "%0")
6769 (match_operand:SI 2 "x86_64_general_operand" "rme"))
6771 (set (match_operand:DI 0 "register_operand" "=r")
6772 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6773 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6774 "add{l}\t{%2, %k0|%k0, %2}"
6775 [(set_attr "type" "alu")
6776 (set_attr "mode" "SI")])
6778 ;; The patterns that match these are at the end of this file.
6780 (define_expand "<plusminus_insn>xf3"
6781 [(set (match_operand:XF 0 "register_operand")
6783 (match_operand:XF 1 "register_operand")
6784 (match_operand:XF 2 "register_operand")))]
6787 (define_expand "<plusminus_insn><mode>3"
6788 [(set (match_operand:MODEF 0 "register_operand")
6790 (match_operand:MODEF 1 "register_operand")
6791 (match_operand:MODEF 2 "nonimmediate_operand")))]
6792 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
6793 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
6795 ;; Multiply instructions
6797 (define_expand "mul<mode>3"
6798 [(parallel [(set (match_operand:SWIM248 0 "register_operand")
6800 (match_operand:SWIM248 1 "register_operand")
6801 (match_operand:SWIM248 2 "<general_operand>")))
6802 (clobber (reg:CC FLAGS_REG))])])
6804 (define_expand "mulqi3"
6805 [(parallel [(set (match_operand:QI 0 "register_operand")
6807 (match_operand:QI 1 "register_operand")
6808 (match_operand:QI 2 "nonimmediate_operand")))
6809 (clobber (reg:CC FLAGS_REG))])]
6810 "TARGET_QIMODE_MATH")
6813 ;; IMUL reg32/64, reg32/64, imm8 Direct
6814 ;; IMUL reg32/64, mem32/64, imm8 VectorPath
6815 ;; IMUL reg32/64, reg32/64, imm32 Direct
6816 ;; IMUL reg32/64, mem32/64, imm32 VectorPath
6817 ;; IMUL reg32/64, reg32/64 Direct
6818 ;; IMUL reg32/64, mem32/64 Direct
6820 ;; On BDVER1, all above IMULs use DirectPath
6823 ;; IMUL reg16, reg16, imm8 VectorPath
6824 ;; IMUL reg16, mem16, imm8 VectorPath
6825 ;; IMUL reg16, reg16, imm16 VectorPath
6826 ;; IMUL reg16, mem16, imm16 VectorPath
6827 ;; IMUL reg16, reg16 Direct
6828 ;; IMUL reg16, mem16 Direct
6830 ;; On BDVER1, all HI MULs use DoublePath
6832 (define_insn "*mul<mode>3_1"
6833 [(set (match_operand:SWIM248 0 "register_operand" "=r,r,r")
6835 (match_operand:SWIM248 1 "nonimmediate_operand" "%rm,rm,0")
6836 (match_operand:SWIM248 2 "<general_operand>" "K,<i>,mr")))
6837 (clobber (reg:CC FLAGS_REG))]
6838 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6840 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6841 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6842 imul{<imodesuffix>}\t{%2, %0|%0, %2}"
6843 [(set_attr "type" "imul")
6844 (set_attr "prefix_0f" "0,0,1")
6845 (set (attr "athlon_decode")
6846 (cond [(eq_attr "cpu" "athlon")
6847 (const_string "vector")
6848 (eq_attr "alternative" "1")
6849 (const_string "vector")
6850 (and (eq_attr "alternative" "2")
6851 (ior (match_test "<MODE>mode == HImode")
6852 (match_operand 1 "memory_operand")))
6853 (const_string "vector")]
6854 (const_string "direct")))
6855 (set (attr "amdfam10_decode")
6856 (cond [(and (eq_attr "alternative" "0,1")
6857 (ior (match_test "<MODE>mode == HImode")
6858 (match_operand 1 "memory_operand")))
6859 (const_string "vector")]
6860 (const_string "direct")))
6861 (set (attr "bdver1_decode")
6863 (match_test "<MODE>mode == HImode")
6864 (const_string "double")
6865 (const_string "direct")))
6866 (set_attr "mode" "<MODE>")])
6868 (define_insn "*mulsi3_1_zext"
6869 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6871 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6872 (match_operand:SI 2 "x86_64_general_operand" "K,e,mr"))))
6873 (clobber (reg:CC FLAGS_REG))]
6875 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6877 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6878 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6879 imul{l}\t{%2, %k0|%k0, %2}"
6880 [(set_attr "type" "imul")
6881 (set_attr "prefix_0f" "0,0,1")
6882 (set (attr "athlon_decode")
6883 (cond [(eq_attr "cpu" "athlon")
6884 (const_string "vector")
6885 (eq_attr "alternative" "1")
6886 (const_string "vector")
6887 (and (eq_attr "alternative" "2")
6888 (match_operand 1 "memory_operand"))
6889 (const_string "vector")]
6890 (const_string "direct")))
6891 (set (attr "amdfam10_decode")
6892 (cond [(and (eq_attr "alternative" "0,1")
6893 (match_operand 1 "memory_operand"))
6894 (const_string "vector")]
6895 (const_string "direct")))
6896 (set_attr "bdver1_decode" "direct")
6897 (set_attr "mode" "SI")])
6899 ;;On AMDFAM10 and BDVER1
6903 (define_insn "*mulqi3_1"
6904 [(set (match_operand:QI 0 "register_operand" "=a")
6905 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6906 (match_operand:QI 2 "nonimmediate_operand" "qm")))
6907 (clobber (reg:CC FLAGS_REG))]
6909 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6911 [(set_attr "type" "imul")
6912 (set_attr "length_immediate" "0")
6913 (set (attr "athlon_decode")
6914 (if_then_else (eq_attr "cpu" "athlon")
6915 (const_string "vector")
6916 (const_string "direct")))
6917 (set_attr "amdfam10_decode" "direct")
6918 (set_attr "bdver1_decode" "direct")
6919 (set_attr "mode" "QI")])
6921 ;; Multiply with jump on overflow.
6922 (define_expand "mulv<mode>4"
6923 [(parallel [(set (reg:CCO FLAGS_REG)
6926 (match_operand:SWI248 1 "register_operand"))
6929 (mult:SWI248 (match_dup 1)
6930 (match_operand:SWI248 2
6931 "<general_operand>")))))
6932 (set (match_operand:SWI248 0 "register_operand")
6933 (mult:SWI248 (match_dup 1) (match_dup 2)))])
6934 (set (pc) (if_then_else
6935 (eq (reg:CCO FLAGS_REG) (const_int 0))
6936 (label_ref (match_operand 3))
6940 if (CONST_INT_P (operands[2]))
6941 operands[4] = operands[2];
6943 operands[4] = gen_rtx_SIGN_EXTEND (<DWI>mode, operands[2]);
6946 (define_insn "*mulv<mode>4"
6947 [(set (reg:CCO FLAGS_REG)
6950 (match_operand:SWI48 1 "nonimmediate_operand" "%rm,0"))
6952 (match_operand:SWI48 2 "x86_64_sext_operand" "We,mr")))
6954 (mult:SWI48 (match_dup 1) (match_dup 2)))))
6955 (set (match_operand:SWI48 0 "register_operand" "=r,r")
6956 (mult:SWI48 (match_dup 1) (match_dup 2)))]
6957 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6959 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6960 imul{<imodesuffix>}\t{%2, %0|%0, %2}"
6961 [(set_attr "type" "imul")
6962 (set_attr "prefix_0f" "0,1")
6963 (set (attr "athlon_decode")
6964 (cond [(eq_attr "cpu" "athlon")
6965 (const_string "vector")
6966 (eq_attr "alternative" "0")
6967 (const_string "vector")
6968 (and (eq_attr "alternative" "1")
6969 (match_operand 1 "memory_operand"))
6970 (const_string "vector")]
6971 (const_string "direct")))
6972 (set (attr "amdfam10_decode")
6973 (cond [(and (eq_attr "alternative" "1")
6974 (match_operand 1 "memory_operand"))
6975 (const_string "vector")]
6976 (const_string "direct")))
6977 (set_attr "bdver1_decode" "direct")
6978 (set_attr "mode" "<MODE>")])
6980 (define_insn "*mulvhi4"
6981 [(set (reg:CCO FLAGS_REG)
6984 (match_operand:HI 1 "nonimmediate_operand" "%0"))
6986 (match_operand:HI 2 "nonimmediate_operand" "mr")))
6988 (mult:HI (match_dup 1) (match_dup 2)))))
6989 (set (match_operand:HI 0 "register_operand" "=r")
6990 (mult:HI (match_dup 1) (match_dup 2)))]
6991 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6992 "imul{w}\t{%2, %0|%0, %2}"
6993 [(set_attr "type" "imul")
6994 (set_attr "prefix_0f" "1")
6995 (set_attr "athlon_decode" "vector")
6996 (set_attr "amdfam10_decode" "direct")
6997 (set_attr "bdver1_decode" "double")
6998 (set_attr "mode" "HI")])
7000 (define_insn "*mulv<mode>4_1"
7001 [(set (reg:CCO FLAGS_REG)
7004 (match_operand:SWI248 1 "nonimmediate_operand" "rm,rm"))
7005 (match_operand:<DWI> 3 "const_int_operand" "K,i"))
7007 (mult:SWI248 (match_dup 1)
7008 (match_operand:SWI248 2
7009 "<immediate_operand>" "K,<i>")))))
7010 (set (match_operand:SWI248 0 "register_operand" "=r,r")
7011 (mult:SWI248 (match_dup 1) (match_dup 2)))]
7012 "!(MEM_P (operands[1]) && MEM_P (operands[2]))
7013 && CONST_INT_P (operands[2])
7014 && INTVAL (operands[2]) == INTVAL (operands[3])"
7015 "imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}"
7016 [(set_attr "type" "imul")
7017 (set (attr "prefix_0f")
7019 (match_test "<MODE>mode == HImode")
7021 (const_string "*")))
7022 (set (attr "athlon_decode")
7023 (cond [(eq_attr "cpu" "athlon")
7024 (const_string "vector")
7025 (eq_attr "alternative" "1")
7026 (const_string "vector")]
7027 (const_string "direct")))
7028 (set (attr "amdfam10_decode")
7029 (cond [(ior (match_test "<MODE>mode == HImode")
7030 (match_operand 1 "memory_operand"))
7031 (const_string "vector")]
7032 (const_string "direct")))
7033 (set (attr "bdver1_decode")
7035 (match_test "<MODE>mode == HImode")
7036 (const_string "double")
7037 (const_string "direct")))
7038 (set_attr "mode" "<MODE>")
7039 (set (attr "length_immediate")
7040 (cond [(eq_attr "alternative" "0")
7042 (match_test "<MODE_SIZE> == 8")
7044 (const_string "<MODE_SIZE>")))])
7046 (define_expand "umulv<mode>4"
7047 [(parallel [(set (reg:CCO FLAGS_REG)
7050 (match_operand:SWI248 1
7051 "nonimmediate_operand"))
7053 (match_operand:SWI248 2
7054 "nonimmediate_operand")))
7056 (mult:SWI248 (match_dup 1) (match_dup 2)))))
7057 (set (match_operand:SWI248 0 "register_operand")
7058 (mult:SWI248 (match_dup 1) (match_dup 2)))
7059 (clobber (match_scratch:SWI248 4))])
7060 (set (pc) (if_then_else
7061 (eq (reg:CCO FLAGS_REG) (const_int 0))
7062 (label_ref (match_operand 3))
7066 if (MEM_P (operands[1]) && MEM_P (operands[2]))
7067 operands[1] = force_reg (<MODE>mode, operands[1]);
7070 (define_insn "*umulv<mode>4"
7071 [(set (reg:CCO FLAGS_REG)
7074 (match_operand:SWI248 1 "nonimmediate_operand" "%0"))
7076 (match_operand:SWI248 2 "nonimmediate_operand" "rm")))
7078 (mult:SWI248 (match_dup 1) (match_dup 2)))))
7079 (set (match_operand:SWI248 0 "register_operand" "=a")
7080 (mult:SWI248 (match_dup 1) (match_dup 2)))
7081 (clobber (match_scratch:SWI248 3 "=d"))]
7082 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7083 "mul{<imodesuffix>}\t%2"
7084 [(set_attr "type" "imul")
7085 (set_attr "length_immediate" "0")
7086 (set (attr "athlon_decode")
7087 (if_then_else (eq_attr "cpu" "athlon")
7088 (const_string "vector")
7089 (const_string "double")))
7090 (set_attr "amdfam10_decode" "double")
7091 (set_attr "bdver1_decode" "direct")
7092 (set_attr "mode" "<MODE>")])
7094 (define_expand "<u>mulvqi4"
7095 [(parallel [(set (reg:CCO FLAGS_REG)
7098 (match_operand:QI 1 "nonimmediate_operand"))
7100 (match_operand:QI 2 "nonimmediate_operand")))
7102 (mult:QI (match_dup 1) (match_dup 2)))))
7103 (set (match_operand:QI 0 "register_operand")
7104 (mult:QI (match_dup 1) (match_dup 2)))])
7105 (set (pc) (if_then_else
7106 (eq (reg:CCO FLAGS_REG) (const_int 0))
7107 (label_ref (match_operand 3))
7109 "TARGET_QIMODE_MATH"
7111 if (MEM_P (operands[1]) && MEM_P (operands[2]))
7112 operands[1] = force_reg (QImode, operands[1]);
7115 (define_insn "*<u>mulvqi4"
7116 [(set (reg:CCO FLAGS_REG)
7119 (match_operand:QI 1 "nonimmediate_operand" "%0"))
7121 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7123 (mult:QI (match_dup 1) (match_dup 2)))))
7124 (set (match_operand:QI 0 "register_operand" "=a")
7125 (mult:QI (match_dup 1) (match_dup 2)))]
7127 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7128 "<sgnprefix>mul{b}\t%2"
7129 [(set_attr "type" "imul")
7130 (set_attr "length_immediate" "0")
7131 (set (attr "athlon_decode")
7132 (if_then_else (eq_attr "cpu" "athlon")
7133 (const_string "vector")
7134 (const_string "direct")))
7135 (set_attr "amdfam10_decode" "direct")
7136 (set_attr "bdver1_decode" "direct")
7137 (set_attr "mode" "QI")])
7139 (define_expand "<u>mul<mode><dwi>3"
7140 [(parallel [(set (match_operand:<DWI> 0 "register_operand")
7143 (match_operand:DWIH 1 "nonimmediate_operand"))
7145 (match_operand:DWIH 2 "register_operand"))))
7146 (clobber (reg:CC FLAGS_REG))])])
7148 (define_expand "<u>mulqihi3"
7149 [(parallel [(set (match_operand:HI 0 "register_operand")
7152 (match_operand:QI 1 "nonimmediate_operand"))
7154 (match_operand:QI 2 "register_operand"))))
7155 (clobber (reg:CC FLAGS_REG))])]
7156 "TARGET_QIMODE_MATH")
7158 (define_insn "*bmi2_umul<mode><dwi>3_1"
7159 [(set (match_operand:DWIH 0 "register_operand" "=r")
7161 (match_operand:DWIH 2 "nonimmediate_operand" "%d")
7162 (match_operand:DWIH 3 "nonimmediate_operand" "rm")))
7163 (set (match_operand:DWIH 1 "register_operand" "=r")
7166 (mult:<DWI> (zero_extend:<DWI> (match_dup 2))
7167 (zero_extend:<DWI> (match_dup 3)))
7168 (match_operand:QI 4 "const_int_operand" "n"))))]
7169 "TARGET_BMI2 && INTVAL (operands[4]) == <MODE_SIZE> * BITS_PER_UNIT
7170 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7171 "mulx\t{%3, %0, %1|%1, %0, %3}"
7172 [(set_attr "type" "imulx")
7173 (set_attr "prefix" "vex")
7174 (set_attr "mode" "<MODE>")])
7176 (define_insn "*umul<mode><dwi>3_1"
7177 [(set (match_operand:<DWI> 0 "register_operand" "=r,A")
7180 (match_operand:DWIH 1 "nonimmediate_operand" "%d,0"))
7182 (match_operand:DWIH 2 "nonimmediate_operand" "rm,rm"))))
7183 (clobber (reg:CC FLAGS_REG))]
7184 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7187 mul{<imodesuffix>}\t%2"
7188 [(set_attr "isa" "bmi2,*")
7189 (set_attr "type" "imulx,imul")
7190 (set_attr "length_immediate" "*,0")
7191 (set (attr "athlon_decode")
7192 (cond [(eq_attr "alternative" "1")
7193 (if_then_else (eq_attr "cpu" "athlon")
7194 (const_string "vector")
7195 (const_string "double"))]
7196 (const_string "*")))
7197 (set_attr "amdfam10_decode" "*,double")
7198 (set_attr "bdver1_decode" "*,direct")
7199 (set_attr "prefix" "vex,orig")
7200 (set_attr "mode" "<MODE>")])
7202 ;; Convert mul to the mulx pattern to avoid flags dependency.
7204 [(set (match_operand:<DWI> 0 "register_operand")
7207 (match_operand:DWIH 1 "register_operand"))
7209 (match_operand:DWIH 2 "nonimmediate_operand"))))
7210 (clobber (reg:CC FLAGS_REG))]
7211 "TARGET_BMI2 && reload_completed
7212 && REGNO (operands[1]) == DX_REG"
7213 [(parallel [(set (match_dup 3)
7214 (mult:DWIH (match_dup 1) (match_dup 2)))
7218 (mult:<DWI> (zero_extend:<DWI> (match_dup 1))
7219 (zero_extend:<DWI> (match_dup 2)))
7222 split_double_mode (<DWI>mode, &operands[0], 1, &operands[3], &operands[4]);
7224 operands[5] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT);
7227 (define_insn "*mul<mode><dwi>3_1"
7228 [(set (match_operand:<DWI> 0 "register_operand" "=A")
7231 (match_operand:DWIH 1 "nonimmediate_operand" "%0"))
7233 (match_operand:DWIH 2 "nonimmediate_operand" "rm"))))
7234 (clobber (reg:CC FLAGS_REG))]
7235 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7236 "imul{<imodesuffix>}\t%2"
7237 [(set_attr "type" "imul")
7238 (set_attr "length_immediate" "0")
7239 (set (attr "athlon_decode")
7240 (if_then_else (eq_attr "cpu" "athlon")
7241 (const_string "vector")
7242 (const_string "double")))
7243 (set_attr "amdfam10_decode" "double")
7244 (set_attr "bdver1_decode" "direct")
7245 (set_attr "mode" "<MODE>")])
7247 (define_insn "*<u>mulqihi3_1"
7248 [(set (match_operand:HI 0 "register_operand" "=a")
7251 (match_operand:QI 1 "nonimmediate_operand" "%0"))
7253 (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7254 (clobber (reg:CC FLAGS_REG))]
7256 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7257 "<sgnprefix>mul{b}\t%2"
7258 [(set_attr "type" "imul")
7259 (set_attr "length_immediate" "0")
7260 (set (attr "athlon_decode")
7261 (if_then_else (eq_attr "cpu" "athlon")
7262 (const_string "vector")
7263 (const_string "direct")))
7264 (set_attr "amdfam10_decode" "direct")
7265 (set_attr "bdver1_decode" "direct")
7266 (set_attr "mode" "QI")])
7268 (define_expand "<s>mul<mode>3_highpart"
7269 [(parallel [(set (match_operand:DWIH 0 "register_operand")
7274 (match_operand:DWIH 1 "nonimmediate_operand"))
7276 (match_operand:DWIH 2 "register_operand")))
7278 (clobber (match_scratch:DWIH 4))
7279 (clobber (reg:CC FLAGS_REG))])]
7281 "operands[3] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
7283 (define_insn "*<s>muldi3_highpart_1"
7284 [(set (match_operand:DI 0 "register_operand" "=d")
7289 (match_operand:DI 1 "nonimmediate_operand" "%a"))
7291 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7293 (clobber (match_scratch:DI 3 "=1"))
7294 (clobber (reg:CC FLAGS_REG))]
7296 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7297 "<sgnprefix>mul{q}\t%2"
7298 [(set_attr "type" "imul")
7299 (set_attr "length_immediate" "0")
7300 (set (attr "athlon_decode")
7301 (if_then_else (eq_attr "cpu" "athlon")
7302 (const_string "vector")
7303 (const_string "double")))
7304 (set_attr "amdfam10_decode" "double")
7305 (set_attr "bdver1_decode" "direct")
7306 (set_attr "mode" "DI")])
7308 (define_insn "*<s>mulsi3_highpart_zext"
7309 [(set (match_operand:DI 0 "register_operand" "=d")
7310 (zero_extend:DI (truncate:SI
7312 (mult:DI (any_extend:DI
7313 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7315 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7317 (clobber (match_scratch:SI 3 "=1"))
7318 (clobber (reg:CC FLAGS_REG))]
7320 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7321 "<sgnprefix>mul{l}\t%2"
7322 [(set_attr "type" "imul")
7323 (set_attr "length_immediate" "0")
7324 (set (attr "athlon_decode")
7325 (if_then_else (eq_attr "cpu" "athlon")
7326 (const_string "vector")
7327 (const_string "double")))
7328 (set_attr "amdfam10_decode" "double")
7329 (set_attr "bdver1_decode" "direct")
7330 (set_attr "mode" "SI")])
7332 (define_insn "*<s>mulsi3_highpart_1"
7333 [(set (match_operand:SI 0 "register_operand" "=d")
7338 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7340 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7342 (clobber (match_scratch:SI 3 "=1"))
7343 (clobber (reg:CC FLAGS_REG))]
7344 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7345 "<sgnprefix>mul{l}\t%2"
7346 [(set_attr "type" "imul")
7347 (set_attr "length_immediate" "0")
7348 (set (attr "athlon_decode")
7349 (if_then_else (eq_attr "cpu" "athlon")
7350 (const_string "vector")
7351 (const_string "double")))
7352 (set_attr "amdfam10_decode" "double")
7353 (set_attr "bdver1_decode" "direct")
7354 (set_attr "mode" "SI")])
7356 ;; The patterns that match these are at the end of this file.
7358 (define_expand "mulxf3"
7359 [(set (match_operand:XF 0 "register_operand")
7360 (mult:XF (match_operand:XF 1 "register_operand")
7361 (match_operand:XF 2 "register_operand")))]
7364 (define_expand "mul<mode>3"
7365 [(set (match_operand:MODEF 0 "register_operand")
7366 (mult:MODEF (match_operand:MODEF 1 "register_operand")
7367 (match_operand:MODEF 2 "nonimmediate_operand")))]
7368 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
7369 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
7371 ;; Divide instructions
7373 ;; The patterns that match these are at the end of this file.
7375 (define_expand "divxf3"
7376 [(set (match_operand:XF 0 "register_operand")
7377 (div:XF (match_operand:XF 1 "register_operand")
7378 (match_operand:XF 2 "register_operand")))]
7381 (define_expand "div<mode>3"
7382 [(set (match_operand:MODEF 0 "register_operand")
7383 (div:MODEF (match_operand:MODEF 1 "register_operand")
7384 (match_operand:MODEF 2 "nonimmediate_operand")))]
7385 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
7386 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
7388 if (<MODE>mode == SFmode
7389 && TARGET_SSE && TARGET_SSE_MATH
7391 && optimize_insn_for_speed_p ()
7392 && flag_finite_math_only && !flag_trapping_math
7393 && flag_unsafe_math_optimizations)
7395 ix86_emit_swdivsf (operands[0], operands[1],
7396 operands[2], SFmode);
7401 ;; Divmod instructions.
7403 (define_expand "divmod<mode>4"
7404 [(parallel [(set (match_operand:SWIM248 0 "register_operand")
7406 (match_operand:SWIM248 1 "register_operand")
7407 (match_operand:SWIM248 2 "nonimmediate_operand")))
7408 (set (match_operand:SWIM248 3 "register_operand")
7409 (mod:SWIM248 (match_dup 1) (match_dup 2)))
7410 (clobber (reg:CC FLAGS_REG))])])
7412 ;; Split with 8bit unsigned divide:
7413 ;; if (dividend an divisor are in [0-255])
7414 ;; use 8bit unsigned integer divide
7416 ;; use original integer divide
7418 [(set (match_operand:SWI48 0 "register_operand")
7419 (div:SWI48 (match_operand:SWI48 2 "register_operand")
7420 (match_operand:SWI48 3 "nonimmediate_operand")))
7421 (set (match_operand:SWI48 1 "register_operand")
7422 (mod:SWI48 (match_dup 2) (match_dup 3)))
7423 (clobber (reg:CC FLAGS_REG))]
7424 "TARGET_USE_8BIT_IDIV
7425 && TARGET_QIMODE_MATH
7426 && can_create_pseudo_p ()
7427 && !optimize_insn_for_size_p ()"
7429 "ix86_split_idivmod (<MODE>mode, operands, true); DONE;")
7432 [(set (match_operand:DI 0 "register_operand")
7434 (div:SI (match_operand:SI 2 "register_operand")
7435 (match_operand:SI 3 "nonimmediate_operand"))))
7436 (set (match_operand:SI 1 "register_operand")
7437 (mod:SI (match_dup 2) (match_dup 3)))
7438 (clobber (reg:CC FLAGS_REG))]
7439 "TARGET_USE_8BIT_IDIV
7440 && TARGET_QIMODE_MATH
7441 && can_create_pseudo_p ()
7442 && !optimize_insn_for_size_p ()"
7444 "ix86_split_idivmod (SImode, operands, true); DONE;")
7447 [(set (match_operand:DI 1 "register_operand")
7449 (mod:SI (match_operand:SI 2 "register_operand")
7450 (match_operand:SI 3 "nonimmediate_operand"))))
7451 (set (match_operand:SI 0 "register_operand")
7452 (div:SI (match_dup 2) (match_dup 3)))
7453 (clobber (reg:CC FLAGS_REG))]
7454 "TARGET_USE_8BIT_IDIV
7455 && TARGET_QIMODE_MATH
7456 && can_create_pseudo_p ()
7457 && !optimize_insn_for_size_p ()"
7459 "ix86_split_idivmod (SImode, operands, true); DONE;")
7461 (define_insn_and_split "divmod<mode>4_1"
7462 [(set (match_operand:SWI48 0 "register_operand" "=a")
7463 (div:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7464 (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
7465 (set (match_operand:SWI48 1 "register_operand" "=&d")
7466 (mod:SWI48 (match_dup 2) (match_dup 3)))
7467 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7468 (clobber (reg:CC FLAGS_REG))]
7472 [(parallel [(set (match_dup 1)
7473 (ashiftrt:SWI48 (match_dup 4) (match_dup 5)))
7474 (clobber (reg:CC FLAGS_REG))])
7475 (parallel [(set (match_dup 0)
7476 (div:SWI48 (match_dup 2) (match_dup 3)))
7478 (mod:SWI48 (match_dup 2) (match_dup 3)))
7480 (clobber (reg:CC FLAGS_REG))])]
7482 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7484 if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
7485 operands[4] = operands[2];
7488 /* Avoid use of cltd in favor of a mov+shift. */
7489 emit_move_insn (operands[1], operands[2]);
7490 operands[4] = operands[1];
7493 [(set_attr "type" "multi")
7494 (set_attr "mode" "<MODE>")])
7496 (define_insn_and_split "divmodsi4_zext_1"
7497 [(set (match_operand:DI 0 "register_operand" "=a")
7499 (div:SI (match_operand:SI 2 "register_operand" "0")
7500 (match_operand:SI 3 "nonimmediate_operand" "rm"))))
7501 (set (match_operand:SI 1 "register_operand" "=&d")
7502 (mod:SI (match_dup 2) (match_dup 3)))
7503 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7504 (clobber (reg:CC FLAGS_REG))]
7508 [(parallel [(set (match_dup 1)
7509 (ashiftrt:SI (match_dup 4) (match_dup 5)))
7510 (clobber (reg:CC FLAGS_REG))])
7511 (parallel [(set (match_dup 0)
7512 (zero_extend:DI (div:SI (match_dup 2) (match_dup 3))))
7514 (mod:SI (match_dup 2) (match_dup 3)))
7516 (clobber (reg:CC FLAGS_REG))])]
7518 operands[5] = GEN_INT (GET_MODE_BITSIZE (SImode)-1);
7520 if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
7521 operands[4] = operands[2];
7524 /* Avoid use of cltd in favor of a mov+shift. */
7525 emit_move_insn (operands[1], operands[2]);
7526 operands[4] = operands[1];
7529 [(set_attr "type" "multi")
7530 (set_attr "mode" "SI")])
7532 (define_insn_and_split "divmodsi4_zext_2"
7533 [(set (match_operand:DI 1 "register_operand" "=&d")
7535 (mod:SI (match_operand:SI 2 "register_operand" "0")
7536 (match_operand:SI 3 "nonimmediate_operand" "rm"))))
7537 (set (match_operand:SI 0 "register_operand" "=a")
7538 (div:SI (match_dup 2) (match_dup 3)))
7539 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7540 (clobber (reg:CC FLAGS_REG))]
7544 [(parallel [(set (match_dup 6)
7545 (ashiftrt:SI (match_dup 4) (match_dup 5)))
7546 (clobber (reg:CC FLAGS_REG))])
7547 (parallel [(set (match_dup 1)
7548 (zero_extend:DI (mod:SI (match_dup 2) (match_dup 3))))
7550 (div:SI (match_dup 2) (match_dup 3)))
7552 (clobber (reg:CC FLAGS_REG))])]
7554 operands[5] = GEN_INT (GET_MODE_BITSIZE (SImode)-1);
7555 operands[6] = gen_lowpart (SImode, operands[1]);
7557 if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
7558 operands[4] = operands[2];
7561 /* Avoid use of cltd in favor of a mov+shift. */
7562 emit_move_insn (operands[6], operands[2]);
7563 operands[4] = operands[6];
7566 [(set_attr "type" "multi")
7567 (set_attr "mode" "SI")])
7569 (define_insn_and_split "*divmod<mode>4"
7570 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7571 (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7572 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7573 (set (match_operand:SWIM248 1 "register_operand" "=&d")
7574 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7575 (clobber (reg:CC FLAGS_REG))]
7579 [(parallel [(set (match_dup 1)
7580 (ashiftrt:SWIM248 (match_dup 4) (match_dup 5)))
7581 (clobber (reg:CC FLAGS_REG))])
7582 (parallel [(set (match_dup 0)
7583 (div:SWIM248 (match_dup 2) (match_dup 3)))
7585 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7587 (clobber (reg:CC FLAGS_REG))])]
7589 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7591 if (<MODE>mode != HImode
7592 && (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD))
7593 operands[4] = operands[2];
7596 /* Avoid use of cltd in favor of a mov+shift. */
7597 emit_move_insn (operands[1], operands[2]);
7598 operands[4] = operands[1];
7601 [(set_attr "type" "multi")
7602 (set_attr "mode" "<MODE>")])
7604 (define_insn_and_split "*divmodsi4_zext_1"
7605 [(set (match_operand:DI 0 "register_operand" "=a")
7607 (div:SI (match_operand:SI 2 "register_operand" "0")
7608 (match_operand:SI 3 "nonimmediate_operand" "rm"))))
7609 (set (match_operand:SI 1 "register_operand" "=&d")
7610 (mod:SI (match_dup 2) (match_dup 3)))
7611 (clobber (reg:CC FLAGS_REG))]
7615 [(parallel [(set (match_dup 1)
7616 (ashiftrt:SI (match_dup 4) (match_dup 5)))
7617 (clobber (reg:CC FLAGS_REG))])
7618 (parallel [(set (match_dup 0)
7619 (zero_extend:DI (div:SI (match_dup 2) (match_dup 3))))
7621 (mod:SI (match_dup 2) (match_dup 3)))
7623 (clobber (reg:CC FLAGS_REG))])]
7625 operands[5] = GEN_INT (GET_MODE_BITSIZE (SImode)-1);
7627 if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
7628 operands[4] = operands[2];
7631 /* Avoid use of cltd in favor of a mov+shift. */
7632 emit_move_insn (operands[1], operands[2]);
7633 operands[4] = operands[1];
7636 [(set_attr "type" "multi")
7637 (set_attr "mode" "SI")])
7639 (define_insn_and_split "*divmodsi4_zext_2"
7640 [(set (match_operand:DI 1 "register_operand" "=&d")
7642 (mod:SI (match_operand:SI 2 "register_operand" "0")
7643 (match_operand:SI 3 "nonimmediate_operand" "rm"))))
7644 (set (match_operand:SI 0 "register_operand" "=a")
7645 (div:SI (match_dup 2) (match_dup 3)))
7646 (clobber (reg:CC FLAGS_REG))]
7650 [(parallel [(set (match_dup 6)
7651 (ashiftrt:SI (match_dup 4) (match_dup 5)))
7652 (clobber (reg:CC FLAGS_REG))])
7653 (parallel [(set (match_dup 1)
7654 (zero_extend:DI (mod:SI (match_dup 2) (match_dup 3))))
7656 (div:SI (match_dup 2) (match_dup 3)))
7658 (clobber (reg:CC FLAGS_REG))])]
7660 operands[5] = GEN_INT (GET_MODE_BITSIZE (SImode)-1);
7661 operands[6] = gen_lowpart (SImode, operands[1]);
7663 if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
7664 operands[4] = operands[2];
7667 /* Avoid use of cltd in favor of a mov+shift. */
7668 emit_move_insn (operands[6], operands[2]);
7669 operands[4] = operands[6];
7672 [(set_attr "type" "multi")
7673 (set_attr "mode" "SI")])
7675 (define_insn "*divmod<mode>4_noext"
7676 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7677 (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7678 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7679 (set (match_operand:SWIM248 1 "register_operand" "=d")
7680 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7681 (use (match_operand:SWIM248 4 "register_operand" "1"))
7682 (clobber (reg:CC FLAGS_REG))]
7684 "idiv{<imodesuffix>}\t%3"
7685 [(set_attr "type" "idiv")
7686 (set_attr "mode" "<MODE>")])
7688 (define_insn "*divmodsi4_noext_zext_1"
7689 [(set (match_operand:DI 0 "register_operand" "=a")
7691 (div:SI (match_operand:SI 2 "register_operand" "0")
7692 (match_operand:SI 3 "nonimmediate_operand" "rm"))))
7693 (set (match_operand:SI 1 "register_operand" "=d")
7694 (mod:SI (match_dup 2) (match_dup 3)))
7695 (use (match_operand:SI 4 "register_operand" "1"))
7696 (clobber (reg:CC FLAGS_REG))]
7699 [(set_attr "type" "idiv")
7700 (set_attr "mode" "SI")])
7702 (define_insn "*divmodsi4_noext_zext_2"
7703 [(set (match_operand:DI 1 "register_operand" "=d")
7705 (mod:SI (match_operand:SI 2 "register_operand" "0")
7706 (match_operand:SI 3 "nonimmediate_operand" "rm"))))
7707 (set (match_operand:SI 0 "register_operand" "=a")
7708 (div:SI (match_dup 2) (match_dup 3)))
7709 (use (match_operand:SI 4 "register_operand" "1"))
7710 (clobber (reg:CC FLAGS_REG))]
7713 [(set_attr "type" "idiv")
7714 (set_attr "mode" "SI")])
7716 (define_expand "divmodqi4"
7717 [(parallel [(set (match_operand:QI 0 "register_operand")
7719 (match_operand:QI 1 "register_operand")
7720 (match_operand:QI 2 "nonimmediate_operand")))
7721 (set (match_operand:QI 3 "register_operand")
7722 (mod:QI (match_dup 1) (match_dup 2)))
7723 (clobber (reg:CC FLAGS_REG))])]
7724 "TARGET_QIMODE_MATH"
7729 tmp0 = gen_reg_rtx (HImode);
7730 tmp1 = gen_reg_rtx (HImode);
7732 /* Extend operands[1] to HImode. Generate 8bit divide. Result is in AX. */
7733 emit_insn (gen_extendqihi2 (tmp1, operands[1]));
7734 emit_insn (gen_divmodhiqi3 (tmp0, tmp1, operands[2]));
7736 /* Extract remainder from AH. */
7737 tmp1 = gen_rtx_ZERO_EXTRACT (SImode, tmp0, GEN_INT (8), GEN_INT (8));
7738 tmp1 = lowpart_subreg (QImode, tmp1, SImode);
7739 rtx_insn *insn = emit_move_insn (operands[3], tmp1);
7741 mod = gen_rtx_MOD (QImode, operands[1], operands[2]);
7742 set_unique_reg_note (insn, REG_EQUAL, mod);
7744 /* Extract quotient from AL. */
7745 insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
7747 div = gen_rtx_DIV (QImode, operands[1], operands[2]);
7748 set_unique_reg_note (insn, REG_EQUAL, div);
7753 ;; Divide AX by r/m8, with result stored in
7756 ;; Change div/mod to HImode and extend the second argument to HImode
7757 ;; so that mode of div/mod matches with mode of arguments. Otherwise
7758 ;; combine may fail.
7759 (define_insn "divmodhiqi3"
7760 [(set (match_operand:HI 0 "register_operand" "=a")
7765 (mod:HI (match_operand:HI 1 "register_operand" "0")
7767 (match_operand:QI 2 "nonimmediate_operand" "qm")))))
7771 (div:HI (match_dup 1) (sign_extend:HI (match_dup 2)))))))
7772 (clobber (reg:CC FLAGS_REG))]
7773 "TARGET_QIMODE_MATH"
7775 [(set_attr "type" "idiv")
7776 (set_attr "mode" "QI")])
7778 (define_expand "udivmod<mode>4"
7779 [(parallel [(set (match_operand:SWIM248 0 "register_operand")
7781 (match_operand:SWIM248 1 "register_operand")
7782 (match_operand:SWIM248 2 "nonimmediate_operand")))
7783 (set (match_operand:SWIM248 3 "register_operand")
7784 (umod:SWIM248 (match_dup 1) (match_dup 2)))
7785 (clobber (reg:CC FLAGS_REG))])])
7787 ;; Split with 8bit unsigned divide:
7788 ;; if (dividend an divisor are in [0-255])
7789 ;; use 8bit unsigned integer divide
7791 ;; use original integer divide
7793 [(set (match_operand:SWI48 0 "register_operand")
7794 (udiv:SWI48 (match_operand:SWI48 2 "register_operand")
7795 (match_operand:SWI48 3 "nonimmediate_operand")))
7796 (set (match_operand:SWI48 1 "register_operand")
7797 (umod:SWI48 (match_dup 2) (match_dup 3)))
7798 (clobber (reg:CC FLAGS_REG))]
7799 "TARGET_USE_8BIT_IDIV
7800 && TARGET_QIMODE_MATH
7801 && can_create_pseudo_p ()
7802 && !optimize_insn_for_size_p ()"
7804 "ix86_split_idivmod (<MODE>mode, operands, false); DONE;")
7807 [(set (match_operand:DI 0 "register_operand")
7809 (udiv:SI (match_operand:SI 2 "register_operand")
7810 (match_operand:SI 3 "nonimmediate_operand"))))
7811 (set (match_operand:SI 1 "register_operand")
7812 (umod:SI (match_dup 2) (match_dup 3)))
7813 (clobber (reg:CC FLAGS_REG))]
7815 && TARGET_USE_8BIT_IDIV
7816 && TARGET_QIMODE_MATH
7817 && can_create_pseudo_p ()
7818 && !optimize_insn_for_size_p ()"
7820 "ix86_split_idivmod (SImode, operands, false); DONE;")
7823 [(set (match_operand:DI 1 "register_operand")
7825 (umod:SI (match_operand:SI 2 "register_operand")
7826 (match_operand:SI 3 "nonimmediate_operand"))))
7827 (set (match_operand:SI 0 "register_operand")
7828 (udiv:SI (match_dup 2) (match_dup 3)))
7829 (clobber (reg:CC FLAGS_REG))]
7831 && TARGET_USE_8BIT_IDIV
7832 && TARGET_QIMODE_MATH
7833 && can_create_pseudo_p ()
7834 && !optimize_insn_for_size_p ()"
7836 "ix86_split_idivmod (SImode, operands, false); DONE;")
7838 (define_insn_and_split "udivmod<mode>4_1"
7839 [(set (match_operand:SWI48 0 "register_operand" "=a")
7840 (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7841 (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
7842 (set (match_operand:SWI48 1 "register_operand" "=&d")
7843 (umod:SWI48 (match_dup 2) (match_dup 3)))
7844 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7845 (clobber (reg:CC FLAGS_REG))]
7849 [(set (match_dup 1) (const_int 0))
7850 (parallel [(set (match_dup 0)
7851 (udiv:SWI48 (match_dup 2) (match_dup 3)))
7853 (umod:SWI48 (match_dup 2) (match_dup 3)))
7855 (clobber (reg:CC FLAGS_REG))])]
7857 [(set_attr "type" "multi")
7858 (set_attr "mode" "<MODE>")])
7860 (define_insn_and_split "udivmodsi4_zext_1"
7861 [(set (match_operand:DI 0 "register_operand" "=a")
7863 (udiv:SI (match_operand:SI 2 "register_operand" "0")
7864 (match_operand:SI 3 "nonimmediate_operand" "rm"))))
7865 (set (match_operand:SI 1 "register_operand" "=&d")
7866 (umod:SI (match_dup 2) (match_dup 3)))
7867 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7868 (clobber (reg:CC FLAGS_REG))]
7872 [(set (match_dup 1) (const_int 0))
7873 (parallel [(set (match_dup 0)
7874 (zero_extend:DI (udiv:SI (match_dup 2) (match_dup 3))))
7876 (umod:SI (match_dup 2) (match_dup 3)))
7878 (clobber (reg:CC FLAGS_REG))])]
7880 [(set_attr "type" "multi")
7881 (set_attr "mode" "SI")])
7883 (define_insn_and_split "udivmodsi4_zext_2"
7884 [(set (match_operand:DI 1 "register_operand" "=&d")
7886 (umod:SI (match_operand:SI 2 "register_operand" "0")
7887 (match_operand:SI 3 "nonimmediate_operand" "rm"))))
7888 (set (match_operand:SI 0 "register_operand" "=a")
7889 (udiv:SI (match_dup 2) (match_dup 3)))
7890 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7891 (clobber (reg:CC FLAGS_REG))]
7895 [(set (match_dup 4) (const_int 0))
7896 (parallel [(set (match_dup 1)
7897 (zero_extend:DI (umod:SI (match_dup 2) (match_dup 3))))
7899 (udiv:SI (match_dup 2) (match_dup 3)))
7901 (clobber (reg:CC FLAGS_REG))])]
7902 "operands[4] = gen_lowpart (SImode, operands[1]);"
7903 [(set_attr "type" "multi")
7904 (set_attr "mode" "SI")])
7906 (define_insn_and_split "*udivmod<mode>4"
7907 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7908 (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7909 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7910 (set (match_operand:SWIM248 1 "register_operand" "=&d")
7911 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7912 (clobber (reg:CC FLAGS_REG))]
7916 [(set (match_dup 1) (const_int 0))
7917 (parallel [(set (match_dup 0)
7918 (udiv:SWIM248 (match_dup 2) (match_dup 3)))
7920 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7922 (clobber (reg:CC FLAGS_REG))])]
7924 [(set_attr "type" "multi")
7925 (set_attr "mode" "<MODE>")])
7927 (define_insn_and_split "*udivmodsi4_zext_1"
7928 [(set (match_operand:DI 0 "register_operand" "=a")
7930 (udiv:SI (match_operand:SI 2 "register_operand" "0")
7931 (match_operand:SI 3 "nonimmediate_operand" "rm"))))
7932 (set (match_operand:SI 1 "register_operand" "=&d")
7933 (umod:SI (match_dup 2) (match_dup 3)))
7934 (clobber (reg:CC FLAGS_REG))]
7938 [(set (match_dup 1) (const_int 0))
7939 (parallel [(set (match_dup 0)
7940 (zero_extend:DI (udiv:SI (match_dup 2) (match_dup 3))))
7942 (umod:SI (match_dup 2) (match_dup 3)))
7944 (clobber (reg:CC FLAGS_REG))])]
7946 [(set_attr "type" "multi")
7947 (set_attr "mode" "SI")])
7949 (define_insn_and_split "*udivmodsi4_zext_2"
7950 [(set (match_operand:DI 1 "register_operand" "=&d")
7952 (umod:SI (match_operand:SI 2 "register_operand" "0")
7953 (match_operand:SI 3 "nonimmediate_operand" "rm"))))
7954 (set (match_operand:SI 0 "register_operand" "=a")
7955 (udiv:SI (match_dup 2) (match_dup 3)))
7956 (clobber (reg:CC FLAGS_REG))]
7960 [(set (match_dup 4) (const_int 0))
7961 (parallel [(set (match_dup 1)
7962 (zero_extend:DI (umod:SI (match_dup 2) (match_dup 3))))
7964 (udiv:SI (match_dup 2) (match_dup 3)))
7966 (clobber (reg:CC FLAGS_REG))])]
7967 "operands[4] = gen_lowpart (SImode, operands[1]);"
7968 [(set_attr "type" "multi")
7969 (set_attr "mode" "SI")])
7971 ;; Optimize division or modulo by constant power of 2, if the constant
7972 ;; materializes only after expansion.
7973 (define_insn_and_split "*udivmod<mode>4_pow2"
7974 [(set (match_operand:SWI48 0 "register_operand" "=r")
7975 (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7976 (match_operand:SWI48 3 "const_int_operand" "n")))
7977 (set (match_operand:SWI48 1 "register_operand" "=r")
7978 (umod:SWI48 (match_dup 2) (match_dup 3)))
7979 (clobber (reg:CC FLAGS_REG))]
7980 "IN_RANGE (INTVAL (operands[3]), 2, HOST_WIDE_INT_UC (0x80000000))
7981 && (UINTVAL (operands[3]) & (UINTVAL (operands[3]) - 1)) == 0"
7984 [(set (match_dup 1) (match_dup 2))
7985 (parallel [(set (match_dup 0) (lshiftrt:<MODE> (match_dup 2) (match_dup 4)))
7986 (clobber (reg:CC FLAGS_REG))])
7987 (parallel [(set (match_dup 1) (and:<MODE> (match_dup 1) (match_dup 5)))
7988 (clobber (reg:CC FLAGS_REG))])]
7990 int v = exact_log2 (UINTVAL (operands[3]));
7991 operands[4] = GEN_INT (v);
7992 operands[5] = GEN_INT ((HOST_WIDE_INT_1U << v) - 1);
7994 [(set_attr "type" "multi")
7995 (set_attr "mode" "<MODE>")])
7997 (define_insn_and_split "*udivmodsi4_pow2_zext_1"
7998 [(set (match_operand:DI 0 "register_operand" "=r")
8000 (udiv:SI (match_operand:SI 2 "register_operand" "0")
8001 (match_operand:SI 3 "const_int_operand" "n"))))
8002 (set (match_operand:SI 1 "register_operand" "=r")
8003 (umod:SI (match_dup 2) (match_dup 3)))
8004 (clobber (reg:CC FLAGS_REG))]
8006 && IN_RANGE (INTVAL (operands[3]), 2, HOST_WIDE_INT_UC (0x80000000))
8007 && (UINTVAL (operands[3]) & (UINTVAL (operands[3]) - 1)) == 0"
8010 [(set (match_dup 1) (match_dup 2))
8011 (parallel [(set (match_dup 0)
8012 (zero_extend:DI (lshiftrt:SI (match_dup 2) (match_dup 4))))
8013 (clobber (reg:CC FLAGS_REG))])
8014 (parallel [(set (match_dup 1) (and:SI (match_dup 1) (match_dup 5)))
8015 (clobber (reg:CC FLAGS_REG))])]
8017 int v = exact_log2 (UINTVAL (operands[3]));
8018 operands[4] = GEN_INT (v);
8019 operands[5] = GEN_INT ((HOST_WIDE_INT_1U << v) - 1);
8021 [(set_attr "type" "multi")
8022 (set_attr "mode" "SI")])
8024 (define_insn_and_split "*udivmodsi4_pow2_zext_2"
8025 [(set (match_operand:DI 1 "register_operand" "=r")
8027 (umod:SI (match_operand:SI 2 "register_operand" "0")
8028 (match_operand:SI 3 "const_int_operand" "n"))))
8029 (set (match_operand:SI 0 "register_operand" "=r")
8030 (umod:SI (match_dup 2) (match_dup 3)))
8031 (clobber (reg:CC FLAGS_REG))]
8033 && IN_RANGE (INTVAL (operands[3]), 2, HOST_WIDE_INT_UC (0x80000000))
8034 && (UINTVAL (operands[3]) & (UINTVAL (operands[3]) - 1)) == 0"
8037 [(set (match_dup 1) (match_dup 2))
8038 (parallel [(set (match_dup 0) (lshiftrt:SI (match_dup 2) (match_dup 4)))
8039 (clobber (reg:CC FLAGS_REG))])
8040 (parallel [(set (match_dup 1)
8041 (zero_extend:DI (and:SI (match_dup 1) (match_dup 5))))
8042 (clobber (reg:CC FLAGS_REG))])]
8044 int v = exact_log2 (UINTVAL (operands[3]));
8045 operands[4] = GEN_INT (v);
8046 operands[5] = GEN_INT ((HOST_WIDE_INT_1U << v) - 1);
8048 [(set_attr "type" "multi")
8049 (set_attr "mode" "SI")])
8051 (define_insn "*udivmod<mode>4_noext"
8052 [(set (match_operand:SWIM248 0 "register_operand" "=a")
8053 (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
8054 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
8055 (set (match_operand:SWIM248 1 "register_operand" "=d")
8056 (umod:SWIM248 (match_dup 2) (match_dup 3)))
8057 (use (match_operand:SWIM248 4 "register_operand" "1"))
8058 (clobber (reg:CC FLAGS_REG))]
8060 "div{<imodesuffix>}\t%3"
8061 [(set_attr "type" "idiv")
8062 (set_attr "mode" "<MODE>")])
8064 (define_insn "*udivmodsi4_noext_zext_1"
8065 [(set (match_operand:DI 0 "register_operand" "=a")
8067 (udiv:SI (match_operand:SI 2 "register_operand" "0")
8068 (match_operand:SI 3 "nonimmediate_operand" "rm"))))
8069 (set (match_operand:SI 1 "register_operand" "=d")
8070 (umod:SI (match_dup 2) (match_dup 3)))
8071 (use (match_operand:SI 4 "register_operand" "1"))
8072 (clobber (reg:CC FLAGS_REG))]
8075 [(set_attr "type" "idiv")
8076 (set_attr "mode" "SI")])
8078 (define_insn "*udivmodsi4_noext_zext_2"
8079 [(set (match_operand:DI 1 "register_operand" "=d")
8081 (umod:SI (match_operand:SI 2 "register_operand" "0")
8082 (match_operand:SI 3 "nonimmediate_operand" "rm"))))
8083 (set (match_operand:SI 0 "register_operand" "=a")
8084 (udiv:SI (match_dup 2) (match_dup 3)))
8085 (use (match_operand:SI 4 "register_operand" "1"))
8086 (clobber (reg:CC FLAGS_REG))]
8089 [(set_attr "type" "idiv")
8090 (set_attr "mode" "SI")])
8092 (define_expand "udivmodqi4"
8093 [(parallel [(set (match_operand:QI 0 "register_operand")
8095 (match_operand:QI 1 "register_operand")
8096 (match_operand:QI 2 "nonimmediate_operand")))
8097 (set (match_operand:QI 3 "register_operand")
8098 (umod:QI (match_dup 1) (match_dup 2)))
8099 (clobber (reg:CC FLAGS_REG))])]
8100 "TARGET_QIMODE_MATH"
8105 tmp0 = gen_reg_rtx (HImode);
8106 tmp1 = gen_reg_rtx (HImode);
8108 /* Extend operands[1] to HImode. Generate 8bit divide. Result is in AX. */
8109 emit_insn (gen_zero_extendqihi2 (tmp1, operands[1]));
8110 emit_insn (gen_udivmodhiqi3 (tmp0, tmp1, operands[2]));
8112 /* Extract remainder from AH. */
8113 tmp1 = gen_rtx_ZERO_EXTRACT (SImode, tmp0, GEN_INT (8), GEN_INT (8));
8114 tmp1 = lowpart_subreg (QImode, tmp1, SImode);
8115 rtx_insn *insn = emit_move_insn (operands[3], tmp1);
8117 mod = gen_rtx_UMOD (QImode, operands[1], operands[2]);
8118 set_unique_reg_note (insn, REG_EQUAL, mod);
8120 /* Extract quotient from AL. */
8121 insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
8123 div = gen_rtx_UDIV (QImode, operands[1], operands[2]);
8124 set_unique_reg_note (insn, REG_EQUAL, div);
8129 (define_insn "udivmodhiqi3"
8130 [(set (match_operand:HI 0 "register_operand" "=a")
8135 (mod:HI (match_operand:HI 1 "register_operand" "0")
8137 (match_operand:QI 2 "nonimmediate_operand" "qm")))))
8141 (div:HI (match_dup 1) (zero_extend:HI (match_dup 2)))))))
8142 (clobber (reg:CC FLAGS_REG))]
8143 "TARGET_QIMODE_MATH"
8145 [(set_attr "type" "idiv")
8146 (set_attr "mode" "QI")])
8148 ;; We cannot use div/idiv for double division, because it causes
8149 ;; "division by zero" on the overflow and that's not what we expect
8150 ;; from truncate. Because true (non truncating) double division is
8151 ;; never generated, we can't create this insn anyway.
8154 ; [(set (match_operand:SI 0 "register_operand" "=a")
8156 ; (udiv:DI (match_operand:DI 1 "register_operand" "A")
8158 ; (match_operand:SI 2 "nonimmediate_operand" "rm")))))
8159 ; (set (match_operand:SI 3 "register_operand" "=d")
8161 ; (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
8162 ; (clobber (reg:CC FLAGS_REG))]
8164 ; "div{l}\t{%2, %0|%0, %2}"
8165 ; [(set_attr "type" "idiv")])
8167 ;;- Logical AND instructions
8169 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
8170 ;; Note that this excludes ah.
8172 (define_expand "testsi_ccno_1"
8173 [(set (reg:CCNO FLAGS_REG)
8175 (and:SI (match_operand:SI 0 "nonimmediate_operand")
8176 (match_operand:SI 1 "x86_64_nonmemory_operand"))
8179 (define_expand "testqi_ccz_1"
8180 [(set (reg:CCZ FLAGS_REG)
8181 (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand")
8182 (match_operand:QI 1 "nonmemory_operand"))
8185 (define_expand "testdi_ccno_1"
8186 [(set (reg:CCNO FLAGS_REG)
8188 (and:DI (match_operand:DI 0 "nonimmediate_operand")
8189 (match_operand:DI 1 "x86_64_szext_general_operand"))
8191 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))")
8193 (define_insn "*testdi_1"
8194 [(set (reg FLAGS_REG)
8197 (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
8198 (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
8200 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8201 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8203 test{l}\t{%k1, %k0|%k0, %k1}
8204 test{l}\t{%k1, %k0|%k0, %k1}
8205 test{q}\t{%1, %0|%0, %1}
8206 test{q}\t{%1, %0|%0, %1}
8207 test{q}\t{%1, %0|%0, %1}"
8208 [(set_attr "type" "test")
8209 (set_attr "modrm" "0,1,0,1,1")
8210 (set_attr "mode" "SI,SI,DI,DI,DI")])
8212 (define_insn "*testqi_1_maybe_si"
8213 [(set (reg FLAGS_REG)
8216 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
8217 (match_operand:QI 1 "general_operand" "n,n,qn,n"))
8219 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
8220 && ix86_match_ccmode (insn,
8221 CONST_INT_P (operands[1])
8222 && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
8224 if (which_alternative == 3)
8226 if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
8227 operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
8228 return "test{l}\t{%1, %k0|%k0, %1}";
8230 return "test{b}\t{%1, %0|%0, %1}";
8232 [(set_attr "type" "test")
8233 (set_attr "modrm" "0,1,1,1")
8234 (set_attr "mode" "QI,QI,QI,SI")
8235 (set_attr "pent_pair" "uv,np,uv,np")])
8237 (define_insn "*test<mode>_1"
8238 [(set (reg FLAGS_REG)
8241 (match_operand:SWI124 0 "nonimmediate_operand" "%!*a,<r>,<r>m")
8242 (match_operand:SWI124 1 "<general_operand>" "<i>,<i>,<r><i>"))
8244 "ix86_match_ccmode (insn, CCNOmode)
8245 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8246 "test{<imodesuffix>}\t{%1, %0|%0, %1}"
8247 [(set_attr "type" "test")
8248 (set_attr "modrm" "0,1,1")
8249 (set_attr "mode" "<MODE>")
8250 (set_attr "pent_pair" "uv,np,uv")])
8252 (define_expand "testqi_ext_1_ccno"
8253 [(set (reg:CCNO FLAGS_REG)
8257 (zero_extract:SI (match_operand 0 "ext_register_operand")
8260 (match_operand 1 "const_int_operand"))
8263 (define_insn "*testqi_ext_1"
8264 [(set (reg FLAGS_REG)
8268 (zero_extract:SI (match_operand 0 "ext_register_operand" "Q,Q")
8271 (match_operand:QI 1 "general_operand" "QnBc,m"))
8273 "ix86_match_ccmode (insn, CCNOmode)"
8274 "test{b}\t{%1, %h0|%h0, %1}"
8275 [(set_attr "isa" "*,nox64")
8276 (set_attr "type" "test")
8277 (set_attr "mode" "QI")])
8279 (define_insn "*testqi_ext_2"
8280 [(set (reg FLAGS_REG)
8284 (zero_extract:SI (match_operand 0 "ext_register_operand" "Q")
8288 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q")
8292 "ix86_match_ccmode (insn, CCNOmode)"
8293 "test{b}\t{%h1, %h0|%h0, %h1}"
8294 [(set_attr "type" "test")
8295 (set_attr "mode" "QI")])
8297 ;; Combine likes to form bit extractions for some tests. Humor it.
8298 (define_insn_and_split "*testqi_ext_3"
8299 [(set (match_operand 0 "flags_reg_operand")
8300 (match_operator 1 "compare_operator"
8301 [(zero_extract:SWI248
8302 (match_operand 2 "nonimmediate_operand" "rm")
8303 (match_operand 3 "const_int_operand" "n")
8304 (match_operand 4 "const_int_operand" "n"))
8306 "ix86_match_ccmode (insn, CCNOmode)
8307 && ((TARGET_64BIT && GET_MODE (operands[2]) == DImode)
8308 || GET_MODE (operands[2]) == SImode
8309 || GET_MODE (operands[2]) == HImode
8310 || GET_MODE (operands[2]) == QImode)
8311 /* Ensure that resulting mask is zero or sign extended operand. */
8312 && INTVAL (operands[4]) >= 0
8313 && ((INTVAL (operands[3]) > 0
8314 && INTVAL (operands[3]) + INTVAL (operands[4]) <= 32)
8315 || (<MODE>mode == DImode
8316 && INTVAL (operands[3]) > 32
8317 && INTVAL (operands[3]) + INTVAL (operands[4]) == 64))"
8320 [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
8322 rtx val = operands[2];
8323 HOST_WIDE_INT len = INTVAL (operands[3]);
8324 HOST_WIDE_INT pos = INTVAL (operands[4]);
8325 machine_mode mode = GET_MODE (val);
8329 machine_mode submode = GET_MODE (SUBREG_REG (val));
8331 /* Narrow paradoxical subregs to prevent partial register stalls. */
8332 if (GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode)
8333 && GET_MODE_CLASS (submode) == MODE_INT)
8335 val = SUBREG_REG (val);
8340 /* Small HImode tests can be converted to QImode. */
8341 if (register_operand (val, HImode) && pos + len <= 8)
8343 val = gen_lowpart (QImode, val);
8347 gcc_assert (pos + len <= GET_MODE_PRECISION (mode));
8350 = wi::shifted_mask (pos, len, false, GET_MODE_PRECISION (mode));
8352 operands[2] = gen_rtx_AND (mode, val, immed_wide_int_const (mask, mode));
8355 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
8356 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
8357 ;; this is relatively important trick.
8358 ;; Do the conversion only post-reload to avoid limiting of the register class
8361 [(set (match_operand 0 "flags_reg_operand")
8362 (match_operator 1 "compare_operator"
8363 [(and (match_operand 2 "QIreg_operand")
8364 (match_operand 3 "const_int_operand"))
8367 && GET_MODE (operands[2]) != QImode
8368 && ((ix86_match_ccmode (insn, CCZmode)
8369 && !(INTVAL (operands[3]) & ~(255 << 8)))
8370 || (ix86_match_ccmode (insn, CCNOmode)
8371 && !(INTVAL (operands[3]) & ~(127 << 8))))"
8376 (zero_extract:SI (match_dup 2)
8382 operands[2] = gen_lowpart (SImode, operands[2]);
8383 operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, QImode);
8387 [(set (match_operand 0 "flags_reg_operand")
8388 (match_operator 1 "compare_operator"
8389 [(and (match_operand 2 "nonimmediate_operand")
8390 (match_operand 3 "const_int_operand"))
8393 && GET_MODE (operands[2]) != QImode
8394 && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
8395 && ((ix86_match_ccmode (insn, CCZmode)
8396 && !(INTVAL (operands[3]) & ~255))
8397 || (ix86_match_ccmode (insn, CCNOmode)
8398 && !(INTVAL (operands[3]) & ~127)))"
8400 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
8403 operands[2] = gen_lowpart (QImode, operands[2]);
8404 operands[3] = gen_int_mode (INTVAL (operands[3]), QImode);
8407 ;; %%% This used to optimize known byte-wide and operations to memory,
8408 ;; and sometimes to QImode registers. If this is considered useful,
8409 ;; it should be done with splitters.
8411 (define_expand "and<mode>3"
8412 [(set (match_operand:SWIM1248x 0 "nonimmediate_operand")
8413 (and:SWIM1248x (match_operand:SWIM1248x 1 "nonimmediate_operand")
8414 (match_operand:SWIM1248x 2 "<general_szext_operand>")))]
8417 machine_mode mode = <MODE>mode;
8418 rtx (*insn) (rtx, rtx);
8420 if (CONST_INT_P (operands[2]) && REG_P (operands[0]))
8422 HOST_WIDE_INT ival = INTVAL (operands[2]);
8424 if (ival == (HOST_WIDE_INT) 0xffffffff)
8426 else if (ival == 0xffff)
8428 else if (ival == 0xff)
8432 if (mode == <MODE>mode)
8434 ix86_expand_binary_operator (AND, <MODE>mode, operands);
8438 if (<MODE>mode == DImode)
8439 insn = (mode == SImode)
8440 ? gen_zero_extendsidi2
8442 ? gen_zero_extendhidi2
8443 : gen_zero_extendqidi2;
8444 else if (<MODE>mode == SImode)
8445 insn = (mode == HImode)
8446 ? gen_zero_extendhisi2
8447 : gen_zero_extendqisi2;
8448 else if (<MODE>mode == HImode)
8449 insn = gen_zero_extendqihi2;
8453 emit_insn (insn (operands[0], gen_lowpart (mode, operands[1])));
8457 (define_insn_and_split "*anddi3_doubleword"
8458 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r")
8460 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8461 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm")))
8462 (clobber (reg:CC FLAGS_REG))]
8463 "!TARGET_64BIT && TARGET_STV && TARGET_SSE2
8464 && ix86_binary_operator_ok (AND, DImode, operands)"
8466 "&& reload_completed"
8469 split_double_mode (DImode, &operands[0], 3, &operands[0], &operands[3]);
8470 if (operands[2] == const0_rtx)
8472 operands[1] = const0_rtx;
8473 ix86_expand_move (SImode, &operands[0]);
8475 else if (operands[2] != constm1_rtx)
8476 ix86_expand_binary_operator (AND, SImode, &operands[0]);
8477 else if (operands[5] == constm1_rtx)
8478 emit_note (NOTE_INSN_DELETED);
8479 if (operands[5] == const0_rtx)
8481 operands[4] = const0_rtx;
8482 ix86_expand_move (SImode, &operands[3]);
8484 else if (operands[5] != constm1_rtx)
8485 ix86_expand_binary_operator (AND, SImode, &operands[3]);
8489 (define_insn "*anddi_1"
8490 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
8492 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
8493 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
8494 (clobber (reg:CC FLAGS_REG))]
8495 "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
8497 and{l}\t{%k2, %k0|%k0, %k2}
8498 and{q}\t{%2, %0|%0, %2}
8499 and{q}\t{%2, %0|%0, %2}
8501 [(set_attr "type" "alu,alu,alu,imovx")
8502 (set_attr "length_immediate" "*,*,*,0")
8503 (set (attr "prefix_rex")
8505 (and (eq_attr "type" "imovx")
8506 (and (match_test "INTVAL (operands[2]) == 0xff")
8507 (match_operand 1 "ext_QIreg_operand")))
8509 (const_string "*")))
8510 (set_attr "mode" "SI,DI,DI,SI")])
8512 (define_insn_and_split "*anddi_1_btr"
8513 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
8515 (match_operand:DI 1 "nonimmediate_operand" "%0")
8516 (match_operand:DI 2 "const_int_operand" "n")))
8517 (clobber (reg:CC FLAGS_REG))]
8518 "TARGET_64BIT && TARGET_USE_BT
8519 && ix86_binary_operator_ok (AND, DImode, operands)
8520 && IN_RANGE (exact_log2 (~INTVAL (operands[2])), 31, 63)"
8522 "&& reload_completed"
8523 [(parallel [(set (zero_extract:DI (match_dup 0)
8527 (clobber (reg:CC FLAGS_REG))])]
8528 "operands[3] = GEN_INT (exact_log2 (~INTVAL (operands[2])));"
8529 [(set_attr "type" "alu1")
8530 (set_attr "prefix_0f" "1")
8531 (set_attr "znver1_decode" "double")
8532 (set_attr "mode" "DI")])
8534 ;; Turn *anddi_1 into *andsi_1_zext if possible.
8536 [(set (match_operand:DI 0 "register_operand")
8537 (and:DI (subreg:DI (match_operand:SI 1 "register_operand") 0)
8538 (match_operand:DI 2 "x86_64_zext_immediate_operand")))
8539 (clobber (reg:CC FLAGS_REG))]
8541 [(parallel [(set (match_dup 0)
8542 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))
8543 (clobber (reg:CC FLAGS_REG))])]
8544 "operands[2] = gen_lowpart (SImode, operands[2]);")
8546 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8547 (define_insn "*andsi_1_zext"
8548 [(set (match_operand:DI 0 "register_operand" "=r")
8550 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8551 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
8552 (clobber (reg:CC FLAGS_REG))]
8553 "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
8554 "and{l}\t{%2, %k0|%k0, %2}"
8555 [(set_attr "type" "alu")
8556 (set_attr "mode" "SI")])
8558 (define_insn "*and<mode>_1"
8559 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=rm,r,Ya")
8560 (and:SWI24 (match_operand:SWI24 1 "nonimmediate_operand" "%0,0,qm")
8561 (match_operand:SWI24 2 "<general_operand>" "r<i>,rm,L")))
8562 (clobber (reg:CC FLAGS_REG))]
8563 "ix86_binary_operator_ok (AND, <MODE>mode, operands)"
8565 and{<imodesuffix>}\t{%2, %0|%0, %2}
8566 and{<imodesuffix>}\t{%2, %0|%0, %2}
8568 [(set_attr "type" "alu,alu,imovx")
8569 (set_attr "length_immediate" "*,*,0")
8570 (set (attr "prefix_rex")
8572 (and (eq_attr "type" "imovx")
8573 (and (match_test "INTVAL (operands[2]) == 0xff")
8574 (match_operand 1 "ext_QIreg_operand")))
8576 (const_string "*")))
8577 (set_attr "mode" "<MODE>,<MODE>,SI")])
8579 (define_insn "*andqi_1"
8580 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
8581 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8582 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
8583 (clobber (reg:CC FLAGS_REG))]
8584 "ix86_binary_operator_ok (AND, QImode, operands)"
8586 and{b}\t{%2, %0|%0, %2}
8587 and{b}\t{%2, %0|%0, %2}
8588 and{l}\t{%k2, %k0|%k0, %k2}"
8589 [(set_attr "type" "alu")
8590 (set_attr "mode" "QI,QI,SI")
8591 ;; Potential partial reg stall on alternative 2.
8592 (set (attr "preferred_for_speed")
8593 (cond [(eq_attr "alternative" "2")
8594 (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
8595 (symbol_ref "true")))])
8597 (define_insn "*andqi_1_slp"
8598 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
8599 (and:QI (match_dup 0)
8600 (match_operand:QI 1 "general_operand" "qn,qmn")))
8601 (clobber (reg:CC FLAGS_REG))]
8602 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8603 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8604 "and{b}\t{%1, %0|%0, %1}"
8605 [(set_attr "type" "alu1")
8606 (set_attr "mode" "QI")])
8609 [(set (match_operand:SWI248 0 "register_operand")
8610 (and:SWI248 (match_operand:SWI248 1 "nonimmediate_operand")
8611 (match_operand:SWI248 2 "const_int_operand")))
8612 (clobber (reg:CC FLAGS_REG))]
8614 && (!REG_P (operands[1])
8615 || REGNO (operands[0]) != REGNO (operands[1]))"
8618 HOST_WIDE_INT ival = INTVAL (operands[2]);
8620 rtx (*insn) (rtx, rtx);
8622 if (ival == (HOST_WIDE_INT) 0xffffffff)
8624 else if (ival == 0xffff)
8628 gcc_assert (ival == 0xff);
8632 if (<MODE>mode == DImode)
8633 insn = (mode == SImode)
8634 ? gen_zero_extendsidi2
8636 ? gen_zero_extendhidi2
8637 : gen_zero_extendqidi2;
8640 if (<MODE>mode != SImode)
8641 /* Zero extend to SImode to avoid partial register stalls. */
8642 operands[0] = gen_lowpart (SImode, operands[0]);
8644 insn = (mode == HImode)
8645 ? gen_zero_extendhisi2
8646 : gen_zero_extendqisi2;
8648 emit_insn (insn (operands[0], gen_lowpart (mode, operands[1])));
8653 [(set (match_operand:SWI48 0 "register_operand")
8654 (and:SWI48 (match_dup 0)
8655 (const_int -65536)))
8656 (clobber (reg:CC FLAGS_REG))]
8657 "(TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)
8658 || optimize_function_for_size_p (cfun)"
8659 [(set (strict_low_part (match_dup 1)) (const_int 0))]
8660 "operands[1] = gen_lowpart (HImode, operands[0]);")
8663 [(set (match_operand:SWI248 0 "any_QIreg_operand")
8664 (and:SWI248 (match_dup 0)
8666 (clobber (reg:CC FLAGS_REG))]
8667 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8668 && reload_completed"
8669 [(set (strict_low_part (match_dup 1)) (const_int 0))]
8670 "operands[1] = gen_lowpart (QImode, operands[0]);")
8673 [(set (match_operand:SWI248 0 "QIreg_operand")
8674 (and:SWI248 (match_dup 0)
8675 (const_int -65281)))
8676 (clobber (reg:CC FLAGS_REG))]
8677 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8678 && reload_completed"
8680 [(set (zero_extract:SI (match_dup 0)
8686 (zero_extract:SI (match_dup 0)
8690 (zero_extract:SI (match_dup 0)
8692 (const_int 8)) 0)) 0))
8693 (clobber (reg:CC FLAGS_REG))])]
8694 "operands[0] = gen_lowpart (SImode, operands[0]);")
8696 (define_insn "*anddi_2"
8697 [(set (reg FLAGS_REG)
8700 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8701 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
8703 (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
8704 (and:DI (match_dup 1) (match_dup 2)))]
8706 && ix86_match_ccmode
8708 /* If we are going to emit andl instead of andq, and the operands[2]
8709 constant might have the SImode sign bit set, make sure the sign
8710 flag isn't tested, because the instruction will set the sign flag
8711 based on bit 31 rather than bit 63. If it isn't CONST_INT,
8712 conservatively assume it might have bit 31 set. */
8713 (satisfies_constraint_Z (operands[2])
8714 && (!CONST_INT_P (operands[2])
8715 || val_signbit_known_set_p (SImode, INTVAL (operands[2]))))
8716 ? CCZmode : CCNOmode)
8717 && ix86_binary_operator_ok (AND, DImode, operands)"
8719 and{l}\t{%k2, %k0|%k0, %k2}
8720 and{q}\t{%2, %0|%0, %2}
8721 and{q}\t{%2, %0|%0, %2}"
8722 [(set_attr "type" "alu")
8723 (set_attr "mode" "SI,DI,DI")])
8725 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8726 (define_insn "*andsi_2_zext"
8727 [(set (reg FLAGS_REG)
8729 (match_operand:SI 1 "nonimmediate_operand" "%0")
8730 (match_operand:SI 2 "x86_64_general_operand" "rme"))
8732 (set (match_operand:DI 0 "register_operand" "=r")
8733 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
8734 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8735 && ix86_binary_operator_ok (AND, SImode, operands)"
8736 "and{l}\t{%2, %k0|%k0, %2}"
8737 [(set_attr "type" "alu")
8738 (set_attr "mode" "SI")])
8740 (define_insn "*andqi_2_maybe_si"
8741 [(set (reg FLAGS_REG)
8743 (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8744 (match_operand:QI 2 "general_operand" "qmn,qn,n"))
8746 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
8747 (and:QI (match_dup 1) (match_dup 2)))]
8748 "ix86_binary_operator_ok (AND, QImode, operands)
8749 && ix86_match_ccmode (insn,
8750 CONST_INT_P (operands[2])
8751 && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
8753 if (which_alternative == 2)
8755 if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
8756 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
8757 return "and{l}\t{%2, %k0|%k0, %2}";
8759 return "and{b}\t{%2, %0|%0, %2}";
8761 [(set_attr "type" "alu")
8762 (set_attr "mode" "QI,QI,SI")])
8764 (define_insn "*and<mode>_2"
8765 [(set (reg FLAGS_REG)
8766 (compare (and:SWI124
8767 (match_operand:SWI124 1 "nonimmediate_operand" "%0,0")
8768 (match_operand:SWI124 2 "<general_operand>" "<g>,<r><i>"))
8770 (set (match_operand:SWI124 0 "nonimmediate_operand" "=<r>,<r>m")
8771 (and:SWI124 (match_dup 1) (match_dup 2)))]
8772 "ix86_match_ccmode (insn, CCNOmode)
8773 && ix86_binary_operator_ok (AND, <MODE>mode, operands)"
8774 "and{<imodesuffix>}\t{%2, %0|%0, %2}"
8775 [(set_attr "type" "alu")
8776 (set_attr "mode" "<MODE>")])
8778 (define_insn "*andqi_2_slp"
8779 [(set (reg FLAGS_REG)
8781 (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8782 (match_operand:QI 1 "nonimmediate_operand" "qmn,qn"))
8784 (set (strict_low_part (match_dup 0))
8785 (and:QI (match_dup 0) (match_dup 1)))]
8786 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8787 && ix86_match_ccmode (insn, CCNOmode)
8788 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8789 "and{b}\t{%1, %0|%0, %1}"
8790 [(set_attr "type" "alu1")
8791 (set_attr "mode" "QI")])
8793 (define_insn "andqi_ext_1"
8794 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q,Q")
8800 (zero_extract:SI (match_operand 1 "ext_register_operand" "0,0")
8803 (match_operand:QI 2 "general_operand" "QnBc,m")) 0))
8804 (clobber (reg:CC FLAGS_REG))]
8805 "/* FIXME: without this LRA can't reload this pattern, see PR82524. */
8806 rtx_equal_p (operands[0], operands[1])"
8807 "and{b}\t{%2, %h0|%h0, %2}"
8808 [(set_attr "isa" "*,nox64")
8809 (set_attr "type" "alu")
8810 (set_attr "mode" "QI")])
8812 ;; Generated by peephole translating test to and. This shows up
8813 ;; often in fp comparisons.
8814 (define_insn "*andqi_ext_1_cc"
8815 [(set (reg FLAGS_REG)
8819 (zero_extract:SI (match_operand 1 "ext_register_operand" "0,0")
8822 (match_operand:QI 2 "general_operand" "QnBc,m"))
8824 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q,Q")
8830 (zero_extract:SI (match_dup 1)
8834 "ix86_match_ccmode (insn, CCNOmode)
8835 /* FIXME: without this LRA can't reload this pattern, see PR82524. */
8836 && rtx_equal_p (operands[0], operands[1])"
8837 "and{b}\t{%2, %h0|%h0, %2}"
8838 [(set_attr "isa" "*,nox64")
8839 (set_attr "type" "alu")
8840 (set_attr "mode" "QI")])
8842 (define_insn "*andqi_ext_2"
8843 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
8849 (zero_extract:SI (match_operand 1 "ext_register_operand" "%0")
8853 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
8855 (const_int 8)) 0)) 0))
8856 (clobber (reg:CC FLAGS_REG))]
8857 "/* FIXME: without this LRA can't reload this pattern, see PR82524. */
8858 rtx_equal_p (operands[0], operands[1])
8859 || rtx_equal_p (operands[0], operands[2])"
8860 "and{b}\t{%h2, %h0|%h0, %h2}"
8861 [(set_attr "type" "alu")
8862 (set_attr "mode" "QI")])
8864 ;; Convert wide AND instructions with immediate operand to shorter QImode
8865 ;; equivalents when possible.
8866 ;; Don't do the splitting with memory operands, since it introduces risk
8867 ;; of memory mismatch stalls. We may want to do the splitting for optimizing
8868 ;; for size, but that can (should?) be handled by generic code instead.
8870 [(set (match_operand:SWI248 0 "QIreg_operand")
8871 (and:SWI248 (match_operand:SWI248 1 "register_operand")
8872 (match_operand:SWI248 2 "const_int_operand")))
8873 (clobber (reg:CC FLAGS_REG))]
8875 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8876 && !(~INTVAL (operands[2]) & ~(255 << 8))"
8878 [(set (zero_extract:SI (match_dup 0)
8884 (zero_extract:SI (match_dup 1)
8888 (clobber (reg:CC FLAGS_REG))])]
8890 operands[0] = gen_lowpart (SImode, operands[0]);
8891 operands[1] = gen_lowpart (SImode, operands[1]);
8892 operands[2] = gen_int_mode (INTVAL (operands[2]) >> 8, QImode);
8895 ;; Since AND can be encoded with sign extended immediate, this is only
8896 ;; profitable when 7th bit is not set.
8898 [(set (match_operand:SWI248 0 "any_QIreg_operand")
8899 (and:SWI248 (match_operand:SWI248 1 "general_operand")
8900 (match_operand:SWI248 2 "const_int_operand")))
8901 (clobber (reg:CC FLAGS_REG))]
8903 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8904 && !(~INTVAL (operands[2]) & ~255)
8905 && !(INTVAL (operands[2]) & 128)"
8906 [(parallel [(set (strict_low_part (match_dup 0))
8907 (and:QI (match_dup 1)
8909 (clobber (reg:CC FLAGS_REG))])]
8911 operands[0] = gen_lowpart (QImode, operands[0]);
8912 operands[1] = gen_lowpart (QImode, operands[1]);
8913 operands[2] = gen_int_mode (INTVAL (operands[2]), QImode);
8916 (define_insn "*andndi3_doubleword"
8917 [(set (match_operand:DI 0 "register_operand" "=&r,r,r,&r")
8919 (not:DI (match_operand:DI 1 "register_operand" "r,0,r,0"))
8920 (match_operand:DI 2 "nonimmediate_operand" "rm,rm,0,rm")))
8921 (clobber (reg:CC FLAGS_REG))]
8922 "!TARGET_64BIT && TARGET_STV && TARGET_SSE2"
8924 [(set_attr "isa" "bmi,bmi,bmi,*")])
8927 [(set (match_operand:DI 0 "register_operand")
8929 (not:DI (match_operand:DI 1 "register_operand"))
8930 (match_operand:DI 2 "nonimmediate_operand")))
8931 (clobber (reg:CC FLAGS_REG))]
8932 "!TARGET_64BIT && TARGET_BMI && TARGET_STV && TARGET_SSE2
8933 && reload_completed"
8934 [(parallel [(set (match_dup 0)
8935 (and:SI (not:SI (match_dup 1)) (match_dup 2)))
8936 (clobber (reg:CC FLAGS_REG))])
8937 (parallel [(set (match_dup 3)
8938 (and:SI (not:SI (match_dup 4)) (match_dup 5)))
8939 (clobber (reg:CC FLAGS_REG))])]
8940 "split_double_mode (DImode, &operands[0], 3, &operands[0], &operands[3]);")
8943 [(set (match_operand:DI 0 "register_operand")
8945 (not:DI (match_dup 0))
8946 (match_operand:DI 1 "nonimmediate_operand")))
8947 (clobber (reg:CC FLAGS_REG))]
8948 "!TARGET_64BIT && !TARGET_BMI && TARGET_STV && TARGET_SSE2
8949 && reload_completed"
8950 [(set (match_dup 0) (not:SI (match_dup 0)))
8951 (parallel [(set (match_dup 0)
8952 (and:SI (match_dup 0) (match_dup 1)))
8953 (clobber (reg:CC FLAGS_REG))])
8954 (set (match_dup 2) (not:SI (match_dup 2)))
8955 (parallel [(set (match_dup 2)
8956 (and:SI (match_dup 2) (match_dup 3)))
8957 (clobber (reg:CC FLAGS_REG))])]
8958 "split_double_mode (DImode, &operands[0], 2, &operands[0], &operands[2]);")
8960 (define_insn "*andn<mode>_1"
8961 [(set (match_operand:SWI48 0 "register_operand" "=r,r")
8963 (not:SWI48 (match_operand:SWI48 1 "register_operand" "r,r"))
8964 (match_operand:SWI48 2 "nonimmediate_operand" "r,m")))
8965 (clobber (reg:CC FLAGS_REG))]
8967 "andn\t{%2, %1, %0|%0, %1, %2}"
8968 [(set_attr "type" "bitmanip")
8969 (set_attr "btver2_decode" "direct, double")
8970 (set_attr "mode" "<MODE>")])
8972 (define_insn "*andn<mode>_1"
8973 [(set (match_operand:SWI12 0 "register_operand" "=r")
8975 (not:SWI12 (match_operand:SWI12 1 "register_operand" "r"))
8976 (match_operand:SWI12 2 "register_operand" "r")))
8977 (clobber (reg:CC FLAGS_REG))]
8979 "andn\t{%k2, %k1, %k0|%k0, %k1, %k2}"
8980 [(set_attr "type" "bitmanip")
8981 (set_attr "btver2_decode" "direct")
8982 (set_attr "mode" "SI")])
8984 (define_insn "*andn_<mode>_ccno"
8985 [(set (reg FLAGS_REG)
8988 (not:SWI48 (match_operand:SWI48 1 "register_operand" "r,r"))
8989 (match_operand:SWI48 2 "nonimmediate_operand" "r,m"))
8991 (clobber (match_scratch:SWI48 0 "=r,r"))]
8992 "TARGET_BMI && ix86_match_ccmode (insn, CCNOmode)"
8993 "andn\t{%2, %1, %0|%0, %1, %2}"
8994 [(set_attr "type" "bitmanip")
8995 (set_attr "btver2_decode" "direct, double")
8996 (set_attr "mode" "<MODE>")])
8998 ;; Logical inclusive and exclusive OR instructions
9000 ;; %%% This used to optimize known byte-wide and operations to memory.
9001 ;; If this is considered useful, it should be done with splitters.
9003 (define_expand "<code><mode>3"
9004 [(set (match_operand:SWIM1248x 0 "nonimmediate_operand")
9005 (any_or:SWIM1248x (match_operand:SWIM1248x 1 "nonimmediate_operand")
9006 (match_operand:SWIM1248x 2 "<general_operand>")))]
9008 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
9010 (define_insn_and_split "*<code>di3_doubleword"
9011 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r")
9013 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
9014 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm")))
9015 (clobber (reg:CC FLAGS_REG))]
9016 "!TARGET_64BIT && TARGET_STV && TARGET_SSE2
9017 && ix86_binary_operator_ok (<CODE>, DImode, operands)"
9019 "&& reload_completed"
9022 split_double_mode (DImode, &operands[0], 3, &operands[0], &operands[3]);
9023 if (operands[2] == constm1_rtx)
9027 operands[1] = constm1_rtx;
9028 ix86_expand_move (SImode, &operands[0]);
9031 ix86_expand_unary_operator (NOT, SImode, &operands[0]);
9033 else if (operands[2] != const0_rtx)
9034 ix86_expand_binary_operator (<CODE>, SImode, &operands[0]);
9035 else if (operands[5] == const0_rtx)
9036 emit_note (NOTE_INSN_DELETED);
9037 if (operands[5] == constm1_rtx)
9041 operands[4] = constm1_rtx;
9042 ix86_expand_move (SImode, &operands[3]);
9045 ix86_expand_unary_operator (NOT, SImode, &operands[3]);
9047 else if (operands[5] != const0_rtx)
9048 ix86_expand_binary_operator (<CODE>, SImode, &operands[3]);
9052 (define_insn "*<code><mode>_1"
9053 [(set (match_operand:SWI248 0 "nonimmediate_operand" "=r,rm")
9055 (match_operand:SWI248 1 "nonimmediate_operand" "%0,0")
9056 (match_operand:SWI248 2 "<general_operand>" "<g>,r<i>")))
9057 (clobber (reg:CC FLAGS_REG))]
9058 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9059 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
9060 [(set_attr "type" "alu")
9061 (set_attr "mode" "<MODE>")])
9063 (define_insn_and_split "*iordi_1_bts"
9064 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9066 (match_operand:DI 1 "nonimmediate_operand" "%0")
9067 (match_operand:DI 2 "const_int_operand" "n")))
9068 (clobber (reg:CC FLAGS_REG))]
9069 "TARGET_64BIT && TARGET_USE_BT
9070 && ix86_binary_operator_ok (IOR, DImode, operands)
9071 && IN_RANGE (exact_log2 (INTVAL (operands[2])), 31, 63)"
9073 "&& reload_completed"
9074 [(parallel [(set (zero_extract:DI (match_dup 0)
9078 (clobber (reg:CC FLAGS_REG))])]
9079 "operands[3] = GEN_INT (exact_log2 (INTVAL (operands[2])));"
9080 [(set_attr "type" "alu1")
9081 (set_attr "prefix_0f" "1")
9082 (set_attr "znver1_decode" "double")
9083 (set_attr "mode" "DI")])
9085 (define_insn_and_split "*xordi_1_btc"
9086 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9088 (match_operand:DI 1 "nonimmediate_operand" "%0")
9089 (match_operand:DI 2 "const_int_operand" "n")))
9090 (clobber (reg:CC FLAGS_REG))]
9091 "TARGET_64BIT && TARGET_USE_BT
9092 && ix86_binary_operator_ok (XOR, DImode, operands)
9093 && IN_RANGE (exact_log2 (INTVAL (operands[2])), 31, 63)"
9095 "&& reload_completed"
9096 [(parallel [(set (zero_extract:DI (match_dup 0)
9099 (not:DI (zero_extract:DI (match_dup 0)
9102 (clobber (reg:CC FLAGS_REG))])]
9103 "operands[3] = GEN_INT (exact_log2 (INTVAL (operands[2])));"
9104 [(set_attr "type" "alu1")
9105 (set_attr "prefix_0f" "1")
9106 (set_attr "znver1_decode" "double")
9107 (set_attr "mode" "DI")])
9109 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9110 (define_insn "*<code>si_1_zext"
9111 [(set (match_operand:DI 0 "register_operand" "=r")
9113 (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9114 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
9115 (clobber (reg:CC FLAGS_REG))]
9116 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
9117 "<logic>{l}\t{%2, %k0|%k0, %2}"
9118 [(set_attr "type" "alu")
9119 (set_attr "mode" "SI")])
9121 (define_insn "*<code>si_1_zext_imm"
9122 [(set (match_operand:DI 0 "register_operand" "=r")
9124 (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
9125 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
9126 (clobber (reg:CC FLAGS_REG))]
9127 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
9128 "<logic>{l}\t{%2, %k0|%k0, %2}"
9129 [(set_attr "type" "alu")
9130 (set_attr "mode" "SI")])
9132 (define_insn "*<code>qi_1"
9133 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
9134 (any_or:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9135 (match_operand:QI 2 "general_operand" "qmn,qn,rn")))
9136 (clobber (reg:CC FLAGS_REG))]
9137 "ix86_binary_operator_ok (<CODE>, QImode, operands)"
9139 <logic>{b}\t{%2, %0|%0, %2}
9140 <logic>{b}\t{%2, %0|%0, %2}
9141 <logic>{l}\t{%k2, %k0|%k0, %k2}"
9142 [(set_attr "type" "alu")
9143 (set_attr "mode" "QI,QI,SI")
9144 ;; Potential partial reg stall on alternative 2.
9145 (set (attr "preferred_for_speed")
9146 (cond [(eq_attr "alternative" "2")
9147 (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
9148 (symbol_ref "true")))])
9150 (define_insn "*<code>qi_1_slp"
9151 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
9152 (any_or:QI (match_dup 0)
9153 (match_operand:QI 1 "general_operand" "qmn,qn")))
9154 (clobber (reg:CC FLAGS_REG))]
9155 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9156 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9157 "<logic>{b}\t{%1, %0|%0, %1}"
9158 [(set_attr "type" "alu1")
9159 (set_attr "mode" "QI")])
9161 (define_insn "*<code><mode>_2"
9162 [(set (reg FLAGS_REG)
9163 (compare (any_or:SWI
9164 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
9165 (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>"))
9167 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
9168 (any_or:SWI (match_dup 1) (match_dup 2)))]
9169 "ix86_match_ccmode (insn, CCNOmode)
9170 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9171 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
9172 [(set_attr "type" "alu")
9173 (set_attr "mode" "<MODE>")])
9175 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9176 ;; ??? Special case for immediate operand is missing - it is tricky.
9177 (define_insn "*<code>si_2_zext"
9178 [(set (reg FLAGS_REG)
9179 (compare (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9180 (match_operand:SI 2 "x86_64_general_operand" "rme"))
9182 (set (match_operand:DI 0 "register_operand" "=r")
9183 (zero_extend:DI (any_or:SI (match_dup 1) (match_dup 2))))]
9184 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9185 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
9186 "<logic>{l}\t{%2, %k0|%k0, %2}"
9187 [(set_attr "type" "alu")
9188 (set_attr "mode" "SI")])
9190 (define_insn "*<code>si_2_zext_imm"
9191 [(set (reg FLAGS_REG)
9193 (match_operand:SI 1 "nonimmediate_operand" "%0")
9194 (match_operand:SI 2 "x86_64_zext_immediate_operand" "Z"))
9196 (set (match_operand:DI 0 "register_operand" "=r")
9197 (any_or:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
9198 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9199 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
9200 "<logic>{l}\t{%2, %k0|%k0, %2}"
9201 [(set_attr "type" "alu")
9202 (set_attr "mode" "SI")])
9204 (define_insn "*<code>qi_2_slp"
9205 [(set (reg FLAGS_REG)
9206 (compare (any_or:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9207 (match_operand:QI 1 "general_operand" "qmn,qn"))
9209 (set (strict_low_part (match_dup 0))
9210 (any_or:QI (match_dup 0) (match_dup 1)))]
9211 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9212 && ix86_match_ccmode (insn, CCNOmode)
9213 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9214 "<logic>{b}\t{%1, %0|%0, %1}"
9215 [(set_attr "type" "alu1")
9216 (set_attr "mode" "QI")])
9218 (define_insn "*<code><mode>_3"
9219 [(set (reg FLAGS_REG)
9220 (compare (any_or:SWI
9221 (match_operand:SWI 1 "nonimmediate_operand" "%0")
9222 (match_operand:SWI 2 "<general_operand>" "<g>"))
9224 (clobber (match_scratch:SWI 0 "=<r>"))]
9225 "ix86_match_ccmode (insn, CCNOmode)
9226 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9227 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
9228 [(set_attr "type" "alu")
9229 (set_attr "mode" "<MODE>")])
9231 (define_insn "*<code>qi_ext_1"
9232 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q,Q")
9238 (zero_extract:SI (match_operand 1 "ext_register_operand" "0,0")
9241 (match_operand:QI 2 "general_operand" "QnBc,m")) 0))
9242 (clobber (reg:CC FLAGS_REG))]
9243 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9244 /* FIXME: without this LRA can't reload this pattern, see PR82524. */
9245 && rtx_equal_p (operands[0], operands[1])"
9246 "<logic>{b}\t{%2, %h0|%h0, %2}"
9247 [(set_attr "isa" "*,nox64")
9248 (set_attr "type" "alu")
9249 (set_attr "mode" "QI")])
9251 (define_insn "*<code>qi_ext_2"
9252 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
9258 (zero_extract:SI (match_operand 1 "ext_register_operand" "%0")
9262 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9264 (const_int 8)) 0)) 0))
9265 (clobber (reg:CC FLAGS_REG))]
9266 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9267 /* FIXME: without this LRA can't reload this pattern, see PR82524. */
9268 && (rtx_equal_p (operands[0], operands[1])
9269 || rtx_equal_p (operands[0], operands[2]))"
9270 "<logic>{b}\t{%h2, %h0|%h0, %h2}"
9271 [(set_attr "type" "alu")
9272 (set_attr "mode" "QI")])
9274 ;; Convert wide OR instructions with immediate operand to shorter QImode
9275 ;; equivalents when possible.
9276 ;; Don't do the splitting with memory operands, since it introduces risk
9277 ;; of memory mismatch stalls. We may want to do the splitting for optimizing
9278 ;; for size, but that can (should?) be handled by generic code instead.
9280 [(set (match_operand:SWI248 0 "QIreg_operand")
9281 (any_or:SWI248 (match_operand:SWI248 1 "register_operand")
9282 (match_operand:SWI248 2 "const_int_operand")))
9283 (clobber (reg:CC FLAGS_REG))]
9285 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9286 && !(INTVAL (operands[2]) & ~(255 << 8))"
9288 [(set (zero_extract:SI (match_dup 0)
9294 (zero_extract:SI (match_dup 1)
9298 (clobber (reg:CC FLAGS_REG))])]
9300 operands[0] = gen_lowpart (SImode, operands[0]);
9301 operands[1] = gen_lowpart (SImode, operands[1]);
9302 operands[2] = gen_int_mode (INTVAL (operands[2]) >> 8, QImode);
9305 ;; Since OR can be encoded with sign extended immediate, this is only
9306 ;; profitable when 7th bit is set.
9308 [(set (match_operand:SWI248 0 "any_QIreg_operand")
9309 (any_or:SWI248 (match_operand:SWI248 1 "general_operand")
9310 (match_operand:SWI248 2 "const_int_operand")))
9311 (clobber (reg:CC FLAGS_REG))]
9313 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9314 && !(INTVAL (operands[2]) & ~255)
9315 && (INTVAL (operands[2]) & 128)"
9316 [(parallel [(set (strict_low_part (match_dup 0))
9317 (any_or:QI (match_dup 1)
9319 (clobber (reg:CC FLAGS_REG))])]
9321 operands[0] = gen_lowpart (QImode, operands[0]);
9322 operands[1] = gen_lowpart (QImode, operands[1]);
9323 operands[2] = gen_int_mode (INTVAL (operands[2]), QImode);
9326 (define_expand "xorqi_ext_1_cc"
9328 (set (reg:CCNO FLAGS_REG)
9332 (zero_extract:SI (match_operand 1 "ext_register_operand")
9335 (match_operand 2 "const_int_operand"))
9337 (set (zero_extract:SI (match_operand 0 "ext_register_operand")
9343 (zero_extract:SI (match_dup 1)
9346 (match_dup 2)) 0))])])
9348 (define_insn "*xorqi_ext_1_cc"
9349 [(set (reg FLAGS_REG)
9353 (zero_extract:SI (match_operand 1 "ext_register_operand" "0,0")
9356 (match_operand:QI 2 "general_operand" "QnBc,m"))
9358 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q,Q")
9364 (zero_extract:SI (match_dup 1)
9368 "ix86_match_ccmode (insn, CCNOmode)
9369 /* FIXME: without this LRA can't reload this pattern, see PR82524. */
9370 && rtx_equal_p (operands[0], operands[1])"
9371 "xor{b}\t{%2, %h0|%h0, %2}"
9372 [(set_attr "isa" "*,nox64")
9373 (set_attr "type" "alu")
9374 (set_attr "mode" "QI")])
9376 ;; Negation instructions
9378 (define_expand "neg<mode>2"
9379 [(set (match_operand:SDWIM 0 "nonimmediate_operand")
9380 (neg:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")))]
9382 "ix86_expand_unary_operator (NEG, <MODE>mode, operands); DONE;")
9384 (define_insn_and_split "*neg<dwi>2_doubleword"
9385 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro")
9386 (neg:<DWI> (match_operand:<DWI> 1 "nonimmediate_operand" "0")))
9387 (clobber (reg:CC FLAGS_REG))]
9388 "ix86_unary_operator_ok (NEG, <DWI>mode, operands)"
9392 [(set (reg:CCZ FLAGS_REG)
9393 (compare:CCZ (neg:DWIH (match_dup 1)) (const_int 0)))
9394 (set (match_dup 0) (neg:DWIH (match_dup 1)))])
9397 (plus:DWIH (plus:DWIH (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
9400 (clobber (reg:CC FLAGS_REG))])
9403 (neg:DWIH (match_dup 2)))
9404 (clobber (reg:CC FLAGS_REG))])]
9405 "split_double_mode (<DWI>mode, &operands[0], 2, &operands[0], &operands[2]);")
9407 (define_insn "*neg<mode>2_1"
9408 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9409 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")))
9410 (clobber (reg:CC FLAGS_REG))]
9411 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
9412 "neg{<imodesuffix>}\t%0"
9413 [(set_attr "type" "negnot")
9414 (set_attr "mode" "<MODE>")])
9416 ;; Combine is quite creative about this pattern.
9417 (define_insn "*negsi2_1_zext"
9418 [(set (match_operand:DI 0 "register_operand" "=r")
9420 (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
9423 (clobber (reg:CC FLAGS_REG))]
9424 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9426 [(set_attr "type" "negnot")
9427 (set_attr "mode" "SI")])
9429 ;; The problem with neg is that it does not perform (compare x 0),
9430 ;; it really performs (compare 0 x), which leaves us with the zero
9431 ;; flag being the only useful item.
9433 (define_insn "*neg<mode>2_cmpz"
9434 [(set (reg:CCZ FLAGS_REG)
9436 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
9438 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9439 (neg:SWI (match_dup 1)))]
9440 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
9441 "neg{<imodesuffix>}\t%0"
9442 [(set_attr "type" "negnot")
9443 (set_attr "mode" "<MODE>")])
9445 (define_insn "*negsi2_cmpz_zext"
9446 [(set (reg:CCZ FLAGS_REG)
9450 (match_operand:DI 1 "register_operand" "0")
9454 (set (match_operand:DI 0 "register_operand" "=r")
9455 (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
9458 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9460 [(set_attr "type" "negnot")
9461 (set_attr "mode" "SI")])
9463 ;; Negate with jump on overflow.
9464 (define_expand "negv<mode>3"
9465 [(parallel [(set (reg:CCO FLAGS_REG)
9466 (ne:CCO (match_operand:SWI 1 "register_operand")
9468 (set (match_operand:SWI 0 "register_operand")
9469 (neg:SWI (match_dup 1)))])
9470 (set (pc) (if_then_else
9471 (eq (reg:CCO FLAGS_REG) (const_int 0))
9472 (label_ref (match_operand 2))
9477 = gen_int_mode (HOST_WIDE_INT_1U << (GET_MODE_BITSIZE (<MODE>mode) - 1),
9481 (define_insn "*negv<mode>3"
9482 [(set (reg:CCO FLAGS_REG)
9483 (ne:CCO (match_operand:SWI 1 "nonimmediate_operand" "0")
9484 (match_operand:SWI 2 "const_int_operand")))
9485 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9486 (neg:SWI (match_dup 1)))]
9487 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)
9488 && mode_signbit_p (<MODE>mode, operands[2])"
9489 "neg{<imodesuffix>}\t%0"
9490 [(set_attr "type" "negnot")
9491 (set_attr "mode" "<MODE>")])
9493 ;; Changing of sign for FP values is doable using integer unit too.
9495 (define_expand "<code><mode>2"
9496 [(set (match_operand:X87MODEF 0 "register_operand")
9497 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand")))]
9498 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
9499 "ix86_expand_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
9501 (define_insn "*absneg<mode>2"
9502 [(set (match_operand:MODEF 0 "register_operand" "=Yv,Yv,f,!r")
9503 (match_operator:MODEF 3 "absneg_operator"
9504 [(match_operand:MODEF 1 "register_operand" "0,Yv,0,0")]))
9505 (use (match_operand:<ssevecmode> 2 "nonimmediate_operand" "Yvm,0,X,X"))
9506 (clobber (reg:CC FLAGS_REG))]
9507 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
9509 [(set (attr "enabled")
9511 (match_test ("SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"))
9513 (eq_attr "alternative" "2")
9514 (symbol_ref "TARGET_MIX_SSE_I387")
9515 (symbol_ref "true"))
9517 (eq_attr "alternative" "2,3")
9519 (symbol_ref "false"))))])
9521 (define_insn "*absnegxf2_i387"
9522 [(set (match_operand:XF 0 "register_operand" "=f,!r")
9523 (match_operator:XF 3 "absneg_operator"
9524 [(match_operand:XF 1 "register_operand" "0,0")]))
9525 (use (match_operand 2))
9526 (clobber (reg:CC FLAGS_REG))]
9530 (define_expand "<code>tf2"
9531 [(set (match_operand:TF 0 "register_operand")
9532 (absneg:TF (match_operand:TF 1 "register_operand")))]
9534 "ix86_expand_fp_absneg_operator (<CODE>, TFmode, operands); DONE;")
9536 (define_insn "*absnegtf2_sse"
9537 [(set (match_operand:TF 0 "register_operand" "=Yv,Yv")
9538 (match_operator:TF 3 "absneg_operator"
9539 [(match_operand:TF 1 "register_operand" "0,Yv")]))
9540 (use (match_operand:TF 2 "nonimmediate_operand" "Yvm,0"))
9541 (clobber (reg:CC FLAGS_REG))]
9545 ;; Splitters for fp abs and neg.
9548 [(set (match_operand 0 "fp_register_operand")
9549 (match_operator 1 "absneg_operator" [(match_dup 0)]))
9550 (use (match_operand 2))
9551 (clobber (reg:CC FLAGS_REG))]
9553 [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
9556 [(set (match_operand 0 "sse_reg_operand")
9557 (match_operator 3 "absneg_operator"
9558 [(match_operand 1 "register_operand")]))
9559 (use (match_operand 2 "nonimmediate_operand"))
9560 (clobber (reg:CC FLAGS_REG))]
9562 [(set (match_dup 0) (match_dup 3))]
9564 machine_mode mode = GET_MODE (operands[0]);
9565 machine_mode vmode = GET_MODE (operands[2]);
9568 operands[0] = lowpart_subreg (vmode, operands[0], mode);
9569 operands[1] = lowpart_subreg (vmode, operands[1], mode);
9570 if (operands_match_p (operands[0], operands[2]))
9571 std::swap (operands[1], operands[2]);
9572 if (GET_CODE (operands[3]) == ABS)
9573 tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
9575 tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
9580 [(set (match_operand:SF 0 "general_reg_operand")
9581 (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
9582 (use (match_operand:V4SF 2))
9583 (clobber (reg:CC FLAGS_REG))]
9585 [(parallel [(set (match_dup 0) (match_dup 1))
9586 (clobber (reg:CC FLAGS_REG))])]
9589 operands[0] = gen_lowpart (SImode, operands[0]);
9590 if (GET_CODE (operands[1]) == ABS)
9592 tmp = gen_int_mode (0x7fffffff, SImode);
9593 tmp = gen_rtx_AND (SImode, operands[0], tmp);
9597 tmp = gen_int_mode (0x80000000, SImode);
9598 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9604 [(set (match_operand:DF 0 "general_reg_operand")
9605 (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
9606 (use (match_operand 2))
9607 (clobber (reg:CC FLAGS_REG))]
9609 [(parallel [(set (match_dup 0) (match_dup 1))
9610 (clobber (reg:CC FLAGS_REG))])]
9615 tmp = gen_lowpart (DImode, operands[0]);
9616 tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
9619 if (GET_CODE (operands[1]) == ABS)
9622 tmp = gen_rtx_NOT (DImode, tmp);
9626 operands[0] = gen_highpart (SImode, operands[0]);
9627 if (GET_CODE (operands[1]) == ABS)
9629 tmp = gen_int_mode (0x7fffffff, SImode);
9630 tmp = gen_rtx_AND (SImode, operands[0], tmp);
9634 tmp = gen_int_mode (0x80000000, SImode);
9635 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9642 [(set (match_operand:XF 0 "general_reg_operand")
9643 (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
9644 (use (match_operand 2))
9645 (clobber (reg:CC FLAGS_REG))]
9647 [(parallel [(set (match_dup 0) (match_dup 1))
9648 (clobber (reg:CC FLAGS_REG))])]
9651 operands[0] = gen_rtx_REG (SImode,
9652 REGNO (operands[0]) + (TARGET_64BIT ? 1 : 2));
9653 if (GET_CODE (operands[1]) == ABS)
9655 tmp = GEN_INT (0x7fff);
9656 tmp = gen_rtx_AND (SImode, operands[0], tmp);
9660 tmp = GEN_INT (0x8000);
9661 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9666 ;; Conditionalize these after reload. If they match before reload, we
9667 ;; lose the clobber and ability to use integer instructions.
9669 (define_insn "*<code><mode>2_1"
9670 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
9671 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "0")))]
9673 && (reload_completed
9674 || !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
9676 [(set_attr "type" "fsgn")
9677 (set_attr "mode" "<MODE>")])
9679 ;; Copysign instructions
9681 (define_mode_iterator CSGNMODE [SF DF TF])
9682 (define_mode_attr CSGNVMODE [(SF "V4SF") (DF "V2DF") (TF "TF")])
9684 (define_expand "copysign<mode>3"
9685 [(match_operand:CSGNMODE 0 "register_operand")
9686 (match_operand:CSGNMODE 1 "nonmemory_operand")
9687 (match_operand:CSGNMODE 2 "register_operand")]
9688 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
9689 || (TARGET_SSE && (<MODE>mode == TFmode))"
9690 "ix86_expand_copysign (operands); DONE;")
9692 (define_insn_and_split "copysign<mode>3_const"
9693 [(set (match_operand:CSGNMODE 0 "register_operand" "=Yv")
9695 [(match_operand:<CSGNVMODE> 1 "nonimm_or_0_operand" "YvmC")
9696 (match_operand:CSGNMODE 2 "register_operand" "0")
9697 (match_operand:<CSGNVMODE> 3 "nonimmediate_operand" "Yvm")]
9699 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
9700 || (TARGET_SSE && (<MODE>mode == TFmode))"
9702 "&& reload_completed"
9704 "ix86_split_copysign_const (operands); DONE;")
9706 (define_insn "copysign<mode>3_var"
9707 [(set (match_operand:CSGNMODE 0 "register_operand" "=Yv,Yv,Yv,Yv,Yv")
9709 [(match_operand:CSGNMODE 2 "register_operand" "Yv,0,0,Yv,Yv")
9710 (match_operand:CSGNMODE 3 "register_operand" "1,1,Yv,1,Yv")
9711 (match_operand:<CSGNVMODE> 4
9712 "nonimmediate_operand" "X,Yvm,Yvm,0,0")
9713 (match_operand:<CSGNVMODE> 5
9714 "nonimmediate_operand" "0,Yvm,1,Yvm,1")]
9716 (clobber (match_scratch:<CSGNVMODE> 1 "=Yv,Yv,Yv,Yv,Yv"))]
9717 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
9718 || (TARGET_SSE && (<MODE>mode == TFmode))"
9722 [(set (match_operand:CSGNMODE 0 "register_operand")
9724 [(match_operand:CSGNMODE 2 "register_operand")
9725 (match_operand:CSGNMODE 3 "register_operand")
9726 (match_operand:<CSGNVMODE> 4)
9727 (match_operand:<CSGNVMODE> 5)]
9729 (clobber (match_scratch:<CSGNVMODE> 1))]
9730 "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
9731 || (TARGET_SSE && (<MODE>mode == TFmode)))
9732 && reload_completed"
9734 "ix86_split_copysign_var (operands); DONE;")
9736 ;; One complement instructions
9738 (define_expand "one_cmpl<mode>2"
9739 [(set (match_operand:SWIM1248x 0 "nonimmediate_operand")
9740 (not:SWIM1248x (match_operand:SWIM1248x 1 "nonimmediate_operand")))]
9742 "ix86_expand_unary_operator (NOT, <MODE>mode, operands); DONE;")
9744 (define_insn_and_split "*one_cmpldi2_doubleword"
9745 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9746 (not:DI (match_operand:DI 1 "nonimmediate_operand" "0")))]
9747 "!TARGET_64BIT && TARGET_STV && TARGET_SSE2
9748 && ix86_unary_operator_ok (NOT, DImode, operands)"
9750 "&& reload_completed"
9752 (not:SI (match_dup 1)))
9754 (not:SI (match_dup 3)))]
9755 "split_double_mode (DImode, &operands[0], 2, &operands[0], &operands[2]);")
9757 (define_insn "*one_cmpl<mode>2_1"
9758 [(set (match_operand:SWI248 0 "nonimmediate_operand" "=rm")
9759 (not:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "0")))]
9760 "ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
9761 "not{<imodesuffix>}\t%0"
9762 [(set_attr "type" "negnot")
9763 (set_attr "mode" "<MODE>")])
9765 ;; ??? Currently never generated - xor is used instead.
9766 (define_insn "*one_cmplsi2_1_zext"
9767 [(set (match_operand:DI 0 "register_operand" "=r")
9769 (not:SI (match_operand:SI 1 "register_operand" "0"))))]
9770 "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
9772 [(set_attr "type" "negnot")
9773 (set_attr "mode" "SI")])
9775 (define_insn "*one_cmplqi2_1"
9776 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
9777 (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
9778 "ix86_unary_operator_ok (NOT, QImode, operands)"
9782 [(set_attr "type" "negnot")
9783 (set_attr "mode" "QI,SI")
9784 ;; Potential partial reg stall on alternative 1.
9785 (set (attr "preferred_for_speed")
9786 (cond [(eq_attr "alternative" "1")
9787 (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
9788 (symbol_ref "true")))])
9790 (define_insn "*one_cmpl<mode>2_2"
9791 [(set (reg FLAGS_REG)
9792 (compare (not:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
9794 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9795 (not:SWI (match_dup 1)))]
9796 "ix86_match_ccmode (insn, CCNOmode)
9797 && ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
9799 [(set_attr "type" "alu1")
9800 (set_attr "mode" "<MODE>")])
9803 [(set (match_operand 0 "flags_reg_operand")
9804 (match_operator 2 "compare_operator"
9805 [(not:SWI (match_operand:SWI 3 "nonimmediate_operand"))
9807 (set (match_operand:SWI 1 "nonimmediate_operand")
9808 (not:SWI (match_dup 3)))]
9809 "ix86_match_ccmode (insn, CCNOmode)"
9810 [(parallel [(set (match_dup 0)
9811 (match_op_dup 2 [(xor:SWI (match_dup 3) (const_int -1))
9814 (xor:SWI (match_dup 3) (const_int -1)))])])
9816 ;; ??? Currently never generated - xor is used instead.
9817 (define_insn "*one_cmplsi2_2_zext"
9818 [(set (reg FLAGS_REG)
9819 (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
9821 (set (match_operand:DI 0 "register_operand" "=r")
9822 (zero_extend:DI (not:SI (match_dup 1))))]
9823 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9824 && ix86_unary_operator_ok (NOT, SImode, operands)"
9826 [(set_attr "type" "alu1")
9827 (set_attr "mode" "SI")])
9830 [(set (match_operand 0 "flags_reg_operand")
9831 (match_operator 2 "compare_operator"
9832 [(not:SI (match_operand:SI 3 "register_operand"))
9834 (set (match_operand:DI 1 "register_operand")
9835 (zero_extend:DI (not:SI (match_dup 3))))]
9836 "ix86_match_ccmode (insn, CCNOmode)"
9837 [(parallel [(set (match_dup 0)
9838 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
9841 (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])])
9843 ;; Shift instructions
9845 ;; DImode shifts are implemented using the i386 "shift double" opcode,
9846 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem". If the shift count
9847 ;; is variable, then the count is in %cl and the "imm" operand is dropped
9848 ;; from the assembler input.
9850 ;; This instruction shifts the target reg/mem as usual, but instead of
9851 ;; shifting in zeros, bits are shifted in from reg operand. If the insn
9852 ;; is a left shift double, bits are taken from the high order bits of
9853 ;; reg, else if the insn is a shift right double, bits are taken from the
9854 ;; low order bits of reg. So if %eax is "1234" and %edx is "5678",
9855 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
9857 ;; Since sh[lr]d does not change the `reg' operand, that is done
9858 ;; separately, making all shifts emit pairs of shift double and normal
9859 ;; shift. Since sh[lr]d does not shift more than 31 bits, and we wish to
9860 ;; support a 63 bit shift, each shift where the count is in a reg expands
9861 ;; to a pair of shifts, a branch, a shift by 32 and a label.
9863 ;; If the shift count is a constant, we need never emit more than one
9864 ;; shift pair, instead using moves and sign extension for counts greater
9867 (define_expand "ashl<mode>3"
9868 [(set (match_operand:SDWIM 0 "<shift_operand>")
9869 (ashift:SDWIM (match_operand:SDWIM 1 "<ashl_input_operand>")
9870 (match_operand:QI 2 "nonmemory_operand")))]
9872 "ix86_expand_binary_operator (ASHIFT, <MODE>mode, operands); DONE;")
9874 (define_insn_and_split "*ashl<dwi>3_doubleword_mask"
9875 [(set (match_operand:<DWI> 0 "register_operand")
9877 (match_operand:<DWI> 1 "register_operand")
9880 (match_operand:SI 2 "register_operand" "c")
9881 (match_operand:SI 3 "const_int_operand")) 0)))
9882 (clobber (reg:CC FLAGS_REG))]
9883 "(INTVAL (operands[3]) & (<MODE_SIZE> * BITS_PER_UNIT)) == 0
9884 && can_create_pseudo_p ()"
9889 (ior:DWIH (ashift:DWIH (match_dup 6) (match_dup 2))
9890 (lshiftrt:DWIH (match_dup 5)
9891 (minus:QI (match_dup 8) (match_dup 2)))))
9892 (clobber (reg:CC FLAGS_REG))])
9895 (ashift:DWIH (match_dup 5) (match_dup 2)))
9896 (clobber (reg:CC FLAGS_REG))])]
9898 split_double_mode (<DWI>mode, &operands[0], 2, &operands[4], &operands[6]);
9900 operands[8] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT);
9902 if ((INTVAL (operands[3]) & ((<MODE_SIZE> * BITS_PER_UNIT) - 1))
9903 != ((<MODE_SIZE> * BITS_PER_UNIT) - 1))
9905 rtx tem = gen_reg_rtx (SImode);
9906 emit_insn (gen_andsi3 (tem, operands[2], operands[3]));
9910 operands[2] = gen_lowpart (QImode, operands[2]);
9912 if (!rtx_equal_p (operands[6], operands[7]))
9913 emit_move_insn (operands[6], operands[7]);
9916 (define_insn_and_split "*ashl<dwi>3_doubleword_mask_1"
9917 [(set (match_operand:<DWI> 0 "register_operand")
9919 (match_operand:<DWI> 1 "register_operand")
9921 (match_operand:QI 2 "register_operand" "c")
9922 (match_operand:QI 3 "const_int_operand"))))
9923 (clobber (reg:CC FLAGS_REG))]
9924 "(INTVAL (operands[3]) & (<MODE_SIZE> * BITS_PER_UNIT)) == 0
9925 && can_create_pseudo_p ()"
9930 (ior:DWIH (ashift:DWIH (match_dup 6) (match_dup 2))
9931 (lshiftrt:DWIH (match_dup 5)
9932 (minus:QI (match_dup 8) (match_dup 2)))))
9933 (clobber (reg:CC FLAGS_REG))])
9936 (ashift:DWIH (match_dup 5) (match_dup 2)))
9937 (clobber (reg:CC FLAGS_REG))])]
9939 split_double_mode (<DWI>mode, &operands[0], 2, &operands[4], &operands[6]);
9941 operands[8] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT);
9943 if ((INTVAL (operands[3]) & ((<MODE_SIZE> * BITS_PER_UNIT) - 1))
9944 != ((<MODE_SIZE> * BITS_PER_UNIT) - 1))
9946 rtx tem = gen_reg_rtx (QImode);
9947 emit_insn (gen_andqi3 (tem, operands[2], operands[3]));
9951 if (!rtx_equal_p (operands[6], operands[7]))
9952 emit_move_insn (operands[6], operands[7]);
9955 (define_insn "*ashl<mode>3_doubleword"
9956 [(set (match_operand:DWI 0 "register_operand" "=&r")
9957 (ashift:DWI (match_operand:DWI 1 "reg_or_pm1_operand" "0n")
9958 (match_operand:QI 2 "nonmemory_operand" "<S>c")))
9959 (clobber (reg:CC FLAGS_REG))]
9962 [(set_attr "type" "multi")])
9965 [(set (match_operand:DWI 0 "register_operand")
9966 (ashift:DWI (match_operand:DWI 1 "nonmemory_operand")
9967 (match_operand:QI 2 "nonmemory_operand")))
9968 (clobber (reg:CC FLAGS_REG))]
9969 "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
9971 "ix86_split_ashl (operands, NULL_RTX, <MODE>mode); DONE;")
9973 ;; By default we don't ask for a scratch register, because when DWImode
9974 ;; values are manipulated, registers are already at a premium. But if
9975 ;; we have one handy, we won't turn it away.
9978 [(match_scratch:DWIH 3 "r")
9979 (parallel [(set (match_operand:<DWI> 0 "register_operand")
9981 (match_operand:<DWI> 1 "nonmemory_operand")
9982 (match_operand:QI 2 "nonmemory_operand")))
9983 (clobber (reg:CC FLAGS_REG))])
9987 "ix86_split_ashl (operands, operands[3], <DWI>mode); DONE;")
9989 (define_insn "x86_64_shld"
9990 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
9991 (ior:DI (ashift:DI (match_dup 0)
9992 (match_operand:QI 2 "nonmemory_operand" "Jc"))
9993 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
9994 (minus:QI (const_int 64) (match_dup 2)))))
9995 (clobber (reg:CC FLAGS_REG))]
9997 "shld{q}\t{%s2%1, %0|%0, %1, %2}"
9998 [(set_attr "type" "ishift")
9999 (set_attr "prefix_0f" "1")
10000 (set_attr "mode" "DI")
10001 (set_attr "athlon_decode" "vector")
10002 (set_attr "amdfam10_decode" "vector")
10003 (set_attr "bdver1_decode" "vector")])
10005 (define_insn "x86_shld"
10006 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
10007 (ior:SI (ashift:SI (match_dup 0)
10008 (match_operand:QI 2 "nonmemory_operand" "Ic"))
10009 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
10010 (minus:QI (const_int 32) (match_dup 2)))))
10011 (clobber (reg:CC FLAGS_REG))]
10013 "shld{l}\t{%s2%1, %0|%0, %1, %2}"
10014 [(set_attr "type" "ishift")
10015 (set_attr "prefix_0f" "1")
10016 (set_attr "mode" "SI")
10017 (set_attr "pent_pair" "np")
10018 (set_attr "athlon_decode" "vector")
10019 (set_attr "amdfam10_decode" "vector")
10020 (set_attr "bdver1_decode" "vector")])
10022 (define_expand "x86_shift<mode>_adj_1"
10023 [(set (reg:CCZ FLAGS_REG)
10024 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand")
10027 (set (match_operand:SWI48 0 "register_operand")
10028 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
10029 (match_operand:SWI48 1 "register_operand")
10032 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
10033 (match_operand:SWI48 3 "register_operand")
10036 "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
10038 (define_expand "x86_shift<mode>_adj_2"
10039 [(use (match_operand:SWI48 0 "register_operand"))
10040 (use (match_operand:SWI48 1 "register_operand"))
10041 (use (match_operand:QI 2 "register_operand"))]
10044 rtx_code_label *label = gen_label_rtx ();
10047 emit_insn (gen_testqi_ccz_1 (operands[2],
10048 GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
10050 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
10051 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
10052 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
10053 gen_rtx_LABEL_REF (VOIDmode, label),
10055 tmp = emit_jump_insn (gen_rtx_SET (pc_rtx, tmp));
10056 JUMP_LABEL (tmp) = label;
10058 emit_move_insn (operands[0], operands[1]);
10059 ix86_expand_clear (operands[1]);
10061 emit_label (label);
10062 LABEL_NUSES (label) = 1;
10067 ;; Avoid useless masking of count operand.
10068 (define_insn_and_split "*ashl<mode>3_mask"
10069 [(set (match_operand:SWI48 0 "nonimmediate_operand")
10071 (match_operand:SWI48 1 "nonimmediate_operand")
10074 (match_operand:SI 2 "register_operand" "c,r")
10075 (match_operand:SI 3 "const_int_operand")) 0)))
10076 (clobber (reg:CC FLAGS_REG))]
10077 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)
10078 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10079 == GET_MODE_BITSIZE (<MODE>mode)-1
10080 && can_create_pseudo_p ()"
10084 [(set (match_dup 0)
10085 (ashift:SWI48 (match_dup 1)
10087 (clobber (reg:CC FLAGS_REG))])]
10088 "operands[2] = gen_lowpart (QImode, operands[2]);"
10089 [(set_attr "isa" "*,bmi2")])
10091 (define_insn_and_split "*ashl<mode>3_mask_1"
10092 [(set (match_operand:SWI48 0 "nonimmediate_operand")
10094 (match_operand:SWI48 1 "nonimmediate_operand")
10096 (match_operand:QI 2 "register_operand" "c,r")
10097 (match_operand:QI 3 "const_int_operand"))))
10098 (clobber (reg:CC FLAGS_REG))]
10099 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)
10100 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10101 == GET_MODE_BITSIZE (<MODE>mode)-1
10102 && can_create_pseudo_p ()"
10106 [(set (match_dup 0)
10107 (ashift:SWI48 (match_dup 1)
10109 (clobber (reg:CC FLAGS_REG))])]
10111 [(set_attr "isa" "*,bmi2")])
10113 (define_insn "*bmi2_ashl<mode>3_1"
10114 [(set (match_operand:SWI48 0 "register_operand" "=r")
10115 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
10116 (match_operand:SWI48 2 "register_operand" "r")))]
10118 "shlx\t{%2, %1, %0|%0, %1, %2}"
10119 [(set_attr "type" "ishiftx")
10120 (set_attr "mode" "<MODE>")])
10122 (define_insn "*ashl<mode>3_1"
10123 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r,r")
10124 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,l,rm")
10125 (match_operand:QI 2 "nonmemory_operand" "c<S>,M,r")))
10126 (clobber (reg:CC FLAGS_REG))]
10127 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
10129 switch (get_attr_type (insn))
10136 gcc_assert (operands[2] == const1_rtx);
10137 gcc_assert (rtx_equal_p (operands[0], operands[1]));
10138 return "add{<imodesuffix>}\t%0, %0";
10141 if (operands[2] == const1_rtx
10142 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10143 return "sal{<imodesuffix>}\t%0";
10145 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
10148 [(set_attr "isa" "*,*,bmi2")
10150 (cond [(eq_attr "alternative" "1")
10151 (const_string "lea")
10152 (eq_attr "alternative" "2")
10153 (const_string "ishiftx")
10154 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
10155 (match_operand 0 "register_operand"))
10156 (match_operand 2 "const1_operand"))
10157 (const_string "alu")
10159 (const_string "ishift")))
10160 (set (attr "length_immediate")
10162 (ior (eq_attr "type" "alu")
10163 (and (eq_attr "type" "ishift")
10164 (and (match_operand 2 "const1_operand")
10165 (ior (match_test "TARGET_SHIFT1")
10166 (match_test "optimize_function_for_size_p (cfun)")))))
10168 (const_string "*")))
10169 (set_attr "mode" "<MODE>")])
10171 ;; Convert shift to the shiftx pattern to avoid flags dependency.
10173 [(set (match_operand:SWI48 0 "register_operand")
10174 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
10175 (match_operand:QI 2 "register_operand")))
10176 (clobber (reg:CC FLAGS_REG))]
10177 "TARGET_BMI2 && reload_completed"
10178 [(set (match_dup 0)
10179 (ashift:SWI48 (match_dup 1) (match_dup 2)))]
10180 "operands[2] = gen_lowpart (<MODE>mode, operands[2]);")
10182 (define_insn "*bmi2_ashlsi3_1_zext"
10183 [(set (match_operand:DI 0 "register_operand" "=r")
10185 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
10186 (match_operand:SI 2 "register_operand" "r"))))]
10187 "TARGET_64BIT && TARGET_BMI2"
10188 "shlx\t{%2, %1, %k0|%k0, %1, %2}"
10189 [(set_attr "type" "ishiftx")
10190 (set_attr "mode" "SI")])
10192 (define_insn "*ashlsi3_1_zext"
10193 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
10195 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l,rm")
10196 (match_operand:QI 2 "nonmemory_operand" "cI,M,r"))))
10197 (clobber (reg:CC FLAGS_REG))]
10198 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10200 switch (get_attr_type (insn))
10207 gcc_assert (operands[2] == const1_rtx);
10208 return "add{l}\t%k0, %k0";
10211 if (operands[2] == const1_rtx
10212 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10213 return "sal{l}\t%k0";
10215 return "sal{l}\t{%2, %k0|%k0, %2}";
10218 [(set_attr "isa" "*,*,bmi2")
10220 (cond [(eq_attr "alternative" "1")
10221 (const_string "lea")
10222 (eq_attr "alternative" "2")
10223 (const_string "ishiftx")
10224 (and (match_test "TARGET_DOUBLE_WITH_ADD")
10225 (match_operand 2 "const1_operand"))
10226 (const_string "alu")
10228 (const_string "ishift")))
10229 (set (attr "length_immediate")
10231 (ior (eq_attr "type" "alu")
10232 (and (eq_attr "type" "ishift")
10233 (and (match_operand 2 "const1_operand")
10234 (ior (match_test "TARGET_SHIFT1")
10235 (match_test "optimize_function_for_size_p (cfun)")))))
10237 (const_string "*")))
10238 (set_attr "mode" "SI")])
10240 ;; Convert shift to the shiftx pattern to avoid flags dependency.
10242 [(set (match_operand:DI 0 "register_operand")
10244 (ashift:SI (match_operand:SI 1 "nonimmediate_operand")
10245 (match_operand:QI 2 "register_operand"))))
10246 (clobber (reg:CC FLAGS_REG))]
10247 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
10248 [(set (match_dup 0)
10249 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
10250 "operands[2] = gen_lowpart (SImode, operands[2]);")
10252 (define_insn "*ashlhi3_1"
10253 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,Yp")
10254 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
10255 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10256 (clobber (reg:CC FLAGS_REG))]
10257 "ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10259 switch (get_attr_type (insn))
10265 gcc_assert (operands[2] == const1_rtx);
10266 return "add{w}\t%0, %0";
10269 if (operands[2] == const1_rtx
10270 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10271 return "sal{w}\t%0";
10273 return "sal{w}\t{%2, %0|%0, %2}";
10276 [(set (attr "type")
10277 (cond [(eq_attr "alternative" "1")
10278 (const_string "lea")
10279 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
10280 (match_operand 0 "register_operand"))
10281 (match_operand 2 "const1_operand"))
10282 (const_string "alu")
10284 (const_string "ishift")))
10285 (set (attr "length_immediate")
10287 (ior (eq_attr "type" "alu")
10288 (and (eq_attr "type" "ishift")
10289 (and (match_operand 2 "const1_operand")
10290 (ior (match_test "TARGET_SHIFT1")
10291 (match_test "optimize_function_for_size_p (cfun)")))))
10293 (const_string "*")))
10294 (set_attr "mode" "HI,SI")])
10296 (define_insn "*ashlqi3_1"
10297 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,Yp")
10298 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
10299 (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
10300 (clobber (reg:CC FLAGS_REG))]
10301 "ix86_binary_operator_ok (ASHIFT, QImode, operands)"
10303 switch (get_attr_type (insn))
10309 gcc_assert (operands[2] == const1_rtx);
10310 if (REG_P (operands[1]) && !ANY_QI_REGNO_P (REGNO (operands[1])))
10311 return "add{l}\t%k0, %k0";
10313 return "add{b}\t%0, %0";
10316 if (operands[2] == const1_rtx
10317 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10319 if (get_attr_mode (insn) == MODE_SI)
10320 return "sal{l}\t%k0";
10322 return "sal{b}\t%0";
10326 if (get_attr_mode (insn) == MODE_SI)
10327 return "sal{l}\t{%2, %k0|%k0, %2}";
10329 return "sal{b}\t{%2, %0|%0, %2}";
10333 [(set (attr "type")
10334 (cond [(eq_attr "alternative" "2")
10335 (const_string "lea")
10336 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
10337 (match_operand 0 "register_operand"))
10338 (match_operand 2 "const1_operand"))
10339 (const_string "alu")
10341 (const_string "ishift")))
10342 (set (attr "length_immediate")
10344 (ior (eq_attr "type" "alu")
10345 (and (eq_attr "type" "ishift")
10346 (and (match_operand 2 "const1_operand")
10347 (ior (match_test "TARGET_SHIFT1")
10348 (match_test "optimize_function_for_size_p (cfun)")))))
10350 (const_string "*")))
10351 (set_attr "mode" "QI,SI,SI")
10352 ;; Potential partial reg stall on alternative 1.
10353 (set (attr "preferred_for_speed")
10354 (cond [(eq_attr "alternative" "1")
10355 (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
10356 (symbol_ref "true")))])
10358 (define_insn "*ashlqi3_1_slp"
10359 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10360 (ashift:QI (match_dup 0)
10361 (match_operand:QI 1 "nonmemory_operand" "cI")))
10362 (clobber (reg:CC FLAGS_REG))]
10363 "(optimize_function_for_size_p (cfun)
10364 || !TARGET_PARTIAL_FLAG_REG_STALL
10365 || (operands[1] == const1_rtx
10367 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
10369 switch (get_attr_type (insn))
10372 gcc_assert (operands[1] == const1_rtx);
10373 return "add{b}\t%0, %0";
10376 if (operands[1] == const1_rtx
10377 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10378 return "sal{b}\t%0";
10380 return "sal{b}\t{%1, %0|%0, %1}";
10383 [(set (attr "type")
10384 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
10385 (match_operand 0 "register_operand"))
10386 (match_operand 1 "const1_operand"))
10387 (const_string "alu1")
10389 (const_string "ishift1")))
10390 (set (attr "length_immediate")
10392 (ior (eq_attr "type" "alu1")
10393 (and (eq_attr "type" "ishift1")
10394 (and (match_operand 1 "const1_operand")
10395 (ior (match_test "TARGET_SHIFT1")
10396 (match_test "optimize_function_for_size_p (cfun)")))))
10398 (const_string "*")))
10399 (set_attr "mode" "QI")])
10401 ;; Convert ashift to the lea pattern to avoid flags dependency.
10403 [(set (match_operand:SWI 0 "register_operand")
10404 (ashift:SWI (match_operand:SWI 1 "index_register_operand")
10405 (match_operand 2 "const_0_to_3_operand")))
10406 (clobber (reg:CC FLAGS_REG))]
10408 && REGNO (operands[0]) != REGNO (operands[1])"
10409 [(set (match_dup 0)
10410 (mult:<LEAMODE> (match_dup 1) (match_dup 2)))]
10412 if (<MODE>mode != <LEAMODE>mode)
10414 operands[0] = gen_lowpart (<LEAMODE>mode, operands[0]);
10415 operands[1] = gen_lowpart (<LEAMODE>mode, operands[1]);
10417 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
10420 ;; Convert ashift to the lea pattern to avoid flags dependency.
10422 [(set (match_operand:DI 0 "register_operand")
10424 (ashift:SI (match_operand:SI 1 "index_register_operand")
10425 (match_operand 2 "const_0_to_3_operand"))))
10426 (clobber (reg:CC FLAGS_REG))]
10427 "TARGET_64BIT && reload_completed
10428 && REGNO (operands[0]) != REGNO (operands[1])"
10429 [(set (match_dup 0)
10430 (zero_extend:DI (mult:SI (match_dup 1) (match_dup 2))))]
10432 operands[1] = gen_lowpart (SImode, operands[1]);
10433 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
10436 ;; This pattern can't accept a variable shift count, since shifts by
10437 ;; zero don't affect the flags. We assume that shifts by constant
10438 ;; zero are optimized away.
10439 (define_insn "*ashl<mode>3_cmp"
10440 [(set (reg FLAGS_REG)
10442 (ashift:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
10443 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
10445 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
10446 (ashift:SWI (match_dup 1) (match_dup 2)))]
10447 "(optimize_function_for_size_p (cfun)
10448 || !TARGET_PARTIAL_FLAG_REG_STALL
10449 || (operands[2] == const1_rtx
10451 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
10452 && ix86_match_ccmode (insn, CCGOCmode)
10453 && ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
10455 switch (get_attr_type (insn))
10458 gcc_assert (operands[2] == const1_rtx);
10459 return "add{<imodesuffix>}\t%0, %0";
10462 if (operands[2] == const1_rtx
10463 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10464 return "sal{<imodesuffix>}\t%0";
10466 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
10469 [(set (attr "type")
10470 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
10471 (match_operand 0 "register_operand"))
10472 (match_operand 2 "const1_operand"))
10473 (const_string "alu")
10475 (const_string "ishift")))
10476 (set (attr "length_immediate")
10478 (ior (eq_attr "type" "alu")
10479 (and (eq_attr "type" "ishift")
10480 (and (match_operand 2 "const1_operand")
10481 (ior (match_test "TARGET_SHIFT1")
10482 (match_test "optimize_function_for_size_p (cfun)")))))
10484 (const_string "*")))
10485 (set_attr "mode" "<MODE>")])
10487 (define_insn "*ashlsi3_cmp_zext"
10488 [(set (reg FLAGS_REG)
10490 (ashift:SI (match_operand:SI 1 "register_operand" "0")
10491 (match_operand:QI 2 "const_1_to_31_operand" "I"))
10493 (set (match_operand:DI 0 "register_operand" "=r")
10494 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
10496 && (optimize_function_for_size_p (cfun)
10497 || !TARGET_PARTIAL_FLAG_REG_STALL
10498 || (operands[2] == const1_rtx
10500 || TARGET_DOUBLE_WITH_ADD)))
10501 && ix86_match_ccmode (insn, CCGOCmode)
10502 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10504 switch (get_attr_type (insn))
10507 gcc_assert (operands[2] == const1_rtx);
10508 return "add{l}\t%k0, %k0";
10511 if (operands[2] == const1_rtx
10512 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10513 return "sal{l}\t%k0";
10515 return "sal{l}\t{%2, %k0|%k0, %2}";
10518 [(set (attr "type")
10519 (cond [(and (match_test "TARGET_DOUBLE_WITH_ADD")
10520 (match_operand 2 "const1_operand"))
10521 (const_string "alu")
10523 (const_string "ishift")))
10524 (set (attr "length_immediate")
10526 (ior (eq_attr "type" "alu")
10527 (and (eq_attr "type" "ishift")
10528 (and (match_operand 2 "const1_operand")
10529 (ior (match_test "TARGET_SHIFT1")
10530 (match_test "optimize_function_for_size_p (cfun)")))))
10532 (const_string "*")))
10533 (set_attr "mode" "SI")])
10535 (define_insn "*ashl<mode>3_cconly"
10536 [(set (reg FLAGS_REG)
10538 (ashift:SWI (match_operand:SWI 1 "register_operand" "0")
10539 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
10541 (clobber (match_scratch:SWI 0 "=<r>"))]
10542 "(optimize_function_for_size_p (cfun)
10543 || !TARGET_PARTIAL_FLAG_REG_STALL
10544 || (operands[2] == const1_rtx
10546 || TARGET_DOUBLE_WITH_ADD)))
10547 && ix86_match_ccmode (insn, CCGOCmode)"
10549 switch (get_attr_type (insn))
10552 gcc_assert (operands[2] == const1_rtx);
10553 return "add{<imodesuffix>}\t%0, %0";
10556 if (operands[2] == const1_rtx
10557 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10558 return "sal{<imodesuffix>}\t%0";
10560 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
10563 [(set (attr "type")
10564 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
10565 (match_operand 0 "register_operand"))
10566 (match_operand 2 "const1_operand"))
10567 (const_string "alu")
10569 (const_string "ishift")))
10570 (set (attr "length_immediate")
10572 (ior (eq_attr "type" "alu")
10573 (and (eq_attr "type" "ishift")
10574 (and (match_operand 2 "const1_operand")
10575 (ior (match_test "TARGET_SHIFT1")
10576 (match_test "optimize_function_for_size_p (cfun)")))))
10578 (const_string "*")))
10579 (set_attr "mode" "<MODE>")])
10581 ;; See comment above `ashl<mode>3' about how this works.
10583 (define_expand "<shift_insn><mode>3"
10584 [(set (match_operand:SDWIM 0 "<shift_operand>")
10585 (any_shiftrt:SDWIM (match_operand:SDWIM 1 "<shift_operand>")
10586 (match_operand:QI 2 "nonmemory_operand")))]
10588 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
10590 ;; Avoid useless masking of count operand.
10591 (define_insn_and_split "*<shift_insn><mode>3_mask"
10592 [(set (match_operand:SWI48 0 "nonimmediate_operand")
10594 (match_operand:SWI48 1 "nonimmediate_operand")
10597 (match_operand:SI 2 "register_operand" "c,r")
10598 (match_operand:SI 3 "const_int_operand")) 0)))
10599 (clobber (reg:CC FLAGS_REG))]
10600 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
10601 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10602 == GET_MODE_BITSIZE (<MODE>mode)-1
10603 && can_create_pseudo_p ()"
10607 [(set (match_dup 0)
10608 (any_shiftrt:SWI48 (match_dup 1)
10610 (clobber (reg:CC FLAGS_REG))])]
10611 "operands[2] = gen_lowpart (QImode, operands[2]);"
10612 [(set_attr "isa" "*,bmi2")])
10614 (define_insn_and_split "*<shift_insn><mode>3_mask_1"
10615 [(set (match_operand:SWI48 0 "nonimmediate_operand")
10617 (match_operand:SWI48 1 "nonimmediate_operand")
10619 (match_operand:QI 2 "register_operand" "c,r")
10620 (match_operand:QI 3 "const_int_operand"))))
10621 (clobber (reg:CC FLAGS_REG))]
10622 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
10623 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10624 == GET_MODE_BITSIZE (<MODE>mode)-1
10625 && can_create_pseudo_p ()"
10629 [(set (match_dup 0)
10630 (any_shiftrt:SWI48 (match_dup 1)
10632 (clobber (reg:CC FLAGS_REG))])]
10634 [(set_attr "isa" "*,bmi2")])
10636 (define_insn_and_split "*<shift_insn><dwi>3_doubleword_mask"
10637 [(set (match_operand:<DWI> 0 "register_operand")
10639 (match_operand:<DWI> 1 "register_operand")
10642 (match_operand:SI 2 "register_operand" "c")
10643 (match_operand:SI 3 "const_int_operand")) 0)))
10644 (clobber (reg:CC FLAGS_REG))]
10645 "(INTVAL (operands[3]) & (<MODE_SIZE> * BITS_PER_UNIT)) == 0
10646 && can_create_pseudo_p ()"
10650 [(set (match_dup 4)
10651 (ior:DWIH (lshiftrt:DWIH (match_dup 4) (match_dup 2))
10652 (ashift:DWIH (match_dup 7)
10653 (minus:QI (match_dup 8) (match_dup 2)))))
10654 (clobber (reg:CC FLAGS_REG))])
10656 [(set (match_dup 6)
10657 (any_shiftrt:DWIH (match_dup 7) (match_dup 2)))
10658 (clobber (reg:CC FLAGS_REG))])]
10660 split_double_mode (<DWI>mode, &operands[0], 2, &operands[4], &operands[6]);
10662 operands[8] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT);
10664 if ((INTVAL (operands[3]) & ((<MODE_SIZE> * BITS_PER_UNIT) - 1))
10665 != ((<MODE_SIZE> * BITS_PER_UNIT) - 1))
10667 rtx tem = gen_reg_rtx (SImode);
10668 emit_insn (gen_andsi3 (tem, operands[2], operands[3]));
10672 operands[2] = gen_lowpart (QImode, operands[2]);
10674 if (!rtx_equal_p (operands[4], operands[5]))
10675 emit_move_insn (operands[4], operands[5]);
10678 (define_insn_and_split "*<shift_insn><dwi>3_doubleword_mask_1"
10679 [(set (match_operand:<DWI> 0 "register_operand")
10681 (match_operand:<DWI> 1 "register_operand")
10683 (match_operand:QI 2 "register_operand" "c")
10684 (match_operand:QI 3 "const_int_operand"))))
10685 (clobber (reg:CC FLAGS_REG))]
10686 "(INTVAL (operands[3]) & (<MODE_SIZE> * BITS_PER_UNIT)) == 0
10687 && can_create_pseudo_p ()"
10691 [(set (match_dup 4)
10692 (ior:DWIH (lshiftrt:DWIH (match_dup 4) (match_dup 2))
10693 (ashift:DWIH (match_dup 7)
10694 (minus:QI (match_dup 8) (match_dup 2)))))
10695 (clobber (reg:CC FLAGS_REG))])
10697 [(set (match_dup 6)
10698 (any_shiftrt:DWIH (match_dup 7) (match_dup 2)))
10699 (clobber (reg:CC FLAGS_REG))])]
10701 split_double_mode (<DWI>mode, &operands[0], 2, &operands[4], &operands[6]);
10703 operands[8] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT);
10705 if ((INTVAL (operands[3]) & ((<MODE_SIZE> * BITS_PER_UNIT) - 1))
10706 != ((<MODE_SIZE> * BITS_PER_UNIT) - 1))
10708 rtx tem = gen_reg_rtx (QImode);
10709 emit_insn (gen_andqi3 (tem, operands[2], operands[3]));
10713 if (!rtx_equal_p (operands[4], operands[5]))
10714 emit_move_insn (operands[4], operands[5]);
10717 (define_insn_and_split "*<shift_insn><mode>3_doubleword"
10718 [(set (match_operand:DWI 0 "register_operand" "=&r")
10719 (any_shiftrt:DWI (match_operand:DWI 1 "register_operand" "0")
10720 (match_operand:QI 2 "nonmemory_operand" "<S>c")))
10721 (clobber (reg:CC FLAGS_REG))]
10724 "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
10726 "ix86_split_<shift_insn> (operands, NULL_RTX, <MODE>mode); DONE;"
10727 [(set_attr "type" "multi")])
10729 ;; By default we don't ask for a scratch register, because when DWImode
10730 ;; values are manipulated, registers are already at a premium. But if
10731 ;; we have one handy, we won't turn it away.
10734 [(match_scratch:DWIH 3 "r")
10735 (parallel [(set (match_operand:<DWI> 0 "register_operand")
10737 (match_operand:<DWI> 1 "register_operand")
10738 (match_operand:QI 2 "nonmemory_operand")))
10739 (clobber (reg:CC FLAGS_REG))])
10743 "ix86_split_<shift_insn> (operands, operands[3], <DWI>mode); DONE;")
10745 (define_insn "x86_64_shrd"
10746 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
10747 (ior:DI (lshiftrt:DI (match_dup 0)
10748 (match_operand:QI 2 "nonmemory_operand" "Jc"))
10749 (ashift:DI (match_operand:DI 1 "register_operand" "r")
10750 (minus:QI (const_int 64) (match_dup 2)))))
10751 (clobber (reg:CC FLAGS_REG))]
10753 "shrd{q}\t{%s2%1, %0|%0, %1, %2}"
10754 [(set_attr "type" "ishift")
10755 (set_attr "prefix_0f" "1")
10756 (set_attr "mode" "DI")
10757 (set_attr "athlon_decode" "vector")
10758 (set_attr "amdfam10_decode" "vector")
10759 (set_attr "bdver1_decode" "vector")])
10761 (define_insn "x86_shrd"
10762 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
10763 (ior:SI (lshiftrt:SI (match_dup 0)
10764 (match_operand:QI 2 "nonmemory_operand" "Ic"))
10765 (ashift:SI (match_operand:SI 1 "register_operand" "r")
10766 (minus:QI (const_int 32) (match_dup 2)))))
10767 (clobber (reg:CC FLAGS_REG))]
10769 "shrd{l}\t{%s2%1, %0|%0, %1, %2}"
10770 [(set_attr "type" "ishift")
10771 (set_attr "prefix_0f" "1")
10772 (set_attr "mode" "SI")
10773 (set_attr "pent_pair" "np")
10774 (set_attr "athlon_decode" "vector")
10775 (set_attr "amdfam10_decode" "vector")
10776 (set_attr "bdver1_decode" "vector")])
10778 (define_insn "ashrdi3_cvt"
10779 [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
10780 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
10781 (match_operand:QI 2 "const_int_operand")))
10782 (clobber (reg:CC FLAGS_REG))]
10783 "TARGET_64BIT && INTVAL (operands[2]) == 63
10784 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
10785 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
10788 sar{q}\t{%2, %0|%0, %2}"
10789 [(set_attr "type" "imovx,ishift")
10790 (set_attr "prefix_0f" "0,*")
10791 (set_attr "length_immediate" "0,*")
10792 (set_attr "modrm" "0,1")
10793 (set_attr "mode" "DI")])
10795 (define_insn "*ashrsi3_cvt_zext"
10796 [(set (match_operand:DI 0 "register_operand" "=*d,r")
10798 (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
10799 (match_operand:QI 2 "const_int_operand"))))
10800 (clobber (reg:CC FLAGS_REG))]
10801 "TARGET_64BIT && INTVAL (operands[2]) == 31
10802 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
10803 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
10806 sar{l}\t{%2, %k0|%k0, %2}"
10807 [(set_attr "type" "imovx,ishift")
10808 (set_attr "prefix_0f" "0,*")
10809 (set_attr "length_immediate" "0,*")
10810 (set_attr "modrm" "0,1")
10811 (set_attr "mode" "SI")])
10813 (define_insn "ashrsi3_cvt"
10814 [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
10815 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
10816 (match_operand:QI 2 "const_int_operand")))
10817 (clobber (reg:CC FLAGS_REG))]
10818 "INTVAL (operands[2]) == 31
10819 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
10820 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
10823 sar{l}\t{%2, %0|%0, %2}"
10824 [(set_attr "type" "imovx,ishift")
10825 (set_attr "prefix_0f" "0,*")
10826 (set_attr "length_immediate" "0,*")
10827 (set_attr "modrm" "0,1")
10828 (set_attr "mode" "SI")])
10830 (define_expand "x86_shift<mode>_adj_3"
10831 [(use (match_operand:SWI48 0 "register_operand"))
10832 (use (match_operand:SWI48 1 "register_operand"))
10833 (use (match_operand:QI 2 "register_operand"))]
10836 rtx_code_label *label = gen_label_rtx ();
10839 emit_insn (gen_testqi_ccz_1 (operands[2],
10840 GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
10842 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
10843 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
10844 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
10845 gen_rtx_LABEL_REF (VOIDmode, label),
10847 tmp = emit_jump_insn (gen_rtx_SET (pc_rtx, tmp));
10848 JUMP_LABEL (tmp) = label;
10850 emit_move_insn (operands[0], operands[1]);
10851 emit_insn (gen_ashr<mode>3_cvt (operands[1], operands[1],
10852 GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1)));
10853 emit_label (label);
10854 LABEL_NUSES (label) = 1;
10859 (define_insn "*bmi2_<shift_insn><mode>3_1"
10860 [(set (match_operand:SWI48 0 "register_operand" "=r")
10861 (any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
10862 (match_operand:SWI48 2 "register_operand" "r")))]
10864 "<shift>x\t{%2, %1, %0|%0, %1, %2}"
10865 [(set_attr "type" "ishiftx")
10866 (set_attr "mode" "<MODE>")])
10868 (define_insn "*<shift_insn><mode>3_1"
10869 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
10871 (match_operand:SWI48 1 "nonimmediate_operand" "0,rm")
10872 (match_operand:QI 2 "nonmemory_operand" "c<S>,r")))
10873 (clobber (reg:CC FLAGS_REG))]
10874 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10876 switch (get_attr_type (insn))
10882 if (operands[2] == const1_rtx
10883 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10884 return "<shift>{<imodesuffix>}\t%0";
10886 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
10889 [(set_attr "isa" "*,bmi2")
10890 (set_attr "type" "ishift,ishiftx")
10891 (set (attr "length_immediate")
10893 (and (match_operand 2 "const1_operand")
10894 (ior (match_test "TARGET_SHIFT1")
10895 (match_test "optimize_function_for_size_p (cfun)")))
10897 (const_string "*")))
10898 (set_attr "mode" "<MODE>")])
10900 ;; Convert shift to the shiftx pattern to avoid flags dependency.
10902 [(set (match_operand:SWI48 0 "register_operand")
10903 (any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
10904 (match_operand:QI 2 "register_operand")))
10905 (clobber (reg:CC FLAGS_REG))]
10906 "TARGET_BMI2 && reload_completed"
10907 [(set (match_dup 0)
10908 (any_shiftrt:SWI48 (match_dup 1) (match_dup 2)))]
10909 "operands[2] = gen_lowpart (<MODE>mode, operands[2]);")
10911 (define_insn "*bmi2_<shift_insn>si3_1_zext"
10912 [(set (match_operand:DI 0 "register_operand" "=r")
10914 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
10915 (match_operand:SI 2 "register_operand" "r"))))]
10916 "TARGET_64BIT && TARGET_BMI2"
10917 "<shift>x\t{%2, %1, %k0|%k0, %1, %2}"
10918 [(set_attr "type" "ishiftx")
10919 (set_attr "mode" "SI")])
10921 (define_insn "*<shift_insn>si3_1_zext"
10922 [(set (match_operand:DI 0 "register_operand" "=r,r")
10924 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm")
10925 (match_operand:QI 2 "nonmemory_operand" "cI,r"))))
10926 (clobber (reg:CC FLAGS_REG))]
10927 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10929 switch (get_attr_type (insn))
10935 if (operands[2] == const1_rtx
10936 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10937 return "<shift>{l}\t%k0";
10939 return "<shift>{l}\t{%2, %k0|%k0, %2}";
10942 [(set_attr "isa" "*,bmi2")
10943 (set_attr "type" "ishift,ishiftx")
10944 (set (attr "length_immediate")
10946 (and (match_operand 2 "const1_operand")
10947 (ior (match_test "TARGET_SHIFT1")
10948 (match_test "optimize_function_for_size_p (cfun)")))
10950 (const_string "*")))
10951 (set_attr "mode" "SI")])
10953 ;; Convert shift to the shiftx pattern to avoid flags dependency.
10955 [(set (match_operand:DI 0 "register_operand")
10957 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand")
10958 (match_operand:QI 2 "register_operand"))))
10959 (clobber (reg:CC FLAGS_REG))]
10960 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
10961 [(set (match_dup 0)
10962 (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
10963 "operands[2] = gen_lowpart (SImode, operands[2]);")
10965 (define_insn "*<shift_insn><mode>3_1"
10966 [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m")
10968 (match_operand:SWI12 1 "nonimmediate_operand" "0")
10969 (match_operand:QI 2 "nonmemory_operand" "c<S>")))
10970 (clobber (reg:CC FLAGS_REG))]
10971 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10973 if (operands[2] == const1_rtx
10974 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10975 return "<shift>{<imodesuffix>}\t%0";
10977 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
10979 [(set_attr "type" "ishift")
10980 (set (attr "length_immediate")
10982 (and (match_operand 2 "const1_operand")
10983 (ior (match_test "TARGET_SHIFT1")
10984 (match_test "optimize_function_for_size_p (cfun)")))
10986 (const_string "*")))
10987 (set_attr "mode" "<MODE>")])
10989 (define_insn "*<shift_insn>qi3_1_slp"
10990 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10991 (any_shiftrt:QI (match_dup 0)
10992 (match_operand:QI 1 "nonmemory_operand" "cI")))
10993 (clobber (reg:CC FLAGS_REG))]
10994 "(optimize_function_for_size_p (cfun)
10995 || !TARGET_PARTIAL_REG_STALL
10996 || (operands[1] == const1_rtx
10997 && TARGET_SHIFT1))"
10999 if (operands[1] == const1_rtx
11000 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11001 return "<shift>{b}\t%0";
11003 return "<shift>{b}\t{%1, %0|%0, %1}";
11005 [(set_attr "type" "ishift1")
11006 (set (attr "length_immediate")
11008 (and (match_operand 1 "const1_operand")
11009 (ior (match_test "TARGET_SHIFT1")
11010 (match_test "optimize_function_for_size_p (cfun)")))
11012 (const_string "*")))
11013 (set_attr "mode" "QI")])
11015 ;; This pattern can't accept a variable shift count, since shifts by
11016 ;; zero don't affect the flags. We assume that shifts by constant
11017 ;; zero are optimized away.
11018 (define_insn "*<shift_insn><mode>3_cmp"
11019 [(set (reg FLAGS_REG)
11022 (match_operand:SWI 1 "nonimmediate_operand" "0")
11023 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
11025 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
11026 (any_shiftrt:SWI (match_dup 1) (match_dup 2)))]
11027 "(optimize_function_for_size_p (cfun)
11028 || !TARGET_PARTIAL_FLAG_REG_STALL
11029 || (operands[2] == const1_rtx
11031 && ix86_match_ccmode (insn, CCGOCmode)
11032 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
11034 if (operands[2] == const1_rtx
11035 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11036 return "<shift>{<imodesuffix>}\t%0";
11038 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
11040 [(set_attr "type" "ishift")
11041 (set (attr "length_immediate")
11043 (and (match_operand 2 "const1_operand")
11044 (ior (match_test "TARGET_SHIFT1")
11045 (match_test "optimize_function_for_size_p (cfun)")))
11047 (const_string "*")))
11048 (set_attr "mode" "<MODE>")])
11050 (define_insn "*<shift_insn>si3_cmp_zext"
11051 [(set (reg FLAGS_REG)
11053 (any_shiftrt:SI (match_operand:SI 1 "register_operand" "0")
11054 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11056 (set (match_operand:DI 0 "register_operand" "=r")
11057 (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
11059 && (optimize_function_for_size_p (cfun)
11060 || !TARGET_PARTIAL_FLAG_REG_STALL
11061 || (operands[2] == const1_rtx
11063 && ix86_match_ccmode (insn, CCGOCmode)
11064 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
11066 if (operands[2] == const1_rtx
11067 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11068 return "<shift>{l}\t%k0";
11070 return "<shift>{l}\t{%2, %k0|%k0, %2}";
11072 [(set_attr "type" "ishift")
11073 (set (attr "length_immediate")
11075 (and (match_operand 2 "const1_operand")
11076 (ior (match_test "TARGET_SHIFT1")
11077 (match_test "optimize_function_for_size_p (cfun)")))
11079 (const_string "*")))
11080 (set_attr "mode" "SI")])
11082 (define_insn "*<shift_insn><mode>3_cconly"
11083 [(set (reg FLAGS_REG)
11086 (match_operand:SWI 1 "register_operand" "0")
11087 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
11089 (clobber (match_scratch:SWI 0 "=<r>"))]
11090 "(optimize_function_for_size_p (cfun)
11091 || !TARGET_PARTIAL_FLAG_REG_STALL
11092 || (operands[2] == const1_rtx
11094 && ix86_match_ccmode (insn, CCGOCmode)"
11096 if (operands[2] == const1_rtx
11097 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11098 return "<shift>{<imodesuffix>}\t%0";
11100 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
11102 [(set_attr "type" "ishift")
11103 (set (attr "length_immediate")
11105 (and (match_operand 2 "const1_operand")
11106 (ior (match_test "TARGET_SHIFT1")
11107 (match_test "optimize_function_for_size_p (cfun)")))
11109 (const_string "*")))
11110 (set_attr "mode" "<MODE>")])
11112 ;; Rotate instructions
11114 (define_expand "<rotate_insn>ti3"
11115 [(set (match_operand:TI 0 "register_operand")
11116 (any_rotate:TI (match_operand:TI 1 "register_operand")
11117 (match_operand:QI 2 "nonmemory_operand")))]
11120 if (const_1_to_63_operand (operands[2], VOIDmode))
11121 emit_insn (gen_ix86_<rotate_insn>ti3_doubleword
11122 (operands[0], operands[1], operands[2]));
11129 (define_expand "<rotate_insn>di3"
11130 [(set (match_operand:DI 0 "shiftdi_operand")
11131 (any_rotate:DI (match_operand:DI 1 "shiftdi_operand")
11132 (match_operand:QI 2 "nonmemory_operand")))]
11136 ix86_expand_binary_operator (<CODE>, DImode, operands);
11137 else if (const_1_to_31_operand (operands[2], VOIDmode))
11138 emit_insn (gen_ix86_<rotate_insn>di3_doubleword
11139 (operands[0], operands[1], operands[2]));
11146 (define_expand "<rotate_insn><mode>3"
11147 [(set (match_operand:SWIM124 0 "nonimmediate_operand")
11148 (any_rotate:SWIM124 (match_operand:SWIM124 1 "nonimmediate_operand")
11149 (match_operand:QI 2 "nonmemory_operand")))]
11151 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
11153 ;; Avoid useless masking of count operand.
11154 (define_insn_and_split "*<rotate_insn><mode>3_mask"
11155 [(set (match_operand:SWI48 0 "nonimmediate_operand")
11157 (match_operand:SWI48 1 "nonimmediate_operand")
11160 (match_operand:SI 2 "register_operand" "c")
11161 (match_operand:SI 3 "const_int_operand")) 0)))
11162 (clobber (reg:CC FLAGS_REG))]
11163 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
11164 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
11165 == GET_MODE_BITSIZE (<MODE>mode)-1
11166 && can_create_pseudo_p ()"
11170 [(set (match_dup 0)
11171 (any_rotate:SWI48 (match_dup 1)
11173 (clobber (reg:CC FLAGS_REG))])]
11174 "operands[2] = gen_lowpart (QImode, operands[2]);")
11176 (define_insn_and_split "*<rotate_insn><mode>3_mask_1"
11177 [(set (match_operand:SWI48 0 "nonimmediate_operand")
11179 (match_operand:SWI48 1 "nonimmediate_operand")
11181 (match_operand:QI 2 "register_operand" "c")
11182 (match_operand:QI 3 "const_int_operand"))))
11183 (clobber (reg:CC FLAGS_REG))]
11184 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
11185 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
11186 == GET_MODE_BITSIZE (<MODE>mode)-1
11187 && can_create_pseudo_p ()"
11191 [(set (match_dup 0)
11192 (any_rotate:SWI48 (match_dup 1)
11194 (clobber (reg:CC FLAGS_REG))])])
11196 ;; Implement rotation using two double-precision
11197 ;; shift instructions and a scratch register.
11199 (define_insn_and_split "ix86_rotl<dwi>3_doubleword"
11200 [(set (match_operand:<DWI> 0 "register_operand" "=r")
11201 (rotate:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
11202 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
11203 (clobber (reg:CC FLAGS_REG))
11204 (clobber (match_scratch:DWIH 3 "=&r"))]
11208 [(set (match_dup 3) (match_dup 4))
11210 [(set (match_dup 4)
11211 (ior:DWIH (ashift:DWIH (match_dup 4) (match_dup 2))
11212 (lshiftrt:DWIH (match_dup 5)
11213 (minus:QI (match_dup 6) (match_dup 2)))))
11214 (clobber (reg:CC FLAGS_REG))])
11216 [(set (match_dup 5)
11217 (ior:DWIH (ashift:DWIH (match_dup 5) (match_dup 2))
11218 (lshiftrt:DWIH (match_dup 3)
11219 (minus:QI (match_dup 6) (match_dup 2)))))
11220 (clobber (reg:CC FLAGS_REG))])]
11222 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
11224 split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
11227 (define_insn_and_split "ix86_rotr<dwi>3_doubleword"
11228 [(set (match_operand:<DWI> 0 "register_operand" "=r")
11229 (rotatert:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
11230 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
11231 (clobber (reg:CC FLAGS_REG))
11232 (clobber (match_scratch:DWIH 3 "=&r"))]
11236 [(set (match_dup 3) (match_dup 4))
11238 [(set (match_dup 4)
11239 (ior:DWIH (lshiftrt:DWIH (match_dup 4) (match_dup 2))
11240 (ashift:DWIH (match_dup 5)
11241 (minus:QI (match_dup 6) (match_dup 2)))))
11242 (clobber (reg:CC FLAGS_REG))])
11244 [(set (match_dup 5)
11245 (ior:DWIH (lshiftrt:DWIH (match_dup 5) (match_dup 2))
11246 (ashift:DWIH (match_dup 3)
11247 (minus:QI (match_dup 6) (match_dup 2)))))
11248 (clobber (reg:CC FLAGS_REG))])]
11250 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
11252 split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
11255 (define_mode_attr rorx_immediate_operand
11256 [(SI "const_0_to_31_operand")
11257 (DI "const_0_to_63_operand")])
11259 (define_insn "*bmi2_rorx<mode>3_1"
11260 [(set (match_operand:SWI48 0 "register_operand" "=r")
11262 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11263 (match_operand:QI 2 "<rorx_immediate_operand>" "<S>")))]
11265 "rorx\t{%2, %1, %0|%0, %1, %2}"
11266 [(set_attr "type" "rotatex")
11267 (set_attr "mode" "<MODE>")])
11269 (define_insn "*<rotate_insn><mode>3_1"
11270 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
11272 (match_operand:SWI48 1 "nonimmediate_operand" "0,rm")
11273 (match_operand:QI 2 "nonmemory_operand" "c<S>,<S>")))
11274 (clobber (reg:CC FLAGS_REG))]
11275 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
11277 switch (get_attr_type (insn))
11283 if (operands[2] == const1_rtx
11284 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11285 return "<rotate>{<imodesuffix>}\t%0";
11287 return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
11290 [(set_attr "isa" "*,bmi2")
11291 (set_attr "type" "rotate,rotatex")
11292 (set (attr "length_immediate")
11294 (and (eq_attr "type" "rotate")
11295 (and (match_operand 2 "const1_operand")
11296 (ior (match_test "TARGET_SHIFT1")
11297 (match_test "optimize_function_for_size_p (cfun)"))))
11299 (const_string "*")))
11300 (set_attr "mode" "<MODE>")])
11302 ;; Convert rotate to the rotatex pattern to avoid flags dependency.
11304 [(set (match_operand:SWI48 0 "register_operand")
11305 (rotate:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
11306 (match_operand:QI 2 "const_int_operand")))
11307 (clobber (reg:CC FLAGS_REG))]
11308 "TARGET_BMI2 && reload_completed"
11309 [(set (match_dup 0)
11310 (rotatert:SWI48 (match_dup 1) (match_dup 2)))]
11312 int bitsize = GET_MODE_BITSIZE (<MODE>mode);
11314 operands[2] = GEN_INT ((bitsize - INTVAL (operands[2])) % bitsize);
11318 [(set (match_operand:SWI48 0 "register_operand")
11319 (rotatert:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
11320 (match_operand:QI 2 "const_int_operand")))
11321 (clobber (reg:CC FLAGS_REG))]
11322 "TARGET_BMI2 && reload_completed"
11323 [(set (match_dup 0)
11324 (rotatert:SWI48 (match_dup 1) (match_dup 2)))])
11326 (define_insn "*bmi2_rorxsi3_1_zext"
11327 [(set (match_operand:DI 0 "register_operand" "=r")
11329 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
11330 (match_operand:QI 2 "const_0_to_31_operand" "I"))))]
11331 "TARGET_64BIT && TARGET_BMI2"
11332 "rorx\t{%2, %1, %k0|%k0, %1, %2}"
11333 [(set_attr "type" "rotatex")
11334 (set_attr "mode" "SI")])
11336 (define_insn "*<rotate_insn>si3_1_zext"
11337 [(set (match_operand:DI 0 "register_operand" "=r,r")
11339 (any_rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm")
11340 (match_operand:QI 2 "nonmemory_operand" "cI,I"))))
11341 (clobber (reg:CC FLAGS_REG))]
11342 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
11344 switch (get_attr_type (insn))
11350 if (operands[2] == const1_rtx
11351 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11352 return "<rotate>{l}\t%k0";
11354 return "<rotate>{l}\t{%2, %k0|%k0, %2}";
11357 [(set_attr "isa" "*,bmi2")
11358 (set_attr "type" "rotate,rotatex")
11359 (set (attr "length_immediate")
11361 (and (eq_attr "type" "rotate")
11362 (and (match_operand 2 "const1_operand")
11363 (ior (match_test "TARGET_SHIFT1")
11364 (match_test "optimize_function_for_size_p (cfun)"))))
11366 (const_string "*")))
11367 (set_attr "mode" "SI")])
11369 ;; Convert rotate to the rotatex pattern to avoid flags dependency.
11371 [(set (match_operand:DI 0 "register_operand")
11373 (rotate:SI (match_operand:SI 1 "nonimmediate_operand")
11374 (match_operand:QI 2 "const_int_operand"))))
11375 (clobber (reg:CC FLAGS_REG))]
11376 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
11377 [(set (match_dup 0)
11378 (zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))]
11380 int bitsize = GET_MODE_BITSIZE (SImode);
11382 operands[2] = GEN_INT ((bitsize - INTVAL (operands[2])) % bitsize);
11386 [(set (match_operand:DI 0 "register_operand")
11388 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand")
11389 (match_operand:QI 2 "const_int_operand"))))
11390 (clobber (reg:CC FLAGS_REG))]
11391 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
11392 [(set (match_dup 0)
11393 (zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))])
11395 (define_insn "*<rotate_insn><mode>3_1"
11396 [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m")
11397 (any_rotate:SWI12 (match_operand:SWI12 1 "nonimmediate_operand" "0")
11398 (match_operand:QI 2 "nonmemory_operand" "c<S>")))
11399 (clobber (reg:CC FLAGS_REG))]
11400 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
11402 if (operands[2] == const1_rtx
11403 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11404 return "<rotate>{<imodesuffix>}\t%0";
11406 return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
11408 [(set_attr "type" "rotate")
11409 (set (attr "length_immediate")
11411 (and (match_operand 2 "const1_operand")
11412 (ior (match_test "TARGET_SHIFT1")
11413 (match_test "optimize_function_for_size_p (cfun)")))
11415 (const_string "*")))
11416 (set_attr "mode" "<MODE>")])
11418 (define_insn "*<rotate_insn>qi3_1_slp"
11419 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
11420 (any_rotate:QI (match_dup 0)
11421 (match_operand:QI 1 "nonmemory_operand" "cI")))
11422 (clobber (reg:CC FLAGS_REG))]
11423 "(optimize_function_for_size_p (cfun)
11424 || !TARGET_PARTIAL_REG_STALL
11425 || (operands[1] == const1_rtx
11426 && TARGET_SHIFT1))"
11428 if (operands[1] == const1_rtx
11429 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11430 return "<rotate>{b}\t%0";
11432 return "<rotate>{b}\t{%1, %0|%0, %1}";
11434 [(set_attr "type" "rotate1")
11435 (set (attr "length_immediate")
11437 (and (match_operand 1 "const1_operand")
11438 (ior (match_test "TARGET_SHIFT1")
11439 (match_test "optimize_function_for_size_p (cfun)")))
11441 (const_string "*")))
11442 (set_attr "mode" "QI")])
11445 [(set (match_operand:HI 0 "QIreg_operand")
11446 (any_rotate:HI (match_dup 0) (const_int 8)))
11447 (clobber (reg:CC FLAGS_REG))]
11449 && (TARGET_USE_XCHGB || optimize_function_for_size_p (cfun))"
11450 [(parallel [(set (strict_low_part (match_dup 0))
11451 (bswap:HI (match_dup 0)))
11452 (clobber (reg:CC FLAGS_REG))])])
11454 ;; Bit set / bit test instructions
11456 ;; %%% bts, btr, btc
11458 ;; These instructions are *slow* when applied to memory.
11460 (define_code_attr btsc [(ior "bts") (xor "btc")])
11462 (define_insn "*<btsc><mode>"
11463 [(set (match_operand:SWI48 0 "register_operand" "=r")
11465 (ashift:SWI48 (const_int 1)
11466 (match_operand:QI 2 "register_operand" "r"))
11467 (match_operand:SWI48 1 "register_operand" "0")))
11468 (clobber (reg:CC FLAGS_REG))]
11470 "<btsc>{<imodesuffix>}\t{%<k>2, %0|%0, %<k>2}"
11471 [(set_attr "type" "alu1")
11472 (set_attr "prefix_0f" "1")
11473 (set_attr "znver1_decode" "double")
11474 (set_attr "mode" "<MODE>")])
11476 ;; Avoid useless masking of count operand.
11477 (define_insn_and_split "*<btsc><mode>_mask"
11478 [(set (match_operand:SWI48 0 "register_operand")
11484 (match_operand:SI 1 "register_operand")
11485 (match_operand:SI 2 "const_int_operand")) 0))
11486 (match_operand:SWI48 3 "register_operand")))
11487 (clobber (reg:CC FLAGS_REG))]
11489 && (INTVAL (operands[2]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
11490 == GET_MODE_BITSIZE (<MODE>mode)-1
11491 && can_create_pseudo_p ()"
11495 [(set (match_dup 0)
11497 (ashift:SWI48 (const_int 1)
11500 (clobber (reg:CC FLAGS_REG))])]
11501 "operands[1] = gen_lowpart (QImode, operands[1]);")
11503 (define_insn_and_split "*<btsc><mode>_mask_1"
11504 [(set (match_operand:SWI48 0 "register_operand")
11509 (match_operand:QI 1 "register_operand")
11510 (match_operand:QI 2 "const_int_operand")))
11511 (match_operand:SWI48 3 "register_operand")))
11512 (clobber (reg:CC FLAGS_REG))]
11514 && (INTVAL (operands[2]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
11515 == GET_MODE_BITSIZE (<MODE>mode)-1
11516 && can_create_pseudo_p ()"
11520 [(set (match_dup 0)
11522 (ashift:SWI48 (const_int 1)
11525 (clobber (reg:CC FLAGS_REG))])])
11527 (define_insn "*btr<mode>"
11528 [(set (match_operand:SWI48 0 "register_operand" "=r")
11530 (rotate:SWI48 (const_int -2)
11531 (match_operand:QI 2 "register_operand" "r"))
11532 (match_operand:SWI48 1 "register_operand" "0")))
11533 (clobber (reg:CC FLAGS_REG))]
11535 "btr{<imodesuffix>}\t{%<k>2, %0|%0, %<k>2}"
11536 [(set_attr "type" "alu1")
11537 (set_attr "prefix_0f" "1")
11538 (set_attr "znver1_decode" "double")
11539 (set_attr "mode" "<MODE>")])
11541 ;; Avoid useless masking of count operand.
11542 (define_insn_and_split "*btr<mode>_mask"
11543 [(set (match_operand:SWI48 0 "register_operand")
11549 (match_operand:SI 1 "register_operand")
11550 (match_operand:SI 2 "const_int_operand")) 0))
11551 (match_operand:SWI48 3 "register_operand")))
11552 (clobber (reg:CC FLAGS_REG))]
11554 && (INTVAL (operands[2]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
11555 == GET_MODE_BITSIZE (<MODE>mode)-1
11556 && can_create_pseudo_p ()"
11560 [(set (match_dup 0)
11562 (rotate:SWI48 (const_int -2)
11565 (clobber (reg:CC FLAGS_REG))])]
11566 "operands[1] = gen_lowpart (QImode, operands[1]);")
11568 (define_insn_and_split "*btr<mode>_mask_1"
11569 [(set (match_operand:SWI48 0 "register_operand")
11574 (match_operand:QI 1 "register_operand")
11575 (match_operand:QI 2 "const_int_operand")))
11576 (match_operand:SWI48 3 "register_operand")))
11577 (clobber (reg:CC FLAGS_REG))]
11579 && (INTVAL (operands[2]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
11580 == GET_MODE_BITSIZE (<MODE>mode)-1
11581 && can_create_pseudo_p ()"
11585 [(set (match_dup 0)
11587 (rotate:SWI48 (const_int -2)
11590 (clobber (reg:CC FLAGS_REG))])])
11592 ;; These instructions are never faster than the corresponding
11593 ;; and/ior/xor operations when using immediate operand, so with
11594 ;; 32-bit there's no point. But in 64-bit, we can't hold the
11595 ;; relevant immediates within the instruction itself, so operating
11596 ;; on bits in the high 32-bits of a register becomes easier.
11598 ;; These are slow on Nocona, but fast on Athlon64. We do require the use
11599 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
11600 ;; negdf respectively, so they can never be disabled entirely.
11602 (define_insn "*btsq_imm"
11603 [(set (zero_extract:DI (match_operand:DI 0 "nonimmediate_operand" "+rm")
11605 (match_operand 1 "const_0_to_63_operand" "J"))
11607 (clobber (reg:CC FLAGS_REG))]
11608 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
11609 "bts{q}\t{%1, %0|%0, %1}"
11610 [(set_attr "type" "alu1")
11611 (set_attr "prefix_0f" "1")
11612 (set_attr "znver1_decode" "double")
11613 (set_attr "mode" "DI")])
11615 (define_insn "*btrq_imm"
11616 [(set (zero_extract:DI (match_operand:DI 0 "nonimmediate_operand" "+rm")
11618 (match_operand 1 "const_0_to_63_operand" "J"))
11620 (clobber (reg:CC FLAGS_REG))]
11621 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
11622 "btr{q}\t{%1, %0|%0, %1}"
11623 [(set_attr "type" "alu1")
11624 (set_attr "prefix_0f" "1")
11625 (set_attr "znver1_decode" "double")
11626 (set_attr "mode" "DI")])
11628 (define_insn "*btcq_imm"
11629 [(set (zero_extract:DI (match_operand:DI 0 "nonimmediate_operand" "+rm")
11631 (match_operand 1 "const_0_to_63_operand" "J"))
11632 (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
11633 (clobber (reg:CC FLAGS_REG))]
11634 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
11635 "btc{q}\t{%1, %0|%0, %1}"
11636 [(set_attr "type" "alu1")
11637 (set_attr "prefix_0f" "1")
11638 (set_attr "znver1_decode" "double")
11639 (set_attr "mode" "DI")])
11641 ;; Allow Nocona to avoid these instructions if a register is available.
11644 [(match_scratch:DI 2 "r")
11645 (parallel [(set (zero_extract:DI
11646 (match_operand:DI 0 "nonimmediate_operand")
11648 (match_operand 1 "const_0_to_63_operand"))
11650 (clobber (reg:CC FLAGS_REG))])]
11651 "TARGET_64BIT && !TARGET_USE_BT"
11652 [(parallel [(set (match_dup 0)
11653 (ior:DI (match_dup 0) (match_dup 3)))
11654 (clobber (reg:CC FLAGS_REG))])]
11656 int i = INTVAL (operands[1]);
11658 operands[3] = gen_int_mode (HOST_WIDE_INT_1U << i, DImode);
11660 if (!x86_64_immediate_operand (operands[3], DImode))
11662 emit_move_insn (operands[2], operands[3]);
11663 operands[3] = operands[2];
11668 [(match_scratch:DI 2 "r")
11669 (parallel [(set (zero_extract:DI
11670 (match_operand:DI 0 "nonimmediate_operand")
11672 (match_operand 1 "const_0_to_63_operand"))
11674 (clobber (reg:CC FLAGS_REG))])]
11675 "TARGET_64BIT && !TARGET_USE_BT"
11676 [(parallel [(set (match_dup 0)
11677 (and:DI (match_dup 0) (match_dup 3)))
11678 (clobber (reg:CC FLAGS_REG))])]
11680 int i = INTVAL (operands[1]);
11682 operands[3] = gen_int_mode (~(HOST_WIDE_INT_1U << i), DImode);
11684 if (!x86_64_immediate_operand (operands[3], DImode))
11686 emit_move_insn (operands[2], operands[3]);
11687 operands[3] = operands[2];
11692 [(match_scratch:DI 2 "r")
11693 (parallel [(set (zero_extract:DI
11694 (match_operand:DI 0 "nonimmediate_operand")
11696 (match_operand 1 "const_0_to_63_operand"))
11697 (not:DI (zero_extract:DI
11698 (match_dup 0) (const_int 1) (match_dup 1))))
11699 (clobber (reg:CC FLAGS_REG))])]
11700 "TARGET_64BIT && !TARGET_USE_BT"
11701 [(parallel [(set (match_dup 0)
11702 (xor:DI (match_dup 0) (match_dup 3)))
11703 (clobber (reg:CC FLAGS_REG))])]
11705 int i = INTVAL (operands[1]);
11707 operands[3] = gen_int_mode (HOST_WIDE_INT_1U << i, DImode);
11709 if (!x86_64_immediate_operand (operands[3], DImode))
11711 emit_move_insn (operands[2], operands[3]);
11712 operands[3] = operands[2];
11718 (define_insn "*bt<mode>"
11719 [(set (reg:CCC FLAGS_REG)
11721 (zero_extract:SWI48
11722 (match_operand:SWI48 0 "nonimmediate_operand" "r,m")
11724 (match_operand:SI 1 "nonmemory_operand" "r<S>,<S>"))
11728 switch (get_attr_mode (insn))
11731 return "bt{l}\t{%1, %k0|%k0, %1}";
11734 return "bt{q}\t{%q1, %0|%0, %q1}";
11737 gcc_unreachable ();
11740 [(set_attr "type" "alu1")
11741 (set_attr "prefix_0f" "1")
11744 (and (match_test "CONST_INT_P (operands[1])")
11745 (match_test "INTVAL (operands[1]) < 32"))
11746 (const_string "SI")
11747 (const_string "<MODE>")))])
11749 (define_insn_and_split "*jcc_bt<mode>"
11751 (if_then_else (match_operator 0 "bt_comparison_operator"
11752 [(zero_extract:SWI48
11753 (match_operand:SWI48 1 "nonimmediate_operand")
11755 (match_operand:SI 2 "nonmemory_operand"))
11757 (label_ref (match_operand 3))
11759 (clobber (reg:CC FLAGS_REG))]
11760 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
11761 && (CONST_INT_P (operands[2])
11762 ? (INTVAL (operands[2]) < GET_MODE_BITSIZE (<MODE>mode)
11763 && INTVAL (operands[2])
11764 >= (optimize_function_for_size_p (cfun) ? 8 : 32))
11765 : !memory_operand (operands[1], <MODE>mode))
11766 && can_create_pseudo_p ()"
11769 [(set (reg:CCC FLAGS_REG)
11771 (zero_extract:SWI48
11777 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
11778 (label_ref (match_dup 3))
11781 operands[0] = shallow_copy_rtx (operands[0]);
11782 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
11785 (define_insn_and_split "*jcc_bt<mode>_1"
11787 (if_then_else (match_operator 0 "bt_comparison_operator"
11788 [(zero_extract:SWI48
11789 (match_operand:SWI48 1 "register_operand")
11792 (match_operand:QI 2 "register_operand")))
11794 (label_ref (match_operand 3))
11796 (clobber (reg:CC FLAGS_REG))]
11797 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
11798 && can_create_pseudo_p ()"
11801 [(set (reg:CCC FLAGS_REG)
11803 (zero_extract:SWI48
11809 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
11810 (label_ref (match_dup 3))
11813 operands[2] = lowpart_subreg (SImode, operands[2], QImode);
11814 operands[0] = shallow_copy_rtx (operands[0]);
11815 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
11818 ;; Avoid useless masking of bit offset operand.
11819 (define_insn_and_split "*jcc_bt<mode>_mask"
11821 (if_then_else (match_operator 0 "bt_comparison_operator"
11822 [(zero_extract:SWI48
11823 (match_operand:SWI48 1 "register_operand")
11826 (match_operand:SI 2 "register_operand")
11827 (match_operand 3 "const_int_operand")))])
11828 (label_ref (match_operand 4))
11830 (clobber (reg:CC FLAGS_REG))]
11831 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
11832 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
11833 == GET_MODE_BITSIZE (<MODE>mode)-1
11834 && can_create_pseudo_p ()"
11837 [(set (reg:CCC FLAGS_REG)
11839 (zero_extract:SWI48
11845 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
11846 (label_ref (match_dup 4))
11849 operands[0] = shallow_copy_rtx (operands[0]);
11850 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
11853 ;; Store-flag instructions.
11855 ;; For all sCOND expanders, also expand the compare or test insn that
11856 ;; generates cc0. Generate an equality comparison if `seq' or `sne'.
11858 (define_insn_and_split "*setcc_di_1"
11859 [(set (match_operand:DI 0 "register_operand" "=q")
11860 (match_operator:DI 1 "ix86_comparison_operator"
11861 [(reg FLAGS_REG) (const_int 0)]))]
11862 "TARGET_64BIT && !TARGET_PARTIAL_REG_STALL"
11864 "&& reload_completed"
11865 [(set (match_dup 2) (match_dup 1))
11866 (set (match_dup 0) (zero_extend:DI (match_dup 2)))]
11868 operands[1] = shallow_copy_rtx (operands[1]);
11869 PUT_MODE (operands[1], QImode);
11870 operands[2] = gen_lowpart (QImode, operands[0]);
11873 (define_insn_and_split "*setcc_si_1_and"
11874 [(set (match_operand:SI 0 "register_operand" "=q")
11875 (match_operator:SI 1 "ix86_comparison_operator"
11876 [(reg FLAGS_REG) (const_int 0)]))
11877 (clobber (reg:CC FLAGS_REG))]
11878 "!TARGET_PARTIAL_REG_STALL
11879 && TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
11881 "&& reload_completed"
11882 [(set (match_dup 2) (match_dup 1))
11883 (parallel [(set (match_dup 0) (zero_extend:SI (match_dup 2)))
11884 (clobber (reg:CC FLAGS_REG))])]
11886 operands[1] = shallow_copy_rtx (operands[1]);
11887 PUT_MODE (operands[1], QImode);
11888 operands[2] = gen_lowpart (QImode, operands[0]);
11891 (define_insn_and_split "*setcc_si_1_movzbl"
11892 [(set (match_operand:SI 0 "register_operand" "=q")
11893 (match_operator:SI 1 "ix86_comparison_operator"
11894 [(reg FLAGS_REG) (const_int 0)]))]
11895 "!TARGET_PARTIAL_REG_STALL
11896 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
11898 "&& reload_completed"
11899 [(set (match_dup 2) (match_dup 1))
11900 (set (match_dup 0) (zero_extend:SI (match_dup 2)))]
11902 operands[1] = shallow_copy_rtx (operands[1]);
11903 PUT_MODE (operands[1], QImode);
11904 operands[2] = gen_lowpart (QImode, operands[0]);
11907 (define_insn "*setcc_qi"
11908 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11909 (match_operator:QI 1 "ix86_comparison_operator"
11910 [(reg FLAGS_REG) (const_int 0)]))]
11913 [(set_attr "type" "setcc")
11914 (set_attr "mode" "QI")])
11916 (define_insn "*setcc_qi_slp"
11917 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
11918 (match_operator:QI 1 "ix86_comparison_operator"
11919 [(reg FLAGS_REG) (const_int 0)]))]
11922 [(set_attr "type" "setcc")
11923 (set_attr "mode" "QI")])
11925 ;; In general it is not safe to assume too much about CCmode registers,
11926 ;; so simplify-rtx stops when it sees a second one. Under certain
11927 ;; conditions this is safe on x86, so help combine not create
11934 [(set (match_operand:QI 0 "nonimmediate_operand")
11935 (ne:QI (match_operator 1 "ix86_comparison_operator"
11936 [(reg FLAGS_REG) (const_int 0)])
11939 [(set (match_dup 0) (match_dup 1))]
11941 operands[1] = shallow_copy_rtx (operands[1]);
11942 PUT_MODE (operands[1], QImode);
11946 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand"))
11947 (ne:QI (match_operator 1 "ix86_comparison_operator"
11948 [(reg FLAGS_REG) (const_int 0)])
11951 [(set (match_dup 0) (match_dup 1))]
11953 operands[1] = shallow_copy_rtx (operands[1]);
11954 PUT_MODE (operands[1], QImode);
11958 [(set (match_operand:QI 0 "nonimmediate_operand")
11959 (eq:QI (match_operator 1 "ix86_comparison_operator"
11960 [(reg FLAGS_REG) (const_int 0)])
11963 [(set (match_dup 0) (match_dup 1))]
11965 operands[1] = shallow_copy_rtx (operands[1]);
11966 PUT_MODE (operands[1], QImode);
11967 PUT_CODE (operands[1],
11968 ix86_reverse_condition (GET_CODE (operands[1]),
11969 GET_MODE (XEXP (operands[1], 0))));
11971 /* Make sure that (a) the CCmode we have for the flags is strong
11972 enough for the reversed compare or (b) we have a valid FP compare. */
11973 if (! ix86_comparison_operator (operands[1], VOIDmode))
11978 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand"))
11979 (eq:QI (match_operator 1 "ix86_comparison_operator"
11980 [(reg FLAGS_REG) (const_int 0)])
11983 [(set (match_dup 0) (match_dup 1))]
11985 operands[1] = shallow_copy_rtx (operands[1]);
11986 PUT_MODE (operands[1], QImode);
11987 PUT_CODE (operands[1],
11988 ix86_reverse_condition (GET_CODE (operands[1]),
11989 GET_MODE (XEXP (operands[1], 0))));
11991 /* Make sure that (a) the CCmode we have for the flags is strong
11992 enough for the reversed compare or (b) we have a valid FP compare. */
11993 if (! ix86_comparison_operator (operands[1], VOIDmode))
11997 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
11998 ;; subsequent logical operations are used to imitate conditional moves.
11999 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
12002 (define_insn "setcc_<mode>_sse"
12003 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
12004 (match_operator:MODEF 3 "sse_comparison_operator"
12005 [(match_operand:MODEF 1 "register_operand" "0,x")
12006 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
12007 "SSE_FLOAT_MODE_P (<MODE>mode)"
12009 cmp%D3<ssemodesuffix>\t{%2, %0|%0, %2}
12010 vcmp%D3<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
12011 [(set_attr "isa" "noavx,avx")
12012 (set_attr "type" "ssecmp")
12013 (set_attr "length_immediate" "1")
12014 (set_attr "prefix" "orig,vex")
12015 (set_attr "mode" "<MODE>")])
12017 ;; Basic conditional jump instructions.
12018 ;; We ignore the overflow flag for signed branch instructions.
12020 (define_insn "*jcc"
12022 (if_then_else (match_operator 1 "ix86_comparison_operator"
12023 [(reg FLAGS_REG) (const_int 0)])
12024 (label_ref (match_operand 0))
12028 [(set_attr "type" "ibr")
12029 (set_attr "modrm" "0")
12030 (set (attr "length")
12032 (and (ge (minus (match_dup 0) (pc))
12034 (lt (minus (match_dup 0) (pc))
12039 ;; In general it is not safe to assume too much about CCmode registers,
12040 ;; so simplify-rtx stops when it sees a second one. Under certain
12041 ;; conditions this is safe on x86, so help combine not create
12049 (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
12050 [(reg FLAGS_REG) (const_int 0)])
12052 (label_ref (match_operand 1))
12056 (if_then_else (match_dup 0)
12057 (label_ref (match_dup 1))
12060 operands[0] = shallow_copy_rtx (operands[0]);
12061 PUT_MODE (operands[0], VOIDmode);
12066 (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
12067 [(reg FLAGS_REG) (const_int 0)])
12069 (label_ref (match_operand 1))
12073 (if_then_else (match_dup 0)
12074 (label_ref (match_dup 1))
12077 operands[0] = shallow_copy_rtx (operands[0]);
12078 PUT_MODE (operands[0], VOIDmode);
12079 PUT_CODE (operands[0],
12080 ix86_reverse_condition (GET_CODE (operands[0]),
12081 GET_MODE (XEXP (operands[0], 0))));
12083 /* Make sure that (a) the CCmode we have for the flags is strong
12084 enough for the reversed compare or (b) we have a valid FP compare. */
12085 if (! ix86_comparison_operator (operands[0], VOIDmode))
12089 ;; Unconditional and other jump instructions
12091 (define_insn "jump"
12093 (label_ref (match_operand 0)))]
12096 [(set_attr "type" "ibr")
12097 (set_attr "modrm" "0")
12098 (set (attr "length")
12100 (and (ge (minus (match_dup 0) (pc))
12102 (lt (minus (match_dup 0) (pc))
12107 (define_expand "indirect_jump"
12108 [(set (pc) (match_operand 0 "indirect_branch_operand"))]
12111 if (TARGET_X32 || TARGET_INDIRECT_BRANCH_REGISTER)
12112 operands[0] = convert_memory_address (word_mode, operands[0]);
12113 cfun->machine->has_local_indirect_jump = true;
12116 (define_insn "*indirect_jump"
12117 [(set (pc) (match_operand:W 0 "indirect_branch_operand" "rBw"))]
12119 "* return ix86_output_indirect_jmp (operands[0]);"
12120 [(set (attr "type")
12121 (if_then_else (match_test "(cfun->machine->indirect_branch_type
12122 != indirect_branch_keep)")
12123 (const_string "multi")
12124 (const_string "ibr")))
12125 (set_attr "length_immediate" "0")])
12127 (define_expand "tablejump"
12128 [(parallel [(set (pc) (match_operand 0 "indirect_branch_operand"))
12129 (use (label_ref (match_operand 1)))])]
12132 /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
12133 relative. Convert the relative address to an absolute address. */
12137 enum rtx_code code;
12139 /* We can't use @GOTOFF for text labels on VxWorks;
12140 see gotoff_operand. */
12141 if (TARGET_64BIT || TARGET_VXWORKS_RTP)
12145 op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
12147 else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
12151 op1 = pic_offset_table_rtx;
12156 op0 = pic_offset_table_rtx;
12160 operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
12164 if (TARGET_X32 || TARGET_INDIRECT_BRANCH_REGISTER)
12165 operands[0] = convert_memory_address (word_mode, operands[0]);
12166 cfun->machine->has_local_indirect_jump = true;
12169 (define_insn "*tablejump_1"
12170 [(set (pc) (match_operand:W 0 "indirect_branch_operand" "rBw"))
12171 (use (label_ref (match_operand 1)))]
12173 "* return ix86_output_indirect_jmp (operands[0]);"
12174 [(set (attr "type")
12175 (if_then_else (match_test "(cfun->machine->indirect_branch_type
12176 != indirect_branch_keep)")
12177 (const_string "multi")
12178 (const_string "ibr")))
12179 (set_attr "length_immediate" "0")])
12181 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
12184 [(set (reg FLAGS_REG) (match_operand 0))
12185 (set (match_operand:QI 1 "register_operand")
12186 (match_operator:QI 2 "ix86_comparison_operator"
12187 [(reg FLAGS_REG) (const_int 0)]))
12188 (set (match_operand 3 "any_QIreg_operand")
12189 (zero_extend (match_dup 1)))]
12190 "(peep2_reg_dead_p (3, operands[1])
12191 || operands_match_p (operands[1], operands[3]))
12192 && ! reg_overlap_mentioned_p (operands[3], operands[0])
12193 && peep2_regno_dead_p (0, FLAGS_REG)"
12194 [(set (match_dup 4) (match_dup 0))
12195 (set (strict_low_part (match_dup 5))
12198 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
12199 operands[5] = gen_lowpart (QImode, operands[3]);
12200 ix86_expand_clear (operands[3]);
12204 [(parallel [(set (reg FLAGS_REG) (match_operand 0))
12205 (match_operand 4)])
12206 (set (match_operand:QI 1 "register_operand")
12207 (match_operator:QI 2 "ix86_comparison_operator"
12208 [(reg FLAGS_REG) (const_int 0)]))
12209 (set (match_operand 3 "any_QIreg_operand")
12210 (zero_extend (match_dup 1)))]
12211 "(peep2_reg_dead_p (3, operands[1])
12212 || operands_match_p (operands[1], operands[3]))
12213 && ! reg_overlap_mentioned_p (operands[3], operands[0])
12214 && ! reg_overlap_mentioned_p (operands[3], operands[4])
12215 && ! reg_set_p (operands[3], operands[4])
12216 && peep2_regno_dead_p (0, FLAGS_REG)"
12217 [(parallel [(set (match_dup 5) (match_dup 0))
12219 (set (strict_low_part (match_dup 6))
12222 operands[5] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
12223 operands[6] = gen_lowpart (QImode, operands[3]);
12224 ix86_expand_clear (operands[3]);
12228 [(set (reg FLAGS_REG) (match_operand 0))
12229 (parallel [(set (reg FLAGS_REG) (match_operand 1))
12230 (match_operand 5)])
12231 (set (match_operand:QI 2 "register_operand")
12232 (match_operator:QI 3 "ix86_comparison_operator"
12233 [(reg FLAGS_REG) (const_int 0)]))
12234 (set (match_operand 4 "any_QIreg_operand")
12235 (zero_extend (match_dup 2)))]
12236 "(peep2_reg_dead_p (4, operands[2])
12237 || operands_match_p (operands[2], operands[4]))
12238 && ! reg_overlap_mentioned_p (operands[4], operands[0])
12239 && ! reg_overlap_mentioned_p (operands[4], operands[1])
12240 && ! reg_overlap_mentioned_p (operands[4], operands[5])
12241 && ! reg_set_p (operands[4], operands[5])
12242 && refers_to_regno_p (FLAGS_REG, operands[1], (rtx *)NULL)
12243 && peep2_regno_dead_p (0, FLAGS_REG)"
12244 [(set (match_dup 6) (match_dup 0))
12245 (parallel [(set (match_dup 7) (match_dup 1))
12247 (set (strict_low_part (match_dup 8))
12250 operands[6] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
12251 operands[7] = gen_rtx_REG (GET_MODE (operands[1]), FLAGS_REG);
12252 operands[8] = gen_lowpart (QImode, operands[4]);
12253 ix86_expand_clear (operands[4]);
12256 ;; Similar, but match zero extend with andsi3.
12259 [(set (reg FLAGS_REG) (match_operand 0))
12260 (set (match_operand:QI 1 "register_operand")
12261 (match_operator:QI 2 "ix86_comparison_operator"
12262 [(reg FLAGS_REG) (const_int 0)]))
12263 (parallel [(set (match_operand:SI 3 "any_QIreg_operand")
12264 (and:SI (match_dup 3) (const_int 255)))
12265 (clobber (reg:CC FLAGS_REG))])]
12266 "REGNO (operands[1]) == REGNO (operands[3])
12267 && ! reg_overlap_mentioned_p (operands[3], operands[0])
12268 && peep2_regno_dead_p (0, FLAGS_REG)"
12269 [(set (match_dup 4) (match_dup 0))
12270 (set (strict_low_part (match_dup 5))
12273 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
12274 operands[5] = gen_lowpart (QImode, operands[3]);
12275 ix86_expand_clear (operands[3]);
12279 [(parallel [(set (reg FLAGS_REG) (match_operand 0))
12280 (match_operand 4)])
12281 (set (match_operand:QI 1 "register_operand")
12282 (match_operator:QI 2 "ix86_comparison_operator"
12283 [(reg FLAGS_REG) (const_int 0)]))
12284 (parallel [(set (match_operand 3 "any_QIreg_operand")
12285 (zero_extend (match_dup 1)))
12286 (clobber (reg:CC FLAGS_REG))])]
12287 "(peep2_reg_dead_p (3, operands[1])
12288 || operands_match_p (operands[1], operands[3]))
12289 && ! reg_overlap_mentioned_p (operands[3], operands[0])
12290 && ! reg_overlap_mentioned_p (operands[3], operands[4])
12291 && ! reg_set_p (operands[3], operands[4])
12292 && peep2_regno_dead_p (0, FLAGS_REG)"
12293 [(parallel [(set (match_dup 5) (match_dup 0))
12295 (set (strict_low_part (match_dup 6))
12298 operands[5] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
12299 operands[6] = gen_lowpart (QImode, operands[3]);
12300 ix86_expand_clear (operands[3]);
12304 [(set (reg FLAGS_REG) (match_operand 0))
12305 (parallel [(set (reg FLAGS_REG) (match_operand 1))
12306 (match_operand 5)])
12307 (set (match_operand:QI 2 "register_operand")
12308 (match_operator:QI 3 "ix86_comparison_operator"
12309 [(reg FLAGS_REG) (const_int 0)]))
12310 (parallel [(set (match_operand 4 "any_QIreg_operand")
12311 (zero_extend (match_dup 2)))
12312 (clobber (reg:CC FLAGS_REG))])]
12313 "(peep2_reg_dead_p (4, operands[2])
12314 || operands_match_p (operands[2], operands[4]))
12315 && ! reg_overlap_mentioned_p (operands[4], operands[0])
12316 && ! reg_overlap_mentioned_p (operands[4], operands[1])
12317 && ! reg_overlap_mentioned_p (operands[4], operands[5])
12318 && ! reg_set_p (operands[4], operands[5])
12319 && refers_to_regno_p (FLAGS_REG, operands[1], (rtx *)NULL)
12320 && peep2_regno_dead_p (0, FLAGS_REG)"
12321 [(set (match_dup 6) (match_dup 0))
12322 (parallel [(set (match_dup 7) (match_dup 1))
12324 (set (strict_low_part (match_dup 8))
12327 operands[6] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
12328 operands[7] = gen_rtx_REG (GET_MODE (operands[1]), FLAGS_REG);
12329 operands[8] = gen_lowpart (QImode, operands[4]);
12330 ix86_expand_clear (operands[4]);
12333 ;; Call instructions.
12335 ;; The predicates normally associated with named expanders are not properly
12336 ;; checked for calls. This is a bug in the generic code, but it isn't that
12337 ;; easy to fix. Ignore it for now and be prepared to fix things up.
12339 ;; P6 processors will jump to the address after the decrement when %esp
12340 ;; is used as a call operand, so they will execute return address as a code.
12341 ;; See Pentium Pro errata 70, Pentium 2 errata A33 and Pentium 3 errata E17.
12343 ;; Register constraint for call instruction.
12344 (define_mode_attr c [(SI "l") (DI "r")])
12346 ;; Call subroutine returning no value.
12348 (define_expand "call"
12349 [(call (match_operand:QI 0)
12351 (use (match_operand 2))]
12354 ix86_expand_call (NULL, operands[0], operands[1],
12355 operands[2], NULL, false);
12359 (define_expand "sibcall"
12360 [(call (match_operand:QI 0)
12362 (use (match_operand 2))]
12365 ix86_expand_call (NULL, operands[0], operands[1],
12366 operands[2], NULL, true);
12370 (define_insn "*call"
12371 [(call (mem:QI (match_operand:W 0 "call_insn_operand" "<c>BwBz"))
12372 (match_operand 1))]
12373 "!SIBLING_CALL_P (insn)"
12374 "* return ix86_output_call_insn (insn, operands[0]);"
12375 [(set_attr "type" "call")])
12377 ;; This covers both call and sibcall since only GOT slot is allowed.
12378 (define_insn "*call_got_x32"
12379 [(call (mem:QI (zero_extend:DI
12380 (match_operand:SI 0 "GOT_memory_operand" "Bg")))
12381 (match_operand 1))]
12384 rtx fnaddr = gen_const_mem (DImode, XEXP (operands[0], 0));
12385 return ix86_output_call_insn (insn, fnaddr);
12387 [(set_attr "type" "call")])
12389 ;; Since sibcall never returns, we can only use call-clobbered register
12391 (define_insn "*sibcall_GOT_32"
12394 (match_operand:SI 0 "register_no_elim_operand" "U")
12395 (match_operand:SI 1 "GOT32_symbol_operand"))))
12396 (match_operand 2))]
12399 && !TARGET_INDIRECT_BRANCH_REGISTER
12400 && SIBLING_CALL_P (insn)"
12402 rtx fnaddr = gen_rtx_PLUS (SImode, operands[0], operands[1]);
12403 fnaddr = gen_const_mem (SImode, fnaddr);
12404 return ix86_output_call_insn (insn, fnaddr);
12406 [(set_attr "type" "call")])
12408 (define_insn "*sibcall"
12409 [(call (mem:QI (match_operand:W 0 "sibcall_insn_operand" "UBsBz"))
12410 (match_operand 1))]
12411 "SIBLING_CALL_P (insn)"
12412 "* return ix86_output_call_insn (insn, operands[0]);"
12413 [(set_attr "type" "call")])
12415 (define_insn "*sibcall_memory"
12416 [(call (mem:QI (match_operand:W 0 "memory_operand" "m"))
12418 (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
12419 "!TARGET_X32 && !TARGET_INDIRECT_BRANCH_REGISTER"
12420 "* return ix86_output_call_insn (insn, operands[0]);"
12421 [(set_attr "type" "call")])
12424 [(set (match_operand:W 0 "register_operand")
12425 (match_operand:W 1 "memory_operand"))
12426 (call (mem:QI (match_dup 0))
12427 (match_operand 3))]
12429 && !TARGET_INDIRECT_BRANCH_REGISTER
12430 && SIBLING_CALL_P (peep2_next_insn (1))
12431 && !reg_mentioned_p (operands[0],
12432 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (1)))"
12433 [(parallel [(call (mem:QI (match_dup 1))
12435 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
12438 [(set (match_operand:W 0 "register_operand")
12439 (match_operand:W 1 "memory_operand"))
12440 (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
12441 (call (mem:QI (match_dup 0))
12442 (match_operand 3))]
12444 && !TARGET_INDIRECT_BRANCH_REGISTER
12445 && SIBLING_CALL_P (peep2_next_insn (2))
12446 && !reg_mentioned_p (operands[0],
12447 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (2)))"
12448 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
12449 (parallel [(call (mem:QI (match_dup 1))
12451 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
12453 (define_expand "call_pop"
12454 [(parallel [(call (match_operand:QI 0)
12455 (match_operand:SI 1))
12456 (set (reg:SI SP_REG)
12457 (plus:SI (reg:SI SP_REG)
12458 (match_operand:SI 3)))])]
12461 ix86_expand_call (NULL, operands[0], operands[1],
12462 operands[2], operands[3], false);
12466 (define_insn "*call_pop"
12467 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lBwBz"))
12469 (set (reg:SI SP_REG)
12470 (plus:SI (reg:SI SP_REG)
12471 (match_operand:SI 2 "immediate_operand" "i")))]
12472 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
12473 "* return ix86_output_call_insn (insn, operands[0]);"
12474 [(set_attr "type" "call")])
12476 (define_insn "*sibcall_pop"
12477 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "UBsBz"))
12479 (set (reg:SI SP_REG)
12480 (plus:SI (reg:SI SP_REG)
12481 (match_operand:SI 2 "immediate_operand" "i")))]
12482 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
12483 "* return ix86_output_call_insn (insn, operands[0]);"
12484 [(set_attr "type" "call")])
12486 (define_insn "*sibcall_pop_memory"
12487 [(call (mem:QI (match_operand:SI 0 "memory_operand" "Bs"))
12489 (set (reg:SI SP_REG)
12490 (plus:SI (reg:SI SP_REG)
12491 (match_operand:SI 2 "immediate_operand" "i")))
12492 (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
12494 "* return ix86_output_call_insn (insn, operands[0]);"
12495 [(set_attr "type" "call")])
12498 [(set (match_operand:SI 0 "register_operand")
12499 (match_operand:SI 1 "memory_operand"))
12500 (parallel [(call (mem:QI (match_dup 0))
12502 (set (reg:SI SP_REG)
12503 (plus:SI (reg:SI SP_REG)
12504 (match_operand:SI 4 "immediate_operand")))])]
12505 "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (1))
12506 && !reg_mentioned_p (operands[0],
12507 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (1)))"
12508 [(parallel [(call (mem:QI (match_dup 1))
12510 (set (reg:SI SP_REG)
12511 (plus:SI (reg:SI SP_REG)
12513 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
12516 [(set (match_operand:SI 0 "register_operand")
12517 (match_operand:SI 1 "memory_operand"))
12518 (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
12519 (parallel [(call (mem:QI (match_dup 0))
12521 (set (reg:SI SP_REG)
12522 (plus:SI (reg:SI SP_REG)
12523 (match_operand:SI 4 "immediate_operand")))])]
12524 "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (2))
12525 && !reg_mentioned_p (operands[0],
12526 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (2)))"
12527 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
12528 (parallel [(call (mem:QI (match_dup 1))
12530 (set (reg:SI SP_REG)
12531 (plus:SI (reg:SI SP_REG)
12533 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
12535 ;; Combining simple memory jump instruction
12538 [(set (match_operand:W 0 "register_operand")
12539 (match_operand:W 1 "memory_operand"))
12540 (set (pc) (match_dup 0))]
12542 && !TARGET_INDIRECT_BRANCH_REGISTER
12543 && peep2_reg_dead_p (2, operands[0])"
12544 [(set (pc) (match_dup 1))])
12546 ;; Call subroutine, returning value in operand 0
12548 (define_expand "call_value"
12549 [(set (match_operand 0)
12550 (call (match_operand:QI 1)
12551 (match_operand 2)))
12552 (use (match_operand 3))]
12555 ix86_expand_call (operands[0], operands[1], operands[2],
12556 operands[3], NULL, false);
12560 (define_expand "sibcall_value"
12561 [(set (match_operand 0)
12562 (call (match_operand:QI 1)
12563 (match_operand 2)))
12564 (use (match_operand 3))]
12567 ix86_expand_call (operands[0], operands[1], operands[2],
12568 operands[3], NULL, true);
12572 (define_insn "*call_value"
12573 [(set (match_operand 0)
12574 (call (mem:QI (match_operand:W 1 "call_insn_operand" "<c>BwBz"))
12575 (match_operand 2)))]
12576 "!SIBLING_CALL_P (insn)"
12577 "* return ix86_output_call_insn (insn, operands[1]);"
12578 [(set_attr "type" "callv")])
12580 ;; This covers both call and sibcall since only GOT slot is allowed.
12581 (define_insn "*call_value_got_x32"
12582 [(set (match_operand 0)
12585 (match_operand:SI 1 "GOT_memory_operand" "Bg")))
12586 (match_operand 2)))]
12589 rtx fnaddr = gen_const_mem (DImode, XEXP (operands[1], 0));
12590 return ix86_output_call_insn (insn, fnaddr);
12592 [(set_attr "type" "callv")])
12594 ;; Since sibcall never returns, we can only use call-clobbered register
12596 (define_insn "*sibcall_value_GOT_32"
12597 [(set (match_operand 0)
12600 (match_operand:SI 1 "register_no_elim_operand" "U")
12601 (match_operand:SI 2 "GOT32_symbol_operand"))))
12602 (match_operand 3)))]
12605 && !TARGET_INDIRECT_BRANCH_REGISTER
12606 && SIBLING_CALL_P (insn)"
12608 rtx fnaddr = gen_rtx_PLUS (SImode, operands[1], operands[2]);
12609 fnaddr = gen_const_mem (SImode, fnaddr);
12610 return ix86_output_call_insn (insn, fnaddr);
12612 [(set_attr "type" "callv")])
12614 (define_insn "*sibcall_value"
12615 [(set (match_operand 0)
12616 (call (mem:QI (match_operand:W 1 "sibcall_insn_operand" "UBsBz"))
12617 (match_operand 2)))]
12618 "SIBLING_CALL_P (insn)"
12619 "* return ix86_output_call_insn (insn, operands[1]);"
12620 [(set_attr "type" "callv")])
12622 (define_insn "*sibcall_value_memory"
12623 [(set (match_operand 0)
12624 (call (mem:QI (match_operand:W 1 "memory_operand" "m"))
12625 (match_operand 2)))
12626 (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
12627 "!TARGET_X32 && !TARGET_INDIRECT_BRANCH_REGISTER"
12628 "* return ix86_output_call_insn (insn, operands[1]);"
12629 [(set_attr "type" "callv")])
12632 [(set (match_operand:W 0 "register_operand")
12633 (match_operand:W 1 "memory_operand"))
12634 (set (match_operand 2)
12635 (call (mem:QI (match_dup 0))
12636 (match_operand 3)))]
12638 && !TARGET_INDIRECT_BRANCH_REGISTER
12639 && SIBLING_CALL_P (peep2_next_insn (1))
12640 && !reg_mentioned_p (operands[0],
12641 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (1)))"
12642 [(parallel [(set (match_dup 2)
12643 (call (mem:QI (match_dup 1))
12645 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
12648 [(set (match_operand:W 0 "register_operand")
12649 (match_operand:W 1 "memory_operand"))
12650 (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
12651 (set (match_operand 2)
12652 (call (mem:QI (match_dup 0))
12653 (match_operand 3)))]
12655 && !TARGET_INDIRECT_BRANCH_REGISTER
12656 && SIBLING_CALL_P (peep2_next_insn (2))
12657 && !reg_mentioned_p (operands[0],
12658 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (2)))"
12659 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
12660 (parallel [(set (match_dup 2)
12661 (call (mem:QI (match_dup 1))
12663 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
12665 (define_expand "call_value_pop"
12666 [(parallel [(set (match_operand 0)
12667 (call (match_operand:QI 1)
12668 (match_operand:SI 2)))
12669 (set (reg:SI SP_REG)
12670 (plus:SI (reg:SI SP_REG)
12671 (match_operand:SI 4)))])]
12674 ix86_expand_call (operands[0], operands[1], operands[2],
12675 operands[3], operands[4], false);
12679 (define_insn "*call_value_pop"
12680 [(set (match_operand 0)
12681 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lBwBz"))
12682 (match_operand 2)))
12683 (set (reg:SI SP_REG)
12684 (plus:SI (reg:SI SP_REG)
12685 (match_operand:SI 3 "immediate_operand" "i")))]
12686 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
12687 "* return ix86_output_call_insn (insn, operands[1]);"
12688 [(set_attr "type" "callv")])
12690 (define_insn "*sibcall_value_pop"
12691 [(set (match_operand 0)
12692 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "UBsBz"))
12693 (match_operand 2)))
12694 (set (reg:SI SP_REG)
12695 (plus:SI (reg:SI SP_REG)
12696 (match_operand:SI 3 "immediate_operand" "i")))]
12697 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
12698 "* return ix86_output_call_insn (insn, operands[1]);"
12699 [(set_attr "type" "callv")])
12701 (define_insn "*sibcall_value_pop_memory"
12702 [(set (match_operand 0)
12703 (call (mem:QI (match_operand:SI 1 "memory_operand" "m"))
12704 (match_operand 2)))
12705 (set (reg:SI SP_REG)
12706 (plus:SI (reg:SI SP_REG)
12707 (match_operand:SI 3 "immediate_operand" "i")))
12708 (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
12710 "* return ix86_output_call_insn (insn, operands[1]);"
12711 [(set_attr "type" "callv")])
12714 [(set (match_operand:SI 0 "register_operand")
12715 (match_operand:SI 1 "memory_operand"))
12716 (parallel [(set (match_operand 2)
12717 (call (mem:QI (match_dup 0))
12718 (match_operand 3)))
12719 (set (reg:SI SP_REG)
12720 (plus:SI (reg:SI SP_REG)
12721 (match_operand:SI 4 "immediate_operand")))])]
12722 "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (1))
12723 && !reg_mentioned_p (operands[0],
12724 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (1)))"
12725 [(parallel [(set (match_dup 2)
12726 (call (mem:QI (match_dup 1))
12728 (set (reg:SI SP_REG)
12729 (plus:SI (reg:SI SP_REG)
12731 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
12734 [(set (match_operand:SI 0 "register_operand")
12735 (match_operand:SI 1 "memory_operand"))
12736 (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
12737 (parallel [(set (match_operand 2)
12738 (call (mem:QI (match_dup 0))
12739 (match_operand 3)))
12740 (set (reg:SI SP_REG)
12741 (plus:SI (reg:SI SP_REG)
12742 (match_operand:SI 4 "immediate_operand")))])]
12743 "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (2))
12744 && !reg_mentioned_p (operands[0],
12745 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (2)))"
12746 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
12747 (parallel [(set (match_dup 2)
12748 (call (mem:QI (match_dup 1))
12750 (set (reg:SI SP_REG)
12751 (plus:SI (reg:SI SP_REG)
12753 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
12755 ;; Call subroutine returning any type.
12757 (define_expand "untyped_call"
12758 [(parallel [(call (match_operand 0)
12761 (match_operand 2)])]
12766 /* In order to give reg-stack an easier job in validating two
12767 coprocessor registers as containing a possible return value,
12768 simply pretend the untyped call returns a complex long double
12771 We can't use SSE_REGPARM_MAX here since callee is unprototyped
12772 and should have the default ABI. */
12774 ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
12775 ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
12776 operands[0], const0_rtx,
12777 GEN_INT ((TARGET_64BIT
12778 ? (ix86_abi == SYSV_ABI
12779 ? X86_64_SSE_REGPARM_MAX
12780 : X86_64_MS_SSE_REGPARM_MAX)
12781 : X86_32_SSE_REGPARM_MAX)
12785 for (i = 0; i < XVECLEN (operands[2], 0); i++)
12787 rtx set = XVECEXP (operands[2], 0, i);
12788 emit_move_insn (SET_DEST (set), SET_SRC (set));
12791 /* The optimizer does not know that the call sets the function value
12792 registers we stored in the result block. We avoid problems by
12793 claiming that all hard registers are used and clobbered at this
12795 emit_insn (gen_blockage ());
12800 ;; Prologue and epilogue instructions
12802 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
12803 ;; all of memory. This blocks insns from being moved across this point.
12805 (define_insn "blockage"
12806 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
12809 [(set_attr "length" "0")])
12811 ;; Do not schedule instructions accessing memory across this point.
12813 (define_expand "memory_blockage"
12814 [(set (match_dup 0)
12815 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
12818 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
12819 MEM_VOLATILE_P (operands[0]) = 1;
12822 (define_insn "*memory_blockage"
12823 [(set (match_operand:BLK 0)
12824 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
12827 [(set_attr "length" "0")])
12829 ;; As USE insns aren't meaningful after reload, this is used instead
12830 ;; to prevent deleting instructions setting registers for PIC code
12831 (define_insn "prologue_use"
12832 [(unspec_volatile [(match_operand 0)] UNSPECV_PROLOGUE_USE)]
12835 [(set_attr "length" "0")])
12837 ;; Insn emitted into the body of a function to return from a function.
12838 ;; This is only done if the function's epilogue is known to be simple.
12839 ;; See comments for ix86_can_use_return_insn_p in i386.c.
12841 (define_expand "return"
12843 "ix86_can_use_return_insn_p ()"
12845 if (crtl->args.pops_args)
12847 rtx popc = GEN_INT (crtl->args.pops_args);
12848 emit_jump_insn (gen_simple_return_pop_internal (popc));
12853 ;; We need to disable this for TARGET_SEH, as otherwise
12854 ;; shrink-wrapped prologue gets enabled too. This might exceed
12855 ;; the maximum size of prologue in unwind information.
12856 ;; Also disallow shrink-wrapping if using stack slot to pass the
12857 ;; static chain pointer - the first instruction has to be pushl %esi
12858 ;; and it can't be moved around, as we use alternate entry points
12861 (define_expand "simple_return"
12863 "!TARGET_SEH && !ix86_static_chain_on_stack"
12865 if (crtl->args.pops_args)
12867 rtx popc = GEN_INT (crtl->args.pops_args);
12868 emit_jump_insn (gen_simple_return_pop_internal (popc));
12873 (define_insn "simple_return_internal"
12876 "* return ix86_output_function_return (false);"
12877 [(set_attr "length" "1")
12878 (set_attr "atom_unit" "jeu")
12879 (set_attr "length_immediate" "0")
12880 (set_attr "modrm" "0")])
12882 (define_insn "interrupt_return"
12884 (unspec [(const_int 0)] UNSPEC_INTERRUPT_RETURN)]
12887 return TARGET_64BIT ? "iretq" : "iret";
12890 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
12891 ;; instruction Athlon and K8 have.
12893 (define_insn "simple_return_internal_long"
12895 (unspec [(const_int 0)] UNSPEC_REP)]
12897 "* return ix86_output_function_return (true);"
12898 [(set_attr "length" "2")
12899 (set_attr "atom_unit" "jeu")
12900 (set_attr "length_immediate" "0")
12901 (set_attr "prefix_rep" "1")
12902 (set_attr "modrm" "0")])
12904 (define_insn_and_split "simple_return_pop_internal"
12906 (use (match_operand:SI 0 "const_int_operand"))]
12909 "&& cfun->machine->function_return_type != indirect_branch_keep"
12911 "ix86_split_simple_return_pop_internal (operands[0]); DONE;"
12912 [(set_attr "length" "3")
12913 (set_attr "atom_unit" "jeu")
12914 (set_attr "length_immediate" "2")
12915 (set_attr "modrm" "0")])
12917 (define_expand "simple_return_indirect_internal"
12920 (use (match_operand 0 "register_operand"))])])
12922 (define_insn "*simple_return_indirect_internal<mode>"
12924 (use (match_operand:W 0 "register_operand" "r"))]
12926 "* return ix86_output_indirect_function_return (operands[0]);"
12927 [(set (attr "type")
12928 (if_then_else (match_test "(cfun->machine->indirect_branch_type
12929 != indirect_branch_keep)")
12930 (const_string "multi")
12931 (const_string "ibr")))
12932 (set_attr "length_immediate" "0")])
12938 [(set_attr "length" "1")
12939 (set_attr "length_immediate" "0")
12940 (set_attr "modrm" "0")])
12942 ;; Generate nops. Operand 0 is the number of nops, up to 8.
12943 (define_insn "nops"
12944 [(unspec_volatile [(match_operand 0 "const_int_operand")]
12948 int num = INTVAL (operands[0]);
12950 gcc_assert (IN_RANGE (num, 1, 8));
12953 fputs ("\tnop\n", asm_out_file);
12957 [(set (attr "length") (symbol_ref "INTVAL (operands[0])"))
12958 (set_attr "length_immediate" "0")
12959 (set_attr "modrm" "0")])
12961 ;; Pad to 16-byte boundary, max skip in op0. Used to avoid
12962 ;; branch prediction penalty for the third jump in a 16-byte
12966 [(unspec_volatile [(match_operand 0)] UNSPECV_ALIGN)]
12969 #ifdef ASM_OUTPUT_MAX_SKIP_PAD
12970 ASM_OUTPUT_MAX_SKIP_PAD (asm_out_file, 4, (int)INTVAL (operands[0]));
12972 /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
12973 The align insn is used to avoid 3 jump instructions in the row to improve
12974 branch prediction and the benefits hardly outweigh the cost of extra 8
12975 nops on the average inserted by full alignment pseudo operation. */
12979 [(set_attr "length" "16")])
12981 (define_expand "prologue"
12984 "ix86_expand_prologue (); DONE;")
12986 (define_expand "set_got"
12988 [(set (match_operand:SI 0 "register_operand")
12989 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
12990 (clobber (reg:CC FLAGS_REG))])]
12993 if (flag_pic && !TARGET_VXWORKS_RTP)
12994 ix86_pc_thunk_call_expanded = true;
12997 (define_insn "*set_got"
12998 [(set (match_operand:SI 0 "register_operand" "=r")
12999 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
13000 (clobber (reg:CC FLAGS_REG))]
13002 "* return output_set_got (operands[0], NULL_RTX);"
13003 [(set_attr "type" "multi")
13004 (set_attr "length" "12")])
13006 (define_expand "set_got_labelled"
13008 [(set (match_operand:SI 0 "register_operand")
13009 (unspec:SI [(label_ref (match_operand 1))]
13011 (clobber (reg:CC FLAGS_REG))])]
13014 if (flag_pic && !TARGET_VXWORKS_RTP)
13015 ix86_pc_thunk_call_expanded = true;
13018 (define_insn "*set_got_labelled"
13019 [(set (match_operand:SI 0 "register_operand" "=r")
13020 (unspec:SI [(label_ref (match_operand 1))]
13022 (clobber (reg:CC FLAGS_REG))]
13024 "* return output_set_got (operands[0], operands[1]);"
13025 [(set_attr "type" "multi")
13026 (set_attr "length" "12")])
13028 (define_insn "set_got_rex64"
13029 [(set (match_operand:DI 0 "register_operand" "=r")
13030 (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
13032 "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}"
13033 [(set_attr "type" "lea")
13034 (set_attr "length_address" "4")
13035 (set_attr "mode" "DI")])
13037 (define_insn "set_rip_rex64"
13038 [(set (match_operand:DI 0 "register_operand" "=r")
13039 (unspec:DI [(label_ref (match_operand 1))] UNSPEC_SET_RIP))]
13041 "lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}"
13042 [(set_attr "type" "lea")
13043 (set_attr "length_address" "4")
13044 (set_attr "mode" "DI")])
13046 (define_insn "set_got_offset_rex64"
13047 [(set (match_operand:DI 0 "register_operand" "=r")
13049 [(label_ref (match_operand 1))]
13050 UNSPEC_SET_GOT_OFFSET))]
13052 "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}"
13053 [(set_attr "type" "imov")
13054 (set_attr "length_immediate" "0")
13055 (set_attr "length_address" "8")
13056 (set_attr "mode" "DI")])
13058 (define_expand "epilogue"
13061 "ix86_expand_epilogue (1); DONE;")
13063 (define_expand "sibcall_epilogue"
13066 "ix86_expand_epilogue (0); DONE;")
13068 (define_expand "eh_return"
13069 [(use (match_operand 0 "register_operand"))]
13072 rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
13074 /* Tricky bit: we write the address of the handler to which we will
13075 be returning into someone else's stack frame, one word below the
13076 stack address we wish to restore. */
13077 tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
13078 tmp = plus_constant (Pmode, tmp, -UNITS_PER_WORD);
13079 /* Return address is always in word_mode. */
13080 tmp = gen_rtx_MEM (word_mode, tmp);
13081 if (GET_MODE (ra) != word_mode)
13082 ra = convert_to_mode (word_mode, ra, 1);
13083 emit_move_insn (tmp, ra);
13085 emit_jump_insn (gen_eh_return_internal ());
13090 (define_insn_and_split "eh_return_internal"
13094 "epilogue_completed"
13096 "ix86_expand_epilogue (2); DONE;")
13098 (define_insn "leave"
13099 [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
13100 (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
13101 (clobber (mem:BLK (scratch)))]
13104 [(set_attr "type" "leave")])
13106 (define_insn "leave_rex64"
13107 [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
13108 (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
13109 (clobber (mem:BLK (scratch)))]
13112 [(set_attr "type" "leave")])
13114 ;; Handle -fsplit-stack.
13116 (define_expand "split_stack_prologue"
13120 ix86_expand_split_stack_prologue ();
13124 ;; In order to support the call/return predictor, we use a return
13125 ;; instruction which the middle-end doesn't see.
13126 (define_insn "split_stack_return"
13127 [(unspec_volatile [(match_operand:SI 0 "const_int_operand")]
13128 UNSPECV_SPLIT_STACK_RETURN)]
13131 if (operands[0] == const0_rtx)
13136 [(set_attr "atom_unit" "jeu")
13137 (set_attr "modrm" "0")
13138 (set (attr "length")
13139 (if_then_else (match_operand:SI 0 "const0_operand")
13142 (set (attr "length_immediate")
13143 (if_then_else (match_operand:SI 0 "const0_operand")
13147 ;; If there are operand 0 bytes available on the stack, jump to
13150 (define_expand "split_stack_space_check"
13151 [(set (pc) (if_then_else
13152 (ltu (minus (reg SP_REG)
13153 (match_operand 0 "register_operand"))
13155 (label_ref (match_operand 1))
13159 rtx reg = gen_reg_rtx (Pmode);
13161 emit_insn (gen_sub3_insn (reg, stack_pointer_rtx, operands[0]));
13163 operands[2] = ix86_split_stack_guard ();
13164 ix86_expand_branch (GEU, reg, operands[2], operands[1]);
13169 ;; Bit manipulation instructions.
13171 (define_expand "ffs<mode>2"
13172 [(set (match_dup 2) (const_int -1))
13173 (parallel [(set (match_dup 3) (match_dup 4))
13174 (set (match_operand:SWI48 0 "register_operand")
13176 (match_operand:SWI48 1 "nonimmediate_operand")))])
13177 (set (match_dup 0) (if_then_else:SWI48
13178 (eq (match_dup 3) (const_int 0))
13181 (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (const_int 1)))
13182 (clobber (reg:CC FLAGS_REG))])]
13185 machine_mode flags_mode;
13187 if (<MODE>mode == SImode && !TARGET_CMOVE)
13189 emit_insn (gen_ffssi2_no_cmove (operands[0], operands [1]));
13193 flags_mode = TARGET_BMI ? CCCmode : CCZmode;
13195 operands[2] = gen_reg_rtx (<MODE>mode);
13196 operands[3] = gen_rtx_REG (flags_mode, FLAGS_REG);
13197 operands[4] = gen_rtx_COMPARE (flags_mode, operands[1], const0_rtx);
13200 (define_insn_and_split "ffssi2_no_cmove"
13201 [(set (match_operand:SI 0 "register_operand" "=r")
13202 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
13203 (clobber (match_scratch:SI 2 "=&q"))
13204 (clobber (reg:CC FLAGS_REG))]
13207 "&& reload_completed"
13208 [(parallel [(set (match_dup 4) (match_dup 5))
13209 (set (match_dup 0) (ctz:SI (match_dup 1)))])
13210 (set (strict_low_part (match_dup 3))
13211 (eq:QI (match_dup 4) (const_int 0)))
13212 (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
13213 (clobber (reg:CC FLAGS_REG))])
13214 (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
13215 (clobber (reg:CC FLAGS_REG))])
13216 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
13217 (clobber (reg:CC FLAGS_REG))])]
13219 machine_mode flags_mode = TARGET_BMI ? CCCmode : CCZmode;
13221 operands[3] = gen_lowpart (QImode, operands[2]);
13222 operands[4] = gen_rtx_REG (flags_mode, FLAGS_REG);
13223 operands[5] = gen_rtx_COMPARE (flags_mode, operands[1], const0_rtx);
13225 ix86_expand_clear (operands[2]);
13228 (define_insn_and_split "*tzcnt<mode>_1"
13229 [(set (reg:CCC FLAGS_REG)
13230 (compare:CCC (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13232 (set (match_operand:SWI48 0 "register_operand" "=r")
13233 (ctz:SWI48 (match_dup 1)))]
13235 "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
13236 "&& TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
13237 && optimize_function_for_speed_p (cfun)
13238 && !reg_mentioned_p (operands[0], operands[1])"
13240 [(set (reg:CCC FLAGS_REG)
13241 (compare:CCC (match_dup 1) (const_int 0)))
13243 (ctz:SWI48 (match_dup 1)))
13244 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)])]
13245 "ix86_expand_clear (operands[0]);"
13246 [(set_attr "type" "alu1")
13247 (set_attr "prefix_0f" "1")
13248 (set_attr "prefix_rep" "1")
13249 (set_attr "btver2_decode" "double")
13250 (set_attr "mode" "<MODE>")])
13252 ; False dependency happens when destination is only updated by tzcnt,
13253 ; lzcnt or popcnt. There is no false dependency when destination is
13254 ; also used in source.
13255 (define_insn "*tzcnt<mode>_1_falsedep"
13256 [(set (reg:CCC FLAGS_REG)
13257 (compare:CCC (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13259 (set (match_operand:SWI48 0 "register_operand" "=r")
13260 (ctz:SWI48 (match_dup 1)))
13261 (unspec [(match_operand:SWI48 2 "register_operand" "0")]
13262 UNSPEC_INSN_FALSE_DEP)]
13264 "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
13265 [(set_attr "type" "alu1")
13266 (set_attr "prefix_0f" "1")
13267 (set_attr "prefix_rep" "1")
13268 (set_attr "btver2_decode" "double")
13269 (set_attr "mode" "<MODE>")])
13271 (define_insn "*bsf<mode>_1"
13272 [(set (reg:CCZ FLAGS_REG)
13273 (compare:CCZ (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13275 (set (match_operand:SWI48 0 "register_operand" "=r")
13276 (ctz:SWI48 (match_dup 1)))]
13278 "bsf{<imodesuffix>}\t{%1, %0|%0, %1}"
13279 [(set_attr "type" "alu1")
13280 (set_attr "prefix_0f" "1")
13281 (set_attr "btver2_decode" "double")
13282 (set_attr "znver1_decode" "vector")
13283 (set_attr "mode" "<MODE>")])
13285 (define_insn_and_split "ctz<mode>2"
13286 [(set (match_operand:SWI48 0 "register_operand" "=r")
13288 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
13289 (clobber (reg:CC FLAGS_REG))]
13293 return "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
13294 else if (optimize_function_for_size_p (cfun))
13296 else if (TARGET_GENERIC)
13297 /* tzcnt expands to 'rep bsf' and we can use it even if !TARGET_BMI. */
13298 return "rep%; bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
13300 return "bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
13302 "(TARGET_BMI || TARGET_GENERIC)
13303 && TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
13304 && optimize_function_for_speed_p (cfun)
13305 && !reg_mentioned_p (operands[0], operands[1])"
13307 [(set (match_dup 0)
13308 (ctz:SWI48 (match_dup 1)))
13309 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
13310 (clobber (reg:CC FLAGS_REG))])]
13311 "ix86_expand_clear (operands[0]);"
13312 [(set_attr "type" "alu1")
13313 (set_attr "prefix_0f" "1")
13314 (set (attr "prefix_rep")
13316 (ior (match_test "TARGET_BMI")
13317 (and (not (match_test "optimize_function_for_size_p (cfun)"))
13318 (match_test "TARGET_GENERIC")))
13320 (const_string "0")))
13321 (set_attr "mode" "<MODE>")])
13323 ; False dependency happens when destination is only updated by tzcnt,
13324 ; lzcnt or popcnt. There is no false dependency when destination is
13325 ; also used in source.
13326 (define_insn "*ctz<mode>2_falsedep"
13327 [(set (match_operand:SWI48 0 "register_operand" "=r")
13329 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
13330 (unspec [(match_operand:SWI48 2 "register_operand" "0")]
13331 UNSPEC_INSN_FALSE_DEP)
13332 (clobber (reg:CC FLAGS_REG))]
13336 return "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
13337 else if (TARGET_GENERIC)
13338 /* tzcnt expands to 'rep bsf' and we can use it even if !TARGET_BMI. */
13339 return "rep%; bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
13341 gcc_unreachable ();
13343 [(set_attr "type" "alu1")
13344 (set_attr "prefix_0f" "1")
13345 (set_attr "prefix_rep" "1")
13346 (set_attr "mode" "<MODE>")])
13348 (define_insn "bsr_rex64"
13349 [(set (match_operand:DI 0 "register_operand" "=r")
13350 (minus:DI (const_int 63)
13351 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
13352 (clobber (reg:CC FLAGS_REG))]
13354 "bsr{q}\t{%1, %0|%0, %1}"
13355 [(set_attr "type" "alu1")
13356 (set_attr "prefix_0f" "1")
13357 (set_attr "znver1_decode" "vector")
13358 (set_attr "mode" "DI")])
13361 [(set (match_operand:SI 0 "register_operand" "=r")
13362 (minus:SI (const_int 31)
13363 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
13364 (clobber (reg:CC FLAGS_REG))]
13366 "bsr{l}\t{%1, %0|%0, %1}"
13367 [(set_attr "type" "alu1")
13368 (set_attr "prefix_0f" "1")
13369 (set_attr "znver1_decode" "vector")
13370 (set_attr "mode" "SI")])
13372 (define_insn "*bsrhi"
13373 [(set (match_operand:HI 0 "register_operand" "=r")
13374 (minus:HI (const_int 15)
13375 (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
13376 (clobber (reg:CC FLAGS_REG))]
13378 "bsr{w}\t{%1, %0|%0, %1}"
13379 [(set_attr "type" "alu1")
13380 (set_attr "prefix_0f" "1")
13381 (set_attr "znver1_decode" "vector")
13382 (set_attr "mode" "HI")])
13384 (define_expand "clz<mode>2"
13386 [(set (match_operand:SWI48 0 "register_operand")
13389 (clz:SWI48 (match_operand:SWI48 1 "nonimmediate_operand"))))
13390 (clobber (reg:CC FLAGS_REG))])
13392 [(set (match_dup 0) (xor:SWI48 (match_dup 0) (match_dup 2)))
13393 (clobber (reg:CC FLAGS_REG))])]
13398 emit_insn (gen_clz<mode>2_lzcnt (operands[0], operands[1]));
13401 operands[2] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
13404 (define_insn_and_split "clz<mode>2_lzcnt"
13405 [(set (match_operand:SWI48 0 "register_operand" "=r")
13407 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
13408 (clobber (reg:CC FLAGS_REG))]
13410 "lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
13411 "&& TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
13412 && optimize_function_for_speed_p (cfun)
13413 && !reg_mentioned_p (operands[0], operands[1])"
13415 [(set (match_dup 0)
13416 (clz:SWI48 (match_dup 1)))
13417 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
13418 (clobber (reg:CC FLAGS_REG))])]
13419 "ix86_expand_clear (operands[0]);"
13420 [(set_attr "prefix_rep" "1")
13421 (set_attr "type" "bitmanip")
13422 (set_attr "mode" "<MODE>")])
13424 ; False dependency happens when destination is only updated by tzcnt,
13425 ; lzcnt or popcnt. There is no false dependency when destination is
13426 ; also used in source.
13427 (define_insn "*clz<mode>2_lzcnt_falsedep"
13428 [(set (match_operand:SWI48 0 "register_operand" "=r")
13430 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
13431 (unspec [(match_operand:SWI48 2 "register_operand" "0")]
13432 UNSPEC_INSN_FALSE_DEP)
13433 (clobber (reg:CC FLAGS_REG))]
13435 "lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
13436 [(set_attr "prefix_rep" "1")
13437 (set_attr "type" "bitmanip")
13438 (set_attr "mode" "<MODE>")])
13440 (define_int_iterator LT_ZCNT
13441 [(UNSPEC_TZCNT "TARGET_BMI")
13442 (UNSPEC_LZCNT "TARGET_LZCNT")])
13444 (define_int_attr lt_zcnt
13445 [(UNSPEC_TZCNT "tzcnt")
13446 (UNSPEC_LZCNT "lzcnt")])
13448 (define_int_attr lt_zcnt_type
13449 [(UNSPEC_TZCNT "alu1")
13450 (UNSPEC_LZCNT "bitmanip")])
13452 ;; Version of lzcnt/tzcnt that is expanded from intrinsics. This version
13453 ;; provides operand size as output when source operand is zero.
13455 (define_insn_and_split "<lt_zcnt>_<mode>"
13456 [(set (match_operand:SWI48 0 "register_operand" "=r")
13458 [(match_operand:SWI48 1 "nonimmediate_operand" "rm")] LT_ZCNT))
13459 (clobber (reg:CC FLAGS_REG))]
13461 "<lt_zcnt>{<imodesuffix>}\t{%1, %0|%0, %1}"
13462 "&& TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
13463 && optimize_function_for_speed_p (cfun)
13464 && !reg_mentioned_p (operands[0], operands[1])"
13466 [(set (match_dup 0)
13467 (unspec:SWI48 [(match_dup 1)] LT_ZCNT))
13468 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
13469 (clobber (reg:CC FLAGS_REG))])]
13470 "ix86_expand_clear (operands[0]);"
13471 [(set_attr "type" "<lt_zcnt_type>")
13472 (set_attr "prefix_0f" "1")
13473 (set_attr "prefix_rep" "1")
13474 (set_attr "mode" "<MODE>")])
13476 ; False dependency happens when destination is only updated by tzcnt,
13477 ; lzcnt or popcnt. There is no false dependency when destination is
13478 ; also used in source.
13479 (define_insn "*<lt_zcnt>_<mode>_falsedep"
13480 [(set (match_operand:SWI48 0 "register_operand" "=r")
13482 [(match_operand:SWI48 1 "nonimmediate_operand" "rm")] LT_ZCNT))
13483 (unspec [(match_operand:SWI48 2 "register_operand" "0")]
13484 UNSPEC_INSN_FALSE_DEP)
13485 (clobber (reg:CC FLAGS_REG))]
13487 "<lt_zcnt>{<imodesuffix>}\t{%1, %0|%0, %1}"
13488 [(set_attr "type" "<lt_zcnt_type>")
13489 (set_attr "prefix_0f" "1")
13490 (set_attr "prefix_rep" "1")
13491 (set_attr "mode" "<MODE>")])
13493 (define_insn "<lt_zcnt>_hi"
13494 [(set (match_operand:HI 0 "register_operand" "=r")
13496 [(match_operand:HI 1 "nonimmediate_operand" "rm")] LT_ZCNT))
13497 (clobber (reg:CC FLAGS_REG))]
13499 "<lt_zcnt>{w}\t{%1, %0|%0, %1}"
13500 [(set_attr "type" "<lt_zcnt_type>")
13501 (set_attr "prefix_0f" "1")
13502 (set_attr "prefix_rep" "1")
13503 (set_attr "mode" "HI")])
13505 ;; BMI instructions.
13507 (define_insn "bmi_bextr_<mode>"
13508 [(set (match_operand:SWI48 0 "register_operand" "=r,r")
13509 (unspec:SWI48 [(match_operand:SWI48 1 "nonimmediate_operand" "r,m")
13510 (match_operand:SWI48 2 "register_operand" "r,r")]
13512 (clobber (reg:CC FLAGS_REG))]
13514 "bextr\t{%2, %1, %0|%0, %1, %2}"
13515 [(set_attr "type" "bitmanip")
13516 (set_attr "btver2_decode" "direct, double")
13517 (set_attr "mode" "<MODE>")])
13519 (define_insn "*bmi_bextr_<mode>_ccz"
13520 [(set (reg:CCZ FLAGS_REG)
13522 (unspec:SWI48 [(match_operand:SWI48 1 "nonimmediate_operand" "r,m")
13523 (match_operand:SWI48 2 "register_operand" "r,r")]
13526 (clobber (match_scratch:SWI48 0 "=r,r"))]
13528 "bextr\t{%2, %1, %0|%0, %1, %2}"
13529 [(set_attr "type" "bitmanip")
13530 (set_attr "btver2_decode" "direct, double")
13531 (set_attr "mode" "<MODE>")])
13533 (define_insn "*bmi_blsi_<mode>"
13534 [(set (match_operand:SWI48 0 "register_operand" "=r")
13537 (match_operand:SWI48 1 "nonimmediate_operand" "rm"))
13539 (clobber (reg:CC FLAGS_REG))]
13541 "blsi\t{%1, %0|%0, %1}"
13542 [(set_attr "type" "bitmanip")
13543 (set_attr "btver2_decode" "double")
13544 (set_attr "mode" "<MODE>")])
13546 (define_insn "*bmi_blsmsk_<mode>"
13547 [(set (match_operand:SWI48 0 "register_operand" "=r")
13550 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13553 (clobber (reg:CC FLAGS_REG))]
13555 "blsmsk\t{%1, %0|%0, %1}"
13556 [(set_attr "type" "bitmanip")
13557 (set_attr "btver2_decode" "double")
13558 (set_attr "mode" "<MODE>")])
13560 (define_insn "*bmi_blsr_<mode>"
13561 [(set (match_operand:SWI48 0 "register_operand" "=r")
13564 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13567 (clobber (reg:CC FLAGS_REG))]
13569 "blsr\t{%1, %0|%0, %1}"
13570 [(set_attr "type" "bitmanip")
13571 (set_attr "btver2_decode" "double")
13572 (set_attr "mode" "<MODE>")])
13574 (define_insn "*bmi_blsr_<mode>_cmp"
13575 [(set (reg:CCZ FLAGS_REG)
13579 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13583 (set (match_operand:SWI48 0 "register_operand" "=r")
13590 "blsr\t{%1, %0|%0, %1}"
13591 [(set_attr "type" "bitmanip")
13592 (set_attr "btver2_decode" "double")
13593 (set_attr "mode" "<MODE>")])
13595 (define_insn "*bmi_blsr_<mode>_ccz"
13596 [(set (reg:CCZ FLAGS_REG)
13600 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13604 (clobber (match_scratch:SWI48 0 "=r"))]
13606 "blsr\t{%1, %0|%0, %1}"
13607 [(set_attr "type" "bitmanip")
13608 (set_attr "btver2_decode" "double")
13609 (set_attr "mode" "<MODE>")])
13611 ;; BMI2 instructions.
13612 (define_expand "bmi2_bzhi_<mode>3"
13614 [(set (match_operand:SWI48 0 "register_operand")
13615 (zero_extract:SWI48
13616 (match_operand:SWI48 1 "nonimmediate_operand")
13618 (and:SWI48 (match_operand:SWI48 2 "register_operand")
13622 (clobber (reg:CC FLAGS_REG))])]
13624 "operands[3] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT);")
13626 (define_insn "*bmi2_bzhi_<mode>3"
13627 [(set (match_operand:SWI48 0 "register_operand" "=r")
13628 (zero_extract:SWI48
13629 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13631 (and:SWI48 (match_operand:SWI48 2 "register_operand" "r")
13633 (match_operand:SWI48 3 "const_int_operand" "n"))
13635 (clobber (reg:CC FLAGS_REG))]
13636 "TARGET_BMI2 && INTVAL (operands[3]) == <MODE_SIZE> * BITS_PER_UNIT"
13637 "bzhi\t{%2, %1, %0|%0, %1, %2}"
13638 [(set_attr "type" "bitmanip")
13639 (set_attr "prefix" "vex")
13640 (set_attr "mode" "<MODE>")])
13642 (define_insn "*bmi2_bzhi_<mode>3_1"
13643 [(set (match_operand:SWI48 0 "register_operand" "=r")
13644 (zero_extract:SWI48
13645 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13647 (zero_extend:SWI48 (match_operand:QI 2 "register_operand" "r"))
13648 (match_operand:SWI48 3 "const_int_operand" "n"))
13650 (clobber (reg:CC FLAGS_REG))]
13651 "TARGET_BMI2 && INTVAL (operands[3]) == <MODE_SIZE> * BITS_PER_UNIT"
13652 "bzhi\t{%<k>2, %1, %0|%0, %1, %<k>2}"
13653 [(set_attr "type" "bitmanip")
13654 (set_attr "prefix" "vex")
13655 (set_attr "mode" "<MODE>")])
13657 (define_insn "*bmi2_bzhi_<mode>3_1_ccz"
13658 [(set (reg:CCZ FLAGS_REG)
13660 (zero_extract:SWI48
13661 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13663 (zero_extend:SWI48 (match_operand:QI 2 "register_operand" "r"))
13664 (match_operand:SWI48 3 "const_int_operand" "n"))
13667 (clobber (match_scratch:SWI48 0 "=r"))]
13668 "TARGET_BMI2 && INTVAL (operands[3]) == <MODE_SIZE> * BITS_PER_UNIT"
13669 "bzhi\t{%<k>2, %1, %0|%0, %1, %<k>2}"
13670 [(set_attr "type" "bitmanip")
13671 (set_attr "prefix" "vex")
13672 (set_attr "mode" "<MODE>")])
13674 (define_insn "bmi2_pdep_<mode>3"
13675 [(set (match_operand:SWI48 0 "register_operand" "=r")
13676 (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
13677 (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
13680 "pdep\t{%2, %1, %0|%0, %1, %2}"
13681 [(set_attr "type" "bitmanip")
13682 (set_attr "prefix" "vex")
13683 (set_attr "mode" "<MODE>")])
13685 (define_insn "bmi2_pext_<mode>3"
13686 [(set (match_operand:SWI48 0 "register_operand" "=r")
13687 (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
13688 (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
13691 "pext\t{%2, %1, %0|%0, %1, %2}"
13692 [(set_attr "type" "bitmanip")
13693 (set_attr "prefix" "vex")
13694 (set_attr "mode" "<MODE>")])
13696 ;; TBM instructions.
13697 (define_insn "tbm_bextri_<mode>"
13698 [(set (match_operand:SWI48 0 "register_operand" "=r")
13699 (zero_extract:SWI48
13700 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13701 (match_operand 2 "const_0_to_255_operand" "N")
13702 (match_operand 3 "const_0_to_255_operand" "N")))
13703 (clobber (reg:CC FLAGS_REG))]
13706 operands[2] = GEN_INT (INTVAL (operands[2]) << 8 | INTVAL (operands[3]));
13707 return "bextr\t{%2, %1, %0|%0, %1, %2}";
13709 [(set_attr "type" "bitmanip")
13710 (set_attr "mode" "<MODE>")])
13712 (define_insn "*tbm_blcfill_<mode>"
13713 [(set (match_operand:SWI48 0 "register_operand" "=r")
13716 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13719 (clobber (reg:CC FLAGS_REG))]
13721 "blcfill\t{%1, %0|%0, %1}"
13722 [(set_attr "type" "bitmanip")
13723 (set_attr "mode" "<MODE>")])
13725 (define_insn "*tbm_blci_<mode>"
13726 [(set (match_operand:SWI48 0 "register_operand" "=r")
13730 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13733 (clobber (reg:CC FLAGS_REG))]
13735 "blci\t{%1, %0|%0, %1}"
13736 [(set_attr "type" "bitmanip")
13737 (set_attr "mode" "<MODE>")])
13739 (define_insn "*tbm_blcic_<mode>"
13740 [(set (match_operand:SWI48 0 "register_operand" "=r")
13743 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13747 (clobber (reg:CC FLAGS_REG))]
13749 "blcic\t{%1, %0|%0, %1}"
13750 [(set_attr "type" "bitmanip")
13751 (set_attr "mode" "<MODE>")])
13753 (define_insn "*tbm_blcmsk_<mode>"
13754 [(set (match_operand:SWI48 0 "register_operand" "=r")
13757 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13760 (clobber (reg:CC FLAGS_REG))]
13762 "blcmsk\t{%1, %0|%0, %1}"
13763 [(set_attr "type" "bitmanip")
13764 (set_attr "mode" "<MODE>")])
13766 (define_insn "*tbm_blcs_<mode>"
13767 [(set (match_operand:SWI48 0 "register_operand" "=r")
13770 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13773 (clobber (reg:CC FLAGS_REG))]
13775 "blcs\t{%1, %0|%0, %1}"
13776 [(set_attr "type" "bitmanip")
13777 (set_attr "mode" "<MODE>")])
13779 (define_insn "*tbm_blsfill_<mode>"
13780 [(set (match_operand:SWI48 0 "register_operand" "=r")
13783 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13786 (clobber (reg:CC FLAGS_REG))]
13788 "blsfill\t{%1, %0|%0, %1}"
13789 [(set_attr "type" "bitmanip")
13790 (set_attr "mode" "<MODE>")])
13792 (define_insn "*tbm_blsic_<mode>"
13793 [(set (match_operand:SWI48 0 "register_operand" "=r")
13796 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13800 (clobber (reg:CC FLAGS_REG))]
13802 "blsic\t{%1, %0|%0, %1}"
13803 [(set_attr "type" "bitmanip")
13804 (set_attr "mode" "<MODE>")])
13806 (define_insn "*tbm_t1mskc_<mode>"
13807 [(set (match_operand:SWI48 0 "register_operand" "=r")
13810 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13814 (clobber (reg:CC FLAGS_REG))]
13816 "t1mskc\t{%1, %0|%0, %1}"
13817 [(set_attr "type" "bitmanip")
13818 (set_attr "mode" "<MODE>")])
13820 (define_insn "*tbm_tzmsk_<mode>"
13821 [(set (match_operand:SWI48 0 "register_operand" "=r")
13824 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13828 (clobber (reg:CC FLAGS_REG))]
13830 "tzmsk\t{%1, %0|%0, %1}"
13831 [(set_attr "type" "bitmanip")
13832 (set_attr "mode" "<MODE>")])
13834 (define_insn_and_split "popcount<mode>2"
13835 [(set (match_operand:SWI48 0 "register_operand" "=r")
13837 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
13838 (clobber (reg:CC FLAGS_REG))]
13842 return "popcnt\t{%1, %0|%0, %1}";
13844 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
13847 "&& TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
13848 && optimize_function_for_speed_p (cfun)
13849 && !reg_mentioned_p (operands[0], operands[1])"
13851 [(set (match_dup 0)
13852 (popcount:SWI48 (match_dup 1)))
13853 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
13854 (clobber (reg:CC FLAGS_REG))])]
13855 "ix86_expand_clear (operands[0]);"
13856 [(set_attr "prefix_rep" "1")
13857 (set_attr "type" "bitmanip")
13858 (set_attr "mode" "<MODE>")])
13860 ; False dependency happens when destination is only updated by tzcnt,
13861 ; lzcnt or popcnt. There is no false dependency when destination is
13862 ; also used in source.
13863 (define_insn "*popcount<mode>2_falsedep"
13864 [(set (match_operand:SWI48 0 "register_operand" "=r")
13866 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
13867 (unspec [(match_operand:SWI48 2 "register_operand" "0")]
13868 UNSPEC_INSN_FALSE_DEP)
13869 (clobber (reg:CC FLAGS_REG))]
13873 return "popcnt\t{%1, %0|%0, %1}";
13875 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
13878 [(set_attr "prefix_rep" "1")
13879 (set_attr "type" "bitmanip")
13880 (set_attr "mode" "<MODE>")])
13882 (define_insn_and_split "*popcounthi2_1"
13883 [(set (match_operand:SI 0 "register_operand")
13885 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand"))))
13886 (clobber (reg:CC FLAGS_REG))]
13888 && can_create_pseudo_p ()"
13893 rtx tmp = gen_reg_rtx (HImode);
13895 emit_insn (gen_popcounthi2 (tmp, operands[1]));
13896 emit_insn (gen_zero_extendhisi2 (operands[0], tmp));
13900 (define_insn "popcounthi2"
13901 [(set (match_operand:HI 0 "register_operand" "=r")
13903 (match_operand:HI 1 "nonimmediate_operand" "rm")))
13904 (clobber (reg:CC FLAGS_REG))]
13908 return "popcnt\t{%1, %0|%0, %1}";
13910 return "popcnt{w}\t{%1, %0|%0, %1}";
13913 [(set_attr "prefix_rep" "1")
13914 (set_attr "type" "bitmanip")
13915 (set_attr "mode" "HI")])
13917 (define_expand "bswapdi2"
13918 [(set (match_operand:DI 0 "register_operand")
13919 (bswap:DI (match_operand:DI 1 "nonimmediate_operand")))]
13923 operands[1] = force_reg (DImode, operands[1]);
13926 (define_expand "bswapsi2"
13927 [(set (match_operand:SI 0 "register_operand")
13928 (bswap:SI (match_operand:SI 1 "nonimmediate_operand")))]
13933 else if (TARGET_BSWAP)
13934 operands[1] = force_reg (SImode, operands[1]);
13937 rtx x = operands[0];
13939 emit_move_insn (x, operands[1]);
13940 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
13941 emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
13942 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
13947 (define_insn "*bswap<mode>2_movbe"
13948 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,r,m")
13949 (bswap:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,m,r")))]
13951 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
13954 movbe{<imodesuffix>}\t{%1, %0|%0, %1}
13955 movbe{<imodesuffix>}\t{%1, %0|%0, %1}"
13956 [(set_attr "type" "bitmanip,imov,imov")
13957 (set_attr "modrm" "0,1,1")
13958 (set_attr "prefix_0f" "*,1,1")
13959 (set_attr "prefix_extra" "*,1,1")
13960 (set_attr "mode" "<MODE>")])
13962 (define_insn "*bswap<mode>2"
13963 [(set (match_operand:SWI48 0 "register_operand" "=r")
13964 (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "0")))]
13967 [(set_attr "type" "bitmanip")
13968 (set_attr "modrm" "0")
13969 (set_attr "mode" "<MODE>")])
13971 (define_expand "bswaphi2"
13972 [(set (match_operand:HI 0 "register_operand")
13973 (bswap:HI (match_operand:HI 1 "nonimmediate_operand")))]
13976 (define_insn "*bswaphi2_movbe"
13977 [(set (match_operand:HI 0 "nonimmediate_operand" "=Q,r,m")
13978 (bswap:HI (match_operand:HI 1 "nonimmediate_operand" "0,m,r")))]
13980 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
13982 xchg{b}\t{%h0, %b0|%b0, %h0}
13983 movbe{w}\t{%1, %0|%0, %1}
13984 movbe{w}\t{%1, %0|%0, %1}"
13985 [(set_attr "type" "imov")
13986 (set_attr "modrm" "*,1,1")
13987 (set_attr "prefix_0f" "*,1,1")
13988 (set_attr "prefix_extra" "*,1,1")
13989 (set_attr "pent_pair" "np,*,*")
13990 (set_attr "athlon_decode" "vector,*,*")
13991 (set_attr "amdfam10_decode" "double,*,*")
13992 (set_attr "bdver1_decode" "double,*,*")
13993 (set_attr "mode" "QI,HI,HI")])
13996 [(set (match_operand:HI 0 "general_reg_operand")
13997 (bswap:HI (match_dup 0)))]
13999 && !(TARGET_USE_XCHGB || optimize_function_for_size_p (cfun))
14000 && peep2_regno_dead_p (0, FLAGS_REG)"
14001 [(parallel [(set (match_dup 0) (rotate:HI (match_dup 0) (const_int 8)))
14002 (clobber (reg:CC FLAGS_REG))])])
14004 (define_insn "bswaphi_lowpart"
14005 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
14006 (bswap:HI (match_dup 0)))
14007 (clobber (reg:CC FLAGS_REG))]
14010 xchg{b}\t{%h0, %b0|%b0, %h0}
14011 rol{w}\t{$8, %0|%0, 8}"
14012 [(set (attr "preferred_for_size")
14013 (cond [(eq_attr "alternative" "0")
14014 (symbol_ref "true")]
14015 (symbol_ref "false")))
14016 (set (attr "preferred_for_speed")
14017 (cond [(eq_attr "alternative" "0")
14018 (symbol_ref "TARGET_USE_XCHGB")]
14019 (symbol_ref "!TARGET_USE_XCHGB")))
14020 (set_attr "length" "2,4")
14021 (set_attr "mode" "QI,HI")])
14023 (define_expand "paritydi2"
14024 [(set (match_operand:DI 0 "register_operand")
14025 (parity:DI (match_operand:DI 1 "register_operand")))]
14028 rtx scratch = gen_reg_rtx (QImode);
14030 emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX,
14031 NULL_RTX, operands[1]));
14033 ix86_expand_setcc (scratch, ORDERED,
14034 gen_rtx_REG (CCmode, FLAGS_REG), const0_rtx);
14037 emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
14040 rtx tmp = gen_reg_rtx (SImode);
14042 emit_insn (gen_zero_extendqisi2 (tmp, scratch));
14043 emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
14048 (define_expand "paritysi2"
14049 [(set (match_operand:SI 0 "register_operand")
14050 (parity:SI (match_operand:SI 1 "register_operand")))]
14053 rtx scratch = gen_reg_rtx (QImode);
14055 emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1]));
14057 ix86_expand_setcc (scratch, ORDERED,
14058 gen_rtx_REG (CCmode, FLAGS_REG), const0_rtx);
14060 emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
14064 (define_insn_and_split "paritydi2_cmp"
14065 [(set (reg:CC FLAGS_REG)
14066 (unspec:CC [(match_operand:DI 3 "register_operand" "0")]
14068 (clobber (match_scratch:DI 0 "=r"))
14069 (clobber (match_scratch:SI 1 "=&r"))
14070 (clobber (match_scratch:HI 2 "=Q"))]
14073 "&& reload_completed"
14075 [(set (match_dup 1)
14076 (xor:SI (match_dup 1) (match_dup 4)))
14077 (clobber (reg:CC FLAGS_REG))])
14079 [(set (reg:CC FLAGS_REG)
14080 (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
14081 (clobber (match_dup 1))
14082 (clobber (match_dup 2))])]
14084 operands[4] = gen_lowpart (SImode, operands[3]);
14088 emit_move_insn (operands[1], gen_lowpart (SImode, operands[3]));
14089 emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32)));
14092 operands[1] = gen_highpart (SImode, operands[3]);
14095 (define_insn_and_split "paritysi2_cmp"
14096 [(set (reg:CC FLAGS_REG)
14097 (unspec:CC [(match_operand:SI 2 "register_operand" "0")]
14099 (clobber (match_scratch:SI 0 "=r"))
14100 (clobber (match_scratch:HI 1 "=&Q"))]
14103 "&& reload_completed"
14105 [(set (match_dup 1)
14106 (xor:HI (match_dup 1) (match_dup 3)))
14107 (clobber (reg:CC FLAGS_REG))])
14109 [(set (reg:CC FLAGS_REG)
14110 (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
14111 (clobber (match_dup 1))])]
14113 operands[3] = gen_lowpart (HImode, operands[2]);
14115 emit_move_insn (operands[1], gen_lowpart (HImode, operands[2]));
14116 emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16)));
14119 (define_insn "*parityhi2_cmp"
14120 [(set (reg:CC FLAGS_REG)
14121 (unspec:CC [(match_operand:HI 1 "register_operand" "0")]
14123 (clobber (match_scratch:HI 0 "=Q"))]
14125 "xor{b}\t{%h0, %b0|%b0, %h0}"
14126 [(set_attr "length" "2")
14127 (set_attr "mode" "HI")])
14130 ;; Thread-local storage patterns for ELF.
14132 ;; Note that these code sequences must appear exactly as shown
14133 ;; in order to allow linker relaxation.
14135 (define_insn "*tls_global_dynamic_32_gnu"
14136 [(set (match_operand:SI 0 "register_operand" "=a")
14138 [(match_operand:SI 1 "register_operand" "Yb")
14139 (match_operand 2 "tls_symbolic_operand")
14140 (match_operand 3 "constant_call_address_operand" "Bz")
14143 (clobber (match_scratch:SI 4 "=d"))
14144 (clobber (match_scratch:SI 5 "=c"))
14145 (clobber (reg:CC FLAGS_REG))]
14146 "!TARGET_64BIT && TARGET_GNU_TLS"
14148 if (TARGET_SUN_TLS || flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT)
14150 ("lea{l}\t{%E2@tlsgd(,%1,1), %0|%0, %E2@tlsgd[%1*1]}", operands);
14153 ("lea{l}\t{%E2@tlsgd(%1), %0|%0, %E2@tlsgd[%1]}", operands);
14154 if (TARGET_SUN_TLS)
14155 #ifdef HAVE_AS_IX86_TLSGDPLT
14156 return "call\t%a2@tlsgdplt";
14158 return "call\t%p3@plt";
14160 if (flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT)
14161 return "call\t%P3";
14162 return "call\t{*%p3@GOT(%1)|[DWORD PTR %p3@GOT[%1]]}";
14164 [(set_attr "type" "multi")
14165 (set_attr "length" "12")])
14167 (define_expand "tls_global_dynamic_32"
14169 [(set (match_operand:SI 0 "register_operand")
14170 (unspec:SI [(match_operand:SI 2 "register_operand")
14171 (match_operand 1 "tls_symbolic_operand")
14172 (match_operand 3 "constant_call_address_operand")
14175 (clobber (match_scratch:SI 4))
14176 (clobber (match_scratch:SI 5))
14177 (clobber (reg:CC FLAGS_REG))])]
14179 "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
14181 (define_insn "*tls_global_dynamic_64_<mode>"
14182 [(set (match_operand:P 0 "register_operand" "=a")
14184 (mem:QI (match_operand 2 "constant_call_address_operand" "Bz"))
14185 (match_operand 3)))
14186 (unspec:P [(match_operand 1 "tls_symbolic_operand")
14192 /* The .loc directive has effect for 'the immediately following assembly
14193 instruction'. So for a sequence:
14197 the 'immediately following assembly instruction' is insn1.
14198 We want to emit an insn prefix here, but if we use .byte (as shown in
14199 'ELF Handling For Thread-Local Storage'), a preceding .loc will point
14200 inside the insn sequence, rather than to the start. After relaxation
14201 of the sequence by the linker, the .loc might point inside an insn.
14202 Use data16 prefix instead, which doesn't have this problem. */
14203 fputs ("\tdata16", asm_out_file);
14205 ("lea{q}\t{%E1@tlsgd(%%rip), %%rdi|rdi, %E1@tlsgd[rip]}", operands);
14206 if (TARGET_SUN_TLS || flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT)
14207 fputs (ASM_SHORT "0x6666\n", asm_out_file);
14209 fputs (ASM_BYTE "0x66\n", asm_out_file);
14210 fputs ("\trex64\n", asm_out_file);
14211 if (TARGET_SUN_TLS)
14212 return "call\t%p2@plt";
14213 if (flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT)
14214 return "call\t%P2";
14215 return "call\t{*%p2@GOTPCREL(%%rip)|[QWORD PTR %p2@GOTPCREL[rip]]}";
14217 [(set_attr "type" "multi")
14218 (set (attr "length")
14219 (symbol_ref "TARGET_X32 ? 15 : 16"))])
14221 (define_insn "*tls_global_dynamic_64_largepic"
14222 [(set (match_operand:DI 0 "register_operand" "=a")
14224 (mem:QI (plus:DI (match_operand:DI 2 "register_operand" "b")
14225 (match_operand:DI 3 "immediate_operand" "i")))
14226 (match_operand 4)))
14227 (unspec:DI [(match_operand 1 "tls_symbolic_operand")
14230 "TARGET_64BIT && ix86_cmodel == CM_LARGE_PIC && !TARGET_PECOFF
14231 && GET_CODE (operands[3]) == CONST
14232 && GET_CODE (XEXP (operands[3], 0)) == UNSPEC
14233 && XINT (XEXP (operands[3], 0), 1) == UNSPEC_PLTOFF"
14236 ("lea{q}\t{%E1@tlsgd(%%rip), %%rdi|rdi, %E1@tlsgd[rip]}", operands);
14237 output_asm_insn ("movabs{q}\t{%3, %%rax|rax, %3}", operands);
14238 output_asm_insn ("add{q}\t{%2, %%rax|rax, %2}", operands);
14239 return "call\t{*%%rax|rax}";
14241 [(set_attr "type" "multi")
14242 (set_attr "length" "22")])
14244 (define_expand "tls_global_dynamic_64_<mode>"
14246 [(set (match_operand:P 0 "register_operand")
14248 (mem:QI (match_operand 2))
14250 (unspec:P [(match_operand 1 "tls_symbolic_operand")
14254 "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
14256 (define_insn "*tls_local_dynamic_base_32_gnu"
14257 [(set (match_operand:SI 0 "register_operand" "=a")
14259 [(match_operand:SI 1 "register_operand" "Yb")
14260 (match_operand 2 "constant_call_address_operand" "Bz")
14262 UNSPEC_TLS_LD_BASE))
14263 (clobber (match_scratch:SI 3 "=d"))
14264 (clobber (match_scratch:SI 4 "=c"))
14265 (clobber (reg:CC FLAGS_REG))]
14266 "!TARGET_64BIT && TARGET_GNU_TLS"
14269 ("lea{l}\t{%&@tlsldm(%1), %0|%0, %&@tlsldm[%1]}", operands);
14270 if (TARGET_SUN_TLS)
14272 if (HAVE_AS_IX86_TLSLDMPLT)
14273 return "call\t%&@tlsldmplt";
14275 return "call\t%p2@plt";
14277 if (flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT)
14278 return "call\t%P2";
14279 return "call\t{*%p2@GOT(%1)|[DWORD PTR %p2@GOT[%1]]}";
14281 [(set_attr "type" "multi")
14282 (set_attr "length" "11")])
14284 (define_expand "tls_local_dynamic_base_32"
14286 [(set (match_operand:SI 0 "register_operand")
14288 [(match_operand:SI 1 "register_operand")
14289 (match_operand 2 "constant_call_address_operand")
14291 UNSPEC_TLS_LD_BASE))
14292 (clobber (match_scratch:SI 3))
14293 (clobber (match_scratch:SI 4))
14294 (clobber (reg:CC FLAGS_REG))])]
14296 "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
14298 (define_insn "*tls_local_dynamic_base_64_<mode>"
14299 [(set (match_operand:P 0 "register_operand" "=a")
14301 (mem:QI (match_operand 1 "constant_call_address_operand" "Bz"))
14302 (match_operand 2)))
14303 (unspec:P [(reg:P SP_REG)] UNSPEC_TLS_LD_BASE)]
14307 ("lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}", operands);
14308 if (TARGET_SUN_TLS)
14309 return "call\t%p1@plt";
14310 if (flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT)
14311 return "call\t%P1";
14312 return "call\t{*%p1@GOTPCREL(%%rip)|[QWORD PTR %p1@GOTPCREL[rip]]}";
14314 [(set_attr "type" "multi")
14315 (set_attr "length" "12")])
14317 (define_insn "*tls_local_dynamic_base_64_largepic"
14318 [(set (match_operand:DI 0 "register_operand" "=a")
14320 (mem:QI (plus:DI (match_operand:DI 1 "register_operand" "b")
14321 (match_operand:DI 2 "immediate_operand" "i")))
14322 (match_operand 3)))
14323 (unspec:DI [(reg:DI SP_REG)] UNSPEC_TLS_LD_BASE)]
14324 "TARGET_64BIT && ix86_cmodel == CM_LARGE_PIC && !TARGET_PECOFF
14325 && GET_CODE (operands[2]) == CONST
14326 && GET_CODE (XEXP (operands[2], 0)) == UNSPEC
14327 && XINT (XEXP (operands[2], 0), 1) == UNSPEC_PLTOFF"
14330 ("lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}", operands);
14331 output_asm_insn ("movabs{q}\t{%2, %%rax|rax, %2}", operands);
14332 output_asm_insn ("add{q}\t{%1, %%rax|rax, %1}", operands);
14333 return "call\t{*%%rax|rax}";
14335 [(set_attr "type" "multi")
14336 (set_attr "length" "22")])
14338 (define_expand "tls_local_dynamic_base_64_<mode>"
14340 [(set (match_operand:P 0 "register_operand")
14342 (mem:QI (match_operand 1))
14344 (unspec:P [(reg:P SP_REG)] UNSPEC_TLS_LD_BASE)])]
14346 "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
14348 ;; Local dynamic of a single variable is a lose. Show combine how
14349 ;; to convert that back to global dynamic.
14351 (define_insn_and_split "*tls_local_dynamic_32_once"
14352 [(set (match_operand:SI 0 "register_operand" "=a")
14354 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14355 (match_operand 2 "constant_call_address_operand" "Bz")
14357 UNSPEC_TLS_LD_BASE)
14358 (const:SI (unspec:SI
14359 [(match_operand 3 "tls_symbolic_operand")]
14361 (clobber (match_scratch:SI 4 "=d"))
14362 (clobber (match_scratch:SI 5 "=c"))
14363 (clobber (reg:CC FLAGS_REG))]
14368 [(set (match_dup 0)
14369 (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)
14372 (clobber (match_dup 4))
14373 (clobber (match_dup 5))
14374 (clobber (reg:CC FLAGS_REG))])])
14376 ;; Load and add the thread base pointer from %<tp_seg>:0.
14377 (define_insn_and_split "*load_tp_<mode>"
14378 [(set (match_operand:PTR 0 "register_operand" "=r")
14379 (unspec:PTR [(const_int 0)] UNSPEC_TP))]
14383 [(set (match_dup 0)
14386 addr_space_t as = DEFAULT_TLS_SEG_REG;
14388 operands[1] = gen_const_mem (<MODE>mode, const0_rtx);
14389 set_mem_addr_space (operands[1], as);
14392 (define_insn_and_split "*load_tp_x32_zext"
14393 [(set (match_operand:DI 0 "register_operand" "=r")
14395 (unspec:SI [(const_int 0)] UNSPEC_TP)))]
14399 [(set (match_dup 0)
14400 (zero_extend:DI (match_dup 1)))]
14402 addr_space_t as = DEFAULT_TLS_SEG_REG;
14404 operands[1] = gen_const_mem (SImode, const0_rtx);
14405 set_mem_addr_space (operands[1], as);
14408 (define_insn_and_split "*add_tp_<mode>"
14409 [(set (match_operand:PTR 0 "register_operand" "=r")
14411 (unspec:PTR [(const_int 0)] UNSPEC_TP)
14412 (match_operand:PTR 1 "register_operand" "0")))
14413 (clobber (reg:CC FLAGS_REG))]
14418 [(set (match_dup 0)
14419 (plus:PTR (match_dup 1) (match_dup 2)))
14420 (clobber (reg:CC FLAGS_REG))])]
14422 addr_space_t as = DEFAULT_TLS_SEG_REG;
14424 operands[2] = gen_const_mem (<MODE>mode, const0_rtx);
14425 set_mem_addr_space (operands[2], as);
14428 (define_insn_and_split "*add_tp_x32_zext"
14429 [(set (match_operand:DI 0 "register_operand" "=r")
14431 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
14432 (match_operand:SI 1 "register_operand" "0"))))
14433 (clobber (reg:CC FLAGS_REG))]
14438 [(set (match_dup 0)
14440 (plus:SI (match_dup 1) (match_dup 2))))
14441 (clobber (reg:CC FLAGS_REG))])]
14443 addr_space_t as = DEFAULT_TLS_SEG_REG;
14445 operands[2] = gen_const_mem (SImode, const0_rtx);
14446 set_mem_addr_space (operands[2], as);
14449 ;; The Sun linker took the AMD64 TLS spec literally and can only handle
14450 ;; %rax as destination of the initial executable code sequence.
14451 (define_insn "tls_initial_exec_64_sun"
14452 [(set (match_operand:DI 0 "register_operand" "=a")
14454 [(match_operand 1 "tls_symbolic_operand")]
14455 UNSPEC_TLS_IE_SUN))
14456 (clobber (reg:CC FLAGS_REG))]
14457 "TARGET_64BIT && TARGET_SUN_TLS"
14460 ("mov{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}", operands);
14461 return "add{q}\t{%a1@gottpoff(%%rip), %0|%0, %a1@gottpoff[rip]}";
14463 [(set_attr "type" "multi")])
14465 ;; GNU2 TLS patterns can be split.
14467 (define_expand "tls_dynamic_gnu2_32"
14468 [(set (match_dup 3)
14469 (plus:SI (match_operand:SI 2 "register_operand")
14471 (unspec:SI [(match_operand 1 "tls_symbolic_operand")]
14474 [(set (match_operand:SI 0 "register_operand")
14475 (unspec:SI [(match_dup 1) (match_dup 3)
14476 (match_dup 2) (reg:SI SP_REG)]
14478 (clobber (reg:CC FLAGS_REG))])]
14479 "!TARGET_64BIT && TARGET_GNU2_TLS"
14481 operands[3] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
14482 ix86_tls_descriptor_calls_expanded_in_cfun = true;
14485 (define_insn "*tls_dynamic_gnu2_lea_32"
14486 [(set (match_operand:SI 0 "register_operand" "=r")
14487 (plus:SI (match_operand:SI 1 "register_operand" "b")
14489 (unspec:SI [(match_operand 2 "tls_symbolic_operand")]
14490 UNSPEC_TLSDESC))))]
14491 "!TARGET_64BIT && TARGET_GNU2_TLS"
14492 "lea{l}\t{%E2@TLSDESC(%1), %0|%0, %E2@TLSDESC[%1]}"
14493 [(set_attr "type" "lea")
14494 (set_attr "mode" "SI")
14495 (set_attr "length" "6")
14496 (set_attr "length_address" "4")])
14498 (define_insn "*tls_dynamic_gnu2_call_32"
14499 [(set (match_operand:SI 0 "register_operand" "=a")
14500 (unspec:SI [(match_operand 1 "tls_symbolic_operand")
14501 (match_operand:SI 2 "register_operand" "0")
14502 ;; we have to make sure %ebx still points to the GOT
14503 (match_operand:SI 3 "register_operand" "b")
14506 (clobber (reg:CC FLAGS_REG))]
14507 "!TARGET_64BIT && TARGET_GNU2_TLS"
14508 "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
14509 [(set_attr "type" "call")
14510 (set_attr "length" "2")
14511 (set_attr "length_address" "0")])
14513 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
14514 [(set (match_operand:SI 0 "register_operand" "=&a")
14516 (unspec:SI [(match_operand 3 "tls_modbase_operand")
14517 (match_operand:SI 4)
14518 (match_operand:SI 2 "register_operand" "b")
14521 (const:SI (unspec:SI
14522 [(match_operand 1 "tls_symbolic_operand")]
14524 (clobber (reg:CC FLAGS_REG))]
14525 "!TARGET_64BIT && TARGET_GNU2_TLS"
14528 [(set (match_dup 0) (match_dup 5))]
14530 operands[5] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
14531 emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
14534 (define_expand "tls_dynamic_gnu2_64"
14535 [(set (match_dup 2)
14536 (unspec:DI [(match_operand 1 "tls_symbolic_operand")]
14539 [(set (match_operand:DI 0 "register_operand")
14540 (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
14542 (clobber (reg:CC FLAGS_REG))])]
14543 "TARGET_64BIT && TARGET_GNU2_TLS"
14545 operands[2] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
14546 ix86_tls_descriptor_calls_expanded_in_cfun = true;
14549 (define_insn "*tls_dynamic_gnu2_lea_64"
14550 [(set (match_operand:DI 0 "register_operand" "=r")
14551 (unspec:DI [(match_operand 1 "tls_symbolic_operand")]
14553 "TARGET_64BIT && TARGET_GNU2_TLS"
14554 "lea{q}\t{%E1@TLSDESC(%%rip), %0|%0, %E1@TLSDESC[rip]}"
14555 [(set_attr "type" "lea")
14556 (set_attr "mode" "DI")
14557 (set_attr "length" "7")
14558 (set_attr "length_address" "4")])
14560 (define_insn "*tls_dynamic_gnu2_call_64"
14561 [(set (match_operand:DI 0 "register_operand" "=a")
14562 (unspec:DI [(match_operand 1 "tls_symbolic_operand")
14563 (match_operand:DI 2 "register_operand" "0")
14566 (clobber (reg:CC FLAGS_REG))]
14567 "TARGET_64BIT && TARGET_GNU2_TLS"
14568 "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
14569 [(set_attr "type" "call")
14570 (set_attr "length" "2")
14571 (set_attr "length_address" "0")])
14573 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
14574 [(set (match_operand:DI 0 "register_operand" "=&a")
14576 (unspec:DI [(match_operand 2 "tls_modbase_operand")
14577 (match_operand:DI 3)
14580 (const:DI (unspec:DI
14581 [(match_operand 1 "tls_symbolic_operand")]
14583 (clobber (reg:CC FLAGS_REG))]
14584 "TARGET_64BIT && TARGET_GNU2_TLS"
14587 [(set (match_dup 0) (match_dup 4))]
14589 operands[4] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
14590 emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
14594 [(match_operand 0 "tls_address_pattern")]
14595 "TARGET_TLS_DIRECT_SEG_REFS"
14597 "operands[0] = ix86_rewrite_tls_address (operands[0]);")
14600 ;; These patterns match the binary 387 instructions for addM3, subM3,
14601 ;; mulM3 and divM3. There are three patterns for each of DFmode and
14602 ;; SFmode. The first is the normal insn, the second the same insn but
14603 ;; with one operand a conversion, and the third the same insn but with
14604 ;; the other operand a conversion. The conversion may be SFmode or
14605 ;; SImode if the target mode DFmode, but only SImode if the target mode
14608 ;; Gcc is slightly more smart about handling normal two address instructions
14609 ;; so use special patterns for add and mull.
14611 (define_insn "*fop_xf_comm_i387"
14612 [(set (match_operand:XF 0 "register_operand" "=f")
14613 (match_operator:XF 3 "binary_fp_operator"
14614 [(match_operand:XF 1 "register_operand" "%0")
14615 (match_operand:XF 2 "register_operand" "f")]))]
14617 && COMMUTATIVE_ARITH_P (operands[3])"
14618 "* return output_387_binary_op (insn, operands);"
14619 [(set (attr "type")
14620 (if_then_else (match_operand:XF 3 "mult_operator")
14621 (const_string "fmul")
14622 (const_string "fop")))
14623 (set_attr "mode" "XF")])
14625 (define_insn "*fop_<mode>_comm"
14626 [(set (match_operand:MODEF 0 "register_operand" "=f,x,v")
14627 (match_operator:MODEF 3 "binary_fp_operator"
14628 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,0,v")
14629 (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm,vm")]))]
14630 "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14631 || (TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)))
14632 && COMMUTATIVE_ARITH_P (operands[3])
14633 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
14634 "* return output_387_binary_op (insn, operands);"
14635 [(set (attr "type")
14636 (if_then_else (eq_attr "alternative" "1,2")
14637 (if_then_else (match_operand:MODEF 3 "mult_operator")
14638 (const_string "ssemul")
14639 (const_string "sseadd"))
14640 (if_then_else (match_operand:MODEF 3 "mult_operator")
14641 (const_string "fmul")
14642 (const_string "fop"))))
14643 (set_attr "isa" "*,noavx,avx")
14644 (set_attr "prefix" "orig,orig,vex")
14645 (set_attr "mode" "<MODE>")
14646 (set (attr "enabled")
14648 (match_test ("SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"))
14650 (eq_attr "alternative" "0")
14651 (symbol_ref "TARGET_MIX_SSE_I387
14652 && X87_ENABLE_ARITH (<MODE>mode)")
14653 (const_string "*"))
14655 (eq_attr "alternative" "0")
14656 (symbol_ref "true")
14657 (symbol_ref "false"))))])
14659 (define_insn "*rcpsf2_sse"
14660 [(set (match_operand:SF 0 "register_operand" "=x,x")
14661 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "x,m")]
14663 "TARGET_SSE && TARGET_SSE_MATH"
14665 %vrcpss\t{%d1, %0|%0, %d1}
14666 %vrcpss\t{%1, %d0|%d0, %1}"
14667 [(set_attr "type" "sse")
14668 (set_attr "atom_sse_attr" "rcp")
14669 (set_attr "btver2_sse_attr" "rcp")
14670 (set_attr "prefix" "maybe_vex")
14671 (set_attr "mode" "SF")])
14673 (define_insn "*fop_xf_1_i387"
14674 [(set (match_operand:XF 0 "register_operand" "=f,f")
14675 (match_operator:XF 3 "binary_fp_operator"
14676 [(match_operand:XF 1 "register_operand" "0,f")
14677 (match_operand:XF 2 "register_operand" "f,0")]))]
14679 && !COMMUTATIVE_ARITH_P (operands[3])"
14680 "* return output_387_binary_op (insn, operands);"
14681 [(set (attr "type")
14682 (if_then_else (match_operand:XF 3 "div_operator")
14683 (const_string "fdiv")
14684 (const_string "fop")))
14685 (set_attr "mode" "XF")])
14687 (define_insn "*fop_<mode>_1"
14688 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,v")
14689 (match_operator:MODEF 3 "binary_fp_operator"
14690 [(match_operand:MODEF 1
14691 "x87nonimm_ssenomem_operand" "0,fm,0,v")
14692 (match_operand:MODEF 2
14693 "nonimmediate_operand" "fm,0,xm,vm")]))]
14694 "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14695 || (TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)))
14696 && !COMMUTATIVE_ARITH_P (operands[3])
14697 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
14698 "* return output_387_binary_op (insn, operands);"
14699 [(set (attr "type")
14700 (if_then_else (eq_attr "alternative" "2,3")
14701 (if_then_else (match_operand:MODEF 3 "div_operator")
14702 (const_string "ssediv")
14703 (const_string "sseadd"))
14704 (if_then_else (match_operand:MODEF 3 "div_operator")
14705 (const_string "fdiv")
14706 (const_string "fop"))))
14707 (set_attr "isa" "*,*,noavx,avx")
14708 (set_attr "prefix" "orig,orig,orig,vex")
14709 (set_attr "mode" "<MODE>")
14710 (set (attr "enabled")
14712 (match_test ("SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"))
14714 (eq_attr "alternative" "0,1")
14715 (symbol_ref "TARGET_MIX_SSE_I387
14716 && X87_ENABLE_ARITH (<MODE>mode)")
14717 (const_string "*"))
14719 (eq_attr "alternative" "0,1")
14720 (symbol_ref "true")
14721 (symbol_ref "false"))))])
14723 (define_insn "*fop_<X87MODEF:mode>_2_i387"
14724 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
14725 (match_operator:X87MODEF 3 "binary_fp_operator"
14727 (match_operand:SWI24 1 "nonimmediate_operand" "m"))
14728 (match_operand:X87MODEF 2 "register_operand" "0")]))]
14729 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI24:MODE>mode)
14730 && !(SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
14731 && (TARGET_USE_<SWI24:MODE>MODE_FIOP
14732 || optimize_function_for_size_p (cfun))"
14733 "* return output_387_binary_op (insn, operands);"
14734 [(set (attr "type")
14735 (cond [(match_operand:X87MODEF 3 "mult_operator")
14736 (const_string "fmul")
14737 (match_operand:X87MODEF 3 "div_operator")
14738 (const_string "fdiv")
14740 (const_string "fop")))
14741 (set_attr "fp_int_src" "true")
14742 (set_attr "mode" "<SWI24:MODE>")])
14744 (define_insn "*fop_<X87MODEF:mode>_3_i387"
14745 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
14746 (match_operator:X87MODEF 3 "binary_fp_operator"
14747 [(match_operand:X87MODEF 1 "register_operand" "0")
14749 (match_operand:SWI24 2 "nonimmediate_operand" "m"))]))]
14750 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI24:MODE>mode)
14751 && !(SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
14752 && (TARGET_USE_<SWI24:MODE>MODE_FIOP
14753 || optimize_function_for_size_p (cfun))"
14754 "* return output_387_binary_op (insn, operands);"
14755 [(set (attr "type")
14756 (cond [(match_operand:X87MODEF 3 "mult_operator")
14757 (const_string "fmul")
14758 (match_operand:X87MODEF 3 "div_operator")
14759 (const_string "fdiv")
14761 (const_string "fop")))
14762 (set_attr "fp_int_src" "true")
14763 (set_attr "mode" "<MODE>")])
14765 (define_insn "*fop_xf_4_i387"
14766 [(set (match_operand:XF 0 "register_operand" "=f,f")
14767 (match_operator:XF 3 "binary_fp_operator"
14769 (match_operand:MODEF 1 "nonimmediate_operand" "fm,0"))
14770 (match_operand:XF 2 "register_operand" "0,f")]))]
14772 "* return output_387_binary_op (insn, operands);"
14773 [(set (attr "type")
14774 (cond [(match_operand:XF 3 "mult_operator")
14775 (const_string "fmul")
14776 (match_operand:XF 3 "div_operator")
14777 (const_string "fdiv")
14779 (const_string "fop")))
14780 (set_attr "mode" "<MODE>")])
14782 (define_insn "*fop_df_4_i387"
14783 [(set (match_operand:DF 0 "register_operand" "=f,f")
14784 (match_operator:DF 3 "binary_fp_operator"
14786 (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
14787 (match_operand:DF 2 "register_operand" "0,f")]))]
14788 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
14789 && !(SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
14790 "* return output_387_binary_op (insn, operands);"
14791 [(set (attr "type")
14792 (cond [(match_operand:DF 3 "mult_operator")
14793 (const_string "fmul")
14794 (match_operand:DF 3 "div_operator")
14795 (const_string "fdiv")
14797 (const_string "fop")))
14798 (set_attr "mode" "SF")])
14800 (define_insn "*fop_xf_5_i387"
14801 [(set (match_operand:XF 0 "register_operand" "=f,f")
14802 (match_operator:XF 3 "binary_fp_operator"
14803 [(match_operand:XF 1 "register_operand" "0,f")
14805 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
14807 "* return output_387_binary_op (insn, operands);"
14808 [(set (attr "type")
14809 (cond [(match_operand:XF 3 "mult_operator")
14810 (const_string "fmul")
14811 (match_operand:XF 3 "div_operator")
14812 (const_string "fdiv")
14814 (const_string "fop")))
14815 (set_attr "mode" "<MODE>")])
14817 (define_insn "*fop_df_5_i387"
14818 [(set (match_operand:DF 0 "register_operand" "=f,f")
14819 (match_operator:DF 3 "binary_fp_operator"
14820 [(match_operand:DF 1 "register_operand" "0,f")
14822 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
14823 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
14824 && !(SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
14825 "* return output_387_binary_op (insn, operands);"
14826 [(set (attr "type")
14827 (cond [(match_operand:DF 3 "mult_operator")
14828 (const_string "fmul")
14829 (match_operand:DF 3 "div_operator")
14830 (const_string "fdiv")
14832 (const_string "fop")))
14833 (set_attr "mode" "SF")])
14835 (define_insn "*fop_xf_6_i387"
14836 [(set (match_operand:XF 0 "register_operand" "=f,f")
14837 (match_operator:XF 3 "binary_fp_operator"
14839 (match_operand:MODEF 1 "register_operand" "0,f"))
14841 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
14843 "* return output_387_binary_op (insn, operands);"
14844 [(set (attr "type")
14845 (cond [(match_operand:XF 3 "mult_operator")
14846 (const_string "fmul")
14847 (match_operand:XF 3 "div_operator")
14848 (const_string "fdiv")
14850 (const_string "fop")))
14851 (set_attr "mode" "<MODE>")])
14853 (define_insn "*fop_df_6_i387"
14854 [(set (match_operand:DF 0 "register_operand" "=f,f")
14855 (match_operator:DF 3 "binary_fp_operator"
14857 (match_operand:SF 1 "register_operand" "0,f"))
14859 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
14860 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
14861 && !(SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
14862 "* return output_387_binary_op (insn, operands);"
14863 [(set (attr "type")
14864 (cond [(match_operand:DF 3 "mult_operator")
14865 (const_string "fmul")
14866 (match_operand:DF 3 "div_operator")
14867 (const_string "fdiv")
14869 (const_string "fop")))
14870 (set_attr "mode" "SF")])
14872 ;; FPU special functions.
14874 ;; This pattern implements a no-op XFmode truncation for
14875 ;; all fancy i386 XFmode math functions.
14877 (define_insn "truncxf<mode>2_i387_noop_unspec"
14878 [(set (match_operand:MODEF 0 "nonimmediate_operand" "=mf")
14879 (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")]
14880 UNSPEC_TRUNC_NOOP))]
14881 "TARGET_USE_FANCY_MATH_387"
14882 "* return output_387_reg_move (insn, operands);"
14883 [(set_attr "type" "fmov")
14884 (set_attr "mode" "<MODE>")])
14886 (define_insn "sqrtxf2"
14887 [(set (match_operand:XF 0 "register_operand" "=f")
14888 (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
14889 "TARGET_USE_FANCY_MATH_387"
14891 [(set_attr "type" "fpspc")
14892 (set_attr "mode" "XF")
14893 (set_attr "athlon_decode" "direct")
14894 (set_attr "amdfam10_decode" "direct")
14895 (set_attr "bdver1_decode" "direct")])
14897 (define_insn "*rsqrtsf2_sse"
14898 [(set (match_operand:SF 0 "register_operand" "=x,x")
14899 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "x,m")]
14901 "TARGET_SSE && TARGET_SSE_MATH"
14903 %vrsqrtss\t{%d1, %0|%0, %d1}
14904 %vrsqrtss\t{%1, %d0|%d0, %1}"
14905 [(set_attr "type" "sse")
14906 (set_attr "atom_sse_attr" "rcp")
14907 (set_attr "btver2_sse_attr" "rcp")
14908 (set_attr "prefix" "maybe_vex")
14909 (set_attr "mode" "SF")])
14911 (define_expand "rsqrtsf2"
14912 [(set (match_operand:SF 0 "register_operand")
14913 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand")]
14915 "TARGET_SSE && TARGET_SSE_MATH"
14917 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
14921 (define_insn "*sqrt<mode>2_sse"
14922 [(set (match_operand:MODEF 0 "register_operand" "=v,v")
14924 (match_operand:MODEF 1 "nonimmediate_operand" "v,m")))]
14925 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
14927 %vsqrt<ssemodesuffix>\t{%d1, %0|%0, %d1}
14928 %vsqrt<ssemodesuffix>\t{%1, %d0|%d0, %1}"
14929 [(set_attr "type" "sse")
14930 (set_attr "atom_sse_attr" "sqrt")
14931 (set_attr "btver2_sse_attr" "sqrt")
14932 (set_attr "prefix" "maybe_vex")
14933 (set_attr "mode" "<MODE>")
14934 (set_attr "athlon_decode" "*")
14935 (set_attr "amdfam10_decode" "*")
14936 (set_attr "bdver1_decode" "*")])
14938 (define_expand "sqrt<mode>2"
14939 [(set (match_operand:MODEF 0 "register_operand")
14941 (match_operand:MODEF 1 "nonimmediate_operand")))]
14942 "(TARGET_USE_FANCY_MATH_387 && X87_ENABLE_ARITH (<MODE>mode))
14943 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
14945 if (<MODE>mode == SFmode
14946 && TARGET_SSE && TARGET_SSE_MATH
14947 && TARGET_RECIP_SQRT
14948 && !optimize_function_for_size_p (cfun)
14949 && flag_finite_math_only && !flag_trapping_math
14950 && flag_unsafe_math_optimizations)
14952 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
14956 if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
14958 rtx op0 = gen_reg_rtx (XFmode);
14959 rtx op1 = gen_reg_rtx (XFmode);
14961 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14962 emit_insn (gen_sqrtxf2 (op0, op1));
14963 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
14968 (define_insn "x86_fnstsw_1"
14969 [(set (match_operand:HI 0 "register_operand" "=a")
14970 (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
14973 [(set_attr "length" "2")
14974 (set_attr "mode" "SI")
14975 (set_attr "unit" "i387")])
14977 (define_insn "fpremxf4_i387"
14978 [(set (match_operand:XF 0 "register_operand" "=f")
14979 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
14980 (match_operand:XF 3 "register_operand" "1")]
14982 (set (match_operand:XF 1 "register_operand" "=f")
14983 (unspec:XF [(match_dup 2) (match_dup 3)]
14985 (set (reg:CCFP FPSR_REG)
14986 (unspec:CCFP [(match_dup 2) (match_dup 3)]
14988 "TARGET_USE_FANCY_MATH_387
14989 && flag_finite_math_only"
14991 [(set_attr "type" "fpspc")
14992 (set_attr "znver1_decode" "vector")
14993 (set_attr "mode" "XF")])
14995 (define_expand "fmodxf3"
14996 [(use (match_operand:XF 0 "register_operand"))
14997 (use (match_operand:XF 1 "general_operand"))
14998 (use (match_operand:XF 2 "general_operand"))]
14999 "TARGET_USE_FANCY_MATH_387
15000 && flag_finite_math_only"
15002 rtx_code_label *label = gen_label_rtx ();
15004 rtx op1 = gen_reg_rtx (XFmode);
15005 rtx op2 = gen_reg_rtx (XFmode);
15007 emit_move_insn (op2, operands[2]);
15008 emit_move_insn (op1, operands[1]);
15010 emit_label (label);
15011 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
15012 ix86_emit_fp_unordered_jump (label);
15013 LABEL_NUSES (label) = 1;
15015 emit_move_insn (operands[0], op1);
15019 (define_expand "fmod<mode>3"
15020 [(use (match_operand:MODEF 0 "register_operand"))
15021 (use (match_operand:MODEF 1 "general_operand"))
15022 (use (match_operand:MODEF 2 "general_operand"))]
15023 "TARGET_USE_FANCY_MATH_387
15024 && flag_finite_math_only"
15026 rtx (*gen_truncxf) (rtx, rtx);
15028 rtx_code_label *label = gen_label_rtx ();
15030 rtx op1 = gen_reg_rtx (XFmode);
15031 rtx op2 = gen_reg_rtx (XFmode);
15033 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
15034 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15036 emit_label (label);
15037 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
15038 ix86_emit_fp_unordered_jump (label);
15039 LABEL_NUSES (label) = 1;
15041 /* Truncate the result properly for strict SSE math. */
15042 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15043 && !TARGET_MIX_SSE_I387)
15044 gen_truncxf = gen_truncxf<mode>2;
15046 gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
15048 emit_insn (gen_truncxf (operands[0], op1));
15052 (define_insn "fprem1xf4_i387"
15053 [(set (match_operand:XF 0 "register_operand" "=f")
15054 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15055 (match_operand:XF 3 "register_operand" "1")]
15057 (set (match_operand:XF 1 "register_operand" "=f")
15058 (unspec:XF [(match_dup 2) (match_dup 3)]
15060 (set (reg:CCFP FPSR_REG)
15061 (unspec:CCFP [(match_dup 2) (match_dup 3)]
15063 "TARGET_USE_FANCY_MATH_387
15064 && flag_finite_math_only"
15066 [(set_attr "type" "fpspc")
15067 (set_attr "znver1_decode" "vector")
15068 (set_attr "mode" "XF")])
15070 (define_expand "remainderxf3"
15071 [(use (match_operand:XF 0 "register_operand"))
15072 (use (match_operand:XF 1 "general_operand"))
15073 (use (match_operand:XF 2 "general_operand"))]
15074 "TARGET_USE_FANCY_MATH_387
15075 && flag_finite_math_only"
15077 rtx_code_label *label = gen_label_rtx ();
15079 rtx op1 = gen_reg_rtx (XFmode);
15080 rtx op2 = gen_reg_rtx (XFmode);
15082 emit_move_insn (op2, operands[2]);
15083 emit_move_insn (op1, operands[1]);
15085 emit_label (label);
15086 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
15087 ix86_emit_fp_unordered_jump (label);
15088 LABEL_NUSES (label) = 1;
15090 emit_move_insn (operands[0], op1);
15094 (define_expand "remainder<mode>3"
15095 [(use (match_operand:MODEF 0 "register_operand"))
15096 (use (match_operand:MODEF 1 "general_operand"))
15097 (use (match_operand:MODEF 2 "general_operand"))]
15098 "TARGET_USE_FANCY_MATH_387
15099 && flag_finite_math_only"
15101 rtx (*gen_truncxf) (rtx, rtx);
15103 rtx_code_label *label = gen_label_rtx ();
15105 rtx op1 = gen_reg_rtx (XFmode);
15106 rtx op2 = gen_reg_rtx (XFmode);
15108 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
15109 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15111 emit_label (label);
15113 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
15114 ix86_emit_fp_unordered_jump (label);
15115 LABEL_NUSES (label) = 1;
15117 /* Truncate the result properly for strict SSE math. */
15118 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15119 && !TARGET_MIX_SSE_I387)
15120 gen_truncxf = gen_truncxf<mode>2;
15122 gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
15124 emit_insn (gen_truncxf (operands[0], op1));
15128 (define_int_iterator SINCOS
15132 (define_int_attr sincos
15133 [(UNSPEC_SIN "sin")
15134 (UNSPEC_COS "cos")])
15136 (define_insn "<sincos>xf2"
15137 [(set (match_operand:XF 0 "register_operand" "=f")
15138 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15140 "TARGET_USE_FANCY_MATH_387
15141 && flag_unsafe_math_optimizations"
15143 [(set_attr "type" "fpspc")
15144 (set_attr "znver1_decode" "vector")
15145 (set_attr "mode" "XF")])
15147 (define_expand "<sincos><mode>2"
15148 [(set (match_operand:MODEF 0 "register_operand")
15149 (unspec:MODEF [(match_operand:MODEF 1 "general_operand")]
15151 "TARGET_USE_FANCY_MATH_387
15152 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15153 || TARGET_MIX_SSE_I387)
15154 && flag_unsafe_math_optimizations"
15156 rtx op0 = gen_reg_rtx (XFmode);
15157 rtx op1 = gen_reg_rtx (XFmode);
15159 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15160 emit_insn (gen_<sincos>xf2 (op0, op1));
15161 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
15165 (define_insn "sincosxf3"
15166 [(set (match_operand:XF 0 "register_operand" "=f")
15167 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15168 UNSPEC_SINCOS_COS))
15169 (set (match_operand:XF 1 "register_operand" "=f")
15170 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15171 "TARGET_USE_FANCY_MATH_387
15172 && flag_unsafe_math_optimizations"
15174 [(set_attr "type" "fpspc")
15175 (set_attr "znver1_decode" "vector")
15176 (set_attr "mode" "XF")])
15178 (define_expand "sincos<mode>3"
15179 [(use (match_operand:MODEF 0 "register_operand"))
15180 (use (match_operand:MODEF 1 "register_operand"))
15181 (use (match_operand:MODEF 2 "general_operand"))]
15182 "TARGET_USE_FANCY_MATH_387
15183 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15184 || TARGET_MIX_SSE_I387)
15185 && flag_unsafe_math_optimizations"
15187 rtx op0 = gen_reg_rtx (XFmode);
15188 rtx op1 = gen_reg_rtx (XFmode);
15189 rtx op2 = gen_reg_rtx (XFmode);
15191 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
15192 emit_insn (gen_sincosxf3 (op0, op1, op2));
15193 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
15194 emit_insn (gen_truncxf<mode>2 (operands[1], op1));
15198 (define_insn "fptanxf4_i387"
15199 [(set (match_operand:SF 0 "register_operand" "=f")
15200 (match_operand:SF 3 "const1_operand"))
15201 (set (match_operand:XF 1 "register_operand" "=f")
15202 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15204 "TARGET_USE_FANCY_MATH_387
15205 && flag_unsafe_math_optimizations"
15207 [(set_attr "type" "fpspc")
15208 (set_attr "znver1_decode" "vector")
15209 (set_attr "mode" "XF")])
15211 (define_expand "tanxf2"
15212 [(use (match_operand:XF 0 "register_operand"))
15213 (use (match_operand:XF 1 "register_operand"))]
15214 "TARGET_USE_FANCY_MATH_387
15215 && flag_unsafe_math_optimizations"
15217 rtx one = gen_reg_rtx (SFmode);
15218 emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1],
15219 CONST1_RTX (SFmode)));
15223 (define_expand "tan<mode>2"
15224 [(use (match_operand:MODEF 0 "register_operand"))
15225 (use (match_operand:MODEF 1 "general_operand"))]
15226 "TARGET_USE_FANCY_MATH_387
15227 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15228 || TARGET_MIX_SSE_I387)
15229 && flag_unsafe_math_optimizations"
15231 rtx op0 = gen_reg_rtx (XFmode);
15232 rtx op1 = gen_reg_rtx (XFmode);
15234 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15235 emit_insn (gen_tanxf2 (op0, op1));
15236 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
15240 (define_insn "atan2xf3"
15241 [(set (match_operand:XF 0 "register_operand" "=f")
15242 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
15243 (match_operand:XF 2 "register_operand" "f")]
15245 (clobber (match_scratch:XF 3 "=2"))]
15246 "TARGET_USE_FANCY_MATH_387
15247 && flag_unsafe_math_optimizations"
15249 [(set_attr "type" "fpspc")
15250 (set_attr "znver1_decode" "vector")
15251 (set_attr "mode" "XF")])
15253 (define_expand "atan2<mode>3"
15254 [(use (match_operand:MODEF 0 "register_operand"))
15255 (use (match_operand:MODEF 1 "general_operand"))
15256 (use (match_operand:MODEF 2 "general_operand"))]
15257 "TARGET_USE_FANCY_MATH_387
15258 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15259 || TARGET_MIX_SSE_I387)
15260 && flag_unsafe_math_optimizations"
15262 rtx op0 = gen_reg_rtx (XFmode);
15263 rtx op1 = gen_reg_rtx (XFmode);
15264 rtx op2 = gen_reg_rtx (XFmode);
15266 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
15267 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15269 emit_insn (gen_atan2xf3 (op0, op2, op1));
15270 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
15274 (define_expand "atanxf2"
15275 [(parallel [(set (match_operand:XF 0 "register_operand")
15276 (unspec:XF [(match_dup 2)
15277 (match_operand:XF 1 "register_operand")]
15279 (clobber (match_scratch:XF 3))])]
15280 "TARGET_USE_FANCY_MATH_387
15281 && flag_unsafe_math_optimizations"
15282 "operands[2] = force_reg (XFmode, CONST1_RTX (XFmode));")
15284 (define_expand "atan<mode>2"
15285 [(use (match_operand:MODEF 0 "register_operand"))
15286 (use (match_operand:MODEF 1 "general_operand"))]
15287 "TARGET_USE_FANCY_MATH_387
15288 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15289 || TARGET_MIX_SSE_I387)
15290 && flag_unsafe_math_optimizations"
15292 rtx op0 = gen_reg_rtx (XFmode);
15293 rtx op1 = gen_reg_rtx (XFmode);
15295 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15296 emit_insn (gen_atanxf2 (op0, op1));
15297 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
15301 (define_expand "asinxf2"
15302 [(set (match_dup 2)
15303 (mult:XF (match_operand:XF 1 "register_operand")
15305 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
15306 (set (match_dup 5) (sqrt:XF (match_dup 4)))
15307 (parallel [(set (match_operand:XF 0 "register_operand")
15308 (unspec:XF [(match_dup 5) (match_dup 1)]
15310 (clobber (match_scratch:XF 6))])]
15311 "TARGET_USE_FANCY_MATH_387
15312 && flag_unsafe_math_optimizations"
15316 for (i = 2; i < 6; i++)
15317 operands[i] = gen_reg_rtx (XFmode);
15319 emit_move_insn (operands[3], CONST1_RTX (XFmode));
15322 (define_expand "asin<mode>2"
15323 [(use (match_operand:MODEF 0 "register_operand"))
15324 (use (match_operand:MODEF 1 "general_operand"))]
15325 "TARGET_USE_FANCY_MATH_387
15326 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15327 || TARGET_MIX_SSE_I387)
15328 && flag_unsafe_math_optimizations"
15330 rtx op0 = gen_reg_rtx (XFmode);
15331 rtx op1 = gen_reg_rtx (XFmode);
15333 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15334 emit_insn (gen_asinxf2 (op0, op1));
15335 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
15339 (define_expand "acosxf2"
15340 [(set (match_dup 2)
15341 (mult:XF (match_operand:XF 1 "register_operand")
15343 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
15344 (set (match_dup 5) (sqrt:XF (match_dup 4)))
15345 (parallel [(set (match_operand:XF 0 "register_operand")
15346 (unspec:XF [(match_dup 1) (match_dup 5)]
15348 (clobber (match_scratch:XF 6))])]
15349 "TARGET_USE_FANCY_MATH_387
15350 && flag_unsafe_math_optimizations"
15354 for (i = 2; i < 6; i++)
15355 operands[i] = gen_reg_rtx (XFmode);
15357 emit_move_insn (operands[3], CONST1_RTX (XFmode));
15360 (define_expand "acos<mode>2"
15361 [(use (match_operand:MODEF 0 "register_operand"))
15362 (use (match_operand:MODEF 1 "general_operand"))]
15363 "TARGET_USE_FANCY_MATH_387
15364 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15365 || TARGET_MIX_SSE_I387)
15366 && flag_unsafe_math_optimizations"
15368 rtx op0 = gen_reg_rtx (XFmode);
15369 rtx op1 = gen_reg_rtx (XFmode);
15371 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15372 emit_insn (gen_acosxf2 (op0, op1));
15373 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
15377 (define_insn "fyl2xxf3_i387"
15378 [(set (match_operand:XF 0 "register_operand" "=f")
15379 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
15380 (match_operand:XF 2 "register_operand" "f")]
15382 (clobber (match_scratch:XF 3 "=2"))]
15383 "TARGET_USE_FANCY_MATH_387
15384 && flag_unsafe_math_optimizations"
15386 [(set_attr "type" "fpspc")
15387 (set_attr "znver1_decode" "vector")
15388 (set_attr "mode" "XF")])
15390 (define_expand "logxf2"
15391 [(parallel [(set (match_operand:XF 0 "register_operand")
15392 (unspec:XF [(match_operand:XF 1 "register_operand")
15393 (match_dup 2)] UNSPEC_FYL2X))
15394 (clobber (match_scratch:XF 3))])]
15395 "TARGET_USE_FANCY_MATH_387
15396 && flag_unsafe_math_optimizations"
15399 = force_reg (XFmode, standard_80387_constant_rtx (4)); /* fldln2 */
15402 (define_expand "log<mode>2"
15403 [(use (match_operand:MODEF 0 "register_operand"))
15404 (use (match_operand:MODEF 1 "general_operand"))]
15405 "TARGET_USE_FANCY_MATH_387
15406 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15407 || TARGET_MIX_SSE_I387)
15408 && flag_unsafe_math_optimizations"
15410 rtx op0 = gen_reg_rtx (XFmode);
15411 rtx op1 = gen_reg_rtx (XFmode);
15413 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15414 emit_insn (gen_logxf2 (op0, op1));
15415 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
15419 (define_expand "log10xf2"
15420 [(parallel [(set (match_operand:XF 0 "register_operand")
15421 (unspec:XF [(match_operand:XF 1 "register_operand")
15422 (match_dup 2)] UNSPEC_FYL2X))
15423 (clobber (match_scratch:XF 3))])]
15424 "TARGET_USE_FANCY_MATH_387
15425 && flag_unsafe_math_optimizations"
15428 = force_reg (XFmode, standard_80387_constant_rtx (3)); /* fldlg2 */
15431 (define_expand "log10<mode>2"
15432 [(use (match_operand:MODEF 0 "register_operand"))
15433 (use (match_operand:MODEF 1 "general_operand"))]
15434 "TARGET_USE_FANCY_MATH_387
15435 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15436 || TARGET_MIX_SSE_I387)
15437 && flag_unsafe_math_optimizations"
15439 rtx op0 = gen_reg_rtx (XFmode);
15440 rtx op1 = gen_reg_rtx (XFmode);
15442 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15443 emit_insn (gen_log10xf2 (op0, op1));
15444 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
15448 (define_expand "log2xf2"
15449 [(parallel [(set (match_operand:XF 0 "register_operand")
15450 (unspec:XF [(match_operand:XF 1 "register_operand")
15451 (match_dup 2)] UNSPEC_FYL2X))
15452 (clobber (match_scratch:XF 3))])]
15453 "TARGET_USE_FANCY_MATH_387
15454 && flag_unsafe_math_optimizations"
15455 "operands[2] = force_reg (XFmode, CONST1_RTX (XFmode));")
15457 (define_expand "log2<mode>2"
15458 [(use (match_operand:MODEF 0 "register_operand"))
15459 (use (match_operand:MODEF 1 "general_operand"))]
15460 "TARGET_USE_FANCY_MATH_387
15461 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15462 || TARGET_MIX_SSE_I387)
15463 && flag_unsafe_math_optimizations"
15465 rtx op0 = gen_reg_rtx (XFmode);
15466 rtx op1 = gen_reg_rtx (XFmode);
15468 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15469 emit_insn (gen_log2xf2 (op0, op1));
15470 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
15474 (define_insn "fyl2xp1xf3_i387"
15475 [(set (match_operand:XF 0 "register_operand" "=f")
15476 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
15477 (match_operand:XF 2 "register_operand" "f")]
15479 (clobber (match_scratch:XF 3 "=2"))]
15480 "TARGET_USE_FANCY_MATH_387
15481 && flag_unsafe_math_optimizations"
15483 [(set_attr "type" "fpspc")
15484 (set_attr "znver1_decode" "vector")
15485 (set_attr "mode" "XF")])
15487 (define_expand "log1pxf2"
15488 [(use (match_operand:XF 0 "register_operand"))
15489 (use (match_operand:XF 1 "register_operand"))]
15490 "TARGET_USE_FANCY_MATH_387
15491 && flag_unsafe_math_optimizations"
15493 ix86_emit_i387_log1p (operands[0], operands[1]);
15497 (define_expand "log1p<mode>2"
15498 [(use (match_operand:MODEF 0 "register_operand"))
15499 (use (match_operand:MODEF 1 "general_operand"))]
15500 "TARGET_USE_FANCY_MATH_387
15501 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15502 || TARGET_MIX_SSE_I387)
15503 && flag_unsafe_math_optimizations"
15505 rtx op0 = gen_reg_rtx (XFmode);
15506 rtx op1 = gen_reg_rtx (XFmode);
15508 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15509 emit_insn (gen_log1pxf2 (op0, op1));
15510 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
15514 (define_insn "fxtractxf3_i387"
15515 [(set (match_operand:XF 0 "register_operand" "=f")
15516 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15517 UNSPEC_XTRACT_FRACT))
15518 (set (match_operand:XF 1 "register_operand" "=f")
15519 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
15520 "TARGET_USE_FANCY_MATH_387
15521 && flag_unsafe_math_optimizations"
15523 [(set_attr "type" "fpspc")
15524 (set_attr "znver1_decode" "vector")
15525 (set_attr "mode" "XF")])
15527 (define_expand "logbxf2"
15528 [(parallel [(set (match_dup 2)
15529 (unspec:XF [(match_operand:XF 1 "register_operand")]
15530 UNSPEC_XTRACT_FRACT))
15531 (set (match_operand:XF 0 "register_operand")
15532 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
15533 "TARGET_USE_FANCY_MATH_387
15534 && flag_unsafe_math_optimizations"
15535 "operands[2] = gen_reg_rtx (XFmode);")
15537 (define_expand "logb<mode>2"
15538 [(use (match_operand:MODEF 0 "register_operand"))
15539 (use (match_operand:MODEF 1 "general_operand"))]
15540 "TARGET_USE_FANCY_MATH_387
15541 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15542 || TARGET_MIX_SSE_I387)
15543 && flag_unsafe_math_optimizations"
15545 rtx op0 = gen_reg_rtx (XFmode);
15546 rtx op1 = gen_reg_rtx (XFmode);
15548 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15549 emit_insn (gen_logbxf2 (op0, op1));
15550 emit_insn (gen_truncxf<mode>2 (operands[0], op1));
15554 (define_expand "ilogbxf2"
15555 [(use (match_operand:SI 0 "register_operand"))
15556 (use (match_operand:XF 1 "register_operand"))]
15557 "TARGET_USE_FANCY_MATH_387
15558 && flag_unsafe_math_optimizations"
15562 if (optimize_insn_for_size_p ())
15565 op0 = gen_reg_rtx (XFmode);
15566 op1 = gen_reg_rtx (XFmode);
15568 emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
15569 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
15573 (define_expand "ilogb<mode>2"
15574 [(use (match_operand:SI 0 "register_operand"))
15575 (use (match_operand:MODEF 1 "general_operand"))]
15576 "TARGET_USE_FANCY_MATH_387
15577 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15578 || TARGET_MIX_SSE_I387)
15579 && flag_unsafe_math_optimizations"
15583 if (optimize_insn_for_size_p ())
15586 op0 = gen_reg_rtx (XFmode);
15587 op1 = gen_reg_rtx (XFmode);
15588 op2 = gen_reg_rtx (XFmode);
15590 emit_insn (gen_extend<mode>xf2 (op2, operands[1]));
15591 emit_insn (gen_fxtractxf3_i387 (op0, op1, op2));
15592 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
15596 (define_insn "*f2xm1xf2_i387"
15597 [(set (match_operand:XF 0 "register_operand" "=f")
15598 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15600 "TARGET_USE_FANCY_MATH_387
15601 && flag_unsafe_math_optimizations"
15603 [(set_attr "type" "fpspc")
15604 (set_attr "znver1_decode" "vector")
15605 (set_attr "mode" "XF")])
15607 (define_insn "fscalexf4_i387"
15608 [(set (match_operand:XF 0 "register_operand" "=f")
15609 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15610 (match_operand:XF 3 "register_operand" "1")]
15611 UNSPEC_FSCALE_FRACT))
15612 (set (match_operand:XF 1 "register_operand" "=f")
15613 (unspec:XF [(match_dup 2) (match_dup 3)]
15614 UNSPEC_FSCALE_EXP))]
15615 "TARGET_USE_FANCY_MATH_387
15616 && flag_unsafe_math_optimizations"
15618 [(set_attr "type" "fpspc")
15619 (set_attr "znver1_decode" "vector")
15620 (set_attr "mode" "XF")])
15622 (define_expand "expNcorexf3"
15623 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand")
15624 (match_operand:XF 2 "register_operand")))
15625 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
15626 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
15627 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
15628 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
15629 (parallel [(set (match_operand:XF 0 "register_operand")
15630 (unspec:XF [(match_dup 8) (match_dup 4)]
15631 UNSPEC_FSCALE_FRACT))
15633 (unspec:XF [(match_dup 8) (match_dup 4)]
15634 UNSPEC_FSCALE_EXP))])]
15635 "TARGET_USE_FANCY_MATH_387
15636 && flag_unsafe_math_optimizations"
15640 for (i = 3; i < 10; i++)
15641 operands[i] = gen_reg_rtx (XFmode);
15643 emit_move_insn (operands[7], CONST1_RTX (XFmode));
15646 (define_expand "expxf2"
15647 [(use (match_operand:XF 0 "register_operand"))
15648 (use (match_operand:XF 1 "register_operand"))]
15649 "TARGET_USE_FANCY_MATH_387
15650 && flag_unsafe_math_optimizations"
15652 rtx op2 = force_reg (XFmode, standard_80387_constant_rtx (5)); /* fldl2e */
15654 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
15658 (define_expand "exp<mode>2"
15659 [(use (match_operand:MODEF 0 "register_operand"))
15660 (use (match_operand:MODEF 1 "general_operand"))]
15661 "TARGET_USE_FANCY_MATH_387
15662 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15663 || TARGET_MIX_SSE_I387)
15664 && flag_unsafe_math_optimizations"
15666 rtx op0 = gen_reg_rtx (XFmode);
15667 rtx op1 = gen_reg_rtx (XFmode);
15669 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15670 emit_insn (gen_expxf2 (op0, op1));
15671 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
15675 (define_expand "exp10xf2"
15676 [(use (match_operand:XF 0 "register_operand"))
15677 (use (match_operand:XF 1 "register_operand"))]
15678 "TARGET_USE_FANCY_MATH_387
15679 && flag_unsafe_math_optimizations"
15681 rtx op2 = force_reg (XFmode, standard_80387_constant_rtx (6)); /* fldl2t */
15683 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
15687 (define_expand "exp10<mode>2"
15688 [(use (match_operand:MODEF 0 "register_operand"))
15689 (use (match_operand:MODEF 1 "general_operand"))]
15690 "TARGET_USE_FANCY_MATH_387
15691 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15692 || TARGET_MIX_SSE_I387)
15693 && flag_unsafe_math_optimizations"
15695 rtx op0 = gen_reg_rtx (XFmode);
15696 rtx op1 = gen_reg_rtx (XFmode);
15698 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15699 emit_insn (gen_exp10xf2 (op0, op1));
15700 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
15704 (define_expand "exp2xf2"
15705 [(use (match_operand:XF 0 "register_operand"))
15706 (use (match_operand:XF 1 "register_operand"))]
15707 "TARGET_USE_FANCY_MATH_387
15708 && flag_unsafe_math_optimizations"
15710 rtx op2 = force_reg (XFmode, CONST1_RTX (XFmode));
15712 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
15716 (define_expand "exp2<mode>2"
15717 [(use (match_operand:MODEF 0 "register_operand"))
15718 (use (match_operand:MODEF 1 "general_operand"))]
15719 "TARGET_USE_FANCY_MATH_387
15720 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15721 || TARGET_MIX_SSE_I387)
15722 && flag_unsafe_math_optimizations"
15724 rtx op0 = gen_reg_rtx (XFmode);
15725 rtx op1 = gen_reg_rtx (XFmode);
15727 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15728 emit_insn (gen_exp2xf2 (op0, op1));
15729 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
15733 (define_expand "expm1xf2"
15734 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand")
15736 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
15737 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
15738 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
15739 (parallel [(set (match_dup 7)
15740 (unspec:XF [(match_dup 6) (match_dup 4)]
15741 UNSPEC_FSCALE_FRACT))
15743 (unspec:XF [(match_dup 6) (match_dup 4)]
15744 UNSPEC_FSCALE_EXP))])
15745 (parallel [(set (match_dup 10)
15746 (unspec:XF [(match_dup 9) (match_dup 8)]
15747 UNSPEC_FSCALE_FRACT))
15748 (set (match_dup 11)
15749 (unspec:XF [(match_dup 9) (match_dup 8)]
15750 UNSPEC_FSCALE_EXP))])
15751 (set (match_dup 12) (minus:XF (match_dup 10) (match_dup 9)))
15752 (set (match_operand:XF 0 "register_operand")
15753 (plus:XF (match_dup 12) (match_dup 7)))]
15754 "TARGET_USE_FANCY_MATH_387
15755 && flag_unsafe_math_optimizations"
15759 for (i = 2; i < 13; i++)
15760 operands[i] = gen_reg_rtx (XFmode);
15762 emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
15763 emit_move_insn (operands[9], CONST1_RTX (XFmode));
15766 (define_expand "expm1<mode>2"
15767 [(use (match_operand:MODEF 0 "register_operand"))
15768 (use (match_operand:MODEF 1 "general_operand"))]
15769 "TARGET_USE_FANCY_MATH_387
15770 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15771 || TARGET_MIX_SSE_I387)
15772 && flag_unsafe_math_optimizations"
15774 rtx op0 = gen_reg_rtx (XFmode);
15775 rtx op1 = gen_reg_rtx (XFmode);
15777 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15778 emit_insn (gen_expm1xf2 (op0, op1));
15779 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
15783 (define_expand "ldexpxf3"
15784 [(match_operand:XF 0 "register_operand")
15785 (match_operand:XF 1 "register_operand")
15786 (match_operand:SI 2 "register_operand")]
15787 "TARGET_USE_FANCY_MATH_387
15788 && flag_unsafe_math_optimizations"
15790 rtx tmp1 = gen_reg_rtx (XFmode);
15791 rtx tmp2 = gen_reg_rtx (XFmode);
15793 emit_insn (gen_floatsixf2 (tmp1, operands[2]));
15794 emit_insn (gen_fscalexf4_i387 (operands[0], tmp2,
15795 operands[1], tmp1));
15799 (define_expand "ldexp<mode>3"
15800 [(use (match_operand:MODEF 0 "register_operand"))
15801 (use (match_operand:MODEF 1 "general_operand"))
15802 (use (match_operand:SI 2 "register_operand"))]
15803 "TARGET_USE_FANCY_MATH_387
15804 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15805 || TARGET_MIX_SSE_I387)
15806 && flag_unsafe_math_optimizations"
15808 rtx op0 = gen_reg_rtx (XFmode);
15809 rtx op1 = gen_reg_rtx (XFmode);
15811 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15812 emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
15813 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
15817 (define_expand "scalbxf3"
15818 [(parallel [(set (match_operand:XF 0 " register_operand")
15819 (unspec:XF [(match_operand:XF 1 "register_operand")
15820 (match_operand:XF 2 "register_operand")]
15821 UNSPEC_FSCALE_FRACT))
15823 (unspec:XF [(match_dup 1) (match_dup 2)]
15824 UNSPEC_FSCALE_EXP))])]
15825 "TARGET_USE_FANCY_MATH_387
15826 && flag_unsafe_math_optimizations"
15827 "operands[3] = gen_reg_rtx (XFmode);")
15829 (define_expand "scalb<mode>3"
15830 [(use (match_operand:MODEF 0 "register_operand"))
15831 (use (match_operand:MODEF 1 "general_operand"))
15832 (use (match_operand:MODEF 2 "general_operand"))]
15833 "TARGET_USE_FANCY_MATH_387
15834 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15835 || TARGET_MIX_SSE_I387)
15836 && flag_unsafe_math_optimizations"
15838 rtx op0 = gen_reg_rtx (XFmode);
15839 rtx op1 = gen_reg_rtx (XFmode);
15840 rtx op2 = gen_reg_rtx (XFmode);
15842 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15843 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
15844 emit_insn (gen_scalbxf3 (op0, op1, op2));
15845 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
15849 (define_expand "significandxf2"
15850 [(parallel [(set (match_operand:XF 0 "register_operand")
15851 (unspec:XF [(match_operand:XF 1 "register_operand")]
15852 UNSPEC_XTRACT_FRACT))
15854 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
15855 "TARGET_USE_FANCY_MATH_387
15856 && flag_unsafe_math_optimizations"
15857 "operands[2] = gen_reg_rtx (XFmode);")
15859 (define_expand "significand<mode>2"
15860 [(use (match_operand:MODEF 0 "register_operand"))
15861 (use (match_operand:MODEF 1 "general_operand"))]
15862 "TARGET_USE_FANCY_MATH_387
15863 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15864 || TARGET_MIX_SSE_I387)
15865 && flag_unsafe_math_optimizations"
15867 rtx op0 = gen_reg_rtx (XFmode);
15868 rtx op1 = gen_reg_rtx (XFmode);
15870 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15871 emit_insn (gen_significandxf2 (op0, op1));
15872 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
15877 (define_insn "sse4_1_round<mode>2"
15878 [(set (match_operand:MODEF 0 "register_operand" "=x,v")
15879 (unspec:MODEF [(match_operand:MODEF 1 "nonimmediate_operand" "xm,vm")
15880 (match_operand:SI 2 "const_0_to_15_operand" "n,n")]
15884 %vround<ssemodesuffix>\t{%2, %1, %d0|%d0, %1, %2}
15885 vrndscale<ssemodesuffix>\t{%2, %1, %d0|%d0, %1, %2}"
15886 [(set_attr "type" "ssecvt")
15887 (set_attr "prefix_extra" "1,*")
15888 (set_attr "length_immediate" "*,1")
15889 (set_attr "prefix" "maybe_vex,evex")
15890 (set_attr "isa" "noavx512f,avx512f")
15891 (set_attr "mode" "<MODE>")])
15893 (define_insn "rintxf2"
15894 [(set (match_operand:XF 0 "register_operand" "=f")
15895 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15897 "TARGET_USE_FANCY_MATH_387"
15899 [(set_attr "type" "fpspc")
15900 (set_attr "znver1_decode" "vector")
15901 (set_attr "mode" "XF")])
15903 (define_expand "rint<mode>2"
15904 [(use (match_operand:MODEF 0 "register_operand"))
15905 (use (match_operand:MODEF 1 "nonimmediate_operand"))]
15906 "TARGET_USE_FANCY_MATH_387
15907 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
15909 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15912 emit_insn (gen_sse4_1_round<mode>2
15913 (operands[0], operands[1], GEN_INT (ROUND_MXCSR)));
15915 ix86_expand_rint (operands[0], operands[1]);
15919 rtx op0 = gen_reg_rtx (XFmode);
15920 rtx op1 = gen_reg_rtx (XFmode);
15922 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15923 emit_insn (gen_rintxf2 (op0, op1));
15924 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
15929 (define_expand "nearbyintxf2"
15930 [(set (match_operand:XF 0 "register_operand")
15931 (unspec:XF [(match_operand:XF 1 "register_operand")]
15933 "TARGET_USE_FANCY_MATH_387
15934 && !flag_trapping_math")
15936 (define_expand "nearbyint<mode>2"
15937 [(use (match_operand:MODEF 0 "register_operand"))
15938 (use (match_operand:MODEF 1 "nonimmediate_operand"))]
15939 "(TARGET_USE_FANCY_MATH_387
15940 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15941 || TARGET_MIX_SSE_I387)
15942 && !flag_trapping_math)
15943 || (TARGET_SSE4_1 && TARGET_SSE_MATH)"
15945 if (TARGET_SSE4_1 && TARGET_SSE_MATH)
15946 emit_insn (gen_sse4_1_round<mode>2
15947 (operands[0], operands[1], GEN_INT (ROUND_MXCSR
15951 rtx op0 = gen_reg_rtx (XFmode);
15952 rtx op1 = gen_reg_rtx (XFmode);
15954 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15955 emit_insn (gen_nearbyintxf2 (op0, op1));
15956 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
15961 (define_expand "round<mode>2"
15962 [(match_operand:X87MODEF 0 "register_operand")
15963 (match_operand:X87MODEF 1 "nonimmediate_operand")]
15964 "(TARGET_USE_FANCY_MATH_387
15965 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15966 || TARGET_MIX_SSE_I387)
15967 && flag_unsafe_math_optimizations
15968 && (flag_fp_int_builtin_inexact || !flag_trapping_math))
15969 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15970 && !flag_trapping_math && !flag_rounding_math)"
15972 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15973 && !flag_trapping_math && !flag_rounding_math)
15977 operands[1] = force_reg (<MODE>mode, operands[1]);
15978 ix86_expand_round_sse4 (operands[0], operands[1]);
15980 else if (TARGET_64BIT || (<MODE>mode != DFmode))
15981 ix86_expand_round (operands[0], operands[1]);
15983 ix86_expand_rounddf_32 (operands[0], operands[1]);
15987 operands[1] = force_reg (<MODE>mode, operands[1]);
15988 ix86_emit_i387_round (operands[0], operands[1]);
15993 (define_insn "lrintxfdi2"
15994 [(set (match_operand:DI 0 "nonimmediate_operand" "=m")
15995 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
15997 (clobber (match_scratch:XF 2 "=&f"))]
15998 "TARGET_USE_FANCY_MATH_387"
15999 "* return output_fix_trunc (insn, operands, false);"
16000 [(set_attr "type" "fpspc")
16001 (set_attr "mode" "DI")])
16003 (define_insn "lrintxf<mode>2"
16004 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m")
16005 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
16007 "TARGET_USE_FANCY_MATH_387"
16008 "* return output_fix_trunc (insn, operands, false);"
16009 [(set_attr "type" "fpspc")
16010 (set_attr "mode" "<MODE>")])
16012 (define_expand "lrint<MODEF:mode><SWI48:mode>2"
16013 [(set (match_operand:SWI48 0 "nonimmediate_operand")
16014 (unspec:SWI48 [(match_operand:MODEF 1 "register_operand")]
16015 UNSPEC_FIX_NOTRUNC))]
16016 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH")
16018 (define_expand "lround<X87MODEF:mode><SWI248x:mode>2"
16019 [(match_operand:SWI248x 0 "nonimmediate_operand")
16020 (match_operand:X87MODEF 1 "register_operand")]
16021 "(TARGET_USE_FANCY_MATH_387
16022 && (!(SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
16023 || TARGET_MIX_SSE_I387)
16024 && flag_unsafe_math_optimizations)
16025 || (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
16026 && <SWI248x:MODE>mode != HImode
16027 && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT)
16028 && !flag_trapping_math && !flag_rounding_math)"
16030 if (optimize_insn_for_size_p ())
16033 if (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
16034 && <SWI248x:MODE>mode != HImode
16035 && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT)
16036 && !flag_trapping_math && !flag_rounding_math)
16037 ix86_expand_lround (operands[0], operands[1]);
16039 ix86_emit_i387_round (operands[0], operands[1]);
16043 (define_int_iterator FRNDINT_ROUNDING
16044 [UNSPEC_FRNDINT_FLOOR
16045 UNSPEC_FRNDINT_CEIL
16046 UNSPEC_FRNDINT_TRUNC])
16048 (define_int_iterator FIST_ROUNDING
16052 ;; Base name for define_insn
16053 (define_int_attr rounding_insn
16054 [(UNSPEC_FRNDINT_FLOOR "floor")
16055 (UNSPEC_FRNDINT_CEIL "ceil")
16056 (UNSPEC_FRNDINT_TRUNC "btrunc")
16057 (UNSPEC_FIST_FLOOR "floor")
16058 (UNSPEC_FIST_CEIL "ceil")])
16060 (define_int_attr rounding
16061 [(UNSPEC_FRNDINT_FLOOR "floor")
16062 (UNSPEC_FRNDINT_CEIL "ceil")
16063 (UNSPEC_FRNDINT_TRUNC "trunc")
16064 (UNSPEC_FIST_FLOOR "floor")
16065 (UNSPEC_FIST_CEIL "ceil")])
16067 (define_int_attr ROUNDING
16068 [(UNSPEC_FRNDINT_FLOOR "FLOOR")
16069 (UNSPEC_FRNDINT_CEIL "CEIL")
16070 (UNSPEC_FRNDINT_TRUNC "TRUNC")
16071 (UNSPEC_FIST_FLOOR "FLOOR")
16072 (UNSPEC_FIST_CEIL "CEIL")])
16074 ;; Rounding mode control word calculation could clobber FLAGS_REG.
16075 (define_insn_and_split "frndintxf2_<rounding>"
16076 [(set (match_operand:XF 0 "register_operand")
16077 (unspec:XF [(match_operand:XF 1 "register_operand")]
16079 (clobber (reg:CC FLAGS_REG))]
16080 "TARGET_USE_FANCY_MATH_387
16081 && (flag_fp_int_builtin_inexact || !flag_trapping_math)
16082 && can_create_pseudo_p ()"
16087 ix86_optimize_mode_switching[I387_<ROUNDING>] = 1;
16089 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
16090 operands[3] = assign_386_stack_local (HImode, SLOT_CW_<ROUNDING>);
16092 emit_insn (gen_frndintxf2_<rounding>_i387 (operands[0], operands[1],
16093 operands[2], operands[3]));
16096 [(set_attr "type" "frndint")
16097 (set_attr "i387_cw" "<rounding>")
16098 (set_attr "mode" "XF")])
16100 (define_insn "frndintxf2_<rounding>_i387"
16101 [(set (match_operand:XF 0 "register_operand" "=f")
16102 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16104 (use (match_operand:HI 2 "memory_operand" "m"))
16105 (use (match_operand:HI 3 "memory_operand" "m"))]
16106 "TARGET_USE_FANCY_MATH_387
16107 && (flag_fp_int_builtin_inexact || !flag_trapping_math)"
16108 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
16109 [(set_attr "type" "frndint")
16110 (set_attr "i387_cw" "<rounding>")
16111 (set_attr "mode" "XF")])
16113 (define_expand "<rounding_insn>xf2"
16114 [(parallel [(set (match_operand:XF 0 "register_operand")
16115 (unspec:XF [(match_operand:XF 1 "register_operand")]
16117 (clobber (reg:CC FLAGS_REG))])]
16118 "TARGET_USE_FANCY_MATH_387
16119 && (flag_fp_int_builtin_inexact || !flag_trapping_math)")
16121 (define_expand "<rounding_insn><mode>2"
16122 [(parallel [(set (match_operand:MODEF 0 "register_operand")
16123 (unspec:MODEF [(match_operand:MODEF 1 "register_operand")]
16125 (clobber (reg:CC FLAGS_REG))])]
16126 "(TARGET_USE_FANCY_MATH_387
16127 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16128 || TARGET_MIX_SSE_I387)
16129 && (flag_fp_int_builtin_inexact || !flag_trapping_math))
16130 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16131 && (TARGET_SSE4_1 || flag_fp_int_builtin_inexact
16132 || !flag_trapping_math))"
16134 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16135 && (TARGET_SSE4_1 || flag_fp_int_builtin_inexact || !flag_trapping_math))
16138 emit_insn (gen_sse4_1_round<mode>2
16139 (operands[0], operands[1], GEN_INT (ROUND_<ROUNDING>
16141 else if (TARGET_64BIT || (<MODE>mode != DFmode))
16143 if (ROUND_<ROUNDING> == ROUND_FLOOR)
16144 ix86_expand_floorceil (operands[0], operands[1], true);
16145 else if (ROUND_<ROUNDING> == ROUND_CEIL)
16146 ix86_expand_floorceil (operands[0], operands[1], false);
16147 else if (ROUND_<ROUNDING> == ROUND_TRUNC)
16148 ix86_expand_trunc (operands[0], operands[1]);
16150 gcc_unreachable ();
16154 if (ROUND_<ROUNDING> == ROUND_FLOOR)
16155 ix86_expand_floorceildf_32 (operands[0], operands[1], true);
16156 else if (ROUND_<ROUNDING> == ROUND_CEIL)
16157 ix86_expand_floorceildf_32 (operands[0], operands[1], false);
16158 else if (ROUND_<ROUNDING> == ROUND_TRUNC)
16159 ix86_expand_truncdf_32 (operands[0], operands[1]);
16161 gcc_unreachable ();
16166 rtx op0 = gen_reg_rtx (XFmode);
16167 rtx op1 = gen_reg_rtx (XFmode);
16169 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16170 emit_insn (gen_frndintxf2_<rounding> (op0, op1));
16171 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
16176 ;; Rounding mode control word calculation could clobber FLAGS_REG.
16177 (define_insn_and_split "*fist<mode>2_<rounding>_1"
16178 [(set (match_operand:SWI248x 0 "nonimmediate_operand")
16179 (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
16181 (clobber (reg:CC FLAGS_REG))]
16182 "TARGET_USE_FANCY_MATH_387
16183 && flag_unsafe_math_optimizations
16184 && can_create_pseudo_p ()"
16189 ix86_optimize_mode_switching[I387_<ROUNDING>] = 1;
16191 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
16192 operands[3] = assign_386_stack_local (HImode, SLOT_CW_<ROUNDING>);
16194 emit_insn (gen_fist<mode>2_<rounding> (operands[0], operands[1],
16195 operands[2], operands[3]));
16198 [(set_attr "type" "fistp")
16199 (set_attr "i387_cw" "<rounding>")
16200 (set_attr "mode" "<MODE>")])
16202 (define_insn "fistdi2_<rounding>"
16203 [(set (match_operand:DI 0 "nonimmediate_operand" "=m")
16204 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
16206 (use (match_operand:HI 2 "memory_operand" "m"))
16207 (use (match_operand:HI 3 "memory_operand" "m"))
16208 (clobber (match_scratch:XF 4 "=&f"))]
16209 "TARGET_USE_FANCY_MATH_387
16210 && flag_unsafe_math_optimizations"
16211 "* return output_fix_trunc (insn, operands, false);"
16212 [(set_attr "type" "fistp")
16213 (set_attr "i387_cw" "<rounding>")
16214 (set_attr "mode" "DI")])
16216 (define_insn "fist<mode>2_<rounding>"
16217 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m")
16218 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
16220 (use (match_operand:HI 2 "memory_operand" "m"))
16221 (use (match_operand:HI 3 "memory_operand" "m"))]
16222 "TARGET_USE_FANCY_MATH_387
16223 && flag_unsafe_math_optimizations"
16224 "* return output_fix_trunc (insn, operands, false);"
16225 [(set_attr "type" "fistp")
16226 (set_attr "i387_cw" "<rounding>")
16227 (set_attr "mode" "<MODE>")])
16229 (define_expand "l<rounding_insn>xf<mode>2"
16230 [(parallel [(set (match_operand:SWI248x 0 "nonimmediate_operand")
16231 (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
16233 (clobber (reg:CC FLAGS_REG))])]
16234 "TARGET_USE_FANCY_MATH_387
16235 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16236 && flag_unsafe_math_optimizations")
16238 (define_expand "l<rounding_insn><MODEF:mode><SWI48:mode>2"
16239 [(parallel [(set (match_operand:SWI48 0 "nonimmediate_operand")
16240 (unspec:SWI48 [(match_operand:MODEF 1 "register_operand")]
16242 (clobber (reg:CC FLAGS_REG))])]
16243 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
16244 && (TARGET_SSE4_1 || !flag_trapping_math)"
16248 rtx tmp = gen_reg_rtx (<MODEF:MODE>mode);
16250 emit_insn (gen_sse4_1_round<mode>2
16251 (tmp, operands[1], GEN_INT (ROUND_<ROUNDING>
16253 emit_insn (gen_fix_trunc<MODEF:mode><SWI48:mode>2
16254 (operands[0], tmp));
16256 else if (ROUND_<ROUNDING> == ROUND_FLOOR)
16257 ix86_expand_lfloorceil (operands[0], operands[1], true);
16258 else if (ROUND_<ROUNDING> == ROUND_CEIL)
16259 ix86_expand_lfloorceil (operands[0], operands[1], false);
16261 gcc_unreachable ();
16266 (define_insn "fxam<mode>2_i387"
16267 [(set (match_operand:HI 0 "register_operand" "=a")
16269 [(match_operand:X87MODEF 1 "register_operand" "f")]
16271 "TARGET_USE_FANCY_MATH_387"
16272 "fxam\n\tfnstsw\t%0"
16273 [(set_attr "type" "multi")
16274 (set_attr "length" "4")
16275 (set_attr "unit" "i387")
16276 (set_attr "mode" "<MODE>")])
16278 (define_expand "signbittf2"
16279 [(use (match_operand:SI 0 "register_operand"))
16280 (use (match_operand:TF 1 "register_operand"))]
16285 rtx mask = ix86_build_signbit_mask (TFmode, 0, 0);
16286 rtx scratch = gen_reg_rtx (QImode);
16288 emit_insn (gen_ptesttf2 (operands[1], mask));
16289 ix86_expand_setcc (scratch, NE,
16290 gen_rtx_REG (CCZmode, FLAGS_REG), const0_rtx);
16292 emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
16296 emit_insn (gen_sse_movmskps (operands[0],
16297 gen_lowpart (V4SFmode, operands[1])));
16298 emit_insn (gen_andsi3 (operands[0], operands[0], GEN_INT (0x8)));
16303 (define_expand "signbitxf2"
16304 [(use (match_operand:SI 0 "register_operand"))
16305 (use (match_operand:XF 1 "register_operand"))]
16306 "TARGET_USE_FANCY_MATH_387"
16308 rtx scratch = gen_reg_rtx (HImode);
16310 emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
16311 emit_insn (gen_andsi3 (operands[0],
16312 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
16316 (define_insn "movmsk_df"
16317 [(set (match_operand:SI 0 "register_operand" "=r")
16319 [(match_operand:DF 1 "register_operand" "x")]
16321 "SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH"
16322 "%vmovmskpd\t{%1, %0|%0, %1}"
16323 [(set_attr "type" "ssemov")
16324 (set_attr "prefix" "maybe_vex")
16325 (set_attr "mode" "DF")])
16327 ;; Use movmskpd in SSE mode to avoid store forwarding stall
16328 ;; for 32bit targets and movq+shrq sequence for 64bit targets.
16329 (define_expand "signbitdf2"
16330 [(use (match_operand:SI 0 "register_operand"))
16331 (use (match_operand:DF 1 "register_operand"))]
16332 "TARGET_USE_FANCY_MATH_387
16333 || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
16335 if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)
16337 emit_insn (gen_movmsk_df (operands[0], operands[1]));
16338 emit_insn (gen_andsi3 (operands[0], operands[0], const1_rtx));
16342 rtx scratch = gen_reg_rtx (HImode);
16344 emit_insn (gen_fxamdf2_i387 (scratch, operands[1]));
16345 emit_insn (gen_andsi3 (operands[0],
16346 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
16351 (define_expand "signbitsf2"
16352 [(use (match_operand:SI 0 "register_operand"))
16353 (use (match_operand:SF 1 "register_operand"))]
16354 "TARGET_USE_FANCY_MATH_387
16355 && !(SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH)"
16357 rtx scratch = gen_reg_rtx (HImode);
16359 emit_insn (gen_fxamsf2_i387 (scratch, operands[1]));
16360 emit_insn (gen_andsi3 (operands[0],
16361 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
16365 ;; Block operation instructions
16368 [(unspec_volatile [(const_int 0)] UNSPECV_CLD)]
16371 [(set_attr "length" "1")
16372 (set_attr "length_immediate" "0")
16373 (set_attr "modrm" "0")])
16375 (define_expand "movmem<mode>"
16376 [(use (match_operand:BLK 0 "memory_operand"))
16377 (use (match_operand:BLK 1 "memory_operand"))
16378 (use (match_operand:SWI48 2 "nonmemory_operand"))
16379 (use (match_operand:SWI48 3 "const_int_operand"))
16380 (use (match_operand:SI 4 "const_int_operand"))
16381 (use (match_operand:SI 5 "const_int_operand"))
16382 (use (match_operand:SI 6 ""))
16383 (use (match_operand:SI 7 ""))
16384 (use (match_operand:SI 8 ""))]
16387 if (ix86_expand_set_or_movmem (operands[0], operands[1],
16388 operands[2], NULL, operands[3],
16389 operands[4], operands[5],
16390 operands[6], operands[7],
16391 operands[8], false))
16397 ;; Most CPUs don't like single string operations
16398 ;; Handle this case here to simplify previous expander.
16400 (define_expand "strmov"
16401 [(set (match_dup 4) (match_operand 3 "memory_operand"))
16402 (set (match_operand 1 "memory_operand") (match_dup 4))
16403 (parallel [(set (match_operand 0 "register_operand") (match_dup 5))
16404 (clobber (reg:CC FLAGS_REG))])
16405 (parallel [(set (match_operand 2 "register_operand") (match_dup 6))
16406 (clobber (reg:CC FLAGS_REG))])]
16409 /* Can't use this for non-default address spaces. */
16410 if (!ADDR_SPACE_GENERIC_P (MEM_ADDR_SPACE (operands[3])))
16413 rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
16415 /* If .md ever supports :P for Pmode, these can be directly
16416 in the pattern above. */
16417 operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
16418 operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
16420 /* Can't use this if the user has appropriated esi or edi. */
16421 if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
16422 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG]))
16424 emit_insn (gen_strmov_singleop (operands[0], operands[1],
16425 operands[2], operands[3],
16426 operands[5], operands[6]));
16430 operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
16433 (define_expand "strmov_singleop"
16434 [(parallel [(set (match_operand 1 "memory_operand")
16435 (match_operand 3 "memory_operand"))
16436 (set (match_operand 0 "register_operand")
16438 (set (match_operand 2 "register_operand")
16439 (match_operand 5))])]
16443 ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
16446 (define_insn "*strmovdi_rex_1"
16447 [(set (mem:DI (match_operand:P 2 "register_operand" "0"))
16448 (mem:DI (match_operand:P 3 "register_operand" "1")))
16449 (set (match_operand:P 0 "register_operand" "=D")
16450 (plus:P (match_dup 2)
16452 (set (match_operand:P 1 "register_operand" "=S")
16453 (plus:P (match_dup 3)
16456 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG])
16457 && ix86_check_no_addr_space (insn)"
16459 [(set_attr "type" "str")
16460 (set_attr "memory" "both")
16461 (set_attr "mode" "DI")])
16463 (define_insn "*strmovsi_1"
16464 [(set (mem:SI (match_operand:P 2 "register_operand" "0"))
16465 (mem:SI (match_operand:P 3 "register_operand" "1")))
16466 (set (match_operand:P 0 "register_operand" "=D")
16467 (plus:P (match_dup 2)
16469 (set (match_operand:P 1 "register_operand" "=S")
16470 (plus:P (match_dup 3)
16472 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])
16473 && ix86_check_no_addr_space (insn)"
16475 [(set_attr "type" "str")
16476 (set_attr "memory" "both")
16477 (set_attr "mode" "SI")])
16479 (define_insn "*strmovhi_1"
16480 [(set (mem:HI (match_operand:P 2 "register_operand" "0"))
16481 (mem:HI (match_operand:P 3 "register_operand" "1")))
16482 (set (match_operand:P 0 "register_operand" "=D")
16483 (plus:P (match_dup 2)
16485 (set (match_operand:P 1 "register_operand" "=S")
16486 (plus:P (match_dup 3)
16488 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])
16489 && ix86_check_no_addr_space (insn)"
16491 [(set_attr "type" "str")
16492 (set_attr "memory" "both")
16493 (set_attr "mode" "HI")])
16495 (define_insn "*strmovqi_1"
16496 [(set (mem:QI (match_operand:P 2 "register_operand" "0"))
16497 (mem:QI (match_operand:P 3 "register_operand" "1")))
16498 (set (match_operand:P 0 "register_operand" "=D")
16499 (plus:P (match_dup 2)
16501 (set (match_operand:P 1 "register_operand" "=S")
16502 (plus:P (match_dup 3)
16504 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])
16505 && ix86_check_no_addr_space (insn)"
16507 [(set_attr "type" "str")
16508 (set_attr "memory" "both")
16509 (set (attr "prefix_rex")
16511 (match_test "<P:MODE>mode == DImode")
16513 (const_string "*")))
16514 (set_attr "mode" "QI")])
16516 (define_expand "rep_mov"
16517 [(parallel [(set (match_operand 4 "register_operand") (const_int 0))
16518 (set (match_operand 0 "register_operand")
16520 (set (match_operand 2 "register_operand")
16522 (set (match_operand 1 "memory_operand")
16523 (match_operand 3 "memory_operand"))
16524 (use (match_dup 4))])]
16528 ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
16531 (define_insn "*rep_movdi_rex64"
16532 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
16533 (set (match_operand:P 0 "register_operand" "=D")
16534 (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
16536 (match_operand:P 3 "register_operand" "0")))
16537 (set (match_operand:P 1 "register_operand" "=S")
16538 (plus:P (ashift:P (match_dup 5) (const_int 3))
16539 (match_operand:P 4 "register_operand" "1")))
16540 (set (mem:BLK (match_dup 3))
16541 (mem:BLK (match_dup 4)))
16542 (use (match_dup 5))]
16544 && !(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
16545 && ix86_check_no_addr_space (insn)"
16547 [(set_attr "type" "str")
16548 (set_attr "prefix_rep" "1")
16549 (set_attr "memory" "both")
16550 (set_attr "mode" "DI")])
16552 (define_insn "*rep_movsi"
16553 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
16554 (set (match_operand:P 0 "register_operand" "=D")
16555 (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
16557 (match_operand:P 3 "register_operand" "0")))
16558 (set (match_operand:P 1 "register_operand" "=S")
16559 (plus:P (ashift:P (match_dup 5) (const_int 2))
16560 (match_operand:P 4 "register_operand" "1")))
16561 (set (mem:BLK (match_dup 3))
16562 (mem:BLK (match_dup 4)))
16563 (use (match_dup 5))]
16564 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
16565 && ix86_check_no_addr_space (insn)"
16566 "%^rep{%;} movs{l|d}"
16567 [(set_attr "type" "str")
16568 (set_attr "prefix_rep" "1")
16569 (set_attr "memory" "both")
16570 (set_attr "mode" "SI")])
16572 (define_insn "*rep_movqi"
16573 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
16574 (set (match_operand:P 0 "register_operand" "=D")
16575 (plus:P (match_operand:P 3 "register_operand" "0")
16576 (match_operand:P 5 "register_operand" "2")))
16577 (set (match_operand:P 1 "register_operand" "=S")
16578 (plus:P (match_operand:P 4 "register_operand" "1") (match_dup 5)))
16579 (set (mem:BLK (match_dup 3))
16580 (mem:BLK (match_dup 4)))
16581 (use (match_dup 5))]
16582 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
16583 && ix86_check_no_addr_space (insn)"
16585 [(set_attr "type" "str")
16586 (set_attr "prefix_rep" "1")
16587 (set_attr "memory" "both")
16588 (set_attr "mode" "QI")])
16590 (define_expand "setmem<mode>"
16591 [(use (match_operand:BLK 0 "memory_operand"))
16592 (use (match_operand:SWI48 1 "nonmemory_operand"))
16593 (use (match_operand:QI 2 "nonmemory_operand"))
16594 (use (match_operand 3 "const_int_operand"))
16595 (use (match_operand:SI 4 "const_int_operand"))
16596 (use (match_operand:SI 5 "const_int_operand"))
16597 (use (match_operand:SI 6 ""))
16598 (use (match_operand:SI 7 ""))
16599 (use (match_operand:SI 8 ""))]
16602 if (ix86_expand_set_or_movmem (operands[0], NULL,
16603 operands[1], operands[2],
16604 operands[3], operands[4],
16605 operands[5], operands[6],
16606 operands[7], operands[8], true))
16612 ;; Most CPUs don't like single string operations
16613 ;; Handle this case here to simplify previous expander.
16615 (define_expand "strset"
16616 [(set (match_operand 1 "memory_operand")
16617 (match_operand 2 "register_operand"))
16618 (parallel [(set (match_operand 0 "register_operand")
16620 (clobber (reg:CC FLAGS_REG))])]
16623 /* Can't use this for non-default address spaces. */
16624 if (!ADDR_SPACE_GENERIC_P (MEM_ADDR_SPACE (operands[1])))
16627 if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
16628 operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
16630 /* If .md ever supports :P for Pmode, this can be directly
16631 in the pattern above. */
16632 operands[3] = gen_rtx_PLUS (Pmode, operands[0],
16633 GEN_INT (GET_MODE_SIZE (GET_MODE
16635 /* Can't use this if the user has appropriated eax or edi. */
16636 if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
16637 && !(fixed_regs[AX_REG] || fixed_regs[DI_REG]))
16639 emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
16645 (define_expand "strset_singleop"
16646 [(parallel [(set (match_operand 1 "memory_operand")
16647 (match_operand 2 "register_operand"))
16648 (set (match_operand 0 "register_operand")
16650 (unspec [(const_int 0)] UNSPEC_STOS)])]
16654 ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
16657 (define_insn "*strsetdi_rex_1"
16658 [(set (mem:DI (match_operand:P 1 "register_operand" "0"))
16659 (match_operand:DI 2 "register_operand" "a"))
16660 (set (match_operand:P 0 "register_operand" "=D")
16661 (plus:P (match_dup 1)
16663 (unspec [(const_int 0)] UNSPEC_STOS)]
16665 && !(fixed_regs[AX_REG] || fixed_regs[DI_REG])
16666 && ix86_check_no_addr_space (insn)"
16668 [(set_attr "type" "str")
16669 (set_attr "memory" "store")
16670 (set_attr "mode" "DI")])
16672 (define_insn "*strsetsi_1"
16673 [(set (mem:SI (match_operand:P 1 "register_operand" "0"))
16674 (match_operand:SI 2 "register_operand" "a"))
16675 (set (match_operand:P 0 "register_operand" "=D")
16676 (plus:P (match_dup 1)
16678 (unspec [(const_int 0)] UNSPEC_STOS)]
16679 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])
16680 && ix86_check_no_addr_space (insn)"
16682 [(set_attr "type" "str")
16683 (set_attr "memory" "store")
16684 (set_attr "mode" "SI")])
16686 (define_insn "*strsethi_1"
16687 [(set (mem:HI (match_operand:P 1 "register_operand" "0"))
16688 (match_operand:HI 2 "register_operand" "a"))
16689 (set (match_operand:P 0 "register_operand" "=D")
16690 (plus:P (match_dup 1)
16692 (unspec [(const_int 0)] UNSPEC_STOS)]
16693 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])
16694 && ix86_check_no_addr_space (insn)"
16696 [(set_attr "type" "str")
16697 (set_attr "memory" "store")
16698 (set_attr "mode" "HI")])
16700 (define_insn "*strsetqi_1"
16701 [(set (mem:QI (match_operand:P 1 "register_operand" "0"))
16702 (match_operand:QI 2 "register_operand" "a"))
16703 (set (match_operand:P 0 "register_operand" "=D")
16704 (plus:P (match_dup 1)
16706 (unspec [(const_int 0)] UNSPEC_STOS)]
16707 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])
16708 && ix86_check_no_addr_space (insn)"
16710 [(set_attr "type" "str")
16711 (set_attr "memory" "store")
16712 (set (attr "prefix_rex")
16714 (match_test "<P:MODE>mode == DImode")
16716 (const_string "*")))
16717 (set_attr "mode" "QI")])
16719 (define_expand "rep_stos"
16720 [(parallel [(set (match_operand 1 "register_operand") (const_int 0))
16721 (set (match_operand 0 "register_operand")
16723 (set (match_operand 2 "memory_operand") (const_int 0))
16724 (use (match_operand 3 "register_operand"))
16725 (use (match_dup 1))])]
16729 ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
16732 (define_insn "*rep_stosdi_rex64"
16733 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
16734 (set (match_operand:P 0 "register_operand" "=D")
16735 (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
16737 (match_operand:P 3 "register_operand" "0")))
16738 (set (mem:BLK (match_dup 3))
16740 (use (match_operand:DI 2 "register_operand" "a"))
16741 (use (match_dup 4))]
16743 && !(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])
16744 && ix86_check_no_addr_space (insn)"
16746 [(set_attr "type" "str")
16747 (set_attr "prefix_rep" "1")
16748 (set_attr "memory" "store")
16749 (set_attr "mode" "DI")])
16751 (define_insn "*rep_stossi"
16752 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
16753 (set (match_operand:P 0 "register_operand" "=D")
16754 (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
16756 (match_operand:P 3 "register_operand" "0")))
16757 (set (mem:BLK (match_dup 3))
16759 (use (match_operand:SI 2 "register_operand" "a"))
16760 (use (match_dup 4))]
16761 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])
16762 && ix86_check_no_addr_space (insn)"
16763 "%^rep{%;} stos{l|d}"
16764 [(set_attr "type" "str")
16765 (set_attr "prefix_rep" "1")
16766 (set_attr "memory" "store")
16767 (set_attr "mode" "SI")])
16769 (define_insn "*rep_stosqi"
16770 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
16771 (set (match_operand:P 0 "register_operand" "=D")
16772 (plus:P (match_operand:P 3 "register_operand" "0")
16773 (match_operand:P 4 "register_operand" "1")))
16774 (set (mem:BLK (match_dup 3))
16776 (use (match_operand:QI 2 "register_operand" "a"))
16777 (use (match_dup 4))]
16778 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])
16779 && ix86_check_no_addr_space (insn)"
16781 [(set_attr "type" "str")
16782 (set_attr "prefix_rep" "1")
16783 (set_attr "memory" "store")
16784 (set (attr "prefix_rex")
16786 (match_test "<P:MODE>mode == DImode")
16788 (const_string "*")))
16789 (set_attr "mode" "QI")])
16791 (define_expand "cmpstrnsi"
16792 [(set (match_operand:SI 0 "register_operand")
16793 (compare:SI (match_operand:BLK 1 "general_operand")
16794 (match_operand:BLK 2 "general_operand")))
16795 (use (match_operand 3 "general_operand"))
16796 (use (match_operand 4 "immediate_operand"))]
16799 rtx addr1, addr2, out, outlow, count, countreg, align;
16801 if (optimize_insn_for_size_p () && !TARGET_INLINE_ALL_STRINGOPS)
16804 /* Can't use this if the user has appropriated ecx, esi or edi. */
16805 if (fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
16808 /* One of the strings must be a constant. If so, expand_builtin_strncmp()
16809 will have rewritten the length arg to be the minimum of the const string
16810 length and the actual length arg. If both strings are the same and
16811 shorter than the length arg, repz cmpsb will not stop at the 0 byte and
16812 will incorrectly base the results on chars past the 0 byte. */
16813 tree t1 = MEM_EXPR (operands[1]);
16814 tree t2 = MEM_EXPR (operands[2]);
16815 if (!((t1 && TREE_CODE (t1) == MEM_REF
16816 && TREE_CODE (TREE_OPERAND (t1, 0)) == ADDR_EXPR
16817 && TREE_CODE (TREE_OPERAND (TREE_OPERAND (t1, 0), 0)) == STRING_CST)
16818 || (t2 && TREE_CODE (t2) == MEM_REF
16819 && TREE_CODE (TREE_OPERAND (t2, 0)) == ADDR_EXPR
16820 && TREE_CODE (TREE_OPERAND (TREE_OPERAND (t2, 0), 0)) == STRING_CST)))
16825 out = gen_reg_rtx (SImode);
16827 addr1 = copy_addr_to_reg (XEXP (operands[1], 0));
16828 addr2 = copy_addr_to_reg (XEXP (operands[2], 0));
16829 if (addr1 != XEXP (operands[1], 0))
16830 operands[1] = replace_equiv_address_nv (operands[1], addr1);
16831 if (addr2 != XEXP (operands[2], 0))
16832 operands[2] = replace_equiv_address_nv (operands[2], addr2);
16834 count = operands[3];
16835 countreg = ix86_zero_extend_to_Pmode (count);
16837 /* %%% Iff we are testing strict equality, we can use known alignment
16838 to good advantage. This may be possible with combine, particularly
16839 once cc0 is dead. */
16840 align = operands[4];
16842 if (CONST_INT_P (count))
16844 if (INTVAL (count) == 0)
16846 emit_move_insn (operands[0], const0_rtx);
16849 emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
16850 operands[1], operands[2]));
16854 rtx (*gen_cmp) (rtx, rtx);
16856 gen_cmp = (TARGET_64BIT
16857 ? gen_cmpdi_1 : gen_cmpsi_1);
16859 emit_insn (gen_cmp (countreg, countreg));
16860 emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
16861 operands[1], operands[2]));
16864 outlow = gen_lowpart (QImode, out);
16865 emit_insn (gen_cmpintqi (outlow));
16866 emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
16868 if (operands[0] != out)
16869 emit_move_insn (operands[0], out);
16874 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
16876 (define_expand "cmpintqi"
16877 [(set (match_dup 1)
16878 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16880 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16881 (parallel [(set (match_operand:QI 0 "register_operand")
16882 (minus:QI (match_dup 1)
16884 (clobber (reg:CC FLAGS_REG))])]
16887 operands[1] = gen_reg_rtx (QImode);
16888 operands[2] = gen_reg_rtx (QImode);
16891 ;; memcmp recognizers. The `cmpsb' opcode does nothing if the count is
16892 ;; zero. Emit extra code to make sure that a zero-length compare is EQ.
16894 (define_expand "cmpstrnqi_nz_1"
16895 [(parallel [(set (reg:CC FLAGS_REG)
16896 (compare:CC (match_operand 4 "memory_operand")
16897 (match_operand 5 "memory_operand")))
16898 (use (match_operand 2 "register_operand"))
16899 (use (match_operand:SI 3 "immediate_operand"))
16900 (clobber (match_operand 0 "register_operand"))
16901 (clobber (match_operand 1 "register_operand"))
16902 (clobber (match_dup 2))])]
16906 ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
16909 (define_insn "*cmpstrnqi_nz_1"
16910 [(set (reg:CC FLAGS_REG)
16911 (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
16912 (mem:BLK (match_operand:P 5 "register_operand" "1"))))
16913 (use (match_operand:P 6 "register_operand" "2"))
16914 (use (match_operand:SI 3 "immediate_operand" "i"))
16915 (clobber (match_operand:P 0 "register_operand" "=S"))
16916 (clobber (match_operand:P 1 "register_operand" "=D"))
16917 (clobber (match_operand:P 2 "register_operand" "=c"))]
16918 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
16919 && ix86_check_no_addr_space (insn)"
16921 [(set_attr "type" "str")
16922 (set_attr "mode" "QI")
16923 (set (attr "prefix_rex")
16925 (match_test "<P:MODE>mode == DImode")
16927 (const_string "*")))
16928 (set_attr "prefix_rep" "1")])
16930 ;; The same, but the count is not known to not be zero.
16932 (define_expand "cmpstrnqi_1"
16933 [(parallel [(set (reg:CC FLAGS_REG)
16934 (if_then_else:CC (ne (match_operand 2 "register_operand")
16936 (compare:CC (match_operand 4 "memory_operand")
16937 (match_operand 5 "memory_operand"))
16939 (use (match_operand:SI 3 "immediate_operand"))
16940 (use (reg:CC FLAGS_REG))
16941 (clobber (match_operand 0 "register_operand"))
16942 (clobber (match_operand 1 "register_operand"))
16943 (clobber (match_dup 2))])]
16947 ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
16950 (define_insn "*cmpstrnqi_1"
16951 [(set (reg:CC FLAGS_REG)
16952 (if_then_else:CC (ne (match_operand:P 6 "register_operand" "2")
16954 (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
16955 (mem:BLK (match_operand:P 5 "register_operand" "1")))
16957 (use (match_operand:SI 3 "immediate_operand" "i"))
16958 (use (reg:CC FLAGS_REG))
16959 (clobber (match_operand:P 0 "register_operand" "=S"))
16960 (clobber (match_operand:P 1 "register_operand" "=D"))
16961 (clobber (match_operand:P 2 "register_operand" "=c"))]
16962 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
16963 && ix86_check_no_addr_space (insn)"
16965 [(set_attr "type" "str")
16966 (set_attr "mode" "QI")
16967 (set (attr "prefix_rex")
16969 (match_test "<P:MODE>mode == DImode")
16971 (const_string "*")))
16972 (set_attr "prefix_rep" "1")])
16974 (define_expand "strlen<mode>"
16975 [(set (match_operand:P 0 "register_operand")
16976 (unspec:P [(match_operand:BLK 1 "general_operand")
16977 (match_operand:QI 2 "immediate_operand")
16978 (match_operand 3 "immediate_operand")]
16982 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
16988 (define_expand "strlenqi_1"
16989 [(parallel [(set (match_operand 0 "register_operand")
16991 (clobber (match_operand 1 "register_operand"))
16992 (clobber (reg:CC FLAGS_REG))])]
16996 ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
16999 (define_insn "*strlenqi_1"
17000 [(set (match_operand:P 0 "register_operand" "=&c")
17001 (unspec:P [(mem:BLK (match_operand:P 5 "register_operand" "1"))
17002 (match_operand:QI 2 "register_operand" "a")
17003 (match_operand:P 3 "immediate_operand" "i")
17004 (match_operand:P 4 "register_operand" "0")] UNSPEC_SCAS))
17005 (clobber (match_operand:P 1 "register_operand" "=D"))
17006 (clobber (reg:CC FLAGS_REG))]
17007 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])
17008 && ix86_check_no_addr_space (insn)"
17009 "%^repnz{%;} scasb"
17010 [(set_attr "type" "str")
17011 (set_attr "mode" "QI")
17012 (set (attr "prefix_rex")
17014 (match_test "<P:MODE>mode == DImode")
17016 (const_string "*")))
17017 (set_attr "prefix_rep" "1")])
17019 ;; Peephole optimizations to clean up after cmpstrn*. This should be
17020 ;; handled in combine, but it is not currently up to the task.
17021 ;; When used for their truth value, the cmpstrn* expanders generate
17030 ;; The intermediate three instructions are unnecessary.
17032 ;; This one handles cmpstrn*_nz_1...
17035 (set (reg:CC FLAGS_REG)
17036 (compare:CC (mem:BLK (match_operand 4 "register_operand"))
17037 (mem:BLK (match_operand 5 "register_operand"))))
17038 (use (match_operand 6 "register_operand"))
17039 (use (match_operand:SI 3 "immediate_operand"))
17040 (clobber (match_operand 0 "register_operand"))
17041 (clobber (match_operand 1 "register_operand"))
17042 (clobber (match_operand 2 "register_operand"))])
17043 (set (match_operand:QI 7 "register_operand")
17044 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
17045 (set (match_operand:QI 8 "register_operand")
17046 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
17047 (set (reg FLAGS_REG)
17048 (compare (match_dup 7) (match_dup 8)))
17050 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
17052 (set (reg:CC FLAGS_REG)
17053 (compare:CC (mem:BLK (match_dup 4))
17054 (mem:BLK (match_dup 5))))
17055 (use (match_dup 6))
17056 (use (match_dup 3))
17057 (clobber (match_dup 0))
17058 (clobber (match_dup 1))
17059 (clobber (match_dup 2))])])
17061 ;; ...and this one handles cmpstrn*_1.
17064 (set (reg:CC FLAGS_REG)
17065 (if_then_else:CC (ne (match_operand 6 "register_operand")
17067 (compare:CC (mem:BLK (match_operand 4 "register_operand"))
17068 (mem:BLK (match_operand 5 "register_operand")))
17070 (use (match_operand:SI 3 "immediate_operand"))
17071 (use (reg:CC FLAGS_REG))
17072 (clobber (match_operand 0 "register_operand"))
17073 (clobber (match_operand 1 "register_operand"))
17074 (clobber (match_operand 2 "register_operand"))])
17075 (set (match_operand:QI 7 "register_operand")
17076 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
17077 (set (match_operand:QI 8 "register_operand")
17078 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
17079 (set (reg FLAGS_REG)
17080 (compare (match_dup 7) (match_dup 8)))
17082 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
17084 (set (reg:CC FLAGS_REG)
17085 (if_then_else:CC (ne (match_dup 6)
17087 (compare:CC (mem:BLK (match_dup 4))
17088 (mem:BLK (match_dup 5)))
17090 (use (match_dup 3))
17091 (use (reg:CC FLAGS_REG))
17092 (clobber (match_dup 0))
17093 (clobber (match_dup 1))
17094 (clobber (match_dup 2))])])
17096 ;; Conditional move instructions.
17098 (define_expand "mov<mode>cc"
17099 [(set (match_operand:SWIM 0 "register_operand")
17100 (if_then_else:SWIM (match_operand 1 "comparison_operator")
17101 (match_operand:SWIM 2 "<general_operand>")
17102 (match_operand:SWIM 3 "<general_operand>")))]
17104 "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
17106 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
17107 ;; the register first winds up with `sbbl $0,reg', which is also weird.
17108 ;; So just document what we're doing explicitly.
17110 (define_expand "x86_mov<mode>cc_0_m1"
17112 [(set (match_operand:SWI48 0 "register_operand")
17113 (if_then_else:SWI48
17114 (match_operator:SWI48 2 "ix86_carry_flag_operator"
17115 [(match_operand 1 "flags_reg_operand")
17119 (clobber (reg:CC FLAGS_REG))])])
17121 (define_insn "*x86_mov<mode>cc_0_m1"
17122 [(set (match_operand:SWI48 0 "register_operand" "=r")
17123 (if_then_else:SWI48 (match_operator 1 "ix86_carry_flag_operator"
17124 [(reg FLAGS_REG) (const_int 0)])
17127 (clobber (reg:CC FLAGS_REG))]
17129 "sbb{<imodesuffix>}\t%0, %0"
17130 [(set_attr "type" "alu1")
17131 (set_attr "use_carry" "1")
17132 (set_attr "pent_pair" "pu")
17133 (set_attr "mode" "<MODE>")
17134 (set_attr "length_immediate" "0")])
17136 (define_insn "*x86_mov<mode>cc_0_m1_se"
17137 [(set (match_operand:SWI48 0 "register_operand" "=r")
17138 (sign_extract:SWI48 (match_operator 1 "ix86_carry_flag_operator"
17139 [(reg FLAGS_REG) (const_int 0)])
17142 (clobber (reg:CC FLAGS_REG))]
17144 "sbb{<imodesuffix>}\t%0, %0"
17145 [(set_attr "type" "alu1")
17146 (set_attr "use_carry" "1")
17147 (set_attr "pent_pair" "pu")
17148 (set_attr "mode" "<MODE>")
17149 (set_attr "length_immediate" "0")])
17151 (define_insn "*x86_mov<mode>cc_0_m1_neg"
17152 [(set (match_operand:SWI48 0 "register_operand" "=r")
17153 (neg:SWI48 (match_operator 1 "ix86_carry_flag_operator"
17154 [(reg FLAGS_REG) (const_int 0)])))
17155 (clobber (reg:CC FLAGS_REG))]
17157 "sbb{<imodesuffix>}\t%0, %0"
17158 [(set_attr "type" "alu1")
17159 (set_attr "use_carry" "1")
17160 (set_attr "pent_pair" "pu")
17161 (set_attr "mode" "<MODE>")
17162 (set_attr "length_immediate" "0")])
17164 (define_insn "*mov<mode>cc_noc"
17165 [(set (match_operand:SWI248 0 "register_operand" "=r,r")
17166 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
17167 [(reg FLAGS_REG) (const_int 0)])
17168 (match_operand:SWI248 2 "nonimmediate_operand" "rm,0")
17169 (match_operand:SWI248 3 "nonimmediate_operand" "0,rm")))]
17170 "TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
17172 cmov%O2%C1\t{%2, %0|%0, %2}
17173 cmov%O2%c1\t{%3, %0|%0, %3}"
17174 [(set_attr "type" "icmov")
17175 (set_attr "mode" "<MODE>")])
17177 (define_insn "*movsicc_noc_zext"
17178 [(set (match_operand:DI 0 "register_operand" "=r,r")
17179 (if_then_else:DI (match_operator 1 "ix86_comparison_operator"
17180 [(reg FLAGS_REG) (const_int 0)])
17182 (match_operand:SI 2 "nonimmediate_operand" "rm,0"))
17184 (match_operand:SI 3 "nonimmediate_operand" "0,rm"))))]
17186 && TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
17188 cmov%O2%C1\t{%2, %k0|%k0, %2}
17189 cmov%O2%c1\t{%3, %k0|%k0, %3}"
17190 [(set_attr "type" "icmov")
17191 (set_attr "mode" "SI")])
17193 ;; Don't do conditional moves with memory inputs. This splitter helps
17194 ;; register starved x86_32 by forcing inputs into registers before reload.
17196 [(set (match_operand:SWI248 0 "register_operand")
17197 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
17198 [(reg FLAGS_REG) (const_int 0)])
17199 (match_operand:SWI248 2 "nonimmediate_operand")
17200 (match_operand:SWI248 3 "nonimmediate_operand")))]
17201 "!TARGET_64BIT && TARGET_CMOVE
17202 && TARGET_AVOID_MEM_OPND_FOR_CMOVE
17203 && (MEM_P (operands[2]) || MEM_P (operands[3]))
17204 && can_create_pseudo_p ()
17205 && optimize_insn_for_speed_p ()"
17206 [(set (match_dup 0)
17207 (if_then_else:SWI248 (match_dup 1) (match_dup 2) (match_dup 3)))]
17209 if (MEM_P (operands[2]))
17210 operands[2] = force_reg (<MODE>mode, operands[2]);
17211 if (MEM_P (operands[3]))
17212 operands[3] = force_reg (<MODE>mode, operands[3]);
17215 (define_insn "*movqicc_noc"
17216 [(set (match_operand:QI 0 "register_operand" "=r,r")
17217 (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
17218 [(reg FLAGS_REG) (const_int 0)])
17219 (match_operand:QI 2 "register_operand" "r,0")
17220 (match_operand:QI 3 "register_operand" "0,r")))]
17221 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
17223 [(set_attr "type" "icmov")
17224 (set_attr "mode" "QI")])
17227 [(set (match_operand:SWI12 0 "register_operand")
17228 (if_then_else:SWI12 (match_operator 1 "ix86_comparison_operator"
17229 [(reg FLAGS_REG) (const_int 0)])
17230 (match_operand:SWI12 2 "register_operand")
17231 (match_operand:SWI12 3 "register_operand")))]
17232 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL
17233 && reload_completed"
17234 [(set (match_dup 0)
17235 (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
17237 operands[0] = gen_lowpart (SImode, operands[0]);
17238 operands[2] = gen_lowpart (SImode, operands[2]);
17239 operands[3] = gen_lowpart (SImode, operands[3]);
17242 ;; Don't do conditional moves with memory inputs
17244 [(match_scratch:SWI248 4 "r")
17245 (set (match_operand:SWI248 0 "register_operand")
17246 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
17247 [(reg FLAGS_REG) (const_int 0)])
17248 (match_operand:SWI248 2 "nonimmediate_operand")
17249 (match_operand:SWI248 3 "nonimmediate_operand")))]
17250 "TARGET_CMOVE && TARGET_AVOID_MEM_OPND_FOR_CMOVE
17251 && (MEM_P (operands[2]) || MEM_P (operands[3]))
17252 && optimize_insn_for_speed_p ()"
17253 [(set (match_dup 4) (match_dup 5))
17255 (if_then_else:SWI248 (match_dup 1) (match_dup 2) (match_dup 3)))]
17257 if (MEM_P (operands[2]))
17259 operands[5] = operands[2];
17260 operands[2] = operands[4];
17262 else if (MEM_P (operands[3]))
17264 operands[5] = operands[3];
17265 operands[3] = operands[4];
17268 gcc_unreachable ();
17272 [(match_scratch:SI 4 "r")
17273 (set (match_operand:DI 0 "register_operand")
17274 (if_then_else:DI (match_operator 1 "ix86_comparison_operator"
17275 [(reg FLAGS_REG) (const_int 0)])
17277 (match_operand:SI 2 "nonimmediate_operand"))
17279 (match_operand:SI 3 "nonimmediate_operand"))))]
17281 && TARGET_CMOVE && TARGET_AVOID_MEM_OPND_FOR_CMOVE
17282 && (MEM_P (operands[2]) || MEM_P (operands[3]))
17283 && optimize_insn_for_speed_p ()"
17284 [(set (match_dup 4) (match_dup 5))
17286 (if_then_else:DI (match_dup 1)
17287 (zero_extend:DI (match_dup 2))
17288 (zero_extend:DI (match_dup 3))))]
17290 if (MEM_P (operands[2]))
17292 operands[5] = operands[2];
17293 operands[2] = operands[4];
17295 else if (MEM_P (operands[3]))
17297 operands[5] = operands[3];
17298 operands[3] = operands[4];
17301 gcc_unreachable ();
17304 (define_expand "mov<mode>cc"
17305 [(set (match_operand:X87MODEF 0 "register_operand")
17306 (if_then_else:X87MODEF
17307 (match_operand 1 "comparison_operator")
17308 (match_operand:X87MODEF 2 "register_operand")
17309 (match_operand:X87MODEF 3 "register_operand")))]
17310 "(TARGET_80387 && TARGET_CMOVE)
17311 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
17312 "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
17314 (define_insn "*movxfcc_1"
17315 [(set (match_operand:XF 0 "register_operand" "=f,f")
17316 (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
17317 [(reg FLAGS_REG) (const_int 0)])
17318 (match_operand:XF 2 "register_operand" "f,0")
17319 (match_operand:XF 3 "register_operand" "0,f")))]
17320 "TARGET_80387 && TARGET_CMOVE"
17322 fcmov%F1\t{%2, %0|%0, %2}
17323 fcmov%f1\t{%3, %0|%0, %3}"
17324 [(set_attr "type" "fcmov")
17325 (set_attr "mode" "XF")])
17327 (define_insn "*movdfcc_1"
17328 [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r,r ,r")
17329 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
17330 [(reg FLAGS_REG) (const_int 0)])
17331 (match_operand:DF 2 "nonimmediate_operand"
17333 (match_operand:DF 3 "nonimmediate_operand"
17334 "0 ,f,0 ,rm,0, rm")))]
17335 "TARGET_80387 && TARGET_CMOVE
17336 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
17338 fcmov%F1\t{%2, %0|%0, %2}
17339 fcmov%f1\t{%3, %0|%0, %3}
17342 cmov%O2%C1\t{%2, %0|%0, %2}
17343 cmov%O2%c1\t{%3, %0|%0, %3}"
17344 [(set_attr "isa" "*,*,nox64,nox64,x64,x64")
17345 (set_attr "type" "fcmov,fcmov,multi,multi,icmov,icmov")
17346 (set_attr "mode" "DF,DF,DI,DI,DI,DI")])
17349 [(set (match_operand:DF 0 "general_reg_operand")
17350 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
17351 [(reg FLAGS_REG) (const_int 0)])
17352 (match_operand:DF 2 "nonimmediate_operand")
17353 (match_operand:DF 3 "nonimmediate_operand")))]
17354 "!TARGET_64BIT && reload_completed"
17355 [(set (match_dup 2)
17356 (if_then_else:SI (match_dup 1) (match_dup 4) (match_dup 5)))
17358 (if_then_else:SI (match_dup 1) (match_dup 6) (match_dup 7)))]
17360 split_double_mode (DImode, &operands[2], 2, &operands[4], &operands[6]);
17361 split_double_mode (DImode, &operands[0], 1, &operands[2], &operands[3]);
17364 (define_insn "*movsfcc_1_387"
17365 [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
17366 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
17367 [(reg FLAGS_REG) (const_int 0)])
17368 (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
17369 (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
17370 "TARGET_80387 && TARGET_CMOVE
17371 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
17373 fcmov%F1\t{%2, %0|%0, %2}
17374 fcmov%f1\t{%3, %0|%0, %3}
17375 cmov%O2%C1\t{%2, %0|%0, %2}
17376 cmov%O2%c1\t{%3, %0|%0, %3}"
17377 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
17378 (set_attr "mode" "SF,SF,SI,SI")])
17380 ;; Don't do conditional moves with memory inputs. This splitter helps
17381 ;; register starved x86_32 by forcing inputs into registers before reload.
17383 [(set (match_operand:MODEF 0 "register_operand")
17384 (if_then_else:MODEF (match_operator 1 "ix86_comparison_operator"
17385 [(reg FLAGS_REG) (const_int 0)])
17386 (match_operand:MODEF 2 "nonimmediate_operand")
17387 (match_operand:MODEF 3 "nonimmediate_operand")))]
17388 "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
17389 && TARGET_AVOID_MEM_OPND_FOR_CMOVE
17390 && (MEM_P (operands[2]) || MEM_P (operands[3]))
17391 && can_create_pseudo_p ()
17392 && optimize_insn_for_speed_p ()"
17393 [(set (match_dup 0)
17394 (if_then_else:MODEF (match_dup 1) (match_dup 2) (match_dup 3)))]
17396 if (MEM_P (operands[2]))
17397 operands[2] = force_reg (<MODE>mode, operands[2]);
17398 if (MEM_P (operands[3]))
17399 operands[3] = force_reg (<MODE>mode, operands[3]);
17402 ;; Don't do conditional moves with memory inputs
17404 [(match_scratch:MODEF 4 "r")
17405 (set (match_operand:MODEF 0 "general_reg_operand")
17406 (if_then_else:MODEF (match_operator 1 "fcmov_comparison_operator"
17407 [(reg FLAGS_REG) (const_int 0)])
17408 (match_operand:MODEF 2 "nonimmediate_operand")
17409 (match_operand:MODEF 3 "nonimmediate_operand")))]
17410 "(<MODE>mode != DFmode || TARGET_64BIT)
17411 && TARGET_80387 && TARGET_CMOVE
17412 && TARGET_AVOID_MEM_OPND_FOR_CMOVE
17413 && (MEM_P (operands[2]) || MEM_P (operands[3]))
17414 && optimize_insn_for_speed_p ()"
17415 [(set (match_dup 4) (match_dup 5))
17417 (if_then_else:MODEF (match_dup 1) (match_dup 2) (match_dup 3)))]
17419 if (MEM_P (operands[2]))
17421 operands[5] = operands[2];
17422 operands[2] = operands[4];
17424 else if (MEM_P (operands[3]))
17426 operands[5] = operands[3];
17427 operands[3] = operands[4];
17430 gcc_unreachable ();
17433 ;; All moves in XOP pcmov instructions are 128 bits and hence we restrict
17434 ;; the scalar versions to have only XMM registers as operands.
17436 ;; XOP conditional move
17437 (define_insn "*xop_pcmov_<mode>"
17438 [(set (match_operand:MODEF 0 "register_operand" "=x")
17439 (if_then_else:MODEF
17440 (match_operand:MODEF 1 "register_operand" "x")
17441 (match_operand:MODEF 2 "register_operand" "x")
17442 (match_operand:MODEF 3 "register_operand" "x")))]
17444 "vpcmov\t{%1, %3, %2, %0|%0, %2, %3, %1}"
17445 [(set_attr "type" "sse4arg")])
17447 ;; These versions of the min/max patterns are intentionally ignorant of
17448 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
17449 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
17450 ;; are undefined in this condition, we're certain this is correct.
17452 (define_insn "<code><mode>3"
17453 [(set (match_operand:MODEF 0 "register_operand" "=x,v")
17455 (match_operand:MODEF 1 "nonimmediate_operand" "%0,v")
17456 (match_operand:MODEF 2 "nonimmediate_operand" "xm,vm")))]
17457 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
17459 <maxmin_float><ssemodesuffix>\t{%2, %0|%0, %2}
17460 v<maxmin_float><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
17461 [(set_attr "isa" "noavx,avx")
17462 (set_attr "prefix" "orig,vex")
17463 (set_attr "type" "sseadd")
17464 (set_attr "mode" "<MODE>")])
17466 ;; These versions of the min/max patterns implement exactly the operations
17467 ;; min = (op1 < op2 ? op1 : op2)
17468 ;; max = (!(op1 < op2) ? op1 : op2)
17469 ;; Their operands are not commutative, and thus they may be used in the
17470 ;; presence of -0.0 and NaN.
17472 (define_insn "*ieee_s<ieee_maxmin><mode>3"
17473 [(set (match_operand:MODEF 0 "register_operand" "=x,v")
17475 [(match_operand:MODEF 1 "register_operand" "0,v")
17476 (match_operand:MODEF 2 "nonimmediate_operand" "xm,vm")]
17478 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
17480 <ieee_maxmin><ssemodesuffix>\t{%2, %0|%0, %2}
17481 v<ieee_maxmin><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
17482 [(set_attr "isa" "noavx,avx")
17483 (set_attr "prefix" "orig,maybe_evex")
17484 (set_attr "type" "sseadd")
17485 (set_attr "mode" "<MODE>")])
17487 ;; Make two stack loads independent:
17489 ;; fld %st(0) -> fld bb
17490 ;; fmul bb fmul %st(1), %st
17492 ;; Actually we only match the last two instructions for simplicity.
17495 [(set (match_operand 0 "fp_register_operand")
17496 (match_operand 1 "fp_register_operand"))
17498 (match_operator 2 "binary_fp_operator"
17500 (match_operand 3 "memory_operand")]))]
17501 "REGNO (operands[0]) != REGNO (operands[1])"
17502 [(set (match_dup 0) (match_dup 3))
17505 [(match_dup 5) (match_dup 4)]))]
17507 operands[4] = operands[0];
17508 operands[5] = operands[1];
17510 /* The % modifier is not operational anymore in peephole2's, so we have to
17511 swap the operands manually in the case of addition and multiplication. */
17512 if (COMMUTATIVE_ARITH_P (operands[2]))
17513 std::swap (operands[4], operands[5]);
17517 [(set (match_operand 0 "fp_register_operand")
17518 (match_operand 1 "fp_register_operand"))
17520 (match_operator 2 "binary_fp_operator"
17521 [(match_operand 3 "memory_operand")
17523 "REGNO (operands[0]) != REGNO (operands[1])"
17524 [(set (match_dup 0) (match_dup 3))
17527 [(match_dup 4) (match_dup 5)]))]
17529 operands[4] = operands[0];
17530 operands[5] = operands[1];
17532 /* The % modifier is not operational anymore in peephole2's, so we have to
17533 swap the operands manually in the case of addition and multiplication. */
17534 if (COMMUTATIVE_ARITH_P (operands[2]))
17535 std::swap (operands[4], operands[5]);
17538 ;; Conditional addition patterns
17539 (define_expand "add<mode>cc"
17540 [(match_operand:SWI 0 "register_operand")
17541 (match_operand 1 "ordered_comparison_operator")
17542 (match_operand:SWI 2 "register_operand")
17543 (match_operand:SWI 3 "const_int_operand")]
17545 "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
17547 ;; Misc patterns (?)
17549 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
17550 ;; Otherwise there will be nothing to keep
17552 ;; [(set (reg ebp) (reg esp))]
17553 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
17554 ;; (clobber (eflags)]
17555 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
17557 ;; in proper program order.
17559 (define_insn "pro_epilogue_adjust_stack_<mode>_add"
17560 [(set (match_operand:P 0 "register_operand" "=r,r")
17561 (plus:P (match_operand:P 1 "register_operand" "0,r")
17562 (match_operand:P 2 "<nonmemory_operand>" "r<i>,l<i>")))
17563 (clobber (reg:CC FLAGS_REG))
17564 (clobber (mem:BLK (scratch)))]
17567 switch (get_attr_type (insn))
17570 return "mov{<imodesuffix>}\t{%1, %0|%0, %1}";
17573 gcc_assert (rtx_equal_p (operands[0], operands[1]));
17574 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
17575 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
17577 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
17580 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
17581 return "lea{<imodesuffix>}\t{%E2, %0|%0, %E2}";
17584 [(set (attr "type")
17585 (cond [(and (eq_attr "alternative" "0")
17586 (not (match_test "TARGET_OPT_AGU")))
17587 (const_string "alu")
17588 (match_operand:<MODE> 2 "const0_operand")
17589 (const_string "imov")
17591 (const_string "lea")))
17592 (set (attr "length_immediate")
17593 (cond [(eq_attr "type" "imov")
17595 (and (eq_attr "type" "alu")
17596 (match_operand 2 "const128_operand"))
17599 (const_string "*")))
17600 (set_attr "mode" "<MODE>")])
17602 (define_insn "pro_epilogue_adjust_stack_<mode>_sub"
17603 [(set (match_operand:P 0 "register_operand" "=r")
17604 (minus:P (match_operand:P 1 "register_operand" "0")
17605 (match_operand:P 2 "register_operand" "r")))
17606 (clobber (reg:CC FLAGS_REG))
17607 (clobber (mem:BLK (scratch)))]
17609 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
17610 [(set_attr "type" "alu")
17611 (set_attr "mode" "<MODE>")])
17613 (define_insn "allocate_stack_worker_probe_<mode>"
17614 [(set (match_operand:P 0 "register_operand" "=a")
17615 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
17616 UNSPECV_STACK_PROBE))
17617 (clobber (reg:CC FLAGS_REG))]
17618 "ix86_target_stack_probe ()"
17619 "call\t___chkstk_ms"
17620 [(set_attr "type" "multi")
17621 (set_attr "length" "5")])
17623 (define_expand "allocate_stack"
17624 [(match_operand 0 "register_operand")
17625 (match_operand 1 "general_operand")]
17626 "ix86_target_stack_probe ()"
17630 #ifndef CHECK_STACK_LIMIT
17631 #define CHECK_STACK_LIMIT 0
17634 if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
17635 && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
17639 rtx (*insn) (rtx, rtx);
17641 x = copy_to_mode_reg (Pmode, operands[1]);
17643 insn = (TARGET_64BIT
17644 ? gen_allocate_stack_worker_probe_di
17645 : gen_allocate_stack_worker_probe_si);
17647 emit_insn (insn (x, x));
17650 x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, x,
17651 stack_pointer_rtx, 0, OPTAB_DIRECT);
17653 if (x != stack_pointer_rtx)
17654 emit_move_insn (stack_pointer_rtx, x);
17656 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
17660 (define_expand "probe_stack"
17661 [(match_operand 0 "memory_operand")]
17664 rtx (*insn) (rtx, rtx)
17665 = (GET_MODE (operands[0]) == DImode
17666 ? gen_probe_stack_di : gen_probe_stack_si);
17668 emit_insn (insn (operands[0], const0_rtx));
17672 ;; Use OR for stack probes, this is shorter.
17673 (define_insn "probe_stack_<mode>"
17674 [(set (match_operand:W 0 "memory_operand" "=m")
17675 (unspec:W [(match_operand:W 1 "const0_operand")]
17676 UNSPEC_PROBE_STACK))
17677 (clobber (reg:CC FLAGS_REG))]
17679 "or{<imodesuffix>}\t{%1, %0|%0, %1}"
17680 [(set_attr "type" "alu1")
17681 (set_attr "mode" "<MODE>")
17682 (set_attr "length_immediate" "1")])
17684 (define_insn "adjust_stack_and_probe<mode>"
17685 [(set (match_operand:P 0 "register_operand" "=r")
17686 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
17687 UNSPECV_PROBE_STACK_RANGE))
17688 (set (reg:P SP_REG)
17689 (minus:P (reg:P SP_REG) (match_operand:P 2 "const_int_operand" "n")))
17690 (clobber (reg:CC FLAGS_REG))
17691 (clobber (mem:BLK (scratch)))]
17693 "* return output_adjust_stack_and_probe (operands[0]);"
17694 [(set_attr "type" "multi")])
17696 (define_insn "probe_stack_range<mode>"
17697 [(set (match_operand:P 0 "register_operand" "=r")
17698 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
17699 (match_operand:P 2 "const_int_operand" "n")]
17700 UNSPECV_PROBE_STACK_RANGE))
17701 (clobber (reg:CC FLAGS_REG))]
17703 "* return output_probe_stack_range (operands[0], operands[2]);"
17704 [(set_attr "type" "multi")])
17706 (define_expand "builtin_setjmp_receiver"
17707 [(label_ref (match_operand 0))]
17708 "!TARGET_64BIT && flag_pic"
17714 rtx_code_label *label_rtx = gen_label_rtx ();
17715 emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
17716 xops[0] = xops[1] = pic_offset_table_rtx;
17717 xops[2] = machopic_gen_offset (gen_rtx_LABEL_REF (SImode, label_rtx));
17718 ix86_expand_binary_operator (MINUS, SImode, xops);
17722 emit_insn (gen_set_got (pic_offset_table_rtx));
17726 (define_expand "save_stack_nonlocal"
17727 [(set (match_operand 0 "memory_operand")
17728 (match_operand 1 "register_operand"))]
17732 if ((flag_cf_protection & CF_RETURN))
17734 /* Copy shadow stack pointer to the first slot and stack ppointer
17735 to the second slot. */
17736 rtx ssp_slot = adjust_address (operands[0], word_mode, 0);
17737 stack_slot = adjust_address (operands[0], Pmode, UNITS_PER_WORD);
17738 rtx ssp = gen_reg_rtx (word_mode);
17739 emit_insn ((word_mode == SImode)
17740 ? gen_rdsspsi (ssp)
17741 : gen_rdsspdi (ssp));
17742 emit_move_insn (ssp_slot, ssp);
17745 stack_slot = adjust_address (operands[0], Pmode, 0);
17746 emit_move_insn (stack_slot, operands[1]);
17750 (define_expand "restore_stack_nonlocal"
17751 [(set (match_operand 0 "register_operand" "")
17752 (match_operand 1 "memory_operand" ""))]
17756 if ((flag_cf_protection & CF_RETURN))
17758 /* Restore shadow stack pointer from the first slot and stack
17759 pointer from the second slot. */
17760 rtx ssp_slot = adjust_address (operands[1], word_mode, 0);
17761 stack_slot = adjust_address (operands[1], Pmode, UNITS_PER_WORD);
17763 rtx flags, jump, noadj_label, inc_label, loop_label;
17764 rtx reg_adj, reg_ssp, tmp, clob;
17766 /* Get the current shadow stack pointer. The code below will check if
17767 SHSTK feature is enabled. If it is not enabled the RDSSP instruction
17769 reg_ssp = gen_reg_rtx (word_mode);
17770 emit_insn (gen_rtx_SET (reg_ssp, const0_rtx));
17771 emit_insn ((word_mode == SImode)
17772 ? gen_rdsspsi (reg_ssp)
17773 : gen_rdsspdi (reg_ssp));
17775 /* Compare through substraction the saved and the current ssp to decide
17776 if ssp has to be adjusted. */
17777 tmp = gen_rtx_SET (reg_ssp, gen_rtx_MINUS (word_mode, reg_ssp,
17779 clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
17780 tmp = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, tmp, clob));
17783 /* Compare and jump over adjustment code. */
17784 noadj_label = gen_label_rtx ();
17785 flags = gen_rtx_REG (CCZmode, FLAGS_REG);
17786 tmp = gen_rtx_EQ (VOIDmode, flags, const0_rtx);
17787 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
17788 gen_rtx_LABEL_REF (VOIDmode, noadj_label),
17790 jump = emit_jump_insn (gen_rtx_SET (pc_rtx, tmp));
17791 JUMP_LABEL (jump) = noadj_label;
17793 /* Compute the numebr of frames to adjust. */
17794 reg_adj = gen_lowpart (ptr_mode, reg_ssp);
17795 tmp = gen_rtx_SET (reg_adj,
17796 gen_rtx_LSHIFTRT (ptr_mode,
17797 negate_rtx (ptr_mode, reg_adj),
17798 GEN_INT ((word_mode == SImode)
17801 clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
17802 tmp = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, tmp, clob));
17805 /* Check if number of frames <= 255 so no loop is needed. */
17806 tmp = gen_rtx_COMPARE (CCmode, reg_adj, GEN_INT (255));
17807 flags = gen_rtx_REG (CCmode, FLAGS_REG);
17808 emit_insn (gen_rtx_SET (flags, tmp));
17810 inc_label = gen_label_rtx ();
17811 tmp = gen_rtx_LEU (VOIDmode, flags, const0_rtx);
17812 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
17813 gen_rtx_LABEL_REF (VOIDmode, inc_label),
17815 jump = emit_jump_insn (gen_rtx_SET (pc_rtx, tmp));
17816 JUMP_LABEL (jump) = inc_label;
17818 rtx reg_255 = gen_reg_rtx (word_mode);
17819 emit_move_insn (reg_255, GEN_INT (255));
17821 /* Adjust the ssp in a loop. */
17822 loop_label = gen_label_rtx ();
17823 emit_label (loop_label);
17824 LABEL_NUSES (loop_label) = 1;
17826 emit_insn ((word_mode == SImode)
17827 ? gen_incsspsi (reg_255)
17828 : gen_incsspdi (reg_255));
17829 tmp = gen_rtx_SET (reg_adj, gen_rtx_MINUS (ptr_mode,
17832 clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
17833 tmp = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, tmp, clob));
17836 tmp = gen_rtx_COMPARE (CCmode, reg_adj, GEN_INT (255));
17837 flags = gen_rtx_REG (CCmode, FLAGS_REG);
17838 emit_insn (gen_rtx_SET (flags, tmp));
17840 /* Jump to the loop label. */
17841 tmp = gen_rtx_GTU (VOIDmode, flags, const0_rtx);
17842 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
17843 gen_rtx_LABEL_REF (VOIDmode, loop_label),
17845 jump = emit_jump_insn (gen_rtx_SET (pc_rtx, tmp));
17846 JUMP_LABEL (jump) = loop_label;
17848 emit_label (inc_label);
17849 LABEL_NUSES (inc_label) = 1;
17850 emit_insn ((word_mode == SImode)
17851 ? gen_incsspsi (reg_ssp)
17852 : gen_incsspdi (reg_ssp));
17854 emit_label (noadj_label);
17855 LABEL_NUSES (noadj_label) = 1;
17858 stack_slot = adjust_address (operands[1], Pmode, 0);
17859 emit_move_insn (operands[0], stack_slot);
17864 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
17865 ;; Do not split instructions with mask registers.
17867 [(set (match_operand 0 "general_reg_operand")
17868 (match_operator 3 "promotable_binary_operator"
17869 [(match_operand 1 "general_reg_operand")
17870 (match_operand 2 "aligned_operand")]))
17871 (clobber (reg:CC FLAGS_REG))]
17872 "! TARGET_PARTIAL_REG_STALL && reload_completed
17873 && ((GET_MODE (operands[0]) == HImode
17874 && ((optimize_function_for_speed_p (cfun) && !TARGET_FAST_PREFIX)
17875 /* ??? next two lines just !satisfies_constraint_K (...) */
17876 || !CONST_INT_P (operands[2])
17877 || satisfies_constraint_K (operands[2])))
17878 || (GET_MODE (operands[0]) == QImode
17879 && (TARGET_PROMOTE_QImode || optimize_function_for_size_p (cfun))))"
17880 [(parallel [(set (match_dup 0)
17881 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
17882 (clobber (reg:CC FLAGS_REG))])]
17884 operands[0] = gen_lowpart (SImode, operands[0]);
17885 operands[1] = gen_lowpart (SImode, operands[1]);
17886 if (GET_CODE (operands[3]) != ASHIFT)
17887 operands[2] = gen_lowpart (SImode, operands[2]);
17888 operands[3] = shallow_copy_rtx (operands[3]);
17889 PUT_MODE (operands[3], SImode);
17892 ; Promote the QImode tests, as i386 has encoding of the AND
17893 ; instruction with 32-bit sign-extended immediate and thus the
17894 ; instruction size is unchanged, except in the %eax case for
17895 ; which it is increased by one byte, hence the ! optimize_size.
17897 [(set (match_operand 0 "flags_reg_operand")
17898 (match_operator 2 "compare_operator"
17899 [(and (match_operand 3 "aligned_operand")
17900 (match_operand 4 "const_int_operand"))
17902 (set (match_operand 1 "register_operand")
17903 (and (match_dup 3) (match_dup 4)))]
17904 "! TARGET_PARTIAL_REG_STALL && reload_completed
17905 && optimize_insn_for_speed_p ()
17906 && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
17907 || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))
17908 /* Ensure that the operand will remain sign-extended immediate. */
17909 && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)"
17910 [(parallel [(set (match_dup 0)
17911 (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
17914 (and:SI (match_dup 3) (match_dup 4)))])]
17917 = gen_int_mode (INTVAL (operands[4])
17918 & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
17919 operands[1] = gen_lowpart (SImode, operands[1]);
17920 operands[3] = gen_lowpart (SImode, operands[3]);
17923 ; Don't promote the QImode tests, as i386 doesn't have encoding of
17924 ; the TEST instruction with 32-bit sign-extended immediate and thus
17925 ; the instruction size would at least double, which is not what we
17926 ; want even with ! optimize_size.
17928 [(set (match_operand 0 "flags_reg_operand")
17929 (match_operator 1 "compare_operator"
17930 [(and (match_operand:HI 2 "aligned_operand")
17931 (match_operand:HI 3 "const_int_operand"))
17933 "! TARGET_PARTIAL_REG_STALL && reload_completed
17934 && ! TARGET_FAST_PREFIX
17935 && optimize_insn_for_speed_p ()
17936 /* Ensure that the operand will remain sign-extended immediate. */
17937 && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)"
17938 [(set (match_dup 0)
17939 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
17943 = gen_int_mode (INTVAL (operands[3])
17944 & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
17945 operands[2] = gen_lowpart (SImode, operands[2]);
17949 [(set (match_operand 0 "register_operand")
17950 (neg (match_operand 1 "register_operand")))
17951 (clobber (reg:CC FLAGS_REG))]
17952 "! TARGET_PARTIAL_REG_STALL && reload_completed
17953 && (GET_MODE (operands[0]) == HImode
17954 || (GET_MODE (operands[0]) == QImode
17955 && (TARGET_PROMOTE_QImode
17956 || optimize_insn_for_size_p ())))"
17957 [(parallel [(set (match_dup 0)
17958 (neg:SI (match_dup 1)))
17959 (clobber (reg:CC FLAGS_REG))])]
17961 operands[0] = gen_lowpart (SImode, operands[0]);
17962 operands[1] = gen_lowpart (SImode, operands[1]);
17965 ;; Do not split instructions with mask regs.
17967 [(set (match_operand 0 "general_reg_operand")
17968 (not (match_operand 1 "general_reg_operand")))]
17969 "! TARGET_PARTIAL_REG_STALL && reload_completed
17970 && (GET_MODE (operands[0]) == HImode
17971 || (GET_MODE (operands[0]) == QImode
17972 && (TARGET_PROMOTE_QImode
17973 || optimize_insn_for_size_p ())))"
17974 [(set (match_dup 0)
17975 (not:SI (match_dup 1)))]
17977 operands[0] = gen_lowpart (SImode, operands[0]);
17978 operands[1] = gen_lowpart (SImode, operands[1]);
17981 ;; RTL Peephole optimizations, run before sched2. These primarily look to
17982 ;; transform a complex memory operation into two memory to register operations.
17984 ;; Don't push memory operands
17986 [(set (match_operand:SWI 0 "push_operand")
17987 (match_operand:SWI 1 "memory_operand"))
17988 (match_scratch:SWI 2 "<r>")]
17989 "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
17990 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
17991 [(set (match_dup 2) (match_dup 1))
17992 (set (match_dup 0) (match_dup 2))])
17994 ;; We need to handle SFmode only, because DFmode and XFmode are split to
17997 [(set (match_operand:SF 0 "push_operand")
17998 (match_operand:SF 1 "memory_operand"))
17999 (match_scratch:SF 2 "r")]
18000 "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
18001 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
18002 [(set (match_dup 2) (match_dup 1))
18003 (set (match_dup 0) (match_dup 2))])
18005 ;; Don't move an immediate directly to memory when the instruction
18006 ;; gets too big, or if LCP stalls are a problem for 16-bit moves.
18008 [(match_scratch:SWI124 1 "<r>")
18009 (set (match_operand:SWI124 0 "memory_operand")
18011 "optimize_insn_for_speed_p ()
18012 && ((<MODE>mode == HImode
18013 && TARGET_LCP_STALL)
18014 || (!TARGET_USE_MOV0
18015 && TARGET_SPLIT_LONG_MOVES
18016 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn))
18017 && peep2_regno_dead_p (0, FLAGS_REG)"
18018 [(parallel [(set (match_dup 2) (const_int 0))
18019 (clobber (reg:CC FLAGS_REG))])
18020 (set (match_dup 0) (match_dup 1))]
18021 "operands[2] = gen_lowpart (SImode, operands[1]);")
18024 [(match_scratch:SWI124 2 "<r>")
18025 (set (match_operand:SWI124 0 "memory_operand")
18026 (match_operand:SWI124 1 "immediate_operand"))]
18027 "optimize_insn_for_speed_p ()
18028 && ((<MODE>mode == HImode
18029 && TARGET_LCP_STALL)
18030 || (TARGET_SPLIT_LONG_MOVES
18031 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn))"
18032 [(set (match_dup 2) (match_dup 1))
18033 (set (match_dup 0) (match_dup 2))])
18035 ;; Don't compare memory with zero, load and use a test instead.
18037 [(set (match_operand 0 "flags_reg_operand")
18038 (match_operator 1 "compare_operator"
18039 [(match_operand:SI 2 "memory_operand")
18041 (match_scratch:SI 3 "r")]
18042 "optimize_insn_for_speed_p () && ix86_match_ccmode (insn, CCNOmode)"
18043 [(set (match_dup 3) (match_dup 2))
18044 (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))])
18046 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
18047 ;; Don't split NOTs with a displacement operand, because resulting XOR
18048 ;; will not be pairable anyway.
18050 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
18051 ;; represented using a modRM byte. The XOR replacement is long decoded,
18052 ;; so this split helps here as well.
18054 ;; Note: Can't do this as a regular split because we can't get proper
18055 ;; lifetime information then.
18058 [(set (match_operand:SWI124 0 "nonimmediate_gr_operand")
18059 (not:SWI124 (match_operand:SWI124 1 "nonimmediate_gr_operand")))]
18060 "optimize_insn_for_speed_p ()
18061 && ((TARGET_NOT_UNPAIRABLE
18062 && (!MEM_P (operands[0])
18063 || !memory_displacement_operand (operands[0], <MODE>mode)))
18064 || (TARGET_NOT_VECTORMODE
18065 && long_memory_operand (operands[0], <MODE>mode)))
18066 && peep2_regno_dead_p (0, FLAGS_REG)"
18067 [(parallel [(set (match_dup 0)
18068 (xor:SWI124 (match_dup 1) (const_int -1)))
18069 (clobber (reg:CC FLAGS_REG))])])
18071 ;; Non pairable "test imm, reg" instructions can be translated to
18072 ;; "and imm, reg" if reg dies. The "and" form is also shorter (one
18073 ;; byte opcode instead of two, have a short form for byte operands),
18074 ;; so do it for other CPUs as well. Given that the value was dead,
18075 ;; this should not create any new dependencies. Pass on the sub-word
18076 ;; versions if we're concerned about partial register stalls.
18079 [(set (match_operand 0 "flags_reg_operand")
18080 (match_operator 1 "compare_operator"
18081 [(and:SI (match_operand:SI 2 "register_operand")
18082 (match_operand:SI 3 "immediate_operand"))
18084 "ix86_match_ccmode (insn, CCNOmode)
18085 && (REGNO (operands[2]) != AX_REG
18086 || satisfies_constraint_K (operands[3]))
18087 && peep2_reg_dead_p (1, operands[2])"
18089 [(set (match_dup 0)
18090 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
18093 (and:SI (match_dup 2) (match_dup 3)))])])
18095 ;; We don't need to handle HImode case, because it will be promoted to SImode
18096 ;; on ! TARGET_PARTIAL_REG_STALL
18099 [(set (match_operand 0 "flags_reg_operand")
18100 (match_operator 1 "compare_operator"
18101 [(and:QI (match_operand:QI 2 "register_operand")
18102 (match_operand:QI 3 "immediate_operand"))
18104 "! TARGET_PARTIAL_REG_STALL
18105 && ix86_match_ccmode (insn, CCNOmode)
18106 && REGNO (operands[2]) != AX_REG
18107 && peep2_reg_dead_p (1, operands[2])"
18109 [(set (match_dup 0)
18110 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
18113 (and:QI (match_dup 2) (match_dup 3)))])])
18116 [(set (match_operand 0 "flags_reg_operand")
18117 (match_operator 1 "compare_operator"
18120 (zero_extract:SI (match_operand 2 "QIreg_operand")
18123 (match_operand 3 "const_int_operand"))
18125 "! TARGET_PARTIAL_REG_STALL
18126 && ix86_match_ccmode (insn, CCNOmode)
18127 && REGNO (operands[2]) != AX_REG
18128 && peep2_reg_dead_p (1, operands[2])"
18130 [(set (match_dup 0)
18134 (zero_extract:SI (match_dup 2)
18139 (set (zero_extract:SI (match_dup 2)
18145 (zero_extract:SI (match_dup 2)
18148 (match_dup 3)) 0))])])
18150 ;; Don't do logical operations with memory inputs.
18152 [(match_scratch:SWI 2 "<r>")
18153 (parallel [(set (match_operand:SWI 0 "register_operand")
18154 (match_operator:SWI 3 "arith_or_logical_operator"
18156 (match_operand:SWI 1 "memory_operand")]))
18157 (clobber (reg:CC FLAGS_REG))])]
18158 "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
18159 [(set (match_dup 2) (match_dup 1))
18160 (parallel [(set (match_dup 0)
18161 (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
18162 (clobber (reg:CC FLAGS_REG))])])
18165 [(match_scratch:SWI 2 "<r>")
18166 (parallel [(set (match_operand:SWI 0 "register_operand")
18167 (match_operator:SWI 3 "arith_or_logical_operator"
18168 [(match_operand:SWI 1 "memory_operand")
18170 (clobber (reg:CC FLAGS_REG))])]
18171 "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
18172 [(set (match_dup 2) (match_dup 1))
18173 (parallel [(set (match_dup 0)
18174 (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
18175 (clobber (reg:CC FLAGS_REG))])])
18177 ;; Prefer Load+RegOp to Mov+MemOp. Watch out for cases when
18178 ;; the memory address refers to the destination of the load!
18181 [(set (match_operand:SWI 0 "general_reg_operand")
18182 (match_operand:SWI 1 "general_reg_operand"))
18183 (parallel [(set (match_dup 0)
18184 (match_operator:SWI 3 "commutative_operator"
18186 (match_operand:SWI 2 "memory_operand")]))
18187 (clobber (reg:CC FLAGS_REG))])]
18188 "REGNO (operands[0]) != REGNO (operands[1])
18189 && (<MODE>mode != QImode
18190 || any_QIreg_operand (operands[1], QImode))"
18191 [(set (match_dup 0) (match_dup 4))
18192 (parallel [(set (match_dup 0)
18193 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))
18194 (clobber (reg:CC FLAGS_REG))])]
18195 "operands[4] = replace_rtx (operands[2], operands[0], operands[1], true);")
18198 [(set (match_operand 0 "mmx_reg_operand")
18199 (match_operand 1 "mmx_reg_operand"))
18201 (match_operator 3 "commutative_operator"
18203 (match_operand 2 "memory_operand")]))]
18204 "REGNO (operands[0]) != REGNO (operands[1])"
18205 [(set (match_dup 0) (match_dup 2))
18207 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))])
18210 [(set (match_operand 0 "sse_reg_operand")
18211 (match_operand 1 "sse_reg_operand"))
18213 (match_operator 3 "commutative_operator"
18215 (match_operand 2 "memory_operand")]))]
18216 "REGNO (operands[0]) != REGNO (operands[1])"
18217 [(set (match_dup 0) (match_dup 2))
18219 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))])
18221 ; Don't do logical operations with memory outputs
18223 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
18224 ; instruction into two 1-uop insns plus a 2-uop insn. That last has
18225 ; the same decoder scheduling characteristics as the original.
18228 [(match_scratch:SWI 2 "<r>")
18229 (parallel [(set (match_operand:SWI 0 "memory_operand")
18230 (match_operator:SWI 3 "arith_or_logical_operator"
18232 (match_operand:SWI 1 "<nonmemory_operand>")]))
18233 (clobber (reg:CC FLAGS_REG))])]
18234 "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())"
18235 [(set (match_dup 2) (match_dup 0))
18236 (parallel [(set (match_dup 2)
18237 (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
18238 (clobber (reg:CC FLAGS_REG))])
18239 (set (match_dup 0) (match_dup 2))])
18242 [(match_scratch:SWI 2 "<r>")
18243 (parallel [(set (match_operand:SWI 0 "memory_operand")
18244 (match_operator:SWI 3 "arith_or_logical_operator"
18245 [(match_operand:SWI 1 "<nonmemory_operand>")
18247 (clobber (reg:CC FLAGS_REG))])]
18248 "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())"
18249 [(set (match_dup 2) (match_dup 0))
18250 (parallel [(set (match_dup 2)
18251 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
18252 (clobber (reg:CC FLAGS_REG))])
18253 (set (match_dup 0) (match_dup 2))])
18255 ;; Attempt to use arith or logical operations with memory outputs with
18256 ;; setting of flags.
18258 [(set (match_operand:SWI 0 "register_operand")
18259 (match_operand:SWI 1 "memory_operand"))
18260 (parallel [(set (match_dup 0)
18261 (match_operator:SWI 3 "plusminuslogic_operator"
18263 (match_operand:SWI 2 "<nonmemory_operand>")]))
18264 (clobber (reg:CC FLAGS_REG))])
18265 (set (match_dup 1) (match_dup 0))
18266 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
18267 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
18268 && peep2_reg_dead_p (4, operands[0])
18269 && !reg_overlap_mentioned_p (operands[0], operands[1])
18270 && !reg_overlap_mentioned_p (operands[0], operands[2])
18271 && (<MODE>mode != QImode
18272 || immediate_operand (operands[2], QImode)
18273 || any_QIreg_operand (operands[2], QImode))
18274 && ix86_match_ccmode (peep2_next_insn (3),
18275 (GET_CODE (operands[3]) == PLUS
18276 || GET_CODE (operands[3]) == MINUS)
18277 ? CCGOCmode : CCNOmode)"
18278 [(parallel [(set (match_dup 4) (match_dup 6))
18279 (set (match_dup 1) (match_dup 5))])]
18281 operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
18283 = gen_rtx_fmt_ee (GET_CODE (operands[3]), GET_MODE (operands[3]),
18284 copy_rtx (operands[1]),
18287 = gen_rtx_COMPARE (GET_MODE (operands[4]),
18288 copy_rtx (operands[5]),
18292 ;; Likewise for cmpelim optimized pattern.
18294 [(set (match_operand:SWI 0 "register_operand")
18295 (match_operand:SWI 1 "memory_operand"))
18296 (parallel [(set (reg FLAGS_REG)
18297 (compare (match_operator:SWI 3 "plusminuslogic_operator"
18299 (match_operand:SWI 2 "<nonmemory_operand>")])
18301 (set (match_dup 0) (match_dup 3))])
18302 (set (match_dup 1) (match_dup 0))]
18303 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
18304 && peep2_reg_dead_p (3, operands[0])
18305 && !reg_overlap_mentioned_p (operands[0], operands[1])
18306 && !reg_overlap_mentioned_p (operands[0], operands[2])
18307 && ix86_match_ccmode (peep2_next_insn (1),
18308 (GET_CODE (operands[3]) == PLUS
18309 || GET_CODE (operands[3]) == MINUS)
18310 ? CCGOCmode : CCNOmode)"
18311 [(parallel [(set (match_dup 4) (match_dup 6))
18312 (set (match_dup 1) (match_dup 5))])]
18314 operands[4] = SET_DEST (XVECEXP (PATTERN (peep2_next_insn (1)), 0, 0));
18316 = gen_rtx_fmt_ee (GET_CODE (operands[3]), GET_MODE (operands[3]),
18317 copy_rtx (operands[1]), operands[2]);
18319 = gen_rtx_COMPARE (GET_MODE (operands[4]), copy_rtx (operands[5]),
18323 ;; Likewise for instances where we have a lea pattern.
18325 [(set (match_operand:SWI 0 "register_operand")
18326 (match_operand:SWI 1 "memory_operand"))
18327 (set (match_operand:SWI 3 "register_operand")
18328 (plus:SWI (match_dup 0)
18329 (match_operand:SWI 2 "<nonmemory_operand>")))
18330 (set (match_dup 1) (match_dup 3))
18331 (set (reg FLAGS_REG) (compare (match_dup 3) (const_int 0)))]
18332 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
18333 && peep2_reg_dead_p (4, operands[3])
18334 && (rtx_equal_p (operands[0], operands[3])
18335 || peep2_reg_dead_p (2, operands[0]))
18336 && !reg_overlap_mentioned_p (operands[0], operands[1])
18337 && !reg_overlap_mentioned_p (operands[3], operands[1])
18338 && !reg_overlap_mentioned_p (operands[0], operands[2])
18339 && (<MODE>mode != QImode
18340 || immediate_operand (operands[2], QImode)
18341 || any_QIreg_operand (operands[2], QImode))
18342 && ix86_match_ccmode (peep2_next_insn (3), CCGOCmode)"
18343 [(parallel [(set (match_dup 4) (match_dup 6))
18344 (set (match_dup 1) (match_dup 5))])]
18346 operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
18348 = gen_rtx_PLUS (<MODE>mode,
18349 copy_rtx (operands[1]),
18352 = gen_rtx_COMPARE (GET_MODE (operands[4]),
18353 copy_rtx (operands[5]),
18358 [(parallel [(set (match_operand:SWI 0 "register_operand")
18359 (match_operator:SWI 2 "plusminuslogic_operator"
18361 (match_operand:SWI 1 "memory_operand")]))
18362 (clobber (reg:CC FLAGS_REG))])
18363 (set (match_dup 1) (match_dup 0))
18364 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
18365 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
18366 && COMMUTATIVE_ARITH_P (operands[2])
18367 && peep2_reg_dead_p (3, operands[0])
18368 && !reg_overlap_mentioned_p (operands[0], operands[1])
18369 && ix86_match_ccmode (peep2_next_insn (2),
18370 GET_CODE (operands[2]) == PLUS
18371 ? CCGOCmode : CCNOmode)"
18372 [(parallel [(set (match_dup 3) (match_dup 5))
18373 (set (match_dup 1) (match_dup 4))])]
18375 operands[3] = SET_DEST (PATTERN (peep2_next_insn (2)));
18377 = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
18378 copy_rtx (operands[1]),
18381 = gen_rtx_COMPARE (GET_MODE (operands[3]),
18382 copy_rtx (operands[4]),
18386 ;; Likewise for cmpelim optimized pattern.
18388 [(parallel [(set (reg FLAGS_REG)
18389 (compare (match_operator:SWI 2 "plusminuslogic_operator"
18390 [(match_operand:SWI 0 "register_operand")
18391 (match_operand:SWI 1 "memory_operand")])
18393 (set (match_dup 0) (match_dup 2))])
18394 (set (match_dup 1) (match_dup 0))]
18395 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
18396 && COMMUTATIVE_ARITH_P (operands[2])
18397 && peep2_reg_dead_p (2, operands[0])
18398 && !reg_overlap_mentioned_p (operands[0], operands[1])
18399 && ix86_match_ccmode (peep2_next_insn (0),
18400 GET_CODE (operands[2]) == PLUS
18401 ? CCGOCmode : CCNOmode)"
18402 [(parallel [(set (match_dup 3) (match_dup 5))
18403 (set (match_dup 1) (match_dup 4))])]
18405 operands[3] = SET_DEST (XVECEXP (PATTERN (peep2_next_insn (0)), 0, 0));
18407 = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
18408 copy_rtx (operands[1]), operands[0]);
18410 = gen_rtx_COMPARE (GET_MODE (operands[3]), copy_rtx (operands[4]),
18415 [(set (match_operand:SWI12 0 "register_operand")
18416 (match_operand:SWI12 1 "memory_operand"))
18417 (parallel [(set (match_operand:SI 4 "register_operand")
18418 (match_operator:SI 3 "plusminuslogic_operator"
18420 (match_operand:SI 2 "nonmemory_operand")]))
18421 (clobber (reg:CC FLAGS_REG))])
18422 (set (match_dup 1) (match_dup 0))
18423 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
18424 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
18425 && REGNO (operands[0]) == REGNO (operands[4])
18426 && peep2_reg_dead_p (4, operands[0])
18427 && (<MODE>mode != QImode
18428 || immediate_operand (operands[2], SImode)
18429 || any_QIreg_operand (operands[2], SImode))
18430 && !reg_overlap_mentioned_p (operands[0], operands[1])
18431 && !reg_overlap_mentioned_p (operands[0], operands[2])
18432 && ix86_match_ccmode (peep2_next_insn (3),
18433 (GET_CODE (operands[3]) == PLUS
18434 || GET_CODE (operands[3]) == MINUS)
18435 ? CCGOCmode : CCNOmode)"
18436 [(parallel [(set (match_dup 4) (match_dup 6))
18437 (set (match_dup 1) (match_dup 5))])]
18439 operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
18441 = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
18442 copy_rtx (operands[1]),
18443 gen_lowpart (<MODE>mode, operands[2]));
18445 = gen_rtx_COMPARE (GET_MODE (operands[4]),
18446 copy_rtx (operands[5]),
18450 ;; Attempt to always use XOR for zeroing registers (including FP modes).
18452 [(set (match_operand 0 "general_reg_operand")
18453 (match_operand 1 "const0_operand"))]
18454 "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
18455 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
18456 && peep2_regno_dead_p (0, FLAGS_REG)"
18457 [(parallel [(set (match_dup 0) (const_int 0))
18458 (clobber (reg:CC FLAGS_REG))])]
18459 "operands[0] = gen_lowpart (word_mode, operands[0]);")
18462 [(set (strict_low_part (match_operand:SWI12 0 "general_reg_operand"))
18464 "(! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
18465 && peep2_regno_dead_p (0, FLAGS_REG)"
18466 [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
18467 (clobber (reg:CC FLAGS_REG))])])
18469 ;; For HI, SI and DI modes, or $-1,reg is smaller than mov $-1,reg.
18471 [(set (match_operand:SWI248 0 "general_reg_operand")
18473 "(TARGET_MOVE_M1_VIA_OR || optimize_insn_for_size_p ())
18474 && peep2_regno_dead_p (0, FLAGS_REG)"
18475 [(parallel [(set (match_dup 0) (const_int -1))
18476 (clobber (reg:CC FLAGS_REG))])]
18478 if (<MODE_SIZE> < GET_MODE_SIZE (SImode))
18479 operands[0] = gen_lowpart (SImode, operands[0]);
18482 ;; Attempt to convert simple lea to add/shift.
18483 ;; These can be created by move expanders.
18484 ;; Disable PLUS peepholes on TARGET_OPT_AGU, since all
18485 ;; relevant lea instructions were already split.
18488 [(set (match_operand:SWI48 0 "register_operand")
18489 (plus:SWI48 (match_dup 0)
18490 (match_operand:SWI48 1 "<nonmemory_operand>")))]
18492 && peep2_regno_dead_p (0, FLAGS_REG)"
18493 [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1)))
18494 (clobber (reg:CC FLAGS_REG))])])
18497 [(set (match_operand:SWI48 0 "register_operand")
18498 (plus:SWI48 (match_operand:SWI48 1 "<nonmemory_operand>")
18501 && peep2_regno_dead_p (0, FLAGS_REG)"
18502 [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1)))
18503 (clobber (reg:CC FLAGS_REG))])])
18506 [(set (match_operand:DI 0 "register_operand")
18508 (plus:SI (match_operand:SI 1 "register_operand")
18509 (match_operand:SI 2 "nonmemory_operand"))))]
18510 "TARGET_64BIT && !TARGET_OPT_AGU
18511 && REGNO (operands[0]) == REGNO (operands[1])
18512 && peep2_regno_dead_p (0, FLAGS_REG)"
18513 [(parallel [(set (match_dup 0)
18514 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))
18515 (clobber (reg:CC FLAGS_REG))])])
18518 [(set (match_operand:DI 0 "register_operand")
18520 (plus:SI (match_operand:SI 1 "nonmemory_operand")
18521 (match_operand:SI 2 "register_operand"))))]
18522 "TARGET_64BIT && !TARGET_OPT_AGU
18523 && REGNO (operands[0]) == REGNO (operands[2])
18524 && peep2_regno_dead_p (0, FLAGS_REG)"
18525 [(parallel [(set (match_dup 0)
18526 (zero_extend:DI (plus:SI (match_dup 2) (match_dup 1))))
18527 (clobber (reg:CC FLAGS_REG))])])
18530 [(set (match_operand:SWI48 0 "register_operand")
18531 (mult:SWI48 (match_dup 0)
18532 (match_operand:SWI48 1 "const_int_operand")))]
18533 "pow2p_hwi (INTVAL (operands[1]))
18534 && peep2_regno_dead_p (0, FLAGS_REG)"
18535 [(parallel [(set (match_dup 0) (ashift:SWI48 (match_dup 0) (match_dup 1)))
18536 (clobber (reg:CC FLAGS_REG))])]
18537 "operands[1] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
18540 [(set (match_operand:DI 0 "register_operand")
18542 (mult:SI (match_operand:SI 1 "register_operand")
18543 (match_operand:SI 2 "const_int_operand"))))]
18545 && pow2p_hwi (INTVAL (operands[2]))
18546 && REGNO (operands[0]) == REGNO (operands[1])
18547 && peep2_regno_dead_p (0, FLAGS_REG)"
18548 [(parallel [(set (match_dup 0)
18549 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))
18550 (clobber (reg:CC FLAGS_REG))])]
18551 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
18553 ;; The ESP adjustments can be done by the push and pop instructions. Resulting
18554 ;; code is shorter, since push is only 1 byte, while add imm, %esp is 3 bytes.
18555 ;; On many CPUs it is also faster, since special hardware to avoid esp
18556 ;; dependencies is present.
18558 ;; While some of these conversions may be done using splitters, we use
18559 ;; peepholes in order to allow combine_stack_adjustments pass to see
18560 ;; nonobfuscated RTL.
18562 ;; Convert prologue esp subtractions to push.
18563 ;; We need register to push. In order to keep verify_flow_info happy we have
18565 ;; - use scratch and clobber it in order to avoid dependencies
18566 ;; - use already live register
18567 ;; We can't use the second way right now, since there is no reliable way how to
18568 ;; verify that given register is live. First choice will also most likely in
18569 ;; fewer dependencies. On the place of esp adjustments it is very likely that
18570 ;; call clobbered registers are dead. We may want to use base pointer as an
18571 ;; alternative when no register is available later.
18574 [(match_scratch:W 1 "r")
18575 (parallel [(set (reg:P SP_REG)
18576 (plus:P (reg:P SP_REG)
18577 (match_operand:P 0 "const_int_operand")))
18578 (clobber (reg:CC FLAGS_REG))
18579 (clobber (mem:BLK (scratch)))])]
18580 "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
18581 && INTVAL (operands[0]) == -GET_MODE_SIZE (word_mode)
18582 && ix86_red_zone_size == 0"
18583 [(clobber (match_dup 1))
18584 (parallel [(set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
18585 (clobber (mem:BLK (scratch)))])])
18588 [(match_scratch:W 1 "r")
18589 (parallel [(set (reg:P SP_REG)
18590 (plus:P (reg:P SP_REG)
18591 (match_operand:P 0 "const_int_operand")))
18592 (clobber (reg:CC FLAGS_REG))
18593 (clobber (mem:BLK (scratch)))])]
18594 "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
18595 && INTVAL (operands[0]) == -2*GET_MODE_SIZE (word_mode)
18596 && ix86_red_zone_size == 0"
18597 [(clobber (match_dup 1))
18598 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
18599 (parallel [(set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
18600 (clobber (mem:BLK (scratch)))])])
18602 ;; Convert esp subtractions to push.
18604 [(match_scratch:W 1 "r")
18605 (parallel [(set (reg:P SP_REG)
18606 (plus:P (reg:P SP_REG)
18607 (match_operand:P 0 "const_int_operand")))
18608 (clobber (reg:CC FLAGS_REG))])]
18609 "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
18610 && INTVAL (operands[0]) == -GET_MODE_SIZE (word_mode)
18611 && ix86_red_zone_size == 0"
18612 [(clobber (match_dup 1))
18613 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
18616 [(match_scratch:W 1 "r")
18617 (parallel [(set (reg:P SP_REG)
18618 (plus:P (reg:P SP_REG)
18619 (match_operand:P 0 "const_int_operand")))
18620 (clobber (reg:CC FLAGS_REG))])]
18621 "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
18622 && INTVAL (operands[0]) == -2*GET_MODE_SIZE (word_mode)
18623 && ix86_red_zone_size == 0"
18624 [(clobber (match_dup 1))
18625 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
18626 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
18628 ;; Convert epilogue deallocator to pop.
18630 [(match_scratch:W 1 "r")
18631 (parallel [(set (reg:P SP_REG)
18632 (plus:P (reg:P SP_REG)
18633 (match_operand:P 0 "const_int_operand")))
18634 (clobber (reg:CC FLAGS_REG))
18635 (clobber (mem:BLK (scratch)))])]
18636 "(TARGET_SINGLE_POP || optimize_insn_for_size_p ())
18637 && INTVAL (operands[0]) == GET_MODE_SIZE (word_mode)"
18638 [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
18639 (clobber (mem:BLK (scratch)))])])
18641 ;; Two pops case is tricky, since pop causes dependency
18642 ;; on destination register. We use two registers if available.
18644 [(match_scratch:W 1 "r")
18645 (match_scratch:W 2 "r")
18646 (parallel [(set (reg:P SP_REG)
18647 (plus:P (reg:P SP_REG)
18648 (match_operand:P 0 "const_int_operand")))
18649 (clobber (reg:CC FLAGS_REG))
18650 (clobber (mem:BLK (scratch)))])]
18651 "(TARGET_DOUBLE_POP || optimize_insn_for_size_p ())
18652 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
18653 [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
18654 (clobber (mem:BLK (scratch)))])
18655 (set (match_dup 2) (mem:W (post_inc:P (reg:P SP_REG))))])
18658 [(match_scratch:W 1 "r")
18659 (parallel [(set (reg:P SP_REG)
18660 (plus:P (reg:P SP_REG)
18661 (match_operand:P 0 "const_int_operand")))
18662 (clobber (reg:CC FLAGS_REG))
18663 (clobber (mem:BLK (scratch)))])]
18664 "optimize_insn_for_size_p ()
18665 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
18666 [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
18667 (clobber (mem:BLK (scratch)))])
18668 (set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
18670 ;; Convert esp additions to pop.
18672 [(match_scratch:W 1 "r")
18673 (parallel [(set (reg:P SP_REG)
18674 (plus:P (reg:P SP_REG)
18675 (match_operand:P 0 "const_int_operand")))
18676 (clobber (reg:CC FLAGS_REG))])]
18677 "INTVAL (operands[0]) == GET_MODE_SIZE (word_mode)"
18678 [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
18680 ;; Two pops case is tricky, since pop causes dependency
18681 ;; on destination register. We use two registers if available.
18683 [(match_scratch:W 1 "r")
18684 (match_scratch:W 2 "r")
18685 (parallel [(set (reg:P SP_REG)
18686 (plus:P (reg:P SP_REG)
18687 (match_operand:P 0 "const_int_operand")))
18688 (clobber (reg:CC FLAGS_REG))])]
18689 "INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
18690 [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
18691 (set (match_dup 2) (mem:W (post_inc:P (reg:P SP_REG))))])
18694 [(match_scratch:W 1 "r")
18695 (parallel [(set (reg:P SP_REG)
18696 (plus:P (reg:P SP_REG)
18697 (match_operand:P 0 "const_int_operand")))
18698 (clobber (reg:CC FLAGS_REG))])]
18699 "optimize_insn_for_size_p ()
18700 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
18701 [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
18702 (set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
18704 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
18705 ;; required and register dies. Similarly for 128 to -128.
18707 [(set (match_operand 0 "flags_reg_operand")
18708 (match_operator 1 "compare_operator"
18709 [(match_operand 2 "register_operand")
18710 (match_operand 3 "const_int_operand")]))]
18711 "(((!TARGET_FUSE_CMP_AND_BRANCH || optimize_insn_for_size_p ())
18712 && incdec_operand (operands[3], GET_MODE (operands[3])))
18713 || (!TARGET_FUSE_CMP_AND_BRANCH
18714 && INTVAL (operands[3]) == 128))
18715 && ix86_match_ccmode (insn, CCGCmode)
18716 && peep2_reg_dead_p (1, operands[2])"
18717 [(parallel [(set (match_dup 0)
18718 (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
18719 (clobber (match_dup 2))])])
18721 ;; Convert imul by three, five and nine into lea
18724 [(set (match_operand:SWI48 0 "register_operand")
18725 (mult:SWI48 (match_operand:SWI48 1 "register_operand")
18726 (match_operand:SWI48 2 "const359_operand")))
18727 (clobber (reg:CC FLAGS_REG))])]
18728 "!TARGET_PARTIAL_REG_STALL
18729 || <MODE>mode == SImode
18730 || optimize_function_for_size_p (cfun)"
18731 [(set (match_dup 0)
18732 (plus:SWI48 (mult:SWI48 (match_dup 1) (match_dup 2))
18734 "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
18738 [(set (match_operand:SWI48 0 "register_operand")
18739 (mult:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
18740 (match_operand:SWI48 2 "const359_operand")))
18741 (clobber (reg:CC FLAGS_REG))])]
18742 "optimize_insn_for_speed_p ()
18743 && (!TARGET_PARTIAL_REG_STALL || <MODE>mode == SImode)"
18744 [(set (match_dup 0) (match_dup 1))
18746 (plus:SWI48 (mult:SWI48 (match_dup 0) (match_dup 2))
18748 "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
18750 ;; imul $32bit_imm, mem, reg is vector decoded, while
18751 ;; imul $32bit_imm, reg, reg is direct decoded.
18753 [(match_scratch:SWI48 3 "r")
18754 (parallel [(set (match_operand:SWI48 0 "register_operand")
18755 (mult:SWI48 (match_operand:SWI48 1 "memory_operand")
18756 (match_operand:SWI48 2 "immediate_operand")))
18757 (clobber (reg:CC FLAGS_REG))])]
18758 "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
18759 && !satisfies_constraint_K (operands[2])"
18760 [(set (match_dup 3) (match_dup 1))
18761 (parallel [(set (match_dup 0) (mult:SWI48 (match_dup 3) (match_dup 2)))
18762 (clobber (reg:CC FLAGS_REG))])])
18765 [(match_scratch:SI 3 "r")
18766 (parallel [(set (match_operand:DI 0 "register_operand")
18768 (mult:SI (match_operand:SI 1 "memory_operand")
18769 (match_operand:SI 2 "immediate_operand"))))
18770 (clobber (reg:CC FLAGS_REG))])]
18772 && TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
18773 && !satisfies_constraint_K (operands[2])"
18774 [(set (match_dup 3) (match_dup 1))
18775 (parallel [(set (match_dup 0)
18776 (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
18777 (clobber (reg:CC FLAGS_REG))])])
18779 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
18780 ;; Convert it into imul reg, reg
18781 ;; It would be better to force assembler to encode instruction using long
18782 ;; immediate, but there is apparently no way to do so.
18784 [(parallel [(set (match_operand:SWI248 0 "register_operand")
18786 (match_operand:SWI248 1 "nonimmediate_operand")
18787 (match_operand:SWI248 2 "const_int_operand")))
18788 (clobber (reg:CC FLAGS_REG))])
18789 (match_scratch:SWI248 3 "r")]
18790 "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
18791 && satisfies_constraint_K (operands[2])"
18792 [(set (match_dup 3) (match_dup 2))
18793 (parallel [(set (match_dup 0) (mult:SWI248 (match_dup 0) (match_dup 3)))
18794 (clobber (reg:CC FLAGS_REG))])]
18796 if (!rtx_equal_p (operands[0], operands[1]))
18797 emit_move_insn (operands[0], operands[1]);
18800 ;; After splitting up read-modify operations, array accesses with memory
18801 ;; operands might end up in form:
18803 ;; movl 4(%esp), %edx
18805 ;; instead of pre-splitting:
18807 ;; addl 4(%esp), %eax
18809 ;; movl 4(%esp), %edx
18810 ;; leal (%edx,%eax,4), %eax
18813 [(match_scratch:W 5 "r")
18814 (parallel [(set (match_operand 0 "register_operand")
18815 (ashift (match_operand 1 "register_operand")
18816 (match_operand 2 "const_int_operand")))
18817 (clobber (reg:CC FLAGS_REG))])
18818 (parallel [(set (match_operand 3 "register_operand")
18819 (plus (match_dup 0)
18820 (match_operand 4 "x86_64_general_operand")))
18821 (clobber (reg:CC FLAGS_REG))])]
18822 "IN_RANGE (INTVAL (operands[2]), 1, 3)
18823 /* Validate MODE for lea. */
18824 && ((!TARGET_PARTIAL_REG_STALL
18825 && (GET_MODE (operands[0]) == QImode
18826 || GET_MODE (operands[0]) == HImode))
18827 || GET_MODE (operands[0]) == SImode
18828 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
18829 && (rtx_equal_p (operands[0], operands[3])
18830 || peep2_reg_dead_p (2, operands[0]))
18831 /* We reorder load and the shift. */
18832 && !reg_overlap_mentioned_p (operands[0], operands[4])"
18833 [(set (match_dup 5) (match_dup 4))
18834 (set (match_dup 0) (match_dup 1))]
18836 machine_mode op1mode = GET_MODE (operands[1]);
18837 machine_mode mode = op1mode == DImode ? DImode : SImode;
18838 int scale = 1 << INTVAL (operands[2]);
18839 rtx index = gen_lowpart (word_mode, operands[1]);
18840 rtx base = gen_lowpart (word_mode, operands[5]);
18841 rtx dest = gen_lowpart (mode, operands[3]);
18843 operands[1] = gen_rtx_PLUS (word_mode, base,
18844 gen_rtx_MULT (word_mode, index, GEN_INT (scale)));
18845 if (mode != word_mode)
18846 operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
18848 operands[5] = base;
18849 if (op1mode != word_mode)
18850 operands[5] = gen_lowpart (op1mode, operands[5]);
18852 operands[0] = dest;
18855 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
18856 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
18857 ;; caught for use by garbage collectors and the like. Using an insn that
18858 ;; maps to SIGILL makes it more likely the program will rightfully die.
18859 ;; Keeping with tradition, "6" is in honor of #UD.
18860 (define_insn "trap"
18861 [(trap_if (const_int 1) (const_int 6))]
18864 #ifdef HAVE_AS_IX86_UD2
18867 return ASM_SHORT "0x0b0f";
18870 [(set_attr "length" "2")])
18873 [(unspec_volatile [(const_int 0)] UNSPECV_UD2)]
18876 #ifdef HAVE_AS_IX86_UD2
18879 return ASM_SHORT "0x0b0f";
18882 [(set_attr "length" "2")])
18884 (define_expand "prefetch"
18885 [(prefetch (match_operand 0 "address_operand")
18886 (match_operand:SI 1 "const_int_operand")
18887 (match_operand:SI 2 "const_int_operand"))]
18888 "TARGET_3DNOW || TARGET_PREFETCH_SSE || TARGET_PRFCHW || TARGET_PREFETCHWT1"
18890 bool write = INTVAL (operands[1]) != 0;
18891 int locality = INTVAL (operands[2]);
18893 gcc_assert (IN_RANGE (locality, 0, 3));
18895 /* Use 3dNOW prefetch in case we are asking for write prefetch not
18896 supported by SSE counterpart (non-SSE2 athlon machines) or the
18897 SSE prefetch is not available (K6 machines). Otherwise use SSE
18898 prefetch as it allows specifying of locality. */
18902 if (TARGET_PREFETCHWT1)
18903 operands[2] = GEN_INT (MAX (locality, 2));
18904 else if (TARGET_PRFCHW)
18905 operands[2] = GEN_INT (3);
18906 else if (TARGET_3DNOW && !TARGET_SSE2)
18907 operands[2] = GEN_INT (3);
18908 else if (TARGET_PREFETCH_SSE)
18909 operands[1] = const0_rtx;
18912 gcc_assert (TARGET_3DNOW);
18913 operands[2] = GEN_INT (3);
18918 if (TARGET_PREFETCH_SSE)
18922 gcc_assert (TARGET_3DNOW);
18923 operands[2] = GEN_INT (3);
18928 (define_insn "*prefetch_sse"
18929 [(prefetch (match_operand 0 "address_operand" "p")
18931 (match_operand:SI 1 "const_int_operand"))]
18932 "TARGET_PREFETCH_SSE"
18934 static const char * const patterns[4] = {
18935 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
18938 int locality = INTVAL (operands[1]);
18939 gcc_assert (IN_RANGE (locality, 0, 3));
18941 return patterns[locality];
18943 [(set_attr "type" "sse")
18944 (set_attr "atom_sse_attr" "prefetch")
18945 (set (attr "length_address")
18946 (symbol_ref "memory_address_length (operands[0], false)"))
18947 (set_attr "memory" "none")])
18949 (define_insn "*prefetch_3dnow"
18950 [(prefetch (match_operand 0 "address_operand" "p")
18951 (match_operand:SI 1 "const_int_operand" "n")
18953 "TARGET_3DNOW || TARGET_PRFCHW || TARGET_PREFETCHWT1"
18955 if (INTVAL (operands[1]) == 0)
18956 return "prefetch\t%a0";
18958 return "prefetchw\t%a0";
18960 [(set_attr "type" "mmx")
18961 (set (attr "length_address")
18962 (symbol_ref "memory_address_length (operands[0], false)"))
18963 (set_attr "memory" "none")])
18965 (define_insn "*prefetch_prefetchwt1"
18966 [(prefetch (match_operand 0 "address_operand" "p")
18969 "TARGET_PREFETCHWT1"
18970 "prefetchwt1\t%a0";
18971 [(set_attr "type" "sse")
18972 (set (attr "length_address")
18973 (symbol_ref "memory_address_length (operands[0], false)"))
18974 (set_attr "memory" "none")])
18976 (define_expand "stack_protect_set"
18977 [(match_operand 0 "memory_operand")
18978 (match_operand 1 "memory_operand")]
18979 "TARGET_SSP_TLS_GUARD"
18981 rtx (*insn)(rtx, rtx);
18983 insn = (TARGET_LP64
18984 ? gen_stack_protect_set_di
18985 : gen_stack_protect_set_si);
18987 emit_insn (insn (operands[0], operands[1]));
18991 (define_insn "stack_protect_set_<mode>"
18992 [(set (match_operand:PTR 0 "memory_operand" "=m")
18993 (unspec:PTR [(match_operand:PTR 1 "memory_operand" "m")]
18995 (set (match_scratch:PTR 2 "=&r") (const_int 0))
18996 (clobber (reg:CC FLAGS_REG))]
18997 "TARGET_SSP_TLS_GUARD"
18998 "mov{<imodesuffix>}\t{%1, %2|%2, %1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
18999 [(set_attr "type" "multi")])
19001 (define_expand "stack_protect_test"
19002 [(match_operand 0 "memory_operand")
19003 (match_operand 1 "memory_operand")
19005 "TARGET_SSP_TLS_GUARD"
19007 rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
19009 rtx (*insn)(rtx, rtx, rtx);
19011 insn = (TARGET_LP64
19012 ? gen_stack_protect_test_di
19013 : gen_stack_protect_test_si);
19015 emit_insn (insn (flags, operands[0], operands[1]));
19017 emit_jump_insn (gen_cbranchcc4 (gen_rtx_EQ (VOIDmode, flags, const0_rtx),
19018 flags, const0_rtx, operands[2]));
19022 (define_insn "stack_protect_test_<mode>"
19023 [(set (match_operand:CCZ 0 "flags_reg_operand")
19024 (unspec:CCZ [(match_operand:PTR 1 "memory_operand" "m")
19025 (match_operand:PTR 2 "memory_operand" "m")]
19027 (clobber (match_scratch:PTR 3 "=&r"))]
19028 "TARGET_SSP_TLS_GUARD"
19029 "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%2, %3|%3, %2}"
19030 [(set_attr "type" "multi")])
19032 (define_insn "sse4_2_crc32<mode>"
19033 [(set (match_operand:SI 0 "register_operand" "=r")
19035 [(match_operand:SI 1 "register_operand" "0")
19036 (match_operand:SWI124 2 "nonimmediate_operand" "<r>m")]
19038 "TARGET_SSE4_2 || TARGET_CRC32"
19039 "crc32{<imodesuffix>}\t{%2, %0|%0, %2}"
19040 [(set_attr "type" "sselog1")
19041 (set_attr "prefix_rep" "1")
19042 (set_attr "prefix_extra" "1")
19043 (set (attr "prefix_data16")
19044 (if_then_else (match_operand:HI 2)
19046 (const_string "*")))
19047 (set (attr "prefix_rex")
19048 (if_then_else (match_operand:QI 2 "ext_QIreg_operand")
19050 (const_string "*")))
19051 (set_attr "mode" "SI")])
19053 (define_insn "sse4_2_crc32di"
19054 [(set (match_operand:DI 0 "register_operand" "=r")
19056 [(match_operand:DI 1 "register_operand" "0")
19057 (match_operand:DI 2 "nonimmediate_operand" "rm")]
19059 "TARGET_64BIT && (TARGET_SSE4_2 || TARGET_CRC32)"
19060 "crc32{q}\t{%2, %0|%0, %2}"
19061 [(set_attr "type" "sselog1")
19062 (set_attr "prefix_rep" "1")
19063 (set_attr "prefix_extra" "1")
19064 (set_attr "mode" "DI")])
19066 (define_insn "rdpmc"
19067 [(set (match_operand:DI 0 "register_operand" "=A")
19068 (unspec_volatile:DI [(match_operand:SI 1 "register_operand" "c")]
19072 [(set_attr "type" "other")
19073 (set_attr "length" "2")])
19075 (define_insn "rdpmc_rex64"
19076 [(set (match_operand:DI 0 "register_operand" "=a")
19077 (unspec_volatile:DI [(match_operand:SI 2 "register_operand" "c")]
19079 (set (match_operand:DI 1 "register_operand" "=d")
19080 (unspec_volatile:DI [(match_dup 2)] UNSPECV_RDPMC))]
19083 [(set_attr "type" "other")
19084 (set_attr "length" "2")])
19086 (define_insn "rdtsc"
19087 [(set (match_operand:DI 0 "register_operand" "=A")
19088 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
19091 [(set_attr "type" "other")
19092 (set_attr "length" "2")])
19094 (define_insn "rdtsc_rex64"
19095 [(set (match_operand:DI 0 "register_operand" "=a")
19096 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))
19097 (set (match_operand:DI 1 "register_operand" "=d")
19098 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
19101 [(set_attr "type" "other")
19102 (set_attr "length" "2")])
19104 (define_insn "rdtscp"
19105 [(set (match_operand:DI 0 "register_operand" "=A")
19106 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
19107 (set (match_operand:SI 1 "register_operand" "=c")
19108 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
19111 [(set_attr "type" "other")
19112 (set_attr "length" "3")])
19114 (define_insn "rdtscp_rex64"
19115 [(set (match_operand:DI 0 "register_operand" "=a")
19116 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
19117 (set (match_operand:DI 1 "register_operand" "=d")
19118 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
19119 (set (match_operand:SI 2 "register_operand" "=c")
19120 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
19123 [(set_attr "type" "other")
19124 (set_attr "length" "3")])
19126 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
19128 ;; FXSR, XSAVE and XSAVEOPT instructions
19130 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
19132 (define_insn "fxsave"
19133 [(set (match_operand:BLK 0 "memory_operand" "=m")
19134 (unspec_volatile:BLK [(const_int 0)] UNSPECV_FXSAVE))]
19137 [(set_attr "type" "other")
19138 (set_attr "memory" "store")
19139 (set (attr "length")
19140 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
19142 (define_insn "fxsave64"
19143 [(set (match_operand:BLK 0 "memory_operand" "=m")
19144 (unspec_volatile:BLK [(const_int 0)] UNSPECV_FXSAVE64))]
19145 "TARGET_64BIT && TARGET_FXSR"
19147 [(set_attr "type" "other")
19148 (set_attr "memory" "store")
19149 (set (attr "length")
19150 (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
19152 (define_insn "fxrstor"
19153 [(unspec_volatile [(match_operand:BLK 0 "memory_operand" "m")]
19157 [(set_attr "type" "other")
19158 (set_attr "memory" "load")
19159 (set (attr "length")
19160 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
19162 (define_insn "fxrstor64"
19163 [(unspec_volatile [(match_operand:BLK 0 "memory_operand" "m")]
19164 UNSPECV_FXRSTOR64)]
19165 "TARGET_64BIT && TARGET_FXSR"
19167 [(set_attr "type" "other")
19168 (set_attr "memory" "load")
19169 (set (attr "length")
19170 (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
19172 (define_int_iterator ANY_XSAVE
19174 (UNSPECV_XSAVEOPT "TARGET_XSAVEOPT")
19175 (UNSPECV_XSAVEC "TARGET_XSAVEC")
19176 (UNSPECV_XSAVES "TARGET_XSAVES")])
19178 (define_int_iterator ANY_XSAVE64
19180 (UNSPECV_XSAVEOPT64 "TARGET_XSAVEOPT")
19181 (UNSPECV_XSAVEC64 "TARGET_XSAVEC")
19182 (UNSPECV_XSAVES64 "TARGET_XSAVES")])
19184 (define_int_attr xsave
19185 [(UNSPECV_XSAVE "xsave")
19186 (UNSPECV_XSAVE64 "xsave64")
19187 (UNSPECV_XSAVEOPT "xsaveopt")
19188 (UNSPECV_XSAVEOPT64 "xsaveopt64")
19189 (UNSPECV_XSAVEC "xsavec")
19190 (UNSPECV_XSAVEC64 "xsavec64")
19191 (UNSPECV_XSAVES "xsaves")
19192 (UNSPECV_XSAVES64 "xsaves64")])
19194 (define_int_iterator ANY_XRSTOR
19196 (UNSPECV_XRSTORS "TARGET_XSAVES")])
19198 (define_int_iterator ANY_XRSTOR64
19200 (UNSPECV_XRSTORS64 "TARGET_XSAVES")])
19202 (define_int_attr xrstor
19203 [(UNSPECV_XRSTOR "xrstor")
19204 (UNSPECV_XRSTOR64 "xrstor")
19205 (UNSPECV_XRSTORS "xrstors")
19206 (UNSPECV_XRSTORS64 "xrstors")])
19208 (define_insn "<xsave>"
19209 [(set (match_operand:BLK 0 "memory_operand" "=m")
19210 (unspec_volatile:BLK
19211 [(match_operand:DI 1 "register_operand" "A")]
19213 "!TARGET_64BIT && TARGET_XSAVE"
19215 [(set_attr "type" "other")
19216 (set_attr "memory" "store")
19217 (set (attr "length")
19218 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
19220 (define_insn "<xsave>_rex64"
19221 [(set (match_operand:BLK 0 "memory_operand" "=m")
19222 (unspec_volatile:BLK
19223 [(match_operand:SI 1 "register_operand" "a")
19224 (match_operand:SI 2 "register_operand" "d")]
19226 "TARGET_64BIT && TARGET_XSAVE"
19228 [(set_attr "type" "other")
19229 (set_attr "memory" "store")
19230 (set (attr "length")
19231 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
19233 (define_insn "<xsave>"
19234 [(set (match_operand:BLK 0 "memory_operand" "=m")
19235 (unspec_volatile:BLK
19236 [(match_operand:SI 1 "register_operand" "a")
19237 (match_operand:SI 2 "register_operand" "d")]
19239 "TARGET_64BIT && TARGET_XSAVE"
19241 [(set_attr "type" "other")
19242 (set_attr "memory" "store")
19243 (set (attr "length")
19244 (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
19246 (define_insn "<xrstor>"
19247 [(unspec_volatile:BLK
19248 [(match_operand:BLK 0 "memory_operand" "m")
19249 (match_operand:DI 1 "register_operand" "A")]
19251 "!TARGET_64BIT && TARGET_XSAVE"
19253 [(set_attr "type" "other")
19254 (set_attr "memory" "load")
19255 (set (attr "length")
19256 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
19258 (define_insn "<xrstor>_rex64"
19259 [(unspec_volatile:BLK
19260 [(match_operand:BLK 0 "memory_operand" "m")
19261 (match_operand:SI 1 "register_operand" "a")
19262 (match_operand:SI 2 "register_operand" "d")]
19264 "TARGET_64BIT && TARGET_XSAVE"
19266 [(set_attr "type" "other")
19267 (set_attr "memory" "load")
19268 (set (attr "length")
19269 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
19271 (define_insn "<xrstor>64"
19272 [(unspec_volatile:BLK
19273 [(match_operand:BLK 0 "memory_operand" "m")
19274 (match_operand:SI 1 "register_operand" "a")
19275 (match_operand:SI 2 "register_operand" "d")]
19277 "TARGET_64BIT && TARGET_XSAVE"
19279 [(set_attr "type" "other")
19280 (set_attr "memory" "load")
19281 (set (attr "length")
19282 (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
19284 (define_insn "xsetbv"
19285 [(unspec_volatile:SI
19286 [(match_operand:SI 0 "register_operand" "c")
19287 (match_operand:DI 1 "register_operand" "A")]
19289 "!TARGET_64BIT && TARGET_XSAVE"
19291 [(set_attr "type" "other")])
19293 (define_insn "xsetbv_rex64"
19294 [(unspec_volatile:SI
19295 [(match_operand:SI 0 "register_operand" "c")
19296 (match_operand:SI 1 "register_operand" "a")
19297 (match_operand:SI 2 "register_operand" "d")]
19299 "TARGET_64BIT && TARGET_XSAVE"
19301 [(set_attr "type" "other")])
19303 (define_insn "xgetbv"
19304 [(set (match_operand:DI 0 "register_operand" "=A")
19305 (unspec_volatile:DI [(match_operand:SI 1 "register_operand" "c")]
19307 "!TARGET_64BIT && TARGET_XSAVE"
19309 [(set_attr "type" "other")])
19311 (define_insn "xgetbv_rex64"
19312 [(set (match_operand:DI 0 "register_operand" "=a")
19313 (unspec_volatile:DI [(match_operand:SI 2 "register_operand" "c")]
19315 (set (match_operand:DI 1 "register_operand" "=d")
19316 (unspec_volatile:DI [(match_dup 2)] UNSPECV_XGETBV))]
19317 "TARGET_64BIT && TARGET_XSAVE"
19319 [(set_attr "type" "other")])
19321 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
19323 ;; Floating-point instructions for atomic compound assignments
19325 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
19327 ; Clobber all floating-point registers on environment save and restore
19328 ; to ensure that the TOS value saved at fnstenv is valid after fldenv.
19329 (define_insn "fnstenv"
19330 [(set (match_operand:BLK 0 "memory_operand" "=m")
19331 (unspec_volatile:BLK [(const_int 0)] UNSPECV_FNSTENV))
19332 (clobber (reg:XF ST0_REG))
19333 (clobber (reg:XF ST1_REG))
19334 (clobber (reg:XF ST2_REG))
19335 (clobber (reg:XF ST3_REG))
19336 (clobber (reg:XF ST4_REG))
19337 (clobber (reg:XF ST5_REG))
19338 (clobber (reg:XF ST6_REG))
19339 (clobber (reg:XF ST7_REG))]
19342 [(set_attr "type" "other")
19343 (set_attr "memory" "store")
19344 (set (attr "length")
19345 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))])
19347 (define_insn "fldenv"
19348 [(unspec_volatile [(match_operand:BLK 0 "memory_operand" "m")]
19350 (clobber (reg:XF ST0_REG))
19351 (clobber (reg:XF ST1_REG))
19352 (clobber (reg:XF ST2_REG))
19353 (clobber (reg:XF ST3_REG))
19354 (clobber (reg:XF ST4_REG))
19355 (clobber (reg:XF ST5_REG))
19356 (clobber (reg:XF ST6_REG))
19357 (clobber (reg:XF ST7_REG))]
19360 [(set_attr "type" "other")
19361 (set_attr "memory" "load")
19362 (set (attr "length")
19363 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))])
19365 (define_insn "fnstsw"
19366 [(set (match_operand:HI 0 "nonimmediate_operand" "=a,m")
19367 (unspec_volatile:HI [(const_int 0)] UNSPECV_FNSTSW))]
19370 [(set_attr "type" "other,other")
19371 (set_attr "memory" "none,store")
19372 (set (attr "length")
19373 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))])
19375 (define_insn "fnclex"
19376 [(unspec_volatile [(const_int 0)] UNSPECV_FNCLEX)]
19379 [(set_attr "type" "other")
19380 (set_attr "memory" "none")
19381 (set_attr "length" "2")])
19383 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
19385 ;; LWP instructions
19387 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
19389 (define_expand "lwp_llwpcb"
19390 [(unspec_volatile [(match_operand 0 "register_operand")]
19391 UNSPECV_LLWP_INTRINSIC)]
19394 (define_insn "*lwp_llwpcb<mode>1"
19395 [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
19396 UNSPECV_LLWP_INTRINSIC)]
19399 [(set_attr "type" "lwp")
19400 (set_attr "mode" "<MODE>")
19401 (set_attr "length" "5")])
19403 (define_expand "lwp_slwpcb"
19404 [(set (match_operand 0 "register_operand")
19405 (unspec_volatile [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
19410 insn = (Pmode == DImode
19412 : gen_lwp_slwpcbsi);
19414 emit_insn (insn (operands[0]));
19418 (define_insn "lwp_slwpcb<mode>"
19419 [(set (match_operand:P 0 "register_operand" "=r")
19420 (unspec_volatile:P [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
19423 [(set_attr "type" "lwp")
19424 (set_attr "mode" "<MODE>")
19425 (set_attr "length" "5")])
19427 (define_expand "lwp_lwpval<mode>3"
19428 [(unspec_volatile [(match_operand:SWI48 1 "register_operand")
19429 (match_operand:SI 2 "nonimmediate_operand")
19430 (match_operand:SI 3 "const_int_operand")]
19431 UNSPECV_LWPVAL_INTRINSIC)]
19433 ;; Avoid unused variable warning.
19434 "(void) operands[0];")
19436 (define_insn "*lwp_lwpval<mode>3_1"
19437 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")
19438 (match_operand:SI 1 "nonimmediate_operand" "rm")
19439 (match_operand:SI 2 "const_int_operand" "i")]
19440 UNSPECV_LWPVAL_INTRINSIC)]
19442 "lwpval\t{%2, %1, %0|%0, %1, %2}"
19443 [(set_attr "type" "lwp")
19444 (set_attr "mode" "<MODE>")
19445 (set (attr "length")
19446 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
19448 (define_expand "lwp_lwpins<mode>3"
19449 [(set (reg:CCC FLAGS_REG)
19450 (unspec_volatile:CCC [(match_operand:SWI48 1 "register_operand")
19451 (match_operand:SI 2 "nonimmediate_operand")
19452 (match_operand:SI 3 "const_int_operand")]
19453 UNSPECV_LWPINS_INTRINSIC))
19454 (set (match_operand:QI 0 "nonimmediate_operand")
19455 (eq:QI (reg:CCC FLAGS_REG) (const_int 0)))]
19458 (define_insn "*lwp_lwpins<mode>3_1"
19459 [(set (reg:CCC FLAGS_REG)
19460 (unspec_volatile:CCC [(match_operand:SWI48 0 "register_operand" "r")
19461 (match_operand:SI 1 "nonimmediate_operand" "rm")
19462 (match_operand:SI 2 "const_int_operand" "i")]
19463 UNSPECV_LWPINS_INTRINSIC))]
19465 "lwpins\t{%2, %1, %0|%0, %1, %2}"
19466 [(set_attr "type" "lwp")
19467 (set_attr "mode" "<MODE>")
19468 (set (attr "length")
19469 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
19471 (define_int_iterator RDFSGSBASE
19475 (define_int_iterator WRFSGSBASE
19479 (define_int_attr fsgs
19480 [(UNSPECV_RDFSBASE "fs")
19481 (UNSPECV_RDGSBASE "gs")
19482 (UNSPECV_WRFSBASE "fs")
19483 (UNSPECV_WRGSBASE "gs")])
19485 (define_insn "rd<fsgs>base<mode>"
19486 [(set (match_operand:SWI48 0 "register_operand" "=r")
19487 (unspec_volatile:SWI48 [(const_int 0)] RDFSGSBASE))]
19488 "TARGET_64BIT && TARGET_FSGSBASE"
19490 [(set_attr "type" "other")
19491 (set_attr "prefix_extra" "2")])
19493 (define_insn "wr<fsgs>base<mode>"
19494 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
19496 "TARGET_64BIT && TARGET_FSGSBASE"
19498 [(set_attr "type" "other")
19499 (set_attr "prefix_extra" "2")])
19501 (define_insn "rdrand<mode>_1"
19502 [(set (match_operand:SWI248 0 "register_operand" "=r")
19503 (unspec_volatile:SWI248 [(const_int 0)] UNSPECV_RDRAND))
19504 (set (reg:CCC FLAGS_REG)
19505 (unspec_volatile:CCC [(const_int 0)] UNSPECV_RDRAND))]
19508 [(set_attr "type" "other")
19509 (set_attr "prefix_extra" "1")])
19511 (define_insn "rdseed<mode>_1"
19512 [(set (match_operand:SWI248 0 "register_operand" "=r")
19513 (unspec_volatile:SWI248 [(const_int 0)] UNSPECV_RDSEED))
19514 (set (reg:CCC FLAGS_REG)
19515 (unspec_volatile:CCC [(const_int 0)] UNSPECV_RDSEED))]
19518 [(set_attr "type" "other")
19519 (set_attr "prefix_extra" "1")])
19521 (define_expand "pause"
19522 [(set (match_dup 0)
19523 (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
19526 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
19527 MEM_VOLATILE_P (operands[0]) = 1;
19530 ;; Use "rep; nop", instead of "pause", to support older assemblers.
19531 ;; They have the same encoding.
19532 (define_insn "*pause"
19533 [(set (match_operand:BLK 0)
19534 (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
19537 [(set_attr "length" "2")
19538 (set_attr "memory" "unknown")])
19540 ;; CET instructions
19541 (define_insn "rdssp<mode>"
19542 [(set (match_operand:SWI48x 0 "register_operand" "=r")
19543 (unspec_volatile:SWI48x [(const_int 0)] UNSPECV_NOP_RDSSP))]
19544 "TARGET_SHSTK || (flag_cf_protection & CF_RETURN)"
19545 "xor{l}\t%k0, %k0\n\trdssp<mskmodesuffix>\t%0"
19546 [(set_attr "length" "6")
19547 (set_attr "type" "other")])
19549 (define_insn "incssp<mode>"
19550 [(unspec_volatile [(match_operand:SWI48x 0 "register_operand" "r")]
19552 "TARGET_SHSTK || (flag_cf_protection & CF_RETURN)"
19553 "incssp<mskmodesuffix>\t%0"
19554 [(set_attr "length" "4")
19555 (set_attr "type" "other")])
19557 (define_insn "saveprevssp"
19558 [(unspec_volatile [(const_int 0)] UNSPECV_SAVEPREVSSP)]
19561 [(set_attr "length" "5")
19562 (set_attr "type" "other")])
19564 (define_expand "rstorssp"
19565 [(unspec_volatile [(match_operand 0 "memory_operand")]
19569 (define_insn "*rstorssp<mode>"
19570 [(unspec_volatile [(match_operand:P 0 "memory_operand" "m")]
19574 [(set_attr "length" "5")
19575 (set_attr "type" "other")])
19577 (define_insn "wrss<mode>"
19578 [(unspec_volatile [(match_operand:SWI48x 0 "register_operand" "r")
19579 (match_operand:SWI48x 1 "memory_operand" "m")]
19582 "wrss<mskmodesuffix>\t%0, %1"
19583 [(set_attr "length" "3")
19584 (set_attr "type" "other")])
19586 (define_insn "wruss<mode>"
19587 [(unspec_volatile [(match_operand:SWI48x 0 "register_operand" "r")
19588 (match_operand:SWI48x 1 "memory_operand" "m")]
19591 "wruss<mskmodesuffix>\t%0, %1"
19592 [(set_attr "length" "4")
19593 (set_attr "type" "other")])
19595 (define_insn "setssbsy"
19596 [(unspec_volatile [(const_int 0)] UNSPECV_SETSSBSY)]
19599 [(set_attr "length" "4")
19600 (set_attr "type" "other")])
19602 (define_expand "clrssbsy"
19603 [(unspec_volatile [(match_operand 0 "memory_operand")]
19607 (define_insn "*clrssbsy<mode>"
19608 [(unspec_volatile [(match_operand:P 0 "memory_operand" "m")]
19612 [(set_attr "length" "4")
19613 (set_attr "type" "other")])
19615 (define_insn "nop_endbr"
19616 [(unspec_volatile [(const_int 0)] UNSPECV_NOP_ENDBR)]
19617 "(flag_cf_protection & CF_BRANCH)"
19619 return TARGET_64BIT ? "endbr64" : "endbr32";
19621 [(set_attr "length" "4")
19622 (set_attr "length_immediate" "0")
19623 (set_attr "modrm" "0")])
19626 (define_expand "xbegin"
19627 [(set (match_operand:SI 0 "register_operand")
19628 (unspec_volatile:SI [(const_int 0)] UNSPECV_XBEGIN))]
19631 rtx_code_label *label = gen_label_rtx ();
19633 /* xbegin is emitted as jump_insn, so reload won't be able
19634 to reload its operand. Force the value into AX hard register. */
19635 rtx ax_reg = gen_rtx_REG (SImode, AX_REG);
19636 emit_move_insn (ax_reg, constm1_rtx);
19638 emit_jump_insn (gen_xbegin_1 (ax_reg, label));
19640 emit_label (label);
19641 LABEL_NUSES (label) = 1;
19643 emit_move_insn (operands[0], ax_reg);
19648 (define_insn "xbegin_1"
19650 (if_then_else (ne (unspec [(const_int 0)] UNSPEC_XBEGIN_ABORT)
19652 (label_ref (match_operand 1))
19654 (set (match_operand:SI 0 "register_operand" "+a")
19655 (unspec_volatile:SI [(match_dup 0)] UNSPECV_XBEGIN))]
19658 [(set_attr "type" "other")
19659 (set_attr "length" "6")])
19661 (define_insn "xend"
19662 [(unspec_volatile [(const_int 0)] UNSPECV_XEND)]
19665 [(set_attr "type" "other")
19666 (set_attr "length" "3")])
19668 (define_insn "xabort"
19669 [(unspec_volatile [(match_operand:SI 0 "const_0_to_255_operand" "n")]
19673 [(set_attr "type" "other")
19674 (set_attr "length" "3")])
19676 (define_expand "xtest"
19677 [(set (match_operand:QI 0 "register_operand")
19678 (unspec_volatile:QI [(const_int 0)] UNSPECV_XTEST))]
19681 emit_insn (gen_xtest_1 ());
19683 ix86_expand_setcc (operands[0], NE,
19684 gen_rtx_REG (CCZmode, FLAGS_REG), const0_rtx);
19688 (define_insn "xtest_1"
19689 [(set (reg:CCZ FLAGS_REG)
19690 (unspec_volatile:CCZ [(const_int 0)] UNSPECV_XTEST))]
19693 [(set_attr "type" "other")
19694 (set_attr "length" "3")])
19696 (define_insn "clwb"
19697 [(unspec_volatile [(match_operand 0 "address_operand" "p")]
19701 [(set_attr "type" "sse")
19702 (set_attr "atom_sse_attr" "fence")
19703 (set_attr "memory" "unknown")])
19705 (define_insn "clflushopt"
19706 [(unspec_volatile [(match_operand 0 "address_operand" "p")]
19707 UNSPECV_CLFLUSHOPT)]
19708 "TARGET_CLFLUSHOPT"
19710 [(set_attr "type" "sse")
19711 (set_attr "atom_sse_attr" "fence")
19712 (set_attr "memory" "unknown")])
19714 ;; MONITORX and MWAITX
19715 (define_insn "mwaitx"
19716 [(unspec_volatile [(match_operand:SI 0 "register_operand" "c")
19717 (match_operand:SI 1 "register_operand" "a")
19718 (match_operand:SI 2 "register_operand" "b")]
19721 ;; 64bit version is "mwaitx %rax,%rcx,%rbx". But only lower 32bits are used.
19722 ;; Since 32bit register operands are implicitly zero extended to 64bit,
19723 ;; we only need to set up 32bit registers.
19725 [(set_attr "length" "3")])
19727 (define_insn "monitorx_<mode>"
19728 [(unspec_volatile [(match_operand:P 0 "register_operand" "a")
19729 (match_operand:SI 1 "register_operand" "c")
19730 (match_operand:SI 2 "register_operand" "d")]
19733 ;; 64bit version is "monitorx %rax,%rcx,%rdx". But only lower 32bits in
19734 ;; RCX and RDX are used. Since 32bit register operands are implicitly
19735 ;; zero extended to 64bit, we only need to set up 32bit registers.
19737 [(set (attr "length")
19738 (symbol_ref ("(Pmode != word_mode) + 3")))])
19741 (define_insn "clzero_<mode>"
19742 [(unspec_volatile [(match_operand: P 0 "register_operand" "a")]
19746 [(set_attr "length" "3")
19747 (set_attr "memory" "unknown")])
19749 ;; RDPKRU and WRPKRU
19751 (define_expand "rdpkru"
19753 [(set (match_operand:SI 0 "register_operand")
19754 (unspec_volatile:SI [(match_dup 1)] UNSPECV_PKU))
19755 (set (match_dup 2) (const_int 0))])]
19758 operands[1] = force_reg (SImode, const0_rtx);
19759 operands[2] = gen_reg_rtx (SImode);
19762 (define_insn "*rdpkru"
19763 [(set (match_operand:SI 0 "register_operand" "=a")
19764 (unspec_volatile:SI [(match_operand:SI 2 "register_operand" "c")]
19766 (set (match_operand:SI 1 "register_operand" "=d")
19770 [(set_attr "type" "other")])
19772 (define_expand "wrpkru"
19773 [(unspec_volatile:SI
19774 [(match_operand:SI 0 "register_operand")
19775 (match_dup 1) (match_dup 2)] UNSPECV_PKU)]
19778 operands[1] = force_reg (SImode, const0_rtx);
19779 operands[2] = force_reg (SImode, const0_rtx);
19782 (define_insn "*wrpkru"
19783 [(unspec_volatile:SI
19784 [(match_operand:SI 0 "register_operand" "a")
19785 (match_operand:SI 1 "register_operand" "d")
19786 (match_operand:SI 2 "register_operand" "c")] UNSPECV_PKU)]
19789 [(set_attr "type" "other")])
19791 (define_insn "rdpid"
19792 [(set (match_operand:SI 0 "register_operand" "=r")
19793 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDPID))]
19794 "!TARGET_64BIT && TARGET_RDPID"
19796 [(set_attr "type" "other")])
19798 (define_insn "rdpid_rex64"
19799 [(set (match_operand:DI 0 "register_operand" "=r")
19800 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDPID))]
19801 "TARGET_64BIT && TARGET_RDPID"
19803 [(set_attr "type" "other")])
19805 ;; Intirinsics for > i486
19807 (define_insn "wbinvd"
19808 [(unspec_volatile [(const_int 0)] UNSPECV_WBINVD)]
19811 [(set_attr "type" "other")])
19813 (define_insn "wbnoinvd"
19814 [(unspec_volatile [(const_int 0)] UNSPECV_WBNOINVD)]
19817 [(set_attr "type" "other")])
19819 ;; MOVDIRI and MOVDIR64B
19821 (define_insn "movdiri<mode>"
19822 [(unspec_volatile:SWI48 [(match_operand:SWI48 0 "memory_operand" "m")
19823 (match_operand:SWI48 1 "register_operand" "r")]
19826 "movdiri\t{%1, %0|%0, %1}"
19827 [(set_attr "type" "other")])
19829 (define_insn "movdir64b_<mode>"
19830 [(unspec_volatile:XI [(match_operand:P 0 "register_operand" "r")
19831 (match_operand:XI 1 "memory_operand")]
19832 UNSPECV_MOVDIR64B)]
19834 "movdir64b\t{%1, %0|%0, %1}"
19835 [(set_attr "type" "other")])
19839 (define_insn "umwait"
19840 [(set (reg:CCC FLAGS_REG)
19841 (unspec_volatile:CCC [(match_operand:SI 0 "register_operand" "r")
19842 (match_operand:DI 1 "register_operand" "A")]
19844 "!TARGET_64BIT && TARGET_WAITPKG"
19846 [(set_attr "length" "3")])
19848 (define_insn "umwait_rex64"
19849 [(set (reg:CCC FLAGS_REG)
19850 (unspec_volatile:CCC [(match_operand:SI 0 "register_operand" "r")
19851 (match_operand:SI 1 "register_operand" "a")
19852 (match_operand:SI 2 "register_operand" "d")]
19854 "TARGET_64BIT && TARGET_WAITPKG"
19856 [(set_attr "length" "3")])
19858 (define_insn "umonitor_<mode>"
19859 [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
19863 [(set (attr "length")
19864 (symbol_ref ("(Pmode != word_mode) + 3")))])
19866 (define_insn "tpause"
19867 [(set (reg:CCC FLAGS_REG)
19868 (unspec_volatile:CCC [(match_operand:SI 0 "register_operand" "r")
19869 (match_operand:DI 1 "register_operand" "A")]
19871 "!TARGET_64BIT && TARGET_WAITPKG"
19873 [(set_attr "length" "3")])
19875 (define_insn "tpause_rex64"
19876 [(set (reg:CCC FLAGS_REG)
19877 (unspec_volatile:CCC [(match_operand:SI 0 "register_operand" "r")
19878 (match_operand:SI 1 "register_operand" "a")
19879 (match_operand:SI 2 "register_operand" "d")]
19881 "TARGET_64BIT && TARGET_WAITPKG"
19883 [(set_attr "length" "3")])
19885 (define_insn "cldemote"
19886 [(unspec_volatile[(match_operand 0 "address_operand" "p")]
19890 [(set_attr "type" "other")
19891 (set_attr "memory" "unknown")])
19893 (define_insn "speculation_barrier"
19894 [(unspec_volatile [(const_int 0)] UNSPECV_SPECULATION_BARRIER)]
19897 [(set_attr "type" "other")
19898 (set_attr "length" "3")])
19902 (include "sync.md")