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 MPX or NOTRACK prefix for jxx/call/ret instructions if required.
67 (define_c_enum "unspec" [
68 ;; Relocation specifiers
79 UNSPEC_MACHOPIC_OFFSET
88 UNSPEC_MEMORY_BLOCKAGE
98 ;; Other random patterns
107 UNSPEC_LD_MPIC ; load_macho_picbase
109 UNSPEC_DIV_ALREADY_SPLIT
115 UNSPEC_INSN_FALSE_DEP
118 ;; For SSE/MMX support:
126 ;; Generic math support
128 UNSPEC_IEEE_MIN ; not commutative
129 UNSPEC_IEEE_MAX ; not commutative
131 ;; x87 Floating point
147 UNSPEC_FRNDINT_MASK_PM
151 ;; x87 Double output FP
176 ;; For LZCNT suppoprt
198 UNSPEC_INTERRUPT_RETURN
201 (define_c_enum "unspecv" [
205 UNSPECV_PROBE_STACK_RANGE
208 UNSPECV_SPLIT_STACK_RETURN
214 UNSPECV_LLWP_INTRINSIC
215 UNSPECV_SLWP_INTRINSIC
216 UNSPECV_LWPVAL_INTRINSIC
217 UNSPECV_LWPINS_INTRINSIC
241 ;; For atomic compound assignments.
247 ;; For RDRAND support
250 ;; For RDSEED support
264 ;; For CLFLUSHOPT support
267 ;; For MONITORX and MWAITX support
271 ;; For CLZERO support
274 ;; For RDPKRU and WRPKRU support
292 ;; Constants to represent rounding modes in the ROUND instruction
301 ;; Constants to represent AVX512F embeded rounding
303 [(ROUND_NEAREST_INT 0)
311 ;; Constants to represent pcomtrue/pcomfalse variants
321 ;; Constants used in the XOP pperm instruction
323 [(PPERM_SRC 0x00) /* copy source */
324 (PPERM_INVERT 0x20) /* invert source */
325 (PPERM_REVERSE 0x40) /* bit reverse source */
326 (PPERM_REV_INV 0x60) /* bit reverse & invert src */
327 (PPERM_ZERO 0x80) /* all 0's */
328 (PPERM_ONES 0xa0) /* all 1's */
329 (PPERM_SIGN 0xc0) /* propagate sign bit */
330 (PPERM_INV_SIGN 0xe0) /* invert & propagate sign */
331 (PPERM_SRC1 0x00) /* use first source byte */
332 (PPERM_SRC2 0x10) /* use second source byte */
335 ;; Registers by name.
418 (FIRST_PSEUDO_REG 81)
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,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 mpxmov,mpxmk,mpxchk,mpxld,mpxst"
455 (const_string "other"))
457 ;; Main data type used by the insn
459 "unknown,none,QI,HI,SI,DI,TI,OI,XI,SF,DF,XF,TF,V16SF,V8SF,V4DF,V4SF,
461 (const_string "unknown"))
463 ;; The CPU unit operations uses.
464 (define_attr "unit" "integer,i387,sse,mmx,unknown"
465 (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,
466 fxch,fistp,fisttp,frndint")
467 (const_string "i387")
468 (eq_attr "type" "sse,ssemov,sseadd,sseadd1,sseiadd,sseiadd1,
469 ssemul,sseimul,ssediv,sselog,sselog1,
470 sseishft,sseishft1,ssecmp,ssecomi,
471 ssecvt,ssecvt1,sseicvt,sseins,
472 sseshuf,sseshuf1,ssemuladd,sse4arg,mskmov")
474 (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
476 (eq_attr "type" "other")
477 (const_string "unknown")]
478 (const_string "integer")))
480 ;; The (bounding maximum) length of an instruction immediate.
481 (define_attr "length_immediate" ""
482 (cond [(eq_attr "type" "incdec,setcc,icmov,str,lea,other,multi,idiv,leave,
483 bitmanip,imulx,msklog,mskmov,mpxmk,mpxmov,mpxchk,
486 (eq_attr "unit" "i387,sse,mmx")
488 (eq_attr "type" "alu,alu1,negnot,imovx,ishift,ishiftx,ishift1,
489 rotate,rotatex,rotate1,imul,icmp,push,pop")
490 (symbol_ref "ix86_attr_length_immediate_default (insn, true)")
491 (eq_attr "type" "imov,test")
492 (symbol_ref "ix86_attr_length_immediate_default (insn, false)")
493 (eq_attr "type" "call")
494 (if_then_else (match_operand 0 "constant_call_address_operand")
497 (eq_attr "type" "callv")
498 (if_then_else (match_operand 1 "constant_call_address_operand")
501 ;; We don't know the size before shorten_branches. Expect
502 ;; the instruction to fit for better scheduling.
503 (eq_attr "type" "ibr")
506 (symbol_ref "/* Update immediate_length and other attributes! */
507 gcc_unreachable (),1")))
509 ;; The (bounding maximum) length of an instruction address.
510 (define_attr "length_address" ""
511 (cond [(eq_attr "type" "str,other,multi,fxch")
513 (and (eq_attr "type" "call")
514 (match_operand 0 "constant_call_address_operand"))
516 (and (eq_attr "type" "callv")
517 (match_operand 1 "constant_call_address_operand"))
520 (symbol_ref "ix86_attr_length_address_default (insn)")))
522 ;; Set when length prefix is used.
523 (define_attr "prefix_data16" ""
524 (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
526 (eq_attr "mode" "HI")
528 (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF,TI"))
533 ;; Set when string REP prefix is used.
534 (define_attr "prefix_rep" ""
535 (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
537 (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
539 (and (eq_attr "type" "ibr,call,callv")
540 (match_test "ix86_bnd_prefixed_insn_p (insn)"))
545 ;; Set when 0f opcode prefix is used.
546 (define_attr "prefix_0f" ""
548 (ior (eq_attr "type" "imovx,setcc,icmov,bitmanip,msklog,mskmov,
549 mpxmk,mpxmov,mpxchk,mpxld,mpxst")
550 (eq_attr "unit" "sse,mmx"))
554 ;; Set when REX opcode prefix is used.
555 (define_attr "prefix_rex" ""
556 (cond [(not (match_test "TARGET_64BIT"))
558 (and (eq_attr "mode" "DI")
559 (and (eq_attr "type" "!push,pop,call,callv,leave,ibr")
560 (eq_attr "unit" "!mmx")))
562 (and (eq_attr "mode" "QI")
563 (match_test "x86_extended_QIreg_mentioned_p (insn)"))
565 (match_test "x86_extended_reg_mentioned_p (insn)")
567 (and (eq_attr "type" "imovx")
568 (match_operand:QI 1 "ext_QIreg_operand"))
573 ;; There are also additional prefixes in 3DNOW, SSSE3.
574 ;; ssemuladd,sse4arg default to 0f24/0f25 and DREX byte,
575 ;; sseiadd1,ssecvt1 to 0f7a with no DREX byte.
576 ;; 3DNOW has 0f0f prefix, SSSE3 and SSE4_{1,2} 0f38/0f3a.
577 (define_attr "prefix_extra" ""
578 (cond [(eq_attr "type" "ssemuladd,sse4arg")
580 (eq_attr "type" "sseiadd1,ssecvt1")
585 ;; Set when BND opcode prefix may be used.
586 (define_attr "maybe_prefix_bnd" "" (const_int 0))
588 ;; Prefix used: original, VEX or maybe VEX.
589 (define_attr "prefix" "orig,vex,maybe_vex,evex,maybe_evex"
590 (cond [(eq_attr "mode" "OI,V8SF,V4DF")
592 (eq_attr "mode" "XI,V16SF,V8DF")
593 (const_string "evex")
595 (const_string "orig")))
597 ;; VEX W bit is used.
598 (define_attr "prefix_vex_w" "" (const_int 0))
600 ;; The length of VEX prefix
601 ;; Only instructions with 0f prefix can have 2 byte VEX prefix,
602 ;; 0f38/0f3a prefixes can't. In i386.md 0f3[8a] is
603 ;; still prefix_0f 1, with prefix_extra 1.
604 (define_attr "length_vex" ""
605 (if_then_else (and (eq_attr "prefix_0f" "1")
606 (eq_attr "prefix_extra" "0"))
607 (if_then_else (eq_attr "prefix_vex_w" "1")
608 (symbol_ref "ix86_attr_length_vex_default (insn, true, true)")
609 (symbol_ref "ix86_attr_length_vex_default (insn, true, false)"))
610 (if_then_else (eq_attr "prefix_vex_w" "1")
611 (symbol_ref "ix86_attr_length_vex_default (insn, false, true)")
612 (symbol_ref "ix86_attr_length_vex_default (insn, false, false)"))))
614 ;; 4-bytes evex prefix and 1 byte opcode.
615 (define_attr "length_evex" "" (const_int 5))
617 ;; Set when modrm byte is used.
618 (define_attr "modrm" ""
619 (cond [(eq_attr "type" "str,leave")
621 (eq_attr "unit" "i387")
623 (and (eq_attr "type" "incdec")
624 (and (not (match_test "TARGET_64BIT"))
625 (ior (match_operand:SI 1 "register_operand")
626 (match_operand:HI 1 "register_operand"))))
628 (and (eq_attr "type" "push")
629 (not (match_operand 1 "memory_operand")))
631 (and (eq_attr "type" "pop")
632 (not (match_operand 0 "memory_operand")))
634 (and (eq_attr "type" "imov")
635 (and (not (eq_attr "mode" "DI"))
636 (ior (and (match_operand 0 "register_operand")
637 (match_operand 1 "immediate_operand"))
638 (ior (and (match_operand 0 "ax_reg_operand")
639 (match_operand 1 "memory_displacement_only_operand"))
640 (and (match_operand 0 "memory_displacement_only_operand")
641 (match_operand 1 "ax_reg_operand"))))))
643 (and (eq_attr "type" "call")
644 (match_operand 0 "constant_call_address_operand"))
646 (and (eq_attr "type" "callv")
647 (match_operand 1 "constant_call_address_operand"))
649 (and (eq_attr "type" "alu,alu1,icmp,test")
650 (match_operand 0 "ax_reg_operand"))
651 (symbol_ref "(get_attr_length_immediate (insn) <= (get_attr_mode (insn) != MODE_QI))")
655 (define_attr "modrm_class" "none,incdec,op0,op01,op02,pushpop,unknown"
656 (cond [(eq_attr "modrm" "0")
657 (const_string "none")
658 (eq_attr "type" "alu,imul,ishift")
659 (const_string "op02")
660 (eq_attr "type" "imov,imovx,lea,alu1,icmp")
661 (const_string "op01")
662 (eq_attr "type" "incdec")
663 (const_string "incdec")
664 (eq_attr "type" "push,pop")
665 (const_string "pushpop")]
666 (const_string "unknown")))
668 ;; The (bounding maximum) length of an instruction in bytes.
669 ;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
670 ;; Later we may want to split them and compute proper length as for
672 (define_attr "length" ""
673 (cond [(eq_attr "type" "other,multi,fistp,frndint")
675 (eq_attr "type" "fcmp")
677 (eq_attr "unit" "i387")
679 (plus (attr "prefix_data16")
680 (attr "length_address")))
681 (ior (eq_attr "prefix" "evex")
682 (and (ior (eq_attr "prefix" "maybe_evex")
683 (eq_attr "prefix" "maybe_vex"))
684 (match_test "TARGET_AVX512F")))
685 (plus (attr "length_evex")
686 (plus (attr "length_immediate")
688 (attr "length_address"))))
689 (ior (eq_attr "prefix" "vex")
690 (and (ior (eq_attr "prefix" "maybe_vex")
691 (eq_attr "prefix" "maybe_evex"))
692 (match_test "TARGET_AVX")))
693 (plus (attr "length_vex")
694 (plus (attr "length_immediate")
696 (attr "length_address"))))]
697 (plus (plus (attr "modrm")
698 (plus (attr "prefix_0f")
699 (plus (attr "prefix_rex")
700 (plus (attr "prefix_extra")
702 (plus (attr "prefix_rep")
703 (plus (attr "prefix_data16")
704 (plus (attr "length_immediate")
705 (attr "length_address")))))))
707 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
708 ;; `store' if there is a simple memory reference therein, or `unknown'
709 ;; if the instruction is complex.
711 (define_attr "memory" "none,load,store,both,unknown"
712 (cond [(eq_attr "type" "other,multi,str,lwp")
713 (const_string "unknown")
714 (eq_attr "type" "lea,fcmov,fpspc,mpxmk,mpxchk")
715 (const_string "none")
716 (eq_attr "type" "fistp,leave")
717 (const_string "both")
718 (eq_attr "type" "frndint")
719 (const_string "load")
720 (eq_attr "type" "mpxld")
721 (const_string "load")
722 (eq_attr "type" "mpxst")
723 (const_string "store")
724 (eq_attr "type" "push")
725 (if_then_else (match_operand 1 "memory_operand")
726 (const_string "both")
727 (const_string "store"))
728 (eq_attr "type" "pop")
729 (if_then_else (match_operand 0 "memory_operand")
730 (const_string "both")
731 (const_string "load"))
732 (eq_attr "type" "setcc")
733 (if_then_else (match_operand 0 "memory_operand")
734 (const_string "store")
735 (const_string "none"))
736 (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
737 (if_then_else (ior (match_operand 0 "memory_operand")
738 (match_operand 1 "memory_operand"))
739 (const_string "load")
740 (const_string "none"))
741 (eq_attr "type" "ibr")
742 (if_then_else (match_operand 0 "memory_operand")
743 (const_string "load")
744 (const_string "none"))
745 (eq_attr "type" "call")
746 (if_then_else (match_operand 0 "constant_call_address_operand")
747 (const_string "none")
748 (const_string "load"))
749 (eq_attr "type" "callv")
750 (if_then_else (match_operand 1 "constant_call_address_operand")
751 (const_string "none")
752 (const_string "load"))
753 (and (eq_attr "type" "alu1,negnot,ishift1,sselog1,sseshuf1")
754 (match_operand 1 "memory_operand"))
755 (const_string "both")
756 (and (match_operand 0 "memory_operand")
757 (match_operand 1 "memory_operand"))
758 (const_string "both")
759 (match_operand 0 "memory_operand")
760 (const_string "store")
761 (match_operand 1 "memory_operand")
762 (const_string "load")
764 "!alu1,negnot,ishift1,
765 imov,imovx,icmp,test,bitmanip,
767 sse,ssemov,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,
768 sselog1,sseshuf1,sseadd1,sseiadd1,sseishft1,
769 mmx,mmxmov,mmxcmp,mmxcvt,mskmov,msklog,mpxmov")
770 (match_operand 2 "memory_operand"))
771 (const_string "load")
772 (and (eq_attr "type" "icmov,ssemuladd,sse4arg")
773 (match_operand 3 "memory_operand"))
774 (const_string "load")
776 (const_string "none")))
778 ;; Indicates if an instruction has both an immediate and a displacement.
780 (define_attr "imm_disp" "false,true,unknown"
781 (cond [(eq_attr "type" "other,multi")
782 (const_string "unknown")
783 (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
784 (and (match_operand 0 "memory_displacement_operand")
785 (match_operand 1 "immediate_operand")))
786 (const_string "true")
787 (and (eq_attr "type" "alu,ishift,ishiftx,rotate,rotatex,imul,idiv")
788 (and (match_operand 0 "memory_displacement_operand")
789 (match_operand 2 "immediate_operand")))
790 (const_string "true")
792 (const_string "false")))
794 ;; Indicates if an FP operation has an integer source.
796 (define_attr "fp_int_src" "false,true"
797 (const_string "false"))
799 ;; Defines rounding mode of an FP operation.
801 (define_attr "i387_cw" "trunc,floor,ceil,mask_pm,uninitialized,any"
802 (const_string "any"))
804 ;; Define attribute to classify add/sub insns that consumes carry flag (CF)
805 (define_attr "use_carry" "0,1" (const_string "0"))
807 ;; Define attribute to indicate unaligned ssemov insns
808 (define_attr "movu" "0,1" (const_string "0"))
810 ;; Used to control the "enabled" attribute on a per-instruction basis.
811 (define_attr "isa" "base,x64,x64_sse4,x64_sse4_noavx,x64_avx,nox64,
812 sse2,sse2_noavx,sse3,sse4,sse4_noavx,avx,noavx,
813 avx2,noavx2,bmi,bmi2,fma4,fma,avx512f,noavx512f,
814 avx512bw,noavx512bw,avx512dq,noavx512dq,
815 avx512vl,noavx512vl,x64_avx512dq,x64_avx512bw"
816 (const_string "base"))
818 (define_attr "enabled" ""
819 (cond [(eq_attr "isa" "x64") (symbol_ref "TARGET_64BIT")
820 (eq_attr "isa" "x64_sse4")
821 (symbol_ref "TARGET_64BIT && TARGET_SSE4_1")
822 (eq_attr "isa" "x64_sse4_noavx")
823 (symbol_ref "TARGET_64BIT && TARGET_SSE4_1 && !TARGET_AVX")
824 (eq_attr "isa" "x64_avx")
825 (symbol_ref "TARGET_64BIT && TARGET_AVX")
826 (eq_attr "isa" "x64_avx512dq")
827 (symbol_ref "TARGET_64BIT && TARGET_AVX512DQ")
828 (eq_attr "isa" "x64_avx512bw")
829 (symbol_ref "TARGET_64BIT && TARGET_AVX512BW")
830 (eq_attr "isa" "nox64") (symbol_ref "!TARGET_64BIT")
831 (eq_attr "isa" "sse2") (symbol_ref "TARGET_SSE2")
832 (eq_attr "isa" "sse2_noavx")
833 (symbol_ref "TARGET_SSE2 && !TARGET_AVX")
834 (eq_attr "isa" "sse3") (symbol_ref "TARGET_SSE3")
835 (eq_attr "isa" "sse4") (symbol_ref "TARGET_SSE4_1")
836 (eq_attr "isa" "sse4_noavx")
837 (symbol_ref "TARGET_SSE4_1 && !TARGET_AVX")
838 (eq_attr "isa" "avx") (symbol_ref "TARGET_AVX")
839 (eq_attr "isa" "noavx") (symbol_ref "!TARGET_AVX")
840 (eq_attr "isa" "avx2") (symbol_ref "TARGET_AVX2")
841 (eq_attr "isa" "noavx2") (symbol_ref "!TARGET_AVX2")
842 (eq_attr "isa" "bmi") (symbol_ref "TARGET_BMI")
843 (eq_attr "isa" "bmi2") (symbol_ref "TARGET_BMI2")
844 (eq_attr "isa" "fma4") (symbol_ref "TARGET_FMA4")
845 (eq_attr "isa" "fma") (symbol_ref "TARGET_FMA")
846 (eq_attr "isa" "avx512f") (symbol_ref "TARGET_AVX512F")
847 (eq_attr "isa" "noavx512f") (symbol_ref "!TARGET_AVX512F")
848 (eq_attr "isa" "avx512bw") (symbol_ref "TARGET_AVX512BW")
849 (eq_attr "isa" "noavx512bw") (symbol_ref "!TARGET_AVX512BW")
850 (eq_attr "isa" "avx512dq") (symbol_ref "TARGET_AVX512DQ")
851 (eq_attr "isa" "noavx512dq") (symbol_ref "!TARGET_AVX512DQ")
852 (eq_attr "isa" "avx512vl") (symbol_ref "TARGET_AVX512VL")
853 (eq_attr "isa" "noavx512vl") (symbol_ref "!TARGET_AVX512VL")
857 (define_attr "preferred_for_size" "" (const_int 1))
858 (define_attr "preferred_for_speed" "" (const_int 1))
860 ;; Describe a user's asm statement.
861 (define_asm_attributes
862 [(set_attr "length" "128")
863 (set_attr "type" "multi")])
865 (define_code_iterator plusminus [plus minus])
867 (define_code_iterator sat_plusminus [ss_plus us_plus ss_minus us_minus])
869 (define_code_iterator multdiv [mult div])
871 ;; Base name for define_insn
872 (define_code_attr plusminus_insn
873 [(plus "add") (ss_plus "ssadd") (us_plus "usadd")
874 (minus "sub") (ss_minus "sssub") (us_minus "ussub")])
876 ;; Base name for insn mnemonic.
877 (define_code_attr plusminus_mnemonic
878 [(plus "add") (ss_plus "adds") (us_plus "addus")
879 (minus "sub") (ss_minus "subs") (us_minus "subus")])
880 (define_code_attr multdiv_mnemonic
881 [(mult "mul") (div "div")])
883 ;; Mark commutative operators as such in constraints.
884 (define_code_attr comm [(plus "%") (ss_plus "%") (us_plus "%")
885 (minus "") (ss_minus "") (us_minus "")])
887 ;; Mapping of max and min
888 (define_code_iterator maxmin [smax smin umax umin])
890 ;; Mapping of signed max and min
891 (define_code_iterator smaxmin [smax smin])
893 ;; Mapping of unsigned max and min
894 (define_code_iterator umaxmin [umax umin])
896 ;; Base name for integer and FP insn mnemonic
897 (define_code_attr maxmin_int [(smax "maxs") (smin "mins")
898 (umax "maxu") (umin "minu")])
899 (define_code_attr maxmin_float [(smax "max") (smin "min")])
901 (define_int_iterator IEEE_MAXMIN
905 (define_int_attr ieee_maxmin
906 [(UNSPEC_IEEE_MAX "max")
907 (UNSPEC_IEEE_MIN "min")])
909 ;; Mapping of logic operators
910 (define_code_iterator any_logic [and ior xor])
911 (define_code_iterator any_or [ior xor])
912 (define_code_iterator fpint_logic [and xor])
914 ;; Base name for insn mnemonic.
915 (define_code_attr logic [(and "and") (ior "or") (xor "xor")])
917 ;; Mapping of logic-shift operators
918 (define_code_iterator any_lshift [ashift lshiftrt])
920 ;; Mapping of shift-right operators
921 (define_code_iterator any_shiftrt [lshiftrt ashiftrt])
923 ;; Mapping of all shift operators
924 (define_code_iterator any_shift [ashift lshiftrt ashiftrt])
926 ;; Base name for define_insn
927 (define_code_attr shift_insn
928 [(ashift "ashl") (lshiftrt "lshr") (ashiftrt "ashr")])
930 ;; Base name for insn mnemonic.
931 (define_code_attr shift [(ashift "sll") (lshiftrt "shr") (ashiftrt "sar")])
932 (define_code_attr vshift [(ashift "sll") (lshiftrt "srl") (ashiftrt "sra")])
934 ;; Mapping of rotate operators
935 (define_code_iterator any_rotate [rotate rotatert])
937 ;; Base name for define_insn
938 (define_code_attr rotate_insn [(rotate "rotl") (rotatert "rotr")])
940 ;; Base name for insn mnemonic.
941 (define_code_attr rotate [(rotate "rol") (rotatert "ror")])
943 ;; Mapping of abs neg operators
944 (define_code_iterator absneg [abs neg])
946 ;; Base name for x87 insn mnemonic.
947 (define_code_attr absneg_mnemonic [(abs "abs") (neg "chs")])
949 ;; Used in signed and unsigned widening multiplications.
950 (define_code_iterator any_extend [sign_extend zero_extend])
952 ;; Prefix for insn menmonic.
953 (define_code_attr sgnprefix [(sign_extend "i") (zero_extend "")])
955 ;; Prefix for define_insn
956 (define_code_attr u [(sign_extend "") (zero_extend "u")])
957 (define_code_attr s [(sign_extend "s") (zero_extend "u")])
958 (define_code_attr u_bool [(sign_extend "false") (zero_extend "true")])
960 ;; Used in signed and unsigned truncations.
961 (define_code_iterator any_truncate [ss_truncate truncate us_truncate])
962 ;; Instruction suffix for truncations.
963 (define_code_attr trunsuffix [(ss_truncate "s") (truncate "") (us_truncate "us")])
965 ;; Used in signed and unsigned fix.
966 (define_code_iterator any_fix [fix unsigned_fix])
967 (define_code_attr fixsuffix [(fix "") (unsigned_fix "u")])
969 ;; Used in signed and unsigned float.
970 (define_code_iterator any_float [float unsigned_float])
971 (define_code_attr floatsuffix [(float "") (unsigned_float "u")])
973 ;; All integer modes.
974 (define_mode_iterator SWI1248x [QI HI SI DI])
976 ;; All integer modes without QImode.
977 (define_mode_iterator SWI248x [HI SI DI])
979 ;; All integer modes without QImode and HImode.
980 (define_mode_iterator SWI48x [SI DI])
982 ;; All integer modes without SImode and DImode.
983 (define_mode_iterator SWI12 [QI HI])
985 ;; All integer modes without DImode.
986 (define_mode_iterator SWI124 [QI HI SI])
988 ;; All integer modes without QImode and DImode.
989 (define_mode_iterator SWI24 [HI SI])
991 ;; Single word integer modes.
992 (define_mode_iterator SWI [QI HI SI (DI "TARGET_64BIT")])
994 ;; Single word integer modes without QImode.
995 (define_mode_iterator SWI248 [HI SI (DI "TARGET_64BIT")])
997 ;; Single word integer modes without QImode and HImode.
998 (define_mode_iterator SWI48 [SI (DI "TARGET_64BIT")])
1000 ;; All math-dependant single and double word integer modes.
1001 (define_mode_iterator SDWIM [(QI "TARGET_QIMODE_MATH")
1002 (HI "TARGET_HIMODE_MATH")
1003 SI DI (TI "TARGET_64BIT")])
1005 ;; Math-dependant single word integer modes.
1006 (define_mode_iterator SWIM [(QI "TARGET_QIMODE_MATH")
1007 (HI "TARGET_HIMODE_MATH")
1008 SI (DI "TARGET_64BIT")])
1010 ;; Math-dependant integer modes without DImode.
1011 (define_mode_iterator SWIM124 [(QI "TARGET_QIMODE_MATH")
1012 (HI "TARGET_HIMODE_MATH")
1015 ;; Math-dependant integer modes with DImode.
1016 (define_mode_iterator SWIM1248x [(QI "TARGET_QIMODE_MATH")
1017 (HI "TARGET_HIMODE_MATH")
1018 SI (DI "(TARGET_STV && TARGET_SSE2) || TARGET_64BIT")])
1020 ;; Math-dependant single word integer modes without QImode.
1021 (define_mode_iterator SWIM248 [(HI "TARGET_HIMODE_MATH")
1022 SI (DI "TARGET_64BIT")])
1024 ;; Double word integer modes.
1025 (define_mode_iterator DWI [(DI "!TARGET_64BIT")
1026 (TI "TARGET_64BIT")])
1028 ;; GET_MODE_SIZE for selected modes. As GET_MODE_SIZE is not
1029 ;; compile time constant, it is faster to use <MODE_SIZE> than
1030 ;; GET_MODE_SIZE (<MODE>mode). For XFmode which depends on
1031 ;; command line options just use GET_MODE_SIZE macro.
1032 (define_mode_attr MODE_SIZE [(QI "1") (HI "2") (SI "4") (DI "8") (TI "16")
1033 (SF "4") (DF "8") (XF "GET_MODE_SIZE (XFmode)")
1034 (V16QI "16") (V32QI "32") (V64QI "64")
1035 (V8HI "16") (V16HI "32") (V32HI "64")
1036 (V4SI "16") (V8SI "32") (V16SI "64")
1037 (V2DI "16") (V4DI "32") (V8DI "64")
1038 (V1TI "16") (V2TI "32") (V4TI "64")
1039 (V2DF "16") (V4DF "32") (V8DF "64")
1040 (V4SF "16") (V8SF "32") (V16SF "64")])
1042 ;; Double word integer modes as mode attribute.
1043 (define_mode_attr DWI [(QI "HI") (HI "SI") (SI "DI") (DI "TI")])
1044 (define_mode_attr dwi [(QI "hi") (HI "si") (SI "di") (DI "ti")])
1046 ;; LEA mode corresponding to an integer mode
1047 (define_mode_attr LEAMODE [(QI "SI") (HI "SI") (SI "SI") (DI "DI")])
1049 ;; Half mode for double word integer modes.
1050 (define_mode_iterator DWIH [(SI "!TARGET_64BIT")
1051 (DI "TARGET_64BIT")])
1054 (define_mode_iterator BND [(BND32 "!TARGET_LP64")
1055 (BND64 "TARGET_LP64")])
1057 ;; Pointer mode corresponding to bound mode.
1058 (define_mode_attr bnd_ptr [(BND32 "SI") (BND64 "DI")])
1061 (define_int_iterator BNDCHECK [UNSPEC_BNDCL UNSPEC_BNDCU UNSPEC_BNDCN])
1064 (define_int_attr bndcheck [(UNSPEC_BNDCL "cl")
1066 (UNSPEC_BNDCN "cn")])
1068 ;; Instruction suffix for integer modes.
1069 (define_mode_attr imodesuffix [(QI "b") (HI "w") (SI "l") (DI "q")])
1071 ;; Instruction suffix for masks.
1072 (define_mode_attr mskmodesuffix [(QI "b") (HI "w") (SI "d") (DI "q")])
1074 ;; Pointer size prefix for integer modes (Intel asm dialect)
1075 (define_mode_attr iptrsize [(QI "BYTE")
1080 ;; Register class for integer modes.
1081 (define_mode_attr r [(QI "q") (HI "r") (SI "r") (DI "r")])
1083 ;; Immediate operand constraint for integer modes.
1084 (define_mode_attr i [(QI "n") (HI "n") (SI "e") (DI "e")])
1086 ;; General operand constraint for word modes.
1087 (define_mode_attr g [(QI "qmn") (HI "rmn") (SI "rme") (DI "rme")])
1089 ;; Immediate operand constraint for double integer modes.
1090 (define_mode_attr di [(SI "nF") (DI "Wd")])
1092 ;; Immediate operand constraint for shifts.
1093 (define_mode_attr S [(QI "I") (HI "I") (SI "I") (DI "J") (TI "O")])
1095 ;; Print register name in the specified mode.
1096 (define_mode_attr k [(QI "b") (HI "w") (SI "k") (DI "q")])
1098 ;; General operand predicate for integer modes.
1099 (define_mode_attr general_operand
1100 [(QI "general_operand")
1101 (HI "general_operand")
1102 (SI "x86_64_general_operand")
1103 (DI "x86_64_general_operand")
1104 (TI "x86_64_general_operand")])
1106 ;; General operand predicate for integer modes, where for TImode
1107 ;; we need both words of the operand to be general operands.
1108 (define_mode_attr general_hilo_operand
1109 [(QI "general_operand")
1110 (HI "general_operand")
1111 (SI "x86_64_general_operand")
1112 (DI "x86_64_general_operand")
1113 (TI "x86_64_hilo_general_operand")])
1115 ;; General sign extend operand predicate for integer modes,
1116 ;; which disallows VOIDmode operands and thus it is suitable
1117 ;; for use inside sign_extend.
1118 (define_mode_attr general_sext_operand
1119 [(QI "sext_operand")
1121 (SI "x86_64_sext_operand")
1122 (DI "x86_64_sext_operand")])
1124 ;; General sign/zero extend operand predicate for integer modes.
1125 (define_mode_attr general_szext_operand
1126 [(QI "general_operand")
1127 (HI "general_operand")
1128 (SI "x86_64_szext_general_operand")
1129 (DI "x86_64_szext_general_operand")])
1131 ;; Immediate operand predicate for integer modes.
1132 (define_mode_attr immediate_operand
1133 [(QI "immediate_operand")
1134 (HI "immediate_operand")
1135 (SI "x86_64_immediate_operand")
1136 (DI "x86_64_immediate_operand")])
1138 ;; Nonmemory operand predicate for integer modes.
1139 (define_mode_attr nonmemory_operand
1140 [(QI "nonmemory_operand")
1141 (HI "nonmemory_operand")
1142 (SI "x86_64_nonmemory_operand")
1143 (DI "x86_64_nonmemory_operand")])
1145 ;; Operand predicate for shifts.
1146 (define_mode_attr shift_operand
1147 [(QI "nonimmediate_operand")
1148 (HI "nonimmediate_operand")
1149 (SI "nonimmediate_operand")
1150 (DI "shiftdi_operand")
1151 (TI "register_operand")])
1153 ;; Operand predicate for shift argument.
1154 (define_mode_attr shift_immediate_operand
1155 [(QI "const_1_to_31_operand")
1156 (HI "const_1_to_31_operand")
1157 (SI "const_1_to_31_operand")
1158 (DI "const_1_to_63_operand")])
1160 ;; Input operand predicate for arithmetic left shifts.
1161 (define_mode_attr ashl_input_operand
1162 [(QI "nonimmediate_operand")
1163 (HI "nonimmediate_operand")
1164 (SI "nonimmediate_operand")
1165 (DI "ashldi_input_operand")
1166 (TI "reg_or_pm1_operand")])
1168 ;; SSE and x87 SFmode and DFmode floating point modes
1169 (define_mode_iterator MODEF [SF DF])
1171 ;; All x87 floating point modes
1172 (define_mode_iterator X87MODEF [SF DF XF])
1174 ;; SSE instruction suffix for various modes
1175 (define_mode_attr ssemodesuffix
1176 [(SF "ss") (DF "sd")
1177 (V16SF "ps") (V8DF "pd")
1178 (V8SF "ps") (V4DF "pd")
1179 (V4SF "ps") (V2DF "pd")
1180 (V16QI "b") (V8HI "w") (V4SI "d") (V2DI "q")
1181 (V32QI "b") (V16HI "w") (V8SI "d") (V4DI "q")
1182 (V64QI "b") (V32HI "w") (V16SI "d") (V8DI "q")])
1184 ;; SSE vector suffix for floating point modes
1185 (define_mode_attr ssevecmodesuffix [(SF "ps") (DF "pd")])
1187 ;; SSE vector mode corresponding to a scalar mode
1188 (define_mode_attr ssevecmode
1189 [(QI "V16QI") (HI "V8HI") (SI "V4SI") (DI "V2DI") (SF "V4SF") (DF "V2DF")])
1190 (define_mode_attr ssevecmodelower
1191 [(QI "v16qi") (HI "v8hi") (SI "v4si") (DI "v2di") (SF "v4sf") (DF "v2df")])
1193 ;; AVX512F vector mode corresponding to a scalar mode
1194 (define_mode_attr avx512fvecmode
1195 [(QI "V64QI") (HI "V32HI") (SI "V16SI") (DI "V8DI") (SF "V16SF") (DF "V8DF")])
1197 ;; Instruction suffix for REX 64bit operators.
1198 (define_mode_attr rex64suffix [(SI "") (DI "{q}")])
1200 ;; This mode iterator allows :P to be used for patterns that operate on
1201 ;; pointer-sized quantities. Exactly one of the two alternatives will match.
1202 (define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
1204 ;; This mode iterator allows :W to be used for patterns that operate on
1205 ;; word_mode sized quantities.
1206 (define_mode_iterator W
1207 [(SI "word_mode == SImode") (DI "word_mode == DImode")])
1209 ;; This mode iterator allows :PTR to be used for patterns that operate on
1210 ;; ptr_mode sized quantities.
1211 (define_mode_iterator PTR
1212 [(SI "ptr_mode == SImode") (DI "ptr_mode == DImode")])
1214 ;; Scheduling descriptions
1216 (include "pentium.md")
1219 (include "athlon.md")
1220 (include "bdver1.md")
1221 (include "bdver3.md")
1222 (include "btver2.md")
1223 (include "znver1.md")
1224 (include "geode.md")
1227 (include "core2.md")
1228 (include "haswell.md")
1231 ;; Operand and operator predicates and constraints
1233 (include "predicates.md")
1234 (include "constraints.md")
1237 ;; Compare and branch/compare and store instructions.
1239 (define_expand "cbranch<mode>4"
1240 [(set (reg:CC FLAGS_REG)
1241 (compare:CC (match_operand:SDWIM 1 "nonimmediate_operand")
1242 (match_operand:SDWIM 2 "<general_operand>")))
1243 (set (pc) (if_then_else
1244 (match_operator 0 "ordered_comparison_operator"
1245 [(reg:CC FLAGS_REG) (const_int 0)])
1246 (label_ref (match_operand 3))
1250 if (MEM_P (operands[1]) && MEM_P (operands[2]))
1251 operands[1] = force_reg (<MODE>mode, operands[1]);
1252 ix86_expand_branch (GET_CODE (operands[0]),
1253 operands[1], operands[2], operands[3]);
1257 (define_expand "cstore<mode>4"
1258 [(set (reg:CC FLAGS_REG)
1259 (compare:CC (match_operand:SWIM 2 "nonimmediate_operand")
1260 (match_operand:SWIM 3 "<general_operand>")))
1261 (set (match_operand:QI 0 "register_operand")
1262 (match_operator 1 "ordered_comparison_operator"
1263 [(reg:CC FLAGS_REG) (const_int 0)]))]
1266 if (MEM_P (operands[2]) && MEM_P (operands[3]))
1267 operands[2] = force_reg (<MODE>mode, operands[2]);
1268 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1269 operands[2], operands[3]);
1273 (define_expand "cmp<mode>_1"
1274 [(set (reg:CC FLAGS_REG)
1275 (compare:CC (match_operand:SWI48 0 "nonimmediate_operand")
1276 (match_operand:SWI48 1 "<general_operand>")))])
1278 (define_mode_iterator SWI1248_AVX512BWDQ2_64
1279 [(QI "TARGET_AVX512DQ") (HI "TARGET_AVX512DQ")
1280 (SI "TARGET_AVX512BW") (DI "TARGET_AVX512BW && TARGET_64BIT")])
1282 (define_insn "*cmp<mode>_ccz_1"
1283 [(set (reg FLAGS_REG)
1284 (compare (match_operand:SWI1248_AVX512BWDQ2_64 0
1285 "nonimmediate_operand" "<r>,?m<r>,$k")
1286 (match_operand:SWI1248_AVX512BWDQ2_64 1 "const0_operand")))]
1287 "ix86_match_ccmode (insn, CCZmode)"
1289 test{<imodesuffix>}\t%0, %0
1290 cmp{<imodesuffix>}\t{%1, %0|%0, %1}
1291 ktest<mskmodesuffix>\t%0, %0"
1292 [(set_attr "type" "test,icmp,msklog")
1293 (set_attr "length_immediate" "0,1,*")
1294 (set_attr "modrm_class" "op0,unknown,*")
1295 (set_attr "prefix" "*,*,vex")
1296 (set_attr "mode" "<MODE>")])
1298 (define_insn "*cmp<mode>_ccno_1"
1299 [(set (reg FLAGS_REG)
1300 (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>,?m<r>")
1301 (match_operand:SWI 1 "const0_operand")))]
1302 "ix86_match_ccmode (insn, CCNOmode)"
1304 test{<imodesuffix>}\t%0, %0
1305 cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1306 [(set_attr "type" "test,icmp")
1307 (set_attr "length_immediate" "0,1")
1308 (set_attr "modrm_class" "op0,unknown")
1309 (set_attr "mode" "<MODE>")])
1311 (define_insn "*cmp<mode>_1"
1312 [(set (reg FLAGS_REG)
1313 (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
1314 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m")))]
1315 "ix86_match_ccmode (insn, CCmode)"
1316 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1317 [(set_attr "type" "icmp")
1318 (set_attr "mode" "<MODE>")])
1320 (define_insn "*cmp<mode>_minus_1"
1321 [(set (reg FLAGS_REG)
1323 (minus:SWI (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
1324 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
1326 "ix86_match_ccmode (insn, CCGOCmode)"
1327 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1328 [(set_attr "type" "icmp")
1329 (set_attr "mode" "<MODE>")])
1331 (define_insn "*cmpqi_ext_1"
1332 [(set (reg FLAGS_REG)
1334 (match_operand:QI 0 "nonimmediate_operand" "QBc,m")
1337 (match_operand 1 "ext_register_operand" "Q,Q")
1339 (const_int 8)) 0)))]
1340 "ix86_match_ccmode (insn, CCmode)"
1341 "cmp{b}\t{%h1, %0|%0, %h1}"
1342 [(set_attr "isa" "*,nox64")
1343 (set_attr "type" "icmp")
1344 (set_attr "mode" "QI")])
1346 (define_insn "*cmpqi_ext_2"
1347 [(set (reg FLAGS_REG)
1351 (match_operand 0 "ext_register_operand" "Q")
1354 (match_operand:QI 1 "const0_operand")))]
1355 "ix86_match_ccmode (insn, CCNOmode)"
1357 [(set_attr "type" "test")
1358 (set_attr "length_immediate" "0")
1359 (set_attr "mode" "QI")])
1361 (define_expand "cmpqi_ext_3"
1362 [(set (reg:CC FLAGS_REG)
1366 (match_operand 0 "ext_register_operand")
1369 (match_operand:QI 1 "const_int_operand")))])
1371 (define_insn "*cmpqi_ext_3"
1372 [(set (reg FLAGS_REG)
1376 (match_operand 0 "ext_register_operand" "Q,Q")
1379 (match_operand:QI 1 "general_operand" "QnBc,m")))]
1380 "ix86_match_ccmode (insn, CCmode)"
1381 "cmp{b}\t{%1, %h0|%h0, %1}"
1382 [(set_attr "isa" "*,nox64")
1383 (set_attr "type" "icmp")
1384 (set_attr "mode" "QI")])
1386 (define_insn "*cmpqi_ext_4"
1387 [(set (reg FLAGS_REG)
1391 (match_operand 0 "ext_register_operand" "Q")
1396 (match_operand 1 "ext_register_operand" "Q")
1398 (const_int 8)) 0)))]
1399 "ix86_match_ccmode (insn, CCmode)"
1400 "cmp{b}\t{%h1, %h0|%h0, %h1}"
1401 [(set_attr "type" "icmp")
1402 (set_attr "mode" "QI")])
1404 ;; These implement float point compares.
1405 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
1406 ;; which would allow mix and match FP modes on the compares. Which is what
1407 ;; the old patterns did, but with many more of them.
1409 (define_expand "cbranchxf4"
1410 [(set (reg:CC FLAGS_REG)
1411 (compare:CC (match_operand:XF 1 "nonmemory_operand")
1412 (match_operand:XF 2 "nonmemory_operand")))
1413 (set (pc) (if_then_else
1414 (match_operator 0 "ix86_fp_comparison_operator"
1417 (label_ref (match_operand 3))
1421 ix86_expand_branch (GET_CODE (operands[0]),
1422 operands[1], operands[2], operands[3]);
1426 (define_expand "cstorexf4"
1427 [(set (reg:CC FLAGS_REG)
1428 (compare:CC (match_operand:XF 2 "nonmemory_operand")
1429 (match_operand:XF 3 "nonmemory_operand")))
1430 (set (match_operand:QI 0 "register_operand")
1431 (match_operator 1 "ix86_fp_comparison_operator"
1436 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1437 operands[2], operands[3]);
1441 (define_expand "cbranch<mode>4"
1442 [(set (reg:CC FLAGS_REG)
1443 (compare:CC (match_operand:MODEF 1 "cmp_fp_expander_operand")
1444 (match_operand:MODEF 2 "cmp_fp_expander_operand")))
1445 (set (pc) (if_then_else
1446 (match_operator 0 "ix86_fp_comparison_operator"
1449 (label_ref (match_operand 3))
1451 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1453 ix86_expand_branch (GET_CODE (operands[0]),
1454 operands[1], operands[2], operands[3]);
1458 (define_expand "cstore<mode>4"
1459 [(set (reg:CC FLAGS_REG)
1460 (compare:CC (match_operand:MODEF 2 "cmp_fp_expander_operand")
1461 (match_operand:MODEF 3 "cmp_fp_expander_operand")))
1462 (set (match_operand:QI 0 "register_operand")
1463 (match_operator 1 "ix86_fp_comparison_operator"
1466 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1468 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1469 operands[2], operands[3]);
1473 (define_expand "cbranchcc4"
1474 [(set (pc) (if_then_else
1475 (match_operator 0 "comparison_operator"
1476 [(match_operand 1 "flags_reg_operand")
1477 (match_operand 2 "const0_operand")])
1478 (label_ref (match_operand 3))
1482 ix86_expand_branch (GET_CODE (operands[0]),
1483 operands[1], operands[2], operands[3]);
1487 (define_expand "cstorecc4"
1488 [(set (match_operand:QI 0 "register_operand")
1489 (match_operator 1 "comparison_operator"
1490 [(match_operand 2 "flags_reg_operand")
1491 (match_operand 3 "const0_operand")]))]
1494 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1495 operands[2], operands[3]);
1500 ;; FP compares, step 1:
1501 ;; Set the FP condition codes.
1503 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
1504 ;; used to manage the reg stack popping would not be preserved.
1506 (define_insn "*cmp<mode>_0_i387"
1507 [(set (match_operand:HI 0 "register_operand" "=a")
1510 (match_operand:X87MODEF 1 "register_operand" "f")
1511 (match_operand:X87MODEF 2 "const0_operand"))]
1514 "* return output_fp_compare (insn, operands, false, false);"
1515 [(set_attr "type" "multi")
1516 (set_attr "unit" "i387")
1517 (set_attr "mode" "<MODE>")])
1519 (define_insn_and_split "*cmp<mode>_0_cc_i387"
1520 [(set (reg:CCFP FLAGS_REG)
1522 (match_operand:X87MODEF 1 "register_operand" "f")
1523 (match_operand:X87MODEF 2 "const0_operand")))
1524 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1525 "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE"
1527 "&& reload_completed"
1530 [(compare:CCFP (match_dup 1)(match_dup 2))]
1532 (set (reg:CC FLAGS_REG)
1533 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1535 [(set_attr "type" "multi")
1536 (set_attr "unit" "i387")
1537 (set_attr "mode" "<MODE>")])
1539 (define_insn "*cmpxf_i387"
1540 [(set (match_operand:HI 0 "register_operand" "=a")
1543 (match_operand:XF 1 "register_operand" "f")
1544 (match_operand:XF 2 "register_operand" "f"))]
1547 "* return output_fp_compare (insn, operands, false, false);"
1548 [(set_attr "type" "multi")
1549 (set_attr "unit" "i387")
1550 (set_attr "mode" "XF")])
1552 (define_insn_and_split "*cmpxf_cc_i387"
1553 [(set (reg:CCFP FLAGS_REG)
1555 (match_operand:XF 1 "register_operand" "f")
1556 (match_operand:XF 2 "register_operand" "f")))
1557 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1558 "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE"
1560 "&& reload_completed"
1563 [(compare:CCFP (match_dup 1)(match_dup 2))]
1565 (set (reg:CC FLAGS_REG)
1566 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1568 [(set_attr "type" "multi")
1569 (set_attr "unit" "i387")
1570 (set_attr "mode" "XF")])
1572 (define_insn "*cmp<mode>_i387"
1573 [(set (match_operand:HI 0 "register_operand" "=a")
1576 (match_operand:MODEF 1 "register_operand" "f")
1577 (match_operand:MODEF 2 "nonimmediate_operand" "fm"))]
1580 "* return output_fp_compare (insn, operands, false, false);"
1581 [(set_attr "type" "multi")
1582 (set_attr "unit" "i387")
1583 (set_attr "mode" "<MODE>")])
1585 (define_insn_and_split "*cmp<mode>_cc_i387"
1586 [(set (reg:CCFP FLAGS_REG)
1588 (match_operand:MODEF 1 "register_operand" "f")
1589 (match_operand:MODEF 2 "nonimmediate_operand" "fm")))
1590 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1591 "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE"
1593 "&& reload_completed"
1596 [(compare:CCFP (match_dup 1)(match_dup 2))]
1598 (set (reg:CC FLAGS_REG)
1599 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1601 [(set_attr "type" "multi")
1602 (set_attr "unit" "i387")
1603 (set_attr "mode" "<MODE>")])
1605 (define_insn "*cmpu<mode>_i387"
1606 [(set (match_operand:HI 0 "register_operand" "=a")
1610 (match_operand:X87MODEF 1 "register_operand" "f")
1611 (match_operand:X87MODEF 2 "register_operand" "f"))]
1615 "* return output_fp_compare (insn, operands, false, true);"
1616 [(set_attr "type" "multi")
1617 (set_attr "unit" "i387")
1618 (set_attr "mode" "<MODE>")])
1620 (define_insn_and_split "*cmpu<mode>_cc_i387"
1621 [(set (reg:CCFP FLAGS_REG)
1624 (match_operand:X87MODEF 1 "register_operand" "f")
1625 (match_operand:X87MODEF 2 "register_operand" "f"))]
1627 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1628 "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE"
1630 "&& reload_completed"
1634 [(compare:CCFP (match_dup 1)(match_dup 2))]
1637 (set (reg:CC FLAGS_REG)
1638 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1640 [(set_attr "type" "multi")
1641 (set_attr "unit" "i387")
1642 (set_attr "mode" "<MODE>")])
1644 (define_insn "*cmp<X87MODEF:mode>_<SWI24:mode>_i387"
1645 [(set (match_operand:HI 0 "register_operand" "=a")
1648 (match_operand:X87MODEF 1 "register_operand" "f")
1650 (match_operand:SWI24 2 "memory_operand" "m")))]
1653 && (TARGET_USE_<SWI24:MODE>MODE_FIOP
1654 || optimize_function_for_size_p (cfun))"
1655 "* return output_fp_compare (insn, operands, false, false);"
1656 [(set_attr "type" "multi")
1657 (set_attr "unit" "i387")
1658 (set_attr "fp_int_src" "true")
1659 (set_attr "mode" "<SWI24:MODE>")])
1661 (define_insn_and_split "*cmp<X87MODEF:mode>_<SWI24:mode>_cc_i387"
1662 [(set (reg:CCFP FLAGS_REG)
1664 (match_operand:X87MODEF 1 "register_operand" "f")
1666 (match_operand:SWI24 2 "memory_operand" "m"))))
1667 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1668 "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE
1669 && (TARGET_USE_<SWI24:MODE>MODE_FIOP
1670 || optimize_function_for_size_p (cfun))"
1672 "&& reload_completed"
1677 (float:X87MODEF (match_dup 2)))]
1679 (set (reg:CC FLAGS_REG)
1680 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1682 [(set_attr "type" "multi")
1683 (set_attr "unit" "i387")
1684 (set_attr "fp_int_src" "true")
1685 (set_attr "mode" "<SWI24:MODE>")])
1687 ;; FP compares, step 2
1688 ;; Move the fpsw to ax.
1690 (define_insn "x86_fnstsw_1"
1691 [(set (match_operand:HI 0 "register_operand" "=a")
1692 (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
1695 [(set_attr "length" "2")
1696 (set_attr "mode" "SI")
1697 (set_attr "unit" "i387")])
1699 ;; FP compares, step 3
1700 ;; Get ax into flags, general case.
1702 (define_insn "x86_sahf_1"
1703 [(set (reg:CC FLAGS_REG)
1704 (unspec:CC [(match_operand:HI 0 "register_operand" "a")]
1708 #ifndef HAVE_AS_IX86_SAHF
1710 return ASM_BYTE "0x9e";
1715 [(set_attr "length" "1")
1716 (set_attr "athlon_decode" "vector")
1717 (set_attr "amdfam10_decode" "direct")
1718 (set_attr "bdver1_decode" "direct")
1719 (set_attr "mode" "SI")])
1721 ;; Pentium Pro can do steps 1 through 3 in one go.
1722 ;; (these instructions set flags directly)
1724 (define_subst_attr "unord" "unord_subst" "" "u")
1725 (define_subst_attr "unordered" "unord_subst" "false" "true")
1727 (define_subst "unord_subst"
1728 [(set (match_operand:CCFP 0)
1729 (match_operand:CCFP 1))]
1736 (define_insn "*cmpi<unord><MODEF:mode>"
1737 [(set (reg:CCFP FLAGS_REG)
1739 (match_operand:MODEF 0 "register_operand" "f,v")
1740 (match_operand:MODEF 1 "register_ssemem_operand" "f,vm")))]
1741 "(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
1742 || (TARGET_80387 && TARGET_CMOVE)"
1744 * return output_fp_compare (insn, operands, true, <unordered>);
1745 %v<unord>comi<MODEF:ssemodesuffix>\t{%1, %0|%0, %1}"
1746 [(set_attr "type" "fcmp,ssecomi")
1747 (set_attr "prefix" "orig,maybe_vex")
1748 (set_attr "mode" "<MODEF:MODE>")
1749 (set_attr "prefix_rep" "*,0")
1750 (set (attr "prefix_data16")
1751 (cond [(eq_attr "alternative" "0")
1753 (eq_attr "mode" "DF")
1756 (const_string "0")))
1757 (set_attr "athlon_decode" "vector")
1758 (set_attr "amdfam10_decode" "direct")
1759 (set_attr "bdver1_decode" "double")
1760 (set_attr "znver1_decode" "double")
1761 (set (attr "enabled")
1763 (match_test ("SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"))
1765 (eq_attr "alternative" "0")
1766 (symbol_ref "TARGET_MIX_SSE_I387")
1767 (symbol_ref "true"))
1769 (eq_attr "alternative" "0")
1771 (symbol_ref "false"))))])
1773 (define_insn "*cmpi<unord>xf_i387"
1774 [(set (reg:CCFP FLAGS_REG)
1776 (match_operand:XF 0 "register_operand" "f")
1777 (match_operand:XF 1 "register_operand" "f")))]
1778 "TARGET_80387 && TARGET_CMOVE"
1779 "* return output_fp_compare (insn, operands, true, <unordered>);"
1780 [(set_attr "type" "fcmp")
1781 (set_attr "mode" "XF")
1782 (set_attr "athlon_decode" "vector")
1783 (set_attr "amdfam10_decode" "direct")
1784 (set_attr "bdver1_decode" "double")
1785 (set_attr "znver1_decode" "double")])
1787 ;; Push/pop instructions.
1789 (define_insn "*push<mode>2"
1790 [(set (match_operand:DWI 0 "push_operand" "=<")
1791 (match_operand:DWI 1 "general_no_elim_operand" "riF*o"))]
1794 [(set_attr "type" "multi")
1795 (set_attr "mode" "<MODE>")])
1798 [(set (match_operand:DWI 0 "push_operand")
1799 (match_operand:DWI 1 "general_gr_operand"))]
1802 "ix86_split_long_move (operands); DONE;")
1804 (define_insn "*pushdi2_rex64"
1805 [(set (match_operand:DI 0 "push_operand" "=<,!<")
1806 (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1811 [(set_attr "type" "push,multi")
1812 (set_attr "mode" "DI")])
1814 ;; Convert impossible pushes of immediate to existing instructions.
1815 ;; First try to get scratch register and go through it. In case this
1816 ;; fails, push sign extended lower part first and then overwrite
1817 ;; upper part by 32bit move.
1819 [(match_scratch:DI 2 "r")
1820 (set (match_operand:DI 0 "push_operand")
1821 (match_operand:DI 1 "immediate_operand"))]
1822 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1823 && !x86_64_immediate_operand (operands[1], DImode)"
1824 [(set (match_dup 2) (match_dup 1))
1825 (set (match_dup 0) (match_dup 2))])
1827 ;; We need to define this as both peepholer and splitter for case
1828 ;; peephole2 pass is not run.
1829 ;; "&& 1" is needed to keep it from matching the previous pattern.
1831 [(set (match_operand:DI 0 "push_operand")
1832 (match_operand:DI 1 "immediate_operand"))]
1833 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1834 && !x86_64_immediate_operand (operands[1], DImode) && 1"
1835 [(set (match_dup 0) (match_dup 1))
1836 (set (match_dup 2) (match_dup 3))]
1838 split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1840 operands[1] = gen_lowpart (DImode, operands[2]);
1841 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (Pmode, stack_pointer_rtx,
1846 [(set (match_operand:DI 0 "push_operand")
1847 (match_operand:DI 1 "immediate_operand"))]
1848 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
1849 ? epilogue_completed : reload_completed)
1850 && !symbolic_operand (operands[1], DImode)
1851 && !x86_64_immediate_operand (operands[1], DImode)"
1852 [(set (match_dup 0) (match_dup 1))
1853 (set (match_dup 2) (match_dup 3))]
1855 split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1857 operands[1] = gen_lowpart (DImode, operands[2]);
1858 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (Pmode, stack_pointer_rtx,
1862 (define_insn "*pushsi2"
1863 [(set (match_operand:SI 0 "push_operand" "=<")
1864 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1867 [(set_attr "type" "push")
1868 (set_attr "mode" "SI")])
1870 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1871 ;; "push a byte/word". But actually we use pushl, which has the effect
1872 ;; of rounding the amount pushed up to a word.
1874 ;; For TARGET_64BIT we always round up to 8 bytes.
1875 (define_insn "*push<mode>2_rex64"
1876 [(set (match_operand:SWI124 0 "push_operand" "=X")
1877 (match_operand:SWI124 1 "nonmemory_no_elim_operand" "r<i>"))]
1880 [(set_attr "type" "push")
1881 (set_attr "mode" "DI")])
1883 (define_insn "*push<mode>2"
1884 [(set (match_operand:SWI12 0 "push_operand" "=X")
1885 (match_operand:SWI12 1 "nonmemory_no_elim_operand" "rn"))]
1888 [(set_attr "type" "push")
1889 (set_attr "mode" "SI")])
1891 (define_insn "*push<mode>2_prologue"
1892 [(set (match_operand:W 0 "push_operand" "=<")
1893 (match_operand:W 1 "general_no_elim_operand" "r<i>*m"))
1894 (clobber (mem:BLK (scratch)))]
1896 "push{<imodesuffix>}\t%1"
1897 [(set_attr "type" "push")
1898 (set_attr "mode" "<MODE>")])
1900 (define_insn "*pop<mode>1"
1901 [(set (match_operand:W 0 "nonimmediate_operand" "=r*m")
1902 (match_operand:W 1 "pop_operand" ">"))]
1904 "pop{<imodesuffix>}\t%0"
1905 [(set_attr "type" "pop")
1906 (set_attr "mode" "<MODE>")])
1908 (define_insn "*pop<mode>1_epilogue"
1909 [(set (match_operand:W 0 "nonimmediate_operand" "=r*m")
1910 (match_operand:W 1 "pop_operand" ">"))
1911 (clobber (mem:BLK (scratch)))]
1913 "pop{<imodesuffix>}\t%0"
1914 [(set_attr "type" "pop")
1915 (set_attr "mode" "<MODE>")])
1917 (define_insn "*pushfl<mode>2"
1918 [(set (match_operand:W 0 "push_operand" "=<")
1919 (match_operand:W 1 "flags_reg_operand"))]
1921 "pushf{<imodesuffix>}"
1922 [(set_attr "type" "push")
1923 (set_attr "mode" "<MODE>")])
1925 (define_insn "*popfl<mode>1"
1926 [(set (match_operand:W 0 "flags_reg_operand")
1927 (match_operand:W 1 "pop_operand" ">"))]
1929 "popf{<imodesuffix>}"
1930 [(set_attr "type" "pop")
1931 (set_attr "mode" "<MODE>")])
1934 ;; Reload patterns to support multi-word load/store
1935 ;; with non-offsetable address.
1936 (define_expand "reload_noff_store"
1937 [(parallel [(match_operand 0 "memory_operand" "=m")
1938 (match_operand 1 "register_operand" "r")
1939 (match_operand:DI 2 "register_operand" "=&r")])]
1942 rtx mem = operands[0];
1943 rtx addr = XEXP (mem, 0);
1945 emit_move_insn (operands[2], addr);
1946 mem = replace_equiv_address_nv (mem, operands[2]);
1948 emit_insn (gen_rtx_SET (mem, operands[1]));
1952 (define_expand "reload_noff_load"
1953 [(parallel [(match_operand 0 "register_operand" "=r")
1954 (match_operand 1 "memory_operand" "m")
1955 (match_operand:DI 2 "register_operand" "=r")])]
1958 rtx mem = operands[1];
1959 rtx addr = XEXP (mem, 0);
1961 emit_move_insn (operands[2], addr);
1962 mem = replace_equiv_address_nv (mem, operands[2]);
1964 emit_insn (gen_rtx_SET (operands[0], mem));
1968 ;; Move instructions.
1970 (define_expand "movxi"
1971 [(set (match_operand:XI 0 "nonimmediate_operand")
1972 (match_operand:XI 1 "general_operand"))]
1974 "ix86_expand_vector_move (XImode, operands); DONE;")
1976 (define_expand "movoi"
1977 [(set (match_operand:OI 0 "nonimmediate_operand")
1978 (match_operand:OI 1 "general_operand"))]
1980 "ix86_expand_vector_move (OImode, operands); DONE;")
1982 (define_expand "movti"
1983 [(set (match_operand:TI 0 "nonimmediate_operand")
1984 (match_operand:TI 1 "general_operand"))]
1985 "TARGET_64BIT || TARGET_SSE"
1988 ix86_expand_move (TImode, operands);
1990 ix86_expand_vector_move (TImode, operands);
1994 ;; This expands to what emit_move_complex would generate if we didn't
1995 ;; have a movti pattern. Having this avoids problems with reload on
1996 ;; 32-bit targets when SSE is present, but doesn't seem to be harmful
1997 ;; to have around all the time.
1998 (define_expand "movcdi"
1999 [(set (match_operand:CDI 0 "nonimmediate_operand")
2000 (match_operand:CDI 1 "general_operand"))]
2003 if (push_operand (operands[0], CDImode))
2004 emit_move_complex_push (CDImode, operands[0], operands[1]);
2006 emit_move_complex_parts (operands[0], operands[1]);
2010 (define_expand "mov<mode>"
2011 [(set (match_operand:SWI1248x 0 "nonimmediate_operand")
2012 (match_operand:SWI1248x 1 "general_operand"))]
2014 "ix86_expand_move (<MODE>mode, operands); DONE;")
2016 (define_insn "*mov<mode>_xor"
2017 [(set (match_operand:SWI48 0 "register_operand" "=r")
2018 (match_operand:SWI48 1 "const0_operand"))
2019 (clobber (reg:CC FLAGS_REG))]
2022 [(set_attr "type" "alu1")
2023 (set_attr "modrm_class" "op0")
2024 (set_attr "mode" "SI")
2025 (set_attr "length_immediate" "0")])
2027 (define_insn "*mov<mode>_or"
2028 [(set (match_operand:SWI48 0 "register_operand" "=r")
2029 (match_operand:SWI48 1 "constm1_operand"))
2030 (clobber (reg:CC FLAGS_REG))]
2032 "or{<imodesuffix>}\t{%1, %0|%0, %1}"
2033 [(set_attr "type" "alu1")
2034 (set_attr "mode" "<MODE>")
2035 (set_attr "length_immediate" "1")])
2037 (define_insn "*movxi_internal_avx512f"
2038 [(set (match_operand:XI 0 "nonimmediate_operand" "=v,v ,v ,m")
2039 (match_operand:XI 1 "nonimmediate_or_sse_const_operand" " C,BC,vm,v"))]
2041 && (register_operand (operands[0], XImode)
2042 || register_operand (operands[1], XImode))"
2044 switch (get_attr_type (insn))
2047 return standard_sse_constant_opcode (insn, operands);
2050 if (misaligned_operand (operands[0], XImode)
2051 || misaligned_operand (operands[1], XImode))
2052 return "vmovdqu32\t{%1, %0|%0, %1}";
2054 return "vmovdqa32\t{%1, %0|%0, %1}";
2060 [(set_attr "type" "sselog1,sselog1,ssemov,ssemov")
2061 (set_attr "prefix" "evex")
2062 (set_attr "mode" "XI")])
2064 (define_insn "*movoi_internal_avx"
2065 [(set (match_operand:OI 0 "nonimmediate_operand" "=v,v ,v ,m")
2066 (match_operand:OI 1 "nonimmediate_or_sse_const_operand" " C,BC,vm,v"))]
2068 && (register_operand (operands[0], OImode)
2069 || register_operand (operands[1], OImode))"
2071 switch (get_attr_type (insn))
2074 return standard_sse_constant_opcode (insn, operands);
2077 if (misaligned_operand (operands[0], OImode)
2078 || misaligned_operand (operands[1], OImode))
2080 if (get_attr_mode (insn) == MODE_V8SF)
2081 return "vmovups\t{%1, %0|%0, %1}";
2082 else if (get_attr_mode (insn) == MODE_XI)
2083 return "vmovdqu32\t{%1, %0|%0, %1}";
2085 return "vmovdqu\t{%1, %0|%0, %1}";
2089 if (get_attr_mode (insn) == MODE_V8SF)
2090 return "vmovaps\t{%1, %0|%0, %1}";
2091 else if (get_attr_mode (insn) == MODE_XI)
2092 return "vmovdqa32\t{%1, %0|%0, %1}";
2094 return "vmovdqa\t{%1, %0|%0, %1}";
2101 [(set_attr "isa" "*,avx2,*,*")
2102 (set_attr "type" "sselog1,sselog1,ssemov,ssemov")
2103 (set_attr "prefix" "vex")
2105 (cond [(ior (match_operand 0 "ext_sse_reg_operand")
2106 (match_operand 1 "ext_sse_reg_operand"))
2108 (and (eq_attr "alternative" "1")
2109 (match_test "TARGET_AVX512VL"))
2111 (ior (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
2112 (and (eq_attr "alternative" "3")
2113 (match_test "TARGET_SSE_TYPELESS_STORES")))
2114 (const_string "V8SF")
2116 (const_string "OI")))])
2118 (define_insn "*movti_internal"
2119 [(set (match_operand:TI 0 "nonimmediate_operand" "=!r ,o ,v,v ,v ,m,?r,?Yd")
2120 (match_operand:TI 1 "general_operand" "riFo,re,C,BC,vm,v,Ye,r"))]
2122 && !(MEM_P (operands[0]) && MEM_P (operands[1])))
2124 && nonimmediate_or_sse_const_operand (operands[1], TImode)
2125 && (register_operand (operands[0], TImode)
2126 || register_operand (operands[1], TImode)))"
2128 switch (get_attr_type (insn))
2134 return standard_sse_constant_opcode (insn, operands);
2137 /* TDmode values are passed as TImode on the stack. Moving them
2138 to stack may result in unaligned memory access. */
2139 if (misaligned_operand (operands[0], TImode)
2140 || misaligned_operand (operands[1], TImode))
2142 if (get_attr_mode (insn) == MODE_V4SF)
2143 return "%vmovups\t{%1, %0|%0, %1}";
2144 else if (get_attr_mode (insn) == MODE_XI)
2145 return "vmovdqu32\t{%1, %0|%0, %1}";
2147 return "%vmovdqu\t{%1, %0|%0, %1}";
2151 if (get_attr_mode (insn) == MODE_V4SF)
2152 return "%vmovaps\t{%1, %0|%0, %1}";
2153 else if (get_attr_mode (insn) == MODE_XI)
2154 return "vmovdqa32\t{%1, %0|%0, %1}";
2156 return "%vmovdqa\t{%1, %0|%0, %1}";
2164 (cond [(eq_attr "alternative" "0,1,6,7")
2165 (const_string "x64")
2166 (eq_attr "alternative" "3")
2167 (const_string "sse2")
2169 (const_string "*")))
2171 (cond [(eq_attr "alternative" "0,1,6,7")
2172 (const_string "multi")
2173 (eq_attr "alternative" "2,3")
2174 (const_string "sselog1")
2176 (const_string "ssemov")))
2177 (set (attr "prefix")
2178 (if_then_else (eq_attr "type" "sselog1,ssemov")
2179 (const_string "maybe_vex")
2180 (const_string "orig")))
2182 (cond [(eq_attr "alternative" "0,1")
2184 (ior (match_operand 0 "ext_sse_reg_operand")
2185 (match_operand 1 "ext_sse_reg_operand"))
2187 (and (eq_attr "alternative" "3")
2188 (match_test "TARGET_AVX512VL"))
2190 (ior (not (match_test "TARGET_SSE2"))
2191 (ior (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
2192 (and (eq_attr "alternative" "5")
2193 (match_test "TARGET_SSE_TYPELESS_STORES"))))
2194 (const_string "V4SF")
2195 (match_test "TARGET_AVX")
2197 (match_test "optimize_function_for_size_p (cfun)")
2198 (const_string "V4SF")
2200 (const_string "TI")))])
2203 [(set (match_operand:TI 0 "sse_reg_operand")
2204 (match_operand:TI 1 "general_reg_operand"))]
2205 "TARGET_64BIT && TARGET_SSE4_1 && TARGET_INTER_UNIT_MOVES_TO_VEC
2206 && reload_completed"
2209 (vec_duplicate:V2DI (match_dup 3))
2213 operands[2] = lowpart_subreg (V2DImode, operands[0], TImode);
2214 operands[3] = gen_highpart (DImode, operands[1]);
2216 emit_move_insn (gen_lowpart (DImode, operands[0]),
2217 gen_lowpart (DImode, operands[1]));
2220 (define_insn "*movdi_internal"
2221 [(set (match_operand:DI 0 "nonimmediate_operand"
2222 "=r ,o ,r,r ,r,m ,*y,*y,?*y,?m,?r ,?*Ym,*v,*v,*v,m ,m,?r ,?*Yd,?r ,?*Yi,?*Ym,?*Yi,*k,*k ,*r,*m")
2223 (match_operand:DI 1 "general_operand"
2224 "riFo,riF,Z,rem,i,re,C ,*y,m ,*y,*Yn,r ,C ,*v,m ,*v,v,*Ye,r ,*Yj,r ,*Yj ,*Yn ,*r,*km,*k,*k"))]
2225 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2227 switch (get_attr_type (insn))
2230 return "kmovq\t{%1, %0|%0, %1}";
2236 return "pxor\t%0, %0";
2239 /* Handle broken assemblers that require movd instead of movq. */
2240 if (!HAVE_AS_IX86_INTERUNIT_MOVQ
2241 && (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1])))
2242 return "movd\t{%1, %0|%0, %1}";
2243 return "movq\t{%1, %0|%0, %1}";
2246 return standard_sse_constant_opcode (insn, operands);
2249 switch (get_attr_mode (insn))
2252 /* Handle broken assemblers that require movd instead of movq. */
2253 if (!HAVE_AS_IX86_INTERUNIT_MOVQ
2254 && (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1])))
2255 return "%vmovd\t{%1, %0|%0, %1}";
2256 return "%vmovq\t{%1, %0|%0, %1}";
2259 /* Handle AVX512 registers set. */
2260 if (EXT_REX_SSE_REG_P (operands[0])
2261 || EXT_REX_SSE_REG_P (operands[1]))
2262 return "vmovdqa64\t{%1, %0|%0, %1}";
2263 return "%vmovdqa\t{%1, %0|%0, %1}";
2266 gcc_assert (!TARGET_AVX);
2267 return "movlps\t{%1, %0|%0, %1}";
2269 return "%vmovaps\t{%1, %0|%0, %1}";
2276 if (SSE_REG_P (operands[0]))
2277 return "movq2dq\t{%1, %0|%0, %1}";
2279 return "movdq2q\t{%1, %0|%0, %1}";
2282 return "lea{q}\t{%E1, %0|%0, %E1}";
2285 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2286 if (get_attr_mode (insn) == MODE_SI)
2287 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2288 else if (which_alternative == 4)
2289 return "movabs{q}\t{%1, %0|%0, %1}";
2290 else if (ix86_use_lea_for_mov (insn, operands))
2291 return "lea{q}\t{%E1, %0|%0, %E1}";
2293 return "mov{q}\t{%1, %0|%0, %1}";
2300 (cond [(eq_attr "alternative" "0,1,17,18")
2301 (const_string "nox64")
2302 (eq_attr "alternative" "2,3,4,5,10,11,19,20,23,25")
2303 (const_string "x64")
2305 (const_string "*")))
2307 (cond [(eq_attr "alternative" "0,1,17,18")
2308 (const_string "multi")
2309 (eq_attr "alternative" "6")
2310 (const_string "mmx")
2311 (eq_attr "alternative" "7,8,9,10,11")
2312 (const_string "mmxmov")
2313 (eq_attr "alternative" "12")
2314 (const_string "sselog1")
2315 (eq_attr "alternative" "13,14,15,16,19,20")
2316 (const_string "ssemov")
2317 (eq_attr "alternative" "21,22")
2318 (const_string "ssecvt")
2319 (eq_attr "alternative" "23,24,25,26")
2320 (const_string "mskmov")
2321 (and (match_operand 0 "register_operand")
2322 (match_operand 1 "pic_32bit_operand"))
2323 (const_string "lea")
2325 (const_string "imov")))
2328 (and (eq_attr "alternative" "4") (eq_attr "type" "imov"))
2330 (const_string "*")))
2331 (set (attr "length_immediate")
2333 (and (eq_attr "alternative" "4") (eq_attr "type" "imov"))
2335 (const_string "*")))
2336 (set (attr "prefix_rex")
2338 (eq_attr "alternative" "10,11,19,20")
2340 (const_string "*")))
2341 (set (attr "prefix")
2342 (if_then_else (eq_attr "type" "sselog1,ssemov")
2343 (const_string "maybe_vex")
2344 (const_string "orig")))
2345 (set (attr "prefix_data16")
2346 (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "DI"))
2348 (const_string "*")))
2350 (cond [(eq_attr "alternative" "2")
2352 (eq_attr "alternative" "12,13")
2353 (cond [(ior (match_operand 0 "ext_sse_reg_operand")
2354 (match_operand 1 "ext_sse_reg_operand"))
2356 (ior (not (match_test "TARGET_SSE2"))
2357 (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL"))
2358 (const_string "V4SF")
2359 (match_test "TARGET_AVX")
2361 (match_test "optimize_function_for_size_p (cfun)")
2362 (const_string "V4SF")
2364 (const_string "TI"))
2366 (and (eq_attr "alternative" "14,15,16")
2367 (not (match_test "TARGET_SSE2")))
2368 (const_string "V2SF")
2370 (const_string "DI")))
2371 (set (attr "enabled")
2372 (cond [(eq_attr "alternative" "15")
2374 (match_test "TARGET_STV && TARGET_SSE2")
2375 (symbol_ref "false")
2377 (eq_attr "alternative" "16")
2379 (match_test "TARGET_STV && TARGET_SSE2")
2381 (symbol_ref "false"))
2383 (const_string "*")))])
2386 [(set (match_operand:<DWI> 0 "general_reg_operand")
2387 (match_operand:<DWI> 1 "sse_reg_operand"))]
2388 "TARGET_SSE4_1 && TARGET_INTER_UNIT_MOVES_FROM_VEC
2389 && reload_completed"
2393 (parallel [(const_int 1)])))]
2395 operands[2] = gen_highpart (<MODE>mode, operands[0]);
2396 operands[3] = lowpart_subreg (<ssevecmode>mode, operands[1], <DWI>mode);
2398 emit_move_insn (gen_lowpart (<MODE>mode, operands[0]),
2399 gen_lowpart (<MODE>mode, operands[1]));
2403 [(set (match_operand:DWI 0 "nonimmediate_gr_operand")
2404 (match_operand:DWI 1 "general_gr_operand"))]
2407 "ix86_split_long_move (operands); DONE;")
2410 [(set (match_operand:DI 0 "sse_reg_operand")
2411 (match_operand:DI 1 "general_reg_operand"))]
2412 "!TARGET_64BIT && TARGET_SSE4_1 && TARGET_INTER_UNIT_MOVES_TO_VEC
2413 && reload_completed"
2416 (vec_duplicate:V4SI (match_dup 3))
2420 operands[2] = lowpart_subreg (V4SImode, operands[0], DImode);
2421 operands[3] = gen_highpart (SImode, operands[1]);
2423 emit_move_insn (gen_lowpart (SImode, operands[0]),
2424 gen_lowpart (SImode, operands[1]));
2427 ;; movabsq $0x0012345678000000, %rax is longer
2428 ;; than movl $0x12345678, %eax; shlq $24, %rax.
2430 [(set (match_operand:DI 0 "register_operand")
2431 (match_operand:DI 1 "const_int_operand"))]
2433 && optimize_insn_for_size_p ()
2434 && LEGACY_INT_REG_P (operands[0])
2435 && !x86_64_immediate_operand (operands[1], DImode)
2436 && !x86_64_zext_immediate_operand (operands[1], DImode)
2437 && !((UINTVAL (operands[1]) >> ctz_hwi (UINTVAL (operands[1])))
2438 & ~(HOST_WIDE_INT) 0xffffffff)
2439 && peep2_regno_dead_p (0, FLAGS_REG)"
2440 [(set (match_dup 0) (match_dup 1))
2441 (parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
2442 (clobber (reg:CC FLAGS_REG))])]
2444 int shift = ctz_hwi (UINTVAL (operands[1]));
2445 operands[1] = gen_int_mode (UINTVAL (operands[1]) >> shift, DImode);
2446 operands[2] = gen_int_mode (shift, QImode);
2449 (define_insn "*movsi_internal"
2450 [(set (match_operand:SI 0 "nonimmediate_operand"
2451 "=r,m ,*y,*y,?*y,?m,?r ,?*Ym,*v,*v,*v,m ,?r ,?*Yi,*k,*k ,*rm")
2452 (match_operand:SI 1 "general_operand"
2453 "g ,re,C ,*y,m ,*y,*Yn,r ,C ,*v,m ,*v,*Yj,r ,*r,*km,*k"))]
2454 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2456 switch (get_attr_type (insn))
2459 return standard_sse_constant_opcode (insn, operands);
2462 return "kmovd\t{%1, %0|%0, %1}";
2465 switch (get_attr_mode (insn))
2468 return "%vmovd\t{%1, %0|%0, %1}";
2470 return "%vmovdqa\t{%1, %0|%0, %1}";
2472 return "vmovdqa32\t{%g1, %g0|%g0, %g1}";
2475 return "%vmovaps\t{%1, %0|%0, %1}";
2478 gcc_assert (!TARGET_AVX);
2479 return "movss\t{%1, %0|%0, %1}";
2486 return "pxor\t%0, %0";
2489 switch (get_attr_mode (insn))
2492 return "movq\t{%1, %0|%0, %1}";
2494 return "movd\t{%1, %0|%0, %1}";
2501 return "lea{l}\t{%E1, %0|%0, %E1}";
2504 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2505 if (ix86_use_lea_for_mov (insn, operands))
2506 return "lea{l}\t{%E1, %0|%0, %E1}";
2508 return "mov{l}\t{%1, %0|%0, %1}";
2515 (cond [(eq_attr "alternative" "2")
2516 (const_string "mmx")
2517 (eq_attr "alternative" "3,4,5,6,7")
2518 (const_string "mmxmov")
2519 (eq_attr "alternative" "8")
2520 (const_string "sselog1")
2521 (eq_attr "alternative" "9,10,11,12,13")
2522 (const_string "ssemov")
2523 (eq_attr "alternative" "14,15,16")
2524 (const_string "mskmov")
2525 (and (match_operand 0 "register_operand")
2526 (match_operand 1 "pic_32bit_operand"))
2527 (const_string "lea")
2529 (const_string "imov")))
2530 (set (attr "prefix")
2531 (if_then_else (eq_attr "type" "sselog1,ssemov")
2532 (const_string "maybe_vex")
2533 (const_string "orig")))
2534 (set (attr "prefix_data16")
2535 (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
2537 (const_string "*")))
2539 (cond [(eq_attr "alternative" "2,3")
2541 (eq_attr "alternative" "8,9")
2542 (cond [(ior (match_operand 0 "ext_sse_reg_operand")
2543 (match_operand 1 "ext_sse_reg_operand"))
2545 (ior (not (match_test "TARGET_SSE2"))
2546 (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL"))
2547 (const_string "V4SF")
2548 (match_test "TARGET_AVX")
2550 (match_test "optimize_function_for_size_p (cfun)")
2551 (const_string "V4SF")
2553 (const_string "TI"))
2555 (and (eq_attr "alternative" "10,11")
2556 (not (match_test "TARGET_SSE2")))
2559 (const_string "SI")))])
2561 (define_insn "*movhi_internal"
2562 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r ,r ,m ,k,k ,r,m")
2563 (match_operand:HI 1 "general_operand" "r ,rn,rm,rn,r,km,k,k"))]
2564 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2566 switch (get_attr_type (insn))
2569 /* movzwl is faster than movw on p2 due to partial word stalls,
2570 though not as fast as an aligned movl. */
2571 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
2574 switch (which_alternative)
2577 return "kmovw\t{%k1, %0|%0, %k1}";
2579 return "kmovw\t{%1, %k0|%k0, %1}";
2582 return "kmovw\t{%1, %0|%0, %1}";
2588 if (get_attr_mode (insn) == MODE_SI)
2589 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2591 return "mov{w}\t{%1, %0|%0, %1}";
2595 (cond [(eq_attr "alternative" "4,5,6,7")
2596 (const_string "mskmov")
2597 (match_test "optimize_function_for_size_p (cfun)")
2598 (const_string "imov")
2599 (and (eq_attr "alternative" "0")
2600 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2601 (not (match_test "TARGET_HIMODE_MATH"))))
2602 (const_string "imov")
2603 (and (eq_attr "alternative" "1,2")
2604 (match_operand:HI 1 "aligned_operand"))
2605 (const_string "imov")
2606 (and (match_test "TARGET_MOVX")
2607 (eq_attr "alternative" "0,2"))
2608 (const_string "imovx")
2610 (const_string "imov")))
2611 (set (attr "prefix")
2612 (if_then_else (eq_attr "alternative" "4,5,6,7")
2613 (const_string "vex")
2614 (const_string "orig")))
2616 (cond [(eq_attr "type" "imovx")
2618 (and (eq_attr "alternative" "1,2")
2619 (match_operand:HI 1 "aligned_operand"))
2621 (and (eq_attr "alternative" "0")
2622 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2623 (not (match_test "TARGET_HIMODE_MATH"))))
2626 (const_string "HI")))])
2628 ;; Situation is quite tricky about when to choose full sized (SImode) move
2629 ;; over QImode moves. For Q_REG -> Q_REG move we use full size only for
2630 ;; partial register dependency machines (such as AMD Athlon), where QImode
2631 ;; moves issue extra dependency and for partial register stalls machines
2632 ;; that don't use QImode patterns (and QImode move cause stall on the next
2635 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
2636 ;; register stall machines with, where we use QImode instructions, since
2637 ;; partial register stall can be caused there. Then we use movzx.
2639 (define_insn "*movqi_internal"
2640 [(set (match_operand:QI 0 "nonimmediate_operand"
2641 "=Q,R,r,q,q,r,r ,?r,m ,k,k,r,m,k")
2642 (match_operand:QI 1 "general_operand"
2643 "Q ,R,r,n,m,q,rn, m,qn,r,k,k,k,m"))]
2644 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2646 static char buf[128];
2650 switch (get_attr_type (insn))
2653 gcc_assert (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]));
2654 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
2657 switch (which_alternative)
2660 ops = "kmov%s\t{%%k1, %%0|%%0, %%k1}";
2663 ops = "kmov%s\t{%%1, %%k0|%%k0, %%1}";
2667 gcc_assert (TARGET_AVX512DQ);
2670 ops = "kmov%s\t{%%1, %%0|%%0, %%1}";
2676 suffix = (get_attr_mode (insn) == MODE_HI) ? "w" : "b";
2678 snprintf (buf, sizeof (buf), ops, suffix);
2682 if (get_attr_mode (insn) == MODE_SI)
2683 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2685 return "mov{b}\t{%1, %0|%0, %1}";
2689 (cond [(eq_attr "alternative" "1,2")
2690 (const_string "x64")
2691 (eq_attr "alternative" "12,13")
2692 (const_string "avx512dq")
2694 (const_string "*")))
2696 (cond [(eq_attr "alternative" "9,10,11,12,13")
2697 (const_string "mskmov")
2698 (and (eq_attr "alternative" "7")
2699 (not (match_operand:QI 1 "aligned_operand")))
2700 (const_string "imovx")
2701 (match_test "optimize_function_for_size_p (cfun)")
2702 (const_string "imov")
2703 (and (eq_attr "alternative" "5")
2704 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2705 (not (match_test "TARGET_QIMODE_MATH"))))
2706 (const_string "imov")
2707 (eq_attr "alternative" "5,7")
2708 (const_string "imovx")
2709 (and (match_test "TARGET_MOVX")
2710 (eq_attr "alternative" "4"))
2711 (const_string "imovx")
2713 (const_string "imov")))
2714 (set (attr "prefix")
2715 (if_then_else (eq_attr "alternative" "9,10,11")
2716 (const_string "vex")
2717 (const_string "orig")))
2719 (cond [(eq_attr "alternative" "5,6,7")
2721 (eq_attr "alternative" "8")
2723 (and (eq_attr "alternative" "9,10,11")
2724 (not (match_test "TARGET_AVX512DQ")))
2726 (eq_attr "type" "imovx")
2728 ;; For -Os, 8-bit immediates are always shorter than 32-bit
2730 (and (eq_attr "type" "imov")
2731 (and (eq_attr "alternative" "3")
2732 (match_test "optimize_function_for_size_p (cfun)")))
2734 ;; For -Os, movl where one or both operands are NON_Q_REGS
2735 ;; and both are LEGACY_REGS is shorter than movb.
2736 ;; Otherwise movb and movl sizes are the same, so decide purely
2737 ;; based on speed factors.
2738 (and (eq_attr "type" "imov")
2739 (and (eq_attr "alternative" "1")
2740 (match_test "optimize_function_for_size_p (cfun)")))
2742 (and (eq_attr "type" "imov")
2743 (and (eq_attr "alternative" "0,1,2,3")
2744 (and (match_test "TARGET_PARTIAL_REG_DEPENDENCY")
2745 (not (match_test "TARGET_PARTIAL_REG_STALL")))))
2747 ;; Avoid partial register stalls when not using QImode arithmetic
2748 (and (eq_attr "type" "imov")
2749 (and (eq_attr "alternative" "0,1,2,3")
2750 (and (match_test "TARGET_PARTIAL_REG_STALL")
2751 (not (match_test "TARGET_QIMODE_MATH")))))
2754 (const_string "QI")))])
2756 ;; Stores and loads of ax to arbitrary constant address.
2757 ;; We fake an second form of instruction to force reload to load address
2758 ;; into register when rax is not available
2759 (define_insn "*movabs<mode>_1"
2760 [(set (mem:SWI1248x (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2761 (match_operand:SWI1248x 1 "nonmemory_operand" "a,r<i>"))]
2762 "TARGET_LP64 && ix86_check_movabs (insn, 0)"
2764 /* Recover the full memory rtx. */
2765 operands[0] = SET_DEST (PATTERN (insn));
2766 switch (which_alternative)
2769 return "movabs{<imodesuffix>}\t{%1, %P0|<iptrsize> PTR [%P0], %1}";
2771 return "mov{<imodesuffix>}\t{%1, %0|%0, %1}";
2776 [(set_attr "type" "imov")
2777 (set_attr "modrm" "0,*")
2778 (set_attr "length_address" "8,0")
2779 (set_attr "length_immediate" "0,*")
2780 (set_attr "memory" "store")
2781 (set_attr "mode" "<MODE>")])
2783 (define_insn "*movabs<mode>_2"
2784 [(set (match_operand:SWI1248x 0 "register_operand" "=a,r")
2785 (mem:SWI1248x (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2786 "TARGET_LP64 && ix86_check_movabs (insn, 1)"
2788 /* Recover the full memory rtx. */
2789 operands[1] = SET_SRC (PATTERN (insn));
2790 switch (which_alternative)
2793 return "movabs{<imodesuffix>}\t{%P1, %0|%0, <iptrsize> PTR [%P1]}";
2795 return "mov{<imodesuffix>}\t{%1, %0|%0, %1}";
2800 [(set_attr "type" "imov")
2801 (set_attr "modrm" "0,*")
2802 (set_attr "length_address" "8,0")
2803 (set_attr "length_immediate" "0")
2804 (set_attr "memory" "load")
2805 (set_attr "mode" "<MODE>")])
2807 (define_insn "*swap<mode>"
2808 [(set (match_operand:SWI48 0 "register_operand" "+r")
2809 (match_operand:SWI48 1 "register_operand" "+r"))
2813 "xchg{<imodesuffix>}\t%1, %0"
2814 [(set_attr "type" "imov")
2815 (set_attr "mode" "<MODE>")
2816 (set_attr "pent_pair" "np")
2817 (set_attr "athlon_decode" "vector")
2818 (set_attr "amdfam10_decode" "double")
2819 (set_attr "bdver1_decode" "double")])
2821 (define_insn "*swap<mode>"
2822 [(set (match_operand:SWI12 0 "register_operand" "+<r>,r")
2823 (match_operand:SWI12 1 "register_operand" "+<r>,r"))
2828 xchg{<imodesuffix>}\t%1, %0
2830 [(set_attr "type" "imov")
2831 (set_attr "mode" "<MODE>,SI")
2832 (set (attr "preferred_for_size")
2833 (cond [(eq_attr "alternative" "0")
2834 (symbol_ref "false")]
2835 (symbol_ref "true")))
2836 ;; Potential partial reg stall on alternative 1.
2837 (set (attr "preferred_for_speed")
2838 (cond [(eq_attr "alternative" "1")
2839 (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
2840 (symbol_ref "true")))
2841 (set_attr "pent_pair" "np")
2842 (set_attr "athlon_decode" "vector")
2843 (set_attr "amdfam10_decode" "double")
2844 (set_attr "bdver1_decode" "double")])
2846 (define_expand "movstrict<mode>"
2847 [(set (strict_low_part (match_operand:SWI12 0 "nonimmediate_operand"))
2848 (match_operand:SWI12 1 "general_operand"))]
2851 if (TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun))
2853 if (SUBREG_P (operands[0])
2854 && GET_MODE_CLASS (GET_MODE (SUBREG_REG (operands[0]))) != MODE_INT)
2856 /* Don't generate memory->memory moves, go through a register */
2857 if (MEM_P (operands[0]) && MEM_P (operands[1]))
2858 operands[1] = force_reg (<MODE>mode, operands[1]);
2861 (define_insn "*movstrict<mode>_1"
2862 [(set (strict_low_part
2863 (match_operand:SWI12 0 "nonimmediate_operand" "+<r>m,<r>"))
2864 (match_operand:SWI12 1 "general_operand" "<r>n,m"))]
2865 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
2866 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2867 "mov{<imodesuffix>}\t{%1, %0|%0, %1}"
2868 [(set_attr "type" "imov")
2869 (set_attr "mode" "<MODE>")])
2871 (define_insn "*movstrict<mode>_xor"
2872 [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>"))
2873 (match_operand:SWI12 1 "const0_operand"))
2874 (clobber (reg:CC FLAGS_REG))]
2876 "xor{<imodesuffix>}\t%0, %0"
2877 [(set_attr "type" "alu1")
2878 (set_attr "modrm_class" "op0")
2879 (set_attr "mode" "<MODE>")
2880 (set_attr "length_immediate" "0")])
2882 (define_expand "extv<mode>"
2883 [(set (match_operand:SWI24 0 "register_operand")
2884 (sign_extract:SWI24 (match_operand:SWI24 1 "register_operand")
2885 (match_operand:SI 2 "const_int_operand")
2886 (match_operand:SI 3 "const_int_operand")))]
2889 /* Handle extractions from %ah et al. */
2890 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
2893 unsigned int regno = reg_or_subregno (operands[1]);
2895 /* Be careful to expand only with registers having upper parts. */
2896 if (regno <= LAST_VIRTUAL_REGISTER && !QI_REGNO_P (regno))
2897 operands[1] = copy_to_reg (operands[1]);
2900 (define_insn "*extv<mode>"
2901 [(set (match_operand:SWI24 0 "register_operand" "=R")
2902 (sign_extract:SWI24 (match_operand 1 "ext_register_operand" "Q")
2906 "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
2907 [(set_attr "type" "imovx")
2908 (set_attr "mode" "SI")])
2910 (define_expand "extzv<mode>"
2911 [(set (match_operand:SWI248 0 "register_operand")
2912 (zero_extract:SWI248 (match_operand:SWI248 1 "register_operand")
2913 (match_operand:SI 2 "const_int_operand")
2914 (match_operand:SI 3 "const_int_operand")))]
2917 if (ix86_expand_pextr (operands))
2920 /* Handle extractions from %ah et al. */
2921 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
2924 unsigned int regno = reg_or_subregno (operands[1]);
2926 /* Be careful to expand only with registers having upper parts. */
2927 if (regno <= LAST_VIRTUAL_REGISTER && !QI_REGNO_P (regno))
2928 operands[1] = copy_to_reg (operands[1]);
2931 (define_insn "*extzvqi_mem_rex64"
2932 [(set (match_operand:QI 0 "norex_memory_operand" "=Bn")
2934 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q")
2937 "TARGET_64BIT && reload_completed"
2938 "mov{b}\t{%h1, %0|%0, %h1}"
2939 [(set_attr "type" "imov")
2940 (set_attr "mode" "QI")])
2942 (define_insn "*extzv<mode>"
2943 [(set (match_operand:SWI248 0 "register_operand" "=R")
2944 (zero_extract:SWI248 (match_operand 1 "ext_register_operand" "Q")
2948 "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
2949 [(set_attr "type" "imovx")
2950 (set_attr "mode" "SI")])
2952 (define_insn "*extzvqi"
2953 [(set (match_operand:QI 0 "nonimmediate_operand" "=QBc,?R,m")
2955 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q,Q")
2960 switch (get_attr_type (insn))
2963 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2965 return "mov{b}\t{%h1, %0|%0, %h1}";
2968 [(set_attr "isa" "*,*,nox64")
2970 (if_then_else (and (match_operand:QI 0 "register_operand")
2971 (ior (not (match_operand:QI 0 "QIreg_operand"))
2972 (match_test "TARGET_MOVX")))
2973 (const_string "imovx")
2974 (const_string "imov")))
2976 (if_then_else (eq_attr "type" "imovx")
2978 (const_string "QI")))])
2981 [(set (match_operand:QI 0 "register_operand")
2983 (zero_extract:SI (match_operand 1 "ext_register_operand")
2986 (set (match_operand:QI 2 "norex_memory_operand") (match_dup 0))]
2988 && peep2_reg_dead_p (2, operands[0])"
2991 (zero_extract:SI (match_dup 1)
2993 (const_int 8)) 0))])
2995 (define_expand "insv<mode>"
2996 [(set (zero_extract:SWI248 (match_operand:SWI248 0 "register_operand")
2997 (match_operand:SI 1 "const_int_operand")
2998 (match_operand:SI 2 "const_int_operand"))
2999 (match_operand:SWI248 3 "register_operand"))]
3004 if (ix86_expand_pinsr (operands))
3007 /* Handle insertions to %ah et al. */
3008 if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
3011 unsigned int regno = reg_or_subregno (operands[0]);
3013 /* Be careful to expand only with registers having upper parts. */
3014 if (regno <= LAST_VIRTUAL_REGISTER && !QI_REGNO_P (regno))
3015 dst = copy_to_reg (operands[0]);
3019 emit_insn (gen_insv<mode>_1 (dst, operands[3]));
3021 /* Fix up the destination if needed. */
3022 if (dst != operands[0])
3023 emit_move_insn (operands[0], dst);
3028 (define_insn "*insvqi_1_mem_rex64"
3029 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
3033 (match_operand:QI 1 "norex_memory_operand" "Bn") 0))]
3034 "TARGET_64BIT && reload_completed"
3035 "mov{b}\t{%1, %h0|%h0, %1}"
3036 [(set_attr "type" "imov")
3037 (set_attr "mode" "QI")])
3039 (define_insn "insv<mode>_1"
3040 [(set (zero_extract:SWI248 (match_operand 0 "ext_register_operand" "+Q,Q")
3043 (match_operand:SWI248 1 "general_operand" "QnBc,m"))]
3046 if (CONST_INT_P (operands[1]))
3047 operands[1] = gen_int_mode (INTVAL (operands[1]), QImode);
3048 return "mov{b}\t{%b1, %h0|%h0, %b1}";
3050 [(set_attr "isa" "*,nox64")
3051 (set_attr "type" "imov")
3052 (set_attr "mode" "QI")])
3054 (define_insn "*insvqi_1"
3055 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q,Q")
3059 (match_operand:QI 1 "general_operand" "QnBc,m") 0))]
3061 "mov{b}\t{%1, %h0|%h0, %1}"
3062 [(set_attr "isa" "*,nox64")
3063 (set_attr "type" "imov")
3064 (set_attr "mode" "QI")])
3067 [(set (match_operand:QI 0 "register_operand")
3068 (match_operand:QI 1 "norex_memory_operand"))
3069 (set (zero_extract:SI (match_operand 2 "ext_register_operand")
3072 (subreg:SI (match_dup 0) 0))]
3074 && peep2_reg_dead_p (2, operands[0])"
3075 [(set (zero_extract:SI (match_dup 2)
3078 (subreg:SI (match_dup 1) 0))])
3080 (define_code_iterator any_extract [sign_extract zero_extract])
3082 (define_insn "*insvqi_2"
3083 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
3086 (any_extract:SI (match_operand 1 "ext_register_operand" "Q")
3090 "mov{b}\t{%h1, %h0|%h0, %h1}"
3091 [(set_attr "type" "imov")
3092 (set_attr "mode" "QI")])
3094 (define_insn "*insvqi_3"
3095 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
3098 (any_shiftrt:SI (match_operand:SI 1 "register_operand" "Q")
3101 "mov{b}\t{%h1, %h0|%h0, %h1}"
3102 [(set_attr "type" "imov")
3103 (set_attr "mode" "QI")])
3105 ;; Floating point push instructions.
3107 (define_insn "*pushtf"
3108 [(set (match_operand:TF 0 "push_operand" "=<,<")
3109 (match_operand:TF 1 "general_no_elim_operand" "v,*roC"))]
3110 "TARGET_64BIT || TARGET_SSE"
3112 /* This insn should be already split before reg-stack. */
3115 [(set_attr "isa" "*,x64")
3116 (set_attr "type" "multi")
3117 (set_attr "unit" "sse,*")
3118 (set_attr "mode" "TF,DI")])
3120 ;; %%% Kill this when call knows how to work this out.
3122 [(set (match_operand:TF 0 "push_operand")
3123 (match_operand:TF 1 "sse_reg_operand"))]
3124 "TARGET_SSE && reload_completed"
3125 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -16)))
3126 (set (match_dup 0) (match_dup 1))]
3128 /* Preserve memory attributes. */
3129 operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
3132 (define_insn_and_split "*pushxf_rounded"
3136 (plus:P (reg:P SP_REG) (const_int -16))))
3137 (match_operand:XF 0 "nonmemory_no_elim_operand" "f,r,*r,C"))]
3141 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -16)))
3142 (set (match_dup 1) (match_dup 0))]
3144 rtx pat = PATTERN (curr_insn);
3145 operands[1] = SET_DEST (pat);
3147 /* Preserve memory attributes. */
3148 operands[1] = replace_equiv_address (operands[1], stack_pointer_rtx);
3150 [(set_attr "type" "multi")
3151 (set_attr "unit" "i387,*,*,*")
3153 (cond [(eq_attr "alternative" "1,2,3")
3156 (const_string "XF")))
3157 (set (attr "preferred_for_size")
3158 (cond [(eq_attr "alternative" "1")
3159 (symbol_ref "false")]
3160 (symbol_ref "true")))])
3162 (define_insn "*pushxf"
3163 [(set (match_operand:XF 0 "push_operand" "=<,<,<,<,<")
3164 (match_operand:XF 1 "general_no_elim_operand" "f,r,*r,oF,oC"))]
3167 /* This insn should be already split before reg-stack. */
3170 [(set_attr "isa" "*,*,*,nox64,x64")
3171 (set_attr "type" "multi")
3172 (set_attr "unit" "i387,*,*,*,*")
3174 (cond [(eq_attr "alternative" "1,2,3,4")
3175 (if_then_else (match_test "TARGET_64BIT")
3177 (const_string "SI"))
3179 (const_string "XF")))
3180 (set (attr "preferred_for_size")
3181 (cond [(eq_attr "alternative" "1")
3182 (symbol_ref "false")]
3183 (symbol_ref "true")))])
3185 ;; %%% Kill this when call knows how to work this out.
3187 [(set (match_operand:XF 0 "push_operand")
3188 (match_operand:XF 1 "fp_register_operand"))]
3190 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
3191 (set (match_dup 0) (match_dup 1))]
3193 operands[2] = GEN_INT (-PUSH_ROUNDING (GET_MODE_SIZE (XFmode)));
3194 /* Preserve memory attributes. */
3195 operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
3198 (define_insn "*pushdf"
3199 [(set (match_operand:DF 0 "push_operand" "=<,<,<,<,<,<")
3200 (match_operand:DF 1 "general_no_elim_operand" "f,r,*r,oF,rmC,x"))]
3203 /* This insn should be already split before reg-stack. */
3206 [(set_attr "isa" "*,nox64,nox64,nox64,x64,sse2")
3207 (set_attr "type" "multi")
3208 (set_attr "unit" "i387,*,*,*,*,sse")
3209 (set_attr "mode" "DF,SI,SI,SI,DI,DF")
3210 (set (attr "preferred_for_size")
3211 (cond [(eq_attr "alternative" "1")
3212 (symbol_ref "false")]
3213 (symbol_ref "true")))
3214 (set (attr "preferred_for_speed")
3215 (cond [(eq_attr "alternative" "1")
3216 (symbol_ref "TARGET_INTEGER_DFMODE_MOVES")]
3217 (symbol_ref "true")))])
3219 ;; %%% Kill this when call knows how to work this out.
3221 [(set (match_operand:DF 0 "push_operand")
3222 (match_operand:DF 1 "any_fp_register_operand"))]
3224 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
3225 (set (match_dup 0) (match_dup 1))]
3227 /* Preserve memory attributes. */
3228 operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
3231 (define_insn "*pushsf_rex64"
3232 [(set (match_operand:SF 0 "push_operand" "=X,X,X")
3233 (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
3236 /* Anything else should be already split before reg-stack. */
3237 gcc_assert (which_alternative == 1);
3238 return "push{q}\t%q1";
3240 [(set_attr "type" "multi,push,multi")
3241 (set_attr "unit" "i387,*,*")
3242 (set_attr "mode" "SF,DI,SF")])
3244 (define_insn "*pushsf"
3245 [(set (match_operand:SF 0 "push_operand" "=<,<,<")
3246 (match_operand:SF 1 "general_no_elim_operand" "f,rmF,x"))]
3249 /* Anything else should be already split before reg-stack. */
3250 gcc_assert (which_alternative == 1);
3251 return "push{l}\t%1";
3253 [(set_attr "type" "multi,push,multi")
3254 (set_attr "unit" "i387,*,*")
3255 (set_attr "mode" "SF,SI,SF")])
3257 ;; %%% Kill this when call knows how to work this out.
3259 [(set (match_operand:SF 0 "push_operand")
3260 (match_operand:SF 1 "any_fp_register_operand"))]
3262 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
3263 (set (match_dup 0) (match_dup 1))]
3265 rtx op = XEXP (operands[0], 0);
3266 if (GET_CODE (op) == PRE_DEC)
3268 gcc_assert (!TARGET_64BIT);
3273 op = XEXP (XEXP (op, 1), 1);
3274 gcc_assert (CONST_INT_P (op));
3277 /* Preserve memory attributes. */
3278 operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
3282 [(set (match_operand:SF 0 "push_operand")
3283 (match_operand:SF 1 "memory_operand"))]
3285 && find_constant_src (insn)"
3286 [(set (match_dup 0) (match_dup 2))]
3287 "operands[2] = find_constant_src (curr_insn);")
3290 [(set (match_operand 0 "push_operand")
3291 (match_operand 1 "general_gr_operand"))]
3293 && (GET_MODE (operands[0]) == TFmode
3294 || GET_MODE (operands[0]) == XFmode
3295 || GET_MODE (operands[0]) == DFmode)"
3297 "ix86_split_long_move (operands); DONE;")
3299 ;; Floating point move instructions.
3301 (define_expand "movtf"
3302 [(set (match_operand:TF 0 "nonimmediate_operand")
3303 (match_operand:TF 1 "nonimmediate_operand"))]
3304 "TARGET_64BIT || TARGET_SSE"
3305 "ix86_expand_move (TFmode, operands); DONE;")
3307 (define_expand "mov<mode>"
3308 [(set (match_operand:X87MODEF 0 "nonimmediate_operand")
3309 (match_operand:X87MODEF 1 "general_operand"))]
3311 "ix86_expand_move (<MODE>mode, operands); DONE;")
3313 (define_insn "*movtf_internal"
3314 [(set (match_operand:TF 0 "nonimmediate_operand" "=v,v ,m,?*r ,!o")
3315 (match_operand:TF 1 "general_operand" "C ,vm,v,*roF,*rC"))]
3316 "(TARGET_64BIT || TARGET_SSE)
3317 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3318 && (lra_in_progress || reload_completed
3319 || !CONST_DOUBLE_P (operands[1])
3320 || ((optimize_function_for_size_p (cfun)
3321 || (ix86_cmodel == CM_LARGE || ix86_cmodel == CM_LARGE_PIC))
3322 && standard_sse_constant_p (operands[1], TFmode) == 1
3323 && !memory_operand (operands[0], TFmode))
3324 || (!TARGET_MEMORY_MISMATCH_STALL
3325 && memory_operand (operands[0], TFmode)))"
3327 switch (get_attr_type (insn))
3330 return standard_sse_constant_opcode (insn, operands);
3333 /* Handle misaligned load/store since we
3334 don't have movmisaligntf pattern. */
3335 if (misaligned_operand (operands[0], TFmode)
3336 || misaligned_operand (operands[1], TFmode))
3338 if (get_attr_mode (insn) == MODE_V4SF)
3339 return "%vmovups\t{%1, %0|%0, %1}";
3340 else if (TARGET_AVX512VL
3341 && (EXT_REX_SSE_REG_P (operands[0])
3342 || EXT_REX_SSE_REG_P (operands[1])))
3343 return "vmovdqu64\t{%1, %0|%0, %1}";
3345 return "%vmovdqu\t{%1, %0|%0, %1}";
3349 if (get_attr_mode (insn) == MODE_V4SF)
3350 return "%vmovaps\t{%1, %0|%0, %1}";
3351 else if (TARGET_AVX512VL
3352 && (EXT_REX_SSE_REG_P (operands[0])
3353 || EXT_REX_SSE_REG_P (operands[1])))
3354 return "vmovdqa64\t{%1, %0|%0, %1}";
3356 return "%vmovdqa\t{%1, %0|%0, %1}";
3366 [(set_attr "isa" "*,*,*,x64,x64")
3367 (set_attr "type" "sselog1,ssemov,ssemov,multi,multi")
3368 (set (attr "prefix")
3369 (if_then_else (eq_attr "type" "sselog1,ssemov")
3370 (const_string "maybe_vex")
3371 (const_string "orig")))
3373 (cond [(eq_attr "alternative" "3,4")
3375 (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
3376 (const_string "V4SF")
3377 (and (eq_attr "alternative" "2")
3378 (match_test "TARGET_SSE_TYPELESS_STORES"))
3379 (const_string "V4SF")
3380 (match_test "TARGET_AVX")
3382 (ior (not (match_test "TARGET_SSE2"))
3383 (match_test "optimize_function_for_size_p (cfun)"))
3384 (const_string "V4SF")
3386 (const_string "TI")))])
3389 [(set (match_operand:TF 0 "nonimmediate_gr_operand")
3390 (match_operand:TF 1 "general_gr_operand"))]
3393 "ix86_split_long_move (operands); DONE;")
3395 ;; Possible store forwarding (partial memory) stall
3396 ;; in alternatives 4, 6, 7 and 8.
3397 (define_insn "*movxf_internal"
3398 [(set (match_operand:XF 0 "nonimmediate_operand"
3399 "=f,m,f,?r ,!o,?*r ,!o,!o,!o,r ,o ,o")
3400 (match_operand:XF 1 "general_operand"
3401 "fm,f,G,roF,r ,*roF,*r,F ,C ,roF,rF,rC"))]
3402 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3403 && (lra_in_progress || reload_completed
3404 || !CONST_DOUBLE_P (operands[1])
3405 || ((optimize_function_for_size_p (cfun)
3406 || (ix86_cmodel == CM_LARGE || ix86_cmodel == CM_LARGE_PIC))
3407 && standard_80387_constant_p (operands[1]) > 0
3408 && !memory_operand (operands[0], XFmode))
3409 || (!TARGET_MEMORY_MISMATCH_STALL
3410 && memory_operand (operands[0], XFmode))
3411 || !TARGET_HARD_XF_REGS)"
3413 switch (get_attr_type (insn))
3416 if (which_alternative == 2)
3417 return standard_80387_constant_opcode (operands[1]);
3418 return output_387_reg_move (insn, operands);
3428 (cond [(eq_attr "alternative" "7,10")
3429 (const_string "nox64")
3430 (eq_attr "alternative" "8,11")
3431 (const_string "x64")
3433 (const_string "*")))
3435 (cond [(eq_attr "alternative" "3,4,5,6,7,8,9,10,11")
3436 (const_string "multi")
3438 (const_string "fmov")))
3440 (cond [(eq_attr "alternative" "3,4,5,6,7,8,9,10,11")
3441 (if_then_else (match_test "TARGET_64BIT")
3443 (const_string "SI"))
3445 (const_string "XF")))
3446 (set (attr "preferred_for_size")
3447 (cond [(eq_attr "alternative" "3,4")
3448 (symbol_ref "false")]
3449 (symbol_ref "true")))
3450 (set (attr "enabled")
3451 (cond [(eq_attr "alternative" "9,10,11")
3453 (match_test "TARGET_HARD_XF_REGS")
3454 (symbol_ref "false")
3456 (not (match_test "TARGET_HARD_XF_REGS"))
3457 (symbol_ref "false")
3459 (const_string "*")))])
3462 [(set (match_operand:XF 0 "nonimmediate_gr_operand")
3463 (match_operand:XF 1 "general_gr_operand"))]
3466 "ix86_split_long_move (operands); DONE;")
3468 ;; Possible store forwarding (partial memory) stall in alternatives 4, 6 and 7.
3469 (define_insn "*movdf_internal"
3470 [(set (match_operand:DF 0 "nonimmediate_operand"
3471 "=Yf*f,m ,Yf*f,?r ,!o,?*r ,!o,!o,?r,?m,?r,?r,v,v,v,m,*x,*x,*x,m ,r ,Yi,r ,o ,r ,m")
3472 (match_operand:DF 1 "general_operand"
3473 "Yf*fm,Yf*f,G ,roF,r ,*roF,*r,F ,rm,rC,C ,F ,C,v,m,v,C ,*x,m ,*x,Yj,r ,roF,rF,rmF,rC"))]
3474 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3475 && (lra_in_progress || reload_completed
3476 || !CONST_DOUBLE_P (operands[1])
3477 || ((optimize_function_for_size_p (cfun)
3478 || (ix86_cmodel == CM_LARGE || ix86_cmodel == CM_LARGE_PIC))
3479 && ((IS_STACK_MODE (DFmode)
3480 && standard_80387_constant_p (operands[1]) > 0)
3481 || (TARGET_SSE2 && TARGET_SSE_MATH
3482 && standard_sse_constant_p (operands[1], DFmode) == 1))
3483 && !memory_operand (operands[0], DFmode))
3484 || ((TARGET_64BIT || !TARGET_MEMORY_MISMATCH_STALL)
3485 && memory_operand (operands[0], DFmode))
3486 || !TARGET_HARD_DF_REGS)"
3488 switch (get_attr_type (insn))
3491 if (which_alternative == 2)
3492 return standard_80387_constant_opcode (operands[1]);
3493 return output_387_reg_move (insn, operands);
3499 if (get_attr_mode (insn) == MODE_SI)
3500 return "mov{l}\t{%1, %k0|%k0, %1}";
3501 else if (which_alternative == 11)
3502 return "movabs{q}\t{%1, %0|%0, %1}";
3504 return "mov{q}\t{%1, %0|%0, %1}";
3507 return standard_sse_constant_opcode (insn, operands);
3510 switch (get_attr_mode (insn))
3513 if (TARGET_AVX && REG_P (operands[0]) && REG_P (operands[1]))
3514 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
3515 return "%vmovsd\t{%1, %0|%0, %1}";
3518 return "%vmovaps\t{%1, %0|%0, %1}";
3520 return "vmovapd\t{%g1, %g0|%g0, %g1}";
3522 return "%vmovapd\t{%1, %0|%0, %1}";
3525 gcc_assert (!TARGET_AVX);
3526 return "movlps\t{%1, %0|%0, %1}";
3528 gcc_assert (!TARGET_AVX);
3529 return "movlpd\t{%1, %0|%0, %1}";
3532 /* Handle broken assemblers that require movd instead of movq. */
3533 if (!HAVE_AS_IX86_INTERUNIT_MOVQ
3534 && (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1])))
3535 return "%vmovd\t{%1, %0|%0, %1}";
3536 return "%vmovq\t{%1, %0|%0, %1}";
3547 (cond [(eq_attr "alternative" "3,4,5,6,7,22,23")
3548 (const_string "nox64")
3549 (eq_attr "alternative" "8,9,10,11,20,21,24,25")
3550 (const_string "x64")
3551 (eq_attr "alternative" "12,13,14,15")
3552 (const_string "sse2")
3554 (const_string "*")))
3556 (cond [(eq_attr "alternative" "0,1,2")
3557 (const_string "fmov")
3558 (eq_attr "alternative" "3,4,5,6,7,22,23")
3559 (const_string "multi")
3560 (eq_attr "alternative" "8,9,10,11,24,25")
3561 (const_string "imov")
3562 (eq_attr "alternative" "12,16")
3563 (const_string "sselog1")
3565 (const_string "ssemov")))
3567 (if_then_else (eq_attr "alternative" "11")
3569 (const_string "*")))
3570 (set (attr "length_immediate")
3571 (if_then_else (eq_attr "alternative" "11")
3573 (const_string "*")))
3574 (set (attr "prefix")
3575 (if_then_else (eq_attr "type" "sselog1,ssemov")
3576 (const_string "maybe_vex")
3577 (const_string "orig")))
3578 (set (attr "prefix_data16")
3580 (ior (and (eq_attr "type" "ssemov") (eq_attr "mode" "DI"))
3581 (eq_attr "mode" "V1DF"))
3583 (const_string "*")))
3585 (cond [(eq_attr "alternative" "3,4,5,6,7,10,22,23")
3587 (eq_attr "alternative" "8,9,11,20,21,24,25")
3590 /* xorps is one byte shorter for non-AVX targets. */
3591 (eq_attr "alternative" "12,16")
3592 (cond [(not (match_test "TARGET_SSE2"))
3593 (const_string "V4SF")
3594 (and (match_test "TARGET_AVX512F")
3595 (not (match_test "TARGET_PREFER_AVX256")))
3597 (match_test "TARGET_AVX")
3598 (const_string "V2DF")
3599 (match_test "optimize_function_for_size_p (cfun)")
3600 (const_string "V4SF")
3601 (match_test "TARGET_SSE_LOAD0_BY_PXOR")
3604 (const_string "V2DF"))
3606 /* For architectures resolving dependencies on
3607 whole SSE registers use movapd to break dependency
3608 chains, otherwise use short move to avoid extra work. */
3610 /* movaps is one byte shorter for non-AVX targets. */
3611 (eq_attr "alternative" "13,17")
3612 (cond [(and (ior (not (match_test "TARGET_PREFER_AVX256"))
3613 (not (match_test "TARGET_AVX512VL")))
3614 (ior (match_operand 0 "ext_sse_reg_operand")
3615 (match_operand 1 "ext_sse_reg_operand")))
3616 (const_string "V8DF")
3617 (ior (not (match_test "TARGET_SSE2"))
3618 (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL"))
3619 (const_string "V4SF")
3620 (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3621 (const_string "V2DF")
3622 (match_test "TARGET_AVX")
3624 (match_test "optimize_function_for_size_p (cfun)")
3625 (const_string "V4SF")
3627 (const_string "DF"))
3629 /* For architectures resolving dependencies on register
3630 parts we may avoid extra work to zero out upper part
3632 (eq_attr "alternative" "14,18")
3633 (cond [(not (match_test "TARGET_SSE2"))
3634 (const_string "V2SF")
3635 (match_test "TARGET_AVX")
3637 (match_test "TARGET_SSE_SPLIT_REGS")
3638 (const_string "V1DF")
3640 (const_string "DF"))
3642 (and (eq_attr "alternative" "15,19")
3643 (not (match_test "TARGET_SSE2")))
3644 (const_string "V2SF")
3646 (const_string "DF")))
3647 (set (attr "preferred_for_size")
3648 (cond [(eq_attr "alternative" "3,4")
3649 (symbol_ref "false")]
3650 (symbol_ref "true")))
3651 (set (attr "preferred_for_speed")
3652 (cond [(eq_attr "alternative" "3,4")
3653 (symbol_ref "TARGET_INTEGER_DFMODE_MOVES")]
3654 (symbol_ref "true")))
3655 (set (attr "enabled")
3656 (cond [(eq_attr "alternative" "22,23,24,25")
3658 (match_test "TARGET_HARD_DF_REGS")
3659 (symbol_ref "false")
3661 (not (match_test "TARGET_HARD_DF_REGS"))
3662 (symbol_ref "false")
3664 (const_string "*")))])
3667 [(set (match_operand:DF 0 "nonimmediate_gr_operand")
3668 (match_operand:DF 1 "general_gr_operand"))]
3669 "!TARGET_64BIT && reload_completed"
3671 "ix86_split_long_move (operands); DONE;")
3673 (define_insn "*movsf_internal"
3674 [(set (match_operand:SF 0 "nonimmediate_operand"
3675 "=Yf*f,m ,Yf*f,?r ,?m,v,v,v,m,?r,?Yi,!*y,!*y,!m,!r ,!*Ym,r ,m")
3676 (match_operand:SF 1 "general_operand"
3677 "Yf*fm,Yf*f,G ,rmF,rF,C,v,m,v,Yj,r ,*y ,m ,*y,*Yn,r ,rmF,rF"))]
3678 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3679 && (lra_in_progress || reload_completed
3680 || !CONST_DOUBLE_P (operands[1])
3681 || ((optimize_function_for_size_p (cfun)
3682 || (ix86_cmodel == CM_LARGE || ix86_cmodel == CM_LARGE_PIC))
3683 && ((IS_STACK_MODE (SFmode)
3684 && standard_80387_constant_p (operands[1]) > 0)
3685 || (TARGET_SSE && TARGET_SSE_MATH
3686 && standard_sse_constant_p (operands[1], SFmode) == 1)))
3687 || memory_operand (operands[0], SFmode)
3688 || !TARGET_HARD_SF_REGS)"
3690 switch (get_attr_type (insn))
3693 if (which_alternative == 2)
3694 return standard_80387_constant_opcode (operands[1]);
3695 return output_387_reg_move (insn, operands);
3698 return "mov{l}\t{%1, %0|%0, %1}";
3701 return standard_sse_constant_opcode (insn, operands);
3704 switch (get_attr_mode (insn))
3707 if (TARGET_AVX && REG_P (operands[0]) && REG_P (operands[1]))
3708 return "vmovss\t{%1, %0, %0|%0, %0, %1}";
3709 return "%vmovss\t{%1, %0|%0, %1}";
3712 return "vmovaps\t{%g1, %g0|%g0, %g1}";
3714 return "%vmovaps\t{%1, %0|%0, %1}";
3717 return "%vmovd\t{%1, %0|%0, %1}";
3724 switch (get_attr_mode (insn))
3727 return "movq\t{%1, %0|%0, %1}";
3729 return "movd\t{%1, %0|%0, %1}";
3740 (cond [(eq_attr "alternative" "0,1,2")
3741 (const_string "fmov")
3742 (eq_attr "alternative" "3,4,16,17")
3743 (const_string "imov")
3744 (eq_attr "alternative" "5")
3745 (const_string "sselog1")
3746 (eq_attr "alternative" "11,12,13,14,15")
3747 (const_string "mmxmov")
3749 (const_string "ssemov")))
3750 (set (attr "prefix")
3751 (if_then_else (eq_attr "type" "sselog1,ssemov")
3752 (const_string "maybe_vex")
3753 (const_string "orig")))
3754 (set (attr "prefix_data16")
3755 (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
3757 (const_string "*")))
3759 (cond [(eq_attr "alternative" "3,4,9,10,12,13,14,15,16,17")
3761 (eq_attr "alternative" "11")
3763 (eq_attr "alternative" "5")
3764 (cond [(not (match_test "TARGET_SSE2"))
3765 (const_string "V4SF")
3766 (and (match_test "TARGET_AVX512F")
3767 (not (match_test "TARGET_PREFER_AVX256")))
3768 (const_string "V16SF")
3769 (match_test "TARGET_AVX")
3770 (const_string "V4SF")
3771 (match_test "optimize_function_for_size_p (cfun)")
3772 (const_string "V4SF")
3773 (match_test "TARGET_SSE_LOAD0_BY_PXOR")
3776 (const_string "V4SF"))
3778 /* For architectures resolving dependencies on
3779 whole SSE registers use APS move to break dependency
3780 chains, otherwise use short move to avoid extra work.
3782 Do the same for architectures resolving dependencies on
3783 the parts. While in DF mode it is better to always handle
3784 just register parts, the SF mode is different due to lack
3785 of instructions to load just part of the register. It is
3786 better to maintain the whole registers in single format
3787 to avoid problems on using packed logical operations. */
3788 (eq_attr "alternative" "6")
3789 (cond [(and (ior (not (match_test "TARGET_PREFER_AVX256"))
3790 (not (match_test "TARGET_AVX512VL")))
3791 (ior (match_operand 0 "ext_sse_reg_operand")
3792 (match_operand 1 "ext_sse_reg_operand")))
3793 (const_string "V16SF")
3794 (ior (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3795 (match_test "TARGET_SSE_SPLIT_REGS"))
3796 (const_string "V4SF")
3798 (const_string "SF"))
3800 (const_string "SF")))
3801 (set (attr "enabled")
3802 (cond [(eq_attr "alternative" "16,17")
3804 (match_test "TARGET_HARD_SF_REGS")
3805 (symbol_ref "false")
3807 (not (match_test "TARGET_HARD_SF_REGS"))
3808 (symbol_ref "false")
3810 (const_string "*")))])
3813 [(set (match_operand 0 "any_fp_register_operand")
3814 (match_operand 1 "nonimmediate_operand"))]
3816 && (GET_MODE (operands[0]) == TFmode
3817 || GET_MODE (operands[0]) == XFmode
3818 || GET_MODE (operands[0]) == DFmode
3819 || GET_MODE (operands[0]) == SFmode)
3820 && ix86_standard_x87sse_constant_load_p (insn, operands[0])"
3821 [(set (match_dup 0) (match_dup 2))]
3822 "operands[2] = find_constant_src (curr_insn);")
3825 [(set (match_operand 0 "any_fp_register_operand")
3826 (float_extend (match_operand 1 "nonimmediate_operand")))]
3828 && (GET_MODE (operands[0]) == TFmode
3829 || GET_MODE (operands[0]) == XFmode
3830 || GET_MODE (operands[0]) == DFmode)
3831 && ix86_standard_x87sse_constant_load_p (insn, operands[0])"
3832 [(set (match_dup 0) (match_dup 2))]
3833 "operands[2] = find_constant_src (curr_insn);")
3835 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
3837 [(set (match_operand:X87MODEF 0 "fp_register_operand")
3838 (match_operand:X87MODEF 1 "immediate_operand"))]
3840 && (standard_80387_constant_p (operands[1]) == 8
3841 || standard_80387_constant_p (operands[1]) == 9)"
3842 [(set (match_dup 0)(match_dup 1))
3844 (neg:X87MODEF (match_dup 0)))]
3846 if (real_isnegzero (CONST_DOUBLE_REAL_VALUE (operands[1])))
3847 operands[1] = CONST0_RTX (<MODE>mode);
3849 operands[1] = CONST1_RTX (<MODE>mode);
3852 (define_insn "swapxf"
3853 [(set (match_operand:XF 0 "register_operand" "+f")
3854 (match_operand:XF 1 "register_operand" "+f"))
3859 if (STACK_TOP_P (operands[0]))
3864 [(set_attr "type" "fxch")
3865 (set_attr "mode" "XF")])
3867 (define_insn "*swap<mode>"
3868 [(set (match_operand:MODEF 0 "fp_register_operand" "+f")
3869 (match_operand:MODEF 1 "fp_register_operand" "+f"))
3872 "TARGET_80387 || reload_completed"
3874 if (STACK_TOP_P (operands[0]))
3879 [(set_attr "type" "fxch")
3880 (set_attr "mode" "<MODE>")])
3882 ;; Zero extension instructions
3884 (define_expand "zero_extendsidi2"
3885 [(set (match_operand:DI 0 "nonimmediate_operand")
3886 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand")))])
3888 (define_insn "*zero_extendsidi2"
3889 [(set (match_operand:DI 0 "nonimmediate_operand"
3890 "=r,?r,?o,r ,o,?*Ym,?!*y,$r,$Yi,$x,*x,*v,*r")
3892 (match_operand:SI 1 "x86_64_zext_operand"
3893 "0 ,rm,r ,rmWz,0,r ,m ,Yj,r ,m ,*x,*v,*k")))]
3896 switch (get_attr_type (insn))
3899 if (ix86_use_lea_for_mov (insn, operands))
3900 return "lea{l}\t{%E1, %k0|%k0, %E1}";
3902 return "mov{l}\t{%1, %k0|%k0, %1}";
3908 return "movd\t{%1, %0|%0, %1}";
3911 if (SSE_REG_P (operands[0]) && SSE_REG_P (operands[1]))
3913 if (EXT_REX_SSE_REG_P (operands[0])
3914 || EXT_REX_SSE_REG_P (operands[1]))
3915 return "vpmovzxdq\t{%t1, %g0|%g0, %t1}";
3917 return "%vpmovzxdq\t{%1, %0|%0, %1}";
3920 if (GENERAL_REG_P (operands[0]))
3921 return "%vmovd\t{%1, %k0|%k0, %1}";
3923 return "%vmovd\t{%1, %0|%0, %1}";
3926 return "kmovd\t{%1, %k0|%k0, %1}";
3933 (cond [(eq_attr "alternative" "0,1,2")
3934 (const_string "nox64")
3935 (eq_attr "alternative" "3")
3936 (const_string "x64")
3937 (eq_attr "alternative" "9")
3938 (const_string "sse2")
3939 (eq_attr "alternative" "10")
3940 (const_string "sse4")
3941 (eq_attr "alternative" "11")
3942 (const_string "avx512f")
3943 (eq_attr "alternative" "12")
3944 (const_string "x64_avx512bw")
3946 (const_string "*")))
3948 (cond [(eq_attr "alternative" "0,1,2,4")
3949 (const_string "multi")
3950 (eq_attr "alternative" "5,6")
3951 (const_string "mmxmov")
3952 (eq_attr "alternative" "7")
3953 (if_then_else (match_test "TARGET_64BIT")
3954 (const_string "ssemov")
3955 (const_string "multi"))
3956 (eq_attr "alternative" "8,9,10,11")
3957 (const_string "ssemov")
3958 (eq_attr "alternative" "12")
3959 (const_string "mskmov")
3961 (const_string "imovx")))
3962 (set (attr "prefix_extra")
3963 (if_then_else (eq_attr "alternative" "10,11")
3965 (const_string "*")))
3966 (set (attr "prefix")
3967 (if_then_else (eq_attr "type" "ssemov")
3968 (const_string "maybe_vex")
3969 (const_string "orig")))
3970 (set (attr "prefix_0f")
3971 (if_then_else (eq_attr "type" "imovx")
3973 (const_string "*")))
3975 (cond [(eq_attr "alternative" "5,6")
3977 (and (eq_attr "alternative" "7")
3978 (match_test "TARGET_64BIT"))
3980 (eq_attr "alternative" "8,10,11")
3983 (const_string "SI")))])
3986 [(set (match_operand:DI 0 "memory_operand")
3987 (zero_extend:DI (match_operand:SI 1 "memory_operand")))]
3989 [(set (match_dup 4) (const_int 0))]
3990 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3993 [(set (match_operand:DI 0 "general_reg_operand")
3994 (zero_extend:DI (match_operand:SI 1 "general_reg_operand")))]
3995 "!TARGET_64BIT && reload_completed
3996 && REGNO (operands[0]) == REGNO (operands[1])"
3997 [(set (match_dup 4) (const_int 0))]
3998 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
4001 [(set (match_operand:DI 0 "nonimmediate_gr_operand")
4002 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand")))]
4003 "!TARGET_64BIT && reload_completed
4004 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
4005 [(set (match_dup 3) (match_dup 1))
4006 (set (match_dup 4) (const_int 0))]
4007 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
4009 (define_mode_attr kmov_isa
4010 [(QI "avx512dq") (HI "avx512f") (SI "avx512bw") (DI "avx512bw")])
4012 (define_insn "zero_extend<mode>di2"
4013 [(set (match_operand:DI 0 "register_operand" "=r,*r")
4015 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m,*k")))]
4018 movz{<imodesuffix>l|x}\t{%1, %k0|%k0, %1}
4019 kmov<mskmodesuffix>\t{%1, %k0|%k0, %1}"
4020 [(set_attr "isa" "*,<kmov_isa>")
4021 (set_attr "type" "imovx,mskmov")
4022 (set_attr "mode" "SI,<MODE>")])
4024 (define_expand "zero_extend<mode>si2"
4025 [(set (match_operand:SI 0 "register_operand")
4026 (zero_extend:SI (match_operand:SWI12 1 "nonimmediate_operand")))]
4029 if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
4031 operands[1] = force_reg (<MODE>mode, operands[1]);
4032 emit_insn (gen_zero_extend<mode>si2_and (operands[0], operands[1]));
4037 (define_insn_and_split "zero_extend<mode>si2_and"
4038 [(set (match_operand:SI 0 "register_operand" "=r,?&<r>")
4040 (match_operand:SWI12 1 "nonimmediate_operand" "0,<r>m")))
4041 (clobber (reg:CC FLAGS_REG))]
4042 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
4044 "&& reload_completed"
4045 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (match_dup 2)))
4046 (clobber (reg:CC FLAGS_REG))])]
4048 if (!REG_P (operands[1])
4049 || REGNO (operands[0]) != REGNO (operands[1]))
4051 ix86_expand_clear (operands[0]);
4053 gcc_assert (!TARGET_PARTIAL_REG_STALL);
4054 emit_insn (gen_movstrict<mode>
4055 (gen_lowpart (<MODE>mode, operands[0]), operands[1]));
4059 operands[2] = GEN_INT (GET_MODE_MASK (<MODE>mode));
4061 [(set_attr "type" "alu1")
4062 (set_attr "mode" "SI")])
4064 (define_insn "*zero_extend<mode>si2"
4065 [(set (match_operand:SI 0 "register_operand" "=r,*r")
4067 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m,*k")))]
4068 "!(TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))"
4070 movz{<imodesuffix>l|x}\t{%1, %0|%0, %1}
4071 kmov<mskmodesuffix>\t{%1, %0|%0, %1}"
4072 [(set_attr "isa" "*,<kmov_isa>")
4073 (set_attr "type" "imovx,mskmov")
4074 (set_attr "mode" "SI,<MODE>")])
4076 (define_expand "zero_extendqihi2"
4077 [(set (match_operand:HI 0 "register_operand")
4078 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand")))]
4081 if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
4083 operands[1] = force_reg (QImode, operands[1]);
4084 emit_insn (gen_zero_extendqihi2_and (operands[0], operands[1]));
4089 (define_insn_and_split "zero_extendqihi2_and"
4090 [(set (match_operand:HI 0 "register_operand" "=r,?&q")
4091 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
4092 (clobber (reg:CC FLAGS_REG))]
4093 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
4095 "&& reload_completed"
4096 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
4097 (clobber (reg:CC FLAGS_REG))])]
4099 if (!REG_P (operands[1])
4100 || REGNO (operands[0]) != REGNO (operands[1]))
4102 ix86_expand_clear (operands[0]);
4104 gcc_assert (!TARGET_PARTIAL_REG_STALL);
4105 emit_insn (gen_movstrictqi
4106 (gen_lowpart (QImode, operands[0]), operands[1]));
4110 operands[0] = gen_lowpart (SImode, operands[0]);
4112 [(set_attr "type" "alu1")
4113 (set_attr "mode" "SI")])
4115 ; zero extend to SImode to avoid partial register stalls
4116 (define_insn "*zero_extendqihi2"
4117 [(set (match_operand:HI 0 "register_operand" "=r,*r")
4118 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,*k")))]
4119 "!(TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))"
4121 movz{bl|x}\t{%1, %k0|%k0, %1}
4122 kmovb\t{%1, %k0|%k0, %1}"
4123 [(set_attr "isa" "*,avx512dq")
4124 (set_attr "type" "imovx,mskmov")
4125 (set_attr "mode" "SI,QI")])
4127 (define_insn_and_split "*zext<mode>_doubleword_and"
4128 [(set (match_operand:DI 0 "register_operand" "=&<r>")
4129 (zero_extend:DI (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
4130 "!TARGET_64BIT && TARGET_STV && TARGET_SSE2
4131 && TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
4133 "&& reload_completed && GENERAL_REG_P (operands[0])"
4134 [(set (match_dup 2) (const_int 0))]
4136 split_double_mode (DImode, &operands[0], 1, &operands[0], &operands[2]);
4138 emit_move_insn (operands[0], const0_rtx);
4140 gcc_assert (!TARGET_PARTIAL_REG_STALL);
4141 emit_insn (gen_movstrict<mode>
4142 (gen_lowpart (<MODE>mode, operands[0]), operands[1]));
4145 (define_insn_and_split "*zext<mode>_doubleword"
4146 [(set (match_operand:DI 0 "register_operand" "=r")
4147 (zero_extend:DI (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
4148 "!TARGET_64BIT && TARGET_STV && TARGET_SSE2
4149 && !(TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))"
4151 "&& reload_completed && GENERAL_REG_P (operands[0])"
4152 [(set (match_dup 0) (zero_extend:SI (match_dup 1)))
4153 (set (match_dup 2) (const_int 0))]
4154 "split_double_mode (DImode, &operands[0], 1, &operands[0], &operands[2]);")
4156 (define_insn_and_split "*zextsi_doubleword"
4157 [(set (match_operand:DI 0 "register_operand" "=r")
4158 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm")))]
4159 "!TARGET_64BIT && TARGET_STV && TARGET_SSE2"
4161 "&& reload_completed && GENERAL_REG_P (operands[0])"
4162 [(set (match_dup 0) (match_dup 1))
4163 (set (match_dup 2) (const_int 0))]
4164 "split_double_mode (DImode, &operands[0], 1, &operands[0], &operands[2]);")
4166 ;; Sign extension instructions
4168 (define_expand "extendsidi2"
4169 [(set (match_operand:DI 0 "register_operand")
4170 (sign_extend:DI (match_operand:SI 1 "register_operand")))]
4175 emit_insn (gen_extendsidi2_1 (operands[0], operands[1]));
4180 (define_insn "*extendsidi2_rex64"
4181 [(set (match_operand:DI 0 "register_operand" "=*a,r")
4182 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
4186 movs{lq|x}\t{%1, %0|%0, %1}"
4187 [(set_attr "type" "imovx")
4188 (set_attr "mode" "DI")
4189 (set_attr "prefix_0f" "0")
4190 (set_attr "modrm" "0,1")])
4192 (define_insn "extendsidi2_1"
4193 [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
4194 (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
4195 (clobber (reg:CC FLAGS_REG))
4196 (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
4200 ;; Split the memory case. If the source register doesn't die, it will stay
4201 ;; this way, if it does die, following peephole2s take care of it.
4203 [(set (match_operand:DI 0 "memory_operand")
4204 (sign_extend:DI (match_operand:SI 1 "register_operand")))
4205 (clobber (reg:CC FLAGS_REG))
4206 (clobber (match_operand:SI 2 "register_operand"))]
4210 split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
4212 emit_move_insn (operands[3], operands[1]);
4214 /* Generate a cltd if possible and doing so it profitable. */
4215 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
4216 && REGNO (operands[1]) == AX_REG
4217 && REGNO (operands[2]) == DX_REG)
4219 emit_insn (gen_ashrsi3_cvt (operands[2], operands[1], GEN_INT (31)));
4223 emit_move_insn (operands[2], operands[1]);
4224 emit_insn (gen_ashrsi3_cvt (operands[2], operands[2], GEN_INT (31)));
4226 emit_move_insn (operands[4], operands[2]);
4230 ;; Peepholes for the case where the source register does die, after
4231 ;; being split with the above splitter.
4233 [(set (match_operand:SI 0 "memory_operand")
4234 (match_operand:SI 1 "general_reg_operand"))
4235 (set (match_operand:SI 2 "general_reg_operand") (match_dup 1))
4236 (parallel [(set (match_dup 2)
4237 (ashiftrt:SI (match_dup 2) (const_int 31)))
4238 (clobber (reg:CC FLAGS_REG))])
4239 (set (match_operand:SI 3 "memory_operand") (match_dup 2))]
4240 "REGNO (operands[1]) != REGNO (operands[2])
4241 && peep2_reg_dead_p (2, operands[1])
4242 && peep2_reg_dead_p (4, operands[2])
4243 && !reg_mentioned_p (operands[2], operands[3])"
4244 [(set (match_dup 0) (match_dup 1))
4245 (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
4246 (clobber (reg:CC FLAGS_REG))])
4247 (set (match_dup 3) (match_dup 1))])
4250 [(set (match_operand:SI 0 "memory_operand")
4251 (match_operand:SI 1 "general_reg_operand"))
4252 (parallel [(set (match_operand:SI 2 "general_reg_operand")
4253 (ashiftrt:SI (match_dup 1) (const_int 31)))
4254 (clobber (reg:CC FLAGS_REG))])
4255 (set (match_operand:SI 3 "memory_operand") (match_dup 2))]
4256 "/* cltd is shorter than sarl $31, %eax */
4257 !optimize_function_for_size_p (cfun)
4258 && REGNO (operands[1]) == AX_REG
4259 && REGNO (operands[2]) == DX_REG
4260 && peep2_reg_dead_p (2, operands[1])
4261 && peep2_reg_dead_p (3, operands[2])
4262 && !reg_mentioned_p (operands[2], operands[3])"
4263 [(set (match_dup 0) (match_dup 1))
4264 (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
4265 (clobber (reg:CC FLAGS_REG))])
4266 (set (match_dup 3) (match_dup 1))])
4268 ;; Extend to register case. Optimize case where source and destination
4269 ;; registers match and cases where we can use cltd.
4271 [(set (match_operand:DI 0 "register_operand")
4272 (sign_extend:DI (match_operand:SI 1 "register_operand")))
4273 (clobber (reg:CC FLAGS_REG))
4274 (clobber (match_scratch:SI 2))]
4278 split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
4280 if (REGNO (operands[3]) != REGNO (operands[1]))
4281 emit_move_insn (operands[3], operands[1]);
4283 /* Generate a cltd if possible and doing so it profitable. */
4284 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
4285 && REGNO (operands[3]) == AX_REG
4286 && REGNO (operands[4]) == DX_REG)
4288 emit_insn (gen_ashrsi3_cvt (operands[4], operands[3], GEN_INT (31)));
4292 if (REGNO (operands[4]) != REGNO (operands[1]))
4293 emit_move_insn (operands[4], operands[1]);
4295 emit_insn (gen_ashrsi3_cvt (operands[4], operands[4], GEN_INT (31)));
4299 (define_insn "extend<mode>di2"
4300 [(set (match_operand:DI 0 "register_operand" "=r")
4302 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
4304 "movs{<imodesuffix>q|x}\t{%1, %0|%0, %1}"
4305 [(set_attr "type" "imovx")
4306 (set_attr "mode" "DI")])
4308 (define_insn "extendhisi2"
4309 [(set (match_operand:SI 0 "register_operand" "=*a,r")
4310 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
4313 switch (get_attr_prefix_0f (insn))
4316 return "{cwtl|cwde}";
4318 return "movs{wl|x}\t{%1, %0|%0, %1}";
4321 [(set_attr "type" "imovx")
4322 (set_attr "mode" "SI")
4323 (set (attr "prefix_0f")
4324 ;; movsx is short decodable while cwtl is vector decoded.
4325 (if_then_else (and (eq_attr "cpu" "!k6")
4326 (eq_attr "alternative" "0"))
4328 (const_string "1")))
4329 (set (attr "znver1_decode")
4330 (if_then_else (eq_attr "prefix_0f" "0")
4331 (const_string "double")
4332 (const_string "direct")))
4334 (if_then_else (eq_attr "prefix_0f" "0")
4336 (const_string "1")))])
4338 (define_insn "*extendhisi2_zext"
4339 [(set (match_operand:DI 0 "register_operand" "=*a,r")
4342 (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
4345 switch (get_attr_prefix_0f (insn))
4348 return "{cwtl|cwde}";
4350 return "movs{wl|x}\t{%1, %k0|%k0, %1}";
4353 [(set_attr "type" "imovx")
4354 (set_attr "mode" "SI")
4355 (set (attr "prefix_0f")
4356 ;; movsx is short decodable while cwtl is vector decoded.
4357 (if_then_else (and (eq_attr "cpu" "!k6")
4358 (eq_attr "alternative" "0"))
4360 (const_string "1")))
4362 (if_then_else (eq_attr "prefix_0f" "0")
4364 (const_string "1")))])
4366 (define_insn "extendqisi2"
4367 [(set (match_operand:SI 0 "register_operand" "=r")
4368 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
4370 "movs{bl|x}\t{%1, %0|%0, %1}"
4371 [(set_attr "type" "imovx")
4372 (set_attr "mode" "SI")])
4374 (define_insn "*extendqisi2_zext"
4375 [(set (match_operand:DI 0 "register_operand" "=r")
4377 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
4379 "movs{bl|x}\t{%1, %k0|%k0, %1}"
4380 [(set_attr "type" "imovx")
4381 (set_attr "mode" "SI")])
4383 (define_insn "extendqihi2"
4384 [(set (match_operand:HI 0 "register_operand" "=*a,r")
4385 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
4388 switch (get_attr_prefix_0f (insn))
4391 return "{cbtw|cbw}";
4393 return "movs{bw|x}\t{%1, %0|%0, %1}";
4396 [(set_attr "type" "imovx")
4397 (set_attr "mode" "HI")
4398 (set (attr "prefix_0f")
4399 ;; movsx is short decodable while cwtl is vector decoded.
4400 (if_then_else (and (eq_attr "cpu" "!k6")
4401 (eq_attr "alternative" "0"))
4403 (const_string "1")))
4405 (if_then_else (eq_attr "prefix_0f" "0")
4407 (const_string "1")))])
4409 ;; Conversions between float and double.
4411 ;; These are all no-ops in the model used for the 80387.
4412 ;; So just emit moves.
4414 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
4416 [(set (match_operand:DF 0 "push_operand")
4417 (float_extend:DF (match_operand:SF 1 "fp_register_operand")))]
4419 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
4420 (set (mem:DF (reg:P SP_REG)) (float_extend:DF (match_dup 1)))])
4423 [(set (match_operand:XF 0 "push_operand")
4424 (float_extend:XF (match_operand:MODEF 1 "fp_register_operand")))]
4426 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
4427 (set (mem:XF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
4428 "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
4430 (define_expand "extendsfdf2"
4431 [(set (match_operand:DF 0 "nonimm_ssenomem_operand")
4432 (float_extend:DF (match_operand:SF 1 "general_operand")))]
4433 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4435 /* ??? Needed for compress_float_constant since all fp constants
4436 are TARGET_LEGITIMATE_CONSTANT_P. */
4437 if (CONST_DOUBLE_P (operands[1]))
4439 if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
4440 && standard_80387_constant_p (operands[1]) > 0)
4442 operands[1] = simplify_const_unary_operation
4443 (FLOAT_EXTEND, DFmode, operands[1], SFmode);
4444 emit_move_insn_1 (operands[0], operands[1]);
4447 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
4451 /* For converting SF(xmm2) to DF(xmm1), use the following code instead of
4453 unpcklps xmm2,xmm2 ; packed conversion might crash on signaling NaNs
4455 We do the conversion post reload to avoid producing of 128bit spills
4456 that might lead to ICE on 32bit target. The sequence unlikely combine
4459 [(set (match_operand:DF 0 "sse_reg_operand")
4461 (match_operand:SF 1 "nonimmediate_operand")))]
4462 "TARGET_USE_VECTOR_FP_CONVERTS
4463 && optimize_insn_for_speed_p ()
4465 && (!EXT_REX_SSE_REG_P (operands[0])
4466 || TARGET_AVX512VL)"
4471 (parallel [(const_int 0) (const_int 1)]))))]
4473 operands[2] = lowpart_subreg (V2DFmode, operands[0], DFmode);
4474 operands[3] = lowpart_subreg (V4SFmode, operands[0], DFmode);
4475 /* Use movss for loading from memory, unpcklps reg, reg for registers.
4476 Try to avoid move when unpacking can be done in source. */
4477 if (REG_P (operands[1]))
4479 /* If it is unsafe to overwrite upper half of source, we need
4480 to move to destination and unpack there. */
4481 if (REGNO (operands[0]) != REGNO (operands[1])
4482 || (EXT_REX_SSE_REG_P (operands[1])
4483 && !TARGET_AVX512VL))
4485 rtx tmp = lowpart_subreg (SFmode, operands[0], DFmode);
4486 emit_move_insn (tmp, operands[1]);
4489 operands[3] = lowpart_subreg (V4SFmode, operands[1], SFmode);
4490 /* FIXME: vec_interleave_lowv4sf for AVX512VL should allow
4491 =v, v, then vbroadcastss will be only needed for AVX512F without
4493 if (!EXT_REX_SSE_REGNO_P (REGNO (operands[3])))
4494 emit_insn (gen_vec_interleave_lowv4sf (operands[3], operands[3],
4498 rtx tmp = lowpart_subreg (V16SFmode, operands[3], V4SFmode);
4499 emit_insn (gen_avx512f_vec_dupv16sf_1 (tmp, tmp));
4503 emit_insn (gen_vec_setv4sf_0 (operands[3],
4504 CONST0_RTX (V4SFmode), operands[1]));
4507 ;; It's more profitable to split and then extend in the same register.
4509 [(set (match_operand:DF 0 "sse_reg_operand")
4511 (match_operand:SF 1 "memory_operand")))]
4512 "TARGET_SPLIT_MEM_OPND_FOR_FP_CONVERTS
4513 && optimize_insn_for_speed_p ()"
4514 [(set (match_dup 2) (match_dup 1))
4515 (set (match_dup 0) (float_extend:DF (match_dup 2)))]
4516 "operands[2] = lowpart_subreg (SFmode, operands[0], DFmode);")
4518 (define_insn "*extendsfdf2"
4519 [(set (match_operand:DF 0 "nonimm_ssenomem_operand" "=f,m,v")
4521 (match_operand:SF 1 "nonimmediate_operand" "fm,f,vm")))]
4522 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4524 switch (which_alternative)
4528 return output_387_reg_move (insn, operands);
4531 return "%vcvtss2sd\t{%1, %d0|%d0, %1}";
4537 [(set_attr "type" "fmov,fmov,ssecvt")
4538 (set_attr "prefix" "orig,orig,maybe_vex")
4539 (set_attr "mode" "SF,XF,DF")
4540 (set (attr "enabled")
4542 (match_test ("TARGET_SSE2 && TARGET_SSE_MATH"))
4544 (eq_attr "alternative" "0,1")
4545 (symbol_ref "TARGET_MIX_SSE_I387")
4546 (symbol_ref "true"))
4548 (eq_attr "alternative" "0,1")
4550 (symbol_ref "false"))))])
4552 (define_expand "extend<mode>xf2"
4553 [(set (match_operand:XF 0 "nonimmediate_operand")
4554 (float_extend:XF (match_operand:MODEF 1 "general_operand")))]
4557 /* ??? Needed for compress_float_constant since all fp constants
4558 are TARGET_LEGITIMATE_CONSTANT_P. */
4559 if (CONST_DOUBLE_P (operands[1]))
4561 if (standard_80387_constant_p (operands[1]) > 0)
4563 operands[1] = simplify_const_unary_operation
4564 (FLOAT_EXTEND, XFmode, operands[1], <MODE>mode);
4565 emit_move_insn_1 (operands[0], operands[1]);
4568 operands[1] = validize_mem (force_const_mem (<MODE>mode, operands[1]));
4572 (define_insn "*extend<mode>xf2_i387"
4573 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
4575 (match_operand:MODEF 1 "nonimmediate_operand" "fm,f")))]
4577 "* return output_387_reg_move (insn, operands);"
4578 [(set_attr "type" "fmov")
4579 (set_attr "mode" "<MODE>,XF")])
4581 ;; %%% This seems like bad news.
4582 ;; This cannot output into an f-reg because there is no way to be sure
4583 ;; of truncating in that case. Otherwise this is just like a simple move
4584 ;; insn. So we pretend we can output to a reg in order to get better
4585 ;; register preferencing, but we really use a stack slot.
4587 ;; Conversion from DFmode to SFmode.
4589 (define_expand "truncdfsf2"
4590 [(set (match_operand:SF 0 "nonimmediate_operand")
4592 (match_operand:DF 1 "nonimmediate_operand")))]
4593 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4595 if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
4597 else if (flag_unsafe_math_optimizations)
4601 rtx temp = assign_386_stack_local (SFmode, SLOT_TEMP);
4602 emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
4607 /* For converting DF(xmm2) to SF(xmm1), use the following code instead of
4609 unpcklpd xmm2,xmm2 ; packed conversion might crash on signaling NaNs
4611 We do the conversion post reload to avoid producing of 128bit spills
4612 that might lead to ICE on 32bit target. The sequence unlikely combine
4615 [(set (match_operand:SF 0 "sse_reg_operand")
4617 (match_operand:DF 1 "nonimmediate_operand")))]
4618 "TARGET_USE_VECTOR_FP_CONVERTS
4619 && optimize_insn_for_speed_p ()
4621 && (!EXT_REX_SSE_REG_P (operands[0])
4622 || TARGET_AVX512VL)"
4625 (float_truncate:V2SF
4629 operands[2] = lowpart_subreg (V4SFmode, operands[0], SFmode);
4630 operands[3] = CONST0_RTX (V2SFmode);
4631 operands[4] = lowpart_subreg (V2DFmode, operands[0], SFmode);
4632 /* Use movsd for loading from memory, unpcklpd for registers.
4633 Try to avoid move when unpacking can be done in source, or SSE3
4634 movddup is available. */
4635 if (REG_P (operands[1]))
4638 && REGNO (operands[0]) != REGNO (operands[1]))
4640 rtx tmp = lowpart_subreg (DFmode, operands[0], SFmode);
4641 emit_move_insn (tmp, operands[1]);
4644 else if (!TARGET_SSE3)
4645 operands[4] = lowpart_subreg (V2DFmode, operands[1], DFmode);
4646 emit_insn (gen_vec_dupv2df (operands[4], operands[1]));
4649 emit_insn (gen_vec_concatv2df (operands[4], operands[1],
4650 CONST0_RTX (DFmode)));
4653 ;; It's more profitable to split and then extend in the same register.
4655 [(set (match_operand:SF 0 "sse_reg_operand")
4657 (match_operand:DF 1 "memory_operand")))]
4658 "TARGET_SPLIT_MEM_OPND_FOR_FP_CONVERTS
4659 && optimize_insn_for_speed_p ()"
4660 [(set (match_dup 2) (match_dup 1))
4661 (set (match_dup 0) (float_truncate:SF (match_dup 2)))]
4662 "operands[2] = lowpart_subreg (DFmode, operands[0], SFmode);")
4664 (define_expand "truncdfsf2_with_temp"
4665 [(parallel [(set (match_operand:SF 0)
4666 (float_truncate:SF (match_operand:DF 1)))
4667 (clobber (match_operand:SF 2))])])
4669 ;; SSE alternative doesn't depend on flag_unsafe_math_optimizations,
4670 ;; because nothing we do there is unsafe.
4671 (define_insn "*truncdfsf_fast_mixed"
4672 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm,v")
4674 (match_operand:DF 1 "nonimmediate_operand" "f ,vm")))]
4675 "TARGET_SSE2 && TARGET_SSE_MATH"
4677 switch (which_alternative)
4680 return output_387_reg_move (insn, operands);
4682 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4687 [(set_attr "type" "fmov,ssecvt")
4688 (set_attr "prefix" "orig,maybe_vex")
4689 (set_attr "mode" "SF")
4690 (set (attr "enabled")
4691 (cond [(eq_attr "alternative" "0")
4692 (symbol_ref "TARGET_MIX_SSE_I387
4693 && flag_unsafe_math_optimizations")
4695 (symbol_ref "true")))])
4697 (define_insn "*truncdfsf_fast_i387"
4698 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm")
4700 (match_operand:DF 1 "nonimmediate_operand" "f")))]
4701 "TARGET_80387 && flag_unsafe_math_optimizations"
4702 "* return output_387_reg_move (insn, operands);"
4703 [(set_attr "type" "fmov")
4704 (set_attr "mode" "SF")])
4706 (define_insn "*truncdfsf_mixed"
4707 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,v ,?f,?v,?*r")
4709 (match_operand:DF 1 "nonimmediate_operand" "f ,vm,f ,f ,f")))
4710 (clobber (match_operand:SF 2 "memory_operand" "=X,X ,m ,m ,m"))]
4711 "TARGET_MIX_SSE_I387"
4713 switch (which_alternative)
4716 return output_387_reg_move (insn, operands);
4718 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4724 [(set_attr "isa" "*,sse2,*,*,*")
4725 (set_attr "type" "fmov,ssecvt,multi,multi,multi")
4726 (set_attr "unit" "*,*,i387,i387,i387")
4727 (set_attr "prefix" "orig,maybe_vex,orig,orig,orig")
4728 (set_attr "mode" "SF")])
4730 (define_insn "*truncdfsf_i387"
4731 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?v,?*r")
4733 (match_operand:DF 1 "nonimmediate_operand" "f ,f ,f ,f")))
4734 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,m ,m"))]
4737 switch (which_alternative)
4740 return output_387_reg_move (insn, operands);
4746 [(set_attr "type" "fmov,multi,multi,multi")
4747 (set_attr "unit" "*,i387,i387,i387")
4748 (set_attr "mode" "SF")])
4750 (define_insn "*truncdfsf2_i387_1"
4751 [(set (match_operand:SF 0 "memory_operand" "=m")
4753 (match_operand:DF 1 "register_operand" "f")))]
4755 && !(TARGET_SSE2 && TARGET_SSE_MATH)
4756 && !TARGET_MIX_SSE_I387"
4757 "* return output_387_reg_move (insn, operands);"
4758 [(set_attr "type" "fmov")
4759 (set_attr "mode" "SF")])
4762 [(set (match_operand:SF 0 "register_operand")
4764 (match_operand:DF 1 "fp_register_operand")))
4765 (clobber (match_operand 2))]
4767 [(set (match_dup 2) (match_dup 1))
4768 (set (match_dup 0) (match_dup 2))]
4769 "operands[1] = gen_rtx_REG (SFmode, REGNO (operands[1]));")
4771 ;; Conversion from XFmode to {SF,DF}mode
4773 (define_expand "truncxf<mode>2"
4774 [(parallel [(set (match_operand:MODEF 0 "nonimmediate_operand")
4775 (float_truncate:MODEF
4776 (match_operand:XF 1 "register_operand")))
4777 (clobber (match_dup 2))])]
4780 if (flag_unsafe_math_optimizations)
4782 rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (<MODE>mode);
4783 emit_insn (gen_truncxf<mode>2_i387_noop (reg, operands[1]));
4784 if (reg != operands[0])
4785 emit_move_insn (operands[0], reg);
4789 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4792 (define_insn "*truncxfsf2_mixed"
4793 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?v,?*r")
4795 (match_operand:XF 1 "register_operand" "f ,f ,f ,f")))
4796 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,m ,m"))]
4799 gcc_assert (!which_alternative);
4800 return output_387_reg_move (insn, operands);
4802 [(set_attr "type" "fmov,multi,multi,multi")
4803 (set_attr "unit" "*,i387,i387,i387")
4804 (set_attr "mode" "SF")])
4806 (define_insn "*truncxfdf2_mixed"
4807 [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?v,?*r")
4809 (match_operand:XF 1 "register_operand" "f ,f ,f ,f")))
4810 (clobber (match_operand:DF 2 "memory_operand" "=X,m ,m ,m"))]
4813 gcc_assert (!which_alternative);
4814 return output_387_reg_move (insn, operands);
4816 [(set_attr "isa" "*,*,sse2,*")
4817 (set_attr "type" "fmov,multi,multi,multi")
4818 (set_attr "unit" "*,i387,i387,i387")
4819 (set_attr "mode" "DF")])
4821 (define_insn "truncxf<mode>2_i387_noop"
4822 [(set (match_operand:MODEF 0 "register_operand" "=f")
4823 (float_truncate:MODEF
4824 (match_operand:XF 1 "register_operand" "f")))]
4825 "TARGET_80387 && flag_unsafe_math_optimizations"
4826 "* return output_387_reg_move (insn, operands);"
4827 [(set_attr "type" "fmov")
4828 (set_attr "mode" "<MODE>")])
4830 (define_insn "*truncxf<mode>2_i387"
4831 [(set (match_operand:MODEF 0 "memory_operand" "=m")
4832 (float_truncate:MODEF
4833 (match_operand:XF 1 "register_operand" "f")))]
4835 "* return output_387_reg_move (insn, operands);"
4836 [(set_attr "type" "fmov")
4837 (set_attr "mode" "<MODE>")])
4840 [(set (match_operand:MODEF 0 "register_operand")
4841 (float_truncate:MODEF
4842 (match_operand:XF 1 "register_operand")))
4843 (clobber (match_operand:MODEF 2 "memory_operand"))]
4844 "TARGET_80387 && reload_completed"
4845 [(set (match_dup 2) (float_truncate:MODEF (match_dup 1)))
4846 (set (match_dup 0) (match_dup 2))])
4849 [(set (match_operand:MODEF 0 "memory_operand")
4850 (float_truncate:MODEF
4851 (match_operand:XF 1 "register_operand")))
4852 (clobber (match_operand:MODEF 2 "memory_operand"))]
4854 [(set (match_dup 0) (float_truncate:MODEF (match_dup 1)))])
4856 ;; Signed conversion to DImode.
4858 (define_expand "fix_truncxfdi2"
4859 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand")
4860 (fix:DI (match_operand:XF 1 "register_operand")))
4861 (clobber (reg:CC FLAGS_REG))])]
4866 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4871 (define_expand "fix_trunc<mode>di2"
4872 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand")
4873 (fix:DI (match_operand:MODEF 1 "register_operand")))
4874 (clobber (reg:CC FLAGS_REG))])]
4875 "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4878 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4880 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4883 if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4885 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4886 emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4887 if (out != operands[0])
4888 emit_move_insn (operands[0], out);
4893 ;; Signed conversion to SImode.
4895 (define_expand "fix_truncxfsi2"
4896 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand")
4897 (fix:SI (match_operand:XF 1 "register_operand")))
4898 (clobber (reg:CC FLAGS_REG))])]
4903 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4908 (define_expand "fix_trunc<mode>si2"
4909 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand")
4910 (fix:SI (match_operand:MODEF 1 "register_operand")))
4911 (clobber (reg:CC FLAGS_REG))])]
4912 "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4915 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4917 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4920 if (SSE_FLOAT_MODE_P (<MODE>mode))
4922 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4923 emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4924 if (out != operands[0])
4925 emit_move_insn (operands[0], out);
4930 ;; Signed conversion to HImode.
4932 (define_expand "fix_trunc<mode>hi2"
4933 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand")
4934 (fix:HI (match_operand:X87MODEF 1 "register_operand")))
4935 (clobber (reg:CC FLAGS_REG))])]
4937 && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4941 emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4946 ;; Unsigned conversion to SImode.
4948 (define_expand "fixuns_trunc<mode>si2"
4950 [(set (match_operand:SI 0 "register_operand")
4952 (match_operand:MODEF 1 "nonimmediate_operand")))
4954 (clobber (match_scratch:<ssevecmode> 3))
4955 (clobber (match_scratch:<ssevecmode> 4))])]
4956 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4958 machine_mode mode = <MODE>mode;
4959 machine_mode vecmode = <ssevecmode>mode;
4960 REAL_VALUE_TYPE TWO31r;
4963 if (optimize_insn_for_size_p ())
4966 real_ldexp (&TWO31r, &dconst1, 31);
4967 two31 = const_double_from_real_value (TWO31r, mode);
4968 two31 = ix86_build_const_vector (vecmode, true, two31);
4969 operands[2] = force_reg (vecmode, two31);
4972 (define_insn_and_split "*fixuns_trunc<mode>_1"
4973 [(set (match_operand:SI 0 "register_operand" "=&x,&x")
4975 (match_operand:MODEF 3 "nonimmediate_operand" "xm,xm")))
4976 (use (match_operand:<ssevecmode> 4 "nonimmediate_operand" "m,x"))
4977 (clobber (match_scratch:<ssevecmode> 1 "=x,&x"))
4978 (clobber (match_scratch:<ssevecmode> 2 "=x,x"))]
4979 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH
4980 && optimize_function_for_speed_p (cfun)"
4982 "&& reload_completed"
4985 ix86_split_convert_uns_si_sse (operands);
4989 ;; Unsigned conversion to HImode.
4990 ;; Without these patterns, we'll try the unsigned SI conversion which
4991 ;; is complex for SSE, rather than the signed SI conversion, which isn't.
4993 (define_expand "fixuns_trunc<mode>hi2"
4995 (fix:SI (match_operand:MODEF 1 "nonimmediate_operand")))
4996 (set (match_operand:HI 0 "nonimmediate_operand")
4997 (subreg:HI (match_dup 2) 0))]
4998 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
4999 "operands[2] = gen_reg_rtx (SImode);")
5001 ;; When SSE is available, it is always faster to use it!
5002 (define_insn "fix_trunc<MODEF:mode><SWI48:mode>_sse"
5003 [(set (match_operand:SWI48 0 "register_operand" "=r,r")
5004 (fix:SWI48 (match_operand:MODEF 1 "nonimmediate_operand" "v,m")))]
5005 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode)
5006 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
5007 "%vcvtt<MODEF:ssemodesuffix>2si<SWI48:rex64suffix>\t{%1, %0|%0, %1}"
5008 [(set_attr "type" "sseicvt")
5009 (set_attr "prefix" "maybe_vex")
5010 (set (attr "prefix_rex")
5012 (match_test "<SWI48:MODE>mode == DImode")
5014 (const_string "*")))
5015 (set_attr "mode" "<MODEF:MODE>")
5016 (set_attr "athlon_decode" "double,vector")
5017 (set_attr "amdfam10_decode" "double,double")
5018 (set_attr "bdver1_decode" "double,double")])
5020 ;; Avoid vector decoded forms of the instruction.
5022 [(match_scratch:MODEF 2 "x")
5023 (set (match_operand:SWI48 0 "register_operand")
5024 (fix:SWI48 (match_operand:MODEF 1 "memory_operand")))]
5025 "TARGET_AVOID_VECTOR_DECODE
5026 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode)
5027 && optimize_insn_for_speed_p ()"
5028 [(set (match_dup 2) (match_dup 1))
5029 (set (match_dup 0) (fix:SWI48 (match_dup 2)))])
5031 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
5032 [(set (match_operand:SWI248x 0 "nonimmediate_operand")
5033 (fix:SWI248x (match_operand 1 "register_operand")))]
5034 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5036 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
5037 && (TARGET_64BIT || <MODE>mode != DImode))
5039 && can_create_pseudo_p ()"
5044 if (memory_operand (operands[0], VOIDmode))
5045 emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
5048 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
5049 emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
5055 [(set_attr "type" "fisttp")
5056 (set_attr "mode" "<MODE>")])
5058 (define_insn "fix_trunc<mode>_i387_fisttp"
5059 [(set (match_operand:SWI248x 0 "memory_operand" "=m")
5060 (fix:SWI248x (match_operand 1 "register_operand" "f")))
5061 (clobber (match_scratch:XF 2 "=&1f"))]
5062 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5064 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
5065 && (TARGET_64BIT || <MODE>mode != DImode))
5066 && TARGET_SSE_MATH)"
5067 "* return output_fix_trunc (insn, operands, true);"
5068 [(set_attr "type" "fisttp")
5069 (set_attr "mode" "<MODE>")])
5071 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
5072 [(set (match_operand:SWI248x 0 "nonimmediate_operand" "=m,?r")
5073 (fix:SWI248x (match_operand 1 "register_operand" "f,f")))
5074 (clobber (match_operand:SWI248x 2 "memory_operand" "=X,m"))
5075 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
5076 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5078 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
5079 && (TARGET_64BIT || <MODE>mode != DImode))
5080 && TARGET_SSE_MATH)"
5082 [(set_attr "type" "fisttp")
5083 (set_attr "mode" "<MODE>")])
5086 [(set (match_operand:SWI248x 0 "register_operand")
5087 (fix:SWI248x (match_operand 1 "register_operand")))
5088 (clobber (match_operand:SWI248x 2 "memory_operand"))
5089 (clobber (match_scratch 3))]
5091 [(parallel [(set (match_dup 2) (fix:SWI248x (match_dup 1)))
5092 (clobber (match_dup 3))])
5093 (set (match_dup 0) (match_dup 2))])
5096 [(set (match_operand:SWI248x 0 "memory_operand")
5097 (fix:SWI248x (match_operand 1 "register_operand")))
5098 (clobber (match_operand:SWI248x 2 "memory_operand"))
5099 (clobber (match_scratch 3))]
5101 [(parallel [(set (match_dup 0) (fix:SWI248x (match_dup 1)))
5102 (clobber (match_dup 3))])])
5104 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
5105 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
5106 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
5107 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
5108 ;; function in i386.c.
5109 (define_insn_and_split "*fix_trunc<mode>_i387_1"
5110 [(set (match_operand:SWI248x 0 "nonimmediate_operand")
5111 (fix:SWI248x (match_operand 1 "register_operand")))
5112 (clobber (reg:CC FLAGS_REG))]
5113 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5115 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
5116 && (TARGET_64BIT || <MODE>mode != DImode))
5117 && can_create_pseudo_p ()"
5122 ix86_optimize_mode_switching[I387_TRUNC] = 1;
5124 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
5125 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
5126 if (memory_operand (operands[0], VOIDmode))
5127 emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
5128 operands[2], operands[3]));
5131 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
5132 emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
5133 operands[2], operands[3],
5138 [(set_attr "type" "fistp")
5139 (set_attr "i387_cw" "trunc")
5140 (set_attr "mode" "<MODE>")])
5142 (define_insn "fix_truncdi_i387"
5143 [(set (match_operand:DI 0 "memory_operand" "=m")
5144 (fix:DI (match_operand 1 "register_operand" "f")))
5145 (use (match_operand:HI 2 "memory_operand" "m"))
5146 (use (match_operand:HI 3 "memory_operand" "m"))
5147 (clobber (match_scratch:XF 4 "=&1f"))]
5148 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5150 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
5151 "* return output_fix_trunc (insn, operands, false);"
5152 [(set_attr "type" "fistp")
5153 (set_attr "i387_cw" "trunc")
5154 (set_attr "mode" "DI")])
5156 (define_insn "fix_truncdi_i387_with_temp"
5157 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
5158 (fix:DI (match_operand 1 "register_operand" "f,f")))
5159 (use (match_operand:HI 2 "memory_operand" "m,m"))
5160 (use (match_operand:HI 3 "memory_operand" "m,m"))
5161 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
5162 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
5163 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5165 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
5167 [(set_attr "type" "fistp")
5168 (set_attr "i387_cw" "trunc")
5169 (set_attr "mode" "DI")])
5172 [(set (match_operand:DI 0 "register_operand")
5173 (fix:DI (match_operand 1 "register_operand")))
5174 (use (match_operand:HI 2 "memory_operand"))
5175 (use (match_operand:HI 3 "memory_operand"))
5176 (clobber (match_operand:DI 4 "memory_operand"))
5177 (clobber (match_scratch 5))]
5179 [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
5182 (clobber (match_dup 5))])
5183 (set (match_dup 0) (match_dup 4))])
5186 [(set (match_operand:DI 0 "memory_operand")
5187 (fix:DI (match_operand 1 "register_operand")))
5188 (use (match_operand:HI 2 "memory_operand"))
5189 (use (match_operand:HI 3 "memory_operand"))
5190 (clobber (match_operand:DI 4 "memory_operand"))
5191 (clobber (match_scratch 5))]
5193 [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
5196 (clobber (match_dup 5))])])
5198 (define_insn "fix_trunc<mode>_i387"
5199 [(set (match_operand:SWI24 0 "memory_operand" "=m")
5200 (fix:SWI24 (match_operand 1 "register_operand" "f")))
5201 (use (match_operand:HI 2 "memory_operand" "m"))
5202 (use (match_operand:HI 3 "memory_operand" "m"))]
5203 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5205 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
5206 "* return output_fix_trunc (insn, operands, false);"
5207 [(set_attr "type" "fistp")
5208 (set_attr "i387_cw" "trunc")
5209 (set_attr "mode" "<MODE>")])
5211 (define_insn "fix_trunc<mode>_i387_with_temp"
5212 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
5213 (fix:SWI24 (match_operand 1 "register_operand" "f,f")))
5214 (use (match_operand:HI 2 "memory_operand" "m,m"))
5215 (use (match_operand:HI 3 "memory_operand" "m,m"))
5216 (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
5217 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5219 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
5221 [(set_attr "type" "fistp")
5222 (set_attr "i387_cw" "trunc")
5223 (set_attr "mode" "<MODE>")])
5226 [(set (match_operand:SWI24 0 "register_operand")
5227 (fix:SWI24 (match_operand 1 "register_operand")))
5228 (use (match_operand:HI 2 "memory_operand"))
5229 (use (match_operand:HI 3 "memory_operand"))
5230 (clobber (match_operand:SWI24 4 "memory_operand"))]
5232 [(parallel [(set (match_dup 4) (fix:SWI24 (match_dup 1)))
5234 (use (match_dup 3))])
5235 (set (match_dup 0) (match_dup 4))])
5238 [(set (match_operand:SWI24 0 "memory_operand")
5239 (fix:SWI24 (match_operand 1 "register_operand")))
5240 (use (match_operand:HI 2 "memory_operand"))
5241 (use (match_operand:HI 3 "memory_operand"))
5242 (clobber (match_operand:SWI24 4 "memory_operand"))]
5244 [(parallel [(set (match_dup 0) (fix:SWI24 (match_dup 1)))
5246 (use (match_dup 3))])])
5248 (define_insn "x86_fnstcw_1"
5249 [(set (match_operand:HI 0 "memory_operand" "=m")
5250 (unspec:HI [(reg:HI FPCR_REG)] UNSPEC_FSTCW))]
5253 [(set (attr "length")
5254 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
5255 (set_attr "mode" "HI")
5256 (set_attr "unit" "i387")
5257 (set_attr "bdver1_decode" "vector")])
5259 (define_insn "x86_fldcw_1"
5260 [(set (reg:HI FPCR_REG)
5261 (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
5264 [(set (attr "length")
5265 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
5266 (set_attr "mode" "HI")
5267 (set_attr "unit" "i387")
5268 (set_attr "athlon_decode" "vector")
5269 (set_attr "amdfam10_decode" "vector")
5270 (set_attr "bdver1_decode" "vector")])
5272 ;; Conversion between fixed point and floating point.
5274 ;; Even though we only accept memory inputs, the backend _really_
5275 ;; wants to be able to do this between registers. Thankfully, LRA
5276 ;; will fix this up for us during register allocation.
5278 (define_insn "floathi<mode>2"
5279 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5280 (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "m")))]
5282 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5283 || TARGET_MIX_SSE_I387)"
5285 [(set_attr "type" "fmov")
5286 (set_attr "mode" "<MODE>")
5287 (set_attr "znver1_decode" "double")
5288 (set_attr "fp_int_src" "true")])
5290 (define_insn "float<SWI48x:mode>xf2"
5291 [(set (match_operand:XF 0 "register_operand" "=f")
5292 (float:XF (match_operand:SWI48x 1 "nonimmediate_operand" "m")))]
5295 [(set_attr "type" "fmov")
5296 (set_attr "mode" "XF")
5297 (set_attr "znver1_decode" "double")
5298 (set_attr "fp_int_src" "true")])
5300 (define_expand "float<SWI48:mode><MODEF:mode>2"
5301 [(set (match_operand:MODEF 0 "register_operand")
5302 (float:MODEF (match_operand:SWI48 1 "nonimmediate_operand")))]
5303 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)"
5305 if (!(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
5306 && !X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI48:MODE>mode))
5308 rtx reg = gen_reg_rtx (XFmode);
5309 rtx (*insn)(rtx, rtx);
5311 emit_insn (gen_float<SWI48:mode>xf2 (reg, operands[1]));
5313 if (<MODEF:MODE>mode == SFmode)
5314 insn = gen_truncxfsf2;
5315 else if (<MODEF:MODE>mode == DFmode)
5316 insn = gen_truncxfdf2;
5320 emit_insn (insn (operands[0], reg));
5325 (define_insn "*float<SWI48:mode><MODEF:mode>2_mixed"
5326 [(set (match_operand:MODEF 0 "register_operand" "=f,Yc,v")
5328 (match_operand:SWI48 1 "nonimmediate_operand" "m,r,m")))]
5329 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
5332 %vcvtsi2<MODEF:ssemodesuffix><SWI48:rex64suffix>\t{%1, %d0|%d0, %1}
5333 %vcvtsi2<MODEF:ssemodesuffix><SWI48:rex64suffix>\t{%1, %d0|%d0, %1}"
5334 [(set_attr "type" "fmov,sseicvt,sseicvt")
5335 (set_attr "prefix" "orig,maybe_vex,maybe_vex")
5336 (set_attr "mode" "<MODEF:MODE>")
5337 (set (attr "prefix_rex")
5339 (and (eq_attr "prefix" "maybe_vex")
5340 (match_test "<SWI48:MODE>mode == DImode"))
5342 (const_string "*")))
5343 (set_attr "unit" "i387,*,*")
5344 (set_attr "athlon_decode" "*,double,direct")
5345 (set_attr "amdfam10_decode" "*,vector,double")
5346 (set_attr "bdver1_decode" "*,double,direct")
5347 (set_attr "znver1_decode" "double,*,*")
5348 (set_attr "fp_int_src" "true")
5349 (set (attr "enabled")
5350 (cond [(eq_attr "alternative" "0")
5351 (symbol_ref "TARGET_MIX_SSE_I387
5352 && X87_ENABLE_FLOAT (<MODEF:MODE>mode,
5355 (symbol_ref "true")))])
5357 (define_insn "*float<SWI48x:mode><MODEF:mode>2_i387"
5358 [(set (match_operand:MODEF 0 "register_operand" "=f")
5359 (float:MODEF (match_operand:SWI48x 1 "nonimmediate_operand" "m")))]
5360 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI48x:MODE>mode)"
5362 [(set_attr "type" "fmov")
5363 (set_attr "mode" "<MODEF:MODE>")
5364 (set_attr "znver1_decode" "double")
5365 (set_attr "fp_int_src" "true")])
5367 ;; Try TARGET_USE_VECTOR_CONVERTS, but not so hard as to require extra memory
5368 ;; slots when !TARGET_INTER_UNIT_MOVES_TO_VEC disables the general_regs
5369 ;; alternative in sse2_loadld.
5371 [(set (match_operand:MODEF 0 "sse_reg_operand")
5372 (float:MODEF (match_operand:SI 1 "nonimmediate_operand")))]
5374 && TARGET_USE_VECTOR_CONVERTS
5375 && optimize_function_for_speed_p (cfun)
5377 && (MEM_P (operands[1]) || TARGET_INTER_UNIT_MOVES_TO_VEC)
5378 && (!EXT_REX_SSE_REG_P (operands[0])
5379 || TARGET_AVX512VL)"
5382 operands[3] = lowpart_subreg (<ssevecmode>mode, operands[0], <MODE>mode);
5383 operands[4] = lowpart_subreg (V4SImode, operands[0], <MODE>mode);
5385 emit_insn (gen_sse2_loadld (operands[4],
5386 CONST0_RTX (V4SImode), operands[1]));
5388 if (<ssevecmode>mode == V4SFmode)
5389 emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
5391 emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
5395 ;; Avoid partial SSE register dependency stalls. This splitter should split
5396 ;; late in the pass sequence (after register rename pass), so allocated
5397 ;; registers won't change anymore
5400 [(set (match_operand:MODEF 0 "sse_reg_operand")
5401 (float:MODEF (match_operand:SWI48 1 "nonimmediate_operand")))]
5402 "TARGET_SSE_PARTIAL_REG_DEPENDENCY && epilogue_completed
5403 && optimize_function_for_speed_p (cfun)
5404 && (!EXT_REX_SSE_REG_P (operands[0])
5405 || TARGET_AVX512VL)"
5407 (vec_merge:<MODEF:ssevecmode>
5408 (vec_duplicate:<MODEF:ssevecmode>
5414 const machine_mode vmode = <MODEF:ssevecmode>mode;
5416 operands[0] = lowpart_subreg (vmode, operands[0], <MODEF:MODE>mode);
5417 emit_move_insn (operands[0], CONST0_RTX (vmode));
5420 ;; Break partial reg stall for cvtsd2ss. This splitter should split
5421 ;; late in the pass sequence (after register rename pass),
5422 ;; so allocated registers won't change anymore.
5425 [(set (match_operand:SF 0 "sse_reg_operand")
5427 (match_operand:DF 1 "nonimmediate_operand")))]
5428 "TARGET_SSE_PARTIAL_REG_DEPENDENCY && epilogue_completed
5429 && optimize_function_for_speed_p (cfun)
5430 && (!REG_P (operands[1])
5431 || REGNO (operands[0]) != REGNO (operands[1]))
5432 && (!EXT_REX_SSE_REG_P (operands[0])
5433 || TARGET_AVX512VL)"
5442 operands[0] = lowpart_subreg (V4SFmode, operands[0], SFmode);
5443 emit_move_insn (operands[0], CONST0_RTX (V4SFmode));
5446 ;; Break partial reg stall for cvtss2sd. This splitter should split
5447 ;; late in the pass sequence (after register rename pass),
5448 ;; so allocated registers won't change anymore.
5451 [(set (match_operand:DF 0 "sse_reg_operand")
5453 (match_operand:SF 1 "nonimmediate_operand")))]
5454 "TARGET_SSE_PARTIAL_REG_DEPENDENCY && epilogue_completed
5455 && optimize_function_for_speed_p (cfun)
5456 && (!REG_P (operands[1])
5457 || REGNO (operands[0]) != REGNO (operands[1]))
5458 && (!EXT_REX_SSE_REG_P (operands[0])
5459 || TARGET_AVX512VL)"
5468 operands[0] = lowpart_subreg (V2DFmode, operands[0], DFmode);
5469 emit_move_insn (operands[0], CONST0_RTX (V2DFmode));
5472 ;; Avoid store forwarding (partial memory) stall penalty
5473 ;; by passing DImode value through XMM registers. */
5475 (define_insn "floatdi<X87MODEF:mode>2_i387_with_xmm"
5476 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5478 (match_operand:DI 1 "nonimmediate_operand" "m,?r")))
5479 (clobber (match_scratch:V4SI 3 "=X,x"))
5480 (clobber (match_scratch:V4SI 4 "=X,x"))
5481 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))]
5482 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5483 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC
5484 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)"
5486 [(set_attr "type" "multi")
5487 (set_attr "mode" "<X87MODEF:MODE>")
5488 (set_attr "unit" "i387")
5489 (set_attr "fp_int_src" "true")])
5492 [(set (match_operand:X87MODEF 0 "fp_register_operand")
5493 (float:X87MODEF (match_operand:DI 1 "register_operand")))
5494 (clobber (match_scratch:V4SI 3))
5495 (clobber (match_scratch:V4SI 4))
5496 (clobber (match_operand:DI 2 "memory_operand"))]
5497 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5498 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC
5499 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5500 && reload_completed"
5501 [(set (match_dup 2) (match_dup 3))
5502 (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5504 /* The DImode arrived in a pair of integral registers (e.g. %edx:%eax).
5505 Assemble the 64-bit DImode value in an xmm register. */
5506 emit_insn (gen_sse2_loadld (operands[3], CONST0_RTX (V4SImode),
5507 gen_lowpart (SImode, operands[1])));
5508 emit_insn (gen_sse2_loadld (operands[4], CONST0_RTX (V4SImode),
5509 gen_highpart (SImode, operands[1])));
5510 emit_insn (gen_vec_interleave_lowv4si (operands[3], operands[3],
5513 operands[3] = gen_lowpart (DImode, operands[3]);
5517 [(set (match_operand:X87MODEF 0 "fp_register_operand")
5518 (float:X87MODEF (match_operand:DI 1 "memory_operand")))
5519 (clobber (match_scratch:V4SI 3))
5520 (clobber (match_scratch:V4SI 4))
5521 (clobber (match_operand:DI 2 "memory_operand"))]
5522 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5523 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC
5524 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5525 && reload_completed"
5526 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
5528 (define_expand "floatuns<SWI12:mode><MODEF:mode>2"
5529 [(set (match_operand:MODEF 0 "register_operand")
5530 (unsigned_float:MODEF
5531 (match_operand:SWI12 1 "nonimmediate_operand")))]
5533 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
5535 operands[1] = convert_to_mode (SImode, operands[1], 1);
5536 emit_insn (gen_floatsi<MODEF:mode>2 (operands[0], operands[1]));
5540 ;; Avoid store forwarding (partial memory) stall penalty by extending
5541 ;; SImode value to DImode through XMM register instead of pushing two
5542 ;; SImode values to stack. Also note that fild loads from memory only.
5544 (define_insn_and_split "*floatunssi<mode>2_i387_with_xmm"
5545 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5546 (unsigned_float:X87MODEF
5547 (match_operand:SI 1 "nonimmediate_operand" "rm")))
5548 (clobber (match_scratch:DI 3 "=x"))
5549 (clobber (match_operand:DI 2 "memory_operand" "=m"))]
5551 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5552 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC"
5554 "&& reload_completed"
5555 [(set (match_dup 3) (zero_extend:DI (match_dup 1)))
5556 (set (match_dup 2) (match_dup 3))
5558 (float:X87MODEF (match_dup 2)))]
5560 [(set_attr "type" "multi")
5561 (set_attr "mode" "<MODE>")])
5563 (define_expand "floatunssi<mode>2"
5565 [(set (match_operand:X87MODEF 0 "register_operand")
5566 (unsigned_float:X87MODEF
5567 (match_operand:SI 1 "nonimmediate_operand")))
5568 (clobber (match_scratch:DI 3))
5569 (clobber (match_dup 2))])]
5571 && ((TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5572 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC)
5573 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
5575 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5577 ix86_expand_convert_uns_si<mode>_sse (operands[0], operands[1]);
5581 operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
5584 (define_expand "floatunsdisf2"
5585 [(use (match_operand:SF 0 "register_operand"))
5586 (use (match_operand:DI 1 "nonimmediate_operand"))]
5587 "TARGET_64BIT && TARGET_SSE && TARGET_SSE_MATH"
5588 "x86_emit_floatuns (operands); DONE;")
5590 (define_expand "floatunsdidf2"
5591 [(use (match_operand:DF 0 "register_operand"))
5592 (use (match_operand:DI 1 "nonimmediate_operand"))]
5593 "(TARGET_64BIT || TARGET_KEEPS_VECTOR_ALIGNED_STACK)
5594 && TARGET_SSE2 && TARGET_SSE_MATH"
5597 x86_emit_floatuns (operands);
5599 ix86_expand_convert_uns_didf_sse (operands[0], operands[1]);
5603 ;; Load effective address instructions
5605 (define_insn_and_split "*lea<mode>"
5606 [(set (match_operand:SWI48 0 "register_operand" "=r")
5607 (match_operand:SWI48 1 "address_no_seg_operand" "Ts"))]
5610 if (SImode_address_operand (operands[1], VOIDmode))
5612 gcc_assert (TARGET_64BIT);
5613 return "lea{l}\t{%E1, %k0|%k0, %E1}";
5616 return "lea{<imodesuffix>}\t{%E1, %0|%0, %E1}";
5618 "reload_completed && ix86_avoid_lea_for_addr (insn, operands)"
5621 machine_mode mode = <MODE>mode;
5624 /* ix86_avoid_lea_for_addr re-recognizes insn and may
5625 change operands[] array behind our back. */
5626 pat = PATTERN (curr_insn);
5628 operands[0] = SET_DEST (pat);
5629 operands[1] = SET_SRC (pat);
5631 /* Emit all operations in SImode for zero-extended addresses. */
5632 if (SImode_address_operand (operands[1], VOIDmode))
5635 ix86_split_lea_for_addr (curr_insn, operands, mode);
5637 /* Zero-extend return register to DImode for zero-extended addresses. */
5638 if (mode != <MODE>mode)
5639 emit_insn (gen_zero_extendsidi2
5640 (operands[0], gen_lowpart (mode, operands[0])));
5644 [(set_attr "type" "lea")
5647 (match_operand 1 "SImode_address_operand")
5649 (const_string "<MODE>")))])
5653 (define_expand "add<mode>3"
5654 [(set (match_operand:SDWIM 0 "nonimmediate_operand")
5655 (plus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")
5656 (match_operand:SDWIM 2 "<general_hilo_operand>")))]
5658 "ix86_expand_binary_operator (PLUS, <MODE>mode, operands); DONE;")
5660 (define_insn_and_split "*add<dwi>3_doubleword"
5661 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
5663 (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0")
5664 (match_operand:<DWI> 2 "x86_64_hilo_general_operand"
5666 (clobber (reg:CC FLAGS_REG))]
5667 "ix86_binary_operator_ok (PLUS, <DWI>mode, operands)"
5670 [(parallel [(set (reg:CCC FLAGS_REG)
5672 (plus:DWIH (match_dup 1) (match_dup 2))
5675 (plus:DWIH (match_dup 1) (match_dup 2)))])
5676 (parallel [(set (match_dup 3)
5679 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
5682 (clobber (reg:CC FLAGS_REG))])]
5684 split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
5685 if (operands[2] == const0_rtx)
5687 ix86_expand_binary_operator (PLUS, <MODE>mode, &operands[3]);
5692 (define_insn "*add<mode>_1"
5693 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,rm,r,r")
5695 (match_operand:SWI48 1 "nonimmediate_operand" "%0,0,r,r")
5696 (match_operand:SWI48 2 "x86_64_general_operand" "rme,re,0,le")))
5697 (clobber (reg:CC FLAGS_REG))]
5698 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5700 switch (get_attr_type (insn))
5706 gcc_assert (rtx_equal_p (operands[0], operands[1]));
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 /* For most processors, ADD is faster than LEA. This alternative
5717 was added to use ADD as much as possible. */
5718 if (which_alternative == 2)
5719 std::swap (operands[1], operands[2]);
5721 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5722 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5723 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5725 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5729 (cond [(eq_attr "alternative" "3")
5730 (const_string "lea")
5731 (match_operand:SWI48 2 "incdec_operand")
5732 (const_string "incdec")
5734 (const_string "alu")))
5735 (set (attr "length_immediate")
5737 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5739 (const_string "*")))
5740 (set_attr "mode" "<MODE>")])
5742 ;; It may seem that nonimmediate operand is proper one for operand 1.
5743 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5744 ;; we take care in ix86_binary_operator_ok to not allow two memory
5745 ;; operands so proper swapping will be done in reload. This allow
5746 ;; patterns constructed from addsi_1 to match.
5748 (define_insn "addsi_1_zext"
5749 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
5751 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r,r")
5752 (match_operand:SI 2 "x86_64_general_operand" "rme,0,le"))))
5753 (clobber (reg:CC FLAGS_REG))]
5754 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5756 switch (get_attr_type (insn))
5762 if (operands[2] == const1_rtx)
5763 return "inc{l}\t%k0";
5766 gcc_assert (operands[2] == constm1_rtx);
5767 return "dec{l}\t%k0";
5771 /* For most processors, ADD is faster than LEA. This alternative
5772 was added to use ADD as much as possible. */
5773 if (which_alternative == 1)
5774 std::swap (operands[1], operands[2]);
5776 if (x86_maybe_negate_const_int (&operands[2], SImode))
5777 return "sub{l}\t{%2, %k0|%k0, %2}";
5779 return "add{l}\t{%2, %k0|%k0, %2}";
5783 (cond [(eq_attr "alternative" "2")
5784 (const_string "lea")
5785 (match_operand:SI 2 "incdec_operand")
5786 (const_string "incdec")
5788 (const_string "alu")))
5789 (set (attr "length_immediate")
5791 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5793 (const_string "*")))
5794 (set_attr "mode" "SI")])
5796 (define_insn "*addhi_1"
5797 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r,Yp")
5798 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r,Yp")
5799 (match_operand:HI 2 "general_operand" "rn,rm,0,ln")))
5800 (clobber (reg:CC FLAGS_REG))]
5801 "ix86_binary_operator_ok (PLUS, HImode, operands)"
5803 switch (get_attr_type (insn))
5809 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5810 if (operands[2] == const1_rtx)
5811 return "inc{w}\t%0";
5814 gcc_assert (operands[2] == constm1_rtx);
5815 return "dec{w}\t%0";
5819 /* For most processors, ADD is faster than LEA. This alternative
5820 was added to use ADD as much as possible. */
5821 if (which_alternative == 2)
5822 std::swap (operands[1], operands[2]);
5824 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5825 if (x86_maybe_negate_const_int (&operands[2], HImode))
5826 return "sub{w}\t{%2, %0|%0, %2}";
5828 return "add{w}\t{%2, %0|%0, %2}";
5832 (cond [(eq_attr "alternative" "3")
5833 (const_string "lea")
5834 (match_operand:HI 2 "incdec_operand")
5835 (const_string "incdec")
5837 (const_string "alu")))
5838 (set (attr "length_immediate")
5840 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5842 (const_string "*")))
5843 (set_attr "mode" "HI,HI,HI,SI")])
5845 (define_insn "*addqi_1"
5846 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,q,r,r,Yp")
5847 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,q,0,r,Yp")
5848 (match_operand:QI 2 "general_operand" "qn,qm,0,rn,0,ln")))
5849 (clobber (reg:CC FLAGS_REG))]
5850 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5852 bool widen = (get_attr_mode (insn) != MODE_QI);
5854 switch (get_attr_type (insn))
5860 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5861 if (operands[2] == const1_rtx)
5862 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
5865 gcc_assert (operands[2] == constm1_rtx);
5866 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
5870 /* For most processors, ADD is faster than LEA. These alternatives
5871 were added to use ADD as much as possible. */
5872 if (which_alternative == 2 || which_alternative == 4)
5873 std::swap (operands[1], operands[2]);
5875 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5876 if (x86_maybe_negate_const_int (&operands[2], QImode))
5879 return "sub{l}\t{%2, %k0|%k0, %2}";
5881 return "sub{b}\t{%2, %0|%0, %2}";
5884 return "add{l}\t{%k2, %k0|%k0, %k2}";
5886 return "add{b}\t{%2, %0|%0, %2}";
5890 (cond [(eq_attr "alternative" "5")
5891 (const_string "lea")
5892 (match_operand:QI 2 "incdec_operand")
5893 (const_string "incdec")
5895 (const_string "alu")))
5896 (set (attr "length_immediate")
5898 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5900 (const_string "*")))
5901 (set_attr "mode" "QI,QI,QI,SI,SI,SI")
5902 ;; Potential partial reg stall on alternatives 3 and 4.
5903 (set (attr "preferred_for_speed")
5904 (cond [(eq_attr "alternative" "3,4")
5905 (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
5906 (symbol_ref "true")))])
5908 (define_insn "*addqi_1_slp"
5909 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
5910 (plus:QI (match_dup 0)
5911 (match_operand:QI 1 "general_operand" "qn,qm")))
5912 (clobber (reg:CC FLAGS_REG))]
5913 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
5914 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
5916 switch (get_attr_type (insn))
5919 if (operands[1] == const1_rtx)
5920 return "inc{b}\t%0";
5923 gcc_assert (operands[1] == constm1_rtx);
5924 return "dec{b}\t%0";
5928 if (x86_maybe_negate_const_int (&operands[1], QImode))
5929 return "sub{b}\t{%1, %0|%0, %1}";
5931 return "add{b}\t{%1, %0|%0, %1}";
5935 (if_then_else (match_operand:QI 1 "incdec_operand")
5936 (const_string "incdec")
5937 (const_string "alu1")))
5938 (set (attr "memory")
5939 (if_then_else (match_operand 1 "memory_operand")
5940 (const_string "load")
5941 (const_string "none")))
5942 (set_attr "mode" "QI")])
5944 ;; Split non destructive adds if we cannot use lea.
5946 [(set (match_operand:SWI48 0 "register_operand")
5947 (plus:SWI48 (match_operand:SWI48 1 "register_operand")
5948 (match_operand:SWI48 2 "x86_64_nonmemory_operand")))
5949 (clobber (reg:CC FLAGS_REG))]
5950 "reload_completed && ix86_avoid_lea_for_add (insn, operands)"
5951 [(set (match_dup 0) (match_dup 1))
5952 (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 2)))
5953 (clobber (reg:CC FLAGS_REG))])])
5955 ;; Split non destructive adds if we cannot use lea.
5957 [(set (match_operand:DI 0 "register_operand")
5959 (plus:SI (match_operand:SI 1 "register_operand")
5960 (match_operand:SI 2 "x86_64_nonmemory_operand"))))
5961 (clobber (reg:CC FLAGS_REG))]
5963 && reload_completed && ix86_avoid_lea_for_add (insn, operands)"
5964 [(set (match_dup 3) (match_dup 1))
5965 (parallel [(set (match_dup 0)
5966 (zero_extend:DI (plus:SI (match_dup 3) (match_dup 2))))
5967 (clobber (reg:CC FLAGS_REG))])]
5968 "operands[3] = gen_lowpart (SImode, operands[0]);")
5970 ;; Convert add to the lea pattern to avoid flags dependency.
5972 [(set (match_operand:SWI 0 "register_operand")
5973 (plus:SWI (match_operand:SWI 1 "register_operand")
5974 (match_operand:SWI 2 "<nonmemory_operand>")))
5975 (clobber (reg:CC FLAGS_REG))]
5976 "reload_completed && ix86_lea_for_add_ok (insn, operands)"
5978 (plus:<LEAMODE> (match_dup 1) (match_dup 2)))]
5980 if (<MODE>mode != <LEAMODE>mode)
5982 operands[0] = gen_lowpart (<LEAMODE>mode, operands[0]);
5983 operands[1] = gen_lowpart (<LEAMODE>mode, operands[1]);
5984 operands[2] = gen_lowpart (<LEAMODE>mode, operands[2]);
5988 ;; Convert add to the lea pattern to avoid flags dependency.
5990 [(set (match_operand:DI 0 "register_operand")
5992 (plus:SI (match_operand:SI 1 "register_operand")
5993 (match_operand:SI 2 "x86_64_nonmemory_operand"))))
5994 (clobber (reg:CC FLAGS_REG))]
5995 "TARGET_64BIT && reload_completed && ix86_lea_for_add_ok (insn, operands)"
5997 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))])
5999 (define_insn "*add<mode>_2"
6000 [(set (reg FLAGS_REG)
6003 (match_operand:SWI 1 "nonimmediate_operand" "%0,0,<r>")
6004 (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>,0"))
6006 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m,<r>")
6007 (plus:SWI (match_dup 1) (match_dup 2)))]
6008 "ix86_match_ccmode (insn, CCGOCmode)
6009 && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6011 switch (get_attr_type (insn))
6014 if (operands[2] == const1_rtx)
6015 return "inc{<imodesuffix>}\t%0";
6018 gcc_assert (operands[2] == constm1_rtx);
6019 return "dec{<imodesuffix>}\t%0";
6023 if (which_alternative == 2)
6024 std::swap (operands[1], operands[2]);
6026 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6027 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6028 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6030 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6034 (if_then_else (match_operand:SWI 2 "incdec_operand")
6035 (const_string "incdec")
6036 (const_string "alu")))
6037 (set (attr "length_immediate")
6039 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6041 (const_string "*")))
6042 (set_attr "mode" "<MODE>")])
6044 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6045 (define_insn "*addsi_2_zext"
6046 [(set (reg FLAGS_REG)
6048 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
6049 (match_operand:SI 2 "x86_64_general_operand" "rme,0"))
6051 (set (match_operand:DI 0 "register_operand" "=r,r")
6052 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6053 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6054 && ix86_binary_operator_ok (PLUS, SImode, operands)"
6056 switch (get_attr_type (insn))
6059 if (operands[2] == const1_rtx)
6060 return "inc{l}\t%k0";
6063 gcc_assert (operands[2] == constm1_rtx);
6064 return "dec{l}\t%k0";
6068 if (which_alternative == 1)
6069 std::swap (operands[1], operands[2]);
6071 if (x86_maybe_negate_const_int (&operands[2], SImode))
6072 return "sub{l}\t{%2, %k0|%k0, %2}";
6074 return "add{l}\t{%2, %k0|%k0, %2}";
6078 (if_then_else (match_operand:SI 2 "incdec_operand")
6079 (const_string "incdec")
6080 (const_string "alu")))
6081 (set (attr "length_immediate")
6083 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6085 (const_string "*")))
6086 (set_attr "mode" "SI")])
6088 (define_insn "*add<mode>_3"
6089 [(set (reg FLAGS_REG)
6091 (neg:SWI (match_operand:SWI 2 "<general_operand>" "<g>,0"))
6092 (match_operand:SWI 1 "nonimmediate_operand" "%0,<r>")))
6093 (clobber (match_scratch:SWI 0 "=<r>,<r>"))]
6094 "ix86_match_ccmode (insn, CCZmode)
6095 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6097 switch (get_attr_type (insn))
6100 if (operands[2] == const1_rtx)
6101 return "inc{<imodesuffix>}\t%0";
6104 gcc_assert (operands[2] == constm1_rtx);
6105 return "dec{<imodesuffix>}\t%0";
6109 if (which_alternative == 1)
6110 std::swap (operands[1], operands[2]);
6112 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6113 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6114 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6116 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6120 (if_then_else (match_operand:SWI 2 "incdec_operand")
6121 (const_string "incdec")
6122 (const_string "alu")))
6123 (set (attr "length_immediate")
6125 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6127 (const_string "*")))
6128 (set_attr "mode" "<MODE>")])
6130 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6131 (define_insn "*addsi_3_zext"
6132 [(set (reg FLAGS_REG)
6134 (neg:SI (match_operand:SI 2 "x86_64_general_operand" "rme,0"))
6135 (match_operand:SI 1 "nonimmediate_operand" "%0,r")))
6136 (set (match_operand:DI 0 "register_operand" "=r,r")
6137 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6138 "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
6139 && ix86_binary_operator_ok (PLUS, SImode, operands)"
6141 switch (get_attr_type (insn))
6144 if (operands[2] == const1_rtx)
6145 return "inc{l}\t%k0";
6148 gcc_assert (operands[2] == constm1_rtx);
6149 return "dec{l}\t%k0";
6153 if (which_alternative == 1)
6154 std::swap (operands[1], operands[2]);
6156 if (x86_maybe_negate_const_int (&operands[2], SImode))
6157 return "sub{l}\t{%2, %k0|%k0, %2}";
6159 return "add{l}\t{%2, %k0|%k0, %2}";
6163 (if_then_else (match_operand:SI 2 "incdec_operand")
6164 (const_string "incdec")
6165 (const_string "alu")))
6166 (set (attr "length_immediate")
6168 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6170 (const_string "*")))
6171 (set_attr "mode" "SI")])
6173 ; For comparisons against 1, -1 and 128, we may generate better code
6174 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
6175 ; is matched then. We can't accept general immediate, because for
6176 ; case of overflows, the result is messed up.
6177 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6178 ; only for comparisons not depending on it.
6180 (define_insn "*adddi_4"
6181 [(set (reg FLAGS_REG)
6183 (match_operand:DI 1 "nonimmediate_operand" "0")
6184 (match_operand:DI 2 "x86_64_immediate_operand" "e")))
6185 (clobber (match_scratch:DI 0 "=rm"))]
6187 && ix86_match_ccmode (insn, CCGCmode)"
6189 switch (get_attr_type (insn))
6192 if (operands[2] == constm1_rtx)
6193 return "inc{q}\t%0";
6196 gcc_assert (operands[2] == const1_rtx);
6197 return "dec{q}\t%0";
6201 if (x86_maybe_negate_const_int (&operands[2], DImode))
6202 return "add{q}\t{%2, %0|%0, %2}";
6204 return "sub{q}\t{%2, %0|%0, %2}";
6208 (if_then_else (match_operand:DI 2 "incdec_operand")
6209 (const_string "incdec")
6210 (const_string "alu")))
6211 (set (attr "length_immediate")
6213 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6215 (const_string "*")))
6216 (set_attr "mode" "DI")])
6218 ; For comparisons against 1, -1 and 128, we may generate better code
6219 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
6220 ; is matched then. We can't accept general immediate, because for
6221 ; case of overflows, the result is messed up.
6222 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6223 ; only for comparisons not depending on it.
6225 (define_insn "*add<mode>_4"
6226 [(set (reg FLAGS_REG)
6228 (match_operand:SWI124 1 "nonimmediate_operand" "0")
6229 (match_operand:SWI124 2 "const_int_operand" "n")))
6230 (clobber (match_scratch:SWI124 0 "=<r>m"))]
6231 "ix86_match_ccmode (insn, CCGCmode)"
6233 switch (get_attr_type (insn))
6236 if (operands[2] == constm1_rtx)
6237 return "inc{<imodesuffix>}\t%0";
6240 gcc_assert (operands[2] == const1_rtx);
6241 return "dec{<imodesuffix>}\t%0";
6245 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6246 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6248 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6252 (if_then_else (match_operand:<MODE> 2 "incdec_operand")
6253 (const_string "incdec")
6254 (const_string "alu")))
6255 (set (attr "length_immediate")
6257 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6259 (const_string "*")))
6260 (set_attr "mode" "<MODE>")])
6262 (define_insn "*add<mode>_5"
6263 [(set (reg FLAGS_REG)
6266 (match_operand:SWI 1 "nonimmediate_operand" "%0,<r>")
6267 (match_operand:SWI 2 "<general_operand>" "<g>,0"))
6269 (clobber (match_scratch:SWI 0 "=<r>,<r>"))]
6270 "ix86_match_ccmode (insn, CCGOCmode)
6271 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6273 switch (get_attr_type (insn))
6276 if (operands[2] == const1_rtx)
6277 return "inc{<imodesuffix>}\t%0";
6280 gcc_assert (operands[2] == constm1_rtx);
6281 return "dec{<imodesuffix>}\t%0";
6285 if (which_alternative == 1)
6286 std::swap (operands[1], operands[2]);
6288 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6289 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6290 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6292 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6296 (if_then_else (match_operand:SWI 2 "incdec_operand")
6297 (const_string "incdec")
6298 (const_string "alu")))
6299 (set (attr "length_immediate")
6301 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6303 (const_string "*")))
6304 (set_attr "mode" "<MODE>")])
6306 (define_insn "addqi_ext_1"
6307 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q,Q")
6313 (zero_extract:SI (match_operand 1 "ext_register_operand" "0,0")
6316 (match_operand:QI 2 "general_operand" "QnBc,m")) 0))
6317 (clobber (reg:CC FLAGS_REG))]
6318 "/* FIXME: without this LRA can't reload this pattern, see PR82524. */
6319 rtx_equal_p (operands[0], operands[1])"
6321 switch (get_attr_type (insn))
6324 if (operands[2] == const1_rtx)
6325 return "inc{b}\t%h0";
6328 gcc_assert (operands[2] == constm1_rtx);
6329 return "dec{b}\t%h0";
6333 return "add{b}\t{%2, %h0|%h0, %2}";
6336 [(set_attr "isa" "*,nox64")
6338 (if_then_else (match_operand:QI 2 "incdec_operand")
6339 (const_string "incdec")
6340 (const_string "alu")))
6341 (set_attr "mode" "QI")])
6343 (define_insn "*addqi_ext_2"
6344 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
6350 (zero_extract:SI (match_operand 1 "ext_register_operand" "%0")
6354 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
6356 (const_int 8)) 0)) 0))
6357 (clobber (reg:CC FLAGS_REG))]
6358 "/* FIXME: without this LRA can't reload this pattern, see PR82524. */
6359 rtx_equal_p (operands[0], operands[1])
6360 || rtx_equal_p (operands[0], operands[2])"
6361 "add{b}\t{%h2, %h0|%h0, %h2}"
6362 [(set_attr "type" "alu")
6363 (set_attr "mode" "QI")])
6365 ;; Add with jump on overflow.
6366 (define_expand "addv<mode>4"
6367 [(parallel [(set (reg:CCO FLAGS_REG)
6370 (match_operand:SWI 1 "nonimmediate_operand"))
6373 (plus:SWI (match_dup 1)
6374 (match_operand:SWI 2
6375 "<general_operand>")))))
6376 (set (match_operand:SWI 0 "register_operand")
6377 (plus:SWI (match_dup 1) (match_dup 2)))])
6378 (set (pc) (if_then_else
6379 (eq (reg:CCO FLAGS_REG) (const_int 0))
6380 (label_ref (match_operand 3))
6384 ix86_fixup_binary_operands_no_copy (PLUS, <MODE>mode, operands);
6385 if (CONST_INT_P (operands[2]))
6386 operands[4] = operands[2];
6388 operands[4] = gen_rtx_SIGN_EXTEND (<DWI>mode, operands[2]);
6391 (define_insn "*addv<mode>4"
6392 [(set (reg:CCO FLAGS_REG)
6395 (match_operand:SWI 1 "nonimmediate_operand" "%0,0"))
6397 (match_operand:SWI 2 "<general_sext_operand>"
6400 (plus:SWI (match_dup 1) (match_dup 2)))))
6401 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
6402 (plus:SWI (match_dup 1) (match_dup 2)))]
6403 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6404 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6405 [(set_attr "type" "alu")
6406 (set_attr "mode" "<MODE>")])
6408 (define_insn "*addv<mode>4_1"
6409 [(set (reg:CCO FLAGS_REG)
6412 (match_operand:SWI 1 "nonimmediate_operand" "0"))
6413 (match_operand:<DWI> 3 "const_int_operand" "i"))
6415 (plus:SWI (match_dup 1)
6416 (match_operand:SWI 2 "x86_64_immediate_operand"
6418 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
6419 (plus:SWI (match_dup 1) (match_dup 2)))]
6420 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)
6421 && CONST_INT_P (operands[2])
6422 && INTVAL (operands[2]) == INTVAL (operands[3])"
6423 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6424 [(set_attr "type" "alu")
6425 (set_attr "mode" "<MODE>")
6426 (set (attr "length_immediate")
6427 (cond [(match_test "IN_RANGE (INTVAL (operands[2]), -128, 127)")
6429 (match_test "<MODE_SIZE> == 8")
6431 (const_string "<MODE_SIZE>")))])
6433 (define_expand "uaddv<mode>4"
6434 [(parallel [(set (reg:CCC FLAGS_REG)
6437 (match_operand:SWI 1 "nonimmediate_operand")
6438 (match_operand:SWI 2 "<general_operand>"))
6440 (set (match_operand:SWI 0 "register_operand")
6441 (plus:SWI (match_dup 1) (match_dup 2)))])
6442 (set (pc) (if_then_else
6443 (ltu (reg:CCC FLAGS_REG) (const_int 0))
6444 (label_ref (match_operand 3))
6447 "ix86_fixup_binary_operands_no_copy (PLUS, <MODE>mode, operands);")
6449 ;; The lea patterns for modes less than 32 bits need to be matched by
6450 ;; several insns converted to real lea by splitters.
6452 (define_insn_and_split "*lea<mode>_general_1"
6453 [(set (match_operand:SWI12 0 "register_operand" "=r")
6455 (plus:SWI12 (match_operand:SWI12 1 "index_register_operand" "l")
6456 (match_operand:SWI12 2 "register_operand" "r"))
6457 (match_operand:SWI12 3 "immediate_operand" "i")))]
6458 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
6460 "&& reload_completed"
6463 (plus:SI (match_dup 1) (match_dup 2))
6466 operands[0] = gen_lowpart (SImode, operands[0]);
6467 operands[1] = gen_lowpart (SImode, operands[1]);
6468 operands[2] = gen_lowpart (SImode, operands[2]);
6469 operands[3] = gen_lowpart (SImode, operands[3]);
6471 [(set_attr "type" "lea")
6472 (set_attr "mode" "SI")])
6474 (define_insn_and_split "*lea<mode>_general_2"
6475 [(set (match_operand:SWI12 0 "register_operand" "=r")
6477 (mult:SWI12 (match_operand:SWI12 1 "index_register_operand" "l")
6478 (match_operand 2 "const248_operand" "n"))
6479 (match_operand:SWI12 3 "nonmemory_operand" "ri")))]
6480 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
6482 "&& reload_completed"
6485 (mult:SI (match_dup 1) (match_dup 2))
6488 operands[0] = gen_lowpart (SImode, operands[0]);
6489 operands[1] = gen_lowpart (SImode, operands[1]);
6490 operands[3] = gen_lowpart (SImode, operands[3]);
6492 [(set_attr "type" "lea")
6493 (set_attr "mode" "SI")])
6495 (define_insn_and_split "*lea<mode>_general_2b"
6496 [(set (match_operand:SWI12 0 "register_operand" "=r")
6498 (ashift:SWI12 (match_operand:SWI12 1 "index_register_operand" "l")
6499 (match_operand 2 "const123_operand" "n"))
6500 (match_operand:SWI12 3 "nonmemory_operand" "ri")))]
6501 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
6503 "&& reload_completed"
6506 (ashift:SI (match_dup 1) (match_dup 2))
6509 operands[0] = gen_lowpart (SImode, operands[0]);
6510 operands[1] = gen_lowpart (SImode, operands[1]);
6511 operands[3] = gen_lowpart (SImode, operands[3]);
6513 [(set_attr "type" "lea")
6514 (set_attr "mode" "SI")])
6516 (define_insn_and_split "*lea<mode>_general_3"
6517 [(set (match_operand:SWI12 0 "register_operand" "=r")
6520 (mult:SWI12 (match_operand:SWI12 1 "index_register_operand" "l")
6521 (match_operand 2 "const248_operand" "n"))
6522 (match_operand:SWI12 3 "register_operand" "r"))
6523 (match_operand:SWI12 4 "immediate_operand" "i")))]
6524 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
6526 "&& reload_completed"
6530 (mult:SI (match_dup 1) (match_dup 2))
6534 operands[0] = gen_lowpart (SImode, operands[0]);
6535 operands[1] = gen_lowpart (SImode, operands[1]);
6536 operands[3] = gen_lowpart (SImode, operands[3]);
6537 operands[4] = gen_lowpart (SImode, operands[4]);
6539 [(set_attr "type" "lea")
6540 (set_attr "mode" "SI")])
6542 (define_insn_and_split "*lea<mode>_general_3b"
6543 [(set (match_operand:SWI12 0 "register_operand" "=r")
6546 (ashift:SWI12 (match_operand:SWI12 1 "index_register_operand" "l")
6547 (match_operand 2 "const123_operand" "n"))
6548 (match_operand:SWI12 3 "register_operand" "r"))
6549 (match_operand:SWI12 4 "immediate_operand" "i")))]
6550 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
6552 "&& reload_completed"
6556 (ashift:SI (match_dup 1) (match_dup 2))
6560 operands[0] = gen_lowpart (SImode, operands[0]);
6561 operands[1] = gen_lowpart (SImode, operands[1]);
6562 operands[3] = gen_lowpart (SImode, operands[3]);
6563 operands[4] = gen_lowpart (SImode, operands[4]);
6565 [(set_attr "type" "lea")
6566 (set_attr "mode" "SI")])
6568 (define_insn_and_split "*lea<mode>_general_4"
6569 [(set (match_operand:SWI12 0 "register_operand" "=r")
6572 (match_operand:SWI12 1 "index_register_operand" "l")
6573 (match_operand 2 "const_0_to_3_operand" "n"))
6574 (match_operand 3 "const_int_operand" "n")))]
6575 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6576 && ((unsigned HOST_WIDE_INT) INTVAL (operands[3])
6577 < (HOST_WIDE_INT_1U << INTVAL (operands[2])))"
6579 "&& reload_completed"
6582 (mult:SI (match_dup 1) (match_dup 2))
6585 operands[0] = gen_lowpart (SImode, operands[0]);
6586 operands[1] = gen_lowpart (SImode, operands[1]);
6587 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
6589 [(set_attr "type" "lea")
6590 (set_attr "mode" "SI")])
6592 (define_insn_and_split "*lea<mode>_general_4"
6593 [(set (match_operand:SWI48 0 "register_operand" "=r")
6596 (match_operand:SWI48 1 "index_register_operand" "l")
6597 (match_operand 2 "const_0_to_3_operand" "n"))
6598 (match_operand 3 "const_int_operand" "n")))]
6599 "(unsigned HOST_WIDE_INT) INTVAL (operands[3])
6600 < (HOST_WIDE_INT_1U << INTVAL (operands[2]))"
6602 "&& reload_completed"
6605 (mult:SWI48 (match_dup 1) (match_dup 2))
6607 "operands[2] = GEN_INT (1 << INTVAL (operands[2]));"
6608 [(set_attr "type" "lea")
6609 (set_attr "mode" "<MODE>")])
6611 ;; Subtract instructions
6613 (define_expand "sub<mode>3"
6614 [(set (match_operand:SDWIM 0 "nonimmediate_operand")
6615 (minus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")
6616 (match_operand:SDWIM 2 "<general_hilo_operand>")))]
6618 "ix86_expand_binary_operator (MINUS, <MODE>mode, operands); DONE;")
6620 (define_insn_and_split "*sub<dwi>3_doubleword"
6621 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
6623 (match_operand:<DWI> 1 "nonimmediate_operand" "0,0")
6624 (match_operand:<DWI> 2 "x86_64_hilo_general_operand"
6626 (clobber (reg:CC FLAGS_REG))]
6627 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6630 [(parallel [(set (reg:CC FLAGS_REG)
6631 (compare:CC (match_dup 1) (match_dup 2)))
6633 (minus:DWIH (match_dup 1) (match_dup 2)))])
6634 (parallel [(set (match_dup 3)
6638 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0)))
6640 (clobber (reg:CC FLAGS_REG))])]
6642 split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
6643 if (operands[2] == const0_rtx)
6645 ix86_expand_binary_operator (MINUS, <MODE>mode, &operands[3]);
6650 (define_insn "*sub<mode>_1"
6651 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6653 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6654 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6655 (clobber (reg:CC FLAGS_REG))]
6656 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6657 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6658 [(set_attr "type" "alu")
6659 (set_attr "mode" "<MODE>")])
6661 (define_insn "*subsi_1_zext"
6662 [(set (match_operand:DI 0 "register_operand" "=r")
6664 (minus:SI (match_operand:SI 1 "register_operand" "0")
6665 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
6666 (clobber (reg:CC FLAGS_REG))]
6667 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6668 "sub{l}\t{%2, %k0|%k0, %2}"
6669 [(set_attr "type" "alu")
6670 (set_attr "mode" "SI")])
6672 (define_insn "*subqi_1_slp"
6673 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6674 (minus:QI (match_dup 0)
6675 (match_operand:QI 1 "general_operand" "qn,qm")))
6676 (clobber (reg:CC FLAGS_REG))]
6677 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6678 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
6679 "sub{b}\t{%1, %0|%0, %1}"
6680 [(set_attr "type" "alu1")
6681 (set_attr "mode" "QI")])
6683 (define_insn "*sub<mode>_2"
6684 [(set (reg FLAGS_REG)
6687 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6688 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6690 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6691 (minus:SWI (match_dup 1) (match_dup 2)))]
6692 "ix86_match_ccmode (insn, CCGOCmode)
6693 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6694 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6695 [(set_attr "type" "alu")
6696 (set_attr "mode" "<MODE>")])
6698 (define_insn "*subsi_2_zext"
6699 [(set (reg FLAGS_REG)
6701 (minus:SI (match_operand:SI 1 "register_operand" "0")
6702 (match_operand:SI 2 "x86_64_general_operand" "rme"))
6704 (set (match_operand:DI 0 "register_operand" "=r")
6706 (minus:SI (match_dup 1)
6708 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6709 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6710 "sub{l}\t{%2, %k0|%k0, %2}"
6711 [(set_attr "type" "alu")
6712 (set_attr "mode" "SI")])
6714 ;; Subtract with jump on overflow.
6715 (define_expand "subv<mode>4"
6716 [(parallel [(set (reg:CCO FLAGS_REG)
6717 (eq:CCO (minus:<DWI>
6719 (match_operand:SWI 1 "nonimmediate_operand"))
6722 (minus:SWI (match_dup 1)
6723 (match_operand:SWI 2
6724 "<general_operand>")))))
6725 (set (match_operand:SWI 0 "register_operand")
6726 (minus:SWI (match_dup 1) (match_dup 2)))])
6727 (set (pc) (if_then_else
6728 (eq (reg:CCO FLAGS_REG) (const_int 0))
6729 (label_ref (match_operand 3))
6733 ix86_fixup_binary_operands_no_copy (MINUS, <MODE>mode, operands);
6734 if (CONST_INT_P (operands[2]))
6735 operands[4] = operands[2];
6737 operands[4] = gen_rtx_SIGN_EXTEND (<DWI>mode, operands[2]);
6740 (define_insn "*subv<mode>4"
6741 [(set (reg:CCO FLAGS_REG)
6742 (eq:CCO (minus:<DWI>
6744 (match_operand:SWI 1 "nonimmediate_operand" "0,0"))
6746 (match_operand:SWI 2 "<general_sext_operand>"
6749 (minus:SWI (match_dup 1) (match_dup 2)))))
6750 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6751 (minus:SWI (match_dup 1) (match_dup 2)))]
6752 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6753 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6754 [(set_attr "type" "alu")
6755 (set_attr "mode" "<MODE>")])
6757 (define_insn "*subv<mode>4_1"
6758 [(set (reg:CCO FLAGS_REG)
6759 (eq:CCO (minus:<DWI>
6761 (match_operand:SWI 1 "nonimmediate_operand" "0"))
6762 (match_operand:<DWI> 3 "const_int_operand" "i"))
6764 (minus:SWI (match_dup 1)
6765 (match_operand:SWI 2 "x86_64_immediate_operand"
6767 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
6768 (minus:SWI (match_dup 1) (match_dup 2)))]
6769 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)
6770 && CONST_INT_P (operands[2])
6771 && INTVAL (operands[2]) == INTVAL (operands[3])"
6772 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6773 [(set_attr "type" "alu")
6774 (set_attr "mode" "<MODE>")
6775 (set (attr "length_immediate")
6776 (cond [(match_test "IN_RANGE (INTVAL (operands[2]), -128, 127)")
6778 (match_test "<MODE_SIZE> == 8")
6780 (const_string "<MODE_SIZE>")))])
6782 (define_expand "usubv<mode>4"
6783 [(parallel [(set (reg:CC FLAGS_REG)
6785 (match_operand:SWI 1 "nonimmediate_operand")
6786 (match_operand:SWI 2 "<general_operand>")))
6787 (set (match_operand:SWI 0 "register_operand")
6788 (minus:SWI (match_dup 1) (match_dup 2)))])
6789 (set (pc) (if_then_else
6790 (ltu (reg:CC FLAGS_REG) (const_int 0))
6791 (label_ref (match_operand 3))
6794 "ix86_fixup_binary_operands_no_copy (MINUS, <MODE>mode, operands);")
6796 (define_insn "*sub<mode>_3"
6797 [(set (reg FLAGS_REG)
6798 (compare (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6799 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6800 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6801 (minus:SWI (match_dup 1) (match_dup 2)))]
6802 "ix86_match_ccmode (insn, CCmode)
6803 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6804 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6805 [(set_attr "type" "alu")
6806 (set_attr "mode" "<MODE>")])
6810 [(set (reg:CC FLAGS_REG)
6811 (compare:CC (match_operand:SWI 0 "general_reg_operand")
6812 (match_operand:SWI 1 "general_gr_operand")))
6814 (minus:SWI (match_dup 0) (match_dup 1)))])]
6815 "find_regno_note (peep2_next_insn (0), REG_UNUSED, REGNO (operands[0])) != 0"
6816 [(set (reg:CC FLAGS_REG)
6817 (compare:CC (match_dup 0) (match_dup 1)))])
6819 (define_insn "*subsi_3_zext"
6820 [(set (reg FLAGS_REG)
6821 (compare (match_operand:SI 1 "register_operand" "0")
6822 (match_operand:SI 2 "x86_64_general_operand" "rme")))
6823 (set (match_operand:DI 0 "register_operand" "=r")
6825 (minus:SI (match_dup 1)
6827 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6828 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6829 "sub{l}\t{%2, %1|%1, %2}"
6830 [(set_attr "type" "alu")
6831 (set_attr "mode" "SI")])
6833 ;; Add with carry and subtract with borrow
6835 (define_insn "add<mode>3_carry"
6836 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6839 (match_operator:SWI 4 "ix86_carry_flag_operator"
6840 [(match_operand 3 "flags_reg_operand") (const_int 0)])
6841 (match_operand:SWI 1 "nonimmediate_operand" "%0,0"))
6842 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6843 (clobber (reg:CC FLAGS_REG))]
6844 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6845 "adc{<imodesuffix>}\t{%2, %0|%0, %2}"
6846 [(set_attr "type" "alu")
6847 (set_attr "use_carry" "1")
6848 (set_attr "pent_pair" "pu")
6849 (set_attr "mode" "<MODE>")])
6851 (define_insn "*addsi3_carry_zext"
6852 [(set (match_operand:DI 0 "register_operand" "=r")
6855 (plus:SI (match_operator:SI 3 "ix86_carry_flag_operator"
6856 [(reg FLAGS_REG) (const_int 0)])
6857 (match_operand:SI 1 "register_operand" "%0"))
6858 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
6859 (clobber (reg:CC FLAGS_REG))]
6860 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6861 "adc{l}\t{%2, %k0|%k0, %2}"
6862 [(set_attr "type" "alu")
6863 (set_attr "use_carry" "1")
6864 (set_attr "pent_pair" "pu")
6865 (set_attr "mode" "SI")])
6867 ;; There is no point to generate ADCX instruction. ADC is shorter and faster.
6869 (define_insn "addcarry<mode>"
6870 [(set (reg:CCC FLAGS_REG)
6875 (match_operator:SWI48 5 "ix86_carry_flag_operator"
6876 [(match_operand 3 "flags_reg_operand") (const_int 0)])
6877 (match_operand:SWI48 1 "nonimmediate_operand" "%0"))
6878 (match_operand:SWI48 2 "nonimmediate_operand" "rm")))
6880 (zero_extend:<DWI> (match_dup 2))
6881 (match_operator:<DWI> 4 "ix86_carry_flag_operator"
6882 [(match_dup 3) (const_int 0)]))))
6883 (set (match_operand:SWI48 0 "register_operand" "=r")
6884 (plus:SWI48 (plus:SWI48 (match_op_dup 5
6885 [(match_dup 3) (const_int 0)])
6888 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6889 "adc{<imodesuffix>}\t{%2, %0|%0, %2}"
6890 [(set_attr "type" "alu")
6891 (set_attr "use_carry" "1")
6892 (set_attr "pent_pair" "pu")
6893 (set_attr "mode" "<MODE>")])
6895 (define_expand "addcarry<mode>_0"
6897 [(set (reg:CCC FLAGS_REG)
6900 (match_operand:SWI48 1 "nonimmediate_operand")
6901 (match_operand:SWI48 2 "x86_64_general_operand"))
6903 (set (match_operand:SWI48 0 "register_operand")
6904 (plus:SWI48 (match_dup 1) (match_dup 2)))])]
6905 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)")
6907 (define_insn "sub<mode>3_carry"
6908 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6911 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6912 (match_operator:SWI 4 "ix86_carry_flag_operator"
6913 [(match_operand 3 "flags_reg_operand") (const_int 0)]))
6914 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6915 (clobber (reg:CC FLAGS_REG))]
6916 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6917 "sbb{<imodesuffix>}\t{%2, %0|%0, %2}"
6918 [(set_attr "type" "alu")
6919 (set_attr "use_carry" "1")
6920 (set_attr "pent_pair" "pu")
6921 (set_attr "mode" "<MODE>")])
6923 (define_insn "*subsi3_carry_zext"
6924 [(set (match_operand:DI 0 "register_operand" "=r")
6928 (match_operand:SI 1 "register_operand" "0")
6929 (match_operator:SI 3 "ix86_carry_flag_operator"
6930 [(reg FLAGS_REG) (const_int 0)]))
6931 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
6932 (clobber (reg:CC FLAGS_REG))]
6933 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6934 "sbb{l}\t{%2, %k0|%k0, %2}"
6935 [(set_attr "type" "alu")
6936 (set_attr "use_carry" "1")
6937 (set_attr "pent_pair" "pu")
6938 (set_attr "mode" "SI")])
6940 (define_insn "sub<mode>3_carry_ccc"
6941 [(set (reg:CCC FLAGS_REG)
6943 (zero_extend:<DWI> (match_operand:DWIH 1 "register_operand" "0"))
6945 (ltu:<DWI> (reg:CC FLAGS_REG) (const_int 0))
6947 (match_operand:DWIH 2 "x86_64_sext_operand" "rmWe")))))
6948 (clobber (match_scratch:DWIH 0 "=r"))]
6950 "sbb{<imodesuffix>}\t{%2, %0|%0, %2}"
6951 [(set_attr "type" "alu")
6952 (set_attr "mode" "<MODE>")])
6954 (define_insn "*sub<mode>3_carry_ccc_1"
6955 [(set (reg:CCC FLAGS_REG)
6957 (zero_extend:<DWI> (match_operand:DWIH 1 "register_operand" "0"))
6959 (ltu:<DWI> (reg:CC FLAGS_REG) (const_int 0))
6960 (match_operand:<DWI> 2 "x86_64_dwzext_immediate_operand" "Wf"))))
6961 (clobber (match_scratch:DWIH 0 "=r"))]
6964 operands[3] = simplify_subreg (<MODE>mode, operands[2], <DWI>mode, 0);
6965 return "sbb{<imodesuffix>}\t{%3, %0|%0, %3}";
6967 [(set_attr "type" "alu")
6968 (set_attr "mode" "<MODE>")])
6970 ;; The sign flag is set from the
6971 ;; (compare (match_dup 1) (plus:DWIH (ltu:DWIH ...) (match_dup 2)))
6972 ;; result, the overflow flag likewise, but the overflow flag is also
6973 ;; set if the (plus:DWIH (ltu:DWIH ...) (match_dup 2)) overflows.
6974 (define_insn "sub<mode>3_carry_ccgz"
6975 [(set (reg:CCGZ FLAGS_REG)
6976 (unspec:CCGZ [(match_operand:DWIH 1 "register_operand" "0")
6977 (match_operand:DWIH 2 "x86_64_general_operand" "rme")
6978 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))]
6980 (clobber (match_scratch:DWIH 0 "=r"))]
6982 "sbb{<imodesuffix>}\t{%2, %0|%0, %2}"
6983 [(set_attr "type" "alu")
6984 (set_attr "mode" "<MODE>")])
6986 (define_insn "subborrow<mode>"
6987 [(set (reg:CCC FLAGS_REG)
6990 (match_operand:SWI48 1 "nonimmediate_operand" "0"))
6992 (match_operator:<DWI> 4 "ix86_carry_flag_operator"
6993 [(match_operand 3 "flags_reg_operand") (const_int 0)])
6995 (match_operand:SWI48 2 "nonimmediate_operand" "rm")))))
6996 (set (match_operand:SWI48 0 "register_operand" "=r")
6997 (minus:SWI48 (minus:SWI48
6999 (match_operator:SWI48 5 "ix86_carry_flag_operator"
7000 [(match_dup 3) (const_int 0)]))
7002 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
7003 "sbb{<imodesuffix>}\t{%2, %0|%0, %2}"
7004 [(set_attr "type" "alu")
7005 (set_attr "use_carry" "1")
7006 (set_attr "pent_pair" "pu")
7007 (set_attr "mode" "<MODE>")])
7009 (define_expand "subborrow<mode>_0"
7011 [(set (reg:CC FLAGS_REG)
7013 (match_operand:SWI48 1 "nonimmediate_operand")
7014 (match_operand:SWI48 2 "<general_operand>")))
7015 (set (match_operand:SWI48 0 "register_operand")
7016 (minus:SWI48 (match_dup 1) (match_dup 2)))])]
7017 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)")
7019 ;; Overflow setting add instructions
7021 (define_expand "addqi3_cconly_overflow"
7023 [(set (reg:CCC FLAGS_REG)
7026 (match_operand:QI 0 "nonimmediate_operand")
7027 (match_operand:QI 1 "general_operand"))
7029 (clobber (match_scratch:QI 2))])]
7030 "!(MEM_P (operands[0]) && MEM_P (operands[1]))")
7032 (define_insn "*add<mode>3_cconly_overflow_1"
7033 [(set (reg:CCC FLAGS_REG)
7036 (match_operand:SWI 1 "nonimmediate_operand" "%0")
7037 (match_operand:SWI 2 "<general_operand>" "<g>"))
7039 (clobber (match_scratch:SWI 0 "=<r>"))]
7040 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7041 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
7042 [(set_attr "type" "alu")
7043 (set_attr "mode" "<MODE>")])
7045 (define_insn "*add<mode>3_cc_overflow_1"
7046 [(set (reg:CCC FLAGS_REG)
7049 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
7050 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
7052 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
7053 (plus:SWI (match_dup 1) (match_dup 2)))]
7054 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
7055 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
7056 [(set_attr "type" "alu")
7057 (set_attr "mode" "<MODE>")])
7059 (define_insn "*addsi3_zext_cc_overflow_1"
7060 [(set (reg:CCC FLAGS_REG)
7063 (match_operand:SI 1 "nonimmediate_operand" "%0")
7064 (match_operand:SI 2 "x86_64_general_operand" "rme"))
7066 (set (match_operand:DI 0 "register_operand" "=r")
7067 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
7068 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
7069 "add{l}\t{%2, %k0|%k0, %2}"
7070 [(set_attr "type" "alu")
7071 (set_attr "mode" "SI")])
7073 (define_insn "*add<mode>3_cconly_overflow_2"
7074 [(set (reg:CCC FLAGS_REG)
7077 (match_operand:SWI 1 "nonimmediate_operand" "%0")
7078 (match_operand:SWI 2 "<general_operand>" "<g>"))
7080 (clobber (match_scratch:SWI 0 "=<r>"))]
7081 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7082 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
7083 [(set_attr "type" "alu")
7084 (set_attr "mode" "<MODE>")])
7086 (define_insn "*add<mode>3_cc_overflow_2"
7087 [(set (reg:CCC FLAGS_REG)
7090 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
7091 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
7093 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
7094 (plus:SWI (match_dup 1) (match_dup 2)))]
7095 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
7096 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
7097 [(set_attr "type" "alu")
7098 (set_attr "mode" "<MODE>")])
7100 (define_insn "*addsi3_zext_cc_overflow_2"
7101 [(set (reg:CCC FLAGS_REG)
7104 (match_operand:SI 1 "nonimmediate_operand" "%0")
7105 (match_operand:SI 2 "x86_64_general_operand" "rme"))
7107 (set (match_operand:DI 0 "register_operand" "=r")
7108 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
7109 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
7110 "add{l}\t{%2, %k0|%k0, %2}"
7111 [(set_attr "type" "alu")
7112 (set_attr "mode" "SI")])
7114 ;; The patterns that match these are at the end of this file.
7116 (define_expand "<plusminus_insn>xf3"
7117 [(set (match_operand:XF 0 "register_operand")
7119 (match_operand:XF 1 "register_operand")
7120 (match_operand:XF 2 "register_operand")))]
7123 (define_expand "<plusminus_insn><mode>3"
7124 [(set (match_operand:MODEF 0 "register_operand")
7126 (match_operand:MODEF 1 "register_operand")
7127 (match_operand:MODEF 2 "nonimmediate_operand")))]
7128 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
7129 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
7131 ;; Multiply instructions
7133 (define_expand "mul<mode>3"
7134 [(parallel [(set (match_operand:SWIM248 0 "register_operand")
7136 (match_operand:SWIM248 1 "register_operand")
7137 (match_operand:SWIM248 2 "<general_operand>")))
7138 (clobber (reg:CC FLAGS_REG))])])
7140 (define_expand "mulqi3"
7141 [(parallel [(set (match_operand:QI 0 "register_operand")
7143 (match_operand:QI 1 "register_operand")
7144 (match_operand:QI 2 "nonimmediate_operand")))
7145 (clobber (reg:CC FLAGS_REG))])]
7146 "TARGET_QIMODE_MATH")
7149 ;; IMUL reg32/64, reg32/64, imm8 Direct
7150 ;; IMUL reg32/64, mem32/64, imm8 VectorPath
7151 ;; IMUL reg32/64, reg32/64, imm32 Direct
7152 ;; IMUL reg32/64, mem32/64, imm32 VectorPath
7153 ;; IMUL reg32/64, reg32/64 Direct
7154 ;; IMUL reg32/64, mem32/64 Direct
7156 ;; On BDVER1, all above IMULs use DirectPath
7159 ;; IMUL reg16, reg16, imm8 VectorPath
7160 ;; IMUL reg16, mem16, imm8 VectorPath
7161 ;; IMUL reg16, reg16, imm16 VectorPath
7162 ;; IMUL reg16, mem16, imm16 VectorPath
7163 ;; IMUL reg16, reg16 Direct
7164 ;; IMUL reg16, mem16 Direct
7166 ;; On BDVER1, all HI MULs use DoublePath
7168 (define_insn "*mul<mode>3_1"
7169 [(set (match_operand:SWIM248 0 "register_operand" "=r,r,r")
7171 (match_operand:SWIM248 1 "nonimmediate_operand" "%rm,rm,0")
7172 (match_operand:SWIM248 2 "<general_operand>" "K,<i>,mr")))
7173 (clobber (reg:CC FLAGS_REG))]
7174 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7176 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
7177 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
7178 imul{<imodesuffix>}\t{%2, %0|%0, %2}"
7179 [(set_attr "type" "imul")
7180 (set_attr "prefix_0f" "0,0,1")
7181 (set (attr "athlon_decode")
7182 (cond [(eq_attr "cpu" "athlon")
7183 (const_string "vector")
7184 (eq_attr "alternative" "1")
7185 (const_string "vector")
7186 (and (eq_attr "alternative" "2")
7187 (ior (match_test "<MODE>mode == HImode")
7188 (match_operand 1 "memory_operand")))
7189 (const_string "vector")]
7190 (const_string "direct")))
7191 (set (attr "amdfam10_decode")
7192 (cond [(and (eq_attr "alternative" "0,1")
7193 (ior (match_test "<MODE>mode == HImode")
7194 (match_operand 1 "memory_operand")))
7195 (const_string "vector")]
7196 (const_string "direct")))
7197 (set (attr "bdver1_decode")
7199 (match_test "<MODE>mode == HImode")
7200 (const_string "double")
7201 (const_string "direct")))
7202 (set_attr "mode" "<MODE>")])
7204 (define_insn "*mulsi3_1_zext"
7205 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
7207 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
7208 (match_operand:SI 2 "x86_64_general_operand" "K,e,mr"))))
7209 (clobber (reg:CC FLAGS_REG))]
7211 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7213 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7214 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7215 imul{l}\t{%2, %k0|%k0, %2}"
7216 [(set_attr "type" "imul")
7217 (set_attr "prefix_0f" "0,0,1")
7218 (set (attr "athlon_decode")
7219 (cond [(eq_attr "cpu" "athlon")
7220 (const_string "vector")
7221 (eq_attr "alternative" "1")
7222 (const_string "vector")
7223 (and (eq_attr "alternative" "2")
7224 (match_operand 1 "memory_operand"))
7225 (const_string "vector")]
7226 (const_string "direct")))
7227 (set (attr "amdfam10_decode")
7228 (cond [(and (eq_attr "alternative" "0,1")
7229 (match_operand 1 "memory_operand"))
7230 (const_string "vector")]
7231 (const_string "direct")))
7232 (set_attr "bdver1_decode" "direct")
7233 (set_attr "mode" "SI")])
7235 ;;On AMDFAM10 and BDVER1
7239 (define_insn "*mulqi3_1"
7240 [(set (match_operand:QI 0 "register_operand" "=a")
7241 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
7242 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7243 (clobber (reg:CC FLAGS_REG))]
7245 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7247 [(set_attr "type" "imul")
7248 (set_attr "length_immediate" "0")
7249 (set (attr "athlon_decode")
7250 (if_then_else (eq_attr "cpu" "athlon")
7251 (const_string "vector")
7252 (const_string "direct")))
7253 (set_attr "amdfam10_decode" "direct")
7254 (set_attr "bdver1_decode" "direct")
7255 (set_attr "mode" "QI")])
7257 ;; Multiply with jump on overflow.
7258 (define_expand "mulv<mode>4"
7259 [(parallel [(set (reg:CCO FLAGS_REG)
7262 (match_operand:SWI248 1 "register_operand"))
7265 (mult:SWI248 (match_dup 1)
7266 (match_operand:SWI248 2
7267 "<general_operand>")))))
7268 (set (match_operand:SWI248 0 "register_operand")
7269 (mult:SWI248 (match_dup 1) (match_dup 2)))])
7270 (set (pc) (if_then_else
7271 (eq (reg:CCO FLAGS_REG) (const_int 0))
7272 (label_ref (match_operand 3))
7276 if (CONST_INT_P (operands[2]))
7277 operands[4] = operands[2];
7279 operands[4] = gen_rtx_SIGN_EXTEND (<DWI>mode, operands[2]);
7282 (define_insn "*mulv<mode>4"
7283 [(set (reg:CCO FLAGS_REG)
7286 (match_operand:SWI48 1 "nonimmediate_operand" "%rm,0"))
7288 (match_operand:SWI48 2 "x86_64_sext_operand" "We,mr")))
7290 (mult:SWI48 (match_dup 1) (match_dup 2)))))
7291 (set (match_operand:SWI48 0 "register_operand" "=r,r")
7292 (mult:SWI48 (match_dup 1) (match_dup 2)))]
7293 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7295 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
7296 imul{<imodesuffix>}\t{%2, %0|%0, %2}"
7297 [(set_attr "type" "imul")
7298 (set_attr "prefix_0f" "0,1")
7299 (set (attr "athlon_decode")
7300 (cond [(eq_attr "cpu" "athlon")
7301 (const_string "vector")
7302 (eq_attr "alternative" "0")
7303 (const_string "vector")
7304 (and (eq_attr "alternative" "1")
7305 (match_operand 1 "memory_operand"))
7306 (const_string "vector")]
7307 (const_string "direct")))
7308 (set (attr "amdfam10_decode")
7309 (cond [(and (eq_attr "alternative" "1")
7310 (match_operand 1 "memory_operand"))
7311 (const_string "vector")]
7312 (const_string "direct")))
7313 (set_attr "bdver1_decode" "direct")
7314 (set_attr "mode" "<MODE>")])
7316 (define_insn "*mulvhi4"
7317 [(set (reg:CCO FLAGS_REG)
7320 (match_operand:HI 1 "nonimmediate_operand" "%0"))
7322 (match_operand:HI 2 "nonimmediate_operand" "mr")))
7324 (mult:HI (match_dup 1) (match_dup 2)))))
7325 (set (match_operand:HI 0 "register_operand" "=r")
7326 (mult:HI (match_dup 1) (match_dup 2)))]
7327 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7328 "imul{w}\t{%2, %0|%0, %2}"
7329 [(set_attr "type" "imul")
7330 (set_attr "prefix_0f" "1")
7331 (set_attr "athlon_decode" "vector")
7332 (set_attr "amdfam10_decode" "direct")
7333 (set_attr "bdver1_decode" "double")
7334 (set_attr "mode" "HI")])
7336 (define_insn "*mulv<mode>4_1"
7337 [(set (reg:CCO FLAGS_REG)
7340 (match_operand:SWI248 1 "nonimmediate_operand" "rm,rm"))
7341 (match_operand:<DWI> 3 "const_int_operand" "K,i"))
7343 (mult:SWI248 (match_dup 1)
7344 (match_operand:SWI248 2
7345 "<immediate_operand>" "K,<i>")))))
7346 (set (match_operand:SWI248 0 "register_operand" "=r,r")
7347 (mult:SWI248 (match_dup 1) (match_dup 2)))]
7348 "!(MEM_P (operands[1]) && MEM_P (operands[2]))
7349 && CONST_INT_P (operands[2])
7350 && INTVAL (operands[2]) == INTVAL (operands[3])"
7351 "imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}"
7352 [(set_attr "type" "imul")
7353 (set (attr "prefix_0f")
7355 (match_test "<MODE>mode == HImode")
7357 (const_string "*")))
7358 (set (attr "athlon_decode")
7359 (cond [(eq_attr "cpu" "athlon")
7360 (const_string "vector")
7361 (eq_attr "alternative" "1")
7362 (const_string "vector")]
7363 (const_string "direct")))
7364 (set (attr "amdfam10_decode")
7365 (cond [(ior (match_test "<MODE>mode == HImode")
7366 (match_operand 1 "memory_operand"))
7367 (const_string "vector")]
7368 (const_string "direct")))
7369 (set (attr "bdver1_decode")
7371 (match_test "<MODE>mode == HImode")
7372 (const_string "double")
7373 (const_string "direct")))
7374 (set_attr "mode" "<MODE>")
7375 (set (attr "length_immediate")
7376 (cond [(eq_attr "alternative" "0")
7378 (match_test "<MODE_SIZE> == 8")
7380 (const_string "<MODE_SIZE>")))])
7382 (define_expand "umulv<mode>4"
7383 [(parallel [(set (reg:CCO FLAGS_REG)
7386 (match_operand:SWI248 1
7387 "nonimmediate_operand"))
7389 (match_operand:SWI248 2
7390 "nonimmediate_operand")))
7392 (mult:SWI248 (match_dup 1) (match_dup 2)))))
7393 (set (match_operand:SWI248 0 "register_operand")
7394 (mult:SWI248 (match_dup 1) (match_dup 2)))
7395 (clobber (match_scratch:SWI248 4))])
7396 (set (pc) (if_then_else
7397 (eq (reg:CCO FLAGS_REG) (const_int 0))
7398 (label_ref (match_operand 3))
7402 if (MEM_P (operands[1]) && MEM_P (operands[2]))
7403 operands[1] = force_reg (<MODE>mode, operands[1]);
7406 (define_insn "*umulv<mode>4"
7407 [(set (reg:CCO FLAGS_REG)
7410 (match_operand:SWI248 1 "nonimmediate_operand" "%0"))
7412 (match_operand:SWI248 2 "nonimmediate_operand" "rm")))
7414 (mult:SWI248 (match_dup 1) (match_dup 2)))))
7415 (set (match_operand:SWI248 0 "register_operand" "=a")
7416 (mult:SWI248 (match_dup 1) (match_dup 2)))
7417 (clobber (match_scratch:SWI248 3 "=d"))]
7418 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7419 "mul{<imodesuffix>}\t%2"
7420 [(set_attr "type" "imul")
7421 (set_attr "length_immediate" "0")
7422 (set (attr "athlon_decode")
7423 (if_then_else (eq_attr "cpu" "athlon")
7424 (const_string "vector")
7425 (const_string "double")))
7426 (set_attr "amdfam10_decode" "double")
7427 (set_attr "bdver1_decode" "direct")
7428 (set_attr "mode" "<MODE>")])
7430 (define_expand "<u>mulvqi4"
7431 [(parallel [(set (reg:CCO FLAGS_REG)
7434 (match_operand:QI 1 "nonimmediate_operand"))
7436 (match_operand:QI 2 "nonimmediate_operand")))
7438 (mult:QI (match_dup 1) (match_dup 2)))))
7439 (set (match_operand:QI 0 "register_operand")
7440 (mult:QI (match_dup 1) (match_dup 2)))])
7441 (set (pc) (if_then_else
7442 (eq (reg:CCO FLAGS_REG) (const_int 0))
7443 (label_ref (match_operand 3))
7445 "TARGET_QIMODE_MATH"
7447 if (MEM_P (operands[1]) && MEM_P (operands[2]))
7448 operands[1] = force_reg (QImode, operands[1]);
7451 (define_insn "*<u>mulvqi4"
7452 [(set (reg:CCO FLAGS_REG)
7455 (match_operand:QI 1 "nonimmediate_operand" "%0"))
7457 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7459 (mult:QI (match_dup 1) (match_dup 2)))))
7460 (set (match_operand:QI 0 "register_operand" "=a")
7461 (mult:QI (match_dup 1) (match_dup 2)))]
7463 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7464 "<sgnprefix>mul{b}\t%2"
7465 [(set_attr "type" "imul")
7466 (set_attr "length_immediate" "0")
7467 (set (attr "athlon_decode")
7468 (if_then_else (eq_attr "cpu" "athlon")
7469 (const_string "vector")
7470 (const_string "direct")))
7471 (set_attr "amdfam10_decode" "direct")
7472 (set_attr "bdver1_decode" "direct")
7473 (set_attr "mode" "QI")])
7475 (define_expand "<u>mul<mode><dwi>3"
7476 [(parallel [(set (match_operand:<DWI> 0 "register_operand")
7479 (match_operand:DWIH 1 "nonimmediate_operand"))
7481 (match_operand:DWIH 2 "register_operand"))))
7482 (clobber (reg:CC FLAGS_REG))])])
7484 (define_expand "<u>mulqihi3"
7485 [(parallel [(set (match_operand:HI 0 "register_operand")
7488 (match_operand:QI 1 "nonimmediate_operand"))
7490 (match_operand:QI 2 "register_operand"))))
7491 (clobber (reg:CC FLAGS_REG))])]
7492 "TARGET_QIMODE_MATH")
7494 (define_insn "*bmi2_umul<mode><dwi>3_1"
7495 [(set (match_operand:DWIH 0 "register_operand" "=r")
7497 (match_operand:DWIH 2 "nonimmediate_operand" "%d")
7498 (match_operand:DWIH 3 "nonimmediate_operand" "rm")))
7499 (set (match_operand:DWIH 1 "register_operand" "=r")
7502 (mult:<DWI> (zero_extend:<DWI> (match_dup 2))
7503 (zero_extend:<DWI> (match_dup 3)))
7504 (match_operand:QI 4 "const_int_operand" "n"))))]
7505 "TARGET_BMI2 && INTVAL (operands[4]) == <MODE_SIZE> * BITS_PER_UNIT
7506 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7507 "mulx\t{%3, %0, %1|%1, %0, %3}"
7508 [(set_attr "type" "imulx")
7509 (set_attr "prefix" "vex")
7510 (set_attr "mode" "<MODE>")])
7512 (define_insn "*umul<mode><dwi>3_1"
7513 [(set (match_operand:<DWI> 0 "register_operand" "=r,A")
7516 (match_operand:DWIH 1 "nonimmediate_operand" "%d,0"))
7518 (match_operand:DWIH 2 "nonimmediate_operand" "rm,rm"))))
7519 (clobber (reg:CC FLAGS_REG))]
7520 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7523 mul{<imodesuffix>}\t%2"
7524 [(set_attr "isa" "bmi2,*")
7525 (set_attr "type" "imulx,imul")
7526 (set_attr "length_immediate" "*,0")
7527 (set (attr "athlon_decode")
7528 (cond [(eq_attr "alternative" "1")
7529 (if_then_else (eq_attr "cpu" "athlon")
7530 (const_string "vector")
7531 (const_string "double"))]
7532 (const_string "*")))
7533 (set_attr "amdfam10_decode" "*,double")
7534 (set_attr "bdver1_decode" "*,direct")
7535 (set_attr "prefix" "vex,orig")
7536 (set_attr "mode" "<MODE>")])
7538 ;; Convert mul to the mulx pattern to avoid flags dependency.
7540 [(set (match_operand:<DWI> 0 "register_operand")
7543 (match_operand:DWIH 1 "register_operand"))
7545 (match_operand:DWIH 2 "nonimmediate_operand"))))
7546 (clobber (reg:CC FLAGS_REG))]
7547 "TARGET_BMI2 && reload_completed
7548 && REGNO (operands[1]) == DX_REG"
7549 [(parallel [(set (match_dup 3)
7550 (mult:DWIH (match_dup 1) (match_dup 2)))
7554 (mult:<DWI> (zero_extend:<DWI> (match_dup 1))
7555 (zero_extend:<DWI> (match_dup 2)))
7558 split_double_mode (<DWI>mode, &operands[0], 1, &operands[3], &operands[4]);
7560 operands[5] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT);
7563 (define_insn "*mul<mode><dwi>3_1"
7564 [(set (match_operand:<DWI> 0 "register_operand" "=A")
7567 (match_operand:DWIH 1 "nonimmediate_operand" "%0"))
7569 (match_operand:DWIH 2 "nonimmediate_operand" "rm"))))
7570 (clobber (reg:CC FLAGS_REG))]
7571 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7572 "imul{<imodesuffix>}\t%2"
7573 [(set_attr "type" "imul")
7574 (set_attr "length_immediate" "0")
7575 (set (attr "athlon_decode")
7576 (if_then_else (eq_attr "cpu" "athlon")
7577 (const_string "vector")
7578 (const_string "double")))
7579 (set_attr "amdfam10_decode" "double")
7580 (set_attr "bdver1_decode" "direct")
7581 (set_attr "mode" "<MODE>")])
7583 (define_insn "*<u>mulqihi3_1"
7584 [(set (match_operand:HI 0 "register_operand" "=a")
7587 (match_operand:QI 1 "nonimmediate_operand" "%0"))
7589 (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7590 (clobber (reg:CC FLAGS_REG))]
7592 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7593 "<sgnprefix>mul{b}\t%2"
7594 [(set_attr "type" "imul")
7595 (set_attr "length_immediate" "0")
7596 (set (attr "athlon_decode")
7597 (if_then_else (eq_attr "cpu" "athlon")
7598 (const_string "vector")
7599 (const_string "direct")))
7600 (set_attr "amdfam10_decode" "direct")
7601 (set_attr "bdver1_decode" "direct")
7602 (set_attr "mode" "QI")])
7604 (define_expand "<s>mul<mode>3_highpart"
7605 [(parallel [(set (match_operand:SWI48 0 "register_operand")
7610 (match_operand:SWI48 1 "nonimmediate_operand"))
7612 (match_operand:SWI48 2 "register_operand")))
7614 (clobber (match_scratch:SWI48 4))
7615 (clobber (reg:CC FLAGS_REG))])]
7617 "operands[3] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
7619 (define_insn "*<s>muldi3_highpart_1"
7620 [(set (match_operand:DI 0 "register_operand" "=d")
7625 (match_operand:DI 1 "nonimmediate_operand" "%a"))
7627 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7629 (clobber (match_scratch:DI 3 "=1"))
7630 (clobber (reg:CC FLAGS_REG))]
7632 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7633 "<sgnprefix>mul{q}\t%2"
7634 [(set_attr "type" "imul")
7635 (set_attr "length_immediate" "0")
7636 (set (attr "athlon_decode")
7637 (if_then_else (eq_attr "cpu" "athlon")
7638 (const_string "vector")
7639 (const_string "double")))
7640 (set_attr "amdfam10_decode" "double")
7641 (set_attr "bdver1_decode" "direct")
7642 (set_attr "mode" "DI")])
7644 (define_insn "*<s>mulsi3_highpart_zext"
7645 [(set (match_operand:DI 0 "register_operand" "=d")
7646 (zero_extend:DI (truncate:SI
7648 (mult:DI (any_extend:DI
7649 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7651 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7653 (clobber (match_scratch:SI 3 "=1"))
7654 (clobber (reg:CC FLAGS_REG))]
7656 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7657 "<sgnprefix>mul{l}\t%2"
7658 [(set_attr "type" "imul")
7659 (set_attr "length_immediate" "0")
7660 (set (attr "athlon_decode")
7661 (if_then_else (eq_attr "cpu" "athlon")
7662 (const_string "vector")
7663 (const_string "double")))
7664 (set_attr "amdfam10_decode" "double")
7665 (set_attr "bdver1_decode" "direct")
7666 (set_attr "mode" "SI")])
7668 (define_insn "*<s>mulsi3_highpart_1"
7669 [(set (match_operand:SI 0 "register_operand" "=d")
7674 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7676 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7678 (clobber (match_scratch:SI 3 "=1"))
7679 (clobber (reg:CC FLAGS_REG))]
7680 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7681 "<sgnprefix>mul{l}\t%2"
7682 [(set_attr "type" "imul")
7683 (set_attr "length_immediate" "0")
7684 (set (attr "athlon_decode")
7685 (if_then_else (eq_attr "cpu" "athlon")
7686 (const_string "vector")
7687 (const_string "double")))
7688 (set_attr "amdfam10_decode" "double")
7689 (set_attr "bdver1_decode" "direct")
7690 (set_attr "mode" "SI")])
7692 ;; The patterns that match these are at the end of this file.
7694 (define_expand "mulxf3"
7695 [(set (match_operand:XF 0 "register_operand")
7696 (mult:XF (match_operand:XF 1 "register_operand")
7697 (match_operand:XF 2 "register_operand")))]
7700 (define_expand "mul<mode>3"
7701 [(set (match_operand:MODEF 0 "register_operand")
7702 (mult:MODEF (match_operand:MODEF 1 "register_operand")
7703 (match_operand:MODEF 2 "nonimmediate_operand")))]
7704 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
7705 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
7707 ;; Divide instructions
7709 ;; The patterns that match these are at the end of this file.
7711 (define_expand "divxf3"
7712 [(set (match_operand:XF 0 "register_operand")
7713 (div:XF (match_operand:XF 1 "register_operand")
7714 (match_operand:XF 2 "register_operand")))]
7717 (define_expand "div<mode>3"
7718 [(set (match_operand:MODEF 0 "register_operand")
7719 (div:MODEF (match_operand:MODEF 1 "register_operand")
7720 (match_operand:MODEF 2 "nonimmediate_operand")))]
7721 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
7722 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
7724 if (<MODE>mode == SFmode
7725 && TARGET_SSE && TARGET_SSE_MATH
7727 && optimize_insn_for_speed_p ()
7728 && flag_finite_math_only && !flag_trapping_math
7729 && flag_unsafe_math_optimizations)
7731 ix86_emit_swdivsf (operands[0], operands[1],
7732 operands[2], SFmode);
7737 ;; Divmod instructions.
7739 (define_expand "divmod<mode>4"
7740 [(parallel [(set (match_operand:SWIM248 0 "register_operand")
7742 (match_operand:SWIM248 1 "register_operand")
7743 (match_operand:SWIM248 2 "nonimmediate_operand")))
7744 (set (match_operand:SWIM248 3 "register_operand")
7745 (mod:SWIM248 (match_dup 1) (match_dup 2)))
7746 (clobber (reg:CC FLAGS_REG))])])
7748 ;; Split with 8bit unsigned divide:
7749 ;; if (dividend an divisor are in [0-255])
7750 ;; use 8bit unsigned integer divide
7752 ;; use original integer divide
7754 [(set (match_operand:SWI48 0 "register_operand")
7755 (div:SWI48 (match_operand:SWI48 2 "register_operand")
7756 (match_operand:SWI48 3 "nonimmediate_operand")))
7757 (set (match_operand:SWI48 1 "register_operand")
7758 (mod:SWI48 (match_dup 2) (match_dup 3)))
7759 (clobber (reg:CC FLAGS_REG))]
7760 "TARGET_USE_8BIT_IDIV
7761 && TARGET_QIMODE_MATH
7762 && can_create_pseudo_p ()
7763 && !optimize_insn_for_size_p ()"
7765 "ix86_split_idivmod (<MODE>mode, operands, true); DONE;")
7768 [(set (match_operand:DI 0 "register_operand")
7770 (div:SI (match_operand:SI 2 "register_operand")
7771 (match_operand:SI 3 "nonimmediate_operand"))))
7772 (set (match_operand:SI 1 "register_operand")
7773 (mod:SI (match_dup 2) (match_dup 3)))
7774 (clobber (reg:CC FLAGS_REG))]
7775 "TARGET_USE_8BIT_IDIV
7776 && TARGET_QIMODE_MATH
7777 && can_create_pseudo_p ()
7778 && !optimize_insn_for_size_p ()"
7780 "ix86_split_idivmod (SImode, operands, true); DONE;")
7783 [(set (match_operand:DI 1 "register_operand")
7785 (mod:SI (match_operand:SI 2 "register_operand")
7786 (match_operand:SI 3 "nonimmediate_operand"))))
7787 (set (match_operand:SI 0 "register_operand")
7788 (div:SI (match_dup 2) (match_dup 3)))
7789 (clobber (reg:CC FLAGS_REG))]
7790 "TARGET_USE_8BIT_IDIV
7791 && TARGET_QIMODE_MATH
7792 && can_create_pseudo_p ()
7793 && !optimize_insn_for_size_p ()"
7795 "ix86_split_idivmod (SImode, operands, true); DONE;")
7797 (define_insn_and_split "divmod<mode>4_1"
7798 [(set (match_operand:SWI48 0 "register_operand" "=a")
7799 (div:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7800 (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
7801 (set (match_operand:SWI48 1 "register_operand" "=&d")
7802 (mod:SWI48 (match_dup 2) (match_dup 3)))
7803 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7804 (clobber (reg:CC FLAGS_REG))]
7808 [(parallel [(set (match_dup 1)
7809 (ashiftrt:SWI48 (match_dup 4) (match_dup 5)))
7810 (clobber (reg:CC FLAGS_REG))])
7811 (parallel [(set (match_dup 0)
7812 (div:SWI48 (match_dup 2) (match_dup 3)))
7814 (mod:SWI48 (match_dup 2) (match_dup 3)))
7816 (clobber (reg:CC FLAGS_REG))])]
7818 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7820 if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
7821 operands[4] = operands[2];
7824 /* Avoid use of cltd in favor of a mov+shift. */
7825 emit_move_insn (operands[1], operands[2]);
7826 operands[4] = operands[1];
7829 [(set_attr "type" "multi")
7830 (set_attr "mode" "<MODE>")])
7832 (define_insn_and_split "divmodsi4_zext_1"
7833 [(set (match_operand:DI 0 "register_operand" "=a")
7835 (div:SI (match_operand:SI 2 "register_operand" "0")
7836 (match_operand:SI 3 "nonimmediate_operand" "rm"))))
7837 (set (match_operand:SI 1 "register_operand" "=&d")
7838 (mod:SI (match_dup 2) (match_dup 3)))
7839 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7840 (clobber (reg:CC FLAGS_REG))]
7844 [(parallel [(set (match_dup 1)
7845 (ashiftrt:SI (match_dup 4) (match_dup 5)))
7846 (clobber (reg:CC FLAGS_REG))])
7847 (parallel [(set (match_dup 0)
7848 (zero_extend:DI (div:SI (match_dup 2) (match_dup 3))))
7850 (mod:SI (match_dup 2) (match_dup 3)))
7852 (clobber (reg:CC FLAGS_REG))])]
7854 operands[5] = GEN_INT (GET_MODE_BITSIZE (SImode)-1);
7856 if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
7857 operands[4] = operands[2];
7860 /* Avoid use of cltd in favor of a mov+shift. */
7861 emit_move_insn (operands[1], operands[2]);
7862 operands[4] = operands[1];
7865 [(set_attr "type" "multi")
7866 (set_attr "mode" "SI")])
7868 (define_insn_and_split "divmodsi4_zext_2"
7869 [(set (match_operand:DI 1 "register_operand" "=&d")
7871 (mod:SI (match_operand:SI 2 "register_operand" "0")
7872 (match_operand:SI 3 "nonimmediate_operand" "rm"))))
7873 (set (match_operand:SI 0 "register_operand" "=a")
7874 (div:SI (match_dup 2) (match_dup 3)))
7875 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7876 (clobber (reg:CC FLAGS_REG))]
7880 [(parallel [(set (match_dup 6)
7881 (ashiftrt:SI (match_dup 4) (match_dup 5)))
7882 (clobber (reg:CC FLAGS_REG))])
7883 (parallel [(set (match_dup 1)
7884 (zero_extend:DI (mod:SI (match_dup 2) (match_dup 3))))
7886 (div:SI (match_dup 2) (match_dup 3)))
7888 (clobber (reg:CC FLAGS_REG))])]
7890 operands[5] = GEN_INT (GET_MODE_BITSIZE (SImode)-1);
7891 operands[6] = gen_lowpart (SImode, operands[1]);
7893 if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
7894 operands[4] = operands[2];
7897 /* Avoid use of cltd in favor of a mov+shift. */
7898 emit_move_insn (operands[6], operands[2]);
7899 operands[4] = operands[6];
7902 [(set_attr "type" "multi")
7903 (set_attr "mode" "SI")])
7905 (define_insn_and_split "*divmod<mode>4"
7906 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7907 (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7908 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7909 (set (match_operand:SWIM248 1 "register_operand" "=&d")
7910 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7911 (clobber (reg:CC FLAGS_REG))]
7915 [(parallel [(set (match_dup 1)
7916 (ashiftrt:SWIM248 (match_dup 4) (match_dup 5)))
7917 (clobber (reg:CC FLAGS_REG))])
7918 (parallel [(set (match_dup 0)
7919 (div:SWIM248 (match_dup 2) (match_dup 3)))
7921 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7923 (clobber (reg:CC FLAGS_REG))])]
7925 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7927 if (<MODE>mode != HImode
7928 && (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD))
7929 operands[4] = operands[2];
7932 /* Avoid use of cltd in favor of a mov+shift. */
7933 emit_move_insn (operands[1], operands[2]);
7934 operands[4] = operands[1];
7937 [(set_attr "type" "multi")
7938 (set_attr "mode" "<MODE>")])
7940 (define_insn_and_split "*divmodsi4_zext_1"
7941 [(set (match_operand:DI 0 "register_operand" "=a")
7943 (div:SI (match_operand:SI 2 "register_operand" "0")
7944 (match_operand:SI 3 "nonimmediate_operand" "rm"))))
7945 (set (match_operand:SI 1 "register_operand" "=&d")
7946 (mod:SI (match_dup 2) (match_dup 3)))
7947 (clobber (reg:CC FLAGS_REG))]
7951 [(parallel [(set (match_dup 1)
7952 (ashiftrt:SI (match_dup 4) (match_dup 5)))
7953 (clobber (reg:CC FLAGS_REG))])
7954 (parallel [(set (match_dup 0)
7955 (zero_extend:DI (div:SI (match_dup 2) (match_dup 3))))
7957 (mod:SI (match_dup 2) (match_dup 3)))
7959 (clobber (reg:CC FLAGS_REG))])]
7961 operands[5] = GEN_INT (GET_MODE_BITSIZE (SImode)-1);
7963 if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
7964 operands[4] = operands[2];
7967 /* Avoid use of cltd in favor of a mov+shift. */
7968 emit_move_insn (operands[1], operands[2]);
7969 operands[4] = operands[1];
7972 [(set_attr "type" "multi")
7973 (set_attr "mode" "SI")])
7975 (define_insn_and_split "*divmodsi4_zext_2"
7976 [(set (match_operand:DI 1 "register_operand" "=&d")
7978 (mod:SI (match_operand:SI 2 "register_operand" "0")
7979 (match_operand:SI 3 "nonimmediate_operand" "rm"))))
7980 (set (match_operand:SI 0 "register_operand" "=a")
7981 (div:SI (match_dup 2) (match_dup 3)))
7982 (clobber (reg:CC FLAGS_REG))]
7986 [(parallel [(set (match_dup 6)
7987 (ashiftrt:SI (match_dup 4) (match_dup 5)))
7988 (clobber (reg:CC FLAGS_REG))])
7989 (parallel [(set (match_dup 1)
7990 (zero_extend:DI (mod:SI (match_dup 2) (match_dup 3))))
7992 (div:SI (match_dup 2) (match_dup 3)))
7994 (clobber (reg:CC FLAGS_REG))])]
7996 operands[5] = GEN_INT (GET_MODE_BITSIZE (SImode)-1);
7997 operands[6] = gen_lowpart (SImode, operands[1]);
7999 if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
8000 operands[4] = operands[2];
8003 /* Avoid use of cltd in favor of a mov+shift. */
8004 emit_move_insn (operands[6], operands[2]);
8005 operands[4] = operands[6];
8008 [(set_attr "type" "multi")
8009 (set_attr "mode" "SI")])
8011 (define_insn "*divmod<mode>4_noext"
8012 [(set (match_operand:SWIM248 0 "register_operand" "=a")
8013 (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
8014 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
8015 (set (match_operand:SWIM248 1 "register_operand" "=d")
8016 (mod:SWIM248 (match_dup 2) (match_dup 3)))
8017 (use (match_operand:SWIM248 4 "register_operand" "1"))
8018 (clobber (reg:CC FLAGS_REG))]
8020 "idiv{<imodesuffix>}\t%3"
8021 [(set_attr "type" "idiv")
8022 (set_attr "mode" "<MODE>")])
8024 (define_insn "*divmodsi4_noext_zext_1"
8025 [(set (match_operand:DI 0 "register_operand" "=a")
8027 (div:SI (match_operand:SI 2 "register_operand" "0")
8028 (match_operand:SI 3 "nonimmediate_operand" "rm"))))
8029 (set (match_operand:SI 1 "register_operand" "=d")
8030 (mod:SI (match_dup 2) (match_dup 3)))
8031 (use (match_operand:SI 4 "register_operand" "1"))
8032 (clobber (reg:CC FLAGS_REG))]
8035 [(set_attr "type" "idiv")
8036 (set_attr "mode" "SI")])
8038 (define_insn "*divmodsi4_noext_zext_2"
8039 [(set (match_operand:DI 1 "register_operand" "=d")
8041 (mod:SI (match_operand:SI 2 "register_operand" "0")
8042 (match_operand:SI 3 "nonimmediate_operand" "rm"))))
8043 (set (match_operand:SI 0 "register_operand" "=a")
8044 (div:SI (match_dup 2) (match_dup 3)))
8045 (use (match_operand:SI 4 "register_operand" "1"))
8046 (clobber (reg:CC FLAGS_REG))]
8049 [(set_attr "type" "idiv")
8050 (set_attr "mode" "SI")])
8052 (define_expand "divmodqi4"
8053 [(parallel [(set (match_operand:QI 0 "register_operand")
8055 (match_operand:QI 1 "register_operand")
8056 (match_operand:QI 2 "nonimmediate_operand")))
8057 (set (match_operand:QI 3 "register_operand")
8058 (mod:QI (match_dup 1) (match_dup 2)))
8059 (clobber (reg:CC FLAGS_REG))])]
8060 "TARGET_QIMODE_MATH"
8065 tmp0 = gen_reg_rtx (HImode);
8066 tmp1 = gen_reg_rtx (HImode);
8068 /* Extend operands[1] to HImode. Generate 8bit divide. Result is in AX. */
8069 emit_insn (gen_extendqihi2 (tmp1, operands[1]));
8070 emit_insn (gen_divmodhiqi3 (tmp0, tmp1, operands[2]));
8072 /* Extract remainder from AH. */
8073 tmp1 = gen_rtx_ZERO_EXTRACT (SImode, tmp0, GEN_INT (8), GEN_INT (8));
8074 tmp1 = lowpart_subreg (QImode, tmp1, SImode);
8075 rtx_insn *insn = emit_move_insn (operands[3], tmp1);
8077 mod = gen_rtx_MOD (QImode, operands[1], operands[2]);
8078 set_unique_reg_note (insn, REG_EQUAL, mod);
8080 /* Extract quotient from AL. */
8081 insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
8083 div = gen_rtx_DIV (QImode, operands[1], operands[2]);
8084 set_unique_reg_note (insn, REG_EQUAL, div);
8089 ;; Divide AX by r/m8, with result stored in
8092 ;; Change div/mod to HImode and extend the second argument to HImode
8093 ;; so that mode of div/mod matches with mode of arguments. Otherwise
8094 ;; combine may fail.
8095 (define_insn "divmodhiqi3"
8096 [(set (match_operand:HI 0 "register_operand" "=a")
8101 (mod:HI (match_operand:HI 1 "register_operand" "0")
8103 (match_operand:QI 2 "nonimmediate_operand" "qm")))))
8107 (div:HI (match_dup 1) (sign_extend:HI (match_dup 2)))))))
8108 (clobber (reg:CC FLAGS_REG))]
8109 "TARGET_QIMODE_MATH"
8111 [(set_attr "type" "idiv")
8112 (set_attr "mode" "QI")])
8114 (define_expand "udivmod<mode>4"
8115 [(parallel [(set (match_operand:SWIM248 0 "register_operand")
8117 (match_operand:SWIM248 1 "register_operand")
8118 (match_operand:SWIM248 2 "nonimmediate_operand")))
8119 (set (match_operand:SWIM248 3 "register_operand")
8120 (umod:SWIM248 (match_dup 1) (match_dup 2)))
8121 (clobber (reg:CC FLAGS_REG))])])
8123 ;; Split with 8bit unsigned divide:
8124 ;; if (dividend an divisor are in [0-255])
8125 ;; use 8bit unsigned integer divide
8127 ;; use original integer divide
8129 [(set (match_operand:SWI48 0 "register_operand")
8130 (udiv:SWI48 (match_operand:SWI48 2 "register_operand")
8131 (match_operand:SWI48 3 "nonimmediate_operand")))
8132 (set (match_operand:SWI48 1 "register_operand")
8133 (umod:SWI48 (match_dup 2) (match_dup 3)))
8134 (clobber (reg:CC FLAGS_REG))]
8135 "TARGET_USE_8BIT_IDIV
8136 && TARGET_QIMODE_MATH
8137 && can_create_pseudo_p ()
8138 && !optimize_insn_for_size_p ()"
8140 "ix86_split_idivmod (<MODE>mode, operands, false); DONE;")
8143 [(set (match_operand:DI 0 "register_operand")
8145 (udiv:SI (match_operand:SI 2 "register_operand")
8146 (match_operand:SI 3 "nonimmediate_operand"))))
8147 (set (match_operand:SI 1 "register_operand")
8148 (umod:SI (match_dup 2) (match_dup 3)))
8149 (clobber (reg:CC FLAGS_REG))]
8151 && TARGET_USE_8BIT_IDIV
8152 && TARGET_QIMODE_MATH
8153 && can_create_pseudo_p ()
8154 && !optimize_insn_for_size_p ()"
8156 "ix86_split_idivmod (SImode, operands, false); DONE;")
8159 [(set (match_operand:DI 1 "register_operand")
8161 (umod:SI (match_operand:SI 2 "register_operand")
8162 (match_operand:SI 3 "nonimmediate_operand"))))
8163 (set (match_operand:SI 0 "register_operand")
8164 (udiv:SI (match_dup 2) (match_dup 3)))
8165 (clobber (reg:CC FLAGS_REG))]
8167 && TARGET_USE_8BIT_IDIV
8168 && TARGET_QIMODE_MATH
8169 && can_create_pseudo_p ()
8170 && !optimize_insn_for_size_p ()"
8172 "ix86_split_idivmod (SImode, operands, false); DONE;")
8174 (define_insn_and_split "udivmod<mode>4_1"
8175 [(set (match_operand:SWI48 0 "register_operand" "=a")
8176 (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "0")
8177 (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
8178 (set (match_operand:SWI48 1 "register_operand" "=&d")
8179 (umod:SWI48 (match_dup 2) (match_dup 3)))
8180 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
8181 (clobber (reg:CC FLAGS_REG))]
8185 [(set (match_dup 1) (const_int 0))
8186 (parallel [(set (match_dup 0)
8187 (udiv:SWI48 (match_dup 2) (match_dup 3)))
8189 (umod:SWI48 (match_dup 2) (match_dup 3)))
8191 (clobber (reg:CC FLAGS_REG))])]
8193 [(set_attr "type" "multi")
8194 (set_attr "mode" "<MODE>")])
8196 (define_insn_and_split "udivmodsi4_zext_1"
8197 [(set (match_operand:DI 0 "register_operand" "=a")
8199 (udiv:SI (match_operand:SI 2 "register_operand" "0")
8200 (match_operand:SI 3 "nonimmediate_operand" "rm"))))
8201 (set (match_operand:SI 1 "register_operand" "=&d")
8202 (umod:SI (match_dup 2) (match_dup 3)))
8203 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
8204 (clobber (reg:CC FLAGS_REG))]
8208 [(set (match_dup 1) (const_int 0))
8209 (parallel [(set (match_dup 0)
8210 (zero_extend:DI (udiv:SI (match_dup 2) (match_dup 3))))
8212 (umod:SI (match_dup 2) (match_dup 3)))
8214 (clobber (reg:CC FLAGS_REG))])]
8216 [(set_attr "type" "multi")
8217 (set_attr "mode" "SI")])
8219 (define_insn_and_split "udivmodsi4_zext_2"
8220 [(set (match_operand:DI 1 "register_operand" "=&d")
8222 (umod:SI (match_operand:SI 2 "register_operand" "0")
8223 (match_operand:SI 3 "nonimmediate_operand" "rm"))))
8224 (set (match_operand:SI 0 "register_operand" "=a")
8225 (udiv:SI (match_dup 2) (match_dup 3)))
8226 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
8227 (clobber (reg:CC FLAGS_REG))]
8231 [(set (match_dup 4) (const_int 0))
8232 (parallel [(set (match_dup 1)
8233 (zero_extend:DI (umod:SI (match_dup 2) (match_dup 3))))
8235 (udiv:SI (match_dup 2) (match_dup 3)))
8237 (clobber (reg:CC FLAGS_REG))])]
8238 "operands[4] = gen_lowpart (SImode, operands[1]);"
8239 [(set_attr "type" "multi")
8240 (set_attr "mode" "SI")])
8242 (define_insn_and_split "*udivmod<mode>4"
8243 [(set (match_operand:SWIM248 0 "register_operand" "=a")
8244 (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
8245 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
8246 (set (match_operand:SWIM248 1 "register_operand" "=&d")
8247 (umod:SWIM248 (match_dup 2) (match_dup 3)))
8248 (clobber (reg:CC FLAGS_REG))]
8252 [(set (match_dup 1) (const_int 0))
8253 (parallel [(set (match_dup 0)
8254 (udiv:SWIM248 (match_dup 2) (match_dup 3)))
8256 (umod:SWIM248 (match_dup 2) (match_dup 3)))
8258 (clobber (reg:CC FLAGS_REG))])]
8260 [(set_attr "type" "multi")
8261 (set_attr "mode" "<MODE>")])
8263 (define_insn_and_split "*udivmodsi4_zext_1"
8264 [(set (match_operand:DI 0 "register_operand" "=a")
8266 (udiv:SI (match_operand:SI 2 "register_operand" "0")
8267 (match_operand:SI 3 "nonimmediate_operand" "rm"))))
8268 (set (match_operand:SI 1 "register_operand" "=&d")
8269 (umod:SI (match_dup 2) (match_dup 3)))
8270 (clobber (reg:CC FLAGS_REG))]
8274 [(set (match_dup 1) (const_int 0))
8275 (parallel [(set (match_dup 0)
8276 (zero_extend:DI (udiv:SI (match_dup 2) (match_dup 3))))
8278 (umod:SI (match_dup 2) (match_dup 3)))
8280 (clobber (reg:CC FLAGS_REG))])]
8282 [(set_attr "type" "multi")
8283 (set_attr "mode" "SI")])
8285 (define_insn_and_split "*udivmodsi4_zext_2"
8286 [(set (match_operand:DI 1 "register_operand" "=&d")
8288 (umod:SI (match_operand:SI 2 "register_operand" "0")
8289 (match_operand:SI 3 "nonimmediate_operand" "rm"))))
8290 (set (match_operand:SI 0 "register_operand" "=a")
8291 (udiv:SI (match_dup 2) (match_dup 3)))
8292 (clobber (reg:CC FLAGS_REG))]
8296 [(set (match_dup 4) (const_int 0))
8297 (parallel [(set (match_dup 1)
8298 (zero_extend:DI (umod:SI (match_dup 2) (match_dup 3))))
8300 (udiv:SI (match_dup 2) (match_dup 3)))
8302 (clobber (reg:CC FLAGS_REG))])]
8303 "operands[4] = gen_lowpart (SImode, operands[1]);"
8304 [(set_attr "type" "multi")
8305 (set_attr "mode" "SI")])
8307 ;; Optimize division or modulo by constant power of 2, if the constant
8308 ;; materializes only after expansion.
8309 (define_insn_and_split "*udivmod<mode>4_pow2"
8310 [(set (match_operand:SWI48 0 "register_operand" "=r")
8311 (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "0")
8312 (match_operand:SWI48 3 "const_int_operand" "n")))
8313 (set (match_operand:SWI48 1 "register_operand" "=r")
8314 (umod:SWI48 (match_dup 2) (match_dup 3)))
8315 (clobber (reg:CC FLAGS_REG))]
8316 "IN_RANGE (INTVAL (operands[3]), 2, HOST_WIDE_INT_UC (0x80000000))
8317 && (UINTVAL (operands[3]) & (UINTVAL (operands[3]) - 1)) == 0"
8320 [(set (match_dup 1) (match_dup 2))
8321 (parallel [(set (match_dup 0) (lshiftrt:<MODE> (match_dup 2) (match_dup 4)))
8322 (clobber (reg:CC FLAGS_REG))])
8323 (parallel [(set (match_dup 1) (and:<MODE> (match_dup 1) (match_dup 5)))
8324 (clobber (reg:CC FLAGS_REG))])]
8326 int v = exact_log2 (UINTVAL (operands[3]));
8327 operands[4] = GEN_INT (v);
8328 operands[5] = GEN_INT ((HOST_WIDE_INT_1U << v) - 1);
8330 [(set_attr "type" "multi")
8331 (set_attr "mode" "<MODE>")])
8333 (define_insn_and_split "*udivmodsi4_pow2_zext_1"
8334 [(set (match_operand:DI 0 "register_operand" "=r")
8336 (udiv:SI (match_operand:SI 2 "register_operand" "0")
8337 (match_operand:SI 3 "const_int_operand" "n"))))
8338 (set (match_operand:SI 1 "register_operand" "=r")
8339 (umod:SI (match_dup 2) (match_dup 3)))
8340 (clobber (reg:CC FLAGS_REG))]
8342 && IN_RANGE (INTVAL (operands[3]), 2, HOST_WIDE_INT_UC (0x80000000))
8343 && (UINTVAL (operands[3]) & (UINTVAL (operands[3]) - 1)) == 0"
8346 [(set (match_dup 1) (match_dup 2))
8347 (parallel [(set (match_dup 0)
8348 (zero_extend:DI (lshiftrt:SI (match_dup 2) (match_dup 4))))
8349 (clobber (reg:CC FLAGS_REG))])
8350 (parallel [(set (match_dup 1) (and:SI (match_dup 1) (match_dup 5)))
8351 (clobber (reg:CC FLAGS_REG))])]
8353 int v = exact_log2 (UINTVAL (operands[3]));
8354 operands[4] = GEN_INT (v);
8355 operands[5] = GEN_INT ((HOST_WIDE_INT_1U << v) - 1);
8357 [(set_attr "type" "multi")
8358 (set_attr "mode" "SI")])
8360 (define_insn_and_split "*udivmodsi4_pow2_zext_2"
8361 [(set (match_operand:DI 1 "register_operand" "=r")
8363 (umod:SI (match_operand:SI 2 "register_operand" "0")
8364 (match_operand:SI 3 "const_int_operand" "n"))))
8365 (set (match_operand:SI 0 "register_operand" "=r")
8366 (umod:SI (match_dup 2) (match_dup 3)))
8367 (clobber (reg:CC FLAGS_REG))]
8369 && IN_RANGE (INTVAL (operands[3]), 2, HOST_WIDE_INT_UC (0x80000000))
8370 && (UINTVAL (operands[3]) & (UINTVAL (operands[3]) - 1)) == 0"
8373 [(set (match_dup 1) (match_dup 2))
8374 (parallel [(set (match_dup 0) (lshiftrt:SI (match_dup 2) (match_dup 4)))
8375 (clobber (reg:CC FLAGS_REG))])
8376 (parallel [(set (match_dup 1)
8377 (zero_extend:DI (and:SI (match_dup 1) (match_dup 5))))
8378 (clobber (reg:CC FLAGS_REG))])]
8380 int v = exact_log2 (UINTVAL (operands[3]));
8381 operands[4] = GEN_INT (v);
8382 operands[5] = GEN_INT ((HOST_WIDE_INT_1U << v) - 1);
8384 [(set_attr "type" "multi")
8385 (set_attr "mode" "SI")])
8387 (define_insn "*udivmod<mode>4_noext"
8388 [(set (match_operand:SWIM248 0 "register_operand" "=a")
8389 (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
8390 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
8391 (set (match_operand:SWIM248 1 "register_operand" "=d")
8392 (umod:SWIM248 (match_dup 2) (match_dup 3)))
8393 (use (match_operand:SWIM248 4 "register_operand" "1"))
8394 (clobber (reg:CC FLAGS_REG))]
8396 "div{<imodesuffix>}\t%3"
8397 [(set_attr "type" "idiv")
8398 (set_attr "mode" "<MODE>")])
8400 (define_insn "*udivmodsi4_noext_zext_1"
8401 [(set (match_operand:DI 0 "register_operand" "=a")
8403 (udiv:SI (match_operand:SI 2 "register_operand" "0")
8404 (match_operand:SI 3 "nonimmediate_operand" "rm"))))
8405 (set (match_operand:SI 1 "register_operand" "=d")
8406 (umod:SI (match_dup 2) (match_dup 3)))
8407 (use (match_operand:SI 4 "register_operand" "1"))
8408 (clobber (reg:CC FLAGS_REG))]
8411 [(set_attr "type" "idiv")
8412 (set_attr "mode" "SI")])
8414 (define_insn "*udivmodsi4_noext_zext_2"
8415 [(set (match_operand:DI 1 "register_operand" "=d")
8417 (umod:SI (match_operand:SI 2 "register_operand" "0")
8418 (match_operand:SI 3 "nonimmediate_operand" "rm"))))
8419 (set (match_operand:SI 0 "register_operand" "=a")
8420 (udiv:SI (match_dup 2) (match_dup 3)))
8421 (use (match_operand:SI 4 "register_operand" "1"))
8422 (clobber (reg:CC FLAGS_REG))]
8425 [(set_attr "type" "idiv")
8426 (set_attr "mode" "SI")])
8428 (define_expand "udivmodqi4"
8429 [(parallel [(set (match_operand:QI 0 "register_operand")
8431 (match_operand:QI 1 "register_operand")
8432 (match_operand:QI 2 "nonimmediate_operand")))
8433 (set (match_operand:QI 3 "register_operand")
8434 (umod:QI (match_dup 1) (match_dup 2)))
8435 (clobber (reg:CC FLAGS_REG))])]
8436 "TARGET_QIMODE_MATH"
8441 tmp0 = gen_reg_rtx (HImode);
8442 tmp1 = gen_reg_rtx (HImode);
8444 /* Extend operands[1] to HImode. Generate 8bit divide. Result is in AX. */
8445 emit_insn (gen_zero_extendqihi2 (tmp1, operands[1]));
8446 emit_insn (gen_udivmodhiqi3 (tmp0, tmp1, operands[2]));
8448 /* Extract remainder from AH. */
8449 tmp1 = gen_rtx_ZERO_EXTRACT (SImode, tmp0, GEN_INT (8), GEN_INT (8));
8450 tmp1 = lowpart_subreg (QImode, tmp1, SImode);
8451 rtx_insn *insn = emit_move_insn (operands[3], tmp1);
8453 mod = gen_rtx_UMOD (QImode, operands[1], operands[2]);
8454 set_unique_reg_note (insn, REG_EQUAL, mod);
8456 /* Extract quotient from AL. */
8457 insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
8459 div = gen_rtx_UDIV (QImode, operands[1], operands[2]);
8460 set_unique_reg_note (insn, REG_EQUAL, div);
8465 (define_insn "udivmodhiqi3"
8466 [(set (match_operand:HI 0 "register_operand" "=a")
8471 (mod:HI (match_operand:HI 1 "register_operand" "0")
8473 (match_operand:QI 2 "nonimmediate_operand" "qm")))))
8477 (div:HI (match_dup 1) (zero_extend:HI (match_dup 2)))))))
8478 (clobber (reg:CC FLAGS_REG))]
8479 "TARGET_QIMODE_MATH"
8481 [(set_attr "type" "idiv")
8482 (set_attr "mode" "QI")])
8484 ;; We cannot use div/idiv for double division, because it causes
8485 ;; "division by zero" on the overflow and that's not what we expect
8486 ;; from truncate. Because true (non truncating) double division is
8487 ;; never generated, we can't create this insn anyway.
8490 ; [(set (match_operand:SI 0 "register_operand" "=a")
8492 ; (udiv:DI (match_operand:DI 1 "register_operand" "A")
8494 ; (match_operand:SI 2 "nonimmediate_operand" "rm")))))
8495 ; (set (match_operand:SI 3 "register_operand" "=d")
8497 ; (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
8498 ; (clobber (reg:CC FLAGS_REG))]
8500 ; "div{l}\t{%2, %0|%0, %2}"
8501 ; [(set_attr "type" "idiv")])
8503 ;;- Logical AND instructions
8505 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
8506 ;; Note that this excludes ah.
8508 (define_expand "testsi_ccno_1"
8509 [(set (reg:CCNO FLAGS_REG)
8511 (and:SI (match_operand:SI 0 "nonimmediate_operand")
8512 (match_operand:SI 1 "x86_64_nonmemory_operand"))
8515 (define_expand "testqi_ccz_1"
8516 [(set (reg:CCZ FLAGS_REG)
8517 (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand")
8518 (match_operand:QI 1 "nonmemory_operand"))
8521 (define_expand "testdi_ccno_1"
8522 [(set (reg:CCNO FLAGS_REG)
8524 (and:DI (match_operand:DI 0 "nonimmediate_operand")
8525 (match_operand:DI 1 "x86_64_szext_general_operand"))
8527 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))")
8529 (define_insn "*testdi_1"
8530 [(set (reg FLAGS_REG)
8533 (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
8534 (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
8536 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8537 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8539 test{l}\t{%k1, %k0|%k0, %k1}
8540 test{l}\t{%k1, %k0|%k0, %k1}
8541 test{q}\t{%1, %0|%0, %1}
8542 test{q}\t{%1, %0|%0, %1}
8543 test{q}\t{%1, %0|%0, %1}"
8544 [(set_attr "type" "test")
8545 (set_attr "modrm" "0,1,0,1,1")
8546 (set_attr "mode" "SI,SI,DI,DI,DI")])
8548 (define_insn "*testqi_1_maybe_si"
8549 [(set (reg FLAGS_REG)
8552 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
8553 (match_operand:QI 1 "general_operand" "n,n,qn,n"))
8555 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
8556 && ix86_match_ccmode (insn,
8557 CONST_INT_P (operands[1])
8558 && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
8560 if (which_alternative == 3)
8562 if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
8563 operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
8564 return "test{l}\t{%1, %k0|%k0, %1}";
8566 return "test{b}\t{%1, %0|%0, %1}";
8568 [(set_attr "type" "test")
8569 (set_attr "modrm" "0,1,1,1")
8570 (set_attr "mode" "QI,QI,QI,SI")
8571 (set_attr "pent_pair" "uv,np,uv,np")])
8573 (define_insn "*test<mode>_1"
8574 [(set (reg FLAGS_REG)
8577 (match_operand:SWI124 0 "nonimmediate_operand" "%!*a,<r>,<r>m")
8578 (match_operand:SWI124 1 "<general_operand>" "<i>,<i>,<r><i>"))
8580 "ix86_match_ccmode (insn, CCNOmode)
8581 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8582 "test{<imodesuffix>}\t{%1, %0|%0, %1}"
8583 [(set_attr "type" "test")
8584 (set_attr "modrm" "0,1,1")
8585 (set_attr "mode" "<MODE>")
8586 (set_attr "pent_pair" "uv,np,uv")])
8588 (define_expand "testqi_ext_1_ccno"
8589 [(set (reg:CCNO FLAGS_REG)
8593 (zero_extract:SI (match_operand 0 "ext_register_operand")
8596 (match_operand 1 "const_int_operand"))
8599 (define_insn "*testqi_ext_1"
8600 [(set (reg FLAGS_REG)
8604 (zero_extract:SI (match_operand 0 "ext_register_operand" "Q,Q")
8607 (match_operand:QI 1 "general_operand" "QnBc,m"))
8609 "ix86_match_ccmode (insn, CCNOmode)"
8610 "test{b}\t{%1, %h0|%h0, %1}"
8611 [(set_attr "isa" "*,nox64")
8612 (set_attr "type" "test")
8613 (set_attr "mode" "QI")])
8615 (define_insn "*testqi_ext_2"
8616 [(set (reg FLAGS_REG)
8620 (zero_extract:SI (match_operand 0 "ext_register_operand" "Q")
8624 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q")
8628 "ix86_match_ccmode (insn, CCNOmode)"
8629 "test{b}\t{%h1, %h0|%h0, %h1}"
8630 [(set_attr "type" "test")
8631 (set_attr "mode" "QI")])
8633 ;; Combine likes to form bit extractions for some tests. Humor it.
8634 (define_insn_and_split "*testqi_ext_3"
8635 [(set (match_operand 0 "flags_reg_operand")
8636 (match_operator 1 "compare_operator"
8637 [(zero_extract:SWI248
8638 (match_operand 2 "nonimmediate_operand" "rm")
8639 (match_operand 3 "const_int_operand" "n")
8640 (match_operand 4 "const_int_operand" "n"))
8642 "ix86_match_ccmode (insn, CCNOmode)
8643 && ((TARGET_64BIT && GET_MODE (operands[2]) == DImode)
8644 || GET_MODE (operands[2]) == SImode
8645 || GET_MODE (operands[2]) == HImode
8646 || GET_MODE (operands[2]) == QImode)
8647 /* Ensure that resulting mask is zero or sign extended operand. */
8648 && INTVAL (operands[4]) >= 0
8649 && ((INTVAL (operands[3]) > 0
8650 && INTVAL (operands[3]) + INTVAL (operands[4]) <= 32)
8651 || (<MODE>mode == DImode
8652 && INTVAL (operands[3]) > 32
8653 && INTVAL (operands[3]) + INTVAL (operands[4]) == 64))"
8656 [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
8658 rtx val = operands[2];
8659 HOST_WIDE_INT len = INTVAL (operands[3]);
8660 HOST_WIDE_INT pos = INTVAL (operands[4]);
8661 machine_mode mode = GET_MODE (val);
8665 machine_mode submode = GET_MODE (SUBREG_REG (val));
8667 /* Narrow paradoxical subregs to prevent partial register stalls. */
8668 if (GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode)
8669 && GET_MODE_CLASS (submode) == MODE_INT)
8671 val = SUBREG_REG (val);
8676 /* Small HImode tests can be converted to QImode. */
8677 if (register_operand (val, HImode) && pos + len <= 8)
8679 val = gen_lowpart (QImode, val);
8683 gcc_assert (pos + len <= GET_MODE_PRECISION (mode));
8686 = wi::shifted_mask (pos, len, false, GET_MODE_PRECISION (mode));
8688 operands[2] = gen_rtx_AND (mode, val, immed_wide_int_const (mask, mode));
8691 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
8692 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
8693 ;; this is relatively important trick.
8694 ;; Do the conversion only post-reload to avoid limiting of the register class
8697 [(set (match_operand 0 "flags_reg_operand")
8698 (match_operator 1 "compare_operator"
8699 [(and (match_operand 2 "QIreg_operand")
8700 (match_operand 3 "const_int_operand"))
8703 && GET_MODE (operands[2]) != QImode
8704 && ((ix86_match_ccmode (insn, CCZmode)
8705 && !(INTVAL (operands[3]) & ~(255 << 8)))
8706 || (ix86_match_ccmode (insn, CCNOmode)
8707 && !(INTVAL (operands[3]) & ~(127 << 8))))"
8712 (zero_extract:SI (match_dup 2)
8718 operands[2] = gen_lowpart (SImode, operands[2]);
8719 operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, QImode);
8723 [(set (match_operand 0 "flags_reg_operand")
8724 (match_operator 1 "compare_operator"
8725 [(and (match_operand 2 "nonimmediate_operand")
8726 (match_operand 3 "const_int_operand"))
8729 && GET_MODE (operands[2]) != QImode
8730 && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
8731 && ((ix86_match_ccmode (insn, CCZmode)
8732 && !(INTVAL (operands[3]) & ~255))
8733 || (ix86_match_ccmode (insn, CCNOmode)
8734 && !(INTVAL (operands[3]) & ~127)))"
8736 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
8739 operands[2] = gen_lowpart (QImode, operands[2]);
8740 operands[3] = gen_int_mode (INTVAL (operands[3]), QImode);
8743 ;; %%% This used to optimize known byte-wide and operations to memory,
8744 ;; and sometimes to QImode registers. If this is considered useful,
8745 ;; it should be done with splitters.
8747 (define_expand "and<mode>3"
8748 [(set (match_operand:SWIM1248x 0 "nonimmediate_operand")
8749 (and:SWIM1248x (match_operand:SWIM1248x 1 "nonimmediate_operand")
8750 (match_operand:SWIM1248x 2 "<general_szext_operand>")))]
8753 machine_mode mode = <MODE>mode;
8754 rtx (*insn) (rtx, rtx);
8756 if (CONST_INT_P (operands[2]) && REG_P (operands[0]))
8758 HOST_WIDE_INT ival = INTVAL (operands[2]);
8760 if (ival == (HOST_WIDE_INT) 0xffffffff)
8762 else if (ival == 0xffff)
8764 else if (ival == 0xff)
8768 if (mode == <MODE>mode)
8770 ix86_expand_binary_operator (AND, <MODE>mode, operands);
8774 if (<MODE>mode == DImode)
8775 insn = (mode == SImode)
8776 ? gen_zero_extendsidi2
8778 ? gen_zero_extendhidi2
8779 : gen_zero_extendqidi2;
8780 else if (<MODE>mode == SImode)
8781 insn = (mode == HImode)
8782 ? gen_zero_extendhisi2
8783 : gen_zero_extendqisi2;
8784 else if (<MODE>mode == HImode)
8785 insn = gen_zero_extendqihi2;
8789 emit_insn (insn (operands[0], gen_lowpart (mode, operands[1])));
8793 (define_insn_and_split "*anddi3_doubleword"
8794 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r")
8796 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8797 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm")))
8798 (clobber (reg:CC FLAGS_REG))]
8799 "!TARGET_64BIT && TARGET_STV && TARGET_SSE2
8800 && ix86_binary_operator_ok (AND, DImode, operands)"
8802 "&& reload_completed"
8805 split_double_mode (DImode, &operands[0], 3, &operands[0], &operands[3]);
8806 if (operands[2] == const0_rtx)
8808 operands[1] = const0_rtx;
8809 ix86_expand_move (SImode, &operands[0]);
8811 else if (operands[2] != constm1_rtx)
8812 ix86_expand_binary_operator (AND, SImode, &operands[0]);
8813 else if (operands[5] == constm1_rtx)
8814 emit_note (NOTE_INSN_DELETED);
8815 if (operands[5] == const0_rtx)
8817 operands[4] = const0_rtx;
8818 ix86_expand_move (SImode, &operands[3]);
8820 else if (operands[5] != constm1_rtx)
8821 ix86_expand_binary_operator (AND, SImode, &operands[3]);
8825 (define_insn "*anddi_1"
8826 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
8828 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
8829 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
8830 (clobber (reg:CC FLAGS_REG))]
8831 "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
8833 and{l}\t{%k2, %k0|%k0, %k2}
8834 and{q}\t{%2, %0|%0, %2}
8835 and{q}\t{%2, %0|%0, %2}
8837 [(set_attr "type" "alu,alu,alu,imovx")
8838 (set_attr "length_immediate" "*,*,*,0")
8839 (set (attr "prefix_rex")
8841 (and (eq_attr "type" "imovx")
8842 (and (match_test "INTVAL (operands[2]) == 0xff")
8843 (match_operand 1 "ext_QIreg_operand")))
8845 (const_string "*")))
8846 (set_attr "mode" "SI,DI,DI,SI")])
8848 (define_insn_and_split "*anddi_1_btr"
8849 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
8851 (match_operand:DI 1 "nonimmediate_operand" "%0")
8852 (match_operand:DI 2 "const_int_operand" "n")))
8853 (clobber (reg:CC FLAGS_REG))]
8854 "TARGET_64BIT && TARGET_USE_BT
8855 && ix86_binary_operator_ok (AND, DImode, operands)
8856 && IN_RANGE (exact_log2 (~INTVAL (operands[2])), 31, 63)"
8858 "&& reload_completed"
8859 [(parallel [(set (zero_extract:DI (match_dup 0)
8863 (clobber (reg:CC FLAGS_REG))])]
8864 "operands[3] = GEN_INT (exact_log2 (~INTVAL (operands[2])));"
8865 [(set_attr "type" "alu1")
8866 (set_attr "prefix_0f" "1")
8867 (set_attr "znver1_decode" "double")
8868 (set_attr "mode" "DI")])
8870 ;; Turn *anddi_1 into *andsi_1_zext if possible.
8872 [(set (match_operand:DI 0 "register_operand")
8873 (and:DI (subreg:DI (match_operand:SI 1 "register_operand") 0)
8874 (match_operand:DI 2 "x86_64_zext_immediate_operand")))
8875 (clobber (reg:CC FLAGS_REG))]
8877 [(parallel [(set (match_dup 0)
8878 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))
8879 (clobber (reg:CC FLAGS_REG))])]
8880 "operands[2] = gen_lowpart (SImode, operands[2]);")
8882 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8883 (define_insn "*andsi_1_zext"
8884 [(set (match_operand:DI 0 "register_operand" "=r")
8886 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8887 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
8888 (clobber (reg:CC FLAGS_REG))]
8889 "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
8890 "and{l}\t{%2, %k0|%k0, %2}"
8891 [(set_attr "type" "alu")
8892 (set_attr "mode" "SI")])
8894 (define_insn "*and<mode>_1"
8895 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=rm,r,Ya")
8896 (and:SWI24 (match_operand:SWI24 1 "nonimmediate_operand" "%0,0,qm")
8897 (match_operand:SWI24 2 "<general_operand>" "r<i>,rm,L")))
8898 (clobber (reg:CC FLAGS_REG))]
8899 "ix86_binary_operator_ok (AND, <MODE>mode, operands)"
8901 and{<imodesuffix>}\t{%2, %0|%0, %2}
8902 and{<imodesuffix>}\t{%2, %0|%0, %2}
8904 [(set_attr "type" "alu,alu,imovx")
8905 (set_attr "length_immediate" "*,*,0")
8906 (set (attr "prefix_rex")
8908 (and (eq_attr "type" "imovx")
8909 (and (match_test "INTVAL (operands[2]) == 0xff")
8910 (match_operand 1 "ext_QIreg_operand")))
8912 (const_string "*")))
8913 (set_attr "mode" "<MODE>,<MODE>,SI")])
8915 (define_insn "*andqi_1"
8916 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
8917 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8918 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
8919 (clobber (reg:CC FLAGS_REG))]
8920 "ix86_binary_operator_ok (AND, QImode, operands)"
8922 and{b}\t{%2, %0|%0, %2}
8923 and{b}\t{%2, %0|%0, %2}
8924 and{l}\t{%k2, %k0|%k0, %k2}"
8925 [(set_attr "type" "alu")
8926 (set_attr "mode" "QI,QI,SI")
8927 ;; Potential partial reg stall on alternative 2.
8928 (set (attr "preferred_for_speed")
8929 (cond [(eq_attr "alternative" "2")
8930 (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
8931 (symbol_ref "true")))])
8933 (define_insn "*andqi_1_slp"
8934 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
8935 (and:QI (match_dup 0)
8936 (match_operand:QI 1 "general_operand" "qn,qmn")))
8937 (clobber (reg:CC FLAGS_REG))]
8938 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8939 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8940 "and{b}\t{%1, %0|%0, %1}"
8941 [(set_attr "type" "alu1")
8942 (set_attr "mode" "QI")])
8945 [(set (match_operand:SWI248 0 "register_operand")
8946 (and:SWI248 (match_operand:SWI248 1 "nonimmediate_operand")
8947 (match_operand:SWI248 2 "const_int_operand")))
8948 (clobber (reg:CC FLAGS_REG))]
8950 && (!REG_P (operands[1])
8951 || REGNO (operands[0]) != REGNO (operands[1]))"
8954 HOST_WIDE_INT ival = INTVAL (operands[2]);
8956 rtx (*insn) (rtx, rtx);
8958 if (ival == (HOST_WIDE_INT) 0xffffffff)
8960 else if (ival == 0xffff)
8964 gcc_assert (ival == 0xff);
8968 if (<MODE>mode == DImode)
8969 insn = (mode == SImode)
8970 ? gen_zero_extendsidi2
8972 ? gen_zero_extendhidi2
8973 : gen_zero_extendqidi2;
8976 if (<MODE>mode != SImode)
8977 /* Zero extend to SImode to avoid partial register stalls. */
8978 operands[0] = gen_lowpart (SImode, operands[0]);
8980 insn = (mode == HImode)
8981 ? gen_zero_extendhisi2
8982 : gen_zero_extendqisi2;
8984 emit_insn (insn (operands[0], gen_lowpart (mode, operands[1])));
8989 [(set (match_operand:SWI48 0 "register_operand")
8990 (and:SWI48 (match_dup 0)
8991 (const_int -65536)))
8992 (clobber (reg:CC FLAGS_REG))]
8993 "(TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)
8994 || optimize_function_for_size_p (cfun)"
8995 [(set (strict_low_part (match_dup 1)) (const_int 0))]
8996 "operands[1] = gen_lowpart (HImode, operands[0]);")
8999 [(set (match_operand:SWI248 0 "any_QIreg_operand")
9000 (and:SWI248 (match_dup 0)
9002 (clobber (reg:CC FLAGS_REG))]
9003 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9004 && reload_completed"
9005 [(set (strict_low_part (match_dup 1)) (const_int 0))]
9006 "operands[1] = gen_lowpart (QImode, operands[0]);")
9009 [(set (match_operand:SWI248 0 "QIreg_operand")
9010 (and:SWI248 (match_dup 0)
9011 (const_int -65281)))
9012 (clobber (reg:CC FLAGS_REG))]
9013 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9014 && reload_completed"
9016 [(set (zero_extract:SI (match_dup 0)
9022 (zero_extract:SI (match_dup 0)
9026 (zero_extract:SI (match_dup 0)
9028 (const_int 8)) 0)) 0))
9029 (clobber (reg:CC FLAGS_REG))])]
9030 "operands[0] = gen_lowpart (SImode, operands[0]);")
9032 (define_insn "*anddi_2"
9033 [(set (reg FLAGS_REG)
9036 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
9037 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
9039 (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
9040 (and:DI (match_dup 1) (match_dup 2)))]
9042 && ix86_match_ccmode
9044 /* If we are going to emit andl instead of andq, and the operands[2]
9045 constant might have the SImode sign bit set, make sure the sign
9046 flag isn't tested, because the instruction will set the sign flag
9047 based on bit 31 rather than bit 63. If it isn't CONST_INT,
9048 conservatively assume it might have bit 31 set. */
9049 (satisfies_constraint_Z (operands[2])
9050 && (!CONST_INT_P (operands[2])
9051 || val_signbit_known_set_p (SImode, INTVAL (operands[2]))))
9052 ? CCZmode : CCNOmode)
9053 && ix86_binary_operator_ok (AND, DImode, operands)"
9055 and{l}\t{%k2, %k0|%k0, %k2}
9056 and{q}\t{%2, %0|%0, %2}
9057 and{q}\t{%2, %0|%0, %2}"
9058 [(set_attr "type" "alu")
9059 (set_attr "mode" "SI,DI,DI")])
9061 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9062 (define_insn "*andsi_2_zext"
9063 [(set (reg FLAGS_REG)
9065 (match_operand:SI 1 "nonimmediate_operand" "%0")
9066 (match_operand:SI 2 "x86_64_general_operand" "rme"))
9068 (set (match_operand:DI 0 "register_operand" "=r")
9069 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
9070 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9071 && ix86_binary_operator_ok (AND, SImode, operands)"
9072 "and{l}\t{%2, %k0|%k0, %2}"
9073 [(set_attr "type" "alu")
9074 (set_attr "mode" "SI")])
9076 (define_insn "*andqi_2_maybe_si"
9077 [(set (reg FLAGS_REG)
9079 (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9080 (match_operand:QI 2 "general_operand" "qmn,qn,n"))
9082 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
9083 (and:QI (match_dup 1) (match_dup 2)))]
9084 "ix86_binary_operator_ok (AND, QImode, operands)
9085 && ix86_match_ccmode (insn,
9086 CONST_INT_P (operands[2])
9087 && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
9089 if (which_alternative == 2)
9091 if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
9092 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
9093 return "and{l}\t{%2, %k0|%k0, %2}";
9095 return "and{b}\t{%2, %0|%0, %2}";
9097 [(set_attr "type" "alu")
9098 (set_attr "mode" "QI,QI,SI")])
9100 (define_insn "*and<mode>_2"
9101 [(set (reg FLAGS_REG)
9102 (compare (and:SWI124
9103 (match_operand:SWI124 1 "nonimmediate_operand" "%0,0")
9104 (match_operand:SWI124 2 "<general_operand>" "<g>,<r><i>"))
9106 (set (match_operand:SWI124 0 "nonimmediate_operand" "=<r>,<r>m")
9107 (and:SWI124 (match_dup 1) (match_dup 2)))]
9108 "ix86_match_ccmode (insn, CCNOmode)
9109 && ix86_binary_operator_ok (AND, <MODE>mode, operands)"
9110 "and{<imodesuffix>}\t{%2, %0|%0, %2}"
9111 [(set_attr "type" "alu")
9112 (set_attr "mode" "<MODE>")])
9114 (define_insn "*andqi_2_slp"
9115 [(set (reg FLAGS_REG)
9117 (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9118 (match_operand:QI 1 "nonimmediate_operand" "qmn,qn"))
9120 (set (strict_low_part (match_dup 0))
9121 (and:QI (match_dup 0) (match_dup 1)))]
9122 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9123 && ix86_match_ccmode (insn, CCNOmode)
9124 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9125 "and{b}\t{%1, %0|%0, %1}"
9126 [(set_attr "type" "alu1")
9127 (set_attr "mode" "QI")])
9129 (define_insn "andqi_ext_1"
9130 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q,Q")
9136 (zero_extract:SI (match_operand 1 "ext_register_operand" "0,0")
9139 (match_operand:QI 2 "general_operand" "QnBc,m")) 0))
9140 (clobber (reg:CC FLAGS_REG))]
9141 "/* FIXME: without this LRA can't reload this pattern, see PR82524. */
9142 rtx_equal_p (operands[0], operands[1])"
9143 "and{b}\t{%2, %h0|%h0, %2}"
9144 [(set_attr "isa" "*,nox64")
9145 (set_attr "type" "alu")
9146 (set_attr "mode" "QI")])
9148 ;; Generated by peephole translating test to and. This shows up
9149 ;; often in fp comparisons.
9150 (define_insn "*andqi_ext_1_cc"
9151 [(set (reg FLAGS_REG)
9155 (zero_extract:SI (match_operand 1 "ext_register_operand" "0,0")
9158 (match_operand:QI 2 "general_operand" "QnBc,m"))
9160 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q,Q")
9166 (zero_extract:SI (match_dup 1)
9170 "ix86_match_ccmode (insn, CCNOmode)
9171 /* FIXME: without this LRA can't reload this pattern, see PR82524. */
9172 && rtx_equal_p (operands[0], operands[1])"
9173 "and{b}\t{%2, %h0|%h0, %2}"
9174 [(set_attr "isa" "*,nox64")
9175 (set_attr "type" "alu")
9176 (set_attr "mode" "QI")])
9178 (define_insn "*andqi_ext_2"
9179 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
9185 (zero_extract:SI (match_operand 1 "ext_register_operand" "%0")
9189 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9191 (const_int 8)) 0)) 0))
9192 (clobber (reg:CC FLAGS_REG))]
9193 "/* FIXME: without this LRA can't reload this pattern, see PR82524. */
9194 rtx_equal_p (operands[0], operands[1])
9195 || rtx_equal_p (operands[0], operands[2])"
9196 "and{b}\t{%h2, %h0|%h0, %h2}"
9197 [(set_attr "type" "alu")
9198 (set_attr "mode" "QI")])
9200 ;; Convert wide AND instructions with immediate operand to shorter QImode
9201 ;; equivalents when possible.
9202 ;; Don't do the splitting with memory operands, since it introduces risk
9203 ;; of memory mismatch stalls. We may want to do the splitting for optimizing
9204 ;; for size, but that can (should?) be handled by generic code instead.
9206 [(set (match_operand:SWI248 0 "QIreg_operand")
9207 (and:SWI248 (match_operand:SWI248 1 "register_operand")
9208 (match_operand:SWI248 2 "const_int_operand")))
9209 (clobber (reg:CC FLAGS_REG))]
9211 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9212 && !(~INTVAL (operands[2]) & ~(255 << 8))"
9214 [(set (zero_extract:SI (match_dup 0)
9220 (zero_extract:SI (match_dup 1)
9224 (clobber (reg:CC FLAGS_REG))])]
9226 operands[0] = gen_lowpart (SImode, operands[0]);
9227 operands[1] = gen_lowpart (SImode, operands[1]);
9228 operands[2] = gen_int_mode (INTVAL (operands[2]) >> 8, QImode);
9231 ;; Since AND can be encoded with sign extended immediate, this is only
9232 ;; profitable when 7th bit is not set.
9234 [(set (match_operand:SWI248 0 "any_QIreg_operand")
9235 (and:SWI248 (match_operand:SWI248 1 "general_operand")
9236 (match_operand:SWI248 2 "const_int_operand")))
9237 (clobber (reg:CC FLAGS_REG))]
9239 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9240 && !(~INTVAL (operands[2]) & ~255)
9241 && !(INTVAL (operands[2]) & 128)"
9242 [(parallel [(set (strict_low_part (match_dup 0))
9243 (and:QI (match_dup 1)
9245 (clobber (reg:CC FLAGS_REG))])]
9247 operands[0] = gen_lowpart (QImode, operands[0]);
9248 operands[1] = gen_lowpart (QImode, operands[1]);
9249 operands[2] = gen_int_mode (INTVAL (operands[2]), QImode);
9252 (define_insn "*andndi3_doubleword"
9253 [(set (match_operand:DI 0 "register_operand" "=&r,r,r,&r")
9255 (not:DI (match_operand:DI 1 "register_operand" "r,0,r,0"))
9256 (match_operand:DI 2 "nonimmediate_operand" "rm,rm,0,rm")))
9257 (clobber (reg:CC FLAGS_REG))]
9258 "!TARGET_64BIT && TARGET_STV && TARGET_SSE2"
9260 [(set_attr "isa" "bmi,bmi,bmi,*")])
9263 [(set (match_operand:DI 0 "register_operand")
9265 (not:DI (match_operand:DI 1 "register_operand"))
9266 (match_operand:DI 2 "nonimmediate_operand")))
9267 (clobber (reg:CC FLAGS_REG))]
9268 "!TARGET_64BIT && TARGET_BMI && TARGET_STV && TARGET_SSE2
9269 && reload_completed"
9270 [(parallel [(set (match_dup 0)
9271 (and:SI (not:SI (match_dup 1)) (match_dup 2)))
9272 (clobber (reg:CC FLAGS_REG))])
9273 (parallel [(set (match_dup 3)
9274 (and:SI (not:SI (match_dup 4)) (match_dup 5)))
9275 (clobber (reg:CC FLAGS_REG))])]
9276 "split_double_mode (DImode, &operands[0], 3, &operands[0], &operands[3]);")
9279 [(set (match_operand:DI 0 "register_operand")
9281 (not:DI (match_dup 0))
9282 (match_operand:DI 1 "nonimmediate_operand")))
9283 (clobber (reg:CC FLAGS_REG))]
9284 "!TARGET_64BIT && !TARGET_BMI && TARGET_STV && TARGET_SSE2
9285 && reload_completed"
9286 [(set (match_dup 0) (not:SI (match_dup 0)))
9287 (parallel [(set (match_dup 0)
9288 (and:SI (match_dup 0) (match_dup 1)))
9289 (clobber (reg:CC FLAGS_REG))])
9290 (set (match_dup 2) (not:SI (match_dup 2)))
9291 (parallel [(set (match_dup 2)
9292 (and:SI (match_dup 2) (match_dup 3)))
9293 (clobber (reg:CC FLAGS_REG))])]
9294 "split_double_mode (DImode, &operands[0], 2, &operands[0], &operands[2]);")
9296 (define_insn "*andn<mode>_1"
9297 [(set (match_operand:SWI48 0 "register_operand" "=r,r")
9299 (not:SWI48 (match_operand:SWI48 1 "register_operand" "r,r"))
9300 (match_operand:SWI48 2 "nonimmediate_operand" "r,m")))
9301 (clobber (reg:CC FLAGS_REG))]
9303 "andn\t{%2, %1, %0|%0, %1, %2}"
9304 [(set_attr "type" "bitmanip")
9305 (set_attr "btver2_decode" "direct, double")
9306 (set_attr "mode" "<MODE>")])
9308 (define_insn "*andn<mode>_1"
9309 [(set (match_operand:SWI12 0 "register_operand" "=r")
9311 (not:SWI12 (match_operand:SWI12 1 "register_operand" "r"))
9312 (match_operand:SWI12 2 "register_operand" "r")))
9313 (clobber (reg:CC FLAGS_REG))]
9315 "andn\t{%k2, %k1, %k0|%k0, %k1, %k2}"
9316 [(set_attr "type" "bitmanip")
9317 (set_attr "btver2_decode" "direct")
9318 (set_attr "mode" "SI")])
9320 (define_insn "*andn_<mode>_ccno"
9321 [(set (reg FLAGS_REG)
9324 (not:SWI48 (match_operand:SWI48 1 "register_operand" "r,r"))
9325 (match_operand:SWI48 2 "nonimmediate_operand" "r,m"))
9327 (clobber (match_scratch:SWI48 0 "=r,r"))]
9328 "TARGET_BMI && ix86_match_ccmode (insn, CCNOmode)"
9329 "andn\t{%2, %1, %0|%0, %1, %2}"
9330 [(set_attr "type" "bitmanip")
9331 (set_attr "btver2_decode" "direct, double")
9332 (set_attr "mode" "<MODE>")])
9334 ;; Logical inclusive and exclusive OR instructions
9336 ;; %%% This used to optimize known byte-wide and operations to memory.
9337 ;; If this is considered useful, it should be done with splitters.
9339 (define_expand "<code><mode>3"
9340 [(set (match_operand:SWIM1248x 0 "nonimmediate_operand")
9341 (any_or:SWIM1248x (match_operand:SWIM1248x 1 "nonimmediate_operand")
9342 (match_operand:SWIM1248x 2 "<general_operand>")))]
9344 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
9346 (define_insn_and_split "*<code>di3_doubleword"
9347 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r")
9349 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
9350 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm")))
9351 (clobber (reg:CC FLAGS_REG))]
9352 "!TARGET_64BIT && TARGET_STV && TARGET_SSE2
9353 && ix86_binary_operator_ok (<CODE>, DImode, operands)"
9355 "&& reload_completed"
9358 split_double_mode (DImode, &operands[0], 3, &operands[0], &operands[3]);
9359 if (operands[2] == constm1_rtx)
9363 operands[1] = constm1_rtx;
9364 ix86_expand_move (SImode, &operands[0]);
9367 ix86_expand_unary_operator (NOT, SImode, &operands[0]);
9369 else if (operands[2] != const0_rtx)
9370 ix86_expand_binary_operator (<CODE>, SImode, &operands[0]);
9371 else if (operands[5] == const0_rtx)
9372 emit_note (NOTE_INSN_DELETED);
9373 if (operands[5] == constm1_rtx)
9377 operands[4] = constm1_rtx;
9378 ix86_expand_move (SImode, &operands[3]);
9381 ix86_expand_unary_operator (NOT, SImode, &operands[3]);
9383 else if (operands[5] != const0_rtx)
9384 ix86_expand_binary_operator (<CODE>, SImode, &operands[3]);
9388 (define_insn "*<code><mode>_1"
9389 [(set (match_operand:SWI248 0 "nonimmediate_operand" "=r,rm")
9391 (match_operand:SWI248 1 "nonimmediate_operand" "%0,0")
9392 (match_operand:SWI248 2 "<general_operand>" "<g>,r<i>")))
9393 (clobber (reg:CC FLAGS_REG))]
9394 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9395 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
9396 [(set_attr "type" "alu")
9397 (set_attr "mode" "<MODE>")])
9399 (define_insn_and_split "*iordi_1_bts"
9400 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9402 (match_operand:DI 1 "nonimmediate_operand" "%0")
9403 (match_operand:DI 2 "const_int_operand" "n")))
9404 (clobber (reg:CC FLAGS_REG))]
9405 "TARGET_64BIT && TARGET_USE_BT
9406 && ix86_binary_operator_ok (IOR, DImode, operands)
9407 && IN_RANGE (exact_log2 (INTVAL (operands[2])), 31, 63)"
9409 "&& reload_completed"
9410 [(parallel [(set (zero_extract:DI (match_dup 0)
9414 (clobber (reg:CC FLAGS_REG))])]
9415 "operands[3] = GEN_INT (exact_log2 (INTVAL (operands[2])));"
9416 [(set_attr "type" "alu1")
9417 (set_attr "prefix_0f" "1")
9418 (set_attr "znver1_decode" "double")
9419 (set_attr "mode" "DI")])
9421 (define_insn_and_split "*xordi_1_btc"
9422 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9424 (match_operand:DI 1 "nonimmediate_operand" "%0")
9425 (match_operand:DI 2 "const_int_operand" "n")))
9426 (clobber (reg:CC FLAGS_REG))]
9427 "TARGET_64BIT && TARGET_USE_BT
9428 && ix86_binary_operator_ok (XOR, DImode, operands)
9429 && IN_RANGE (exact_log2 (INTVAL (operands[2])), 31, 63)"
9431 "&& reload_completed"
9432 [(parallel [(set (zero_extract:DI (match_dup 0)
9435 (not:DI (zero_extract:DI (match_dup 0)
9438 (clobber (reg:CC FLAGS_REG))])]
9439 "operands[3] = GEN_INT (exact_log2 (INTVAL (operands[2])));"
9440 [(set_attr "type" "alu1")
9441 (set_attr "prefix_0f" "1")
9442 (set_attr "znver1_decode" "double")
9443 (set_attr "mode" "DI")])
9445 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9446 (define_insn "*<code>si_1_zext"
9447 [(set (match_operand:DI 0 "register_operand" "=r")
9449 (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9450 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
9451 (clobber (reg:CC FLAGS_REG))]
9452 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
9453 "<logic>{l}\t{%2, %k0|%k0, %2}"
9454 [(set_attr "type" "alu")
9455 (set_attr "mode" "SI")])
9457 (define_insn "*<code>si_1_zext_imm"
9458 [(set (match_operand:DI 0 "register_operand" "=r")
9460 (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
9461 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
9462 (clobber (reg:CC FLAGS_REG))]
9463 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
9464 "<logic>{l}\t{%2, %k0|%k0, %2}"
9465 [(set_attr "type" "alu")
9466 (set_attr "mode" "SI")])
9468 (define_insn "*<code>qi_1"
9469 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
9470 (any_or:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9471 (match_operand:QI 2 "general_operand" "qmn,qn,rn")))
9472 (clobber (reg:CC FLAGS_REG))]
9473 "ix86_binary_operator_ok (<CODE>, QImode, operands)"
9475 <logic>{b}\t{%2, %0|%0, %2}
9476 <logic>{b}\t{%2, %0|%0, %2}
9477 <logic>{l}\t{%k2, %k0|%k0, %k2}"
9478 [(set_attr "type" "alu")
9479 (set_attr "mode" "QI,QI,SI")
9480 ;; Potential partial reg stall on alternative 2.
9481 (set (attr "preferred_for_speed")
9482 (cond [(eq_attr "alternative" "2")
9483 (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
9484 (symbol_ref "true")))])
9486 (define_insn "*<code>qi_1_slp"
9487 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
9488 (any_or:QI (match_dup 0)
9489 (match_operand:QI 1 "general_operand" "qmn,qn")))
9490 (clobber (reg:CC FLAGS_REG))]
9491 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9492 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9493 "<logic>{b}\t{%1, %0|%0, %1}"
9494 [(set_attr "type" "alu1")
9495 (set_attr "mode" "QI")])
9497 (define_insn "*<code><mode>_2"
9498 [(set (reg FLAGS_REG)
9499 (compare (any_or:SWI
9500 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
9501 (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>"))
9503 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
9504 (any_or:SWI (match_dup 1) (match_dup 2)))]
9505 "ix86_match_ccmode (insn, CCNOmode)
9506 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9507 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
9508 [(set_attr "type" "alu")
9509 (set_attr "mode" "<MODE>")])
9511 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9512 ;; ??? Special case for immediate operand is missing - it is tricky.
9513 (define_insn "*<code>si_2_zext"
9514 [(set (reg FLAGS_REG)
9515 (compare (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9516 (match_operand:SI 2 "x86_64_general_operand" "rme"))
9518 (set (match_operand:DI 0 "register_operand" "=r")
9519 (zero_extend:DI (any_or:SI (match_dup 1) (match_dup 2))))]
9520 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9521 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
9522 "<logic>{l}\t{%2, %k0|%k0, %2}"
9523 [(set_attr "type" "alu")
9524 (set_attr "mode" "SI")])
9526 (define_insn "*<code>si_2_zext_imm"
9527 [(set (reg FLAGS_REG)
9529 (match_operand:SI 1 "nonimmediate_operand" "%0")
9530 (match_operand:SI 2 "x86_64_zext_immediate_operand" "Z"))
9532 (set (match_operand:DI 0 "register_operand" "=r")
9533 (any_or:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
9534 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9535 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
9536 "<logic>{l}\t{%2, %k0|%k0, %2}"
9537 [(set_attr "type" "alu")
9538 (set_attr "mode" "SI")])
9540 (define_insn "*<code>qi_2_slp"
9541 [(set (reg FLAGS_REG)
9542 (compare (any_or:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9543 (match_operand:QI 1 "general_operand" "qmn,qn"))
9545 (set (strict_low_part (match_dup 0))
9546 (any_or:QI (match_dup 0) (match_dup 1)))]
9547 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9548 && ix86_match_ccmode (insn, CCNOmode)
9549 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9550 "<logic>{b}\t{%1, %0|%0, %1}"
9551 [(set_attr "type" "alu1")
9552 (set_attr "mode" "QI")])
9554 (define_insn "*<code><mode>_3"
9555 [(set (reg FLAGS_REG)
9556 (compare (any_or:SWI
9557 (match_operand:SWI 1 "nonimmediate_operand" "%0")
9558 (match_operand:SWI 2 "<general_operand>" "<g>"))
9560 (clobber (match_scratch:SWI 0 "=<r>"))]
9561 "ix86_match_ccmode (insn, CCNOmode)
9562 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9563 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
9564 [(set_attr "type" "alu")
9565 (set_attr "mode" "<MODE>")])
9567 (define_insn "*<code>qi_ext_1"
9568 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q,Q")
9574 (zero_extract:SI (match_operand 1 "ext_register_operand" "0,0")
9577 (match_operand:QI 2 "general_operand" "QnBc,m")) 0))
9578 (clobber (reg:CC FLAGS_REG))]
9579 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9580 /* FIXME: without this LRA can't reload this pattern, see PR82524. */
9581 && rtx_equal_p (operands[0], operands[1])"
9582 "<logic>{b}\t{%2, %h0|%h0, %2}"
9583 [(set_attr "isa" "*,nox64")
9584 (set_attr "type" "alu")
9585 (set_attr "mode" "QI")])
9587 (define_insn "*<code>qi_ext_2"
9588 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
9594 (zero_extract:SI (match_operand 1 "ext_register_operand" "%0")
9598 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9600 (const_int 8)) 0)) 0))
9601 (clobber (reg:CC FLAGS_REG))]
9602 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9603 /* FIXME: without this LRA can't reload this pattern, see PR82524. */
9604 && (rtx_equal_p (operands[0], operands[1])
9605 || rtx_equal_p (operands[0], operands[2]))"
9606 "<logic>{b}\t{%h2, %h0|%h0, %h2}"
9607 [(set_attr "type" "alu")
9608 (set_attr "mode" "QI")])
9610 ;; Convert wide OR instructions with immediate operand to shorter QImode
9611 ;; equivalents when possible.
9612 ;; Don't do the splitting with memory operands, since it introduces risk
9613 ;; of memory mismatch stalls. We may want to do the splitting for optimizing
9614 ;; for size, but that can (should?) be handled by generic code instead.
9616 [(set (match_operand:SWI248 0 "QIreg_operand")
9617 (any_or:SWI248 (match_operand:SWI248 1 "register_operand")
9618 (match_operand:SWI248 2 "const_int_operand")))
9619 (clobber (reg:CC FLAGS_REG))]
9621 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9622 && !(INTVAL (operands[2]) & ~(255 << 8))"
9624 [(set (zero_extract:SI (match_dup 0)
9630 (zero_extract:SI (match_dup 1)
9634 (clobber (reg:CC FLAGS_REG))])]
9636 operands[0] = gen_lowpart (SImode, operands[0]);
9637 operands[1] = gen_lowpart (SImode, operands[1]);
9638 operands[2] = gen_int_mode (INTVAL (operands[2]) >> 8, QImode);
9641 ;; Since OR can be encoded with sign extended immediate, this is only
9642 ;; profitable when 7th bit is set.
9644 [(set (match_operand:SWI248 0 "any_QIreg_operand")
9645 (any_or:SWI248 (match_operand:SWI248 1 "general_operand")
9646 (match_operand:SWI248 2 "const_int_operand")))
9647 (clobber (reg:CC FLAGS_REG))]
9649 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9650 && !(INTVAL (operands[2]) & ~255)
9651 && (INTVAL (operands[2]) & 128)"
9652 [(parallel [(set (strict_low_part (match_dup 0))
9653 (any_or:QI (match_dup 1)
9655 (clobber (reg:CC FLAGS_REG))])]
9657 operands[0] = gen_lowpart (QImode, operands[0]);
9658 operands[1] = gen_lowpart (QImode, operands[1]);
9659 operands[2] = gen_int_mode (INTVAL (operands[2]), QImode);
9662 (define_expand "xorqi_ext_1_cc"
9664 (set (reg:CCNO FLAGS_REG)
9668 (zero_extract:SI (match_operand 1 "ext_register_operand")
9671 (match_operand 2 "const_int_operand"))
9673 (set (zero_extract:SI (match_operand 0 "ext_register_operand")
9679 (zero_extract:SI (match_dup 1)
9682 (match_dup 2)) 0))])])
9684 (define_insn "*xorqi_ext_1_cc"
9685 [(set (reg FLAGS_REG)
9689 (zero_extract:SI (match_operand 1 "ext_register_operand" "0,0")
9692 (match_operand:QI 2 "general_operand" "QnBc,m"))
9694 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q,Q")
9700 (zero_extract:SI (match_dup 1)
9704 "ix86_match_ccmode (insn, CCNOmode)
9705 /* FIXME: without this LRA can't reload this pattern, see PR82524. */
9706 && rtx_equal_p (operands[0], operands[1])"
9707 "xor{b}\t{%2, %h0|%h0, %2}"
9708 [(set_attr "isa" "*,nox64")
9709 (set_attr "type" "alu")
9710 (set_attr "mode" "QI")])
9712 ;; Negation instructions
9714 (define_expand "neg<mode>2"
9715 [(set (match_operand:SDWIM 0 "nonimmediate_operand")
9716 (neg:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")))]
9718 "ix86_expand_unary_operator (NEG, <MODE>mode, operands); DONE;")
9720 (define_insn_and_split "*neg<dwi>2_doubleword"
9721 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro")
9722 (neg:<DWI> (match_operand:<DWI> 1 "nonimmediate_operand" "0")))
9723 (clobber (reg:CC FLAGS_REG))]
9724 "ix86_unary_operator_ok (NEG, <DWI>mode, operands)"
9728 [(set (reg:CCZ FLAGS_REG)
9729 (compare:CCZ (neg:DWIH (match_dup 1)) (const_int 0)))
9730 (set (match_dup 0) (neg:DWIH (match_dup 1)))])
9733 (plus:DWIH (plus:DWIH (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
9736 (clobber (reg:CC FLAGS_REG))])
9739 (neg:DWIH (match_dup 2)))
9740 (clobber (reg:CC FLAGS_REG))])]
9741 "split_double_mode (<DWI>mode, &operands[0], 2, &operands[0], &operands[2]);")
9743 (define_insn "*neg<mode>2_1"
9744 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9745 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")))
9746 (clobber (reg:CC FLAGS_REG))]
9747 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
9748 "neg{<imodesuffix>}\t%0"
9749 [(set_attr "type" "negnot")
9750 (set_attr "mode" "<MODE>")])
9752 ;; Combine is quite creative about this pattern.
9753 (define_insn "*negsi2_1_zext"
9754 [(set (match_operand:DI 0 "register_operand" "=r")
9756 (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
9759 (clobber (reg:CC FLAGS_REG))]
9760 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9762 [(set_attr "type" "negnot")
9763 (set_attr "mode" "SI")])
9765 ;; The problem with neg is that it does not perform (compare x 0),
9766 ;; it really performs (compare 0 x), which leaves us with the zero
9767 ;; flag being the only useful item.
9769 (define_insn "*neg<mode>2_cmpz"
9770 [(set (reg:CCZ FLAGS_REG)
9772 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
9774 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9775 (neg:SWI (match_dup 1)))]
9776 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
9777 "neg{<imodesuffix>}\t%0"
9778 [(set_attr "type" "negnot")
9779 (set_attr "mode" "<MODE>")])
9781 (define_insn "*negsi2_cmpz_zext"
9782 [(set (reg:CCZ FLAGS_REG)
9786 (match_operand:DI 1 "register_operand" "0")
9790 (set (match_operand:DI 0 "register_operand" "=r")
9791 (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
9794 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9796 [(set_attr "type" "negnot")
9797 (set_attr "mode" "SI")])
9799 ;; Negate with jump on overflow.
9800 (define_expand "negv<mode>3"
9801 [(parallel [(set (reg:CCO FLAGS_REG)
9802 (ne:CCO (match_operand:SWI 1 "register_operand")
9804 (set (match_operand:SWI 0 "register_operand")
9805 (neg:SWI (match_dup 1)))])
9806 (set (pc) (if_then_else
9807 (eq (reg:CCO FLAGS_REG) (const_int 0))
9808 (label_ref (match_operand 2))
9813 = gen_int_mode (HOST_WIDE_INT_1U << (GET_MODE_BITSIZE (<MODE>mode) - 1),
9817 (define_insn "*negv<mode>3"
9818 [(set (reg:CCO FLAGS_REG)
9819 (ne:CCO (match_operand:SWI 1 "nonimmediate_operand" "0")
9820 (match_operand:SWI 2 "const_int_operand")))
9821 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9822 (neg:SWI (match_dup 1)))]
9823 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)
9824 && mode_signbit_p (<MODE>mode, operands[2])"
9825 "neg{<imodesuffix>}\t%0"
9826 [(set_attr "type" "negnot")
9827 (set_attr "mode" "<MODE>")])
9829 ;; Changing of sign for FP values is doable using integer unit too.
9831 (define_expand "<code><mode>2"
9832 [(set (match_operand:X87MODEF 0 "register_operand")
9833 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand")))]
9834 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
9835 "ix86_expand_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
9837 (define_insn "*absneg<mode>2"
9838 [(set (match_operand:MODEF 0 "register_operand" "=Yv,Yv,f,!r")
9839 (match_operator:MODEF 3 "absneg_operator"
9840 [(match_operand:MODEF 1 "register_operand" "0,Yv,0,0")]))
9841 (use (match_operand:<ssevecmode> 2 "nonimmediate_operand" "Yvm,0,X,X"))
9842 (clobber (reg:CC FLAGS_REG))]
9843 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
9845 [(set (attr "enabled")
9847 (match_test ("SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"))
9849 (eq_attr "alternative" "2")
9850 (symbol_ref "TARGET_MIX_SSE_I387")
9851 (symbol_ref "true"))
9853 (eq_attr "alternative" "2,3")
9855 (symbol_ref "false"))))])
9857 (define_insn "*absnegxf2_i387"
9858 [(set (match_operand:XF 0 "register_operand" "=f,!r")
9859 (match_operator:XF 3 "absneg_operator"
9860 [(match_operand:XF 1 "register_operand" "0,0")]))
9861 (use (match_operand 2))
9862 (clobber (reg:CC FLAGS_REG))]
9866 (define_expand "<code>tf2"
9867 [(set (match_operand:TF 0 "register_operand")
9868 (absneg:TF (match_operand:TF 1 "register_operand")))]
9870 "ix86_expand_fp_absneg_operator (<CODE>, TFmode, operands); DONE;")
9872 (define_insn "*absnegtf2_sse"
9873 [(set (match_operand:TF 0 "register_operand" "=Yv,Yv")
9874 (match_operator:TF 3 "absneg_operator"
9875 [(match_operand:TF 1 "register_operand" "0,Yv")]))
9876 (use (match_operand:TF 2 "nonimmediate_operand" "Yvm,0"))
9877 (clobber (reg:CC FLAGS_REG))]
9881 ;; Splitters for fp abs and neg.
9884 [(set (match_operand 0 "fp_register_operand")
9885 (match_operator 1 "absneg_operator" [(match_dup 0)]))
9886 (use (match_operand 2))
9887 (clobber (reg:CC FLAGS_REG))]
9889 [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
9892 [(set (match_operand 0 "sse_reg_operand")
9893 (match_operator 3 "absneg_operator"
9894 [(match_operand 1 "register_operand")]))
9895 (use (match_operand 2 "nonimmediate_operand"))
9896 (clobber (reg:CC FLAGS_REG))]
9898 [(set (match_dup 0) (match_dup 3))]
9900 machine_mode mode = GET_MODE (operands[0]);
9901 machine_mode vmode = GET_MODE (operands[2]);
9904 operands[0] = lowpart_subreg (vmode, operands[0], mode);
9905 operands[1] = lowpart_subreg (vmode, operands[1], mode);
9906 if (operands_match_p (operands[0], operands[2]))
9907 std::swap (operands[1], operands[2]);
9908 if (GET_CODE (operands[3]) == ABS)
9909 tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
9911 tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
9916 [(set (match_operand:SF 0 "general_reg_operand")
9917 (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
9918 (use (match_operand:V4SF 2))
9919 (clobber (reg:CC FLAGS_REG))]
9921 [(parallel [(set (match_dup 0) (match_dup 1))
9922 (clobber (reg:CC FLAGS_REG))])]
9925 operands[0] = gen_lowpart (SImode, operands[0]);
9926 if (GET_CODE (operands[1]) == ABS)
9928 tmp = gen_int_mode (0x7fffffff, SImode);
9929 tmp = gen_rtx_AND (SImode, operands[0], tmp);
9933 tmp = gen_int_mode (0x80000000, SImode);
9934 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9940 [(set (match_operand:DF 0 "general_reg_operand")
9941 (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
9942 (use (match_operand 2))
9943 (clobber (reg:CC FLAGS_REG))]
9945 [(parallel [(set (match_dup 0) (match_dup 1))
9946 (clobber (reg:CC FLAGS_REG))])]
9951 tmp = gen_lowpart (DImode, operands[0]);
9952 tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
9955 if (GET_CODE (operands[1]) == ABS)
9958 tmp = gen_rtx_NOT (DImode, tmp);
9962 operands[0] = gen_highpart (SImode, operands[0]);
9963 if (GET_CODE (operands[1]) == ABS)
9965 tmp = gen_int_mode (0x7fffffff, SImode);
9966 tmp = gen_rtx_AND (SImode, operands[0], tmp);
9970 tmp = gen_int_mode (0x80000000, SImode);
9971 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9978 [(set (match_operand:XF 0 "general_reg_operand")
9979 (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
9980 (use (match_operand 2))
9981 (clobber (reg:CC FLAGS_REG))]
9983 [(parallel [(set (match_dup 0) (match_dup 1))
9984 (clobber (reg:CC FLAGS_REG))])]
9987 operands[0] = gen_rtx_REG (SImode,
9988 REGNO (operands[0]) + (TARGET_64BIT ? 1 : 2));
9989 if (GET_CODE (operands[1]) == ABS)
9991 tmp = GEN_INT (0x7fff);
9992 tmp = gen_rtx_AND (SImode, operands[0], tmp);
9996 tmp = GEN_INT (0x8000);
9997 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
10002 ;; Conditionalize these after reload. If they match before reload, we
10003 ;; lose the clobber and ability to use integer instructions.
10005 (define_insn "*<code><mode>2_1"
10006 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
10007 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "0")))]
10009 && (reload_completed
10010 || !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
10011 "f<absneg_mnemonic>"
10012 [(set_attr "type" "fsgn")
10013 (set_attr "mode" "<MODE>")])
10015 (define_insn "*<code>extendsfdf2"
10016 [(set (match_operand:DF 0 "register_operand" "=f")
10017 (absneg:DF (float_extend:DF
10018 (match_operand:SF 1 "register_operand" "0"))))]
10019 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
10020 "f<absneg_mnemonic>"
10021 [(set_attr "type" "fsgn")
10022 (set_attr "mode" "DF")])
10024 (define_insn "*<code>extendsfxf2"
10025 [(set (match_operand:XF 0 "register_operand" "=f")
10026 (absneg:XF (float_extend:XF
10027 (match_operand:SF 1 "register_operand" "0"))))]
10029 "f<absneg_mnemonic>"
10030 [(set_attr "type" "fsgn")
10031 (set_attr "mode" "XF")])
10033 (define_insn "*<code>extenddfxf2"
10034 [(set (match_operand:XF 0 "register_operand" "=f")
10035 (absneg:XF (float_extend:XF
10036 (match_operand:DF 1 "register_operand" "0"))))]
10038 "f<absneg_mnemonic>"
10039 [(set_attr "type" "fsgn")
10040 (set_attr "mode" "XF")])
10042 ;; Copysign instructions
10044 (define_mode_iterator CSGNMODE [SF DF TF])
10045 (define_mode_attr CSGNVMODE [(SF "V4SF") (DF "V2DF") (TF "TF")])
10047 (define_expand "copysign<mode>3"
10048 [(match_operand:CSGNMODE 0 "register_operand")
10049 (match_operand:CSGNMODE 1 "nonmemory_operand")
10050 (match_operand:CSGNMODE 2 "register_operand")]
10051 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10052 || (TARGET_SSE && (<MODE>mode == TFmode))"
10053 "ix86_expand_copysign (operands); DONE;")
10055 (define_insn_and_split "copysign<mode>3_const"
10056 [(set (match_operand:CSGNMODE 0 "register_operand" "=Yv")
10058 [(match_operand:<CSGNVMODE> 1 "vector_move_operand" "YvmC")
10059 (match_operand:CSGNMODE 2 "register_operand" "0")
10060 (match_operand:<CSGNVMODE> 3 "nonimmediate_operand" "Yvm")]
10062 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10063 || (TARGET_SSE && (<MODE>mode == TFmode))"
10065 "&& reload_completed"
10067 "ix86_split_copysign_const (operands); DONE;")
10069 (define_insn "copysign<mode>3_var"
10070 [(set (match_operand:CSGNMODE 0 "register_operand" "=Yv,Yv,Yv,Yv,Yv")
10072 [(match_operand:CSGNMODE 2 "register_operand" "Yv,0,0,Yv,Yv")
10073 (match_operand:CSGNMODE 3 "register_operand" "1,1,Yv,1,Yv")
10074 (match_operand:<CSGNVMODE> 4
10075 "nonimmediate_operand" "X,Yvm,Yvm,0,0")
10076 (match_operand:<CSGNVMODE> 5
10077 "nonimmediate_operand" "0,Yvm,1,Yvm,1")]
10079 (clobber (match_scratch:<CSGNVMODE> 1 "=Yv,Yv,Yv,Yv,Yv"))]
10080 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10081 || (TARGET_SSE && (<MODE>mode == TFmode))"
10085 [(set (match_operand:CSGNMODE 0 "register_operand")
10087 [(match_operand:CSGNMODE 2 "register_operand")
10088 (match_operand:CSGNMODE 3 "register_operand")
10089 (match_operand:<CSGNVMODE> 4)
10090 (match_operand:<CSGNVMODE> 5)]
10092 (clobber (match_scratch:<CSGNVMODE> 1))]
10093 "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10094 || (TARGET_SSE && (<MODE>mode == TFmode)))
10095 && reload_completed"
10097 "ix86_split_copysign_var (operands); DONE;")
10099 ;; One complement instructions
10101 (define_expand "one_cmpl<mode>2"
10102 [(set (match_operand:SWIM1248x 0 "nonimmediate_operand")
10103 (not:SWIM1248x (match_operand:SWIM1248x 1 "nonimmediate_operand")))]
10105 "ix86_expand_unary_operator (NOT, <MODE>mode, operands); DONE;")
10107 (define_insn_and_split "*one_cmpldi2_doubleword"
10108 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10109 (not:DI (match_operand:DI 1 "nonimmediate_operand" "0")))]
10110 "!TARGET_64BIT && TARGET_STV && TARGET_SSE2
10111 && ix86_unary_operator_ok (NOT, DImode, operands)"
10113 "&& reload_completed"
10114 [(set (match_dup 0)
10115 (not:SI (match_dup 1)))
10117 (not:SI (match_dup 3)))]
10118 "split_double_mode (DImode, &operands[0], 2, &operands[0], &operands[2]);")
10120 (define_insn "*one_cmpl<mode>2_1"
10121 [(set (match_operand:SWI248 0 "nonimmediate_operand" "=rm")
10122 (not:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "0")))]
10123 "ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
10124 "not{<imodesuffix>}\t%0"
10125 [(set_attr "type" "negnot")
10126 (set_attr "mode" "<MODE>")])
10128 ;; ??? Currently never generated - xor is used instead.
10129 (define_insn "*one_cmplsi2_1_zext"
10130 [(set (match_operand:DI 0 "register_operand" "=r")
10132 (not:SI (match_operand:SI 1 "register_operand" "0"))))]
10133 "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
10135 [(set_attr "type" "negnot")
10136 (set_attr "mode" "SI")])
10138 (define_insn "*one_cmplqi2_1"
10139 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
10140 (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
10141 "ix86_unary_operator_ok (NOT, QImode, operands)"
10145 [(set_attr "type" "negnot")
10146 (set_attr "mode" "QI,SI")
10147 ;; Potential partial reg stall on alternative 1.
10148 (set (attr "preferred_for_speed")
10149 (cond [(eq_attr "alternative" "1")
10150 (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
10151 (symbol_ref "true")))])
10153 (define_insn "*one_cmpl<mode>2_2"
10154 [(set (reg FLAGS_REG)
10155 (compare (not:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
10157 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
10158 (not:SWI (match_dup 1)))]
10159 "ix86_match_ccmode (insn, CCNOmode)
10160 && ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
10162 [(set_attr "type" "alu1")
10163 (set_attr "mode" "<MODE>")])
10166 [(set (match_operand 0 "flags_reg_operand")
10167 (match_operator 2 "compare_operator"
10168 [(not:SWI (match_operand:SWI 3 "nonimmediate_operand"))
10170 (set (match_operand:SWI 1 "nonimmediate_operand")
10171 (not:SWI (match_dup 3)))]
10172 "ix86_match_ccmode (insn, CCNOmode)"
10173 [(parallel [(set (match_dup 0)
10174 (match_op_dup 2 [(xor:SWI (match_dup 3) (const_int -1))
10177 (xor:SWI (match_dup 3) (const_int -1)))])])
10179 ;; ??? Currently never generated - xor is used instead.
10180 (define_insn "*one_cmplsi2_2_zext"
10181 [(set (reg FLAGS_REG)
10182 (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
10184 (set (match_operand:DI 0 "register_operand" "=r")
10185 (zero_extend:DI (not:SI (match_dup 1))))]
10186 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10187 && ix86_unary_operator_ok (NOT, SImode, operands)"
10189 [(set_attr "type" "alu1")
10190 (set_attr "mode" "SI")])
10193 [(set (match_operand 0 "flags_reg_operand")
10194 (match_operator 2 "compare_operator"
10195 [(not:SI (match_operand:SI 3 "register_operand"))
10197 (set (match_operand:DI 1 "register_operand")
10198 (zero_extend:DI (not:SI (match_dup 3))))]
10199 "ix86_match_ccmode (insn, CCNOmode)"
10200 [(parallel [(set (match_dup 0)
10201 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10204 (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])])
10206 ;; Shift instructions
10208 ;; DImode shifts are implemented using the i386 "shift double" opcode,
10209 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem". If the shift count
10210 ;; is variable, then the count is in %cl and the "imm" operand is dropped
10211 ;; from the assembler input.
10213 ;; This instruction shifts the target reg/mem as usual, but instead of
10214 ;; shifting in zeros, bits are shifted in from reg operand. If the insn
10215 ;; is a left shift double, bits are taken from the high order bits of
10216 ;; reg, else if the insn is a shift right double, bits are taken from the
10217 ;; low order bits of reg. So if %eax is "1234" and %edx is "5678",
10218 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
10220 ;; Since sh[lr]d does not change the `reg' operand, that is done
10221 ;; separately, making all shifts emit pairs of shift double and normal
10222 ;; shift. Since sh[lr]d does not shift more than 31 bits, and we wish to
10223 ;; support a 63 bit shift, each shift where the count is in a reg expands
10224 ;; to a pair of shifts, a branch, a shift by 32 and a label.
10226 ;; If the shift count is a constant, we need never emit more than one
10227 ;; shift pair, instead using moves and sign extension for counts greater
10230 (define_expand "ashl<mode>3"
10231 [(set (match_operand:SDWIM 0 "<shift_operand>")
10232 (ashift:SDWIM (match_operand:SDWIM 1 "<ashl_input_operand>")
10233 (match_operand:QI 2 "nonmemory_operand")))]
10235 "ix86_expand_binary_operator (ASHIFT, <MODE>mode, operands); DONE;")
10237 (define_insn "*ashl<mode>3_doubleword"
10238 [(set (match_operand:DWI 0 "register_operand" "=&r")
10239 (ashift:DWI (match_operand:DWI 1 "reg_or_pm1_operand" "0n")
10240 (match_operand:QI 2 "nonmemory_operand" "<S>c")))
10241 (clobber (reg:CC FLAGS_REG))]
10244 [(set_attr "type" "multi")])
10247 [(set (match_operand:DWI 0 "register_operand")
10248 (ashift:DWI (match_operand:DWI 1 "nonmemory_operand")
10249 (match_operand:QI 2 "nonmemory_operand")))
10250 (clobber (reg:CC FLAGS_REG))]
10251 "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
10253 "ix86_split_ashl (operands, NULL_RTX, <MODE>mode); DONE;")
10255 ;; By default we don't ask for a scratch register, because when DWImode
10256 ;; values are manipulated, registers are already at a premium. But if
10257 ;; we have one handy, we won't turn it away.
10260 [(match_scratch:DWIH 3 "r")
10261 (parallel [(set (match_operand:<DWI> 0 "register_operand")
10263 (match_operand:<DWI> 1 "nonmemory_operand")
10264 (match_operand:QI 2 "nonmemory_operand")))
10265 (clobber (reg:CC FLAGS_REG))])
10269 "ix86_split_ashl (operands, operands[3], <DWI>mode); DONE;")
10271 (define_insn "x86_64_shld"
10272 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
10273 (ior:DI (ashift:DI (match_dup 0)
10274 (match_operand:QI 2 "nonmemory_operand" "Jc"))
10275 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
10276 (minus:QI (const_int 64) (match_dup 2)))))
10277 (clobber (reg:CC FLAGS_REG))]
10279 "shld{q}\t{%s2%1, %0|%0, %1, %2}"
10280 [(set_attr "type" "ishift")
10281 (set_attr "prefix_0f" "1")
10282 (set_attr "mode" "DI")
10283 (set_attr "athlon_decode" "vector")
10284 (set_attr "amdfam10_decode" "vector")
10285 (set_attr "bdver1_decode" "vector")])
10287 (define_insn "x86_shld"
10288 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
10289 (ior:SI (ashift:SI (match_dup 0)
10290 (match_operand:QI 2 "nonmemory_operand" "Ic"))
10291 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
10292 (minus:QI (const_int 32) (match_dup 2)))))
10293 (clobber (reg:CC FLAGS_REG))]
10295 "shld{l}\t{%s2%1, %0|%0, %1, %2}"
10296 [(set_attr "type" "ishift")
10297 (set_attr "prefix_0f" "1")
10298 (set_attr "mode" "SI")
10299 (set_attr "pent_pair" "np")
10300 (set_attr "athlon_decode" "vector")
10301 (set_attr "amdfam10_decode" "vector")
10302 (set_attr "bdver1_decode" "vector")])
10304 (define_expand "x86_shift<mode>_adj_1"
10305 [(set (reg:CCZ FLAGS_REG)
10306 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand")
10309 (set (match_operand:SWI48 0 "register_operand")
10310 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
10311 (match_operand:SWI48 1 "register_operand")
10314 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
10315 (match_operand:SWI48 3 "register_operand")
10318 "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
10320 (define_expand "x86_shift<mode>_adj_2"
10321 [(use (match_operand:SWI48 0 "register_operand"))
10322 (use (match_operand:SWI48 1 "register_operand"))
10323 (use (match_operand:QI 2 "register_operand"))]
10326 rtx_code_label *label = gen_label_rtx ();
10329 emit_insn (gen_testqi_ccz_1 (operands[2],
10330 GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
10332 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
10333 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
10334 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
10335 gen_rtx_LABEL_REF (VOIDmode, label),
10337 tmp = emit_jump_insn (gen_rtx_SET (pc_rtx, tmp));
10338 JUMP_LABEL (tmp) = label;
10340 emit_move_insn (operands[0], operands[1]);
10341 ix86_expand_clear (operands[1]);
10343 emit_label (label);
10344 LABEL_NUSES (label) = 1;
10349 ;; Avoid useless masking of count operand.
10350 (define_insn_and_split "*ashl<mode>3_mask"
10351 [(set (match_operand:SWI48 0 "nonimmediate_operand")
10353 (match_operand:SWI48 1 "nonimmediate_operand")
10356 (match_operand:SI 2 "register_operand" "c,r")
10357 (match_operand:SI 3 "const_int_operand")) 0)))
10358 (clobber (reg:CC FLAGS_REG))]
10359 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)
10360 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10361 == GET_MODE_BITSIZE (<MODE>mode)-1
10362 && can_create_pseudo_p ()"
10366 [(set (match_dup 0)
10367 (ashift:SWI48 (match_dup 1)
10369 (clobber (reg:CC FLAGS_REG))])]
10370 "operands[2] = gen_lowpart (QImode, operands[2]);"
10371 [(set_attr "isa" "*,bmi2")])
10373 (define_insn_and_split "*ashl<mode>3_mask_1"
10374 [(set (match_operand:SWI48 0 "nonimmediate_operand")
10376 (match_operand:SWI48 1 "nonimmediate_operand")
10378 (match_operand:QI 2 "register_operand" "c,r")
10379 (match_operand:QI 3 "const_int_operand"))))
10380 (clobber (reg:CC FLAGS_REG))]
10381 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)
10382 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10383 == GET_MODE_BITSIZE (<MODE>mode)-1
10384 && can_create_pseudo_p ()"
10388 [(set (match_dup 0)
10389 (ashift:SWI48 (match_dup 1)
10391 (clobber (reg:CC FLAGS_REG))])]
10393 [(set_attr "isa" "*,bmi2")])
10395 (define_insn "*bmi2_ashl<mode>3_1"
10396 [(set (match_operand:SWI48 0 "register_operand" "=r")
10397 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
10398 (match_operand:SWI48 2 "register_operand" "r")))]
10400 "shlx\t{%2, %1, %0|%0, %1, %2}"
10401 [(set_attr "type" "ishiftx")
10402 (set_attr "mode" "<MODE>")])
10404 (define_insn "*ashl<mode>3_1"
10405 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r,r")
10406 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,l,rm")
10407 (match_operand:QI 2 "nonmemory_operand" "c<S>,M,r")))
10408 (clobber (reg:CC FLAGS_REG))]
10409 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
10411 switch (get_attr_type (insn))
10418 gcc_assert (operands[2] == const1_rtx);
10419 gcc_assert (rtx_equal_p (operands[0], operands[1]));
10420 return "add{<imodesuffix>}\t%0, %0";
10423 if (operands[2] == const1_rtx
10424 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10425 return "sal{<imodesuffix>}\t%0";
10427 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
10430 [(set_attr "isa" "*,*,bmi2")
10432 (cond [(eq_attr "alternative" "1")
10433 (const_string "lea")
10434 (eq_attr "alternative" "2")
10435 (const_string "ishiftx")
10436 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
10437 (match_operand 0 "register_operand"))
10438 (match_operand 2 "const1_operand"))
10439 (const_string "alu")
10441 (const_string "ishift")))
10442 (set (attr "length_immediate")
10444 (ior (eq_attr "type" "alu")
10445 (and (eq_attr "type" "ishift")
10446 (and (match_operand 2 "const1_operand")
10447 (ior (match_test "TARGET_SHIFT1")
10448 (match_test "optimize_function_for_size_p (cfun)")))))
10450 (const_string "*")))
10451 (set_attr "mode" "<MODE>")])
10453 ;; Convert shift to the shiftx pattern to avoid flags dependency.
10455 [(set (match_operand:SWI48 0 "register_operand")
10456 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
10457 (match_operand:QI 2 "register_operand")))
10458 (clobber (reg:CC FLAGS_REG))]
10459 "TARGET_BMI2 && reload_completed"
10460 [(set (match_dup 0)
10461 (ashift:SWI48 (match_dup 1) (match_dup 2)))]
10462 "operands[2] = gen_lowpart (<MODE>mode, operands[2]);")
10464 (define_insn "*bmi2_ashlsi3_1_zext"
10465 [(set (match_operand:DI 0 "register_operand" "=r")
10467 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
10468 (match_operand:SI 2 "register_operand" "r"))))]
10469 "TARGET_64BIT && TARGET_BMI2"
10470 "shlx\t{%2, %1, %k0|%k0, %1, %2}"
10471 [(set_attr "type" "ishiftx")
10472 (set_attr "mode" "SI")])
10474 (define_insn "*ashlsi3_1_zext"
10475 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
10477 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l,rm")
10478 (match_operand:QI 2 "nonmemory_operand" "cI,M,r"))))
10479 (clobber (reg:CC FLAGS_REG))]
10480 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10482 switch (get_attr_type (insn))
10489 gcc_assert (operands[2] == const1_rtx);
10490 return "add{l}\t%k0, %k0";
10493 if (operands[2] == const1_rtx
10494 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10495 return "sal{l}\t%k0";
10497 return "sal{l}\t{%2, %k0|%k0, %2}";
10500 [(set_attr "isa" "*,*,bmi2")
10502 (cond [(eq_attr "alternative" "1")
10503 (const_string "lea")
10504 (eq_attr "alternative" "2")
10505 (const_string "ishiftx")
10506 (and (match_test "TARGET_DOUBLE_WITH_ADD")
10507 (match_operand 2 "const1_operand"))
10508 (const_string "alu")
10510 (const_string "ishift")))
10511 (set (attr "length_immediate")
10513 (ior (eq_attr "type" "alu")
10514 (and (eq_attr "type" "ishift")
10515 (and (match_operand 2 "const1_operand")
10516 (ior (match_test "TARGET_SHIFT1")
10517 (match_test "optimize_function_for_size_p (cfun)")))))
10519 (const_string "*")))
10520 (set_attr "mode" "SI")])
10522 ;; Convert shift to the shiftx pattern to avoid flags dependency.
10524 [(set (match_operand:DI 0 "register_operand")
10526 (ashift:SI (match_operand:SI 1 "nonimmediate_operand")
10527 (match_operand:QI 2 "register_operand"))))
10528 (clobber (reg:CC FLAGS_REG))]
10529 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
10530 [(set (match_dup 0)
10531 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
10532 "operands[2] = gen_lowpart (SImode, operands[2]);")
10534 (define_insn "*ashlhi3_1"
10535 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,Yp")
10536 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
10537 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10538 (clobber (reg:CC FLAGS_REG))]
10539 "ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10541 switch (get_attr_type (insn))
10547 gcc_assert (operands[2] == const1_rtx);
10548 return "add{w}\t%0, %0";
10551 if (operands[2] == const1_rtx
10552 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10553 return "sal{w}\t%0";
10555 return "sal{w}\t{%2, %0|%0, %2}";
10558 [(set (attr "type")
10559 (cond [(eq_attr "alternative" "1")
10560 (const_string "lea")
10561 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
10562 (match_operand 0 "register_operand"))
10563 (match_operand 2 "const1_operand"))
10564 (const_string "alu")
10566 (const_string "ishift")))
10567 (set (attr "length_immediate")
10569 (ior (eq_attr "type" "alu")
10570 (and (eq_attr "type" "ishift")
10571 (and (match_operand 2 "const1_operand")
10572 (ior (match_test "TARGET_SHIFT1")
10573 (match_test "optimize_function_for_size_p (cfun)")))))
10575 (const_string "*")))
10576 (set_attr "mode" "HI,SI")])
10578 (define_insn "*ashlqi3_1"
10579 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,Yp")
10580 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
10581 (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
10582 (clobber (reg:CC FLAGS_REG))]
10583 "ix86_binary_operator_ok (ASHIFT, QImode, operands)"
10585 switch (get_attr_type (insn))
10591 gcc_assert (operands[2] == const1_rtx);
10592 if (REG_P (operands[1]) && !ANY_QI_REGNO_P (REGNO (operands[1])))
10593 return "add{l}\t%k0, %k0";
10595 return "add{b}\t%0, %0";
10598 if (operands[2] == const1_rtx
10599 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10601 if (get_attr_mode (insn) == MODE_SI)
10602 return "sal{l}\t%k0";
10604 return "sal{b}\t%0";
10608 if (get_attr_mode (insn) == MODE_SI)
10609 return "sal{l}\t{%2, %k0|%k0, %2}";
10611 return "sal{b}\t{%2, %0|%0, %2}";
10615 [(set (attr "type")
10616 (cond [(eq_attr "alternative" "2")
10617 (const_string "lea")
10618 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
10619 (match_operand 0 "register_operand"))
10620 (match_operand 2 "const1_operand"))
10621 (const_string "alu")
10623 (const_string "ishift")))
10624 (set (attr "length_immediate")
10626 (ior (eq_attr "type" "alu")
10627 (and (eq_attr "type" "ishift")
10628 (and (match_operand 2 "const1_operand")
10629 (ior (match_test "TARGET_SHIFT1")
10630 (match_test "optimize_function_for_size_p (cfun)")))))
10632 (const_string "*")))
10633 (set_attr "mode" "QI,SI,SI")
10634 ;; Potential partial reg stall on alternative 1.
10635 (set (attr "preferred_for_speed")
10636 (cond [(eq_attr "alternative" "1")
10637 (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
10638 (symbol_ref "true")))])
10640 (define_insn "*ashlqi3_1_slp"
10641 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10642 (ashift:QI (match_dup 0)
10643 (match_operand:QI 1 "nonmemory_operand" "cI")))
10644 (clobber (reg:CC FLAGS_REG))]
10645 "(optimize_function_for_size_p (cfun)
10646 || !TARGET_PARTIAL_FLAG_REG_STALL
10647 || (operands[1] == const1_rtx
10649 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
10651 switch (get_attr_type (insn))
10654 gcc_assert (operands[1] == const1_rtx);
10655 return "add{b}\t%0, %0";
10658 if (operands[1] == const1_rtx
10659 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10660 return "sal{b}\t%0";
10662 return "sal{b}\t{%1, %0|%0, %1}";
10665 [(set (attr "type")
10666 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
10667 (match_operand 0 "register_operand"))
10668 (match_operand 1 "const1_operand"))
10669 (const_string "alu")
10671 (const_string "ishift1")))
10672 (set (attr "length_immediate")
10674 (ior (eq_attr "type" "alu")
10675 (and (eq_attr "type" "ishift1")
10676 (and (match_operand 1 "const1_operand")
10677 (ior (match_test "TARGET_SHIFT1")
10678 (match_test "optimize_function_for_size_p (cfun)")))))
10680 (const_string "*")))
10681 (set_attr "mode" "QI")])
10683 ;; Convert ashift to the lea pattern to avoid flags dependency.
10685 [(set (match_operand:SWI 0 "register_operand")
10686 (ashift:SWI (match_operand:SWI 1 "index_register_operand")
10687 (match_operand 2 "const_0_to_3_operand")))
10688 (clobber (reg:CC FLAGS_REG))]
10690 && REGNO (operands[0]) != REGNO (operands[1])"
10691 [(set (match_dup 0)
10692 (mult:<LEAMODE> (match_dup 1) (match_dup 2)))]
10694 if (<MODE>mode != <LEAMODE>mode)
10696 operands[0] = gen_lowpart (<LEAMODE>mode, operands[0]);
10697 operands[1] = gen_lowpart (<LEAMODE>mode, operands[1]);
10699 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
10702 ;; Convert ashift to the lea pattern to avoid flags dependency.
10704 [(set (match_operand:DI 0 "register_operand")
10706 (ashift:SI (match_operand:SI 1 "index_register_operand")
10707 (match_operand 2 "const_0_to_3_operand"))))
10708 (clobber (reg:CC FLAGS_REG))]
10709 "TARGET_64BIT && reload_completed
10710 && REGNO (operands[0]) != REGNO (operands[1])"
10711 [(set (match_dup 0)
10712 (zero_extend:DI (mult:SI (match_dup 1) (match_dup 2))))]
10714 operands[1] = gen_lowpart (SImode, operands[1]);
10715 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
10718 ;; This pattern can't accept a variable shift count, since shifts by
10719 ;; zero don't affect the flags. We assume that shifts by constant
10720 ;; zero are optimized away.
10721 (define_insn "*ashl<mode>3_cmp"
10722 [(set (reg FLAGS_REG)
10724 (ashift:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
10725 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
10727 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
10728 (ashift:SWI (match_dup 1) (match_dup 2)))]
10729 "(optimize_function_for_size_p (cfun)
10730 || !TARGET_PARTIAL_FLAG_REG_STALL
10731 || (operands[2] == const1_rtx
10733 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
10734 && ix86_match_ccmode (insn, CCGOCmode)
10735 && ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
10737 switch (get_attr_type (insn))
10740 gcc_assert (operands[2] == const1_rtx);
10741 return "add{<imodesuffix>}\t%0, %0";
10744 if (operands[2] == const1_rtx
10745 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10746 return "sal{<imodesuffix>}\t%0";
10748 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
10751 [(set (attr "type")
10752 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
10753 (match_operand 0 "register_operand"))
10754 (match_operand 2 "const1_operand"))
10755 (const_string "alu")
10757 (const_string "ishift")))
10758 (set (attr "length_immediate")
10760 (ior (eq_attr "type" "alu")
10761 (and (eq_attr "type" "ishift")
10762 (and (match_operand 2 "const1_operand")
10763 (ior (match_test "TARGET_SHIFT1")
10764 (match_test "optimize_function_for_size_p (cfun)")))))
10766 (const_string "*")))
10767 (set_attr "mode" "<MODE>")])
10769 (define_insn "*ashlsi3_cmp_zext"
10770 [(set (reg FLAGS_REG)
10772 (ashift:SI (match_operand:SI 1 "register_operand" "0")
10773 (match_operand:QI 2 "const_1_to_31_operand" "I"))
10775 (set (match_operand:DI 0 "register_operand" "=r")
10776 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
10778 && (optimize_function_for_size_p (cfun)
10779 || !TARGET_PARTIAL_FLAG_REG_STALL
10780 || (operands[2] == const1_rtx
10782 || TARGET_DOUBLE_WITH_ADD)))
10783 && ix86_match_ccmode (insn, CCGOCmode)
10784 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10786 switch (get_attr_type (insn))
10789 gcc_assert (operands[2] == const1_rtx);
10790 return "add{l}\t%k0, %k0";
10793 if (operands[2] == const1_rtx
10794 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10795 return "sal{l}\t%k0";
10797 return "sal{l}\t{%2, %k0|%k0, %2}";
10800 [(set (attr "type")
10801 (cond [(and (match_test "TARGET_DOUBLE_WITH_ADD")
10802 (match_operand 2 "const1_operand"))
10803 (const_string "alu")
10805 (const_string "ishift")))
10806 (set (attr "length_immediate")
10808 (ior (eq_attr "type" "alu")
10809 (and (eq_attr "type" "ishift")
10810 (and (match_operand 2 "const1_operand")
10811 (ior (match_test "TARGET_SHIFT1")
10812 (match_test "optimize_function_for_size_p (cfun)")))))
10814 (const_string "*")))
10815 (set_attr "mode" "SI")])
10817 (define_insn "*ashl<mode>3_cconly"
10818 [(set (reg FLAGS_REG)
10820 (ashift:SWI (match_operand:SWI 1 "register_operand" "0")
10821 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
10823 (clobber (match_scratch:SWI 0 "=<r>"))]
10824 "(optimize_function_for_size_p (cfun)
10825 || !TARGET_PARTIAL_FLAG_REG_STALL
10826 || (operands[2] == const1_rtx
10828 || TARGET_DOUBLE_WITH_ADD)))
10829 && ix86_match_ccmode (insn, CCGOCmode)"
10831 switch (get_attr_type (insn))
10834 gcc_assert (operands[2] == const1_rtx);
10835 return "add{<imodesuffix>}\t%0, %0";
10838 if (operands[2] == const1_rtx
10839 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10840 return "sal{<imodesuffix>}\t%0";
10842 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
10845 [(set (attr "type")
10846 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
10847 (match_operand 0 "register_operand"))
10848 (match_operand 2 "const1_operand"))
10849 (const_string "alu")
10851 (const_string "ishift")))
10852 (set (attr "length_immediate")
10854 (ior (eq_attr "type" "alu")
10855 (and (eq_attr "type" "ishift")
10856 (and (match_operand 2 "const1_operand")
10857 (ior (match_test "TARGET_SHIFT1")
10858 (match_test "optimize_function_for_size_p (cfun)")))))
10860 (const_string "*")))
10861 (set_attr "mode" "<MODE>")])
10863 ;; See comment above `ashl<mode>3' about how this works.
10865 (define_expand "<shift_insn><mode>3"
10866 [(set (match_operand:SDWIM 0 "<shift_operand>")
10867 (any_shiftrt:SDWIM (match_operand:SDWIM 1 "<shift_operand>")
10868 (match_operand:QI 2 "nonmemory_operand")))]
10870 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
10872 ;; Avoid useless masking of count operand.
10873 (define_insn_and_split "*<shift_insn><mode>3_mask"
10874 [(set (match_operand:SWI48 0 "nonimmediate_operand")
10876 (match_operand:SWI48 1 "nonimmediate_operand")
10879 (match_operand:SI 2 "register_operand" "c,r")
10880 (match_operand:SI 3 "const_int_operand")) 0)))
10881 (clobber (reg:CC FLAGS_REG))]
10882 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
10883 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10884 == GET_MODE_BITSIZE (<MODE>mode)-1
10885 && can_create_pseudo_p ()"
10889 [(set (match_dup 0)
10890 (any_shiftrt:SWI48 (match_dup 1)
10892 (clobber (reg:CC FLAGS_REG))])]
10893 "operands[2] = gen_lowpart (QImode, operands[2]);"
10894 [(set_attr "isa" "*,bmi2")])
10896 (define_insn_and_split "*<shift_insn><mode>3_mask_1"
10897 [(set (match_operand:SWI48 0 "nonimmediate_operand")
10899 (match_operand:SWI48 1 "nonimmediate_operand")
10901 (match_operand:QI 2 "register_operand" "c,r")
10902 (match_operand:QI 3 "const_int_operand"))))
10903 (clobber (reg:CC FLAGS_REG))]
10904 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
10905 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10906 == GET_MODE_BITSIZE (<MODE>mode)-1
10907 && can_create_pseudo_p ()"
10911 [(set (match_dup 0)
10912 (any_shiftrt:SWI48 (match_dup 1)
10914 (clobber (reg:CC FLAGS_REG))])]
10916 [(set_attr "isa" "*,bmi2")])
10918 (define_insn_and_split "*<shift_insn><mode>3_doubleword"
10919 [(set (match_operand:DWI 0 "register_operand" "=&r")
10920 (any_shiftrt:DWI (match_operand:DWI 1 "register_operand" "0")
10921 (match_operand:QI 2 "nonmemory_operand" "<S>c")))
10922 (clobber (reg:CC FLAGS_REG))]
10925 "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
10927 "ix86_split_<shift_insn> (operands, NULL_RTX, <MODE>mode); DONE;"
10928 [(set_attr "type" "multi")])
10930 ;; By default we don't ask for a scratch register, because when DWImode
10931 ;; values are manipulated, registers are already at a premium. But if
10932 ;; we have one handy, we won't turn it away.
10935 [(match_scratch:DWIH 3 "r")
10936 (parallel [(set (match_operand:<DWI> 0 "register_operand")
10938 (match_operand:<DWI> 1 "register_operand")
10939 (match_operand:QI 2 "nonmemory_operand")))
10940 (clobber (reg:CC FLAGS_REG))])
10944 "ix86_split_<shift_insn> (operands, operands[3], <DWI>mode); DONE;")
10946 (define_insn "x86_64_shrd"
10947 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
10948 (ior:DI (lshiftrt:DI (match_dup 0)
10949 (match_operand:QI 2 "nonmemory_operand" "Jc"))
10950 (ashift:DI (match_operand:DI 1 "register_operand" "r")
10951 (minus:QI (const_int 64) (match_dup 2)))))
10952 (clobber (reg:CC FLAGS_REG))]
10954 "shrd{q}\t{%s2%1, %0|%0, %1, %2}"
10955 [(set_attr "type" "ishift")
10956 (set_attr "prefix_0f" "1")
10957 (set_attr "mode" "DI")
10958 (set_attr "athlon_decode" "vector")
10959 (set_attr "amdfam10_decode" "vector")
10960 (set_attr "bdver1_decode" "vector")])
10962 (define_insn "x86_shrd"
10963 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
10964 (ior:SI (lshiftrt:SI (match_dup 0)
10965 (match_operand:QI 2 "nonmemory_operand" "Ic"))
10966 (ashift:SI (match_operand:SI 1 "register_operand" "r")
10967 (minus:QI (const_int 32) (match_dup 2)))))
10968 (clobber (reg:CC FLAGS_REG))]
10970 "shrd{l}\t{%s2%1, %0|%0, %1, %2}"
10971 [(set_attr "type" "ishift")
10972 (set_attr "prefix_0f" "1")
10973 (set_attr "mode" "SI")
10974 (set_attr "pent_pair" "np")
10975 (set_attr "athlon_decode" "vector")
10976 (set_attr "amdfam10_decode" "vector")
10977 (set_attr "bdver1_decode" "vector")])
10979 (define_insn "ashrdi3_cvt"
10980 [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
10981 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
10982 (match_operand:QI 2 "const_int_operand")))
10983 (clobber (reg:CC FLAGS_REG))]
10984 "TARGET_64BIT && INTVAL (operands[2]) == 63
10985 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
10986 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
10989 sar{q}\t{%2, %0|%0, %2}"
10990 [(set_attr "type" "imovx,ishift")
10991 (set_attr "prefix_0f" "0,*")
10992 (set_attr "length_immediate" "0,*")
10993 (set_attr "modrm" "0,1")
10994 (set_attr "mode" "DI")])
10996 (define_insn "*ashrsi3_cvt_zext"
10997 [(set (match_operand:DI 0 "register_operand" "=*d,r")
10999 (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
11000 (match_operand:QI 2 "const_int_operand"))))
11001 (clobber (reg:CC FLAGS_REG))]
11002 "TARGET_64BIT && INTVAL (operands[2]) == 31
11003 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
11004 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11007 sar{l}\t{%2, %k0|%k0, %2}"
11008 [(set_attr "type" "imovx,ishift")
11009 (set_attr "prefix_0f" "0,*")
11010 (set_attr "length_immediate" "0,*")
11011 (set_attr "modrm" "0,1")
11012 (set_attr "mode" "SI")])
11014 (define_insn "ashrsi3_cvt"
11015 [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
11016 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
11017 (match_operand:QI 2 "const_int_operand")))
11018 (clobber (reg:CC FLAGS_REG))]
11019 "INTVAL (operands[2]) == 31
11020 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
11021 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11024 sar{l}\t{%2, %0|%0, %2}"
11025 [(set_attr "type" "imovx,ishift")
11026 (set_attr "prefix_0f" "0,*")
11027 (set_attr "length_immediate" "0,*")
11028 (set_attr "modrm" "0,1")
11029 (set_attr "mode" "SI")])
11031 (define_expand "x86_shift<mode>_adj_3"
11032 [(use (match_operand:SWI48 0 "register_operand"))
11033 (use (match_operand:SWI48 1 "register_operand"))
11034 (use (match_operand:QI 2 "register_operand"))]
11037 rtx_code_label *label = gen_label_rtx ();
11040 emit_insn (gen_testqi_ccz_1 (operands[2],
11041 GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
11043 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
11044 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
11045 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
11046 gen_rtx_LABEL_REF (VOIDmode, label),
11048 tmp = emit_jump_insn (gen_rtx_SET (pc_rtx, tmp));
11049 JUMP_LABEL (tmp) = label;
11051 emit_move_insn (operands[0], operands[1]);
11052 emit_insn (gen_ashr<mode>3_cvt (operands[1], operands[1],
11053 GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1)));
11054 emit_label (label);
11055 LABEL_NUSES (label) = 1;
11060 (define_insn "*bmi2_<shift_insn><mode>3_1"
11061 [(set (match_operand:SWI48 0 "register_operand" "=r")
11062 (any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11063 (match_operand:SWI48 2 "register_operand" "r")))]
11065 "<shift>x\t{%2, %1, %0|%0, %1, %2}"
11066 [(set_attr "type" "ishiftx")
11067 (set_attr "mode" "<MODE>")])
11069 (define_insn "*<shift_insn><mode>3_1"
11070 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
11072 (match_operand:SWI48 1 "nonimmediate_operand" "0,rm")
11073 (match_operand:QI 2 "nonmemory_operand" "c<S>,r")))
11074 (clobber (reg:CC FLAGS_REG))]
11075 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
11077 switch (get_attr_type (insn))
11083 if (operands[2] == const1_rtx
11084 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11085 return "<shift>{<imodesuffix>}\t%0";
11087 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
11090 [(set_attr "isa" "*,bmi2")
11091 (set_attr "type" "ishift,ishiftx")
11092 (set (attr "length_immediate")
11094 (and (match_operand 2 "const1_operand")
11095 (ior (match_test "TARGET_SHIFT1")
11096 (match_test "optimize_function_for_size_p (cfun)")))
11098 (const_string "*")))
11099 (set_attr "mode" "<MODE>")])
11101 ;; Convert shift to the shiftx pattern to avoid flags dependency.
11103 [(set (match_operand:SWI48 0 "register_operand")
11104 (any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
11105 (match_operand:QI 2 "register_operand")))
11106 (clobber (reg:CC FLAGS_REG))]
11107 "TARGET_BMI2 && reload_completed"
11108 [(set (match_dup 0)
11109 (any_shiftrt:SWI48 (match_dup 1) (match_dup 2)))]
11110 "operands[2] = gen_lowpart (<MODE>mode, operands[2]);")
11112 (define_insn "*bmi2_<shift_insn>si3_1_zext"
11113 [(set (match_operand:DI 0 "register_operand" "=r")
11115 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
11116 (match_operand:SI 2 "register_operand" "r"))))]
11117 "TARGET_64BIT && TARGET_BMI2"
11118 "<shift>x\t{%2, %1, %k0|%k0, %1, %2}"
11119 [(set_attr "type" "ishiftx")
11120 (set_attr "mode" "SI")])
11122 (define_insn "*<shift_insn>si3_1_zext"
11123 [(set (match_operand:DI 0 "register_operand" "=r,r")
11125 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm")
11126 (match_operand:QI 2 "nonmemory_operand" "cI,r"))))
11127 (clobber (reg:CC FLAGS_REG))]
11128 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
11130 switch (get_attr_type (insn))
11136 if (operands[2] == const1_rtx
11137 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11138 return "<shift>{l}\t%k0";
11140 return "<shift>{l}\t{%2, %k0|%k0, %2}";
11143 [(set_attr "isa" "*,bmi2")
11144 (set_attr "type" "ishift,ishiftx")
11145 (set (attr "length_immediate")
11147 (and (match_operand 2 "const1_operand")
11148 (ior (match_test "TARGET_SHIFT1")
11149 (match_test "optimize_function_for_size_p (cfun)")))
11151 (const_string "*")))
11152 (set_attr "mode" "SI")])
11154 ;; Convert shift to the shiftx pattern to avoid flags dependency.
11156 [(set (match_operand:DI 0 "register_operand")
11158 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand")
11159 (match_operand:QI 2 "register_operand"))))
11160 (clobber (reg:CC FLAGS_REG))]
11161 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
11162 [(set (match_dup 0)
11163 (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
11164 "operands[2] = gen_lowpart (SImode, operands[2]);")
11166 (define_insn "*<shift_insn><mode>3_1"
11167 [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m")
11169 (match_operand:SWI12 1 "nonimmediate_operand" "0")
11170 (match_operand:QI 2 "nonmemory_operand" "c<S>")))
11171 (clobber (reg:CC FLAGS_REG))]
11172 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
11174 if (operands[2] == const1_rtx
11175 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11176 return "<shift>{<imodesuffix>}\t%0";
11178 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
11180 [(set_attr "type" "ishift")
11181 (set (attr "length_immediate")
11183 (and (match_operand 2 "const1_operand")
11184 (ior (match_test "TARGET_SHIFT1")
11185 (match_test "optimize_function_for_size_p (cfun)")))
11187 (const_string "*")))
11188 (set_attr "mode" "<MODE>")])
11190 (define_insn "*<shift_insn>qi3_1_slp"
11191 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
11192 (any_shiftrt:QI (match_dup 0)
11193 (match_operand:QI 1 "nonmemory_operand" "cI")))
11194 (clobber (reg:CC FLAGS_REG))]
11195 "(optimize_function_for_size_p (cfun)
11196 || !TARGET_PARTIAL_REG_STALL
11197 || (operands[1] == const1_rtx
11198 && TARGET_SHIFT1))"
11200 if (operands[1] == const1_rtx
11201 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11202 return "<shift>{b}\t%0";
11204 return "<shift>{b}\t{%1, %0|%0, %1}";
11206 [(set_attr "type" "ishift1")
11207 (set (attr "length_immediate")
11209 (and (match_operand 1 "const1_operand")
11210 (ior (match_test "TARGET_SHIFT1")
11211 (match_test "optimize_function_for_size_p (cfun)")))
11213 (const_string "*")))
11214 (set_attr "mode" "QI")])
11216 ;; This pattern can't accept a variable shift count, since shifts by
11217 ;; zero don't affect the flags. We assume that shifts by constant
11218 ;; zero are optimized away.
11219 (define_insn "*<shift_insn><mode>3_cmp"
11220 [(set (reg FLAGS_REG)
11223 (match_operand:SWI 1 "nonimmediate_operand" "0")
11224 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
11226 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
11227 (any_shiftrt:SWI (match_dup 1) (match_dup 2)))]
11228 "(optimize_function_for_size_p (cfun)
11229 || !TARGET_PARTIAL_FLAG_REG_STALL
11230 || (operands[2] == const1_rtx
11232 && ix86_match_ccmode (insn, CCGOCmode)
11233 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
11235 if (operands[2] == const1_rtx
11236 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11237 return "<shift>{<imodesuffix>}\t%0";
11239 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
11241 [(set_attr "type" "ishift")
11242 (set (attr "length_immediate")
11244 (and (match_operand 2 "const1_operand")
11245 (ior (match_test "TARGET_SHIFT1")
11246 (match_test "optimize_function_for_size_p (cfun)")))
11248 (const_string "*")))
11249 (set_attr "mode" "<MODE>")])
11251 (define_insn "*<shift_insn>si3_cmp_zext"
11252 [(set (reg FLAGS_REG)
11254 (any_shiftrt:SI (match_operand:SI 1 "register_operand" "0")
11255 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11257 (set (match_operand:DI 0 "register_operand" "=r")
11258 (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
11260 && (optimize_function_for_size_p (cfun)
11261 || !TARGET_PARTIAL_FLAG_REG_STALL
11262 || (operands[2] == const1_rtx
11264 && ix86_match_ccmode (insn, CCGOCmode)
11265 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
11267 if (operands[2] == const1_rtx
11268 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11269 return "<shift>{l}\t%k0";
11271 return "<shift>{l}\t{%2, %k0|%k0, %2}";
11273 [(set_attr "type" "ishift")
11274 (set (attr "length_immediate")
11276 (and (match_operand 2 "const1_operand")
11277 (ior (match_test "TARGET_SHIFT1")
11278 (match_test "optimize_function_for_size_p (cfun)")))
11280 (const_string "*")))
11281 (set_attr "mode" "SI")])
11283 (define_insn "*<shift_insn><mode>3_cconly"
11284 [(set (reg FLAGS_REG)
11287 (match_operand:SWI 1 "register_operand" "0")
11288 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
11290 (clobber (match_scratch:SWI 0 "=<r>"))]
11291 "(optimize_function_for_size_p (cfun)
11292 || !TARGET_PARTIAL_FLAG_REG_STALL
11293 || (operands[2] == const1_rtx
11295 && ix86_match_ccmode (insn, CCGOCmode)"
11297 if (operands[2] == const1_rtx
11298 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11299 return "<shift>{<imodesuffix>}\t%0";
11301 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
11303 [(set_attr "type" "ishift")
11304 (set (attr "length_immediate")
11306 (and (match_operand 2 "const1_operand")
11307 (ior (match_test "TARGET_SHIFT1")
11308 (match_test "optimize_function_for_size_p (cfun)")))
11310 (const_string "*")))
11311 (set_attr "mode" "<MODE>")])
11313 ;; Rotate instructions
11315 (define_expand "<rotate_insn>ti3"
11316 [(set (match_operand:TI 0 "register_operand")
11317 (any_rotate:TI (match_operand:TI 1 "register_operand")
11318 (match_operand:QI 2 "nonmemory_operand")))]
11321 if (const_1_to_63_operand (operands[2], VOIDmode))
11322 emit_insn (gen_ix86_<rotate_insn>ti3_doubleword
11323 (operands[0], operands[1], operands[2]));
11330 (define_expand "<rotate_insn>di3"
11331 [(set (match_operand:DI 0 "shiftdi_operand")
11332 (any_rotate:DI (match_operand:DI 1 "shiftdi_operand")
11333 (match_operand:QI 2 "nonmemory_operand")))]
11337 ix86_expand_binary_operator (<CODE>, DImode, operands);
11338 else if (const_1_to_31_operand (operands[2], VOIDmode))
11339 emit_insn (gen_ix86_<rotate_insn>di3_doubleword
11340 (operands[0], operands[1], operands[2]));
11347 (define_expand "<rotate_insn><mode>3"
11348 [(set (match_operand:SWIM124 0 "nonimmediate_operand")
11349 (any_rotate:SWIM124 (match_operand:SWIM124 1 "nonimmediate_operand")
11350 (match_operand:QI 2 "nonmemory_operand")))]
11352 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
11354 ;; Avoid useless masking of count operand.
11355 (define_insn_and_split "*<rotate_insn><mode>3_mask"
11356 [(set (match_operand:SWI48 0 "nonimmediate_operand")
11358 (match_operand:SWI48 1 "nonimmediate_operand")
11361 (match_operand:SI 2 "register_operand" "c")
11362 (match_operand:SI 3 "const_int_operand")) 0)))
11363 (clobber (reg:CC FLAGS_REG))]
11364 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
11365 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
11366 == GET_MODE_BITSIZE (<MODE>mode)-1
11367 && can_create_pseudo_p ()"
11371 [(set (match_dup 0)
11372 (any_rotate:SWI48 (match_dup 1)
11374 (clobber (reg:CC FLAGS_REG))])]
11375 "operands[2] = gen_lowpart (QImode, operands[2]);")
11377 (define_insn_and_split "*<rotate_insn><mode>3_mask_1"
11378 [(set (match_operand:SWI48 0 "nonimmediate_operand")
11380 (match_operand:SWI48 1 "nonimmediate_operand")
11382 (match_operand:QI 2 "register_operand" "c")
11383 (match_operand:QI 3 "const_int_operand"))))
11384 (clobber (reg:CC FLAGS_REG))]
11385 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
11386 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
11387 == GET_MODE_BITSIZE (<MODE>mode)-1
11388 && can_create_pseudo_p ()"
11392 [(set (match_dup 0)
11393 (any_rotate:SWI48 (match_dup 1)
11395 (clobber (reg:CC FLAGS_REG))])])
11397 ;; Implement rotation using two double-precision
11398 ;; shift instructions and a scratch register.
11400 (define_insn_and_split "ix86_rotl<dwi>3_doubleword"
11401 [(set (match_operand:<DWI> 0 "register_operand" "=r")
11402 (rotate:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
11403 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
11404 (clobber (reg:CC FLAGS_REG))
11405 (clobber (match_scratch:DWIH 3 "=&r"))]
11409 [(set (match_dup 3) (match_dup 4))
11411 [(set (match_dup 4)
11412 (ior:DWIH (ashift:DWIH (match_dup 4) (match_dup 2))
11413 (lshiftrt:DWIH (match_dup 5)
11414 (minus:QI (match_dup 6) (match_dup 2)))))
11415 (clobber (reg:CC FLAGS_REG))])
11417 [(set (match_dup 5)
11418 (ior:DWIH (ashift:DWIH (match_dup 5) (match_dup 2))
11419 (lshiftrt:DWIH (match_dup 3)
11420 (minus:QI (match_dup 6) (match_dup 2)))))
11421 (clobber (reg:CC FLAGS_REG))])]
11423 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
11425 split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
11428 (define_insn_and_split "ix86_rotr<dwi>3_doubleword"
11429 [(set (match_operand:<DWI> 0 "register_operand" "=r")
11430 (rotatert:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
11431 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
11432 (clobber (reg:CC FLAGS_REG))
11433 (clobber (match_scratch:DWIH 3 "=&r"))]
11437 [(set (match_dup 3) (match_dup 4))
11439 [(set (match_dup 4)
11440 (ior:DWIH (lshiftrt:DWIH (match_dup 4) (match_dup 2))
11441 (ashift:DWIH (match_dup 5)
11442 (minus:QI (match_dup 6) (match_dup 2)))))
11443 (clobber (reg:CC FLAGS_REG))])
11445 [(set (match_dup 5)
11446 (ior:DWIH (lshiftrt:DWIH (match_dup 5) (match_dup 2))
11447 (ashift:DWIH (match_dup 3)
11448 (minus:QI (match_dup 6) (match_dup 2)))))
11449 (clobber (reg:CC FLAGS_REG))])]
11451 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
11453 split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
11456 (define_mode_attr rorx_immediate_operand
11457 [(SI "const_0_to_31_operand")
11458 (DI "const_0_to_63_operand")])
11460 (define_insn "*bmi2_rorx<mode>3_1"
11461 [(set (match_operand:SWI48 0 "register_operand" "=r")
11463 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11464 (match_operand:QI 2 "<rorx_immediate_operand>" "<S>")))]
11466 "rorx\t{%2, %1, %0|%0, %1, %2}"
11467 [(set_attr "type" "rotatex")
11468 (set_attr "mode" "<MODE>")])
11470 (define_insn "*<rotate_insn><mode>3_1"
11471 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
11473 (match_operand:SWI48 1 "nonimmediate_operand" "0,rm")
11474 (match_operand:QI 2 "nonmemory_operand" "c<S>,<S>")))
11475 (clobber (reg:CC FLAGS_REG))]
11476 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
11478 switch (get_attr_type (insn))
11484 if (operands[2] == const1_rtx
11485 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11486 return "<rotate>{<imodesuffix>}\t%0";
11488 return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
11491 [(set_attr "isa" "*,bmi2")
11492 (set_attr "type" "rotate,rotatex")
11493 (set (attr "length_immediate")
11495 (and (eq_attr "type" "rotate")
11496 (and (match_operand 2 "const1_operand")
11497 (ior (match_test "TARGET_SHIFT1")
11498 (match_test "optimize_function_for_size_p (cfun)"))))
11500 (const_string "*")))
11501 (set_attr "mode" "<MODE>")])
11503 ;; Convert rotate to the rotatex pattern to avoid flags dependency.
11505 [(set (match_operand:SWI48 0 "register_operand")
11506 (rotate:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
11507 (match_operand:QI 2 "const_int_operand")))
11508 (clobber (reg:CC FLAGS_REG))]
11509 "TARGET_BMI2 && reload_completed"
11510 [(set (match_dup 0)
11511 (rotatert:SWI48 (match_dup 1) (match_dup 2)))]
11513 int bitsize = GET_MODE_BITSIZE (<MODE>mode);
11515 operands[2] = GEN_INT ((bitsize - INTVAL (operands[2])) % bitsize);
11519 [(set (match_operand:SWI48 0 "register_operand")
11520 (rotatert:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
11521 (match_operand:QI 2 "const_int_operand")))
11522 (clobber (reg:CC FLAGS_REG))]
11523 "TARGET_BMI2 && reload_completed"
11524 [(set (match_dup 0)
11525 (rotatert:SWI48 (match_dup 1) (match_dup 2)))])
11527 (define_insn "*bmi2_rorxsi3_1_zext"
11528 [(set (match_operand:DI 0 "register_operand" "=r")
11530 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
11531 (match_operand:QI 2 "const_0_to_31_operand" "I"))))]
11532 "TARGET_64BIT && TARGET_BMI2"
11533 "rorx\t{%2, %1, %k0|%k0, %1, %2}"
11534 [(set_attr "type" "rotatex")
11535 (set_attr "mode" "SI")])
11537 (define_insn "*<rotate_insn>si3_1_zext"
11538 [(set (match_operand:DI 0 "register_operand" "=r,r")
11540 (any_rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm")
11541 (match_operand:QI 2 "nonmemory_operand" "cI,I"))))
11542 (clobber (reg:CC FLAGS_REG))]
11543 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
11545 switch (get_attr_type (insn))
11551 if (operands[2] == const1_rtx
11552 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11553 return "<rotate>{l}\t%k0";
11555 return "<rotate>{l}\t{%2, %k0|%k0, %2}";
11558 [(set_attr "isa" "*,bmi2")
11559 (set_attr "type" "rotate,rotatex")
11560 (set (attr "length_immediate")
11562 (and (eq_attr "type" "rotate")
11563 (and (match_operand 2 "const1_operand")
11564 (ior (match_test "TARGET_SHIFT1")
11565 (match_test "optimize_function_for_size_p (cfun)"))))
11567 (const_string "*")))
11568 (set_attr "mode" "SI")])
11570 ;; Convert rotate to the rotatex pattern to avoid flags dependency.
11572 [(set (match_operand:DI 0 "register_operand")
11574 (rotate:SI (match_operand:SI 1 "nonimmediate_operand")
11575 (match_operand:QI 2 "const_int_operand"))))
11576 (clobber (reg:CC FLAGS_REG))]
11577 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
11578 [(set (match_dup 0)
11579 (zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))]
11581 int bitsize = GET_MODE_BITSIZE (SImode);
11583 operands[2] = GEN_INT ((bitsize - INTVAL (operands[2])) % bitsize);
11587 [(set (match_operand:DI 0 "register_operand")
11589 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand")
11590 (match_operand:QI 2 "const_int_operand"))))
11591 (clobber (reg:CC FLAGS_REG))]
11592 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
11593 [(set (match_dup 0)
11594 (zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))])
11596 (define_insn "*<rotate_insn><mode>3_1"
11597 [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m")
11598 (any_rotate:SWI12 (match_operand:SWI12 1 "nonimmediate_operand" "0")
11599 (match_operand:QI 2 "nonmemory_operand" "c<S>")))
11600 (clobber (reg:CC FLAGS_REG))]
11601 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
11603 if (operands[2] == const1_rtx
11604 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11605 return "<rotate>{<imodesuffix>}\t%0";
11607 return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
11609 [(set_attr "type" "rotate")
11610 (set (attr "length_immediate")
11612 (and (match_operand 2 "const1_operand")
11613 (ior (match_test "TARGET_SHIFT1")
11614 (match_test "optimize_function_for_size_p (cfun)")))
11616 (const_string "*")))
11617 (set_attr "mode" "<MODE>")])
11619 (define_insn "*<rotate_insn>qi3_1_slp"
11620 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
11621 (any_rotate:QI (match_dup 0)
11622 (match_operand:QI 1 "nonmemory_operand" "cI")))
11623 (clobber (reg:CC FLAGS_REG))]
11624 "(optimize_function_for_size_p (cfun)
11625 || !TARGET_PARTIAL_REG_STALL
11626 || (operands[1] == const1_rtx
11627 && TARGET_SHIFT1))"
11629 if (operands[1] == const1_rtx
11630 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11631 return "<rotate>{b}\t%0";
11633 return "<rotate>{b}\t{%1, %0|%0, %1}";
11635 [(set_attr "type" "rotate1")
11636 (set (attr "length_immediate")
11638 (and (match_operand 1 "const1_operand")
11639 (ior (match_test "TARGET_SHIFT1")
11640 (match_test "optimize_function_for_size_p (cfun)")))
11642 (const_string "*")))
11643 (set_attr "mode" "QI")])
11646 [(set (match_operand:HI 0 "QIreg_operand")
11647 (any_rotate:HI (match_dup 0) (const_int 8)))
11648 (clobber (reg:CC FLAGS_REG))]
11650 && (TARGET_USE_XCHGB || optimize_function_for_size_p (cfun))"
11651 [(parallel [(set (strict_low_part (match_dup 0))
11652 (bswap:HI (match_dup 0)))
11653 (clobber (reg:CC FLAGS_REG))])])
11655 ;; Bit set / bit test instructions
11657 ;; %%% bts, btr, btc
11659 ;; These instructions are *slow* when applied to memory.
11661 (define_code_attr btsc [(ior "bts") (xor "btc")])
11663 (define_insn "*<btsc><mode>"
11664 [(set (match_operand:SWI48 0 "register_operand" "=r")
11666 (ashift:SWI48 (const_int 1)
11667 (match_operand:QI 2 "register_operand" "r"))
11668 (match_operand:SWI48 1 "register_operand" "0")))
11669 (clobber (reg:CC FLAGS_REG))]
11671 "<btsc>{<imodesuffix>}\t{%<k>2, %0|%0, %<k>2}"
11672 [(set_attr "type" "alu1")
11673 (set_attr "prefix_0f" "1")
11674 (set_attr "znver1_decode" "double")
11675 (set_attr "mode" "<MODE>")])
11677 ;; Avoid useless masking of count operand.
11678 (define_insn_and_split "*<btsc><mode>_mask"
11679 [(set (match_operand:SWI48 0 "register_operand")
11685 (match_operand:SI 1 "register_operand")
11686 (match_operand:SI 2 "const_int_operand")) 0))
11687 (match_operand:SWI48 3 "register_operand")))
11688 (clobber (reg:CC FLAGS_REG))]
11690 && (INTVAL (operands[2]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
11691 == GET_MODE_BITSIZE (<MODE>mode)-1
11692 && can_create_pseudo_p ()"
11696 [(set (match_dup 0)
11698 (ashift:SWI48 (const_int 1)
11701 (clobber (reg:CC FLAGS_REG))])]
11702 "operands[1] = gen_lowpart (QImode, operands[1]);")
11704 (define_insn_and_split "*<btsc><mode>_mask_1"
11705 [(set (match_operand:SWI48 0 "register_operand")
11710 (match_operand:QI 1 "register_operand")
11711 (match_operand:QI 2 "const_int_operand")))
11712 (match_operand:SWI48 3 "register_operand")))
11713 (clobber (reg:CC FLAGS_REG))]
11715 && (INTVAL (operands[2]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
11716 == GET_MODE_BITSIZE (<MODE>mode)-1
11717 && can_create_pseudo_p ()"
11721 [(set (match_dup 0)
11723 (ashift:SWI48 (const_int 1)
11726 (clobber (reg:CC FLAGS_REG))])])
11728 (define_insn "*btr<mode>"
11729 [(set (match_operand:SWI48 0 "register_operand" "=r")
11731 (rotate:SWI48 (const_int -2)
11732 (match_operand:QI 2 "register_operand" "r"))
11733 (match_operand:SWI48 1 "register_operand" "0")))
11734 (clobber (reg:CC FLAGS_REG))]
11736 "btr{<imodesuffix>}\t{%<k>2, %0|%0, %<k>2}"
11737 [(set_attr "type" "alu1")
11738 (set_attr "prefix_0f" "1")
11739 (set_attr "znver1_decode" "double")
11740 (set_attr "mode" "<MODE>")])
11742 ;; Avoid useless masking of count operand.
11743 (define_insn_and_split "*btr<mode>_mask"
11744 [(set (match_operand:SWI48 0 "register_operand")
11750 (match_operand:SI 1 "register_operand")
11751 (match_operand:SI 2 "const_int_operand")) 0))
11752 (match_operand:SWI48 3 "register_operand")))
11753 (clobber (reg:CC FLAGS_REG))]
11755 && (INTVAL (operands[2]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
11756 == GET_MODE_BITSIZE (<MODE>mode)-1
11757 && can_create_pseudo_p ()"
11761 [(set (match_dup 0)
11763 (rotate:SWI48 (const_int -2)
11766 (clobber (reg:CC FLAGS_REG))])]
11767 "operands[1] = gen_lowpart (QImode, operands[1]);")
11769 (define_insn_and_split "*btr<mode>_mask_1"
11770 [(set (match_operand:SWI48 0 "register_operand")
11775 (match_operand:QI 1 "register_operand")
11776 (match_operand:QI 2 "const_int_operand")))
11777 (match_operand:SWI48 3 "register_operand")))
11778 (clobber (reg:CC FLAGS_REG))]
11780 && (INTVAL (operands[2]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
11781 == GET_MODE_BITSIZE (<MODE>mode)-1
11782 && can_create_pseudo_p ()"
11786 [(set (match_dup 0)
11788 (rotate:SWI48 (const_int -2)
11791 (clobber (reg:CC FLAGS_REG))])])
11793 ;; These instructions are never faster than the corresponding
11794 ;; and/ior/xor operations when using immediate operand, so with
11795 ;; 32-bit there's no point. But in 64-bit, we can't hold the
11796 ;; relevant immediates within the instruction itself, so operating
11797 ;; on bits in the high 32-bits of a register becomes easier.
11799 ;; These are slow on Nocona, but fast on Athlon64. We do require the use
11800 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
11801 ;; negdf respectively, so they can never be disabled entirely.
11803 (define_insn "*btsq_imm"
11804 [(set (zero_extract:DI (match_operand:DI 0 "nonimmediate_operand" "+rm")
11806 (match_operand 1 "const_0_to_63_operand" "J"))
11808 (clobber (reg:CC FLAGS_REG))]
11809 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
11810 "bts{q}\t{%1, %0|%0, %1}"
11811 [(set_attr "type" "alu1")
11812 (set_attr "prefix_0f" "1")
11813 (set_attr "znver1_decode" "double")
11814 (set_attr "mode" "DI")])
11816 (define_insn "*btrq_imm"
11817 [(set (zero_extract:DI (match_operand:DI 0 "nonimmediate_operand" "+rm")
11819 (match_operand 1 "const_0_to_63_operand" "J"))
11821 (clobber (reg:CC FLAGS_REG))]
11822 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
11823 "btr{q}\t{%1, %0|%0, %1}"
11824 [(set_attr "type" "alu1")
11825 (set_attr "prefix_0f" "1")
11826 (set_attr "znver1_decode" "double")
11827 (set_attr "mode" "DI")])
11829 (define_insn "*btcq_imm"
11830 [(set (zero_extract:DI (match_operand:DI 0 "nonimmediate_operand" "+rm")
11832 (match_operand 1 "const_0_to_63_operand" "J"))
11833 (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
11834 (clobber (reg:CC FLAGS_REG))]
11835 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
11836 "btc{q}\t{%1, %0|%0, %1}"
11837 [(set_attr "type" "alu1")
11838 (set_attr "prefix_0f" "1")
11839 (set_attr "znver1_decode" "double")
11840 (set_attr "mode" "DI")])
11842 ;; Allow Nocona to avoid these instructions if a register is available.
11845 [(match_scratch:DI 2 "r")
11846 (parallel [(set (zero_extract:DI
11847 (match_operand:DI 0 "nonimmediate_operand")
11849 (match_operand 1 "const_0_to_63_operand"))
11851 (clobber (reg:CC FLAGS_REG))])]
11852 "TARGET_64BIT && !TARGET_USE_BT"
11853 [(parallel [(set (match_dup 0)
11854 (ior:DI (match_dup 0) (match_dup 3)))
11855 (clobber (reg:CC FLAGS_REG))])]
11857 int i = INTVAL (operands[1]);
11859 operands[3] = gen_int_mode (HOST_WIDE_INT_1U << i, DImode);
11861 if (!x86_64_immediate_operand (operands[3], DImode))
11863 emit_move_insn (operands[2], operands[3]);
11864 operands[3] = operands[2];
11869 [(match_scratch:DI 2 "r")
11870 (parallel [(set (zero_extract:DI
11871 (match_operand:DI 0 "nonimmediate_operand")
11873 (match_operand 1 "const_0_to_63_operand"))
11875 (clobber (reg:CC FLAGS_REG))])]
11876 "TARGET_64BIT && !TARGET_USE_BT"
11877 [(parallel [(set (match_dup 0)
11878 (and:DI (match_dup 0) (match_dup 3)))
11879 (clobber (reg:CC FLAGS_REG))])]
11881 int i = INTVAL (operands[1]);
11883 operands[3] = gen_int_mode (~(HOST_WIDE_INT_1U << i), DImode);
11885 if (!x86_64_immediate_operand (operands[3], DImode))
11887 emit_move_insn (operands[2], operands[3]);
11888 operands[3] = operands[2];
11893 [(match_scratch:DI 2 "r")
11894 (parallel [(set (zero_extract:DI
11895 (match_operand:DI 0 "nonimmediate_operand")
11897 (match_operand 1 "const_0_to_63_operand"))
11898 (not:DI (zero_extract:DI
11899 (match_dup 0) (const_int 1) (match_dup 1))))
11900 (clobber (reg:CC FLAGS_REG))])]
11901 "TARGET_64BIT && !TARGET_USE_BT"
11902 [(parallel [(set (match_dup 0)
11903 (xor:DI (match_dup 0) (match_dup 3)))
11904 (clobber (reg:CC FLAGS_REG))])]
11906 int i = INTVAL (operands[1]);
11908 operands[3] = gen_int_mode (HOST_WIDE_INT_1U << i, DImode);
11910 if (!x86_64_immediate_operand (operands[3], DImode))
11912 emit_move_insn (operands[2], operands[3]);
11913 operands[3] = operands[2];
11919 (define_insn "*bt<mode>"
11920 [(set (reg:CCC FLAGS_REG)
11922 (zero_extract:SWI48
11923 (match_operand:SWI48 0 "nonimmediate_operand" "r,m")
11925 (match_operand:SI 1 "nonmemory_operand" "r<S>,<S>"))
11929 switch (get_attr_mode (insn))
11932 return "bt{l}\t{%1, %k0|%k0, %1}";
11935 return "bt{q}\t{%q1, %0|%0, %q1}";
11938 gcc_unreachable ();
11941 [(set_attr "type" "alu1")
11942 (set_attr "prefix_0f" "1")
11945 (and (match_test "CONST_INT_P (operands[1])")
11946 (match_test "INTVAL (operands[1]) < 32"))
11947 (const_string "SI")
11948 (const_string "<MODE>")))])
11950 (define_insn_and_split "*jcc_bt<mode>"
11952 (if_then_else (match_operator 0 "bt_comparison_operator"
11953 [(zero_extract:SWI48
11954 (match_operand:SWI48 1 "nonimmediate_operand")
11956 (match_operand:SI 2 "nonmemory_operand"))
11958 (label_ref (match_operand 3))
11960 (clobber (reg:CC FLAGS_REG))]
11961 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
11962 && (CONST_INT_P (operands[2])
11963 ? (INTVAL (operands[2]) < GET_MODE_BITSIZE (<MODE>mode)
11964 && INTVAL (operands[2])
11965 >= (optimize_function_for_size_p (cfun) ? 8 : 32))
11966 : !memory_operand (operands[1], <MODE>mode))
11967 && can_create_pseudo_p ()"
11970 [(set (reg:CCC FLAGS_REG)
11972 (zero_extract:SWI48
11978 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
11979 (label_ref (match_dup 3))
11982 operands[0] = shallow_copy_rtx (operands[0]);
11983 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
11986 (define_insn_and_split "*jcc_bt<mode>_1"
11988 (if_then_else (match_operator 0 "bt_comparison_operator"
11989 [(zero_extract:SWI48
11990 (match_operand:SWI48 1 "register_operand")
11993 (match_operand:QI 2 "register_operand")))
11995 (label_ref (match_operand 3))
11997 (clobber (reg:CC FLAGS_REG))]
11998 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
11999 && can_create_pseudo_p ()"
12002 [(set (reg:CCC FLAGS_REG)
12004 (zero_extract:SWI48
12010 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
12011 (label_ref (match_dup 3))
12014 operands[2] = lowpart_subreg (SImode, operands[2], QImode);
12015 operands[0] = shallow_copy_rtx (operands[0]);
12016 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
12019 ;; Avoid useless masking of bit offset operand.
12020 (define_insn_and_split "*jcc_bt<mode>_mask"
12022 (if_then_else (match_operator 0 "bt_comparison_operator"
12023 [(zero_extract:SWI48
12024 (match_operand:SWI48 1 "register_operand")
12027 (match_operand:SI 2 "register_operand")
12028 (match_operand 3 "const_int_operand")))])
12029 (label_ref (match_operand 4))
12031 (clobber (reg:CC FLAGS_REG))]
12032 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
12033 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
12034 == GET_MODE_BITSIZE (<MODE>mode)-1
12035 && can_create_pseudo_p ()"
12038 [(set (reg:CCC FLAGS_REG)
12040 (zero_extract:SWI48
12046 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
12047 (label_ref (match_dup 4))
12050 operands[0] = shallow_copy_rtx (operands[0]);
12051 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
12054 ;; Store-flag instructions.
12056 ;; For all sCOND expanders, also expand the compare or test insn that
12057 ;; generates cc0. Generate an equality comparison if `seq' or `sne'.
12059 (define_insn_and_split "*setcc_di_1"
12060 [(set (match_operand:DI 0 "register_operand" "=q")
12061 (match_operator:DI 1 "ix86_comparison_operator"
12062 [(reg FLAGS_REG) (const_int 0)]))]
12063 "TARGET_64BIT && !TARGET_PARTIAL_REG_STALL"
12065 "&& reload_completed"
12066 [(set (match_dup 2) (match_dup 1))
12067 (set (match_dup 0) (zero_extend:DI (match_dup 2)))]
12069 operands[1] = shallow_copy_rtx (operands[1]);
12070 PUT_MODE (operands[1], QImode);
12071 operands[2] = gen_lowpart (QImode, operands[0]);
12074 (define_insn_and_split "*setcc_si_1_and"
12075 [(set (match_operand:SI 0 "register_operand" "=q")
12076 (match_operator:SI 1 "ix86_comparison_operator"
12077 [(reg FLAGS_REG) (const_int 0)]))
12078 (clobber (reg:CC FLAGS_REG))]
12079 "!TARGET_PARTIAL_REG_STALL
12080 && TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
12082 "&& reload_completed"
12083 [(set (match_dup 2) (match_dup 1))
12084 (parallel [(set (match_dup 0) (zero_extend:SI (match_dup 2)))
12085 (clobber (reg:CC FLAGS_REG))])]
12087 operands[1] = shallow_copy_rtx (operands[1]);
12088 PUT_MODE (operands[1], QImode);
12089 operands[2] = gen_lowpart (QImode, operands[0]);
12092 (define_insn_and_split "*setcc_si_1_movzbl"
12093 [(set (match_operand:SI 0 "register_operand" "=q")
12094 (match_operator:SI 1 "ix86_comparison_operator"
12095 [(reg FLAGS_REG) (const_int 0)]))]
12096 "!TARGET_PARTIAL_REG_STALL
12097 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
12099 "&& reload_completed"
12100 [(set (match_dup 2) (match_dup 1))
12101 (set (match_dup 0) (zero_extend:SI (match_dup 2)))]
12103 operands[1] = shallow_copy_rtx (operands[1]);
12104 PUT_MODE (operands[1], QImode);
12105 operands[2] = gen_lowpart (QImode, operands[0]);
12108 (define_insn "*setcc_qi"
12109 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12110 (match_operator:QI 1 "ix86_comparison_operator"
12111 [(reg FLAGS_REG) (const_int 0)]))]
12114 [(set_attr "type" "setcc")
12115 (set_attr "mode" "QI")])
12117 (define_insn "*setcc_qi_slp"
12118 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12119 (match_operator:QI 1 "ix86_comparison_operator"
12120 [(reg FLAGS_REG) (const_int 0)]))]
12123 [(set_attr "type" "setcc")
12124 (set_attr "mode" "QI")])
12126 ;; In general it is not safe to assume too much about CCmode registers,
12127 ;; so simplify-rtx stops when it sees a second one. Under certain
12128 ;; conditions this is safe on x86, so help combine not create
12135 [(set (match_operand:QI 0 "nonimmediate_operand")
12136 (ne:QI (match_operator 1 "ix86_comparison_operator"
12137 [(reg FLAGS_REG) (const_int 0)])
12140 [(set (match_dup 0) (match_dup 1))]
12142 operands[1] = shallow_copy_rtx (operands[1]);
12143 PUT_MODE (operands[1], QImode);
12147 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand"))
12148 (ne:QI (match_operator 1 "ix86_comparison_operator"
12149 [(reg FLAGS_REG) (const_int 0)])
12152 [(set (match_dup 0) (match_dup 1))]
12154 operands[1] = shallow_copy_rtx (operands[1]);
12155 PUT_MODE (operands[1], QImode);
12159 [(set (match_operand:QI 0 "nonimmediate_operand")
12160 (eq:QI (match_operator 1 "ix86_comparison_operator"
12161 [(reg FLAGS_REG) (const_int 0)])
12164 [(set (match_dup 0) (match_dup 1))]
12166 operands[1] = shallow_copy_rtx (operands[1]);
12167 PUT_MODE (operands[1], QImode);
12168 PUT_CODE (operands[1],
12169 ix86_reverse_condition (GET_CODE (operands[1]),
12170 GET_MODE (XEXP (operands[1], 0))));
12172 /* Make sure that (a) the CCmode we have for the flags is strong
12173 enough for the reversed compare or (b) we have a valid FP compare. */
12174 if (! ix86_comparison_operator (operands[1], VOIDmode))
12179 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand"))
12180 (eq:QI (match_operator 1 "ix86_comparison_operator"
12181 [(reg FLAGS_REG) (const_int 0)])
12184 [(set (match_dup 0) (match_dup 1))]
12186 operands[1] = shallow_copy_rtx (operands[1]);
12187 PUT_MODE (operands[1], QImode);
12188 PUT_CODE (operands[1],
12189 ix86_reverse_condition (GET_CODE (operands[1]),
12190 GET_MODE (XEXP (operands[1], 0))));
12192 /* Make sure that (a) the CCmode we have for the flags is strong
12193 enough for the reversed compare or (b) we have a valid FP compare. */
12194 if (! ix86_comparison_operator (operands[1], VOIDmode))
12198 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
12199 ;; subsequent logical operations are used to imitate conditional moves.
12200 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
12203 (define_insn "setcc_<mode>_sse"
12204 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
12205 (match_operator:MODEF 3 "sse_comparison_operator"
12206 [(match_operand:MODEF 1 "register_operand" "0,x")
12207 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
12208 "SSE_FLOAT_MODE_P (<MODE>mode)"
12210 cmp%D3<ssemodesuffix>\t{%2, %0|%0, %2}
12211 vcmp%D3<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
12212 [(set_attr "isa" "noavx,avx")
12213 (set_attr "type" "ssecmp")
12214 (set_attr "length_immediate" "1")
12215 (set_attr "prefix" "orig,vex")
12216 (set_attr "mode" "<MODE>")])
12218 ;; Basic conditional jump instructions.
12219 ;; We ignore the overflow flag for signed branch instructions.
12221 (define_insn "*jcc"
12223 (if_then_else (match_operator 1 "ix86_comparison_operator"
12224 [(reg FLAGS_REG) (const_int 0)])
12225 (label_ref (match_operand 0))
12229 [(set_attr "type" "ibr")
12230 (set_attr "modrm" "0")
12231 (set (attr "length")
12233 (and (ge (minus (match_dup 0) (pc))
12235 (lt (minus (match_dup 0) (pc))
12239 (set_attr "maybe_prefix_bnd" "1")])
12241 ;; In general it is not safe to assume too much about CCmode registers,
12242 ;; so simplify-rtx stops when it sees a second one. Under certain
12243 ;; conditions this is safe on x86, so help combine not create
12251 (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
12252 [(reg FLAGS_REG) (const_int 0)])
12254 (label_ref (match_operand 1))
12258 (if_then_else (match_dup 0)
12259 (label_ref (match_dup 1))
12262 operands[0] = shallow_copy_rtx (operands[0]);
12263 PUT_MODE (operands[0], VOIDmode);
12268 (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
12269 [(reg FLAGS_REG) (const_int 0)])
12271 (label_ref (match_operand 1))
12275 (if_then_else (match_dup 0)
12276 (label_ref (match_dup 1))
12279 operands[0] = shallow_copy_rtx (operands[0]);
12280 PUT_MODE (operands[0], VOIDmode);
12281 PUT_CODE (operands[0],
12282 ix86_reverse_condition (GET_CODE (operands[0]),
12283 GET_MODE (XEXP (operands[0], 0))));
12285 /* Make sure that (a) the CCmode we have for the flags is strong
12286 enough for the reversed compare or (b) we have a valid FP compare. */
12287 if (! ix86_comparison_operator (operands[0], VOIDmode))
12291 ;; Unconditional and other jump instructions
12293 (define_insn "jump"
12295 (label_ref (match_operand 0)))]
12298 [(set_attr "type" "ibr")
12299 (set_attr "modrm" "0")
12300 (set (attr "length")
12302 (and (ge (minus (match_dup 0) (pc))
12304 (lt (minus (match_dup 0) (pc))
12308 (set_attr "maybe_prefix_bnd" "1")])
12310 (define_expand "indirect_jump"
12311 [(set (pc) (match_operand 0 "indirect_branch_operand"))]
12314 if (TARGET_X32 || TARGET_INDIRECT_BRANCH_REGISTER)
12315 operands[0] = convert_memory_address (word_mode, operands[0]);
12316 cfun->machine->has_local_indirect_jump = true;
12319 (define_insn "*indirect_jump"
12320 [(set (pc) (match_operand:W 0 "indirect_branch_operand" "rBw"))]
12322 "* return ix86_output_indirect_jmp (operands[0]);"
12323 [(set (attr "type")
12324 (if_then_else (match_test "(cfun->machine->indirect_branch_type
12325 != indirect_branch_keep)")
12326 (const_string "multi")
12327 (const_string "ibr")))
12328 (set_attr "length_immediate" "0")
12329 (set_attr "maybe_prefix_bnd" "1")])
12331 (define_expand "tablejump"
12332 [(parallel [(set (pc) (match_operand 0 "indirect_branch_operand"))
12333 (use (label_ref (match_operand 1)))])]
12336 /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
12337 relative. Convert the relative address to an absolute address. */
12341 enum rtx_code code;
12343 /* We can't use @GOTOFF for text labels on VxWorks;
12344 see gotoff_operand. */
12345 if (TARGET_64BIT || TARGET_VXWORKS_RTP)
12349 op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
12351 else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
12355 op1 = pic_offset_table_rtx;
12360 op0 = pic_offset_table_rtx;
12364 operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
12368 if (TARGET_X32 || TARGET_INDIRECT_BRANCH_REGISTER)
12369 operands[0] = convert_memory_address (word_mode, operands[0]);
12370 cfun->machine->has_local_indirect_jump = true;
12373 (define_insn "*tablejump_1"
12374 [(set (pc) (match_operand:W 0 "indirect_branch_operand" "rBw"))
12375 (use (label_ref (match_operand 1)))]
12377 "* return ix86_output_indirect_jmp (operands[0]);"
12378 [(set (attr "type")
12379 (if_then_else (match_test "(cfun->machine->indirect_branch_type
12380 != indirect_branch_keep)")
12381 (const_string "multi")
12382 (const_string "ibr")))
12383 (set_attr "length_immediate" "0")
12384 (set_attr "maybe_prefix_bnd" "1")])
12386 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
12389 [(set (reg FLAGS_REG) (match_operand 0))
12390 (set (match_operand:QI 1 "register_operand")
12391 (match_operator:QI 2 "ix86_comparison_operator"
12392 [(reg FLAGS_REG) (const_int 0)]))
12393 (set (match_operand 3 "any_QIreg_operand")
12394 (zero_extend (match_dup 1)))]
12395 "(peep2_reg_dead_p (3, operands[1])
12396 || operands_match_p (operands[1], operands[3]))
12397 && ! reg_overlap_mentioned_p (operands[3], operands[0])
12398 && peep2_regno_dead_p (0, FLAGS_REG)"
12399 [(set (match_dup 4) (match_dup 0))
12400 (set (strict_low_part (match_dup 5))
12403 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
12404 operands[5] = gen_lowpart (QImode, operands[3]);
12405 ix86_expand_clear (operands[3]);
12409 [(parallel [(set (reg FLAGS_REG) (match_operand 0))
12410 (match_operand 4)])
12411 (set (match_operand:QI 1 "register_operand")
12412 (match_operator:QI 2 "ix86_comparison_operator"
12413 [(reg FLAGS_REG) (const_int 0)]))
12414 (set (match_operand 3 "any_QIreg_operand")
12415 (zero_extend (match_dup 1)))]
12416 "(peep2_reg_dead_p (3, operands[1])
12417 || operands_match_p (operands[1], operands[3]))
12418 && ! reg_overlap_mentioned_p (operands[3], operands[0])
12419 && ! reg_set_p (operands[3], operands[4])
12420 && peep2_regno_dead_p (0, FLAGS_REG)"
12421 [(parallel [(set (match_dup 5) (match_dup 0))
12423 (set (strict_low_part (match_dup 6))
12426 operands[5] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
12427 operands[6] = gen_lowpart (QImode, operands[3]);
12428 ix86_expand_clear (operands[3]);
12432 [(set (reg FLAGS_REG) (match_operand 0))
12433 (parallel [(set (reg FLAGS_REG) (match_operand 1))
12434 (match_operand 5)])
12435 (set (match_operand:QI 2 "register_operand")
12436 (match_operator:QI 3 "ix86_comparison_operator"
12437 [(reg FLAGS_REG) (const_int 0)]))
12438 (set (match_operand 4 "any_QIreg_operand")
12439 (zero_extend (match_dup 2)))]
12440 "(peep2_reg_dead_p (4, operands[2])
12441 || operands_match_p (operands[2], operands[4]))
12442 && ! reg_overlap_mentioned_p (operands[4], operands[0])
12443 && ! reg_overlap_mentioned_p (operands[4], operands[1])
12444 && ! reg_set_p (operands[4], operands[5])
12445 && refers_to_regno_p (FLAGS_REG, operands[1], (rtx *)NULL)
12446 && peep2_regno_dead_p (0, FLAGS_REG)"
12447 [(set (match_dup 6) (match_dup 0))
12448 (parallel [(set (match_dup 7) (match_dup 1))
12450 (set (strict_low_part (match_dup 8))
12453 operands[6] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
12454 operands[7] = gen_rtx_REG (GET_MODE (operands[1]), FLAGS_REG);
12455 operands[8] = gen_lowpart (QImode, operands[4]);
12456 ix86_expand_clear (operands[4]);
12459 ;; Similar, but match zero extend with andsi3.
12462 [(set (reg FLAGS_REG) (match_operand 0))
12463 (set (match_operand:QI 1 "register_operand")
12464 (match_operator:QI 2 "ix86_comparison_operator"
12465 [(reg FLAGS_REG) (const_int 0)]))
12466 (parallel [(set (match_operand:SI 3 "any_QIreg_operand")
12467 (and:SI (match_dup 3) (const_int 255)))
12468 (clobber (reg:CC FLAGS_REG))])]
12469 "REGNO (operands[1]) == REGNO (operands[3])
12470 && ! reg_overlap_mentioned_p (operands[3], operands[0])
12471 && peep2_regno_dead_p (0, FLAGS_REG)"
12472 [(set (match_dup 4) (match_dup 0))
12473 (set (strict_low_part (match_dup 5))
12476 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
12477 operands[5] = gen_lowpart (QImode, operands[3]);
12478 ix86_expand_clear (operands[3]);
12482 [(parallel [(set (reg FLAGS_REG) (match_operand 0))
12483 (match_operand 4)])
12484 (set (match_operand:QI 1 "register_operand")
12485 (match_operator:QI 2 "ix86_comparison_operator"
12486 [(reg FLAGS_REG) (const_int 0)]))
12487 (parallel [(set (match_operand 3 "any_QIreg_operand")
12488 (zero_extend (match_dup 1)))
12489 (clobber (reg:CC FLAGS_REG))])]
12490 "(peep2_reg_dead_p (3, operands[1])
12491 || operands_match_p (operands[1], operands[3]))
12492 && ! reg_overlap_mentioned_p (operands[3], operands[0])
12493 && ! reg_set_p (operands[3], operands[4])
12494 && peep2_regno_dead_p (0, FLAGS_REG)"
12495 [(parallel [(set (match_dup 5) (match_dup 0))
12497 (set (strict_low_part (match_dup 6))
12500 operands[5] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
12501 operands[6] = gen_lowpart (QImode, operands[3]);
12502 ix86_expand_clear (operands[3]);
12506 [(set (reg FLAGS_REG) (match_operand 0))
12507 (parallel [(set (reg FLAGS_REG) (match_operand 1))
12508 (match_operand 5)])
12509 (set (match_operand:QI 2 "register_operand")
12510 (match_operator:QI 3 "ix86_comparison_operator"
12511 [(reg FLAGS_REG) (const_int 0)]))
12512 (parallel [(set (match_operand 4 "any_QIreg_operand")
12513 (zero_extend (match_dup 2)))
12514 (clobber (reg:CC FLAGS_REG))])]
12515 "(peep2_reg_dead_p (4, operands[2])
12516 || operands_match_p (operands[2], operands[4]))
12517 && ! reg_overlap_mentioned_p (operands[4], operands[0])
12518 && ! reg_overlap_mentioned_p (operands[4], operands[1])
12519 && ! reg_set_p (operands[4], operands[5])
12520 && refers_to_regno_p (FLAGS_REG, operands[1], (rtx *)NULL)
12521 && peep2_regno_dead_p (0, FLAGS_REG)"
12522 [(set (match_dup 6) (match_dup 0))
12523 (parallel [(set (match_dup 7) (match_dup 1))
12525 (set (strict_low_part (match_dup 8))
12528 operands[6] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
12529 operands[7] = gen_rtx_REG (GET_MODE (operands[1]), FLAGS_REG);
12530 operands[8] = gen_lowpart (QImode, operands[4]);
12531 ix86_expand_clear (operands[4]);
12534 ;; Call instructions.
12536 ;; The predicates normally associated with named expanders are not properly
12537 ;; checked for calls. This is a bug in the generic code, but it isn't that
12538 ;; easy to fix. Ignore it for now and be prepared to fix things up.
12540 ;; P6 processors will jump to the address after the decrement when %esp
12541 ;; is used as a call operand, so they will execute return address as a code.
12542 ;; See Pentium Pro errata 70, Pentium 2 errata A33 and Pentium 3 errata E17.
12544 ;; Register constraint for call instruction.
12545 (define_mode_attr c [(SI "l") (DI "r")])
12547 ;; Call subroutine returning no value.
12549 (define_expand "call"
12550 [(call (match_operand:QI 0)
12552 (use (match_operand 2))]
12555 ix86_expand_call (NULL, operands[0], operands[1],
12556 operands[2], NULL, false);
12560 (define_expand "sibcall"
12561 [(call (match_operand:QI 0)
12563 (use (match_operand 2))]
12566 ix86_expand_call (NULL, operands[0], operands[1],
12567 operands[2], NULL, true);
12571 (define_insn "*call"
12572 [(call (mem:QI (match_operand:W 0 "call_insn_operand" "<c>BwBz"))
12573 (match_operand 1))]
12574 "!SIBLING_CALL_P (insn)"
12575 "* return ix86_output_call_insn (insn, operands[0]);"
12576 [(set_attr "type" "call")])
12578 ;; This covers both call and sibcall since only GOT slot is allowed.
12579 (define_insn "*call_got_x32"
12580 [(call (mem:QI (zero_extend:DI
12581 (match_operand:SI 0 "GOT_memory_operand" "Bg")))
12582 (match_operand 1))]
12585 rtx fnaddr = gen_const_mem (DImode, XEXP (operands[0], 0));
12586 return ix86_output_call_insn (insn, fnaddr);
12588 [(set_attr "type" "call")])
12590 ;; Since sibcall never returns, we can only use call-clobbered register
12592 (define_insn "*sibcall_GOT_32"
12595 (match_operand:SI 0 "register_no_elim_operand" "U")
12596 (match_operand:SI 1 "GOT32_symbol_operand"))))
12597 (match_operand 2))]
12600 && !TARGET_INDIRECT_BRANCH_REGISTER
12601 && SIBLING_CALL_P (insn)"
12603 rtx fnaddr = gen_rtx_PLUS (SImode, operands[0], operands[1]);
12604 fnaddr = gen_const_mem (SImode, fnaddr);
12605 return ix86_output_call_insn (insn, fnaddr);
12607 [(set_attr "type" "call")])
12609 (define_insn "*sibcall"
12610 [(call (mem:QI (match_operand:W 0 "sibcall_insn_operand" "UBsBz"))
12611 (match_operand 1))]
12612 "SIBLING_CALL_P (insn)"
12613 "* return ix86_output_call_insn (insn, operands[0]);"
12614 [(set_attr "type" "call")])
12616 (define_insn "*sibcall_memory"
12617 [(call (mem:QI (match_operand:W 0 "memory_operand" "m"))
12619 (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
12620 "!TARGET_X32 && !TARGET_INDIRECT_BRANCH_REGISTER"
12621 "* return ix86_output_call_insn (insn, operands[0]);"
12622 [(set_attr "type" "call")])
12625 [(set (match_operand:W 0 "register_operand")
12626 (match_operand:W 1 "memory_operand"))
12627 (call (mem:QI (match_dup 0))
12628 (match_operand 3))]
12630 && !TARGET_INDIRECT_BRANCH_REGISTER
12631 && SIBLING_CALL_P (peep2_next_insn (1))
12632 && !reg_mentioned_p (operands[0],
12633 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (1)))"
12634 [(parallel [(call (mem:QI (match_dup 1))
12636 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
12639 [(set (match_operand:W 0 "register_operand")
12640 (match_operand:W 1 "memory_operand"))
12641 (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
12642 (call (mem:QI (match_dup 0))
12643 (match_operand 3))]
12645 && !TARGET_INDIRECT_BRANCH_REGISTER
12646 && SIBLING_CALL_P (peep2_next_insn (2))
12647 && !reg_mentioned_p (operands[0],
12648 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (2)))"
12649 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
12650 (parallel [(call (mem:QI (match_dup 1))
12652 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
12654 (define_expand "call_pop"
12655 [(parallel [(call (match_operand:QI 0)
12656 (match_operand:SI 1))
12657 (set (reg:SI SP_REG)
12658 (plus:SI (reg:SI SP_REG)
12659 (match_operand:SI 3)))])]
12662 ix86_expand_call (NULL, operands[0], operands[1],
12663 operands[2], operands[3], false);
12667 (define_insn "*call_pop"
12668 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lBwBz"))
12670 (set (reg:SI SP_REG)
12671 (plus:SI (reg:SI SP_REG)
12672 (match_operand:SI 2 "immediate_operand" "i")))]
12673 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
12674 "* return ix86_output_call_insn (insn, operands[0]);"
12675 [(set_attr "type" "call")])
12677 (define_insn "*sibcall_pop"
12678 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "UBsBz"))
12680 (set (reg:SI SP_REG)
12681 (plus:SI (reg:SI SP_REG)
12682 (match_operand:SI 2 "immediate_operand" "i")))]
12683 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
12684 "* return ix86_output_call_insn (insn, operands[0]);"
12685 [(set_attr "type" "call")])
12687 (define_insn "*sibcall_pop_memory"
12688 [(call (mem:QI (match_operand:SI 0 "memory_operand" "Bs"))
12690 (set (reg:SI SP_REG)
12691 (plus:SI (reg:SI SP_REG)
12692 (match_operand:SI 2 "immediate_operand" "i")))
12693 (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
12695 "* return ix86_output_call_insn (insn, operands[0]);"
12696 [(set_attr "type" "call")])
12699 [(set (match_operand:SI 0 "register_operand")
12700 (match_operand:SI 1 "memory_operand"))
12701 (parallel [(call (mem:QI (match_dup 0))
12703 (set (reg:SI SP_REG)
12704 (plus:SI (reg:SI SP_REG)
12705 (match_operand:SI 4 "immediate_operand")))])]
12706 "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (1))
12707 && !reg_mentioned_p (operands[0],
12708 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (1)))"
12709 [(parallel [(call (mem:QI (match_dup 1))
12711 (set (reg:SI SP_REG)
12712 (plus:SI (reg:SI SP_REG)
12714 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
12717 [(set (match_operand:SI 0 "register_operand")
12718 (match_operand:SI 1 "memory_operand"))
12719 (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
12720 (parallel [(call (mem:QI (match_dup 0))
12722 (set (reg:SI SP_REG)
12723 (plus:SI (reg:SI SP_REG)
12724 (match_operand:SI 4 "immediate_operand")))])]
12725 "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (2))
12726 && !reg_mentioned_p (operands[0],
12727 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (2)))"
12728 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
12729 (parallel [(call (mem:QI (match_dup 1))
12731 (set (reg:SI SP_REG)
12732 (plus:SI (reg:SI SP_REG)
12734 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
12736 ;; Combining simple memory jump instruction
12739 [(set (match_operand:W 0 "register_operand")
12740 (match_operand:W 1 "memory_operand"))
12741 (set (pc) (match_dup 0))]
12743 && !TARGET_INDIRECT_BRANCH_REGISTER
12744 && peep2_reg_dead_p (2, operands[0])"
12745 [(set (pc) (match_dup 1))])
12747 ;; Call subroutine, returning value in operand 0
12749 (define_expand "call_value"
12750 [(set (match_operand 0)
12751 (call (match_operand:QI 1)
12752 (match_operand 2)))
12753 (use (match_operand 3))]
12756 ix86_expand_call (operands[0], operands[1], operands[2],
12757 operands[3], NULL, false);
12761 (define_expand "sibcall_value"
12762 [(set (match_operand 0)
12763 (call (match_operand:QI 1)
12764 (match_operand 2)))
12765 (use (match_operand 3))]
12768 ix86_expand_call (operands[0], operands[1], operands[2],
12769 operands[3], NULL, true);
12773 (define_insn "*call_value"
12774 [(set (match_operand 0)
12775 (call (mem:QI (match_operand:W 1 "call_insn_operand" "<c>BwBz"))
12776 (match_operand 2)))]
12777 "!SIBLING_CALL_P (insn)"
12778 "* return ix86_output_call_insn (insn, operands[1]);"
12779 [(set_attr "type" "callv")])
12781 ;; This covers both call and sibcall since only GOT slot is allowed.
12782 (define_insn "*call_value_got_x32"
12783 [(set (match_operand 0)
12786 (match_operand:SI 1 "GOT_memory_operand" "Bg")))
12787 (match_operand 2)))]
12790 rtx fnaddr = gen_const_mem (DImode, XEXP (operands[1], 0));
12791 return ix86_output_call_insn (insn, fnaddr);
12793 [(set_attr "type" "callv")])
12795 ;; Since sibcall never returns, we can only use call-clobbered register
12797 (define_insn "*sibcall_value_GOT_32"
12798 [(set (match_operand 0)
12801 (match_operand:SI 1 "register_no_elim_operand" "U")
12802 (match_operand:SI 2 "GOT32_symbol_operand"))))
12803 (match_operand 3)))]
12806 && !TARGET_INDIRECT_BRANCH_REGISTER
12807 && SIBLING_CALL_P (insn)"
12809 rtx fnaddr = gen_rtx_PLUS (SImode, operands[1], operands[2]);
12810 fnaddr = gen_const_mem (SImode, fnaddr);
12811 return ix86_output_call_insn (insn, fnaddr);
12813 [(set_attr "type" "callv")])
12815 (define_insn "*sibcall_value"
12816 [(set (match_operand 0)
12817 (call (mem:QI (match_operand:W 1 "sibcall_insn_operand" "UBsBz"))
12818 (match_operand 2)))]
12819 "SIBLING_CALL_P (insn)"
12820 "* return ix86_output_call_insn (insn, operands[1]);"
12821 [(set_attr "type" "callv")])
12823 (define_insn "*sibcall_value_memory"
12824 [(set (match_operand 0)
12825 (call (mem:QI (match_operand:W 1 "memory_operand" "m"))
12826 (match_operand 2)))
12827 (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
12828 "!TARGET_X32 && !TARGET_INDIRECT_BRANCH_REGISTER"
12829 "* return ix86_output_call_insn (insn, operands[1]);"
12830 [(set_attr "type" "callv")])
12833 [(set (match_operand:W 0 "register_operand")
12834 (match_operand:W 1 "memory_operand"))
12835 (set (match_operand 2)
12836 (call (mem:QI (match_dup 0))
12837 (match_operand 3)))]
12839 && !TARGET_INDIRECT_BRANCH_REGISTER
12840 && SIBLING_CALL_P (peep2_next_insn (1))
12841 && !reg_mentioned_p (operands[0],
12842 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (1)))"
12843 [(parallel [(set (match_dup 2)
12844 (call (mem:QI (match_dup 1))
12846 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
12849 [(set (match_operand:W 0 "register_operand")
12850 (match_operand:W 1 "memory_operand"))
12851 (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
12852 (set (match_operand 2)
12853 (call (mem:QI (match_dup 0))
12854 (match_operand 3)))]
12856 && !TARGET_INDIRECT_BRANCH_REGISTER
12857 && SIBLING_CALL_P (peep2_next_insn (2))
12858 && !reg_mentioned_p (operands[0],
12859 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (2)))"
12860 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
12861 (parallel [(set (match_dup 2)
12862 (call (mem:QI (match_dup 1))
12864 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
12866 (define_expand "call_value_pop"
12867 [(parallel [(set (match_operand 0)
12868 (call (match_operand:QI 1)
12869 (match_operand:SI 2)))
12870 (set (reg:SI SP_REG)
12871 (plus:SI (reg:SI SP_REG)
12872 (match_operand:SI 4)))])]
12875 ix86_expand_call (operands[0], operands[1], operands[2],
12876 operands[3], operands[4], false);
12880 (define_insn "*call_value_pop"
12881 [(set (match_operand 0)
12882 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lBwBz"))
12883 (match_operand 2)))
12884 (set (reg:SI SP_REG)
12885 (plus:SI (reg:SI SP_REG)
12886 (match_operand:SI 3 "immediate_operand" "i")))]
12887 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
12888 "* return ix86_output_call_insn (insn, operands[1]);"
12889 [(set_attr "type" "callv")])
12891 (define_insn "*sibcall_value_pop"
12892 [(set (match_operand 0)
12893 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "UBsBz"))
12894 (match_operand 2)))
12895 (set (reg:SI SP_REG)
12896 (plus:SI (reg:SI SP_REG)
12897 (match_operand:SI 3 "immediate_operand" "i")))]
12898 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
12899 "* return ix86_output_call_insn (insn, operands[1]);"
12900 [(set_attr "type" "callv")])
12902 (define_insn "*sibcall_value_pop_memory"
12903 [(set (match_operand 0)
12904 (call (mem:QI (match_operand:SI 1 "memory_operand" "m"))
12905 (match_operand 2)))
12906 (set (reg:SI SP_REG)
12907 (plus:SI (reg:SI SP_REG)
12908 (match_operand:SI 3 "immediate_operand" "i")))
12909 (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
12911 "* return ix86_output_call_insn (insn, operands[1]);"
12912 [(set_attr "type" "callv")])
12915 [(set (match_operand:SI 0 "register_operand")
12916 (match_operand:SI 1 "memory_operand"))
12917 (parallel [(set (match_operand 2)
12918 (call (mem:QI (match_dup 0))
12919 (match_operand 3)))
12920 (set (reg:SI SP_REG)
12921 (plus:SI (reg:SI SP_REG)
12922 (match_operand:SI 4 "immediate_operand")))])]
12923 "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (1))
12924 && !reg_mentioned_p (operands[0],
12925 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (1)))"
12926 [(parallel [(set (match_dup 2)
12927 (call (mem:QI (match_dup 1))
12929 (set (reg:SI SP_REG)
12930 (plus:SI (reg:SI SP_REG)
12932 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
12935 [(set (match_operand:SI 0 "register_operand")
12936 (match_operand:SI 1 "memory_operand"))
12937 (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
12938 (parallel [(set (match_operand 2)
12939 (call (mem:QI (match_dup 0))
12940 (match_operand 3)))
12941 (set (reg:SI SP_REG)
12942 (plus:SI (reg:SI SP_REG)
12943 (match_operand:SI 4 "immediate_operand")))])]
12944 "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (2))
12945 && !reg_mentioned_p (operands[0],
12946 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (2)))"
12947 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
12948 (parallel [(set (match_dup 2)
12949 (call (mem:QI (match_dup 1))
12951 (set (reg:SI SP_REG)
12952 (plus:SI (reg:SI SP_REG)
12954 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
12956 ;; Call subroutine returning any type.
12958 (define_expand "untyped_call"
12959 [(parallel [(call (match_operand 0)
12962 (match_operand 2)])]
12967 /* In order to give reg-stack an easier job in validating two
12968 coprocessor registers as containing a possible return value,
12969 simply pretend the untyped call returns a complex long double
12972 We can't use SSE_REGPARM_MAX here since callee is unprototyped
12973 and should have the default ABI. */
12975 ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
12976 ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
12977 operands[0], const0_rtx,
12978 GEN_INT ((TARGET_64BIT
12979 ? (ix86_abi == SYSV_ABI
12980 ? X86_64_SSE_REGPARM_MAX
12981 : X86_64_MS_SSE_REGPARM_MAX)
12982 : X86_32_SSE_REGPARM_MAX)
12986 for (i = 0; i < XVECLEN (operands[2], 0); i++)
12988 rtx set = XVECEXP (operands[2], 0, i);
12989 emit_move_insn (SET_DEST (set), SET_SRC (set));
12992 /* The optimizer does not know that the call sets the function value
12993 registers we stored in the result block. We avoid problems by
12994 claiming that all hard registers are used and clobbered at this
12996 emit_insn (gen_blockage ());
13001 ;; Prologue and epilogue instructions
13003 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
13004 ;; all of memory. This blocks insns from being moved across this point.
13006 (define_insn "blockage"
13007 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
13010 [(set_attr "length" "0")])
13012 ;; Do not schedule instructions accessing memory across this point.
13014 (define_expand "memory_blockage"
13015 [(set (match_dup 0)
13016 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
13019 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
13020 MEM_VOLATILE_P (operands[0]) = 1;
13023 (define_insn "*memory_blockage"
13024 [(set (match_operand:BLK 0)
13025 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
13028 [(set_attr "length" "0")])
13030 ;; As USE insns aren't meaningful after reload, this is used instead
13031 ;; to prevent deleting instructions setting registers for PIC code
13032 (define_insn "prologue_use"
13033 [(unspec_volatile [(match_operand 0)] UNSPECV_PROLOGUE_USE)]
13036 [(set_attr "length" "0")])
13038 ;; Insn emitted into the body of a function to return from a function.
13039 ;; This is only done if the function's epilogue is known to be simple.
13040 ;; See comments for ix86_can_use_return_insn_p in i386.c.
13042 (define_expand "return"
13044 "ix86_can_use_return_insn_p ()"
13046 if (crtl->args.pops_args)
13048 rtx popc = GEN_INT (crtl->args.pops_args);
13049 emit_jump_insn (gen_simple_return_pop_internal (popc));
13054 ;; We need to disable this for TARGET_SEH, as otherwise
13055 ;; shrink-wrapped prologue gets enabled too. This might exceed
13056 ;; the maximum size of prologue in unwind information.
13057 ;; Also disallow shrink-wrapping if using stack slot to pass the
13058 ;; static chain pointer - the first instruction has to be pushl %esi
13059 ;; and it can't be moved around, as we use alternate entry points
13062 (define_expand "simple_return"
13064 "!TARGET_SEH && !ix86_static_chain_on_stack"
13066 if (crtl->args.pops_args)
13068 rtx popc = GEN_INT (crtl->args.pops_args);
13069 emit_jump_insn (gen_simple_return_pop_internal (popc));
13074 (define_insn "simple_return_internal"
13077 "* return ix86_output_function_return (false);"
13078 [(set_attr "length" "1")
13079 (set_attr "atom_unit" "jeu")
13080 (set_attr "length_immediate" "0")
13081 (set_attr "modrm" "0")
13082 (set_attr "maybe_prefix_bnd" "1")])
13084 (define_insn "interrupt_return"
13086 (unspec [(const_int 0)] UNSPEC_INTERRUPT_RETURN)]
13089 return TARGET_64BIT ? "iretq" : "iret";
13092 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
13093 ;; instruction Athlon and K8 have.
13095 (define_insn "simple_return_internal_long"
13097 (unspec [(const_int 0)] UNSPEC_REP)]
13099 "* return ix86_output_function_return (true);"
13100 [(set_attr "length" "2")
13101 (set_attr "atom_unit" "jeu")
13102 (set_attr "length_immediate" "0")
13103 (set_attr "prefix_rep" "1")
13104 (set_attr "modrm" "0")])
13106 (define_insn_and_split "simple_return_pop_internal"
13108 (use (match_operand:SI 0 "const_int_operand"))]
13111 "&& cfun->machine->function_return_type != indirect_branch_keep"
13113 "ix86_split_simple_return_pop_internal (operands[0]); DONE;"
13114 [(set_attr "length" "3")
13115 (set_attr "atom_unit" "jeu")
13116 (set_attr "length_immediate" "2")
13117 (set_attr "modrm" "0")
13118 (set_attr "maybe_prefix_bnd" "1")])
13120 (define_insn "simple_return_indirect_internal"
13122 (use (match_operand 0 "register_operand" "r"))]
13124 "* return ix86_output_indirect_function_return (operands[0]);"
13125 [(set (attr "type")
13126 (if_then_else (match_test "(cfun->machine->indirect_branch_type
13127 != indirect_branch_keep)")
13128 (const_string "multi")
13129 (const_string "ibr")))
13130 (set_attr "length_immediate" "0")
13131 (set_attr "maybe_prefix_bnd" "1")])
13137 [(set_attr "length" "1")
13138 (set_attr "length_immediate" "0")
13139 (set_attr "modrm" "0")])
13141 ;; Generate nops. Operand 0 is the number of nops, up to 8.
13142 (define_insn "nops"
13143 [(unspec_volatile [(match_operand 0 "const_int_operand")]
13147 int num = INTVAL (operands[0]);
13149 gcc_assert (IN_RANGE (num, 1, 8));
13152 fputs ("\tnop\n", asm_out_file);
13156 [(set (attr "length") (symbol_ref "INTVAL (operands[0])"))
13157 (set_attr "length_immediate" "0")
13158 (set_attr "modrm" "0")])
13160 ;; Pad to 16-byte boundary, max skip in op0. Used to avoid
13161 ;; branch prediction penalty for the third jump in a 16-byte
13165 [(unspec_volatile [(match_operand 0)] UNSPECV_ALIGN)]
13168 #ifdef ASM_OUTPUT_MAX_SKIP_PAD
13169 ASM_OUTPUT_MAX_SKIP_PAD (asm_out_file, 4, (int)INTVAL (operands[0]));
13171 /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
13172 The align insn is used to avoid 3 jump instructions in the row to improve
13173 branch prediction and the benefits hardly outweigh the cost of extra 8
13174 nops on the average inserted by full alignment pseudo operation. */
13178 [(set_attr "length" "16")])
13180 (define_expand "prologue"
13183 "ix86_expand_prologue (); DONE;")
13185 (define_expand "set_got"
13187 [(set (match_operand:SI 0 "register_operand")
13188 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
13189 (clobber (reg:CC FLAGS_REG))])]
13192 if (flag_pic && !TARGET_VXWORKS_RTP)
13193 ix86_pc_thunk_call_expanded = true;
13196 (define_insn "*set_got"
13197 [(set (match_operand:SI 0 "register_operand" "=r")
13198 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
13199 (clobber (reg:CC FLAGS_REG))]
13201 "* return output_set_got (operands[0], NULL_RTX);"
13202 [(set_attr "type" "multi")
13203 (set_attr "length" "12")])
13205 (define_expand "set_got_labelled"
13207 [(set (match_operand:SI 0 "register_operand")
13208 (unspec:SI [(label_ref (match_operand 1))]
13210 (clobber (reg:CC FLAGS_REG))])]
13213 if (flag_pic && !TARGET_VXWORKS_RTP)
13214 ix86_pc_thunk_call_expanded = true;
13217 (define_insn "*set_got_labelled"
13218 [(set (match_operand:SI 0 "register_operand" "=r")
13219 (unspec:SI [(label_ref (match_operand 1))]
13221 (clobber (reg:CC FLAGS_REG))]
13223 "* return output_set_got (operands[0], operands[1]);"
13224 [(set_attr "type" "multi")
13225 (set_attr "length" "12")])
13227 (define_insn "set_got_rex64"
13228 [(set (match_operand:DI 0 "register_operand" "=r")
13229 (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
13231 "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}"
13232 [(set_attr "type" "lea")
13233 (set_attr "length_address" "4")
13234 (set_attr "modrm_class" "unknown")
13235 (set_attr "mode" "DI")])
13237 (define_insn "set_rip_rex64"
13238 [(set (match_operand:DI 0 "register_operand" "=r")
13239 (unspec:DI [(label_ref (match_operand 1))] UNSPEC_SET_RIP))]
13241 "lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}"
13242 [(set_attr "type" "lea")
13243 (set_attr "length_address" "4")
13244 (set_attr "mode" "DI")])
13246 (define_insn "set_got_offset_rex64"
13247 [(set (match_operand:DI 0 "register_operand" "=r")
13249 [(label_ref (match_operand 1))]
13250 UNSPEC_SET_GOT_OFFSET))]
13252 "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}"
13253 [(set_attr "type" "imov")
13254 (set_attr "length_immediate" "0")
13255 (set_attr "length_address" "8")
13256 (set_attr "mode" "DI")])
13258 (define_expand "epilogue"
13261 "ix86_expand_epilogue (1); DONE;")
13263 (define_expand "sibcall_epilogue"
13266 "ix86_expand_epilogue (0); DONE;")
13268 (define_expand "eh_return"
13269 [(use (match_operand 0 "register_operand"))]
13272 rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
13274 /* Tricky bit: we write the address of the handler to which we will
13275 be returning into someone else's stack frame, one word below the
13276 stack address we wish to restore. */
13277 tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
13278 tmp = plus_constant (Pmode, tmp, -UNITS_PER_WORD);
13279 tmp = gen_rtx_MEM (Pmode, tmp);
13280 emit_move_insn (tmp, ra);
13282 emit_jump_insn (gen_eh_return_internal ());
13287 (define_insn_and_split "eh_return_internal"
13291 "epilogue_completed"
13293 "ix86_expand_epilogue (2); DONE;")
13295 (define_insn "leave"
13296 [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
13297 (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
13298 (clobber (mem:BLK (scratch)))]
13301 [(set_attr "type" "leave")])
13303 (define_insn "leave_rex64"
13304 [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
13305 (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
13306 (clobber (mem:BLK (scratch)))]
13309 [(set_attr "type" "leave")])
13311 ;; Handle -fsplit-stack.
13313 (define_expand "split_stack_prologue"
13317 ix86_expand_split_stack_prologue ();
13321 ;; In order to support the call/return predictor, we use a return
13322 ;; instruction which the middle-end doesn't see.
13323 (define_insn "split_stack_return"
13324 [(unspec_volatile [(match_operand:SI 0 "const_int_operand")]
13325 UNSPECV_SPLIT_STACK_RETURN)]
13328 if (operands[0] == const0_rtx)
13333 [(set_attr "atom_unit" "jeu")
13334 (set_attr "modrm" "0")
13335 (set (attr "length")
13336 (if_then_else (match_operand:SI 0 "const0_operand")
13339 (set (attr "length_immediate")
13340 (if_then_else (match_operand:SI 0 "const0_operand")
13344 ;; If there are operand 0 bytes available on the stack, jump to
13347 (define_expand "split_stack_space_check"
13348 [(set (pc) (if_then_else
13349 (ltu (minus (reg SP_REG)
13350 (match_operand 0 "register_operand"))
13352 (label_ref (match_operand 1))
13356 rtx reg = gen_reg_rtx (Pmode);
13358 emit_insn (gen_sub3_insn (reg, stack_pointer_rtx, operands[0]));
13360 operands[2] = ix86_split_stack_guard ();
13361 ix86_expand_branch (GEU, reg, operands[2], operands[1]);
13366 ;; Bit manipulation instructions.
13368 (define_expand "ffs<mode>2"
13369 [(set (match_dup 2) (const_int -1))
13370 (parallel [(set (match_dup 3) (match_dup 4))
13371 (set (match_operand:SWI48 0 "register_operand")
13373 (match_operand:SWI48 1 "nonimmediate_operand")))])
13374 (set (match_dup 0) (if_then_else:SWI48
13375 (eq (match_dup 3) (const_int 0))
13378 (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (const_int 1)))
13379 (clobber (reg:CC FLAGS_REG))])]
13382 machine_mode flags_mode;
13384 if (<MODE>mode == SImode && !TARGET_CMOVE)
13386 emit_insn (gen_ffssi2_no_cmove (operands[0], operands [1]));
13390 flags_mode = TARGET_BMI ? CCCmode : CCZmode;
13392 operands[2] = gen_reg_rtx (<MODE>mode);
13393 operands[3] = gen_rtx_REG (flags_mode, FLAGS_REG);
13394 operands[4] = gen_rtx_COMPARE (flags_mode, operands[1], const0_rtx);
13397 (define_insn_and_split "ffssi2_no_cmove"
13398 [(set (match_operand:SI 0 "register_operand" "=r")
13399 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
13400 (clobber (match_scratch:SI 2 "=&q"))
13401 (clobber (reg:CC FLAGS_REG))]
13404 "&& reload_completed"
13405 [(parallel [(set (match_dup 4) (match_dup 5))
13406 (set (match_dup 0) (ctz:SI (match_dup 1)))])
13407 (set (strict_low_part (match_dup 3))
13408 (eq:QI (match_dup 4) (const_int 0)))
13409 (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
13410 (clobber (reg:CC FLAGS_REG))])
13411 (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
13412 (clobber (reg:CC FLAGS_REG))])
13413 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
13414 (clobber (reg:CC FLAGS_REG))])]
13416 machine_mode flags_mode = TARGET_BMI ? CCCmode : CCZmode;
13418 operands[3] = gen_lowpart (QImode, operands[2]);
13419 operands[4] = gen_rtx_REG (flags_mode, FLAGS_REG);
13420 operands[5] = gen_rtx_COMPARE (flags_mode, operands[1], const0_rtx);
13422 ix86_expand_clear (operands[2]);
13425 (define_insn_and_split "*tzcnt<mode>_1"
13426 [(set (reg:CCC FLAGS_REG)
13427 (compare:CCC (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13429 (set (match_operand:SWI48 0 "register_operand" "=r")
13430 (ctz:SWI48 (match_dup 1)))]
13432 "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
13433 "&& TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
13434 && optimize_function_for_speed_p (cfun)
13435 && !reg_mentioned_p (operands[0], operands[1])"
13437 [(set (reg:CCC FLAGS_REG)
13438 (compare:CCC (match_dup 1) (const_int 0)))
13440 (ctz:SWI48 (match_dup 1)))
13441 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)])]
13442 "ix86_expand_clear (operands[0]);"
13443 [(set_attr "type" "alu1")
13444 (set_attr "prefix_0f" "1")
13445 (set_attr "prefix_rep" "1")
13446 (set_attr "btver2_decode" "double")
13447 (set_attr "mode" "<MODE>")])
13449 ; False dependency happens when destination is only updated by tzcnt,
13450 ; lzcnt or popcnt. There is no false dependency when destination is
13451 ; also used in source.
13452 (define_insn "*tzcnt<mode>_1_falsedep"
13453 [(set (reg:CCC FLAGS_REG)
13454 (compare:CCC (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13456 (set (match_operand:SWI48 0 "register_operand" "=r")
13457 (ctz:SWI48 (match_dup 1)))
13458 (unspec [(match_operand:SWI48 2 "register_operand" "0")]
13459 UNSPEC_INSN_FALSE_DEP)]
13461 "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
13462 [(set_attr "type" "alu1")
13463 (set_attr "prefix_0f" "1")
13464 (set_attr "prefix_rep" "1")
13465 (set_attr "btver2_decode" "double")
13466 (set_attr "mode" "<MODE>")])
13468 (define_insn "*bsf<mode>_1"
13469 [(set (reg:CCZ FLAGS_REG)
13470 (compare:CCZ (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13472 (set (match_operand:SWI48 0 "register_operand" "=r")
13473 (ctz:SWI48 (match_dup 1)))]
13475 "bsf{<imodesuffix>}\t{%1, %0|%0, %1}"
13476 [(set_attr "type" "alu1")
13477 (set_attr "prefix_0f" "1")
13478 (set_attr "btver2_decode" "double")
13479 (set_attr "znver1_decode" "vector")
13480 (set_attr "mode" "<MODE>")])
13482 (define_insn_and_split "ctz<mode>2"
13483 [(set (match_operand:SWI48 0 "register_operand" "=r")
13485 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
13486 (clobber (reg:CC FLAGS_REG))]
13490 return "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
13491 else if (optimize_function_for_size_p (cfun))
13493 else if (TARGET_GENERIC)
13494 /* tzcnt expands to 'rep bsf' and we can use it even if !TARGET_BMI. */
13495 return "rep%; bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
13497 return "bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
13499 "(TARGET_BMI || TARGET_GENERIC)
13500 && TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
13501 && optimize_function_for_speed_p (cfun)
13502 && !reg_mentioned_p (operands[0], operands[1])"
13504 [(set (match_dup 0)
13505 (ctz:SWI48 (match_dup 1)))
13506 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
13507 (clobber (reg:CC FLAGS_REG))])]
13508 "ix86_expand_clear (operands[0]);"
13509 [(set_attr "type" "alu1")
13510 (set_attr "prefix_0f" "1")
13511 (set (attr "prefix_rep")
13513 (ior (match_test "TARGET_BMI")
13514 (and (not (match_test "optimize_function_for_size_p (cfun)"))
13515 (match_test "TARGET_GENERIC")))
13517 (const_string "0")))
13518 (set_attr "mode" "<MODE>")])
13520 ; False dependency happens when destination is only updated by tzcnt,
13521 ; lzcnt or popcnt. There is no false dependency when destination is
13522 ; also used in source.
13523 (define_insn "*ctz<mode>2_falsedep"
13524 [(set (match_operand:SWI48 0 "register_operand" "=r")
13526 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
13527 (unspec [(match_operand:SWI48 2 "register_operand" "0")]
13528 UNSPEC_INSN_FALSE_DEP)
13529 (clobber (reg:CC FLAGS_REG))]
13533 return "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
13534 else if (TARGET_GENERIC)
13535 /* tzcnt expands to 'rep bsf' and we can use it even if !TARGET_BMI. */
13536 return "rep%; bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
13538 gcc_unreachable ();
13540 [(set_attr "type" "alu1")
13541 (set_attr "prefix_0f" "1")
13542 (set_attr "prefix_rep" "1")
13543 (set_attr "mode" "<MODE>")])
13545 (define_insn "bsr_rex64"
13546 [(set (match_operand:DI 0 "register_operand" "=r")
13547 (minus:DI (const_int 63)
13548 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
13549 (clobber (reg:CC FLAGS_REG))]
13551 "bsr{q}\t{%1, %0|%0, %1}"
13552 [(set_attr "type" "alu1")
13553 (set_attr "prefix_0f" "1")
13554 (set_attr "znver1_decode" "vector")
13555 (set_attr "mode" "DI")])
13558 [(set (match_operand:SI 0 "register_operand" "=r")
13559 (minus:SI (const_int 31)
13560 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
13561 (clobber (reg:CC FLAGS_REG))]
13563 "bsr{l}\t{%1, %0|%0, %1}"
13564 [(set_attr "type" "alu1")
13565 (set_attr "prefix_0f" "1")
13566 (set_attr "znver1_decode" "vector")
13567 (set_attr "mode" "SI")])
13569 (define_insn "*bsrhi"
13570 [(set (match_operand:HI 0 "register_operand" "=r")
13571 (minus:HI (const_int 15)
13572 (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
13573 (clobber (reg:CC FLAGS_REG))]
13575 "bsr{w}\t{%1, %0|%0, %1}"
13576 [(set_attr "type" "alu1")
13577 (set_attr "prefix_0f" "1")
13578 (set_attr "znver1_decode" "vector")
13579 (set_attr "mode" "HI")])
13581 (define_expand "clz<mode>2"
13583 [(set (match_operand:SWI48 0 "register_operand")
13586 (clz:SWI48 (match_operand:SWI48 1 "nonimmediate_operand"))))
13587 (clobber (reg:CC FLAGS_REG))])
13589 [(set (match_dup 0) (xor:SWI48 (match_dup 0) (match_dup 2)))
13590 (clobber (reg:CC FLAGS_REG))])]
13595 emit_insn (gen_clz<mode>2_lzcnt (operands[0], operands[1]));
13598 operands[2] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
13601 (define_insn_and_split "clz<mode>2_lzcnt"
13602 [(set (match_operand:SWI48 0 "register_operand" "=r")
13604 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
13605 (clobber (reg:CC FLAGS_REG))]
13607 "lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
13608 "&& TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
13609 && optimize_function_for_speed_p (cfun)
13610 && !reg_mentioned_p (operands[0], operands[1])"
13612 [(set (match_dup 0)
13613 (clz:SWI48 (match_dup 1)))
13614 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
13615 (clobber (reg:CC FLAGS_REG))])]
13616 "ix86_expand_clear (operands[0]);"
13617 [(set_attr "prefix_rep" "1")
13618 (set_attr "type" "bitmanip")
13619 (set_attr "mode" "<MODE>")])
13621 ; False dependency happens when destination is only updated by tzcnt,
13622 ; lzcnt or popcnt. There is no false dependency when destination is
13623 ; also used in source.
13624 (define_insn "*clz<mode>2_lzcnt_falsedep"
13625 [(set (match_operand:SWI48 0 "register_operand" "=r")
13627 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
13628 (unspec [(match_operand:SWI48 2 "register_operand" "0")]
13629 UNSPEC_INSN_FALSE_DEP)
13630 (clobber (reg:CC FLAGS_REG))]
13632 "lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
13633 [(set_attr "prefix_rep" "1")
13634 (set_attr "type" "bitmanip")
13635 (set_attr "mode" "<MODE>")])
13637 (define_int_iterator LT_ZCNT
13638 [(UNSPEC_TZCNT "TARGET_BMI")
13639 (UNSPEC_LZCNT "TARGET_LZCNT")])
13641 (define_int_attr lt_zcnt
13642 [(UNSPEC_TZCNT "tzcnt")
13643 (UNSPEC_LZCNT "lzcnt")])
13645 (define_int_attr lt_zcnt_type
13646 [(UNSPEC_TZCNT "alu1")
13647 (UNSPEC_LZCNT "bitmanip")])
13649 ;; Version of lzcnt/tzcnt that is expanded from intrinsics. This version
13650 ;; provides operand size as output when source operand is zero.
13652 (define_insn_and_split "<lt_zcnt>_<mode>"
13653 [(set (match_operand:SWI48 0 "register_operand" "=r")
13655 [(match_operand:SWI48 1 "nonimmediate_operand" "rm")] LT_ZCNT))
13656 (clobber (reg:CC FLAGS_REG))]
13658 "<lt_zcnt>{<imodesuffix>}\t{%1, %0|%0, %1}"
13659 "&& TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
13660 && optimize_function_for_speed_p (cfun)
13661 && !reg_mentioned_p (operands[0], operands[1])"
13663 [(set (match_dup 0)
13664 (unspec:SWI48 [(match_dup 1)] LT_ZCNT))
13665 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
13666 (clobber (reg:CC FLAGS_REG))])]
13667 "ix86_expand_clear (operands[0]);"
13668 [(set_attr "type" "<lt_zcnt_type>")
13669 (set_attr "prefix_0f" "1")
13670 (set_attr "prefix_rep" "1")
13671 (set_attr "mode" "<MODE>")])
13673 ; False dependency happens when destination is only updated by tzcnt,
13674 ; lzcnt or popcnt. There is no false dependency when destination is
13675 ; also used in source.
13676 (define_insn "*<lt_zcnt>_<mode>_falsedep"
13677 [(set (match_operand:SWI48 0 "register_operand" "=r")
13679 [(match_operand:SWI48 1 "nonimmediate_operand" "rm")] LT_ZCNT))
13680 (unspec [(match_operand:SWI48 2 "register_operand" "0")]
13681 UNSPEC_INSN_FALSE_DEP)
13682 (clobber (reg:CC FLAGS_REG))]
13684 "<lt_zcnt>{<imodesuffix>}\t{%1, %0|%0, %1}"
13685 [(set_attr "type" "<lt_zcnt_type>")
13686 (set_attr "prefix_0f" "1")
13687 (set_attr "prefix_rep" "1")
13688 (set_attr "mode" "<MODE>")])
13690 (define_insn "<lt_zcnt>_hi"
13691 [(set (match_operand:HI 0 "register_operand" "=r")
13693 [(match_operand:HI 1 "nonimmediate_operand" "rm")] LT_ZCNT))
13694 (clobber (reg:CC FLAGS_REG))]
13696 "<lt_zcnt>{w}\t{%1, %0|%0, %1}"
13697 [(set_attr "type" "<lt_zcnt_type>")
13698 (set_attr "prefix_0f" "1")
13699 (set_attr "prefix_rep" "1")
13700 (set_attr "mode" "HI")])
13702 ;; BMI instructions.
13704 (define_insn "bmi_bextr_<mode>"
13705 [(set (match_operand:SWI48 0 "register_operand" "=r,r")
13706 (unspec:SWI48 [(match_operand:SWI48 1 "nonimmediate_operand" "r,m")
13707 (match_operand:SWI48 2 "register_operand" "r,r")]
13709 (clobber (reg:CC FLAGS_REG))]
13711 "bextr\t{%2, %1, %0|%0, %1, %2}"
13712 [(set_attr "type" "bitmanip")
13713 (set_attr "btver2_decode" "direct, double")
13714 (set_attr "mode" "<MODE>")])
13716 (define_insn "*bmi_bextr_<mode>_ccz"
13717 [(set (reg:CCZ FLAGS_REG)
13719 (unspec:SWI48 [(match_operand:SWI48 1 "nonimmediate_operand" "r,m")
13720 (match_operand:SWI48 2 "register_operand" "r,r")]
13723 (clobber (match_scratch:SWI48 0 "=r,r"))]
13725 "bextr\t{%2, %1, %0|%0, %1, %2}"
13726 [(set_attr "type" "bitmanip")
13727 (set_attr "btver2_decode" "direct, double")
13728 (set_attr "mode" "<MODE>")])
13730 (define_insn "*bmi_blsi_<mode>"
13731 [(set (match_operand:SWI48 0 "register_operand" "=r")
13734 (match_operand:SWI48 1 "nonimmediate_operand" "rm"))
13736 (clobber (reg:CC FLAGS_REG))]
13738 "blsi\t{%1, %0|%0, %1}"
13739 [(set_attr "type" "bitmanip")
13740 (set_attr "btver2_decode" "double")
13741 (set_attr "mode" "<MODE>")])
13743 (define_insn "*bmi_blsmsk_<mode>"
13744 [(set (match_operand:SWI48 0 "register_operand" "=r")
13747 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13750 (clobber (reg:CC FLAGS_REG))]
13752 "blsmsk\t{%1, %0|%0, %1}"
13753 [(set_attr "type" "bitmanip")
13754 (set_attr "btver2_decode" "double")
13755 (set_attr "mode" "<MODE>")])
13757 (define_insn "*bmi_blsr_<mode>"
13758 [(set (match_operand:SWI48 0 "register_operand" "=r")
13761 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13764 (clobber (reg:CC FLAGS_REG))]
13766 "blsr\t{%1, %0|%0, %1}"
13767 [(set_attr "type" "bitmanip")
13768 (set_attr "btver2_decode" "double")
13769 (set_attr "mode" "<MODE>")])
13771 ;; BMI2 instructions.
13772 (define_expand "bmi2_bzhi_<mode>3"
13774 [(set (match_operand:SWI48 0 "register_operand")
13775 (zero_extract:SWI48
13776 (match_operand:SWI48 1 "nonimmediate_operand")
13778 (and:SWI48 (match_operand:SWI48 2 "register_operand")
13782 (clobber (reg:CC FLAGS_REG))])]
13784 "operands[3] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT);")
13786 (define_insn "*bmi2_bzhi_<mode>3"
13787 [(set (match_operand:SWI48 0 "register_operand" "=r")
13788 (zero_extract:SWI48
13789 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13791 (and:SWI48 (match_operand:SWI48 2 "register_operand" "r")
13793 (match_operand:SWI48 3 "const_int_operand" "n"))
13795 (clobber (reg:CC FLAGS_REG))]
13796 "TARGET_BMI2 && INTVAL (operands[3]) == <MODE_SIZE> * BITS_PER_UNIT"
13797 "bzhi\t{%2, %1, %0|%0, %1, %2}"
13798 [(set_attr "type" "bitmanip")
13799 (set_attr "prefix" "vex")
13800 (set_attr "mode" "<MODE>")])
13802 (define_insn "*bmi2_bzhi_<mode>3_1"
13803 [(set (match_operand:SWI48 0 "register_operand" "=r")
13804 (zero_extract:SWI48
13805 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13807 (zero_extend:SWI48 (match_operand:QI 2 "register_operand" "r"))
13808 (match_operand:SWI48 3 "const_int_operand" "n"))
13810 (clobber (reg:CC FLAGS_REG))]
13811 "TARGET_BMI2 && INTVAL (operands[3]) == <MODE_SIZE> * BITS_PER_UNIT"
13812 "bzhi\t{%<k>2, %1, %0|%0, %1, %<k>2}"
13813 [(set_attr "type" "bitmanip")
13814 (set_attr "prefix" "vex")
13815 (set_attr "mode" "<MODE>")])
13817 (define_insn "*bmi2_bzhi_<mode>3_1_ccz"
13818 [(set (reg:CCZ FLAGS_REG)
13820 (zero_extract:SWI48
13821 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13823 (zero_extend:SWI48 (match_operand:QI 2 "register_operand" "r"))
13824 (match_operand:SWI48 3 "const_int_operand" "n"))
13827 (clobber (match_scratch:SWI48 0 "=r"))]
13828 "TARGET_BMI2 && INTVAL (operands[3]) == <MODE_SIZE> * BITS_PER_UNIT"
13829 "bzhi\t{%<k>2, %1, %0|%0, %1, %<k>2}"
13830 [(set_attr "type" "bitmanip")
13831 (set_attr "prefix" "vex")
13832 (set_attr "mode" "<MODE>")])
13834 (define_insn "bmi2_pdep_<mode>3"
13835 [(set (match_operand:SWI48 0 "register_operand" "=r")
13836 (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
13837 (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
13840 "pdep\t{%2, %1, %0|%0, %1, %2}"
13841 [(set_attr "type" "bitmanip")
13842 (set_attr "prefix" "vex")
13843 (set_attr "mode" "<MODE>")])
13845 (define_insn "bmi2_pext_<mode>3"
13846 [(set (match_operand:SWI48 0 "register_operand" "=r")
13847 (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
13848 (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
13851 "pext\t{%2, %1, %0|%0, %1, %2}"
13852 [(set_attr "type" "bitmanip")
13853 (set_attr "prefix" "vex")
13854 (set_attr "mode" "<MODE>")])
13856 ;; TBM instructions.
13857 (define_insn "tbm_bextri_<mode>"
13858 [(set (match_operand:SWI48 0 "register_operand" "=r")
13859 (zero_extract:SWI48
13860 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13861 (match_operand 2 "const_0_to_255_operand" "N")
13862 (match_operand 3 "const_0_to_255_operand" "N")))
13863 (clobber (reg:CC FLAGS_REG))]
13866 operands[2] = GEN_INT (INTVAL (operands[2]) << 8 | INTVAL (operands[3]));
13867 return "bextr\t{%2, %1, %0|%0, %1, %2}";
13869 [(set_attr "type" "bitmanip")
13870 (set_attr "mode" "<MODE>")])
13872 (define_insn "*tbm_blcfill_<mode>"
13873 [(set (match_operand:SWI48 0 "register_operand" "=r")
13876 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13879 (clobber (reg:CC FLAGS_REG))]
13881 "blcfill\t{%1, %0|%0, %1}"
13882 [(set_attr "type" "bitmanip")
13883 (set_attr "mode" "<MODE>")])
13885 (define_insn "*tbm_blci_<mode>"
13886 [(set (match_operand:SWI48 0 "register_operand" "=r")
13890 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13893 (clobber (reg:CC FLAGS_REG))]
13895 "blci\t{%1, %0|%0, %1}"
13896 [(set_attr "type" "bitmanip")
13897 (set_attr "mode" "<MODE>")])
13899 (define_insn "*tbm_blcic_<mode>"
13900 [(set (match_operand:SWI48 0 "register_operand" "=r")
13903 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13907 (clobber (reg:CC FLAGS_REG))]
13909 "blcic\t{%1, %0|%0, %1}"
13910 [(set_attr "type" "bitmanip")
13911 (set_attr "mode" "<MODE>")])
13913 (define_insn "*tbm_blcmsk_<mode>"
13914 [(set (match_operand:SWI48 0 "register_operand" "=r")
13917 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13920 (clobber (reg:CC FLAGS_REG))]
13922 "blcmsk\t{%1, %0|%0, %1}"
13923 [(set_attr "type" "bitmanip")
13924 (set_attr "mode" "<MODE>")])
13926 (define_insn "*tbm_blcs_<mode>"
13927 [(set (match_operand:SWI48 0 "register_operand" "=r")
13930 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13933 (clobber (reg:CC FLAGS_REG))]
13935 "blcs\t{%1, %0|%0, %1}"
13936 [(set_attr "type" "bitmanip")
13937 (set_attr "mode" "<MODE>")])
13939 (define_insn "*tbm_blsfill_<mode>"
13940 [(set (match_operand:SWI48 0 "register_operand" "=r")
13943 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13946 (clobber (reg:CC FLAGS_REG))]
13948 "blsfill\t{%1, %0|%0, %1}"
13949 [(set_attr "type" "bitmanip")
13950 (set_attr "mode" "<MODE>")])
13952 (define_insn "*tbm_blsic_<mode>"
13953 [(set (match_operand:SWI48 0 "register_operand" "=r")
13956 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13960 (clobber (reg:CC FLAGS_REG))]
13962 "blsic\t{%1, %0|%0, %1}"
13963 [(set_attr "type" "bitmanip")
13964 (set_attr "mode" "<MODE>")])
13966 (define_insn "*tbm_t1mskc_<mode>"
13967 [(set (match_operand:SWI48 0 "register_operand" "=r")
13970 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13974 (clobber (reg:CC FLAGS_REG))]
13976 "t1mskc\t{%1, %0|%0, %1}"
13977 [(set_attr "type" "bitmanip")
13978 (set_attr "mode" "<MODE>")])
13980 (define_insn "*tbm_tzmsk_<mode>"
13981 [(set (match_operand:SWI48 0 "register_operand" "=r")
13984 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13988 (clobber (reg:CC FLAGS_REG))]
13990 "tzmsk\t{%1, %0|%0, %1}"
13991 [(set_attr "type" "bitmanip")
13992 (set_attr "mode" "<MODE>")])
13994 (define_insn_and_split "popcount<mode>2"
13995 [(set (match_operand:SWI48 0 "register_operand" "=r")
13997 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
13998 (clobber (reg:CC FLAGS_REG))]
14002 return "popcnt\t{%1, %0|%0, %1}";
14004 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
14007 "&& TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
14008 && optimize_function_for_speed_p (cfun)
14009 && !reg_mentioned_p (operands[0], operands[1])"
14011 [(set (match_dup 0)
14012 (popcount:SWI48 (match_dup 1)))
14013 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
14014 (clobber (reg:CC FLAGS_REG))])]
14015 "ix86_expand_clear (operands[0]);"
14016 [(set_attr "prefix_rep" "1")
14017 (set_attr "type" "bitmanip")
14018 (set_attr "mode" "<MODE>")])
14020 ; False dependency happens when destination is only updated by tzcnt,
14021 ; lzcnt or popcnt. There is no false dependency when destination is
14022 ; also used in source.
14023 (define_insn "*popcount<mode>2_falsedep"
14024 [(set (match_operand:SWI48 0 "register_operand" "=r")
14026 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
14027 (unspec [(match_operand:SWI48 2 "register_operand" "0")]
14028 UNSPEC_INSN_FALSE_DEP)
14029 (clobber (reg:CC FLAGS_REG))]
14033 return "popcnt\t{%1, %0|%0, %1}";
14035 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
14038 [(set_attr "prefix_rep" "1")
14039 (set_attr "type" "bitmanip")
14040 (set_attr "mode" "<MODE>")])
14042 (define_insn_and_split "*popcounthi2_1"
14043 [(set (match_operand:SI 0 "register_operand")
14045 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand"))))
14046 (clobber (reg:CC FLAGS_REG))]
14048 && can_create_pseudo_p ()"
14053 rtx tmp = gen_reg_rtx (HImode);
14055 emit_insn (gen_popcounthi2 (tmp, operands[1]));
14056 emit_insn (gen_zero_extendhisi2 (operands[0], tmp));
14060 (define_insn "popcounthi2"
14061 [(set (match_operand:HI 0 "register_operand" "=r")
14063 (match_operand:HI 1 "nonimmediate_operand" "rm")))
14064 (clobber (reg:CC FLAGS_REG))]
14068 return "popcnt\t{%1, %0|%0, %1}";
14070 return "popcnt{w}\t{%1, %0|%0, %1}";
14073 [(set_attr "prefix_rep" "1")
14074 (set_attr "type" "bitmanip")
14075 (set_attr "mode" "HI")])
14077 (define_expand "bswapdi2"
14078 [(set (match_operand:DI 0 "register_operand")
14079 (bswap:DI (match_operand:DI 1 "nonimmediate_operand")))]
14083 operands[1] = force_reg (DImode, operands[1]);
14086 (define_expand "bswapsi2"
14087 [(set (match_operand:SI 0 "register_operand")
14088 (bswap:SI (match_operand:SI 1 "nonimmediate_operand")))]
14093 else if (TARGET_BSWAP)
14094 operands[1] = force_reg (SImode, operands[1]);
14097 rtx x = operands[0];
14099 emit_move_insn (x, operands[1]);
14100 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
14101 emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
14102 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
14107 (define_insn "*bswap<mode>2_movbe"
14108 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,r,m")
14109 (bswap:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,m,r")))]
14111 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
14114 movbe{<imodesuffix>}\t{%1, %0|%0, %1}
14115 movbe{<imodesuffix>}\t{%1, %0|%0, %1}"
14116 [(set_attr "type" "bitmanip,imov,imov")
14117 (set_attr "modrm" "0,1,1")
14118 (set_attr "prefix_0f" "*,1,1")
14119 (set_attr "prefix_extra" "*,1,1")
14120 (set_attr "mode" "<MODE>")])
14122 (define_insn "*bswap<mode>2"
14123 [(set (match_operand:SWI48 0 "register_operand" "=r")
14124 (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "0")))]
14127 [(set_attr "type" "bitmanip")
14128 (set_attr "modrm" "0")
14129 (set_attr "mode" "<MODE>")])
14131 (define_expand "bswaphi2"
14132 [(set (match_operand:HI 0 "register_operand")
14133 (bswap:HI (match_operand:HI 1 "nonimmediate_operand")))]
14136 (define_insn "*bswaphi2_movbe"
14137 [(set (match_operand:HI 0 "nonimmediate_operand" "=Q,r,m")
14138 (bswap:HI (match_operand:HI 1 "nonimmediate_operand" "0,m,r")))]
14140 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
14142 xchg{b}\t{%h0, %b0|%b0, %h0}
14143 movbe{w}\t{%1, %0|%0, %1}
14144 movbe{w}\t{%1, %0|%0, %1}"
14145 [(set_attr "type" "imov")
14146 (set_attr "modrm" "*,1,1")
14147 (set_attr "prefix_0f" "*,1,1")
14148 (set_attr "prefix_extra" "*,1,1")
14149 (set_attr "pent_pair" "np,*,*")
14150 (set_attr "athlon_decode" "vector,*,*")
14151 (set_attr "amdfam10_decode" "double,*,*")
14152 (set_attr "bdver1_decode" "double,*,*")
14153 (set_attr "mode" "QI,HI,HI")])
14156 [(set (match_operand:HI 0 "general_reg_operand")
14157 (bswap:HI (match_dup 0)))]
14159 && !(TARGET_USE_XCHGB || optimize_function_for_size_p (cfun))
14160 && peep2_regno_dead_p (0, FLAGS_REG)"
14161 [(parallel [(set (match_dup 0) (rotate:HI (match_dup 0) (const_int 8)))
14162 (clobber (reg:CC FLAGS_REG))])])
14164 (define_insn "bswaphi_lowpart"
14165 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
14166 (bswap:HI (match_dup 0)))
14167 (clobber (reg:CC FLAGS_REG))]
14170 xchg{b}\t{%h0, %b0|%b0, %h0}
14171 rol{w}\t{$8, %0|%0, 8}"
14172 [(set (attr "preferred_for_size")
14173 (cond [(eq_attr "alternative" "0")
14174 (symbol_ref "true")]
14175 (symbol_ref "false")))
14176 (set (attr "preferred_for_speed")
14177 (cond [(eq_attr "alternative" "0")
14178 (symbol_ref "TARGET_USE_XCHGB")]
14179 (symbol_ref "!TARGET_USE_XCHGB")))
14180 (set_attr "length" "2,4")
14181 (set_attr "mode" "QI,HI")])
14183 (define_expand "paritydi2"
14184 [(set (match_operand:DI 0 "register_operand")
14185 (parity:DI (match_operand:DI 1 "register_operand")))]
14188 rtx scratch = gen_reg_rtx (QImode);
14190 emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX,
14191 NULL_RTX, operands[1]));
14193 ix86_expand_setcc (scratch, ORDERED,
14194 gen_rtx_REG (CCmode, FLAGS_REG), const0_rtx);
14197 emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
14200 rtx tmp = gen_reg_rtx (SImode);
14202 emit_insn (gen_zero_extendqisi2 (tmp, scratch));
14203 emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
14208 (define_expand "paritysi2"
14209 [(set (match_operand:SI 0 "register_operand")
14210 (parity:SI (match_operand:SI 1 "register_operand")))]
14213 rtx scratch = gen_reg_rtx (QImode);
14215 emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1]));
14217 ix86_expand_setcc (scratch, ORDERED,
14218 gen_rtx_REG (CCmode, FLAGS_REG), const0_rtx);
14220 emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
14224 (define_insn_and_split "paritydi2_cmp"
14225 [(set (reg:CC FLAGS_REG)
14226 (unspec:CC [(match_operand:DI 3 "register_operand" "0")]
14228 (clobber (match_scratch:DI 0 "=r"))
14229 (clobber (match_scratch:SI 1 "=&r"))
14230 (clobber (match_scratch:HI 2 "=Q"))]
14233 "&& reload_completed"
14235 [(set (match_dup 1)
14236 (xor:SI (match_dup 1) (match_dup 4)))
14237 (clobber (reg:CC FLAGS_REG))])
14239 [(set (reg:CC FLAGS_REG)
14240 (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
14241 (clobber (match_dup 1))
14242 (clobber (match_dup 2))])]
14244 operands[4] = gen_lowpart (SImode, operands[3]);
14248 emit_move_insn (operands[1], gen_lowpart (SImode, operands[3]));
14249 emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32)));
14252 operands[1] = gen_highpart (SImode, operands[3]);
14255 (define_insn_and_split "paritysi2_cmp"
14256 [(set (reg:CC FLAGS_REG)
14257 (unspec:CC [(match_operand:SI 2 "register_operand" "0")]
14259 (clobber (match_scratch:SI 0 "=r"))
14260 (clobber (match_scratch:HI 1 "=&Q"))]
14263 "&& reload_completed"
14265 [(set (match_dup 1)
14266 (xor:HI (match_dup 1) (match_dup 3)))
14267 (clobber (reg:CC FLAGS_REG))])
14269 [(set (reg:CC FLAGS_REG)
14270 (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
14271 (clobber (match_dup 1))])]
14273 operands[3] = gen_lowpart (HImode, operands[2]);
14275 emit_move_insn (operands[1], gen_lowpart (HImode, operands[2]));
14276 emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16)));
14279 (define_insn "*parityhi2_cmp"
14280 [(set (reg:CC FLAGS_REG)
14281 (unspec:CC [(match_operand:HI 1 "register_operand" "0")]
14283 (clobber (match_scratch:HI 0 "=Q"))]
14285 "xor{b}\t{%h0, %b0|%b0, %h0}"
14286 [(set_attr "length" "2")
14287 (set_attr "mode" "HI")])
14290 ;; Thread-local storage patterns for ELF.
14292 ;; Note that these code sequences must appear exactly as shown
14293 ;; in order to allow linker relaxation.
14295 (define_insn "*tls_global_dynamic_32_gnu"
14296 [(set (match_operand:SI 0 "register_operand" "=a")
14298 [(match_operand:SI 1 "register_operand" "Yb")
14299 (match_operand 2 "tls_symbolic_operand")
14300 (match_operand 3 "constant_call_address_operand" "Bz")
14303 (clobber (match_scratch:SI 4 "=d"))
14304 (clobber (match_scratch:SI 5 "=c"))
14305 (clobber (reg:CC FLAGS_REG))]
14306 "!TARGET_64BIT && TARGET_GNU_TLS"
14308 if (TARGET_SUN_TLS || flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT)
14310 ("lea{l}\t{%E2@tlsgd(,%1,1), %0|%0, %E2@tlsgd[%1*1]}", operands);
14313 ("lea{l}\t{%E2@tlsgd(%1), %0|%0, %E2@tlsgd[%1]}", operands);
14314 if (TARGET_SUN_TLS)
14315 #ifdef HAVE_AS_IX86_TLSGDPLT
14316 return "call\t%a2@tlsgdplt";
14318 return "call\t%p3@plt";
14320 if (flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT)
14321 return "call\t%P3";
14322 return "call\t{*%p3@GOT(%1)|[DWORD PTR %p3@GOT[%1]]}";
14324 [(set_attr "type" "multi")
14325 (set_attr "length" "12")])
14327 (define_expand "tls_global_dynamic_32"
14329 [(set (match_operand:SI 0 "register_operand")
14330 (unspec:SI [(match_operand:SI 2 "register_operand")
14331 (match_operand 1 "tls_symbolic_operand")
14332 (match_operand 3 "constant_call_address_operand")
14335 (clobber (match_scratch:SI 4))
14336 (clobber (match_scratch:SI 5))
14337 (clobber (reg:CC FLAGS_REG))])]
14339 "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
14341 (define_insn "*tls_global_dynamic_64_<mode>"
14342 [(set (match_operand:P 0 "register_operand" "=a")
14344 (mem:QI (match_operand 2 "constant_call_address_operand" "Bz"))
14345 (match_operand 3)))
14346 (unspec:P [(match_operand 1 "tls_symbolic_operand")
14352 fputs (ASM_BYTE "0x66\n", asm_out_file);
14354 ("lea{q}\t{%E1@tlsgd(%%rip), %%rdi|rdi, %E1@tlsgd[rip]}", operands);
14355 if (TARGET_SUN_TLS || flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT)
14356 fputs (ASM_SHORT "0x6666\n", asm_out_file);
14358 fputs (ASM_BYTE "0x66\n", asm_out_file);
14359 fputs ("\trex64\n", asm_out_file);
14360 if (TARGET_SUN_TLS)
14361 return "call\t%p2@plt";
14362 if (flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT)
14363 return "call\t%P2";
14364 return "call\t{*%p2@GOTPCREL(%%rip)|[QWORD PTR %p2@GOTPCREL[rip]]}";
14366 [(set_attr "type" "multi")
14367 (set (attr "length")
14368 (symbol_ref "TARGET_X32 ? 15 : 16"))])
14370 (define_insn "*tls_global_dynamic_64_largepic"
14371 [(set (match_operand:DI 0 "register_operand" "=a")
14373 (mem:QI (plus:DI (match_operand:DI 2 "register_operand" "b")
14374 (match_operand:DI 3 "immediate_operand" "i")))
14375 (match_operand 4)))
14376 (unspec:DI [(match_operand 1 "tls_symbolic_operand")
14379 "TARGET_64BIT && ix86_cmodel == CM_LARGE_PIC && !TARGET_PECOFF
14380 && GET_CODE (operands[3]) == CONST
14381 && GET_CODE (XEXP (operands[3], 0)) == UNSPEC
14382 && XINT (XEXP (operands[3], 0), 1) == UNSPEC_PLTOFF"
14385 ("lea{q}\t{%E1@tlsgd(%%rip), %%rdi|rdi, %E1@tlsgd[rip]}", operands);
14386 output_asm_insn ("movabs{q}\t{%3, %%rax|rax, %3}", operands);
14387 output_asm_insn ("add{q}\t{%2, %%rax|rax, %2}", operands);
14388 return "call\t{*%%rax|rax}";
14390 [(set_attr "type" "multi")
14391 (set_attr "length" "22")])
14393 (define_expand "tls_global_dynamic_64_<mode>"
14395 [(set (match_operand:P 0 "register_operand")
14397 (mem:QI (match_operand 2))
14399 (unspec:P [(match_operand 1 "tls_symbolic_operand")
14403 "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
14405 (define_insn "*tls_local_dynamic_base_32_gnu"
14406 [(set (match_operand:SI 0 "register_operand" "=a")
14408 [(match_operand:SI 1 "register_operand" "Yb")
14409 (match_operand 2 "constant_call_address_operand" "Bz")
14411 UNSPEC_TLS_LD_BASE))
14412 (clobber (match_scratch:SI 3 "=d"))
14413 (clobber (match_scratch:SI 4 "=c"))
14414 (clobber (reg:CC FLAGS_REG))]
14415 "!TARGET_64BIT && TARGET_GNU_TLS"
14418 ("lea{l}\t{%&@tlsldm(%1), %0|%0, %&@tlsldm[%1]}", operands);
14419 if (TARGET_SUN_TLS)
14421 if (HAVE_AS_IX86_TLSLDMPLT)
14422 return "call\t%&@tlsldmplt";
14424 return "call\t%p2@plt";
14426 if (flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT)
14427 return "call\t%P2";
14428 return "call\t{*%p2@GOT(%1)|[DWORD PTR %p2@GOT[%1]]}";
14430 [(set_attr "type" "multi")
14431 (set_attr "length" "11")])
14433 (define_expand "tls_local_dynamic_base_32"
14435 [(set (match_operand:SI 0 "register_operand")
14437 [(match_operand:SI 1 "register_operand")
14438 (match_operand 2 "constant_call_address_operand")
14440 UNSPEC_TLS_LD_BASE))
14441 (clobber (match_scratch:SI 3))
14442 (clobber (match_scratch:SI 4))
14443 (clobber (reg:CC FLAGS_REG))])]
14445 "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
14447 (define_insn "*tls_local_dynamic_base_64_<mode>"
14448 [(set (match_operand:P 0 "register_operand" "=a")
14450 (mem:QI (match_operand 1 "constant_call_address_operand" "Bz"))
14451 (match_operand 2)))
14452 (unspec:P [(reg:P SP_REG)] UNSPEC_TLS_LD_BASE)]
14456 ("lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}", operands);
14457 if (TARGET_SUN_TLS)
14458 return "call\t%p1@plt";
14459 if (flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT)
14460 return "call\t%P1";
14461 return "call\t{*%p1@GOTPCREL(%%rip)|[QWORD PTR %p1@GOTPCREL[rip]]}";
14463 [(set_attr "type" "multi")
14464 (set_attr "length" "12")])
14466 (define_insn "*tls_local_dynamic_base_64_largepic"
14467 [(set (match_operand:DI 0 "register_operand" "=a")
14469 (mem:QI (plus:DI (match_operand:DI 1 "register_operand" "b")
14470 (match_operand:DI 2 "immediate_operand" "i")))
14471 (match_operand 3)))
14472 (unspec:DI [(reg:DI SP_REG)] UNSPEC_TLS_LD_BASE)]
14473 "TARGET_64BIT && ix86_cmodel == CM_LARGE_PIC && !TARGET_PECOFF
14474 && GET_CODE (operands[2]) == CONST
14475 && GET_CODE (XEXP (operands[2], 0)) == UNSPEC
14476 && XINT (XEXP (operands[2], 0), 1) == UNSPEC_PLTOFF"
14479 ("lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}", operands);
14480 output_asm_insn ("movabs{q}\t{%2, %%rax|rax, %2}", operands);
14481 output_asm_insn ("add{q}\t{%1, %%rax|rax, %1}", operands);
14482 return "call\t{*%%rax|rax}";
14484 [(set_attr "type" "multi")
14485 (set_attr "length" "22")])
14487 (define_expand "tls_local_dynamic_base_64_<mode>"
14489 [(set (match_operand:P 0 "register_operand")
14491 (mem:QI (match_operand 1))
14493 (unspec:P [(reg:P SP_REG)] UNSPEC_TLS_LD_BASE)])]
14495 "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
14497 ;; Local dynamic of a single variable is a lose. Show combine how
14498 ;; to convert that back to global dynamic.
14500 (define_insn_and_split "*tls_local_dynamic_32_once"
14501 [(set (match_operand:SI 0 "register_operand" "=a")
14503 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14504 (match_operand 2 "constant_call_address_operand" "Bz")
14506 UNSPEC_TLS_LD_BASE)
14507 (const:SI (unspec:SI
14508 [(match_operand 3 "tls_symbolic_operand")]
14510 (clobber (match_scratch:SI 4 "=d"))
14511 (clobber (match_scratch:SI 5 "=c"))
14512 (clobber (reg:CC FLAGS_REG))]
14517 [(set (match_dup 0)
14518 (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)
14521 (clobber (match_dup 4))
14522 (clobber (match_dup 5))
14523 (clobber (reg:CC FLAGS_REG))])])
14525 ;; Load and add the thread base pointer from %<tp_seg>:0.
14526 (define_insn_and_split "*load_tp_<mode>"
14527 [(set (match_operand:PTR 0 "register_operand" "=r")
14528 (unspec:PTR [(const_int 0)] UNSPEC_TP))]
14532 [(set (match_dup 0)
14535 addr_space_t as = DEFAULT_TLS_SEG_REG;
14537 operands[1] = gen_const_mem (<MODE>mode, const0_rtx);
14538 set_mem_addr_space (operands[1], as);
14541 (define_insn_and_split "*load_tp_x32_zext"
14542 [(set (match_operand:DI 0 "register_operand" "=r")
14544 (unspec:SI [(const_int 0)] UNSPEC_TP)))]
14548 [(set (match_dup 0)
14549 (zero_extend:DI (match_dup 1)))]
14551 addr_space_t as = DEFAULT_TLS_SEG_REG;
14553 operands[1] = gen_const_mem (SImode, const0_rtx);
14554 set_mem_addr_space (operands[1], as);
14557 (define_insn_and_split "*add_tp_<mode>"
14558 [(set (match_operand:PTR 0 "register_operand" "=r")
14560 (unspec:PTR [(const_int 0)] UNSPEC_TP)
14561 (match_operand:PTR 1 "register_operand" "0")))
14562 (clobber (reg:CC FLAGS_REG))]
14567 [(set (match_dup 0)
14568 (plus:PTR (match_dup 1) (match_dup 2)))
14569 (clobber (reg:CC FLAGS_REG))])]
14571 addr_space_t as = DEFAULT_TLS_SEG_REG;
14573 operands[2] = gen_const_mem (<MODE>mode, const0_rtx);
14574 set_mem_addr_space (operands[2], as);
14577 (define_insn_and_split "*add_tp_x32_zext"
14578 [(set (match_operand:DI 0 "register_operand" "=r")
14580 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
14581 (match_operand:SI 1 "register_operand" "0"))))
14582 (clobber (reg:CC FLAGS_REG))]
14587 [(set (match_dup 0)
14589 (plus:SI (match_dup 1) (match_dup 2))))
14590 (clobber (reg:CC FLAGS_REG))])]
14592 addr_space_t as = DEFAULT_TLS_SEG_REG;
14594 operands[2] = gen_const_mem (SImode, const0_rtx);
14595 set_mem_addr_space (operands[2], as);
14598 ;; The Sun linker took the AMD64 TLS spec literally and can only handle
14599 ;; %rax as destination of the initial executable code sequence.
14600 (define_insn "tls_initial_exec_64_sun"
14601 [(set (match_operand:DI 0 "register_operand" "=a")
14603 [(match_operand 1 "tls_symbolic_operand")]
14604 UNSPEC_TLS_IE_SUN))
14605 (clobber (reg:CC FLAGS_REG))]
14606 "TARGET_64BIT && TARGET_SUN_TLS"
14609 ("mov{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}", operands);
14610 return "add{q}\t{%a1@gottpoff(%%rip), %0|%0, %a1@gottpoff[rip]}";
14612 [(set_attr "type" "multi")])
14614 ;; GNU2 TLS patterns can be split.
14616 (define_expand "tls_dynamic_gnu2_32"
14617 [(set (match_dup 3)
14618 (plus:SI (match_operand:SI 2 "register_operand")
14620 (unspec:SI [(match_operand 1 "tls_symbolic_operand")]
14623 [(set (match_operand:SI 0 "register_operand")
14624 (unspec:SI [(match_dup 1) (match_dup 3)
14625 (match_dup 2) (reg:SI SP_REG)]
14627 (clobber (reg:CC FLAGS_REG))])]
14628 "!TARGET_64BIT && TARGET_GNU2_TLS"
14630 operands[3] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
14631 ix86_tls_descriptor_calls_expanded_in_cfun = true;
14634 (define_insn "*tls_dynamic_gnu2_lea_32"
14635 [(set (match_operand:SI 0 "register_operand" "=r")
14636 (plus:SI (match_operand:SI 1 "register_operand" "b")
14638 (unspec:SI [(match_operand 2 "tls_symbolic_operand")]
14639 UNSPEC_TLSDESC))))]
14640 "!TARGET_64BIT && TARGET_GNU2_TLS"
14641 "lea{l}\t{%E2@TLSDESC(%1), %0|%0, %E2@TLSDESC[%1]}"
14642 [(set_attr "type" "lea")
14643 (set_attr "mode" "SI")
14644 (set_attr "length" "6")
14645 (set_attr "length_address" "4")])
14647 (define_insn "*tls_dynamic_gnu2_call_32"
14648 [(set (match_operand:SI 0 "register_operand" "=a")
14649 (unspec:SI [(match_operand 1 "tls_symbolic_operand")
14650 (match_operand:SI 2 "register_operand" "0")
14651 ;; we have to make sure %ebx still points to the GOT
14652 (match_operand:SI 3 "register_operand" "b")
14655 (clobber (reg:CC FLAGS_REG))]
14656 "!TARGET_64BIT && TARGET_GNU2_TLS"
14657 "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
14658 [(set_attr "type" "call")
14659 (set_attr "length" "2")
14660 (set_attr "length_address" "0")])
14662 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
14663 [(set (match_operand:SI 0 "register_operand" "=&a")
14665 (unspec:SI [(match_operand 3 "tls_modbase_operand")
14666 (match_operand:SI 4)
14667 (match_operand:SI 2 "register_operand" "b")
14670 (const:SI (unspec:SI
14671 [(match_operand 1 "tls_symbolic_operand")]
14673 (clobber (reg:CC FLAGS_REG))]
14674 "!TARGET_64BIT && TARGET_GNU2_TLS"
14677 [(set (match_dup 0) (match_dup 5))]
14679 operands[5] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
14680 emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
14683 (define_expand "tls_dynamic_gnu2_64"
14684 [(set (match_dup 2)
14685 (unspec:DI [(match_operand 1 "tls_symbolic_operand")]
14688 [(set (match_operand:DI 0 "register_operand")
14689 (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
14691 (clobber (reg:CC FLAGS_REG))])]
14692 "TARGET_64BIT && TARGET_GNU2_TLS"
14694 operands[2] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
14695 ix86_tls_descriptor_calls_expanded_in_cfun = true;
14698 (define_insn "*tls_dynamic_gnu2_lea_64"
14699 [(set (match_operand:DI 0 "register_operand" "=r")
14700 (unspec:DI [(match_operand 1 "tls_symbolic_operand")]
14702 "TARGET_64BIT && TARGET_GNU2_TLS"
14703 "lea{q}\t{%E1@TLSDESC(%%rip), %0|%0, %E1@TLSDESC[rip]}"
14704 [(set_attr "type" "lea")
14705 (set_attr "mode" "DI")
14706 (set_attr "length" "7")
14707 (set_attr "length_address" "4")])
14709 (define_insn "*tls_dynamic_gnu2_call_64"
14710 [(set (match_operand:DI 0 "register_operand" "=a")
14711 (unspec:DI [(match_operand 1 "tls_symbolic_operand")
14712 (match_operand:DI 2 "register_operand" "0")
14715 (clobber (reg:CC FLAGS_REG))]
14716 "TARGET_64BIT && TARGET_GNU2_TLS"
14717 "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
14718 [(set_attr "type" "call")
14719 (set_attr "length" "2")
14720 (set_attr "length_address" "0")])
14722 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
14723 [(set (match_operand:DI 0 "register_operand" "=&a")
14725 (unspec:DI [(match_operand 2 "tls_modbase_operand")
14726 (match_operand:DI 3)
14729 (const:DI (unspec:DI
14730 [(match_operand 1 "tls_symbolic_operand")]
14732 (clobber (reg:CC FLAGS_REG))]
14733 "TARGET_64BIT && TARGET_GNU2_TLS"
14736 [(set (match_dup 0) (match_dup 4))]
14738 operands[4] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
14739 emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
14743 [(match_operand 0 "tls_address_pattern")]
14744 "TARGET_TLS_DIRECT_SEG_REFS"
14746 "operands[0] = ix86_rewrite_tls_address (operands[0]);")
14749 ;; These patterns match the binary 387 instructions for addM3, subM3,
14750 ;; mulM3 and divM3. There are three patterns for each of DFmode and
14751 ;; SFmode. The first is the normal insn, the second the same insn but
14752 ;; with one operand a conversion, and the third the same insn but with
14753 ;; the other operand a conversion. The conversion may be SFmode or
14754 ;; SImode if the target mode DFmode, but only SImode if the target mode
14757 ;; Gcc is slightly more smart about handling normal two address instructions
14758 ;; so use special patterns for add and mull.
14760 (define_insn "*fop_<mode>_comm"
14761 [(set (match_operand:MODEF 0 "register_operand" "=f,x,v")
14762 (match_operator:MODEF 3 "binary_fp_operator"
14763 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,0,v")
14764 (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm,vm")]))]
14765 "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14766 || (TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)))
14767 && COMMUTATIVE_ARITH_P (operands[3])
14768 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
14769 "* return output_387_binary_op (insn, operands);"
14770 [(set (attr "type")
14771 (if_then_else (eq_attr "alternative" "1,2")
14772 (if_then_else (match_operand:MODEF 3 "mult_operator")
14773 (const_string "ssemul")
14774 (const_string "sseadd"))
14775 (if_then_else (match_operand:MODEF 3 "mult_operator")
14776 (const_string "fmul")
14777 (const_string "fop"))))
14778 (set_attr "isa" "*,noavx,avx")
14779 (set_attr "prefix" "orig,orig,vex")
14780 (set_attr "mode" "<MODE>")
14781 (set (attr "enabled")
14783 (match_test ("SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"))
14785 (eq_attr "alternative" "0")
14786 (symbol_ref "TARGET_MIX_SSE_I387
14787 && X87_ENABLE_ARITH (<MODE>mode)")
14788 (const_string "*"))
14790 (eq_attr "alternative" "0")
14791 (symbol_ref "true")
14792 (symbol_ref "false"))))])
14794 (define_insn "*rcpsf2_sse"
14795 [(set (match_operand:SF 0 "register_operand" "=x")
14796 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
14798 "TARGET_SSE && TARGET_SSE_MATH"
14799 "%vrcpss\t{%1, %d0|%d0, %1}"
14800 [(set_attr "type" "sse")
14801 (set_attr "atom_sse_attr" "rcp")
14802 (set_attr "btver2_sse_attr" "rcp")
14803 (set_attr "prefix" "maybe_vex")
14804 (set_attr "mode" "SF")])
14806 (define_insn "*fop_<mode>_1"
14807 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,v")
14808 (match_operator:MODEF 3 "binary_fp_operator"
14809 [(match_operand:MODEF 1
14810 "x87nonimm_ssenomem_operand" "0,fm,0,v")
14811 (match_operand:MODEF 2
14812 "nonimmediate_operand" "fm,0,xm,vm")]))]
14813 "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14814 || (TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)))
14815 && !COMMUTATIVE_ARITH_P (operands[3])
14816 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
14817 "* return output_387_binary_op (insn, operands);"
14818 [(set (attr "type")
14819 (if_then_else (eq_attr "alternative" "2,3")
14820 (if_then_else (match_operand:MODEF 3 "div_operator")
14821 (const_string "ssediv")
14822 (const_string "sseadd"))
14823 (if_then_else (match_operand:MODEF 3 "div_operator")
14824 (const_string "fdiv")
14825 (const_string "fop"))))
14826 (set_attr "isa" "*,*,noavx,avx")
14827 (set_attr "prefix" "orig,orig,orig,vex")
14828 (set_attr "mode" "<MODE>")
14829 (set (attr "enabled")
14831 (match_test ("SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"))
14833 (eq_attr "alternative" "0,1")
14834 (symbol_ref "TARGET_MIX_SSE_I387
14835 && X87_ENABLE_ARITH (<MODE>mode)")
14836 (const_string "*"))
14838 (eq_attr "alternative" "0,1")
14839 (symbol_ref "true")
14840 (symbol_ref "false"))))])
14842 ;; ??? Add SSE splitters for these!
14843 (define_insn "*fop_<MODEF:mode>_2_i387"
14844 [(set (match_operand:MODEF 0 "register_operand" "=f")
14845 (match_operator:MODEF 3 "binary_fp_operator"
14847 (match_operand:SWI24 1 "nonimmediate_operand" "m"))
14848 (match_operand:MODEF 2 "register_operand" "0")]))]
14849 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI24:MODE>mode)
14850 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
14851 && (TARGET_USE_<SWI24:MODE>MODE_FIOP
14852 || optimize_function_for_size_p (cfun))"
14853 "* return output_387_binary_op (insn, operands);"
14854 [(set (attr "type")
14855 (cond [(match_operand:MODEF 3 "mult_operator")
14856 (const_string "fmul")
14857 (match_operand:MODEF 3 "div_operator")
14858 (const_string "fdiv")
14860 (const_string "fop")))
14861 (set_attr "fp_int_src" "true")
14862 (set_attr "mode" "<SWI24:MODE>")])
14864 (define_insn "*fop_<MODEF:mode>_3_i387"
14865 [(set (match_operand:MODEF 0 "register_operand" "=f")
14866 (match_operator:MODEF 3 "binary_fp_operator"
14867 [(match_operand:MODEF 1 "register_operand" "0")
14869 (match_operand:SWI24 2 "nonimmediate_operand" "m"))]))]
14870 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI24:MODE>mode)
14871 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
14872 && (TARGET_USE_<SWI24:MODE>MODE_FIOP
14873 || optimize_function_for_size_p (cfun))"
14874 "* return output_387_binary_op (insn, operands);"
14875 [(set (attr "type")
14876 (cond [(match_operand:MODEF 3 "mult_operator")
14877 (const_string "fmul")
14878 (match_operand:MODEF 3 "div_operator")
14879 (const_string "fdiv")
14881 (const_string "fop")))
14882 (set_attr "fp_int_src" "true")
14883 (set_attr "mode" "<MODE>")])
14885 (define_insn "*fop_df_4_i387"
14886 [(set (match_operand:DF 0 "register_operand" "=f,f")
14887 (match_operator:DF 3 "binary_fp_operator"
14889 (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
14890 (match_operand:DF 2 "register_operand" "0,f")]))]
14891 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
14892 && !(SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
14893 "* return output_387_binary_op (insn, operands);"
14894 [(set (attr "type")
14895 (cond [(match_operand:DF 3 "mult_operator")
14896 (const_string "fmul")
14897 (match_operand:DF 3 "div_operator")
14898 (const_string "fdiv")
14900 (const_string "fop")))
14901 (set_attr "mode" "SF")])
14903 (define_insn "*fop_df_5_i387"
14904 [(set (match_operand:DF 0 "register_operand" "=f,f")
14905 (match_operator:DF 3 "binary_fp_operator"
14906 [(match_operand:DF 1 "register_operand" "0,f")
14908 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
14909 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
14910 && !(SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
14911 "* return output_387_binary_op (insn, operands);"
14912 [(set (attr "type")
14913 (cond [(match_operand:DF 3 "mult_operator")
14914 (const_string "fmul")
14915 (match_operand:DF 3 "div_operator")
14916 (const_string "fdiv")
14918 (const_string "fop")))
14919 (set_attr "mode" "SF")])
14921 (define_insn "*fop_df_6_i387"
14922 [(set (match_operand:DF 0 "register_operand" "=f,f")
14923 (match_operator:DF 3 "binary_fp_operator"
14925 (match_operand:SF 1 "register_operand" "0,f"))
14927 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
14928 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
14929 && !(SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
14930 "* return output_387_binary_op (insn, operands);"
14931 [(set (attr "type")
14932 (cond [(match_operand:DF 3 "mult_operator")
14933 (const_string "fmul")
14934 (match_operand:DF 3 "div_operator")
14935 (const_string "fdiv")
14937 (const_string "fop")))
14938 (set_attr "mode" "SF")])
14940 (define_insn "*fop_xf_comm_i387"
14941 [(set (match_operand:XF 0 "register_operand" "=f")
14942 (match_operator:XF 3 "binary_fp_operator"
14943 [(match_operand:XF 1 "register_operand" "%0")
14944 (match_operand:XF 2 "register_operand" "f")]))]
14946 && COMMUTATIVE_ARITH_P (operands[3])"
14947 "* return output_387_binary_op (insn, operands);"
14948 [(set (attr "type")
14949 (if_then_else (match_operand:XF 3 "mult_operator")
14950 (const_string "fmul")
14951 (const_string "fop")))
14952 (set_attr "mode" "XF")])
14954 (define_insn "*fop_xf_1_i387"
14955 [(set (match_operand:XF 0 "register_operand" "=f,f")
14956 (match_operator:XF 3 "binary_fp_operator"
14957 [(match_operand:XF 1 "register_operand" "0,f")
14958 (match_operand:XF 2 "register_operand" "f,0")]))]
14960 && !COMMUTATIVE_ARITH_P (operands[3])"
14961 "* return output_387_binary_op (insn, operands);"
14962 [(set (attr "type")
14963 (if_then_else (match_operand:XF 3 "div_operator")
14964 (const_string "fdiv")
14965 (const_string "fop")))
14966 (set_attr "mode" "XF")])
14968 (define_insn "*fop_xf_2_i387"
14969 [(set (match_operand:XF 0 "register_operand" "=f")
14970 (match_operator:XF 3 "binary_fp_operator"
14972 (match_operand:SWI24 1 "nonimmediate_operand" "m"))
14973 (match_operand:XF 2 "register_operand" "0")]))]
14975 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
14976 "* return output_387_binary_op (insn, operands);"
14977 [(set (attr "type")
14978 (cond [(match_operand:XF 3 "mult_operator")
14979 (const_string "fmul")
14980 (match_operand:XF 3 "div_operator")
14981 (const_string "fdiv")
14983 (const_string "fop")))
14984 (set_attr "fp_int_src" "true")
14985 (set_attr "mode" "<MODE>")])
14987 (define_insn "*fop_xf_3_i387"
14988 [(set (match_operand:XF 0 "register_operand" "=f")
14989 (match_operator:XF 3 "binary_fp_operator"
14990 [(match_operand:XF 1 "register_operand" "0")
14992 (match_operand:SWI24 2 "nonimmediate_operand" "m"))]))]
14994 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
14995 "* return output_387_binary_op (insn, operands);"
14996 [(set (attr "type")
14997 (cond [(match_operand:XF 3 "mult_operator")
14998 (const_string "fmul")
14999 (match_operand:XF 3 "div_operator")
15000 (const_string "fdiv")
15002 (const_string "fop")))
15003 (set_attr "fp_int_src" "true")
15004 (set_attr "mode" "<MODE>")])
15006 (define_insn "*fop_xf_4_i387"
15007 [(set (match_operand:XF 0 "register_operand" "=f,f")
15008 (match_operator:XF 3 "binary_fp_operator"
15010 (match_operand:MODEF 1 "nonimmediate_operand" "fm,0"))
15011 (match_operand:XF 2 "register_operand" "0,f")]))]
15013 "* return output_387_binary_op (insn, operands);"
15014 [(set (attr "type")
15015 (cond [(match_operand:XF 3 "mult_operator")
15016 (const_string "fmul")
15017 (match_operand:XF 3 "div_operator")
15018 (const_string "fdiv")
15020 (const_string "fop")))
15021 (set_attr "mode" "<MODE>")])
15023 (define_insn "*fop_xf_5_i387"
15024 [(set (match_operand:XF 0 "register_operand" "=f,f")
15025 (match_operator:XF 3 "binary_fp_operator"
15026 [(match_operand:XF 1 "register_operand" "0,f")
15028 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
15030 "* return output_387_binary_op (insn, operands);"
15031 [(set (attr "type")
15032 (cond [(match_operand:XF 3 "mult_operator")
15033 (const_string "fmul")
15034 (match_operand:XF 3 "div_operator")
15035 (const_string "fdiv")
15037 (const_string "fop")))
15038 (set_attr "mode" "<MODE>")])
15040 (define_insn "*fop_xf_6_i387"
15041 [(set (match_operand:XF 0 "register_operand" "=f,f")
15042 (match_operator:XF 3 "binary_fp_operator"
15044 (match_operand:MODEF 1 "register_operand" "0,f"))
15046 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
15048 "* return output_387_binary_op (insn, operands);"
15049 [(set (attr "type")
15050 (cond [(match_operand:XF 3 "mult_operator")
15051 (const_string "fmul")
15052 (match_operand:XF 3 "div_operator")
15053 (const_string "fdiv")
15055 (const_string "fop")))
15056 (set_attr "mode" "<MODE>")])
15058 ;; FPU special functions.
15060 ;; This pattern implements a no-op XFmode truncation for
15061 ;; all fancy i386 XFmode math functions.
15063 (define_insn "truncxf<mode>2_i387_noop_unspec"
15064 [(set (match_operand:MODEF 0 "register_operand" "=f")
15065 (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")]
15066 UNSPEC_TRUNC_NOOP))]
15067 "TARGET_USE_FANCY_MATH_387"
15068 "* return output_387_reg_move (insn, operands);"
15069 [(set_attr "type" "fmov")
15070 (set_attr "mode" "<MODE>")])
15072 (define_insn "sqrtxf2"
15073 [(set (match_operand:XF 0 "register_operand" "=f")
15074 (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
15075 "TARGET_USE_FANCY_MATH_387"
15077 [(set_attr "type" "fpspc")
15078 (set_attr "mode" "XF")
15079 (set_attr "athlon_decode" "direct")
15080 (set_attr "amdfam10_decode" "direct")
15081 (set_attr "bdver1_decode" "direct")])
15083 (define_insn "sqrt_extend<mode>xf2_i387"
15084 [(set (match_operand:XF 0 "register_operand" "=f")
15087 (match_operand:MODEF 1 "register_operand" "0"))))]
15088 "TARGET_USE_FANCY_MATH_387"
15090 [(set_attr "type" "fpspc")
15091 (set_attr "mode" "XF")
15092 (set_attr "athlon_decode" "direct")
15093 (set_attr "amdfam10_decode" "direct")
15094 (set_attr "bdver1_decode" "direct")])
15096 (define_insn "*rsqrtsf2_sse"
15097 [(set (match_operand:SF 0 "register_operand" "=x")
15098 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
15100 "TARGET_SSE && TARGET_SSE_MATH"
15101 "%vrsqrtss\t{%1, %d0|%d0, %1}"
15102 [(set_attr "type" "sse")
15103 (set_attr "atom_sse_attr" "rcp")
15104 (set_attr "btver2_sse_attr" "rcp")
15105 (set_attr "prefix" "maybe_vex")
15106 (set_attr "mode" "SF")])
15108 (define_expand "rsqrtsf2"
15109 [(set (match_operand:SF 0 "register_operand")
15110 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand")]
15112 "TARGET_SSE && TARGET_SSE_MATH"
15114 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
15118 (define_insn "*sqrt<mode>2_sse"
15119 [(set (match_operand:MODEF 0 "register_operand" "=v")
15121 (match_operand:MODEF 1 "nonimmediate_operand" "vm")))]
15122 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
15123 "%vsqrt<ssemodesuffix>\t{%1, %d0|%d0, %1}"
15124 [(set_attr "type" "sse")
15125 (set_attr "atom_sse_attr" "sqrt")
15126 (set_attr "btver2_sse_attr" "sqrt")
15127 (set_attr "prefix" "maybe_vex")
15128 (set_attr "mode" "<MODE>")
15129 (set_attr "athlon_decode" "*")
15130 (set_attr "amdfam10_decode" "*")
15131 (set_attr "bdver1_decode" "*")])
15133 (define_expand "sqrt<mode>2"
15134 [(set (match_operand:MODEF 0 "register_operand")
15136 (match_operand:MODEF 1 "nonimmediate_operand")))]
15137 "(TARGET_USE_FANCY_MATH_387 && X87_ENABLE_ARITH (<MODE>mode))
15138 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
15140 if (<MODE>mode == SFmode
15141 && TARGET_SSE && TARGET_SSE_MATH
15142 && TARGET_RECIP_SQRT
15143 && !optimize_function_for_size_p (cfun)
15144 && flag_finite_math_only && !flag_trapping_math
15145 && flag_unsafe_math_optimizations)
15147 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
15151 if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
15153 rtx op0 = gen_reg_rtx (XFmode);
15154 rtx op1 = force_reg (<MODE>mode, operands[1]);
15156 emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
15157 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
15162 (define_insn "fpremxf4_i387"
15163 [(set (match_operand:XF 0 "register_operand" "=f")
15164 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15165 (match_operand:XF 3 "register_operand" "1")]
15167 (set (match_operand:XF 1 "register_operand" "=u")
15168 (unspec:XF [(match_dup 2) (match_dup 3)]
15170 (set (reg:CCFP FPSR_REG)
15171 (unspec:CCFP [(match_dup 2) (match_dup 3)]
15173 "TARGET_USE_FANCY_MATH_387
15174 && flag_finite_math_only"
15176 [(set_attr "type" "fpspc")
15177 (set_attr "znver1_decode" "vector")
15178 (set_attr "mode" "XF")])
15180 (define_expand "fmodxf3"
15181 [(use (match_operand:XF 0 "register_operand"))
15182 (use (match_operand:XF 1 "general_operand"))
15183 (use (match_operand:XF 2 "general_operand"))]
15184 "TARGET_USE_FANCY_MATH_387
15185 && flag_finite_math_only"
15187 rtx_code_label *label = gen_label_rtx ();
15189 rtx op1 = gen_reg_rtx (XFmode);
15190 rtx op2 = gen_reg_rtx (XFmode);
15192 emit_move_insn (op2, operands[2]);
15193 emit_move_insn (op1, operands[1]);
15195 emit_label (label);
15196 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
15197 ix86_emit_fp_unordered_jump (label);
15198 LABEL_NUSES (label) = 1;
15200 emit_move_insn (operands[0], op1);
15204 (define_expand "fmod<mode>3"
15205 [(use (match_operand:MODEF 0 "register_operand"))
15206 (use (match_operand:MODEF 1 "general_operand"))
15207 (use (match_operand:MODEF 2 "general_operand"))]
15208 "TARGET_USE_FANCY_MATH_387
15209 && flag_finite_math_only"
15211 rtx (*gen_truncxf) (rtx, rtx);
15213 rtx_code_label *label = gen_label_rtx ();
15215 rtx op1 = gen_reg_rtx (XFmode);
15216 rtx op2 = gen_reg_rtx (XFmode);
15218 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
15219 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15221 emit_label (label);
15222 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
15223 ix86_emit_fp_unordered_jump (label);
15224 LABEL_NUSES (label) = 1;
15226 /* Truncate the result properly for strict SSE math. */
15227 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15228 && !TARGET_MIX_SSE_I387)
15229 gen_truncxf = gen_truncxf<mode>2;
15231 gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
15233 emit_insn (gen_truncxf (operands[0], op1));
15237 (define_insn "fprem1xf4_i387"
15238 [(set (match_operand:XF 0 "register_operand" "=f")
15239 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15240 (match_operand:XF 3 "register_operand" "1")]
15242 (set (match_operand:XF 1 "register_operand" "=u")
15243 (unspec:XF [(match_dup 2) (match_dup 3)]
15245 (set (reg:CCFP FPSR_REG)
15246 (unspec:CCFP [(match_dup 2) (match_dup 3)]
15248 "TARGET_USE_FANCY_MATH_387
15249 && flag_finite_math_only"
15251 [(set_attr "type" "fpspc")
15252 (set_attr "znver1_decode" "vector")
15253 (set_attr "mode" "XF")])
15255 (define_expand "remainderxf3"
15256 [(use (match_operand:XF 0 "register_operand"))
15257 (use (match_operand:XF 1 "general_operand"))
15258 (use (match_operand:XF 2 "general_operand"))]
15259 "TARGET_USE_FANCY_MATH_387
15260 && flag_finite_math_only"
15262 rtx_code_label *label = gen_label_rtx ();
15264 rtx op1 = gen_reg_rtx (XFmode);
15265 rtx op2 = gen_reg_rtx (XFmode);
15267 emit_move_insn (op2, operands[2]);
15268 emit_move_insn (op1, operands[1]);
15270 emit_label (label);
15271 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
15272 ix86_emit_fp_unordered_jump (label);
15273 LABEL_NUSES (label) = 1;
15275 emit_move_insn (operands[0], op1);
15279 (define_expand "remainder<mode>3"
15280 [(use (match_operand:MODEF 0 "register_operand"))
15281 (use (match_operand:MODEF 1 "general_operand"))
15282 (use (match_operand:MODEF 2 "general_operand"))]
15283 "TARGET_USE_FANCY_MATH_387
15284 && flag_finite_math_only"
15286 rtx (*gen_truncxf) (rtx, rtx);
15288 rtx_code_label *label = gen_label_rtx ();
15290 rtx op1 = gen_reg_rtx (XFmode);
15291 rtx op2 = gen_reg_rtx (XFmode);
15293 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
15294 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15296 emit_label (label);
15298 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
15299 ix86_emit_fp_unordered_jump (label);
15300 LABEL_NUSES (label) = 1;
15302 /* Truncate the result properly for strict SSE math. */
15303 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15304 && !TARGET_MIX_SSE_I387)
15305 gen_truncxf = gen_truncxf<mode>2;
15307 gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
15309 emit_insn (gen_truncxf (operands[0], op1));
15313 (define_int_iterator SINCOS
15317 (define_int_attr sincos
15318 [(UNSPEC_SIN "sin")
15319 (UNSPEC_COS "cos")])
15321 (define_insn "*<sincos>xf2_i387"
15322 [(set (match_operand:XF 0 "register_operand" "=f")
15323 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15325 "TARGET_USE_FANCY_MATH_387
15326 && flag_unsafe_math_optimizations"
15328 [(set_attr "type" "fpspc")
15329 (set_attr "znver1_decode" "vector")
15330 (set_attr "mode" "XF")])
15332 (define_insn "*<sincos>_extend<mode>xf2_i387"
15333 [(set (match_operand:XF 0 "register_operand" "=f")
15334 (unspec:XF [(float_extend:XF
15335 (match_operand:MODEF 1 "register_operand" "0"))]
15337 "TARGET_USE_FANCY_MATH_387
15338 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15339 || TARGET_MIX_SSE_I387)
15340 && flag_unsafe_math_optimizations"
15342 [(set_attr "type" "fpspc")
15343 (set_attr "znver1_decode" "vector")
15344 (set_attr "mode" "XF")])
15346 ;; When sincos pattern is defined, sin and cos builtin functions will be
15347 ;; expanded to sincos pattern with one of its outputs left unused.
15348 ;; CSE pass will figure out if two sincos patterns can be combined,
15349 ;; otherwise sincos pattern will be split back to sin or cos pattern,
15350 ;; depending on the unused output.
15352 (define_insn "sincosxf3"
15353 [(set (match_operand:XF 0 "register_operand" "=f")
15354 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15355 UNSPEC_SINCOS_COS))
15356 (set (match_operand:XF 1 "register_operand" "=u")
15357 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15358 "TARGET_USE_FANCY_MATH_387
15359 && flag_unsafe_math_optimizations"
15361 [(set_attr "type" "fpspc")
15362 (set_attr "znver1_decode" "vector")
15363 (set_attr "mode" "XF")])
15366 [(set (match_operand:XF 0 "register_operand")
15367 (unspec:XF [(match_operand:XF 2 "register_operand")]
15368 UNSPEC_SINCOS_COS))
15369 (set (match_operand:XF 1 "register_operand")
15370 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15371 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15372 && can_create_pseudo_p ()"
15373 [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))])
15376 [(set (match_operand:XF 0 "register_operand")
15377 (unspec:XF [(match_operand:XF 2 "register_operand")]
15378 UNSPEC_SINCOS_COS))
15379 (set (match_operand:XF 1 "register_operand")
15380 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15381 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15382 && can_create_pseudo_p ()"
15383 [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))])
15385 (define_insn "sincos_extend<mode>xf3_i387"
15386 [(set (match_operand:XF 0 "register_operand" "=f")
15387 (unspec:XF [(float_extend:XF
15388 (match_operand:MODEF 2 "register_operand" "0"))]
15389 UNSPEC_SINCOS_COS))
15390 (set (match_operand:XF 1 "register_operand" "=u")
15391 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
15392 "TARGET_USE_FANCY_MATH_387
15393 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15394 || TARGET_MIX_SSE_I387)
15395 && flag_unsafe_math_optimizations"
15397 [(set_attr "type" "fpspc")
15398 (set_attr "znver1_decode" "vector")
15399 (set_attr "mode" "XF")])
15402 [(set (match_operand:XF 0 "register_operand")
15403 (unspec:XF [(float_extend:XF
15404 (match_operand:MODEF 2 "register_operand"))]
15405 UNSPEC_SINCOS_COS))
15406 (set (match_operand:XF 1 "register_operand")
15407 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
15408 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15409 && can_create_pseudo_p ()"
15410 [(set (match_dup 1)
15411 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))])
15414 [(set (match_operand:XF 0 "register_operand")
15415 (unspec:XF [(float_extend:XF
15416 (match_operand:MODEF 2 "register_operand"))]
15417 UNSPEC_SINCOS_COS))
15418 (set (match_operand:XF 1 "register_operand")
15419 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
15420 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15421 && can_create_pseudo_p ()"
15422 [(set (match_dup 0)
15423 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))])
15425 (define_expand "sincos<mode>3"
15426 [(use (match_operand:MODEF 0 "register_operand"))
15427 (use (match_operand:MODEF 1 "register_operand"))
15428 (use (match_operand:MODEF 2 "register_operand"))]
15429 "TARGET_USE_FANCY_MATH_387
15430 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15431 || TARGET_MIX_SSE_I387)
15432 && flag_unsafe_math_optimizations"
15434 rtx op0 = gen_reg_rtx (XFmode);
15435 rtx op1 = gen_reg_rtx (XFmode);
15437 emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
15438 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15439 emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
15443 (define_insn "fptanxf4_i387"
15444 [(set (match_operand:XF 0 "register_operand" "=f")
15445 (match_operand:XF 3 "const_double_operand" "F"))
15446 (set (match_operand:XF 1 "register_operand" "=u")
15447 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15449 "TARGET_USE_FANCY_MATH_387
15450 && flag_unsafe_math_optimizations
15451 && standard_80387_constant_p (operands[3]) == 2"
15453 [(set_attr "type" "fpspc")
15454 (set_attr "znver1_decode" "vector")
15455 (set_attr "mode" "XF")])
15457 (define_insn "fptan_extend<mode>xf4_i387"
15458 [(set (match_operand:MODEF 0 "register_operand" "=f")
15459 (match_operand:MODEF 3 "const_double_operand" "F"))
15460 (set (match_operand:XF 1 "register_operand" "=u")
15461 (unspec:XF [(float_extend:XF
15462 (match_operand:MODEF 2 "register_operand" "0"))]
15464 "TARGET_USE_FANCY_MATH_387
15465 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15466 || TARGET_MIX_SSE_I387)
15467 && flag_unsafe_math_optimizations
15468 && standard_80387_constant_p (operands[3]) == 2"
15470 [(set_attr "type" "fpspc")
15471 (set_attr "znver1_decode" "vector")
15472 (set_attr "mode" "XF")])
15474 (define_expand "tanxf2"
15475 [(use (match_operand:XF 0 "register_operand"))
15476 (use (match_operand:XF 1 "register_operand"))]
15477 "TARGET_USE_FANCY_MATH_387
15478 && flag_unsafe_math_optimizations"
15480 rtx one = gen_reg_rtx (XFmode);
15481 rtx op2 = CONST1_RTX (XFmode); /* fld1 */
15483 emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2));
15487 (define_expand "tan<mode>2"
15488 [(use (match_operand:MODEF 0 "register_operand"))
15489 (use (match_operand:MODEF 1 "register_operand"))]
15490 "TARGET_USE_FANCY_MATH_387
15491 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15492 || TARGET_MIX_SSE_I387)
15493 && flag_unsafe_math_optimizations"
15495 rtx op0 = gen_reg_rtx (XFmode);
15497 rtx one = gen_reg_rtx (<MODE>mode);
15498 rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */
15500 emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
15501 operands[1], op2));
15502 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15506 (define_insn "*fpatanxf3_i387"
15507 [(set (match_operand:XF 0 "register_operand" "=f")
15508 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
15509 (match_operand:XF 2 "register_operand" "u")]
15511 (clobber (match_scratch:XF 3 "=2"))]
15512 "TARGET_USE_FANCY_MATH_387
15513 && flag_unsafe_math_optimizations"
15515 [(set_attr "type" "fpspc")
15516 (set_attr "znver1_decode" "vector")
15517 (set_attr "mode" "XF")])
15519 (define_insn "fpatan_extend<mode>xf3_i387"
15520 [(set (match_operand:XF 0 "register_operand" "=f")
15521 (unspec:XF [(float_extend:XF
15522 (match_operand:MODEF 1 "register_operand" "0"))
15524 (match_operand:MODEF 2 "register_operand" "u"))]
15526 (clobber (match_scratch:XF 3 "=2"))]
15527 "TARGET_USE_FANCY_MATH_387
15528 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15529 || TARGET_MIX_SSE_I387)
15530 && flag_unsafe_math_optimizations"
15532 [(set_attr "type" "fpspc")
15533 (set_attr "znver1_decode" "vector")
15534 (set_attr "mode" "XF")])
15536 (define_expand "atan2xf3"
15537 [(parallel [(set (match_operand:XF 0 "register_operand")
15538 (unspec:XF [(match_operand:XF 2 "register_operand")
15539 (match_operand:XF 1 "register_operand")]
15541 (clobber (match_scratch:XF 3))])]
15542 "TARGET_USE_FANCY_MATH_387
15543 && flag_unsafe_math_optimizations")
15545 (define_expand "atan2<mode>3"
15546 [(use (match_operand:MODEF 0 "register_operand"))
15547 (use (match_operand:MODEF 1 "register_operand"))
15548 (use (match_operand:MODEF 2 "register_operand"))]
15549 "TARGET_USE_FANCY_MATH_387
15550 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15551 || TARGET_MIX_SSE_I387)
15552 && flag_unsafe_math_optimizations"
15554 rtx op0 = gen_reg_rtx (XFmode);
15556 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
15557 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15561 (define_expand "atanxf2"
15562 [(parallel [(set (match_operand:XF 0 "register_operand")
15563 (unspec:XF [(match_dup 2)
15564 (match_operand:XF 1 "register_operand")]
15566 (clobber (match_scratch:XF 3))])]
15567 "TARGET_USE_FANCY_MATH_387
15568 && flag_unsafe_math_optimizations"
15570 operands[2] = gen_reg_rtx (XFmode);
15571 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
15574 (define_expand "atan<mode>2"
15575 [(use (match_operand:MODEF 0 "register_operand"))
15576 (use (match_operand:MODEF 1 "register_operand"))]
15577 "TARGET_USE_FANCY_MATH_387
15578 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15579 || TARGET_MIX_SSE_I387)
15580 && flag_unsafe_math_optimizations"
15582 rtx op0 = gen_reg_rtx (XFmode);
15584 rtx op2 = gen_reg_rtx (<MODE>mode);
15585 emit_move_insn (op2, CONST1_RTX (<MODE>mode)); /* fld1 */
15587 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1]));
15588 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15592 (define_expand "asinxf2"
15593 [(set (match_dup 2)
15594 (mult:XF (match_operand:XF 1 "register_operand")
15596 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
15597 (set (match_dup 5) (sqrt:XF (match_dup 4)))
15598 (parallel [(set (match_operand:XF 0 "register_operand")
15599 (unspec:XF [(match_dup 5) (match_dup 1)]
15601 (clobber (match_scratch:XF 6))])]
15602 "TARGET_USE_FANCY_MATH_387
15603 && flag_unsafe_math_optimizations"
15607 for (i = 2; i < 6; i++)
15608 operands[i] = gen_reg_rtx (XFmode);
15610 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
15613 (define_expand "asin<mode>2"
15614 [(use (match_operand:MODEF 0 "register_operand"))
15615 (use (match_operand:MODEF 1 "general_operand"))]
15616 "TARGET_USE_FANCY_MATH_387
15617 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15618 || TARGET_MIX_SSE_I387)
15619 && flag_unsafe_math_optimizations"
15621 rtx op0 = gen_reg_rtx (XFmode);
15622 rtx op1 = gen_reg_rtx (XFmode);
15624 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15625 emit_insn (gen_asinxf2 (op0, op1));
15626 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15630 (define_expand "acosxf2"
15631 [(set (match_dup 2)
15632 (mult:XF (match_operand:XF 1 "register_operand")
15634 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
15635 (set (match_dup 5) (sqrt:XF (match_dup 4)))
15636 (parallel [(set (match_operand:XF 0 "register_operand")
15637 (unspec:XF [(match_dup 1) (match_dup 5)]
15639 (clobber (match_scratch:XF 6))])]
15640 "TARGET_USE_FANCY_MATH_387
15641 && flag_unsafe_math_optimizations"
15645 for (i = 2; i < 6; i++)
15646 operands[i] = gen_reg_rtx (XFmode);
15648 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
15651 (define_expand "acos<mode>2"
15652 [(use (match_operand:MODEF 0 "register_operand"))
15653 (use (match_operand:MODEF 1 "general_operand"))]
15654 "TARGET_USE_FANCY_MATH_387
15655 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15656 || TARGET_MIX_SSE_I387)
15657 && flag_unsafe_math_optimizations"
15659 rtx op0 = gen_reg_rtx (XFmode);
15660 rtx op1 = gen_reg_rtx (XFmode);
15662 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15663 emit_insn (gen_acosxf2 (op0, op1));
15664 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15668 (define_insn "fyl2xxf3_i387"
15669 [(set (match_operand:XF 0 "register_operand" "=f")
15670 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
15671 (match_operand:XF 2 "register_operand" "u")]
15673 (clobber (match_scratch:XF 3 "=2"))]
15674 "TARGET_USE_FANCY_MATH_387
15675 && flag_unsafe_math_optimizations"
15677 [(set_attr "type" "fpspc")
15678 (set_attr "znver1_decode" "vector")
15679 (set_attr "mode" "XF")])
15681 (define_insn "fyl2x_extend<mode>xf3_i387"
15682 [(set (match_operand:XF 0 "register_operand" "=f")
15683 (unspec:XF [(float_extend:XF
15684 (match_operand:MODEF 1 "register_operand" "0"))
15685 (match_operand:XF 2 "register_operand" "u")]
15687 (clobber (match_scratch:XF 3 "=2"))]
15688 "TARGET_USE_FANCY_MATH_387
15689 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15690 || TARGET_MIX_SSE_I387)
15691 && flag_unsafe_math_optimizations"
15693 [(set_attr "type" "fpspc")
15694 (set_attr "znver1_decode" "vector")
15695 (set_attr "mode" "XF")])
15697 (define_expand "logxf2"
15698 [(parallel [(set (match_operand:XF 0 "register_operand")
15699 (unspec:XF [(match_operand:XF 1 "register_operand")
15700 (match_dup 2)] UNSPEC_FYL2X))
15701 (clobber (match_scratch:XF 3))])]
15702 "TARGET_USE_FANCY_MATH_387
15703 && flag_unsafe_math_optimizations"
15705 operands[2] = gen_reg_rtx (XFmode);
15706 emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */
15709 (define_expand "log<mode>2"
15710 [(use (match_operand:MODEF 0 "register_operand"))
15711 (use (match_operand:MODEF 1 "register_operand"))]
15712 "TARGET_USE_FANCY_MATH_387
15713 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15714 || TARGET_MIX_SSE_I387)
15715 && flag_unsafe_math_optimizations"
15717 rtx op0 = gen_reg_rtx (XFmode);
15719 rtx op2 = gen_reg_rtx (XFmode);
15720 emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */
15722 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
15723 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15727 (define_expand "log10xf2"
15728 [(parallel [(set (match_operand:XF 0 "register_operand")
15729 (unspec:XF [(match_operand:XF 1 "register_operand")
15730 (match_dup 2)] UNSPEC_FYL2X))
15731 (clobber (match_scratch:XF 3))])]
15732 "TARGET_USE_FANCY_MATH_387
15733 && flag_unsafe_math_optimizations"
15735 operands[2] = gen_reg_rtx (XFmode);
15736 emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
15739 (define_expand "log10<mode>2"
15740 [(use (match_operand:MODEF 0 "register_operand"))
15741 (use (match_operand:MODEF 1 "register_operand"))]
15742 "TARGET_USE_FANCY_MATH_387
15743 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15744 || TARGET_MIX_SSE_I387)
15745 && flag_unsafe_math_optimizations"
15747 rtx op0 = gen_reg_rtx (XFmode);
15749 rtx op2 = gen_reg_rtx (XFmode);
15750 emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */
15752 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
15753 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15757 (define_expand "log2xf2"
15758 [(parallel [(set (match_operand:XF 0 "register_operand")
15759 (unspec:XF [(match_operand:XF 1 "register_operand")
15760 (match_dup 2)] UNSPEC_FYL2X))
15761 (clobber (match_scratch:XF 3))])]
15762 "TARGET_USE_FANCY_MATH_387
15763 && flag_unsafe_math_optimizations"
15765 operands[2] = gen_reg_rtx (XFmode);
15766 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
15769 (define_expand "log2<mode>2"
15770 [(use (match_operand:MODEF 0 "register_operand"))
15771 (use (match_operand:MODEF 1 "register_operand"))]
15772 "TARGET_USE_FANCY_MATH_387
15773 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15774 || TARGET_MIX_SSE_I387)
15775 && flag_unsafe_math_optimizations"
15777 rtx op0 = gen_reg_rtx (XFmode);
15779 rtx op2 = gen_reg_rtx (XFmode);
15780 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
15782 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
15783 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15787 (define_insn "fyl2xp1xf3_i387"
15788 [(set (match_operand:XF 0 "register_operand" "=f")
15789 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
15790 (match_operand:XF 2 "register_operand" "u")]
15792 (clobber (match_scratch:XF 3 "=2"))]
15793 "TARGET_USE_FANCY_MATH_387
15794 && flag_unsafe_math_optimizations"
15796 [(set_attr "type" "fpspc")
15797 (set_attr "znver1_decode" "vector")
15798 (set_attr "mode" "XF")])
15800 (define_insn "fyl2xp1_extend<mode>xf3_i387"
15801 [(set (match_operand:XF 0 "register_operand" "=f")
15802 (unspec:XF [(float_extend:XF
15803 (match_operand:MODEF 1 "register_operand" "0"))
15804 (match_operand:XF 2 "register_operand" "u")]
15806 (clobber (match_scratch:XF 3 "=2"))]
15807 "TARGET_USE_FANCY_MATH_387
15808 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15809 || TARGET_MIX_SSE_I387)
15810 && flag_unsafe_math_optimizations"
15812 [(set_attr "type" "fpspc")
15813 (set_attr "znver1_decode" "vector")
15814 (set_attr "mode" "XF")])
15816 (define_expand "log1pxf2"
15817 [(use (match_operand:XF 0 "register_operand"))
15818 (use (match_operand:XF 1 "register_operand"))]
15819 "TARGET_USE_FANCY_MATH_387
15820 && flag_unsafe_math_optimizations"
15822 ix86_emit_i387_log1p (operands[0], operands[1]);
15826 (define_expand "log1p<mode>2"
15827 [(use (match_operand:MODEF 0 "register_operand"))
15828 (use (match_operand:MODEF 1 "register_operand"))]
15829 "TARGET_USE_FANCY_MATH_387
15830 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15831 || TARGET_MIX_SSE_I387)
15832 && flag_unsafe_math_optimizations"
15836 op0 = gen_reg_rtx (XFmode);
15838 operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
15840 ix86_emit_i387_log1p (op0, operands[1]);
15841 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15845 (define_insn "fxtractxf3_i387"
15846 [(set (match_operand:XF 0 "register_operand" "=f")
15847 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15848 UNSPEC_XTRACT_FRACT))
15849 (set (match_operand:XF 1 "register_operand" "=u")
15850 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
15851 "TARGET_USE_FANCY_MATH_387
15852 && flag_unsafe_math_optimizations"
15854 [(set_attr "type" "fpspc")
15855 (set_attr "znver1_decode" "vector")
15856 (set_attr "mode" "XF")])
15858 (define_insn "fxtract_extend<mode>xf3_i387"
15859 [(set (match_operand:XF 0 "register_operand" "=f")
15860 (unspec:XF [(float_extend:XF
15861 (match_operand:MODEF 2 "register_operand" "0"))]
15862 UNSPEC_XTRACT_FRACT))
15863 (set (match_operand:XF 1 "register_operand" "=u")
15864 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
15865 "TARGET_USE_FANCY_MATH_387
15866 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15867 || TARGET_MIX_SSE_I387)
15868 && flag_unsafe_math_optimizations"
15870 [(set_attr "type" "fpspc")
15871 (set_attr "znver1_decode" "vector")
15872 (set_attr "mode" "XF")])
15874 (define_expand "logbxf2"
15875 [(parallel [(set (match_dup 2)
15876 (unspec:XF [(match_operand:XF 1 "register_operand")]
15877 UNSPEC_XTRACT_FRACT))
15878 (set (match_operand:XF 0 "register_operand")
15879 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
15880 "TARGET_USE_FANCY_MATH_387
15881 && flag_unsafe_math_optimizations"
15882 "operands[2] = gen_reg_rtx (XFmode);")
15884 (define_expand "logb<mode>2"
15885 [(use (match_operand:MODEF 0 "register_operand"))
15886 (use (match_operand:MODEF 1 "register_operand"))]
15887 "TARGET_USE_FANCY_MATH_387
15888 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15889 || TARGET_MIX_SSE_I387)
15890 && flag_unsafe_math_optimizations"
15892 rtx op0 = gen_reg_rtx (XFmode);
15893 rtx op1 = gen_reg_rtx (XFmode);
15895 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
15896 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1));
15900 (define_expand "ilogbxf2"
15901 [(use (match_operand:SI 0 "register_operand"))
15902 (use (match_operand:XF 1 "register_operand"))]
15903 "TARGET_USE_FANCY_MATH_387
15904 && flag_unsafe_math_optimizations"
15908 if (optimize_insn_for_size_p ())
15911 op0 = gen_reg_rtx (XFmode);
15912 op1 = gen_reg_rtx (XFmode);
15914 emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
15915 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
15919 (define_expand "ilogb<mode>2"
15920 [(use (match_operand:SI 0 "register_operand"))
15921 (use (match_operand:MODEF 1 "register_operand"))]
15922 "TARGET_USE_FANCY_MATH_387
15923 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15924 || TARGET_MIX_SSE_I387)
15925 && flag_unsafe_math_optimizations"
15929 if (optimize_insn_for_size_p ())
15932 op0 = gen_reg_rtx (XFmode);
15933 op1 = gen_reg_rtx (XFmode);
15935 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
15936 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
15940 (define_insn "*f2xm1xf2_i387"
15941 [(set (match_operand:XF 0 "register_operand" "=f")
15942 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15944 "TARGET_USE_FANCY_MATH_387
15945 && flag_unsafe_math_optimizations"
15947 [(set_attr "type" "fpspc")
15948 (set_attr "znver1_decode" "vector")
15949 (set_attr "mode" "XF")])
15951 (define_insn "fscalexf4_i387"
15952 [(set (match_operand:XF 0 "register_operand" "=f")
15953 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15954 (match_operand:XF 3 "register_operand" "1")]
15955 UNSPEC_FSCALE_FRACT))
15956 (set (match_operand:XF 1 "register_operand" "=u")
15957 (unspec:XF [(match_dup 2) (match_dup 3)]
15958 UNSPEC_FSCALE_EXP))]
15959 "TARGET_USE_FANCY_MATH_387
15960 && flag_unsafe_math_optimizations"
15962 [(set_attr "type" "fpspc")
15963 (set_attr "znver1_decode" "vector")
15964 (set_attr "mode" "XF")])
15966 (define_expand "expNcorexf3"
15967 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand")
15968 (match_operand:XF 2 "register_operand")))
15969 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
15970 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
15971 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
15972 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
15973 (parallel [(set (match_operand:XF 0 "register_operand")
15974 (unspec:XF [(match_dup 8) (match_dup 4)]
15975 UNSPEC_FSCALE_FRACT))
15977 (unspec:XF [(match_dup 8) (match_dup 4)]
15978 UNSPEC_FSCALE_EXP))])]
15979 "TARGET_USE_FANCY_MATH_387
15980 && flag_unsafe_math_optimizations"
15984 for (i = 3; i < 10; i++)
15985 operands[i] = gen_reg_rtx (XFmode);
15987 emit_move_insn (operands[7], CONST1_RTX (XFmode)); /* fld1 */
15990 (define_expand "expxf2"
15991 [(use (match_operand:XF 0 "register_operand"))
15992 (use (match_operand:XF 1 "register_operand"))]
15993 "TARGET_USE_FANCY_MATH_387
15994 && flag_unsafe_math_optimizations"
15998 op2 = gen_reg_rtx (XFmode);
15999 emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */
16001 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
16005 (define_expand "exp<mode>2"
16006 [(use (match_operand:MODEF 0 "register_operand"))
16007 (use (match_operand:MODEF 1 "general_operand"))]
16008 "TARGET_USE_FANCY_MATH_387
16009 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16010 || TARGET_MIX_SSE_I387)
16011 && flag_unsafe_math_optimizations"
16015 op0 = gen_reg_rtx (XFmode);
16016 op1 = gen_reg_rtx (XFmode);
16018 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16019 emit_insn (gen_expxf2 (op0, op1));
16020 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16024 (define_expand "exp10xf2"
16025 [(use (match_operand:XF 0 "register_operand"))
16026 (use (match_operand:XF 1 "register_operand"))]
16027 "TARGET_USE_FANCY_MATH_387
16028 && flag_unsafe_math_optimizations"
16032 op2 = gen_reg_rtx (XFmode);
16033 emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */
16035 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
16039 (define_expand "exp10<mode>2"
16040 [(use (match_operand:MODEF 0 "register_operand"))
16041 (use (match_operand:MODEF 1 "general_operand"))]
16042 "TARGET_USE_FANCY_MATH_387
16043 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16044 || TARGET_MIX_SSE_I387)
16045 && flag_unsafe_math_optimizations"
16049 op0 = gen_reg_rtx (XFmode);
16050 op1 = gen_reg_rtx (XFmode);
16052 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16053 emit_insn (gen_exp10xf2 (op0, op1));
16054 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16058 (define_expand "exp2xf2"
16059 [(use (match_operand:XF 0 "register_operand"))
16060 (use (match_operand:XF 1 "register_operand"))]
16061 "TARGET_USE_FANCY_MATH_387
16062 && flag_unsafe_math_optimizations"
16066 op2 = gen_reg_rtx (XFmode);
16067 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
16069 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
16073 (define_expand "exp2<mode>2"
16074 [(use (match_operand:MODEF 0 "register_operand"))
16075 (use (match_operand:MODEF 1 "general_operand"))]
16076 "TARGET_USE_FANCY_MATH_387
16077 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16078 || TARGET_MIX_SSE_I387)
16079 && flag_unsafe_math_optimizations"
16083 op0 = gen_reg_rtx (XFmode);
16084 op1 = gen_reg_rtx (XFmode);
16086 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16087 emit_insn (gen_exp2xf2 (op0, op1));
16088 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16092 (define_expand "expm1xf2"
16093 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand")
16095 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16096 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16097 (set (match_dup 9) (float_extend:XF (match_dup 13)))
16098 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16099 (parallel [(set (match_dup 7)
16100 (unspec:XF [(match_dup 6) (match_dup 4)]
16101 UNSPEC_FSCALE_FRACT))
16103 (unspec:XF [(match_dup 6) (match_dup 4)]
16104 UNSPEC_FSCALE_EXP))])
16105 (parallel [(set (match_dup 10)
16106 (unspec:XF [(match_dup 9) (match_dup 8)]
16107 UNSPEC_FSCALE_FRACT))
16108 (set (match_dup 11)
16109 (unspec:XF [(match_dup 9) (match_dup 8)]
16110 UNSPEC_FSCALE_EXP))])
16111 (set (match_dup 12) (minus:XF (match_dup 10)
16112 (float_extend:XF (match_dup 13))))
16113 (set (match_operand:XF 0 "register_operand")
16114 (plus:XF (match_dup 12) (match_dup 7)))]
16115 "TARGET_USE_FANCY_MATH_387
16116 && flag_unsafe_math_optimizations"
16120 for (i = 2; i < 13; i++)
16121 operands[i] = gen_reg_rtx (XFmode);
16124 = validize_mem (force_const_mem (SFmode, CONST1_RTX (SFmode))); /* fld1 */
16126 emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
16129 (define_expand "expm1<mode>2"
16130 [(use (match_operand:MODEF 0 "register_operand"))
16131 (use (match_operand:MODEF 1 "general_operand"))]
16132 "TARGET_USE_FANCY_MATH_387
16133 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16134 || TARGET_MIX_SSE_I387)
16135 && flag_unsafe_math_optimizations"
16139 op0 = gen_reg_rtx (XFmode);
16140 op1 = gen_reg_rtx (XFmode);
16142 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16143 emit_insn (gen_expm1xf2 (op0, op1));
16144 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16148 (define_expand "ldexpxf3"
16149 [(match_operand:XF 0 "register_operand")
16150 (match_operand:XF 1 "register_operand")
16151 (match_operand:SI 2 "register_operand")]
16152 "TARGET_USE_FANCY_MATH_387
16153 && flag_unsafe_math_optimizations"
16157 tmp1 = gen_reg_rtx (XFmode);
16158 tmp2 = gen_reg_rtx (XFmode);
16160 emit_insn (gen_floatsixf2 (tmp1, operands[2]));
16161 emit_insn (gen_fscalexf4_i387 (operands[0], tmp2,
16162 operands[1], tmp1));
16166 (define_expand "ldexp<mode>3"
16167 [(use (match_operand:MODEF 0 "register_operand"))
16168 (use (match_operand:MODEF 1 "general_operand"))
16169 (use (match_operand:SI 2 "register_operand"))]
16170 "TARGET_USE_FANCY_MATH_387
16171 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16172 || TARGET_MIX_SSE_I387)
16173 && flag_unsafe_math_optimizations"
16177 op0 = gen_reg_rtx (XFmode);
16178 op1 = gen_reg_rtx (XFmode);
16180 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16181 emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
16182 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16186 (define_expand "scalbxf3"
16187 [(parallel [(set (match_operand:XF 0 " register_operand")
16188 (unspec:XF [(match_operand:XF 1 "register_operand")
16189 (match_operand:XF 2 "register_operand")]
16190 UNSPEC_FSCALE_FRACT))
16192 (unspec:XF [(match_dup 1) (match_dup 2)]
16193 UNSPEC_FSCALE_EXP))])]
16194 "TARGET_USE_FANCY_MATH_387
16195 && flag_unsafe_math_optimizations"
16197 operands[3] = gen_reg_rtx (XFmode);
16200 (define_expand "scalb<mode>3"
16201 [(use (match_operand:MODEF 0 "register_operand"))
16202 (use (match_operand:MODEF 1 "general_operand"))
16203 (use (match_operand:MODEF 2 "general_operand"))]
16204 "TARGET_USE_FANCY_MATH_387
16205 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16206 || TARGET_MIX_SSE_I387)
16207 && flag_unsafe_math_optimizations"
16211 op0 = gen_reg_rtx (XFmode);
16212 op1 = gen_reg_rtx (XFmode);
16213 op2 = gen_reg_rtx (XFmode);
16215 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16216 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
16217 emit_insn (gen_scalbxf3 (op0, op1, op2));
16218 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16222 (define_expand "significandxf2"
16223 [(parallel [(set (match_operand:XF 0 "register_operand")
16224 (unspec:XF [(match_operand:XF 1 "register_operand")]
16225 UNSPEC_XTRACT_FRACT))
16227 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
16228 "TARGET_USE_FANCY_MATH_387
16229 && flag_unsafe_math_optimizations"
16230 "operands[2] = gen_reg_rtx (XFmode);")
16232 (define_expand "significand<mode>2"
16233 [(use (match_operand:MODEF 0 "register_operand"))
16234 (use (match_operand:MODEF 1 "register_operand"))]
16235 "TARGET_USE_FANCY_MATH_387
16236 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16237 || TARGET_MIX_SSE_I387)
16238 && flag_unsafe_math_optimizations"
16240 rtx op0 = gen_reg_rtx (XFmode);
16241 rtx op1 = gen_reg_rtx (XFmode);
16243 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
16244 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16249 (define_insn "sse4_1_round<mode>2"
16250 [(set (match_operand:MODEF 0 "register_operand" "=x,v")
16251 (unspec:MODEF [(match_operand:MODEF 1 "register_operand" "x,v")
16252 (match_operand:SI 2 "const_0_to_15_operand" "n,n")]
16256 %vround<ssemodesuffix>\t{%2, %1, %d0|%d0, %1, %2}
16257 vrndscale<ssemodesuffix>\t{%2, %1, %d0|%d0, %1, %2}"
16258 [(set_attr "type" "ssecvt")
16259 (set_attr "prefix_extra" "1,*")
16260 (set_attr "length_immediate" "*,1")
16261 (set_attr "prefix" "maybe_vex,evex")
16262 (set_attr "isa" "noavx512f,avx512f")
16263 (set_attr "mode" "<MODE>")])
16265 (define_insn "rintxf2"
16266 [(set (match_operand:XF 0 "register_operand" "=f")
16267 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16269 "TARGET_USE_FANCY_MATH_387"
16271 [(set_attr "type" "fpspc")
16272 (set_attr "znver1_decode" "vector")
16273 (set_attr "mode" "XF")])
16275 (define_insn "rint<mode>2_frndint"
16276 [(set (match_operand:MODEF 0 "register_operand" "=f")
16277 (unspec:MODEF [(match_operand:MODEF 1 "register_operand" "0")]
16279 "TARGET_USE_FANCY_MATH_387"
16281 [(set_attr "type" "fpspc")
16282 (set_attr "znver1_decode" "vector")
16283 (set_attr "mode" "<MODE>")])
16285 (define_expand "rint<mode>2"
16286 [(use (match_operand:MODEF 0 "register_operand"))
16287 (use (match_operand:MODEF 1 "register_operand"))]
16288 "(TARGET_USE_FANCY_MATH_387
16289 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16290 || TARGET_MIX_SSE_I387))
16291 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
16293 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16296 emit_insn (gen_sse4_1_round<mode>2
16297 (operands[0], operands[1], GEN_INT (ROUND_MXCSR)));
16299 ix86_expand_rint (operands[0], operands[1]);
16302 emit_insn (gen_rint<mode>2_frndint (operands[0], operands[1]));
16306 (define_expand "round<mode>2"
16307 [(match_operand:X87MODEF 0 "register_operand")
16308 (match_operand:X87MODEF 1 "nonimmediate_operand")]
16309 "(TARGET_USE_FANCY_MATH_387
16310 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16311 || TARGET_MIX_SSE_I387)
16312 && flag_unsafe_math_optimizations)
16313 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16314 && !flag_trapping_math && !flag_rounding_math)"
16316 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16317 && !flag_trapping_math && !flag_rounding_math)
16321 operands[1] = force_reg (<MODE>mode, operands[1]);
16322 ix86_expand_round_sse4 (operands[0], operands[1]);
16324 else if (TARGET_64BIT || (<MODE>mode != DFmode))
16325 ix86_expand_round (operands[0], operands[1]);
16327 ix86_expand_rounddf_32 (operands[0], operands[1]);
16331 operands[1] = force_reg (<MODE>mode, operands[1]);
16332 ix86_emit_i387_round (operands[0], operands[1]);
16337 (define_insn_and_split "*fistdi2_1"
16338 [(set (match_operand:DI 0 "nonimmediate_operand")
16339 (unspec:DI [(match_operand:XF 1 "register_operand")]
16341 "TARGET_USE_FANCY_MATH_387
16342 && can_create_pseudo_p ()"
16347 if (memory_operand (operands[0], VOIDmode))
16348 emit_insn (gen_fistdi2 (operands[0], operands[1]));
16351 operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
16352 emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
16357 [(set_attr "type" "fpspc")
16358 (set_attr "mode" "DI")])
16360 (define_insn "fistdi2"
16361 [(set (match_operand:DI 0 "memory_operand" "=m")
16362 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
16364 (clobber (match_scratch:XF 2 "=&1f"))]
16365 "TARGET_USE_FANCY_MATH_387"
16366 "* return output_fix_trunc (insn, operands, false);"
16367 [(set_attr "type" "fpspc")
16368 (set_attr "mode" "DI")])
16370 (define_insn "fistdi2_with_temp"
16371 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
16372 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
16374 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))
16375 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
16376 "TARGET_USE_FANCY_MATH_387"
16378 [(set_attr "type" "fpspc")
16379 (set_attr "mode" "DI")])
16382 [(set (match_operand:DI 0 "register_operand")
16383 (unspec:DI [(match_operand:XF 1 "register_operand")]
16385 (clobber (match_operand:DI 2 "memory_operand"))
16386 (clobber (match_scratch 3))]
16388 [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
16389 (clobber (match_dup 3))])
16390 (set (match_dup 0) (match_dup 2))])
16393 [(set (match_operand:DI 0 "memory_operand")
16394 (unspec:DI [(match_operand:XF 1 "register_operand")]
16396 (clobber (match_operand:DI 2 "memory_operand"))
16397 (clobber (match_scratch 3))]
16399 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
16400 (clobber (match_dup 3))])])
16402 (define_insn_and_split "*fist<mode>2_1"
16403 [(set (match_operand:SWI24 0 "register_operand")
16404 (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
16406 "TARGET_USE_FANCY_MATH_387
16407 && can_create_pseudo_p ()"
16412 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
16413 emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
16417 [(set_attr "type" "fpspc")
16418 (set_attr "mode" "<MODE>")])
16420 (define_insn "fist<mode>2"
16421 [(set (match_operand:SWI24 0 "memory_operand" "=m")
16422 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
16424 "TARGET_USE_FANCY_MATH_387"
16425 "* return output_fix_trunc (insn, operands, false);"
16426 [(set_attr "type" "fpspc")
16427 (set_attr "mode" "<MODE>")])
16429 (define_insn "fist<mode>2_with_temp"
16430 [(set (match_operand:SWI24 0 "register_operand" "=r")
16431 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
16433 (clobber (match_operand:SWI24 2 "memory_operand" "=m"))]
16434 "TARGET_USE_FANCY_MATH_387"
16436 [(set_attr "type" "fpspc")
16437 (set_attr "mode" "<MODE>")])
16440 [(set (match_operand:SWI24 0 "register_operand")
16441 (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
16443 (clobber (match_operand:SWI24 2 "memory_operand"))]
16445 [(set (match_dup 2) (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST))
16446 (set (match_dup 0) (match_dup 2))])
16449 [(set (match_operand:SWI24 0 "memory_operand")
16450 (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
16452 (clobber (match_operand:SWI24 2 "memory_operand"))]
16454 [(set (match_dup 0) (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST))])
16456 (define_expand "lrintxf<mode>2"
16457 [(set (match_operand:SWI248x 0 "nonimmediate_operand")
16458 (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
16460 "TARGET_USE_FANCY_MATH_387")
16462 (define_expand "lrint<MODEF:mode><SWI48:mode>2"
16463 [(set (match_operand:SWI48 0 "nonimmediate_operand")
16464 (unspec:SWI48 [(match_operand:MODEF 1 "register_operand")]
16465 UNSPEC_FIX_NOTRUNC))]
16466 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH")
16468 (define_expand "lround<X87MODEF:mode><SWI248x:mode>2"
16469 [(match_operand:SWI248x 0 "nonimmediate_operand")
16470 (match_operand:X87MODEF 1 "register_operand")]
16471 "(TARGET_USE_FANCY_MATH_387
16472 && (!(SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
16473 || TARGET_MIX_SSE_I387)
16474 && flag_unsafe_math_optimizations)
16475 || (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
16476 && <SWI248x:MODE>mode != HImode
16477 && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT)
16478 && !flag_trapping_math && !flag_rounding_math)"
16480 if (optimize_insn_for_size_p ())
16483 if (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
16484 && <SWI248x:MODE>mode != HImode
16485 && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT)
16486 && !flag_trapping_math && !flag_rounding_math)
16487 ix86_expand_lround (operands[0], operands[1]);
16489 ix86_emit_i387_round (operands[0], operands[1]);
16493 (define_int_iterator FRNDINT_ROUNDING
16494 [UNSPEC_FRNDINT_FLOOR
16495 UNSPEC_FRNDINT_CEIL
16496 UNSPEC_FRNDINT_TRUNC])
16498 (define_int_iterator FIST_ROUNDING
16502 ;; Base name for define_insn
16503 (define_int_attr rounding_insn
16504 [(UNSPEC_FRNDINT_FLOOR "floor")
16505 (UNSPEC_FRNDINT_CEIL "ceil")
16506 (UNSPEC_FRNDINT_TRUNC "btrunc")
16507 (UNSPEC_FIST_FLOOR "floor")
16508 (UNSPEC_FIST_CEIL "ceil")])
16510 (define_int_attr rounding
16511 [(UNSPEC_FRNDINT_FLOOR "floor")
16512 (UNSPEC_FRNDINT_CEIL "ceil")
16513 (UNSPEC_FRNDINT_TRUNC "trunc")
16514 (UNSPEC_FIST_FLOOR "floor")
16515 (UNSPEC_FIST_CEIL "ceil")])
16517 (define_int_attr ROUNDING
16518 [(UNSPEC_FRNDINT_FLOOR "FLOOR")
16519 (UNSPEC_FRNDINT_CEIL "CEIL")
16520 (UNSPEC_FRNDINT_TRUNC "TRUNC")
16521 (UNSPEC_FIST_FLOOR "FLOOR")
16522 (UNSPEC_FIST_CEIL "CEIL")])
16524 ;; Rounding mode control word calculation could clobber FLAGS_REG.
16525 (define_insn_and_split "frndint<mode>2_<rounding>"
16526 [(set (match_operand:X87MODEF 0 "register_operand")
16527 (unspec:X87MODEF [(match_operand:X87MODEF 1 "register_operand")]
16529 (clobber (reg:CC FLAGS_REG))]
16530 "TARGET_USE_FANCY_MATH_387
16531 && (flag_fp_int_builtin_inexact || !flag_trapping_math)
16532 && can_create_pseudo_p ()"
16537 ix86_optimize_mode_switching[I387_<ROUNDING>] = 1;
16539 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
16540 operands[3] = assign_386_stack_local (HImode, SLOT_CW_<ROUNDING>);
16542 emit_insn (gen_frndint<mode>2_<rounding>_i387 (operands[0], operands[1],
16543 operands[2], operands[3]));
16546 [(set_attr "type" "frndint")
16547 (set_attr "i387_cw" "<rounding>")
16548 (set_attr "mode" "<MODE>")])
16550 (define_insn "frndint<mode>2_<rounding>_i387"
16551 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
16552 (unspec:X87MODEF [(match_operand:X87MODEF 1 "register_operand" "0")]
16554 (use (match_operand:HI 2 "memory_operand" "m"))
16555 (use (match_operand:HI 3 "memory_operand" "m"))]
16556 "TARGET_USE_FANCY_MATH_387
16557 && (flag_fp_int_builtin_inexact || !flag_trapping_math)"
16558 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
16559 [(set_attr "type" "frndint")
16560 (set_attr "i387_cw" "<rounding>")
16561 (set_attr "mode" "<MODE>")])
16563 (define_expand "<rounding_insn>xf2"
16564 [(parallel [(set (match_operand:XF 0 "register_operand")
16565 (unspec:XF [(match_operand:XF 1 "register_operand")]
16567 (clobber (reg:CC FLAGS_REG))])]
16568 "TARGET_USE_FANCY_MATH_387
16569 && (flag_fp_int_builtin_inexact || !flag_trapping_math)")
16571 (define_expand "<rounding_insn><mode>2"
16572 [(parallel [(set (match_operand:MODEF 0 "register_operand")
16573 (unspec:MODEF [(match_operand:MODEF 1 "register_operand")]
16575 (clobber (reg:CC FLAGS_REG))])]
16576 "(TARGET_USE_FANCY_MATH_387
16577 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16578 || TARGET_MIX_SSE_I387)
16579 && (flag_fp_int_builtin_inexact || !flag_trapping_math))
16580 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16581 && (TARGET_SSE4_1 || !flag_trapping_math
16582 || flag_fp_int_builtin_inexact))"
16584 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16585 && (TARGET_SSE4_1 || !flag_trapping_math || flag_fp_int_builtin_inexact))
16588 emit_insn (gen_sse4_1_round<mode>2
16589 (operands[0], operands[1], GEN_INT (ROUND_<ROUNDING>
16591 else if (TARGET_64BIT || (<MODE>mode != DFmode))
16593 if (ROUND_<ROUNDING> == ROUND_FLOOR)
16594 ix86_expand_floorceil (operands[0], operands[1], true);
16595 else if (ROUND_<ROUNDING> == ROUND_CEIL)
16596 ix86_expand_floorceil (operands[0], operands[1], false);
16597 else if (ROUND_<ROUNDING> == ROUND_TRUNC)
16598 ix86_expand_trunc (operands[0], operands[1]);
16600 gcc_unreachable ();
16604 if (ROUND_<ROUNDING> == ROUND_FLOOR)
16605 ix86_expand_floorceildf_32 (operands[0], operands[1], true);
16606 else if (ROUND_<ROUNDING> == ROUND_CEIL)
16607 ix86_expand_floorceildf_32 (operands[0], operands[1], false);
16608 else if (ROUND_<ROUNDING> == ROUND_TRUNC)
16609 ix86_expand_truncdf_32 (operands[0], operands[1]);
16611 gcc_unreachable ();
16615 emit_insn (gen_frndint<mode>2_<rounding> (operands[0], operands[1]));
16619 ;; Rounding mode control word calculation could clobber FLAGS_REG.
16620 (define_insn_and_split "frndintxf2_mask_pm"
16621 [(set (match_operand:XF 0 "register_operand")
16622 (unspec:XF [(match_operand:XF 1 "register_operand")]
16623 UNSPEC_FRNDINT_MASK_PM))
16624 (clobber (reg:CC FLAGS_REG))]
16625 "TARGET_USE_FANCY_MATH_387
16626 && flag_unsafe_math_optimizations
16627 && can_create_pseudo_p ()"
16632 ix86_optimize_mode_switching[I387_MASK_PM] = 1;
16634 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
16635 operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
16637 emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
16638 operands[2], operands[3]));
16641 [(set_attr "type" "frndint")
16642 (set_attr "i387_cw" "mask_pm")
16643 (set_attr "mode" "XF")])
16645 (define_insn "frndintxf2_mask_pm_i387"
16646 [(set (match_operand:XF 0 "register_operand" "=f")
16647 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16648 UNSPEC_FRNDINT_MASK_PM))
16649 (use (match_operand:HI 2 "memory_operand" "m"))
16650 (use (match_operand:HI 3 "memory_operand" "m"))]
16651 "TARGET_USE_FANCY_MATH_387
16652 && flag_unsafe_math_optimizations"
16653 "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
16654 [(set_attr "type" "frndint")
16655 (set_attr "i387_cw" "mask_pm")
16656 (set_attr "mode" "XF")])
16658 (define_expand "nearbyintxf2"
16659 [(parallel [(set (match_operand:XF 0 "register_operand")
16660 (unspec:XF [(match_operand:XF 1 "register_operand")]
16661 UNSPEC_FRNDINT_MASK_PM))
16662 (clobber (reg:CC FLAGS_REG))])]
16663 "TARGET_USE_FANCY_MATH_387
16664 && flag_unsafe_math_optimizations")
16666 (define_expand "nearbyint<mode>2"
16667 [(use (match_operand:MODEF 0 "register_operand"))
16668 (use (match_operand:MODEF 1 "register_operand"))]
16669 "TARGET_USE_FANCY_MATH_387
16670 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16671 || TARGET_MIX_SSE_I387)
16672 && flag_unsafe_math_optimizations"
16674 rtx op0 = gen_reg_rtx (XFmode);
16675 rtx op1 = gen_reg_rtx (XFmode);
16677 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16678 emit_insn (gen_frndintxf2_mask_pm (op0, op1));
16680 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16684 ;; Rounding mode control word calculation could clobber FLAGS_REG.
16685 (define_insn_and_split "*fist<mode>2_<rounding>_1"
16686 [(set (match_operand:SWI248x 0 "nonimmediate_operand")
16687 (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
16689 (clobber (reg:CC FLAGS_REG))]
16690 "TARGET_USE_FANCY_MATH_387
16691 && flag_unsafe_math_optimizations
16692 && can_create_pseudo_p ()"
16697 ix86_optimize_mode_switching[I387_<ROUNDING>] = 1;
16699 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
16700 operands[3] = assign_386_stack_local (HImode, SLOT_CW_<ROUNDING>);
16701 if (memory_operand (operands[0], VOIDmode))
16702 emit_insn (gen_fist<mode>2_<rounding> (operands[0], operands[1],
16703 operands[2], operands[3]));
16706 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
16707 emit_insn (gen_fist<mode>2_<rounding>_with_temp
16708 (operands[0], operands[1], operands[2],
16709 operands[3], operands[4]));
16713 [(set_attr "type" "fistp")
16714 (set_attr "i387_cw" "<rounding>")
16715 (set_attr "mode" "<MODE>")])
16717 (define_insn "fistdi2_<rounding>"
16718 [(set (match_operand:DI 0 "memory_operand" "=m")
16719 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
16721 (use (match_operand:HI 2 "memory_operand" "m"))
16722 (use (match_operand:HI 3 "memory_operand" "m"))
16723 (clobber (match_scratch:XF 4 "=&1f"))]
16724 "TARGET_USE_FANCY_MATH_387
16725 && flag_unsafe_math_optimizations"
16726 "* return output_fix_trunc (insn, operands, false);"
16727 [(set_attr "type" "fistp")
16728 (set_attr "i387_cw" "<rounding>")
16729 (set_attr "mode" "DI")])
16731 (define_insn "fistdi2_<rounding>_with_temp"
16732 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
16733 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
16735 (use (match_operand:HI 2 "memory_operand" "m,m"))
16736 (use (match_operand:HI 3 "memory_operand" "m,m"))
16737 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
16738 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
16739 "TARGET_USE_FANCY_MATH_387
16740 && flag_unsafe_math_optimizations"
16742 [(set_attr "type" "fistp")
16743 (set_attr "i387_cw" "<rounding>")
16744 (set_attr "mode" "DI")])
16747 [(set (match_operand:DI 0 "register_operand")
16748 (unspec:DI [(match_operand:XF 1 "register_operand")]
16750 (use (match_operand:HI 2 "memory_operand"))
16751 (use (match_operand:HI 3 "memory_operand"))
16752 (clobber (match_operand:DI 4 "memory_operand"))
16753 (clobber (match_scratch 5))]
16755 [(parallel [(set (match_dup 4)
16756 (unspec:DI [(match_dup 1)] FIST_ROUNDING))
16757 (use (match_dup 2))
16758 (use (match_dup 3))
16759 (clobber (match_dup 5))])
16760 (set (match_dup 0) (match_dup 4))])
16763 [(set (match_operand:DI 0 "memory_operand")
16764 (unspec:DI [(match_operand:XF 1 "register_operand")]
16766 (use (match_operand:HI 2 "memory_operand"))
16767 (use (match_operand:HI 3 "memory_operand"))
16768 (clobber (match_operand:DI 4 "memory_operand"))
16769 (clobber (match_scratch 5))]
16771 [(parallel [(set (match_dup 0)
16772 (unspec:DI [(match_dup 1)] FIST_ROUNDING))
16773 (use (match_dup 2))
16774 (use (match_dup 3))
16775 (clobber (match_dup 5))])])
16777 (define_insn "fist<mode>2_<rounding>"
16778 [(set (match_operand:SWI24 0 "memory_operand" "=m")
16779 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
16781 (use (match_operand:HI 2 "memory_operand" "m"))
16782 (use (match_operand:HI 3 "memory_operand" "m"))]
16783 "TARGET_USE_FANCY_MATH_387
16784 && flag_unsafe_math_optimizations"
16785 "* return output_fix_trunc (insn, operands, false);"
16786 [(set_attr "type" "fistp")
16787 (set_attr "i387_cw" "<rounding>")
16788 (set_attr "mode" "<MODE>")])
16790 (define_insn "fist<mode>2_<rounding>_with_temp"
16791 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
16792 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f,f")]
16794 (use (match_operand:HI 2 "memory_operand" "m,m"))
16795 (use (match_operand:HI 3 "memory_operand" "m,m"))
16796 (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
16797 "TARGET_USE_FANCY_MATH_387
16798 && flag_unsafe_math_optimizations"
16800 [(set_attr "type" "fistp")
16801 (set_attr "i387_cw" "<rounding>")
16802 (set_attr "mode" "<MODE>")])
16805 [(set (match_operand:SWI24 0 "register_operand")
16806 (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
16808 (use (match_operand:HI 2 "memory_operand"))
16809 (use (match_operand:HI 3 "memory_operand"))
16810 (clobber (match_operand:SWI24 4 "memory_operand"))]
16812 [(parallel [(set (match_dup 4)
16813 (unspec:SWI24 [(match_dup 1)] FIST_ROUNDING))
16814 (use (match_dup 2))
16815 (use (match_dup 3))])
16816 (set (match_dup 0) (match_dup 4))])
16819 [(set (match_operand:SWI24 0 "memory_operand")
16820 (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
16822 (use (match_operand:HI 2 "memory_operand"))
16823 (use (match_operand:HI 3 "memory_operand"))
16824 (clobber (match_operand:SWI24 4 "memory_operand"))]
16826 [(parallel [(set (match_dup 0)
16827 (unspec:SWI24 [(match_dup 1)] FIST_ROUNDING))
16828 (use (match_dup 2))
16829 (use (match_dup 3))])])
16831 (define_expand "l<rounding_insn>xf<mode>2"
16832 [(parallel [(set (match_operand:SWI248x 0 "nonimmediate_operand")
16833 (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
16835 (clobber (reg:CC FLAGS_REG))])]
16836 "TARGET_USE_FANCY_MATH_387
16837 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16838 && flag_unsafe_math_optimizations")
16840 (define_expand "l<rounding_insn><MODEF:mode><SWI48:mode>2"
16841 [(parallel [(set (match_operand:SWI48 0 "nonimmediate_operand")
16842 (unspec:SWI48 [(match_operand:MODEF 1 "register_operand")]
16844 (clobber (reg:CC FLAGS_REG))])]
16845 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
16846 && !flag_trapping_math"
16848 if (TARGET_64BIT && optimize_insn_for_size_p ())
16851 if (ROUND_<ROUNDING> == ROUND_FLOOR)
16852 ix86_expand_lfloorceil (operands[0], operands[1], true);
16853 else if (ROUND_<ROUNDING> == ROUND_CEIL)
16854 ix86_expand_lfloorceil (operands[0], operands[1], false);
16856 gcc_unreachable ();
16861 (define_insn "fxam<mode>2_i387"
16862 [(set (match_operand:HI 0 "register_operand" "=a")
16864 [(match_operand:X87MODEF 1 "register_operand" "f")]
16866 "TARGET_USE_FANCY_MATH_387"
16867 "fxam\n\tfnstsw\t%0"
16868 [(set_attr "type" "multi")
16869 (set_attr "length" "4")
16870 (set_attr "unit" "i387")
16871 (set_attr "mode" "<MODE>")])
16873 (define_insn_and_split "fxam<mode>2_i387_with_temp"
16874 [(set (match_operand:HI 0 "register_operand")
16876 [(match_operand:MODEF 1 "memory_operand")]
16878 "TARGET_USE_FANCY_MATH_387
16879 && can_create_pseudo_p ()"
16882 [(set (match_dup 2)(match_dup 1))
16884 (unspec:HI [(match_dup 2)] UNSPEC_FXAM))]
16886 operands[2] = gen_reg_rtx (<MODE>mode);
16888 MEM_VOLATILE_P (operands[1]) = 1;
16890 [(set_attr "type" "multi")
16891 (set_attr "unit" "i387")
16892 (set_attr "mode" "<MODE>")])
16894 (define_expand "isinfxf2"
16895 [(use (match_operand:SI 0 "register_operand"))
16896 (use (match_operand:XF 1 "register_operand"))]
16897 "TARGET_USE_FANCY_MATH_387
16898 && ix86_libc_has_function (function_c99_misc)"
16900 rtx mask = GEN_INT (0x45);
16901 rtx val = GEN_INT (0x05);
16903 rtx scratch = gen_reg_rtx (HImode);
16904 rtx res = gen_reg_rtx (QImode);
16906 emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
16908 emit_insn (gen_andqi_ext_1 (scratch, scratch, mask));
16909 emit_insn (gen_cmpqi_ext_3 (scratch, val));
16910 ix86_expand_setcc (res, EQ,
16911 gen_rtx_REG (CCmode, FLAGS_REG), const0_rtx);
16912 emit_insn (gen_zero_extendqisi2 (operands[0], res));
16916 (define_expand "isinf<mode>2"
16917 [(use (match_operand:SI 0 "register_operand"))
16918 (use (match_operand:MODEF 1 "nonimmediate_operand"))]
16919 "TARGET_USE_FANCY_MATH_387
16920 && ix86_libc_has_function (function_c99_misc)
16921 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
16923 rtx mask = GEN_INT (0x45);
16924 rtx val = GEN_INT (0x05);
16926 rtx scratch = gen_reg_rtx (HImode);
16927 rtx res = gen_reg_rtx (QImode);
16929 /* Remove excess precision by forcing value through memory. */
16930 if (memory_operand (operands[1], VOIDmode))
16931 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, operands[1]));
16934 rtx temp = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
16936 emit_move_insn (temp, operands[1]);
16937 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, temp));
16940 emit_insn (gen_andqi_ext_1 (scratch, scratch, mask));
16941 emit_insn (gen_cmpqi_ext_3 (scratch, val));
16942 ix86_expand_setcc (res, EQ,
16943 gen_rtx_REG (CCmode, FLAGS_REG), const0_rtx);
16944 emit_insn (gen_zero_extendqisi2 (operands[0], res));
16948 (define_expand "signbittf2"
16949 [(use (match_operand:SI 0 "register_operand"))
16950 (use (match_operand:TF 1 "register_operand"))]
16955 rtx mask = ix86_build_signbit_mask (TFmode, 0, 0);
16956 rtx scratch = gen_reg_rtx (QImode);
16958 emit_insn (gen_ptesttf2 (operands[1], mask));
16959 ix86_expand_setcc (scratch, NE,
16960 gen_rtx_REG (CCZmode, FLAGS_REG), const0_rtx);
16962 emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
16966 emit_insn (gen_sse_movmskps (operands[0],
16967 gen_lowpart (V4SFmode, operands[1])));
16968 emit_insn (gen_andsi3 (operands[0], operands[0], GEN_INT (0x8)));
16973 (define_expand "signbitxf2"
16974 [(use (match_operand:SI 0 "register_operand"))
16975 (use (match_operand:XF 1 "register_operand"))]
16976 "TARGET_USE_FANCY_MATH_387"
16978 rtx scratch = gen_reg_rtx (HImode);
16980 emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
16981 emit_insn (gen_andsi3 (operands[0],
16982 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
16986 (define_insn "movmsk_df"
16987 [(set (match_operand:SI 0 "register_operand" "=r")
16989 [(match_operand:DF 1 "register_operand" "x")]
16991 "SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH"
16992 "%vmovmskpd\t{%1, %0|%0, %1}"
16993 [(set_attr "type" "ssemov")
16994 (set_attr "prefix" "maybe_vex")
16995 (set_attr "mode" "DF")])
16997 ;; Use movmskpd in SSE mode to avoid store forwarding stall
16998 ;; for 32bit targets and movq+shrq sequence for 64bit targets.
16999 (define_expand "signbitdf2"
17000 [(use (match_operand:SI 0 "register_operand"))
17001 (use (match_operand:DF 1 "register_operand"))]
17002 "TARGET_USE_FANCY_MATH_387
17003 || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
17005 if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)
17007 emit_insn (gen_movmsk_df (operands[0], operands[1]));
17008 emit_insn (gen_andsi3 (operands[0], operands[0], const1_rtx));
17012 rtx scratch = gen_reg_rtx (HImode);
17014 emit_insn (gen_fxamdf2_i387 (scratch, operands[1]));
17015 emit_insn (gen_andsi3 (operands[0],
17016 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
17021 (define_expand "signbitsf2"
17022 [(use (match_operand:SI 0 "register_operand"))
17023 (use (match_operand:SF 1 "register_operand"))]
17024 "TARGET_USE_FANCY_MATH_387
17025 && !(SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH)"
17027 rtx scratch = gen_reg_rtx (HImode);
17029 emit_insn (gen_fxamsf2_i387 (scratch, operands[1]));
17030 emit_insn (gen_andsi3 (operands[0],
17031 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
17035 ;; Block operation instructions
17038 [(unspec_volatile [(const_int 0)] UNSPECV_CLD)]
17041 [(set_attr "length" "1")
17042 (set_attr "length_immediate" "0")
17043 (set_attr "modrm" "0")])
17045 (define_expand "movmem<mode>"
17046 [(use (match_operand:BLK 0 "memory_operand"))
17047 (use (match_operand:BLK 1 "memory_operand"))
17048 (use (match_operand:SWI48 2 "nonmemory_operand"))
17049 (use (match_operand:SWI48 3 "const_int_operand"))
17050 (use (match_operand:SI 4 "const_int_operand"))
17051 (use (match_operand:SI 5 "const_int_operand"))
17052 (use (match_operand:SI 6 ""))
17053 (use (match_operand:SI 7 ""))
17054 (use (match_operand:SI 8 ""))]
17057 if (ix86_expand_set_or_movmem (operands[0], operands[1],
17058 operands[2], NULL, operands[3],
17059 operands[4], operands[5],
17060 operands[6], operands[7],
17061 operands[8], false))
17067 ;; Most CPUs don't like single string operations
17068 ;; Handle this case here to simplify previous expander.
17070 (define_expand "strmov"
17071 [(set (match_dup 4) (match_operand 3 "memory_operand"))
17072 (set (match_operand 1 "memory_operand") (match_dup 4))
17073 (parallel [(set (match_operand 0 "register_operand") (match_dup 5))
17074 (clobber (reg:CC FLAGS_REG))])
17075 (parallel [(set (match_operand 2 "register_operand") (match_dup 6))
17076 (clobber (reg:CC FLAGS_REG))])]
17079 /* Can't use this for non-default address spaces. */
17080 if (!ADDR_SPACE_GENERIC_P (MEM_ADDR_SPACE (operands[3])))
17083 rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
17085 /* If .md ever supports :P for Pmode, these can be directly
17086 in the pattern above. */
17087 operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
17088 operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
17090 /* Can't use this if the user has appropriated esi or edi. */
17091 if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
17092 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG]))
17094 emit_insn (gen_strmov_singleop (operands[0], operands[1],
17095 operands[2], operands[3],
17096 operands[5], operands[6]));
17100 operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
17103 (define_expand "strmov_singleop"
17104 [(parallel [(set (match_operand 1 "memory_operand")
17105 (match_operand 3 "memory_operand"))
17106 (set (match_operand 0 "register_operand")
17108 (set (match_operand 2 "register_operand")
17109 (match_operand 5))])]
17113 ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
17116 (define_insn "*strmovdi_rex_1"
17117 [(set (mem:DI (match_operand:P 2 "register_operand" "0"))
17118 (mem:DI (match_operand:P 3 "register_operand" "1")))
17119 (set (match_operand:P 0 "register_operand" "=D")
17120 (plus:P (match_dup 2)
17122 (set (match_operand:P 1 "register_operand" "=S")
17123 (plus:P (match_dup 3)
17126 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG])
17127 && ix86_check_no_addr_space (insn)"
17129 [(set_attr "type" "str")
17130 (set_attr "memory" "both")
17131 (set_attr "mode" "DI")])
17133 (define_insn "*strmovsi_1"
17134 [(set (mem:SI (match_operand:P 2 "register_operand" "0"))
17135 (mem:SI (match_operand:P 3 "register_operand" "1")))
17136 (set (match_operand:P 0 "register_operand" "=D")
17137 (plus:P (match_dup 2)
17139 (set (match_operand:P 1 "register_operand" "=S")
17140 (plus:P (match_dup 3)
17142 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])
17143 && ix86_check_no_addr_space (insn)"
17145 [(set_attr "type" "str")
17146 (set_attr "memory" "both")
17147 (set_attr "mode" "SI")])
17149 (define_insn "*strmovhi_1"
17150 [(set (mem:HI (match_operand:P 2 "register_operand" "0"))
17151 (mem:HI (match_operand:P 3 "register_operand" "1")))
17152 (set (match_operand:P 0 "register_operand" "=D")
17153 (plus:P (match_dup 2)
17155 (set (match_operand:P 1 "register_operand" "=S")
17156 (plus:P (match_dup 3)
17158 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])
17159 && ix86_check_no_addr_space (insn)"
17161 [(set_attr "type" "str")
17162 (set_attr "memory" "both")
17163 (set_attr "mode" "HI")])
17165 (define_insn "*strmovqi_1"
17166 [(set (mem:QI (match_operand:P 2 "register_operand" "0"))
17167 (mem:QI (match_operand:P 3 "register_operand" "1")))
17168 (set (match_operand:P 0 "register_operand" "=D")
17169 (plus:P (match_dup 2)
17171 (set (match_operand:P 1 "register_operand" "=S")
17172 (plus:P (match_dup 3)
17174 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])
17175 && ix86_check_no_addr_space (insn)"
17177 [(set_attr "type" "str")
17178 (set_attr "memory" "both")
17179 (set (attr "prefix_rex")
17181 (match_test "<P:MODE>mode == DImode")
17183 (const_string "*")))
17184 (set_attr "mode" "QI")])
17186 (define_expand "rep_mov"
17187 [(parallel [(set (match_operand 4 "register_operand") (const_int 0))
17188 (set (match_operand 0 "register_operand")
17190 (set (match_operand 2 "register_operand")
17192 (set (match_operand 1 "memory_operand")
17193 (match_operand 3 "memory_operand"))
17194 (use (match_dup 4))])]
17198 ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
17201 (define_insn "*rep_movdi_rex64"
17202 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
17203 (set (match_operand:P 0 "register_operand" "=D")
17204 (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
17206 (match_operand:P 3 "register_operand" "0")))
17207 (set (match_operand:P 1 "register_operand" "=S")
17208 (plus:P (ashift:P (match_dup 5) (const_int 3))
17209 (match_operand:P 4 "register_operand" "1")))
17210 (set (mem:BLK (match_dup 3))
17211 (mem:BLK (match_dup 4)))
17212 (use (match_dup 5))]
17214 && !(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
17215 && ix86_check_no_addr_space (insn)"
17217 [(set_attr "type" "str")
17218 (set_attr "prefix_rep" "1")
17219 (set_attr "memory" "both")
17220 (set_attr "mode" "DI")])
17222 (define_insn "*rep_movsi"
17223 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
17224 (set (match_operand:P 0 "register_operand" "=D")
17225 (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
17227 (match_operand:P 3 "register_operand" "0")))
17228 (set (match_operand:P 1 "register_operand" "=S")
17229 (plus:P (ashift:P (match_dup 5) (const_int 2))
17230 (match_operand:P 4 "register_operand" "1")))
17231 (set (mem:BLK (match_dup 3))
17232 (mem:BLK (match_dup 4)))
17233 (use (match_dup 5))]
17234 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
17235 && ix86_check_no_addr_space (insn)"
17236 "%^rep{%;} movs{l|d}"
17237 [(set_attr "type" "str")
17238 (set_attr "prefix_rep" "1")
17239 (set_attr "memory" "both")
17240 (set_attr "mode" "SI")])
17242 (define_insn "*rep_movqi"
17243 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
17244 (set (match_operand:P 0 "register_operand" "=D")
17245 (plus:P (match_operand:P 3 "register_operand" "0")
17246 (match_operand:P 5 "register_operand" "2")))
17247 (set (match_operand:P 1 "register_operand" "=S")
17248 (plus:P (match_operand:P 4 "register_operand" "1") (match_dup 5)))
17249 (set (mem:BLK (match_dup 3))
17250 (mem:BLK (match_dup 4)))
17251 (use (match_dup 5))]
17252 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
17253 && ix86_check_no_addr_space (insn)"
17255 [(set_attr "type" "str")
17256 (set_attr "prefix_rep" "1")
17257 (set_attr "memory" "both")
17258 (set_attr "mode" "QI")])
17260 (define_expand "setmem<mode>"
17261 [(use (match_operand:BLK 0 "memory_operand"))
17262 (use (match_operand:SWI48 1 "nonmemory_operand"))
17263 (use (match_operand:QI 2 "nonmemory_operand"))
17264 (use (match_operand 3 "const_int_operand"))
17265 (use (match_operand:SI 4 "const_int_operand"))
17266 (use (match_operand:SI 5 "const_int_operand"))
17267 (use (match_operand:SI 6 ""))
17268 (use (match_operand:SI 7 ""))
17269 (use (match_operand:SI 8 ""))]
17272 if (ix86_expand_set_or_movmem (operands[0], NULL,
17273 operands[1], operands[2],
17274 operands[3], operands[4],
17275 operands[5], operands[6],
17276 operands[7], operands[8], true))
17282 ;; Most CPUs don't like single string operations
17283 ;; Handle this case here to simplify previous expander.
17285 (define_expand "strset"
17286 [(set (match_operand 1 "memory_operand")
17287 (match_operand 2 "register_operand"))
17288 (parallel [(set (match_operand 0 "register_operand")
17290 (clobber (reg:CC FLAGS_REG))])]
17293 /* Can't use this for non-default address spaces. */
17294 if (!ADDR_SPACE_GENERIC_P (MEM_ADDR_SPACE (operands[1])))
17297 if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
17298 operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
17300 /* If .md ever supports :P for Pmode, this can be directly
17301 in the pattern above. */
17302 operands[3] = gen_rtx_PLUS (Pmode, operands[0],
17303 GEN_INT (GET_MODE_SIZE (GET_MODE
17305 /* Can't use this if the user has appropriated eax or edi. */
17306 if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
17307 && !(fixed_regs[AX_REG] || fixed_regs[DI_REG]))
17309 emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
17315 (define_expand "strset_singleop"
17316 [(parallel [(set (match_operand 1 "memory_operand")
17317 (match_operand 2 "register_operand"))
17318 (set (match_operand 0 "register_operand")
17320 (unspec [(const_int 0)] UNSPEC_STOS)])]
17324 ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
17327 (define_insn "*strsetdi_rex_1"
17328 [(set (mem:DI (match_operand:P 1 "register_operand" "0"))
17329 (match_operand:DI 2 "register_operand" "a"))
17330 (set (match_operand:P 0 "register_operand" "=D")
17331 (plus:P (match_dup 1)
17333 (unspec [(const_int 0)] UNSPEC_STOS)]
17335 && !(fixed_regs[AX_REG] || fixed_regs[DI_REG])
17336 && ix86_check_no_addr_space (insn)"
17338 [(set_attr "type" "str")
17339 (set_attr "memory" "store")
17340 (set_attr "mode" "DI")])
17342 (define_insn "*strsetsi_1"
17343 [(set (mem:SI (match_operand:P 1 "register_operand" "0"))
17344 (match_operand:SI 2 "register_operand" "a"))
17345 (set (match_operand:P 0 "register_operand" "=D")
17346 (plus:P (match_dup 1)
17348 (unspec [(const_int 0)] UNSPEC_STOS)]
17349 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])
17350 && ix86_check_no_addr_space (insn)"
17352 [(set_attr "type" "str")
17353 (set_attr "memory" "store")
17354 (set_attr "mode" "SI")])
17356 (define_insn "*strsethi_1"
17357 [(set (mem:HI (match_operand:P 1 "register_operand" "0"))
17358 (match_operand:HI 2 "register_operand" "a"))
17359 (set (match_operand:P 0 "register_operand" "=D")
17360 (plus:P (match_dup 1)
17362 (unspec [(const_int 0)] UNSPEC_STOS)]
17363 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])
17364 && ix86_check_no_addr_space (insn)"
17366 [(set_attr "type" "str")
17367 (set_attr "memory" "store")
17368 (set_attr "mode" "HI")])
17370 (define_insn "*strsetqi_1"
17371 [(set (mem:QI (match_operand:P 1 "register_operand" "0"))
17372 (match_operand:QI 2 "register_operand" "a"))
17373 (set (match_operand:P 0 "register_operand" "=D")
17374 (plus:P (match_dup 1)
17376 (unspec [(const_int 0)] UNSPEC_STOS)]
17377 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])
17378 && ix86_check_no_addr_space (insn)"
17380 [(set_attr "type" "str")
17381 (set_attr "memory" "store")
17382 (set (attr "prefix_rex")
17384 (match_test "<P:MODE>mode == DImode")
17386 (const_string "*")))
17387 (set_attr "mode" "QI")])
17389 (define_expand "rep_stos"
17390 [(parallel [(set (match_operand 1 "register_operand") (const_int 0))
17391 (set (match_operand 0 "register_operand")
17393 (set (match_operand 2 "memory_operand") (const_int 0))
17394 (use (match_operand 3 "register_operand"))
17395 (use (match_dup 1))])]
17399 ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
17402 (define_insn "*rep_stosdi_rex64"
17403 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
17404 (set (match_operand:P 0 "register_operand" "=D")
17405 (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
17407 (match_operand:P 3 "register_operand" "0")))
17408 (set (mem:BLK (match_dup 3))
17410 (use (match_operand:DI 2 "register_operand" "a"))
17411 (use (match_dup 4))]
17413 && !(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])
17414 && ix86_check_no_addr_space (insn)"
17416 [(set_attr "type" "str")
17417 (set_attr "prefix_rep" "1")
17418 (set_attr "memory" "store")
17419 (set_attr "mode" "DI")])
17421 (define_insn "*rep_stossi"
17422 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
17423 (set (match_operand:P 0 "register_operand" "=D")
17424 (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
17426 (match_operand:P 3 "register_operand" "0")))
17427 (set (mem:BLK (match_dup 3))
17429 (use (match_operand:SI 2 "register_operand" "a"))
17430 (use (match_dup 4))]
17431 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])
17432 && ix86_check_no_addr_space (insn)"
17433 "%^rep{%;} stos{l|d}"
17434 [(set_attr "type" "str")
17435 (set_attr "prefix_rep" "1")
17436 (set_attr "memory" "store")
17437 (set_attr "mode" "SI")])
17439 (define_insn "*rep_stosqi"
17440 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
17441 (set (match_operand:P 0 "register_operand" "=D")
17442 (plus:P (match_operand:P 3 "register_operand" "0")
17443 (match_operand:P 4 "register_operand" "1")))
17444 (set (mem:BLK (match_dup 3))
17446 (use (match_operand:QI 2 "register_operand" "a"))
17447 (use (match_dup 4))]
17448 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])
17449 && ix86_check_no_addr_space (insn)"
17451 [(set_attr "type" "str")
17452 (set_attr "prefix_rep" "1")
17453 (set_attr "memory" "store")
17454 (set (attr "prefix_rex")
17456 (match_test "<P:MODE>mode == DImode")
17458 (const_string "*")))
17459 (set_attr "mode" "QI")])
17461 (define_expand "cmpstrnsi"
17462 [(set (match_operand:SI 0 "register_operand")
17463 (compare:SI (match_operand:BLK 1 "general_operand")
17464 (match_operand:BLK 2 "general_operand")))
17465 (use (match_operand 3 "general_operand"))
17466 (use (match_operand 4 "immediate_operand"))]
17469 rtx addr1, addr2, out, outlow, count, countreg, align;
17471 if (optimize_insn_for_size_p () && !TARGET_INLINE_ALL_STRINGOPS)
17474 /* Can't use this if the user has appropriated ecx, esi or edi. */
17475 if (fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
17478 /* One of the strings must be a constant. If so, expand_builtin_strncmp()
17479 will have rewritten the length arg to be the minimum of the const string
17480 length and the actual length arg. If both strings are the same and
17481 shorter than the length arg, repz cmpsb will not stop at the 0 byte and
17482 will incorrectly base the results on chars past the 0 byte. */
17483 tree t1 = MEM_EXPR (operands[1]);
17484 tree t2 = MEM_EXPR (operands[2]);
17485 if (!((t1 && TREE_CODE (t1) == MEM_REF
17486 && TREE_CODE (TREE_OPERAND (t1, 0)) == ADDR_EXPR
17487 && TREE_CODE (TREE_OPERAND (TREE_OPERAND (t1, 0), 0)) == STRING_CST)
17488 || (t2 && TREE_CODE (t2) == MEM_REF
17489 && TREE_CODE (TREE_OPERAND (t2, 0)) == ADDR_EXPR
17490 && TREE_CODE (TREE_OPERAND (TREE_OPERAND (t2, 0), 0)) == STRING_CST)))
17495 out = gen_reg_rtx (SImode);
17497 addr1 = copy_addr_to_reg (XEXP (operands[1], 0));
17498 addr2 = copy_addr_to_reg (XEXP (operands[2], 0));
17499 if (addr1 != XEXP (operands[1], 0))
17500 operands[1] = replace_equiv_address_nv (operands[1], addr1);
17501 if (addr2 != XEXP (operands[2], 0))
17502 operands[2] = replace_equiv_address_nv (operands[2], addr2);
17504 count = operands[3];
17505 countreg = ix86_zero_extend_to_Pmode (count);
17507 /* %%% Iff we are testing strict equality, we can use known alignment
17508 to good advantage. This may be possible with combine, particularly
17509 once cc0 is dead. */
17510 align = operands[4];
17512 if (CONST_INT_P (count))
17514 if (INTVAL (count) == 0)
17516 emit_move_insn (operands[0], const0_rtx);
17519 emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
17520 operands[1], operands[2]));
17524 rtx (*gen_cmp) (rtx, rtx);
17526 gen_cmp = (TARGET_64BIT
17527 ? gen_cmpdi_1 : gen_cmpsi_1);
17529 emit_insn (gen_cmp (countreg, countreg));
17530 emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
17531 operands[1], operands[2]));
17534 outlow = gen_lowpart (QImode, out);
17535 emit_insn (gen_cmpintqi (outlow));
17536 emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
17538 if (operands[0] != out)
17539 emit_move_insn (operands[0], out);
17544 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
17546 (define_expand "cmpintqi"
17547 [(set (match_dup 1)
17548 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
17550 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
17551 (parallel [(set (match_operand:QI 0 "register_operand")
17552 (minus:QI (match_dup 1)
17554 (clobber (reg:CC FLAGS_REG))])]
17557 operands[1] = gen_reg_rtx (QImode);
17558 operands[2] = gen_reg_rtx (QImode);
17561 ;; memcmp recognizers. The `cmpsb' opcode does nothing if the count is
17562 ;; zero. Emit extra code to make sure that a zero-length compare is EQ.
17564 (define_expand "cmpstrnqi_nz_1"
17565 [(parallel [(set (reg:CC FLAGS_REG)
17566 (compare:CC (match_operand 4 "memory_operand")
17567 (match_operand 5 "memory_operand")))
17568 (use (match_operand 2 "register_operand"))
17569 (use (match_operand:SI 3 "immediate_operand"))
17570 (clobber (match_operand 0 "register_operand"))
17571 (clobber (match_operand 1 "register_operand"))
17572 (clobber (match_dup 2))])]
17576 ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
17579 (define_insn "*cmpstrnqi_nz_1"
17580 [(set (reg:CC FLAGS_REG)
17581 (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
17582 (mem:BLK (match_operand:P 5 "register_operand" "1"))))
17583 (use (match_operand:P 6 "register_operand" "2"))
17584 (use (match_operand:SI 3 "immediate_operand" "i"))
17585 (clobber (match_operand:P 0 "register_operand" "=S"))
17586 (clobber (match_operand:P 1 "register_operand" "=D"))
17587 (clobber (match_operand:P 2 "register_operand" "=c"))]
17588 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
17589 && ix86_check_no_addr_space (insn)"
17591 [(set_attr "type" "str")
17592 (set_attr "mode" "QI")
17593 (set (attr "prefix_rex")
17595 (match_test "<P:MODE>mode == DImode")
17597 (const_string "*")))
17598 (set_attr "prefix_rep" "1")])
17600 ;; The same, but the count is not known to not be zero.
17602 (define_expand "cmpstrnqi_1"
17603 [(parallel [(set (reg:CC FLAGS_REG)
17604 (if_then_else:CC (ne (match_operand 2 "register_operand")
17606 (compare:CC (match_operand 4 "memory_operand")
17607 (match_operand 5 "memory_operand"))
17609 (use (match_operand:SI 3 "immediate_operand"))
17610 (use (reg:CC FLAGS_REG))
17611 (clobber (match_operand 0 "register_operand"))
17612 (clobber (match_operand 1 "register_operand"))
17613 (clobber (match_dup 2))])]
17617 ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
17620 (define_insn "*cmpstrnqi_1"
17621 [(set (reg:CC FLAGS_REG)
17622 (if_then_else:CC (ne (match_operand:P 6 "register_operand" "2")
17624 (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
17625 (mem:BLK (match_operand:P 5 "register_operand" "1")))
17627 (use (match_operand:SI 3 "immediate_operand" "i"))
17628 (use (reg:CC FLAGS_REG))
17629 (clobber (match_operand:P 0 "register_operand" "=S"))
17630 (clobber (match_operand:P 1 "register_operand" "=D"))
17631 (clobber (match_operand:P 2 "register_operand" "=c"))]
17632 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
17633 && ix86_check_no_addr_space (insn)"
17635 [(set_attr "type" "str")
17636 (set_attr "mode" "QI")
17637 (set (attr "prefix_rex")
17639 (match_test "<P:MODE>mode == DImode")
17641 (const_string "*")))
17642 (set_attr "prefix_rep" "1")])
17644 (define_expand "strlen<mode>"
17645 [(set (match_operand:P 0 "register_operand")
17646 (unspec:P [(match_operand:BLK 1 "general_operand")
17647 (match_operand:QI 2 "immediate_operand")
17648 (match_operand 3 "immediate_operand")]
17652 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
17658 (define_expand "strlenqi_1"
17659 [(parallel [(set (match_operand 0 "register_operand")
17661 (clobber (match_operand 1 "register_operand"))
17662 (clobber (reg:CC FLAGS_REG))])]
17666 ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
17669 (define_insn "*strlenqi_1"
17670 [(set (match_operand:P 0 "register_operand" "=&c")
17671 (unspec:P [(mem:BLK (match_operand:P 5 "register_operand" "1"))
17672 (match_operand:QI 2 "register_operand" "a")
17673 (match_operand:P 3 "immediate_operand" "i")
17674 (match_operand:P 4 "register_operand" "0")] UNSPEC_SCAS))
17675 (clobber (match_operand:P 1 "register_operand" "=D"))
17676 (clobber (reg:CC FLAGS_REG))]
17677 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])
17678 && ix86_check_no_addr_space (insn)"
17679 "%^repnz{%;} scasb"
17680 [(set_attr "type" "str")
17681 (set_attr "mode" "QI")
17682 (set (attr "prefix_rex")
17684 (match_test "<P:MODE>mode == DImode")
17686 (const_string "*")))
17687 (set_attr "prefix_rep" "1")])
17689 ;; Peephole optimizations to clean up after cmpstrn*. This should be
17690 ;; handled in combine, but it is not currently up to the task.
17691 ;; When used for their truth value, the cmpstrn* expanders generate
17700 ;; The intermediate three instructions are unnecessary.
17702 ;; This one handles cmpstrn*_nz_1...
17705 (set (reg:CC FLAGS_REG)
17706 (compare:CC (mem:BLK (match_operand 4 "register_operand"))
17707 (mem:BLK (match_operand 5 "register_operand"))))
17708 (use (match_operand 6 "register_operand"))
17709 (use (match_operand:SI 3 "immediate_operand"))
17710 (clobber (match_operand 0 "register_operand"))
17711 (clobber (match_operand 1 "register_operand"))
17712 (clobber (match_operand 2 "register_operand"))])
17713 (set (match_operand:QI 7 "register_operand")
17714 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
17715 (set (match_operand:QI 8 "register_operand")
17716 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
17717 (set (reg FLAGS_REG)
17718 (compare (match_dup 7) (match_dup 8)))
17720 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
17722 (set (reg:CC FLAGS_REG)
17723 (compare:CC (mem:BLK (match_dup 4))
17724 (mem:BLK (match_dup 5))))
17725 (use (match_dup 6))
17726 (use (match_dup 3))
17727 (clobber (match_dup 0))
17728 (clobber (match_dup 1))
17729 (clobber (match_dup 2))])])
17731 ;; ...and this one handles cmpstrn*_1.
17734 (set (reg:CC FLAGS_REG)
17735 (if_then_else:CC (ne (match_operand 6 "register_operand")
17737 (compare:CC (mem:BLK (match_operand 4 "register_operand"))
17738 (mem:BLK (match_operand 5 "register_operand")))
17740 (use (match_operand:SI 3 "immediate_operand"))
17741 (use (reg:CC FLAGS_REG))
17742 (clobber (match_operand 0 "register_operand"))
17743 (clobber (match_operand 1 "register_operand"))
17744 (clobber (match_operand 2 "register_operand"))])
17745 (set (match_operand:QI 7 "register_operand")
17746 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
17747 (set (match_operand:QI 8 "register_operand")
17748 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
17749 (set (reg FLAGS_REG)
17750 (compare (match_dup 7) (match_dup 8)))
17752 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
17754 (set (reg:CC FLAGS_REG)
17755 (if_then_else:CC (ne (match_dup 6)
17757 (compare:CC (mem:BLK (match_dup 4))
17758 (mem:BLK (match_dup 5)))
17760 (use (match_dup 3))
17761 (use (reg:CC FLAGS_REG))
17762 (clobber (match_dup 0))
17763 (clobber (match_dup 1))
17764 (clobber (match_dup 2))])])
17766 ;; Conditional move instructions.
17768 (define_expand "mov<mode>cc"
17769 [(set (match_operand:SWIM 0 "register_operand")
17770 (if_then_else:SWIM (match_operand 1 "comparison_operator")
17771 (match_operand:SWIM 2 "<general_operand>")
17772 (match_operand:SWIM 3 "<general_operand>")))]
17774 "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
17776 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
17777 ;; the register first winds up with `sbbl $0,reg', which is also weird.
17778 ;; So just document what we're doing explicitly.
17780 (define_expand "x86_mov<mode>cc_0_m1"
17782 [(set (match_operand:SWI48 0 "register_operand")
17783 (if_then_else:SWI48
17784 (match_operator:SWI48 2 "ix86_carry_flag_operator"
17785 [(match_operand 1 "flags_reg_operand")
17789 (clobber (reg:CC FLAGS_REG))])])
17791 (define_insn "*x86_mov<mode>cc_0_m1"
17792 [(set (match_operand:SWI48 0 "register_operand" "=r")
17793 (if_then_else:SWI48 (match_operator 1 "ix86_carry_flag_operator"
17794 [(reg FLAGS_REG) (const_int 0)])
17797 (clobber (reg:CC FLAGS_REG))]
17799 "sbb{<imodesuffix>}\t%0, %0"
17800 ; Since we don't have the proper number of operands for an alu insn,
17801 ; fill in all the blanks.
17802 [(set_attr "type" "alu")
17803 (set_attr "modrm_class" "op0")
17804 (set_attr "use_carry" "1")
17805 (set_attr "pent_pair" "pu")
17806 (set_attr "memory" "none")
17807 (set_attr "imm_disp" "false")
17808 (set_attr "mode" "<MODE>")
17809 (set_attr "length_immediate" "0")])
17811 (define_insn "*x86_mov<mode>cc_0_m1_se"
17812 [(set (match_operand:SWI48 0 "register_operand" "=r")
17813 (sign_extract:SWI48 (match_operator 1 "ix86_carry_flag_operator"
17814 [(reg FLAGS_REG) (const_int 0)])
17817 (clobber (reg:CC FLAGS_REG))]
17819 "sbb{<imodesuffix>}\t%0, %0"
17820 [(set_attr "type" "alu")
17821 (set_attr "modrm_class" "op0")
17822 (set_attr "use_carry" "1")
17823 (set_attr "pent_pair" "pu")
17824 (set_attr "memory" "none")
17825 (set_attr "imm_disp" "false")
17826 (set_attr "mode" "<MODE>")
17827 (set_attr "length_immediate" "0")])
17829 (define_insn "*x86_mov<mode>cc_0_m1_neg"
17830 [(set (match_operand:SWI48 0 "register_operand" "=r")
17831 (neg:SWI48 (match_operator 1 "ix86_carry_flag_operator"
17832 [(reg FLAGS_REG) (const_int 0)])))
17833 (clobber (reg:CC FLAGS_REG))]
17835 "sbb{<imodesuffix>}\t%0, %0"
17836 [(set_attr "type" "alu")
17837 (set_attr "modrm_class" "op0")
17838 (set_attr "use_carry" "1")
17839 (set_attr "pent_pair" "pu")
17840 (set_attr "memory" "none")
17841 (set_attr "imm_disp" "false")
17842 (set_attr "mode" "<MODE>")
17843 (set_attr "length_immediate" "0")])
17845 (define_insn "*mov<mode>cc_noc"
17846 [(set (match_operand:SWI248 0 "register_operand" "=r,r")
17847 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
17848 [(reg FLAGS_REG) (const_int 0)])
17849 (match_operand:SWI248 2 "nonimmediate_operand" "rm,0")
17850 (match_operand:SWI248 3 "nonimmediate_operand" "0,rm")))]
17851 "TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
17853 cmov%O2%C1\t{%2, %0|%0, %2}
17854 cmov%O2%c1\t{%3, %0|%0, %3}"
17855 [(set_attr "type" "icmov")
17856 (set_attr "mode" "<MODE>")])
17858 (define_insn "*movsicc_noc_zext"
17859 [(set (match_operand:DI 0 "register_operand" "=r,r")
17860 (if_then_else:DI (match_operator 1 "ix86_comparison_operator"
17861 [(reg FLAGS_REG) (const_int 0)])
17863 (match_operand:SI 2 "nonimmediate_operand" "rm,0"))
17865 (match_operand:SI 3 "nonimmediate_operand" "0,rm"))))]
17867 && TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
17869 cmov%O2%C1\t{%2, %k0|%k0, %2}
17870 cmov%O2%c1\t{%3, %k0|%k0, %3}"
17871 [(set_attr "type" "icmov")
17872 (set_attr "mode" "SI")])
17874 ;; Don't do conditional moves with memory inputs. This splitter helps
17875 ;; register starved x86_32 by forcing inputs into registers before reload.
17877 [(set (match_operand:SWI248 0 "register_operand")
17878 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
17879 [(reg FLAGS_REG) (const_int 0)])
17880 (match_operand:SWI248 2 "nonimmediate_operand")
17881 (match_operand:SWI248 3 "nonimmediate_operand")))]
17882 "!TARGET_64BIT && TARGET_CMOVE
17883 && TARGET_AVOID_MEM_OPND_FOR_CMOVE
17884 && (MEM_P (operands[2]) || MEM_P (operands[3]))
17885 && can_create_pseudo_p ()
17886 && optimize_insn_for_speed_p ()"
17887 [(set (match_dup 0)
17888 (if_then_else:SWI248 (match_dup 1) (match_dup 2) (match_dup 3)))]
17890 if (MEM_P (operands[2]))
17891 operands[2] = force_reg (<MODE>mode, operands[2]);
17892 if (MEM_P (operands[3]))
17893 operands[3] = force_reg (<MODE>mode, operands[3]);
17896 (define_insn "*movqicc_noc"
17897 [(set (match_operand:QI 0 "register_operand" "=r,r")
17898 (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
17899 [(reg FLAGS_REG) (const_int 0)])
17900 (match_operand:QI 2 "register_operand" "r,0")
17901 (match_operand:QI 3 "register_operand" "0,r")))]
17902 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
17904 [(set_attr "type" "icmov")
17905 (set_attr "mode" "QI")])
17908 [(set (match_operand:SWI12 0 "register_operand")
17909 (if_then_else:SWI12 (match_operator 1 "ix86_comparison_operator"
17910 [(reg FLAGS_REG) (const_int 0)])
17911 (match_operand:SWI12 2 "register_operand")
17912 (match_operand:SWI12 3 "register_operand")))]
17913 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL
17914 && reload_completed"
17915 [(set (match_dup 0)
17916 (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
17918 operands[0] = gen_lowpart (SImode, operands[0]);
17919 operands[2] = gen_lowpart (SImode, operands[2]);
17920 operands[3] = gen_lowpart (SImode, operands[3]);
17923 ;; Don't do conditional moves with memory inputs
17925 [(match_scratch:SWI248 4 "r")
17926 (set (match_operand:SWI248 0 "register_operand")
17927 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
17928 [(reg FLAGS_REG) (const_int 0)])
17929 (match_operand:SWI248 2 "nonimmediate_operand")
17930 (match_operand:SWI248 3 "nonimmediate_operand")))]
17931 "TARGET_CMOVE && TARGET_AVOID_MEM_OPND_FOR_CMOVE
17932 && (MEM_P (operands[2]) || MEM_P (operands[3]))
17933 && optimize_insn_for_speed_p ()"
17934 [(set (match_dup 4) (match_dup 5))
17936 (if_then_else:SWI248 (match_dup 1) (match_dup 2) (match_dup 3)))]
17938 if (MEM_P (operands[2]))
17940 operands[5] = operands[2];
17941 operands[2] = operands[4];
17943 else if (MEM_P (operands[3]))
17945 operands[5] = operands[3];
17946 operands[3] = operands[4];
17949 gcc_unreachable ();
17953 [(match_scratch:SI 4 "r")
17954 (set (match_operand:DI 0 "register_operand")
17955 (if_then_else:DI (match_operator 1 "ix86_comparison_operator"
17956 [(reg FLAGS_REG) (const_int 0)])
17958 (match_operand:SI 2 "nonimmediate_operand"))
17960 (match_operand:SI 3 "nonimmediate_operand"))))]
17962 && TARGET_CMOVE && TARGET_AVOID_MEM_OPND_FOR_CMOVE
17963 && (MEM_P (operands[2]) || MEM_P (operands[3]))
17964 && optimize_insn_for_speed_p ()"
17965 [(set (match_dup 4) (match_dup 5))
17967 (if_then_else:DI (match_dup 1)
17968 (zero_extend:DI (match_dup 2))
17969 (zero_extend:DI (match_dup 3))))]
17971 if (MEM_P (operands[2]))
17973 operands[5] = operands[2];
17974 operands[2] = operands[4];
17976 else if (MEM_P (operands[3]))
17978 operands[5] = operands[3];
17979 operands[3] = operands[4];
17982 gcc_unreachable ();
17985 (define_expand "mov<mode>cc"
17986 [(set (match_operand:X87MODEF 0 "register_operand")
17987 (if_then_else:X87MODEF
17988 (match_operand 1 "comparison_operator")
17989 (match_operand:X87MODEF 2 "register_operand")
17990 (match_operand:X87MODEF 3 "register_operand")))]
17991 "(TARGET_80387 && TARGET_CMOVE)
17992 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
17993 "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
17995 (define_insn "*movxfcc_1"
17996 [(set (match_operand:XF 0 "register_operand" "=f,f")
17997 (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
17998 [(reg FLAGS_REG) (const_int 0)])
17999 (match_operand:XF 2 "register_operand" "f,0")
18000 (match_operand:XF 3 "register_operand" "0,f")))]
18001 "TARGET_80387 && TARGET_CMOVE"
18003 fcmov%F1\t{%2, %0|%0, %2}
18004 fcmov%f1\t{%3, %0|%0, %3}"
18005 [(set_attr "type" "fcmov")
18006 (set_attr "mode" "XF")])
18008 (define_insn "*movdfcc_1"
18009 [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r,r ,r")
18010 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
18011 [(reg FLAGS_REG) (const_int 0)])
18012 (match_operand:DF 2 "nonimmediate_operand"
18014 (match_operand:DF 3 "nonimmediate_operand"
18015 "0 ,f,0 ,rm,0, rm")))]
18016 "TARGET_80387 && TARGET_CMOVE
18017 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
18019 fcmov%F1\t{%2, %0|%0, %2}
18020 fcmov%f1\t{%3, %0|%0, %3}
18023 cmov%O2%C1\t{%2, %0|%0, %2}
18024 cmov%O2%c1\t{%3, %0|%0, %3}"
18025 [(set_attr "isa" "*,*,nox64,nox64,x64,x64")
18026 (set_attr "type" "fcmov,fcmov,multi,multi,icmov,icmov")
18027 (set_attr "mode" "DF,DF,DI,DI,DI,DI")])
18030 [(set (match_operand:DF 0 "general_reg_operand")
18031 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
18032 [(reg FLAGS_REG) (const_int 0)])
18033 (match_operand:DF 2 "nonimmediate_operand")
18034 (match_operand:DF 3 "nonimmediate_operand")))]
18035 "!TARGET_64BIT && reload_completed"
18036 [(set (match_dup 2)
18037 (if_then_else:SI (match_dup 1) (match_dup 4) (match_dup 5)))
18039 (if_then_else:SI (match_dup 1) (match_dup 6) (match_dup 7)))]
18041 split_double_mode (DImode, &operands[2], 2, &operands[4], &operands[6]);
18042 split_double_mode (DImode, &operands[0], 1, &operands[2], &operands[3]);
18045 (define_insn "*movsfcc_1_387"
18046 [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
18047 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
18048 [(reg FLAGS_REG) (const_int 0)])
18049 (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
18050 (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
18051 "TARGET_80387 && TARGET_CMOVE
18052 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
18054 fcmov%F1\t{%2, %0|%0, %2}
18055 fcmov%f1\t{%3, %0|%0, %3}
18056 cmov%O2%C1\t{%2, %0|%0, %2}
18057 cmov%O2%c1\t{%3, %0|%0, %3}"
18058 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
18059 (set_attr "mode" "SF,SF,SI,SI")])
18061 ;; Don't do conditional moves with memory inputs. This splitter helps
18062 ;; register starved x86_32 by forcing inputs into registers before reload.
18064 [(set (match_operand:MODEF 0 "register_operand")
18065 (if_then_else:MODEF (match_operator 1 "ix86_comparison_operator"
18066 [(reg FLAGS_REG) (const_int 0)])
18067 (match_operand:MODEF 2 "nonimmediate_operand")
18068 (match_operand:MODEF 3 "nonimmediate_operand")))]
18069 "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
18070 && TARGET_AVOID_MEM_OPND_FOR_CMOVE
18071 && (MEM_P (operands[2]) || MEM_P (operands[3]))
18072 && can_create_pseudo_p ()
18073 && optimize_insn_for_speed_p ()"
18074 [(set (match_dup 0)
18075 (if_then_else:MODEF (match_dup 1) (match_dup 2) (match_dup 3)))]
18077 if (MEM_P (operands[2]))
18078 operands[2] = force_reg (<MODE>mode, operands[2]);
18079 if (MEM_P (operands[3]))
18080 operands[3] = force_reg (<MODE>mode, operands[3]);
18083 ;; Don't do conditional moves with memory inputs
18085 [(match_scratch:MODEF 4 "r")
18086 (set (match_operand:MODEF 0 "general_reg_operand")
18087 (if_then_else:MODEF (match_operator 1 "fcmov_comparison_operator"
18088 [(reg FLAGS_REG) (const_int 0)])
18089 (match_operand:MODEF 2 "nonimmediate_operand")
18090 (match_operand:MODEF 3 "nonimmediate_operand")))]
18091 "(<MODE>mode != DFmode || TARGET_64BIT)
18092 && TARGET_80387 && TARGET_CMOVE
18093 && TARGET_AVOID_MEM_OPND_FOR_CMOVE
18094 && (MEM_P (operands[2]) || MEM_P (operands[3]))
18095 && optimize_insn_for_speed_p ()"
18096 [(set (match_dup 4) (match_dup 5))
18098 (if_then_else:MODEF (match_dup 1) (match_dup 2) (match_dup 3)))]
18100 if (MEM_P (operands[2]))
18102 operands[5] = operands[2];
18103 operands[2] = operands[4];
18105 else if (MEM_P (operands[3]))
18107 operands[5] = operands[3];
18108 operands[3] = operands[4];
18111 gcc_unreachable ();
18114 ;; All moves in XOP pcmov instructions are 128 bits and hence we restrict
18115 ;; the scalar versions to have only XMM registers as operands.
18117 ;; XOP conditional move
18118 (define_insn "*xop_pcmov_<mode>"
18119 [(set (match_operand:MODEF 0 "register_operand" "=x")
18120 (if_then_else:MODEF
18121 (match_operand:MODEF 1 "register_operand" "x")
18122 (match_operand:MODEF 2 "register_operand" "x")
18123 (match_operand:MODEF 3 "register_operand" "x")))]
18125 "vpcmov\t{%1, %3, %2, %0|%0, %2, %3, %1}"
18126 [(set_attr "type" "sse4arg")])
18128 ;; These versions of the min/max patterns are intentionally ignorant of
18129 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
18130 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
18131 ;; are undefined in this condition, we're certain this is correct.
18133 (define_insn "<code><mode>3"
18134 [(set (match_operand:MODEF 0 "register_operand" "=x,v")
18136 (match_operand:MODEF 1 "nonimmediate_operand" "%0,v")
18137 (match_operand:MODEF 2 "nonimmediate_operand" "xm,vm")))]
18138 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
18140 <maxmin_float><ssemodesuffix>\t{%2, %0|%0, %2}
18141 v<maxmin_float><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
18142 [(set_attr "isa" "noavx,avx")
18143 (set_attr "prefix" "orig,vex")
18144 (set_attr "type" "sseadd")
18145 (set_attr "mode" "<MODE>")])
18147 ;; These versions of the min/max patterns implement exactly the operations
18148 ;; min = (op1 < op2 ? op1 : op2)
18149 ;; max = (!(op1 < op2) ? op1 : op2)
18150 ;; Their operands are not commutative, and thus they may be used in the
18151 ;; presence of -0.0 and NaN.
18153 (define_insn "*ieee_s<ieee_maxmin><mode>3"
18154 [(set (match_operand:MODEF 0 "register_operand" "=x,v")
18156 [(match_operand:MODEF 1 "register_operand" "0,v")
18157 (match_operand:MODEF 2 "nonimmediate_operand" "xm,vm")]
18159 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
18161 <ieee_maxmin><ssemodesuffix>\t{%2, %0|%0, %2}
18162 v<ieee_maxmin><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
18163 [(set_attr "isa" "noavx,avx")
18164 (set_attr "prefix" "orig,maybe_evex")
18165 (set_attr "type" "sseadd")
18166 (set_attr "mode" "<MODE>")])
18168 ;; Make two stack loads independent:
18170 ;; fld %st(0) -> fld bb
18171 ;; fmul bb fmul %st(1), %st
18173 ;; Actually we only match the last two instructions for simplicity.
18176 [(set (match_operand 0 "fp_register_operand")
18177 (match_operand 1 "fp_register_operand"))
18179 (match_operator 2 "binary_fp_operator"
18181 (match_operand 3 "memory_operand")]))]
18182 "REGNO (operands[0]) != REGNO (operands[1])"
18183 [(set (match_dup 0) (match_dup 3))
18186 [(match_dup 5) (match_dup 4)]))]
18188 operands[4] = operands[0];
18189 operands[5] = operands[1];
18191 /* The % modifier is not operational anymore in peephole2's, so we have to
18192 swap the operands manually in the case of addition and multiplication. */
18193 if (COMMUTATIVE_ARITH_P (operands[2]))
18194 std::swap (operands[4], operands[5]);
18198 [(set (match_operand 0 "fp_register_operand")
18199 (match_operand 1 "fp_register_operand"))
18201 (match_operator 2 "binary_fp_operator"
18202 [(match_operand 3 "memory_operand")
18204 "REGNO (operands[0]) != REGNO (operands[1])"
18205 [(set (match_dup 0) (match_dup 3))
18208 [(match_dup 4) (match_dup 5)]))]
18210 operands[4] = operands[0];
18211 operands[5] = operands[1];
18213 /* The % modifier is not operational anymore in peephole2's, so we have to
18214 swap the operands manually in the case of addition and multiplication. */
18215 if (COMMUTATIVE_ARITH_P (operands[2]))
18216 std::swap (operands[4], operands[5]);
18219 ;; Conditional addition patterns
18220 (define_expand "add<mode>cc"
18221 [(match_operand:SWI 0 "register_operand")
18222 (match_operand 1 "ordered_comparison_operator")
18223 (match_operand:SWI 2 "register_operand")
18224 (match_operand:SWI 3 "const_int_operand")]
18226 "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
18228 ;; Misc patterns (?)
18230 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
18231 ;; Otherwise there will be nothing to keep
18233 ;; [(set (reg ebp) (reg esp))]
18234 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
18235 ;; (clobber (eflags)]
18236 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
18238 ;; in proper program order.
18240 (define_insn "pro_epilogue_adjust_stack_<mode>_add"
18241 [(set (match_operand:P 0 "register_operand" "=r,r")
18242 (plus:P (match_operand:P 1 "register_operand" "0,r")
18243 (match_operand:P 2 "<nonmemory_operand>" "r<i>,l<i>")))
18244 (clobber (reg:CC FLAGS_REG))
18245 (clobber (mem:BLK (scratch)))]
18248 switch (get_attr_type (insn))
18251 return "mov{<imodesuffix>}\t{%1, %0|%0, %1}";
18254 gcc_assert (rtx_equal_p (operands[0], operands[1]));
18255 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
18256 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
18258 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
18261 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
18262 return "lea{<imodesuffix>}\t{%E2, %0|%0, %E2}";
18265 [(set (attr "type")
18266 (cond [(and (eq_attr "alternative" "0")
18267 (not (match_test "TARGET_OPT_AGU")))
18268 (const_string "alu")
18269 (match_operand:<MODE> 2 "const0_operand")
18270 (const_string "imov")
18272 (const_string "lea")))
18273 (set (attr "length_immediate")
18274 (cond [(eq_attr "type" "imov")
18276 (and (eq_attr "type" "alu")
18277 (match_operand 2 "const128_operand"))
18280 (const_string "*")))
18281 (set_attr "mode" "<MODE>")])
18283 (define_insn "pro_epilogue_adjust_stack_<mode>_sub"
18284 [(set (match_operand:P 0 "register_operand" "=r")
18285 (minus:P (match_operand:P 1 "register_operand" "0")
18286 (match_operand:P 2 "register_operand" "r")))
18287 (clobber (reg:CC FLAGS_REG))
18288 (clobber (mem:BLK (scratch)))]
18290 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
18291 [(set_attr "type" "alu")
18292 (set_attr "mode" "<MODE>")])
18294 (define_insn "allocate_stack_worker_probe_<mode>"
18295 [(set (match_operand:P 0 "register_operand" "=a")
18296 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
18297 UNSPECV_STACK_PROBE))
18298 (clobber (reg:CC FLAGS_REG))]
18299 "ix86_target_stack_probe ()"
18300 "call\t___chkstk_ms"
18301 [(set_attr "type" "multi")
18302 (set_attr "length" "5")])
18304 (define_expand "allocate_stack"
18305 [(match_operand 0 "register_operand")
18306 (match_operand 1 "general_operand")]
18307 "ix86_target_stack_probe ()"
18311 #ifndef CHECK_STACK_LIMIT
18312 #define CHECK_STACK_LIMIT 0
18315 if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
18316 && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
18320 rtx (*insn) (rtx, rtx);
18322 x = copy_to_mode_reg (Pmode, operands[1]);
18324 insn = (TARGET_64BIT
18325 ? gen_allocate_stack_worker_probe_di
18326 : gen_allocate_stack_worker_probe_si);
18328 emit_insn (insn (x, x));
18331 x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, x,
18332 stack_pointer_rtx, 0, OPTAB_DIRECT);
18334 if (x != stack_pointer_rtx)
18335 emit_move_insn (stack_pointer_rtx, x);
18337 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
18341 (define_expand "probe_stack"
18342 [(match_operand 0 "memory_operand")]
18345 rtx (*insn) (rtx, rtx)
18346 = (GET_MODE (operands[0]) == DImode
18347 ? gen_probe_stack_di : gen_probe_stack_si);
18349 emit_insn (insn (operands[0], const0_rtx));
18353 ;; Use OR for stack probes, this is shorter.
18354 (define_insn "probe_stack_<mode>"
18355 [(set (match_operand:W 0 "memory_operand" "=m")
18356 (unspec:W [(match_operand:W 1 "const0_operand")]
18357 UNSPEC_PROBE_STACK))
18358 (clobber (reg:CC FLAGS_REG))]
18360 "or{<imodesuffix>}\t{%1, %0|%0, %1}"
18361 [(set_attr "type" "alu1")
18362 (set_attr "mode" "<MODE>")
18363 (set_attr "length_immediate" "1")])
18365 (define_insn "adjust_stack_and_probe<mode>"
18366 [(set (match_operand:P 0 "register_operand" "=r")
18367 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
18368 UNSPECV_PROBE_STACK_RANGE))
18369 (set (reg:P SP_REG)
18370 (minus:P (reg:P SP_REG) (match_operand:P 2 "const_int_operand" "n")))
18371 (clobber (reg:CC FLAGS_REG))
18372 (clobber (mem:BLK (scratch)))]
18374 "* return output_adjust_stack_and_probe (operands[0]);"
18375 [(set_attr "type" "multi")])
18377 (define_insn "probe_stack_range<mode>"
18378 [(set (match_operand:P 0 "register_operand" "=r")
18379 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
18380 (match_operand:P 2 "const_int_operand" "n")]
18381 UNSPECV_PROBE_STACK_RANGE))
18382 (clobber (reg:CC FLAGS_REG))]
18384 "* return output_probe_stack_range (operands[0], operands[2]);"
18385 [(set_attr "type" "multi")])
18387 /* Additional processing for builtin_setjmp. Store the shadow stack pointer
18388 as a forth element in jmpbuf. */
18389 (define_expand "builtin_setjmp_setup"
18390 [(match_operand 0 "address_operand")]
18393 if (flag_cf_protection & CF_RETURN)
18397 mem = gen_rtx_MEM (word_mode,
18398 plus_constant (Pmode, operands[0],
18399 3 * GET_MODE_SIZE (ptr_mode)));
18400 reg_ssp = gen_reg_rtx (word_mode);
18401 emit_insn (gen_rtx_SET (reg_ssp, const0_rtx));
18402 emit_insn ((word_mode == SImode)
18403 ? gen_rdsspsi (reg_ssp)
18404 : gen_rdsspdi (reg_ssp));
18405 emit_move_insn (mem, reg_ssp);
18410 (define_expand "builtin_setjmp_receiver"
18411 [(label_ref (match_operand 0))]
18412 "!TARGET_64BIT && flag_pic"
18418 rtx_code_label *label_rtx = gen_label_rtx ();
18419 emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
18420 xops[0] = xops[1] = pic_offset_table_rtx;
18421 xops[2] = machopic_gen_offset (gen_rtx_LABEL_REF (SImode, label_rtx));
18422 ix86_expand_binary_operator (MINUS, SImode, xops);
18426 emit_insn (gen_set_got (pic_offset_table_rtx));
18430 (define_expand "builtin_longjmp"
18431 [(match_operand 0 "address_operand")]
18434 rtx fp, lab, stack;
18435 rtx flags, jump, noadj_label, inc_label, loop_label;
18436 rtx reg_adj, reg_ssp, mem_buf, tmp, clob;
18437 machine_mode sa_mode = STACK_SAVEAREA_MODE (SAVE_NONLOCAL);
18439 /* Adjust the shadow stack pointer (ssp) to the value saved in the
18440 jmp_buf. The saving was done in the builtin_setjmp_setup. */
18441 if (flag_cf_protection & CF_RETURN)
18443 /* Get the current shadow stack pointer. The code below will check if
18444 SHSTK feature is enabled. If it is not enabled the RDSSP instruction
18446 reg_ssp = gen_reg_rtx (word_mode);
18447 emit_insn (gen_rtx_SET (reg_ssp, const0_rtx));
18448 emit_insn ((word_mode == SImode)
18449 ? gen_rdsspsi (reg_ssp)
18450 : gen_rdsspdi (reg_ssp));
18451 mem_buf = gen_rtx_MEM (word_mode,
18452 plus_constant (Pmode, operands[0],
18453 3 * GET_MODE_SIZE (ptr_mode)));
18455 /* Compare through substraction the saved and the current ssp to decide
18456 if ssp has to be adjusted. */
18457 tmp = gen_rtx_SET (reg_ssp, gen_rtx_MINUS (word_mode, reg_ssp, mem_buf));
18458 clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
18459 tmp = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, tmp, clob));
18462 /* Compare and jump over adjustment code. */
18463 noadj_label = gen_label_rtx ();
18464 flags = gen_rtx_REG (CCZmode, FLAGS_REG);
18465 tmp = gen_rtx_EQ (VOIDmode, flags, const0_rtx);
18466 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
18467 gen_rtx_LABEL_REF (VOIDmode, noadj_label),
18469 jump = emit_jump_insn (gen_rtx_SET (pc_rtx, tmp));
18470 JUMP_LABEL (jump) = noadj_label;
18472 /* Compute the numebr of frames to adjust. */
18473 reg_adj = gen_lowpart (ptr_mode, reg_ssp);
18474 tmp = gen_rtx_SET (reg_adj,
18475 gen_rtx_LSHIFTRT (ptr_mode,
18476 negate_rtx (ptr_mode, reg_adj),
18477 GEN_INT ((word_mode == SImode)
18480 clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
18481 tmp = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, tmp, clob));
18484 /* Check if number of frames <= 255 so no loop is needed. */
18485 tmp = gen_rtx_COMPARE (CCmode, reg_adj, GEN_INT (255));
18486 flags = gen_rtx_REG (CCmode, FLAGS_REG);
18487 emit_insn (gen_rtx_SET (flags, tmp));
18489 inc_label = gen_label_rtx ();
18490 tmp = gen_rtx_LEU (VOIDmode, flags, const0_rtx);
18491 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
18492 gen_rtx_LABEL_REF (VOIDmode, inc_label),
18494 jump = emit_jump_insn (gen_rtx_SET (pc_rtx, tmp));
18495 JUMP_LABEL (jump) = inc_label;
18497 /* Adjust the ssp in a loop. */
18498 loop_label = gen_label_rtx ();
18499 emit_label (loop_label);
18500 LABEL_NUSES (loop_label) = 1;
18502 emit_insn ((word_mode == SImode)
18503 ? gen_incsspsi (reg_ssp)
18504 : gen_incsspdi (reg_ssp));
18505 tmp = gen_rtx_SET (reg_adj, gen_rtx_MINUS (ptr_mode,
18508 clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
18509 tmp = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, tmp, clob));
18512 tmp = gen_rtx_COMPARE (CCmode, reg_adj, GEN_INT (255));
18513 flags = gen_rtx_REG (CCmode, FLAGS_REG);
18514 emit_insn (gen_rtx_SET (flags, tmp));
18516 /* Jump to the loop label. */
18517 tmp = gen_rtx_GTU (VOIDmode, flags, const0_rtx);
18518 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
18519 gen_rtx_LABEL_REF (VOIDmode, loop_label),
18521 jump = emit_jump_insn (gen_rtx_SET (pc_rtx, tmp));
18522 JUMP_LABEL (jump) = loop_label;
18524 emit_label (inc_label);
18525 LABEL_NUSES (inc_label) = 1;
18526 emit_insn ((word_mode == SImode)
18527 ? gen_incsspsi (reg_ssp)
18528 : gen_incsspdi (reg_ssp));
18530 emit_label (noadj_label);
18531 LABEL_NUSES (noadj_label) = 1;
18534 /* This code is the same as in expand_buildin_longjmp. */
18535 fp = gen_rtx_MEM (ptr_mode, operands[0]);
18536 lab = gen_rtx_MEM (ptr_mode, plus_constant (Pmode, operands[0],
18537 GET_MODE_SIZE (ptr_mode)));
18538 stack = gen_rtx_MEM (sa_mode, plus_constant (Pmode, operands[0],
18539 2 * GET_MODE_SIZE (ptr_mode)));
18540 lab = copy_to_reg (lab);
18542 emit_clobber (gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (VOIDmode)));
18543 emit_clobber (gen_rtx_MEM (BLKmode, hard_frame_pointer_rtx));
18545 if (GET_MODE (fp) != Pmode)
18546 fp = convert_to_mode (Pmode, fp, 1);
18547 emit_move_insn (hard_frame_pointer_rtx, fp);
18548 emit_stack_restore (SAVE_NONLOCAL, stack);
18550 emit_use (hard_frame_pointer_rtx);
18551 emit_use (stack_pointer_rtx);
18552 emit_indirect_jump (lab);
18556 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
18557 ;; Do not split instructions with mask registers.
18559 [(set (match_operand 0 "general_reg_operand")
18560 (match_operator 3 "promotable_binary_operator"
18561 [(match_operand 1 "general_reg_operand")
18562 (match_operand 2 "aligned_operand")]))
18563 (clobber (reg:CC FLAGS_REG))]
18564 "! TARGET_PARTIAL_REG_STALL && reload_completed
18565 && ((GET_MODE (operands[0]) == HImode
18566 && ((optimize_function_for_speed_p (cfun) && !TARGET_FAST_PREFIX)
18567 /* ??? next two lines just !satisfies_constraint_K (...) */
18568 || !CONST_INT_P (operands[2])
18569 || satisfies_constraint_K (operands[2])))
18570 || (GET_MODE (operands[0]) == QImode
18571 && (TARGET_PROMOTE_QImode || optimize_function_for_size_p (cfun))))"
18572 [(parallel [(set (match_dup 0)
18573 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
18574 (clobber (reg:CC FLAGS_REG))])]
18576 operands[0] = gen_lowpart (SImode, operands[0]);
18577 operands[1] = gen_lowpart (SImode, operands[1]);
18578 if (GET_CODE (operands[3]) != ASHIFT)
18579 operands[2] = gen_lowpart (SImode, operands[2]);
18580 operands[3] = shallow_copy_rtx (operands[3]);
18581 PUT_MODE (operands[3], SImode);
18584 ; Promote the QImode tests, as i386 has encoding of the AND
18585 ; instruction with 32-bit sign-extended immediate and thus the
18586 ; instruction size is unchanged, except in the %eax case for
18587 ; which it is increased by one byte, hence the ! optimize_size.
18589 [(set (match_operand 0 "flags_reg_operand")
18590 (match_operator 2 "compare_operator"
18591 [(and (match_operand 3 "aligned_operand")
18592 (match_operand 4 "const_int_operand"))
18594 (set (match_operand 1 "register_operand")
18595 (and (match_dup 3) (match_dup 4)))]
18596 "! TARGET_PARTIAL_REG_STALL && reload_completed
18597 && optimize_insn_for_speed_p ()
18598 && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
18599 || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))
18600 /* Ensure that the operand will remain sign-extended immediate. */
18601 && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)"
18602 [(parallel [(set (match_dup 0)
18603 (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
18606 (and:SI (match_dup 3) (match_dup 4)))])]
18609 = gen_int_mode (INTVAL (operands[4])
18610 & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
18611 operands[1] = gen_lowpart (SImode, operands[1]);
18612 operands[3] = gen_lowpart (SImode, operands[3]);
18615 ; Don't promote the QImode tests, as i386 doesn't have encoding of
18616 ; the TEST instruction with 32-bit sign-extended immediate and thus
18617 ; the instruction size would at least double, which is not what we
18618 ; want even with ! optimize_size.
18620 [(set (match_operand 0 "flags_reg_operand")
18621 (match_operator 1 "compare_operator"
18622 [(and (match_operand:HI 2 "aligned_operand")
18623 (match_operand:HI 3 "const_int_operand"))
18625 "! TARGET_PARTIAL_REG_STALL && reload_completed
18626 && ! TARGET_FAST_PREFIX
18627 && optimize_insn_for_speed_p ()
18628 /* Ensure that the operand will remain sign-extended immediate. */
18629 && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)"
18630 [(set (match_dup 0)
18631 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
18635 = gen_int_mode (INTVAL (operands[3])
18636 & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
18637 operands[2] = gen_lowpart (SImode, operands[2]);
18641 [(set (match_operand 0 "register_operand")
18642 (neg (match_operand 1 "register_operand")))
18643 (clobber (reg:CC FLAGS_REG))]
18644 "! TARGET_PARTIAL_REG_STALL && reload_completed
18645 && (GET_MODE (operands[0]) == HImode
18646 || (GET_MODE (operands[0]) == QImode
18647 && (TARGET_PROMOTE_QImode
18648 || optimize_insn_for_size_p ())))"
18649 [(parallel [(set (match_dup 0)
18650 (neg:SI (match_dup 1)))
18651 (clobber (reg:CC FLAGS_REG))])]
18653 operands[0] = gen_lowpart (SImode, operands[0]);
18654 operands[1] = gen_lowpart (SImode, operands[1]);
18657 ;; Do not split instructions with mask regs.
18659 [(set (match_operand 0 "general_reg_operand")
18660 (not (match_operand 1 "general_reg_operand")))]
18661 "! TARGET_PARTIAL_REG_STALL && reload_completed
18662 && (GET_MODE (operands[0]) == HImode
18663 || (GET_MODE (operands[0]) == QImode
18664 && (TARGET_PROMOTE_QImode
18665 || optimize_insn_for_size_p ())))"
18666 [(set (match_dup 0)
18667 (not:SI (match_dup 1)))]
18669 operands[0] = gen_lowpart (SImode, operands[0]);
18670 operands[1] = gen_lowpart (SImode, operands[1]);
18673 ;; RTL Peephole optimizations, run before sched2. These primarily look to
18674 ;; transform a complex memory operation into two memory to register operations.
18676 ;; Don't push memory operands
18678 [(set (match_operand:SWI 0 "push_operand")
18679 (match_operand:SWI 1 "memory_operand"))
18680 (match_scratch:SWI 2 "<r>")]
18681 "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
18682 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
18683 [(set (match_dup 2) (match_dup 1))
18684 (set (match_dup 0) (match_dup 2))])
18686 ;; We need to handle SFmode only, because DFmode and XFmode are split to
18689 [(set (match_operand:SF 0 "push_operand")
18690 (match_operand:SF 1 "memory_operand"))
18691 (match_scratch:SF 2 "r")]
18692 "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
18693 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
18694 [(set (match_dup 2) (match_dup 1))
18695 (set (match_dup 0) (match_dup 2))])
18697 ;; Don't move an immediate directly to memory when the instruction
18698 ;; gets too big, or if LCP stalls are a problem for 16-bit moves.
18700 [(match_scratch:SWI124 1 "<r>")
18701 (set (match_operand:SWI124 0 "memory_operand")
18703 "optimize_insn_for_speed_p ()
18704 && ((<MODE>mode == HImode
18705 && TARGET_LCP_STALL)
18706 || (!TARGET_USE_MOV0
18707 && TARGET_SPLIT_LONG_MOVES
18708 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn))
18709 && peep2_regno_dead_p (0, FLAGS_REG)"
18710 [(parallel [(set (match_dup 2) (const_int 0))
18711 (clobber (reg:CC FLAGS_REG))])
18712 (set (match_dup 0) (match_dup 1))]
18713 "operands[2] = gen_lowpart (SImode, operands[1]);")
18716 [(match_scratch:SWI124 2 "<r>")
18717 (set (match_operand:SWI124 0 "memory_operand")
18718 (match_operand:SWI124 1 "immediate_operand"))]
18719 "optimize_insn_for_speed_p ()
18720 && ((<MODE>mode == HImode
18721 && TARGET_LCP_STALL)
18722 || (TARGET_SPLIT_LONG_MOVES
18723 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn))"
18724 [(set (match_dup 2) (match_dup 1))
18725 (set (match_dup 0) (match_dup 2))])
18727 ;; Don't compare memory with zero, load and use a test instead.
18729 [(set (match_operand 0 "flags_reg_operand")
18730 (match_operator 1 "compare_operator"
18731 [(match_operand:SI 2 "memory_operand")
18733 (match_scratch:SI 3 "r")]
18734 "optimize_insn_for_speed_p () && ix86_match_ccmode (insn, CCNOmode)"
18735 [(set (match_dup 3) (match_dup 2))
18736 (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))])
18738 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
18739 ;; Don't split NOTs with a displacement operand, because resulting XOR
18740 ;; will not be pairable anyway.
18742 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
18743 ;; represented using a modRM byte. The XOR replacement is long decoded,
18744 ;; so this split helps here as well.
18746 ;; Note: Can't do this as a regular split because we can't get proper
18747 ;; lifetime information then.
18750 [(set (match_operand:SWI124 0 "nonimmediate_gr_operand")
18751 (not:SWI124 (match_operand:SWI124 1 "nonimmediate_gr_operand")))]
18752 "optimize_insn_for_speed_p ()
18753 && ((TARGET_NOT_UNPAIRABLE
18754 && (!MEM_P (operands[0])
18755 || !memory_displacement_operand (operands[0], <MODE>mode)))
18756 || (TARGET_NOT_VECTORMODE
18757 && long_memory_operand (operands[0], <MODE>mode)))
18758 && peep2_regno_dead_p (0, FLAGS_REG)"
18759 [(parallel [(set (match_dup 0)
18760 (xor:SWI124 (match_dup 1) (const_int -1)))
18761 (clobber (reg:CC FLAGS_REG))])])
18763 ;; Non pairable "test imm, reg" instructions can be translated to
18764 ;; "and imm, reg" if reg dies. The "and" form is also shorter (one
18765 ;; byte opcode instead of two, have a short form for byte operands),
18766 ;; so do it for other CPUs as well. Given that the value was dead,
18767 ;; this should not create any new dependencies. Pass on the sub-word
18768 ;; versions if we're concerned about partial register stalls.
18771 [(set (match_operand 0 "flags_reg_operand")
18772 (match_operator 1 "compare_operator"
18773 [(and:SI (match_operand:SI 2 "register_operand")
18774 (match_operand:SI 3 "immediate_operand"))
18776 "ix86_match_ccmode (insn, CCNOmode)
18777 && (REGNO (operands[2]) != AX_REG
18778 || satisfies_constraint_K (operands[3]))
18779 && peep2_reg_dead_p (1, operands[2])"
18781 [(set (match_dup 0)
18782 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
18785 (and:SI (match_dup 2) (match_dup 3)))])])
18787 ;; We don't need to handle HImode case, because it will be promoted to SImode
18788 ;; on ! TARGET_PARTIAL_REG_STALL
18791 [(set (match_operand 0 "flags_reg_operand")
18792 (match_operator 1 "compare_operator"
18793 [(and:QI (match_operand:QI 2 "register_operand")
18794 (match_operand:QI 3 "immediate_operand"))
18796 "! TARGET_PARTIAL_REG_STALL
18797 && ix86_match_ccmode (insn, CCNOmode)
18798 && REGNO (operands[2]) != AX_REG
18799 && peep2_reg_dead_p (1, operands[2])"
18801 [(set (match_dup 0)
18802 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
18805 (and:QI (match_dup 2) (match_dup 3)))])])
18808 [(set (match_operand 0 "flags_reg_operand")
18809 (match_operator 1 "compare_operator"
18812 (zero_extract:SI (match_operand 2 "QIreg_operand")
18815 (match_operand 3 "const_int_operand"))
18817 "! TARGET_PARTIAL_REG_STALL
18818 && ix86_match_ccmode (insn, CCNOmode)
18819 && REGNO (operands[2]) != AX_REG
18820 && peep2_reg_dead_p (1, operands[2])"
18822 [(set (match_dup 0)
18826 (zero_extract:SI (match_dup 2)
18831 (set (zero_extract:SI (match_dup 2)
18837 (zero_extract:SI (match_dup 2)
18840 (match_dup 3)) 0))])])
18842 ;; Don't do logical operations with memory inputs.
18844 [(match_scratch:SWI 2 "<r>")
18845 (parallel [(set (match_operand:SWI 0 "register_operand")
18846 (match_operator:SWI 3 "arith_or_logical_operator"
18848 (match_operand:SWI 1 "memory_operand")]))
18849 (clobber (reg:CC FLAGS_REG))])]
18850 "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
18851 [(set (match_dup 2) (match_dup 1))
18852 (parallel [(set (match_dup 0)
18853 (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
18854 (clobber (reg:CC FLAGS_REG))])])
18857 [(match_scratch:SWI 2 "<r>")
18858 (parallel [(set (match_operand:SWI 0 "register_operand")
18859 (match_operator:SWI 3 "arith_or_logical_operator"
18860 [(match_operand:SWI 1 "memory_operand")
18862 (clobber (reg:CC FLAGS_REG))])]
18863 "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
18864 [(set (match_dup 2) (match_dup 1))
18865 (parallel [(set (match_dup 0)
18866 (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
18867 (clobber (reg:CC FLAGS_REG))])])
18869 ;; Prefer Load+RegOp to Mov+MemOp. Watch out for cases when
18870 ;; the memory address refers to the destination of the load!
18873 [(set (match_operand:SWI 0 "general_reg_operand")
18874 (match_operand:SWI 1 "general_reg_operand"))
18875 (parallel [(set (match_dup 0)
18876 (match_operator:SWI 3 "commutative_operator"
18878 (match_operand:SWI 2 "memory_operand")]))
18879 (clobber (reg:CC FLAGS_REG))])]
18880 "REGNO (operands[0]) != REGNO (operands[1])
18881 && (<MODE>mode != QImode
18882 || any_QIreg_operand (operands[1], QImode))"
18883 [(set (match_dup 0) (match_dup 4))
18884 (parallel [(set (match_dup 0)
18885 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))
18886 (clobber (reg:CC FLAGS_REG))])]
18887 "operands[4] = replace_rtx (operands[2], operands[0], operands[1], true);")
18890 [(set (match_operand 0 "mmx_reg_operand")
18891 (match_operand 1 "mmx_reg_operand"))
18893 (match_operator 3 "commutative_operator"
18895 (match_operand 2 "memory_operand")]))]
18896 "REGNO (operands[0]) != REGNO (operands[1])"
18897 [(set (match_dup 0) (match_dup 2))
18899 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))])
18902 [(set (match_operand 0 "sse_reg_operand")
18903 (match_operand 1 "sse_reg_operand"))
18905 (match_operator 3 "commutative_operator"
18907 (match_operand 2 "memory_operand")]))]
18908 "REGNO (operands[0]) != REGNO (operands[1])"
18909 [(set (match_dup 0) (match_dup 2))
18911 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))])
18913 ; Don't do logical operations with memory outputs
18915 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
18916 ; instruction into two 1-uop insns plus a 2-uop insn. That last has
18917 ; the same decoder scheduling characteristics as the original.
18920 [(match_scratch:SWI 2 "<r>")
18921 (parallel [(set (match_operand:SWI 0 "memory_operand")
18922 (match_operator:SWI 3 "arith_or_logical_operator"
18924 (match_operand:SWI 1 "<nonmemory_operand>")]))
18925 (clobber (reg:CC FLAGS_REG))])]
18926 "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())"
18927 [(set (match_dup 2) (match_dup 0))
18928 (parallel [(set (match_dup 2)
18929 (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
18930 (clobber (reg:CC FLAGS_REG))])
18931 (set (match_dup 0) (match_dup 2))])
18934 [(match_scratch:SWI 2 "<r>")
18935 (parallel [(set (match_operand:SWI 0 "memory_operand")
18936 (match_operator:SWI 3 "arith_or_logical_operator"
18937 [(match_operand:SWI 1 "<nonmemory_operand>")
18939 (clobber (reg:CC FLAGS_REG))])]
18940 "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())"
18941 [(set (match_dup 2) (match_dup 0))
18942 (parallel [(set (match_dup 2)
18943 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
18944 (clobber (reg:CC FLAGS_REG))])
18945 (set (match_dup 0) (match_dup 2))])
18947 ;; Attempt to use arith or logical operations with memory outputs with
18948 ;; setting of flags.
18950 [(set (match_operand:SWI 0 "register_operand")
18951 (match_operand:SWI 1 "memory_operand"))
18952 (parallel [(set (match_dup 0)
18953 (match_operator:SWI 3 "plusminuslogic_operator"
18955 (match_operand:SWI 2 "<nonmemory_operand>")]))
18956 (clobber (reg:CC FLAGS_REG))])
18957 (set (match_dup 1) (match_dup 0))
18958 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
18959 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
18960 && peep2_reg_dead_p (4, operands[0])
18961 && !reg_overlap_mentioned_p (operands[0], operands[1])
18962 && !reg_overlap_mentioned_p (operands[0], operands[2])
18963 && (<MODE>mode != QImode
18964 || immediate_operand (operands[2], QImode)
18965 || any_QIreg_operand (operands[2], QImode))
18966 && ix86_match_ccmode (peep2_next_insn (3),
18967 (GET_CODE (operands[3]) == PLUS
18968 || GET_CODE (operands[3]) == MINUS)
18969 ? CCGOCmode : CCNOmode)"
18970 [(parallel [(set (match_dup 4) (match_dup 6))
18971 (set (match_dup 1) (match_dup 5))])]
18973 operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
18975 = gen_rtx_fmt_ee (GET_CODE (operands[3]), GET_MODE (operands[3]),
18976 copy_rtx (operands[1]),
18979 = gen_rtx_COMPARE (GET_MODE (operands[4]),
18980 copy_rtx (operands[5]),
18984 ;; Likewise for instances where we have a lea pattern.
18986 [(set (match_operand:SWI 0 "register_operand")
18987 (match_operand:SWI 1 "memory_operand"))
18988 (set (match_operand:SWI 3 "register_operand")
18989 (plus:SWI (match_dup 0)
18990 (match_operand:SWI 2 "<nonmemory_operand>")))
18991 (set (match_dup 1) (match_dup 3))
18992 (set (reg FLAGS_REG) (compare (match_dup 3) (const_int 0)))]
18993 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
18994 && peep2_reg_dead_p (4, operands[3])
18995 && (rtx_equal_p (operands[0], operands[3])
18996 || peep2_reg_dead_p (2, operands[0]))
18997 && !reg_overlap_mentioned_p (operands[0], operands[1])
18998 && !reg_overlap_mentioned_p (operands[3], operands[1])
18999 && !reg_overlap_mentioned_p (operands[0], operands[2])
19000 && (<MODE>mode != QImode
19001 || immediate_operand (operands[2], QImode)
19002 || any_QIreg_operand (operands[2], QImode))
19003 && ix86_match_ccmode (peep2_next_insn (3), CCGOCmode)"
19004 [(parallel [(set (match_dup 4) (match_dup 6))
19005 (set (match_dup 1) (match_dup 5))])]
19007 operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
19009 = gen_rtx_PLUS (<MODE>mode,
19010 copy_rtx (operands[1]),
19013 = gen_rtx_COMPARE (GET_MODE (operands[4]),
19014 copy_rtx (operands[5]),
19019 [(parallel [(set (match_operand:SWI 0 "register_operand")
19020 (match_operator:SWI 2 "plusminuslogic_operator"
19022 (match_operand:SWI 1 "memory_operand")]))
19023 (clobber (reg:CC FLAGS_REG))])
19024 (set (match_dup 1) (match_dup 0))
19025 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
19026 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
19027 && GET_CODE (operands[2]) != MINUS
19028 && peep2_reg_dead_p (3, operands[0])
19029 && !reg_overlap_mentioned_p (operands[0], operands[1])
19030 && ix86_match_ccmode (peep2_next_insn (2),
19031 GET_CODE (operands[2]) == PLUS
19032 ? CCGOCmode : CCNOmode)"
19033 [(parallel [(set (match_dup 3) (match_dup 5))
19034 (set (match_dup 1) (match_dup 4))])]
19036 operands[3] = SET_DEST (PATTERN (peep2_next_insn (2)));
19038 = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
19039 copy_rtx (operands[1]),
19042 = gen_rtx_COMPARE (GET_MODE (operands[3]),
19043 copy_rtx (operands[4]),
19048 [(set (match_operand:SWI12 0 "register_operand")
19049 (match_operand:SWI12 1 "memory_operand"))
19050 (parallel [(set (match_operand:SI 4 "register_operand")
19051 (match_operator:SI 3 "plusminuslogic_operator"
19053 (match_operand:SI 2 "nonmemory_operand")]))
19054 (clobber (reg:CC FLAGS_REG))])
19055 (set (match_dup 1) (match_dup 0))
19056 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
19057 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
19058 && REGNO (operands[0]) == REGNO (operands[4])
19059 && peep2_reg_dead_p (4, operands[0])
19060 && (<MODE>mode != QImode
19061 || immediate_operand (operands[2], SImode)
19062 || any_QIreg_operand (operands[2], SImode))
19063 && !reg_overlap_mentioned_p (operands[0], operands[1])
19064 && !reg_overlap_mentioned_p (operands[0], operands[2])
19065 && ix86_match_ccmode (peep2_next_insn (3),
19066 (GET_CODE (operands[3]) == PLUS
19067 || GET_CODE (operands[3]) == MINUS)
19068 ? CCGOCmode : CCNOmode)"
19069 [(parallel [(set (match_dup 4) (match_dup 6))
19070 (set (match_dup 1) (match_dup 5))])]
19072 operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
19074 = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
19075 copy_rtx (operands[1]),
19076 gen_lowpart (<MODE>mode, operands[2]));
19078 = gen_rtx_COMPARE (GET_MODE (operands[4]),
19079 copy_rtx (operands[5]),
19083 ;; Attempt to always use XOR for zeroing registers (including FP modes).
19085 [(set (match_operand 0 "general_reg_operand")
19086 (match_operand 1 "const0_operand"))]
19087 "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
19088 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
19089 && peep2_regno_dead_p (0, FLAGS_REG)"
19090 [(parallel [(set (match_dup 0) (const_int 0))
19091 (clobber (reg:CC FLAGS_REG))])]
19092 "operands[0] = gen_lowpart (word_mode, operands[0]);")
19095 [(set (strict_low_part (match_operand:SWI12 0 "general_reg_operand"))
19097 "(! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
19098 && peep2_regno_dead_p (0, FLAGS_REG)"
19099 [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
19100 (clobber (reg:CC FLAGS_REG))])])
19102 ;; For HI, SI and DI modes, or $-1,reg is smaller than mov $-1,reg.
19104 [(set (match_operand:SWI248 0 "general_reg_operand")
19106 "(TARGET_MOVE_M1_VIA_OR || optimize_insn_for_size_p ())
19107 && peep2_regno_dead_p (0, FLAGS_REG)"
19108 [(parallel [(set (match_dup 0) (const_int -1))
19109 (clobber (reg:CC FLAGS_REG))])]
19111 if (<MODE_SIZE> < GET_MODE_SIZE (SImode))
19112 operands[0] = gen_lowpart (SImode, operands[0]);
19115 ;; Attempt to convert simple lea to add/shift.
19116 ;; These can be created by move expanders.
19117 ;; Disable PLUS peepholes on TARGET_OPT_AGU, since all
19118 ;; relevant lea instructions were already split.
19121 [(set (match_operand:SWI48 0 "register_operand")
19122 (plus:SWI48 (match_dup 0)
19123 (match_operand:SWI48 1 "<nonmemory_operand>")))]
19125 && peep2_regno_dead_p (0, FLAGS_REG)"
19126 [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1)))
19127 (clobber (reg:CC FLAGS_REG))])])
19130 [(set (match_operand:SWI48 0 "register_operand")
19131 (plus:SWI48 (match_operand:SWI48 1 "<nonmemory_operand>")
19134 && peep2_regno_dead_p (0, FLAGS_REG)"
19135 [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1)))
19136 (clobber (reg:CC FLAGS_REG))])])
19139 [(set (match_operand:DI 0 "register_operand")
19141 (plus:SI (match_operand:SI 1 "register_operand")
19142 (match_operand:SI 2 "nonmemory_operand"))))]
19143 "TARGET_64BIT && !TARGET_OPT_AGU
19144 && REGNO (operands[0]) == REGNO (operands[1])
19145 && peep2_regno_dead_p (0, FLAGS_REG)"
19146 [(parallel [(set (match_dup 0)
19147 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))
19148 (clobber (reg:CC FLAGS_REG))])])
19151 [(set (match_operand:DI 0 "register_operand")
19153 (plus:SI (match_operand:SI 1 "nonmemory_operand")
19154 (match_operand:SI 2 "register_operand"))))]
19155 "TARGET_64BIT && !TARGET_OPT_AGU
19156 && REGNO (operands[0]) == REGNO (operands[2])
19157 && peep2_regno_dead_p (0, FLAGS_REG)"
19158 [(parallel [(set (match_dup 0)
19159 (zero_extend:DI (plus:SI (match_dup 2) (match_dup 1))))
19160 (clobber (reg:CC FLAGS_REG))])])
19163 [(set (match_operand:SWI48 0 "register_operand")
19164 (mult:SWI48 (match_dup 0)
19165 (match_operand:SWI48 1 "const_int_operand")))]
19166 "pow2p_hwi (INTVAL (operands[1]))
19167 && peep2_regno_dead_p (0, FLAGS_REG)"
19168 [(parallel [(set (match_dup 0) (ashift:SWI48 (match_dup 0) (match_dup 1)))
19169 (clobber (reg:CC FLAGS_REG))])]
19170 "operands[1] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
19173 [(set (match_operand:DI 0 "register_operand")
19175 (mult:SI (match_operand:SI 1 "register_operand")
19176 (match_operand:SI 2 "const_int_operand"))))]
19178 && pow2p_hwi (INTVAL (operands[2]))
19179 && REGNO (operands[0]) == REGNO (operands[1])
19180 && peep2_regno_dead_p (0, FLAGS_REG)"
19181 [(parallel [(set (match_dup 0)
19182 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))
19183 (clobber (reg:CC FLAGS_REG))])]
19184 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
19186 ;; The ESP adjustments can be done by the push and pop instructions. Resulting
19187 ;; code is shorter, since push is only 1 byte, while add imm, %esp is 3 bytes.
19188 ;; On many CPUs it is also faster, since special hardware to avoid esp
19189 ;; dependencies is present.
19191 ;; While some of these conversions may be done using splitters, we use
19192 ;; peepholes in order to allow combine_stack_adjustments pass to see
19193 ;; nonobfuscated RTL.
19195 ;; Convert prologue esp subtractions to push.
19196 ;; We need register to push. In order to keep verify_flow_info happy we have
19198 ;; - use scratch and clobber it in order to avoid dependencies
19199 ;; - use already live register
19200 ;; We can't use the second way right now, since there is no reliable way how to
19201 ;; verify that given register is live. First choice will also most likely in
19202 ;; fewer dependencies. On the place of esp adjustments it is very likely that
19203 ;; call clobbered registers are dead. We may want to use base pointer as an
19204 ;; alternative when no register is available later.
19207 [(match_scratch:W 1 "r")
19208 (parallel [(set (reg:P SP_REG)
19209 (plus:P (reg:P SP_REG)
19210 (match_operand:P 0 "const_int_operand")))
19211 (clobber (reg:CC FLAGS_REG))
19212 (clobber (mem:BLK (scratch)))])]
19213 "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
19214 && INTVAL (operands[0]) == -GET_MODE_SIZE (word_mode)
19215 && ix86_red_zone_size == 0"
19216 [(clobber (match_dup 1))
19217 (parallel [(set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
19218 (clobber (mem:BLK (scratch)))])])
19221 [(match_scratch:W 1 "r")
19222 (parallel [(set (reg:P SP_REG)
19223 (plus:P (reg:P SP_REG)
19224 (match_operand:P 0 "const_int_operand")))
19225 (clobber (reg:CC FLAGS_REG))
19226 (clobber (mem:BLK (scratch)))])]
19227 "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
19228 && INTVAL (operands[0]) == -2*GET_MODE_SIZE (word_mode)
19229 && ix86_red_zone_size == 0"
19230 [(clobber (match_dup 1))
19231 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
19232 (parallel [(set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
19233 (clobber (mem:BLK (scratch)))])])
19235 ;; Convert esp subtractions to push.
19237 [(match_scratch:W 1 "r")
19238 (parallel [(set (reg:P SP_REG)
19239 (plus:P (reg:P SP_REG)
19240 (match_operand:P 0 "const_int_operand")))
19241 (clobber (reg:CC FLAGS_REG))])]
19242 "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
19243 && INTVAL (operands[0]) == -GET_MODE_SIZE (word_mode)
19244 && ix86_red_zone_size == 0"
19245 [(clobber (match_dup 1))
19246 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
19249 [(match_scratch:W 1 "r")
19250 (parallel [(set (reg:P SP_REG)
19251 (plus:P (reg:P SP_REG)
19252 (match_operand:P 0 "const_int_operand")))
19253 (clobber (reg:CC FLAGS_REG))])]
19254 "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
19255 && INTVAL (operands[0]) == -2*GET_MODE_SIZE (word_mode)
19256 && ix86_red_zone_size == 0"
19257 [(clobber (match_dup 1))
19258 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
19259 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
19261 ;; Convert epilogue deallocator to pop.
19263 [(match_scratch:W 1 "r")
19264 (parallel [(set (reg:P SP_REG)
19265 (plus:P (reg:P SP_REG)
19266 (match_operand:P 0 "const_int_operand")))
19267 (clobber (reg:CC FLAGS_REG))
19268 (clobber (mem:BLK (scratch)))])]
19269 "(TARGET_SINGLE_POP || optimize_insn_for_size_p ())
19270 && INTVAL (operands[0]) == GET_MODE_SIZE (word_mode)"
19271 [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
19272 (clobber (mem:BLK (scratch)))])])
19274 ;; Two pops case is tricky, since pop causes dependency
19275 ;; on destination register. We use two registers if available.
19277 [(match_scratch:W 1 "r")
19278 (match_scratch:W 2 "r")
19279 (parallel [(set (reg:P SP_REG)
19280 (plus:P (reg:P SP_REG)
19281 (match_operand:P 0 "const_int_operand")))
19282 (clobber (reg:CC FLAGS_REG))
19283 (clobber (mem:BLK (scratch)))])]
19284 "(TARGET_DOUBLE_POP || optimize_insn_for_size_p ())
19285 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
19286 [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
19287 (clobber (mem:BLK (scratch)))])
19288 (set (match_dup 2) (mem:W (post_inc:P (reg:P SP_REG))))])
19291 [(match_scratch:W 1 "r")
19292 (parallel [(set (reg:P SP_REG)
19293 (plus:P (reg:P SP_REG)
19294 (match_operand:P 0 "const_int_operand")))
19295 (clobber (reg:CC FLAGS_REG))
19296 (clobber (mem:BLK (scratch)))])]
19297 "optimize_insn_for_size_p ()
19298 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
19299 [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
19300 (clobber (mem:BLK (scratch)))])
19301 (set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
19303 ;; Convert esp additions to pop.
19305 [(match_scratch:W 1 "r")
19306 (parallel [(set (reg:P SP_REG)
19307 (plus:P (reg:P SP_REG)
19308 (match_operand:P 0 "const_int_operand")))
19309 (clobber (reg:CC FLAGS_REG))])]
19310 "INTVAL (operands[0]) == GET_MODE_SIZE (word_mode)"
19311 [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
19313 ;; Two pops case is tricky, since pop causes dependency
19314 ;; on destination register. We use two registers if available.
19316 [(match_scratch:W 1 "r")
19317 (match_scratch:W 2 "r")
19318 (parallel [(set (reg:P SP_REG)
19319 (plus:P (reg:P SP_REG)
19320 (match_operand:P 0 "const_int_operand")))
19321 (clobber (reg:CC FLAGS_REG))])]
19322 "INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
19323 [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
19324 (set (match_dup 2) (mem:W (post_inc:P (reg:P SP_REG))))])
19327 [(match_scratch:W 1 "r")
19328 (parallel [(set (reg:P SP_REG)
19329 (plus:P (reg:P SP_REG)
19330 (match_operand:P 0 "const_int_operand")))
19331 (clobber (reg:CC FLAGS_REG))])]
19332 "optimize_insn_for_size_p ()
19333 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
19334 [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
19335 (set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
19337 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
19338 ;; required and register dies. Similarly for 128 to -128.
19340 [(set (match_operand 0 "flags_reg_operand")
19341 (match_operator 1 "compare_operator"
19342 [(match_operand 2 "register_operand")
19343 (match_operand 3 "const_int_operand")]))]
19344 "(((!TARGET_FUSE_CMP_AND_BRANCH || optimize_insn_for_size_p ())
19345 && incdec_operand (operands[3], GET_MODE (operands[3])))
19346 || (!TARGET_FUSE_CMP_AND_BRANCH
19347 && INTVAL (operands[3]) == 128))
19348 && ix86_match_ccmode (insn, CCGCmode)
19349 && peep2_reg_dead_p (1, operands[2])"
19350 [(parallel [(set (match_dup 0)
19351 (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
19352 (clobber (match_dup 2))])])
19354 ;; Convert imul by three, five and nine into lea
19357 [(set (match_operand:SWI48 0 "register_operand")
19358 (mult:SWI48 (match_operand:SWI48 1 "register_operand")
19359 (match_operand:SWI48 2 "const359_operand")))
19360 (clobber (reg:CC FLAGS_REG))])]
19361 "!TARGET_PARTIAL_REG_STALL
19362 || <MODE>mode == SImode
19363 || optimize_function_for_size_p (cfun)"
19364 [(set (match_dup 0)
19365 (plus:SWI48 (mult:SWI48 (match_dup 1) (match_dup 2))
19367 "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
19371 [(set (match_operand:SWI48 0 "register_operand")
19372 (mult:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
19373 (match_operand:SWI48 2 "const359_operand")))
19374 (clobber (reg:CC FLAGS_REG))])]
19375 "optimize_insn_for_speed_p ()
19376 && (!TARGET_PARTIAL_REG_STALL || <MODE>mode == SImode)"
19377 [(set (match_dup 0) (match_dup 1))
19379 (plus:SWI48 (mult:SWI48 (match_dup 0) (match_dup 2))
19381 "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
19383 ;; imul $32bit_imm, mem, reg is vector decoded, while
19384 ;; imul $32bit_imm, reg, reg is direct decoded.
19386 [(match_scratch:SWI48 3 "r")
19387 (parallel [(set (match_operand:SWI48 0 "register_operand")
19388 (mult:SWI48 (match_operand:SWI48 1 "memory_operand")
19389 (match_operand:SWI48 2 "immediate_operand")))
19390 (clobber (reg:CC FLAGS_REG))])]
19391 "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
19392 && !satisfies_constraint_K (operands[2])"
19393 [(set (match_dup 3) (match_dup 1))
19394 (parallel [(set (match_dup 0) (mult:SWI48 (match_dup 3) (match_dup 2)))
19395 (clobber (reg:CC FLAGS_REG))])])
19398 [(match_scratch:SI 3 "r")
19399 (parallel [(set (match_operand:DI 0 "register_operand")
19401 (mult:SI (match_operand:SI 1 "memory_operand")
19402 (match_operand:SI 2 "immediate_operand"))))
19403 (clobber (reg:CC FLAGS_REG))])]
19405 && TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
19406 && !satisfies_constraint_K (operands[2])"
19407 [(set (match_dup 3) (match_dup 1))
19408 (parallel [(set (match_dup 0)
19409 (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
19410 (clobber (reg:CC FLAGS_REG))])])
19412 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
19413 ;; Convert it into imul reg, reg
19414 ;; It would be better to force assembler to encode instruction using long
19415 ;; immediate, but there is apparently no way to do so.
19417 [(parallel [(set (match_operand:SWI248 0 "register_operand")
19419 (match_operand:SWI248 1 "nonimmediate_operand")
19420 (match_operand:SWI248 2 "const_int_operand")))
19421 (clobber (reg:CC FLAGS_REG))])
19422 (match_scratch:SWI248 3 "r")]
19423 "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
19424 && satisfies_constraint_K (operands[2])"
19425 [(set (match_dup 3) (match_dup 2))
19426 (parallel [(set (match_dup 0) (mult:SWI248 (match_dup 0) (match_dup 3)))
19427 (clobber (reg:CC FLAGS_REG))])]
19429 if (!rtx_equal_p (operands[0], operands[1]))
19430 emit_move_insn (operands[0], operands[1]);
19433 ;; After splitting up read-modify operations, array accesses with memory
19434 ;; operands might end up in form:
19436 ;; movl 4(%esp), %edx
19438 ;; instead of pre-splitting:
19440 ;; addl 4(%esp), %eax
19442 ;; movl 4(%esp), %edx
19443 ;; leal (%edx,%eax,4), %eax
19446 [(match_scratch:W 5 "r")
19447 (parallel [(set (match_operand 0 "register_operand")
19448 (ashift (match_operand 1 "register_operand")
19449 (match_operand 2 "const_int_operand")))
19450 (clobber (reg:CC FLAGS_REG))])
19451 (parallel [(set (match_operand 3 "register_operand")
19452 (plus (match_dup 0)
19453 (match_operand 4 "x86_64_general_operand")))
19454 (clobber (reg:CC FLAGS_REG))])]
19455 "IN_RANGE (INTVAL (operands[2]), 1, 3)
19456 /* Validate MODE for lea. */
19457 && ((!TARGET_PARTIAL_REG_STALL
19458 && (GET_MODE (operands[0]) == QImode
19459 || GET_MODE (operands[0]) == HImode))
19460 || GET_MODE (operands[0]) == SImode
19461 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
19462 && (rtx_equal_p (operands[0], operands[3])
19463 || peep2_reg_dead_p (2, operands[0]))
19464 /* We reorder load and the shift. */
19465 && !reg_overlap_mentioned_p (operands[0], operands[4])"
19466 [(set (match_dup 5) (match_dup 4))
19467 (set (match_dup 0) (match_dup 1))]
19469 machine_mode op1mode = GET_MODE (operands[1]);
19470 machine_mode mode = op1mode == DImode ? DImode : SImode;
19471 int scale = 1 << INTVAL (operands[2]);
19472 rtx index = gen_lowpart (word_mode, operands[1]);
19473 rtx base = gen_lowpart (word_mode, operands[5]);
19474 rtx dest = gen_lowpart (mode, operands[3]);
19476 operands[1] = gen_rtx_PLUS (word_mode, base,
19477 gen_rtx_MULT (word_mode, index, GEN_INT (scale)));
19478 if (mode != word_mode)
19479 operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
19481 operands[5] = base;
19482 if (op1mode != word_mode)
19483 operands[5] = gen_lowpart (op1mode, operands[5]);
19485 operands[0] = dest;
19488 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
19489 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
19490 ;; caught for use by garbage collectors and the like. Using an insn that
19491 ;; maps to SIGILL makes it more likely the program will rightfully die.
19492 ;; Keeping with tradition, "6" is in honor of #UD.
19493 (define_insn "trap"
19494 [(trap_if (const_int 1) (const_int 6))]
19497 #ifdef HAVE_AS_IX86_UD2
19500 return ASM_SHORT "0x0b0f";
19503 [(set_attr "length" "2")])
19506 [(unspec_volatile [(const_int 0)] UNSPECV_UD2)]
19509 #ifdef HAVE_AS_IX86_UD2
19512 return ASM_SHORT "0x0b0f";
19515 [(set_attr "length" "2")])
19517 (define_expand "prefetch"
19518 [(prefetch (match_operand 0 "address_operand")
19519 (match_operand:SI 1 "const_int_operand")
19520 (match_operand:SI 2 "const_int_operand"))]
19521 "TARGET_3DNOW || TARGET_PREFETCH_SSE || TARGET_PRFCHW || TARGET_PREFETCHWT1"
19523 bool write = INTVAL (operands[1]) != 0;
19524 int locality = INTVAL (operands[2]);
19526 gcc_assert (IN_RANGE (locality, 0, 3));
19528 /* Use 3dNOW prefetch in case we are asking for write prefetch not
19529 supported by SSE counterpart (non-SSE2 athlon machines) or the
19530 SSE prefetch is not available (K6 machines). Otherwise use SSE
19531 prefetch as it allows specifying of locality. */
19535 if (TARGET_PREFETCHWT1)
19536 operands[2] = GEN_INT (MAX (locality, 2));
19537 else if (TARGET_PRFCHW)
19538 operands[2] = GEN_INT (3);
19539 else if (TARGET_3DNOW && !TARGET_SSE2)
19540 operands[2] = GEN_INT (3);
19541 else if (TARGET_PREFETCH_SSE)
19542 operands[1] = const0_rtx;
19545 gcc_assert (TARGET_3DNOW);
19546 operands[2] = GEN_INT (3);
19551 if (TARGET_PREFETCH_SSE)
19555 gcc_assert (TARGET_3DNOW);
19556 operands[2] = GEN_INT (3);
19561 (define_insn "*prefetch_sse"
19562 [(prefetch (match_operand 0 "address_operand" "p")
19564 (match_operand:SI 1 "const_int_operand"))]
19565 "TARGET_PREFETCH_SSE"
19567 static const char * const patterns[4] = {
19568 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
19571 int locality = INTVAL (operands[1]);
19572 gcc_assert (IN_RANGE (locality, 0, 3));
19574 return patterns[locality];
19576 [(set_attr "type" "sse")
19577 (set_attr "atom_sse_attr" "prefetch")
19578 (set (attr "length_address")
19579 (symbol_ref "memory_address_length (operands[0], false)"))
19580 (set_attr "memory" "none")])
19582 (define_insn "*prefetch_3dnow"
19583 [(prefetch (match_operand 0 "address_operand" "p")
19584 (match_operand:SI 1 "const_int_operand" "n")
19586 "TARGET_3DNOW || TARGET_PRFCHW || TARGET_PREFETCHWT1"
19588 if (INTVAL (operands[1]) == 0)
19589 return "prefetch\t%a0";
19591 return "prefetchw\t%a0";
19593 [(set_attr "type" "mmx")
19594 (set (attr "length_address")
19595 (symbol_ref "memory_address_length (operands[0], false)"))
19596 (set_attr "memory" "none")])
19598 (define_insn "*prefetch_prefetchwt1"
19599 [(prefetch (match_operand 0 "address_operand" "p")
19602 "TARGET_PREFETCHWT1"
19603 "prefetchwt1\t%a0";
19604 [(set_attr "type" "sse")
19605 (set (attr "length_address")
19606 (symbol_ref "memory_address_length (operands[0], false)"))
19607 (set_attr "memory" "none")])
19609 (define_expand "stack_protect_set"
19610 [(match_operand 0 "memory_operand")
19611 (match_operand 1 "memory_operand")]
19612 "TARGET_SSP_TLS_GUARD"
19614 rtx (*insn)(rtx, rtx);
19616 insn = (TARGET_LP64
19617 ? gen_stack_protect_set_di
19618 : gen_stack_protect_set_si);
19620 emit_insn (insn (operands[0], operands[1]));
19624 (define_insn "stack_protect_set_<mode>"
19625 [(set (match_operand:PTR 0 "memory_operand" "=m")
19626 (unspec:PTR [(match_operand:PTR 1 "memory_operand" "m")]
19628 (set (match_scratch:PTR 2 "=&r") (const_int 0))
19629 (clobber (reg:CC FLAGS_REG))]
19630 "TARGET_SSP_TLS_GUARD"
19631 "mov{<imodesuffix>}\t{%1, %2|%2, %1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
19632 [(set_attr "type" "multi")])
19634 (define_expand "stack_protect_test"
19635 [(match_operand 0 "memory_operand")
19636 (match_operand 1 "memory_operand")
19638 "TARGET_SSP_TLS_GUARD"
19640 rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
19642 rtx (*insn)(rtx, rtx, rtx);
19644 insn = (TARGET_LP64
19645 ? gen_stack_protect_test_di
19646 : gen_stack_protect_test_si);
19648 emit_insn (insn (flags, operands[0], operands[1]));
19650 emit_jump_insn (gen_cbranchcc4 (gen_rtx_EQ (VOIDmode, flags, const0_rtx),
19651 flags, const0_rtx, operands[2]));
19655 (define_insn "stack_protect_test_<mode>"
19656 [(set (match_operand:CCZ 0 "flags_reg_operand")
19657 (unspec:CCZ [(match_operand:PTR 1 "memory_operand" "m")
19658 (match_operand:PTR 2 "memory_operand" "m")]
19660 (clobber (match_scratch:PTR 3 "=&r"))]
19661 "TARGET_SSP_TLS_GUARD"
19662 "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%2, %3|%3, %2}"
19663 [(set_attr "type" "multi")])
19665 (define_insn "sse4_2_crc32<mode>"
19666 [(set (match_operand:SI 0 "register_operand" "=r")
19668 [(match_operand:SI 1 "register_operand" "0")
19669 (match_operand:SWI124 2 "nonimmediate_operand" "<r>m")]
19671 "TARGET_SSE4_2 || TARGET_CRC32"
19672 "crc32{<imodesuffix>}\t{%2, %0|%0, %2}"
19673 [(set_attr "type" "sselog1")
19674 (set_attr "prefix_rep" "1")
19675 (set_attr "prefix_extra" "1")
19676 (set (attr "prefix_data16")
19677 (if_then_else (match_operand:HI 2)
19679 (const_string "*")))
19680 (set (attr "prefix_rex")
19681 (if_then_else (match_operand:QI 2 "ext_QIreg_operand")
19683 (const_string "*")))
19684 (set_attr "mode" "SI")])
19686 (define_insn "sse4_2_crc32di"
19687 [(set (match_operand:DI 0 "register_operand" "=r")
19689 [(match_operand:DI 1 "register_operand" "0")
19690 (match_operand:DI 2 "nonimmediate_operand" "rm")]
19692 "TARGET_64BIT && (TARGET_SSE4_2 || TARGET_CRC32)"
19693 "crc32{q}\t{%2, %0|%0, %2}"
19694 [(set_attr "type" "sselog1")
19695 (set_attr "prefix_rep" "1")
19696 (set_attr "prefix_extra" "1")
19697 (set_attr "mode" "DI")])
19699 (define_insn "rdpmc"
19700 [(set (match_operand:DI 0 "register_operand" "=A")
19701 (unspec_volatile:DI [(match_operand:SI 1 "register_operand" "c")]
19705 [(set_attr "type" "other")
19706 (set_attr "length" "2")])
19708 (define_insn "rdpmc_rex64"
19709 [(set (match_operand:DI 0 "register_operand" "=a")
19710 (unspec_volatile:DI [(match_operand:SI 2 "register_operand" "c")]
19712 (set (match_operand:DI 1 "register_operand" "=d")
19713 (unspec_volatile:DI [(match_dup 2)] UNSPECV_RDPMC))]
19716 [(set_attr "type" "other")
19717 (set_attr "length" "2")])
19719 (define_insn "rdtsc"
19720 [(set (match_operand:DI 0 "register_operand" "=A")
19721 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
19724 [(set_attr "type" "other")
19725 (set_attr "length" "2")])
19727 (define_insn "rdtsc_rex64"
19728 [(set (match_operand:DI 0 "register_operand" "=a")
19729 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))
19730 (set (match_operand:DI 1 "register_operand" "=d")
19731 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
19734 [(set_attr "type" "other")
19735 (set_attr "length" "2")])
19737 (define_insn "rdtscp"
19738 [(set (match_operand:DI 0 "register_operand" "=A")
19739 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
19740 (set (match_operand:SI 1 "register_operand" "=c")
19741 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
19744 [(set_attr "type" "other")
19745 (set_attr "length" "3")])
19747 (define_insn "rdtscp_rex64"
19748 [(set (match_operand:DI 0 "register_operand" "=a")
19749 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
19750 (set (match_operand:DI 1 "register_operand" "=d")
19751 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
19752 (set (match_operand:SI 2 "register_operand" "=c")
19753 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
19756 [(set_attr "type" "other")
19757 (set_attr "length" "3")])
19759 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
19761 ;; FXSR, XSAVE and XSAVEOPT instructions
19763 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
19765 (define_insn "fxsave"
19766 [(set (match_operand:BLK 0 "memory_operand" "=m")
19767 (unspec_volatile:BLK [(const_int 0)] UNSPECV_FXSAVE))]
19770 [(set_attr "type" "other")
19771 (set_attr "memory" "store")
19772 (set (attr "length")
19773 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
19775 (define_insn "fxsave64"
19776 [(set (match_operand:BLK 0 "memory_operand" "=m")
19777 (unspec_volatile:BLK [(const_int 0)] UNSPECV_FXSAVE64))]
19778 "TARGET_64BIT && TARGET_FXSR"
19780 [(set_attr "type" "other")
19781 (set_attr "memory" "store")
19782 (set (attr "length")
19783 (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
19785 (define_insn "fxrstor"
19786 [(unspec_volatile [(match_operand:BLK 0 "memory_operand" "m")]
19790 [(set_attr "type" "other")
19791 (set_attr "memory" "load")
19792 (set (attr "length")
19793 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
19795 (define_insn "fxrstor64"
19796 [(unspec_volatile [(match_operand:BLK 0 "memory_operand" "m")]
19797 UNSPECV_FXRSTOR64)]
19798 "TARGET_64BIT && TARGET_FXSR"
19800 [(set_attr "type" "other")
19801 (set_attr "memory" "load")
19802 (set (attr "length")
19803 (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
19805 (define_int_iterator ANY_XSAVE
19807 (UNSPECV_XSAVEOPT "TARGET_XSAVEOPT")
19808 (UNSPECV_XSAVEC "TARGET_XSAVEC")
19809 (UNSPECV_XSAVES "TARGET_XSAVES")])
19811 (define_int_iterator ANY_XSAVE64
19813 (UNSPECV_XSAVEOPT64 "TARGET_XSAVEOPT")
19814 (UNSPECV_XSAVEC64 "TARGET_XSAVEC")
19815 (UNSPECV_XSAVES64 "TARGET_XSAVES")])
19817 (define_int_attr xsave
19818 [(UNSPECV_XSAVE "xsave")
19819 (UNSPECV_XSAVE64 "xsave64")
19820 (UNSPECV_XSAVEOPT "xsaveopt")
19821 (UNSPECV_XSAVEOPT64 "xsaveopt64")
19822 (UNSPECV_XSAVEC "xsavec")
19823 (UNSPECV_XSAVEC64 "xsavec64")
19824 (UNSPECV_XSAVES "xsaves")
19825 (UNSPECV_XSAVES64 "xsaves64")])
19827 (define_int_iterator ANY_XRSTOR
19829 (UNSPECV_XRSTORS "TARGET_XSAVES")])
19831 (define_int_iterator ANY_XRSTOR64
19833 (UNSPECV_XRSTORS64 "TARGET_XSAVES")])
19835 (define_int_attr xrstor
19836 [(UNSPECV_XRSTOR "xrstor")
19837 (UNSPECV_XRSTOR64 "xrstor")
19838 (UNSPECV_XRSTORS "xrstors")
19839 (UNSPECV_XRSTORS64 "xrstors")])
19841 (define_insn "<xsave>"
19842 [(set (match_operand:BLK 0 "memory_operand" "=m")
19843 (unspec_volatile:BLK
19844 [(match_operand:DI 1 "register_operand" "A")]
19846 "!TARGET_64BIT && TARGET_XSAVE"
19848 [(set_attr "type" "other")
19849 (set_attr "memory" "store")
19850 (set (attr "length")
19851 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
19853 (define_insn "<xsave>_rex64"
19854 [(set (match_operand:BLK 0 "memory_operand" "=m")
19855 (unspec_volatile:BLK
19856 [(match_operand:SI 1 "register_operand" "a")
19857 (match_operand:SI 2 "register_operand" "d")]
19859 "TARGET_64BIT && TARGET_XSAVE"
19861 [(set_attr "type" "other")
19862 (set_attr "memory" "store")
19863 (set (attr "length")
19864 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
19866 (define_insn "<xsave>"
19867 [(set (match_operand:BLK 0 "memory_operand" "=m")
19868 (unspec_volatile:BLK
19869 [(match_operand:SI 1 "register_operand" "a")
19870 (match_operand:SI 2 "register_operand" "d")]
19872 "TARGET_64BIT && TARGET_XSAVE"
19874 [(set_attr "type" "other")
19875 (set_attr "memory" "store")
19876 (set (attr "length")
19877 (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
19879 (define_insn "<xrstor>"
19880 [(unspec_volatile:BLK
19881 [(match_operand:BLK 0 "memory_operand" "m")
19882 (match_operand:DI 1 "register_operand" "A")]
19884 "!TARGET_64BIT && TARGET_XSAVE"
19886 [(set_attr "type" "other")
19887 (set_attr "memory" "load")
19888 (set (attr "length")
19889 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
19891 (define_insn "<xrstor>_rex64"
19892 [(unspec_volatile:BLK
19893 [(match_operand:BLK 0 "memory_operand" "m")
19894 (match_operand:SI 1 "register_operand" "a")
19895 (match_operand:SI 2 "register_operand" "d")]
19897 "TARGET_64BIT && TARGET_XSAVE"
19899 [(set_attr "type" "other")
19900 (set_attr "memory" "load")
19901 (set (attr "length")
19902 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
19904 (define_insn "<xrstor>64"
19905 [(unspec_volatile:BLK
19906 [(match_operand:BLK 0 "memory_operand" "m")
19907 (match_operand:SI 1 "register_operand" "a")
19908 (match_operand:SI 2 "register_operand" "d")]
19910 "TARGET_64BIT && TARGET_XSAVE"
19912 [(set_attr "type" "other")
19913 (set_attr "memory" "load")
19914 (set (attr "length")
19915 (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
19917 (define_insn "xsetbv"
19918 [(unspec_volatile:SI
19919 [(match_operand:SI 0 "register_operand" "c")
19920 (match_operand:DI 1 "register_operand" "A")]
19922 "!TARGET_64BIT && TARGET_XSAVE"
19924 [(set_attr "type" "other")])
19926 (define_insn "xsetbv_rex64"
19927 [(unspec_volatile:SI
19928 [(match_operand:SI 0 "register_operand" "c")
19929 (match_operand:SI 1 "register_operand" "a")
19930 (match_operand:SI 2 "register_operand" "d")]
19932 "TARGET_64BIT && TARGET_XSAVE"
19934 [(set_attr "type" "other")])
19936 (define_insn "xgetbv"
19937 [(set (match_operand:DI 0 "register_operand" "=A")
19938 (unspec_volatile:DI [(match_operand:SI 1 "register_operand" "c")]
19940 "!TARGET_64BIT && TARGET_XSAVE"
19942 [(set_attr "type" "other")])
19944 (define_insn "xgetbv_rex64"
19945 [(set (match_operand:DI 0 "register_operand" "=a")
19946 (unspec_volatile:DI [(match_operand:SI 2 "register_operand" "c")]
19948 (set (match_operand:DI 1 "register_operand" "=d")
19949 (unspec_volatile:DI [(match_dup 2)] UNSPECV_XGETBV))]
19950 "TARGET_64BIT && TARGET_XSAVE"
19952 [(set_attr "type" "other")])
19954 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
19956 ;; Floating-point instructions for atomic compound assignments
19958 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
19960 ; Clobber all floating-point registers on environment save and restore
19961 ; to ensure that the TOS value saved at fnstenv is valid after fldenv.
19962 (define_insn "fnstenv"
19963 [(set (match_operand:BLK 0 "memory_operand" "=m")
19964 (unspec_volatile:BLK [(const_int 0)] UNSPECV_FNSTENV))
19965 (clobber (reg:HI FPCR_REG))
19966 (clobber (reg:XF ST0_REG))
19967 (clobber (reg:XF ST1_REG))
19968 (clobber (reg:XF ST2_REG))
19969 (clobber (reg:XF ST3_REG))
19970 (clobber (reg:XF ST4_REG))
19971 (clobber (reg:XF ST5_REG))
19972 (clobber (reg:XF ST6_REG))
19973 (clobber (reg:XF ST7_REG))]
19976 [(set_attr "type" "other")
19977 (set_attr "memory" "store")
19978 (set (attr "length")
19979 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))])
19981 (define_insn "fldenv"
19982 [(unspec_volatile [(match_operand:BLK 0 "memory_operand" "m")]
19984 (clobber (reg:CCFP FPSR_REG))
19985 (clobber (reg:HI FPCR_REG))
19986 (clobber (reg:XF ST0_REG))
19987 (clobber (reg:XF ST1_REG))
19988 (clobber (reg:XF ST2_REG))
19989 (clobber (reg:XF ST3_REG))
19990 (clobber (reg:XF ST4_REG))
19991 (clobber (reg:XF ST5_REG))
19992 (clobber (reg:XF ST6_REG))
19993 (clobber (reg:XF ST7_REG))]
19996 [(set_attr "type" "other")
19997 (set_attr "memory" "load")
19998 (set (attr "length")
19999 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))])
20001 (define_insn "fnstsw"
20002 [(set (match_operand:HI 0 "nonimmediate_operand" "=a,m")
20003 (unspec_volatile:HI [(const_int 0)] UNSPECV_FNSTSW))]
20006 [(set_attr "type" "other,other")
20007 (set_attr "memory" "none,store")
20008 (set (attr "length")
20009 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))])
20011 (define_insn "fnclex"
20012 [(unspec_volatile [(const_int 0)] UNSPECV_FNCLEX)]
20015 [(set_attr "type" "other")
20016 (set_attr "memory" "none")
20017 (set_attr "length" "2")])
20019 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
20021 ;; LWP instructions
20023 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
20025 (define_expand "lwp_llwpcb"
20026 [(unspec_volatile [(match_operand 0 "register_operand")]
20027 UNSPECV_LLWP_INTRINSIC)]
20030 (define_insn "*lwp_llwpcb<mode>1"
20031 [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
20032 UNSPECV_LLWP_INTRINSIC)]
20035 [(set_attr "type" "lwp")
20036 (set_attr "mode" "<MODE>")
20037 (set_attr "length" "5")])
20039 (define_expand "lwp_slwpcb"
20040 [(set (match_operand 0 "register_operand")
20041 (unspec_volatile [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
20046 insn = (Pmode == DImode
20048 : gen_lwp_slwpcbsi);
20050 emit_insn (insn (operands[0]));
20054 (define_insn "lwp_slwpcb<mode>"
20055 [(set (match_operand:P 0 "register_operand" "=r")
20056 (unspec_volatile:P [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
20059 [(set_attr "type" "lwp")
20060 (set_attr "mode" "<MODE>")
20061 (set_attr "length" "5")])
20063 (define_expand "lwp_lwpval<mode>3"
20064 [(unspec_volatile [(match_operand:SWI48 1 "register_operand")
20065 (match_operand:SI 2 "nonimmediate_operand")
20066 (match_operand:SI 3 "const_int_operand")]
20067 UNSPECV_LWPVAL_INTRINSIC)]
20069 ;; Avoid unused variable warning.
20070 "(void) operands[0];")
20072 (define_insn "*lwp_lwpval<mode>3_1"
20073 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")
20074 (match_operand:SI 1 "nonimmediate_operand" "rm")
20075 (match_operand:SI 2 "const_int_operand" "i")]
20076 UNSPECV_LWPVAL_INTRINSIC)]
20078 "lwpval\t{%2, %1, %0|%0, %1, %2}"
20079 [(set_attr "type" "lwp")
20080 (set_attr "mode" "<MODE>")
20081 (set (attr "length")
20082 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
20084 (define_expand "lwp_lwpins<mode>3"
20085 [(set (reg:CCC FLAGS_REG)
20086 (unspec_volatile:CCC [(match_operand:SWI48 1 "register_operand")
20087 (match_operand:SI 2 "nonimmediate_operand")
20088 (match_operand:SI 3 "const_int_operand")]
20089 UNSPECV_LWPINS_INTRINSIC))
20090 (set (match_operand:QI 0 "nonimmediate_operand")
20091 (eq:QI (reg:CCC FLAGS_REG) (const_int 0)))]
20094 (define_insn "*lwp_lwpins<mode>3_1"
20095 [(set (reg:CCC FLAGS_REG)
20096 (unspec_volatile:CCC [(match_operand:SWI48 0 "register_operand" "r")
20097 (match_operand:SI 1 "nonimmediate_operand" "rm")
20098 (match_operand:SI 2 "const_int_operand" "i")]
20099 UNSPECV_LWPINS_INTRINSIC))]
20101 "lwpins\t{%2, %1, %0|%0, %1, %2}"
20102 [(set_attr "type" "lwp")
20103 (set_attr "mode" "<MODE>")
20104 (set (attr "length")
20105 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
20107 (define_int_iterator RDFSGSBASE
20111 (define_int_iterator WRFSGSBASE
20115 (define_int_attr fsgs
20116 [(UNSPECV_RDFSBASE "fs")
20117 (UNSPECV_RDGSBASE "gs")
20118 (UNSPECV_WRFSBASE "fs")
20119 (UNSPECV_WRGSBASE "gs")])
20121 (define_insn "rd<fsgs>base<mode>"
20122 [(set (match_operand:SWI48 0 "register_operand" "=r")
20123 (unspec_volatile:SWI48 [(const_int 0)] RDFSGSBASE))]
20124 "TARGET_64BIT && TARGET_FSGSBASE"
20126 [(set_attr "type" "other")
20127 (set_attr "prefix_extra" "2")])
20129 (define_insn "wr<fsgs>base<mode>"
20130 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
20132 "TARGET_64BIT && TARGET_FSGSBASE"
20134 [(set_attr "type" "other")
20135 (set_attr "prefix_extra" "2")])
20137 (define_insn "rdrand<mode>_1"
20138 [(set (match_operand:SWI248 0 "register_operand" "=r")
20139 (unspec_volatile:SWI248 [(const_int 0)] UNSPECV_RDRAND))
20140 (set (reg:CCC FLAGS_REG)
20141 (unspec_volatile:CCC [(const_int 0)] UNSPECV_RDRAND))]
20144 [(set_attr "type" "other")
20145 (set_attr "prefix_extra" "1")])
20147 (define_insn "rdseed<mode>_1"
20148 [(set (match_operand:SWI248 0 "register_operand" "=r")
20149 (unspec_volatile:SWI248 [(const_int 0)] UNSPECV_RDSEED))
20150 (set (reg:CCC FLAGS_REG)
20151 (unspec_volatile:CCC [(const_int 0)] UNSPECV_RDSEED))]
20154 [(set_attr "type" "other")
20155 (set_attr "prefix_extra" "1")])
20157 (define_expand "pause"
20158 [(set (match_dup 0)
20159 (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
20162 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
20163 MEM_VOLATILE_P (operands[0]) = 1;
20166 ;; Use "rep; nop", instead of "pause", to support older assemblers.
20167 ;; They have the same encoding.
20168 (define_insn "*pause"
20169 [(set (match_operand:BLK 0)
20170 (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
20173 [(set_attr "length" "2")
20174 (set_attr "memory" "unknown")])
20176 ;; CET instructions
20177 (define_insn "rdssp<mode>"
20178 [(set (match_operand:SWI48x 0 "register_operand" "=r")
20179 (unspec_volatile:SWI48x [(const_int 0)] UNSPECV_NOP_RDSSP))]
20181 "xor{l}\t%k0, %k0\n\trdssp<mskmodesuffix>\t%0"
20182 [(set_attr "length" "6")
20183 (set_attr "type" "other")])
20185 (define_insn "incssp<mode>"
20186 [(unspec_volatile [(match_operand:SWI48x 0 "register_operand" "r")]
20189 "incssp<mskmodesuffix>\t%0"
20190 [(set_attr "length" "4")
20191 (set_attr "type" "other")])
20193 (define_insn "saveprevssp"
20194 [(unspec_volatile [(const_int 0)] UNSPECV_SAVEPREVSSP)]
20197 [(set_attr "length" "5")
20198 (set_attr "type" "other")])
20200 (define_insn "rstorssp"
20201 [(unspec_volatile [(match_operand 0 "memory_operand" "m")]
20205 [(set_attr "length" "5")
20206 (set_attr "type" "other")])
20208 (define_insn "wrss<mode>"
20209 [(unspec_volatile [(match_operand:SWI48x 0 "register_operand" "r")
20210 (match_operand:SWI48x 1 "memory_operand" "m")]
20213 "wrss<mskmodesuffix>\t%0, %1"
20214 [(set_attr "length" "3")
20215 (set_attr "type" "other")])
20217 (define_insn "wruss<mode>"
20218 [(unspec_volatile [(match_operand:SWI48x 0 "register_operand" "r")
20219 (match_operand:SWI48x 1 "memory_operand" "m")]
20222 "wruss<mskmodesuffix>\t%0, %1"
20223 [(set_attr "length" "4")
20224 (set_attr "type" "other")])
20226 (define_insn "setssbsy"
20227 [(unspec_volatile [(const_int 0)] UNSPECV_SETSSBSY)]
20230 [(set_attr "length" "4")
20231 (set_attr "type" "other")])
20233 (define_insn "clrssbsy"
20234 [(unspec_volatile [(match_operand 0 "memory_operand" "m")]
20238 [(set_attr "length" "4")
20239 (set_attr "type" "other")])
20241 (define_insn "nop_endbr"
20242 [(unspec_volatile [(const_int 0)] UNSPECV_NOP_ENDBR)]
20245 { return (TARGET_64BIT)? \"endbr64\" : \"endbr32\"; }"
20246 [(set_attr "length" "4")
20247 (set_attr "length_immediate" "0")
20248 (set_attr "modrm" "0")])
20251 (define_expand "xbegin"
20252 [(set (match_operand:SI 0 "register_operand")
20253 (unspec_volatile:SI [(const_int 0)] UNSPECV_XBEGIN))]
20256 rtx_code_label *label = gen_label_rtx ();
20258 /* xbegin is emitted as jump_insn, so reload won't be able
20259 to reload its operand. Force the value into AX hard register. */
20260 rtx ax_reg = gen_rtx_REG (SImode, AX_REG);
20261 emit_move_insn (ax_reg, constm1_rtx);
20263 emit_jump_insn (gen_xbegin_1 (ax_reg, label));
20265 emit_label (label);
20266 LABEL_NUSES (label) = 1;
20268 emit_move_insn (operands[0], ax_reg);
20273 (define_insn "xbegin_1"
20275 (if_then_else (ne (unspec [(const_int 0)] UNSPEC_XBEGIN_ABORT)
20277 (label_ref (match_operand 1))
20279 (set (match_operand:SI 0 "register_operand" "+a")
20280 (unspec_volatile:SI [(match_dup 0)] UNSPECV_XBEGIN))]
20283 [(set_attr "type" "other")
20284 (set_attr "length" "6")])
20286 (define_insn "xend"
20287 [(unspec_volatile [(const_int 0)] UNSPECV_XEND)]
20290 [(set_attr "type" "other")
20291 (set_attr "length" "3")])
20293 (define_insn "xabort"
20294 [(unspec_volatile [(match_operand:SI 0 "const_0_to_255_operand" "n")]
20298 [(set_attr "type" "other")
20299 (set_attr "length" "3")])
20301 (define_expand "xtest"
20302 [(set (match_operand:QI 0 "register_operand")
20303 (unspec_volatile:QI [(const_int 0)] UNSPECV_XTEST))]
20306 emit_insn (gen_xtest_1 ());
20308 ix86_expand_setcc (operands[0], NE,
20309 gen_rtx_REG (CCZmode, FLAGS_REG), const0_rtx);
20313 (define_insn "xtest_1"
20314 [(set (reg:CCZ FLAGS_REG)
20315 (unspec_volatile:CCZ [(const_int 0)] UNSPECV_XTEST))]
20318 [(set_attr "type" "other")
20319 (set_attr "length" "3")])
20321 (define_insn "clwb"
20322 [(unspec_volatile [(match_operand 0 "address_operand" "p")]
20326 [(set_attr "type" "sse")
20327 (set_attr "atom_sse_attr" "fence")
20328 (set_attr "memory" "unknown")])
20330 (define_insn "clflushopt"
20331 [(unspec_volatile [(match_operand 0 "address_operand" "p")]
20332 UNSPECV_CLFLUSHOPT)]
20333 "TARGET_CLFLUSHOPT"
20335 [(set_attr "type" "sse")
20336 (set_attr "atom_sse_attr" "fence")
20337 (set_attr "memory" "unknown")])
20339 ;; MONITORX and MWAITX
20340 (define_insn "mwaitx"
20341 [(unspec_volatile [(match_operand:SI 0 "register_operand" "c")
20342 (match_operand:SI 1 "register_operand" "a")
20343 (match_operand:SI 2 "register_operand" "b")]
20346 ;; 64bit version is "mwaitx %rax,%rcx,%rbx". But only lower 32bits are used.
20347 ;; Since 32bit register operands are implicitly zero extended to 64bit,
20348 ;; we only need to set up 32bit registers.
20350 [(set_attr "length" "3")])
20352 (define_insn "monitorx_<mode>"
20353 [(unspec_volatile [(match_operand:P 0 "register_operand" "a")
20354 (match_operand:SI 1 "register_operand" "c")
20355 (match_operand:SI 2 "register_operand" "d")]
20358 ;; 64bit version is "monitorx %rax,%rcx,%rdx". But only lower 32bits in
20359 ;; RCX and RDX are used. Since 32bit register operands are implicitly
20360 ;; zero extended to 64bit, we only need to set up 32bit registers.
20362 [(set (attr "length")
20363 (symbol_ref ("(Pmode != word_mode) + 3")))])
20366 (define_insn "clzero_<mode>"
20367 [(unspec_volatile [(match_operand: P 0 "register_operand" "a")]
20371 [(set_attr "length" "3")
20372 (set_attr "memory" "unknown")])
20374 ;; MPX instructions
20376 (define_expand "<mode>_mk"
20377 [(set (match_operand:BND 0 "register_operand")
20381 [(match_operand:<bnd_ptr> 1 "register_operand")
20382 (match_operand:<bnd_ptr> 2 "address_mpx_no_base_operand")]))]
20386 operands[3] = gen_rtx_UNSPEC (Pmode, gen_rtvec (2, operands[1],
20388 UNSPEC_BNDMK_ADDR);
20391 (define_insn "*<mode>_mk"
20392 [(set (match_operand:BND 0 "register_operand" "=w")
20394 [(match_operator:<bnd_ptr> 3 "bnd_mem_operator"
20396 [(match_operand:<bnd_ptr> 1 "register_operand" "r")
20397 (match_operand:<bnd_ptr> 2 "address_mpx_no_base_operand" "Tb")]
20398 UNSPEC_BNDMK_ADDR)])]
20401 "bndmk\t{%3, %0|%0, %3}"
20402 [(set_attr "type" "mpxmk")])
20404 (define_expand "mov<mode>"
20405 [(set (match_operand:BND 0 "general_operand")
20406 (match_operand:BND 1 "general_operand"))]
20408 "ix86_expand_move (<MODE>mode, operands); DONE;")
20410 (define_insn "*mov<mode>_internal_mpx"
20411 [(set (match_operand:BND 0 "nonimmediate_operand" "=w,m")
20412 (match_operand:BND 1 "general_operand" "wm,w"))]
20414 "bndmov\t{%1, %0|%0, %1}"
20415 [(set_attr "type" "mpxmov")])
20417 (define_expand "<mode>_<bndcheck>"
20420 [(match_operand:BND 0 "register_operand")
20421 (match_operand:<bnd_ptr> 1 "address_no_seg_operand")] BNDCHECK)
20423 (unspec:BLK [(match_dup 2)] UNSPEC_MPX_FENCE))])]
20426 operands[2] = gen_rtx_MEM (BLKmode, operands[1]);
20427 MEM_VOLATILE_P (operands[2]) = 1;
20430 (define_insn "*<mode>_<bndcheck>"
20432 [(match_operand:BND 0 "register_operand" "w")
20433 (match_operand:<bnd_ptr> 1 "address_no_seg_operand" "Ts")] BNDCHECK)
20434 (set (match_operand:BLK 2 "bnd_mem_operator")
20435 (unspec:BLK [(match_dup 2)] UNSPEC_MPX_FENCE))]
20437 "bnd<bndcheck>\t{%a1, %0|%0, %a1}"
20438 [(set_attr "type" "mpxchk")])
20440 (define_expand "<mode>_ldx"
20442 [(set (match_operand:BND 0 "register_operand")
20446 [(match_operand:<bnd_ptr> 1 "address_mpx_no_index_operand")
20447 (match_operand:<bnd_ptr> 2 "register_operand")]))]
20449 (use (mem:BLK (match_dup 1)))])]
20452 /* Avoid registers which cannot be used as index. */
20453 if (!index_register_operand (operands[2], Pmode))
20454 operands[2] = copy_addr_to_reg (operands[2]);
20456 operands[3] = gen_rtx_UNSPEC (Pmode, gen_rtvec (2, operands[1],
20458 UNSPEC_BNDLDX_ADDR);
20461 (define_insn "*<mode>_ldx"
20462 [(set (match_operand:BND 0 "register_operand" "=w")
20464 [(match_operator:<bnd_ptr> 3 "bnd_mem_operator"
20466 [(match_operand:<bnd_ptr> 1 "address_mpx_no_index_operand" "Ti")
20467 (match_operand:<bnd_ptr> 2 "register_operand" "l")]
20468 UNSPEC_BNDLDX_ADDR)])]
20470 (use (mem:BLK (match_dup 1)))]
20472 "bndldx\t{%3, %0|%0, %3}"
20473 [(set_attr "type" "mpxld")])
20475 (define_expand "<mode>_stx"
20480 [(match_operand:<bnd_ptr> 0 "address_mpx_no_index_operand")
20481 (match_operand:<bnd_ptr> 1 "register_operand")]))
20482 (match_operand:BND 2 "register_operand")]
20485 (unspec:BLK [(match_dup 4)] UNSPEC_MPX_FENCE))])]
20488 /* Avoid registers which cannot be used as index. */
20489 if (!index_register_operand (operands[1], Pmode))
20490 operands[1] = copy_addr_to_reg (operands[1]);
20492 operands[3] = gen_rtx_UNSPEC (Pmode, gen_rtvec (2, operands[0],
20494 UNSPEC_BNDLDX_ADDR);
20495 operands[4] = gen_rtx_MEM (BLKmode, operands[0]);
20496 MEM_VOLATILE_P (operands[4]) = 1;
20499 (define_insn "*<mode>_stx"
20501 [(match_operator:<bnd_ptr> 3 "bnd_mem_operator"
20503 [(match_operand:<bnd_ptr> 0 "address_mpx_no_index_operand" "Ti")
20504 (match_operand:<bnd_ptr> 1 "register_operand" "l")]
20505 UNSPEC_BNDLDX_ADDR)])
20506 (match_operand:BND 2 "register_operand" "w")]
20508 (set (match_operand:BLK 4 "bnd_mem_operator")
20509 (unspec:BLK [(match_dup 4)] UNSPEC_MPX_FENCE))]
20511 "bndstx\t{%2, %3|%3, %2}"
20512 [(set_attr "type" "mpxst")])
20514 (define_insn "move_size_reloc_<mode>"
20515 [(set (match_operand:SWI48 0 "register_operand" "=r")
20517 [(match_operand:SWI48 1 "symbol_operand")]
20521 if (x86_64_immediate_size_operand (operands[1], VOIDmode))
20522 return "mov{l}\t{%1@SIZE, %k0|%k0, %1@SIZE}";
20524 return "movabs{q}\t{%1@SIZE, %0|%0, %1@SIZE}";
20526 [(set_attr "type" "imov")
20527 (set_attr "mode" "<MODE>")])
20529 ;; RDPKRU and WRPKRU
20531 (define_expand "rdpkru"
20533 [(set (match_operand:SI 0 "register_operand")
20534 (unspec_volatile:SI [(match_dup 1)] UNSPECV_PKU))
20535 (set (match_dup 2) (const_int 0))])]
20538 operands[1] = force_reg (SImode, const0_rtx);
20539 operands[2] = gen_reg_rtx (SImode);
20542 (define_insn "*rdpkru"
20543 [(set (match_operand:SI 0 "register_operand" "=a")
20544 (unspec_volatile:SI [(match_operand:SI 2 "register_operand" "c")]
20546 (set (match_operand:SI 1 "register_operand" "=d")
20550 [(set_attr "type" "other")])
20552 (define_expand "wrpkru"
20553 [(unspec_volatile:SI
20554 [(match_operand:SI 0 "register_operand")
20555 (match_dup 1) (match_dup 2)] UNSPECV_PKU)]
20558 operands[1] = force_reg (SImode, const0_rtx);
20559 operands[2] = force_reg (SImode, const0_rtx);
20562 (define_insn "*wrpkru"
20563 [(unspec_volatile:SI
20564 [(match_operand:SI 0 "register_operand" "a")
20565 (match_operand:SI 1 "register_operand" "d")
20566 (match_operand:SI 2 "register_operand" "c")] UNSPECV_PKU)]
20569 [(set_attr "type" "other")])
20571 (define_insn "rdpid"
20572 [(set (match_operand:SI 0 "register_operand" "=r")
20573 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDPID))]
20574 "!TARGET_64BIT && TARGET_RDPID"
20576 [(set_attr "type" "other")])
20578 (define_insn "rdpid_rex64"
20579 [(set (match_operand:DI 0 "register_operand" "=r")
20580 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDPID))]
20581 "TARGET_64BIT && TARGET_RDPID"
20583 [(set_attr "type" "other")])
20587 (include "sync.md")