1 ;; GCC machine description for IA-32 and x86-64.
2 ;; Copyright (C) 1988-2017 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
106 UNSPEC_LD_MPIC ; load_macho_picbase
108 UNSPEC_DIV_ALREADY_SPLIT
114 UNSPEC_INSN_FALSE_DEP
117 ;; For SSE/MMX support:
125 ;; Generic math support
127 UNSPEC_IEEE_MIN ; not commutative
128 UNSPEC_IEEE_MAX ; not commutative
130 ;; x87 Floating point
146 UNSPEC_FRNDINT_MASK_PM
150 ;; x87 Double output FP
175 ;; For LZCNT suppoprt
197 UNSPEC_INTERRUPT_RETURN
200 (define_c_enum "unspecv" [
204 UNSPECV_PROBE_STACK_RANGE
207 UNSPECV_SPLIT_STACK_RETURN
213 UNSPECV_LLWP_INTRINSIC
214 UNSPECV_SLWP_INTRINSIC
215 UNSPECV_LWPVAL_INTRINSIC
216 UNSPECV_LWPINS_INTRINSIC
240 ;; For atomic compound assignments.
246 ;; For RDRAND support
249 ;; For RDSEED support
263 ;; For CLFLUSHOPT support
266 ;; For MONITORX and MWAITX support
270 ;; For CLZERO support
273 ;; For RDPKRU and WRPKRU support
291 ;; Constants to represent rounding modes in the ROUND instruction
300 ;; Constants to represent AVX512F embeded rounding
302 [(ROUND_NEAREST_INT 0)
310 ;; Constants to represent pcomtrue/pcomfalse variants
320 ;; Constants used in the XOP pperm instruction
322 [(PPERM_SRC 0x00) /* copy source */
323 (PPERM_INVERT 0x20) /* invert source */
324 (PPERM_REVERSE 0x40) /* bit reverse source */
325 (PPERM_REV_INV 0x60) /* bit reverse & invert src */
326 (PPERM_ZERO 0x80) /* all 0's */
327 (PPERM_ONES 0xa0) /* all 1's */
328 (PPERM_SIGN 0xc0) /* propagate sign bit */
329 (PPERM_INV_SIGN 0xe0) /* invert & propagate sign */
330 (PPERM_SRC1 0x00) /* use first source byte */
331 (PPERM_SRC2 0x10) /* use second source byte */
334 ;; Registers by name.
417 (FIRST_PSEUDO_REG 81)
420 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
423 ;; In C guard expressions, put expressions which may be compile-time
424 ;; constants first. This allows for better optimization. For
425 ;; example, write "TARGET_64BIT && reload_completed", not
426 ;; "reload_completed && TARGET_64BIT".
430 (define_attr "cpu" "none,pentium,pentiumpro,geode,k6,athlon,k8,core2,nehalem,
431 atom,slm,haswell,generic,amdfam10,bdver1,bdver2,bdver3,
432 bdver4,btver2,znver1"
433 (const (symbol_ref "ix86_schedule")))
435 ;; A basic instruction type. Refinements due to arguments to be
436 ;; provided in other attributes.
439 alu,alu1,negnot,imov,imovx,lea,
440 incdec,ishift,ishiftx,ishift1,rotate,rotatex,rotate1,
441 imul,imulx,idiv,icmp,test,ibr,setcc,icmov,
442 push,pop,call,callv,leave,
444 fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,
445 fxch,fistp,fisttp,frndint,
446 sse,ssemov,sseadd,sseadd1,sseiadd,sseiadd1,
447 ssemul,sseimul,ssediv,sselog,sselog1,
448 sseishft,sseishft1,ssecmp,ssecomi,
449 ssecvt,ssecvt1,sseicvt,sseins,
450 sseshuf,sseshuf1,ssemuladd,sse4arg,
452 mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft,
453 mpxmov,mpxmk,mpxchk,mpxld,mpxst"
454 (const_string "other"))
456 ;; Main data type used by the insn
458 "unknown,none,QI,HI,SI,DI,TI,OI,XI,SF,DF,XF,TF,V16SF,V8SF,V4DF,V4SF,
460 (const_string "unknown"))
462 ;; The CPU unit operations uses.
463 (define_attr "unit" "integer,i387,sse,mmx,unknown"
464 (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,
465 fxch,fistp,fisttp,frndint")
466 (const_string "i387")
467 (eq_attr "type" "sse,ssemov,sseadd,sseadd1,sseiadd,sseiadd1,
468 ssemul,sseimul,ssediv,sselog,sselog1,
469 sseishft,sseishft1,ssecmp,ssecomi,
470 ssecvt,ssecvt1,sseicvt,sseins,
471 sseshuf,sseshuf1,ssemuladd,sse4arg,mskmov")
473 (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
475 (eq_attr "type" "other")
476 (const_string "unknown")]
477 (const_string "integer")))
479 ;; The (bounding maximum) length of an instruction immediate.
480 (define_attr "length_immediate" ""
481 (cond [(eq_attr "type" "incdec,setcc,icmov,str,lea,other,multi,idiv,leave,
482 bitmanip,imulx,msklog,mskmov,mpxmk,mpxmov,mpxchk,
485 (eq_attr "unit" "i387,sse,mmx")
487 (eq_attr "type" "alu,alu1,negnot,imovx,ishift,ishiftx,ishift1,
488 rotate,rotatex,rotate1,imul,icmp,push,pop")
489 (symbol_ref "ix86_attr_length_immediate_default (insn, true)")
490 (eq_attr "type" "imov,test")
491 (symbol_ref "ix86_attr_length_immediate_default (insn, false)")
492 (eq_attr "type" "call")
493 (if_then_else (match_operand 0 "constant_call_address_operand")
496 (eq_attr "type" "callv")
497 (if_then_else (match_operand 1 "constant_call_address_operand")
500 ;; We don't know the size before shorten_branches. Expect
501 ;; the instruction to fit for better scheduling.
502 (eq_attr "type" "ibr")
505 (symbol_ref "/* Update immediate_length and other attributes! */
506 gcc_unreachable (),1")))
508 ;; The (bounding maximum) length of an instruction address.
509 (define_attr "length_address" ""
510 (cond [(eq_attr "type" "str,other,multi,fxch")
512 (and (eq_attr "type" "call")
513 (match_operand 0 "constant_call_address_operand"))
515 (and (eq_attr "type" "callv")
516 (match_operand 1 "constant_call_address_operand"))
519 (symbol_ref "ix86_attr_length_address_default (insn)")))
521 ;; Set when length prefix is used.
522 (define_attr "prefix_data16" ""
523 (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
525 (eq_attr "mode" "HI")
527 (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF,TI"))
532 ;; Set when string REP prefix is used.
533 (define_attr "prefix_rep" ""
534 (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
536 (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
538 (and (eq_attr "type" "ibr,call,callv")
539 (match_test "ix86_bnd_prefixed_insn_p (insn)"))
544 ;; Set when 0f opcode prefix is used.
545 (define_attr "prefix_0f" ""
547 (ior (eq_attr "type" "imovx,setcc,icmov,bitmanip,msklog,mskmov,
548 mpxmk,mpxmov,mpxchk,mpxld,mpxst")
549 (eq_attr "unit" "sse,mmx"))
553 ;; Set when REX opcode prefix is used.
554 (define_attr "prefix_rex" ""
555 (cond [(not (match_test "TARGET_64BIT"))
557 (and (eq_attr "mode" "DI")
558 (and (eq_attr "type" "!push,pop,call,callv,leave,ibr")
559 (eq_attr "unit" "!mmx")))
561 (and (eq_attr "mode" "QI")
562 (match_test "x86_extended_QIreg_mentioned_p (insn)"))
564 (match_test "x86_extended_reg_mentioned_p (insn)")
566 (and (eq_attr "type" "imovx")
567 (match_operand:QI 1 "ext_QIreg_operand"))
572 ;; There are also additional prefixes in 3DNOW, SSSE3.
573 ;; ssemuladd,sse4arg default to 0f24/0f25 and DREX byte,
574 ;; sseiadd1,ssecvt1 to 0f7a with no DREX byte.
575 ;; 3DNOW has 0f0f prefix, SSSE3 and SSE4_{1,2} 0f38/0f3a.
576 (define_attr "prefix_extra" ""
577 (cond [(eq_attr "type" "ssemuladd,sse4arg")
579 (eq_attr "type" "sseiadd1,ssecvt1")
584 ;; Set when BND opcode prefix may be used.
585 (define_attr "maybe_prefix_bnd" "" (const_int 0))
587 ;; Prefix used: original, VEX or maybe VEX.
588 (define_attr "prefix" "orig,vex,maybe_vex,evex,maybe_evex"
589 (cond [(eq_attr "mode" "OI,V8SF,V4DF")
591 (eq_attr "mode" "XI,V16SF,V8DF")
592 (const_string "evex")
594 (const_string "orig")))
596 ;; VEX W bit is used.
597 (define_attr "prefix_vex_w" "" (const_int 0))
599 ;; The length of VEX prefix
600 ;; Only instructions with 0f prefix can have 2 byte VEX prefix,
601 ;; 0f38/0f3a prefixes can't. In i386.md 0f3[8a] is
602 ;; still prefix_0f 1, with prefix_extra 1.
603 (define_attr "length_vex" ""
604 (if_then_else (and (eq_attr "prefix_0f" "1")
605 (eq_attr "prefix_extra" "0"))
606 (if_then_else (eq_attr "prefix_vex_w" "1")
607 (symbol_ref "ix86_attr_length_vex_default (insn, true, true)")
608 (symbol_ref "ix86_attr_length_vex_default (insn, true, false)"))
609 (if_then_else (eq_attr "prefix_vex_w" "1")
610 (symbol_ref "ix86_attr_length_vex_default (insn, false, true)")
611 (symbol_ref "ix86_attr_length_vex_default (insn, false, false)"))))
613 ;; 4-bytes evex prefix and 1 byte opcode.
614 (define_attr "length_evex" "" (const_int 5))
616 ;; Set when modrm byte is used.
617 (define_attr "modrm" ""
618 (cond [(eq_attr "type" "str,leave")
620 (eq_attr "unit" "i387")
622 (and (eq_attr "type" "incdec")
623 (and (not (match_test "TARGET_64BIT"))
624 (ior (match_operand:SI 1 "register_operand")
625 (match_operand:HI 1 "register_operand"))))
627 (and (eq_attr "type" "push")
628 (not (match_operand 1 "memory_operand")))
630 (and (eq_attr "type" "pop")
631 (not (match_operand 0 "memory_operand")))
633 (and (eq_attr "type" "imov")
634 (and (not (eq_attr "mode" "DI"))
635 (ior (and (match_operand 0 "register_operand")
636 (match_operand 1 "immediate_operand"))
637 (ior (and (match_operand 0 "ax_reg_operand")
638 (match_operand 1 "memory_displacement_only_operand"))
639 (and (match_operand 0 "memory_displacement_only_operand")
640 (match_operand 1 "ax_reg_operand"))))))
642 (and (eq_attr "type" "call")
643 (match_operand 0 "constant_call_address_operand"))
645 (and (eq_attr "type" "callv")
646 (match_operand 1 "constant_call_address_operand"))
648 (and (eq_attr "type" "alu,alu1,icmp,test")
649 (match_operand 0 "ax_reg_operand"))
650 (symbol_ref "(get_attr_length_immediate (insn) <= (get_attr_mode (insn) != MODE_QI))")
654 (define_attr "modrm_class" "none,incdec,op0,op01,op02,pushpop,unknown"
655 (cond [(eq_attr "modrm" "0")
656 (const_string "none")
657 (eq_attr "type" "alu,imul,ishift")
658 (const_string "op02")
659 (eq_attr "type" "imov,imovx,lea,alu1,icmp")
660 (const_string "op01")
661 (eq_attr "type" "incdec")
662 (const_string "incdec")
663 (eq_attr "type" "push,pop")
664 (const_string "pushpop")]
665 (const_string "unknown")))
667 ;; The (bounding maximum) length of an instruction in bytes.
668 ;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
669 ;; Later we may want to split them and compute proper length as for
671 (define_attr "length" ""
672 (cond [(eq_attr "type" "other,multi,fistp,frndint")
674 (eq_attr "type" "fcmp")
676 (eq_attr "unit" "i387")
678 (plus (attr "prefix_data16")
679 (attr "length_address")))
680 (ior (eq_attr "prefix" "evex")
681 (and (ior (eq_attr "prefix" "maybe_evex")
682 (eq_attr "prefix" "maybe_vex"))
683 (match_test "TARGET_AVX512F")))
684 (plus (attr "length_evex")
685 (plus (attr "length_immediate")
687 (attr "length_address"))))
688 (ior (eq_attr "prefix" "vex")
689 (and (ior (eq_attr "prefix" "maybe_vex")
690 (eq_attr "prefix" "maybe_evex"))
691 (match_test "TARGET_AVX")))
692 (plus (attr "length_vex")
693 (plus (attr "length_immediate")
695 (attr "length_address"))))]
696 (plus (plus (attr "modrm")
697 (plus (attr "prefix_0f")
698 (plus (attr "prefix_rex")
699 (plus (attr "prefix_extra")
701 (plus (attr "prefix_rep")
702 (plus (attr "prefix_data16")
703 (plus (attr "length_immediate")
704 (attr "length_address")))))))
706 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
707 ;; `store' if there is a simple memory reference therein, or `unknown'
708 ;; if the instruction is complex.
710 (define_attr "memory" "none,load,store,both,unknown"
711 (cond [(eq_attr "type" "other,multi,str,lwp")
712 (const_string "unknown")
713 (eq_attr "type" "lea,fcmov,fpspc,mpxmk,mpxchk")
714 (const_string "none")
715 (eq_attr "type" "fistp,leave")
716 (const_string "both")
717 (eq_attr "type" "frndint")
718 (const_string "load")
719 (eq_attr "type" "mpxld")
720 (const_string "load")
721 (eq_attr "type" "mpxst")
722 (const_string "store")
723 (eq_attr "type" "push")
724 (if_then_else (match_operand 1 "memory_operand")
725 (const_string "both")
726 (const_string "store"))
727 (eq_attr "type" "pop")
728 (if_then_else (match_operand 0 "memory_operand")
729 (const_string "both")
730 (const_string "load"))
731 (eq_attr "type" "setcc")
732 (if_then_else (match_operand 0 "memory_operand")
733 (const_string "store")
734 (const_string "none"))
735 (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
736 (if_then_else (ior (match_operand 0 "memory_operand")
737 (match_operand 1 "memory_operand"))
738 (const_string "load")
739 (const_string "none"))
740 (eq_attr "type" "ibr")
741 (if_then_else (match_operand 0 "memory_operand")
742 (const_string "load")
743 (const_string "none"))
744 (eq_attr "type" "call")
745 (if_then_else (match_operand 0 "constant_call_address_operand")
746 (const_string "none")
747 (const_string "load"))
748 (eq_attr "type" "callv")
749 (if_then_else (match_operand 1 "constant_call_address_operand")
750 (const_string "none")
751 (const_string "load"))
752 (and (eq_attr "type" "alu1,negnot,ishift1,sselog1,sseshuf1")
753 (match_operand 1 "memory_operand"))
754 (const_string "both")
755 (and (match_operand 0 "memory_operand")
756 (match_operand 1 "memory_operand"))
757 (const_string "both")
758 (match_operand 0 "memory_operand")
759 (const_string "store")
760 (match_operand 1 "memory_operand")
761 (const_string "load")
763 "!alu1,negnot,ishift1,
764 imov,imovx,icmp,test,bitmanip,
766 sse,ssemov,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,
767 sselog1,sseshuf1,sseadd1,sseiadd1,sseishft1,
768 mmx,mmxmov,mmxcmp,mmxcvt,mskmov,msklog,mpxmov")
769 (match_operand 2 "memory_operand"))
770 (const_string "load")
771 (and (eq_attr "type" "icmov,ssemuladd,sse4arg")
772 (match_operand 3 "memory_operand"))
773 (const_string "load")
775 (const_string "none")))
777 ;; Indicates if an instruction has both an immediate and a displacement.
779 (define_attr "imm_disp" "false,true,unknown"
780 (cond [(eq_attr "type" "other,multi")
781 (const_string "unknown")
782 (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
783 (and (match_operand 0 "memory_displacement_operand")
784 (match_operand 1 "immediate_operand")))
785 (const_string "true")
786 (and (eq_attr "type" "alu,ishift,ishiftx,rotate,rotatex,imul,idiv")
787 (and (match_operand 0 "memory_displacement_operand")
788 (match_operand 2 "immediate_operand")))
789 (const_string "true")
791 (const_string "false")))
793 ;; Indicates if an FP operation has an integer source.
795 (define_attr "fp_int_src" "false,true"
796 (const_string "false"))
798 ;; Defines rounding mode of an FP operation.
800 (define_attr "i387_cw" "trunc,floor,ceil,mask_pm,uninitialized,any"
801 (const_string "any"))
803 ;; Define attribute to classify add/sub insns that consumes carry flag (CF)
804 (define_attr "use_carry" "0,1" (const_string "0"))
806 ;; Define attribute to indicate unaligned ssemov insns
807 (define_attr "movu" "0,1" (const_string "0"))
809 ;; Used to control the "enabled" attribute on a per-instruction basis.
810 (define_attr "isa" "base,x64,x64_sse4,x64_sse4_noavx,x64_avx,nox64,
811 sse2,sse2_noavx,sse3,sse4,sse4_noavx,avx,noavx,
812 avx2,noavx2,bmi,bmi2,fma4,fma,avx512f,noavx512f,
813 avx512bw,noavx512bw,avx512dq,noavx512dq,
814 avx512vl,noavx512vl,x64_avx512dq,x64_avx512bw"
815 (const_string "base"))
817 (define_attr "enabled" ""
818 (cond [(eq_attr "isa" "x64") (symbol_ref "TARGET_64BIT")
819 (eq_attr "isa" "x64_sse4")
820 (symbol_ref "TARGET_64BIT && TARGET_SSE4_1")
821 (eq_attr "isa" "x64_sse4_noavx")
822 (symbol_ref "TARGET_64BIT && TARGET_SSE4_1 && !TARGET_AVX")
823 (eq_attr "isa" "x64_avx")
824 (symbol_ref "TARGET_64BIT && TARGET_AVX")
825 (eq_attr "isa" "x64_avx512dq")
826 (symbol_ref "TARGET_64BIT && TARGET_AVX512DQ")
827 (eq_attr "isa" "x64_avx512bw")
828 (symbol_ref "TARGET_64BIT && TARGET_AVX512BW")
829 (eq_attr "isa" "nox64") (symbol_ref "!TARGET_64BIT")
830 (eq_attr "isa" "sse2") (symbol_ref "TARGET_SSE2")
831 (eq_attr "isa" "sse2_noavx")
832 (symbol_ref "TARGET_SSE2 && !TARGET_AVX")
833 (eq_attr "isa" "sse3") (symbol_ref "TARGET_SSE3")
834 (eq_attr "isa" "sse4") (symbol_ref "TARGET_SSE4_1")
835 (eq_attr "isa" "sse4_noavx")
836 (symbol_ref "TARGET_SSE4_1 && !TARGET_AVX")
837 (eq_attr "isa" "avx") (symbol_ref "TARGET_AVX")
838 (eq_attr "isa" "noavx") (symbol_ref "!TARGET_AVX")
839 (eq_attr "isa" "avx2") (symbol_ref "TARGET_AVX2")
840 (eq_attr "isa" "noavx2") (symbol_ref "!TARGET_AVX2")
841 (eq_attr "isa" "bmi") (symbol_ref "TARGET_BMI")
842 (eq_attr "isa" "bmi2") (symbol_ref "TARGET_BMI2")
843 (eq_attr "isa" "fma4") (symbol_ref "TARGET_FMA4")
844 (eq_attr "isa" "fma") (symbol_ref "TARGET_FMA")
845 (eq_attr "isa" "avx512f") (symbol_ref "TARGET_AVX512F")
846 (eq_attr "isa" "noavx512f") (symbol_ref "!TARGET_AVX512F")
847 (eq_attr "isa" "avx512bw") (symbol_ref "TARGET_AVX512BW")
848 (eq_attr "isa" "noavx512bw") (symbol_ref "!TARGET_AVX512BW")
849 (eq_attr "isa" "avx512dq") (symbol_ref "TARGET_AVX512DQ")
850 (eq_attr "isa" "noavx512dq") (symbol_ref "!TARGET_AVX512DQ")
851 (eq_attr "isa" "avx512vl") (symbol_ref "TARGET_AVX512VL")
852 (eq_attr "isa" "noavx512vl") (symbol_ref "!TARGET_AVX512VL")
856 (define_attr "preferred_for_size" "" (const_int 1))
857 (define_attr "preferred_for_speed" "" (const_int 1))
859 ;; Describe a user's asm statement.
860 (define_asm_attributes
861 [(set_attr "length" "128")
862 (set_attr "type" "multi")])
864 (define_code_iterator plusminus [plus minus])
866 (define_code_iterator sat_plusminus [ss_plus us_plus ss_minus us_minus])
868 (define_code_iterator multdiv [mult div])
870 ;; Base name for define_insn
871 (define_code_attr plusminus_insn
872 [(plus "add") (ss_plus "ssadd") (us_plus "usadd")
873 (minus "sub") (ss_minus "sssub") (us_minus "ussub")])
875 ;; Base name for insn mnemonic.
876 (define_code_attr plusminus_mnemonic
877 [(plus "add") (ss_plus "adds") (us_plus "addus")
878 (minus "sub") (ss_minus "subs") (us_minus "subus")])
879 (define_code_attr multdiv_mnemonic
880 [(mult "mul") (div "div")])
882 ;; Mark commutative operators as such in constraints.
883 (define_code_attr comm [(plus "%") (ss_plus "%") (us_plus "%")
884 (minus "") (ss_minus "") (us_minus "")])
886 ;; Mapping of max and min
887 (define_code_iterator maxmin [smax smin umax umin])
889 ;; Mapping of signed max and min
890 (define_code_iterator smaxmin [smax smin])
892 ;; Mapping of unsigned max and min
893 (define_code_iterator umaxmin [umax umin])
895 ;; Base name for integer and FP insn mnemonic
896 (define_code_attr maxmin_int [(smax "maxs") (smin "mins")
897 (umax "maxu") (umin "minu")])
898 (define_code_attr maxmin_float [(smax "max") (smin "min")])
900 (define_int_iterator IEEE_MAXMIN
904 (define_int_attr ieee_maxmin
905 [(UNSPEC_IEEE_MAX "max")
906 (UNSPEC_IEEE_MIN "min")])
908 ;; Mapping of logic operators
909 (define_code_iterator any_logic [and ior xor])
910 (define_code_iterator any_or [ior xor])
911 (define_code_iterator fpint_logic [and xor])
913 ;; Base name for insn mnemonic.
914 (define_code_attr logic [(and "and") (ior "or") (xor "xor")])
916 ;; Mapping of logic-shift operators
917 (define_code_iterator any_lshift [ashift lshiftrt])
919 ;; Mapping of shift-right operators
920 (define_code_iterator any_shiftrt [lshiftrt ashiftrt])
922 ;; Mapping of all shift operators
923 (define_code_iterator any_shift [ashift lshiftrt ashiftrt])
925 ;; Base name for define_insn
926 (define_code_attr shift_insn
927 [(ashift "ashl") (lshiftrt "lshr") (ashiftrt "ashr")])
929 ;; Base name for insn mnemonic.
930 (define_code_attr shift [(ashift "sll") (lshiftrt "shr") (ashiftrt "sar")])
931 (define_code_attr vshift [(ashift "sll") (lshiftrt "srl") (ashiftrt "sra")])
933 ;; Mapping of rotate operators
934 (define_code_iterator any_rotate [rotate rotatert])
936 ;; Base name for define_insn
937 (define_code_attr rotate_insn [(rotate "rotl") (rotatert "rotr")])
939 ;; Base name for insn mnemonic.
940 (define_code_attr rotate [(rotate "rol") (rotatert "ror")])
942 ;; Mapping of abs neg operators
943 (define_code_iterator absneg [abs neg])
945 ;; Base name for x87 insn mnemonic.
946 (define_code_attr absneg_mnemonic [(abs "abs") (neg "chs")])
948 ;; Used in signed and unsigned widening multiplications.
949 (define_code_iterator any_extend [sign_extend zero_extend])
951 ;; Prefix for insn menmonic.
952 (define_code_attr sgnprefix [(sign_extend "i") (zero_extend "")])
954 ;; Prefix for define_insn
955 (define_code_attr u [(sign_extend "") (zero_extend "u")])
956 (define_code_attr s [(sign_extend "s") (zero_extend "u")])
957 (define_code_attr u_bool [(sign_extend "false") (zero_extend "true")])
959 ;; Used in signed and unsigned truncations.
960 (define_code_iterator any_truncate [ss_truncate truncate us_truncate])
961 ;; Instruction suffix for truncations.
962 (define_code_attr trunsuffix [(ss_truncate "s") (truncate "") (us_truncate "us")])
964 ;; Used in signed and unsigned fix.
965 (define_code_iterator any_fix [fix unsigned_fix])
966 (define_code_attr fixsuffix [(fix "") (unsigned_fix "u")])
968 ;; Used in signed and unsigned float.
969 (define_code_iterator any_float [float unsigned_float])
970 (define_code_attr floatsuffix [(float "") (unsigned_float "u")])
972 ;; All integer modes.
973 (define_mode_iterator SWI1248x [QI HI SI DI])
975 ;; All integer modes without QImode.
976 (define_mode_iterator SWI248x [HI SI DI])
978 ;; All integer modes without QImode and HImode.
979 (define_mode_iterator SWI48x [SI DI])
981 ;; All integer modes without SImode and DImode.
982 (define_mode_iterator SWI12 [QI HI])
984 ;; All integer modes without DImode.
985 (define_mode_iterator SWI124 [QI HI SI])
987 ;; All integer modes without QImode and DImode.
988 (define_mode_iterator SWI24 [HI SI])
990 ;; Single word integer modes.
991 (define_mode_iterator SWI [QI HI SI (DI "TARGET_64BIT")])
993 ;; Single word integer modes without QImode.
994 (define_mode_iterator SWI248 [HI SI (DI "TARGET_64BIT")])
996 ;; Single word integer modes without QImode and HImode.
997 (define_mode_iterator SWI48 [SI (DI "TARGET_64BIT")])
999 ;; All math-dependant single and double word integer modes.
1000 (define_mode_iterator SDWIM [(QI "TARGET_QIMODE_MATH")
1001 (HI "TARGET_HIMODE_MATH")
1002 SI DI (TI "TARGET_64BIT")])
1004 ;; Math-dependant single word integer modes.
1005 (define_mode_iterator SWIM [(QI "TARGET_QIMODE_MATH")
1006 (HI "TARGET_HIMODE_MATH")
1007 SI (DI "TARGET_64BIT")])
1009 ;; Math-dependant integer modes without DImode.
1010 (define_mode_iterator SWIM124 [(QI "TARGET_QIMODE_MATH")
1011 (HI "TARGET_HIMODE_MATH")
1014 ;; Math-dependant integer modes with DImode.
1015 (define_mode_iterator SWIM1248x [(QI "TARGET_QIMODE_MATH")
1016 (HI "TARGET_HIMODE_MATH")
1017 SI (DI "(TARGET_STV && TARGET_SSE2) || TARGET_64BIT")])
1019 ;; Math-dependant single word integer modes without QImode.
1020 (define_mode_iterator SWIM248 [(HI "TARGET_HIMODE_MATH")
1021 SI (DI "TARGET_64BIT")])
1023 ;; Double word integer modes.
1024 (define_mode_iterator DWI [(DI "!TARGET_64BIT")
1025 (TI "TARGET_64BIT")])
1027 ;; GET_MODE_SIZE for selected modes. As GET_MODE_SIZE is not
1028 ;; compile time constant, it is faster to use <MODE_SIZE> than
1029 ;; GET_MODE_SIZE (<MODE>mode). For XFmode which depends on
1030 ;; command line options just use GET_MODE_SIZE macro.
1031 (define_mode_attr MODE_SIZE [(QI "1") (HI "2") (SI "4") (DI "8") (TI "16")
1032 (SF "4") (DF "8") (XF "GET_MODE_SIZE (XFmode)")
1033 (V16QI "16") (V32QI "32") (V64QI "64")
1034 (V8HI "16") (V16HI "32") (V32HI "64")
1035 (V4SI "16") (V8SI "32") (V16SI "64")
1036 (V2DI "16") (V4DI "32") (V8DI "64")
1037 (V1TI "16") (V2TI "32") (V4TI "64")
1038 (V2DF "16") (V4DF "32") (V8DF "64")
1039 (V4SF "16") (V8SF "32") (V16SF "64")])
1041 ;; Double word integer modes as mode attribute.
1042 (define_mode_attr DWI [(QI "HI") (HI "SI") (SI "DI") (DI "TI")])
1043 (define_mode_attr dwi [(QI "hi") (HI "si") (SI "di") (DI "ti")])
1045 ;; LEA mode corresponding to an integer mode
1046 (define_mode_attr LEAMODE [(QI "SI") (HI "SI") (SI "SI") (DI "DI")])
1048 ;; Half mode for double word integer modes.
1049 (define_mode_iterator DWIH [(SI "!TARGET_64BIT")
1050 (DI "TARGET_64BIT")])
1053 (define_mode_iterator BND [(BND32 "!TARGET_LP64")
1054 (BND64 "TARGET_LP64")])
1056 ;; Pointer mode corresponding to bound mode.
1057 (define_mode_attr bnd_ptr [(BND32 "SI") (BND64 "DI")])
1060 (define_int_iterator BNDCHECK [UNSPEC_BNDCL UNSPEC_BNDCU UNSPEC_BNDCN])
1063 (define_int_attr bndcheck [(UNSPEC_BNDCL "cl")
1065 (UNSPEC_BNDCN "cn")])
1067 ;; Instruction suffix for integer modes.
1068 (define_mode_attr imodesuffix [(QI "b") (HI "w") (SI "l") (DI "q")])
1070 ;; Instruction suffix for masks.
1071 (define_mode_attr mskmodesuffix [(QI "b") (HI "w") (SI "d") (DI "q")])
1073 ;; Pointer size prefix for integer modes (Intel asm dialect)
1074 (define_mode_attr iptrsize [(QI "BYTE")
1079 ;; Register class for integer modes.
1080 (define_mode_attr r [(QI "q") (HI "r") (SI "r") (DI "r")])
1082 ;; Immediate operand constraint for integer modes.
1083 (define_mode_attr i [(QI "n") (HI "n") (SI "e") (DI "e")])
1085 ;; General operand constraint for word modes.
1086 (define_mode_attr g [(QI "qmn") (HI "rmn") (SI "rme") (DI "rme")])
1088 ;; Immediate operand constraint for double integer modes.
1089 (define_mode_attr di [(SI "nF") (DI "Wd")])
1091 ;; Immediate operand constraint for shifts.
1092 (define_mode_attr S [(QI "I") (HI "I") (SI "I") (DI "J") (TI "O")])
1094 ;; Print register name in the specified mode.
1095 (define_mode_attr k [(QI "b") (HI "w") (SI "k") (DI "q")])
1097 ;; General operand predicate for integer modes.
1098 (define_mode_attr general_operand
1099 [(QI "general_operand")
1100 (HI "general_operand")
1101 (SI "x86_64_general_operand")
1102 (DI "x86_64_general_operand")
1103 (TI "x86_64_general_operand")])
1105 ;; General operand predicate for integer modes, where for TImode
1106 ;; we need both words of the operand to be general operands.
1107 (define_mode_attr general_hilo_operand
1108 [(QI "general_operand")
1109 (HI "general_operand")
1110 (SI "x86_64_general_operand")
1111 (DI "x86_64_general_operand")
1112 (TI "x86_64_hilo_general_operand")])
1114 ;; General sign extend operand predicate for integer modes,
1115 ;; which disallows VOIDmode operands and thus it is suitable
1116 ;; for use inside sign_extend.
1117 (define_mode_attr general_sext_operand
1118 [(QI "sext_operand")
1120 (SI "x86_64_sext_operand")
1121 (DI "x86_64_sext_operand")])
1123 ;; General sign/zero extend operand predicate for integer modes.
1124 (define_mode_attr general_szext_operand
1125 [(QI "general_operand")
1126 (HI "general_operand")
1127 (SI "x86_64_szext_general_operand")
1128 (DI "x86_64_szext_general_operand")])
1130 ;; Immediate operand predicate for integer modes.
1131 (define_mode_attr immediate_operand
1132 [(QI "immediate_operand")
1133 (HI "immediate_operand")
1134 (SI "x86_64_immediate_operand")
1135 (DI "x86_64_immediate_operand")])
1137 ;; Nonmemory operand predicate for integer modes.
1138 (define_mode_attr nonmemory_operand
1139 [(QI "nonmemory_operand")
1140 (HI "nonmemory_operand")
1141 (SI "x86_64_nonmemory_operand")
1142 (DI "x86_64_nonmemory_operand")])
1144 ;; Operand predicate for shifts.
1145 (define_mode_attr shift_operand
1146 [(QI "nonimmediate_operand")
1147 (HI "nonimmediate_operand")
1148 (SI "nonimmediate_operand")
1149 (DI "shiftdi_operand")
1150 (TI "register_operand")])
1152 ;; Operand predicate for shift argument.
1153 (define_mode_attr shift_immediate_operand
1154 [(QI "const_1_to_31_operand")
1155 (HI "const_1_to_31_operand")
1156 (SI "const_1_to_31_operand")
1157 (DI "const_1_to_63_operand")])
1159 ;; Input operand predicate for arithmetic left shifts.
1160 (define_mode_attr ashl_input_operand
1161 [(QI "nonimmediate_operand")
1162 (HI "nonimmediate_operand")
1163 (SI "nonimmediate_operand")
1164 (DI "ashldi_input_operand")
1165 (TI "reg_or_pm1_operand")])
1167 ;; SSE and x87 SFmode and DFmode floating point modes
1168 (define_mode_iterator MODEF [SF DF])
1170 ;; All x87 floating point modes
1171 (define_mode_iterator X87MODEF [SF DF XF])
1173 ;; SSE instruction suffix for various modes
1174 (define_mode_attr ssemodesuffix
1175 [(SF "ss") (DF "sd")
1176 (V16SF "ps") (V8DF "pd")
1177 (V8SF "ps") (V4DF "pd")
1178 (V4SF "ps") (V2DF "pd")
1179 (V16QI "b") (V8HI "w") (V4SI "d") (V2DI "q")
1180 (V32QI "b") (V16HI "w") (V8SI "d") (V4DI "q")
1181 (V64QI "b") (V32HI "w") (V16SI "d") (V8DI "q")])
1183 ;; SSE vector suffix for floating point modes
1184 (define_mode_attr ssevecmodesuffix [(SF "ps") (DF "pd")])
1186 ;; SSE vector mode corresponding to a scalar mode
1187 (define_mode_attr ssevecmode
1188 [(QI "V16QI") (HI "V8HI") (SI "V4SI") (DI "V2DI") (SF "V4SF") (DF "V2DF")])
1189 (define_mode_attr ssevecmodelower
1190 [(QI "v16qi") (HI "v8hi") (SI "v4si") (DI "v2di") (SF "v4sf") (DF "v2df")])
1192 ;; AVX512F vector mode corresponding to a scalar mode
1193 (define_mode_attr avx512fvecmode
1194 [(QI "V64QI") (HI "V32HI") (SI "V16SI") (DI "V8DI") (SF "V16SF") (DF "V8DF")])
1196 ;; Instruction suffix for REX 64bit operators.
1197 (define_mode_attr rex64suffix [(SI "") (DI "{q}")])
1199 ;; This mode iterator allows :P to be used for patterns that operate on
1200 ;; pointer-sized quantities. Exactly one of the two alternatives will match.
1201 (define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
1203 ;; This mode iterator allows :W to be used for patterns that operate on
1204 ;; word_mode sized quantities.
1205 (define_mode_iterator W
1206 [(SI "word_mode == SImode") (DI "word_mode == DImode")])
1208 ;; This mode iterator allows :PTR to be used for patterns that operate on
1209 ;; ptr_mode sized quantities.
1210 (define_mode_iterator PTR
1211 [(SI "ptr_mode == SImode") (DI "ptr_mode == DImode")])
1213 ;; Scheduling descriptions
1215 (include "pentium.md")
1218 (include "athlon.md")
1219 (include "bdver1.md")
1220 (include "bdver3.md")
1221 (include "btver2.md")
1222 (include "znver1.md")
1223 (include "geode.md")
1226 (include "core2.md")
1227 (include "haswell.md")
1230 ;; Operand and operator predicates and constraints
1232 (include "predicates.md")
1233 (include "constraints.md")
1236 ;; Compare and branch/compare and store instructions.
1238 (define_expand "cbranch<mode>4"
1239 [(set (reg:CC FLAGS_REG)
1240 (compare:CC (match_operand:SDWIM 1 "nonimmediate_operand")
1241 (match_operand:SDWIM 2 "<general_operand>")))
1242 (set (pc) (if_then_else
1243 (match_operator 0 "ordered_comparison_operator"
1244 [(reg:CC FLAGS_REG) (const_int 0)])
1245 (label_ref (match_operand 3))
1249 if (MEM_P (operands[1]) && MEM_P (operands[2]))
1250 operands[1] = force_reg (<MODE>mode, operands[1]);
1251 ix86_expand_branch (GET_CODE (operands[0]),
1252 operands[1], operands[2], operands[3]);
1256 (define_expand "cstore<mode>4"
1257 [(set (reg:CC FLAGS_REG)
1258 (compare:CC (match_operand:SWIM 2 "nonimmediate_operand")
1259 (match_operand:SWIM 3 "<general_operand>")))
1260 (set (match_operand:QI 0 "register_operand")
1261 (match_operator 1 "ordered_comparison_operator"
1262 [(reg:CC FLAGS_REG) (const_int 0)]))]
1265 if (MEM_P (operands[2]) && MEM_P (operands[3]))
1266 operands[2] = force_reg (<MODE>mode, operands[2]);
1267 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1268 operands[2], operands[3]);
1272 (define_expand "cmp<mode>_1"
1273 [(set (reg:CC FLAGS_REG)
1274 (compare:CC (match_operand:SWI48 0 "nonimmediate_operand")
1275 (match_operand:SWI48 1 "<general_operand>")))])
1277 (define_insn "*cmp<mode>_ccno_1"
1278 [(set (reg FLAGS_REG)
1279 (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>,?m<r>")
1280 (match_operand:SWI 1 "const0_operand")))]
1281 "ix86_match_ccmode (insn, CCNOmode)"
1283 test{<imodesuffix>}\t%0, %0
1284 cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1285 [(set_attr "type" "test,icmp")
1286 (set_attr "length_immediate" "0,1")
1287 (set_attr "modrm_class" "op0,unknown")
1288 (set_attr "mode" "<MODE>")])
1290 (define_insn "*cmp<mode>_1"
1291 [(set (reg FLAGS_REG)
1292 (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
1293 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m")))]
1294 "ix86_match_ccmode (insn, CCmode)"
1295 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1296 [(set_attr "type" "icmp")
1297 (set_attr "mode" "<MODE>")])
1299 (define_insn "*cmp<mode>_minus_1"
1300 [(set (reg FLAGS_REG)
1302 (minus:SWI (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
1303 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
1305 "ix86_match_ccmode (insn, CCGOCmode)"
1306 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1307 [(set_attr "type" "icmp")
1308 (set_attr "mode" "<MODE>")])
1310 (define_insn "*cmpqi_ext_1"
1311 [(set (reg FLAGS_REG)
1313 (match_operand:QI 0 "nonimmediate_operand" "QBc,m")
1316 (match_operand 1 "ext_register_operand" "Q,Q")
1318 (const_int 8)) 0)))]
1319 "ix86_match_ccmode (insn, CCmode)"
1320 "cmp{b}\t{%h1, %0|%0, %h1}"
1321 [(set_attr "isa" "*,nox64")
1322 (set_attr "type" "icmp")
1323 (set_attr "mode" "QI")])
1325 (define_insn "*cmpqi_ext_2"
1326 [(set (reg FLAGS_REG)
1330 (match_operand 0 "ext_register_operand" "Q")
1333 (match_operand:QI 1 "const0_operand")))]
1334 "ix86_match_ccmode (insn, CCNOmode)"
1336 [(set_attr "type" "test")
1337 (set_attr "length_immediate" "0")
1338 (set_attr "mode" "QI")])
1340 (define_expand "cmpqi_ext_3"
1341 [(set (reg:CC FLAGS_REG)
1345 (match_operand 0 "ext_register_operand")
1348 (match_operand:QI 1 "const_int_operand")))])
1350 (define_insn "*cmpqi_ext_3"
1351 [(set (reg FLAGS_REG)
1355 (match_operand 0 "ext_register_operand" "Q,Q")
1358 (match_operand:QI 1 "general_operand" "QnBc,m")))]
1359 "ix86_match_ccmode (insn, CCmode)"
1360 "cmp{b}\t{%1, %h0|%h0, %1}"
1361 [(set_attr "isa" "*,nox64")
1362 (set_attr "type" "icmp")
1363 (set_attr "mode" "QI")])
1365 (define_insn "*cmpqi_ext_4"
1366 [(set (reg FLAGS_REG)
1370 (match_operand 0 "ext_register_operand" "Q")
1375 (match_operand 1 "ext_register_operand" "Q")
1377 (const_int 8)) 0)))]
1378 "ix86_match_ccmode (insn, CCmode)"
1379 "cmp{b}\t{%h1, %h0|%h0, %h1}"
1380 [(set_attr "type" "icmp")
1381 (set_attr "mode" "QI")])
1383 ;; These implement float point compares.
1384 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
1385 ;; which would allow mix and match FP modes on the compares. Which is what
1386 ;; the old patterns did, but with many more of them.
1388 (define_expand "cbranchxf4"
1389 [(set (reg:CC FLAGS_REG)
1390 (compare:CC (match_operand:XF 1 "nonmemory_operand")
1391 (match_operand:XF 2 "nonmemory_operand")))
1392 (set (pc) (if_then_else
1393 (match_operator 0 "ix86_fp_comparison_operator"
1396 (label_ref (match_operand 3))
1400 ix86_expand_branch (GET_CODE (operands[0]),
1401 operands[1], operands[2], operands[3]);
1405 (define_expand "cstorexf4"
1406 [(set (reg:CC FLAGS_REG)
1407 (compare:CC (match_operand:XF 2 "nonmemory_operand")
1408 (match_operand:XF 3 "nonmemory_operand")))
1409 (set (match_operand:QI 0 "register_operand")
1410 (match_operator 1 "ix86_fp_comparison_operator"
1415 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1416 operands[2], operands[3]);
1420 (define_expand "cbranch<mode>4"
1421 [(set (reg:CC FLAGS_REG)
1422 (compare:CC (match_operand:MODEF 1 "cmp_fp_expander_operand")
1423 (match_operand:MODEF 2 "cmp_fp_expander_operand")))
1424 (set (pc) (if_then_else
1425 (match_operator 0 "ix86_fp_comparison_operator"
1428 (label_ref (match_operand 3))
1430 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1432 ix86_expand_branch (GET_CODE (operands[0]),
1433 operands[1], operands[2], operands[3]);
1437 (define_expand "cstore<mode>4"
1438 [(set (reg:CC FLAGS_REG)
1439 (compare:CC (match_operand:MODEF 2 "cmp_fp_expander_operand")
1440 (match_operand:MODEF 3 "cmp_fp_expander_operand")))
1441 (set (match_operand:QI 0 "register_operand")
1442 (match_operator 1 "ix86_fp_comparison_operator"
1445 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1447 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1448 operands[2], operands[3]);
1452 (define_expand "cbranchcc4"
1453 [(set (pc) (if_then_else
1454 (match_operator 0 "comparison_operator"
1455 [(match_operand 1 "flags_reg_operand")
1456 (match_operand 2 "const0_operand")])
1457 (label_ref (match_operand 3))
1461 ix86_expand_branch (GET_CODE (operands[0]),
1462 operands[1], operands[2], operands[3]);
1466 (define_expand "cstorecc4"
1467 [(set (match_operand:QI 0 "register_operand")
1468 (match_operator 1 "comparison_operator"
1469 [(match_operand 2 "flags_reg_operand")
1470 (match_operand 3 "const0_operand")]))]
1473 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1474 operands[2], operands[3]);
1479 ;; FP compares, step 1:
1480 ;; Set the FP condition codes.
1482 ;; CCFPmode compare with exceptions
1483 ;; CCFPUmode compare with no exceptions
1485 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
1486 ;; used to manage the reg stack popping would not be preserved.
1488 (define_insn "*cmp<mode>_0_i387"
1489 [(set (match_operand:HI 0 "register_operand" "=a")
1492 (match_operand:X87MODEF 1 "register_operand" "f")
1493 (match_operand:X87MODEF 2 "const0_operand"))]
1496 "* return output_fp_compare (insn, operands, false, false);"
1497 [(set_attr "type" "multi")
1498 (set_attr "unit" "i387")
1499 (set_attr "mode" "<MODE>")])
1501 (define_insn_and_split "*cmp<mode>_0_cc_i387"
1502 [(set (reg:CCFP FLAGS_REG)
1504 (match_operand:X87MODEF 1 "register_operand" "f")
1505 (match_operand:X87MODEF 2 "const0_operand")))
1506 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1507 "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE"
1509 "&& reload_completed"
1512 [(compare:CCFP (match_dup 1)(match_dup 2))]
1514 (set (reg:CC FLAGS_REG)
1515 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1517 [(set_attr "type" "multi")
1518 (set_attr "unit" "i387")
1519 (set_attr "mode" "<MODE>")])
1521 (define_insn "*cmpxf_i387"
1522 [(set (match_operand:HI 0 "register_operand" "=a")
1525 (match_operand:XF 1 "register_operand" "f")
1526 (match_operand:XF 2 "register_operand" "f"))]
1529 "* return output_fp_compare (insn, operands, false, false);"
1530 [(set_attr "type" "multi")
1531 (set_attr "unit" "i387")
1532 (set_attr "mode" "XF")])
1534 (define_insn_and_split "*cmpxf_cc_i387"
1535 [(set (reg:CCFP FLAGS_REG)
1537 (match_operand:XF 1 "register_operand" "f")
1538 (match_operand:XF 2 "register_operand" "f")))
1539 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1540 "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE"
1542 "&& reload_completed"
1545 [(compare:CCFP (match_dup 1)(match_dup 2))]
1547 (set (reg:CC FLAGS_REG)
1548 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1550 [(set_attr "type" "multi")
1551 (set_attr "unit" "i387")
1552 (set_attr "mode" "XF")])
1554 (define_insn "*cmp<mode>_i387"
1555 [(set (match_operand:HI 0 "register_operand" "=a")
1558 (match_operand:MODEF 1 "register_operand" "f")
1559 (match_operand:MODEF 2 "nonimmediate_operand" "fm"))]
1562 "* return output_fp_compare (insn, operands, false, false);"
1563 [(set_attr "type" "multi")
1564 (set_attr "unit" "i387")
1565 (set_attr "mode" "<MODE>")])
1567 (define_insn_and_split "*cmp<mode>_cc_i387"
1568 [(set (reg:CCFP FLAGS_REG)
1570 (match_operand:MODEF 1 "register_operand" "f")
1571 (match_operand:MODEF 2 "nonimmediate_operand" "fm")))
1572 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1573 "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE"
1575 "&& reload_completed"
1578 [(compare:CCFP (match_dup 1)(match_dup 2))]
1580 (set (reg:CC FLAGS_REG)
1581 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1583 [(set_attr "type" "multi")
1584 (set_attr "unit" "i387")
1585 (set_attr "mode" "<MODE>")])
1587 (define_insn "*cmpu<mode>_i387"
1588 [(set (match_operand:HI 0 "register_operand" "=a")
1591 (match_operand:X87MODEF 1 "register_operand" "f")
1592 (match_operand:X87MODEF 2 "register_operand" "f"))]
1595 "* return output_fp_compare (insn, operands, false, true);"
1596 [(set_attr "type" "multi")
1597 (set_attr "unit" "i387")
1598 (set_attr "mode" "<MODE>")])
1600 (define_insn_and_split "*cmpu<mode>_cc_i387"
1601 [(set (reg:CCFPU FLAGS_REG)
1603 (match_operand:X87MODEF 1 "register_operand" "f")
1604 (match_operand:X87MODEF 2 "register_operand" "f")))
1605 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1606 "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE"
1608 "&& reload_completed"
1611 [(compare:CCFPU (match_dup 1)(match_dup 2))]
1613 (set (reg:CC FLAGS_REG)
1614 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1616 [(set_attr "type" "multi")
1617 (set_attr "unit" "i387")
1618 (set_attr "mode" "<MODE>")])
1620 (define_insn "*cmp<X87MODEF:mode>_<SWI24:mode>_i387"
1621 [(set (match_operand:HI 0 "register_operand" "=a")
1624 (match_operand:X87MODEF 1 "register_operand" "f")
1626 (match_operand:SWI24 2 "memory_operand" "m")))]
1629 && (TARGET_USE_<SWI24:MODE>MODE_FIOP
1630 || optimize_function_for_size_p (cfun))"
1631 "* return output_fp_compare (insn, operands, false, false);"
1632 [(set_attr "type" "multi")
1633 (set_attr "unit" "i387")
1634 (set_attr "fp_int_src" "true")
1635 (set_attr "mode" "<SWI24:MODE>")])
1637 (define_insn_and_split "*cmp<X87MODEF:mode>_<SWI24:mode>_cc_i387"
1638 [(set (reg:CCFP FLAGS_REG)
1640 (match_operand:X87MODEF 1 "register_operand" "f")
1642 (match_operand:SWI24 2 "memory_operand" "m"))))
1643 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1644 "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE
1645 && (TARGET_USE_<SWI24:MODE>MODE_FIOP
1646 || optimize_function_for_size_p (cfun))"
1648 "&& reload_completed"
1653 (float:X87MODEF (match_dup 2)))]
1655 (set (reg:CC FLAGS_REG)
1656 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1658 [(set_attr "type" "multi")
1659 (set_attr "unit" "i387")
1660 (set_attr "fp_int_src" "true")
1661 (set_attr "mode" "<SWI24:MODE>")])
1663 ;; FP compares, step 2
1664 ;; Move the fpsw to ax.
1666 (define_insn "x86_fnstsw_1"
1667 [(set (match_operand:HI 0 "register_operand" "=a")
1668 (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
1671 [(set_attr "length" "2")
1672 (set_attr "mode" "SI")
1673 (set_attr "unit" "i387")])
1675 ;; FP compares, step 3
1676 ;; Get ax into flags, general case.
1678 (define_insn "x86_sahf_1"
1679 [(set (reg:CC FLAGS_REG)
1680 (unspec:CC [(match_operand:HI 0 "register_operand" "a")]
1684 #ifndef HAVE_AS_IX86_SAHF
1686 return ASM_BYTE "0x9e";
1691 [(set_attr "length" "1")
1692 (set_attr "athlon_decode" "vector")
1693 (set_attr "amdfam10_decode" "direct")
1694 (set_attr "bdver1_decode" "direct")
1695 (set_attr "mode" "SI")])
1697 ;; Pentium Pro can do steps 1 through 3 in one go.
1698 ;; (these instructions set flags directly)
1700 (define_mode_iterator FPCMP [CCFP CCFPU])
1701 (define_mode_attr unord [(CCFP "") (CCFPU "u")])
1703 (define_insn "*cmpi<FPCMP:unord><MODEF:mode>"
1704 [(set (reg:FPCMP FLAGS_REG)
1706 (match_operand:MODEF 0 "register_operand" "f,v")
1707 (match_operand:MODEF 1 "register_ssemem_operand" "f,vm")))]
1708 "(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
1709 || (TARGET_80387 && TARGET_CMOVE)"
1711 * return output_fp_compare (insn, operands, true, \
1712 <FPCMP:MODE>mode == CCFPUmode);
1713 %v<FPCMP:unord>comi<MODEF:ssemodesuffix>\t{%1, %0|%0, %1}"
1714 [(set_attr "type" "fcmp,ssecomi")
1715 (set_attr "prefix" "orig,maybe_vex")
1716 (set_attr "mode" "<MODEF:MODE>")
1717 (set_attr "prefix_rep" "*,0")
1718 (set (attr "prefix_data16")
1719 (cond [(eq_attr "alternative" "0")
1721 (eq_attr "mode" "DF")
1724 (const_string "0")))
1725 (set_attr "athlon_decode" "vector")
1726 (set_attr "amdfam10_decode" "direct")
1727 (set_attr "bdver1_decode" "double")
1728 (set_attr "znver1_decode" "double")
1729 (set (attr "enabled")
1731 (match_test ("SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"))
1733 (eq_attr "alternative" "0")
1734 (symbol_ref "TARGET_MIX_SSE_I387")
1735 (symbol_ref "true"))
1737 (eq_attr "alternative" "0")
1739 (symbol_ref "false"))))])
1741 (define_insn "*cmpi<unord>xf_i387"
1742 [(set (reg:FPCMP FLAGS_REG)
1744 (match_operand:XF 0 "register_operand" "f")
1745 (match_operand:XF 1 "register_operand" "f")))]
1746 "TARGET_80387 && TARGET_CMOVE"
1747 "* return output_fp_compare (insn, operands, true,
1748 <MODE>mode == CCFPUmode);"
1749 [(set_attr "type" "fcmp")
1750 (set_attr "mode" "XF")
1751 (set_attr "athlon_decode" "vector")
1752 (set_attr "amdfam10_decode" "direct")
1753 (set_attr "bdver1_decode" "double")
1754 (set_attr "znver1_decode" "double")])
1756 ;; Push/pop instructions.
1758 (define_insn "*push<mode>2"
1759 [(set (match_operand:DWI 0 "push_operand" "=<")
1760 (match_operand:DWI 1 "general_no_elim_operand" "riF*o"))]
1763 [(set_attr "type" "multi")
1764 (set_attr "mode" "<MODE>")])
1767 [(set (match_operand:DWI 0 "push_operand")
1768 (match_operand:DWI 1 "general_gr_operand"))]
1771 "ix86_split_long_move (operands); DONE;")
1773 (define_insn "*pushdi2_rex64"
1774 [(set (match_operand:DI 0 "push_operand" "=<,!<")
1775 (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1780 [(set_attr "type" "push,multi")
1781 (set_attr "mode" "DI")])
1783 ;; Convert impossible pushes of immediate to existing instructions.
1784 ;; First try to get scratch register and go through it. In case this
1785 ;; fails, push sign extended lower part first and then overwrite
1786 ;; upper part by 32bit move.
1788 [(match_scratch:DI 2 "r")
1789 (set (match_operand:DI 0 "push_operand")
1790 (match_operand:DI 1 "immediate_operand"))]
1791 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1792 && !x86_64_immediate_operand (operands[1], DImode)"
1793 [(set (match_dup 2) (match_dup 1))
1794 (set (match_dup 0) (match_dup 2))])
1796 ;; We need to define this as both peepholer and splitter for case
1797 ;; peephole2 pass is not run.
1798 ;; "&& 1" is needed to keep it from matching the previous pattern.
1800 [(set (match_operand:DI 0 "push_operand")
1801 (match_operand:DI 1 "immediate_operand"))]
1802 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1803 && !x86_64_immediate_operand (operands[1], DImode) && 1"
1804 [(set (match_dup 0) (match_dup 1))
1805 (set (match_dup 2) (match_dup 3))]
1807 split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1809 operands[1] = gen_lowpart (DImode, operands[2]);
1810 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (Pmode, stack_pointer_rtx,
1815 [(set (match_operand:DI 0 "push_operand")
1816 (match_operand:DI 1 "immediate_operand"))]
1817 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
1818 ? epilogue_completed : reload_completed)
1819 && !symbolic_operand (operands[1], DImode)
1820 && !x86_64_immediate_operand (operands[1], DImode)"
1821 [(set (match_dup 0) (match_dup 1))
1822 (set (match_dup 2) (match_dup 3))]
1824 split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1826 operands[1] = gen_lowpart (DImode, operands[2]);
1827 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (Pmode, stack_pointer_rtx,
1831 (define_insn "*pushsi2"
1832 [(set (match_operand:SI 0 "push_operand" "=<")
1833 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1836 [(set_attr "type" "push")
1837 (set_attr "mode" "SI")])
1839 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1840 ;; "push a byte/word". But actually we use pushl, which has the effect
1841 ;; of rounding the amount pushed up to a word.
1843 ;; For TARGET_64BIT we always round up to 8 bytes.
1844 (define_insn "*push<mode>2_rex64"
1845 [(set (match_operand:SWI124 0 "push_operand" "=X")
1846 (match_operand:SWI124 1 "nonmemory_no_elim_operand" "r<i>"))]
1849 [(set_attr "type" "push")
1850 (set_attr "mode" "DI")])
1852 (define_insn "*push<mode>2"
1853 [(set (match_operand:SWI12 0 "push_operand" "=X")
1854 (match_operand:SWI12 1 "nonmemory_no_elim_operand" "rn"))]
1857 [(set_attr "type" "push")
1858 (set_attr "mode" "SI")])
1860 (define_insn "*push<mode>2_prologue"
1861 [(set (match_operand:W 0 "push_operand" "=<")
1862 (match_operand:W 1 "general_no_elim_operand" "r<i>*m"))
1863 (clobber (mem:BLK (scratch)))]
1865 "push{<imodesuffix>}\t%1"
1866 [(set_attr "type" "push")
1867 (set_attr "mode" "<MODE>")])
1869 (define_insn "*pop<mode>1"
1870 [(set (match_operand:W 0 "nonimmediate_operand" "=r*m")
1871 (match_operand:W 1 "pop_operand" ">"))]
1873 "pop{<imodesuffix>}\t%0"
1874 [(set_attr "type" "pop")
1875 (set_attr "mode" "<MODE>")])
1877 (define_insn "*pop<mode>1_epilogue"
1878 [(set (match_operand:W 0 "nonimmediate_operand" "=r*m")
1879 (match_operand:W 1 "pop_operand" ">"))
1880 (clobber (mem:BLK (scratch)))]
1882 "pop{<imodesuffix>}\t%0"
1883 [(set_attr "type" "pop")
1884 (set_attr "mode" "<MODE>")])
1886 (define_insn "*pushfl<mode>2"
1887 [(set (match_operand:W 0 "push_operand" "=<")
1888 (match_operand:W 1 "flags_reg_operand"))]
1890 "pushf{<imodesuffix>}"
1891 [(set_attr "type" "push")
1892 (set_attr "mode" "<MODE>")])
1894 (define_insn "*popfl<mode>1"
1895 [(set (match_operand:W 0 "flags_reg_operand")
1896 (match_operand:W 1 "pop_operand" ">"))]
1898 "popf{<imodesuffix>}"
1899 [(set_attr "type" "pop")
1900 (set_attr "mode" "<MODE>")])
1903 ;; Reload patterns to support multi-word load/store
1904 ;; with non-offsetable address.
1905 (define_expand "reload_noff_store"
1906 [(parallel [(match_operand 0 "memory_operand" "=m")
1907 (match_operand 1 "register_operand" "r")
1908 (match_operand:DI 2 "register_operand" "=&r")])]
1911 rtx mem = operands[0];
1912 rtx addr = XEXP (mem, 0);
1914 emit_move_insn (operands[2], addr);
1915 mem = replace_equiv_address_nv (mem, operands[2]);
1917 emit_insn (gen_rtx_SET (mem, operands[1]));
1921 (define_expand "reload_noff_load"
1922 [(parallel [(match_operand 0 "register_operand" "=r")
1923 (match_operand 1 "memory_operand" "m")
1924 (match_operand:DI 2 "register_operand" "=r")])]
1927 rtx mem = operands[1];
1928 rtx addr = XEXP (mem, 0);
1930 emit_move_insn (operands[2], addr);
1931 mem = replace_equiv_address_nv (mem, operands[2]);
1933 emit_insn (gen_rtx_SET (operands[0], mem));
1937 ;; Move instructions.
1939 (define_expand "movxi"
1940 [(set (match_operand:XI 0 "nonimmediate_operand")
1941 (match_operand:XI 1 "general_operand"))]
1943 "ix86_expand_vector_move (XImode, operands); DONE;")
1945 (define_expand "movoi"
1946 [(set (match_operand:OI 0 "nonimmediate_operand")
1947 (match_operand:OI 1 "general_operand"))]
1949 "ix86_expand_vector_move (OImode, operands); DONE;")
1951 (define_expand "movti"
1952 [(set (match_operand:TI 0 "nonimmediate_operand")
1953 (match_operand:TI 1 "general_operand"))]
1954 "TARGET_64BIT || TARGET_SSE"
1957 ix86_expand_move (TImode, operands);
1959 ix86_expand_vector_move (TImode, operands);
1963 ;; This expands to what emit_move_complex would generate if we didn't
1964 ;; have a movti pattern. Having this avoids problems with reload on
1965 ;; 32-bit targets when SSE is present, but doesn't seem to be harmful
1966 ;; to have around all the time.
1967 (define_expand "movcdi"
1968 [(set (match_operand:CDI 0 "nonimmediate_operand")
1969 (match_operand:CDI 1 "general_operand"))]
1972 if (push_operand (operands[0], CDImode))
1973 emit_move_complex_push (CDImode, operands[0], operands[1]);
1975 emit_move_complex_parts (operands[0], operands[1]);
1979 (define_expand "mov<mode>"
1980 [(set (match_operand:SWI1248x 0 "nonimmediate_operand")
1981 (match_operand:SWI1248x 1 "general_operand"))]
1983 "ix86_expand_move (<MODE>mode, operands); DONE;")
1985 (define_insn "*mov<mode>_xor"
1986 [(set (match_operand:SWI48 0 "register_operand" "=r")
1987 (match_operand:SWI48 1 "const0_operand"))
1988 (clobber (reg:CC FLAGS_REG))]
1991 [(set_attr "type" "alu1")
1992 (set_attr "modrm_class" "op0")
1993 (set_attr "mode" "SI")
1994 (set_attr "length_immediate" "0")])
1996 (define_insn "*mov<mode>_or"
1997 [(set (match_operand:SWI48 0 "register_operand" "=r")
1998 (match_operand:SWI48 1 "constm1_operand"))
1999 (clobber (reg:CC FLAGS_REG))]
2001 "or{<imodesuffix>}\t{%1, %0|%0, %1}"
2002 [(set_attr "type" "alu1")
2003 (set_attr "mode" "<MODE>")
2004 (set_attr "length_immediate" "1")])
2006 (define_insn "*movxi_internal_avx512f"
2007 [(set (match_operand:XI 0 "nonimmediate_operand" "=v,v ,v ,m")
2008 (match_operand:XI 1 "nonimmediate_or_sse_const_operand" " C,BC,vm,v"))]
2010 && (register_operand (operands[0], XImode)
2011 || register_operand (operands[1], XImode))"
2013 switch (get_attr_type (insn))
2016 return standard_sse_constant_opcode (insn, operands[1]);
2019 if (misaligned_operand (operands[0], XImode)
2020 || misaligned_operand (operands[1], XImode))
2021 return "vmovdqu32\t{%1, %0|%0, %1}";
2023 return "vmovdqa32\t{%1, %0|%0, %1}";
2029 [(set_attr "type" "sselog1,sselog1,ssemov,ssemov")
2030 (set_attr "prefix" "evex")
2031 (set_attr "mode" "XI")])
2033 (define_insn "*movoi_internal_avx"
2034 [(set (match_operand:OI 0 "nonimmediate_operand" "=v,v ,v ,m")
2035 (match_operand:OI 1 "nonimmediate_or_sse_const_operand" " C,BC,vm,v"))]
2037 && (register_operand (operands[0], OImode)
2038 || register_operand (operands[1], OImode))"
2040 switch (get_attr_type (insn))
2043 return standard_sse_constant_opcode (insn, operands[1]);
2046 if (misaligned_operand (operands[0], OImode)
2047 || misaligned_operand (operands[1], OImode))
2049 if (get_attr_mode (insn) == MODE_V8SF)
2050 return "vmovups\t{%1, %0|%0, %1}";
2051 else if (get_attr_mode (insn) == MODE_XI)
2052 return "vmovdqu32\t{%1, %0|%0, %1}";
2054 return "vmovdqu\t{%1, %0|%0, %1}";
2058 if (get_attr_mode (insn) == MODE_V8SF)
2059 return "vmovaps\t{%1, %0|%0, %1}";
2060 else if (get_attr_mode (insn) == MODE_XI)
2061 return "vmovdqa32\t{%1, %0|%0, %1}";
2063 return "vmovdqa\t{%1, %0|%0, %1}";
2070 [(set_attr "isa" "*,avx2,*,*")
2071 (set_attr "type" "sselog1,sselog1,ssemov,ssemov")
2072 (set_attr "prefix" "vex")
2074 (cond [(ior (match_operand 0 "ext_sse_reg_operand")
2075 (match_operand 1 "ext_sse_reg_operand"))
2077 (and (eq_attr "alternative" "1")
2078 (match_test "TARGET_AVX512VL"))
2080 (ior (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
2081 (and (eq_attr "alternative" "3")
2082 (match_test "TARGET_SSE_TYPELESS_STORES")))
2083 (const_string "V8SF")
2085 (const_string "OI")))])
2087 (define_insn "*movti_internal"
2088 [(set (match_operand:TI 0 "nonimmediate_operand" "=!r ,o ,v,v ,v ,m,?r,?Yd")
2089 (match_operand:TI 1 "general_operand" "riFo,re,C,BC,vm,v,Ye,r"))]
2091 && !(MEM_P (operands[0]) && MEM_P (operands[1])))
2093 && nonimmediate_or_sse_const_operand (operands[1], TImode)
2094 && (register_operand (operands[0], TImode)
2095 || register_operand (operands[1], TImode)))"
2097 switch (get_attr_type (insn))
2103 return standard_sse_constant_opcode (insn, operands[1]);
2106 /* TDmode values are passed as TImode on the stack. Moving them
2107 to stack may result in unaligned memory access. */
2108 if (misaligned_operand (operands[0], TImode)
2109 || misaligned_operand (operands[1], TImode))
2111 if (get_attr_mode (insn) == MODE_V4SF)
2112 return "%vmovups\t{%1, %0|%0, %1}";
2113 else if (get_attr_mode (insn) == MODE_XI)
2114 return "vmovdqu32\t{%1, %0|%0, %1}";
2116 return "%vmovdqu\t{%1, %0|%0, %1}";
2120 if (get_attr_mode (insn) == MODE_V4SF)
2121 return "%vmovaps\t{%1, %0|%0, %1}";
2122 else if (get_attr_mode (insn) == MODE_XI)
2123 return "vmovdqa32\t{%1, %0|%0, %1}";
2125 return "%vmovdqa\t{%1, %0|%0, %1}";
2133 (cond [(eq_attr "alternative" "0,1,6,7")
2134 (const_string "x64")
2135 (eq_attr "alternative" "3")
2136 (const_string "sse2")
2138 (const_string "*")))
2140 (cond [(eq_attr "alternative" "0,1,6,7")
2141 (const_string "multi")
2142 (eq_attr "alternative" "2,3")
2143 (const_string "sselog1")
2145 (const_string "ssemov")))
2146 (set (attr "prefix")
2147 (if_then_else (eq_attr "type" "sselog1,ssemov")
2148 (const_string "maybe_vex")
2149 (const_string "orig")))
2151 (cond [(eq_attr "alternative" "0,1")
2153 (ior (match_operand 0 "ext_sse_reg_operand")
2154 (match_operand 1 "ext_sse_reg_operand"))
2156 (and (eq_attr "alternative" "3")
2157 (match_test "TARGET_AVX512VL"))
2159 (ior (not (match_test "TARGET_SSE2"))
2160 (ior (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
2161 (and (eq_attr "alternative" "5")
2162 (match_test "TARGET_SSE_TYPELESS_STORES"))))
2163 (const_string "V4SF")
2164 (match_test "TARGET_AVX")
2166 (match_test "optimize_function_for_size_p (cfun)")
2167 (const_string "V4SF")
2169 (const_string "TI")))])
2172 [(set (match_operand:TI 0 "sse_reg_operand")
2173 (match_operand:TI 1 "general_reg_operand"))]
2174 "TARGET_64BIT && TARGET_SSE4_1 && TARGET_INTER_UNIT_MOVES_TO_VEC
2175 && reload_completed"
2178 (vec_duplicate:V2DI (match_dup 3))
2182 operands[2] = lowpart_subreg (V2DImode, operands[0], TImode);
2183 operands[3] = gen_highpart (DImode, operands[1]);
2185 emit_move_insn (gen_lowpart (DImode, operands[0]),
2186 gen_lowpart (DImode, operands[1]));
2189 (define_insn "*movdi_internal"
2190 [(set (match_operand:DI 0 "nonimmediate_operand"
2191 "=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")
2192 (match_operand:DI 1 "general_operand"
2193 "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"))]
2194 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2196 switch (get_attr_type (insn))
2199 return "kmovq\t{%1, %0|%0, %1}";
2205 return "pxor\t%0, %0";
2208 /* Handle broken assemblers that require movd instead of movq. */
2209 if (!HAVE_AS_IX86_INTERUNIT_MOVQ
2210 && (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1])))
2211 return "movd\t{%1, %0|%0, %1}";
2212 return "movq\t{%1, %0|%0, %1}";
2215 return standard_sse_constant_opcode (insn, operands[1]);
2218 switch (get_attr_mode (insn))
2221 /* Handle broken assemblers that require movd instead of movq. */
2222 if (!HAVE_AS_IX86_INTERUNIT_MOVQ
2223 && (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1])))
2224 return "%vmovd\t{%1, %0|%0, %1}";
2225 return "%vmovq\t{%1, %0|%0, %1}";
2227 return "%vmovdqa\t{%1, %0|%0, %1}";
2229 return "vmovdqa64\t{%g1, %g0|%g0, %g1}";
2232 gcc_assert (!TARGET_AVX);
2233 return "movlps\t{%1, %0|%0, %1}";
2235 return "%vmovaps\t{%1, %0|%0, %1}";
2242 if (SSE_REG_P (operands[0]))
2243 return "movq2dq\t{%1, %0|%0, %1}";
2245 return "movdq2q\t{%1, %0|%0, %1}";
2248 return "lea{q}\t{%E1, %0|%0, %E1}";
2251 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2252 if (get_attr_mode (insn) == MODE_SI)
2253 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2254 else if (which_alternative == 4)
2255 return "movabs{q}\t{%1, %0|%0, %1}";
2256 else if (ix86_use_lea_for_mov (insn, operands))
2257 return "lea{q}\t{%E1, %0|%0, %E1}";
2259 return "mov{q}\t{%1, %0|%0, %1}";
2266 (cond [(eq_attr "alternative" "0,1,17,18")
2267 (const_string "nox64")
2268 (eq_attr "alternative" "2,3,4,5,10,11,19,20,23,25")
2269 (const_string "x64")
2271 (const_string "*")))
2273 (cond [(eq_attr "alternative" "0,1,17,18")
2274 (const_string "multi")
2275 (eq_attr "alternative" "6")
2276 (const_string "mmx")
2277 (eq_attr "alternative" "7,8,9,10,11")
2278 (const_string "mmxmov")
2279 (eq_attr "alternative" "12")
2280 (const_string "sselog1")
2281 (eq_attr "alternative" "13,14,15,16,19,20")
2282 (const_string "ssemov")
2283 (eq_attr "alternative" "21,22")
2284 (const_string "ssecvt")
2285 (eq_attr "alternative" "23,24,25,26")
2286 (const_string "mskmov")
2287 (and (match_operand 0 "register_operand")
2288 (match_operand 1 "pic_32bit_operand"))
2289 (const_string "lea")
2291 (const_string "imov")))
2294 (and (eq_attr "alternative" "4") (eq_attr "type" "imov"))
2296 (const_string "*")))
2297 (set (attr "length_immediate")
2299 (and (eq_attr "alternative" "4") (eq_attr "type" "imov"))
2301 (const_string "*")))
2302 (set (attr "prefix_rex")
2304 (eq_attr "alternative" "10,11,19,20")
2306 (const_string "*")))
2307 (set (attr "prefix")
2308 (if_then_else (eq_attr "type" "sselog1,ssemov")
2309 (const_string "maybe_vex")
2310 (const_string "orig")))
2311 (set (attr "prefix_data16")
2312 (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "DI"))
2314 (const_string "*")))
2316 (cond [(eq_attr "alternative" "2")
2318 (eq_attr "alternative" "12,13")
2319 (cond [(ior (match_operand 0 "ext_sse_reg_operand")
2320 (match_operand 1 "ext_sse_reg_operand"))
2322 (ior (not (match_test "TARGET_SSE2"))
2323 (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL"))
2324 (const_string "V4SF")
2325 (match_test "TARGET_AVX")
2327 (match_test "optimize_function_for_size_p (cfun)")
2328 (const_string "V4SF")
2330 (const_string "TI"))
2332 (and (eq_attr "alternative" "14,15,16")
2333 (not (match_test "TARGET_SSE2")))
2334 (const_string "V2SF")
2336 (const_string "DI")))
2337 (set (attr "enabled")
2338 (cond [(eq_attr "alternative" "15")
2340 (match_test "TARGET_STV && TARGET_SSE2")
2341 (symbol_ref "false")
2343 (eq_attr "alternative" "16")
2345 (match_test "TARGET_STV && TARGET_SSE2")
2347 (symbol_ref "false"))
2349 (const_string "*")))])
2352 [(set (match_operand:<DWI> 0 "general_reg_operand")
2353 (match_operand:<DWI> 1 "sse_reg_operand"))]
2354 "TARGET_SSE4_1 && TARGET_INTER_UNIT_MOVES_FROM_VEC
2355 && reload_completed"
2359 (parallel [(const_int 1)])))]
2361 operands[2] = gen_highpart (<MODE>mode, operands[0]);
2362 operands[3] = lowpart_subreg (<ssevecmode>mode, operands[1], <DWI>mode);
2364 emit_move_insn (gen_lowpart (<MODE>mode, operands[0]),
2365 gen_lowpart (<MODE>mode, operands[1]));
2369 [(set (match_operand:DWI 0 "nonimmediate_gr_operand")
2370 (match_operand:DWI 1 "general_gr_operand"))]
2373 "ix86_split_long_move (operands); DONE;")
2376 [(set (match_operand:DI 0 "sse_reg_operand")
2377 (match_operand:DI 1 "general_reg_operand"))]
2378 "!TARGET_64BIT && TARGET_SSE4_1 && TARGET_INTER_UNIT_MOVES_TO_VEC
2379 && reload_completed"
2382 (vec_duplicate:V4SI (match_dup 3))
2386 operands[2] = lowpart_subreg (V4SImode, operands[0], DImode);
2387 operands[3] = gen_highpart (SImode, operands[1]);
2389 emit_move_insn (gen_lowpart (SImode, operands[0]),
2390 gen_lowpart (SImode, operands[1]));
2393 ;; movabsq $0x0012345678000000, %rax is longer
2394 ;; than movl $0x12345678, %eax; shlq $24, %rax.
2396 [(set (match_operand:DI 0 "register_operand")
2397 (match_operand:DI 1 "const_int_operand"))]
2399 && optimize_insn_for_size_p ()
2400 && LEGACY_INT_REG_P (operands[0])
2401 && !x86_64_immediate_operand (operands[1], DImode)
2402 && !x86_64_zext_immediate_operand (operands[1], DImode)
2403 && !((UINTVAL (operands[1]) >> ctz_hwi (UINTVAL (operands[1])))
2404 & ~(HOST_WIDE_INT) 0xffffffff)
2405 && peep2_regno_dead_p (0, FLAGS_REG)"
2406 [(set (match_dup 0) (match_dup 1))
2407 (parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
2408 (clobber (reg:CC FLAGS_REG))])]
2410 int shift = ctz_hwi (UINTVAL (operands[1]));
2411 operands[1] = gen_int_mode (UINTVAL (operands[1]) >> shift, DImode);
2412 operands[2] = gen_int_mode (shift, QImode);
2415 (define_insn "*movsi_internal"
2416 [(set (match_operand:SI 0 "nonimmediate_operand"
2417 "=r,m ,*y,*y,?*y,?m,?r ,?*Ym,*v,*v,*v,m ,?r ,?*Yi,*k,*k ,*rm")
2418 (match_operand:SI 1 "general_operand"
2419 "g ,re,C ,*y,m ,*y,*Yn,r ,C ,*v,m ,*v,*Yj,r ,*r,*km,*k"))]
2420 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2422 switch (get_attr_type (insn))
2425 return standard_sse_constant_opcode (insn, operands[1]);
2428 return "kmovd\t{%1, %0|%0, %1}";
2431 switch (get_attr_mode (insn))
2434 return "%vmovd\t{%1, %0|%0, %1}";
2436 return "%vmovdqa\t{%1, %0|%0, %1}";
2438 return "vmovdqa32\t{%g1, %g0|%g0, %g1}";
2441 return "%vmovaps\t{%1, %0|%0, %1}";
2444 gcc_assert (!TARGET_AVX);
2445 return "movss\t{%1, %0|%0, %1}";
2452 return "pxor\t%0, %0";
2455 switch (get_attr_mode (insn))
2458 return "movq\t{%1, %0|%0, %1}";
2460 return "movd\t{%1, %0|%0, %1}";
2467 return "lea{l}\t{%E1, %0|%0, %E1}";
2470 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2471 if (ix86_use_lea_for_mov (insn, operands))
2472 return "lea{l}\t{%E1, %0|%0, %E1}";
2474 return "mov{l}\t{%1, %0|%0, %1}";
2481 (cond [(eq_attr "alternative" "2")
2482 (const_string "mmx")
2483 (eq_attr "alternative" "3,4,5,6,7")
2484 (const_string "mmxmov")
2485 (eq_attr "alternative" "8")
2486 (const_string "sselog1")
2487 (eq_attr "alternative" "9,10,11,12,13")
2488 (const_string "ssemov")
2489 (eq_attr "alternative" "14,15,16")
2490 (const_string "mskmov")
2491 (and (match_operand 0 "register_operand")
2492 (match_operand 1 "pic_32bit_operand"))
2493 (const_string "lea")
2495 (const_string "imov")))
2496 (set (attr "prefix")
2497 (if_then_else (eq_attr "type" "sselog1,ssemov")
2498 (const_string "maybe_vex")
2499 (const_string "orig")))
2500 (set (attr "prefix_data16")
2501 (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
2503 (const_string "*")))
2505 (cond [(eq_attr "alternative" "2,3")
2507 (eq_attr "alternative" "8,9")
2508 (cond [(ior (match_operand 0 "ext_sse_reg_operand")
2509 (match_operand 1 "ext_sse_reg_operand"))
2511 (ior (not (match_test "TARGET_SSE2"))
2512 (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL"))
2513 (const_string "V4SF")
2514 (match_test "TARGET_AVX")
2516 (match_test "optimize_function_for_size_p (cfun)")
2517 (const_string "V4SF")
2519 (const_string "TI"))
2521 (and (eq_attr "alternative" "10,11")
2522 (not (match_test "TARGET_SSE2")))
2525 (const_string "SI")))])
2527 (define_insn "*movhi_internal"
2528 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r ,r ,m ,k,k ,r,m")
2529 (match_operand:HI 1 "general_operand" "r ,rn,rm,rn,r,km,k,k"))]
2530 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2532 switch (get_attr_type (insn))
2535 /* movzwl is faster than movw on p2 due to partial word stalls,
2536 though not as fast as an aligned movl. */
2537 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
2540 switch (which_alternative)
2543 return "kmovw\t{%k1, %0|%0, %k1}";
2545 return "kmovw\t{%1, %k0|%k0, %1}";
2548 return "kmovw\t{%1, %0|%0, %1}";
2554 if (get_attr_mode (insn) == MODE_SI)
2555 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2557 return "mov{w}\t{%1, %0|%0, %1}";
2561 (cond [(eq_attr "alternative" "4,5,6,7")
2562 (const_string "mskmov")
2563 (match_test "optimize_function_for_size_p (cfun)")
2564 (const_string "imov")
2565 (and (eq_attr "alternative" "0")
2566 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2567 (not (match_test "TARGET_HIMODE_MATH"))))
2568 (const_string "imov")
2569 (and (eq_attr "alternative" "1,2")
2570 (match_operand:HI 1 "aligned_operand"))
2571 (const_string "imov")
2572 (and (match_test "TARGET_MOVX")
2573 (eq_attr "alternative" "0,2"))
2574 (const_string "imovx")
2576 (const_string "imov")))
2577 (set (attr "prefix")
2578 (if_then_else (eq_attr "alternative" "4,5,6,7")
2579 (const_string "vex")
2580 (const_string "orig")))
2582 (cond [(eq_attr "type" "imovx")
2584 (and (eq_attr "alternative" "1,2")
2585 (match_operand:HI 1 "aligned_operand"))
2587 (and (eq_attr "alternative" "0")
2588 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2589 (not (match_test "TARGET_HIMODE_MATH"))))
2592 (const_string "HI")))])
2594 ;; Situation is quite tricky about when to choose full sized (SImode) move
2595 ;; over QImode moves. For Q_REG -> Q_REG move we use full size only for
2596 ;; partial register dependency machines (such as AMD Athlon), where QImode
2597 ;; moves issue extra dependency and for partial register stalls machines
2598 ;; that don't use QImode patterns (and QImode move cause stall on the next
2601 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
2602 ;; register stall machines with, where we use QImode instructions, since
2603 ;; partial register stall can be caused there. Then we use movzx.
2605 (define_insn "*movqi_internal"
2606 [(set (match_operand:QI 0 "nonimmediate_operand"
2607 "=Q,R,r,q,q,r,r ,?r,m ,k,k,r,m,k")
2608 (match_operand:QI 1 "general_operand"
2609 "Q ,R,r,n,m,q,rn, m,qn,r,k,k,k,m"))]
2610 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2612 static char buf[128];
2616 switch (get_attr_type (insn))
2619 gcc_assert (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]));
2620 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
2623 switch (which_alternative)
2626 ops = "kmov%s\t{%%k1, %%0|%%0, %%k1}";
2629 ops = "kmov%s\t{%%1, %%k0|%%k0, %%1}";
2633 gcc_assert (TARGET_AVX512DQ);
2636 ops = "kmov%s\t{%%1, %%0|%%0, %%1}";
2642 suffix = (get_attr_mode (insn) == MODE_HI) ? "w" : "b";
2644 snprintf (buf, sizeof (buf), ops, suffix);
2648 if (get_attr_mode (insn) == MODE_SI)
2649 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2651 return "mov{b}\t{%1, %0|%0, %1}";
2655 (cond [(eq_attr "alternative" "1,2")
2656 (const_string "x64")
2657 (eq_attr "alternative" "12,13")
2658 (const_string "avx512dq")
2660 (const_string "*")))
2662 (cond [(eq_attr "alternative" "9,10,11,12,13")
2663 (const_string "mskmov")
2664 (and (eq_attr "alternative" "7")
2665 (not (match_operand:QI 1 "aligned_operand")))
2666 (const_string "imovx")
2667 (match_test "optimize_function_for_size_p (cfun)")
2668 (const_string "imov")
2669 (and (eq_attr "alternative" "5")
2670 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2671 (not (match_test "TARGET_QIMODE_MATH"))))
2672 (const_string "imov")
2673 (eq_attr "alternative" "5,7")
2674 (const_string "imovx")
2675 (and (match_test "TARGET_MOVX")
2676 (eq_attr "alternative" "4"))
2677 (const_string "imovx")
2679 (const_string "imov")))
2680 (set (attr "prefix")
2681 (if_then_else (eq_attr "alternative" "9,10,11")
2682 (const_string "vex")
2683 (const_string "orig")))
2685 (cond [(eq_attr "alternative" "5,6,7")
2687 (eq_attr "alternative" "8")
2689 (and (eq_attr "alternative" "9,10,11")
2690 (not (match_test "TARGET_AVX512DQ")))
2692 (eq_attr "type" "imovx")
2694 ;; For -Os, 8-bit immediates are always shorter than 32-bit
2696 (and (eq_attr "type" "imov")
2697 (and (eq_attr "alternative" "3")
2698 (match_test "optimize_function_for_size_p (cfun)")))
2700 ;; For -Os, movl where one or both operands are NON_Q_REGS
2701 ;; and both are LEGACY_REGS is shorter than movb.
2702 ;; Otherwise movb and movl sizes are the same, so decide purely
2703 ;; based on speed factors.
2704 (and (eq_attr "type" "imov")
2705 (and (eq_attr "alternative" "1")
2706 (match_test "optimize_function_for_size_p (cfun)")))
2708 (and (eq_attr "type" "imov")
2709 (and (eq_attr "alternative" "0,1,2,3")
2710 (and (match_test "TARGET_PARTIAL_REG_DEPENDENCY")
2711 (not (match_test "TARGET_PARTIAL_REG_STALL")))))
2713 ;; Avoid partial register stalls when not using QImode arithmetic
2714 (and (eq_attr "type" "imov")
2715 (and (eq_attr "alternative" "0,1,2,3")
2716 (and (match_test "TARGET_PARTIAL_REG_STALL")
2717 (not (match_test "TARGET_QIMODE_MATH")))))
2720 (const_string "QI")))])
2722 ;; Stores and loads of ax to arbitrary constant address.
2723 ;; We fake an second form of instruction to force reload to load address
2724 ;; into register when rax is not available
2725 (define_insn "*movabs<mode>_1"
2726 [(set (mem:SWI1248x (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2727 (match_operand:SWI1248x 1 "nonmemory_operand" "a,r<i>"))]
2728 "TARGET_LP64 && ix86_check_movabs (insn, 0)"
2730 /* Recover the full memory rtx. */
2731 operands[0] = SET_DEST (PATTERN (insn));
2732 switch (which_alternative)
2735 return "movabs{<imodesuffix>}\t{%1, %P0|<iptrsize> PTR [%P0], %1}";
2737 return "mov{<imodesuffix>}\t{%1, %0|%0, %1}";
2742 [(set_attr "type" "imov")
2743 (set_attr "modrm" "0,*")
2744 (set_attr "length_address" "8,0")
2745 (set_attr "length_immediate" "0,*")
2746 (set_attr "memory" "store")
2747 (set_attr "mode" "<MODE>")])
2749 (define_insn "*movabs<mode>_2"
2750 [(set (match_operand:SWI1248x 0 "register_operand" "=a,r")
2751 (mem:SWI1248x (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2752 "TARGET_LP64 && ix86_check_movabs (insn, 1)"
2754 /* Recover the full memory rtx. */
2755 operands[1] = SET_SRC (PATTERN (insn));
2756 switch (which_alternative)
2759 return "movabs{<imodesuffix>}\t{%P1, %0|%0, <iptrsize> PTR [%P1]}";
2761 return "mov{<imodesuffix>}\t{%1, %0|%0, %1}";
2766 [(set_attr "type" "imov")
2767 (set_attr "modrm" "0,*")
2768 (set_attr "length_address" "8,0")
2769 (set_attr "length_immediate" "0")
2770 (set_attr "memory" "load")
2771 (set_attr "mode" "<MODE>")])
2773 (define_insn "*swap<mode>"
2774 [(set (match_operand:SWI48 0 "register_operand" "+r")
2775 (match_operand:SWI48 1 "register_operand" "+r"))
2779 "xchg{<imodesuffix>}\t%1, %0"
2780 [(set_attr "type" "imov")
2781 (set_attr "mode" "<MODE>")
2782 (set_attr "pent_pair" "np")
2783 (set_attr "athlon_decode" "vector")
2784 (set_attr "amdfam10_decode" "double")
2785 (set_attr "bdver1_decode" "double")])
2787 (define_insn "*swap<mode>"
2788 [(set (match_operand:SWI12 0 "register_operand" "+<r>,r")
2789 (match_operand:SWI12 1 "register_operand" "+<r>,r"))
2794 xchg{<imodesuffix>}\t%1, %0
2796 [(set_attr "type" "imov")
2797 (set_attr "mode" "<MODE>,SI")
2798 (set (attr "preferred_for_size")
2799 (cond [(eq_attr "alternative" "0")
2800 (symbol_ref "false")]
2801 (symbol_ref "true")))
2802 ;; Potential partial reg stall on alternative 1.
2803 (set (attr "preferred_for_speed")
2804 (cond [(eq_attr "alternative" "1")
2805 (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
2806 (symbol_ref "true")))
2807 (set_attr "pent_pair" "np")
2808 (set_attr "athlon_decode" "vector")
2809 (set_attr "amdfam10_decode" "double")
2810 (set_attr "bdver1_decode" "double")])
2812 (define_expand "movstrict<mode>"
2813 [(set (strict_low_part (match_operand:SWI12 0 "nonimmediate_operand"))
2814 (match_operand:SWI12 1 "general_operand"))]
2817 if (TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun))
2819 if (SUBREG_P (operands[0])
2820 && GET_MODE_CLASS (GET_MODE (SUBREG_REG (operands[0]))) != MODE_INT)
2822 /* Don't generate memory->memory moves, go through a register */
2823 if (MEM_P (operands[0]) && MEM_P (operands[1]))
2824 operands[1] = force_reg (<MODE>mode, operands[1]);
2827 (define_insn "*movstrict<mode>_1"
2828 [(set (strict_low_part
2829 (match_operand:SWI12 0 "nonimmediate_operand" "+<r>m,<r>"))
2830 (match_operand:SWI12 1 "general_operand" "<r>n,m"))]
2831 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
2832 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2833 "mov{<imodesuffix>}\t{%1, %0|%0, %1}"
2834 [(set_attr "type" "imov")
2835 (set_attr "mode" "<MODE>")])
2837 (define_insn "*movstrict<mode>_xor"
2838 [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>"))
2839 (match_operand:SWI12 1 "const0_operand"))
2840 (clobber (reg:CC FLAGS_REG))]
2842 "xor{<imodesuffix>}\t%0, %0"
2843 [(set_attr "type" "alu1")
2844 (set_attr "modrm_class" "op0")
2845 (set_attr "mode" "<MODE>")
2846 (set_attr "length_immediate" "0")])
2848 (define_expand "extv<mode>"
2849 [(set (match_operand:SWI24 0 "register_operand")
2850 (sign_extract:SWI24 (match_operand:SWI24 1 "register_operand")
2851 (match_operand:SI 2 "const_int_operand")
2852 (match_operand:SI 3 "const_int_operand")))]
2855 /* Handle extractions from %ah et al. */
2856 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
2859 unsigned int regno = reg_or_subregno (operands[1]);
2861 /* Be careful to expand only with registers having upper parts. */
2862 if (regno <= LAST_VIRTUAL_REGISTER && !QI_REGNO_P (regno))
2863 operands[1] = copy_to_reg (operands[1]);
2866 (define_insn "*extv<mode>"
2867 [(set (match_operand:SWI24 0 "register_operand" "=R")
2868 (sign_extract:SWI24 (match_operand 1 "ext_register_operand" "Q")
2872 "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
2873 [(set_attr "type" "imovx")
2874 (set_attr "mode" "SI")])
2876 (define_expand "extzv<mode>"
2877 [(set (match_operand:SWI248 0 "register_operand")
2878 (zero_extract:SWI248 (match_operand:SWI248 1 "register_operand")
2879 (match_operand:SI 2 "const_int_operand")
2880 (match_operand:SI 3 "const_int_operand")))]
2883 if (ix86_expand_pextr (operands))
2886 /* Handle extractions from %ah et al. */
2887 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
2890 unsigned int regno = reg_or_subregno (operands[1]);
2892 /* Be careful to expand only with registers having upper parts. */
2893 if (regno <= LAST_VIRTUAL_REGISTER && !QI_REGNO_P (regno))
2894 operands[1] = copy_to_reg (operands[1]);
2897 (define_insn "*extzvqi_mem_rex64"
2898 [(set (match_operand:QI 0 "norex_memory_operand" "=Bn")
2900 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q")
2903 "TARGET_64BIT && reload_completed"
2904 "mov{b}\t{%h1, %0|%0, %h1}"
2905 [(set_attr "type" "imov")
2906 (set_attr "mode" "QI")])
2908 (define_insn "*extzv<mode>"
2909 [(set (match_operand:SWI248 0 "register_operand" "=R")
2910 (zero_extract:SWI248 (match_operand 1 "ext_register_operand" "Q")
2914 "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
2915 [(set_attr "type" "imovx")
2916 (set_attr "mode" "SI")])
2918 (define_insn "*extzvqi"
2919 [(set (match_operand:QI 0 "nonimmediate_operand" "=QBc,?R,m")
2921 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q,Q")
2926 switch (get_attr_type (insn))
2929 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2931 return "mov{b}\t{%h1, %0|%0, %h1}";
2934 [(set_attr "isa" "*,*,nox64")
2936 (if_then_else (and (match_operand:QI 0 "register_operand")
2937 (ior (not (match_operand:QI 0 "QIreg_operand"))
2938 (match_test "TARGET_MOVX")))
2939 (const_string "imovx")
2940 (const_string "imov")))
2942 (if_then_else (eq_attr "type" "imovx")
2944 (const_string "QI")))])
2947 [(set (match_operand:QI 0 "register_operand")
2949 (zero_extract:SI (match_operand 1 "ext_register_operand")
2952 (set (match_operand:QI 2 "norex_memory_operand") (match_dup 0))]
2954 && peep2_reg_dead_p (2, operands[0])"
2957 (zero_extract:SI (match_dup 1)
2959 (const_int 8)) 0))])
2961 (define_expand "insv<mode>"
2962 [(set (zero_extract:SWI248 (match_operand:SWI248 0 "register_operand")
2963 (match_operand:SI 1 "const_int_operand")
2964 (match_operand:SI 2 "const_int_operand"))
2965 (match_operand:SWI248 3 "register_operand"))]
2970 if (ix86_expand_pinsr (operands))
2973 /* Handle insertions to %ah et al. */
2974 if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
2977 unsigned int regno = reg_or_subregno (operands[0]);
2979 /* Be careful to expand only with registers having upper parts. */
2980 if (regno <= LAST_VIRTUAL_REGISTER && !QI_REGNO_P (regno))
2981 dst = copy_to_reg (operands[0]);
2985 emit_insn (gen_insv<mode>_1 (dst, operands[3]));
2987 /* Fix up the destination if needed. */
2988 if (dst != operands[0])
2989 emit_move_insn (operands[0], dst);
2994 (define_insn "*insvqi_1_mem_rex64"
2995 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2999 (match_operand:QI 1 "norex_memory_operand" "Bn") 0))]
3000 "TARGET_64BIT && reload_completed"
3001 "mov{b}\t{%1, %h0|%h0, %1}"
3002 [(set_attr "type" "imov")
3003 (set_attr "mode" "QI")])
3005 (define_insn "insv<mode>_1"
3006 [(set (zero_extract:SWI248 (match_operand 0 "ext_register_operand" "+Q,Q")
3009 (match_operand:SWI248 1 "general_operand" "QnBc,m"))]
3012 if (CONST_INT_P (operands[1]))
3013 operands[1] = gen_int_mode (INTVAL (operands[1]), QImode);
3014 return "mov{b}\t{%b1, %h0|%h0, %b1}";
3016 [(set_attr "isa" "*,nox64")
3017 (set_attr "type" "imov")
3018 (set_attr "mode" "QI")])
3020 (define_insn "*insvqi_1"
3021 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q,Q")
3025 (match_operand:QI 1 "general_operand" "QnBc,m") 0))]
3027 "mov{b}\t{%1, %h0|%h0, %1}"
3028 [(set_attr "isa" "*,nox64")
3029 (set_attr "type" "imov")
3030 (set_attr "mode" "QI")])
3033 [(set (match_operand:QI 0 "register_operand")
3034 (match_operand:QI 1 "norex_memory_operand"))
3035 (set (zero_extract:SI (match_operand 2 "ext_register_operand")
3038 (subreg:SI (match_dup 0) 0))]
3040 && peep2_reg_dead_p (2, operands[0])"
3041 [(set (zero_extract:SI (match_dup 2)
3044 (subreg:SI (match_dup 1) 0))])
3046 (define_code_iterator any_extract [sign_extract zero_extract])
3048 (define_insn "*insvqi_2"
3049 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
3052 (any_extract:SI (match_operand 1 "ext_register_operand" "Q")
3056 "mov{b}\t{%h1, %h0|%h0, %h1}"
3057 [(set_attr "type" "imov")
3058 (set_attr "mode" "QI")])
3060 (define_insn "*insvqi_3"
3061 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
3064 (any_shiftrt:SI (match_operand:SI 1 "register_operand" "Q")
3067 "mov{b}\t{%h1, %h0|%h0, %h1}"
3068 [(set_attr "type" "imov")
3069 (set_attr "mode" "QI")])
3071 ;; Floating point push instructions.
3073 (define_insn "*pushtf"
3074 [(set (match_operand:TF 0 "push_operand" "=<,<")
3075 (match_operand:TF 1 "general_no_elim_operand" "v,*roC"))]
3076 "TARGET_64BIT || TARGET_SSE"
3078 /* This insn should be already split before reg-stack. */
3081 [(set_attr "isa" "*,x64")
3082 (set_attr "type" "multi")
3083 (set_attr "unit" "sse,*")
3084 (set_attr "mode" "TF,DI")])
3086 ;; %%% Kill this when call knows how to work this out.
3088 [(set (match_operand:TF 0 "push_operand")
3089 (match_operand:TF 1 "sse_reg_operand"))]
3090 "TARGET_SSE && reload_completed"
3091 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -16)))
3092 (set (match_dup 0) (match_dup 1))]
3094 /* Preserve memory attributes. */
3095 operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
3098 (define_insn_and_split "*pushxf_rounded"
3102 (plus:P (reg:P SP_REG) (const_int -16))))
3103 (match_operand:XF 0 "nonmemory_no_elim_operand" "f,r,*r,C"))]
3107 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -16)))
3108 (set (match_dup 1) (match_dup 0))]
3110 rtx pat = PATTERN (curr_insn);
3111 operands[1] = SET_DEST (pat);
3113 /* Preserve memory attributes. */
3114 operands[1] = replace_equiv_address (operands[1], stack_pointer_rtx);
3116 [(set_attr "type" "multi")
3117 (set_attr "unit" "i387,*,*,*")
3119 (cond [(eq_attr "alternative" "1,2,3")
3122 (const_string "XF")))
3123 (set (attr "preferred_for_size")
3124 (cond [(eq_attr "alternative" "1")
3125 (symbol_ref "false")]
3126 (symbol_ref "true")))])
3128 (define_insn "*pushxf"
3129 [(set (match_operand:XF 0 "push_operand" "=<,<,<,<,<")
3130 (match_operand:XF 1 "general_no_elim_operand" "f,r,*r,oF,oC"))]
3133 /* This insn should be already split before reg-stack. */
3136 [(set_attr "isa" "*,*,*,nox64,x64")
3137 (set_attr "type" "multi")
3138 (set_attr "unit" "i387,*,*,*,*")
3140 (cond [(eq_attr "alternative" "1,2,3,4")
3141 (if_then_else (match_test "TARGET_64BIT")
3143 (const_string "SI"))
3145 (const_string "XF")))
3146 (set (attr "preferred_for_size")
3147 (cond [(eq_attr "alternative" "1")
3148 (symbol_ref "false")]
3149 (symbol_ref "true")))])
3151 ;; %%% Kill this when call knows how to work this out.
3153 [(set (match_operand:XF 0 "push_operand")
3154 (match_operand:XF 1 "fp_register_operand"))]
3156 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
3157 (set (match_dup 0) (match_dup 1))]
3159 operands[2] = GEN_INT (-PUSH_ROUNDING (GET_MODE_SIZE (XFmode)));
3160 /* Preserve memory attributes. */
3161 operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
3164 (define_insn "*pushdf"
3165 [(set (match_operand:DF 0 "push_operand" "=<,<,<,<,<,<")
3166 (match_operand:DF 1 "general_no_elim_operand" "f,r,*r,oF,rmC,x"))]
3169 /* This insn should be already split before reg-stack. */
3172 [(set_attr "isa" "*,nox64,nox64,nox64,x64,sse2")
3173 (set_attr "type" "multi")
3174 (set_attr "unit" "i387,*,*,*,*,sse")
3175 (set_attr "mode" "DF,SI,SI,SI,DI,DF")
3176 (set (attr "preferred_for_size")
3177 (cond [(eq_attr "alternative" "1")
3178 (symbol_ref "false")]
3179 (symbol_ref "true")))
3180 (set (attr "preferred_for_speed")
3181 (cond [(eq_attr "alternative" "1")
3182 (symbol_ref "TARGET_INTEGER_DFMODE_MOVES")]
3183 (symbol_ref "true")))])
3185 ;; %%% Kill this when call knows how to work this out.
3187 [(set (match_operand:DF 0 "push_operand")
3188 (match_operand:DF 1 "any_fp_register_operand"))]
3190 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
3191 (set (match_dup 0) (match_dup 1))]
3193 /* Preserve memory attributes. */
3194 operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
3197 (define_insn "*pushsf_rex64"
3198 [(set (match_operand:SF 0 "push_operand" "=X,X,X")
3199 (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
3202 /* Anything else should be already split before reg-stack. */
3203 gcc_assert (which_alternative == 1);
3204 return "push{q}\t%q1";
3206 [(set_attr "type" "multi,push,multi")
3207 (set_attr "unit" "i387,*,*")
3208 (set_attr "mode" "SF,DI,SF")])
3210 (define_insn "*pushsf"
3211 [(set (match_operand:SF 0 "push_operand" "=<,<,<")
3212 (match_operand:SF 1 "general_no_elim_operand" "f,rmF,x"))]
3215 /* Anything else should be already split before reg-stack. */
3216 gcc_assert (which_alternative == 1);
3217 return "push{l}\t%1";
3219 [(set_attr "type" "multi,push,multi")
3220 (set_attr "unit" "i387,*,*")
3221 (set_attr "mode" "SF,SI,SF")])
3223 ;; %%% Kill this when call knows how to work this out.
3225 [(set (match_operand:SF 0 "push_operand")
3226 (match_operand:SF 1 "any_fp_register_operand"))]
3228 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
3229 (set (match_dup 0) (match_dup 1))]
3231 rtx op = XEXP (operands[0], 0);
3232 if (GET_CODE (op) == PRE_DEC)
3234 gcc_assert (!TARGET_64BIT);
3239 op = XEXP (XEXP (op, 1), 1);
3240 gcc_assert (CONST_INT_P (op));
3243 /* Preserve memory attributes. */
3244 operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
3248 [(set (match_operand:SF 0 "push_operand")
3249 (match_operand:SF 1 "memory_operand"))]
3251 && find_constant_src (insn)"
3252 [(set (match_dup 0) (match_dup 2))]
3253 "operands[2] = find_constant_src (curr_insn);")
3256 [(set (match_operand 0 "push_operand")
3257 (match_operand 1 "general_gr_operand"))]
3259 && (GET_MODE (operands[0]) == TFmode
3260 || GET_MODE (operands[0]) == XFmode
3261 || GET_MODE (operands[0]) == DFmode)"
3263 "ix86_split_long_move (operands); DONE;")
3265 ;; Floating point move instructions.
3267 (define_expand "movtf"
3268 [(set (match_operand:TF 0 "nonimmediate_operand")
3269 (match_operand:TF 1 "nonimmediate_operand"))]
3270 "TARGET_64BIT || TARGET_SSE"
3271 "ix86_expand_move (TFmode, operands); DONE;")
3273 (define_expand "mov<mode>"
3274 [(set (match_operand:X87MODEF 0 "nonimmediate_operand")
3275 (match_operand:X87MODEF 1 "general_operand"))]
3277 "ix86_expand_move (<MODE>mode, operands); DONE;")
3279 (define_insn "*movtf_internal"
3280 [(set (match_operand:TF 0 "nonimmediate_operand" "=v,v ,m,?*r ,!o")
3281 (match_operand:TF 1 "general_operand" "C ,vm,v,*roF,*rC"))]
3282 "(TARGET_64BIT || TARGET_SSE)
3283 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3284 && (lra_in_progress || reload_completed
3285 || !CONST_DOUBLE_P (operands[1])
3286 || ((optimize_function_for_size_p (cfun)
3287 || (ix86_cmodel == CM_LARGE || ix86_cmodel == CM_LARGE_PIC))
3288 && standard_sse_constant_p (operands[1], TFmode) == 1
3289 && !memory_operand (operands[0], TFmode))
3290 || (!TARGET_MEMORY_MISMATCH_STALL
3291 && memory_operand (operands[0], TFmode)))"
3293 switch (get_attr_type (insn))
3296 return standard_sse_constant_opcode (insn, operands[1]);
3299 /* Handle misaligned load/store since we
3300 don't have movmisaligntf pattern. */
3301 if (misaligned_operand (operands[0], TFmode)
3302 || misaligned_operand (operands[1], TFmode))
3304 if (get_attr_mode (insn) == MODE_V4SF)
3305 return "%vmovups\t{%1, %0|%0, %1}";
3306 else if (TARGET_AVX512VL
3307 && (EXT_REX_SSE_REG_P (operands[0])
3308 || EXT_REX_SSE_REG_P (operands[1])))
3309 return "vmovdqu64\t{%1, %0|%0, %1}";
3311 return "%vmovdqu\t{%1, %0|%0, %1}";
3315 if (get_attr_mode (insn) == MODE_V4SF)
3316 return "%vmovaps\t{%1, %0|%0, %1}";
3317 else if (TARGET_AVX512VL
3318 && (EXT_REX_SSE_REG_P (operands[0])
3319 || EXT_REX_SSE_REG_P (operands[1])))
3320 return "vmovdqa64\t{%1, %0|%0, %1}";
3322 return "%vmovdqa\t{%1, %0|%0, %1}";
3332 [(set_attr "isa" "*,*,*,x64,x64")
3333 (set_attr "type" "sselog1,ssemov,ssemov,multi,multi")
3334 (set (attr "prefix")
3335 (if_then_else (eq_attr "type" "sselog1,ssemov")
3336 (const_string "maybe_vex")
3337 (const_string "orig")))
3339 (cond [(eq_attr "alternative" "3,4")
3341 (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
3342 (const_string "V4SF")
3343 (and (eq_attr "alternative" "2")
3344 (match_test "TARGET_SSE_TYPELESS_STORES"))
3345 (const_string "V4SF")
3346 (match_test "TARGET_AVX")
3348 (ior (not (match_test "TARGET_SSE2"))
3349 (match_test "optimize_function_for_size_p (cfun)"))
3350 (const_string "V4SF")
3352 (const_string "TI")))])
3355 [(set (match_operand:TF 0 "nonimmediate_gr_operand")
3356 (match_operand:TF 1 "general_gr_operand"))]
3359 "ix86_split_long_move (operands); DONE;")
3361 ;; Possible store forwarding (partial memory) stall
3362 ;; in alternatives 4, 6, 7 and 8.
3363 (define_insn "*movxf_internal"
3364 [(set (match_operand:XF 0 "nonimmediate_operand"
3365 "=f,m,f,?r ,!o,?*r ,!o,!o,!o,r ,o ,o")
3366 (match_operand:XF 1 "general_operand"
3367 "fm,f,G,roF,r ,*roF,*r,F ,C ,roF,rF,rC"))]
3368 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3369 && (lra_in_progress || reload_completed
3370 || !CONST_DOUBLE_P (operands[1])
3371 || ((optimize_function_for_size_p (cfun)
3372 || (ix86_cmodel == CM_LARGE || ix86_cmodel == CM_LARGE_PIC))
3373 && standard_80387_constant_p (operands[1]) > 0
3374 && !memory_operand (operands[0], XFmode))
3375 || (!TARGET_MEMORY_MISMATCH_STALL
3376 && memory_operand (operands[0], XFmode))
3377 || !TARGET_HARD_XF_REGS)"
3379 switch (get_attr_type (insn))
3382 if (which_alternative == 2)
3383 return standard_80387_constant_opcode (operands[1]);
3384 return output_387_reg_move (insn, operands);
3394 (cond [(eq_attr "alternative" "7,10")
3395 (const_string "nox64")
3396 (eq_attr "alternative" "8,11")
3397 (const_string "x64")
3399 (const_string "*")))
3401 (cond [(eq_attr "alternative" "3,4,5,6,7,8,9,10,11")
3402 (const_string "multi")
3404 (const_string "fmov")))
3406 (cond [(eq_attr "alternative" "3,4,5,6,7,8,9,10,11")
3407 (if_then_else (match_test "TARGET_64BIT")
3409 (const_string "SI"))
3411 (const_string "XF")))
3412 (set (attr "preferred_for_size")
3413 (cond [(eq_attr "alternative" "3,4")
3414 (symbol_ref "false")]
3415 (symbol_ref "true")))
3416 (set (attr "enabled")
3417 (cond [(eq_attr "alternative" "9,10,11")
3419 (match_test "TARGET_HARD_XF_REGS")
3420 (symbol_ref "false")
3422 (not (match_test "TARGET_HARD_XF_REGS"))
3423 (symbol_ref "false")
3425 (const_string "*")))])
3428 [(set (match_operand:XF 0 "nonimmediate_gr_operand")
3429 (match_operand:XF 1 "general_gr_operand"))]
3432 "ix86_split_long_move (operands); DONE;")
3434 ;; Possible store forwarding (partial memory) stall in alternatives 4, 6 and 7.
3435 (define_insn "*movdf_internal"
3436 [(set (match_operand:DF 0 "nonimmediate_operand"
3437 "=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")
3438 (match_operand:DF 1 "general_operand"
3439 "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"))]
3440 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3441 && (lra_in_progress || reload_completed
3442 || !CONST_DOUBLE_P (operands[1])
3443 || ((optimize_function_for_size_p (cfun)
3444 || (ix86_cmodel == CM_LARGE || ix86_cmodel == CM_LARGE_PIC))
3445 && ((IS_STACK_MODE (DFmode)
3446 && standard_80387_constant_p (operands[1]) > 0)
3447 || (TARGET_SSE2 && TARGET_SSE_MATH
3448 && standard_sse_constant_p (operands[1], DFmode) == 1))
3449 && !memory_operand (operands[0], DFmode))
3450 || ((TARGET_64BIT || !TARGET_MEMORY_MISMATCH_STALL)
3451 && memory_operand (operands[0], DFmode))
3452 || !TARGET_HARD_DF_REGS)"
3454 switch (get_attr_type (insn))
3457 if (which_alternative == 2)
3458 return standard_80387_constant_opcode (operands[1]);
3459 return output_387_reg_move (insn, operands);
3465 if (get_attr_mode (insn) == MODE_SI)
3466 return "mov{l}\t{%1, %k0|%k0, %1}";
3467 else if (which_alternative == 11)
3468 return "movabs{q}\t{%1, %0|%0, %1}";
3470 return "mov{q}\t{%1, %0|%0, %1}";
3473 return standard_sse_constant_opcode (insn, operands[1]);
3476 switch (get_attr_mode (insn))
3479 if (TARGET_AVX && REG_P (operands[0]) && REG_P (operands[1]))
3480 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
3481 return "%vmovsd\t{%1, %0|%0, %1}";
3484 return "%vmovaps\t{%1, %0|%0, %1}";
3486 return "vmovapd\t{%g1, %g0|%g0, %g1}";
3488 return "%vmovapd\t{%1, %0|%0, %1}";
3491 gcc_assert (!TARGET_AVX);
3492 return "movlps\t{%1, %0|%0, %1}";
3494 gcc_assert (!TARGET_AVX);
3495 return "movlpd\t{%1, %0|%0, %1}";
3498 /* Handle broken assemblers that require movd instead of movq. */
3499 if (!HAVE_AS_IX86_INTERUNIT_MOVQ
3500 && (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1])))
3501 return "%vmovd\t{%1, %0|%0, %1}";
3502 return "%vmovq\t{%1, %0|%0, %1}";
3513 (cond [(eq_attr "alternative" "3,4,5,6,7,22,23")
3514 (const_string "nox64")
3515 (eq_attr "alternative" "8,9,10,11,20,21,24,25")
3516 (const_string "x64")
3517 (eq_attr "alternative" "12,13,14,15")
3518 (const_string "sse2")
3520 (const_string "*")))
3522 (cond [(eq_attr "alternative" "0,1,2")
3523 (const_string "fmov")
3524 (eq_attr "alternative" "3,4,5,6,7,22,23")
3525 (const_string "multi")
3526 (eq_attr "alternative" "8,9,10,11,24,25")
3527 (const_string "imov")
3528 (eq_attr "alternative" "12,16")
3529 (const_string "sselog1")
3531 (const_string "ssemov")))
3533 (if_then_else (eq_attr "alternative" "11")
3535 (const_string "*")))
3536 (set (attr "length_immediate")
3537 (if_then_else (eq_attr "alternative" "11")
3539 (const_string "*")))
3540 (set (attr "prefix")
3541 (if_then_else (eq_attr "type" "sselog1,ssemov")
3542 (const_string "maybe_vex")
3543 (const_string "orig")))
3544 (set (attr "prefix_data16")
3546 (ior (and (eq_attr "type" "ssemov") (eq_attr "mode" "DI"))
3547 (eq_attr "mode" "V1DF"))
3549 (const_string "*")))
3551 (cond [(eq_attr "alternative" "3,4,5,6,7,10,22,23")
3553 (eq_attr "alternative" "8,9,11,20,21,24,25")
3556 /* xorps is one byte shorter for non-AVX targets. */
3557 (eq_attr "alternative" "12,16")
3558 (cond [(not (match_test "TARGET_SSE2"))
3559 (const_string "V4SF")
3560 (and (match_test "TARGET_AVX512F")
3561 (not (match_test "TARGET_PREFER_AVX256")))
3563 (match_test "TARGET_AVX")
3564 (const_string "V2DF")
3565 (match_test "optimize_function_for_size_p (cfun)")
3566 (const_string "V4SF")
3567 (match_test "TARGET_SSE_LOAD0_BY_PXOR")
3570 (const_string "V2DF"))
3572 /* For architectures resolving dependencies on
3573 whole SSE registers use movapd to break dependency
3574 chains, otherwise use short move to avoid extra work. */
3576 /* movaps is one byte shorter for non-AVX targets. */
3577 (eq_attr "alternative" "13,17")
3578 (cond [(and (ior (not (match_test "TARGET_PREFER_AVX256"))
3579 (not (match_test "TARGET_AVX512VL")))
3580 (ior (match_operand 0 "ext_sse_reg_operand")
3581 (match_operand 1 "ext_sse_reg_operand")))
3582 (const_string "V8DF")
3583 (ior (not (match_test "TARGET_SSE2"))
3584 (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL"))
3585 (const_string "V4SF")
3586 (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3587 (const_string "V2DF")
3588 (match_test "TARGET_AVX")
3590 (match_test "optimize_function_for_size_p (cfun)")
3591 (const_string "V4SF")
3593 (const_string "DF"))
3595 /* For architectures resolving dependencies on register
3596 parts we may avoid extra work to zero out upper part
3598 (eq_attr "alternative" "14,18")
3599 (cond [(not (match_test "TARGET_SSE2"))
3600 (const_string "V2SF")
3601 (match_test "TARGET_AVX")
3603 (match_test "TARGET_SSE_SPLIT_REGS")
3604 (const_string "V1DF")
3606 (const_string "DF"))
3608 (and (eq_attr "alternative" "15,19")
3609 (not (match_test "TARGET_SSE2")))
3610 (const_string "V2SF")
3612 (const_string "DF")))
3613 (set (attr "preferred_for_size")
3614 (cond [(eq_attr "alternative" "3,4")
3615 (symbol_ref "false")]
3616 (symbol_ref "true")))
3617 (set (attr "preferred_for_speed")
3618 (cond [(eq_attr "alternative" "3,4")
3619 (symbol_ref "TARGET_INTEGER_DFMODE_MOVES")]
3620 (symbol_ref "true")))
3621 (set (attr "enabled")
3622 (cond [(eq_attr "alternative" "22,23,24,25")
3624 (match_test "TARGET_HARD_DF_REGS")
3625 (symbol_ref "false")
3627 (not (match_test "TARGET_HARD_DF_REGS"))
3628 (symbol_ref "false")
3630 (const_string "*")))])
3633 [(set (match_operand:DF 0 "nonimmediate_gr_operand")
3634 (match_operand:DF 1 "general_gr_operand"))]
3635 "!TARGET_64BIT && reload_completed"
3637 "ix86_split_long_move (operands); DONE;")
3639 (define_insn "*movsf_internal"
3640 [(set (match_operand:SF 0 "nonimmediate_operand"
3641 "=Yf*f,m ,Yf*f,?r ,?m,v,v,v,m,?r,?Yi,!*y,!*y,!m,!r ,!*Ym,r ,m")
3642 (match_operand:SF 1 "general_operand"
3643 "Yf*fm,Yf*f,G ,rmF,rF,C,v,m,v,Yj,r ,*y ,m ,*y,*Yn,r ,rmF,rF"))]
3644 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3645 && (lra_in_progress || reload_completed
3646 || !CONST_DOUBLE_P (operands[1])
3647 || ((optimize_function_for_size_p (cfun)
3648 || (ix86_cmodel == CM_LARGE || ix86_cmodel == CM_LARGE_PIC))
3649 && ((IS_STACK_MODE (SFmode)
3650 && standard_80387_constant_p (operands[1]) > 0)
3651 || (TARGET_SSE && TARGET_SSE_MATH
3652 && standard_sse_constant_p (operands[1], SFmode) == 1)))
3653 || memory_operand (operands[0], SFmode)
3654 || !TARGET_HARD_SF_REGS)"
3656 switch (get_attr_type (insn))
3659 if (which_alternative == 2)
3660 return standard_80387_constant_opcode (operands[1]);
3661 return output_387_reg_move (insn, operands);
3664 return "mov{l}\t{%1, %0|%0, %1}";
3667 return standard_sse_constant_opcode (insn, operands[1]);
3670 switch (get_attr_mode (insn))
3673 if (TARGET_AVX && REG_P (operands[0]) && REG_P (operands[1]))
3674 return "vmovss\t{%1, %0, %0|%0, %0, %1}";
3675 return "%vmovss\t{%1, %0|%0, %1}";
3678 return "vmovaps\t{%g1, %g0|%g0, %g1}";
3680 return "%vmovaps\t{%1, %0|%0, %1}";
3683 return "%vmovd\t{%1, %0|%0, %1}";
3690 switch (get_attr_mode (insn))
3693 return "movq\t{%1, %0|%0, %1}";
3695 return "movd\t{%1, %0|%0, %1}";
3706 (cond [(eq_attr "alternative" "0,1,2")
3707 (const_string "fmov")
3708 (eq_attr "alternative" "3,4,16,17")
3709 (const_string "imov")
3710 (eq_attr "alternative" "5")
3711 (const_string "sselog1")
3712 (eq_attr "alternative" "11,12,13,14,15")
3713 (const_string "mmxmov")
3715 (const_string "ssemov")))
3716 (set (attr "prefix")
3717 (if_then_else (eq_attr "type" "sselog1,ssemov")
3718 (const_string "maybe_vex")
3719 (const_string "orig")))
3720 (set (attr "prefix_data16")
3721 (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
3723 (const_string "*")))
3725 (cond [(eq_attr "alternative" "3,4,9,10,12,13,14,15,16,17")
3727 (eq_attr "alternative" "11")
3729 (eq_attr "alternative" "5")
3730 (cond [(not (match_test "TARGET_SSE2"))
3731 (const_string "V4SF")
3732 (and (match_test "TARGET_AVX512F")
3733 (not (match_test "TARGET_PREFER_AVX256")))
3734 (const_string "V16SF")
3735 (match_test "TARGET_AVX")
3736 (const_string "V4SF")
3737 (match_test "optimize_function_for_size_p (cfun)")
3738 (const_string "V4SF")
3739 (match_test "TARGET_SSE_LOAD0_BY_PXOR")
3742 (const_string "V4SF"))
3744 /* For architectures resolving dependencies on
3745 whole SSE registers use APS move to break dependency
3746 chains, otherwise use short move to avoid extra work.
3748 Do the same for architectures resolving dependencies on
3749 the parts. While in DF mode it is better to always handle
3750 just register parts, the SF mode is different due to lack
3751 of instructions to load just part of the register. It is
3752 better to maintain the whole registers in single format
3753 to avoid problems on using packed logical operations. */
3754 (eq_attr "alternative" "6")
3755 (cond [(and (ior (not (match_test "TARGET_PREFER_AVX256"))
3756 (not (match_test "TARGET_AVX512VL")))
3757 (ior (match_operand 0 "ext_sse_reg_operand")
3758 (match_operand 1 "ext_sse_reg_operand")))
3759 (const_string "V16SF")
3760 (ior (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3761 (match_test "TARGET_SSE_SPLIT_REGS"))
3762 (const_string "V4SF")
3764 (const_string "SF"))
3766 (const_string "SF")))
3767 (set (attr "enabled")
3768 (cond [(eq_attr "alternative" "16,17")
3770 (match_test "TARGET_HARD_SF_REGS")
3771 (symbol_ref "false")
3773 (not (match_test "TARGET_HARD_SF_REGS"))
3774 (symbol_ref "false")
3776 (const_string "*")))])
3779 [(set (match_operand 0 "any_fp_register_operand")
3780 (match_operand 1 "nonimmediate_operand"))]
3782 && (GET_MODE (operands[0]) == TFmode
3783 || GET_MODE (operands[0]) == XFmode
3784 || GET_MODE (operands[0]) == DFmode
3785 || GET_MODE (operands[0]) == SFmode)
3786 && ix86_standard_x87sse_constant_load_p (insn, operands[0])"
3787 [(set (match_dup 0) (match_dup 2))]
3788 "operands[2] = find_constant_src (curr_insn);")
3791 [(set (match_operand 0 "any_fp_register_operand")
3792 (float_extend (match_operand 1 "nonimmediate_operand")))]
3794 && (GET_MODE (operands[0]) == TFmode
3795 || GET_MODE (operands[0]) == XFmode
3796 || GET_MODE (operands[0]) == DFmode)
3797 && ix86_standard_x87sse_constant_load_p (insn, operands[0])"
3798 [(set (match_dup 0) (match_dup 2))]
3799 "operands[2] = find_constant_src (curr_insn);")
3801 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
3803 [(set (match_operand:X87MODEF 0 "fp_register_operand")
3804 (match_operand:X87MODEF 1 "immediate_operand"))]
3806 && (standard_80387_constant_p (operands[1]) == 8
3807 || standard_80387_constant_p (operands[1]) == 9)"
3808 [(set (match_dup 0)(match_dup 1))
3810 (neg:X87MODEF (match_dup 0)))]
3812 if (real_isnegzero (CONST_DOUBLE_REAL_VALUE (operands[1])))
3813 operands[1] = CONST0_RTX (<MODE>mode);
3815 operands[1] = CONST1_RTX (<MODE>mode);
3818 (define_insn "swapxf"
3819 [(set (match_operand:XF 0 "register_operand" "+f")
3820 (match_operand:XF 1 "register_operand" "+f"))
3825 if (STACK_TOP_P (operands[0]))
3830 [(set_attr "type" "fxch")
3831 (set_attr "mode" "XF")])
3833 (define_insn "*swap<mode>"
3834 [(set (match_operand:MODEF 0 "fp_register_operand" "+f")
3835 (match_operand:MODEF 1 "fp_register_operand" "+f"))
3838 "TARGET_80387 || reload_completed"
3840 if (STACK_TOP_P (operands[0]))
3845 [(set_attr "type" "fxch")
3846 (set_attr "mode" "<MODE>")])
3848 ;; Zero extension instructions
3850 (define_expand "zero_extendsidi2"
3851 [(set (match_operand:DI 0 "nonimmediate_operand")
3852 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand")))])
3854 (define_insn "*zero_extendsidi2"
3855 [(set (match_operand:DI 0 "nonimmediate_operand"
3856 "=r,?r,?o,r ,o,?*Ym,?!*y,?r ,?*Yi,*x,*x,*v,*r")
3858 (match_operand:SI 1 "x86_64_zext_operand"
3859 "0 ,rm,r ,rmWz,0,r ,m ,*Yj,r ,m ,*x,*v,*k")))]
3862 switch (get_attr_type (insn))
3865 if (ix86_use_lea_for_mov (insn, operands))
3866 return "lea{l}\t{%E1, %k0|%k0, %E1}";
3868 return "mov{l}\t{%1, %k0|%k0, %1}";
3874 return "movd\t{%1, %0|%0, %1}";
3877 if (SSE_REG_P (operands[0]) && SSE_REG_P (operands[1]))
3879 if (EXT_REX_SSE_REG_P (operands[0])
3880 || EXT_REX_SSE_REG_P (operands[1]))
3881 return "vpmovzxdq\t{%t1, %g0|%g0, %t1}";
3883 return "%vpmovzxdq\t{%1, %0|%0, %1}";
3886 if (GENERAL_REG_P (operands[0]))
3887 return "%vmovd\t{%1, %k0|%k0, %1}";
3889 return "%vmovd\t{%1, %0|%0, %1}";
3892 return "kmovd\t{%1, %k0|%k0, %1}";
3899 (cond [(eq_attr "alternative" "0,1,2")
3900 (const_string "nox64")
3901 (eq_attr "alternative" "3")
3902 (const_string "x64")
3903 (eq_attr "alternative" "9")
3904 (const_string "sse2")
3905 (eq_attr "alternative" "10")
3906 (const_string "sse4")
3907 (eq_attr "alternative" "11")
3908 (const_string "avx512f")
3909 (eq_attr "alternative" "12")
3910 (const_string "x64_avx512bw")
3912 (const_string "*")))
3914 (cond [(eq_attr "alternative" "0,1,2,4")
3915 (const_string "multi")
3916 (eq_attr "alternative" "5,6")
3917 (const_string "mmxmov")
3918 (eq_attr "alternative" "7")
3919 (if_then_else (match_test "TARGET_64BIT")
3920 (const_string "ssemov")
3921 (const_string "multi"))
3922 (eq_attr "alternative" "8,9,10,11")
3923 (const_string "ssemov")
3924 (eq_attr "alternative" "12")
3925 (const_string "mskmov")
3927 (const_string "imovx")))
3928 (set (attr "prefix_extra")
3929 (if_then_else (eq_attr "alternative" "10,11")
3931 (const_string "*")))
3932 (set (attr "prefix")
3933 (if_then_else (eq_attr "type" "ssemov")
3934 (const_string "maybe_vex")
3935 (const_string "orig")))
3936 (set (attr "prefix_0f")
3937 (if_then_else (eq_attr "type" "imovx")
3939 (const_string "*")))
3941 (cond [(eq_attr "alternative" "5,6")
3943 (and (eq_attr "alternative" "7")
3944 (match_test "TARGET_64BIT"))
3946 (eq_attr "alternative" "8,10,11")
3949 (const_string "SI")))])
3952 [(set (match_operand:DI 0 "memory_operand")
3953 (zero_extend:DI (match_operand:SI 1 "memory_operand")))]
3955 [(set (match_dup 4) (const_int 0))]
3956 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3959 [(set (match_operand:DI 0 "general_reg_operand")
3960 (zero_extend:DI (match_operand:SI 1 "general_reg_operand")))]
3961 "!TARGET_64BIT && reload_completed
3962 && REGNO (operands[0]) == REGNO (operands[1])"
3963 [(set (match_dup 4) (const_int 0))]
3964 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3967 [(set (match_operand:DI 0 "nonimmediate_gr_operand")
3968 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand")))]
3969 "!TARGET_64BIT && reload_completed
3970 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
3971 [(set (match_dup 3) (match_dup 1))
3972 (set (match_dup 4) (const_int 0))]
3973 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3976 [(set (match_operand:DI 0 "general_reg_operand")
3977 (zero_extend:DI (match_operand:SI 1 "nonimmediate_gr_operand")))
3978 (set (match_operand:DI 2 "sse_reg_operand") (match_dup 0))]
3979 "TARGET_64BIT && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC
3980 && peep2_reg_dead_p (2, operands[0])"
3982 (zero_extend:DI (match_dup 1)))])
3984 (define_mode_attr kmov_isa
3985 [(QI "avx512dq") (HI "avx512f") (SI "avx512bw") (DI "avx512bw")])
3987 (define_insn "zero_extend<mode>di2"
3988 [(set (match_operand:DI 0 "register_operand" "=r,*r")
3990 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m,*k")))]
3993 movz{<imodesuffix>l|x}\t{%1, %k0|%k0, %1}
3994 kmov<mskmodesuffix>\t{%1, %k0|%k0, %1}"
3995 [(set_attr "isa" "*,<kmov_isa>")
3996 (set_attr "type" "imovx,mskmov")
3997 (set_attr "mode" "SI,<MODE>")])
3999 (define_expand "zero_extend<mode>si2"
4000 [(set (match_operand:SI 0 "register_operand")
4001 (zero_extend:SI (match_operand:SWI12 1 "nonimmediate_operand")))]
4004 if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
4006 operands[1] = force_reg (<MODE>mode, operands[1]);
4007 emit_insn (gen_zero_extend<mode>si2_and (operands[0], operands[1]));
4012 (define_insn_and_split "zero_extend<mode>si2_and"
4013 [(set (match_operand:SI 0 "register_operand" "=r,?&<r>")
4015 (match_operand:SWI12 1 "nonimmediate_operand" "0,<r>m")))
4016 (clobber (reg:CC FLAGS_REG))]
4017 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
4019 "&& reload_completed"
4020 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (match_dup 2)))
4021 (clobber (reg:CC FLAGS_REG))])]
4023 if (!REG_P (operands[1])
4024 || REGNO (operands[0]) != REGNO (operands[1]))
4026 ix86_expand_clear (operands[0]);
4028 gcc_assert (!TARGET_PARTIAL_REG_STALL);
4029 emit_insn (gen_movstrict<mode>
4030 (gen_lowpart (<MODE>mode, operands[0]), operands[1]));
4034 operands[2] = GEN_INT (GET_MODE_MASK (<MODE>mode));
4036 [(set_attr "type" "alu1")
4037 (set_attr "mode" "SI")])
4039 (define_insn "*zero_extend<mode>si2"
4040 [(set (match_operand:SI 0 "register_operand" "=r,*r")
4042 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m,*k")))]
4043 "!(TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))"
4045 movz{<imodesuffix>l|x}\t{%1, %0|%0, %1}
4046 kmov<mskmodesuffix>\t{%1, %0|%0, %1}"
4047 [(set_attr "isa" "*,<kmov_isa>")
4048 (set_attr "type" "imovx,mskmov")
4049 (set_attr "mode" "SI,<MODE>")])
4051 (define_expand "zero_extendqihi2"
4052 [(set (match_operand:HI 0 "register_operand")
4053 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand")))]
4056 if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
4058 operands[1] = force_reg (QImode, operands[1]);
4059 emit_insn (gen_zero_extendqihi2_and (operands[0], operands[1]));
4064 (define_insn_and_split "zero_extendqihi2_and"
4065 [(set (match_operand:HI 0 "register_operand" "=r,?&q")
4066 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
4067 (clobber (reg:CC FLAGS_REG))]
4068 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
4070 "&& reload_completed"
4071 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
4072 (clobber (reg:CC FLAGS_REG))])]
4074 if (!REG_P (operands[1])
4075 || REGNO (operands[0]) != REGNO (operands[1]))
4077 ix86_expand_clear (operands[0]);
4079 gcc_assert (!TARGET_PARTIAL_REG_STALL);
4080 emit_insn (gen_movstrictqi
4081 (gen_lowpart (QImode, operands[0]), operands[1]));
4085 operands[0] = gen_lowpart (SImode, operands[0]);
4087 [(set_attr "type" "alu1")
4088 (set_attr "mode" "SI")])
4090 ; zero extend to SImode to avoid partial register stalls
4091 (define_insn "*zero_extendqihi2"
4092 [(set (match_operand:HI 0 "register_operand" "=r,*r")
4093 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,*k")))]
4094 "!(TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))"
4096 movz{bl|x}\t{%1, %k0|%k0, %1}
4097 kmovb\t{%1, %k0|%k0, %1}"
4098 [(set_attr "isa" "*,avx512dq")
4099 (set_attr "type" "imovx,mskmov")
4100 (set_attr "mode" "SI,QI")])
4102 (define_insn_and_split "*zext<mode>_doubleword_and"
4103 [(set (match_operand:DI 0 "register_operand" "=&<r>")
4104 (zero_extend:DI (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
4105 "!TARGET_64BIT && TARGET_STV && TARGET_SSE2
4106 && TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
4108 "&& reload_completed && GENERAL_REG_P (operands[0])"
4109 [(set (match_dup 2) (const_int 0))]
4111 split_double_mode (DImode, &operands[0], 1, &operands[0], &operands[2]);
4113 emit_move_insn (operands[0], const0_rtx);
4115 gcc_assert (!TARGET_PARTIAL_REG_STALL);
4116 emit_insn (gen_movstrict<mode>
4117 (gen_lowpart (<MODE>mode, operands[0]), operands[1]));
4120 (define_insn_and_split "*zext<mode>_doubleword"
4121 [(set (match_operand:DI 0 "register_operand" "=r")
4122 (zero_extend:DI (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
4123 "!TARGET_64BIT && TARGET_STV && TARGET_SSE2
4124 && !(TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))"
4126 "&& reload_completed && GENERAL_REG_P (operands[0])"
4127 [(set (match_dup 0) (zero_extend:SI (match_dup 1)))
4128 (set (match_dup 2) (const_int 0))]
4129 "split_double_mode (DImode, &operands[0], 1, &operands[0], &operands[2]);")
4131 (define_insn_and_split "*zextsi_doubleword"
4132 [(set (match_operand:DI 0 "register_operand" "=r")
4133 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm")))]
4134 "!TARGET_64BIT && TARGET_STV && TARGET_SSE2"
4136 "&& reload_completed && GENERAL_REG_P (operands[0])"
4137 [(set (match_dup 0) (match_dup 1))
4138 (set (match_dup 2) (const_int 0))]
4139 "split_double_mode (DImode, &operands[0], 1, &operands[0], &operands[2]);")
4141 ;; Sign extension instructions
4143 (define_expand "extendsidi2"
4144 [(set (match_operand:DI 0 "register_operand")
4145 (sign_extend:DI (match_operand:SI 1 "register_operand")))]
4150 emit_insn (gen_extendsidi2_1 (operands[0], operands[1]));
4155 (define_insn "*extendsidi2_rex64"
4156 [(set (match_operand:DI 0 "register_operand" "=*a,r")
4157 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
4161 movs{lq|x}\t{%1, %0|%0, %1}"
4162 [(set_attr "type" "imovx")
4163 (set_attr "mode" "DI")
4164 (set_attr "prefix_0f" "0")
4165 (set_attr "modrm" "0,1")])
4167 (define_insn "extendsidi2_1"
4168 [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
4169 (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
4170 (clobber (reg:CC FLAGS_REG))
4171 (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
4175 ;; Split the memory case. If the source register doesn't die, it will stay
4176 ;; this way, if it does die, following peephole2s take care of it.
4178 [(set (match_operand:DI 0 "memory_operand")
4179 (sign_extend:DI (match_operand:SI 1 "register_operand")))
4180 (clobber (reg:CC FLAGS_REG))
4181 (clobber (match_operand:SI 2 "register_operand"))]
4185 split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
4187 emit_move_insn (operands[3], operands[1]);
4189 /* Generate a cltd if possible and doing so it profitable. */
4190 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
4191 && REGNO (operands[1]) == AX_REG
4192 && REGNO (operands[2]) == DX_REG)
4194 emit_insn (gen_ashrsi3_cvt (operands[2], operands[1], GEN_INT (31)));
4198 emit_move_insn (operands[2], operands[1]);
4199 emit_insn (gen_ashrsi3_cvt (operands[2], operands[2], GEN_INT (31)));
4201 emit_move_insn (operands[4], operands[2]);
4205 ;; Peepholes for the case where the source register does die, after
4206 ;; being split with the above splitter.
4208 [(set (match_operand:SI 0 "memory_operand")
4209 (match_operand:SI 1 "general_reg_operand"))
4210 (set (match_operand:SI 2 "general_reg_operand") (match_dup 1))
4211 (parallel [(set (match_dup 2)
4212 (ashiftrt:SI (match_dup 2) (const_int 31)))
4213 (clobber (reg:CC FLAGS_REG))])
4214 (set (match_operand:SI 3 "memory_operand") (match_dup 2))]
4215 "REGNO (operands[1]) != REGNO (operands[2])
4216 && peep2_reg_dead_p (2, operands[1])
4217 && peep2_reg_dead_p (4, operands[2])
4218 && !reg_mentioned_p (operands[2], operands[3])"
4219 [(set (match_dup 0) (match_dup 1))
4220 (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
4221 (clobber (reg:CC FLAGS_REG))])
4222 (set (match_dup 3) (match_dup 1))])
4225 [(set (match_operand:SI 0 "memory_operand")
4226 (match_operand:SI 1 "general_reg_operand"))
4227 (parallel [(set (match_operand:SI 2 "general_reg_operand")
4228 (ashiftrt:SI (match_dup 1) (const_int 31)))
4229 (clobber (reg:CC FLAGS_REG))])
4230 (set (match_operand:SI 3 "memory_operand") (match_dup 2))]
4231 "/* cltd is shorter than sarl $31, %eax */
4232 !optimize_function_for_size_p (cfun)
4233 && REGNO (operands[1]) == AX_REG
4234 && REGNO (operands[2]) == DX_REG
4235 && peep2_reg_dead_p (2, operands[1])
4236 && peep2_reg_dead_p (3, operands[2])
4237 && !reg_mentioned_p (operands[2], operands[3])"
4238 [(set (match_dup 0) (match_dup 1))
4239 (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
4240 (clobber (reg:CC FLAGS_REG))])
4241 (set (match_dup 3) (match_dup 1))])
4243 ;; Extend to register case. Optimize case where source and destination
4244 ;; registers match and cases where we can use cltd.
4246 [(set (match_operand:DI 0 "register_operand")
4247 (sign_extend:DI (match_operand:SI 1 "register_operand")))
4248 (clobber (reg:CC FLAGS_REG))
4249 (clobber (match_scratch:SI 2))]
4253 split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
4255 if (REGNO (operands[3]) != REGNO (operands[1]))
4256 emit_move_insn (operands[3], operands[1]);
4258 /* Generate a cltd if possible and doing so it profitable. */
4259 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
4260 && REGNO (operands[3]) == AX_REG
4261 && REGNO (operands[4]) == DX_REG)
4263 emit_insn (gen_ashrsi3_cvt (operands[4], operands[3], GEN_INT (31)));
4267 if (REGNO (operands[4]) != REGNO (operands[1]))
4268 emit_move_insn (operands[4], operands[1]);
4270 emit_insn (gen_ashrsi3_cvt (operands[4], operands[4], GEN_INT (31)));
4274 (define_insn "extend<mode>di2"
4275 [(set (match_operand:DI 0 "register_operand" "=r")
4277 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
4279 "movs{<imodesuffix>q|x}\t{%1, %0|%0, %1}"
4280 [(set_attr "type" "imovx")
4281 (set_attr "mode" "DI")])
4283 (define_insn "extendhisi2"
4284 [(set (match_operand:SI 0 "register_operand" "=*a,r")
4285 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
4288 switch (get_attr_prefix_0f (insn))
4291 return "{cwtl|cwde}";
4293 return "movs{wl|x}\t{%1, %0|%0, %1}";
4296 [(set_attr "type" "imovx")
4297 (set_attr "mode" "SI")
4298 (set (attr "prefix_0f")
4299 ;; movsx is short decodable while cwtl is vector decoded.
4300 (if_then_else (and (eq_attr "cpu" "!k6")
4301 (eq_attr "alternative" "0"))
4303 (const_string "1")))
4304 (set (attr "znver1_decode")
4305 (if_then_else (eq_attr "prefix_0f" "0")
4306 (const_string "double")
4307 (const_string "direct")))
4309 (if_then_else (eq_attr "prefix_0f" "0")
4311 (const_string "1")))])
4313 (define_insn "*extendhisi2_zext"
4314 [(set (match_operand:DI 0 "register_operand" "=*a,r")
4317 (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
4320 switch (get_attr_prefix_0f (insn))
4323 return "{cwtl|cwde}";
4325 return "movs{wl|x}\t{%1, %k0|%k0, %1}";
4328 [(set_attr "type" "imovx")
4329 (set_attr "mode" "SI")
4330 (set (attr "prefix_0f")
4331 ;; movsx is short decodable while cwtl is vector decoded.
4332 (if_then_else (and (eq_attr "cpu" "!k6")
4333 (eq_attr "alternative" "0"))
4335 (const_string "1")))
4337 (if_then_else (eq_attr "prefix_0f" "0")
4339 (const_string "1")))])
4341 (define_insn "extendqisi2"
4342 [(set (match_operand:SI 0 "register_operand" "=r")
4343 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
4345 "movs{bl|x}\t{%1, %0|%0, %1}"
4346 [(set_attr "type" "imovx")
4347 (set_attr "mode" "SI")])
4349 (define_insn "*extendqisi2_zext"
4350 [(set (match_operand:DI 0 "register_operand" "=r")
4352 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
4354 "movs{bl|x}\t{%1, %k0|%k0, %1}"
4355 [(set_attr "type" "imovx")
4356 (set_attr "mode" "SI")])
4358 (define_insn "extendqihi2"
4359 [(set (match_operand:HI 0 "register_operand" "=*a,r")
4360 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
4363 switch (get_attr_prefix_0f (insn))
4366 return "{cbtw|cbw}";
4368 return "movs{bw|x}\t{%1, %0|%0, %1}";
4371 [(set_attr "type" "imovx")
4372 (set_attr "mode" "HI")
4373 (set (attr "prefix_0f")
4374 ;; movsx is short decodable while cwtl is vector decoded.
4375 (if_then_else (and (eq_attr "cpu" "!k6")
4376 (eq_attr "alternative" "0"))
4378 (const_string "1")))
4380 (if_then_else (eq_attr "prefix_0f" "0")
4382 (const_string "1")))])
4384 ;; Conversions between float and double.
4386 ;; These are all no-ops in the model used for the 80387.
4387 ;; So just emit moves.
4389 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
4391 [(set (match_operand:DF 0 "push_operand")
4392 (float_extend:DF (match_operand:SF 1 "fp_register_operand")))]
4394 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
4395 (set (mem:DF (reg:P SP_REG)) (float_extend:DF (match_dup 1)))])
4398 [(set (match_operand:XF 0 "push_operand")
4399 (float_extend:XF (match_operand:MODEF 1 "fp_register_operand")))]
4401 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
4402 (set (mem:XF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
4403 "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
4405 (define_expand "extendsfdf2"
4406 [(set (match_operand:DF 0 "nonimm_ssenomem_operand")
4407 (float_extend:DF (match_operand:SF 1 "general_operand")))]
4408 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4410 /* ??? Needed for compress_float_constant since all fp constants
4411 are TARGET_LEGITIMATE_CONSTANT_P. */
4412 if (CONST_DOUBLE_P (operands[1]))
4414 if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
4415 && standard_80387_constant_p (operands[1]) > 0)
4417 operands[1] = simplify_const_unary_operation
4418 (FLOAT_EXTEND, DFmode, operands[1], SFmode);
4419 emit_move_insn_1 (operands[0], operands[1]);
4422 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
4426 /* For converting SF(xmm2) to DF(xmm1), use the following code instead of
4428 unpcklps xmm2,xmm2 ; packed conversion might crash on signaling NaNs
4430 We do the conversion post reload to avoid producing of 128bit spills
4431 that might lead to ICE on 32bit target. The sequence unlikely combine
4434 [(set (match_operand:DF 0 "sse_reg_operand")
4436 (match_operand:SF 1 "nonimmediate_operand")))]
4437 "TARGET_USE_VECTOR_FP_CONVERTS
4438 && optimize_insn_for_speed_p ()
4440 && (!EXT_REX_SSE_REG_P (operands[0])
4441 || TARGET_AVX512VL)"
4446 (parallel [(const_int 0) (const_int 1)]))))]
4448 operands[2] = lowpart_subreg (V2DFmode, operands[0], DFmode);
4449 operands[3] = lowpart_subreg (V4SFmode, operands[0], DFmode);
4450 /* Use movss for loading from memory, unpcklps reg, reg for registers.
4451 Try to avoid move when unpacking can be done in source. */
4452 if (REG_P (operands[1]))
4454 /* If it is unsafe to overwrite upper half of source, we need
4455 to move to destination and unpack there. */
4456 if (REGNO (operands[0]) != REGNO (operands[1])
4457 || (EXT_REX_SSE_REG_P (operands[1])
4458 && !TARGET_AVX512VL))
4460 rtx tmp = lowpart_subreg (SFmode, operands[0], DFmode);
4461 emit_move_insn (tmp, operands[1]);
4464 operands[3] = lowpart_subreg (V4SFmode, operands[1], SFmode);
4465 /* FIXME: vec_interleave_lowv4sf for AVX512VL should allow
4466 =v, v, then vbroadcastss will be only needed for AVX512F without
4468 if (!EXT_REX_SSE_REGNO_P (REGNO (operands[3])))
4469 emit_insn (gen_vec_interleave_lowv4sf (operands[3], operands[3],
4473 rtx tmp = lowpart_subreg (V16SFmode, operands[3], V4SFmode);
4474 emit_insn (gen_avx512f_vec_dupv16sf_1 (tmp, tmp));
4478 emit_insn (gen_vec_setv4sf_0 (operands[3],
4479 CONST0_RTX (V4SFmode), operands[1]));
4482 ;; It's more profitable to split and then extend in the same register.
4484 [(set (match_operand:DF 0 "sse_reg_operand")
4486 (match_operand:SF 1 "memory_operand")))]
4487 "TARGET_SPLIT_MEM_OPND_FOR_FP_CONVERTS
4488 && optimize_insn_for_speed_p ()"
4489 [(set (match_dup 2) (match_dup 1))
4490 (set (match_dup 0) (float_extend:DF (match_dup 2)))]
4491 "operands[2] = lowpart_subreg (SFmode, operands[0], DFmode);")
4493 (define_insn "*extendsfdf2"
4494 [(set (match_operand:DF 0 "nonimm_ssenomem_operand" "=f,m,v")
4496 (match_operand:SF 1 "nonimmediate_operand" "fm,f,vm")))]
4497 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4499 switch (which_alternative)
4503 return output_387_reg_move (insn, operands);
4506 return "%vcvtss2sd\t{%1, %d0|%d0, %1}";
4512 [(set_attr "type" "fmov,fmov,ssecvt")
4513 (set_attr "prefix" "orig,orig,maybe_vex")
4514 (set_attr "mode" "SF,XF,DF")
4515 (set (attr "enabled")
4517 (match_test ("TARGET_SSE2 && TARGET_SSE_MATH"))
4519 (eq_attr "alternative" "0,1")
4520 (symbol_ref "TARGET_MIX_SSE_I387")
4521 (symbol_ref "true"))
4523 (eq_attr "alternative" "0,1")
4525 (symbol_ref "false"))))])
4527 (define_expand "extend<mode>xf2"
4528 [(set (match_operand:XF 0 "nonimmediate_operand")
4529 (float_extend:XF (match_operand:MODEF 1 "general_operand")))]
4532 /* ??? Needed for compress_float_constant since all fp constants
4533 are TARGET_LEGITIMATE_CONSTANT_P. */
4534 if (CONST_DOUBLE_P (operands[1]))
4536 if (standard_80387_constant_p (operands[1]) > 0)
4538 operands[1] = simplify_const_unary_operation
4539 (FLOAT_EXTEND, XFmode, operands[1], <MODE>mode);
4540 emit_move_insn_1 (operands[0], operands[1]);
4543 operands[1] = validize_mem (force_const_mem (<MODE>mode, operands[1]));
4547 (define_insn "*extend<mode>xf2_i387"
4548 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
4550 (match_operand:MODEF 1 "nonimmediate_operand" "fm,f")))]
4552 "* return output_387_reg_move (insn, operands);"
4553 [(set_attr "type" "fmov")
4554 (set_attr "mode" "<MODE>,XF")])
4556 ;; %%% This seems like bad news.
4557 ;; This cannot output into an f-reg because there is no way to be sure
4558 ;; of truncating in that case. Otherwise this is just like a simple move
4559 ;; insn. So we pretend we can output to a reg in order to get better
4560 ;; register preferencing, but we really use a stack slot.
4562 ;; Conversion from DFmode to SFmode.
4564 (define_expand "truncdfsf2"
4565 [(set (match_operand:SF 0 "nonimmediate_operand")
4567 (match_operand:DF 1 "nonimmediate_operand")))]
4568 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4570 if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
4572 else if (flag_unsafe_math_optimizations)
4576 rtx temp = assign_386_stack_local (SFmode, SLOT_TEMP);
4577 emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
4582 /* For converting DF(xmm2) to SF(xmm1), use the following code instead of
4584 unpcklpd xmm2,xmm2 ; packed conversion might crash on signaling NaNs
4586 We do the conversion post reload to avoid producing of 128bit spills
4587 that might lead to ICE on 32bit target. The sequence unlikely combine
4590 [(set (match_operand:SF 0 "sse_reg_operand")
4592 (match_operand:DF 1 "nonimmediate_operand")))]
4593 "TARGET_USE_VECTOR_FP_CONVERTS
4594 && optimize_insn_for_speed_p ()
4596 && (!EXT_REX_SSE_REG_P (operands[0])
4597 || TARGET_AVX512VL)"
4600 (float_truncate:V2SF
4604 operands[2] = lowpart_subreg (V4SFmode, operands[0], SFmode);
4605 operands[3] = CONST0_RTX (V2SFmode);
4606 operands[4] = lowpart_subreg (V2DFmode, operands[0], SFmode);
4607 /* Use movsd for loading from memory, unpcklpd for registers.
4608 Try to avoid move when unpacking can be done in source, or SSE3
4609 movddup is available. */
4610 if (REG_P (operands[1]))
4613 && REGNO (operands[0]) != REGNO (operands[1]))
4615 rtx tmp = lowpart_subreg (DFmode, operands[0], SFmode);
4616 emit_move_insn (tmp, operands[1]);
4619 else if (!TARGET_SSE3)
4620 operands[4] = lowpart_subreg (V2DFmode, operands[1], DFmode);
4621 emit_insn (gen_vec_dupv2df (operands[4], operands[1]));
4624 emit_insn (gen_vec_concatv2df (operands[4], operands[1],
4625 CONST0_RTX (DFmode)));
4628 ;; It's more profitable to split and then extend in the same register.
4630 [(set (match_operand:SF 0 "sse_reg_operand")
4632 (match_operand:DF 1 "memory_operand")))]
4633 "TARGET_SPLIT_MEM_OPND_FOR_FP_CONVERTS
4634 && optimize_insn_for_speed_p ()"
4635 [(set (match_dup 2) (match_dup 1))
4636 (set (match_dup 0) (float_truncate:SF (match_dup 2)))]
4637 "operands[2] = lowpart_subreg (DFmode, operands[0], SFmode);")
4639 (define_expand "truncdfsf2_with_temp"
4640 [(parallel [(set (match_operand:SF 0)
4641 (float_truncate:SF (match_operand:DF 1)))
4642 (clobber (match_operand:SF 2))])])
4644 ;; SSE alternative doesn't depend on flag_unsafe_math_optimizations,
4645 ;; because nothing we do there is unsafe.
4646 (define_insn "*truncdfsf_fast_mixed"
4647 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm,v")
4649 (match_operand:DF 1 "nonimmediate_operand" "f ,vm")))]
4650 "TARGET_SSE2 && TARGET_SSE_MATH"
4652 switch (which_alternative)
4655 return output_387_reg_move (insn, operands);
4657 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4662 [(set_attr "type" "fmov,ssecvt")
4663 (set_attr "prefix" "orig,maybe_vex")
4664 (set_attr "mode" "SF")
4665 (set (attr "enabled")
4666 (cond [(eq_attr "alternative" "0")
4667 (symbol_ref "TARGET_MIX_SSE_I387
4668 && flag_unsafe_math_optimizations")
4670 (symbol_ref "true")))])
4672 (define_insn "*truncdfsf_fast_i387"
4673 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm")
4675 (match_operand:DF 1 "nonimmediate_operand" "f")))]
4676 "TARGET_80387 && flag_unsafe_math_optimizations"
4677 "* return output_387_reg_move (insn, operands);"
4678 [(set_attr "type" "fmov")
4679 (set_attr "mode" "SF")])
4681 (define_insn "*truncdfsf_mixed"
4682 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,v ,?f,?v,?*r")
4684 (match_operand:DF 1 "nonimmediate_operand" "f ,vm,f ,f ,f")))
4685 (clobber (match_operand:SF 2 "memory_operand" "=X,X ,m ,m ,m"))]
4686 "TARGET_MIX_SSE_I387"
4688 switch (which_alternative)
4691 return output_387_reg_move (insn, operands);
4693 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4699 [(set_attr "isa" "*,sse2,*,*,*")
4700 (set_attr "type" "fmov,ssecvt,multi,multi,multi")
4701 (set_attr "unit" "*,*,i387,i387,i387")
4702 (set_attr "prefix" "orig,maybe_vex,orig,orig,orig")
4703 (set_attr "mode" "SF")])
4705 (define_insn "*truncdfsf_i387"
4706 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?v,?*r")
4708 (match_operand:DF 1 "nonimmediate_operand" "f ,f ,f ,f")))
4709 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,m ,m"))]
4712 switch (which_alternative)
4715 return output_387_reg_move (insn, operands);
4721 [(set_attr "type" "fmov,multi,multi,multi")
4722 (set_attr "unit" "*,i387,i387,i387")
4723 (set_attr "mode" "SF")])
4725 (define_insn "*truncdfsf2_i387_1"
4726 [(set (match_operand:SF 0 "memory_operand" "=m")
4728 (match_operand:DF 1 "register_operand" "f")))]
4730 && !(TARGET_SSE2 && TARGET_SSE_MATH)
4731 && !TARGET_MIX_SSE_I387"
4732 "* return output_387_reg_move (insn, operands);"
4733 [(set_attr "type" "fmov")
4734 (set_attr "mode" "SF")])
4737 [(set (match_operand:SF 0 "register_operand")
4739 (match_operand:DF 1 "fp_register_operand")))
4740 (clobber (match_operand 2))]
4742 [(set (match_dup 2) (match_dup 1))
4743 (set (match_dup 0) (match_dup 2))]
4744 "operands[1] = gen_rtx_REG (SFmode, REGNO (operands[1]));")
4746 ;; Conversion from XFmode to {SF,DF}mode
4748 (define_expand "truncxf<mode>2"
4749 [(parallel [(set (match_operand:MODEF 0 "nonimmediate_operand")
4750 (float_truncate:MODEF
4751 (match_operand:XF 1 "register_operand")))
4752 (clobber (match_dup 2))])]
4755 if (flag_unsafe_math_optimizations)
4757 rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (<MODE>mode);
4758 emit_insn (gen_truncxf<mode>2_i387_noop (reg, operands[1]));
4759 if (reg != operands[0])
4760 emit_move_insn (operands[0], reg);
4764 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4767 (define_insn "*truncxfsf2_mixed"
4768 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?v,?*r")
4770 (match_operand:XF 1 "register_operand" "f ,f ,f ,f")))
4771 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,m ,m"))]
4774 gcc_assert (!which_alternative);
4775 return output_387_reg_move (insn, operands);
4777 [(set_attr "type" "fmov,multi,multi,multi")
4778 (set_attr "unit" "*,i387,i387,i387")
4779 (set_attr "mode" "SF")])
4781 (define_insn "*truncxfdf2_mixed"
4782 [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?v,?*r")
4784 (match_operand:XF 1 "register_operand" "f ,f ,f ,f")))
4785 (clobber (match_operand:DF 2 "memory_operand" "=X,m ,m ,m"))]
4788 gcc_assert (!which_alternative);
4789 return output_387_reg_move (insn, operands);
4791 [(set_attr "isa" "*,*,sse2,*")
4792 (set_attr "type" "fmov,multi,multi,multi")
4793 (set_attr "unit" "*,i387,i387,i387")
4794 (set_attr "mode" "DF")])
4796 (define_insn "truncxf<mode>2_i387_noop"
4797 [(set (match_operand:MODEF 0 "register_operand" "=f")
4798 (float_truncate:MODEF
4799 (match_operand:XF 1 "register_operand" "f")))]
4800 "TARGET_80387 && flag_unsafe_math_optimizations"
4801 "* return output_387_reg_move (insn, operands);"
4802 [(set_attr "type" "fmov")
4803 (set_attr "mode" "<MODE>")])
4805 (define_insn "*truncxf<mode>2_i387"
4806 [(set (match_operand:MODEF 0 "memory_operand" "=m")
4807 (float_truncate:MODEF
4808 (match_operand:XF 1 "register_operand" "f")))]
4810 "* return output_387_reg_move (insn, operands);"
4811 [(set_attr "type" "fmov")
4812 (set_attr "mode" "<MODE>")])
4815 [(set (match_operand:MODEF 0 "register_operand")
4816 (float_truncate:MODEF
4817 (match_operand:XF 1 "register_operand")))
4818 (clobber (match_operand:MODEF 2 "memory_operand"))]
4819 "TARGET_80387 && reload_completed"
4820 [(set (match_dup 2) (float_truncate:MODEF (match_dup 1)))
4821 (set (match_dup 0) (match_dup 2))])
4824 [(set (match_operand:MODEF 0 "memory_operand")
4825 (float_truncate:MODEF
4826 (match_operand:XF 1 "register_operand")))
4827 (clobber (match_operand:MODEF 2 "memory_operand"))]
4829 [(set (match_dup 0) (float_truncate:MODEF (match_dup 1)))])
4831 ;; Signed conversion to DImode.
4833 (define_expand "fix_truncxfdi2"
4834 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand")
4835 (fix:DI (match_operand:XF 1 "register_operand")))
4836 (clobber (reg:CC FLAGS_REG))])]
4841 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4846 (define_expand "fix_trunc<mode>di2"
4847 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand")
4848 (fix:DI (match_operand:MODEF 1 "register_operand")))
4849 (clobber (reg:CC FLAGS_REG))])]
4850 "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4853 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4855 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4858 if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4860 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4861 emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4862 if (out != operands[0])
4863 emit_move_insn (operands[0], out);
4868 ;; Signed conversion to SImode.
4870 (define_expand "fix_truncxfsi2"
4871 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand")
4872 (fix:SI (match_operand:XF 1 "register_operand")))
4873 (clobber (reg:CC FLAGS_REG))])]
4878 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4883 (define_expand "fix_trunc<mode>si2"
4884 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand")
4885 (fix:SI (match_operand:MODEF 1 "register_operand")))
4886 (clobber (reg:CC FLAGS_REG))])]
4887 "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4890 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4892 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4895 if (SSE_FLOAT_MODE_P (<MODE>mode))
4897 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4898 emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4899 if (out != operands[0])
4900 emit_move_insn (operands[0], out);
4905 ;; Signed conversion to HImode.
4907 (define_expand "fix_trunc<mode>hi2"
4908 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand")
4909 (fix:HI (match_operand:X87MODEF 1 "register_operand")))
4910 (clobber (reg:CC FLAGS_REG))])]
4912 && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4916 emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4921 ;; Unsigned conversion to SImode.
4923 (define_expand "fixuns_trunc<mode>si2"
4925 [(set (match_operand:SI 0 "register_operand")
4927 (match_operand:MODEF 1 "nonimmediate_operand")))
4929 (clobber (match_scratch:<ssevecmode> 3))
4930 (clobber (match_scratch:<ssevecmode> 4))])]
4931 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4933 machine_mode mode = <MODE>mode;
4934 machine_mode vecmode = <ssevecmode>mode;
4935 REAL_VALUE_TYPE TWO31r;
4938 if (optimize_insn_for_size_p ())
4941 real_ldexp (&TWO31r, &dconst1, 31);
4942 two31 = const_double_from_real_value (TWO31r, mode);
4943 two31 = ix86_build_const_vector (vecmode, true, two31);
4944 operands[2] = force_reg (vecmode, two31);
4947 (define_insn_and_split "*fixuns_trunc<mode>_1"
4948 [(set (match_operand:SI 0 "register_operand" "=&x,&x")
4950 (match_operand:MODEF 3 "nonimmediate_operand" "xm,xm")))
4951 (use (match_operand:<ssevecmode> 4 "nonimmediate_operand" "m,x"))
4952 (clobber (match_scratch:<ssevecmode> 1 "=x,&x"))
4953 (clobber (match_scratch:<ssevecmode> 2 "=x,x"))]
4954 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH
4955 && optimize_function_for_speed_p (cfun)"
4957 "&& reload_completed"
4960 ix86_split_convert_uns_si_sse (operands);
4964 ;; Unsigned conversion to HImode.
4965 ;; Without these patterns, we'll try the unsigned SI conversion which
4966 ;; is complex for SSE, rather than the signed SI conversion, which isn't.
4968 (define_expand "fixuns_trunc<mode>hi2"
4970 (fix:SI (match_operand:MODEF 1 "nonimmediate_operand")))
4971 (set (match_operand:HI 0 "nonimmediate_operand")
4972 (subreg:HI (match_dup 2) 0))]
4973 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
4974 "operands[2] = gen_reg_rtx (SImode);")
4976 ;; When SSE is available, it is always faster to use it!
4977 (define_insn "fix_trunc<MODEF:mode><SWI48:mode>_sse"
4978 [(set (match_operand:SWI48 0 "register_operand" "=r,r")
4979 (fix:SWI48 (match_operand:MODEF 1 "nonimmediate_operand" "v,m")))]
4980 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode)
4981 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4982 "%vcvtt<MODEF:ssemodesuffix>2si<SWI48:rex64suffix>\t{%1, %0|%0, %1}"
4983 [(set_attr "type" "sseicvt")
4984 (set_attr "prefix" "maybe_vex")
4985 (set (attr "prefix_rex")
4987 (match_test "<SWI48:MODE>mode == DImode")
4989 (const_string "*")))
4990 (set_attr "mode" "<MODEF:MODE>")
4991 (set_attr "athlon_decode" "double,vector")
4992 (set_attr "amdfam10_decode" "double,double")
4993 (set_attr "bdver1_decode" "double,double")])
4995 ;; Avoid vector decoded forms of the instruction.
4997 [(match_scratch:MODEF 2 "x")
4998 (set (match_operand:SWI48 0 "register_operand")
4999 (fix:SWI48 (match_operand:MODEF 1 "memory_operand")))]
5000 "TARGET_AVOID_VECTOR_DECODE
5001 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode)
5002 && optimize_insn_for_speed_p ()"
5003 [(set (match_dup 2) (match_dup 1))
5004 (set (match_dup 0) (fix:SWI48 (match_dup 2)))])
5006 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
5007 [(set (match_operand:SWI248x 0 "nonimmediate_operand")
5008 (fix:SWI248x (match_operand 1 "register_operand")))]
5009 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5011 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
5012 && (TARGET_64BIT || <MODE>mode != DImode))
5014 && can_create_pseudo_p ()"
5019 if (memory_operand (operands[0], VOIDmode))
5020 emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
5023 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
5024 emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
5030 [(set_attr "type" "fisttp")
5031 (set_attr "mode" "<MODE>")])
5033 (define_insn "fix_trunc<mode>_i387_fisttp"
5034 [(set (match_operand:SWI248x 0 "memory_operand" "=m")
5035 (fix:SWI248x (match_operand 1 "register_operand" "f")))
5036 (clobber (match_scratch:XF 2 "=&1f"))]
5037 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5039 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
5040 && (TARGET_64BIT || <MODE>mode != DImode))
5041 && TARGET_SSE_MATH)"
5042 "* return output_fix_trunc (insn, operands, true);"
5043 [(set_attr "type" "fisttp")
5044 (set_attr "mode" "<MODE>")])
5046 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
5047 [(set (match_operand:SWI248x 0 "nonimmediate_operand" "=m,?r")
5048 (fix:SWI248x (match_operand 1 "register_operand" "f,f")))
5049 (clobber (match_operand:SWI248x 2 "memory_operand" "=X,m"))
5050 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
5051 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5053 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
5054 && (TARGET_64BIT || <MODE>mode != DImode))
5055 && TARGET_SSE_MATH)"
5057 [(set_attr "type" "fisttp")
5058 (set_attr "mode" "<MODE>")])
5061 [(set (match_operand:SWI248x 0 "register_operand")
5062 (fix:SWI248x (match_operand 1 "register_operand")))
5063 (clobber (match_operand:SWI248x 2 "memory_operand"))
5064 (clobber (match_scratch 3))]
5066 [(parallel [(set (match_dup 2) (fix:SWI248x (match_dup 1)))
5067 (clobber (match_dup 3))])
5068 (set (match_dup 0) (match_dup 2))])
5071 [(set (match_operand:SWI248x 0 "memory_operand")
5072 (fix:SWI248x (match_operand 1 "register_operand")))
5073 (clobber (match_operand:SWI248x 2 "memory_operand"))
5074 (clobber (match_scratch 3))]
5076 [(parallel [(set (match_dup 0) (fix:SWI248x (match_dup 1)))
5077 (clobber (match_dup 3))])])
5079 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
5080 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
5081 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
5082 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
5083 ;; function in i386.c.
5084 (define_insn_and_split "*fix_trunc<mode>_i387_1"
5085 [(set (match_operand:SWI248x 0 "nonimmediate_operand")
5086 (fix:SWI248x (match_operand 1 "register_operand")))
5087 (clobber (reg:CC FLAGS_REG))]
5088 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5090 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
5091 && (TARGET_64BIT || <MODE>mode != DImode))
5092 && can_create_pseudo_p ()"
5097 ix86_optimize_mode_switching[I387_TRUNC] = 1;
5099 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
5100 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
5101 if (memory_operand (operands[0], VOIDmode))
5102 emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
5103 operands[2], operands[3]));
5106 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
5107 emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
5108 operands[2], operands[3],
5113 [(set_attr "type" "fistp")
5114 (set_attr "i387_cw" "trunc")
5115 (set_attr "mode" "<MODE>")])
5117 (define_insn "fix_truncdi_i387"
5118 [(set (match_operand:DI 0 "memory_operand" "=m")
5119 (fix:DI (match_operand 1 "register_operand" "f")))
5120 (use (match_operand:HI 2 "memory_operand" "m"))
5121 (use (match_operand:HI 3 "memory_operand" "m"))
5122 (clobber (match_scratch:XF 4 "=&1f"))]
5123 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5125 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
5126 "* return output_fix_trunc (insn, operands, false);"
5127 [(set_attr "type" "fistp")
5128 (set_attr "i387_cw" "trunc")
5129 (set_attr "mode" "DI")])
5131 (define_insn "fix_truncdi_i387_with_temp"
5132 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
5133 (fix:DI (match_operand 1 "register_operand" "f,f")))
5134 (use (match_operand:HI 2 "memory_operand" "m,m"))
5135 (use (match_operand:HI 3 "memory_operand" "m,m"))
5136 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
5137 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
5138 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5140 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
5142 [(set_attr "type" "fistp")
5143 (set_attr "i387_cw" "trunc")
5144 (set_attr "mode" "DI")])
5147 [(set (match_operand:DI 0 "register_operand")
5148 (fix:DI (match_operand 1 "register_operand")))
5149 (use (match_operand:HI 2 "memory_operand"))
5150 (use (match_operand:HI 3 "memory_operand"))
5151 (clobber (match_operand:DI 4 "memory_operand"))
5152 (clobber (match_scratch 5))]
5154 [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
5157 (clobber (match_dup 5))])
5158 (set (match_dup 0) (match_dup 4))])
5161 [(set (match_operand:DI 0 "memory_operand")
5162 (fix:DI (match_operand 1 "register_operand")))
5163 (use (match_operand:HI 2 "memory_operand"))
5164 (use (match_operand:HI 3 "memory_operand"))
5165 (clobber (match_operand:DI 4 "memory_operand"))
5166 (clobber (match_scratch 5))]
5168 [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
5171 (clobber (match_dup 5))])])
5173 (define_insn "fix_trunc<mode>_i387"
5174 [(set (match_operand:SWI24 0 "memory_operand" "=m")
5175 (fix:SWI24 (match_operand 1 "register_operand" "f")))
5176 (use (match_operand:HI 2 "memory_operand" "m"))
5177 (use (match_operand:HI 3 "memory_operand" "m"))]
5178 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5180 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
5181 "* return output_fix_trunc (insn, operands, false);"
5182 [(set_attr "type" "fistp")
5183 (set_attr "i387_cw" "trunc")
5184 (set_attr "mode" "<MODE>")])
5186 (define_insn "fix_trunc<mode>_i387_with_temp"
5187 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
5188 (fix:SWI24 (match_operand 1 "register_operand" "f,f")))
5189 (use (match_operand:HI 2 "memory_operand" "m,m"))
5190 (use (match_operand:HI 3 "memory_operand" "m,m"))
5191 (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
5192 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5194 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
5196 [(set_attr "type" "fistp")
5197 (set_attr "i387_cw" "trunc")
5198 (set_attr "mode" "<MODE>")])
5201 [(set (match_operand:SWI24 0 "register_operand")
5202 (fix:SWI24 (match_operand 1 "register_operand")))
5203 (use (match_operand:HI 2 "memory_operand"))
5204 (use (match_operand:HI 3 "memory_operand"))
5205 (clobber (match_operand:SWI24 4 "memory_operand"))]
5207 [(parallel [(set (match_dup 4) (fix:SWI24 (match_dup 1)))
5209 (use (match_dup 3))])
5210 (set (match_dup 0) (match_dup 4))])
5213 [(set (match_operand:SWI24 0 "memory_operand")
5214 (fix:SWI24 (match_operand 1 "register_operand")))
5215 (use (match_operand:HI 2 "memory_operand"))
5216 (use (match_operand:HI 3 "memory_operand"))
5217 (clobber (match_operand:SWI24 4 "memory_operand"))]
5219 [(parallel [(set (match_dup 0) (fix:SWI24 (match_dup 1)))
5221 (use (match_dup 3))])])
5223 (define_insn "x86_fnstcw_1"
5224 [(set (match_operand:HI 0 "memory_operand" "=m")
5225 (unspec:HI [(reg:HI FPCR_REG)] UNSPEC_FSTCW))]
5228 [(set (attr "length")
5229 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
5230 (set_attr "mode" "HI")
5231 (set_attr "unit" "i387")
5232 (set_attr "bdver1_decode" "vector")])
5234 (define_insn "x86_fldcw_1"
5235 [(set (reg:HI FPCR_REG)
5236 (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
5239 [(set (attr "length")
5240 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
5241 (set_attr "mode" "HI")
5242 (set_attr "unit" "i387")
5243 (set_attr "athlon_decode" "vector")
5244 (set_attr "amdfam10_decode" "vector")
5245 (set_attr "bdver1_decode" "vector")])
5247 ;; Conversion between fixed point and floating point.
5249 ;; Even though we only accept memory inputs, the backend _really_
5250 ;; wants to be able to do this between registers. Thankfully, LRA
5251 ;; will fix this up for us during register allocation.
5253 (define_insn "floathi<mode>2"
5254 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5255 (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "m")))]
5257 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5258 || TARGET_MIX_SSE_I387)"
5260 [(set_attr "type" "fmov")
5261 (set_attr "mode" "<MODE>")
5262 (set_attr "znver1_decode" "double")
5263 (set_attr "fp_int_src" "true")])
5265 (define_insn "float<SWI48x:mode>xf2"
5266 [(set (match_operand:XF 0 "register_operand" "=f")
5267 (float:XF (match_operand:SWI48x 1 "nonimmediate_operand" "m")))]
5270 [(set_attr "type" "fmov")
5271 (set_attr "mode" "XF")
5272 (set_attr "znver1_decode" "double")
5273 (set_attr "fp_int_src" "true")])
5275 (define_expand "float<SWI48:mode><MODEF:mode>2"
5276 [(set (match_operand:MODEF 0 "register_operand")
5277 (float:MODEF (match_operand:SWI48 1 "nonimmediate_operand")))]
5278 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)"
5280 if (!(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
5281 && !X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI48:MODE>mode))
5283 rtx reg = gen_reg_rtx (XFmode);
5284 rtx (*insn)(rtx, rtx);
5286 emit_insn (gen_float<SWI48:mode>xf2 (reg, operands[1]));
5288 if (<MODEF:MODE>mode == SFmode)
5289 insn = gen_truncxfsf2;
5290 else if (<MODEF:MODE>mode == DFmode)
5291 insn = gen_truncxfdf2;
5295 emit_insn (insn (operands[0], reg));
5300 (define_insn "*float<SWI48:mode><MODEF:mode>2_mixed"
5301 [(set (match_operand:MODEF 0 "register_operand" "=f,Yc,v")
5303 (match_operand:SWI48 1 "nonimmediate_operand" "m,r,m")))]
5304 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
5307 %vcvtsi2<MODEF:ssemodesuffix><SWI48:rex64suffix>\t{%1, %d0|%d0, %1}
5308 %vcvtsi2<MODEF:ssemodesuffix><SWI48:rex64suffix>\t{%1, %d0|%d0, %1}"
5309 [(set_attr "type" "fmov,sseicvt,sseicvt")
5310 (set_attr "prefix" "orig,maybe_vex,maybe_vex")
5311 (set_attr "mode" "<MODEF:MODE>")
5312 (set (attr "prefix_rex")
5314 (and (eq_attr "prefix" "maybe_vex")
5315 (match_test "<SWI48:MODE>mode == DImode"))
5317 (const_string "*")))
5318 (set_attr "unit" "i387,*,*")
5319 (set_attr "athlon_decode" "*,double,direct")
5320 (set_attr "amdfam10_decode" "*,vector,double")
5321 (set_attr "bdver1_decode" "*,double,direct")
5322 (set_attr "znver1_decode" "double,*,*")
5323 (set_attr "fp_int_src" "true")
5324 (set (attr "enabled")
5325 (cond [(eq_attr "alternative" "0")
5326 (symbol_ref "TARGET_MIX_SSE_I387
5327 && X87_ENABLE_FLOAT (<MODEF:MODE>mode,
5330 (symbol_ref "true")))])
5332 (define_insn "*float<SWI48x:mode><MODEF:mode>2_i387"
5333 [(set (match_operand:MODEF 0 "register_operand" "=f")
5334 (float:MODEF (match_operand:SWI48x 1 "nonimmediate_operand" "m")))]
5335 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI48x:MODE>mode)"
5337 [(set_attr "type" "fmov")
5338 (set_attr "mode" "<MODEF:MODE>")
5339 (set_attr "znver1_decode" "double")
5340 (set_attr "fp_int_src" "true")])
5342 ;; Try TARGET_USE_VECTOR_CONVERTS, but not so hard as to require extra memory
5343 ;; slots when !TARGET_INTER_UNIT_MOVES_TO_VEC disables the general_regs
5344 ;; alternative in sse2_loadld.
5346 [(set (match_operand:MODEF 0 "sse_reg_operand")
5347 (float:MODEF (match_operand:SI 1 "nonimmediate_operand")))]
5349 && TARGET_USE_VECTOR_CONVERTS
5350 && optimize_function_for_speed_p (cfun)
5352 && (MEM_P (operands[1]) || TARGET_INTER_UNIT_MOVES_TO_VEC)
5353 && (!EXT_REX_SSE_REG_P (operands[0])
5354 || TARGET_AVX512VL)"
5357 operands[3] = lowpart_subreg (<ssevecmode>mode, operands[0], <MODE>mode);
5358 operands[4] = lowpart_subreg (V4SImode, operands[0], <MODE>mode);
5360 emit_insn (gen_sse2_loadld (operands[4],
5361 CONST0_RTX (V4SImode), operands[1]));
5363 if (<ssevecmode>mode == V4SFmode)
5364 emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
5366 emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
5370 ;; Avoid partial SSE register dependency stalls. This splitter should split
5371 ;; late in the pass sequence (after register rename pass), so allocated
5372 ;; registers won't change anymore
5375 [(set (match_operand:MODEF 0 "sse_reg_operand")
5376 (float:MODEF (match_operand:SWI48 1 "nonimmediate_operand")))]
5377 "TARGET_SSE_PARTIAL_REG_DEPENDENCY && epilogue_completed
5378 && optimize_function_for_speed_p (cfun)
5379 && (!EXT_REX_SSE_REG_P (operands[0])
5380 || TARGET_AVX512VL)"
5382 (vec_merge:<MODEF:ssevecmode>
5383 (vec_duplicate:<MODEF:ssevecmode>
5389 const machine_mode vmode = <MODEF:ssevecmode>mode;
5391 operands[0] = lowpart_subreg (vmode, operands[0], <MODEF:MODE>mode);
5392 emit_move_insn (operands[0], CONST0_RTX (vmode));
5395 ;; Break partial reg stall for cvtsd2ss. This splitter should split
5396 ;; late in the pass sequence (after register rename pass),
5397 ;; so allocated registers won't change anymore.
5400 [(set (match_operand:SF 0 "sse_reg_operand")
5402 (match_operand:DF 1 "nonimmediate_operand")))]
5403 "TARGET_SSE_PARTIAL_REG_DEPENDENCY && epilogue_completed
5404 && optimize_function_for_speed_p (cfun)
5405 && (!REG_P (operands[1])
5406 || REGNO (operands[0]) != REGNO (operands[1]))
5407 && (!EXT_REX_SSE_REG_P (operands[0])
5408 || TARGET_AVX512VL)"
5417 operands[0] = lowpart_subreg (V4SFmode, operands[0], SFmode);
5418 emit_move_insn (operands[0], CONST0_RTX (V4SFmode));
5421 ;; Break partial reg stall for cvtss2sd. This splitter should split
5422 ;; late in the pass sequence (after register rename pass),
5423 ;; so allocated registers won't change anymore.
5426 [(set (match_operand:DF 0 "sse_reg_operand")
5428 (match_operand:SF 1 "nonimmediate_operand")))]
5429 "TARGET_SSE_PARTIAL_REG_DEPENDENCY && epilogue_completed
5430 && optimize_function_for_speed_p (cfun)
5431 && (!REG_P (operands[1])
5432 || REGNO (operands[0]) != REGNO (operands[1]))
5433 && (!EXT_REX_SSE_REG_P (operands[0])
5434 || TARGET_AVX512VL)"
5443 operands[0] = lowpart_subreg (V2DFmode, operands[0], DFmode);
5444 emit_move_insn (operands[0], CONST0_RTX (V2DFmode));
5447 ;; Avoid store forwarding (partial memory) stall penalty
5448 ;; by passing DImode value through XMM registers. */
5450 (define_insn "floatdi<X87MODEF:mode>2_i387_with_xmm"
5451 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5453 (match_operand:DI 1 "nonimmediate_operand" "m,?r")))
5454 (clobber (match_scratch:V4SI 3 "=X,x"))
5455 (clobber (match_scratch:V4SI 4 "=X,x"))
5456 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))]
5457 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5458 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC
5459 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)"
5461 [(set_attr "type" "multi")
5462 (set_attr "mode" "<X87MODEF:MODE>")
5463 (set_attr "unit" "i387")
5464 (set_attr "fp_int_src" "true")])
5467 [(set (match_operand:X87MODEF 0 "fp_register_operand")
5468 (float:X87MODEF (match_operand:DI 1 "register_operand")))
5469 (clobber (match_scratch:V4SI 3))
5470 (clobber (match_scratch:V4SI 4))
5471 (clobber (match_operand:DI 2 "memory_operand"))]
5472 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5473 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC
5474 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5475 && reload_completed"
5476 [(set (match_dup 2) (match_dup 3))
5477 (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5479 /* The DImode arrived in a pair of integral registers (e.g. %edx:%eax).
5480 Assemble the 64-bit DImode value in an xmm register. */
5481 emit_insn (gen_sse2_loadld (operands[3], CONST0_RTX (V4SImode),
5482 gen_lowpart (SImode, operands[1])));
5483 emit_insn (gen_sse2_loadld (operands[4], CONST0_RTX (V4SImode),
5484 gen_highpart (SImode, operands[1])));
5485 emit_insn (gen_vec_interleave_lowv4si (operands[3], operands[3],
5488 operands[3] = gen_lowpart (DImode, operands[3]);
5492 [(set (match_operand:X87MODEF 0 "fp_register_operand")
5493 (float:X87MODEF (match_operand:DI 1 "memory_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 0) (float:X87MODEF (match_dup 1)))])
5503 (define_expand "floatuns<SWI12:mode><MODEF:mode>2"
5504 [(set (match_operand:MODEF 0 "register_operand")
5505 (unsigned_float:MODEF
5506 (match_operand:SWI12 1 "nonimmediate_operand")))]
5508 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
5510 operands[1] = convert_to_mode (SImode, operands[1], 1);
5511 emit_insn (gen_floatsi<MODEF:mode>2 (operands[0], operands[1]));
5515 ;; Avoid store forwarding (partial memory) stall penalty by extending
5516 ;; SImode value to DImode through XMM register instead of pushing two
5517 ;; SImode values to stack. Also note that fild loads from memory only.
5519 (define_insn_and_split "*floatunssi<mode>2_i387_with_xmm"
5520 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5521 (unsigned_float:X87MODEF
5522 (match_operand:SI 1 "nonimmediate_operand" "rm")))
5523 (clobber (match_scratch:DI 3 "=x"))
5524 (clobber (match_operand:DI 2 "memory_operand" "=m"))]
5526 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5527 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC"
5529 "&& reload_completed"
5530 [(set (match_dup 3) (zero_extend:DI (match_dup 1)))
5531 (set (match_dup 2) (match_dup 3))
5533 (float:X87MODEF (match_dup 2)))]
5535 [(set_attr "type" "multi")
5536 (set_attr "mode" "<MODE>")])
5538 (define_expand "floatunssi<mode>2"
5540 [(set (match_operand:X87MODEF 0 "register_operand")
5541 (unsigned_float:X87MODEF
5542 (match_operand:SI 1 "nonimmediate_operand")))
5543 (clobber (match_scratch:DI 3))
5544 (clobber (match_dup 2))])]
5546 && ((TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5547 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC)
5548 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
5550 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5552 ix86_expand_convert_uns_si<mode>_sse (operands[0], operands[1]);
5556 operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
5559 (define_expand "floatunsdisf2"
5560 [(use (match_operand:SF 0 "register_operand"))
5561 (use (match_operand:DI 1 "nonimmediate_operand"))]
5562 "TARGET_64BIT && TARGET_SSE && TARGET_SSE_MATH"
5563 "x86_emit_floatuns (operands); DONE;")
5565 (define_expand "floatunsdidf2"
5566 [(use (match_operand:DF 0 "register_operand"))
5567 (use (match_operand:DI 1 "nonimmediate_operand"))]
5568 "(TARGET_64BIT || TARGET_KEEPS_VECTOR_ALIGNED_STACK)
5569 && TARGET_SSE2 && TARGET_SSE_MATH"
5572 x86_emit_floatuns (operands);
5574 ix86_expand_convert_uns_didf_sse (operands[0], operands[1]);
5578 ;; Load effective address instructions
5580 (define_insn_and_split "*lea<mode>"
5581 [(set (match_operand:SWI48 0 "register_operand" "=r")
5582 (match_operand:SWI48 1 "address_no_seg_operand" "Ts"))]
5585 if (SImode_address_operand (operands[1], VOIDmode))
5587 gcc_assert (TARGET_64BIT);
5588 return "lea{l}\t{%E1, %k0|%k0, %E1}";
5591 return "lea{<imodesuffix>}\t{%E1, %0|%0, %E1}";
5593 "reload_completed && ix86_avoid_lea_for_addr (insn, operands)"
5596 machine_mode mode = <MODE>mode;
5599 /* ix86_avoid_lea_for_addr re-recognizes insn and may
5600 change operands[] array behind our back. */
5601 pat = PATTERN (curr_insn);
5603 operands[0] = SET_DEST (pat);
5604 operands[1] = SET_SRC (pat);
5606 /* Emit all operations in SImode for zero-extended addresses. */
5607 if (SImode_address_operand (operands[1], VOIDmode))
5610 ix86_split_lea_for_addr (curr_insn, operands, mode);
5612 /* Zero-extend return register to DImode for zero-extended addresses. */
5613 if (mode != <MODE>mode)
5614 emit_insn (gen_zero_extendsidi2
5615 (operands[0], gen_lowpart (mode, operands[0])));
5619 [(set_attr "type" "lea")
5622 (match_operand 1 "SImode_address_operand")
5624 (const_string "<MODE>")))])
5628 (define_expand "add<mode>3"
5629 [(set (match_operand:SDWIM 0 "nonimmediate_operand")
5630 (plus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")
5631 (match_operand:SDWIM 2 "<general_hilo_operand>")))]
5633 "ix86_expand_binary_operator (PLUS, <MODE>mode, operands); DONE;")
5635 (define_insn_and_split "*add<dwi>3_doubleword"
5636 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
5638 (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0")
5639 (match_operand:<DWI> 2 "x86_64_hilo_general_operand"
5641 (clobber (reg:CC FLAGS_REG))]
5642 "ix86_binary_operator_ok (PLUS, <DWI>mode, operands)"
5645 [(parallel [(set (reg:CCC FLAGS_REG)
5647 (plus:DWIH (match_dup 1) (match_dup 2))
5650 (plus:DWIH (match_dup 1) (match_dup 2)))])
5651 (parallel [(set (match_dup 3)
5654 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
5657 (clobber (reg:CC FLAGS_REG))])]
5659 split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
5660 if (operands[2] == const0_rtx)
5662 ix86_expand_binary_operator (PLUS, <MODE>mode, &operands[3]);
5667 (define_insn "*add<mode>_1"
5668 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,rm,r,r")
5670 (match_operand:SWI48 1 "nonimmediate_operand" "%0,0,r,r")
5671 (match_operand:SWI48 2 "x86_64_general_operand" "rme,re,0,le")))
5672 (clobber (reg:CC FLAGS_REG))]
5673 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5675 switch (get_attr_type (insn))
5681 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5682 if (operands[2] == const1_rtx)
5683 return "inc{<imodesuffix>}\t%0";
5686 gcc_assert (operands[2] == constm1_rtx);
5687 return "dec{<imodesuffix>}\t%0";
5691 /* For most processors, ADD is faster than LEA. This alternative
5692 was added to use ADD as much as possible. */
5693 if (which_alternative == 2)
5694 std::swap (operands[1], operands[2]);
5696 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5697 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5698 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5700 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5704 (cond [(eq_attr "alternative" "3")
5705 (const_string "lea")
5706 (match_operand:SWI48 2 "incdec_operand")
5707 (const_string "incdec")
5709 (const_string "alu")))
5710 (set (attr "length_immediate")
5712 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5714 (const_string "*")))
5715 (set_attr "mode" "<MODE>")])
5717 ;; It may seem that nonimmediate operand is proper one for operand 1.
5718 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5719 ;; we take care in ix86_binary_operator_ok to not allow two memory
5720 ;; operands so proper swapping will be done in reload. This allow
5721 ;; patterns constructed from addsi_1 to match.
5723 (define_insn "addsi_1_zext"
5724 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
5726 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r,r")
5727 (match_operand:SI 2 "x86_64_general_operand" "rme,0,le"))))
5728 (clobber (reg:CC FLAGS_REG))]
5729 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5731 switch (get_attr_type (insn))
5737 if (operands[2] == const1_rtx)
5738 return "inc{l}\t%k0";
5741 gcc_assert (operands[2] == constm1_rtx);
5742 return "dec{l}\t%k0";
5746 /* For most processors, ADD is faster than LEA. This alternative
5747 was added to use ADD as much as possible. */
5748 if (which_alternative == 1)
5749 std::swap (operands[1], operands[2]);
5751 if (x86_maybe_negate_const_int (&operands[2], SImode))
5752 return "sub{l}\t{%2, %k0|%k0, %2}";
5754 return "add{l}\t{%2, %k0|%k0, %2}";
5758 (cond [(eq_attr "alternative" "2")
5759 (const_string "lea")
5760 (match_operand:SI 2 "incdec_operand")
5761 (const_string "incdec")
5763 (const_string "alu")))
5764 (set (attr "length_immediate")
5766 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5768 (const_string "*")))
5769 (set_attr "mode" "SI")])
5771 (define_insn "*addhi_1"
5772 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r,Yp")
5773 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r,Yp")
5774 (match_operand:HI 2 "general_operand" "rn,rm,0,ln")))
5775 (clobber (reg:CC FLAGS_REG))]
5776 "ix86_binary_operator_ok (PLUS, HImode, operands)"
5778 switch (get_attr_type (insn))
5784 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5785 if (operands[2] == const1_rtx)
5786 return "inc{w}\t%0";
5789 gcc_assert (operands[2] == constm1_rtx);
5790 return "dec{w}\t%0";
5794 /* For most processors, ADD is faster than LEA. This alternative
5795 was added to use ADD as much as possible. */
5796 if (which_alternative == 2)
5797 std::swap (operands[1], operands[2]);
5799 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5800 if (x86_maybe_negate_const_int (&operands[2], HImode))
5801 return "sub{w}\t{%2, %0|%0, %2}";
5803 return "add{w}\t{%2, %0|%0, %2}";
5807 (cond [(eq_attr "alternative" "3")
5808 (const_string "lea")
5809 (match_operand:HI 2 "incdec_operand")
5810 (const_string "incdec")
5812 (const_string "alu")))
5813 (set (attr "length_immediate")
5815 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5817 (const_string "*")))
5818 (set_attr "mode" "HI,HI,HI,SI")])
5820 (define_insn "*addqi_1"
5821 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,q,r,r,Yp")
5822 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,q,0,r,Yp")
5823 (match_operand:QI 2 "general_operand" "qn,qm,0,rn,0,ln")))
5824 (clobber (reg:CC FLAGS_REG))]
5825 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5827 bool widen = (get_attr_mode (insn) != MODE_QI);
5829 switch (get_attr_type (insn))
5835 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5836 if (operands[2] == const1_rtx)
5837 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
5840 gcc_assert (operands[2] == constm1_rtx);
5841 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
5845 /* For most processors, ADD is faster than LEA. These alternatives
5846 were added to use ADD as much as possible. */
5847 if (which_alternative == 2 || which_alternative == 4)
5848 std::swap (operands[1], operands[2]);
5850 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5851 if (x86_maybe_negate_const_int (&operands[2], QImode))
5854 return "sub{l}\t{%2, %k0|%k0, %2}";
5856 return "sub{b}\t{%2, %0|%0, %2}";
5859 return "add{l}\t{%k2, %k0|%k0, %k2}";
5861 return "add{b}\t{%2, %0|%0, %2}";
5865 (cond [(eq_attr "alternative" "5")
5866 (const_string "lea")
5867 (match_operand:QI 2 "incdec_operand")
5868 (const_string "incdec")
5870 (const_string "alu")))
5871 (set (attr "length_immediate")
5873 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5875 (const_string "*")))
5876 (set_attr "mode" "QI,QI,QI,SI,SI,SI")
5877 ;; Potential partial reg stall on alternatives 3 and 4.
5878 (set (attr "preferred_for_speed")
5879 (cond [(eq_attr "alternative" "3,4")
5880 (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
5881 (symbol_ref "true")))])
5883 (define_insn "*addqi_1_slp"
5884 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
5885 (plus:QI (match_dup 0)
5886 (match_operand:QI 1 "general_operand" "qn,qm")))
5887 (clobber (reg:CC FLAGS_REG))]
5888 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
5889 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
5891 switch (get_attr_type (insn))
5894 if (operands[1] == const1_rtx)
5895 return "inc{b}\t%0";
5898 gcc_assert (operands[1] == constm1_rtx);
5899 return "dec{b}\t%0";
5903 if (x86_maybe_negate_const_int (&operands[1], QImode))
5904 return "sub{b}\t{%1, %0|%0, %1}";
5906 return "add{b}\t{%1, %0|%0, %1}";
5910 (if_then_else (match_operand:QI 1 "incdec_operand")
5911 (const_string "incdec")
5912 (const_string "alu1")))
5913 (set (attr "memory")
5914 (if_then_else (match_operand 1 "memory_operand")
5915 (const_string "load")
5916 (const_string "none")))
5917 (set_attr "mode" "QI")])
5919 ;; Split non destructive adds if we cannot use lea.
5921 [(set (match_operand:SWI48 0 "register_operand")
5922 (plus:SWI48 (match_operand:SWI48 1 "register_operand")
5923 (match_operand:SWI48 2 "x86_64_nonmemory_operand")))
5924 (clobber (reg:CC FLAGS_REG))]
5925 "reload_completed && ix86_avoid_lea_for_add (insn, operands)"
5926 [(set (match_dup 0) (match_dup 1))
5927 (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 2)))
5928 (clobber (reg:CC FLAGS_REG))])])
5930 ;; Split non destructive adds if we cannot use lea.
5932 [(set (match_operand:DI 0 "register_operand")
5934 (plus:SI (match_operand:SI 1 "register_operand")
5935 (match_operand:SI 2 "x86_64_nonmemory_operand"))))
5936 (clobber (reg:CC FLAGS_REG))]
5938 && reload_completed && ix86_avoid_lea_for_add (insn, operands)"
5939 [(set (match_dup 3) (match_dup 1))
5940 (parallel [(set (match_dup 0)
5941 (zero_extend:DI (plus:SI (match_dup 3) (match_dup 2))))
5942 (clobber (reg:CC FLAGS_REG))])]
5943 "operands[3] = gen_lowpart (SImode, operands[0]);")
5945 ;; Convert add to the lea pattern to avoid flags dependency.
5947 [(set (match_operand:SWI 0 "register_operand")
5948 (plus:SWI (match_operand:SWI 1 "register_operand")
5949 (match_operand:SWI 2 "<nonmemory_operand>")))
5950 (clobber (reg:CC FLAGS_REG))]
5951 "reload_completed && ix86_lea_for_add_ok (insn, operands)"
5953 (plus:<LEAMODE> (match_dup 1) (match_dup 2)))]
5955 if (<MODE>mode != <LEAMODE>mode)
5957 operands[0] = gen_lowpart (<LEAMODE>mode, operands[0]);
5958 operands[1] = gen_lowpart (<LEAMODE>mode, operands[1]);
5959 operands[2] = gen_lowpart (<LEAMODE>mode, operands[2]);
5963 ;; Convert add to the lea pattern to avoid flags dependency.
5965 [(set (match_operand:DI 0 "register_operand")
5967 (plus:SI (match_operand:SI 1 "register_operand")
5968 (match_operand:SI 2 "x86_64_nonmemory_operand"))))
5969 (clobber (reg:CC FLAGS_REG))]
5970 "TARGET_64BIT && reload_completed && ix86_lea_for_add_ok (insn, operands)"
5972 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))])
5974 (define_insn "*add<mode>_2"
5975 [(set (reg FLAGS_REG)
5978 (match_operand:SWI 1 "nonimmediate_operand" "%0,0,<r>")
5979 (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>,0"))
5981 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m,<r>")
5982 (plus:SWI (match_dup 1) (match_dup 2)))]
5983 "ix86_match_ccmode (insn, CCGOCmode)
5984 && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5986 switch (get_attr_type (insn))
5989 if (operands[2] == const1_rtx)
5990 return "inc{<imodesuffix>}\t%0";
5993 gcc_assert (operands[2] == constm1_rtx);
5994 return "dec{<imodesuffix>}\t%0";
5998 if (which_alternative == 2)
5999 std::swap (operands[1], operands[2]);
6001 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6002 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6003 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6005 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6009 (if_then_else (match_operand:SWI 2 "incdec_operand")
6010 (const_string "incdec")
6011 (const_string "alu")))
6012 (set (attr "length_immediate")
6014 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6016 (const_string "*")))
6017 (set_attr "mode" "<MODE>")])
6019 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6020 (define_insn "*addsi_2_zext"
6021 [(set (reg FLAGS_REG)
6023 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
6024 (match_operand:SI 2 "x86_64_general_operand" "rme,0"))
6026 (set (match_operand:DI 0 "register_operand" "=r,r")
6027 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6028 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6029 && ix86_binary_operator_ok (PLUS, SImode, operands)"
6031 switch (get_attr_type (insn))
6034 if (operands[2] == const1_rtx)
6035 return "inc{l}\t%k0";
6038 gcc_assert (operands[2] == constm1_rtx);
6039 return "dec{l}\t%k0";
6043 if (which_alternative == 1)
6044 std::swap (operands[1], operands[2]);
6046 if (x86_maybe_negate_const_int (&operands[2], SImode))
6047 return "sub{l}\t{%2, %k0|%k0, %2}";
6049 return "add{l}\t{%2, %k0|%k0, %2}";
6053 (if_then_else (match_operand:SI 2 "incdec_operand")
6054 (const_string "incdec")
6055 (const_string "alu")))
6056 (set (attr "length_immediate")
6058 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6060 (const_string "*")))
6061 (set_attr "mode" "SI")])
6063 (define_insn "*add<mode>_3"
6064 [(set (reg FLAGS_REG)
6066 (neg:SWI (match_operand:SWI 2 "<general_operand>" "<g>,0"))
6067 (match_operand:SWI 1 "nonimmediate_operand" "%0,<r>")))
6068 (clobber (match_scratch:SWI 0 "=<r>,<r>"))]
6069 "ix86_match_ccmode (insn, CCZmode)
6070 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6072 switch (get_attr_type (insn))
6075 if (operands[2] == const1_rtx)
6076 return "inc{<imodesuffix>}\t%0";
6079 gcc_assert (operands[2] == constm1_rtx);
6080 return "dec{<imodesuffix>}\t%0";
6084 if (which_alternative == 1)
6085 std::swap (operands[1], operands[2]);
6087 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6088 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6089 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6091 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6095 (if_then_else (match_operand:SWI 2 "incdec_operand")
6096 (const_string "incdec")
6097 (const_string "alu")))
6098 (set (attr "length_immediate")
6100 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6102 (const_string "*")))
6103 (set_attr "mode" "<MODE>")])
6105 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6106 (define_insn "*addsi_3_zext"
6107 [(set (reg FLAGS_REG)
6109 (neg:SI (match_operand:SI 2 "x86_64_general_operand" "rme,0"))
6110 (match_operand:SI 1 "nonimmediate_operand" "%0,r")))
6111 (set (match_operand:DI 0 "register_operand" "=r,r")
6112 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6113 "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
6114 && ix86_binary_operator_ok (PLUS, SImode, operands)"
6116 switch (get_attr_type (insn))
6119 if (operands[2] == const1_rtx)
6120 return "inc{l}\t%k0";
6123 gcc_assert (operands[2] == constm1_rtx);
6124 return "dec{l}\t%k0";
6128 if (which_alternative == 1)
6129 std::swap (operands[1], operands[2]);
6131 if (x86_maybe_negate_const_int (&operands[2], SImode))
6132 return "sub{l}\t{%2, %k0|%k0, %2}";
6134 return "add{l}\t{%2, %k0|%k0, %2}";
6138 (if_then_else (match_operand:SI 2 "incdec_operand")
6139 (const_string "incdec")
6140 (const_string "alu")))
6141 (set (attr "length_immediate")
6143 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6145 (const_string "*")))
6146 (set_attr "mode" "SI")])
6148 ; For comparisons against 1, -1 and 128, we may generate better code
6149 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
6150 ; is matched then. We can't accept general immediate, because for
6151 ; case of overflows, the result is messed up.
6152 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6153 ; only for comparisons not depending on it.
6155 (define_insn "*adddi_4"
6156 [(set (reg FLAGS_REG)
6158 (match_operand:DI 1 "nonimmediate_operand" "0")
6159 (match_operand:DI 2 "x86_64_immediate_operand" "e")))
6160 (clobber (match_scratch:DI 0 "=rm"))]
6162 && ix86_match_ccmode (insn, CCGCmode)"
6164 switch (get_attr_type (insn))
6167 if (operands[2] == constm1_rtx)
6168 return "inc{q}\t%0";
6171 gcc_assert (operands[2] == const1_rtx);
6172 return "dec{q}\t%0";
6176 if (x86_maybe_negate_const_int (&operands[2], DImode))
6177 return "add{q}\t{%2, %0|%0, %2}";
6179 return "sub{q}\t{%2, %0|%0, %2}";
6183 (if_then_else (match_operand:DI 2 "incdec_operand")
6184 (const_string "incdec")
6185 (const_string "alu")))
6186 (set (attr "length_immediate")
6188 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6190 (const_string "*")))
6191 (set_attr "mode" "DI")])
6193 ; For comparisons against 1, -1 and 128, we may generate better code
6194 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
6195 ; is matched then. We can't accept general immediate, because for
6196 ; case of overflows, the result is messed up.
6197 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6198 ; only for comparisons not depending on it.
6200 (define_insn "*add<mode>_4"
6201 [(set (reg FLAGS_REG)
6203 (match_operand:SWI124 1 "nonimmediate_operand" "0")
6204 (match_operand:SWI124 2 "const_int_operand" "n")))
6205 (clobber (match_scratch:SWI124 0 "=<r>m"))]
6206 "ix86_match_ccmode (insn, CCGCmode)"
6208 switch (get_attr_type (insn))
6211 if (operands[2] == constm1_rtx)
6212 return "inc{<imodesuffix>}\t%0";
6215 gcc_assert (operands[2] == const1_rtx);
6216 return "dec{<imodesuffix>}\t%0";
6220 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6221 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6223 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6227 (if_then_else (match_operand:<MODE> 2 "incdec_operand")
6228 (const_string "incdec")
6229 (const_string "alu")))
6230 (set (attr "length_immediate")
6232 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6234 (const_string "*")))
6235 (set_attr "mode" "<MODE>")])
6237 (define_insn "*add<mode>_5"
6238 [(set (reg FLAGS_REG)
6241 (match_operand:SWI 1 "nonimmediate_operand" "%0,<r>")
6242 (match_operand:SWI 2 "<general_operand>" "<g>,0"))
6244 (clobber (match_scratch:SWI 0 "=<r>,<r>"))]
6245 "ix86_match_ccmode (insn, CCGOCmode)
6246 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6248 switch (get_attr_type (insn))
6251 if (operands[2] == const1_rtx)
6252 return "inc{<imodesuffix>}\t%0";
6255 gcc_assert (operands[2] == constm1_rtx);
6256 return "dec{<imodesuffix>}\t%0";
6260 if (which_alternative == 1)
6261 std::swap (operands[1], operands[2]);
6263 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6264 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6265 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6267 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6271 (if_then_else (match_operand:SWI 2 "incdec_operand")
6272 (const_string "incdec")
6273 (const_string "alu")))
6274 (set (attr "length_immediate")
6276 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6278 (const_string "*")))
6279 (set_attr "mode" "<MODE>")])
6281 (define_insn "addqi_ext_1"
6282 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q,Q")
6288 (zero_extract:SI (match_operand 1 "ext_register_operand" "0,0")
6291 (match_operand:QI 2 "general_operand" "QnBc,m")) 0))
6292 (clobber (reg:CC FLAGS_REG))]
6293 "/* FIXME: without this LRA can't reload this pattern, see PR82524. */
6294 rtx_equal_p (operands[0], operands[1])"
6296 switch (get_attr_type (insn))
6299 if (operands[2] == const1_rtx)
6300 return "inc{b}\t%h0";
6303 gcc_assert (operands[2] == constm1_rtx);
6304 return "dec{b}\t%h0";
6308 return "add{b}\t{%2, %h0|%h0, %2}";
6311 [(set_attr "isa" "*,nox64")
6313 (if_then_else (match_operand:QI 2 "incdec_operand")
6314 (const_string "incdec")
6315 (const_string "alu")))
6316 (set_attr "mode" "QI")])
6318 (define_insn "*addqi_ext_2"
6319 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
6325 (zero_extract:SI (match_operand 1 "ext_register_operand" "%0")
6329 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
6331 (const_int 8)) 0)) 0))
6332 (clobber (reg:CC FLAGS_REG))]
6333 "/* FIXME: without this LRA can't reload this pattern, see PR82524. */
6334 rtx_equal_p (operands[0], operands[1])
6335 || rtx_equal_p (operands[0], operands[2])"
6336 "add{b}\t{%h2, %h0|%h0, %h2}"
6337 [(set_attr "type" "alu")
6338 (set_attr "mode" "QI")])
6340 ;; Add with jump on overflow.
6341 (define_expand "addv<mode>4"
6342 [(parallel [(set (reg:CCO FLAGS_REG)
6345 (match_operand:SWI 1 "nonimmediate_operand"))
6348 (plus:SWI (match_dup 1)
6349 (match_operand:SWI 2
6350 "<general_operand>")))))
6351 (set (match_operand:SWI 0 "register_operand")
6352 (plus:SWI (match_dup 1) (match_dup 2)))])
6353 (set (pc) (if_then_else
6354 (eq (reg:CCO FLAGS_REG) (const_int 0))
6355 (label_ref (match_operand 3))
6359 ix86_fixup_binary_operands_no_copy (PLUS, <MODE>mode, operands);
6360 if (CONST_INT_P (operands[2]))
6361 operands[4] = operands[2];
6363 operands[4] = gen_rtx_SIGN_EXTEND (<DWI>mode, operands[2]);
6366 (define_insn "*addv<mode>4"
6367 [(set (reg:CCO FLAGS_REG)
6370 (match_operand:SWI 1 "nonimmediate_operand" "%0,0"))
6372 (match_operand:SWI 2 "<general_sext_operand>"
6375 (plus:SWI (match_dup 1) (match_dup 2)))))
6376 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
6377 (plus:SWI (match_dup 1) (match_dup 2)))]
6378 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6379 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6380 [(set_attr "type" "alu")
6381 (set_attr "mode" "<MODE>")])
6383 (define_insn "*addv<mode>4_1"
6384 [(set (reg:CCO FLAGS_REG)
6387 (match_operand:SWI 1 "nonimmediate_operand" "0"))
6388 (match_operand:<DWI> 3 "const_int_operand" "i"))
6390 (plus:SWI (match_dup 1)
6391 (match_operand:SWI 2 "x86_64_immediate_operand"
6393 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
6394 (plus:SWI (match_dup 1) (match_dup 2)))]
6395 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)
6396 && CONST_INT_P (operands[2])
6397 && INTVAL (operands[2]) == INTVAL (operands[3])"
6398 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6399 [(set_attr "type" "alu")
6400 (set_attr "mode" "<MODE>")
6401 (set (attr "length_immediate")
6402 (cond [(match_test "IN_RANGE (INTVAL (operands[2]), -128, 127)")
6404 (match_test "<MODE_SIZE> == 8")
6406 (const_string "<MODE_SIZE>")))])
6408 (define_expand "uaddv<mode>4"
6409 [(parallel [(set (reg:CCC FLAGS_REG)
6412 (match_operand:SWI 1 "nonimmediate_operand")
6413 (match_operand:SWI 2 "<general_operand>"))
6415 (set (match_operand:SWI 0 "register_operand")
6416 (plus:SWI (match_dup 1) (match_dup 2)))])
6417 (set (pc) (if_then_else
6418 (ltu (reg:CCC FLAGS_REG) (const_int 0))
6419 (label_ref (match_operand 3))
6422 "ix86_fixup_binary_operands_no_copy (PLUS, <MODE>mode, operands);")
6424 ;; The lea patterns for modes less than 32 bits need to be matched by
6425 ;; several insns converted to real lea by splitters.
6427 (define_insn_and_split "*lea<mode>_general_1"
6428 [(set (match_operand:SWI12 0 "register_operand" "=r")
6430 (plus:SWI12 (match_operand:SWI12 1 "index_register_operand" "l")
6431 (match_operand:SWI12 2 "register_operand" "r"))
6432 (match_operand:SWI12 3 "immediate_operand" "i")))]
6433 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
6435 "&& reload_completed"
6438 (plus:SI (match_dup 1) (match_dup 2))
6441 operands[0] = gen_lowpart (SImode, operands[0]);
6442 operands[1] = gen_lowpart (SImode, operands[1]);
6443 operands[2] = gen_lowpart (SImode, operands[2]);
6444 operands[3] = gen_lowpart (SImode, operands[3]);
6446 [(set_attr "type" "lea")
6447 (set_attr "mode" "SI")])
6449 (define_insn_and_split "*lea<mode>_general_2"
6450 [(set (match_operand:SWI12 0 "register_operand" "=r")
6452 (mult:SWI12 (match_operand:SWI12 1 "index_register_operand" "l")
6453 (match_operand 2 "const248_operand" "n"))
6454 (match_operand:SWI12 3 "nonmemory_operand" "ri")))]
6455 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
6457 "&& reload_completed"
6460 (mult:SI (match_dup 1) (match_dup 2))
6463 operands[0] = gen_lowpart (SImode, operands[0]);
6464 operands[1] = gen_lowpart (SImode, operands[1]);
6465 operands[3] = gen_lowpart (SImode, operands[3]);
6467 [(set_attr "type" "lea")
6468 (set_attr "mode" "SI")])
6470 (define_insn_and_split "*lea<mode>_general_2b"
6471 [(set (match_operand:SWI12 0 "register_operand" "=r")
6473 (ashift:SWI12 (match_operand:SWI12 1 "index_register_operand" "l")
6474 (match_operand 2 "const123_operand" "n"))
6475 (match_operand:SWI12 3 "nonmemory_operand" "ri")))]
6476 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
6478 "&& reload_completed"
6481 (ashift:SI (match_dup 1) (match_dup 2))
6484 operands[0] = gen_lowpart (SImode, operands[0]);
6485 operands[1] = gen_lowpart (SImode, operands[1]);
6486 operands[3] = gen_lowpart (SImode, operands[3]);
6488 [(set_attr "type" "lea")
6489 (set_attr "mode" "SI")])
6491 (define_insn_and_split "*lea<mode>_general_3"
6492 [(set (match_operand:SWI12 0 "register_operand" "=r")
6495 (mult:SWI12 (match_operand:SWI12 1 "index_register_operand" "l")
6496 (match_operand 2 "const248_operand" "n"))
6497 (match_operand:SWI12 3 "register_operand" "r"))
6498 (match_operand:SWI12 4 "immediate_operand" "i")))]
6499 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
6501 "&& reload_completed"
6505 (mult: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]);
6512 operands[4] = gen_lowpart (SImode, operands[4]);
6514 [(set_attr "type" "lea")
6515 (set_attr "mode" "SI")])
6517 (define_insn_and_split "*lea<mode>_general_3b"
6518 [(set (match_operand:SWI12 0 "register_operand" "=r")
6521 (ashift:SWI12 (match_operand:SWI12 1 "index_register_operand" "l")
6522 (match_operand 2 "const123_operand" "n"))
6523 (match_operand:SWI12 3 "register_operand" "r"))
6524 (match_operand:SWI12 4 "immediate_operand" "i")))]
6525 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
6527 "&& reload_completed"
6531 (ashift:SI (match_dup 1) (match_dup 2))
6535 operands[0] = gen_lowpart (SImode, operands[0]);
6536 operands[1] = gen_lowpart (SImode, operands[1]);
6537 operands[3] = gen_lowpart (SImode, operands[3]);
6538 operands[4] = gen_lowpart (SImode, operands[4]);
6540 [(set_attr "type" "lea")
6541 (set_attr "mode" "SI")])
6543 (define_insn_and_split "*lea<mode>_general_4"
6544 [(set (match_operand:SWI12 0 "register_operand" "=r")
6547 (match_operand:SWI12 1 "index_register_operand" "l")
6548 (match_operand 2 "const_0_to_3_operand" "n"))
6549 (match_operand 3 "const_int_operand" "n")))]
6550 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6551 && ((unsigned HOST_WIDE_INT) INTVAL (operands[3])
6552 < (HOST_WIDE_INT_1U << INTVAL (operands[2])))"
6554 "&& reload_completed"
6557 (mult: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[2] = GEN_INT (1 << INTVAL (operands[2]));
6564 [(set_attr "type" "lea")
6565 (set_attr "mode" "SI")])
6567 (define_insn_and_split "*lea<mode>_general_4"
6568 [(set (match_operand:SWI48 0 "register_operand" "=r")
6571 (match_operand:SWI48 1 "index_register_operand" "l")
6572 (match_operand 2 "const_0_to_3_operand" "n"))
6573 (match_operand 3 "const_int_operand" "n")))]
6574 "(unsigned HOST_WIDE_INT) INTVAL (operands[3])
6575 < (HOST_WIDE_INT_1U << INTVAL (operands[2]))"
6577 "&& reload_completed"
6580 (mult:SWI48 (match_dup 1) (match_dup 2))
6582 "operands[2] = GEN_INT (1 << INTVAL (operands[2]));"
6583 [(set_attr "type" "lea")
6584 (set_attr "mode" "<MODE>")])
6586 ;; Subtract instructions
6588 (define_expand "sub<mode>3"
6589 [(set (match_operand:SDWIM 0 "nonimmediate_operand")
6590 (minus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")
6591 (match_operand:SDWIM 2 "<general_hilo_operand>")))]
6593 "ix86_expand_binary_operator (MINUS, <MODE>mode, operands); DONE;")
6595 (define_insn_and_split "*sub<dwi>3_doubleword"
6596 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
6598 (match_operand:<DWI> 1 "nonimmediate_operand" "0,0")
6599 (match_operand:<DWI> 2 "x86_64_hilo_general_operand"
6601 (clobber (reg:CC FLAGS_REG))]
6602 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6605 [(parallel [(set (reg:CC FLAGS_REG)
6606 (compare:CC (match_dup 1) (match_dup 2)))
6608 (minus:DWIH (match_dup 1) (match_dup 2)))])
6609 (parallel [(set (match_dup 3)
6613 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0)))
6615 (clobber (reg:CC FLAGS_REG))])]
6617 split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
6618 if (operands[2] == const0_rtx)
6620 ix86_expand_binary_operator (MINUS, <MODE>mode, &operands[3]);
6625 (define_insn "*sub<mode>_1"
6626 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6628 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6629 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6630 (clobber (reg:CC FLAGS_REG))]
6631 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6632 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6633 [(set_attr "type" "alu")
6634 (set_attr "mode" "<MODE>")])
6636 (define_insn "*subsi_1_zext"
6637 [(set (match_operand:DI 0 "register_operand" "=r")
6639 (minus:SI (match_operand:SI 1 "register_operand" "0")
6640 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
6641 (clobber (reg:CC FLAGS_REG))]
6642 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6643 "sub{l}\t{%2, %k0|%k0, %2}"
6644 [(set_attr "type" "alu")
6645 (set_attr "mode" "SI")])
6647 (define_insn "*subqi_1_slp"
6648 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6649 (minus:QI (match_dup 0)
6650 (match_operand:QI 1 "general_operand" "qn,qm")))
6651 (clobber (reg:CC FLAGS_REG))]
6652 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6653 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
6654 "sub{b}\t{%1, %0|%0, %1}"
6655 [(set_attr "type" "alu1")
6656 (set_attr "mode" "QI")])
6658 (define_insn "*sub<mode>_2"
6659 [(set (reg FLAGS_REG)
6662 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6663 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6665 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6666 (minus:SWI (match_dup 1) (match_dup 2)))]
6667 "ix86_match_ccmode (insn, CCGOCmode)
6668 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6669 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6670 [(set_attr "type" "alu")
6671 (set_attr "mode" "<MODE>")])
6673 (define_insn "*subsi_2_zext"
6674 [(set (reg FLAGS_REG)
6676 (minus:SI (match_operand:SI 1 "register_operand" "0")
6677 (match_operand:SI 2 "x86_64_general_operand" "rme"))
6679 (set (match_operand:DI 0 "register_operand" "=r")
6681 (minus:SI (match_dup 1)
6683 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6684 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6685 "sub{l}\t{%2, %k0|%k0, %2}"
6686 [(set_attr "type" "alu")
6687 (set_attr "mode" "SI")])
6689 ;; Subtract with jump on overflow.
6690 (define_expand "subv<mode>4"
6691 [(parallel [(set (reg:CCO FLAGS_REG)
6692 (eq:CCO (minus:<DWI>
6694 (match_operand:SWI 1 "nonimmediate_operand"))
6697 (minus:SWI (match_dup 1)
6698 (match_operand:SWI 2
6699 "<general_operand>")))))
6700 (set (match_operand:SWI 0 "register_operand")
6701 (minus:SWI (match_dup 1) (match_dup 2)))])
6702 (set (pc) (if_then_else
6703 (eq (reg:CCO FLAGS_REG) (const_int 0))
6704 (label_ref (match_operand 3))
6708 ix86_fixup_binary_operands_no_copy (MINUS, <MODE>mode, operands);
6709 if (CONST_INT_P (operands[2]))
6710 operands[4] = operands[2];
6712 operands[4] = gen_rtx_SIGN_EXTEND (<DWI>mode, operands[2]);
6715 (define_insn "*subv<mode>4"
6716 [(set (reg:CCO FLAGS_REG)
6717 (eq:CCO (minus:<DWI>
6719 (match_operand:SWI 1 "nonimmediate_operand" "0,0"))
6721 (match_operand:SWI 2 "<general_sext_operand>"
6724 (minus:SWI (match_dup 1) (match_dup 2)))))
6725 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6726 (minus:SWI (match_dup 1) (match_dup 2)))]
6727 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6728 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6729 [(set_attr "type" "alu")
6730 (set_attr "mode" "<MODE>")])
6732 (define_insn "*subv<mode>4_1"
6733 [(set (reg:CCO FLAGS_REG)
6734 (eq:CCO (minus:<DWI>
6736 (match_operand:SWI 1 "nonimmediate_operand" "0"))
6737 (match_operand:<DWI> 3 "const_int_operand" "i"))
6739 (minus:SWI (match_dup 1)
6740 (match_operand:SWI 2 "x86_64_immediate_operand"
6742 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
6743 (minus:SWI (match_dup 1) (match_dup 2)))]
6744 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)
6745 && CONST_INT_P (operands[2])
6746 && INTVAL (operands[2]) == INTVAL (operands[3])"
6747 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6748 [(set_attr "type" "alu")
6749 (set_attr "mode" "<MODE>")
6750 (set (attr "length_immediate")
6751 (cond [(match_test "IN_RANGE (INTVAL (operands[2]), -128, 127)")
6753 (match_test "<MODE_SIZE> == 8")
6755 (const_string "<MODE_SIZE>")))])
6757 (define_expand "usubv<mode>4"
6758 [(parallel [(set (reg:CC FLAGS_REG)
6760 (match_operand:SWI 1 "nonimmediate_operand")
6761 (match_operand:SWI 2 "<general_operand>")))
6762 (set (match_operand:SWI 0 "register_operand")
6763 (minus:SWI (match_dup 1) (match_dup 2)))])
6764 (set (pc) (if_then_else
6765 (ltu (reg:CC FLAGS_REG) (const_int 0))
6766 (label_ref (match_operand 3))
6769 "ix86_fixup_binary_operands_no_copy (MINUS, <MODE>mode, operands);")
6771 (define_insn "*sub<mode>_3"
6772 [(set (reg FLAGS_REG)
6773 (compare (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6774 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6775 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6776 (minus:SWI (match_dup 1) (match_dup 2)))]
6777 "ix86_match_ccmode (insn, CCmode)
6778 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6779 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6780 [(set_attr "type" "alu")
6781 (set_attr "mode" "<MODE>")])
6785 [(set (reg:CC FLAGS_REG)
6786 (compare:CC (match_operand:SWI 0 "general_reg_operand")
6787 (match_operand:SWI 1 "general_gr_operand")))
6789 (minus:SWI (match_dup 0) (match_dup 1)))])]
6790 "find_regno_note (peep2_next_insn (0), REG_UNUSED, REGNO (operands[0])) != 0"
6791 [(set (reg:CC FLAGS_REG)
6792 (compare:CC (match_dup 0) (match_dup 1)))])
6794 (define_insn "*subsi_3_zext"
6795 [(set (reg FLAGS_REG)
6796 (compare (match_operand:SI 1 "register_operand" "0")
6797 (match_operand:SI 2 "x86_64_general_operand" "rme")))
6798 (set (match_operand:DI 0 "register_operand" "=r")
6800 (minus:SI (match_dup 1)
6802 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6803 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6804 "sub{l}\t{%2, %1|%1, %2}"
6805 [(set_attr "type" "alu")
6806 (set_attr "mode" "SI")])
6808 ;; Add with carry and subtract with borrow
6810 (define_insn "add<mode>3_carry"
6811 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6814 (match_operator:SWI 4 "ix86_carry_flag_operator"
6815 [(match_operand 3 "flags_reg_operand") (const_int 0)])
6816 (match_operand:SWI 1 "nonimmediate_operand" "%0,0"))
6817 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6818 (clobber (reg:CC FLAGS_REG))]
6819 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6820 "adc{<imodesuffix>}\t{%2, %0|%0, %2}"
6821 [(set_attr "type" "alu")
6822 (set_attr "use_carry" "1")
6823 (set_attr "pent_pair" "pu")
6824 (set_attr "mode" "<MODE>")])
6826 (define_insn "*addsi3_carry_zext"
6827 [(set (match_operand:DI 0 "register_operand" "=r")
6830 (plus:SI (match_operator:SI 3 "ix86_carry_flag_operator"
6831 [(reg FLAGS_REG) (const_int 0)])
6832 (match_operand:SI 1 "register_operand" "%0"))
6833 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
6834 (clobber (reg:CC FLAGS_REG))]
6835 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6836 "adc{l}\t{%2, %k0|%k0, %2}"
6837 [(set_attr "type" "alu")
6838 (set_attr "use_carry" "1")
6839 (set_attr "pent_pair" "pu")
6840 (set_attr "mode" "SI")])
6842 ;; There is no point to generate ADCX instruction. ADC is shorter and faster.
6844 (define_insn "addcarry<mode>"
6845 [(set (reg:CCC FLAGS_REG)
6850 (match_operator:SWI48 5 "ix86_carry_flag_operator"
6851 [(match_operand 3 "flags_reg_operand") (const_int 0)])
6852 (match_operand:SWI48 1 "nonimmediate_operand" "%0"))
6853 (match_operand:SWI48 2 "nonimmediate_operand" "rm")))
6855 (zero_extend:<DWI> (match_dup 2))
6856 (match_operator:<DWI> 4 "ix86_carry_flag_operator"
6857 [(match_dup 3) (const_int 0)]))))
6858 (set (match_operand:SWI48 0 "register_operand" "=r")
6859 (plus:SWI48 (plus:SWI48 (match_op_dup 5
6860 [(match_dup 3) (const_int 0)])
6863 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6864 "adc{<imodesuffix>}\t{%2, %0|%0, %2}"
6865 [(set_attr "type" "alu")
6866 (set_attr "use_carry" "1")
6867 (set_attr "pent_pair" "pu")
6868 (set_attr "mode" "<MODE>")])
6870 (define_expand "addcarry<mode>_0"
6872 [(set (reg:CCC FLAGS_REG)
6875 (match_operand:SWI48 1 "nonimmediate_operand")
6876 (match_operand:SWI48 2 "x86_64_general_operand"))
6878 (set (match_operand:SWI48 0 "register_operand")
6879 (plus:SWI48 (match_dup 1) (match_dup 2)))])]
6880 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)")
6882 (define_insn "sub<mode>3_carry"
6883 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6886 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6887 (match_operator:SWI 4 "ix86_carry_flag_operator"
6888 [(match_operand 3 "flags_reg_operand") (const_int 0)]))
6889 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6890 (clobber (reg:CC FLAGS_REG))]
6891 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6892 "sbb{<imodesuffix>}\t{%2, %0|%0, %2}"
6893 [(set_attr "type" "alu")
6894 (set_attr "use_carry" "1")
6895 (set_attr "pent_pair" "pu")
6896 (set_attr "mode" "<MODE>")])
6898 (define_insn "*subsi3_carry_zext"
6899 [(set (match_operand:DI 0 "register_operand" "=r")
6903 (match_operand:SI 1 "register_operand" "0")
6904 (match_operator:SI 3 "ix86_carry_flag_operator"
6905 [(reg FLAGS_REG) (const_int 0)]))
6906 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
6907 (clobber (reg:CC FLAGS_REG))]
6908 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6909 "sbb{l}\t{%2, %k0|%k0, %2}"
6910 [(set_attr "type" "alu")
6911 (set_attr "use_carry" "1")
6912 (set_attr "pent_pair" "pu")
6913 (set_attr "mode" "SI")])
6915 (define_insn "sub<mode>3_carry_ccc"
6916 [(set (reg:CCC FLAGS_REG)
6918 (zero_extend:<DWI> (match_operand:DWIH 1 "register_operand" "0"))
6920 (ltu:<DWI> (reg:CC FLAGS_REG) (const_int 0))
6922 (match_operand:DWIH 2 "x86_64_sext_operand" "rmWe")))))
6923 (clobber (match_scratch:DWIH 0 "=r"))]
6925 "sbb{<imodesuffix>}\t{%2, %0|%0, %2}"
6926 [(set_attr "type" "alu")
6927 (set_attr "mode" "<MODE>")])
6929 (define_insn "*sub<mode>3_carry_ccc_1"
6930 [(set (reg:CCC FLAGS_REG)
6932 (zero_extend:<DWI> (match_operand:DWIH 1 "register_operand" "0"))
6934 (ltu:<DWI> (reg:CC FLAGS_REG) (const_int 0))
6935 (match_operand:<DWI> 2 "x86_64_dwzext_immediate_operand" "Wf"))))
6936 (clobber (match_scratch:DWIH 0 "=r"))]
6939 operands[3] = simplify_subreg (<MODE>mode, operands[2], <DWI>mode, 0);
6940 return "sbb{<imodesuffix>}\t{%3, %0|%0, %3}";
6942 [(set_attr "type" "alu")
6943 (set_attr "mode" "<MODE>")])
6945 ;; The sign flag is set from the
6946 ;; (compare (match_dup 1) (plus:DWIH (ltu:DWIH ...) (match_dup 2)))
6947 ;; result, the overflow flag likewise, but the overflow flag is also
6948 ;; set if the (plus:DWIH (ltu:DWIH ...) (match_dup 2)) overflows.
6949 (define_insn "sub<mode>3_carry_ccgz"
6950 [(set (reg:CCGZ FLAGS_REG)
6951 (unspec:CCGZ [(match_operand:DWIH 1 "register_operand" "0")
6952 (match_operand:DWIH 2 "x86_64_general_operand" "rme")
6953 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))]
6955 (clobber (match_scratch:DWIH 0 "=r"))]
6957 "sbb{<imodesuffix>}\t{%2, %0|%0, %2}"
6958 [(set_attr "type" "alu")
6959 (set_attr "mode" "<MODE>")])
6961 (define_insn "subborrow<mode>"
6962 [(set (reg:CCC FLAGS_REG)
6965 (match_operand:SWI48 1 "nonimmediate_operand" "0"))
6967 (match_operator:<DWI> 4 "ix86_carry_flag_operator"
6968 [(match_operand 3 "flags_reg_operand") (const_int 0)])
6970 (match_operand:SWI48 2 "nonimmediate_operand" "rm")))))
6971 (set (match_operand:SWI48 0 "register_operand" "=r")
6972 (minus:SWI48 (minus:SWI48
6974 (match_operator:SWI48 5 "ix86_carry_flag_operator"
6975 [(match_dup 3) (const_int 0)]))
6977 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6978 "sbb{<imodesuffix>}\t{%2, %0|%0, %2}"
6979 [(set_attr "type" "alu")
6980 (set_attr "use_carry" "1")
6981 (set_attr "pent_pair" "pu")
6982 (set_attr "mode" "<MODE>")])
6984 (define_expand "subborrow<mode>_0"
6986 [(set (reg:CC FLAGS_REG)
6988 (match_operand:SWI48 1 "nonimmediate_operand")
6989 (match_operand:SWI48 2 "<general_operand>")))
6990 (set (match_operand:SWI48 0 "register_operand")
6991 (minus:SWI48 (match_dup 1) (match_dup 2)))])]
6992 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)")
6994 ;; Overflow setting add instructions
6996 (define_expand "addqi3_cconly_overflow"
6998 [(set (reg:CCC FLAGS_REG)
7001 (match_operand:QI 0 "nonimmediate_operand")
7002 (match_operand:QI 1 "general_operand"))
7004 (clobber (match_scratch:QI 2))])]
7005 "!(MEM_P (operands[0]) && MEM_P (operands[1]))")
7007 (define_insn "*add<mode>3_cconly_overflow_1"
7008 [(set (reg:CCC FLAGS_REG)
7011 (match_operand:SWI 1 "nonimmediate_operand" "%0")
7012 (match_operand:SWI 2 "<general_operand>" "<g>"))
7014 (clobber (match_scratch:SWI 0 "=<r>"))]
7015 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7016 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
7017 [(set_attr "type" "alu")
7018 (set_attr "mode" "<MODE>")])
7020 (define_insn "*add<mode>3_cc_overflow_1"
7021 [(set (reg:CCC FLAGS_REG)
7024 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
7025 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
7027 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
7028 (plus:SWI (match_dup 1) (match_dup 2)))]
7029 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
7030 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
7031 [(set_attr "type" "alu")
7032 (set_attr "mode" "<MODE>")])
7034 (define_insn "*addsi3_zext_cc_overflow_1"
7035 [(set (reg:CCC FLAGS_REG)
7038 (match_operand:SI 1 "nonimmediate_operand" "%0")
7039 (match_operand:SI 2 "x86_64_general_operand" "rme"))
7041 (set (match_operand:DI 0 "register_operand" "=r")
7042 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
7043 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
7044 "add{l}\t{%2, %k0|%k0, %2}"
7045 [(set_attr "type" "alu")
7046 (set_attr "mode" "SI")])
7048 (define_insn "*add<mode>3_cconly_overflow_2"
7049 [(set (reg:CCC FLAGS_REG)
7052 (match_operand:SWI 1 "nonimmediate_operand" "%0")
7053 (match_operand:SWI 2 "<general_operand>" "<g>"))
7055 (clobber (match_scratch:SWI 0 "=<r>"))]
7056 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7057 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
7058 [(set_attr "type" "alu")
7059 (set_attr "mode" "<MODE>")])
7061 (define_insn "*add<mode>3_cc_overflow_2"
7062 [(set (reg:CCC FLAGS_REG)
7065 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
7066 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
7068 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
7069 (plus:SWI (match_dup 1) (match_dup 2)))]
7070 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
7071 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
7072 [(set_attr "type" "alu")
7073 (set_attr "mode" "<MODE>")])
7075 (define_insn "*addsi3_zext_cc_overflow_2"
7076 [(set (reg:CCC FLAGS_REG)
7079 (match_operand:SI 1 "nonimmediate_operand" "%0")
7080 (match_operand:SI 2 "x86_64_general_operand" "rme"))
7082 (set (match_operand:DI 0 "register_operand" "=r")
7083 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
7084 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
7085 "add{l}\t{%2, %k0|%k0, %2}"
7086 [(set_attr "type" "alu")
7087 (set_attr "mode" "SI")])
7089 ;; The patterns that match these are at the end of this file.
7091 (define_expand "<plusminus_insn>xf3"
7092 [(set (match_operand:XF 0 "register_operand")
7094 (match_operand:XF 1 "register_operand")
7095 (match_operand:XF 2 "register_operand")))]
7098 (define_expand "<plusminus_insn><mode>3"
7099 [(set (match_operand:MODEF 0 "register_operand")
7101 (match_operand:MODEF 1 "register_operand")
7102 (match_operand:MODEF 2 "nonimmediate_operand")))]
7103 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
7104 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
7106 ;; Multiply instructions
7108 (define_expand "mul<mode>3"
7109 [(parallel [(set (match_operand:SWIM248 0 "register_operand")
7111 (match_operand:SWIM248 1 "register_operand")
7112 (match_operand:SWIM248 2 "<general_operand>")))
7113 (clobber (reg:CC FLAGS_REG))])])
7115 (define_expand "mulqi3"
7116 [(parallel [(set (match_operand:QI 0 "register_operand")
7118 (match_operand:QI 1 "register_operand")
7119 (match_operand:QI 2 "nonimmediate_operand")))
7120 (clobber (reg:CC FLAGS_REG))])]
7121 "TARGET_QIMODE_MATH")
7124 ;; IMUL reg32/64, reg32/64, imm8 Direct
7125 ;; IMUL reg32/64, mem32/64, imm8 VectorPath
7126 ;; IMUL reg32/64, reg32/64, imm32 Direct
7127 ;; IMUL reg32/64, mem32/64, imm32 VectorPath
7128 ;; IMUL reg32/64, reg32/64 Direct
7129 ;; IMUL reg32/64, mem32/64 Direct
7131 ;; On BDVER1, all above IMULs use DirectPath
7134 ;; IMUL reg16, reg16, imm8 VectorPath
7135 ;; IMUL reg16, mem16, imm8 VectorPath
7136 ;; IMUL reg16, reg16, imm16 VectorPath
7137 ;; IMUL reg16, mem16, imm16 VectorPath
7138 ;; IMUL reg16, reg16 Direct
7139 ;; IMUL reg16, mem16 Direct
7141 ;; On BDVER1, all HI MULs use DoublePath
7143 (define_insn "*mul<mode>3_1"
7144 [(set (match_operand:SWIM248 0 "register_operand" "=r,r,r")
7146 (match_operand:SWIM248 1 "nonimmediate_operand" "%rm,rm,0")
7147 (match_operand:SWIM248 2 "<general_operand>" "K,<i>,mr")))
7148 (clobber (reg:CC FLAGS_REG))]
7149 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7151 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
7152 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
7153 imul{<imodesuffix>}\t{%2, %0|%0, %2}"
7154 [(set_attr "type" "imul")
7155 (set_attr "prefix_0f" "0,0,1")
7156 (set (attr "athlon_decode")
7157 (cond [(eq_attr "cpu" "athlon")
7158 (const_string "vector")
7159 (eq_attr "alternative" "1")
7160 (const_string "vector")
7161 (and (eq_attr "alternative" "2")
7162 (ior (match_test "<MODE>mode == HImode")
7163 (match_operand 1 "memory_operand")))
7164 (const_string "vector")]
7165 (const_string "direct")))
7166 (set (attr "amdfam10_decode")
7167 (cond [(and (eq_attr "alternative" "0,1")
7168 (ior (match_test "<MODE>mode == HImode")
7169 (match_operand 1 "memory_operand")))
7170 (const_string "vector")]
7171 (const_string "direct")))
7172 (set (attr "bdver1_decode")
7174 (match_test "<MODE>mode == HImode")
7175 (const_string "double")
7176 (const_string "direct")))
7177 (set_attr "mode" "<MODE>")])
7179 (define_insn "*mulsi3_1_zext"
7180 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
7182 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
7183 (match_operand:SI 2 "x86_64_general_operand" "K,e,mr"))))
7184 (clobber (reg:CC FLAGS_REG))]
7186 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7188 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7189 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7190 imul{l}\t{%2, %k0|%k0, %2}"
7191 [(set_attr "type" "imul")
7192 (set_attr "prefix_0f" "0,0,1")
7193 (set (attr "athlon_decode")
7194 (cond [(eq_attr "cpu" "athlon")
7195 (const_string "vector")
7196 (eq_attr "alternative" "1")
7197 (const_string "vector")
7198 (and (eq_attr "alternative" "2")
7199 (match_operand 1 "memory_operand"))
7200 (const_string "vector")]
7201 (const_string "direct")))
7202 (set (attr "amdfam10_decode")
7203 (cond [(and (eq_attr "alternative" "0,1")
7204 (match_operand 1 "memory_operand"))
7205 (const_string "vector")]
7206 (const_string "direct")))
7207 (set_attr "bdver1_decode" "direct")
7208 (set_attr "mode" "SI")])
7210 ;;On AMDFAM10 and BDVER1
7214 (define_insn "*mulqi3_1"
7215 [(set (match_operand:QI 0 "register_operand" "=a")
7216 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
7217 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7218 (clobber (reg:CC FLAGS_REG))]
7220 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7222 [(set_attr "type" "imul")
7223 (set_attr "length_immediate" "0")
7224 (set (attr "athlon_decode")
7225 (if_then_else (eq_attr "cpu" "athlon")
7226 (const_string "vector")
7227 (const_string "direct")))
7228 (set_attr "amdfam10_decode" "direct")
7229 (set_attr "bdver1_decode" "direct")
7230 (set_attr "mode" "QI")])
7232 ;; Multiply with jump on overflow.
7233 (define_expand "mulv<mode>4"
7234 [(parallel [(set (reg:CCO FLAGS_REG)
7237 (match_operand:SWI248 1 "register_operand"))
7240 (mult:SWI248 (match_dup 1)
7241 (match_operand:SWI248 2
7242 "<general_operand>")))))
7243 (set (match_operand:SWI248 0 "register_operand")
7244 (mult:SWI248 (match_dup 1) (match_dup 2)))])
7245 (set (pc) (if_then_else
7246 (eq (reg:CCO FLAGS_REG) (const_int 0))
7247 (label_ref (match_operand 3))
7251 if (CONST_INT_P (operands[2]))
7252 operands[4] = operands[2];
7254 operands[4] = gen_rtx_SIGN_EXTEND (<DWI>mode, operands[2]);
7257 (define_insn "*mulv<mode>4"
7258 [(set (reg:CCO FLAGS_REG)
7261 (match_operand:SWI48 1 "nonimmediate_operand" "%rm,0"))
7263 (match_operand:SWI48 2 "x86_64_sext_operand" "We,mr")))
7265 (mult:SWI48 (match_dup 1) (match_dup 2)))))
7266 (set (match_operand:SWI48 0 "register_operand" "=r,r")
7267 (mult:SWI48 (match_dup 1) (match_dup 2)))]
7268 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7270 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
7271 imul{<imodesuffix>}\t{%2, %0|%0, %2}"
7272 [(set_attr "type" "imul")
7273 (set_attr "prefix_0f" "0,1")
7274 (set (attr "athlon_decode")
7275 (cond [(eq_attr "cpu" "athlon")
7276 (const_string "vector")
7277 (eq_attr "alternative" "0")
7278 (const_string "vector")
7279 (and (eq_attr "alternative" "1")
7280 (match_operand 1 "memory_operand"))
7281 (const_string "vector")]
7282 (const_string "direct")))
7283 (set (attr "amdfam10_decode")
7284 (cond [(and (eq_attr "alternative" "1")
7285 (match_operand 1 "memory_operand"))
7286 (const_string "vector")]
7287 (const_string "direct")))
7288 (set_attr "bdver1_decode" "direct")
7289 (set_attr "mode" "<MODE>")])
7291 (define_insn "*mulvhi4"
7292 [(set (reg:CCO FLAGS_REG)
7295 (match_operand:HI 1 "nonimmediate_operand" "%0"))
7297 (match_operand:HI 2 "nonimmediate_operand" "mr")))
7299 (mult:HI (match_dup 1) (match_dup 2)))))
7300 (set (match_operand:HI 0 "register_operand" "=r")
7301 (mult:HI (match_dup 1) (match_dup 2)))]
7302 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7303 "imul{w}\t{%2, %0|%0, %2}"
7304 [(set_attr "type" "imul")
7305 (set_attr "prefix_0f" "1")
7306 (set_attr "athlon_decode" "vector")
7307 (set_attr "amdfam10_decode" "direct")
7308 (set_attr "bdver1_decode" "double")
7309 (set_attr "mode" "HI")])
7311 (define_insn "*mulv<mode>4_1"
7312 [(set (reg:CCO FLAGS_REG)
7315 (match_operand:SWI248 1 "nonimmediate_operand" "rm,rm"))
7316 (match_operand:<DWI> 3 "const_int_operand" "K,i"))
7318 (mult:SWI248 (match_dup 1)
7319 (match_operand:SWI248 2
7320 "<immediate_operand>" "K,<i>")))))
7321 (set (match_operand:SWI248 0 "register_operand" "=r,r")
7322 (mult:SWI248 (match_dup 1) (match_dup 2)))]
7323 "!(MEM_P (operands[1]) && MEM_P (operands[2]))
7324 && CONST_INT_P (operands[2])
7325 && INTVAL (operands[2]) == INTVAL (operands[3])"
7326 "imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}"
7327 [(set_attr "type" "imul")
7328 (set (attr "prefix_0f")
7330 (match_test "<MODE>mode == HImode")
7332 (const_string "*")))
7333 (set (attr "athlon_decode")
7334 (cond [(eq_attr "cpu" "athlon")
7335 (const_string "vector")
7336 (eq_attr "alternative" "1")
7337 (const_string "vector")]
7338 (const_string "direct")))
7339 (set (attr "amdfam10_decode")
7340 (cond [(ior (match_test "<MODE>mode == HImode")
7341 (match_operand 1 "memory_operand"))
7342 (const_string "vector")]
7343 (const_string "direct")))
7344 (set (attr "bdver1_decode")
7346 (match_test "<MODE>mode == HImode")
7347 (const_string "double")
7348 (const_string "direct")))
7349 (set_attr "mode" "<MODE>")
7350 (set (attr "length_immediate")
7351 (cond [(eq_attr "alternative" "0")
7353 (match_test "<MODE_SIZE> == 8")
7355 (const_string "<MODE_SIZE>")))])
7357 (define_expand "umulv<mode>4"
7358 [(parallel [(set (reg:CCO FLAGS_REG)
7361 (match_operand:SWI248 1
7362 "nonimmediate_operand"))
7364 (match_operand:SWI248 2
7365 "nonimmediate_operand")))
7367 (mult:SWI248 (match_dup 1) (match_dup 2)))))
7368 (set (match_operand:SWI248 0 "register_operand")
7369 (mult:SWI248 (match_dup 1) (match_dup 2)))
7370 (clobber (match_scratch:SWI248 4))])
7371 (set (pc) (if_then_else
7372 (eq (reg:CCO FLAGS_REG) (const_int 0))
7373 (label_ref (match_operand 3))
7377 if (MEM_P (operands[1]) && MEM_P (operands[2]))
7378 operands[1] = force_reg (<MODE>mode, operands[1]);
7381 (define_insn "*umulv<mode>4"
7382 [(set (reg:CCO FLAGS_REG)
7385 (match_operand:SWI248 1 "nonimmediate_operand" "%0"))
7387 (match_operand:SWI248 2 "nonimmediate_operand" "rm")))
7389 (mult:SWI248 (match_dup 1) (match_dup 2)))))
7390 (set (match_operand:SWI248 0 "register_operand" "=a")
7391 (mult:SWI248 (match_dup 1) (match_dup 2)))
7392 (clobber (match_scratch:SWI248 3 "=d"))]
7393 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7394 "mul{<imodesuffix>}\t%2"
7395 [(set_attr "type" "imul")
7396 (set_attr "length_immediate" "0")
7397 (set (attr "athlon_decode")
7398 (if_then_else (eq_attr "cpu" "athlon")
7399 (const_string "vector")
7400 (const_string "double")))
7401 (set_attr "amdfam10_decode" "double")
7402 (set_attr "bdver1_decode" "direct")
7403 (set_attr "mode" "<MODE>")])
7405 (define_expand "<u>mulvqi4"
7406 [(parallel [(set (reg:CCO FLAGS_REG)
7409 (match_operand:QI 1 "nonimmediate_operand"))
7411 (match_operand:QI 2 "nonimmediate_operand")))
7413 (mult:QI (match_dup 1) (match_dup 2)))))
7414 (set (match_operand:QI 0 "register_operand")
7415 (mult:QI (match_dup 1) (match_dup 2)))])
7416 (set (pc) (if_then_else
7417 (eq (reg:CCO FLAGS_REG) (const_int 0))
7418 (label_ref (match_operand 3))
7420 "TARGET_QIMODE_MATH"
7422 if (MEM_P (operands[1]) && MEM_P (operands[2]))
7423 operands[1] = force_reg (QImode, operands[1]);
7426 (define_insn "*<u>mulvqi4"
7427 [(set (reg:CCO FLAGS_REG)
7430 (match_operand:QI 1 "nonimmediate_operand" "%0"))
7432 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7434 (mult:QI (match_dup 1) (match_dup 2)))))
7435 (set (match_operand:QI 0 "register_operand" "=a")
7436 (mult:QI (match_dup 1) (match_dup 2)))]
7438 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7439 "<sgnprefix>mul{b}\t%2"
7440 [(set_attr "type" "imul")
7441 (set_attr "length_immediate" "0")
7442 (set (attr "athlon_decode")
7443 (if_then_else (eq_attr "cpu" "athlon")
7444 (const_string "vector")
7445 (const_string "direct")))
7446 (set_attr "amdfam10_decode" "direct")
7447 (set_attr "bdver1_decode" "direct")
7448 (set_attr "mode" "QI")])
7450 (define_expand "<u>mul<mode><dwi>3"
7451 [(parallel [(set (match_operand:<DWI> 0 "register_operand")
7454 (match_operand:DWIH 1 "nonimmediate_operand"))
7456 (match_operand:DWIH 2 "register_operand"))))
7457 (clobber (reg:CC FLAGS_REG))])])
7459 (define_expand "<u>mulqihi3"
7460 [(parallel [(set (match_operand:HI 0 "register_operand")
7463 (match_operand:QI 1 "nonimmediate_operand"))
7465 (match_operand:QI 2 "register_operand"))))
7466 (clobber (reg:CC FLAGS_REG))])]
7467 "TARGET_QIMODE_MATH")
7469 (define_insn "*bmi2_umul<mode><dwi>3_1"
7470 [(set (match_operand:DWIH 0 "register_operand" "=r")
7472 (match_operand:DWIH 2 "nonimmediate_operand" "%d")
7473 (match_operand:DWIH 3 "nonimmediate_operand" "rm")))
7474 (set (match_operand:DWIH 1 "register_operand" "=r")
7477 (mult:<DWI> (zero_extend:<DWI> (match_dup 2))
7478 (zero_extend:<DWI> (match_dup 3)))
7479 (match_operand:QI 4 "const_int_operand" "n"))))]
7480 "TARGET_BMI2 && INTVAL (operands[4]) == <MODE_SIZE> * BITS_PER_UNIT
7481 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7482 "mulx\t{%3, %0, %1|%1, %0, %3}"
7483 [(set_attr "type" "imulx")
7484 (set_attr "prefix" "vex")
7485 (set_attr "mode" "<MODE>")])
7487 (define_insn "*umul<mode><dwi>3_1"
7488 [(set (match_operand:<DWI> 0 "register_operand" "=r,A")
7491 (match_operand:DWIH 1 "nonimmediate_operand" "%d,0"))
7493 (match_operand:DWIH 2 "nonimmediate_operand" "rm,rm"))))
7494 (clobber (reg:CC FLAGS_REG))]
7495 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7498 mul{<imodesuffix>}\t%2"
7499 [(set_attr "isa" "bmi2,*")
7500 (set_attr "type" "imulx,imul")
7501 (set_attr "length_immediate" "*,0")
7502 (set (attr "athlon_decode")
7503 (cond [(eq_attr "alternative" "1")
7504 (if_then_else (eq_attr "cpu" "athlon")
7505 (const_string "vector")
7506 (const_string "double"))]
7507 (const_string "*")))
7508 (set_attr "amdfam10_decode" "*,double")
7509 (set_attr "bdver1_decode" "*,direct")
7510 (set_attr "prefix" "vex,orig")
7511 (set_attr "mode" "<MODE>")])
7513 ;; Convert mul to the mulx pattern to avoid flags dependency.
7515 [(set (match_operand:<DWI> 0 "register_operand")
7518 (match_operand:DWIH 1 "register_operand"))
7520 (match_operand:DWIH 2 "nonimmediate_operand"))))
7521 (clobber (reg:CC FLAGS_REG))]
7522 "TARGET_BMI2 && reload_completed
7523 && REGNO (operands[1]) == DX_REG"
7524 [(parallel [(set (match_dup 3)
7525 (mult:DWIH (match_dup 1) (match_dup 2)))
7529 (mult:<DWI> (zero_extend:<DWI> (match_dup 1))
7530 (zero_extend:<DWI> (match_dup 2)))
7533 split_double_mode (<DWI>mode, &operands[0], 1, &operands[3], &operands[4]);
7535 operands[5] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT);
7538 (define_insn "*mul<mode><dwi>3_1"
7539 [(set (match_operand:<DWI> 0 "register_operand" "=A")
7542 (match_operand:DWIH 1 "nonimmediate_operand" "%0"))
7544 (match_operand:DWIH 2 "nonimmediate_operand" "rm"))))
7545 (clobber (reg:CC FLAGS_REG))]
7546 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7547 "imul{<imodesuffix>}\t%2"
7548 [(set_attr "type" "imul")
7549 (set_attr "length_immediate" "0")
7550 (set (attr "athlon_decode")
7551 (if_then_else (eq_attr "cpu" "athlon")
7552 (const_string "vector")
7553 (const_string "double")))
7554 (set_attr "amdfam10_decode" "double")
7555 (set_attr "bdver1_decode" "direct")
7556 (set_attr "mode" "<MODE>")])
7558 (define_insn "*<u>mulqihi3_1"
7559 [(set (match_operand:HI 0 "register_operand" "=a")
7562 (match_operand:QI 1 "nonimmediate_operand" "%0"))
7564 (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7565 (clobber (reg:CC FLAGS_REG))]
7567 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7568 "<sgnprefix>mul{b}\t%2"
7569 [(set_attr "type" "imul")
7570 (set_attr "length_immediate" "0")
7571 (set (attr "athlon_decode")
7572 (if_then_else (eq_attr "cpu" "athlon")
7573 (const_string "vector")
7574 (const_string "direct")))
7575 (set_attr "amdfam10_decode" "direct")
7576 (set_attr "bdver1_decode" "direct")
7577 (set_attr "mode" "QI")])
7579 (define_expand "<s>mul<mode>3_highpart"
7580 [(parallel [(set (match_operand:SWI48 0 "register_operand")
7585 (match_operand:SWI48 1 "nonimmediate_operand"))
7587 (match_operand:SWI48 2 "register_operand")))
7589 (clobber (match_scratch:SWI48 4))
7590 (clobber (reg:CC FLAGS_REG))])]
7592 "operands[3] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
7594 (define_insn "*<s>muldi3_highpart_1"
7595 [(set (match_operand:DI 0 "register_operand" "=d")
7600 (match_operand:DI 1 "nonimmediate_operand" "%a"))
7602 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7604 (clobber (match_scratch:DI 3 "=1"))
7605 (clobber (reg:CC FLAGS_REG))]
7607 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7608 "<sgnprefix>mul{q}\t%2"
7609 [(set_attr "type" "imul")
7610 (set_attr "length_immediate" "0")
7611 (set (attr "athlon_decode")
7612 (if_then_else (eq_attr "cpu" "athlon")
7613 (const_string "vector")
7614 (const_string "double")))
7615 (set_attr "amdfam10_decode" "double")
7616 (set_attr "bdver1_decode" "direct")
7617 (set_attr "mode" "DI")])
7619 (define_insn "*<s>mulsi3_highpart_zext"
7620 [(set (match_operand:DI 0 "register_operand" "=d")
7621 (zero_extend:DI (truncate:SI
7623 (mult:DI (any_extend:DI
7624 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7626 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7628 (clobber (match_scratch:SI 3 "=1"))
7629 (clobber (reg:CC FLAGS_REG))]
7631 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7632 "<sgnprefix>mul{l}\t%2"
7633 [(set_attr "type" "imul")
7634 (set_attr "length_immediate" "0")
7635 (set (attr "athlon_decode")
7636 (if_then_else (eq_attr "cpu" "athlon")
7637 (const_string "vector")
7638 (const_string "double")))
7639 (set_attr "amdfam10_decode" "double")
7640 (set_attr "bdver1_decode" "direct")
7641 (set_attr "mode" "SI")])
7643 (define_insn "*<s>mulsi3_highpart_1"
7644 [(set (match_operand:SI 0 "register_operand" "=d")
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))]
7655 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7656 "<sgnprefix>mul{l}\t%2"
7657 [(set_attr "type" "imul")
7658 (set_attr "length_immediate" "0")
7659 (set (attr "athlon_decode")
7660 (if_then_else (eq_attr "cpu" "athlon")
7661 (const_string "vector")
7662 (const_string "double")))
7663 (set_attr "amdfam10_decode" "double")
7664 (set_attr "bdver1_decode" "direct")
7665 (set_attr "mode" "SI")])
7667 ;; The patterns that match these are at the end of this file.
7669 (define_expand "mulxf3"
7670 [(set (match_operand:XF 0 "register_operand")
7671 (mult:XF (match_operand:XF 1 "register_operand")
7672 (match_operand:XF 2 "register_operand")))]
7675 (define_expand "mul<mode>3"
7676 [(set (match_operand:MODEF 0 "register_operand")
7677 (mult:MODEF (match_operand:MODEF 1 "register_operand")
7678 (match_operand:MODEF 2 "nonimmediate_operand")))]
7679 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
7680 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
7682 ;; Divide instructions
7684 ;; The patterns that match these are at the end of this file.
7686 (define_expand "divxf3"
7687 [(set (match_operand:XF 0 "register_operand")
7688 (div:XF (match_operand:XF 1 "register_operand")
7689 (match_operand:XF 2 "register_operand")))]
7692 (define_expand "div<mode>3"
7693 [(set (match_operand:MODEF 0 "register_operand")
7694 (div:MODEF (match_operand:MODEF 1 "register_operand")
7695 (match_operand:MODEF 2 "nonimmediate_operand")))]
7696 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
7697 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
7699 if (<MODE>mode == SFmode
7700 && TARGET_SSE && TARGET_SSE_MATH
7702 && optimize_insn_for_speed_p ()
7703 && flag_finite_math_only && !flag_trapping_math
7704 && flag_unsafe_math_optimizations)
7706 ix86_emit_swdivsf (operands[0], operands[1],
7707 operands[2], SFmode);
7712 ;; Divmod instructions.
7714 (define_expand "divmod<mode>4"
7715 [(parallel [(set (match_operand:SWIM248 0 "register_operand")
7717 (match_operand:SWIM248 1 "register_operand")
7718 (match_operand:SWIM248 2 "nonimmediate_operand")))
7719 (set (match_operand:SWIM248 3 "register_operand")
7720 (mod:SWIM248 (match_dup 1) (match_dup 2)))
7721 (clobber (reg:CC FLAGS_REG))])])
7723 ;; Split with 8bit unsigned divide:
7724 ;; if (dividend an divisor are in [0-255])
7725 ;; use 8bit unsigned integer divide
7727 ;; use original integer divide
7729 [(set (match_operand:SWI48 0 "register_operand")
7730 (div:SWI48 (match_operand:SWI48 2 "register_operand")
7731 (match_operand:SWI48 3 "nonimmediate_operand")))
7732 (set (match_operand:SWI48 1 "register_operand")
7733 (mod:SWI48 (match_dup 2) (match_dup 3)))
7734 (clobber (reg:CC FLAGS_REG))]
7735 "TARGET_USE_8BIT_IDIV
7736 && TARGET_QIMODE_MATH
7737 && can_create_pseudo_p ()
7738 && !optimize_insn_for_size_p ()"
7740 "ix86_split_idivmod (<MODE>mode, operands, true); DONE;")
7743 [(set (match_operand:DI 0 "register_operand")
7745 (div:SI (match_operand:SI 2 "register_operand")
7746 (match_operand:SI 3 "nonimmediate_operand"))))
7747 (set (match_operand:SI 1 "register_operand")
7748 (mod:SI (match_dup 2) (match_dup 3)))
7749 (clobber (reg:CC FLAGS_REG))]
7750 "TARGET_USE_8BIT_IDIV
7751 && TARGET_QIMODE_MATH
7752 && can_create_pseudo_p ()
7753 && !optimize_insn_for_size_p ()"
7755 "ix86_split_idivmod (SImode, operands, true); DONE;")
7758 [(set (match_operand:DI 1 "register_operand")
7760 (mod:SI (match_operand:SI 2 "register_operand")
7761 (match_operand:SI 3 "nonimmediate_operand"))))
7762 (set (match_operand:SI 0 "register_operand")
7763 (div:SI (match_dup 2) (match_dup 3)))
7764 (clobber (reg:CC FLAGS_REG))]
7765 "TARGET_USE_8BIT_IDIV
7766 && TARGET_QIMODE_MATH
7767 && can_create_pseudo_p ()
7768 && !optimize_insn_for_size_p ()"
7770 "ix86_split_idivmod (SImode, operands, true); DONE;")
7772 (define_insn_and_split "divmod<mode>4_1"
7773 [(set (match_operand:SWI48 0 "register_operand" "=a")
7774 (div:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7775 (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
7776 (set (match_operand:SWI48 1 "register_operand" "=&d")
7777 (mod:SWI48 (match_dup 2) (match_dup 3)))
7778 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7779 (clobber (reg:CC FLAGS_REG))]
7783 [(parallel [(set (match_dup 1)
7784 (ashiftrt:SWI48 (match_dup 4) (match_dup 5)))
7785 (clobber (reg:CC FLAGS_REG))])
7786 (parallel [(set (match_dup 0)
7787 (div:SWI48 (match_dup 2) (match_dup 3)))
7789 (mod:SWI48 (match_dup 2) (match_dup 3)))
7791 (clobber (reg:CC FLAGS_REG))])]
7793 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7795 if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
7796 operands[4] = operands[2];
7799 /* Avoid use of cltd in favor of a mov+shift. */
7800 emit_move_insn (operands[1], operands[2]);
7801 operands[4] = operands[1];
7804 [(set_attr "type" "multi")
7805 (set_attr "mode" "<MODE>")])
7807 (define_insn_and_split "divmodsi4_zext_1"
7808 [(set (match_operand:DI 0 "register_operand" "=a")
7810 (div:SI (match_operand:SI 2 "register_operand" "0")
7811 (match_operand:SI 3 "nonimmediate_operand" "rm"))))
7812 (set (match_operand:SI 1 "register_operand" "=&d")
7813 (mod:SI (match_dup 2) (match_dup 3)))
7814 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7815 (clobber (reg:CC FLAGS_REG))]
7819 [(parallel [(set (match_dup 1)
7820 (ashiftrt:SI (match_dup 4) (match_dup 5)))
7821 (clobber (reg:CC FLAGS_REG))])
7822 (parallel [(set (match_dup 0)
7823 (zero_extend:DI (div:SI (match_dup 2) (match_dup 3))))
7825 (mod:SI (match_dup 2) (match_dup 3)))
7827 (clobber (reg:CC FLAGS_REG))])]
7829 operands[5] = GEN_INT (GET_MODE_BITSIZE (SImode)-1);
7831 if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
7832 operands[4] = operands[2];
7835 /* Avoid use of cltd in favor of a mov+shift. */
7836 emit_move_insn (operands[1], operands[2]);
7837 operands[4] = operands[1];
7840 [(set_attr "type" "multi")
7841 (set_attr "mode" "SI")])
7843 (define_insn_and_split "divmodsi4_zext_2"
7844 [(set (match_operand:DI 1 "register_operand" "=&d")
7846 (mod:SI (match_operand:SI 2 "register_operand" "0")
7847 (match_operand:SI 3 "nonimmediate_operand" "rm"))))
7848 (set (match_operand:SI 0 "register_operand" "=a")
7849 (div:SI (match_dup 2) (match_dup 3)))
7850 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7851 (clobber (reg:CC FLAGS_REG))]
7855 [(parallel [(set (match_dup 6)
7856 (ashiftrt:SI (match_dup 4) (match_dup 5)))
7857 (clobber (reg:CC FLAGS_REG))])
7858 (parallel [(set (match_dup 1)
7859 (zero_extend:DI (mod:SI (match_dup 2) (match_dup 3))))
7861 (div:SI (match_dup 2) (match_dup 3)))
7863 (clobber (reg:CC FLAGS_REG))])]
7865 operands[5] = GEN_INT (GET_MODE_BITSIZE (SImode)-1);
7866 operands[6] = gen_lowpart (SImode, operands[1]);
7868 if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
7869 operands[4] = operands[2];
7872 /* Avoid use of cltd in favor of a mov+shift. */
7873 emit_move_insn (operands[6], operands[2]);
7874 operands[4] = operands[6];
7877 [(set_attr "type" "multi")
7878 (set_attr "mode" "SI")])
7880 (define_insn_and_split "*divmod<mode>4"
7881 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7882 (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7883 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7884 (set (match_operand:SWIM248 1 "register_operand" "=&d")
7885 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7886 (clobber (reg:CC FLAGS_REG))]
7890 [(parallel [(set (match_dup 1)
7891 (ashiftrt:SWIM248 (match_dup 4) (match_dup 5)))
7892 (clobber (reg:CC FLAGS_REG))])
7893 (parallel [(set (match_dup 0)
7894 (div:SWIM248 (match_dup 2) (match_dup 3)))
7896 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7898 (clobber (reg:CC FLAGS_REG))])]
7900 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7902 if (<MODE>mode != HImode
7903 && (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD))
7904 operands[4] = operands[2];
7907 /* Avoid use of cltd in favor of a mov+shift. */
7908 emit_move_insn (operands[1], operands[2]);
7909 operands[4] = operands[1];
7912 [(set_attr "type" "multi")
7913 (set_attr "mode" "<MODE>")])
7915 (define_insn_and_split "*divmodsi4_zext_1"
7916 [(set (match_operand:DI 0 "register_operand" "=a")
7918 (div:SI (match_operand:SI 2 "register_operand" "0")
7919 (match_operand:SI 3 "nonimmediate_operand" "rm"))))
7920 (set (match_operand:SI 1 "register_operand" "=&d")
7921 (mod:SI (match_dup 2) (match_dup 3)))
7922 (clobber (reg:CC FLAGS_REG))]
7926 [(parallel [(set (match_dup 1)
7927 (ashiftrt:SI (match_dup 4) (match_dup 5)))
7928 (clobber (reg:CC FLAGS_REG))])
7929 (parallel [(set (match_dup 0)
7930 (zero_extend:DI (div:SI (match_dup 2) (match_dup 3))))
7932 (mod:SI (match_dup 2) (match_dup 3)))
7934 (clobber (reg:CC FLAGS_REG))])]
7936 operands[5] = GEN_INT (GET_MODE_BITSIZE (SImode)-1);
7938 if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
7939 operands[4] = operands[2];
7942 /* Avoid use of cltd in favor of a mov+shift. */
7943 emit_move_insn (operands[1], operands[2]);
7944 operands[4] = operands[1];
7947 [(set_attr "type" "multi")
7948 (set_attr "mode" "SI")])
7950 (define_insn_and_split "*divmodsi4_zext_2"
7951 [(set (match_operand:DI 1 "register_operand" "=&d")
7953 (mod:SI (match_operand:SI 2 "register_operand" "0")
7954 (match_operand:SI 3 "nonimmediate_operand" "rm"))))
7955 (set (match_operand:SI 0 "register_operand" "=a")
7956 (div:SI (match_dup 2) (match_dup 3)))
7957 (clobber (reg:CC FLAGS_REG))]
7961 [(parallel [(set (match_dup 6)
7962 (ashiftrt:SI (match_dup 4) (match_dup 5)))
7963 (clobber (reg:CC FLAGS_REG))])
7964 (parallel [(set (match_dup 1)
7965 (zero_extend:DI (mod:SI (match_dup 2) (match_dup 3))))
7967 (div:SI (match_dup 2) (match_dup 3)))
7969 (clobber (reg:CC FLAGS_REG))])]
7971 operands[5] = GEN_INT (GET_MODE_BITSIZE (SImode)-1);
7972 operands[6] = gen_lowpart (SImode, operands[1]);
7974 if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
7975 operands[4] = operands[2];
7978 /* Avoid use of cltd in favor of a mov+shift. */
7979 emit_move_insn (operands[6], operands[2]);
7980 operands[4] = operands[6];
7983 [(set_attr "type" "multi")
7984 (set_attr "mode" "SI")])
7986 (define_insn "*divmod<mode>4_noext"
7987 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7988 (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7989 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7990 (set (match_operand:SWIM248 1 "register_operand" "=d")
7991 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7992 (use (match_operand:SWIM248 4 "register_operand" "1"))
7993 (clobber (reg:CC FLAGS_REG))]
7995 "idiv{<imodesuffix>}\t%3"
7996 [(set_attr "type" "idiv")
7997 (set_attr "mode" "<MODE>")])
7999 (define_insn "*divmodsi4_noext_zext_1"
8000 [(set (match_operand:DI 0 "register_operand" "=a")
8002 (div:SI (match_operand:SI 2 "register_operand" "0")
8003 (match_operand:SI 3 "nonimmediate_operand" "rm"))))
8004 (set (match_operand:SI 1 "register_operand" "=d")
8005 (mod:SI (match_dup 2) (match_dup 3)))
8006 (use (match_operand:SI 4 "register_operand" "1"))
8007 (clobber (reg:CC FLAGS_REG))]
8010 [(set_attr "type" "idiv")
8011 (set_attr "mode" "SI")])
8013 (define_insn "*divmodsi4_noext_zext_2"
8014 [(set (match_operand:DI 1 "register_operand" "=d")
8016 (mod:SI (match_operand:SI 2 "register_operand" "0")
8017 (match_operand:SI 3 "nonimmediate_operand" "rm"))))
8018 (set (match_operand:SI 0 "register_operand" "=a")
8019 (div:SI (match_dup 2) (match_dup 3)))
8020 (use (match_operand:SI 4 "register_operand" "1"))
8021 (clobber (reg:CC FLAGS_REG))]
8024 [(set_attr "type" "idiv")
8025 (set_attr "mode" "SI")])
8027 (define_expand "divmodqi4"
8028 [(parallel [(set (match_operand:QI 0 "register_operand")
8030 (match_operand:QI 1 "register_operand")
8031 (match_operand:QI 2 "nonimmediate_operand")))
8032 (set (match_operand:QI 3 "register_operand")
8033 (mod:QI (match_dup 1) (match_dup 2)))
8034 (clobber (reg:CC FLAGS_REG))])]
8035 "TARGET_QIMODE_MATH"
8040 tmp0 = gen_reg_rtx (HImode);
8041 tmp1 = gen_reg_rtx (HImode);
8043 /* Extend operands[1] to HImode. Generate 8bit divide. Result is in AX. */
8044 emit_insn (gen_extendqihi2 (tmp1, operands[1]));
8045 emit_insn (gen_divmodhiqi3 (tmp0, tmp1, operands[2]));
8047 /* Extract remainder from AH. */
8048 tmp1 = gen_rtx_ZERO_EXTRACT (SImode, tmp0, GEN_INT (8), GEN_INT (8));
8049 tmp1 = lowpart_subreg (QImode, tmp1, SImode);
8050 rtx_insn *insn = emit_move_insn (operands[3], tmp1);
8052 mod = gen_rtx_MOD (QImode, operands[1], operands[2]);
8053 set_unique_reg_note (insn, REG_EQUAL, mod);
8055 /* Extract quotient from AL. */
8056 insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
8058 div = gen_rtx_DIV (QImode, operands[1], operands[2]);
8059 set_unique_reg_note (insn, REG_EQUAL, div);
8064 ;; Divide AX by r/m8, with result stored in
8067 ;; Change div/mod to HImode and extend the second argument to HImode
8068 ;; so that mode of div/mod matches with mode of arguments. Otherwise
8069 ;; combine may fail.
8070 (define_insn "divmodhiqi3"
8071 [(set (match_operand:HI 0 "register_operand" "=a")
8076 (mod:HI (match_operand:HI 1 "register_operand" "0")
8078 (match_operand:QI 2 "nonimmediate_operand" "qm")))))
8082 (div:HI (match_dup 1) (sign_extend:HI (match_dup 2)))))))
8083 (clobber (reg:CC FLAGS_REG))]
8084 "TARGET_QIMODE_MATH"
8086 [(set_attr "type" "idiv")
8087 (set_attr "mode" "QI")])
8089 (define_expand "udivmod<mode>4"
8090 [(parallel [(set (match_operand:SWIM248 0 "register_operand")
8092 (match_operand:SWIM248 1 "register_operand")
8093 (match_operand:SWIM248 2 "nonimmediate_operand")))
8094 (set (match_operand:SWIM248 3 "register_operand")
8095 (umod:SWIM248 (match_dup 1) (match_dup 2)))
8096 (clobber (reg:CC FLAGS_REG))])])
8098 ;; Split with 8bit unsigned divide:
8099 ;; if (dividend an divisor are in [0-255])
8100 ;; use 8bit unsigned integer divide
8102 ;; use original integer divide
8104 [(set (match_operand:SWI48 0 "register_operand")
8105 (udiv:SWI48 (match_operand:SWI48 2 "register_operand")
8106 (match_operand:SWI48 3 "nonimmediate_operand")))
8107 (set (match_operand:SWI48 1 "register_operand")
8108 (umod:SWI48 (match_dup 2) (match_dup 3)))
8109 (clobber (reg:CC FLAGS_REG))]
8110 "TARGET_USE_8BIT_IDIV
8111 && TARGET_QIMODE_MATH
8112 && can_create_pseudo_p ()
8113 && !optimize_insn_for_size_p ()"
8115 "ix86_split_idivmod (<MODE>mode, operands, false); DONE;")
8118 [(set (match_operand:DI 0 "register_operand")
8120 (udiv:SI (match_operand:SI 2 "register_operand")
8121 (match_operand:SI 3 "nonimmediate_operand"))))
8122 (set (match_operand:SI 1 "register_operand")
8123 (umod:SI (match_dup 2) (match_dup 3)))
8124 (clobber (reg:CC FLAGS_REG))]
8126 && TARGET_USE_8BIT_IDIV
8127 && TARGET_QIMODE_MATH
8128 && can_create_pseudo_p ()
8129 && !optimize_insn_for_size_p ()"
8131 "ix86_split_idivmod (SImode, operands, false); DONE;")
8134 [(set (match_operand:DI 1 "register_operand")
8136 (umod:SI (match_operand:SI 2 "register_operand")
8137 (match_operand:SI 3 "nonimmediate_operand"))))
8138 (set (match_operand:SI 0 "register_operand")
8139 (udiv:SI (match_dup 2) (match_dup 3)))
8140 (clobber (reg:CC FLAGS_REG))]
8142 && TARGET_USE_8BIT_IDIV
8143 && TARGET_QIMODE_MATH
8144 && can_create_pseudo_p ()
8145 && !optimize_insn_for_size_p ()"
8147 "ix86_split_idivmod (SImode, operands, false); DONE;")
8149 (define_insn_and_split "udivmod<mode>4_1"
8150 [(set (match_operand:SWI48 0 "register_operand" "=a")
8151 (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "0")
8152 (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
8153 (set (match_operand:SWI48 1 "register_operand" "=&d")
8154 (umod:SWI48 (match_dup 2) (match_dup 3)))
8155 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
8156 (clobber (reg:CC FLAGS_REG))]
8160 [(set (match_dup 1) (const_int 0))
8161 (parallel [(set (match_dup 0)
8162 (udiv:SWI48 (match_dup 2) (match_dup 3)))
8164 (umod:SWI48 (match_dup 2) (match_dup 3)))
8166 (clobber (reg:CC FLAGS_REG))])]
8168 [(set_attr "type" "multi")
8169 (set_attr "mode" "<MODE>")])
8171 (define_insn_and_split "udivmodsi4_zext_1"
8172 [(set (match_operand:DI 0 "register_operand" "=a")
8174 (udiv:SI (match_operand:SI 2 "register_operand" "0")
8175 (match_operand:SI 3 "nonimmediate_operand" "rm"))))
8176 (set (match_operand:SI 1 "register_operand" "=&d")
8177 (umod:SI (match_dup 2) (match_dup 3)))
8178 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
8179 (clobber (reg:CC FLAGS_REG))]
8183 [(set (match_dup 1) (const_int 0))
8184 (parallel [(set (match_dup 0)
8185 (zero_extend:DI (udiv:SI (match_dup 2) (match_dup 3))))
8187 (umod:SI (match_dup 2) (match_dup 3)))
8189 (clobber (reg:CC FLAGS_REG))])]
8191 [(set_attr "type" "multi")
8192 (set_attr "mode" "SI")])
8194 (define_insn_and_split "udivmodsi4_zext_2"
8195 [(set (match_operand:DI 1 "register_operand" "=&d")
8197 (umod:SI (match_operand:SI 2 "register_operand" "0")
8198 (match_operand:SI 3 "nonimmediate_operand" "rm"))))
8199 (set (match_operand:SI 0 "register_operand" "=a")
8200 (udiv:SI (match_dup 2) (match_dup 3)))
8201 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
8202 (clobber (reg:CC FLAGS_REG))]
8206 [(set (match_dup 4) (const_int 0))
8207 (parallel [(set (match_dup 1)
8208 (zero_extend:DI (umod:SI (match_dup 2) (match_dup 3))))
8210 (udiv:SI (match_dup 2) (match_dup 3)))
8212 (clobber (reg:CC FLAGS_REG))])]
8213 "operands[4] = gen_lowpart (SImode, operands[1]);"
8214 [(set_attr "type" "multi")
8215 (set_attr "mode" "SI")])
8217 (define_insn_and_split "*udivmod<mode>4"
8218 [(set (match_operand:SWIM248 0 "register_operand" "=a")
8219 (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
8220 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
8221 (set (match_operand:SWIM248 1 "register_operand" "=&d")
8222 (umod:SWIM248 (match_dup 2) (match_dup 3)))
8223 (clobber (reg:CC FLAGS_REG))]
8227 [(set (match_dup 1) (const_int 0))
8228 (parallel [(set (match_dup 0)
8229 (udiv:SWIM248 (match_dup 2) (match_dup 3)))
8231 (umod:SWIM248 (match_dup 2) (match_dup 3)))
8233 (clobber (reg:CC FLAGS_REG))])]
8235 [(set_attr "type" "multi")
8236 (set_attr "mode" "<MODE>")])
8238 (define_insn_and_split "*udivmodsi4_zext_1"
8239 [(set (match_operand:DI 0 "register_operand" "=a")
8241 (udiv:SI (match_operand:SI 2 "register_operand" "0")
8242 (match_operand:SI 3 "nonimmediate_operand" "rm"))))
8243 (set (match_operand:SI 1 "register_operand" "=&d")
8244 (umod:SI (match_dup 2) (match_dup 3)))
8245 (clobber (reg:CC FLAGS_REG))]
8249 [(set (match_dup 1) (const_int 0))
8250 (parallel [(set (match_dup 0)
8251 (zero_extend:DI (udiv:SI (match_dup 2) (match_dup 3))))
8253 (umod:SI (match_dup 2) (match_dup 3)))
8255 (clobber (reg:CC FLAGS_REG))])]
8257 [(set_attr "type" "multi")
8258 (set_attr "mode" "SI")])
8260 (define_insn_and_split "*udivmodsi4_zext_2"
8261 [(set (match_operand:DI 1 "register_operand" "=&d")
8263 (umod:SI (match_operand:SI 2 "register_operand" "0")
8264 (match_operand:SI 3 "nonimmediate_operand" "rm"))))
8265 (set (match_operand:SI 0 "register_operand" "=a")
8266 (udiv:SI (match_dup 2) (match_dup 3)))
8267 (clobber (reg:CC FLAGS_REG))]
8271 [(set (match_dup 4) (const_int 0))
8272 (parallel [(set (match_dup 1)
8273 (zero_extend:DI (umod:SI (match_dup 2) (match_dup 3))))
8275 (udiv:SI (match_dup 2) (match_dup 3)))
8277 (clobber (reg:CC FLAGS_REG))])]
8278 "operands[4] = gen_lowpart (SImode, operands[1]);"
8279 [(set_attr "type" "multi")
8280 (set_attr "mode" "SI")])
8282 ;; Optimize division or modulo by constant power of 2, if the constant
8283 ;; materializes only after expansion.
8284 (define_insn_and_split "*udivmod<mode>4_pow2"
8285 [(set (match_operand:SWI48 0 "register_operand" "=r")
8286 (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "0")
8287 (match_operand:SWI48 3 "const_int_operand" "n")))
8288 (set (match_operand:SWI48 1 "register_operand" "=r")
8289 (umod:SWI48 (match_dup 2) (match_dup 3)))
8290 (clobber (reg:CC FLAGS_REG))]
8291 "IN_RANGE (INTVAL (operands[3]), 2, HOST_WIDE_INT_UC (0x80000000))
8292 && (UINTVAL (operands[3]) & (UINTVAL (operands[3]) - 1)) == 0"
8295 [(set (match_dup 1) (match_dup 2))
8296 (parallel [(set (match_dup 0) (lshiftrt:<MODE> (match_dup 2) (match_dup 4)))
8297 (clobber (reg:CC FLAGS_REG))])
8298 (parallel [(set (match_dup 1) (and:<MODE> (match_dup 1) (match_dup 5)))
8299 (clobber (reg:CC FLAGS_REG))])]
8301 int v = exact_log2 (UINTVAL (operands[3]));
8302 operands[4] = GEN_INT (v);
8303 operands[5] = GEN_INT ((HOST_WIDE_INT_1U << v) - 1);
8305 [(set_attr "type" "multi")
8306 (set_attr "mode" "<MODE>")])
8308 (define_insn_and_split "*udivmodsi4_pow2_zext_1"
8309 [(set (match_operand:DI 0 "register_operand" "=r")
8311 (udiv:SI (match_operand:SI 2 "register_operand" "0")
8312 (match_operand:SI 3 "const_int_operand" "n"))))
8313 (set (match_operand:SI 1 "register_operand" "=r")
8314 (umod:SI (match_dup 2) (match_dup 3)))
8315 (clobber (reg:CC FLAGS_REG))]
8317 && IN_RANGE (INTVAL (operands[3]), 2, HOST_WIDE_INT_UC (0x80000000))
8318 && (UINTVAL (operands[3]) & (UINTVAL (operands[3]) - 1)) == 0"
8321 [(set (match_dup 1) (match_dup 2))
8322 (parallel [(set (match_dup 0)
8323 (zero_extend:DI (lshiftrt:SI (match_dup 2) (match_dup 4))))
8324 (clobber (reg:CC FLAGS_REG))])
8325 (parallel [(set (match_dup 1) (and:SI (match_dup 1) (match_dup 5)))
8326 (clobber (reg:CC FLAGS_REG))])]
8328 int v = exact_log2 (UINTVAL (operands[3]));
8329 operands[4] = GEN_INT (v);
8330 operands[5] = GEN_INT ((HOST_WIDE_INT_1U << v) - 1);
8332 [(set_attr "type" "multi")
8333 (set_attr "mode" "SI")])
8335 (define_insn_and_split "*udivmodsi4_pow2_zext_2"
8336 [(set (match_operand:DI 1 "register_operand" "=r")
8338 (umod:SI (match_operand:SI 2 "register_operand" "0")
8339 (match_operand:SI 3 "const_int_operand" "n"))))
8340 (set (match_operand:SI 0 "register_operand" "=r")
8341 (umod:SI (match_dup 2) (match_dup 3)))
8342 (clobber (reg:CC FLAGS_REG))]
8344 && IN_RANGE (INTVAL (operands[3]), 2, HOST_WIDE_INT_UC (0x80000000))
8345 && (UINTVAL (operands[3]) & (UINTVAL (operands[3]) - 1)) == 0"
8348 [(set (match_dup 1) (match_dup 2))
8349 (parallel [(set (match_dup 0) (lshiftrt:SI (match_dup 2) (match_dup 4)))
8350 (clobber (reg:CC FLAGS_REG))])
8351 (parallel [(set (match_dup 1)
8352 (zero_extend:DI (and:SI (match_dup 1) (match_dup 5))))
8353 (clobber (reg:CC FLAGS_REG))])]
8355 int v = exact_log2 (UINTVAL (operands[3]));
8356 operands[4] = GEN_INT (v);
8357 operands[5] = GEN_INT ((HOST_WIDE_INT_1U << v) - 1);
8359 [(set_attr "type" "multi")
8360 (set_attr "mode" "SI")])
8362 (define_insn "*udivmod<mode>4_noext"
8363 [(set (match_operand:SWIM248 0 "register_operand" "=a")
8364 (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
8365 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
8366 (set (match_operand:SWIM248 1 "register_operand" "=d")
8367 (umod:SWIM248 (match_dup 2) (match_dup 3)))
8368 (use (match_operand:SWIM248 4 "register_operand" "1"))
8369 (clobber (reg:CC FLAGS_REG))]
8371 "div{<imodesuffix>}\t%3"
8372 [(set_attr "type" "idiv")
8373 (set_attr "mode" "<MODE>")])
8375 (define_insn "*udivmodsi4_noext_zext_1"
8376 [(set (match_operand:DI 0 "register_operand" "=a")
8378 (udiv:SI (match_operand:SI 2 "register_operand" "0")
8379 (match_operand:SI 3 "nonimmediate_operand" "rm"))))
8380 (set (match_operand:SI 1 "register_operand" "=d")
8381 (umod:SI (match_dup 2) (match_dup 3)))
8382 (use (match_operand:SI 4 "register_operand" "1"))
8383 (clobber (reg:CC FLAGS_REG))]
8386 [(set_attr "type" "idiv")
8387 (set_attr "mode" "SI")])
8389 (define_insn "*udivmodsi4_noext_zext_2"
8390 [(set (match_operand:DI 1 "register_operand" "=d")
8392 (umod:SI (match_operand:SI 2 "register_operand" "0")
8393 (match_operand:SI 3 "nonimmediate_operand" "rm"))))
8394 (set (match_operand:SI 0 "register_operand" "=a")
8395 (udiv:SI (match_dup 2) (match_dup 3)))
8396 (use (match_operand:SI 4 "register_operand" "1"))
8397 (clobber (reg:CC FLAGS_REG))]
8400 [(set_attr "type" "idiv")
8401 (set_attr "mode" "SI")])
8403 (define_expand "udivmodqi4"
8404 [(parallel [(set (match_operand:QI 0 "register_operand")
8406 (match_operand:QI 1 "register_operand")
8407 (match_operand:QI 2 "nonimmediate_operand")))
8408 (set (match_operand:QI 3 "register_operand")
8409 (umod:QI (match_dup 1) (match_dup 2)))
8410 (clobber (reg:CC FLAGS_REG))])]
8411 "TARGET_QIMODE_MATH"
8416 tmp0 = gen_reg_rtx (HImode);
8417 tmp1 = gen_reg_rtx (HImode);
8419 /* Extend operands[1] to HImode. Generate 8bit divide. Result is in AX. */
8420 emit_insn (gen_zero_extendqihi2 (tmp1, operands[1]));
8421 emit_insn (gen_udivmodhiqi3 (tmp0, tmp1, operands[2]));
8423 /* Extract remainder from AH. */
8424 tmp1 = gen_rtx_ZERO_EXTRACT (SImode, tmp0, GEN_INT (8), GEN_INT (8));
8425 tmp1 = lowpart_subreg (QImode, tmp1, SImode);
8426 rtx_insn *insn = emit_move_insn (operands[3], tmp1);
8428 mod = gen_rtx_UMOD (QImode, operands[1], operands[2]);
8429 set_unique_reg_note (insn, REG_EQUAL, mod);
8431 /* Extract quotient from AL. */
8432 insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
8434 div = gen_rtx_UDIV (QImode, operands[1], operands[2]);
8435 set_unique_reg_note (insn, REG_EQUAL, div);
8440 (define_insn "udivmodhiqi3"
8441 [(set (match_operand:HI 0 "register_operand" "=a")
8446 (mod:HI (match_operand:HI 1 "register_operand" "0")
8448 (match_operand:QI 2 "nonimmediate_operand" "qm")))))
8452 (div:HI (match_dup 1) (zero_extend:HI (match_dup 2)))))))
8453 (clobber (reg:CC FLAGS_REG))]
8454 "TARGET_QIMODE_MATH"
8456 [(set_attr "type" "idiv")
8457 (set_attr "mode" "QI")])
8459 ;; We cannot use div/idiv for double division, because it causes
8460 ;; "division by zero" on the overflow and that's not what we expect
8461 ;; from truncate. Because true (non truncating) double division is
8462 ;; never generated, we can't create this insn anyway.
8465 ; [(set (match_operand:SI 0 "register_operand" "=a")
8467 ; (udiv:DI (match_operand:DI 1 "register_operand" "A")
8469 ; (match_operand:SI 2 "nonimmediate_operand" "rm")))))
8470 ; (set (match_operand:SI 3 "register_operand" "=d")
8472 ; (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
8473 ; (clobber (reg:CC FLAGS_REG))]
8475 ; "div{l}\t{%2, %0|%0, %2}"
8476 ; [(set_attr "type" "idiv")])
8478 ;;- Logical AND instructions
8480 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
8481 ;; Note that this excludes ah.
8483 (define_expand "testsi_ccno_1"
8484 [(set (reg:CCNO FLAGS_REG)
8486 (and:SI (match_operand:SI 0 "nonimmediate_operand")
8487 (match_operand:SI 1 "x86_64_nonmemory_operand"))
8490 (define_expand "testqi_ccz_1"
8491 [(set (reg:CCZ FLAGS_REG)
8492 (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand")
8493 (match_operand:QI 1 "nonmemory_operand"))
8496 (define_expand "testdi_ccno_1"
8497 [(set (reg:CCNO FLAGS_REG)
8499 (and:DI (match_operand:DI 0 "nonimmediate_operand")
8500 (match_operand:DI 1 "x86_64_szext_general_operand"))
8502 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))")
8504 (define_insn "*testdi_1"
8505 [(set (reg FLAGS_REG)
8508 (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
8509 (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
8511 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8512 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8514 test{l}\t{%k1, %k0|%k0, %k1}
8515 test{l}\t{%k1, %k0|%k0, %k1}
8516 test{q}\t{%1, %0|%0, %1}
8517 test{q}\t{%1, %0|%0, %1}
8518 test{q}\t{%1, %0|%0, %1}"
8519 [(set_attr "type" "test")
8520 (set_attr "modrm" "0,1,0,1,1")
8521 (set_attr "mode" "SI,SI,DI,DI,DI")])
8523 (define_insn "*testqi_1_maybe_si"
8524 [(set (reg FLAGS_REG)
8527 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
8528 (match_operand:QI 1 "general_operand" "n,n,qn,n"))
8530 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
8531 && ix86_match_ccmode (insn,
8532 CONST_INT_P (operands[1])
8533 && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
8535 if (which_alternative == 3)
8537 if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
8538 operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
8539 return "test{l}\t{%1, %k0|%k0, %1}";
8541 return "test{b}\t{%1, %0|%0, %1}";
8543 [(set_attr "type" "test")
8544 (set_attr "modrm" "0,1,1,1")
8545 (set_attr "mode" "QI,QI,QI,SI")
8546 (set_attr "pent_pair" "uv,np,uv,np")])
8548 (define_insn "*test<mode>_1"
8549 [(set (reg FLAGS_REG)
8552 (match_operand:SWI124 0 "nonimmediate_operand" "%!*a,<r>,<r>m")
8553 (match_operand:SWI124 1 "<general_operand>" "<i>,<i>,<r><i>"))
8555 "ix86_match_ccmode (insn, CCNOmode)
8556 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8557 "test{<imodesuffix>}\t{%1, %0|%0, %1}"
8558 [(set_attr "type" "test")
8559 (set_attr "modrm" "0,1,1")
8560 (set_attr "mode" "<MODE>")
8561 (set_attr "pent_pair" "uv,np,uv")])
8563 (define_expand "testqi_ext_1_ccno"
8564 [(set (reg:CCNO FLAGS_REG)
8568 (zero_extract:SI (match_operand 0 "ext_register_operand")
8571 (match_operand 1 "const_int_operand"))
8574 (define_insn "*testqi_ext_1"
8575 [(set (reg FLAGS_REG)
8579 (zero_extract:SI (match_operand 0 "ext_register_operand" "Q,Q")
8582 (match_operand:QI 1 "general_operand" "QnBc,m"))
8584 "ix86_match_ccmode (insn, CCNOmode)"
8585 "test{b}\t{%1, %h0|%h0, %1}"
8586 [(set_attr "isa" "*,nox64")
8587 (set_attr "type" "test")
8588 (set_attr "mode" "QI")])
8590 (define_insn "*testqi_ext_2"
8591 [(set (reg FLAGS_REG)
8595 (zero_extract:SI (match_operand 0 "ext_register_operand" "Q")
8599 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q")
8603 "ix86_match_ccmode (insn, CCNOmode)"
8604 "test{b}\t{%h1, %h0|%h0, %h1}"
8605 [(set_attr "type" "test")
8606 (set_attr "mode" "QI")])
8608 ;; Combine likes to form bit extractions for some tests. Humor it.
8609 (define_insn_and_split "*testqi_ext_3"
8610 [(set (match_operand 0 "flags_reg_operand")
8611 (match_operator 1 "compare_operator"
8612 [(zero_extract:SWI248
8613 (match_operand 2 "nonimmediate_operand" "rm")
8614 (match_operand 3 "const_int_operand" "n")
8615 (match_operand 4 "const_int_operand" "n"))
8617 "ix86_match_ccmode (insn, CCNOmode)
8618 && ((TARGET_64BIT && GET_MODE (operands[2]) == DImode)
8619 || GET_MODE (operands[2]) == SImode
8620 || GET_MODE (operands[2]) == HImode
8621 || GET_MODE (operands[2]) == QImode)
8622 /* Ensure that resulting mask is zero or sign extended operand. */
8623 && INTVAL (operands[4]) >= 0
8624 && ((INTVAL (operands[3]) > 0
8625 && INTVAL (operands[3]) + INTVAL (operands[4]) <= 32)
8626 || (<MODE>mode == DImode
8627 && INTVAL (operands[3]) > 32
8628 && INTVAL (operands[3]) + INTVAL (operands[4]) == 64))"
8631 [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
8633 rtx val = operands[2];
8634 HOST_WIDE_INT len = INTVAL (operands[3]);
8635 HOST_WIDE_INT pos = INTVAL (operands[4]);
8636 machine_mode mode = GET_MODE (val);
8640 machine_mode submode = GET_MODE (SUBREG_REG (val));
8642 /* Narrow paradoxical subregs to prevent partial register stalls. */
8643 if (GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode)
8644 && GET_MODE_CLASS (submode) == MODE_INT)
8646 val = SUBREG_REG (val);
8651 /* Small HImode tests can be converted to QImode. */
8652 if (register_operand (val, HImode) && pos + len <= 8)
8654 val = gen_lowpart (QImode, val);
8658 gcc_assert (pos + len <= GET_MODE_PRECISION (mode));
8661 = wi::shifted_mask (pos, len, false, GET_MODE_PRECISION (mode));
8663 operands[2] = gen_rtx_AND (mode, val, immed_wide_int_const (mask, mode));
8666 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
8667 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
8668 ;; this is relatively important trick.
8669 ;; Do the conversion only post-reload to avoid limiting of the register class
8672 [(set (match_operand 0 "flags_reg_operand")
8673 (match_operator 1 "compare_operator"
8674 [(and (match_operand 2 "QIreg_operand")
8675 (match_operand 3 "const_int_operand"))
8678 && GET_MODE (operands[2]) != QImode
8679 && ((ix86_match_ccmode (insn, CCZmode)
8680 && !(INTVAL (operands[3]) & ~(255 << 8)))
8681 || (ix86_match_ccmode (insn, CCNOmode)
8682 && !(INTVAL (operands[3]) & ~(127 << 8))))"
8687 (zero_extract:SI (match_dup 2)
8693 operands[2] = gen_lowpart (SImode, operands[2]);
8694 operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, QImode);
8698 [(set (match_operand 0 "flags_reg_operand")
8699 (match_operator 1 "compare_operator"
8700 [(and (match_operand 2 "nonimmediate_operand")
8701 (match_operand 3 "const_int_operand"))
8704 && GET_MODE (operands[2]) != QImode
8705 && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
8706 && ((ix86_match_ccmode (insn, CCZmode)
8707 && !(INTVAL (operands[3]) & ~255))
8708 || (ix86_match_ccmode (insn, CCNOmode)
8709 && !(INTVAL (operands[3]) & ~127)))"
8711 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
8714 operands[2] = gen_lowpart (QImode, operands[2]);
8715 operands[3] = gen_int_mode (INTVAL (operands[3]), QImode);
8718 ;; %%% This used to optimize known byte-wide and operations to memory,
8719 ;; and sometimes to QImode registers. If this is considered useful,
8720 ;; it should be done with splitters.
8722 (define_expand "and<mode>3"
8723 [(set (match_operand:SWIM1248x 0 "nonimmediate_operand")
8724 (and:SWIM1248x (match_operand:SWIM1248x 1 "nonimmediate_operand")
8725 (match_operand:SWIM1248x 2 "<general_szext_operand>")))]
8728 machine_mode mode = <MODE>mode;
8729 rtx (*insn) (rtx, rtx);
8731 if (CONST_INT_P (operands[2]) && REG_P (operands[0]))
8733 HOST_WIDE_INT ival = INTVAL (operands[2]);
8735 if (ival == (HOST_WIDE_INT) 0xffffffff)
8737 else if (ival == 0xffff)
8739 else if (ival == 0xff)
8743 if (mode == <MODE>mode)
8745 ix86_expand_binary_operator (AND, <MODE>mode, operands);
8749 if (<MODE>mode == DImode)
8750 insn = (mode == SImode)
8751 ? gen_zero_extendsidi2
8753 ? gen_zero_extendhidi2
8754 : gen_zero_extendqidi2;
8755 else if (<MODE>mode == SImode)
8756 insn = (mode == HImode)
8757 ? gen_zero_extendhisi2
8758 : gen_zero_extendqisi2;
8759 else if (<MODE>mode == HImode)
8760 insn = gen_zero_extendqihi2;
8764 emit_insn (insn (operands[0], gen_lowpart (mode, operands[1])));
8768 (define_insn_and_split "*anddi3_doubleword"
8769 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r")
8771 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8772 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm")))
8773 (clobber (reg:CC FLAGS_REG))]
8774 "!TARGET_64BIT && TARGET_STV && TARGET_SSE2
8775 && ix86_binary_operator_ok (AND, DImode, operands)"
8777 "&& reload_completed"
8780 split_double_mode (DImode, &operands[0], 3, &operands[0], &operands[3]);
8781 if (operands[2] == const0_rtx)
8783 operands[1] = const0_rtx;
8784 ix86_expand_move (SImode, &operands[0]);
8786 else if (operands[2] != constm1_rtx)
8787 ix86_expand_binary_operator (AND, SImode, &operands[0]);
8788 else if (operands[5] == constm1_rtx)
8789 emit_note (NOTE_INSN_DELETED);
8790 if (operands[5] == const0_rtx)
8792 operands[4] = const0_rtx;
8793 ix86_expand_move (SImode, &operands[3]);
8795 else if (operands[5] != constm1_rtx)
8796 ix86_expand_binary_operator (AND, SImode, &operands[3]);
8800 (define_insn "*anddi_1"
8801 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
8803 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
8804 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
8805 (clobber (reg:CC FLAGS_REG))]
8806 "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
8808 and{l}\t{%k2, %k0|%k0, %k2}
8809 and{q}\t{%2, %0|%0, %2}
8810 and{q}\t{%2, %0|%0, %2}
8812 [(set_attr "type" "alu,alu,alu,imovx")
8813 (set_attr "length_immediate" "*,*,*,0")
8814 (set (attr "prefix_rex")
8816 (and (eq_attr "type" "imovx")
8817 (and (match_test "INTVAL (operands[2]) == 0xff")
8818 (match_operand 1 "ext_QIreg_operand")))
8820 (const_string "*")))
8821 (set_attr "mode" "SI,DI,DI,SI")])
8823 (define_insn_and_split "*anddi_1_btr"
8824 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
8826 (match_operand:DI 1 "nonimmediate_operand" "%0")
8827 (match_operand:DI 2 "const_int_operand" "n")))
8828 (clobber (reg:CC FLAGS_REG))]
8829 "TARGET_64BIT && TARGET_USE_BT
8830 && ix86_binary_operator_ok (AND, DImode, operands)
8831 && IN_RANGE (exact_log2 (~INTVAL (operands[2])), 31, 63)"
8833 "&& reload_completed"
8834 [(parallel [(set (zero_extract:DI (match_dup 0)
8838 (clobber (reg:CC FLAGS_REG))])]
8839 "operands[3] = GEN_INT (exact_log2 (~INTVAL (operands[2])));"
8840 [(set_attr "type" "alu1")
8841 (set_attr "prefix_0f" "1")
8842 (set_attr "znver1_decode" "double")
8843 (set_attr "mode" "DI")])
8845 ;; Turn *anddi_1 into *andsi_1_zext if possible.
8847 [(set (match_operand:DI 0 "register_operand")
8848 (and:DI (subreg:DI (match_operand:SI 1 "register_operand") 0)
8849 (match_operand:DI 2 "x86_64_zext_immediate_operand")))
8850 (clobber (reg:CC FLAGS_REG))]
8852 [(parallel [(set (match_dup 0)
8853 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))
8854 (clobber (reg:CC FLAGS_REG))])]
8855 "operands[2] = gen_lowpart (SImode, operands[2]);")
8857 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8858 (define_insn "*andsi_1_zext"
8859 [(set (match_operand:DI 0 "register_operand" "=r")
8861 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8862 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
8863 (clobber (reg:CC FLAGS_REG))]
8864 "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
8865 "and{l}\t{%2, %k0|%k0, %2}"
8866 [(set_attr "type" "alu")
8867 (set_attr "mode" "SI")])
8869 (define_insn "*and<mode>_1"
8870 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=rm,r,Ya")
8871 (and:SWI24 (match_operand:SWI24 1 "nonimmediate_operand" "%0,0,qm")
8872 (match_operand:SWI24 2 "<general_operand>" "r<i>,rm,L")))
8873 (clobber (reg:CC FLAGS_REG))]
8874 "ix86_binary_operator_ok (AND, <MODE>mode, operands)"
8876 and{<imodesuffix>}\t{%2, %0|%0, %2}
8877 and{<imodesuffix>}\t{%2, %0|%0, %2}
8879 [(set_attr "type" "alu,alu,imovx")
8880 (set_attr "length_immediate" "*,*,0")
8881 (set (attr "prefix_rex")
8883 (and (eq_attr "type" "imovx")
8884 (and (match_test "INTVAL (operands[2]) == 0xff")
8885 (match_operand 1 "ext_QIreg_operand")))
8887 (const_string "*")))
8888 (set_attr "mode" "<MODE>,<MODE>,SI")])
8890 (define_insn "*andqi_1"
8891 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
8892 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8893 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
8894 (clobber (reg:CC FLAGS_REG))]
8895 "ix86_binary_operator_ok (AND, QImode, operands)"
8897 and{b}\t{%2, %0|%0, %2}
8898 and{b}\t{%2, %0|%0, %2}
8899 and{l}\t{%k2, %k0|%k0, %k2}"
8900 [(set_attr "type" "alu")
8901 (set_attr "mode" "QI,QI,SI")
8902 ;; Potential partial reg stall on alternative 2.
8903 (set (attr "preferred_for_speed")
8904 (cond [(eq_attr "alternative" "2")
8905 (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
8906 (symbol_ref "true")))])
8908 (define_insn "*andqi_1_slp"
8909 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
8910 (and:QI (match_dup 0)
8911 (match_operand:QI 1 "general_operand" "qn,qmn")))
8912 (clobber (reg:CC FLAGS_REG))]
8913 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8914 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8915 "and{b}\t{%1, %0|%0, %1}"
8916 [(set_attr "type" "alu1")
8917 (set_attr "mode" "QI")])
8920 [(set (match_operand:SWI248 0 "register_operand")
8921 (and:SWI248 (match_operand:SWI248 1 "nonimmediate_operand")
8922 (match_operand:SWI248 2 "const_int_operand")))
8923 (clobber (reg:CC FLAGS_REG))]
8925 && (!REG_P (operands[1])
8926 || REGNO (operands[0]) != REGNO (operands[1]))"
8929 HOST_WIDE_INT ival = INTVAL (operands[2]);
8931 rtx (*insn) (rtx, rtx);
8933 if (ival == (HOST_WIDE_INT) 0xffffffff)
8935 else if (ival == 0xffff)
8939 gcc_assert (ival == 0xff);
8943 if (<MODE>mode == DImode)
8944 insn = (mode == SImode)
8945 ? gen_zero_extendsidi2
8947 ? gen_zero_extendhidi2
8948 : gen_zero_extendqidi2;
8951 if (<MODE>mode != SImode)
8952 /* Zero extend to SImode to avoid partial register stalls. */
8953 operands[0] = gen_lowpart (SImode, operands[0]);
8955 insn = (mode == HImode)
8956 ? gen_zero_extendhisi2
8957 : gen_zero_extendqisi2;
8959 emit_insn (insn (operands[0], gen_lowpart (mode, operands[1])));
8964 [(set (match_operand:SWI48 0 "register_operand")
8965 (and:SWI48 (match_dup 0)
8966 (const_int -65536)))
8967 (clobber (reg:CC FLAGS_REG))]
8968 "(TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)
8969 || optimize_function_for_size_p (cfun)"
8970 [(set (strict_low_part (match_dup 1)) (const_int 0))]
8971 "operands[1] = gen_lowpart (HImode, operands[0]);")
8974 [(set (match_operand:SWI248 0 "any_QIreg_operand")
8975 (and:SWI248 (match_dup 0)
8977 (clobber (reg:CC FLAGS_REG))]
8978 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8979 && reload_completed"
8980 [(set (strict_low_part (match_dup 1)) (const_int 0))]
8981 "operands[1] = gen_lowpart (QImode, operands[0]);")
8984 [(set (match_operand:SWI248 0 "QIreg_operand")
8985 (and:SWI248 (match_dup 0)
8986 (const_int -65281)))
8987 (clobber (reg:CC FLAGS_REG))]
8988 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8989 && reload_completed"
8991 [(set (zero_extract:SI (match_dup 0)
8997 (zero_extract:SI (match_dup 0)
9001 (zero_extract:SI (match_dup 0)
9003 (const_int 8)) 0)) 0))
9004 (clobber (reg:CC FLAGS_REG))])]
9005 "operands[0] = gen_lowpart (SImode, operands[0]);")
9007 (define_insn "*anddi_2"
9008 [(set (reg FLAGS_REG)
9011 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
9012 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
9014 (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
9015 (and:DI (match_dup 1) (match_dup 2)))]
9017 && ix86_match_ccmode
9019 /* If we are going to emit andl instead of andq, and the operands[2]
9020 constant might have the SImode sign bit set, make sure the sign
9021 flag isn't tested, because the instruction will set the sign flag
9022 based on bit 31 rather than bit 63. If it isn't CONST_INT,
9023 conservatively assume it might have bit 31 set. */
9024 (satisfies_constraint_Z (operands[2])
9025 && (!CONST_INT_P (operands[2])
9026 || val_signbit_known_set_p (SImode, INTVAL (operands[2]))))
9027 ? CCZmode : CCNOmode)
9028 && ix86_binary_operator_ok (AND, DImode, operands)"
9030 and{l}\t{%k2, %k0|%k0, %k2}
9031 and{q}\t{%2, %0|%0, %2}
9032 and{q}\t{%2, %0|%0, %2}"
9033 [(set_attr "type" "alu")
9034 (set_attr "mode" "SI,DI,DI")])
9036 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9037 (define_insn "*andsi_2_zext"
9038 [(set (reg FLAGS_REG)
9040 (match_operand:SI 1 "nonimmediate_operand" "%0")
9041 (match_operand:SI 2 "x86_64_general_operand" "rme"))
9043 (set (match_operand:DI 0 "register_operand" "=r")
9044 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
9045 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9046 && ix86_binary_operator_ok (AND, SImode, operands)"
9047 "and{l}\t{%2, %k0|%k0, %2}"
9048 [(set_attr "type" "alu")
9049 (set_attr "mode" "SI")])
9051 (define_insn "*andqi_2_maybe_si"
9052 [(set (reg FLAGS_REG)
9054 (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9055 (match_operand:QI 2 "general_operand" "qmn,qn,n"))
9057 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
9058 (and:QI (match_dup 1) (match_dup 2)))]
9059 "ix86_binary_operator_ok (AND, QImode, operands)
9060 && ix86_match_ccmode (insn,
9061 CONST_INT_P (operands[2])
9062 && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
9064 if (which_alternative == 2)
9066 if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
9067 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
9068 return "and{l}\t{%2, %k0|%k0, %2}";
9070 return "and{b}\t{%2, %0|%0, %2}";
9072 [(set_attr "type" "alu")
9073 (set_attr "mode" "QI,QI,SI")])
9075 (define_insn "*and<mode>_2"
9076 [(set (reg FLAGS_REG)
9077 (compare (and:SWI124
9078 (match_operand:SWI124 1 "nonimmediate_operand" "%0,0")
9079 (match_operand:SWI124 2 "<general_operand>" "<g>,<r><i>"))
9081 (set (match_operand:SWI124 0 "nonimmediate_operand" "=<r>,<r>m")
9082 (and:SWI124 (match_dup 1) (match_dup 2)))]
9083 "ix86_match_ccmode (insn, CCNOmode)
9084 && ix86_binary_operator_ok (AND, <MODE>mode, operands)"
9085 "and{<imodesuffix>}\t{%2, %0|%0, %2}"
9086 [(set_attr "type" "alu")
9087 (set_attr "mode" "<MODE>")])
9089 (define_insn "*andqi_2_slp"
9090 [(set (reg FLAGS_REG)
9092 (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9093 (match_operand:QI 1 "nonimmediate_operand" "qmn,qn"))
9095 (set (strict_low_part (match_dup 0))
9096 (and:QI (match_dup 0) (match_dup 1)))]
9097 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9098 && ix86_match_ccmode (insn, CCNOmode)
9099 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9100 "and{b}\t{%1, %0|%0, %1}"
9101 [(set_attr "type" "alu1")
9102 (set_attr "mode" "QI")])
9104 (define_insn "andqi_ext_1"
9105 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q,Q")
9111 (zero_extract:SI (match_operand 1 "ext_register_operand" "0,0")
9114 (match_operand:QI 2 "general_operand" "QnBc,m")) 0))
9115 (clobber (reg:CC FLAGS_REG))]
9116 "/* FIXME: without this LRA can't reload this pattern, see PR82524. */
9117 rtx_equal_p (operands[0], operands[1])"
9118 "and{b}\t{%2, %h0|%h0, %2}"
9119 [(set_attr "isa" "*,nox64")
9120 (set_attr "type" "alu")
9121 (set_attr "mode" "QI")])
9123 ;; Generated by peephole translating test to and. This shows up
9124 ;; often in fp comparisons.
9125 (define_insn "*andqi_ext_1_cc"
9126 [(set (reg FLAGS_REG)
9130 (zero_extract:SI (match_operand 1 "ext_register_operand" "0,0")
9133 (match_operand:QI 2 "general_operand" "QnBc,m"))
9135 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q,Q")
9141 (zero_extract:SI (match_dup 1)
9145 "ix86_match_ccmode (insn, CCNOmode)
9146 /* FIXME: without this LRA can't reload this pattern, see PR82524. */
9147 && rtx_equal_p (operands[0], operands[1])"
9148 "and{b}\t{%2, %h0|%h0, %2}"
9149 [(set_attr "isa" "*,nox64")
9150 (set_attr "type" "alu")
9151 (set_attr "mode" "QI")])
9153 (define_insn "*andqi_ext_2"
9154 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
9160 (zero_extract:SI (match_operand 1 "ext_register_operand" "%0")
9164 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9166 (const_int 8)) 0)) 0))
9167 (clobber (reg:CC FLAGS_REG))]
9168 "/* FIXME: without this LRA can't reload this pattern, see PR82524. */
9169 rtx_equal_p (operands[0], operands[1])
9170 || rtx_equal_p (operands[0], operands[2])"
9171 "and{b}\t{%h2, %h0|%h0, %h2}"
9172 [(set_attr "type" "alu")
9173 (set_attr "mode" "QI")])
9175 ;; Convert wide AND instructions with immediate operand to shorter QImode
9176 ;; equivalents when possible.
9177 ;; Don't do the splitting with memory operands, since it introduces risk
9178 ;; of memory mismatch stalls. We may want to do the splitting for optimizing
9179 ;; for size, but that can (should?) be handled by generic code instead.
9181 [(set (match_operand:SWI248 0 "QIreg_operand")
9182 (and:SWI248 (match_operand:SWI248 1 "register_operand")
9183 (match_operand:SWI248 2 "const_int_operand")))
9184 (clobber (reg:CC FLAGS_REG))]
9186 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9187 && !(~INTVAL (operands[2]) & ~(255 << 8))"
9189 [(set (zero_extract:SI (match_dup 0)
9195 (zero_extract:SI (match_dup 1)
9199 (clobber (reg:CC FLAGS_REG))])]
9201 operands[0] = gen_lowpart (SImode, operands[0]);
9202 operands[1] = gen_lowpart (SImode, operands[1]);
9203 operands[2] = gen_int_mode (INTVAL (operands[2]) >> 8, QImode);
9206 ;; Since AND can be encoded with sign extended immediate, this is only
9207 ;; profitable when 7th bit is not set.
9209 [(set (match_operand:SWI248 0 "any_QIreg_operand")
9210 (and:SWI248 (match_operand:SWI248 1 "general_operand")
9211 (match_operand:SWI248 2 "const_int_operand")))
9212 (clobber (reg:CC FLAGS_REG))]
9214 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9215 && !(~INTVAL (operands[2]) & ~255)
9216 && !(INTVAL (operands[2]) & 128)"
9217 [(parallel [(set (strict_low_part (match_dup 0))
9218 (and:QI (match_dup 1)
9220 (clobber (reg:CC FLAGS_REG))])]
9222 operands[0] = gen_lowpart (QImode, operands[0]);
9223 operands[1] = gen_lowpart (QImode, operands[1]);
9224 operands[2] = gen_int_mode (INTVAL (operands[2]), QImode);
9227 (define_insn "*andndi3_doubleword"
9228 [(set (match_operand:DI 0 "register_operand" "=r,&r")
9230 (not:DI (match_operand:DI 1 "register_operand" "r,0"))
9231 (match_operand:DI 2 "nonimmediate_operand" "rm,rm")))
9232 (clobber (reg:CC FLAGS_REG))]
9233 "!TARGET_64BIT && TARGET_STV && TARGET_SSE2"
9235 [(set_attr "isa" "bmi,*")])
9238 [(set (match_operand:DI 0 "register_operand")
9240 (not:DI (match_operand:DI 1 "register_operand"))
9241 (match_operand:DI 2 "nonimmediate_operand")))
9242 (clobber (reg:CC FLAGS_REG))]
9243 "!TARGET_64BIT && TARGET_BMI && TARGET_STV && TARGET_SSE2
9244 && reload_completed"
9245 [(parallel [(set (match_dup 0)
9246 (and:SI (not:SI (match_dup 1)) (match_dup 2)))
9247 (clobber (reg:CC FLAGS_REG))])
9248 (parallel [(set (match_dup 3)
9249 (and:SI (not:SI (match_dup 4)) (match_dup 5)))
9250 (clobber (reg:CC FLAGS_REG))])]
9251 "split_double_mode (DImode, &operands[0], 3, &operands[0], &operands[3]);")
9254 [(set (match_operand:DI 0 "register_operand")
9256 (not:DI (match_dup 0))
9257 (match_operand:DI 1 "nonimmediate_operand")))
9258 (clobber (reg:CC FLAGS_REG))]
9259 "!TARGET_64BIT && !TARGET_BMI && TARGET_STV && TARGET_SSE2
9260 && reload_completed"
9261 [(set (match_dup 0) (not:SI (match_dup 0)))
9262 (parallel [(set (match_dup 0)
9263 (and:SI (match_dup 0) (match_dup 1)))
9264 (clobber (reg:CC FLAGS_REG))])
9265 (set (match_dup 2) (not:SI (match_dup 2)))
9266 (parallel [(set (match_dup 2)
9267 (and:SI (match_dup 2) (match_dup 3)))
9268 (clobber (reg:CC FLAGS_REG))])]
9269 "split_double_mode (DImode, &operands[0], 2, &operands[0], &operands[2]);")
9271 (define_insn "*andn<mode>_1"
9272 [(set (match_operand:SWI48 0 "register_operand" "=r,r")
9274 (not:SWI48 (match_operand:SWI48 1 "register_operand" "r,r"))
9275 (match_operand:SWI48 2 "nonimmediate_operand" "r,m")))
9276 (clobber (reg:CC FLAGS_REG))]
9278 "andn\t{%2, %1, %0|%0, %1, %2}"
9279 [(set_attr "type" "bitmanip")
9280 (set_attr "btver2_decode" "direct, double")
9281 (set_attr "mode" "<MODE>")])
9283 (define_insn "*andn<mode>_1"
9284 [(set (match_operand:SWI12 0 "register_operand" "=r")
9286 (not:SWI12 (match_operand:SWI12 1 "register_operand" "r"))
9287 (match_operand:SWI12 2 "register_operand" "r")))
9288 (clobber (reg:CC FLAGS_REG))]
9290 "andn\t{%k2, %k1, %k0|%k0, %k1, %k2}"
9291 [(set_attr "type" "bitmanip")
9292 (set_attr "btver2_decode" "direct")
9293 (set_attr "mode" "SI")])
9295 (define_insn "*andn_<mode>_ccno"
9296 [(set (reg FLAGS_REG)
9299 (not:SWI48 (match_operand:SWI48 1 "register_operand" "r,r"))
9300 (match_operand:SWI48 2 "nonimmediate_operand" "r,m"))
9302 (clobber (match_scratch:SWI48 0 "=r,r"))]
9303 "TARGET_BMI && ix86_match_ccmode (insn, CCNOmode)"
9304 "andn\t{%2, %1, %0|%0, %1, %2}"
9305 [(set_attr "type" "bitmanip")
9306 (set_attr "btver2_decode" "direct, double")
9307 (set_attr "mode" "<MODE>")])
9309 ;; Logical inclusive and exclusive OR instructions
9311 ;; %%% This used to optimize known byte-wide and operations to memory.
9312 ;; If this is considered useful, it should be done with splitters.
9314 (define_expand "<code><mode>3"
9315 [(set (match_operand:SWIM1248x 0 "nonimmediate_operand")
9316 (any_or:SWIM1248x (match_operand:SWIM1248x 1 "nonimmediate_operand")
9317 (match_operand:SWIM1248x 2 "<general_operand>")))]
9319 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
9321 (define_insn_and_split "*<code>di3_doubleword"
9322 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r")
9324 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
9325 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm")))
9326 (clobber (reg:CC FLAGS_REG))]
9327 "!TARGET_64BIT && TARGET_STV && TARGET_SSE2
9328 && ix86_binary_operator_ok (<CODE>, DImode, operands)"
9330 "&& reload_completed"
9333 split_double_mode (DImode, &operands[0], 3, &operands[0], &operands[3]);
9334 if (operands[2] == constm1_rtx)
9338 operands[1] = constm1_rtx;
9339 ix86_expand_move (SImode, &operands[0]);
9342 ix86_expand_unary_operator (NOT, SImode, &operands[0]);
9344 else if (operands[2] != const0_rtx)
9345 ix86_expand_binary_operator (<CODE>, SImode, &operands[0]);
9346 else if (operands[5] == const0_rtx)
9347 emit_note (NOTE_INSN_DELETED);
9348 if (operands[5] == constm1_rtx)
9352 operands[4] = constm1_rtx;
9353 ix86_expand_move (SImode, &operands[3]);
9356 ix86_expand_unary_operator (NOT, SImode, &operands[3]);
9358 else if (operands[5] != const0_rtx)
9359 ix86_expand_binary_operator (<CODE>, SImode, &operands[3]);
9363 (define_insn "*<code><mode>_1"
9364 [(set (match_operand:SWI248 0 "nonimmediate_operand" "=r,rm")
9366 (match_operand:SWI248 1 "nonimmediate_operand" "%0,0")
9367 (match_operand:SWI248 2 "<general_operand>" "<g>,r<i>")))
9368 (clobber (reg:CC FLAGS_REG))]
9369 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9370 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
9371 [(set_attr "type" "alu")
9372 (set_attr "mode" "<MODE>")])
9374 (define_insn_and_split "*iordi_1_bts"
9375 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9377 (match_operand:DI 1 "nonimmediate_operand" "%0")
9378 (match_operand:DI 2 "const_int_operand" "n")))
9379 (clobber (reg:CC FLAGS_REG))]
9380 "TARGET_64BIT && TARGET_USE_BT
9381 && ix86_binary_operator_ok (IOR, DImode, operands)
9382 && IN_RANGE (exact_log2 (INTVAL (operands[2])), 31, 63)"
9384 "&& reload_completed"
9385 [(parallel [(set (zero_extract:DI (match_dup 0)
9389 (clobber (reg:CC FLAGS_REG))])]
9390 "operands[3] = GEN_INT (exact_log2 (INTVAL (operands[2])));"
9391 [(set_attr "type" "alu1")
9392 (set_attr "prefix_0f" "1")
9393 (set_attr "znver1_decode" "double")
9394 (set_attr "mode" "DI")])
9396 (define_insn_and_split "*xordi_1_btc"
9397 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9399 (match_operand:DI 1 "nonimmediate_operand" "%0")
9400 (match_operand:DI 2 "const_int_operand" "n")))
9401 (clobber (reg:CC FLAGS_REG))]
9402 "TARGET_64BIT && TARGET_USE_BT
9403 && ix86_binary_operator_ok (XOR, DImode, operands)
9404 && IN_RANGE (exact_log2 (INTVAL (operands[2])), 31, 63)"
9406 "&& reload_completed"
9407 [(parallel [(set (zero_extract:DI (match_dup 0)
9410 (not:DI (zero_extract:DI (match_dup 0)
9413 (clobber (reg:CC FLAGS_REG))])]
9414 "operands[3] = GEN_INT (exact_log2 (INTVAL (operands[2])));"
9415 [(set_attr "type" "alu1")
9416 (set_attr "prefix_0f" "1")
9417 (set_attr "znver1_decode" "double")
9418 (set_attr "mode" "DI")])
9420 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9421 (define_insn "*<code>si_1_zext"
9422 [(set (match_operand:DI 0 "register_operand" "=r")
9424 (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9425 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
9426 (clobber (reg:CC FLAGS_REG))]
9427 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
9428 "<logic>{l}\t{%2, %k0|%k0, %2}"
9429 [(set_attr "type" "alu")
9430 (set_attr "mode" "SI")])
9432 (define_insn "*<code>si_1_zext_imm"
9433 [(set (match_operand:DI 0 "register_operand" "=r")
9435 (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
9436 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
9437 (clobber (reg:CC FLAGS_REG))]
9438 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
9439 "<logic>{l}\t{%2, %k0|%k0, %2}"
9440 [(set_attr "type" "alu")
9441 (set_attr "mode" "SI")])
9443 (define_insn "*<code>qi_1"
9444 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
9445 (any_or:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9446 (match_operand:QI 2 "general_operand" "qmn,qn,rn")))
9447 (clobber (reg:CC FLAGS_REG))]
9448 "ix86_binary_operator_ok (<CODE>, QImode, operands)"
9450 <logic>{b}\t{%2, %0|%0, %2}
9451 <logic>{b}\t{%2, %0|%0, %2}
9452 <logic>{l}\t{%k2, %k0|%k0, %k2}"
9453 [(set_attr "type" "alu")
9454 (set_attr "mode" "QI,QI,SI")
9455 ;; Potential partial reg stall on alternative 2.
9456 (set (attr "preferred_for_speed")
9457 (cond [(eq_attr "alternative" "2")
9458 (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
9459 (symbol_ref "true")))])
9461 (define_insn "*<code>qi_1_slp"
9462 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
9463 (any_or:QI (match_dup 0)
9464 (match_operand:QI 1 "general_operand" "qmn,qn")))
9465 (clobber (reg:CC FLAGS_REG))]
9466 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9467 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9468 "<logic>{b}\t{%1, %0|%0, %1}"
9469 [(set_attr "type" "alu1")
9470 (set_attr "mode" "QI")])
9472 (define_insn "*<code><mode>_2"
9473 [(set (reg FLAGS_REG)
9474 (compare (any_or:SWI
9475 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
9476 (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>"))
9478 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
9479 (any_or:SWI (match_dup 1) (match_dup 2)))]
9480 "ix86_match_ccmode (insn, CCNOmode)
9481 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9482 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
9483 [(set_attr "type" "alu")
9484 (set_attr "mode" "<MODE>")])
9486 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9487 ;; ??? Special case for immediate operand is missing - it is tricky.
9488 (define_insn "*<code>si_2_zext"
9489 [(set (reg FLAGS_REG)
9490 (compare (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9491 (match_operand:SI 2 "x86_64_general_operand" "rme"))
9493 (set (match_operand:DI 0 "register_operand" "=r")
9494 (zero_extend:DI (any_or:SI (match_dup 1) (match_dup 2))))]
9495 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9496 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
9497 "<logic>{l}\t{%2, %k0|%k0, %2}"
9498 [(set_attr "type" "alu")
9499 (set_attr "mode" "SI")])
9501 (define_insn "*<code>si_2_zext_imm"
9502 [(set (reg FLAGS_REG)
9504 (match_operand:SI 1 "nonimmediate_operand" "%0")
9505 (match_operand:SI 2 "x86_64_zext_immediate_operand" "Z"))
9507 (set (match_operand:DI 0 "register_operand" "=r")
9508 (any_or:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
9509 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9510 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
9511 "<logic>{l}\t{%2, %k0|%k0, %2}"
9512 [(set_attr "type" "alu")
9513 (set_attr "mode" "SI")])
9515 (define_insn "*<code>qi_2_slp"
9516 [(set (reg FLAGS_REG)
9517 (compare (any_or:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9518 (match_operand:QI 1 "general_operand" "qmn,qn"))
9520 (set (strict_low_part (match_dup 0))
9521 (any_or:QI (match_dup 0) (match_dup 1)))]
9522 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9523 && ix86_match_ccmode (insn, CCNOmode)
9524 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9525 "<logic>{b}\t{%1, %0|%0, %1}"
9526 [(set_attr "type" "alu1")
9527 (set_attr "mode" "QI")])
9529 (define_insn "*<code><mode>_3"
9530 [(set (reg FLAGS_REG)
9531 (compare (any_or:SWI
9532 (match_operand:SWI 1 "nonimmediate_operand" "%0")
9533 (match_operand:SWI 2 "<general_operand>" "<g>"))
9535 (clobber (match_scratch:SWI 0 "=<r>"))]
9536 "ix86_match_ccmode (insn, CCNOmode)
9537 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9538 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
9539 [(set_attr "type" "alu")
9540 (set_attr "mode" "<MODE>")])
9542 (define_insn "*<code>qi_ext_1"
9543 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q,Q")
9549 (zero_extract:SI (match_operand 1 "ext_register_operand" "0,0")
9552 (match_operand:QI 2 "general_operand" "QnBc,m")) 0))
9553 (clobber (reg:CC FLAGS_REG))]
9554 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9555 /* FIXME: without this LRA can't reload this pattern, see PR82524. */
9556 && rtx_equal_p (operands[0], operands[1])"
9557 "<logic>{b}\t{%2, %h0|%h0, %2}"
9558 [(set_attr "isa" "*,nox64")
9559 (set_attr "type" "alu")
9560 (set_attr "mode" "QI")])
9562 (define_insn "*<code>qi_ext_2"
9563 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
9569 (zero_extract:SI (match_operand 1 "ext_register_operand" "%0")
9573 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9575 (const_int 8)) 0)) 0))
9576 (clobber (reg:CC FLAGS_REG))]
9577 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9578 /* FIXME: without this LRA can't reload this pattern, see PR82524. */
9579 && (rtx_equal_p (operands[0], operands[1])
9580 || rtx_equal_p (operands[0], operands[2]))"
9581 "<logic>{b}\t{%h2, %h0|%h0, %h2}"
9582 [(set_attr "type" "alu")
9583 (set_attr "mode" "QI")])
9585 ;; Convert wide OR instructions with immediate operand to shorter QImode
9586 ;; equivalents when possible.
9587 ;; Don't do the splitting with memory operands, since it introduces risk
9588 ;; of memory mismatch stalls. We may want to do the splitting for optimizing
9589 ;; for size, but that can (should?) be handled by generic code instead.
9591 [(set (match_operand:SWI248 0 "QIreg_operand")
9592 (any_or:SWI248 (match_operand:SWI248 1 "register_operand")
9593 (match_operand:SWI248 2 "const_int_operand")))
9594 (clobber (reg:CC FLAGS_REG))]
9596 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9597 && !(INTVAL (operands[2]) & ~(255 << 8))"
9599 [(set (zero_extract:SI (match_dup 0)
9605 (zero_extract:SI (match_dup 1)
9609 (clobber (reg:CC FLAGS_REG))])]
9611 operands[0] = gen_lowpart (SImode, operands[0]);
9612 operands[1] = gen_lowpart (SImode, operands[1]);
9613 operands[2] = gen_int_mode (INTVAL (operands[2]) >> 8, QImode);
9616 ;; Since OR can be encoded with sign extended immediate, this is only
9617 ;; profitable when 7th bit is set.
9619 [(set (match_operand:SWI248 0 "any_QIreg_operand")
9620 (any_or:SWI248 (match_operand:SWI248 1 "general_operand")
9621 (match_operand:SWI248 2 "const_int_operand")))
9622 (clobber (reg:CC FLAGS_REG))]
9624 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9625 && !(INTVAL (operands[2]) & ~255)
9626 && (INTVAL (operands[2]) & 128)"
9627 [(parallel [(set (strict_low_part (match_dup 0))
9628 (any_or:QI (match_dup 1)
9630 (clobber (reg:CC FLAGS_REG))])]
9632 operands[0] = gen_lowpart (QImode, operands[0]);
9633 operands[1] = gen_lowpart (QImode, operands[1]);
9634 operands[2] = gen_int_mode (INTVAL (operands[2]), QImode);
9637 (define_expand "xorqi_ext_1_cc"
9639 (set (reg:CCNO FLAGS_REG)
9643 (zero_extract:SI (match_operand 1 "ext_register_operand")
9646 (match_operand 2 "const_int_operand"))
9648 (set (zero_extract:SI (match_operand 0 "ext_register_operand")
9654 (zero_extract:SI (match_dup 1)
9657 (match_dup 2)) 0))])])
9659 (define_insn "*xorqi_ext_1_cc"
9660 [(set (reg FLAGS_REG)
9664 (zero_extract:SI (match_operand 1 "ext_register_operand" "0,0")
9667 (match_operand:QI 2 "general_operand" "QnBc,m"))
9669 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q,Q")
9675 (zero_extract:SI (match_dup 1)
9679 "ix86_match_ccmode (insn, CCNOmode)
9680 /* FIXME: without this LRA can't reload this pattern, see PR82524. */
9681 && rtx_equal_p (operands[0], operands[1])"
9682 "xor{b}\t{%2, %h0|%h0, %2}"
9683 [(set_attr "isa" "*,nox64")
9684 (set_attr "type" "alu")
9685 (set_attr "mode" "QI")])
9687 ;; Negation instructions
9689 (define_expand "neg<mode>2"
9690 [(set (match_operand:SDWIM 0 "nonimmediate_operand")
9691 (neg:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")))]
9693 "ix86_expand_unary_operator (NEG, <MODE>mode, operands); DONE;")
9695 (define_insn_and_split "*neg<dwi>2_doubleword"
9696 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro")
9697 (neg:<DWI> (match_operand:<DWI> 1 "nonimmediate_operand" "0")))
9698 (clobber (reg:CC FLAGS_REG))]
9699 "ix86_unary_operator_ok (NEG, <DWI>mode, operands)"
9703 [(set (reg:CCZ FLAGS_REG)
9704 (compare:CCZ (neg:DWIH (match_dup 1)) (const_int 0)))
9705 (set (match_dup 0) (neg:DWIH (match_dup 1)))])
9708 (plus:DWIH (plus:DWIH (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
9711 (clobber (reg:CC FLAGS_REG))])
9714 (neg:DWIH (match_dup 2)))
9715 (clobber (reg:CC FLAGS_REG))])]
9716 "split_double_mode (<DWI>mode, &operands[0], 2, &operands[0], &operands[2]);")
9718 (define_insn "*neg<mode>2_1"
9719 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9720 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")))
9721 (clobber (reg:CC FLAGS_REG))]
9722 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
9723 "neg{<imodesuffix>}\t%0"
9724 [(set_attr "type" "negnot")
9725 (set_attr "mode" "<MODE>")])
9727 ;; Combine is quite creative about this pattern.
9728 (define_insn "*negsi2_1_zext"
9729 [(set (match_operand:DI 0 "register_operand" "=r")
9731 (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
9734 (clobber (reg:CC FLAGS_REG))]
9735 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9737 [(set_attr "type" "negnot")
9738 (set_attr "mode" "SI")])
9740 ;; The problem with neg is that it does not perform (compare x 0),
9741 ;; it really performs (compare 0 x), which leaves us with the zero
9742 ;; flag being the only useful item.
9744 (define_insn "*neg<mode>2_cmpz"
9745 [(set (reg:CCZ FLAGS_REG)
9747 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
9749 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9750 (neg:SWI (match_dup 1)))]
9751 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
9752 "neg{<imodesuffix>}\t%0"
9753 [(set_attr "type" "negnot")
9754 (set_attr "mode" "<MODE>")])
9756 (define_insn "*negsi2_cmpz_zext"
9757 [(set (reg:CCZ FLAGS_REG)
9761 (match_operand:DI 1 "register_operand" "0")
9765 (set (match_operand:DI 0 "register_operand" "=r")
9766 (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
9769 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9771 [(set_attr "type" "negnot")
9772 (set_attr "mode" "SI")])
9774 ;; Negate with jump on overflow.
9775 (define_expand "negv<mode>3"
9776 [(parallel [(set (reg:CCO FLAGS_REG)
9777 (ne:CCO (match_operand:SWI 1 "register_operand")
9779 (set (match_operand:SWI 0 "register_operand")
9780 (neg:SWI (match_dup 1)))])
9781 (set (pc) (if_then_else
9782 (eq (reg:CCO FLAGS_REG) (const_int 0))
9783 (label_ref (match_operand 2))
9788 = gen_int_mode (HOST_WIDE_INT_1U << (GET_MODE_BITSIZE (<MODE>mode) - 1),
9792 (define_insn "*negv<mode>3"
9793 [(set (reg:CCO FLAGS_REG)
9794 (ne:CCO (match_operand:SWI 1 "nonimmediate_operand" "0")
9795 (match_operand:SWI 2 "const_int_operand")))
9796 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9797 (neg:SWI (match_dup 1)))]
9798 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)
9799 && mode_signbit_p (<MODE>mode, operands[2])"
9800 "neg{<imodesuffix>}\t%0"
9801 [(set_attr "type" "negnot")
9802 (set_attr "mode" "<MODE>")])
9804 ;; Changing of sign for FP values is doable using integer unit too.
9806 (define_expand "<code><mode>2"
9807 [(set (match_operand:X87MODEF 0 "register_operand")
9808 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand")))]
9809 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
9810 "ix86_expand_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
9812 (define_insn "*absneg<mode>2"
9813 [(set (match_operand:MODEF 0 "register_operand" "=Yv,Yv,f,!r")
9814 (match_operator:MODEF 3 "absneg_operator"
9815 [(match_operand:MODEF 1 "register_operand" "0,Yv,0,0")]))
9816 (use (match_operand:<ssevecmode> 2 "nonimmediate_operand" "Yvm,0,X,X"))
9817 (clobber (reg:CC FLAGS_REG))]
9818 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
9820 [(set (attr "enabled")
9822 (match_test ("SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"))
9824 (eq_attr "alternative" "2")
9825 (symbol_ref "TARGET_MIX_SSE_I387")
9826 (symbol_ref "true"))
9828 (eq_attr "alternative" "2,3")
9830 (symbol_ref "false"))))])
9832 (define_insn "*absnegxf2_i387"
9833 [(set (match_operand:XF 0 "register_operand" "=f,!r")
9834 (match_operator:XF 3 "absneg_operator"
9835 [(match_operand:XF 1 "register_operand" "0,0")]))
9836 (use (match_operand 2))
9837 (clobber (reg:CC FLAGS_REG))]
9841 (define_expand "<code>tf2"
9842 [(set (match_operand:TF 0 "register_operand")
9843 (absneg:TF (match_operand:TF 1 "register_operand")))]
9845 "ix86_expand_fp_absneg_operator (<CODE>, TFmode, operands); DONE;")
9847 (define_insn "*absnegtf2_sse"
9848 [(set (match_operand:TF 0 "register_operand" "=Yv,Yv")
9849 (match_operator:TF 3 "absneg_operator"
9850 [(match_operand:TF 1 "register_operand" "0,Yv")]))
9851 (use (match_operand:TF 2 "nonimmediate_operand" "Yvm,0"))
9852 (clobber (reg:CC FLAGS_REG))]
9856 ;; Splitters for fp abs and neg.
9859 [(set (match_operand 0 "fp_register_operand")
9860 (match_operator 1 "absneg_operator" [(match_dup 0)]))
9861 (use (match_operand 2))
9862 (clobber (reg:CC FLAGS_REG))]
9864 [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
9867 [(set (match_operand 0 "sse_reg_operand")
9868 (match_operator 3 "absneg_operator"
9869 [(match_operand 1 "register_operand")]))
9870 (use (match_operand 2 "nonimmediate_operand"))
9871 (clobber (reg:CC FLAGS_REG))]
9873 [(set (match_dup 0) (match_dup 3))]
9875 machine_mode mode = GET_MODE (operands[0]);
9876 machine_mode vmode = GET_MODE (operands[2]);
9879 operands[0] = lowpart_subreg (vmode, operands[0], mode);
9880 operands[1] = lowpart_subreg (vmode, operands[1], mode);
9881 if (operands_match_p (operands[0], operands[2]))
9882 std::swap (operands[1], operands[2]);
9883 if (GET_CODE (operands[3]) == ABS)
9884 tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
9886 tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
9891 [(set (match_operand:SF 0 "general_reg_operand")
9892 (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
9893 (use (match_operand:V4SF 2))
9894 (clobber (reg:CC FLAGS_REG))]
9896 [(parallel [(set (match_dup 0) (match_dup 1))
9897 (clobber (reg:CC FLAGS_REG))])]
9900 operands[0] = gen_lowpart (SImode, operands[0]);
9901 if (GET_CODE (operands[1]) == ABS)
9903 tmp = gen_int_mode (0x7fffffff, SImode);
9904 tmp = gen_rtx_AND (SImode, operands[0], tmp);
9908 tmp = gen_int_mode (0x80000000, SImode);
9909 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9915 [(set (match_operand:DF 0 "general_reg_operand")
9916 (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
9917 (use (match_operand 2))
9918 (clobber (reg:CC FLAGS_REG))]
9920 [(parallel [(set (match_dup 0) (match_dup 1))
9921 (clobber (reg:CC FLAGS_REG))])]
9926 tmp = gen_lowpart (DImode, operands[0]);
9927 tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
9930 if (GET_CODE (operands[1]) == ABS)
9933 tmp = gen_rtx_NOT (DImode, tmp);
9937 operands[0] = gen_highpart (SImode, operands[0]);
9938 if (GET_CODE (operands[1]) == ABS)
9940 tmp = gen_int_mode (0x7fffffff, SImode);
9941 tmp = gen_rtx_AND (SImode, operands[0], tmp);
9945 tmp = gen_int_mode (0x80000000, SImode);
9946 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9953 [(set (match_operand:XF 0 "general_reg_operand")
9954 (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
9955 (use (match_operand 2))
9956 (clobber (reg:CC FLAGS_REG))]
9958 [(parallel [(set (match_dup 0) (match_dup 1))
9959 (clobber (reg:CC FLAGS_REG))])]
9962 operands[0] = gen_rtx_REG (SImode,
9963 REGNO (operands[0]) + (TARGET_64BIT ? 1 : 2));
9964 if (GET_CODE (operands[1]) == ABS)
9966 tmp = GEN_INT (0x7fff);
9967 tmp = gen_rtx_AND (SImode, operands[0], tmp);
9971 tmp = GEN_INT (0x8000);
9972 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9977 ;; Conditionalize these after reload. If they match before reload, we
9978 ;; lose the clobber and ability to use integer instructions.
9980 (define_insn "*<code><mode>2_1"
9981 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
9982 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "0")))]
9984 && (reload_completed
9985 || !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
9986 "f<absneg_mnemonic>"
9987 [(set_attr "type" "fsgn")
9988 (set_attr "mode" "<MODE>")])
9990 (define_insn "*<code>extendsfdf2"
9991 [(set (match_operand:DF 0 "register_operand" "=f")
9992 (absneg:DF (float_extend:DF
9993 (match_operand:SF 1 "register_operand" "0"))))]
9994 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
9995 "f<absneg_mnemonic>"
9996 [(set_attr "type" "fsgn")
9997 (set_attr "mode" "DF")])
9999 (define_insn "*<code>extendsfxf2"
10000 [(set (match_operand:XF 0 "register_operand" "=f")
10001 (absneg:XF (float_extend:XF
10002 (match_operand:SF 1 "register_operand" "0"))))]
10004 "f<absneg_mnemonic>"
10005 [(set_attr "type" "fsgn")
10006 (set_attr "mode" "XF")])
10008 (define_insn "*<code>extenddfxf2"
10009 [(set (match_operand:XF 0 "register_operand" "=f")
10010 (absneg:XF (float_extend:XF
10011 (match_operand:DF 1 "register_operand" "0"))))]
10013 "f<absneg_mnemonic>"
10014 [(set_attr "type" "fsgn")
10015 (set_attr "mode" "XF")])
10017 ;; Copysign instructions
10019 (define_mode_iterator CSGNMODE [SF DF TF])
10020 (define_mode_attr CSGNVMODE [(SF "V4SF") (DF "V2DF") (TF "TF")])
10022 (define_expand "copysign<mode>3"
10023 [(match_operand:CSGNMODE 0 "register_operand")
10024 (match_operand:CSGNMODE 1 "nonmemory_operand")
10025 (match_operand:CSGNMODE 2 "register_operand")]
10026 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10027 || (TARGET_SSE && (<MODE>mode == TFmode))"
10028 "ix86_expand_copysign (operands); DONE;")
10030 (define_insn_and_split "copysign<mode>3_const"
10031 [(set (match_operand:CSGNMODE 0 "register_operand" "=Yv")
10033 [(match_operand:<CSGNVMODE> 1 "vector_move_operand" "YvmC")
10034 (match_operand:CSGNMODE 2 "register_operand" "0")
10035 (match_operand:<CSGNVMODE> 3 "nonimmediate_operand" "Yvm")]
10037 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10038 || (TARGET_SSE && (<MODE>mode == TFmode))"
10040 "&& reload_completed"
10042 "ix86_split_copysign_const (operands); DONE;")
10044 (define_insn "copysign<mode>3_var"
10045 [(set (match_operand:CSGNMODE 0 "register_operand" "=Yv,Yv,Yv,Yv,Yv")
10047 [(match_operand:CSGNMODE 2 "register_operand" "Yv,0,0,Yv,Yv")
10048 (match_operand:CSGNMODE 3 "register_operand" "1,1,Yv,1,Yv")
10049 (match_operand:<CSGNVMODE> 4
10050 "nonimmediate_operand" "X,Yvm,Yvm,0,0")
10051 (match_operand:<CSGNVMODE> 5
10052 "nonimmediate_operand" "0,Yvm,1,Yvm,1")]
10054 (clobber (match_scratch:<CSGNVMODE> 1 "=Yv,Yv,Yv,Yv,Yv"))]
10055 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10056 || (TARGET_SSE && (<MODE>mode == TFmode))"
10060 [(set (match_operand:CSGNMODE 0 "register_operand")
10062 [(match_operand:CSGNMODE 2 "register_operand")
10063 (match_operand:CSGNMODE 3 "register_operand")
10064 (match_operand:<CSGNVMODE> 4)
10065 (match_operand:<CSGNVMODE> 5)]
10067 (clobber (match_scratch:<CSGNVMODE> 1))]
10068 "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10069 || (TARGET_SSE && (<MODE>mode == TFmode)))
10070 && reload_completed"
10072 "ix86_split_copysign_var (operands); DONE;")
10074 ;; One complement instructions
10076 (define_expand "one_cmpl<mode>2"
10077 [(set (match_operand:SWIM1248x 0 "nonimmediate_operand")
10078 (not:SWIM1248x (match_operand:SWIM1248x 1 "nonimmediate_operand")))]
10080 "ix86_expand_unary_operator (NOT, <MODE>mode, operands); DONE;")
10082 (define_insn_and_split "*one_cmpldi2_doubleword"
10083 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10084 (not:DI (match_operand:DI 1 "nonimmediate_operand" "0")))]
10085 "!TARGET_64BIT && TARGET_STV && TARGET_SSE2
10086 && ix86_unary_operator_ok (NOT, DImode, operands)"
10088 "&& reload_completed"
10089 [(set (match_dup 0)
10090 (not:SI (match_dup 1)))
10092 (not:SI (match_dup 3)))]
10093 "split_double_mode (DImode, &operands[0], 2, &operands[0], &operands[2]);")
10095 (define_insn "*one_cmpl<mode>2_1"
10096 [(set (match_operand:SWI248 0 "nonimmediate_operand" "=rm")
10097 (not:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "0")))]
10098 "ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
10099 "not{<imodesuffix>}\t%0"
10100 [(set_attr "type" "negnot")
10101 (set_attr "mode" "<MODE>")])
10103 ;; ??? Currently never generated - xor is used instead.
10104 (define_insn "*one_cmplsi2_1_zext"
10105 [(set (match_operand:DI 0 "register_operand" "=r")
10107 (not:SI (match_operand:SI 1 "register_operand" "0"))))]
10108 "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
10110 [(set_attr "type" "negnot")
10111 (set_attr "mode" "SI")])
10113 (define_insn "*one_cmplqi2_1"
10114 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
10115 (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
10116 "ix86_unary_operator_ok (NOT, QImode, operands)"
10120 [(set_attr "type" "negnot")
10121 (set_attr "mode" "QI,SI")
10122 ;; Potential partial reg stall on alternative 1.
10123 (set (attr "preferred_for_speed")
10124 (cond [(eq_attr "alternative" "1")
10125 (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
10126 (symbol_ref "true")))])
10128 (define_insn "*one_cmpl<mode>2_2"
10129 [(set (reg FLAGS_REG)
10130 (compare (not:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
10132 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
10133 (not:SWI (match_dup 1)))]
10134 "ix86_match_ccmode (insn, CCNOmode)
10135 && ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
10137 [(set_attr "type" "alu1")
10138 (set_attr "mode" "<MODE>")])
10141 [(set (match_operand 0 "flags_reg_operand")
10142 (match_operator 2 "compare_operator"
10143 [(not:SWI (match_operand:SWI 3 "nonimmediate_operand"))
10145 (set (match_operand:SWI 1 "nonimmediate_operand")
10146 (not:SWI (match_dup 3)))]
10147 "ix86_match_ccmode (insn, CCNOmode)"
10148 [(parallel [(set (match_dup 0)
10149 (match_op_dup 2 [(xor:SWI (match_dup 3) (const_int -1))
10152 (xor:SWI (match_dup 3) (const_int -1)))])])
10154 ;; ??? Currently never generated - xor is used instead.
10155 (define_insn "*one_cmplsi2_2_zext"
10156 [(set (reg FLAGS_REG)
10157 (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
10159 (set (match_operand:DI 0 "register_operand" "=r")
10160 (zero_extend:DI (not:SI (match_dup 1))))]
10161 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10162 && ix86_unary_operator_ok (NOT, SImode, operands)"
10164 [(set_attr "type" "alu1")
10165 (set_attr "mode" "SI")])
10168 [(set (match_operand 0 "flags_reg_operand")
10169 (match_operator 2 "compare_operator"
10170 [(not:SI (match_operand:SI 3 "register_operand"))
10172 (set (match_operand:DI 1 "register_operand")
10173 (zero_extend:DI (not:SI (match_dup 3))))]
10174 "ix86_match_ccmode (insn, CCNOmode)"
10175 [(parallel [(set (match_dup 0)
10176 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10179 (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])])
10181 ;; Shift instructions
10183 ;; DImode shifts are implemented using the i386 "shift double" opcode,
10184 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem". If the shift count
10185 ;; is variable, then the count is in %cl and the "imm" operand is dropped
10186 ;; from the assembler input.
10188 ;; This instruction shifts the target reg/mem as usual, but instead of
10189 ;; shifting in zeros, bits are shifted in from reg operand. If the insn
10190 ;; is a left shift double, bits are taken from the high order bits of
10191 ;; reg, else if the insn is a shift right double, bits are taken from the
10192 ;; low order bits of reg. So if %eax is "1234" and %edx is "5678",
10193 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
10195 ;; Since sh[lr]d does not change the `reg' operand, that is done
10196 ;; separately, making all shifts emit pairs of shift double and normal
10197 ;; shift. Since sh[lr]d does not shift more than 31 bits, and we wish to
10198 ;; support a 63 bit shift, each shift where the count is in a reg expands
10199 ;; to a pair of shifts, a branch, a shift by 32 and a label.
10201 ;; If the shift count is a constant, we need never emit more than one
10202 ;; shift pair, instead using moves and sign extension for counts greater
10205 (define_expand "ashl<mode>3"
10206 [(set (match_operand:SDWIM 0 "<shift_operand>")
10207 (ashift:SDWIM (match_operand:SDWIM 1 "<ashl_input_operand>")
10208 (match_operand:QI 2 "nonmemory_operand")))]
10210 "ix86_expand_binary_operator (ASHIFT, <MODE>mode, operands); DONE;")
10212 (define_insn "*ashl<mode>3_doubleword"
10213 [(set (match_operand:DWI 0 "register_operand" "=&r")
10214 (ashift:DWI (match_operand:DWI 1 "reg_or_pm1_operand" "0n")
10215 (match_operand:QI 2 "nonmemory_operand" "<S>c")))
10216 (clobber (reg:CC FLAGS_REG))]
10219 [(set_attr "type" "multi")])
10222 [(set (match_operand:DWI 0 "register_operand")
10223 (ashift:DWI (match_operand:DWI 1 "nonmemory_operand")
10224 (match_operand:QI 2 "nonmemory_operand")))
10225 (clobber (reg:CC FLAGS_REG))]
10226 "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
10228 "ix86_split_ashl (operands, NULL_RTX, <MODE>mode); DONE;")
10230 ;; By default we don't ask for a scratch register, because when DWImode
10231 ;; values are manipulated, registers are already at a premium. But if
10232 ;; we have one handy, we won't turn it away.
10235 [(match_scratch:DWIH 3 "r")
10236 (parallel [(set (match_operand:<DWI> 0 "register_operand")
10238 (match_operand:<DWI> 1 "nonmemory_operand")
10239 (match_operand:QI 2 "nonmemory_operand")))
10240 (clobber (reg:CC FLAGS_REG))])
10244 "ix86_split_ashl (operands, operands[3], <DWI>mode); DONE;")
10246 (define_insn "x86_64_shld"
10247 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
10248 (ior:DI (ashift:DI (match_dup 0)
10249 (match_operand:QI 2 "nonmemory_operand" "Jc"))
10250 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
10251 (minus:QI (const_int 64) (match_dup 2)))))
10252 (clobber (reg:CC FLAGS_REG))]
10254 "shld{q}\t{%s2%1, %0|%0, %1, %2}"
10255 [(set_attr "type" "ishift")
10256 (set_attr "prefix_0f" "1")
10257 (set_attr "mode" "DI")
10258 (set_attr "athlon_decode" "vector")
10259 (set_attr "amdfam10_decode" "vector")
10260 (set_attr "bdver1_decode" "vector")])
10262 (define_insn "x86_shld"
10263 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
10264 (ior:SI (ashift:SI (match_dup 0)
10265 (match_operand:QI 2 "nonmemory_operand" "Ic"))
10266 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
10267 (minus:QI (const_int 32) (match_dup 2)))))
10268 (clobber (reg:CC FLAGS_REG))]
10270 "shld{l}\t{%s2%1, %0|%0, %1, %2}"
10271 [(set_attr "type" "ishift")
10272 (set_attr "prefix_0f" "1")
10273 (set_attr "mode" "SI")
10274 (set_attr "pent_pair" "np")
10275 (set_attr "athlon_decode" "vector")
10276 (set_attr "amdfam10_decode" "vector")
10277 (set_attr "bdver1_decode" "vector")])
10279 (define_expand "x86_shift<mode>_adj_1"
10280 [(set (reg:CCZ FLAGS_REG)
10281 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand")
10284 (set (match_operand:SWI48 0 "register_operand")
10285 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
10286 (match_operand:SWI48 1 "register_operand")
10289 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
10290 (match_operand:SWI48 3 "register_operand")
10293 "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
10295 (define_expand "x86_shift<mode>_adj_2"
10296 [(use (match_operand:SWI48 0 "register_operand"))
10297 (use (match_operand:SWI48 1 "register_operand"))
10298 (use (match_operand:QI 2 "register_operand"))]
10301 rtx_code_label *label = gen_label_rtx ();
10304 emit_insn (gen_testqi_ccz_1 (operands[2],
10305 GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
10307 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
10308 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
10309 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
10310 gen_rtx_LABEL_REF (VOIDmode, label),
10312 tmp = emit_jump_insn (gen_rtx_SET (pc_rtx, tmp));
10313 JUMP_LABEL (tmp) = label;
10315 emit_move_insn (operands[0], operands[1]);
10316 ix86_expand_clear (operands[1]);
10318 emit_label (label);
10319 LABEL_NUSES (label) = 1;
10324 ;; Avoid useless masking of count operand.
10325 (define_insn_and_split "*ashl<mode>3_mask"
10326 [(set (match_operand:SWI48 0 "nonimmediate_operand")
10328 (match_operand:SWI48 1 "nonimmediate_operand")
10331 (match_operand:SI 2 "register_operand")
10332 (match_operand:SI 3 "const_int_operand")) 0)))
10333 (clobber (reg:CC FLAGS_REG))]
10334 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)
10335 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10336 == GET_MODE_BITSIZE (<MODE>mode)-1
10337 && can_create_pseudo_p ()"
10341 [(set (match_dup 0)
10342 (ashift:SWI48 (match_dup 1)
10344 (clobber (reg:CC FLAGS_REG))])]
10345 "operands[2] = gen_lowpart (QImode, operands[2]);")
10347 (define_insn_and_split "*ashl<mode>3_mask_1"
10348 [(set (match_operand:SWI48 0 "nonimmediate_operand")
10350 (match_operand:SWI48 1 "nonimmediate_operand")
10352 (match_operand:QI 2 "register_operand")
10353 (match_operand:QI 3 "const_int_operand"))))
10354 (clobber (reg:CC FLAGS_REG))]
10355 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)
10356 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10357 == GET_MODE_BITSIZE (<MODE>mode)-1
10358 && can_create_pseudo_p ()"
10362 [(set (match_dup 0)
10363 (ashift:SWI48 (match_dup 1)
10365 (clobber (reg:CC FLAGS_REG))])])
10367 (define_insn "*bmi2_ashl<mode>3_1"
10368 [(set (match_operand:SWI48 0 "register_operand" "=r")
10369 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
10370 (match_operand:SWI48 2 "register_operand" "r")))]
10372 "shlx\t{%2, %1, %0|%0, %1, %2}"
10373 [(set_attr "type" "ishiftx")
10374 (set_attr "mode" "<MODE>")])
10376 (define_insn "*ashl<mode>3_1"
10377 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r,r")
10378 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,l,rm")
10379 (match_operand:QI 2 "nonmemory_operand" "c<S>,M,r")))
10380 (clobber (reg:CC FLAGS_REG))]
10381 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
10383 switch (get_attr_type (insn))
10390 gcc_assert (operands[2] == const1_rtx);
10391 gcc_assert (rtx_equal_p (operands[0], operands[1]));
10392 return "add{<imodesuffix>}\t%0, %0";
10395 if (operands[2] == const1_rtx
10396 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10397 return "sal{<imodesuffix>}\t%0";
10399 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
10402 [(set_attr "isa" "*,*,bmi2")
10404 (cond [(eq_attr "alternative" "1")
10405 (const_string "lea")
10406 (eq_attr "alternative" "2")
10407 (const_string "ishiftx")
10408 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
10409 (match_operand 0 "register_operand"))
10410 (match_operand 2 "const1_operand"))
10411 (const_string "alu")
10413 (const_string "ishift")))
10414 (set (attr "length_immediate")
10416 (ior (eq_attr "type" "alu")
10417 (and (eq_attr "type" "ishift")
10418 (and (match_operand 2 "const1_operand")
10419 (ior (match_test "TARGET_SHIFT1")
10420 (match_test "optimize_function_for_size_p (cfun)")))))
10422 (const_string "*")))
10423 (set_attr "mode" "<MODE>")])
10425 ;; Convert shift to the shiftx pattern to avoid flags dependency.
10427 [(set (match_operand:SWI48 0 "register_operand")
10428 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
10429 (match_operand:QI 2 "register_operand")))
10430 (clobber (reg:CC FLAGS_REG))]
10431 "TARGET_BMI2 && reload_completed"
10432 [(set (match_dup 0)
10433 (ashift:SWI48 (match_dup 1) (match_dup 2)))]
10434 "operands[2] = gen_lowpart (<MODE>mode, operands[2]);")
10436 (define_insn "*bmi2_ashlsi3_1_zext"
10437 [(set (match_operand:DI 0 "register_operand" "=r")
10439 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
10440 (match_operand:SI 2 "register_operand" "r"))))]
10441 "TARGET_64BIT && TARGET_BMI2"
10442 "shlx\t{%2, %1, %k0|%k0, %1, %2}"
10443 [(set_attr "type" "ishiftx")
10444 (set_attr "mode" "SI")])
10446 (define_insn "*ashlsi3_1_zext"
10447 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
10449 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l,rm")
10450 (match_operand:QI 2 "nonmemory_operand" "cI,M,r"))))
10451 (clobber (reg:CC FLAGS_REG))]
10452 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10454 switch (get_attr_type (insn))
10461 gcc_assert (operands[2] == const1_rtx);
10462 return "add{l}\t%k0, %k0";
10465 if (operands[2] == const1_rtx
10466 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10467 return "sal{l}\t%k0";
10469 return "sal{l}\t{%2, %k0|%k0, %2}";
10472 [(set_attr "isa" "*,*,bmi2")
10474 (cond [(eq_attr "alternative" "1")
10475 (const_string "lea")
10476 (eq_attr "alternative" "2")
10477 (const_string "ishiftx")
10478 (and (match_test "TARGET_DOUBLE_WITH_ADD")
10479 (match_operand 2 "const1_operand"))
10480 (const_string "alu")
10482 (const_string "ishift")))
10483 (set (attr "length_immediate")
10485 (ior (eq_attr "type" "alu")
10486 (and (eq_attr "type" "ishift")
10487 (and (match_operand 2 "const1_operand")
10488 (ior (match_test "TARGET_SHIFT1")
10489 (match_test "optimize_function_for_size_p (cfun)")))))
10491 (const_string "*")))
10492 (set_attr "mode" "SI")])
10494 ;; Convert shift to the shiftx pattern to avoid flags dependency.
10496 [(set (match_operand:DI 0 "register_operand")
10498 (ashift:SI (match_operand:SI 1 "nonimmediate_operand")
10499 (match_operand:QI 2 "register_operand"))))
10500 (clobber (reg:CC FLAGS_REG))]
10501 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
10502 [(set (match_dup 0)
10503 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
10504 "operands[2] = gen_lowpart (SImode, operands[2]);")
10506 (define_insn "*ashlhi3_1"
10507 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,Yp")
10508 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
10509 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10510 (clobber (reg:CC FLAGS_REG))]
10511 "ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10513 switch (get_attr_type (insn))
10519 gcc_assert (operands[2] == const1_rtx);
10520 return "add{w}\t%0, %0";
10523 if (operands[2] == const1_rtx
10524 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10525 return "sal{w}\t%0";
10527 return "sal{w}\t{%2, %0|%0, %2}";
10530 [(set (attr "type")
10531 (cond [(eq_attr "alternative" "1")
10532 (const_string "lea")
10533 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
10534 (match_operand 0 "register_operand"))
10535 (match_operand 2 "const1_operand"))
10536 (const_string "alu")
10538 (const_string "ishift")))
10539 (set (attr "length_immediate")
10541 (ior (eq_attr "type" "alu")
10542 (and (eq_attr "type" "ishift")
10543 (and (match_operand 2 "const1_operand")
10544 (ior (match_test "TARGET_SHIFT1")
10545 (match_test "optimize_function_for_size_p (cfun)")))))
10547 (const_string "*")))
10548 (set_attr "mode" "HI,SI")])
10550 (define_insn "*ashlqi3_1"
10551 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,Yp")
10552 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
10553 (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
10554 (clobber (reg:CC FLAGS_REG))]
10555 "ix86_binary_operator_ok (ASHIFT, QImode, operands)"
10557 switch (get_attr_type (insn))
10563 gcc_assert (operands[2] == const1_rtx);
10564 if (REG_P (operands[1]) && !ANY_QI_REGNO_P (REGNO (operands[1])))
10565 return "add{l}\t%k0, %k0";
10567 return "add{b}\t%0, %0";
10570 if (operands[2] == const1_rtx
10571 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10573 if (get_attr_mode (insn) == MODE_SI)
10574 return "sal{l}\t%k0";
10576 return "sal{b}\t%0";
10580 if (get_attr_mode (insn) == MODE_SI)
10581 return "sal{l}\t{%2, %k0|%k0, %2}";
10583 return "sal{b}\t{%2, %0|%0, %2}";
10587 [(set (attr "type")
10588 (cond [(eq_attr "alternative" "2")
10589 (const_string "lea")
10590 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
10591 (match_operand 0 "register_operand"))
10592 (match_operand 2 "const1_operand"))
10593 (const_string "alu")
10595 (const_string "ishift")))
10596 (set (attr "length_immediate")
10598 (ior (eq_attr "type" "alu")
10599 (and (eq_attr "type" "ishift")
10600 (and (match_operand 2 "const1_operand")
10601 (ior (match_test "TARGET_SHIFT1")
10602 (match_test "optimize_function_for_size_p (cfun)")))))
10604 (const_string "*")))
10605 (set_attr "mode" "QI,SI,SI")
10606 ;; Potential partial reg stall on alternative 1.
10607 (set (attr "preferred_for_speed")
10608 (cond [(eq_attr "alternative" "1")
10609 (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
10610 (symbol_ref "true")))])
10612 (define_insn "*ashlqi3_1_slp"
10613 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10614 (ashift:QI (match_dup 0)
10615 (match_operand:QI 1 "nonmemory_operand" "cI")))
10616 (clobber (reg:CC FLAGS_REG))]
10617 "(optimize_function_for_size_p (cfun)
10618 || !TARGET_PARTIAL_FLAG_REG_STALL
10619 || (operands[1] == const1_rtx
10621 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
10623 switch (get_attr_type (insn))
10626 gcc_assert (operands[1] == const1_rtx);
10627 return "add{b}\t%0, %0";
10630 if (operands[1] == const1_rtx
10631 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10632 return "sal{b}\t%0";
10634 return "sal{b}\t{%1, %0|%0, %1}";
10637 [(set (attr "type")
10638 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
10639 (match_operand 0 "register_operand"))
10640 (match_operand 1 "const1_operand"))
10641 (const_string "alu")
10643 (const_string "ishift1")))
10644 (set (attr "length_immediate")
10646 (ior (eq_attr "type" "alu")
10647 (and (eq_attr "type" "ishift1")
10648 (and (match_operand 1 "const1_operand")
10649 (ior (match_test "TARGET_SHIFT1")
10650 (match_test "optimize_function_for_size_p (cfun)")))))
10652 (const_string "*")))
10653 (set_attr "mode" "QI")])
10655 ;; Convert ashift to the lea pattern to avoid flags dependency.
10657 [(set (match_operand:SWI 0 "register_operand")
10658 (ashift:SWI (match_operand:SWI 1 "index_register_operand")
10659 (match_operand 2 "const_0_to_3_operand")))
10660 (clobber (reg:CC FLAGS_REG))]
10662 && REGNO (operands[0]) != REGNO (operands[1])"
10663 [(set (match_dup 0)
10664 (mult:<LEAMODE> (match_dup 1) (match_dup 2)))]
10666 if (<MODE>mode != <LEAMODE>mode)
10668 operands[0] = gen_lowpart (<LEAMODE>mode, operands[0]);
10669 operands[1] = gen_lowpart (<LEAMODE>mode, operands[1]);
10671 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
10674 ;; Convert ashift to the lea pattern to avoid flags dependency.
10676 [(set (match_operand:DI 0 "register_operand")
10678 (ashift:SI (match_operand:SI 1 "index_register_operand")
10679 (match_operand 2 "const_0_to_3_operand"))))
10680 (clobber (reg:CC FLAGS_REG))]
10681 "TARGET_64BIT && reload_completed
10682 && REGNO (operands[0]) != REGNO (operands[1])"
10683 [(set (match_dup 0)
10684 (zero_extend:DI (mult:SI (match_dup 1) (match_dup 2))))]
10686 operands[1] = gen_lowpart (SImode, operands[1]);
10687 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
10690 ;; This pattern can't accept a variable shift count, since shifts by
10691 ;; zero don't affect the flags. We assume that shifts by constant
10692 ;; zero are optimized away.
10693 (define_insn "*ashl<mode>3_cmp"
10694 [(set (reg FLAGS_REG)
10696 (ashift:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
10697 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
10699 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
10700 (ashift:SWI (match_dup 1) (match_dup 2)))]
10701 "(optimize_function_for_size_p (cfun)
10702 || !TARGET_PARTIAL_FLAG_REG_STALL
10703 || (operands[2] == const1_rtx
10705 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
10706 && ix86_match_ccmode (insn, CCGOCmode)
10707 && ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
10709 switch (get_attr_type (insn))
10712 gcc_assert (operands[2] == const1_rtx);
10713 return "add{<imodesuffix>}\t%0, %0";
10716 if (operands[2] == const1_rtx
10717 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10718 return "sal{<imodesuffix>}\t%0";
10720 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
10723 [(set (attr "type")
10724 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
10725 (match_operand 0 "register_operand"))
10726 (match_operand 2 "const1_operand"))
10727 (const_string "alu")
10729 (const_string "ishift")))
10730 (set (attr "length_immediate")
10732 (ior (eq_attr "type" "alu")
10733 (and (eq_attr "type" "ishift")
10734 (and (match_operand 2 "const1_operand")
10735 (ior (match_test "TARGET_SHIFT1")
10736 (match_test "optimize_function_for_size_p (cfun)")))))
10738 (const_string "*")))
10739 (set_attr "mode" "<MODE>")])
10741 (define_insn "*ashlsi3_cmp_zext"
10742 [(set (reg FLAGS_REG)
10744 (ashift:SI (match_operand:SI 1 "register_operand" "0")
10745 (match_operand:QI 2 "const_1_to_31_operand" "I"))
10747 (set (match_operand:DI 0 "register_operand" "=r")
10748 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
10750 && (optimize_function_for_size_p (cfun)
10751 || !TARGET_PARTIAL_FLAG_REG_STALL
10752 || (operands[2] == const1_rtx
10754 || TARGET_DOUBLE_WITH_ADD)))
10755 && ix86_match_ccmode (insn, CCGOCmode)
10756 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10758 switch (get_attr_type (insn))
10761 gcc_assert (operands[2] == const1_rtx);
10762 return "add{l}\t%k0, %k0";
10765 if (operands[2] == const1_rtx
10766 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10767 return "sal{l}\t%k0";
10769 return "sal{l}\t{%2, %k0|%k0, %2}";
10772 [(set (attr "type")
10773 (cond [(and (match_test "TARGET_DOUBLE_WITH_ADD")
10774 (match_operand 2 "const1_operand"))
10775 (const_string "alu")
10777 (const_string "ishift")))
10778 (set (attr "length_immediate")
10780 (ior (eq_attr "type" "alu")
10781 (and (eq_attr "type" "ishift")
10782 (and (match_operand 2 "const1_operand")
10783 (ior (match_test "TARGET_SHIFT1")
10784 (match_test "optimize_function_for_size_p (cfun)")))))
10786 (const_string "*")))
10787 (set_attr "mode" "SI")])
10789 (define_insn "*ashl<mode>3_cconly"
10790 [(set (reg FLAGS_REG)
10792 (ashift:SWI (match_operand:SWI 1 "register_operand" "0")
10793 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
10795 (clobber (match_scratch:SWI 0 "=<r>"))]
10796 "(optimize_function_for_size_p (cfun)
10797 || !TARGET_PARTIAL_FLAG_REG_STALL
10798 || (operands[2] == const1_rtx
10800 || TARGET_DOUBLE_WITH_ADD)))
10801 && ix86_match_ccmode (insn, CCGOCmode)"
10803 switch (get_attr_type (insn))
10806 gcc_assert (operands[2] == const1_rtx);
10807 return "add{<imodesuffix>}\t%0, %0";
10810 if (operands[2] == const1_rtx
10811 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10812 return "sal{<imodesuffix>}\t%0";
10814 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
10817 [(set (attr "type")
10818 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
10819 (match_operand 0 "register_operand"))
10820 (match_operand 2 "const1_operand"))
10821 (const_string "alu")
10823 (const_string "ishift")))
10824 (set (attr "length_immediate")
10826 (ior (eq_attr "type" "alu")
10827 (and (eq_attr "type" "ishift")
10828 (and (match_operand 2 "const1_operand")
10829 (ior (match_test "TARGET_SHIFT1")
10830 (match_test "optimize_function_for_size_p (cfun)")))))
10832 (const_string "*")))
10833 (set_attr "mode" "<MODE>")])
10835 ;; See comment above `ashl<mode>3' about how this works.
10837 (define_expand "<shift_insn><mode>3"
10838 [(set (match_operand:SDWIM 0 "<shift_operand>")
10839 (any_shiftrt:SDWIM (match_operand:SDWIM 1 "<shift_operand>")
10840 (match_operand:QI 2 "nonmemory_operand")))]
10842 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
10844 ;; Avoid useless masking of count operand.
10845 (define_insn_and_split "*<shift_insn><mode>3_mask"
10846 [(set (match_operand:SWI48 0 "nonimmediate_operand")
10848 (match_operand:SWI48 1 "nonimmediate_operand")
10851 (match_operand:SI 2 "register_operand")
10852 (match_operand:SI 3 "const_int_operand")) 0)))
10853 (clobber (reg:CC FLAGS_REG))]
10854 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
10855 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10856 == GET_MODE_BITSIZE (<MODE>mode)-1
10857 && can_create_pseudo_p ()"
10861 [(set (match_dup 0)
10862 (any_shiftrt:SWI48 (match_dup 1)
10864 (clobber (reg:CC FLAGS_REG))])]
10865 "operands[2] = gen_lowpart (QImode, operands[2]);")
10867 (define_insn_and_split "*<shift_insn><mode>3_mask_1"
10868 [(set (match_operand:SWI48 0 "nonimmediate_operand")
10870 (match_operand:SWI48 1 "nonimmediate_operand")
10872 (match_operand:QI 2 "register_operand")
10873 (match_operand:QI 3 "const_int_operand"))))
10874 (clobber (reg:CC FLAGS_REG))]
10875 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
10876 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10877 == GET_MODE_BITSIZE (<MODE>mode)-1
10878 && can_create_pseudo_p ()"
10882 [(set (match_dup 0)
10883 (any_shiftrt:SWI48 (match_dup 1)
10885 (clobber (reg:CC FLAGS_REG))])])
10887 (define_insn_and_split "*<shift_insn><mode>3_doubleword"
10888 [(set (match_operand:DWI 0 "register_operand" "=&r")
10889 (any_shiftrt:DWI (match_operand:DWI 1 "register_operand" "0")
10890 (match_operand:QI 2 "nonmemory_operand" "<S>c")))
10891 (clobber (reg:CC FLAGS_REG))]
10894 "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
10896 "ix86_split_<shift_insn> (operands, NULL_RTX, <MODE>mode); DONE;"
10897 [(set_attr "type" "multi")])
10899 ;; By default we don't ask for a scratch register, because when DWImode
10900 ;; values are manipulated, registers are already at a premium. But if
10901 ;; we have one handy, we won't turn it away.
10904 [(match_scratch:DWIH 3 "r")
10905 (parallel [(set (match_operand:<DWI> 0 "register_operand")
10907 (match_operand:<DWI> 1 "register_operand")
10908 (match_operand:QI 2 "nonmemory_operand")))
10909 (clobber (reg:CC FLAGS_REG))])
10913 "ix86_split_<shift_insn> (operands, operands[3], <DWI>mode); DONE;")
10915 (define_insn "x86_64_shrd"
10916 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
10917 (ior:DI (lshiftrt:DI (match_dup 0)
10918 (match_operand:QI 2 "nonmemory_operand" "Jc"))
10919 (ashift:DI (match_operand:DI 1 "register_operand" "r")
10920 (minus:QI (const_int 64) (match_dup 2)))))
10921 (clobber (reg:CC FLAGS_REG))]
10923 "shrd{q}\t{%s2%1, %0|%0, %1, %2}"
10924 [(set_attr "type" "ishift")
10925 (set_attr "prefix_0f" "1")
10926 (set_attr "mode" "DI")
10927 (set_attr "athlon_decode" "vector")
10928 (set_attr "amdfam10_decode" "vector")
10929 (set_attr "bdver1_decode" "vector")])
10931 (define_insn "x86_shrd"
10932 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
10933 (ior:SI (lshiftrt:SI (match_dup 0)
10934 (match_operand:QI 2 "nonmemory_operand" "Ic"))
10935 (ashift:SI (match_operand:SI 1 "register_operand" "r")
10936 (minus:QI (const_int 32) (match_dup 2)))))
10937 (clobber (reg:CC FLAGS_REG))]
10939 "shrd{l}\t{%s2%1, %0|%0, %1, %2}"
10940 [(set_attr "type" "ishift")
10941 (set_attr "prefix_0f" "1")
10942 (set_attr "mode" "SI")
10943 (set_attr "pent_pair" "np")
10944 (set_attr "athlon_decode" "vector")
10945 (set_attr "amdfam10_decode" "vector")
10946 (set_attr "bdver1_decode" "vector")])
10948 (define_insn "ashrdi3_cvt"
10949 [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
10950 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
10951 (match_operand:QI 2 "const_int_operand")))
10952 (clobber (reg:CC FLAGS_REG))]
10953 "TARGET_64BIT && INTVAL (operands[2]) == 63
10954 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
10955 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
10958 sar{q}\t{%2, %0|%0, %2}"
10959 [(set_attr "type" "imovx,ishift")
10960 (set_attr "prefix_0f" "0,*")
10961 (set_attr "length_immediate" "0,*")
10962 (set_attr "modrm" "0,1")
10963 (set_attr "mode" "DI")])
10965 (define_insn "*ashrsi3_cvt_zext"
10966 [(set (match_operand:DI 0 "register_operand" "=*d,r")
10968 (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
10969 (match_operand:QI 2 "const_int_operand"))))
10970 (clobber (reg:CC FLAGS_REG))]
10971 "TARGET_64BIT && INTVAL (operands[2]) == 31
10972 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
10973 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
10976 sar{l}\t{%2, %k0|%k0, %2}"
10977 [(set_attr "type" "imovx,ishift")
10978 (set_attr "prefix_0f" "0,*")
10979 (set_attr "length_immediate" "0,*")
10980 (set_attr "modrm" "0,1")
10981 (set_attr "mode" "SI")])
10983 (define_insn "ashrsi3_cvt"
10984 [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
10985 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
10986 (match_operand:QI 2 "const_int_operand")))
10987 (clobber (reg:CC FLAGS_REG))]
10988 "INTVAL (operands[2]) == 31
10989 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
10990 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
10993 sar{l}\t{%2, %0|%0, %2}"
10994 [(set_attr "type" "imovx,ishift")
10995 (set_attr "prefix_0f" "0,*")
10996 (set_attr "length_immediate" "0,*")
10997 (set_attr "modrm" "0,1")
10998 (set_attr "mode" "SI")])
11000 (define_expand "x86_shift<mode>_adj_3"
11001 [(use (match_operand:SWI48 0 "register_operand"))
11002 (use (match_operand:SWI48 1 "register_operand"))
11003 (use (match_operand:QI 2 "register_operand"))]
11006 rtx_code_label *label = gen_label_rtx ();
11009 emit_insn (gen_testqi_ccz_1 (operands[2],
11010 GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
11012 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
11013 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
11014 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
11015 gen_rtx_LABEL_REF (VOIDmode, label),
11017 tmp = emit_jump_insn (gen_rtx_SET (pc_rtx, tmp));
11018 JUMP_LABEL (tmp) = label;
11020 emit_move_insn (operands[0], operands[1]);
11021 emit_insn (gen_ashr<mode>3_cvt (operands[1], operands[1],
11022 GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1)));
11023 emit_label (label);
11024 LABEL_NUSES (label) = 1;
11029 (define_insn "*bmi2_<shift_insn><mode>3_1"
11030 [(set (match_operand:SWI48 0 "register_operand" "=r")
11031 (any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11032 (match_operand:SWI48 2 "register_operand" "r")))]
11034 "<shift>x\t{%2, %1, %0|%0, %1, %2}"
11035 [(set_attr "type" "ishiftx")
11036 (set_attr "mode" "<MODE>")])
11038 (define_insn "*<shift_insn><mode>3_1"
11039 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
11041 (match_operand:SWI48 1 "nonimmediate_operand" "0,rm")
11042 (match_operand:QI 2 "nonmemory_operand" "c<S>,r")))
11043 (clobber (reg:CC FLAGS_REG))]
11044 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
11046 switch (get_attr_type (insn))
11052 if (operands[2] == const1_rtx
11053 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11054 return "<shift>{<imodesuffix>}\t%0";
11056 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
11059 [(set_attr "isa" "*,bmi2")
11060 (set_attr "type" "ishift,ishiftx")
11061 (set (attr "length_immediate")
11063 (and (match_operand 2 "const1_operand")
11064 (ior (match_test "TARGET_SHIFT1")
11065 (match_test "optimize_function_for_size_p (cfun)")))
11067 (const_string "*")))
11068 (set_attr "mode" "<MODE>")])
11070 ;; Convert shift to the shiftx pattern to avoid flags dependency.
11072 [(set (match_operand:SWI48 0 "register_operand")
11073 (any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
11074 (match_operand:QI 2 "register_operand")))
11075 (clobber (reg:CC FLAGS_REG))]
11076 "TARGET_BMI2 && reload_completed"
11077 [(set (match_dup 0)
11078 (any_shiftrt:SWI48 (match_dup 1) (match_dup 2)))]
11079 "operands[2] = gen_lowpart (<MODE>mode, operands[2]);")
11081 (define_insn "*bmi2_<shift_insn>si3_1_zext"
11082 [(set (match_operand:DI 0 "register_operand" "=r")
11084 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
11085 (match_operand:SI 2 "register_operand" "r"))))]
11086 "TARGET_64BIT && TARGET_BMI2"
11087 "<shift>x\t{%2, %1, %k0|%k0, %1, %2}"
11088 [(set_attr "type" "ishiftx")
11089 (set_attr "mode" "SI")])
11091 (define_insn "*<shift_insn>si3_1_zext"
11092 [(set (match_operand:DI 0 "register_operand" "=r,r")
11094 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm")
11095 (match_operand:QI 2 "nonmemory_operand" "cI,r"))))
11096 (clobber (reg:CC FLAGS_REG))]
11097 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
11099 switch (get_attr_type (insn))
11105 if (operands[2] == const1_rtx
11106 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11107 return "<shift>{l}\t%k0";
11109 return "<shift>{l}\t{%2, %k0|%k0, %2}";
11112 [(set_attr "isa" "*,bmi2")
11113 (set_attr "type" "ishift,ishiftx")
11114 (set (attr "length_immediate")
11116 (and (match_operand 2 "const1_operand")
11117 (ior (match_test "TARGET_SHIFT1")
11118 (match_test "optimize_function_for_size_p (cfun)")))
11120 (const_string "*")))
11121 (set_attr "mode" "SI")])
11123 ;; Convert shift to the shiftx pattern to avoid flags dependency.
11125 [(set (match_operand:DI 0 "register_operand")
11127 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand")
11128 (match_operand:QI 2 "register_operand"))))
11129 (clobber (reg:CC FLAGS_REG))]
11130 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
11131 [(set (match_dup 0)
11132 (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
11133 "operands[2] = gen_lowpart (SImode, operands[2]);")
11135 (define_insn "*<shift_insn><mode>3_1"
11136 [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m")
11138 (match_operand:SWI12 1 "nonimmediate_operand" "0")
11139 (match_operand:QI 2 "nonmemory_operand" "c<S>")))
11140 (clobber (reg:CC FLAGS_REG))]
11141 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
11143 if (operands[2] == const1_rtx
11144 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11145 return "<shift>{<imodesuffix>}\t%0";
11147 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
11149 [(set_attr "type" "ishift")
11150 (set (attr "length_immediate")
11152 (and (match_operand 2 "const1_operand")
11153 (ior (match_test "TARGET_SHIFT1")
11154 (match_test "optimize_function_for_size_p (cfun)")))
11156 (const_string "*")))
11157 (set_attr "mode" "<MODE>")])
11159 (define_insn "*<shift_insn>qi3_1_slp"
11160 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
11161 (any_shiftrt:QI (match_dup 0)
11162 (match_operand:QI 1 "nonmemory_operand" "cI")))
11163 (clobber (reg:CC FLAGS_REG))]
11164 "(optimize_function_for_size_p (cfun)
11165 || !TARGET_PARTIAL_REG_STALL
11166 || (operands[1] == const1_rtx
11167 && TARGET_SHIFT1))"
11169 if (operands[1] == const1_rtx
11170 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11171 return "<shift>{b}\t%0";
11173 return "<shift>{b}\t{%1, %0|%0, %1}";
11175 [(set_attr "type" "ishift1")
11176 (set (attr "length_immediate")
11178 (and (match_operand 1 "const1_operand")
11179 (ior (match_test "TARGET_SHIFT1")
11180 (match_test "optimize_function_for_size_p (cfun)")))
11182 (const_string "*")))
11183 (set_attr "mode" "QI")])
11185 ;; This pattern can't accept a variable shift count, since shifts by
11186 ;; zero don't affect the flags. We assume that shifts by constant
11187 ;; zero are optimized away.
11188 (define_insn "*<shift_insn><mode>3_cmp"
11189 [(set (reg FLAGS_REG)
11192 (match_operand:SWI 1 "nonimmediate_operand" "0")
11193 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
11195 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
11196 (any_shiftrt:SWI (match_dup 1) (match_dup 2)))]
11197 "(optimize_function_for_size_p (cfun)
11198 || !TARGET_PARTIAL_FLAG_REG_STALL
11199 || (operands[2] == const1_rtx
11201 && ix86_match_ccmode (insn, CCGOCmode)
11202 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
11204 if (operands[2] == const1_rtx
11205 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11206 return "<shift>{<imodesuffix>}\t%0";
11208 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
11210 [(set_attr "type" "ishift")
11211 (set (attr "length_immediate")
11213 (and (match_operand 2 "const1_operand")
11214 (ior (match_test "TARGET_SHIFT1")
11215 (match_test "optimize_function_for_size_p (cfun)")))
11217 (const_string "*")))
11218 (set_attr "mode" "<MODE>")])
11220 (define_insn "*<shift_insn>si3_cmp_zext"
11221 [(set (reg FLAGS_REG)
11223 (any_shiftrt:SI (match_operand:SI 1 "register_operand" "0")
11224 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11226 (set (match_operand:DI 0 "register_operand" "=r")
11227 (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
11229 && (optimize_function_for_size_p (cfun)
11230 || !TARGET_PARTIAL_FLAG_REG_STALL
11231 || (operands[2] == const1_rtx
11233 && ix86_match_ccmode (insn, CCGOCmode)
11234 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
11236 if (operands[2] == const1_rtx
11237 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11238 return "<shift>{l}\t%k0";
11240 return "<shift>{l}\t{%2, %k0|%k0, %2}";
11242 [(set_attr "type" "ishift")
11243 (set (attr "length_immediate")
11245 (and (match_operand 2 "const1_operand")
11246 (ior (match_test "TARGET_SHIFT1")
11247 (match_test "optimize_function_for_size_p (cfun)")))
11249 (const_string "*")))
11250 (set_attr "mode" "SI")])
11252 (define_insn "*<shift_insn><mode>3_cconly"
11253 [(set (reg FLAGS_REG)
11256 (match_operand:SWI 1 "register_operand" "0")
11257 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
11259 (clobber (match_scratch:SWI 0 "=<r>"))]
11260 "(optimize_function_for_size_p (cfun)
11261 || !TARGET_PARTIAL_FLAG_REG_STALL
11262 || (operands[2] == const1_rtx
11264 && ix86_match_ccmode (insn, CCGOCmode)"
11266 if (operands[2] == const1_rtx
11267 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11268 return "<shift>{<imodesuffix>}\t%0";
11270 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
11272 [(set_attr "type" "ishift")
11273 (set (attr "length_immediate")
11275 (and (match_operand 2 "const1_operand")
11276 (ior (match_test "TARGET_SHIFT1")
11277 (match_test "optimize_function_for_size_p (cfun)")))
11279 (const_string "*")))
11280 (set_attr "mode" "<MODE>")])
11282 ;; Rotate instructions
11284 (define_expand "<rotate_insn>ti3"
11285 [(set (match_operand:TI 0 "register_operand")
11286 (any_rotate:TI (match_operand:TI 1 "register_operand")
11287 (match_operand:QI 2 "nonmemory_operand")))]
11290 if (const_1_to_63_operand (operands[2], VOIDmode))
11291 emit_insn (gen_ix86_<rotate_insn>ti3_doubleword
11292 (operands[0], operands[1], operands[2]));
11299 (define_expand "<rotate_insn>di3"
11300 [(set (match_operand:DI 0 "shiftdi_operand")
11301 (any_rotate:DI (match_operand:DI 1 "shiftdi_operand")
11302 (match_operand:QI 2 "nonmemory_operand")))]
11306 ix86_expand_binary_operator (<CODE>, DImode, operands);
11307 else if (const_1_to_31_operand (operands[2], VOIDmode))
11308 emit_insn (gen_ix86_<rotate_insn>di3_doubleword
11309 (operands[0], operands[1], operands[2]));
11316 (define_expand "<rotate_insn><mode>3"
11317 [(set (match_operand:SWIM124 0 "nonimmediate_operand")
11318 (any_rotate:SWIM124 (match_operand:SWIM124 1 "nonimmediate_operand")
11319 (match_operand:QI 2 "nonmemory_operand")))]
11321 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
11323 ;; Avoid useless masking of count operand.
11324 (define_insn_and_split "*<rotate_insn><mode>3_mask"
11325 [(set (match_operand:SWI48 0 "nonimmediate_operand")
11327 (match_operand:SWI48 1 "nonimmediate_operand")
11330 (match_operand:SI 2 "register_operand")
11331 (match_operand:SI 3 "const_int_operand")) 0)))
11332 (clobber (reg:CC FLAGS_REG))]
11333 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
11334 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
11335 == GET_MODE_BITSIZE (<MODE>mode)-1
11336 && can_create_pseudo_p ()"
11340 [(set (match_dup 0)
11341 (any_rotate:SWI48 (match_dup 1)
11343 (clobber (reg:CC FLAGS_REG))])]
11344 "operands[2] = gen_lowpart (QImode, operands[2]);")
11346 (define_insn_and_split "*<rotate_insn><mode>3_mask_1"
11347 [(set (match_operand:SWI48 0 "nonimmediate_operand")
11349 (match_operand:SWI48 1 "nonimmediate_operand")
11351 (match_operand:QI 2 "register_operand")
11352 (match_operand:QI 3 "const_int_operand"))))
11353 (clobber (reg:CC FLAGS_REG))]
11354 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
11355 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
11356 == GET_MODE_BITSIZE (<MODE>mode)-1
11357 && can_create_pseudo_p ()"
11361 [(set (match_dup 0)
11362 (any_rotate:SWI48 (match_dup 1)
11364 (clobber (reg:CC FLAGS_REG))])])
11366 ;; Implement rotation using two double-precision
11367 ;; shift instructions and a scratch register.
11369 (define_insn_and_split "ix86_rotl<dwi>3_doubleword"
11370 [(set (match_operand:<DWI> 0 "register_operand" "=r")
11371 (rotate:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
11372 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
11373 (clobber (reg:CC FLAGS_REG))
11374 (clobber (match_scratch:DWIH 3 "=&r"))]
11378 [(set (match_dup 3) (match_dup 4))
11380 [(set (match_dup 4)
11381 (ior:DWIH (ashift:DWIH (match_dup 4) (match_dup 2))
11382 (lshiftrt:DWIH (match_dup 5)
11383 (minus:QI (match_dup 6) (match_dup 2)))))
11384 (clobber (reg:CC FLAGS_REG))])
11386 [(set (match_dup 5)
11387 (ior:DWIH (ashift:DWIH (match_dup 5) (match_dup 2))
11388 (lshiftrt:DWIH (match_dup 3)
11389 (minus:QI (match_dup 6) (match_dup 2)))))
11390 (clobber (reg:CC FLAGS_REG))])]
11392 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
11394 split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
11397 (define_insn_and_split "ix86_rotr<dwi>3_doubleword"
11398 [(set (match_operand:<DWI> 0 "register_operand" "=r")
11399 (rotatert:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
11400 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
11401 (clobber (reg:CC FLAGS_REG))
11402 (clobber (match_scratch:DWIH 3 "=&r"))]
11406 [(set (match_dup 3) (match_dup 4))
11408 [(set (match_dup 4)
11409 (ior:DWIH (lshiftrt:DWIH (match_dup 4) (match_dup 2))
11410 (ashift:DWIH (match_dup 5)
11411 (minus:QI (match_dup 6) (match_dup 2)))))
11412 (clobber (reg:CC FLAGS_REG))])
11414 [(set (match_dup 5)
11415 (ior:DWIH (lshiftrt:DWIH (match_dup 5) (match_dup 2))
11416 (ashift:DWIH (match_dup 3)
11417 (minus:QI (match_dup 6) (match_dup 2)))))
11418 (clobber (reg:CC FLAGS_REG))])]
11420 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
11422 split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
11425 (define_mode_attr rorx_immediate_operand
11426 [(SI "const_0_to_31_operand")
11427 (DI "const_0_to_63_operand")])
11429 (define_insn "*bmi2_rorx<mode>3_1"
11430 [(set (match_operand:SWI48 0 "register_operand" "=r")
11432 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11433 (match_operand:QI 2 "<rorx_immediate_operand>" "<S>")))]
11435 "rorx\t{%2, %1, %0|%0, %1, %2}"
11436 [(set_attr "type" "rotatex")
11437 (set_attr "mode" "<MODE>")])
11439 (define_insn "*<rotate_insn><mode>3_1"
11440 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
11442 (match_operand:SWI48 1 "nonimmediate_operand" "0,rm")
11443 (match_operand:QI 2 "nonmemory_operand" "c<S>,<S>")))
11444 (clobber (reg:CC FLAGS_REG))]
11445 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
11447 switch (get_attr_type (insn))
11453 if (operands[2] == const1_rtx
11454 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11455 return "<rotate>{<imodesuffix>}\t%0";
11457 return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
11460 [(set_attr "isa" "*,bmi2")
11461 (set_attr "type" "rotate,rotatex")
11462 (set (attr "length_immediate")
11464 (and (eq_attr "type" "rotate")
11465 (and (match_operand 2 "const1_operand")
11466 (ior (match_test "TARGET_SHIFT1")
11467 (match_test "optimize_function_for_size_p (cfun)"))))
11469 (const_string "*")))
11470 (set_attr "mode" "<MODE>")])
11472 ;; Convert rotate to the rotatex pattern to avoid flags dependency.
11474 [(set (match_operand:SWI48 0 "register_operand")
11475 (rotate:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
11476 (match_operand:QI 2 "const_int_operand")))
11477 (clobber (reg:CC FLAGS_REG))]
11478 "TARGET_BMI2 && reload_completed"
11479 [(set (match_dup 0)
11480 (rotatert:SWI48 (match_dup 1) (match_dup 2)))]
11482 int bitsize = GET_MODE_BITSIZE (<MODE>mode);
11484 operands[2] = GEN_INT ((bitsize - INTVAL (operands[2])) % bitsize);
11488 [(set (match_operand:SWI48 0 "register_operand")
11489 (rotatert:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
11490 (match_operand:QI 2 "const_int_operand")))
11491 (clobber (reg:CC FLAGS_REG))]
11492 "TARGET_BMI2 && reload_completed"
11493 [(set (match_dup 0)
11494 (rotatert:SWI48 (match_dup 1) (match_dup 2)))])
11496 (define_insn "*bmi2_rorxsi3_1_zext"
11497 [(set (match_operand:DI 0 "register_operand" "=r")
11499 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
11500 (match_operand:QI 2 "const_0_to_31_operand" "I"))))]
11501 "TARGET_64BIT && TARGET_BMI2"
11502 "rorx\t{%2, %1, %k0|%k0, %1, %2}"
11503 [(set_attr "type" "rotatex")
11504 (set_attr "mode" "SI")])
11506 (define_insn "*<rotate_insn>si3_1_zext"
11507 [(set (match_operand:DI 0 "register_operand" "=r,r")
11509 (any_rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm")
11510 (match_operand:QI 2 "nonmemory_operand" "cI,I"))))
11511 (clobber (reg:CC FLAGS_REG))]
11512 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
11514 switch (get_attr_type (insn))
11520 if (operands[2] == const1_rtx
11521 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11522 return "<rotate>{l}\t%k0";
11524 return "<rotate>{l}\t{%2, %k0|%k0, %2}";
11527 [(set_attr "isa" "*,bmi2")
11528 (set_attr "type" "rotate,rotatex")
11529 (set (attr "length_immediate")
11531 (and (eq_attr "type" "rotate")
11532 (and (match_operand 2 "const1_operand")
11533 (ior (match_test "TARGET_SHIFT1")
11534 (match_test "optimize_function_for_size_p (cfun)"))))
11536 (const_string "*")))
11537 (set_attr "mode" "SI")])
11539 ;; Convert rotate to the rotatex pattern to avoid flags dependency.
11541 [(set (match_operand:DI 0 "register_operand")
11543 (rotate:SI (match_operand:SI 1 "nonimmediate_operand")
11544 (match_operand:QI 2 "const_int_operand"))))
11545 (clobber (reg:CC FLAGS_REG))]
11546 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
11547 [(set (match_dup 0)
11548 (zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))]
11550 int bitsize = GET_MODE_BITSIZE (SImode);
11552 operands[2] = GEN_INT ((bitsize - INTVAL (operands[2])) % bitsize);
11556 [(set (match_operand:DI 0 "register_operand")
11558 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand")
11559 (match_operand:QI 2 "const_int_operand"))))
11560 (clobber (reg:CC FLAGS_REG))]
11561 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
11562 [(set (match_dup 0)
11563 (zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))])
11565 (define_insn "*<rotate_insn><mode>3_1"
11566 [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m")
11567 (any_rotate:SWI12 (match_operand:SWI12 1 "nonimmediate_operand" "0")
11568 (match_operand:QI 2 "nonmemory_operand" "c<S>")))
11569 (clobber (reg:CC FLAGS_REG))]
11570 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
11572 if (operands[2] == const1_rtx
11573 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11574 return "<rotate>{<imodesuffix>}\t%0";
11576 return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
11578 [(set_attr "type" "rotate")
11579 (set (attr "length_immediate")
11581 (and (match_operand 2 "const1_operand")
11582 (ior (match_test "TARGET_SHIFT1")
11583 (match_test "optimize_function_for_size_p (cfun)")))
11585 (const_string "*")))
11586 (set_attr "mode" "<MODE>")])
11588 (define_insn "*<rotate_insn>qi3_1_slp"
11589 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
11590 (any_rotate:QI (match_dup 0)
11591 (match_operand:QI 1 "nonmemory_operand" "cI")))
11592 (clobber (reg:CC FLAGS_REG))]
11593 "(optimize_function_for_size_p (cfun)
11594 || !TARGET_PARTIAL_REG_STALL
11595 || (operands[1] == const1_rtx
11596 && TARGET_SHIFT1))"
11598 if (operands[1] == const1_rtx
11599 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11600 return "<rotate>{b}\t%0";
11602 return "<rotate>{b}\t{%1, %0|%0, %1}";
11604 [(set_attr "type" "rotate1")
11605 (set (attr "length_immediate")
11607 (and (match_operand 1 "const1_operand")
11608 (ior (match_test "TARGET_SHIFT1")
11609 (match_test "optimize_function_for_size_p (cfun)")))
11611 (const_string "*")))
11612 (set_attr "mode" "QI")])
11615 [(set (match_operand:HI 0 "register_operand")
11616 (any_rotate:HI (match_dup 0) (const_int 8)))
11617 (clobber (reg:CC FLAGS_REG))]
11619 && (TARGET_USE_XCHGB || optimize_function_for_size_p (cfun))"
11620 [(parallel [(set (strict_low_part (match_dup 0))
11621 (bswap:HI (match_dup 0)))
11622 (clobber (reg:CC FLAGS_REG))])])
11624 ;; Bit set / bit test instructions
11626 ;; %%% bts, btr, btc
11628 ;; These instructions are *slow* when applied to memory.
11630 (define_code_attr btsc [(ior "bts") (xor "btc")])
11632 (define_insn "*<btsc><mode>"
11633 [(set (match_operand:SWI48 0 "register_operand" "=r")
11635 (ashift:SWI48 (const_int 1)
11636 (match_operand:QI 2 "register_operand" "r"))
11637 (match_operand:SWI48 1 "register_operand" "0")))
11638 (clobber (reg:CC FLAGS_REG))]
11640 "<btsc>{<imodesuffix>}\t{%<k>2, %0|%0, %<k>2}"
11641 [(set_attr "type" "alu1")
11642 (set_attr "prefix_0f" "1")
11643 (set_attr "znver1_decode" "double")
11644 (set_attr "mode" "<MODE>")])
11646 ;; Avoid useless masking of count operand.
11647 (define_insn_and_split "*<btsc><mode>_mask"
11648 [(set (match_operand:SWI48 0 "register_operand")
11654 (match_operand:SI 1 "register_operand")
11655 (match_operand:SI 2 "const_int_operand")) 0))
11656 (match_operand:SWI48 3 "register_operand")))
11657 (clobber (reg:CC FLAGS_REG))]
11659 && (INTVAL (operands[2]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
11660 == GET_MODE_BITSIZE (<MODE>mode)-1
11661 && can_create_pseudo_p ()"
11665 [(set (match_dup 0)
11667 (ashift:SWI48 (const_int 1)
11670 (clobber (reg:CC FLAGS_REG))])]
11671 "operands[1] = gen_lowpart (QImode, operands[1]);")
11673 (define_insn_and_split "*<btsc><mode>_mask_1"
11674 [(set (match_operand:SWI48 0 "register_operand")
11679 (match_operand:QI 1 "register_operand")
11680 (match_operand:QI 2 "const_int_operand")))
11681 (match_operand:SWI48 3 "register_operand")))
11682 (clobber (reg:CC FLAGS_REG))]
11684 && (INTVAL (operands[2]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
11685 == GET_MODE_BITSIZE (<MODE>mode)-1
11686 && can_create_pseudo_p ()"
11690 [(set (match_dup 0)
11692 (ashift:SWI48 (const_int 1)
11695 (clobber (reg:CC FLAGS_REG))])])
11697 (define_insn "*btr<mode>"
11698 [(set (match_operand:SWI48 0 "register_operand" "=r")
11700 (rotate:SWI48 (const_int -2)
11701 (match_operand:QI 2 "register_operand" "r"))
11702 (match_operand:SWI48 1 "register_operand" "0")))
11703 (clobber (reg:CC FLAGS_REG))]
11705 "btr{<imodesuffix>}\t{%<k>2, %0|%0, %<k>2}"
11706 [(set_attr "type" "alu1")
11707 (set_attr "prefix_0f" "1")
11708 (set_attr "znver1_decode" "double")
11709 (set_attr "mode" "<MODE>")])
11711 ;; Avoid useless masking of count operand.
11712 (define_insn_and_split "*btr<mode>_mask"
11713 [(set (match_operand:SWI48 0 "register_operand")
11719 (match_operand:SI 1 "register_operand")
11720 (match_operand:SI 2 "const_int_operand")) 0))
11721 (match_operand:SWI48 3 "register_operand")))
11722 (clobber (reg:CC FLAGS_REG))]
11724 && (INTVAL (operands[2]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
11725 == GET_MODE_BITSIZE (<MODE>mode)-1
11726 && can_create_pseudo_p ()"
11730 [(set (match_dup 0)
11732 (rotate:SWI48 (const_int -2)
11735 (clobber (reg:CC FLAGS_REG))])]
11736 "operands[1] = gen_lowpart (QImode, operands[1]);")
11738 (define_insn_and_split "*btr<mode>_mask_1"
11739 [(set (match_operand:SWI48 0 "register_operand")
11744 (match_operand:QI 1 "register_operand")
11745 (match_operand:QI 2 "const_int_operand")))
11746 (match_operand:SWI48 3 "register_operand")))
11747 (clobber (reg:CC FLAGS_REG))]
11749 && (INTVAL (operands[2]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
11750 == GET_MODE_BITSIZE (<MODE>mode)-1
11751 && can_create_pseudo_p ()"
11755 [(set (match_dup 0)
11757 (rotate:SWI48 (const_int -2)
11760 (clobber (reg:CC FLAGS_REG))])])
11762 ;; These instructions are never faster than the corresponding
11763 ;; and/ior/xor operations when using immediate operand, so with
11764 ;; 32-bit there's no point. But in 64-bit, we can't hold the
11765 ;; relevant immediates within the instruction itself, so operating
11766 ;; on bits in the high 32-bits of a register becomes easier.
11768 ;; These are slow on Nocona, but fast on Athlon64. We do require the use
11769 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
11770 ;; negdf respectively, so they can never be disabled entirely.
11772 (define_insn "*btsq_imm"
11773 [(set (zero_extract:DI (match_operand:DI 0 "nonimmediate_operand" "+rm")
11775 (match_operand 1 "const_0_to_63_operand" "J"))
11777 (clobber (reg:CC FLAGS_REG))]
11778 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
11779 "bts{q}\t{%1, %0|%0, %1}"
11780 [(set_attr "type" "alu1")
11781 (set_attr "prefix_0f" "1")
11782 (set_attr "znver1_decode" "double")
11783 (set_attr "mode" "DI")])
11785 (define_insn "*btrq_imm"
11786 [(set (zero_extract:DI (match_operand:DI 0 "nonimmediate_operand" "+rm")
11788 (match_operand 1 "const_0_to_63_operand" "J"))
11790 (clobber (reg:CC FLAGS_REG))]
11791 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
11792 "btr{q}\t{%1, %0|%0, %1}"
11793 [(set_attr "type" "alu1")
11794 (set_attr "prefix_0f" "1")
11795 (set_attr "znver1_decode" "double")
11796 (set_attr "mode" "DI")])
11798 (define_insn "*btcq_imm"
11799 [(set (zero_extract:DI (match_operand:DI 0 "nonimmediate_operand" "+rm")
11801 (match_operand 1 "const_0_to_63_operand" "J"))
11802 (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
11803 (clobber (reg:CC FLAGS_REG))]
11804 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
11805 "btc{q}\t{%1, %0|%0, %1}"
11806 [(set_attr "type" "alu1")
11807 (set_attr "prefix_0f" "1")
11808 (set_attr "znver1_decode" "double")
11809 (set_attr "mode" "DI")])
11811 ;; Allow Nocona to avoid these instructions if a register is available.
11814 [(match_scratch:DI 2 "r")
11815 (parallel [(set (zero_extract:DI
11816 (match_operand:DI 0 "nonimmediate_operand")
11818 (match_operand 1 "const_0_to_63_operand"))
11820 (clobber (reg:CC FLAGS_REG))])]
11821 "TARGET_64BIT && !TARGET_USE_BT"
11822 [(parallel [(set (match_dup 0)
11823 (ior:DI (match_dup 0) (match_dup 3)))
11824 (clobber (reg:CC FLAGS_REG))])]
11826 int i = INTVAL (operands[1]);
11828 operands[3] = gen_int_mode (HOST_WIDE_INT_1U << i, DImode);
11830 if (!x86_64_immediate_operand (operands[3], DImode))
11832 emit_move_insn (operands[2], operands[3]);
11833 operands[3] = operands[2];
11838 [(match_scratch:DI 2 "r")
11839 (parallel [(set (zero_extract:DI
11840 (match_operand:DI 0 "nonimmediate_operand")
11842 (match_operand 1 "const_0_to_63_operand"))
11844 (clobber (reg:CC FLAGS_REG))])]
11845 "TARGET_64BIT && !TARGET_USE_BT"
11846 [(parallel [(set (match_dup 0)
11847 (and:DI (match_dup 0) (match_dup 3)))
11848 (clobber (reg:CC FLAGS_REG))])]
11850 int i = INTVAL (operands[1]);
11852 operands[3] = gen_int_mode (~(HOST_WIDE_INT_1U << i), DImode);
11854 if (!x86_64_immediate_operand (operands[3], DImode))
11856 emit_move_insn (operands[2], operands[3]);
11857 operands[3] = operands[2];
11862 [(match_scratch:DI 2 "r")
11863 (parallel [(set (zero_extract:DI
11864 (match_operand:DI 0 "nonimmediate_operand")
11866 (match_operand 1 "const_0_to_63_operand"))
11867 (not:DI (zero_extract:DI
11868 (match_dup 0) (const_int 1) (match_dup 1))))
11869 (clobber (reg:CC FLAGS_REG))])]
11870 "TARGET_64BIT && !TARGET_USE_BT"
11871 [(parallel [(set (match_dup 0)
11872 (xor:DI (match_dup 0) (match_dup 3)))
11873 (clobber (reg:CC FLAGS_REG))])]
11875 int i = INTVAL (operands[1]);
11877 operands[3] = gen_int_mode (HOST_WIDE_INT_1U << i, DImode);
11879 if (!x86_64_immediate_operand (operands[3], DImode))
11881 emit_move_insn (operands[2], operands[3]);
11882 operands[3] = operands[2];
11888 (define_insn "*bt<mode>"
11889 [(set (reg:CCC FLAGS_REG)
11891 (zero_extract:SWI48
11892 (match_operand:SWI48 0 "nonimmediate_operand" "r,m")
11894 (match_operand:SI 1 "nonmemory_operand" "r<S>,<S>"))
11898 switch (get_attr_mode (insn))
11901 return "bt{l}\t{%1, %k0|%k0, %1}";
11904 return "bt{q}\t{%q1, %0|%0, %q1}";
11907 gcc_unreachable ();
11910 [(set_attr "type" "alu1")
11911 (set_attr "prefix_0f" "1")
11914 (and (match_test "CONST_INT_P (operands[1])")
11915 (match_test "INTVAL (operands[1]) < 32"))
11916 (const_string "SI")
11917 (const_string "<MODE>")))])
11919 (define_insn_and_split "*jcc_bt<mode>"
11921 (if_then_else (match_operator 0 "bt_comparison_operator"
11922 [(zero_extract:SWI48
11923 (match_operand:SWI48 1 "nonimmediate_operand")
11925 (match_operand:SI 2 "nonmemory_operand"))
11927 (label_ref (match_operand 3))
11929 (clobber (reg:CC FLAGS_REG))]
11930 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
11931 && (CONST_INT_P (operands[2])
11932 ? (INTVAL (operands[2]) < GET_MODE_BITSIZE (<MODE>mode)
11933 && INTVAL (operands[2])
11934 >= (optimize_function_for_size_p (cfun) ? 8 : 32))
11935 : !memory_operand (operands[1], <MODE>mode))
11936 && can_create_pseudo_p ()"
11939 [(set (reg:CCC FLAGS_REG)
11941 (zero_extract:SWI48
11947 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
11948 (label_ref (match_dup 3))
11951 operands[0] = shallow_copy_rtx (operands[0]);
11952 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
11955 (define_insn_and_split "*jcc_bt<mode>_1"
11957 (if_then_else (match_operator 0 "bt_comparison_operator"
11958 [(zero_extract:SWI48
11959 (match_operand:SWI48 1 "register_operand")
11962 (match_operand:QI 2 "register_operand")))
11964 (label_ref (match_operand 3))
11966 (clobber (reg:CC FLAGS_REG))]
11967 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
11968 && can_create_pseudo_p ()"
11971 [(set (reg:CCC FLAGS_REG)
11973 (zero_extract:SWI48
11979 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
11980 (label_ref (match_dup 3))
11983 operands[2] = lowpart_subreg (SImode, operands[2], QImode);
11984 operands[0] = shallow_copy_rtx (operands[0]);
11985 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
11988 ;; Avoid useless masking of bit offset operand.
11989 (define_insn_and_split "*jcc_bt<mode>_mask"
11991 (if_then_else (match_operator 0 "bt_comparison_operator"
11992 [(zero_extract:SWI48
11993 (match_operand:SWI48 1 "register_operand")
11996 (match_operand:SI 2 "register_operand")
11997 (match_operand 3 "const_int_operand")))])
11998 (label_ref (match_operand 4))
12000 (clobber (reg:CC FLAGS_REG))]
12001 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
12002 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
12003 == GET_MODE_BITSIZE (<MODE>mode)-1
12004 && can_create_pseudo_p ()"
12007 [(set (reg:CCC FLAGS_REG)
12009 (zero_extract:SWI48
12015 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
12016 (label_ref (match_dup 4))
12019 operands[0] = shallow_copy_rtx (operands[0]);
12020 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
12023 ;; Store-flag instructions.
12025 ;; For all sCOND expanders, also expand the compare or test insn that
12026 ;; generates cc0. Generate an equality comparison if `seq' or `sne'.
12028 (define_insn_and_split "*setcc_di_1"
12029 [(set (match_operand:DI 0 "register_operand" "=q")
12030 (match_operator:DI 1 "ix86_comparison_operator"
12031 [(reg FLAGS_REG) (const_int 0)]))]
12032 "TARGET_64BIT && !TARGET_PARTIAL_REG_STALL"
12034 "&& reload_completed"
12035 [(set (match_dup 2) (match_dup 1))
12036 (set (match_dup 0) (zero_extend:DI (match_dup 2)))]
12038 operands[1] = shallow_copy_rtx (operands[1]);
12039 PUT_MODE (operands[1], QImode);
12040 operands[2] = gen_lowpart (QImode, operands[0]);
12043 (define_insn_and_split "*setcc_si_1_and"
12044 [(set (match_operand:SI 0 "register_operand" "=q")
12045 (match_operator:SI 1 "ix86_comparison_operator"
12046 [(reg FLAGS_REG) (const_int 0)]))
12047 (clobber (reg:CC FLAGS_REG))]
12048 "!TARGET_PARTIAL_REG_STALL
12049 && TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
12051 "&& reload_completed"
12052 [(set (match_dup 2) (match_dup 1))
12053 (parallel [(set (match_dup 0) (zero_extend:SI (match_dup 2)))
12054 (clobber (reg:CC FLAGS_REG))])]
12056 operands[1] = shallow_copy_rtx (operands[1]);
12057 PUT_MODE (operands[1], QImode);
12058 operands[2] = gen_lowpart (QImode, operands[0]);
12061 (define_insn_and_split "*setcc_si_1_movzbl"
12062 [(set (match_operand:SI 0 "register_operand" "=q")
12063 (match_operator:SI 1 "ix86_comparison_operator"
12064 [(reg FLAGS_REG) (const_int 0)]))]
12065 "!TARGET_PARTIAL_REG_STALL
12066 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
12068 "&& reload_completed"
12069 [(set (match_dup 2) (match_dup 1))
12070 (set (match_dup 0) (zero_extend:SI (match_dup 2)))]
12072 operands[1] = shallow_copy_rtx (operands[1]);
12073 PUT_MODE (operands[1], QImode);
12074 operands[2] = gen_lowpart (QImode, operands[0]);
12077 (define_insn "*setcc_qi"
12078 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12079 (match_operator:QI 1 "ix86_comparison_operator"
12080 [(reg FLAGS_REG) (const_int 0)]))]
12083 [(set_attr "type" "setcc")
12084 (set_attr "mode" "QI")])
12086 (define_insn "*setcc_qi_slp"
12087 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12088 (match_operator:QI 1 "ix86_comparison_operator"
12089 [(reg FLAGS_REG) (const_int 0)]))]
12092 [(set_attr "type" "setcc")
12093 (set_attr "mode" "QI")])
12095 ;; In general it is not safe to assume too much about CCmode registers,
12096 ;; so simplify-rtx stops when it sees a second one. Under certain
12097 ;; conditions this is safe on x86, so help combine not create
12104 [(set (match_operand:QI 0 "nonimmediate_operand")
12105 (ne:QI (match_operator 1 "ix86_comparison_operator"
12106 [(reg FLAGS_REG) (const_int 0)])
12109 [(set (match_dup 0) (match_dup 1))]
12111 operands[1] = shallow_copy_rtx (operands[1]);
12112 PUT_MODE (operands[1], QImode);
12116 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand"))
12117 (ne:QI (match_operator 1 "ix86_comparison_operator"
12118 [(reg FLAGS_REG) (const_int 0)])
12121 [(set (match_dup 0) (match_dup 1))]
12123 operands[1] = shallow_copy_rtx (operands[1]);
12124 PUT_MODE (operands[1], QImode);
12128 [(set (match_operand:QI 0 "nonimmediate_operand")
12129 (eq:QI (match_operator 1 "ix86_comparison_operator"
12130 [(reg FLAGS_REG) (const_int 0)])
12133 [(set (match_dup 0) (match_dup 1))]
12135 operands[1] = shallow_copy_rtx (operands[1]);
12136 PUT_MODE (operands[1], QImode);
12137 PUT_CODE (operands[1],
12138 ix86_reverse_condition (GET_CODE (operands[1]),
12139 GET_MODE (XEXP (operands[1], 0))));
12141 /* Make sure that (a) the CCmode we have for the flags is strong
12142 enough for the reversed compare or (b) we have a valid FP compare. */
12143 if (! ix86_comparison_operator (operands[1], VOIDmode))
12148 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand"))
12149 (eq:QI (match_operator 1 "ix86_comparison_operator"
12150 [(reg FLAGS_REG) (const_int 0)])
12153 [(set (match_dup 0) (match_dup 1))]
12155 operands[1] = shallow_copy_rtx (operands[1]);
12156 PUT_MODE (operands[1], QImode);
12157 PUT_CODE (operands[1],
12158 ix86_reverse_condition (GET_CODE (operands[1]),
12159 GET_MODE (XEXP (operands[1], 0))));
12161 /* Make sure that (a) the CCmode we have for the flags is strong
12162 enough for the reversed compare or (b) we have a valid FP compare. */
12163 if (! ix86_comparison_operator (operands[1], VOIDmode))
12167 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
12168 ;; subsequent logical operations are used to imitate conditional moves.
12169 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
12172 (define_insn "setcc_<mode>_sse"
12173 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
12174 (match_operator:MODEF 3 "sse_comparison_operator"
12175 [(match_operand:MODEF 1 "register_operand" "0,x")
12176 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
12177 "SSE_FLOAT_MODE_P (<MODE>mode)"
12179 cmp%D3<ssemodesuffix>\t{%2, %0|%0, %2}
12180 vcmp%D3<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
12181 [(set_attr "isa" "noavx,avx")
12182 (set_attr "type" "ssecmp")
12183 (set_attr "length_immediate" "1")
12184 (set_attr "prefix" "orig,vex")
12185 (set_attr "mode" "<MODE>")])
12187 ;; Basic conditional jump instructions.
12188 ;; We ignore the overflow flag for signed branch instructions.
12190 (define_insn "*jcc"
12192 (if_then_else (match_operator 1 "ix86_comparison_operator"
12193 [(reg FLAGS_REG) (const_int 0)])
12194 (label_ref (match_operand 0))
12198 [(set_attr "type" "ibr")
12199 (set_attr "modrm" "0")
12200 (set (attr "length")
12202 (and (ge (minus (match_dup 0) (pc))
12204 (lt (minus (match_dup 0) (pc))
12208 (set_attr "maybe_prefix_bnd" "1")])
12210 ;; In general it is not safe to assume too much about CCmode registers,
12211 ;; so simplify-rtx stops when it sees a second one. Under certain
12212 ;; conditions this is safe on x86, so help combine not create
12220 (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
12221 [(reg FLAGS_REG) (const_int 0)])
12223 (label_ref (match_operand 1))
12227 (if_then_else (match_dup 0)
12228 (label_ref (match_dup 1))
12231 operands[0] = shallow_copy_rtx (operands[0]);
12232 PUT_MODE (operands[0], VOIDmode);
12237 (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
12238 [(reg FLAGS_REG) (const_int 0)])
12240 (label_ref (match_operand 1))
12244 (if_then_else (match_dup 0)
12245 (label_ref (match_dup 1))
12248 operands[0] = shallow_copy_rtx (operands[0]);
12249 PUT_MODE (operands[0], VOIDmode);
12250 PUT_CODE (operands[0],
12251 ix86_reverse_condition (GET_CODE (operands[0]),
12252 GET_MODE (XEXP (operands[0], 0))));
12254 /* Make sure that (a) the CCmode we have for the flags is strong
12255 enough for the reversed compare or (b) we have a valid FP compare. */
12256 if (! ix86_comparison_operator (operands[0], VOIDmode))
12260 ;; Unconditional and other jump instructions
12262 (define_insn "jump"
12264 (label_ref (match_operand 0)))]
12267 [(set_attr "type" "ibr")
12268 (set_attr "modrm" "0")
12269 (set (attr "length")
12271 (and (ge (minus (match_dup 0) (pc))
12273 (lt (minus (match_dup 0) (pc))
12277 (set_attr "maybe_prefix_bnd" "1")])
12279 (define_expand "indirect_jump"
12280 [(set (pc) (match_operand 0 "indirect_branch_operand"))]
12284 operands[0] = convert_memory_address (word_mode, operands[0]);
12287 (define_insn "*indirect_jump"
12288 [(set (pc) (match_operand:W 0 "indirect_branch_operand" "rBw"))]
12291 [(set_attr "type" "ibr")
12292 (set_attr "length_immediate" "0")
12293 (set_attr "maybe_prefix_bnd" "1")])
12295 (define_expand "tablejump"
12296 [(parallel [(set (pc) (match_operand 0 "indirect_branch_operand"))
12297 (use (label_ref (match_operand 1)))])]
12300 /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
12301 relative. Convert the relative address to an absolute address. */
12305 enum rtx_code code;
12307 /* We can't use @GOTOFF for text labels on VxWorks;
12308 see gotoff_operand. */
12309 if (TARGET_64BIT || TARGET_VXWORKS_RTP)
12313 op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
12315 else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
12319 op1 = pic_offset_table_rtx;
12324 op0 = pic_offset_table_rtx;
12328 operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
12333 operands[0] = convert_memory_address (word_mode, operands[0]);
12336 (define_insn "*tablejump_1"
12337 [(set (pc) (match_operand:W 0 "indirect_branch_operand" "rBw"))
12338 (use (label_ref (match_operand 1)))]
12341 [(set_attr "type" "ibr")
12342 (set_attr "length_immediate" "0")
12343 (set_attr "maybe_prefix_bnd" "1")])
12345 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
12348 [(set (reg FLAGS_REG) (match_operand 0))
12349 (set (match_operand:QI 1 "register_operand")
12350 (match_operator:QI 2 "ix86_comparison_operator"
12351 [(reg FLAGS_REG) (const_int 0)]))
12352 (set (match_operand 3 "any_QIreg_operand")
12353 (zero_extend (match_dup 1)))]
12354 "(peep2_reg_dead_p (3, operands[1])
12355 || operands_match_p (operands[1], operands[3]))
12356 && ! reg_overlap_mentioned_p (operands[3], operands[0])
12357 && peep2_regno_dead_p (0, FLAGS_REG)"
12358 [(set (match_dup 4) (match_dup 0))
12359 (set (strict_low_part (match_dup 5))
12362 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
12363 operands[5] = gen_lowpart (QImode, operands[3]);
12364 ix86_expand_clear (operands[3]);
12368 [(parallel [(set (reg FLAGS_REG) (match_operand 0))
12369 (match_operand 4)])
12370 (set (match_operand:QI 1 "register_operand")
12371 (match_operator:QI 2 "ix86_comparison_operator"
12372 [(reg FLAGS_REG) (const_int 0)]))
12373 (set (match_operand 3 "any_QIreg_operand")
12374 (zero_extend (match_dup 1)))]
12375 "(peep2_reg_dead_p (3, operands[1])
12376 || operands_match_p (operands[1], operands[3]))
12377 && ! reg_overlap_mentioned_p (operands[3], operands[0])
12378 && ! reg_set_p (operands[3], operands[4])
12379 && peep2_regno_dead_p (0, FLAGS_REG)"
12380 [(parallel [(set (match_dup 5) (match_dup 0))
12382 (set (strict_low_part (match_dup 6))
12385 operands[5] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
12386 operands[6] = gen_lowpart (QImode, operands[3]);
12387 ix86_expand_clear (operands[3]);
12391 [(set (reg FLAGS_REG) (match_operand 0))
12392 (parallel [(set (reg FLAGS_REG) (match_operand 1))
12393 (match_operand 5)])
12394 (set (match_operand:QI 2 "register_operand")
12395 (match_operator:QI 3 "ix86_comparison_operator"
12396 [(reg FLAGS_REG) (const_int 0)]))
12397 (set (match_operand 4 "any_QIreg_operand")
12398 (zero_extend (match_dup 2)))]
12399 "(peep2_reg_dead_p (4, operands[2])
12400 || operands_match_p (operands[2], operands[4]))
12401 && ! reg_overlap_mentioned_p (operands[4], operands[0])
12402 && ! reg_overlap_mentioned_p (operands[4], operands[1])
12403 && ! reg_set_p (operands[4], operands[5])
12404 && refers_to_regno_p (FLAGS_REG, operands[1], (rtx *)NULL)
12405 && peep2_regno_dead_p (0, FLAGS_REG)"
12406 [(set (match_dup 6) (match_dup 0))
12407 (parallel [(set (match_dup 7) (match_dup 1))
12409 (set (strict_low_part (match_dup 8))
12412 operands[6] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
12413 operands[7] = gen_rtx_REG (GET_MODE (operands[1]), FLAGS_REG);
12414 operands[8] = gen_lowpart (QImode, operands[4]);
12415 ix86_expand_clear (operands[4]);
12418 ;; Similar, but match zero extend with andsi3.
12421 [(set (reg FLAGS_REG) (match_operand 0))
12422 (set (match_operand:QI 1 "register_operand")
12423 (match_operator:QI 2 "ix86_comparison_operator"
12424 [(reg FLAGS_REG) (const_int 0)]))
12425 (parallel [(set (match_operand:SI 3 "any_QIreg_operand")
12426 (and:SI (match_dup 3) (const_int 255)))
12427 (clobber (reg:CC FLAGS_REG))])]
12428 "REGNO (operands[1]) == REGNO (operands[3])
12429 && ! reg_overlap_mentioned_p (operands[3], operands[0])
12430 && peep2_regno_dead_p (0, FLAGS_REG)"
12431 [(set (match_dup 4) (match_dup 0))
12432 (set (strict_low_part (match_dup 5))
12435 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
12436 operands[5] = gen_lowpart (QImode, operands[3]);
12437 ix86_expand_clear (operands[3]);
12441 [(parallel [(set (reg FLAGS_REG) (match_operand 0))
12442 (match_operand 4)])
12443 (set (match_operand:QI 1 "register_operand")
12444 (match_operator:QI 2 "ix86_comparison_operator"
12445 [(reg FLAGS_REG) (const_int 0)]))
12446 (parallel [(set (match_operand 3 "any_QIreg_operand")
12447 (zero_extend (match_dup 1)))
12448 (clobber (reg:CC FLAGS_REG))])]
12449 "(peep2_reg_dead_p (3, operands[1])
12450 || operands_match_p (operands[1], operands[3]))
12451 && ! reg_overlap_mentioned_p (operands[3], operands[0])
12452 && ! reg_set_p (operands[3], operands[4])
12453 && peep2_regno_dead_p (0, FLAGS_REG)"
12454 [(parallel [(set (match_dup 5) (match_dup 0))
12456 (set (strict_low_part (match_dup 6))
12459 operands[5] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
12460 operands[6] = gen_lowpart (QImode, operands[3]);
12461 ix86_expand_clear (operands[3]);
12465 [(set (reg FLAGS_REG) (match_operand 0))
12466 (parallel [(set (reg FLAGS_REG) (match_operand 1))
12467 (match_operand 5)])
12468 (set (match_operand:QI 2 "register_operand")
12469 (match_operator:QI 3 "ix86_comparison_operator"
12470 [(reg FLAGS_REG) (const_int 0)]))
12471 (parallel [(set (match_operand 4 "any_QIreg_operand")
12472 (zero_extend (match_dup 2)))
12473 (clobber (reg:CC FLAGS_REG))])]
12474 "(peep2_reg_dead_p (4, operands[2])
12475 || operands_match_p (operands[2], operands[4]))
12476 && ! reg_overlap_mentioned_p (operands[4], operands[0])
12477 && ! reg_overlap_mentioned_p (operands[4], operands[1])
12478 && ! reg_set_p (operands[4], operands[5])
12479 && refers_to_regno_p (FLAGS_REG, operands[1], (rtx *)NULL)
12480 && peep2_regno_dead_p (0, FLAGS_REG)"
12481 [(set (match_dup 6) (match_dup 0))
12482 (parallel [(set (match_dup 7) (match_dup 1))
12484 (set (strict_low_part (match_dup 8))
12487 operands[6] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
12488 operands[7] = gen_rtx_REG (GET_MODE (operands[1]), FLAGS_REG);
12489 operands[8] = gen_lowpart (QImode, operands[4]);
12490 ix86_expand_clear (operands[4]);
12493 ;; Call instructions.
12495 ;; The predicates normally associated with named expanders are not properly
12496 ;; checked for calls. This is a bug in the generic code, but it isn't that
12497 ;; easy to fix. Ignore it for now and be prepared to fix things up.
12499 ;; P6 processors will jump to the address after the decrement when %esp
12500 ;; is used as a call operand, so they will execute return address as a code.
12501 ;; See Pentium Pro errata 70, Pentium 2 errata A33 and Pentium 3 errata E17.
12503 ;; Register constraint for call instruction.
12504 (define_mode_attr c [(SI "l") (DI "r")])
12506 ;; Call subroutine returning no value.
12508 (define_expand "call"
12509 [(call (match_operand:QI 0)
12511 (use (match_operand 2))]
12514 ix86_expand_call (NULL, operands[0], operands[1],
12515 operands[2], NULL, false);
12519 (define_expand "sibcall"
12520 [(call (match_operand:QI 0)
12522 (use (match_operand 2))]
12525 ix86_expand_call (NULL, operands[0], operands[1],
12526 operands[2], NULL, true);
12530 (define_insn "*call"
12531 [(call (mem:QI (match_operand:W 0 "call_insn_operand" "<c>BwBz"))
12532 (match_operand 1))]
12533 "!SIBLING_CALL_P (insn)"
12534 "* return ix86_output_call_insn (insn, operands[0]);"
12535 [(set_attr "type" "call")])
12537 ;; This covers both call and sibcall since only GOT slot is allowed.
12538 (define_insn "*call_got_x32"
12539 [(call (mem:QI (zero_extend:DI
12540 (match_operand:SI 0 "GOT_memory_operand" "Bg")))
12541 (match_operand 1))]
12544 rtx fnaddr = gen_const_mem (DImode, XEXP (operands[0], 0));
12545 return ix86_output_call_insn (insn, fnaddr);
12547 [(set_attr "type" "call")])
12549 ;; Since sibcall never returns, we can only use call-clobbered register
12551 (define_insn "*sibcall_GOT_32"
12554 (match_operand:SI 0 "register_no_elim_operand" "U")
12555 (match_operand:SI 1 "GOT32_symbol_operand"))))
12556 (match_operand 2))]
12557 "!TARGET_MACHO && !TARGET_64BIT && SIBLING_CALL_P (insn)"
12559 rtx fnaddr = gen_rtx_PLUS (SImode, operands[0], operands[1]);
12560 fnaddr = gen_const_mem (SImode, fnaddr);
12561 return ix86_output_call_insn (insn, fnaddr);
12563 [(set_attr "type" "call")])
12565 (define_insn "*sibcall"
12566 [(call (mem:QI (match_operand:W 0 "sibcall_insn_operand" "UBsBz"))
12567 (match_operand 1))]
12568 "SIBLING_CALL_P (insn)"
12569 "* return ix86_output_call_insn (insn, operands[0]);"
12570 [(set_attr "type" "call")])
12572 (define_insn "*sibcall_memory"
12573 [(call (mem:QI (match_operand:W 0 "memory_operand" "m"))
12575 (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
12577 "* return ix86_output_call_insn (insn, operands[0]);"
12578 [(set_attr "type" "call")])
12581 [(set (match_operand:W 0 "register_operand")
12582 (match_operand:W 1 "memory_operand"))
12583 (call (mem:QI (match_dup 0))
12584 (match_operand 3))]
12585 "!TARGET_X32 && SIBLING_CALL_P (peep2_next_insn (1))
12586 && !reg_mentioned_p (operands[0],
12587 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (1)))"
12588 [(parallel [(call (mem:QI (match_dup 1))
12590 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
12593 [(set (match_operand:W 0 "register_operand")
12594 (match_operand:W 1 "memory_operand"))
12595 (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
12596 (call (mem:QI (match_dup 0))
12597 (match_operand 3))]
12598 "!TARGET_X32 && SIBLING_CALL_P (peep2_next_insn (2))
12599 && !reg_mentioned_p (operands[0],
12600 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (2)))"
12601 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
12602 (parallel [(call (mem:QI (match_dup 1))
12604 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
12606 (define_expand "call_pop"
12607 [(parallel [(call (match_operand:QI 0)
12608 (match_operand:SI 1))
12609 (set (reg:SI SP_REG)
12610 (plus:SI (reg:SI SP_REG)
12611 (match_operand:SI 3)))])]
12614 ix86_expand_call (NULL, operands[0], operands[1],
12615 operands[2], operands[3], false);
12619 (define_insn "*call_pop"
12620 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lmBz"))
12622 (set (reg:SI SP_REG)
12623 (plus:SI (reg:SI SP_REG)
12624 (match_operand:SI 2 "immediate_operand" "i")))]
12625 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
12626 "* return ix86_output_call_insn (insn, operands[0]);"
12627 [(set_attr "type" "call")])
12629 (define_insn "*sibcall_pop"
12630 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "UBsBz"))
12632 (set (reg:SI SP_REG)
12633 (plus:SI (reg:SI SP_REG)
12634 (match_operand:SI 2 "immediate_operand" "i")))]
12635 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
12636 "* return ix86_output_call_insn (insn, operands[0]);"
12637 [(set_attr "type" "call")])
12639 (define_insn "*sibcall_pop_memory"
12640 [(call (mem:QI (match_operand:SI 0 "memory_operand" "m"))
12642 (set (reg:SI SP_REG)
12643 (plus:SI (reg:SI SP_REG)
12644 (match_operand:SI 2 "immediate_operand" "i")))
12645 (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
12647 "* return ix86_output_call_insn (insn, operands[0]);"
12648 [(set_attr "type" "call")])
12651 [(set (match_operand:SI 0 "register_operand")
12652 (match_operand:SI 1 "memory_operand"))
12653 (parallel [(call (mem:QI (match_dup 0))
12655 (set (reg:SI SP_REG)
12656 (plus:SI (reg:SI SP_REG)
12657 (match_operand:SI 4 "immediate_operand")))])]
12658 "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (1))
12659 && !reg_mentioned_p (operands[0],
12660 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (1)))"
12661 [(parallel [(call (mem:QI (match_dup 1))
12663 (set (reg:SI SP_REG)
12664 (plus:SI (reg:SI SP_REG)
12666 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
12669 [(set (match_operand:SI 0 "register_operand")
12670 (match_operand:SI 1 "memory_operand"))
12671 (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
12672 (parallel [(call (mem:QI (match_dup 0))
12674 (set (reg:SI SP_REG)
12675 (plus:SI (reg:SI SP_REG)
12676 (match_operand:SI 4 "immediate_operand")))])]
12677 "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (2))
12678 && !reg_mentioned_p (operands[0],
12679 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (2)))"
12680 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
12681 (parallel [(call (mem:QI (match_dup 1))
12683 (set (reg:SI SP_REG)
12684 (plus:SI (reg:SI SP_REG)
12686 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
12688 ;; Combining simple memory jump instruction
12691 [(set (match_operand:W 0 "register_operand")
12692 (match_operand:W 1 "memory_operand"))
12693 (set (pc) (match_dup 0))]
12694 "!TARGET_X32 && peep2_reg_dead_p (2, operands[0])"
12695 [(set (pc) (match_dup 1))])
12697 ;; Call subroutine, returning value in operand 0
12699 (define_expand "call_value"
12700 [(set (match_operand 0)
12701 (call (match_operand:QI 1)
12702 (match_operand 2)))
12703 (use (match_operand 3))]
12706 ix86_expand_call (operands[0], operands[1], operands[2],
12707 operands[3], NULL, false);
12711 (define_expand "sibcall_value"
12712 [(set (match_operand 0)
12713 (call (match_operand:QI 1)
12714 (match_operand 2)))
12715 (use (match_operand 3))]
12718 ix86_expand_call (operands[0], operands[1], operands[2],
12719 operands[3], NULL, true);
12723 (define_insn "*call_value"
12724 [(set (match_operand 0)
12725 (call (mem:QI (match_operand:W 1 "call_insn_operand" "<c>BwBz"))
12726 (match_operand 2)))]
12727 "!SIBLING_CALL_P (insn)"
12728 "* return ix86_output_call_insn (insn, operands[1]);"
12729 [(set_attr "type" "callv")])
12731 ;; This covers both call and sibcall since only GOT slot is allowed.
12732 (define_insn "*call_value_got_x32"
12733 [(set (match_operand 0)
12736 (match_operand:SI 1 "GOT_memory_operand" "Bg")))
12737 (match_operand 2)))]
12740 rtx fnaddr = gen_const_mem (DImode, XEXP (operands[1], 0));
12741 return ix86_output_call_insn (insn, fnaddr);
12743 [(set_attr "type" "callv")])
12745 ;; Since sibcall never returns, we can only use call-clobbered register
12747 (define_insn "*sibcall_value_GOT_32"
12748 [(set (match_operand 0)
12751 (match_operand:SI 1 "register_no_elim_operand" "U")
12752 (match_operand:SI 2 "GOT32_symbol_operand"))))
12753 (match_operand 3)))]
12754 "!TARGET_MACHO && !TARGET_64BIT && SIBLING_CALL_P (insn)"
12756 rtx fnaddr = gen_rtx_PLUS (SImode, operands[1], operands[2]);
12757 fnaddr = gen_const_mem (SImode, fnaddr);
12758 return ix86_output_call_insn (insn, fnaddr);
12760 [(set_attr "type" "callv")])
12762 (define_insn "*sibcall_value"
12763 [(set (match_operand 0)
12764 (call (mem:QI (match_operand:W 1 "sibcall_insn_operand" "UBsBz"))
12765 (match_operand 2)))]
12766 "SIBLING_CALL_P (insn)"
12767 "* return ix86_output_call_insn (insn, operands[1]);"
12768 [(set_attr "type" "callv")])
12770 (define_insn "*sibcall_value_memory"
12771 [(set (match_operand 0)
12772 (call (mem:QI (match_operand:W 1 "memory_operand" "m"))
12773 (match_operand 2)))
12774 (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
12776 "* return ix86_output_call_insn (insn, operands[1]);"
12777 [(set_attr "type" "callv")])
12780 [(set (match_operand:W 0 "register_operand")
12781 (match_operand:W 1 "memory_operand"))
12782 (set (match_operand 2)
12783 (call (mem:QI (match_dup 0))
12784 (match_operand 3)))]
12785 "!TARGET_X32 && SIBLING_CALL_P (peep2_next_insn (1))
12786 && !reg_mentioned_p (operands[0],
12787 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (1)))"
12788 [(parallel [(set (match_dup 2)
12789 (call (mem:QI (match_dup 1))
12791 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
12794 [(set (match_operand:W 0 "register_operand")
12795 (match_operand:W 1 "memory_operand"))
12796 (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
12797 (set (match_operand 2)
12798 (call (mem:QI (match_dup 0))
12799 (match_operand 3)))]
12800 "!TARGET_X32 && SIBLING_CALL_P (peep2_next_insn (2))
12801 && !reg_mentioned_p (operands[0],
12802 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (2)))"
12803 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
12804 (parallel [(set (match_dup 2)
12805 (call (mem:QI (match_dup 1))
12807 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
12809 (define_expand "call_value_pop"
12810 [(parallel [(set (match_operand 0)
12811 (call (match_operand:QI 1)
12812 (match_operand:SI 2)))
12813 (set (reg:SI SP_REG)
12814 (plus:SI (reg:SI SP_REG)
12815 (match_operand:SI 4)))])]
12818 ix86_expand_call (operands[0], operands[1], operands[2],
12819 operands[3], operands[4], false);
12823 (define_insn "*call_value_pop"
12824 [(set (match_operand 0)
12825 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lmBz"))
12826 (match_operand 2)))
12827 (set (reg:SI SP_REG)
12828 (plus:SI (reg:SI SP_REG)
12829 (match_operand:SI 3 "immediate_operand" "i")))]
12830 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
12831 "* return ix86_output_call_insn (insn, operands[1]);"
12832 [(set_attr "type" "callv")])
12834 (define_insn "*sibcall_value_pop"
12835 [(set (match_operand 0)
12836 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "UBsBz"))
12837 (match_operand 2)))
12838 (set (reg:SI SP_REG)
12839 (plus:SI (reg:SI SP_REG)
12840 (match_operand:SI 3 "immediate_operand" "i")))]
12841 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
12842 "* return ix86_output_call_insn (insn, operands[1]);"
12843 [(set_attr "type" "callv")])
12845 (define_insn "*sibcall_value_pop_memory"
12846 [(set (match_operand 0)
12847 (call (mem:QI (match_operand:SI 1 "memory_operand" "m"))
12848 (match_operand 2)))
12849 (set (reg:SI SP_REG)
12850 (plus:SI (reg:SI SP_REG)
12851 (match_operand:SI 3 "immediate_operand" "i")))
12852 (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
12854 "* return ix86_output_call_insn (insn, operands[1]);"
12855 [(set_attr "type" "callv")])
12858 [(set (match_operand:SI 0 "register_operand")
12859 (match_operand:SI 1 "memory_operand"))
12860 (parallel [(set (match_operand 2)
12861 (call (mem:QI (match_dup 0))
12862 (match_operand 3)))
12863 (set (reg:SI SP_REG)
12864 (plus:SI (reg:SI SP_REG)
12865 (match_operand:SI 4 "immediate_operand")))])]
12866 "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (1))
12867 && !reg_mentioned_p (operands[0],
12868 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (1)))"
12869 [(parallel [(set (match_dup 2)
12870 (call (mem:QI (match_dup 1))
12872 (set (reg:SI SP_REG)
12873 (plus:SI (reg:SI SP_REG)
12875 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
12878 [(set (match_operand:SI 0 "register_operand")
12879 (match_operand:SI 1 "memory_operand"))
12880 (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
12881 (parallel [(set (match_operand 2)
12882 (call (mem:QI (match_dup 0))
12883 (match_operand 3)))
12884 (set (reg:SI SP_REG)
12885 (plus:SI (reg:SI SP_REG)
12886 (match_operand:SI 4 "immediate_operand")))])]
12887 "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (2))
12888 && !reg_mentioned_p (operands[0],
12889 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (2)))"
12890 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
12891 (parallel [(set (match_dup 2)
12892 (call (mem:QI (match_dup 1))
12894 (set (reg:SI SP_REG)
12895 (plus:SI (reg:SI SP_REG)
12897 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
12899 ;; Call subroutine returning any type.
12901 (define_expand "untyped_call"
12902 [(parallel [(call (match_operand 0)
12905 (match_operand 2)])]
12910 /* In order to give reg-stack an easier job in validating two
12911 coprocessor registers as containing a possible return value,
12912 simply pretend the untyped call returns a complex long double
12915 We can't use SSE_REGPARM_MAX here since callee is unprototyped
12916 and should have the default ABI. */
12918 ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
12919 ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
12920 operands[0], const0_rtx,
12921 GEN_INT ((TARGET_64BIT
12922 ? (ix86_abi == SYSV_ABI
12923 ? X86_64_SSE_REGPARM_MAX
12924 : X86_64_MS_SSE_REGPARM_MAX)
12925 : X86_32_SSE_REGPARM_MAX)
12929 for (i = 0; i < XVECLEN (operands[2], 0); i++)
12931 rtx set = XVECEXP (operands[2], 0, i);
12932 emit_move_insn (SET_DEST (set), SET_SRC (set));
12935 /* The optimizer does not know that the call sets the function value
12936 registers we stored in the result block. We avoid problems by
12937 claiming that all hard registers are used and clobbered at this
12939 emit_insn (gen_blockage ());
12944 ;; Prologue and epilogue instructions
12946 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
12947 ;; all of memory. This blocks insns from being moved across this point.
12949 (define_insn "blockage"
12950 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
12953 [(set_attr "length" "0")])
12955 ;; Do not schedule instructions accessing memory across this point.
12957 (define_expand "memory_blockage"
12958 [(set (match_dup 0)
12959 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
12962 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
12963 MEM_VOLATILE_P (operands[0]) = 1;
12966 (define_insn "*memory_blockage"
12967 [(set (match_operand:BLK 0)
12968 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
12971 [(set_attr "length" "0")])
12973 ;; As USE insns aren't meaningful after reload, this is used instead
12974 ;; to prevent deleting instructions setting registers for PIC code
12975 (define_insn "prologue_use"
12976 [(unspec_volatile [(match_operand 0)] UNSPECV_PROLOGUE_USE)]
12979 [(set_attr "length" "0")])
12981 ;; Insn emitted into the body of a function to return from a function.
12982 ;; This is only done if the function's epilogue is known to be simple.
12983 ;; See comments for ix86_can_use_return_insn_p in i386.c.
12985 (define_expand "return"
12987 "ix86_can_use_return_insn_p ()"
12989 if (crtl->args.pops_args)
12991 rtx popc = GEN_INT (crtl->args.pops_args);
12992 emit_jump_insn (gen_simple_return_pop_internal (popc));
12997 ;; We need to disable this for TARGET_SEH, as otherwise
12998 ;; shrink-wrapped prologue gets enabled too. This might exceed
12999 ;; the maximum size of prologue in unwind information.
13000 ;; Also disallow shrink-wrapping if using stack slot to pass the
13001 ;; static chain pointer - the first instruction has to be pushl %esi
13002 ;; and it can't be moved around, as we use alternate entry points
13005 (define_expand "simple_return"
13007 "!TARGET_SEH && !ix86_static_chain_on_stack"
13009 if (crtl->args.pops_args)
13011 rtx popc = GEN_INT (crtl->args.pops_args);
13012 emit_jump_insn (gen_simple_return_pop_internal (popc));
13017 (define_insn "simple_return_internal"
13021 [(set_attr "length" "1")
13022 (set_attr "atom_unit" "jeu")
13023 (set_attr "length_immediate" "0")
13024 (set_attr "modrm" "0")
13025 (set_attr "maybe_prefix_bnd" "1")])
13027 (define_insn "interrupt_return"
13029 (unspec [(const_int 0)] UNSPEC_INTERRUPT_RETURN)]
13032 return TARGET_64BIT ? "iretq" : "iret";
13035 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
13036 ;; instruction Athlon and K8 have.
13038 (define_insn "simple_return_internal_long"
13040 (unspec [(const_int 0)] UNSPEC_REP)]
13043 if (ix86_bnd_prefixed_insn_p (insn))
13046 return "rep%; ret";
13048 [(set_attr "length" "2")
13049 (set_attr "atom_unit" "jeu")
13050 (set_attr "length_immediate" "0")
13051 (set_attr "prefix_rep" "1")
13052 (set_attr "modrm" "0")])
13054 (define_insn "simple_return_pop_internal"
13056 (use (match_operand:SI 0 "const_int_operand"))]
13059 [(set_attr "length" "3")
13060 (set_attr "atom_unit" "jeu")
13061 (set_attr "length_immediate" "2")
13062 (set_attr "modrm" "0")
13063 (set_attr "maybe_prefix_bnd" "1")])
13065 (define_insn "simple_return_indirect_internal"
13067 (use (match_operand:SI 0 "register_operand" "r"))]
13070 [(set_attr "type" "ibr")
13071 (set_attr "length_immediate" "0")
13072 (set_attr "maybe_prefix_bnd" "1")])
13078 [(set_attr "length" "1")
13079 (set_attr "length_immediate" "0")
13080 (set_attr "modrm" "0")])
13082 ;; Generate nops. Operand 0 is the number of nops, up to 8.
13083 (define_insn "nops"
13084 [(unspec_volatile [(match_operand 0 "const_int_operand")]
13088 int num = INTVAL (operands[0]);
13090 gcc_assert (IN_RANGE (num, 1, 8));
13093 fputs ("\tnop\n", asm_out_file);
13097 [(set (attr "length") (symbol_ref "INTVAL (operands[0])"))
13098 (set_attr "length_immediate" "0")
13099 (set_attr "modrm" "0")])
13101 ;; Pad to 16-byte boundary, max skip in op0. Used to avoid
13102 ;; branch prediction penalty for the third jump in a 16-byte
13106 [(unspec_volatile [(match_operand 0)] UNSPECV_ALIGN)]
13109 #ifdef ASM_OUTPUT_MAX_SKIP_PAD
13110 ASM_OUTPUT_MAX_SKIP_PAD (asm_out_file, 4, (int)INTVAL (operands[0]));
13112 /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
13113 The align insn is used to avoid 3 jump instructions in the row to improve
13114 branch prediction and the benefits hardly outweigh the cost of extra 8
13115 nops on the average inserted by full alignment pseudo operation. */
13119 [(set_attr "length" "16")])
13121 (define_expand "prologue"
13124 "ix86_expand_prologue (); DONE;")
13126 (define_expand "set_got"
13128 [(set (match_operand:SI 0 "register_operand")
13129 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
13130 (clobber (reg:CC FLAGS_REG))])]
13133 if (flag_pic && !TARGET_VXWORKS_RTP)
13134 ix86_pc_thunk_call_expanded = true;
13137 (define_insn "*set_got"
13138 [(set (match_operand:SI 0 "register_operand" "=r")
13139 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
13140 (clobber (reg:CC FLAGS_REG))]
13142 "* return output_set_got (operands[0], NULL_RTX);"
13143 [(set_attr "type" "multi")
13144 (set_attr "length" "12")])
13146 (define_expand "set_got_labelled"
13148 [(set (match_operand:SI 0 "register_operand")
13149 (unspec:SI [(label_ref (match_operand 1))]
13151 (clobber (reg:CC FLAGS_REG))])]
13154 if (flag_pic && !TARGET_VXWORKS_RTP)
13155 ix86_pc_thunk_call_expanded = true;
13158 (define_insn "*set_got_labelled"
13159 [(set (match_operand:SI 0 "register_operand" "=r")
13160 (unspec:SI [(label_ref (match_operand 1))]
13162 (clobber (reg:CC FLAGS_REG))]
13164 "* return output_set_got (operands[0], operands[1]);"
13165 [(set_attr "type" "multi")
13166 (set_attr "length" "12")])
13168 (define_insn "set_got_rex64"
13169 [(set (match_operand:DI 0 "register_operand" "=r")
13170 (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
13172 "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}"
13173 [(set_attr "type" "lea")
13174 (set_attr "length_address" "4")
13175 (set_attr "modrm_class" "unknown")
13176 (set_attr "mode" "DI")])
13178 (define_insn "set_rip_rex64"
13179 [(set (match_operand:DI 0 "register_operand" "=r")
13180 (unspec:DI [(label_ref (match_operand 1))] UNSPEC_SET_RIP))]
13182 "lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}"
13183 [(set_attr "type" "lea")
13184 (set_attr "length_address" "4")
13185 (set_attr "mode" "DI")])
13187 (define_insn "set_got_offset_rex64"
13188 [(set (match_operand:DI 0 "register_operand" "=r")
13190 [(label_ref (match_operand 1))]
13191 UNSPEC_SET_GOT_OFFSET))]
13193 "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}"
13194 [(set_attr "type" "imov")
13195 (set_attr "length_immediate" "0")
13196 (set_attr "length_address" "8")
13197 (set_attr "mode" "DI")])
13199 (define_expand "epilogue"
13202 "ix86_expand_epilogue (1); DONE;")
13204 (define_expand "sibcall_epilogue"
13207 "ix86_expand_epilogue (0); DONE;")
13209 (define_expand "eh_return"
13210 [(use (match_operand 0 "register_operand"))]
13213 rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
13215 /* Tricky bit: we write the address of the handler to which we will
13216 be returning into someone else's stack frame, one word below the
13217 stack address we wish to restore. */
13218 tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
13219 tmp = plus_constant (Pmode, tmp, -UNITS_PER_WORD);
13220 tmp = gen_rtx_MEM (Pmode, tmp);
13221 emit_move_insn (tmp, ra);
13223 emit_jump_insn (gen_eh_return_internal ());
13228 (define_insn_and_split "eh_return_internal"
13232 "epilogue_completed"
13234 "ix86_expand_epilogue (2); DONE;")
13236 (define_insn "leave"
13237 [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
13238 (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
13239 (clobber (mem:BLK (scratch)))]
13242 [(set_attr "type" "leave")])
13244 (define_insn "leave_rex64"
13245 [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
13246 (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
13247 (clobber (mem:BLK (scratch)))]
13250 [(set_attr "type" "leave")])
13252 ;; Handle -fsplit-stack.
13254 (define_expand "split_stack_prologue"
13258 ix86_expand_split_stack_prologue ();
13262 ;; In order to support the call/return predictor, we use a return
13263 ;; instruction which the middle-end doesn't see.
13264 (define_insn "split_stack_return"
13265 [(unspec_volatile [(match_operand:SI 0 "const_int_operand")]
13266 UNSPECV_SPLIT_STACK_RETURN)]
13269 if (operands[0] == const0_rtx)
13274 [(set_attr "atom_unit" "jeu")
13275 (set_attr "modrm" "0")
13276 (set (attr "length")
13277 (if_then_else (match_operand:SI 0 "const0_operand")
13280 (set (attr "length_immediate")
13281 (if_then_else (match_operand:SI 0 "const0_operand")
13285 ;; If there are operand 0 bytes available on the stack, jump to
13288 (define_expand "split_stack_space_check"
13289 [(set (pc) (if_then_else
13290 (ltu (minus (reg SP_REG)
13291 (match_operand 0 "register_operand"))
13293 (label_ref (match_operand 1))
13297 rtx reg = gen_reg_rtx (Pmode);
13299 emit_insn (gen_sub3_insn (reg, stack_pointer_rtx, operands[0]));
13301 operands[2] = ix86_split_stack_guard ();
13302 ix86_expand_branch (GEU, reg, operands[2], operands[1]);
13307 ;; Bit manipulation instructions.
13309 (define_expand "ffs<mode>2"
13310 [(set (match_dup 2) (const_int -1))
13311 (parallel [(set (match_dup 3) (match_dup 4))
13312 (set (match_operand:SWI48 0 "register_operand")
13314 (match_operand:SWI48 1 "nonimmediate_operand")))])
13315 (set (match_dup 0) (if_then_else:SWI48
13316 (eq (match_dup 3) (const_int 0))
13319 (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (const_int 1)))
13320 (clobber (reg:CC FLAGS_REG))])]
13323 machine_mode flags_mode;
13325 if (<MODE>mode == SImode && !TARGET_CMOVE)
13327 emit_insn (gen_ffssi2_no_cmove (operands[0], operands [1]));
13331 flags_mode = TARGET_BMI ? CCCmode : CCZmode;
13333 operands[2] = gen_reg_rtx (<MODE>mode);
13334 operands[3] = gen_rtx_REG (flags_mode, FLAGS_REG);
13335 operands[4] = gen_rtx_COMPARE (flags_mode, operands[1], const0_rtx);
13338 (define_insn_and_split "ffssi2_no_cmove"
13339 [(set (match_operand:SI 0 "register_operand" "=r")
13340 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
13341 (clobber (match_scratch:SI 2 "=&q"))
13342 (clobber (reg:CC FLAGS_REG))]
13345 "&& reload_completed"
13346 [(parallel [(set (match_dup 4) (match_dup 5))
13347 (set (match_dup 0) (ctz:SI (match_dup 1)))])
13348 (set (strict_low_part (match_dup 3))
13349 (eq:QI (match_dup 4) (const_int 0)))
13350 (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
13351 (clobber (reg:CC FLAGS_REG))])
13352 (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
13353 (clobber (reg:CC FLAGS_REG))])
13354 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
13355 (clobber (reg:CC FLAGS_REG))])]
13357 machine_mode flags_mode = TARGET_BMI ? CCCmode : CCZmode;
13359 operands[3] = gen_lowpart (QImode, operands[2]);
13360 operands[4] = gen_rtx_REG (flags_mode, FLAGS_REG);
13361 operands[5] = gen_rtx_COMPARE (flags_mode, operands[1], const0_rtx);
13363 ix86_expand_clear (operands[2]);
13366 (define_insn_and_split "*tzcnt<mode>_1"
13367 [(set (reg:CCC FLAGS_REG)
13368 (compare:CCC (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13370 (set (match_operand:SWI48 0 "register_operand" "=r")
13371 (ctz:SWI48 (match_dup 1)))]
13373 "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
13374 "&& TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
13375 && optimize_function_for_speed_p (cfun)
13376 && !reg_mentioned_p (operands[0], operands[1])"
13378 [(set (reg:CCC FLAGS_REG)
13379 (compare:CCC (match_dup 1) (const_int 0)))
13381 (ctz:SWI48 (match_dup 1)))
13382 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)])]
13383 "ix86_expand_clear (operands[0]);"
13384 [(set_attr "type" "alu1")
13385 (set_attr "prefix_0f" "1")
13386 (set_attr "prefix_rep" "1")
13387 (set_attr "btver2_decode" "double")
13388 (set_attr "mode" "<MODE>")])
13390 ; False dependency happens when destination is only updated by tzcnt,
13391 ; lzcnt or popcnt. There is no false dependency when destination is
13392 ; also used in source.
13393 (define_insn "*tzcnt<mode>_1_falsedep"
13394 [(set (reg:CCC FLAGS_REG)
13395 (compare:CCC (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13397 (set (match_operand:SWI48 0 "register_operand" "=r")
13398 (ctz:SWI48 (match_dup 1)))
13399 (unspec [(match_operand:SWI48 2 "register_operand" "0")]
13400 UNSPEC_INSN_FALSE_DEP)]
13402 "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
13403 [(set_attr "type" "alu1")
13404 (set_attr "prefix_0f" "1")
13405 (set_attr "prefix_rep" "1")
13406 (set_attr "btver2_decode" "double")
13407 (set_attr "mode" "<MODE>")])
13409 (define_insn "*bsf<mode>_1"
13410 [(set (reg:CCZ FLAGS_REG)
13411 (compare:CCZ (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13413 (set (match_operand:SWI48 0 "register_operand" "=r")
13414 (ctz:SWI48 (match_dup 1)))]
13416 "bsf{<imodesuffix>}\t{%1, %0|%0, %1}"
13417 [(set_attr "type" "alu1")
13418 (set_attr "prefix_0f" "1")
13419 (set_attr "btver2_decode" "double")
13420 (set_attr "znver1_decode" "vector")
13421 (set_attr "mode" "<MODE>")])
13423 (define_insn_and_split "ctz<mode>2"
13424 [(set (match_operand:SWI48 0 "register_operand" "=r")
13426 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
13427 (clobber (reg:CC FLAGS_REG))]
13431 return "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
13432 else if (optimize_function_for_size_p (cfun))
13434 else if (TARGET_GENERIC)
13435 /* tzcnt expands to 'rep bsf' and we can use it even if !TARGET_BMI. */
13436 return "rep%; bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
13438 return "bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
13440 "(TARGET_BMI || TARGET_GENERIC)
13441 && TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
13442 && optimize_function_for_speed_p (cfun)
13443 && !reg_mentioned_p (operands[0], operands[1])"
13445 [(set (match_dup 0)
13446 (ctz:SWI48 (match_dup 1)))
13447 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
13448 (clobber (reg:CC FLAGS_REG))])]
13449 "ix86_expand_clear (operands[0]);"
13450 [(set_attr "type" "alu1")
13451 (set_attr "prefix_0f" "1")
13452 (set (attr "prefix_rep")
13454 (ior (match_test "TARGET_BMI")
13455 (and (not (match_test "optimize_function_for_size_p (cfun)"))
13456 (match_test "TARGET_GENERIC")))
13458 (const_string "0")))
13459 (set_attr "mode" "<MODE>")])
13461 ; False dependency happens when destination is only updated by tzcnt,
13462 ; lzcnt or popcnt. There is no false dependency when destination is
13463 ; also used in source.
13464 (define_insn "*ctz<mode>2_falsedep"
13465 [(set (match_operand:SWI48 0 "register_operand" "=r")
13467 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
13468 (unspec [(match_operand:SWI48 2 "register_operand" "0")]
13469 UNSPEC_INSN_FALSE_DEP)
13470 (clobber (reg:CC FLAGS_REG))]
13474 return "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
13475 else if (TARGET_GENERIC)
13476 /* tzcnt expands to 'rep bsf' and we can use it even if !TARGET_BMI. */
13477 return "rep%; bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
13479 gcc_unreachable ();
13481 [(set_attr "type" "alu1")
13482 (set_attr "prefix_0f" "1")
13483 (set_attr "prefix_rep" "1")
13484 (set_attr "mode" "<MODE>")])
13486 (define_insn "bsr_rex64"
13487 [(set (match_operand:DI 0 "register_operand" "=r")
13488 (minus:DI (const_int 63)
13489 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
13490 (clobber (reg:CC FLAGS_REG))]
13492 "bsr{q}\t{%1, %0|%0, %1}"
13493 [(set_attr "type" "alu1")
13494 (set_attr "prefix_0f" "1")
13495 (set_attr "znver1_decode" "vector")
13496 (set_attr "mode" "DI")])
13499 [(set (match_operand:SI 0 "register_operand" "=r")
13500 (minus:SI (const_int 31)
13501 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
13502 (clobber (reg:CC FLAGS_REG))]
13504 "bsr{l}\t{%1, %0|%0, %1}"
13505 [(set_attr "type" "alu1")
13506 (set_attr "prefix_0f" "1")
13507 (set_attr "znver1_decode" "vector")
13508 (set_attr "mode" "SI")])
13510 (define_insn "*bsrhi"
13511 [(set (match_operand:HI 0 "register_operand" "=r")
13512 (minus:HI (const_int 15)
13513 (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
13514 (clobber (reg:CC FLAGS_REG))]
13516 "bsr{w}\t{%1, %0|%0, %1}"
13517 [(set_attr "type" "alu1")
13518 (set_attr "prefix_0f" "1")
13519 (set_attr "znver1_decode" "vector")
13520 (set_attr "mode" "HI")])
13522 (define_expand "clz<mode>2"
13524 [(set (match_operand:SWI48 0 "register_operand")
13527 (clz:SWI48 (match_operand:SWI48 1 "nonimmediate_operand"))))
13528 (clobber (reg:CC FLAGS_REG))])
13530 [(set (match_dup 0) (xor:SWI48 (match_dup 0) (match_dup 2)))
13531 (clobber (reg:CC FLAGS_REG))])]
13536 emit_insn (gen_clz<mode>2_lzcnt (operands[0], operands[1]));
13539 operands[2] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
13542 (define_insn_and_split "clz<mode>2_lzcnt"
13543 [(set (match_operand:SWI48 0 "register_operand" "=r")
13545 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
13546 (clobber (reg:CC FLAGS_REG))]
13548 "lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
13549 "&& TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
13550 && optimize_function_for_speed_p (cfun)
13551 && !reg_mentioned_p (operands[0], operands[1])"
13553 [(set (match_dup 0)
13554 (clz:SWI48 (match_dup 1)))
13555 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
13556 (clobber (reg:CC FLAGS_REG))])]
13557 "ix86_expand_clear (operands[0]);"
13558 [(set_attr "prefix_rep" "1")
13559 (set_attr "type" "bitmanip")
13560 (set_attr "mode" "<MODE>")])
13562 ; False dependency happens when destination is only updated by tzcnt,
13563 ; lzcnt or popcnt. There is no false dependency when destination is
13564 ; also used in source.
13565 (define_insn "*clz<mode>2_lzcnt_falsedep"
13566 [(set (match_operand:SWI48 0 "register_operand" "=r")
13568 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
13569 (unspec [(match_operand:SWI48 2 "register_operand" "0")]
13570 UNSPEC_INSN_FALSE_DEP)
13571 (clobber (reg:CC FLAGS_REG))]
13573 "lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
13574 [(set_attr "prefix_rep" "1")
13575 (set_attr "type" "bitmanip")
13576 (set_attr "mode" "<MODE>")])
13578 (define_int_iterator LT_ZCNT
13579 [(UNSPEC_TZCNT "TARGET_BMI")
13580 (UNSPEC_LZCNT "TARGET_LZCNT")])
13582 (define_int_attr lt_zcnt
13583 [(UNSPEC_TZCNT "tzcnt")
13584 (UNSPEC_LZCNT "lzcnt")])
13586 (define_int_attr lt_zcnt_type
13587 [(UNSPEC_TZCNT "alu1")
13588 (UNSPEC_LZCNT "bitmanip")])
13590 ;; Version of lzcnt/tzcnt that is expanded from intrinsics. This version
13591 ;; provides operand size as output when source operand is zero.
13593 (define_insn_and_split "<lt_zcnt>_<mode>"
13594 [(set (match_operand:SWI48 0 "register_operand" "=r")
13596 [(match_operand:SWI48 1 "nonimmediate_operand" "rm")] LT_ZCNT))
13597 (clobber (reg:CC FLAGS_REG))]
13599 "<lt_zcnt>{<imodesuffix>}\t{%1, %0|%0, %1}"
13600 "&& TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
13601 && optimize_function_for_speed_p (cfun)
13602 && !reg_mentioned_p (operands[0], operands[1])"
13604 [(set (match_dup 0)
13605 (unspec:SWI48 [(match_dup 1)] LT_ZCNT))
13606 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
13607 (clobber (reg:CC FLAGS_REG))])]
13608 "ix86_expand_clear (operands[0]);"
13609 [(set_attr "type" "<lt_zcnt_type>")
13610 (set_attr "prefix_0f" "1")
13611 (set_attr "prefix_rep" "1")
13612 (set_attr "mode" "<MODE>")])
13614 ; False dependency happens when destination is only updated by tzcnt,
13615 ; lzcnt or popcnt. There is no false dependency when destination is
13616 ; also used in source.
13617 (define_insn "*<lt_zcnt>_<mode>_falsedep"
13618 [(set (match_operand:SWI48 0 "register_operand" "=r")
13620 [(match_operand:SWI48 1 "nonimmediate_operand" "rm")] LT_ZCNT))
13621 (unspec [(match_operand:SWI48 2 "register_operand" "0")]
13622 UNSPEC_INSN_FALSE_DEP)
13623 (clobber (reg:CC FLAGS_REG))]
13625 "<lt_zcnt>{<imodesuffix>}\t{%1, %0|%0, %1}"
13626 [(set_attr "type" "<lt_zcnt_type>")
13627 (set_attr "prefix_0f" "1")
13628 (set_attr "prefix_rep" "1")
13629 (set_attr "mode" "<MODE>")])
13631 (define_insn "<lt_zcnt>_hi"
13632 [(set (match_operand:HI 0 "register_operand" "=r")
13634 [(match_operand:HI 1 "nonimmediate_operand" "rm")] LT_ZCNT))
13635 (clobber (reg:CC FLAGS_REG))]
13637 "<lt_zcnt>{w}\t{%1, %0|%0, %1}"
13638 [(set_attr "type" "<lt_zcnt_type>")
13639 (set_attr "prefix_0f" "1")
13640 (set_attr "prefix_rep" "1")
13641 (set_attr "mode" "HI")])
13643 ;; BMI instructions.
13645 (define_insn "bmi_bextr_<mode>"
13646 [(set (match_operand:SWI48 0 "register_operand" "=r,r")
13647 (unspec:SWI48 [(match_operand:SWI48 1 "nonimmediate_operand" "r,m")
13648 (match_operand:SWI48 2 "register_operand" "r,r")]
13650 (clobber (reg:CC FLAGS_REG))]
13652 "bextr\t{%2, %1, %0|%0, %1, %2}"
13653 [(set_attr "type" "bitmanip")
13654 (set_attr "btver2_decode" "direct, double")
13655 (set_attr "mode" "<MODE>")])
13657 (define_insn "*bmi_bextr_<mode>_ccz"
13658 [(set (reg:CCZ FLAGS_REG)
13660 (unspec:SWI48 [(match_operand:SWI48 1 "nonimmediate_operand" "r,m")
13661 (match_operand:SWI48 2 "register_operand" "r,r")]
13664 (clobber (match_scratch:SWI48 0 "=r,r"))]
13666 "bextr\t{%2, %1, %0|%0, %1, %2}"
13667 [(set_attr "type" "bitmanip")
13668 (set_attr "btver2_decode" "direct, double")
13669 (set_attr "mode" "<MODE>")])
13671 (define_insn "*bmi_blsi_<mode>"
13672 [(set (match_operand:SWI48 0 "register_operand" "=r")
13675 (match_operand:SWI48 1 "nonimmediate_operand" "rm"))
13677 (clobber (reg:CC FLAGS_REG))]
13679 "blsi\t{%1, %0|%0, %1}"
13680 [(set_attr "type" "bitmanip")
13681 (set_attr "btver2_decode" "double")
13682 (set_attr "mode" "<MODE>")])
13684 (define_insn "*bmi_blsmsk_<mode>"
13685 [(set (match_operand:SWI48 0 "register_operand" "=r")
13688 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13691 (clobber (reg:CC FLAGS_REG))]
13693 "blsmsk\t{%1, %0|%0, %1}"
13694 [(set_attr "type" "bitmanip")
13695 (set_attr "btver2_decode" "double")
13696 (set_attr "mode" "<MODE>")])
13698 (define_insn "*bmi_blsr_<mode>"
13699 [(set (match_operand:SWI48 0 "register_operand" "=r")
13702 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13705 (clobber (reg:CC FLAGS_REG))]
13707 "blsr\t{%1, %0|%0, %1}"
13708 [(set_attr "type" "bitmanip")
13709 (set_attr "btver2_decode" "double")
13710 (set_attr "mode" "<MODE>")])
13712 ;; BMI2 instructions.
13713 (define_expand "bmi2_bzhi_<mode>3"
13715 [(set (match_operand:SWI48 0 "register_operand")
13716 (zero_extract:SWI48
13717 (match_operand:SWI48 1 "nonimmediate_operand")
13719 (and:SWI48 (match_operand:SWI48 2 "register_operand")
13723 (clobber (reg:CC FLAGS_REG))])]
13725 "operands[3] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT);")
13727 (define_insn "*bmi2_bzhi_<mode>3"
13728 [(set (match_operand:SWI48 0 "register_operand" "=r")
13729 (zero_extract:SWI48
13730 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13732 (and:SWI48 (match_operand:SWI48 2 "register_operand" "r")
13734 (match_operand:SWI48 3 "const_int_operand" "n"))
13736 (clobber (reg:CC FLAGS_REG))]
13737 "TARGET_BMI2 && INTVAL (operands[3]) == <MODE_SIZE> * BITS_PER_UNIT"
13738 "bzhi\t{%2, %1, %0|%0, %1, %2}"
13739 [(set_attr "type" "bitmanip")
13740 (set_attr "prefix" "vex")
13741 (set_attr "mode" "<MODE>")])
13743 (define_insn "*bmi2_bzhi_<mode>3_1"
13744 [(set (match_operand:SWI48 0 "register_operand" "=r")
13745 (zero_extract:SWI48
13746 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13748 (zero_extend:SWI48 (match_operand:QI 2 "register_operand" "r"))
13749 (match_operand:SWI48 3 "const_int_operand" "n"))
13751 (clobber (reg:CC FLAGS_REG))]
13752 "TARGET_BMI2 && INTVAL (operands[3]) == <MODE_SIZE> * BITS_PER_UNIT"
13753 "bzhi\t{%<k>2, %1, %0|%0, %1, %<k>2}"
13754 [(set_attr "type" "bitmanip")
13755 (set_attr "prefix" "vex")
13756 (set_attr "mode" "<MODE>")])
13758 (define_insn "*bmi2_bzhi_<mode>3_1_ccz"
13759 [(set (reg:CCZ FLAGS_REG)
13761 (zero_extract:SWI48
13762 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13764 (zero_extend:SWI48 (match_operand:QI 2 "register_operand" "r"))
13765 (match_operand:SWI48 3 "const_int_operand" "n"))
13768 (clobber (match_scratch:SWI48 0 "=r"))]
13769 "TARGET_BMI2 && INTVAL (operands[3]) == <MODE_SIZE> * BITS_PER_UNIT"
13770 "bzhi\t{%<k>2, %1, %0|%0, %1, %<k>2}"
13771 [(set_attr "type" "bitmanip")
13772 (set_attr "prefix" "vex")
13773 (set_attr "mode" "<MODE>")])
13775 (define_insn "bmi2_pdep_<mode>3"
13776 [(set (match_operand:SWI48 0 "register_operand" "=r")
13777 (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
13778 (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
13781 "pdep\t{%2, %1, %0|%0, %1, %2}"
13782 [(set_attr "type" "bitmanip")
13783 (set_attr "prefix" "vex")
13784 (set_attr "mode" "<MODE>")])
13786 (define_insn "bmi2_pext_<mode>3"
13787 [(set (match_operand:SWI48 0 "register_operand" "=r")
13788 (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
13789 (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
13792 "pext\t{%2, %1, %0|%0, %1, %2}"
13793 [(set_attr "type" "bitmanip")
13794 (set_attr "prefix" "vex")
13795 (set_attr "mode" "<MODE>")])
13797 ;; TBM instructions.
13798 (define_insn "tbm_bextri_<mode>"
13799 [(set (match_operand:SWI48 0 "register_operand" "=r")
13800 (zero_extract:SWI48
13801 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13802 (match_operand 2 "const_0_to_255_operand" "N")
13803 (match_operand 3 "const_0_to_255_operand" "N")))
13804 (clobber (reg:CC FLAGS_REG))]
13807 operands[2] = GEN_INT (INTVAL (operands[2]) << 8 | INTVAL (operands[3]));
13808 return "bextr\t{%2, %1, %0|%0, %1, %2}";
13810 [(set_attr "type" "bitmanip")
13811 (set_attr "mode" "<MODE>")])
13813 (define_insn "*tbm_blcfill_<mode>"
13814 [(set (match_operand:SWI48 0 "register_operand" "=r")
13817 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13820 (clobber (reg:CC FLAGS_REG))]
13822 "blcfill\t{%1, %0|%0, %1}"
13823 [(set_attr "type" "bitmanip")
13824 (set_attr "mode" "<MODE>")])
13826 (define_insn "*tbm_blci_<mode>"
13827 [(set (match_operand:SWI48 0 "register_operand" "=r")
13831 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13834 (clobber (reg:CC FLAGS_REG))]
13836 "blci\t{%1, %0|%0, %1}"
13837 [(set_attr "type" "bitmanip")
13838 (set_attr "mode" "<MODE>")])
13840 (define_insn "*tbm_blcic_<mode>"
13841 [(set (match_operand:SWI48 0 "register_operand" "=r")
13844 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13848 (clobber (reg:CC FLAGS_REG))]
13850 "blcic\t{%1, %0|%0, %1}"
13851 [(set_attr "type" "bitmanip")
13852 (set_attr "mode" "<MODE>")])
13854 (define_insn "*tbm_blcmsk_<mode>"
13855 [(set (match_operand:SWI48 0 "register_operand" "=r")
13858 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13861 (clobber (reg:CC FLAGS_REG))]
13863 "blcmsk\t{%1, %0|%0, %1}"
13864 [(set_attr "type" "bitmanip")
13865 (set_attr "mode" "<MODE>")])
13867 (define_insn "*tbm_blcs_<mode>"
13868 [(set (match_operand:SWI48 0 "register_operand" "=r")
13871 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13874 (clobber (reg:CC FLAGS_REG))]
13876 "blcs\t{%1, %0|%0, %1}"
13877 [(set_attr "type" "bitmanip")
13878 (set_attr "mode" "<MODE>")])
13880 (define_insn "*tbm_blsfill_<mode>"
13881 [(set (match_operand:SWI48 0 "register_operand" "=r")
13884 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13887 (clobber (reg:CC FLAGS_REG))]
13889 "blsfill\t{%1, %0|%0, %1}"
13890 [(set_attr "type" "bitmanip")
13891 (set_attr "mode" "<MODE>")])
13893 (define_insn "*tbm_blsic_<mode>"
13894 [(set (match_operand:SWI48 0 "register_operand" "=r")
13897 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13901 (clobber (reg:CC FLAGS_REG))]
13903 "blsic\t{%1, %0|%0, %1}"
13904 [(set_attr "type" "bitmanip")
13905 (set_attr "mode" "<MODE>")])
13907 (define_insn "*tbm_t1mskc_<mode>"
13908 [(set (match_operand:SWI48 0 "register_operand" "=r")
13911 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13915 (clobber (reg:CC FLAGS_REG))]
13917 "t1mskc\t{%1, %0|%0, %1}"
13918 [(set_attr "type" "bitmanip")
13919 (set_attr "mode" "<MODE>")])
13921 (define_insn "*tbm_tzmsk_<mode>"
13922 [(set (match_operand:SWI48 0 "register_operand" "=r")
13925 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13929 (clobber (reg:CC FLAGS_REG))]
13931 "tzmsk\t{%1, %0|%0, %1}"
13932 [(set_attr "type" "bitmanip")
13933 (set_attr "mode" "<MODE>")])
13935 (define_insn_and_split "popcount<mode>2"
13936 [(set (match_operand:SWI48 0 "register_operand" "=r")
13938 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
13939 (clobber (reg:CC FLAGS_REG))]
13943 return "popcnt\t{%1, %0|%0, %1}";
13945 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
13948 "&& TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
13949 && optimize_function_for_speed_p (cfun)
13950 && !reg_mentioned_p (operands[0], operands[1])"
13952 [(set (match_dup 0)
13953 (popcount:SWI48 (match_dup 1)))
13954 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
13955 (clobber (reg:CC FLAGS_REG))])]
13956 "ix86_expand_clear (operands[0]);"
13957 [(set_attr "prefix_rep" "1")
13958 (set_attr "type" "bitmanip")
13959 (set_attr "mode" "<MODE>")])
13961 ; False dependency happens when destination is only updated by tzcnt,
13962 ; lzcnt or popcnt. There is no false dependency when destination is
13963 ; also used in source.
13964 (define_insn "*popcount<mode>2_falsedep"
13965 [(set (match_operand:SWI48 0 "register_operand" "=r")
13967 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
13968 (unspec [(match_operand:SWI48 2 "register_operand" "0")]
13969 UNSPEC_INSN_FALSE_DEP)
13970 (clobber (reg:CC FLAGS_REG))]
13974 return "popcnt\t{%1, %0|%0, %1}";
13976 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
13979 [(set_attr "prefix_rep" "1")
13980 (set_attr "type" "bitmanip")
13981 (set_attr "mode" "<MODE>")])
13983 (define_insn_and_split "*popcounthi2_1"
13984 [(set (match_operand:SI 0 "register_operand")
13986 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand"))))
13987 (clobber (reg:CC FLAGS_REG))]
13989 && can_create_pseudo_p ()"
13994 rtx tmp = gen_reg_rtx (HImode);
13996 emit_insn (gen_popcounthi2 (tmp, operands[1]));
13997 emit_insn (gen_zero_extendhisi2 (operands[0], tmp));
14001 (define_insn "popcounthi2"
14002 [(set (match_operand:HI 0 "register_operand" "=r")
14004 (match_operand:HI 1 "nonimmediate_operand" "rm")))
14005 (clobber (reg:CC FLAGS_REG))]
14009 return "popcnt\t{%1, %0|%0, %1}";
14011 return "popcnt{w}\t{%1, %0|%0, %1}";
14014 [(set_attr "prefix_rep" "1")
14015 (set_attr "type" "bitmanip")
14016 (set_attr "mode" "HI")])
14018 (define_expand "bswapdi2"
14019 [(set (match_operand:DI 0 "register_operand")
14020 (bswap:DI (match_operand:DI 1 "nonimmediate_operand")))]
14024 operands[1] = force_reg (DImode, operands[1]);
14027 (define_expand "bswapsi2"
14028 [(set (match_operand:SI 0 "register_operand")
14029 (bswap:SI (match_operand:SI 1 "nonimmediate_operand")))]
14034 else if (TARGET_BSWAP)
14035 operands[1] = force_reg (SImode, operands[1]);
14038 rtx x = operands[0];
14040 emit_move_insn (x, operands[1]);
14041 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
14042 emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
14043 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
14048 (define_insn "*bswap<mode>2_movbe"
14049 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,r,m")
14050 (bswap:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,m,r")))]
14052 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
14055 movbe\t{%1, %0|%0, %1}
14056 movbe\t{%1, %0|%0, %1}"
14057 [(set_attr "type" "bitmanip,imov,imov")
14058 (set_attr "modrm" "0,1,1")
14059 (set_attr "prefix_0f" "*,1,1")
14060 (set_attr "prefix_extra" "*,1,1")
14061 (set_attr "mode" "<MODE>")])
14063 (define_insn "*bswap<mode>2"
14064 [(set (match_operand:SWI48 0 "register_operand" "=r")
14065 (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "0")))]
14068 [(set_attr "type" "bitmanip")
14069 (set_attr "modrm" "0")
14070 (set_attr "mode" "<MODE>")])
14072 (define_insn "*bswaphi_lowpart_1"
14073 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
14074 (bswap:HI (match_dup 0)))
14075 (clobber (reg:CC FLAGS_REG))]
14076 "TARGET_USE_XCHGB || optimize_function_for_size_p (cfun)"
14078 xchg{b}\t{%h0, %b0|%b0, %h0}
14079 rol{w}\t{$8, %0|%0, 8}"
14080 [(set_attr "length" "2,4")
14081 (set_attr "mode" "QI,HI")])
14083 (define_insn "bswaphi_lowpart"
14084 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
14085 (bswap:HI (match_dup 0)))
14086 (clobber (reg:CC FLAGS_REG))]
14088 "rol{w}\t{$8, %0|%0, 8}"
14089 [(set_attr "length" "4")
14090 (set_attr "mode" "HI")])
14092 (define_expand "paritydi2"
14093 [(set (match_operand:DI 0 "register_operand")
14094 (parity:DI (match_operand:DI 1 "register_operand")))]
14097 rtx scratch = gen_reg_rtx (QImode);
14099 emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX,
14100 NULL_RTX, operands[1]));
14102 ix86_expand_setcc (scratch, ORDERED,
14103 gen_rtx_REG (CCmode, FLAGS_REG), const0_rtx);
14106 emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
14109 rtx tmp = gen_reg_rtx (SImode);
14111 emit_insn (gen_zero_extendqisi2 (tmp, scratch));
14112 emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
14117 (define_expand "paritysi2"
14118 [(set (match_operand:SI 0 "register_operand")
14119 (parity:SI (match_operand:SI 1 "register_operand")))]
14122 rtx scratch = gen_reg_rtx (QImode);
14124 emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1]));
14126 ix86_expand_setcc (scratch, ORDERED,
14127 gen_rtx_REG (CCmode, FLAGS_REG), const0_rtx);
14129 emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
14133 (define_insn_and_split "paritydi2_cmp"
14134 [(set (reg:CC FLAGS_REG)
14135 (unspec:CC [(match_operand:DI 3 "register_operand" "0")]
14137 (clobber (match_scratch:DI 0 "=r"))
14138 (clobber (match_scratch:SI 1 "=&r"))
14139 (clobber (match_scratch:HI 2 "=Q"))]
14142 "&& reload_completed"
14144 [(set (match_dup 1)
14145 (xor:SI (match_dup 1) (match_dup 4)))
14146 (clobber (reg:CC FLAGS_REG))])
14148 [(set (reg:CC FLAGS_REG)
14149 (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
14150 (clobber (match_dup 1))
14151 (clobber (match_dup 2))])]
14153 operands[4] = gen_lowpart (SImode, operands[3]);
14157 emit_move_insn (operands[1], gen_lowpart (SImode, operands[3]));
14158 emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32)));
14161 operands[1] = gen_highpart (SImode, operands[3]);
14164 (define_insn_and_split "paritysi2_cmp"
14165 [(set (reg:CC FLAGS_REG)
14166 (unspec:CC [(match_operand:SI 2 "register_operand" "0")]
14168 (clobber (match_scratch:SI 0 "=r"))
14169 (clobber (match_scratch:HI 1 "=&Q"))]
14172 "&& reload_completed"
14174 [(set (match_dup 1)
14175 (xor:HI (match_dup 1) (match_dup 3)))
14176 (clobber (reg:CC FLAGS_REG))])
14178 [(set (reg:CC FLAGS_REG)
14179 (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
14180 (clobber (match_dup 1))])]
14182 operands[3] = gen_lowpart (HImode, operands[2]);
14184 emit_move_insn (operands[1], gen_lowpart (HImode, operands[2]));
14185 emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16)));
14188 (define_insn "*parityhi2_cmp"
14189 [(set (reg:CC FLAGS_REG)
14190 (unspec:CC [(match_operand:HI 1 "register_operand" "0")]
14192 (clobber (match_scratch:HI 0 "=Q"))]
14194 "xor{b}\t{%h0, %b0|%b0, %h0}"
14195 [(set_attr "length" "2")
14196 (set_attr "mode" "HI")])
14199 ;; Thread-local storage patterns for ELF.
14201 ;; Note that these code sequences must appear exactly as shown
14202 ;; in order to allow linker relaxation.
14204 (define_insn "*tls_global_dynamic_32_gnu"
14205 [(set (match_operand:SI 0 "register_operand" "=a")
14207 [(match_operand:SI 1 "register_operand" "Yb")
14208 (match_operand 2 "tls_symbolic_operand")
14209 (match_operand 3 "constant_call_address_operand" "Bz")
14212 (clobber (match_scratch:SI 4 "=d"))
14213 (clobber (match_scratch:SI 5 "=c"))
14214 (clobber (reg:CC FLAGS_REG))]
14215 "!TARGET_64BIT && TARGET_GNU_TLS"
14217 if (TARGET_SUN_TLS || flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT)
14219 ("lea{l}\t{%E2@tlsgd(,%1,1), %0|%0, %E2@tlsgd[%1*1]}", operands);
14222 ("lea{l}\t{%E2@tlsgd(%1), %0|%0, %E2@tlsgd[%1]}", operands);
14223 if (TARGET_SUN_TLS)
14224 #ifdef HAVE_AS_IX86_TLSGDPLT
14225 return "call\t%a2@tlsgdplt";
14227 return "call\t%p3@plt";
14229 if (flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT)
14230 return "call\t%P3";
14231 return "call\t{*%p3@GOT(%1)|[DWORD PTR %p3@GOT[%1]]}";
14233 [(set_attr "type" "multi")
14234 (set_attr "length" "12")])
14236 (define_expand "tls_global_dynamic_32"
14238 [(set (match_operand:SI 0 "register_operand")
14239 (unspec:SI [(match_operand:SI 2 "register_operand")
14240 (match_operand 1 "tls_symbolic_operand")
14241 (match_operand 3 "constant_call_address_operand")
14244 (clobber (match_scratch:SI 4))
14245 (clobber (match_scratch:SI 5))
14246 (clobber (reg:CC FLAGS_REG))])]
14248 "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
14250 (define_insn "*tls_global_dynamic_64_<mode>"
14251 [(set (match_operand:P 0 "register_operand" "=a")
14253 (mem:QI (match_operand 2 "constant_call_address_operand" "Bz"))
14254 (match_operand 3)))
14255 (unspec:P [(match_operand 1 "tls_symbolic_operand")
14261 fputs (ASM_BYTE "0x66\n", asm_out_file);
14263 ("lea{q}\t{%E1@tlsgd(%%rip), %%rdi|rdi, %E1@tlsgd[rip]}", operands);
14264 if (TARGET_SUN_TLS || flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT)
14265 fputs (ASM_SHORT "0x6666\n", asm_out_file);
14267 fputs (ASM_BYTE "0x66\n", asm_out_file);
14268 fputs ("\trex64\n", asm_out_file);
14269 if (TARGET_SUN_TLS)
14270 return "call\t%p2@plt";
14271 if (flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT)
14272 return "call\t%P2";
14273 return "call\t{*%p2@GOTPCREL(%%rip)|[QWORD PTR %p2@GOTPCREL[rip]]}";
14275 [(set_attr "type" "multi")
14276 (set (attr "length")
14277 (symbol_ref "TARGET_X32 ? 15 : 16"))])
14279 (define_insn "*tls_global_dynamic_64_largepic"
14280 [(set (match_operand:DI 0 "register_operand" "=a")
14282 (mem:QI (plus:DI (match_operand:DI 2 "register_operand" "b")
14283 (match_operand:DI 3 "immediate_operand" "i")))
14284 (match_operand 4)))
14285 (unspec:DI [(match_operand 1 "tls_symbolic_operand")
14288 "TARGET_64BIT && ix86_cmodel == CM_LARGE_PIC && !TARGET_PECOFF
14289 && GET_CODE (operands[3]) == CONST
14290 && GET_CODE (XEXP (operands[3], 0)) == UNSPEC
14291 && XINT (XEXP (operands[3], 0), 1) == UNSPEC_PLTOFF"
14294 ("lea{q}\t{%E1@tlsgd(%%rip), %%rdi|rdi, %E1@tlsgd[rip]}", operands);
14295 output_asm_insn ("movabs{q}\t{%3, %%rax|rax, %3}", operands);
14296 output_asm_insn ("add{q}\t{%2, %%rax|rax, %2}", operands);
14297 return "call\t{*%%rax|rax}";
14299 [(set_attr "type" "multi")
14300 (set_attr "length" "22")])
14302 (define_expand "tls_global_dynamic_64_<mode>"
14304 [(set (match_operand:P 0 "register_operand")
14306 (mem:QI (match_operand 2))
14308 (unspec:P [(match_operand 1 "tls_symbolic_operand")
14312 "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
14314 (define_insn "*tls_local_dynamic_base_32_gnu"
14315 [(set (match_operand:SI 0 "register_operand" "=a")
14317 [(match_operand:SI 1 "register_operand" "Yb")
14318 (match_operand 2 "constant_call_address_operand" "Bz")
14320 UNSPEC_TLS_LD_BASE))
14321 (clobber (match_scratch:SI 3 "=d"))
14322 (clobber (match_scratch:SI 4 "=c"))
14323 (clobber (reg:CC FLAGS_REG))]
14324 "!TARGET_64BIT && TARGET_GNU_TLS"
14327 ("lea{l}\t{%&@tlsldm(%1), %0|%0, %&@tlsldm[%1]}", operands);
14328 if (TARGET_SUN_TLS)
14330 if (HAVE_AS_IX86_TLSLDMPLT)
14331 return "call\t%&@tlsldmplt";
14333 return "call\t%p2@plt";
14335 if (flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT)
14336 return "call\t%P2";
14337 return "call\t{*%p2@GOT(%1)|[DWORD PTR %p2@GOT[%1]]}";
14339 [(set_attr "type" "multi")
14340 (set_attr "length" "11")])
14342 (define_expand "tls_local_dynamic_base_32"
14344 [(set (match_operand:SI 0 "register_operand")
14346 [(match_operand:SI 1 "register_operand")
14347 (match_operand 2 "constant_call_address_operand")
14349 UNSPEC_TLS_LD_BASE))
14350 (clobber (match_scratch:SI 3))
14351 (clobber (match_scratch:SI 4))
14352 (clobber (reg:CC FLAGS_REG))])]
14354 "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
14356 (define_insn "*tls_local_dynamic_base_64_<mode>"
14357 [(set (match_operand:P 0 "register_operand" "=a")
14359 (mem:QI (match_operand 1 "constant_call_address_operand" "Bz"))
14360 (match_operand 2)))
14361 (unspec:P [(reg:P SP_REG)] UNSPEC_TLS_LD_BASE)]
14365 ("lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}", operands);
14366 if (TARGET_SUN_TLS)
14367 return "call\t%p1@plt";
14368 if (flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT)
14369 return "call\t%P1";
14370 return "call\t{*%p1@GOTPCREL(%%rip)|[QWORD PTR %p1@GOTPCREL[rip]]}";
14372 [(set_attr "type" "multi")
14373 (set_attr "length" "12")])
14375 (define_insn "*tls_local_dynamic_base_64_largepic"
14376 [(set (match_operand:DI 0 "register_operand" "=a")
14378 (mem:QI (plus:DI (match_operand:DI 1 "register_operand" "b")
14379 (match_operand:DI 2 "immediate_operand" "i")))
14380 (match_operand 3)))
14381 (unspec:DI [(reg:DI SP_REG)] UNSPEC_TLS_LD_BASE)]
14382 "TARGET_64BIT && ix86_cmodel == CM_LARGE_PIC && !TARGET_PECOFF
14383 && GET_CODE (operands[2]) == CONST
14384 && GET_CODE (XEXP (operands[2], 0)) == UNSPEC
14385 && XINT (XEXP (operands[2], 0), 1) == UNSPEC_PLTOFF"
14388 ("lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}", operands);
14389 output_asm_insn ("movabs{q}\t{%2, %%rax|rax, %2}", operands);
14390 output_asm_insn ("add{q}\t{%1, %%rax|rax, %1}", operands);
14391 return "call\t{*%%rax|rax}";
14393 [(set_attr "type" "multi")
14394 (set_attr "length" "22")])
14396 (define_expand "tls_local_dynamic_base_64_<mode>"
14398 [(set (match_operand:P 0 "register_operand")
14400 (mem:QI (match_operand 1))
14402 (unspec:P [(reg:P SP_REG)] UNSPEC_TLS_LD_BASE)])]
14404 "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
14406 ;; Local dynamic of a single variable is a lose. Show combine how
14407 ;; to convert that back to global dynamic.
14409 (define_insn_and_split "*tls_local_dynamic_32_once"
14410 [(set (match_operand:SI 0 "register_operand" "=a")
14412 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14413 (match_operand 2 "constant_call_address_operand" "Bz")
14415 UNSPEC_TLS_LD_BASE)
14416 (const:SI (unspec:SI
14417 [(match_operand 3 "tls_symbolic_operand")]
14419 (clobber (match_scratch:SI 4 "=d"))
14420 (clobber (match_scratch:SI 5 "=c"))
14421 (clobber (reg:CC FLAGS_REG))]
14426 [(set (match_dup 0)
14427 (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)
14430 (clobber (match_dup 4))
14431 (clobber (match_dup 5))
14432 (clobber (reg:CC FLAGS_REG))])])
14434 ;; Load and add the thread base pointer from %<tp_seg>:0.
14435 (define_insn_and_split "*load_tp_<mode>"
14436 [(set (match_operand:PTR 0 "register_operand" "=r")
14437 (unspec:PTR [(const_int 0)] UNSPEC_TP))]
14441 [(set (match_dup 0)
14444 addr_space_t as = DEFAULT_TLS_SEG_REG;
14446 operands[1] = gen_const_mem (<MODE>mode, const0_rtx);
14447 set_mem_addr_space (operands[1], as);
14450 (define_insn_and_split "*load_tp_x32_zext"
14451 [(set (match_operand:DI 0 "register_operand" "=r")
14453 (unspec:SI [(const_int 0)] UNSPEC_TP)))]
14457 [(set (match_dup 0)
14458 (zero_extend:DI (match_dup 1)))]
14460 addr_space_t as = DEFAULT_TLS_SEG_REG;
14462 operands[1] = gen_const_mem (SImode, const0_rtx);
14463 set_mem_addr_space (operands[1], as);
14466 (define_insn_and_split "*add_tp_<mode>"
14467 [(set (match_operand:PTR 0 "register_operand" "=r")
14469 (unspec:PTR [(const_int 0)] UNSPEC_TP)
14470 (match_operand:PTR 1 "register_operand" "0")))
14471 (clobber (reg:CC FLAGS_REG))]
14476 [(set (match_dup 0)
14477 (plus:PTR (match_dup 1) (match_dup 2)))
14478 (clobber (reg:CC FLAGS_REG))])]
14480 addr_space_t as = DEFAULT_TLS_SEG_REG;
14482 operands[2] = gen_const_mem (<MODE>mode, const0_rtx);
14483 set_mem_addr_space (operands[2], as);
14486 (define_insn_and_split "*add_tp_x32_zext"
14487 [(set (match_operand:DI 0 "register_operand" "=r")
14489 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
14490 (match_operand:SI 1 "register_operand" "0"))))
14491 (clobber (reg:CC FLAGS_REG))]
14496 [(set (match_dup 0)
14498 (plus:SI (match_dup 1) (match_dup 2))))
14499 (clobber (reg:CC FLAGS_REG))])]
14501 addr_space_t as = DEFAULT_TLS_SEG_REG;
14503 operands[2] = gen_const_mem (SImode, const0_rtx);
14504 set_mem_addr_space (operands[2], as);
14507 ;; The Sun linker took the AMD64 TLS spec literally and can only handle
14508 ;; %rax as destination of the initial executable code sequence.
14509 (define_insn "tls_initial_exec_64_sun"
14510 [(set (match_operand:DI 0 "register_operand" "=a")
14512 [(match_operand 1 "tls_symbolic_operand")]
14513 UNSPEC_TLS_IE_SUN))
14514 (clobber (reg:CC FLAGS_REG))]
14515 "TARGET_64BIT && TARGET_SUN_TLS"
14518 ("mov{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}", operands);
14519 return "add{q}\t{%a1@gottpoff(%%rip), %0|%0, %a1@gottpoff[rip]}";
14521 [(set_attr "type" "multi")])
14523 ;; GNU2 TLS patterns can be split.
14525 (define_expand "tls_dynamic_gnu2_32"
14526 [(set (match_dup 3)
14527 (plus:SI (match_operand:SI 2 "register_operand")
14529 (unspec:SI [(match_operand 1 "tls_symbolic_operand")]
14532 [(set (match_operand:SI 0 "register_operand")
14533 (unspec:SI [(match_dup 1) (match_dup 3)
14534 (match_dup 2) (reg:SI SP_REG)]
14536 (clobber (reg:CC FLAGS_REG))])]
14537 "!TARGET_64BIT && TARGET_GNU2_TLS"
14539 operands[3] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
14540 ix86_tls_descriptor_calls_expanded_in_cfun = true;
14543 (define_insn "*tls_dynamic_gnu2_lea_32"
14544 [(set (match_operand:SI 0 "register_operand" "=r")
14545 (plus:SI (match_operand:SI 1 "register_operand" "b")
14547 (unspec:SI [(match_operand 2 "tls_symbolic_operand")]
14548 UNSPEC_TLSDESC))))]
14549 "!TARGET_64BIT && TARGET_GNU2_TLS"
14550 "lea{l}\t{%E2@TLSDESC(%1), %0|%0, %E2@TLSDESC[%1]}"
14551 [(set_attr "type" "lea")
14552 (set_attr "mode" "SI")
14553 (set_attr "length" "6")
14554 (set_attr "length_address" "4")])
14556 (define_insn "*tls_dynamic_gnu2_call_32"
14557 [(set (match_operand:SI 0 "register_operand" "=a")
14558 (unspec:SI [(match_operand 1 "tls_symbolic_operand")
14559 (match_operand:SI 2 "register_operand" "0")
14560 ;; we have to make sure %ebx still points to the GOT
14561 (match_operand:SI 3 "register_operand" "b")
14564 (clobber (reg:CC FLAGS_REG))]
14565 "!TARGET_64BIT && TARGET_GNU2_TLS"
14566 "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
14567 [(set_attr "type" "call")
14568 (set_attr "length" "2")
14569 (set_attr "length_address" "0")])
14571 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
14572 [(set (match_operand:SI 0 "register_operand" "=&a")
14574 (unspec:SI [(match_operand 3 "tls_modbase_operand")
14575 (match_operand:SI 4)
14576 (match_operand:SI 2 "register_operand" "b")
14579 (const:SI (unspec:SI
14580 [(match_operand 1 "tls_symbolic_operand")]
14582 (clobber (reg:CC FLAGS_REG))]
14583 "!TARGET_64BIT && TARGET_GNU2_TLS"
14586 [(set (match_dup 0) (match_dup 5))]
14588 operands[5] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
14589 emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
14592 (define_expand "tls_dynamic_gnu2_64"
14593 [(set (match_dup 2)
14594 (unspec:DI [(match_operand 1 "tls_symbolic_operand")]
14597 [(set (match_operand:DI 0 "register_operand")
14598 (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
14600 (clobber (reg:CC FLAGS_REG))])]
14601 "TARGET_64BIT && TARGET_GNU2_TLS"
14603 operands[2] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
14604 ix86_tls_descriptor_calls_expanded_in_cfun = true;
14607 (define_insn "*tls_dynamic_gnu2_lea_64"
14608 [(set (match_operand:DI 0 "register_operand" "=r")
14609 (unspec:DI [(match_operand 1 "tls_symbolic_operand")]
14611 "TARGET_64BIT && TARGET_GNU2_TLS"
14612 "lea{q}\t{%E1@TLSDESC(%%rip), %0|%0, %E1@TLSDESC[rip]}"
14613 [(set_attr "type" "lea")
14614 (set_attr "mode" "DI")
14615 (set_attr "length" "7")
14616 (set_attr "length_address" "4")])
14618 (define_insn "*tls_dynamic_gnu2_call_64"
14619 [(set (match_operand:DI 0 "register_operand" "=a")
14620 (unspec:DI [(match_operand 1 "tls_symbolic_operand")
14621 (match_operand:DI 2 "register_operand" "0")
14624 (clobber (reg:CC FLAGS_REG))]
14625 "TARGET_64BIT && TARGET_GNU2_TLS"
14626 "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
14627 [(set_attr "type" "call")
14628 (set_attr "length" "2")
14629 (set_attr "length_address" "0")])
14631 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
14632 [(set (match_operand:DI 0 "register_operand" "=&a")
14634 (unspec:DI [(match_operand 2 "tls_modbase_operand")
14635 (match_operand:DI 3)
14638 (const:DI (unspec:DI
14639 [(match_operand 1 "tls_symbolic_operand")]
14641 (clobber (reg:CC FLAGS_REG))]
14642 "TARGET_64BIT && TARGET_GNU2_TLS"
14645 [(set (match_dup 0) (match_dup 4))]
14647 operands[4] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
14648 emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
14652 [(match_operand 0 "tls_address_pattern")]
14653 "TARGET_TLS_DIRECT_SEG_REFS"
14655 "operands[0] = ix86_rewrite_tls_address (operands[0]);")
14658 ;; These patterns match the binary 387 instructions for addM3, subM3,
14659 ;; mulM3 and divM3. There are three patterns for each of DFmode and
14660 ;; SFmode. The first is the normal insn, the second the same insn but
14661 ;; with one operand a conversion, and the third the same insn but with
14662 ;; the other operand a conversion. The conversion may be SFmode or
14663 ;; SImode if the target mode DFmode, but only SImode if the target mode
14666 ;; Gcc is slightly more smart about handling normal two address instructions
14667 ;; so use special patterns for add and mull.
14669 (define_insn "*fop_<mode>_comm"
14670 [(set (match_operand:MODEF 0 "register_operand" "=f,x,v")
14671 (match_operator:MODEF 3 "binary_fp_operator"
14672 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,0,v")
14673 (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm,vm")]))]
14674 "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14675 || (TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)))
14676 && COMMUTATIVE_ARITH_P (operands[3])
14677 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
14678 "* return output_387_binary_op (insn, operands);"
14679 [(set (attr "type")
14680 (if_then_else (eq_attr "alternative" "1,2")
14681 (if_then_else (match_operand:MODEF 3 "mult_operator")
14682 (const_string "ssemul")
14683 (const_string "sseadd"))
14684 (if_then_else (match_operand:MODEF 3 "mult_operator")
14685 (const_string "fmul")
14686 (const_string "fop"))))
14687 (set_attr "isa" "*,noavx,avx")
14688 (set_attr "prefix" "orig,orig,vex")
14689 (set_attr "mode" "<MODE>")
14690 (set (attr "enabled")
14692 (match_test ("SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"))
14694 (eq_attr "alternative" "0")
14695 (symbol_ref "TARGET_MIX_SSE_I387
14696 && X87_ENABLE_ARITH (<MODE>mode)")
14697 (const_string "*"))
14699 (eq_attr "alternative" "0")
14700 (symbol_ref "true")
14701 (symbol_ref "false"))))])
14703 (define_insn "*rcpsf2_sse"
14704 [(set (match_operand:SF 0 "register_operand" "=x")
14705 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
14707 "TARGET_SSE && TARGET_SSE_MATH"
14708 "%vrcpss\t{%1, %d0|%d0, %1}"
14709 [(set_attr "type" "sse")
14710 (set_attr "atom_sse_attr" "rcp")
14711 (set_attr "btver2_sse_attr" "rcp")
14712 (set_attr "prefix" "maybe_vex")
14713 (set_attr "mode" "SF")])
14715 (define_insn "*fop_<mode>_1"
14716 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,v")
14717 (match_operator:MODEF 3 "binary_fp_operator"
14718 [(match_operand:MODEF 1
14719 "x87nonimm_ssenomem_operand" "0,fm,0,v")
14720 (match_operand:MODEF 2
14721 "nonimmediate_operand" "fm,0,xm,vm")]))]
14722 "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14723 || (TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)))
14724 && !COMMUTATIVE_ARITH_P (operands[3])
14725 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
14726 "* return output_387_binary_op (insn, operands);"
14727 [(set (attr "type")
14728 (if_then_else (eq_attr "alternative" "2,3")
14729 (if_then_else (match_operand:MODEF 3 "div_operator")
14730 (const_string "ssediv")
14731 (const_string "sseadd"))
14732 (if_then_else (match_operand:MODEF 3 "div_operator")
14733 (const_string "fdiv")
14734 (const_string "fop"))))
14735 (set_attr "isa" "*,*,noavx,avx")
14736 (set_attr "prefix" "orig,orig,orig,vex")
14737 (set_attr "mode" "<MODE>")
14738 (set (attr "enabled")
14740 (match_test ("SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"))
14742 (eq_attr "alternative" "0,1")
14743 (symbol_ref "TARGET_MIX_SSE_I387
14744 && X87_ENABLE_ARITH (<MODE>mode)")
14745 (const_string "*"))
14747 (eq_attr "alternative" "0,1")
14748 (symbol_ref "true")
14749 (symbol_ref "false"))))])
14751 ;; ??? Add SSE splitters for these!
14752 (define_insn "*fop_<MODEF:mode>_2_i387"
14753 [(set (match_operand:MODEF 0 "register_operand" "=f")
14754 (match_operator:MODEF 3 "binary_fp_operator"
14756 (match_operand:SWI24 1 "nonimmediate_operand" "m"))
14757 (match_operand:MODEF 2 "register_operand" "0")]))]
14758 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI24:MODE>mode)
14759 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
14760 && (TARGET_USE_<SWI24:MODE>MODE_FIOP
14761 || optimize_function_for_size_p (cfun))"
14762 "* return output_387_binary_op (insn, operands);"
14763 [(set (attr "type")
14764 (cond [(match_operand:MODEF 3 "mult_operator")
14765 (const_string "fmul")
14766 (match_operand:MODEF 3 "div_operator")
14767 (const_string "fdiv")
14769 (const_string "fop")))
14770 (set_attr "fp_int_src" "true")
14771 (set_attr "mode" "<SWI24:MODE>")])
14773 (define_insn "*fop_<MODEF:mode>_3_i387"
14774 [(set (match_operand:MODEF 0 "register_operand" "=f")
14775 (match_operator:MODEF 3 "binary_fp_operator"
14776 [(match_operand:MODEF 1 "register_operand" "0")
14778 (match_operand:SWI24 2 "nonimmediate_operand" "m"))]))]
14779 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI24:MODE>mode)
14780 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
14781 && (TARGET_USE_<SWI24:MODE>MODE_FIOP
14782 || optimize_function_for_size_p (cfun))"
14783 "* return output_387_binary_op (insn, operands);"
14784 [(set (attr "type")
14785 (cond [(match_operand:MODEF 3 "mult_operator")
14786 (const_string "fmul")
14787 (match_operand:MODEF 3 "div_operator")
14788 (const_string "fdiv")
14790 (const_string "fop")))
14791 (set_attr "fp_int_src" "true")
14792 (set_attr "mode" "<MODE>")])
14794 (define_insn "*fop_df_4_i387"
14795 [(set (match_operand:DF 0 "register_operand" "=f,f")
14796 (match_operator:DF 3 "binary_fp_operator"
14798 (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
14799 (match_operand:DF 2 "register_operand" "0,f")]))]
14800 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
14801 && !(SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
14802 "* return output_387_binary_op (insn, operands);"
14803 [(set (attr "type")
14804 (cond [(match_operand:DF 3 "mult_operator")
14805 (const_string "fmul")
14806 (match_operand:DF 3 "div_operator")
14807 (const_string "fdiv")
14809 (const_string "fop")))
14810 (set_attr "mode" "SF")])
14812 (define_insn "*fop_df_5_i387"
14813 [(set (match_operand:DF 0 "register_operand" "=f,f")
14814 (match_operator:DF 3 "binary_fp_operator"
14815 [(match_operand:DF 1 "register_operand" "0,f")
14817 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
14818 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
14819 && !(SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
14820 "* return output_387_binary_op (insn, operands);"
14821 [(set (attr "type")
14822 (cond [(match_operand:DF 3 "mult_operator")
14823 (const_string "fmul")
14824 (match_operand:DF 3 "div_operator")
14825 (const_string "fdiv")
14827 (const_string "fop")))
14828 (set_attr "mode" "SF")])
14830 (define_insn "*fop_df_6_i387"
14831 [(set (match_operand:DF 0 "register_operand" "=f,f")
14832 (match_operator:DF 3 "binary_fp_operator"
14834 (match_operand:SF 1 "register_operand" "0,f"))
14836 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
14837 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
14838 && !(SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
14839 "* return output_387_binary_op (insn, operands);"
14840 [(set (attr "type")
14841 (cond [(match_operand:DF 3 "mult_operator")
14842 (const_string "fmul")
14843 (match_operand:DF 3 "div_operator")
14844 (const_string "fdiv")
14846 (const_string "fop")))
14847 (set_attr "mode" "SF")])
14849 (define_insn "*fop_xf_comm_i387"
14850 [(set (match_operand:XF 0 "register_operand" "=f")
14851 (match_operator:XF 3 "binary_fp_operator"
14852 [(match_operand:XF 1 "register_operand" "%0")
14853 (match_operand:XF 2 "register_operand" "f")]))]
14855 && COMMUTATIVE_ARITH_P (operands[3])"
14856 "* return output_387_binary_op (insn, operands);"
14857 [(set (attr "type")
14858 (if_then_else (match_operand:XF 3 "mult_operator")
14859 (const_string "fmul")
14860 (const_string "fop")))
14861 (set_attr "mode" "XF")])
14863 (define_insn "*fop_xf_1_i387"
14864 [(set (match_operand:XF 0 "register_operand" "=f,f")
14865 (match_operator:XF 3 "binary_fp_operator"
14866 [(match_operand:XF 1 "register_operand" "0,f")
14867 (match_operand:XF 2 "register_operand" "f,0")]))]
14869 && !COMMUTATIVE_ARITH_P (operands[3])"
14870 "* return output_387_binary_op (insn, operands);"
14871 [(set (attr "type")
14872 (if_then_else (match_operand:XF 3 "div_operator")
14873 (const_string "fdiv")
14874 (const_string "fop")))
14875 (set_attr "mode" "XF")])
14877 (define_insn "*fop_xf_2_i387"
14878 [(set (match_operand:XF 0 "register_operand" "=f")
14879 (match_operator:XF 3 "binary_fp_operator"
14881 (match_operand:SWI24 1 "nonimmediate_operand" "m"))
14882 (match_operand:XF 2 "register_operand" "0")]))]
14884 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
14885 "* return output_387_binary_op (insn, operands);"
14886 [(set (attr "type")
14887 (cond [(match_operand:XF 3 "mult_operator")
14888 (const_string "fmul")
14889 (match_operand:XF 3 "div_operator")
14890 (const_string "fdiv")
14892 (const_string "fop")))
14893 (set_attr "fp_int_src" "true")
14894 (set_attr "mode" "<MODE>")])
14896 (define_insn "*fop_xf_3_i387"
14897 [(set (match_operand:XF 0 "register_operand" "=f")
14898 (match_operator:XF 3 "binary_fp_operator"
14899 [(match_operand:XF 1 "register_operand" "0")
14901 (match_operand:SWI24 2 "nonimmediate_operand" "m"))]))]
14903 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
14904 "* return output_387_binary_op (insn, operands);"
14905 [(set (attr "type")
14906 (cond [(match_operand:XF 3 "mult_operator")
14907 (const_string "fmul")
14908 (match_operand:XF 3 "div_operator")
14909 (const_string "fdiv")
14911 (const_string "fop")))
14912 (set_attr "fp_int_src" "true")
14913 (set_attr "mode" "<MODE>")])
14915 (define_insn "*fop_xf_4_i387"
14916 [(set (match_operand:XF 0 "register_operand" "=f,f")
14917 (match_operator:XF 3 "binary_fp_operator"
14919 (match_operand:MODEF 1 "nonimmediate_operand" "fm,0"))
14920 (match_operand:XF 2 "register_operand" "0,f")]))]
14922 "* return output_387_binary_op (insn, operands);"
14923 [(set (attr "type")
14924 (cond [(match_operand:XF 3 "mult_operator")
14925 (const_string "fmul")
14926 (match_operand:XF 3 "div_operator")
14927 (const_string "fdiv")
14929 (const_string "fop")))
14930 (set_attr "mode" "<MODE>")])
14932 (define_insn "*fop_xf_5_i387"
14933 [(set (match_operand:XF 0 "register_operand" "=f,f")
14934 (match_operator:XF 3 "binary_fp_operator"
14935 [(match_operand:XF 1 "register_operand" "0,f")
14937 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
14939 "* return output_387_binary_op (insn, operands);"
14940 [(set (attr "type")
14941 (cond [(match_operand:XF 3 "mult_operator")
14942 (const_string "fmul")
14943 (match_operand:XF 3 "div_operator")
14944 (const_string "fdiv")
14946 (const_string "fop")))
14947 (set_attr "mode" "<MODE>")])
14949 (define_insn "*fop_xf_6_i387"
14950 [(set (match_operand:XF 0 "register_operand" "=f,f")
14951 (match_operator:XF 3 "binary_fp_operator"
14953 (match_operand:MODEF 1 "register_operand" "0,f"))
14955 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
14957 "* return output_387_binary_op (insn, operands);"
14958 [(set (attr "type")
14959 (cond [(match_operand:XF 3 "mult_operator")
14960 (const_string "fmul")
14961 (match_operand:XF 3 "div_operator")
14962 (const_string "fdiv")
14964 (const_string "fop")))
14965 (set_attr "mode" "<MODE>")])
14967 ;; FPU special functions.
14969 ;; This pattern implements a no-op XFmode truncation for
14970 ;; all fancy i386 XFmode math functions.
14972 (define_insn "truncxf<mode>2_i387_noop_unspec"
14973 [(set (match_operand:MODEF 0 "register_operand" "=f")
14974 (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")]
14975 UNSPEC_TRUNC_NOOP))]
14976 "TARGET_USE_FANCY_MATH_387"
14977 "* return output_387_reg_move (insn, operands);"
14978 [(set_attr "type" "fmov")
14979 (set_attr "mode" "<MODE>")])
14981 (define_insn "sqrtxf2"
14982 [(set (match_operand:XF 0 "register_operand" "=f")
14983 (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
14984 "TARGET_USE_FANCY_MATH_387"
14986 [(set_attr "type" "fpspc")
14987 (set_attr "mode" "XF")
14988 (set_attr "athlon_decode" "direct")
14989 (set_attr "amdfam10_decode" "direct")
14990 (set_attr "bdver1_decode" "direct")])
14992 (define_insn "sqrt_extend<mode>xf2_i387"
14993 [(set (match_operand:XF 0 "register_operand" "=f")
14996 (match_operand:MODEF 1 "register_operand" "0"))))]
14997 "TARGET_USE_FANCY_MATH_387"
14999 [(set_attr "type" "fpspc")
15000 (set_attr "mode" "XF")
15001 (set_attr "athlon_decode" "direct")
15002 (set_attr "amdfam10_decode" "direct")
15003 (set_attr "bdver1_decode" "direct")])
15005 (define_insn "*rsqrtsf2_sse"
15006 [(set (match_operand:SF 0 "register_operand" "=x")
15007 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
15009 "TARGET_SSE && TARGET_SSE_MATH"
15010 "%vrsqrtss\t{%1, %d0|%d0, %1}"
15011 [(set_attr "type" "sse")
15012 (set_attr "atom_sse_attr" "rcp")
15013 (set_attr "btver2_sse_attr" "rcp")
15014 (set_attr "prefix" "maybe_vex")
15015 (set_attr "mode" "SF")])
15017 (define_expand "rsqrtsf2"
15018 [(set (match_operand:SF 0 "register_operand")
15019 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand")]
15021 "TARGET_SSE && TARGET_SSE_MATH"
15023 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
15027 (define_insn "*sqrt<mode>2_sse"
15028 [(set (match_operand:MODEF 0 "register_operand" "=v")
15030 (match_operand:MODEF 1 "nonimmediate_operand" "vm")))]
15031 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
15032 "%vsqrt<ssemodesuffix>\t{%1, %d0|%d0, %1}"
15033 [(set_attr "type" "sse")
15034 (set_attr "atom_sse_attr" "sqrt")
15035 (set_attr "btver2_sse_attr" "sqrt")
15036 (set_attr "prefix" "maybe_vex")
15037 (set_attr "mode" "<MODE>")
15038 (set_attr "athlon_decode" "*")
15039 (set_attr "amdfam10_decode" "*")
15040 (set_attr "bdver1_decode" "*")])
15042 (define_expand "sqrt<mode>2"
15043 [(set (match_operand:MODEF 0 "register_operand")
15045 (match_operand:MODEF 1 "nonimmediate_operand")))]
15046 "(TARGET_USE_FANCY_MATH_387 && X87_ENABLE_ARITH (<MODE>mode))
15047 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
15049 if (<MODE>mode == SFmode
15050 && TARGET_SSE && TARGET_SSE_MATH
15051 && TARGET_RECIP_SQRT
15052 && !optimize_function_for_size_p (cfun)
15053 && flag_finite_math_only && !flag_trapping_math
15054 && flag_unsafe_math_optimizations)
15056 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
15060 if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
15062 rtx op0 = gen_reg_rtx (XFmode);
15063 rtx op1 = force_reg (<MODE>mode, operands[1]);
15065 emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
15066 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
15071 (define_insn "fpremxf4_i387"
15072 [(set (match_operand:XF 0 "register_operand" "=f")
15073 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15074 (match_operand:XF 3 "register_operand" "1")]
15076 (set (match_operand:XF 1 "register_operand" "=u")
15077 (unspec:XF [(match_dup 2) (match_dup 3)]
15079 (set (reg:CCFP FPSR_REG)
15080 (unspec:CCFP [(match_dup 2) (match_dup 3)]
15082 "TARGET_USE_FANCY_MATH_387
15083 && flag_finite_math_only"
15085 [(set_attr "type" "fpspc")
15086 (set_attr "znver1_decode" "vector")
15087 (set_attr "mode" "XF")])
15089 (define_expand "fmodxf3"
15090 [(use (match_operand:XF 0 "register_operand"))
15091 (use (match_operand:XF 1 "general_operand"))
15092 (use (match_operand:XF 2 "general_operand"))]
15093 "TARGET_USE_FANCY_MATH_387
15094 && flag_finite_math_only"
15096 rtx_code_label *label = gen_label_rtx ();
15098 rtx op1 = gen_reg_rtx (XFmode);
15099 rtx op2 = gen_reg_rtx (XFmode);
15101 emit_move_insn (op2, operands[2]);
15102 emit_move_insn (op1, operands[1]);
15104 emit_label (label);
15105 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
15106 ix86_emit_fp_unordered_jump (label);
15107 LABEL_NUSES (label) = 1;
15109 emit_move_insn (operands[0], op1);
15113 (define_expand "fmod<mode>3"
15114 [(use (match_operand:MODEF 0 "register_operand"))
15115 (use (match_operand:MODEF 1 "general_operand"))
15116 (use (match_operand:MODEF 2 "general_operand"))]
15117 "TARGET_USE_FANCY_MATH_387
15118 && flag_finite_math_only"
15120 rtx (*gen_truncxf) (rtx, rtx);
15122 rtx_code_label *label = gen_label_rtx ();
15124 rtx op1 = gen_reg_rtx (XFmode);
15125 rtx op2 = gen_reg_rtx (XFmode);
15127 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
15128 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15130 emit_label (label);
15131 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
15132 ix86_emit_fp_unordered_jump (label);
15133 LABEL_NUSES (label) = 1;
15135 /* Truncate the result properly for strict SSE math. */
15136 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15137 && !TARGET_MIX_SSE_I387)
15138 gen_truncxf = gen_truncxf<mode>2;
15140 gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
15142 emit_insn (gen_truncxf (operands[0], op1));
15146 (define_insn "fprem1xf4_i387"
15147 [(set (match_operand:XF 0 "register_operand" "=f")
15148 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15149 (match_operand:XF 3 "register_operand" "1")]
15151 (set (match_operand:XF 1 "register_operand" "=u")
15152 (unspec:XF [(match_dup 2) (match_dup 3)]
15154 (set (reg:CCFP FPSR_REG)
15155 (unspec:CCFP [(match_dup 2) (match_dup 3)]
15157 "TARGET_USE_FANCY_MATH_387
15158 && flag_finite_math_only"
15160 [(set_attr "type" "fpspc")
15161 (set_attr "znver1_decode" "vector")
15162 (set_attr "mode" "XF")])
15164 (define_expand "remainderxf3"
15165 [(use (match_operand:XF 0 "register_operand"))
15166 (use (match_operand:XF 1 "general_operand"))
15167 (use (match_operand:XF 2 "general_operand"))]
15168 "TARGET_USE_FANCY_MATH_387
15169 && flag_finite_math_only"
15171 rtx_code_label *label = gen_label_rtx ();
15173 rtx op1 = gen_reg_rtx (XFmode);
15174 rtx op2 = gen_reg_rtx (XFmode);
15176 emit_move_insn (op2, operands[2]);
15177 emit_move_insn (op1, operands[1]);
15179 emit_label (label);
15180 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
15181 ix86_emit_fp_unordered_jump (label);
15182 LABEL_NUSES (label) = 1;
15184 emit_move_insn (operands[0], op1);
15188 (define_expand "remainder<mode>3"
15189 [(use (match_operand:MODEF 0 "register_operand"))
15190 (use (match_operand:MODEF 1 "general_operand"))
15191 (use (match_operand:MODEF 2 "general_operand"))]
15192 "TARGET_USE_FANCY_MATH_387
15193 && flag_finite_math_only"
15195 rtx (*gen_truncxf) (rtx, rtx);
15197 rtx_code_label *label = gen_label_rtx ();
15199 rtx op1 = gen_reg_rtx (XFmode);
15200 rtx op2 = gen_reg_rtx (XFmode);
15202 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
15203 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15205 emit_label (label);
15207 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
15208 ix86_emit_fp_unordered_jump (label);
15209 LABEL_NUSES (label) = 1;
15211 /* Truncate the result properly for strict SSE math. */
15212 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15213 && !TARGET_MIX_SSE_I387)
15214 gen_truncxf = gen_truncxf<mode>2;
15216 gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
15218 emit_insn (gen_truncxf (operands[0], op1));
15222 (define_int_iterator SINCOS
15226 (define_int_attr sincos
15227 [(UNSPEC_SIN "sin")
15228 (UNSPEC_COS "cos")])
15230 (define_insn "*<sincos>xf2_i387"
15231 [(set (match_operand:XF 0 "register_operand" "=f")
15232 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15234 "TARGET_USE_FANCY_MATH_387
15235 && flag_unsafe_math_optimizations"
15237 [(set_attr "type" "fpspc")
15238 (set_attr "znver1_decode" "vector")
15239 (set_attr "mode" "XF")])
15241 (define_insn "*<sincos>_extend<mode>xf2_i387"
15242 [(set (match_operand:XF 0 "register_operand" "=f")
15243 (unspec:XF [(float_extend:XF
15244 (match_operand:MODEF 1 "register_operand" "0"))]
15246 "TARGET_USE_FANCY_MATH_387
15247 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15248 || TARGET_MIX_SSE_I387)
15249 && flag_unsafe_math_optimizations"
15251 [(set_attr "type" "fpspc")
15252 (set_attr "znver1_decode" "vector")
15253 (set_attr "mode" "XF")])
15255 ;; When sincos pattern is defined, sin and cos builtin functions will be
15256 ;; expanded to sincos pattern with one of its outputs left unused.
15257 ;; CSE pass will figure out if two sincos patterns can be combined,
15258 ;; otherwise sincos pattern will be split back to sin or cos pattern,
15259 ;; depending on the unused output.
15261 (define_insn "sincosxf3"
15262 [(set (match_operand:XF 0 "register_operand" "=f")
15263 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15264 UNSPEC_SINCOS_COS))
15265 (set (match_operand:XF 1 "register_operand" "=u")
15266 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15267 "TARGET_USE_FANCY_MATH_387
15268 && flag_unsafe_math_optimizations"
15270 [(set_attr "type" "fpspc")
15271 (set_attr "znver1_decode" "vector")
15272 (set_attr "mode" "XF")])
15275 [(set (match_operand:XF 0 "register_operand")
15276 (unspec:XF [(match_operand:XF 2 "register_operand")]
15277 UNSPEC_SINCOS_COS))
15278 (set (match_operand:XF 1 "register_operand")
15279 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15280 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15281 && can_create_pseudo_p ()"
15282 [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))])
15285 [(set (match_operand:XF 0 "register_operand")
15286 (unspec:XF [(match_operand:XF 2 "register_operand")]
15287 UNSPEC_SINCOS_COS))
15288 (set (match_operand:XF 1 "register_operand")
15289 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15290 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15291 && can_create_pseudo_p ()"
15292 [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))])
15294 (define_insn "sincos_extend<mode>xf3_i387"
15295 [(set (match_operand:XF 0 "register_operand" "=f")
15296 (unspec:XF [(float_extend:XF
15297 (match_operand:MODEF 2 "register_operand" "0"))]
15298 UNSPEC_SINCOS_COS))
15299 (set (match_operand:XF 1 "register_operand" "=u")
15300 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
15301 "TARGET_USE_FANCY_MATH_387
15302 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15303 || TARGET_MIX_SSE_I387)
15304 && flag_unsafe_math_optimizations"
15306 [(set_attr "type" "fpspc")
15307 (set_attr "znver1_decode" "vector")
15308 (set_attr "mode" "XF")])
15311 [(set (match_operand:XF 0 "register_operand")
15312 (unspec:XF [(float_extend:XF
15313 (match_operand:MODEF 2 "register_operand"))]
15314 UNSPEC_SINCOS_COS))
15315 (set (match_operand:XF 1 "register_operand")
15316 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
15317 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15318 && can_create_pseudo_p ()"
15319 [(set (match_dup 1)
15320 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))])
15323 [(set (match_operand:XF 0 "register_operand")
15324 (unspec:XF [(float_extend:XF
15325 (match_operand:MODEF 2 "register_operand"))]
15326 UNSPEC_SINCOS_COS))
15327 (set (match_operand:XF 1 "register_operand")
15328 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
15329 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15330 && can_create_pseudo_p ()"
15331 [(set (match_dup 0)
15332 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))])
15334 (define_expand "sincos<mode>3"
15335 [(use (match_operand:MODEF 0 "register_operand"))
15336 (use (match_operand:MODEF 1 "register_operand"))
15337 (use (match_operand:MODEF 2 "register_operand"))]
15338 "TARGET_USE_FANCY_MATH_387
15339 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15340 || TARGET_MIX_SSE_I387)
15341 && flag_unsafe_math_optimizations"
15343 rtx op0 = gen_reg_rtx (XFmode);
15344 rtx op1 = gen_reg_rtx (XFmode);
15346 emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
15347 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15348 emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
15352 (define_insn "fptanxf4_i387"
15353 [(set (match_operand:XF 0 "register_operand" "=f")
15354 (match_operand:XF 3 "const_double_operand" "F"))
15355 (set (match_operand:XF 1 "register_operand" "=u")
15356 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15358 "TARGET_USE_FANCY_MATH_387
15359 && flag_unsafe_math_optimizations
15360 && standard_80387_constant_p (operands[3]) == 2"
15362 [(set_attr "type" "fpspc")
15363 (set_attr "znver1_decode" "vector")
15364 (set_attr "mode" "XF")])
15366 (define_insn "fptan_extend<mode>xf4_i387"
15367 [(set (match_operand:MODEF 0 "register_operand" "=f")
15368 (match_operand:MODEF 3 "const_double_operand" "F"))
15369 (set (match_operand:XF 1 "register_operand" "=u")
15370 (unspec:XF [(float_extend:XF
15371 (match_operand:MODEF 2 "register_operand" "0"))]
15373 "TARGET_USE_FANCY_MATH_387
15374 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15375 || TARGET_MIX_SSE_I387)
15376 && flag_unsafe_math_optimizations
15377 && standard_80387_constant_p (operands[3]) == 2"
15379 [(set_attr "type" "fpspc")
15380 (set_attr "znver1_decode" "vector")
15381 (set_attr "mode" "XF")])
15383 (define_expand "tanxf2"
15384 [(use (match_operand:XF 0 "register_operand"))
15385 (use (match_operand:XF 1 "register_operand"))]
15386 "TARGET_USE_FANCY_MATH_387
15387 && flag_unsafe_math_optimizations"
15389 rtx one = gen_reg_rtx (XFmode);
15390 rtx op2 = CONST1_RTX (XFmode); /* fld1 */
15392 emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2));
15396 (define_expand "tan<mode>2"
15397 [(use (match_operand:MODEF 0 "register_operand"))
15398 (use (match_operand:MODEF 1 "register_operand"))]
15399 "TARGET_USE_FANCY_MATH_387
15400 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15401 || TARGET_MIX_SSE_I387)
15402 && flag_unsafe_math_optimizations"
15404 rtx op0 = gen_reg_rtx (XFmode);
15406 rtx one = gen_reg_rtx (<MODE>mode);
15407 rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */
15409 emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
15410 operands[1], op2));
15411 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15415 (define_insn "*fpatanxf3_i387"
15416 [(set (match_operand:XF 0 "register_operand" "=f")
15417 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
15418 (match_operand:XF 2 "register_operand" "u")]
15420 (clobber (match_scratch:XF 3 "=2"))]
15421 "TARGET_USE_FANCY_MATH_387
15422 && flag_unsafe_math_optimizations"
15424 [(set_attr "type" "fpspc")
15425 (set_attr "znver1_decode" "vector")
15426 (set_attr "mode" "XF")])
15428 (define_insn "fpatan_extend<mode>xf3_i387"
15429 [(set (match_operand:XF 0 "register_operand" "=f")
15430 (unspec:XF [(float_extend:XF
15431 (match_operand:MODEF 1 "register_operand" "0"))
15433 (match_operand:MODEF 2 "register_operand" "u"))]
15435 (clobber (match_scratch:XF 3 "=2"))]
15436 "TARGET_USE_FANCY_MATH_387
15437 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15438 || TARGET_MIX_SSE_I387)
15439 && flag_unsafe_math_optimizations"
15441 [(set_attr "type" "fpspc")
15442 (set_attr "znver1_decode" "vector")
15443 (set_attr "mode" "XF")])
15445 (define_expand "atan2xf3"
15446 [(parallel [(set (match_operand:XF 0 "register_operand")
15447 (unspec:XF [(match_operand:XF 2 "register_operand")
15448 (match_operand:XF 1 "register_operand")]
15450 (clobber (match_scratch:XF 3))])]
15451 "TARGET_USE_FANCY_MATH_387
15452 && flag_unsafe_math_optimizations")
15454 (define_expand "atan2<mode>3"
15455 [(use (match_operand:MODEF 0 "register_operand"))
15456 (use (match_operand:MODEF 1 "register_operand"))
15457 (use (match_operand:MODEF 2 "register_operand"))]
15458 "TARGET_USE_FANCY_MATH_387
15459 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15460 || TARGET_MIX_SSE_I387)
15461 && flag_unsafe_math_optimizations"
15463 rtx op0 = gen_reg_rtx (XFmode);
15465 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
15466 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15470 (define_expand "atanxf2"
15471 [(parallel [(set (match_operand:XF 0 "register_operand")
15472 (unspec:XF [(match_dup 2)
15473 (match_operand:XF 1 "register_operand")]
15475 (clobber (match_scratch:XF 3))])]
15476 "TARGET_USE_FANCY_MATH_387
15477 && flag_unsafe_math_optimizations"
15479 operands[2] = gen_reg_rtx (XFmode);
15480 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
15483 (define_expand "atan<mode>2"
15484 [(use (match_operand:MODEF 0 "register_operand"))
15485 (use (match_operand:MODEF 1 "register_operand"))]
15486 "TARGET_USE_FANCY_MATH_387
15487 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15488 || TARGET_MIX_SSE_I387)
15489 && flag_unsafe_math_optimizations"
15491 rtx op0 = gen_reg_rtx (XFmode);
15493 rtx op2 = gen_reg_rtx (<MODE>mode);
15494 emit_move_insn (op2, CONST1_RTX (<MODE>mode)); /* fld1 */
15496 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1]));
15497 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15501 (define_expand "asinxf2"
15502 [(set (match_dup 2)
15503 (mult:XF (match_operand:XF 1 "register_operand")
15505 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
15506 (set (match_dup 5) (sqrt:XF (match_dup 4)))
15507 (parallel [(set (match_operand:XF 0 "register_operand")
15508 (unspec:XF [(match_dup 5) (match_dup 1)]
15510 (clobber (match_scratch:XF 6))])]
15511 "TARGET_USE_FANCY_MATH_387
15512 && flag_unsafe_math_optimizations"
15516 for (i = 2; i < 6; i++)
15517 operands[i] = gen_reg_rtx (XFmode);
15519 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
15522 (define_expand "asin<mode>2"
15523 [(use (match_operand:MODEF 0 "register_operand"))
15524 (use (match_operand:MODEF 1 "general_operand"))]
15525 "TARGET_USE_FANCY_MATH_387
15526 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15527 || TARGET_MIX_SSE_I387)
15528 && flag_unsafe_math_optimizations"
15530 rtx op0 = gen_reg_rtx (XFmode);
15531 rtx op1 = gen_reg_rtx (XFmode);
15533 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15534 emit_insn (gen_asinxf2 (op0, op1));
15535 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15539 (define_expand "acosxf2"
15540 [(set (match_dup 2)
15541 (mult:XF (match_operand:XF 1 "register_operand")
15543 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
15544 (set (match_dup 5) (sqrt:XF (match_dup 4)))
15545 (parallel [(set (match_operand:XF 0 "register_operand")
15546 (unspec:XF [(match_dup 1) (match_dup 5)]
15548 (clobber (match_scratch:XF 6))])]
15549 "TARGET_USE_FANCY_MATH_387
15550 && flag_unsafe_math_optimizations"
15554 for (i = 2; i < 6; i++)
15555 operands[i] = gen_reg_rtx (XFmode);
15557 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
15560 (define_expand "acos<mode>2"
15561 [(use (match_operand:MODEF 0 "register_operand"))
15562 (use (match_operand:MODEF 1 "general_operand"))]
15563 "TARGET_USE_FANCY_MATH_387
15564 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15565 || TARGET_MIX_SSE_I387)
15566 && flag_unsafe_math_optimizations"
15568 rtx op0 = gen_reg_rtx (XFmode);
15569 rtx op1 = gen_reg_rtx (XFmode);
15571 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15572 emit_insn (gen_acosxf2 (op0, op1));
15573 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15577 (define_insn "fyl2xxf3_i387"
15578 [(set (match_operand:XF 0 "register_operand" "=f")
15579 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
15580 (match_operand:XF 2 "register_operand" "u")]
15582 (clobber (match_scratch:XF 3 "=2"))]
15583 "TARGET_USE_FANCY_MATH_387
15584 && flag_unsafe_math_optimizations"
15586 [(set_attr "type" "fpspc")
15587 (set_attr "znver1_decode" "vector")
15588 (set_attr "mode" "XF")])
15590 (define_insn "fyl2x_extend<mode>xf3_i387"
15591 [(set (match_operand:XF 0 "register_operand" "=f")
15592 (unspec:XF [(float_extend:XF
15593 (match_operand:MODEF 1 "register_operand" "0"))
15594 (match_operand:XF 2 "register_operand" "u")]
15596 (clobber (match_scratch:XF 3 "=2"))]
15597 "TARGET_USE_FANCY_MATH_387
15598 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15599 || TARGET_MIX_SSE_I387)
15600 && flag_unsafe_math_optimizations"
15602 [(set_attr "type" "fpspc")
15603 (set_attr "znver1_decode" "vector")
15604 (set_attr "mode" "XF")])
15606 (define_expand "logxf2"
15607 [(parallel [(set (match_operand:XF 0 "register_operand")
15608 (unspec:XF [(match_operand:XF 1 "register_operand")
15609 (match_dup 2)] UNSPEC_FYL2X))
15610 (clobber (match_scratch:XF 3))])]
15611 "TARGET_USE_FANCY_MATH_387
15612 && flag_unsafe_math_optimizations"
15614 operands[2] = gen_reg_rtx (XFmode);
15615 emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */
15618 (define_expand "log<mode>2"
15619 [(use (match_operand:MODEF 0 "register_operand"))
15620 (use (match_operand:MODEF 1 "register_operand"))]
15621 "TARGET_USE_FANCY_MATH_387
15622 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15623 || TARGET_MIX_SSE_I387)
15624 && flag_unsafe_math_optimizations"
15626 rtx op0 = gen_reg_rtx (XFmode);
15628 rtx op2 = gen_reg_rtx (XFmode);
15629 emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */
15631 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
15632 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15636 (define_expand "log10xf2"
15637 [(parallel [(set (match_operand:XF 0 "register_operand")
15638 (unspec:XF [(match_operand:XF 1 "register_operand")
15639 (match_dup 2)] UNSPEC_FYL2X))
15640 (clobber (match_scratch:XF 3))])]
15641 "TARGET_USE_FANCY_MATH_387
15642 && flag_unsafe_math_optimizations"
15644 operands[2] = gen_reg_rtx (XFmode);
15645 emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
15648 (define_expand "log10<mode>2"
15649 [(use (match_operand:MODEF 0 "register_operand"))
15650 (use (match_operand:MODEF 1 "register_operand"))]
15651 "TARGET_USE_FANCY_MATH_387
15652 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15653 || TARGET_MIX_SSE_I387)
15654 && flag_unsafe_math_optimizations"
15656 rtx op0 = gen_reg_rtx (XFmode);
15658 rtx op2 = gen_reg_rtx (XFmode);
15659 emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */
15661 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
15662 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15666 (define_expand "log2xf2"
15667 [(parallel [(set (match_operand:XF 0 "register_operand")
15668 (unspec:XF [(match_operand:XF 1 "register_operand")
15669 (match_dup 2)] UNSPEC_FYL2X))
15670 (clobber (match_scratch:XF 3))])]
15671 "TARGET_USE_FANCY_MATH_387
15672 && flag_unsafe_math_optimizations"
15674 operands[2] = gen_reg_rtx (XFmode);
15675 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
15678 (define_expand "log2<mode>2"
15679 [(use (match_operand:MODEF 0 "register_operand"))
15680 (use (match_operand:MODEF 1 "register_operand"))]
15681 "TARGET_USE_FANCY_MATH_387
15682 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15683 || TARGET_MIX_SSE_I387)
15684 && flag_unsafe_math_optimizations"
15686 rtx op0 = gen_reg_rtx (XFmode);
15688 rtx op2 = gen_reg_rtx (XFmode);
15689 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
15691 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
15692 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15696 (define_insn "fyl2xp1xf3_i387"
15697 [(set (match_operand:XF 0 "register_operand" "=f")
15698 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
15699 (match_operand:XF 2 "register_operand" "u")]
15701 (clobber (match_scratch:XF 3 "=2"))]
15702 "TARGET_USE_FANCY_MATH_387
15703 && flag_unsafe_math_optimizations"
15705 [(set_attr "type" "fpspc")
15706 (set_attr "znver1_decode" "vector")
15707 (set_attr "mode" "XF")])
15709 (define_insn "fyl2xp1_extend<mode>xf3_i387"
15710 [(set (match_operand:XF 0 "register_operand" "=f")
15711 (unspec:XF [(float_extend:XF
15712 (match_operand:MODEF 1 "register_operand" "0"))
15713 (match_operand:XF 2 "register_operand" "u")]
15715 (clobber (match_scratch:XF 3 "=2"))]
15716 "TARGET_USE_FANCY_MATH_387
15717 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15718 || TARGET_MIX_SSE_I387)
15719 && flag_unsafe_math_optimizations"
15721 [(set_attr "type" "fpspc")
15722 (set_attr "znver1_decode" "vector")
15723 (set_attr "mode" "XF")])
15725 (define_expand "log1pxf2"
15726 [(use (match_operand:XF 0 "register_operand"))
15727 (use (match_operand:XF 1 "register_operand"))]
15728 "TARGET_USE_FANCY_MATH_387
15729 && flag_unsafe_math_optimizations"
15731 ix86_emit_i387_log1p (operands[0], operands[1]);
15735 (define_expand "log1p<mode>2"
15736 [(use (match_operand:MODEF 0 "register_operand"))
15737 (use (match_operand:MODEF 1 "register_operand"))]
15738 "TARGET_USE_FANCY_MATH_387
15739 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15740 || TARGET_MIX_SSE_I387)
15741 && flag_unsafe_math_optimizations"
15745 op0 = gen_reg_rtx (XFmode);
15747 operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
15749 ix86_emit_i387_log1p (op0, operands[1]);
15750 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15754 (define_insn "fxtractxf3_i387"
15755 [(set (match_operand:XF 0 "register_operand" "=f")
15756 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15757 UNSPEC_XTRACT_FRACT))
15758 (set (match_operand:XF 1 "register_operand" "=u")
15759 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
15760 "TARGET_USE_FANCY_MATH_387
15761 && flag_unsafe_math_optimizations"
15763 [(set_attr "type" "fpspc")
15764 (set_attr "znver1_decode" "vector")
15765 (set_attr "mode" "XF")])
15767 (define_insn "fxtract_extend<mode>xf3_i387"
15768 [(set (match_operand:XF 0 "register_operand" "=f")
15769 (unspec:XF [(float_extend:XF
15770 (match_operand:MODEF 2 "register_operand" "0"))]
15771 UNSPEC_XTRACT_FRACT))
15772 (set (match_operand:XF 1 "register_operand" "=u")
15773 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
15774 "TARGET_USE_FANCY_MATH_387
15775 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15776 || TARGET_MIX_SSE_I387)
15777 && flag_unsafe_math_optimizations"
15779 [(set_attr "type" "fpspc")
15780 (set_attr "znver1_decode" "vector")
15781 (set_attr "mode" "XF")])
15783 (define_expand "logbxf2"
15784 [(parallel [(set (match_dup 2)
15785 (unspec:XF [(match_operand:XF 1 "register_operand")]
15786 UNSPEC_XTRACT_FRACT))
15787 (set (match_operand:XF 0 "register_operand")
15788 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
15789 "TARGET_USE_FANCY_MATH_387
15790 && flag_unsafe_math_optimizations"
15791 "operands[2] = gen_reg_rtx (XFmode);")
15793 (define_expand "logb<mode>2"
15794 [(use (match_operand:MODEF 0 "register_operand"))
15795 (use (match_operand:MODEF 1 "register_operand"))]
15796 "TARGET_USE_FANCY_MATH_387
15797 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15798 || TARGET_MIX_SSE_I387)
15799 && flag_unsafe_math_optimizations"
15801 rtx op0 = gen_reg_rtx (XFmode);
15802 rtx op1 = gen_reg_rtx (XFmode);
15804 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
15805 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1));
15809 (define_expand "ilogbxf2"
15810 [(use (match_operand:SI 0 "register_operand"))
15811 (use (match_operand:XF 1 "register_operand"))]
15812 "TARGET_USE_FANCY_MATH_387
15813 && flag_unsafe_math_optimizations"
15817 if (optimize_insn_for_size_p ())
15820 op0 = gen_reg_rtx (XFmode);
15821 op1 = gen_reg_rtx (XFmode);
15823 emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
15824 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
15828 (define_expand "ilogb<mode>2"
15829 [(use (match_operand:SI 0 "register_operand"))
15830 (use (match_operand:MODEF 1 "register_operand"))]
15831 "TARGET_USE_FANCY_MATH_387
15832 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15833 || TARGET_MIX_SSE_I387)
15834 && flag_unsafe_math_optimizations"
15838 if (optimize_insn_for_size_p ())
15841 op0 = gen_reg_rtx (XFmode);
15842 op1 = gen_reg_rtx (XFmode);
15844 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
15845 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
15849 (define_insn "*f2xm1xf2_i387"
15850 [(set (match_operand:XF 0 "register_operand" "=f")
15851 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15853 "TARGET_USE_FANCY_MATH_387
15854 && flag_unsafe_math_optimizations"
15856 [(set_attr "type" "fpspc")
15857 (set_attr "znver1_decode" "vector")
15858 (set_attr "mode" "XF")])
15860 (define_insn "fscalexf4_i387"
15861 [(set (match_operand:XF 0 "register_operand" "=f")
15862 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15863 (match_operand:XF 3 "register_operand" "1")]
15864 UNSPEC_FSCALE_FRACT))
15865 (set (match_operand:XF 1 "register_operand" "=u")
15866 (unspec:XF [(match_dup 2) (match_dup 3)]
15867 UNSPEC_FSCALE_EXP))]
15868 "TARGET_USE_FANCY_MATH_387
15869 && flag_unsafe_math_optimizations"
15871 [(set_attr "type" "fpspc")
15872 (set_attr "znver1_decode" "vector")
15873 (set_attr "mode" "XF")])
15875 (define_expand "expNcorexf3"
15876 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand")
15877 (match_operand:XF 2 "register_operand")))
15878 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
15879 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
15880 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
15881 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
15882 (parallel [(set (match_operand:XF 0 "register_operand")
15883 (unspec:XF [(match_dup 8) (match_dup 4)]
15884 UNSPEC_FSCALE_FRACT))
15886 (unspec:XF [(match_dup 8) (match_dup 4)]
15887 UNSPEC_FSCALE_EXP))])]
15888 "TARGET_USE_FANCY_MATH_387
15889 && flag_unsafe_math_optimizations"
15893 for (i = 3; i < 10; i++)
15894 operands[i] = gen_reg_rtx (XFmode);
15896 emit_move_insn (operands[7], CONST1_RTX (XFmode)); /* fld1 */
15899 (define_expand "expxf2"
15900 [(use (match_operand:XF 0 "register_operand"))
15901 (use (match_operand:XF 1 "register_operand"))]
15902 "TARGET_USE_FANCY_MATH_387
15903 && flag_unsafe_math_optimizations"
15907 op2 = gen_reg_rtx (XFmode);
15908 emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */
15910 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
15914 (define_expand "exp<mode>2"
15915 [(use (match_operand:MODEF 0 "register_operand"))
15916 (use (match_operand:MODEF 1 "general_operand"))]
15917 "TARGET_USE_FANCY_MATH_387
15918 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15919 || TARGET_MIX_SSE_I387)
15920 && flag_unsafe_math_optimizations"
15924 op0 = gen_reg_rtx (XFmode);
15925 op1 = gen_reg_rtx (XFmode);
15927 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15928 emit_insn (gen_expxf2 (op0, op1));
15929 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15933 (define_expand "exp10xf2"
15934 [(use (match_operand:XF 0 "register_operand"))
15935 (use (match_operand:XF 1 "register_operand"))]
15936 "TARGET_USE_FANCY_MATH_387
15937 && flag_unsafe_math_optimizations"
15941 op2 = gen_reg_rtx (XFmode);
15942 emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */
15944 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
15948 (define_expand "exp10<mode>2"
15949 [(use (match_operand:MODEF 0 "register_operand"))
15950 (use (match_operand:MODEF 1 "general_operand"))]
15951 "TARGET_USE_FANCY_MATH_387
15952 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15953 || TARGET_MIX_SSE_I387)
15954 && flag_unsafe_math_optimizations"
15958 op0 = gen_reg_rtx (XFmode);
15959 op1 = gen_reg_rtx (XFmode);
15961 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15962 emit_insn (gen_exp10xf2 (op0, op1));
15963 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15967 (define_expand "exp2xf2"
15968 [(use (match_operand:XF 0 "register_operand"))
15969 (use (match_operand:XF 1 "register_operand"))]
15970 "TARGET_USE_FANCY_MATH_387
15971 && flag_unsafe_math_optimizations"
15975 op2 = gen_reg_rtx (XFmode);
15976 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
15978 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
15982 (define_expand "exp2<mode>2"
15983 [(use (match_operand:MODEF 0 "register_operand"))
15984 (use (match_operand:MODEF 1 "general_operand"))]
15985 "TARGET_USE_FANCY_MATH_387
15986 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15987 || TARGET_MIX_SSE_I387)
15988 && flag_unsafe_math_optimizations"
15992 op0 = gen_reg_rtx (XFmode);
15993 op1 = gen_reg_rtx (XFmode);
15995 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15996 emit_insn (gen_exp2xf2 (op0, op1));
15997 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16001 (define_expand "expm1xf2"
16002 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand")
16004 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16005 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16006 (set (match_dup 9) (float_extend:XF (match_dup 13)))
16007 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16008 (parallel [(set (match_dup 7)
16009 (unspec:XF [(match_dup 6) (match_dup 4)]
16010 UNSPEC_FSCALE_FRACT))
16012 (unspec:XF [(match_dup 6) (match_dup 4)]
16013 UNSPEC_FSCALE_EXP))])
16014 (parallel [(set (match_dup 10)
16015 (unspec:XF [(match_dup 9) (match_dup 8)]
16016 UNSPEC_FSCALE_FRACT))
16017 (set (match_dup 11)
16018 (unspec:XF [(match_dup 9) (match_dup 8)]
16019 UNSPEC_FSCALE_EXP))])
16020 (set (match_dup 12) (minus:XF (match_dup 10)
16021 (float_extend:XF (match_dup 13))))
16022 (set (match_operand:XF 0 "register_operand")
16023 (plus:XF (match_dup 12) (match_dup 7)))]
16024 "TARGET_USE_FANCY_MATH_387
16025 && flag_unsafe_math_optimizations"
16029 for (i = 2; i < 13; i++)
16030 operands[i] = gen_reg_rtx (XFmode);
16033 = validize_mem (force_const_mem (SFmode, CONST1_RTX (SFmode))); /* fld1 */
16035 emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
16038 (define_expand "expm1<mode>2"
16039 [(use (match_operand:MODEF 0 "register_operand"))
16040 (use (match_operand:MODEF 1 "general_operand"))]
16041 "TARGET_USE_FANCY_MATH_387
16042 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16043 || TARGET_MIX_SSE_I387)
16044 && flag_unsafe_math_optimizations"
16048 op0 = gen_reg_rtx (XFmode);
16049 op1 = gen_reg_rtx (XFmode);
16051 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16052 emit_insn (gen_expm1xf2 (op0, op1));
16053 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16057 (define_expand "ldexpxf3"
16058 [(match_operand:XF 0 "register_operand")
16059 (match_operand:XF 1 "register_operand")
16060 (match_operand:SI 2 "register_operand")]
16061 "TARGET_USE_FANCY_MATH_387
16062 && flag_unsafe_math_optimizations"
16066 tmp1 = gen_reg_rtx (XFmode);
16067 tmp2 = gen_reg_rtx (XFmode);
16069 emit_insn (gen_floatsixf2 (tmp1, operands[2]));
16070 emit_insn (gen_fscalexf4_i387 (operands[0], tmp2,
16071 operands[1], tmp1));
16075 (define_expand "ldexp<mode>3"
16076 [(use (match_operand:MODEF 0 "register_operand"))
16077 (use (match_operand:MODEF 1 "general_operand"))
16078 (use (match_operand:SI 2 "register_operand"))]
16079 "TARGET_USE_FANCY_MATH_387
16080 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16081 || TARGET_MIX_SSE_I387)
16082 && flag_unsafe_math_optimizations"
16086 op0 = gen_reg_rtx (XFmode);
16087 op1 = gen_reg_rtx (XFmode);
16089 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16090 emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
16091 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16095 (define_expand "scalbxf3"
16096 [(parallel [(set (match_operand:XF 0 " register_operand")
16097 (unspec:XF [(match_operand:XF 1 "register_operand")
16098 (match_operand:XF 2 "register_operand")]
16099 UNSPEC_FSCALE_FRACT))
16101 (unspec:XF [(match_dup 1) (match_dup 2)]
16102 UNSPEC_FSCALE_EXP))])]
16103 "TARGET_USE_FANCY_MATH_387
16104 && flag_unsafe_math_optimizations"
16106 operands[3] = gen_reg_rtx (XFmode);
16109 (define_expand "scalb<mode>3"
16110 [(use (match_operand:MODEF 0 "register_operand"))
16111 (use (match_operand:MODEF 1 "general_operand"))
16112 (use (match_operand:MODEF 2 "general_operand"))]
16113 "TARGET_USE_FANCY_MATH_387
16114 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16115 || TARGET_MIX_SSE_I387)
16116 && flag_unsafe_math_optimizations"
16120 op0 = gen_reg_rtx (XFmode);
16121 op1 = gen_reg_rtx (XFmode);
16122 op2 = gen_reg_rtx (XFmode);
16124 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16125 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
16126 emit_insn (gen_scalbxf3 (op0, op1, op2));
16127 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16131 (define_expand "significandxf2"
16132 [(parallel [(set (match_operand:XF 0 "register_operand")
16133 (unspec:XF [(match_operand:XF 1 "register_operand")]
16134 UNSPEC_XTRACT_FRACT))
16136 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
16137 "TARGET_USE_FANCY_MATH_387
16138 && flag_unsafe_math_optimizations"
16139 "operands[2] = gen_reg_rtx (XFmode);")
16141 (define_expand "significand<mode>2"
16142 [(use (match_operand:MODEF 0 "register_operand"))
16143 (use (match_operand:MODEF 1 "register_operand"))]
16144 "TARGET_USE_FANCY_MATH_387
16145 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16146 || TARGET_MIX_SSE_I387)
16147 && flag_unsafe_math_optimizations"
16149 rtx op0 = gen_reg_rtx (XFmode);
16150 rtx op1 = gen_reg_rtx (XFmode);
16152 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
16153 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16158 (define_insn "sse4_1_round<mode>2"
16159 [(set (match_operand:MODEF 0 "register_operand" "=x,v")
16160 (unspec:MODEF [(match_operand:MODEF 1 "register_operand" "x,v")
16161 (match_operand:SI 2 "const_0_to_15_operand" "n,n")]
16165 %vround<ssemodesuffix>\t{%2, %1, %d0|%d0, %1, %2}
16166 vrndscale<ssemodesuffix>\t{%2, %1, %d0|%d0, %1, %2}"
16167 [(set_attr "type" "ssecvt")
16168 (set_attr "prefix_extra" "1,*")
16169 (set_attr "length_immediate" "*,1")
16170 (set_attr "prefix" "maybe_vex,evex")
16171 (set_attr "isa" "noavx512f,avx512f")
16172 (set_attr "mode" "<MODE>")])
16174 (define_insn "rintxf2"
16175 [(set (match_operand:XF 0 "register_operand" "=f")
16176 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16178 "TARGET_USE_FANCY_MATH_387"
16180 [(set_attr "type" "fpspc")
16181 (set_attr "znver1_decode" "vector")
16182 (set_attr "mode" "XF")])
16184 (define_insn "rint<mode>2_frndint"
16185 [(set (match_operand:MODEF 0 "register_operand" "=f")
16186 (unspec:MODEF [(match_operand:MODEF 1 "register_operand" "0")]
16188 "TARGET_USE_FANCY_MATH_387"
16190 [(set_attr "type" "fpspc")
16191 (set_attr "znver1_decode" "vector")
16192 (set_attr "mode" "<MODE>")])
16194 (define_expand "rint<mode>2"
16195 [(use (match_operand:MODEF 0 "register_operand"))
16196 (use (match_operand:MODEF 1 "register_operand"))]
16197 "(TARGET_USE_FANCY_MATH_387
16198 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16199 || TARGET_MIX_SSE_I387))
16200 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
16202 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16205 emit_insn (gen_sse4_1_round<mode>2
16206 (operands[0], operands[1], GEN_INT (ROUND_MXCSR)));
16208 ix86_expand_rint (operands[0], operands[1]);
16211 emit_insn (gen_rint<mode>2_frndint (operands[0], operands[1]));
16215 (define_expand "round<mode>2"
16216 [(match_operand:X87MODEF 0 "register_operand")
16217 (match_operand:X87MODEF 1 "nonimmediate_operand")]
16218 "(TARGET_USE_FANCY_MATH_387
16219 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16220 || TARGET_MIX_SSE_I387)
16221 && flag_unsafe_math_optimizations)
16222 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16223 && !flag_trapping_math && !flag_rounding_math)"
16225 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16226 && !flag_trapping_math && !flag_rounding_math)
16230 operands[1] = force_reg (<MODE>mode, operands[1]);
16231 ix86_expand_round_sse4 (operands[0], operands[1]);
16233 else if (TARGET_64BIT || (<MODE>mode != DFmode))
16234 ix86_expand_round (operands[0], operands[1]);
16236 ix86_expand_rounddf_32 (operands[0], operands[1]);
16240 operands[1] = force_reg (<MODE>mode, operands[1]);
16241 ix86_emit_i387_round (operands[0], operands[1]);
16246 (define_insn_and_split "*fistdi2_1"
16247 [(set (match_operand:DI 0 "nonimmediate_operand")
16248 (unspec:DI [(match_operand:XF 1 "register_operand")]
16250 "TARGET_USE_FANCY_MATH_387
16251 && can_create_pseudo_p ()"
16256 if (memory_operand (operands[0], VOIDmode))
16257 emit_insn (gen_fistdi2 (operands[0], operands[1]));
16260 operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
16261 emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
16266 [(set_attr "type" "fpspc")
16267 (set_attr "mode" "DI")])
16269 (define_insn "fistdi2"
16270 [(set (match_operand:DI 0 "memory_operand" "=m")
16271 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
16273 (clobber (match_scratch:XF 2 "=&1f"))]
16274 "TARGET_USE_FANCY_MATH_387"
16275 "* return output_fix_trunc (insn, operands, false);"
16276 [(set_attr "type" "fpspc")
16277 (set_attr "mode" "DI")])
16279 (define_insn "fistdi2_with_temp"
16280 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
16281 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
16283 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))
16284 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
16285 "TARGET_USE_FANCY_MATH_387"
16287 [(set_attr "type" "fpspc")
16288 (set_attr "mode" "DI")])
16291 [(set (match_operand:DI 0 "register_operand")
16292 (unspec:DI [(match_operand:XF 1 "register_operand")]
16294 (clobber (match_operand:DI 2 "memory_operand"))
16295 (clobber (match_scratch 3))]
16297 [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
16298 (clobber (match_dup 3))])
16299 (set (match_dup 0) (match_dup 2))])
16302 [(set (match_operand:DI 0 "memory_operand")
16303 (unspec:DI [(match_operand:XF 1 "register_operand")]
16305 (clobber (match_operand:DI 2 "memory_operand"))
16306 (clobber (match_scratch 3))]
16308 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
16309 (clobber (match_dup 3))])])
16311 (define_insn_and_split "*fist<mode>2_1"
16312 [(set (match_operand:SWI24 0 "register_operand")
16313 (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
16315 "TARGET_USE_FANCY_MATH_387
16316 && can_create_pseudo_p ()"
16321 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
16322 emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
16326 [(set_attr "type" "fpspc")
16327 (set_attr "mode" "<MODE>")])
16329 (define_insn "fist<mode>2"
16330 [(set (match_operand:SWI24 0 "memory_operand" "=m")
16331 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
16333 "TARGET_USE_FANCY_MATH_387"
16334 "* return output_fix_trunc (insn, operands, false);"
16335 [(set_attr "type" "fpspc")
16336 (set_attr "mode" "<MODE>")])
16338 (define_insn "fist<mode>2_with_temp"
16339 [(set (match_operand:SWI24 0 "register_operand" "=r")
16340 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
16342 (clobber (match_operand:SWI24 2 "memory_operand" "=m"))]
16343 "TARGET_USE_FANCY_MATH_387"
16345 [(set_attr "type" "fpspc")
16346 (set_attr "mode" "<MODE>")])
16349 [(set (match_operand:SWI24 0 "register_operand")
16350 (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
16352 (clobber (match_operand:SWI24 2 "memory_operand"))]
16354 [(set (match_dup 2) (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST))
16355 (set (match_dup 0) (match_dup 2))])
16358 [(set (match_operand:SWI24 0 "memory_operand")
16359 (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
16361 (clobber (match_operand:SWI24 2 "memory_operand"))]
16363 [(set (match_dup 0) (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST))])
16365 (define_expand "lrintxf<mode>2"
16366 [(set (match_operand:SWI248x 0 "nonimmediate_operand")
16367 (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
16369 "TARGET_USE_FANCY_MATH_387")
16371 (define_expand "lrint<MODEF:mode><SWI48:mode>2"
16372 [(set (match_operand:SWI48 0 "nonimmediate_operand")
16373 (unspec:SWI48 [(match_operand:MODEF 1 "register_operand")]
16374 UNSPEC_FIX_NOTRUNC))]
16375 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH")
16377 (define_expand "lround<X87MODEF:mode><SWI248x:mode>2"
16378 [(match_operand:SWI248x 0 "nonimmediate_operand")
16379 (match_operand:X87MODEF 1 "register_operand")]
16380 "(TARGET_USE_FANCY_MATH_387
16381 && (!(SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
16382 || TARGET_MIX_SSE_I387)
16383 && flag_unsafe_math_optimizations)
16384 || (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
16385 && <SWI248x:MODE>mode != HImode
16386 && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT)
16387 && !flag_trapping_math && !flag_rounding_math)"
16389 if (optimize_insn_for_size_p ())
16392 if (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
16393 && <SWI248x:MODE>mode != HImode
16394 && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT)
16395 && !flag_trapping_math && !flag_rounding_math)
16396 ix86_expand_lround (operands[0], operands[1]);
16398 ix86_emit_i387_round (operands[0], operands[1]);
16402 (define_int_iterator FRNDINT_ROUNDING
16403 [UNSPEC_FRNDINT_FLOOR
16404 UNSPEC_FRNDINT_CEIL
16405 UNSPEC_FRNDINT_TRUNC])
16407 (define_int_iterator FIST_ROUNDING
16411 ;; Base name for define_insn
16412 (define_int_attr rounding_insn
16413 [(UNSPEC_FRNDINT_FLOOR "floor")
16414 (UNSPEC_FRNDINT_CEIL "ceil")
16415 (UNSPEC_FRNDINT_TRUNC "btrunc")
16416 (UNSPEC_FIST_FLOOR "floor")
16417 (UNSPEC_FIST_CEIL "ceil")])
16419 (define_int_attr rounding
16420 [(UNSPEC_FRNDINT_FLOOR "floor")
16421 (UNSPEC_FRNDINT_CEIL "ceil")
16422 (UNSPEC_FRNDINT_TRUNC "trunc")
16423 (UNSPEC_FIST_FLOOR "floor")
16424 (UNSPEC_FIST_CEIL "ceil")])
16426 (define_int_attr ROUNDING
16427 [(UNSPEC_FRNDINT_FLOOR "FLOOR")
16428 (UNSPEC_FRNDINT_CEIL "CEIL")
16429 (UNSPEC_FRNDINT_TRUNC "TRUNC")
16430 (UNSPEC_FIST_FLOOR "FLOOR")
16431 (UNSPEC_FIST_CEIL "CEIL")])
16433 ;; Rounding mode control word calculation could clobber FLAGS_REG.
16434 (define_insn_and_split "frndint<mode>2_<rounding>"
16435 [(set (match_operand:X87MODEF 0 "register_operand")
16436 (unspec:X87MODEF [(match_operand:X87MODEF 1 "register_operand")]
16438 (clobber (reg:CC FLAGS_REG))]
16439 "TARGET_USE_FANCY_MATH_387
16440 && (flag_fp_int_builtin_inexact || !flag_trapping_math)
16441 && can_create_pseudo_p ()"
16446 ix86_optimize_mode_switching[I387_<ROUNDING>] = 1;
16448 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
16449 operands[3] = assign_386_stack_local (HImode, SLOT_CW_<ROUNDING>);
16451 emit_insn (gen_frndint<mode>2_<rounding>_i387 (operands[0], operands[1],
16452 operands[2], operands[3]));
16455 [(set_attr "type" "frndint")
16456 (set_attr "i387_cw" "<rounding>")
16457 (set_attr "mode" "<MODE>")])
16459 (define_insn "frndint<mode>2_<rounding>_i387"
16460 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
16461 (unspec:X87MODEF [(match_operand:X87MODEF 1 "register_operand" "0")]
16463 (use (match_operand:HI 2 "memory_operand" "m"))
16464 (use (match_operand:HI 3 "memory_operand" "m"))]
16465 "TARGET_USE_FANCY_MATH_387
16466 && (flag_fp_int_builtin_inexact || !flag_trapping_math)"
16467 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
16468 [(set_attr "type" "frndint")
16469 (set_attr "i387_cw" "<rounding>")
16470 (set_attr "mode" "<MODE>")])
16472 (define_expand "<rounding_insn>xf2"
16473 [(parallel [(set (match_operand:XF 0 "register_operand")
16474 (unspec:XF [(match_operand:XF 1 "register_operand")]
16476 (clobber (reg:CC FLAGS_REG))])]
16477 "TARGET_USE_FANCY_MATH_387
16478 && (flag_fp_int_builtin_inexact || !flag_trapping_math)")
16480 (define_expand "<rounding_insn><mode>2"
16481 [(parallel [(set (match_operand:MODEF 0 "register_operand")
16482 (unspec:MODEF [(match_operand:MODEF 1 "register_operand")]
16484 (clobber (reg:CC FLAGS_REG))])]
16485 "(TARGET_USE_FANCY_MATH_387
16486 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16487 || TARGET_MIX_SSE_I387)
16488 && (flag_fp_int_builtin_inexact || !flag_trapping_math))
16489 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16490 && (TARGET_SSE4_1 || !flag_trapping_math
16491 || flag_fp_int_builtin_inexact))"
16493 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16494 && (TARGET_SSE4_1 || !flag_trapping_math || flag_fp_int_builtin_inexact))
16497 emit_insn (gen_sse4_1_round<mode>2
16498 (operands[0], operands[1], GEN_INT (ROUND_<ROUNDING>
16500 else if (TARGET_64BIT || (<MODE>mode != DFmode))
16502 if (ROUND_<ROUNDING> == ROUND_FLOOR)
16503 ix86_expand_floorceil (operands[0], operands[1], true);
16504 else if (ROUND_<ROUNDING> == ROUND_CEIL)
16505 ix86_expand_floorceil (operands[0], operands[1], false);
16506 else if (ROUND_<ROUNDING> == ROUND_TRUNC)
16507 ix86_expand_trunc (operands[0], operands[1]);
16509 gcc_unreachable ();
16513 if (ROUND_<ROUNDING> == ROUND_FLOOR)
16514 ix86_expand_floorceildf_32 (operands[0], operands[1], true);
16515 else if (ROUND_<ROUNDING> == ROUND_CEIL)
16516 ix86_expand_floorceildf_32 (operands[0], operands[1], false);
16517 else if (ROUND_<ROUNDING> == ROUND_TRUNC)
16518 ix86_expand_truncdf_32 (operands[0], operands[1]);
16520 gcc_unreachable ();
16524 emit_insn (gen_frndint<mode>2_<rounding> (operands[0], operands[1]));
16528 ;; Rounding mode control word calculation could clobber FLAGS_REG.
16529 (define_insn_and_split "frndintxf2_mask_pm"
16530 [(set (match_operand:XF 0 "register_operand")
16531 (unspec:XF [(match_operand:XF 1 "register_operand")]
16532 UNSPEC_FRNDINT_MASK_PM))
16533 (clobber (reg:CC FLAGS_REG))]
16534 "TARGET_USE_FANCY_MATH_387
16535 && flag_unsafe_math_optimizations
16536 && can_create_pseudo_p ()"
16541 ix86_optimize_mode_switching[I387_MASK_PM] = 1;
16543 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
16544 operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
16546 emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
16547 operands[2], operands[3]));
16550 [(set_attr "type" "frndint")
16551 (set_attr "i387_cw" "mask_pm")
16552 (set_attr "mode" "XF")])
16554 (define_insn "frndintxf2_mask_pm_i387"
16555 [(set (match_operand:XF 0 "register_operand" "=f")
16556 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16557 UNSPEC_FRNDINT_MASK_PM))
16558 (use (match_operand:HI 2 "memory_operand" "m"))
16559 (use (match_operand:HI 3 "memory_operand" "m"))]
16560 "TARGET_USE_FANCY_MATH_387
16561 && flag_unsafe_math_optimizations"
16562 "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
16563 [(set_attr "type" "frndint")
16564 (set_attr "i387_cw" "mask_pm")
16565 (set_attr "mode" "XF")])
16567 (define_expand "nearbyintxf2"
16568 [(parallel [(set (match_operand:XF 0 "register_operand")
16569 (unspec:XF [(match_operand:XF 1 "register_operand")]
16570 UNSPEC_FRNDINT_MASK_PM))
16571 (clobber (reg:CC FLAGS_REG))])]
16572 "TARGET_USE_FANCY_MATH_387
16573 && flag_unsafe_math_optimizations")
16575 (define_expand "nearbyint<mode>2"
16576 [(use (match_operand:MODEF 0 "register_operand"))
16577 (use (match_operand:MODEF 1 "register_operand"))]
16578 "TARGET_USE_FANCY_MATH_387
16579 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16580 || TARGET_MIX_SSE_I387)
16581 && flag_unsafe_math_optimizations"
16583 rtx op0 = gen_reg_rtx (XFmode);
16584 rtx op1 = gen_reg_rtx (XFmode);
16586 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16587 emit_insn (gen_frndintxf2_mask_pm (op0, op1));
16589 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16593 ;; Rounding mode control word calculation could clobber FLAGS_REG.
16594 (define_insn_and_split "*fist<mode>2_<rounding>_1"
16595 [(set (match_operand:SWI248x 0 "nonimmediate_operand")
16596 (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
16598 (clobber (reg:CC FLAGS_REG))]
16599 "TARGET_USE_FANCY_MATH_387
16600 && flag_unsafe_math_optimizations
16601 && can_create_pseudo_p ()"
16606 ix86_optimize_mode_switching[I387_<ROUNDING>] = 1;
16608 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
16609 operands[3] = assign_386_stack_local (HImode, SLOT_CW_<ROUNDING>);
16610 if (memory_operand (operands[0], VOIDmode))
16611 emit_insn (gen_fist<mode>2_<rounding> (operands[0], operands[1],
16612 operands[2], operands[3]));
16615 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
16616 emit_insn (gen_fist<mode>2_<rounding>_with_temp
16617 (operands[0], operands[1], operands[2],
16618 operands[3], operands[4]));
16622 [(set_attr "type" "fistp")
16623 (set_attr "i387_cw" "<rounding>")
16624 (set_attr "mode" "<MODE>")])
16626 (define_insn "fistdi2_<rounding>"
16627 [(set (match_operand:DI 0 "memory_operand" "=m")
16628 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
16630 (use (match_operand:HI 2 "memory_operand" "m"))
16631 (use (match_operand:HI 3 "memory_operand" "m"))
16632 (clobber (match_scratch:XF 4 "=&1f"))]
16633 "TARGET_USE_FANCY_MATH_387
16634 && flag_unsafe_math_optimizations"
16635 "* return output_fix_trunc (insn, operands, false);"
16636 [(set_attr "type" "fistp")
16637 (set_attr "i387_cw" "<rounding>")
16638 (set_attr "mode" "DI")])
16640 (define_insn "fistdi2_<rounding>_with_temp"
16641 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
16642 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
16644 (use (match_operand:HI 2 "memory_operand" "m,m"))
16645 (use (match_operand:HI 3 "memory_operand" "m,m"))
16646 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
16647 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
16648 "TARGET_USE_FANCY_MATH_387
16649 && flag_unsafe_math_optimizations"
16651 [(set_attr "type" "fistp")
16652 (set_attr "i387_cw" "<rounding>")
16653 (set_attr "mode" "DI")])
16656 [(set (match_operand:DI 0 "register_operand")
16657 (unspec:DI [(match_operand:XF 1 "register_operand")]
16659 (use (match_operand:HI 2 "memory_operand"))
16660 (use (match_operand:HI 3 "memory_operand"))
16661 (clobber (match_operand:DI 4 "memory_operand"))
16662 (clobber (match_scratch 5))]
16664 [(parallel [(set (match_dup 4)
16665 (unspec:DI [(match_dup 1)] FIST_ROUNDING))
16666 (use (match_dup 2))
16667 (use (match_dup 3))
16668 (clobber (match_dup 5))])
16669 (set (match_dup 0) (match_dup 4))])
16672 [(set (match_operand:DI 0 "memory_operand")
16673 (unspec:DI [(match_operand:XF 1 "register_operand")]
16675 (use (match_operand:HI 2 "memory_operand"))
16676 (use (match_operand:HI 3 "memory_operand"))
16677 (clobber (match_operand:DI 4 "memory_operand"))
16678 (clobber (match_scratch 5))]
16680 [(parallel [(set (match_dup 0)
16681 (unspec:DI [(match_dup 1)] FIST_ROUNDING))
16682 (use (match_dup 2))
16683 (use (match_dup 3))
16684 (clobber (match_dup 5))])])
16686 (define_insn "fist<mode>2_<rounding>"
16687 [(set (match_operand:SWI24 0 "memory_operand" "=m")
16688 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
16690 (use (match_operand:HI 2 "memory_operand" "m"))
16691 (use (match_operand:HI 3 "memory_operand" "m"))]
16692 "TARGET_USE_FANCY_MATH_387
16693 && flag_unsafe_math_optimizations"
16694 "* return output_fix_trunc (insn, operands, false);"
16695 [(set_attr "type" "fistp")
16696 (set_attr "i387_cw" "<rounding>")
16697 (set_attr "mode" "<MODE>")])
16699 (define_insn "fist<mode>2_<rounding>_with_temp"
16700 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
16701 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f,f")]
16703 (use (match_operand:HI 2 "memory_operand" "m,m"))
16704 (use (match_operand:HI 3 "memory_operand" "m,m"))
16705 (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
16706 "TARGET_USE_FANCY_MATH_387
16707 && flag_unsafe_math_optimizations"
16709 [(set_attr "type" "fistp")
16710 (set_attr "i387_cw" "<rounding>")
16711 (set_attr "mode" "<MODE>")])
16714 [(set (match_operand:SWI24 0 "register_operand")
16715 (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
16717 (use (match_operand:HI 2 "memory_operand"))
16718 (use (match_operand:HI 3 "memory_operand"))
16719 (clobber (match_operand:SWI24 4 "memory_operand"))]
16721 [(parallel [(set (match_dup 4)
16722 (unspec:SWI24 [(match_dup 1)] FIST_ROUNDING))
16723 (use (match_dup 2))
16724 (use (match_dup 3))])
16725 (set (match_dup 0) (match_dup 4))])
16728 [(set (match_operand:SWI24 0 "memory_operand")
16729 (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
16731 (use (match_operand:HI 2 "memory_operand"))
16732 (use (match_operand:HI 3 "memory_operand"))
16733 (clobber (match_operand:SWI24 4 "memory_operand"))]
16735 [(parallel [(set (match_dup 0)
16736 (unspec:SWI24 [(match_dup 1)] FIST_ROUNDING))
16737 (use (match_dup 2))
16738 (use (match_dup 3))])])
16740 (define_expand "l<rounding_insn>xf<mode>2"
16741 [(parallel [(set (match_operand:SWI248x 0 "nonimmediate_operand")
16742 (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
16744 (clobber (reg:CC FLAGS_REG))])]
16745 "TARGET_USE_FANCY_MATH_387
16746 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16747 && flag_unsafe_math_optimizations")
16749 (define_expand "l<rounding_insn><MODEF:mode><SWI48:mode>2"
16750 [(parallel [(set (match_operand:SWI48 0 "nonimmediate_operand")
16751 (unspec:SWI48 [(match_operand:MODEF 1 "register_operand")]
16753 (clobber (reg:CC FLAGS_REG))])]
16754 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
16755 && !flag_trapping_math"
16757 if (TARGET_64BIT && optimize_insn_for_size_p ())
16760 if (ROUND_<ROUNDING> == ROUND_FLOOR)
16761 ix86_expand_lfloorceil (operands[0], operands[1], true);
16762 else if (ROUND_<ROUNDING> == ROUND_CEIL)
16763 ix86_expand_lfloorceil (operands[0], operands[1], false);
16765 gcc_unreachable ();
16770 (define_insn "fxam<mode>2_i387"
16771 [(set (match_operand:HI 0 "register_operand" "=a")
16773 [(match_operand:X87MODEF 1 "register_operand" "f")]
16775 "TARGET_USE_FANCY_MATH_387"
16776 "fxam\n\tfnstsw\t%0"
16777 [(set_attr "type" "multi")
16778 (set_attr "length" "4")
16779 (set_attr "unit" "i387")
16780 (set_attr "mode" "<MODE>")])
16782 (define_insn_and_split "fxam<mode>2_i387_with_temp"
16783 [(set (match_operand:HI 0 "register_operand")
16785 [(match_operand:MODEF 1 "memory_operand")]
16787 "TARGET_USE_FANCY_MATH_387
16788 && can_create_pseudo_p ()"
16791 [(set (match_dup 2)(match_dup 1))
16793 (unspec:HI [(match_dup 2)] UNSPEC_FXAM))]
16795 operands[2] = gen_reg_rtx (<MODE>mode);
16797 MEM_VOLATILE_P (operands[1]) = 1;
16799 [(set_attr "type" "multi")
16800 (set_attr "unit" "i387")
16801 (set_attr "mode" "<MODE>")])
16803 (define_expand "isinfxf2"
16804 [(use (match_operand:SI 0 "register_operand"))
16805 (use (match_operand:XF 1 "register_operand"))]
16806 "TARGET_USE_FANCY_MATH_387
16807 && ix86_libc_has_function (function_c99_misc)"
16809 rtx mask = GEN_INT (0x45);
16810 rtx val = GEN_INT (0x05);
16812 rtx scratch = gen_reg_rtx (HImode);
16813 rtx res = gen_reg_rtx (QImode);
16815 emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
16817 emit_insn (gen_andqi_ext_1 (scratch, scratch, mask));
16818 emit_insn (gen_cmpqi_ext_3 (scratch, val));
16819 ix86_expand_setcc (res, EQ,
16820 gen_rtx_REG (CCmode, FLAGS_REG), const0_rtx);
16821 emit_insn (gen_zero_extendqisi2 (operands[0], res));
16825 (define_expand "isinf<mode>2"
16826 [(use (match_operand:SI 0 "register_operand"))
16827 (use (match_operand:MODEF 1 "nonimmediate_operand"))]
16828 "TARGET_USE_FANCY_MATH_387
16829 && ix86_libc_has_function (function_c99_misc)
16830 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
16832 rtx mask = GEN_INT (0x45);
16833 rtx val = GEN_INT (0x05);
16835 rtx scratch = gen_reg_rtx (HImode);
16836 rtx res = gen_reg_rtx (QImode);
16838 /* Remove excess precision by forcing value through memory. */
16839 if (memory_operand (operands[1], VOIDmode))
16840 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, operands[1]));
16843 rtx temp = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
16845 emit_move_insn (temp, operands[1]);
16846 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, temp));
16849 emit_insn (gen_andqi_ext_1 (scratch, scratch, mask));
16850 emit_insn (gen_cmpqi_ext_3 (scratch, val));
16851 ix86_expand_setcc (res, EQ,
16852 gen_rtx_REG (CCmode, FLAGS_REG), const0_rtx);
16853 emit_insn (gen_zero_extendqisi2 (operands[0], res));
16857 (define_expand "signbittf2"
16858 [(use (match_operand:SI 0 "register_operand"))
16859 (use (match_operand:TF 1 "register_operand"))]
16864 rtx mask = ix86_build_signbit_mask (TFmode, 0, 0);
16865 rtx scratch = gen_reg_rtx (QImode);
16867 emit_insn (gen_ptesttf2 (operands[1], mask));
16868 ix86_expand_setcc (scratch, NE,
16869 gen_rtx_REG (CCZmode, FLAGS_REG), const0_rtx);
16871 emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
16875 emit_insn (gen_sse_movmskps (operands[0],
16876 gen_lowpart (V4SFmode, operands[1])));
16877 emit_insn (gen_andsi3 (operands[0], operands[0], GEN_INT (0x8)));
16882 (define_expand "signbitxf2"
16883 [(use (match_operand:SI 0 "register_operand"))
16884 (use (match_operand:XF 1 "register_operand"))]
16885 "TARGET_USE_FANCY_MATH_387"
16887 rtx scratch = gen_reg_rtx (HImode);
16889 emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
16890 emit_insn (gen_andsi3 (operands[0],
16891 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
16895 (define_insn "movmsk_df"
16896 [(set (match_operand:SI 0 "register_operand" "=r")
16898 [(match_operand:DF 1 "register_operand" "x")]
16900 "SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH"
16901 "%vmovmskpd\t{%1, %0|%0, %1}"
16902 [(set_attr "type" "ssemov")
16903 (set_attr "prefix" "maybe_vex")
16904 (set_attr "mode" "DF")])
16906 ;; Use movmskpd in SSE mode to avoid store forwarding stall
16907 ;; for 32bit targets and movq+shrq sequence for 64bit targets.
16908 (define_expand "signbitdf2"
16909 [(use (match_operand:SI 0 "register_operand"))
16910 (use (match_operand:DF 1 "register_operand"))]
16911 "TARGET_USE_FANCY_MATH_387
16912 || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
16914 if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)
16916 emit_insn (gen_movmsk_df (operands[0], operands[1]));
16917 emit_insn (gen_andsi3 (operands[0], operands[0], const1_rtx));
16921 rtx scratch = gen_reg_rtx (HImode);
16923 emit_insn (gen_fxamdf2_i387 (scratch, operands[1]));
16924 emit_insn (gen_andsi3 (operands[0],
16925 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
16930 (define_expand "signbitsf2"
16931 [(use (match_operand:SI 0 "register_operand"))
16932 (use (match_operand:SF 1 "register_operand"))]
16933 "TARGET_USE_FANCY_MATH_387
16934 && !(SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH)"
16936 rtx scratch = gen_reg_rtx (HImode);
16938 emit_insn (gen_fxamsf2_i387 (scratch, operands[1]));
16939 emit_insn (gen_andsi3 (operands[0],
16940 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
16944 ;; Block operation instructions
16947 [(unspec_volatile [(const_int 0)] UNSPECV_CLD)]
16950 [(set_attr "length" "1")
16951 (set_attr "length_immediate" "0")
16952 (set_attr "modrm" "0")])
16954 (define_expand "movmem<mode>"
16955 [(use (match_operand:BLK 0 "memory_operand"))
16956 (use (match_operand:BLK 1 "memory_operand"))
16957 (use (match_operand:SWI48 2 "nonmemory_operand"))
16958 (use (match_operand:SWI48 3 "const_int_operand"))
16959 (use (match_operand:SI 4 "const_int_operand"))
16960 (use (match_operand:SI 5 "const_int_operand"))
16961 (use (match_operand:SI 6 ""))
16962 (use (match_operand:SI 7 ""))
16963 (use (match_operand:SI 8 ""))]
16966 if (ix86_expand_set_or_movmem (operands[0], operands[1],
16967 operands[2], NULL, operands[3],
16968 operands[4], operands[5],
16969 operands[6], operands[7],
16970 operands[8], false))
16976 ;; Most CPUs don't like single string operations
16977 ;; Handle this case here to simplify previous expander.
16979 (define_expand "strmov"
16980 [(set (match_dup 4) (match_operand 3 "memory_operand"))
16981 (set (match_operand 1 "memory_operand") (match_dup 4))
16982 (parallel [(set (match_operand 0 "register_operand") (match_dup 5))
16983 (clobber (reg:CC FLAGS_REG))])
16984 (parallel [(set (match_operand 2 "register_operand") (match_dup 6))
16985 (clobber (reg:CC FLAGS_REG))])]
16988 /* Can't use this for non-default address spaces. */
16989 if (!ADDR_SPACE_GENERIC_P (MEM_ADDR_SPACE (operands[3])))
16992 rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
16994 /* If .md ever supports :P for Pmode, these can be directly
16995 in the pattern above. */
16996 operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
16997 operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
16999 /* Can't use this if the user has appropriated esi or edi. */
17000 if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
17001 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG]))
17003 emit_insn (gen_strmov_singleop (operands[0], operands[1],
17004 operands[2], operands[3],
17005 operands[5], operands[6]));
17009 operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
17012 (define_expand "strmov_singleop"
17013 [(parallel [(set (match_operand 1 "memory_operand")
17014 (match_operand 3 "memory_operand"))
17015 (set (match_operand 0 "register_operand")
17017 (set (match_operand 2 "register_operand")
17018 (match_operand 5))])]
17022 ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
17025 (define_insn "*strmovdi_rex_1"
17026 [(set (mem:DI (match_operand:P 2 "register_operand" "0"))
17027 (mem:DI (match_operand:P 3 "register_operand" "1")))
17028 (set (match_operand:P 0 "register_operand" "=D")
17029 (plus:P (match_dup 2)
17031 (set (match_operand:P 1 "register_operand" "=S")
17032 (plus:P (match_dup 3)
17035 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG])
17036 && ix86_check_no_addr_space (insn)"
17038 [(set_attr "type" "str")
17039 (set_attr "memory" "both")
17040 (set_attr "mode" "DI")])
17042 (define_insn "*strmovsi_1"
17043 [(set (mem:SI (match_operand:P 2 "register_operand" "0"))
17044 (mem:SI (match_operand:P 3 "register_operand" "1")))
17045 (set (match_operand:P 0 "register_operand" "=D")
17046 (plus:P (match_dup 2)
17048 (set (match_operand:P 1 "register_operand" "=S")
17049 (plus:P (match_dup 3)
17051 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])
17052 && ix86_check_no_addr_space (insn)"
17054 [(set_attr "type" "str")
17055 (set_attr "memory" "both")
17056 (set_attr "mode" "SI")])
17058 (define_insn "*strmovhi_1"
17059 [(set (mem:HI (match_operand:P 2 "register_operand" "0"))
17060 (mem:HI (match_operand:P 3 "register_operand" "1")))
17061 (set (match_operand:P 0 "register_operand" "=D")
17062 (plus:P (match_dup 2)
17064 (set (match_operand:P 1 "register_operand" "=S")
17065 (plus:P (match_dup 3)
17067 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])
17068 && ix86_check_no_addr_space (insn)"
17070 [(set_attr "type" "str")
17071 (set_attr "memory" "both")
17072 (set_attr "mode" "HI")])
17074 (define_insn "*strmovqi_1"
17075 [(set (mem:QI (match_operand:P 2 "register_operand" "0"))
17076 (mem:QI (match_operand:P 3 "register_operand" "1")))
17077 (set (match_operand:P 0 "register_operand" "=D")
17078 (plus:P (match_dup 2)
17080 (set (match_operand:P 1 "register_operand" "=S")
17081 (plus:P (match_dup 3)
17083 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])
17084 && ix86_check_no_addr_space (insn)"
17086 [(set_attr "type" "str")
17087 (set_attr "memory" "both")
17088 (set (attr "prefix_rex")
17090 (match_test "<P:MODE>mode == DImode")
17092 (const_string "*")))
17093 (set_attr "mode" "QI")])
17095 (define_expand "rep_mov"
17096 [(parallel [(set (match_operand 4 "register_operand") (const_int 0))
17097 (set (match_operand 0 "register_operand")
17099 (set (match_operand 2 "register_operand")
17101 (set (match_operand 1 "memory_operand")
17102 (match_operand 3 "memory_operand"))
17103 (use (match_dup 4))])]
17107 ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
17110 (define_insn "*rep_movdi_rex64"
17111 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
17112 (set (match_operand:P 0 "register_operand" "=D")
17113 (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
17115 (match_operand:P 3 "register_operand" "0")))
17116 (set (match_operand:P 1 "register_operand" "=S")
17117 (plus:P (ashift:P (match_dup 5) (const_int 3))
17118 (match_operand:P 4 "register_operand" "1")))
17119 (set (mem:BLK (match_dup 3))
17120 (mem:BLK (match_dup 4)))
17121 (use (match_dup 5))]
17123 && !(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
17124 && ix86_check_no_addr_space (insn)"
17126 [(set_attr "type" "str")
17127 (set_attr "prefix_rep" "1")
17128 (set_attr "memory" "both")
17129 (set_attr "mode" "DI")])
17131 (define_insn "*rep_movsi"
17132 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
17133 (set (match_operand:P 0 "register_operand" "=D")
17134 (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
17136 (match_operand:P 3 "register_operand" "0")))
17137 (set (match_operand:P 1 "register_operand" "=S")
17138 (plus:P (ashift:P (match_dup 5) (const_int 2))
17139 (match_operand:P 4 "register_operand" "1")))
17140 (set (mem:BLK (match_dup 3))
17141 (mem:BLK (match_dup 4)))
17142 (use (match_dup 5))]
17143 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
17144 && ix86_check_no_addr_space (insn)"
17145 "%^rep{%;} movs{l|d}"
17146 [(set_attr "type" "str")
17147 (set_attr "prefix_rep" "1")
17148 (set_attr "memory" "both")
17149 (set_attr "mode" "SI")])
17151 (define_insn "*rep_movqi"
17152 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
17153 (set (match_operand:P 0 "register_operand" "=D")
17154 (plus:P (match_operand:P 3 "register_operand" "0")
17155 (match_operand:P 5 "register_operand" "2")))
17156 (set (match_operand:P 1 "register_operand" "=S")
17157 (plus:P (match_operand:P 4 "register_operand" "1") (match_dup 5)))
17158 (set (mem:BLK (match_dup 3))
17159 (mem:BLK (match_dup 4)))
17160 (use (match_dup 5))]
17161 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
17162 && ix86_check_no_addr_space (insn)"
17164 [(set_attr "type" "str")
17165 (set_attr "prefix_rep" "1")
17166 (set_attr "memory" "both")
17167 (set_attr "mode" "QI")])
17169 (define_expand "setmem<mode>"
17170 [(use (match_operand:BLK 0 "memory_operand"))
17171 (use (match_operand:SWI48 1 "nonmemory_operand"))
17172 (use (match_operand:QI 2 "nonmemory_operand"))
17173 (use (match_operand 3 "const_int_operand"))
17174 (use (match_operand:SI 4 "const_int_operand"))
17175 (use (match_operand:SI 5 "const_int_operand"))
17176 (use (match_operand:SI 6 ""))
17177 (use (match_operand:SI 7 ""))
17178 (use (match_operand:SI 8 ""))]
17181 if (ix86_expand_set_or_movmem (operands[0], NULL,
17182 operands[1], operands[2],
17183 operands[3], operands[4],
17184 operands[5], operands[6],
17185 operands[7], operands[8], true))
17191 ;; Most CPUs don't like single string operations
17192 ;; Handle this case here to simplify previous expander.
17194 (define_expand "strset"
17195 [(set (match_operand 1 "memory_operand")
17196 (match_operand 2 "register_operand"))
17197 (parallel [(set (match_operand 0 "register_operand")
17199 (clobber (reg:CC FLAGS_REG))])]
17202 /* Can't use this for non-default address spaces. */
17203 if (!ADDR_SPACE_GENERIC_P (MEM_ADDR_SPACE (operands[1])))
17206 if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
17207 operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
17209 /* If .md ever supports :P for Pmode, this can be directly
17210 in the pattern above. */
17211 operands[3] = gen_rtx_PLUS (Pmode, operands[0],
17212 GEN_INT (GET_MODE_SIZE (GET_MODE
17214 /* Can't use this if the user has appropriated eax or edi. */
17215 if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
17216 && !(fixed_regs[AX_REG] || fixed_regs[DI_REG]))
17218 emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
17224 (define_expand "strset_singleop"
17225 [(parallel [(set (match_operand 1 "memory_operand")
17226 (match_operand 2 "register_operand"))
17227 (set (match_operand 0 "register_operand")
17229 (unspec [(const_int 0)] UNSPEC_STOS)])]
17233 ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
17236 (define_insn "*strsetdi_rex_1"
17237 [(set (mem:DI (match_operand:P 1 "register_operand" "0"))
17238 (match_operand:DI 2 "register_operand" "a"))
17239 (set (match_operand:P 0 "register_operand" "=D")
17240 (plus:P (match_dup 1)
17242 (unspec [(const_int 0)] UNSPEC_STOS)]
17244 && !(fixed_regs[AX_REG] || fixed_regs[DI_REG])
17245 && ix86_check_no_addr_space (insn)"
17247 [(set_attr "type" "str")
17248 (set_attr "memory" "store")
17249 (set_attr "mode" "DI")])
17251 (define_insn "*strsetsi_1"
17252 [(set (mem:SI (match_operand:P 1 "register_operand" "0"))
17253 (match_operand:SI 2 "register_operand" "a"))
17254 (set (match_operand:P 0 "register_operand" "=D")
17255 (plus:P (match_dup 1)
17257 (unspec [(const_int 0)] UNSPEC_STOS)]
17258 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])
17259 && ix86_check_no_addr_space (insn)"
17261 [(set_attr "type" "str")
17262 (set_attr "memory" "store")
17263 (set_attr "mode" "SI")])
17265 (define_insn "*strsethi_1"
17266 [(set (mem:HI (match_operand:P 1 "register_operand" "0"))
17267 (match_operand:HI 2 "register_operand" "a"))
17268 (set (match_operand:P 0 "register_operand" "=D")
17269 (plus:P (match_dup 1)
17271 (unspec [(const_int 0)] UNSPEC_STOS)]
17272 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])
17273 && ix86_check_no_addr_space (insn)"
17275 [(set_attr "type" "str")
17276 (set_attr "memory" "store")
17277 (set_attr "mode" "HI")])
17279 (define_insn "*strsetqi_1"
17280 [(set (mem:QI (match_operand:P 1 "register_operand" "0"))
17281 (match_operand:QI 2 "register_operand" "a"))
17282 (set (match_operand:P 0 "register_operand" "=D")
17283 (plus:P (match_dup 1)
17285 (unspec [(const_int 0)] UNSPEC_STOS)]
17286 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])
17287 && ix86_check_no_addr_space (insn)"
17289 [(set_attr "type" "str")
17290 (set_attr "memory" "store")
17291 (set (attr "prefix_rex")
17293 (match_test "<P:MODE>mode == DImode")
17295 (const_string "*")))
17296 (set_attr "mode" "QI")])
17298 (define_expand "rep_stos"
17299 [(parallel [(set (match_operand 1 "register_operand") (const_int 0))
17300 (set (match_operand 0 "register_operand")
17302 (set (match_operand 2 "memory_operand") (const_int 0))
17303 (use (match_operand 3 "register_operand"))
17304 (use (match_dup 1))])]
17308 ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
17311 (define_insn "*rep_stosdi_rex64"
17312 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
17313 (set (match_operand:P 0 "register_operand" "=D")
17314 (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
17316 (match_operand:P 3 "register_operand" "0")))
17317 (set (mem:BLK (match_dup 3))
17319 (use (match_operand:DI 2 "register_operand" "a"))
17320 (use (match_dup 4))]
17322 && !(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])
17323 && ix86_check_no_addr_space (insn)"
17325 [(set_attr "type" "str")
17326 (set_attr "prefix_rep" "1")
17327 (set_attr "memory" "store")
17328 (set_attr "mode" "DI")])
17330 (define_insn "*rep_stossi"
17331 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
17332 (set (match_operand:P 0 "register_operand" "=D")
17333 (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
17335 (match_operand:P 3 "register_operand" "0")))
17336 (set (mem:BLK (match_dup 3))
17338 (use (match_operand:SI 2 "register_operand" "a"))
17339 (use (match_dup 4))]
17340 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])
17341 && ix86_check_no_addr_space (insn)"
17342 "%^rep{%;} stos{l|d}"
17343 [(set_attr "type" "str")
17344 (set_attr "prefix_rep" "1")
17345 (set_attr "memory" "store")
17346 (set_attr "mode" "SI")])
17348 (define_insn "*rep_stosqi"
17349 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
17350 (set (match_operand:P 0 "register_operand" "=D")
17351 (plus:P (match_operand:P 3 "register_operand" "0")
17352 (match_operand:P 4 "register_operand" "1")))
17353 (set (mem:BLK (match_dup 3))
17355 (use (match_operand:QI 2 "register_operand" "a"))
17356 (use (match_dup 4))]
17357 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])
17358 && ix86_check_no_addr_space (insn)"
17360 [(set_attr "type" "str")
17361 (set_attr "prefix_rep" "1")
17362 (set_attr "memory" "store")
17363 (set (attr "prefix_rex")
17365 (match_test "<P:MODE>mode == DImode")
17367 (const_string "*")))
17368 (set_attr "mode" "QI")])
17370 (define_expand "cmpstrnsi"
17371 [(set (match_operand:SI 0 "register_operand")
17372 (compare:SI (match_operand:BLK 1 "general_operand")
17373 (match_operand:BLK 2 "general_operand")))
17374 (use (match_operand 3 "general_operand"))
17375 (use (match_operand 4 "immediate_operand"))]
17378 rtx addr1, addr2, out, outlow, count, countreg, align;
17380 if (optimize_insn_for_size_p () && !TARGET_INLINE_ALL_STRINGOPS)
17383 /* Can't use this if the user has appropriated ecx, esi or edi. */
17384 if (fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
17387 /* One of the strings must be a constant. If so, expand_builtin_strncmp()
17388 will have rewritten the length arg to be the minimum of the const string
17389 length and the actual length arg. If both strings are the same and
17390 shorter than the length arg, repz cmpsb will not stop at the 0 byte and
17391 will incorrectly base the results on chars past the 0 byte. */
17392 tree t1 = MEM_EXPR (operands[1]);
17393 tree t2 = MEM_EXPR (operands[2]);
17394 if (!((t1 && TREE_CODE (t1) == MEM_REF
17395 && TREE_CODE (TREE_OPERAND (t1, 0)) == ADDR_EXPR
17396 && TREE_CODE (TREE_OPERAND (TREE_OPERAND (t1, 0), 0)) == STRING_CST)
17397 || (t2 && TREE_CODE (t2) == MEM_REF
17398 && TREE_CODE (TREE_OPERAND (t2, 0)) == ADDR_EXPR
17399 && TREE_CODE (TREE_OPERAND (TREE_OPERAND (t2, 0), 0)) == STRING_CST)))
17404 out = gen_reg_rtx (SImode);
17406 addr1 = copy_addr_to_reg (XEXP (operands[1], 0));
17407 addr2 = copy_addr_to_reg (XEXP (operands[2], 0));
17408 if (addr1 != XEXP (operands[1], 0))
17409 operands[1] = replace_equiv_address_nv (operands[1], addr1);
17410 if (addr2 != XEXP (operands[2], 0))
17411 operands[2] = replace_equiv_address_nv (operands[2], addr2);
17413 count = operands[3];
17414 countreg = ix86_zero_extend_to_Pmode (count);
17416 /* %%% Iff we are testing strict equality, we can use known alignment
17417 to good advantage. This may be possible with combine, particularly
17418 once cc0 is dead. */
17419 align = operands[4];
17421 if (CONST_INT_P (count))
17423 if (INTVAL (count) == 0)
17425 emit_move_insn (operands[0], const0_rtx);
17428 emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
17429 operands[1], operands[2]));
17433 rtx (*gen_cmp) (rtx, rtx);
17435 gen_cmp = (TARGET_64BIT
17436 ? gen_cmpdi_1 : gen_cmpsi_1);
17438 emit_insn (gen_cmp (countreg, countreg));
17439 emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
17440 operands[1], operands[2]));
17443 outlow = gen_lowpart (QImode, out);
17444 emit_insn (gen_cmpintqi (outlow));
17445 emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
17447 if (operands[0] != out)
17448 emit_move_insn (operands[0], out);
17453 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
17455 (define_expand "cmpintqi"
17456 [(set (match_dup 1)
17457 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
17459 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
17460 (parallel [(set (match_operand:QI 0 "register_operand")
17461 (minus:QI (match_dup 1)
17463 (clobber (reg:CC FLAGS_REG))])]
17466 operands[1] = gen_reg_rtx (QImode);
17467 operands[2] = gen_reg_rtx (QImode);
17470 ;; memcmp recognizers. The `cmpsb' opcode does nothing if the count is
17471 ;; zero. Emit extra code to make sure that a zero-length compare is EQ.
17473 (define_expand "cmpstrnqi_nz_1"
17474 [(parallel [(set (reg:CC FLAGS_REG)
17475 (compare:CC (match_operand 4 "memory_operand")
17476 (match_operand 5 "memory_operand")))
17477 (use (match_operand 2 "register_operand"))
17478 (use (match_operand:SI 3 "immediate_operand"))
17479 (clobber (match_operand 0 "register_operand"))
17480 (clobber (match_operand 1 "register_operand"))
17481 (clobber (match_dup 2))])]
17485 ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
17488 (define_insn "*cmpstrnqi_nz_1"
17489 [(set (reg:CC FLAGS_REG)
17490 (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
17491 (mem:BLK (match_operand:P 5 "register_operand" "1"))))
17492 (use (match_operand:P 6 "register_operand" "2"))
17493 (use (match_operand:SI 3 "immediate_operand" "i"))
17494 (clobber (match_operand:P 0 "register_operand" "=S"))
17495 (clobber (match_operand:P 1 "register_operand" "=D"))
17496 (clobber (match_operand:P 2 "register_operand" "=c"))]
17497 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
17498 && ix86_check_no_addr_space (insn)"
17500 [(set_attr "type" "str")
17501 (set_attr "mode" "QI")
17502 (set (attr "prefix_rex")
17504 (match_test "<P:MODE>mode == DImode")
17506 (const_string "*")))
17507 (set_attr "prefix_rep" "1")])
17509 ;; The same, but the count is not known to not be zero.
17511 (define_expand "cmpstrnqi_1"
17512 [(parallel [(set (reg:CC FLAGS_REG)
17513 (if_then_else:CC (ne (match_operand 2 "register_operand")
17515 (compare:CC (match_operand 4 "memory_operand")
17516 (match_operand 5 "memory_operand"))
17518 (use (match_operand:SI 3 "immediate_operand"))
17519 (use (reg:CC FLAGS_REG))
17520 (clobber (match_operand 0 "register_operand"))
17521 (clobber (match_operand 1 "register_operand"))
17522 (clobber (match_dup 2))])]
17526 ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
17529 (define_insn "*cmpstrnqi_1"
17530 [(set (reg:CC FLAGS_REG)
17531 (if_then_else:CC (ne (match_operand:P 6 "register_operand" "2")
17533 (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
17534 (mem:BLK (match_operand:P 5 "register_operand" "1")))
17536 (use (match_operand:SI 3 "immediate_operand" "i"))
17537 (use (reg:CC FLAGS_REG))
17538 (clobber (match_operand:P 0 "register_operand" "=S"))
17539 (clobber (match_operand:P 1 "register_operand" "=D"))
17540 (clobber (match_operand:P 2 "register_operand" "=c"))]
17541 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
17542 && ix86_check_no_addr_space (insn)"
17544 [(set_attr "type" "str")
17545 (set_attr "mode" "QI")
17546 (set (attr "prefix_rex")
17548 (match_test "<P:MODE>mode == DImode")
17550 (const_string "*")))
17551 (set_attr "prefix_rep" "1")])
17553 (define_expand "strlen<mode>"
17554 [(set (match_operand:P 0 "register_operand")
17555 (unspec:P [(match_operand:BLK 1 "general_operand")
17556 (match_operand:QI 2 "immediate_operand")
17557 (match_operand 3 "immediate_operand")]
17561 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
17567 (define_expand "strlenqi_1"
17568 [(parallel [(set (match_operand 0 "register_operand")
17570 (clobber (match_operand 1 "register_operand"))
17571 (clobber (reg:CC FLAGS_REG))])]
17575 ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
17578 (define_insn "*strlenqi_1"
17579 [(set (match_operand:P 0 "register_operand" "=&c")
17580 (unspec:P [(mem:BLK (match_operand:P 5 "register_operand" "1"))
17581 (match_operand:QI 2 "register_operand" "a")
17582 (match_operand:P 3 "immediate_operand" "i")
17583 (match_operand:P 4 "register_operand" "0")] UNSPEC_SCAS))
17584 (clobber (match_operand:P 1 "register_operand" "=D"))
17585 (clobber (reg:CC FLAGS_REG))]
17586 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])
17587 && ix86_check_no_addr_space (insn)"
17588 "%^repnz{%;} scasb"
17589 [(set_attr "type" "str")
17590 (set_attr "mode" "QI")
17591 (set (attr "prefix_rex")
17593 (match_test "<P:MODE>mode == DImode")
17595 (const_string "*")))
17596 (set_attr "prefix_rep" "1")])
17598 ;; Peephole optimizations to clean up after cmpstrn*. This should be
17599 ;; handled in combine, but it is not currently up to the task.
17600 ;; When used for their truth value, the cmpstrn* expanders generate
17609 ;; The intermediate three instructions are unnecessary.
17611 ;; This one handles cmpstrn*_nz_1...
17614 (set (reg:CC FLAGS_REG)
17615 (compare:CC (mem:BLK (match_operand 4 "register_operand"))
17616 (mem:BLK (match_operand 5 "register_operand"))))
17617 (use (match_operand 6 "register_operand"))
17618 (use (match_operand:SI 3 "immediate_operand"))
17619 (clobber (match_operand 0 "register_operand"))
17620 (clobber (match_operand 1 "register_operand"))
17621 (clobber (match_operand 2 "register_operand"))])
17622 (set (match_operand:QI 7 "register_operand")
17623 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
17624 (set (match_operand:QI 8 "register_operand")
17625 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
17626 (set (reg FLAGS_REG)
17627 (compare (match_dup 7) (match_dup 8)))
17629 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
17631 (set (reg:CC FLAGS_REG)
17632 (compare:CC (mem:BLK (match_dup 4))
17633 (mem:BLK (match_dup 5))))
17634 (use (match_dup 6))
17635 (use (match_dup 3))
17636 (clobber (match_dup 0))
17637 (clobber (match_dup 1))
17638 (clobber (match_dup 2))])])
17640 ;; ...and this one handles cmpstrn*_1.
17643 (set (reg:CC FLAGS_REG)
17644 (if_then_else:CC (ne (match_operand 6 "register_operand")
17646 (compare:CC (mem:BLK (match_operand 4 "register_operand"))
17647 (mem:BLK (match_operand 5 "register_operand")))
17649 (use (match_operand:SI 3 "immediate_operand"))
17650 (use (reg:CC FLAGS_REG))
17651 (clobber (match_operand 0 "register_operand"))
17652 (clobber (match_operand 1 "register_operand"))
17653 (clobber (match_operand 2 "register_operand"))])
17654 (set (match_operand:QI 7 "register_operand")
17655 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
17656 (set (match_operand:QI 8 "register_operand")
17657 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
17658 (set (reg FLAGS_REG)
17659 (compare (match_dup 7) (match_dup 8)))
17661 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
17663 (set (reg:CC FLAGS_REG)
17664 (if_then_else:CC (ne (match_dup 6)
17666 (compare:CC (mem:BLK (match_dup 4))
17667 (mem:BLK (match_dup 5)))
17669 (use (match_dup 3))
17670 (use (reg:CC FLAGS_REG))
17671 (clobber (match_dup 0))
17672 (clobber (match_dup 1))
17673 (clobber (match_dup 2))])])
17675 ;; Conditional move instructions.
17677 (define_expand "mov<mode>cc"
17678 [(set (match_operand:SWIM 0 "register_operand")
17679 (if_then_else:SWIM (match_operand 1 "comparison_operator")
17680 (match_operand:SWIM 2 "<general_operand>")
17681 (match_operand:SWIM 3 "<general_operand>")))]
17683 "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
17685 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
17686 ;; the register first winds up with `sbbl $0,reg', which is also weird.
17687 ;; So just document what we're doing explicitly.
17689 (define_expand "x86_mov<mode>cc_0_m1"
17691 [(set (match_operand:SWI48 0 "register_operand")
17692 (if_then_else:SWI48
17693 (match_operator:SWI48 2 "ix86_carry_flag_operator"
17694 [(match_operand 1 "flags_reg_operand")
17698 (clobber (reg:CC FLAGS_REG))])])
17700 (define_insn "*x86_mov<mode>cc_0_m1"
17701 [(set (match_operand:SWI48 0 "register_operand" "=r")
17702 (if_then_else:SWI48 (match_operator 1 "ix86_carry_flag_operator"
17703 [(reg FLAGS_REG) (const_int 0)])
17706 (clobber (reg:CC FLAGS_REG))]
17708 "sbb{<imodesuffix>}\t%0, %0"
17709 ; Since we don't have the proper number of operands for an alu insn,
17710 ; fill in all the blanks.
17711 [(set_attr "type" "alu")
17712 (set_attr "modrm_class" "op0")
17713 (set_attr "use_carry" "1")
17714 (set_attr "pent_pair" "pu")
17715 (set_attr "memory" "none")
17716 (set_attr "imm_disp" "false")
17717 (set_attr "mode" "<MODE>")
17718 (set_attr "length_immediate" "0")])
17720 (define_insn "*x86_mov<mode>cc_0_m1_se"
17721 [(set (match_operand:SWI48 0 "register_operand" "=r")
17722 (sign_extract:SWI48 (match_operator 1 "ix86_carry_flag_operator"
17723 [(reg FLAGS_REG) (const_int 0)])
17726 (clobber (reg:CC FLAGS_REG))]
17728 "sbb{<imodesuffix>}\t%0, %0"
17729 [(set_attr "type" "alu")
17730 (set_attr "modrm_class" "op0")
17731 (set_attr "use_carry" "1")
17732 (set_attr "pent_pair" "pu")
17733 (set_attr "memory" "none")
17734 (set_attr "imm_disp" "false")
17735 (set_attr "mode" "<MODE>")
17736 (set_attr "length_immediate" "0")])
17738 (define_insn "*x86_mov<mode>cc_0_m1_neg"
17739 [(set (match_operand:SWI48 0 "register_operand" "=r")
17740 (neg:SWI48 (match_operator 1 "ix86_carry_flag_operator"
17741 [(reg FLAGS_REG) (const_int 0)])))
17742 (clobber (reg:CC FLAGS_REG))]
17744 "sbb{<imodesuffix>}\t%0, %0"
17745 [(set_attr "type" "alu")
17746 (set_attr "modrm_class" "op0")
17747 (set_attr "use_carry" "1")
17748 (set_attr "pent_pair" "pu")
17749 (set_attr "memory" "none")
17750 (set_attr "imm_disp" "false")
17751 (set_attr "mode" "<MODE>")
17752 (set_attr "length_immediate" "0")])
17754 (define_insn "*mov<mode>cc_noc"
17755 [(set (match_operand:SWI248 0 "register_operand" "=r,r")
17756 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
17757 [(reg FLAGS_REG) (const_int 0)])
17758 (match_operand:SWI248 2 "nonimmediate_operand" "rm,0")
17759 (match_operand:SWI248 3 "nonimmediate_operand" "0,rm")))]
17760 "TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
17762 cmov%O2%C1\t{%2, %0|%0, %2}
17763 cmov%O2%c1\t{%3, %0|%0, %3}"
17764 [(set_attr "type" "icmov")
17765 (set_attr "mode" "<MODE>")])
17767 (define_insn "*movsicc_noc_zext"
17768 [(set (match_operand:DI 0 "register_operand" "=r,r")
17769 (if_then_else:DI (match_operator 1 "ix86_comparison_operator"
17770 [(reg FLAGS_REG) (const_int 0)])
17772 (match_operand:SI 2 "nonimmediate_operand" "rm,0"))
17774 (match_operand:SI 3 "nonimmediate_operand" "0,rm"))))]
17776 && TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
17778 cmov%O2%C1\t{%2, %k0|%k0, %2}
17779 cmov%O2%c1\t{%3, %k0|%k0, %3}"
17780 [(set_attr "type" "icmov")
17781 (set_attr "mode" "SI")])
17783 ;; Don't do conditional moves with memory inputs. This splitter helps
17784 ;; register starved x86_32 by forcing inputs into registers before reload.
17786 [(set (match_operand:SWI248 0 "register_operand")
17787 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
17788 [(reg FLAGS_REG) (const_int 0)])
17789 (match_operand:SWI248 2 "nonimmediate_operand")
17790 (match_operand:SWI248 3 "nonimmediate_operand")))]
17791 "!TARGET_64BIT && TARGET_CMOVE
17792 && TARGET_AVOID_MEM_OPND_FOR_CMOVE
17793 && (MEM_P (operands[2]) || MEM_P (operands[3]))
17794 && can_create_pseudo_p ()
17795 && optimize_insn_for_speed_p ()"
17796 [(set (match_dup 0)
17797 (if_then_else:SWI248 (match_dup 1) (match_dup 2) (match_dup 3)))]
17799 if (MEM_P (operands[2]))
17800 operands[2] = force_reg (<MODE>mode, operands[2]);
17801 if (MEM_P (operands[3]))
17802 operands[3] = force_reg (<MODE>mode, operands[3]);
17805 (define_insn "*movqicc_noc"
17806 [(set (match_operand:QI 0 "register_operand" "=r,r")
17807 (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
17808 [(reg FLAGS_REG) (const_int 0)])
17809 (match_operand:QI 2 "register_operand" "r,0")
17810 (match_operand:QI 3 "register_operand" "0,r")))]
17811 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
17813 [(set_attr "type" "icmov")
17814 (set_attr "mode" "QI")])
17817 [(set (match_operand:SWI12 0 "register_operand")
17818 (if_then_else:SWI12 (match_operator 1 "ix86_comparison_operator"
17819 [(reg FLAGS_REG) (const_int 0)])
17820 (match_operand:SWI12 2 "register_operand")
17821 (match_operand:SWI12 3 "register_operand")))]
17822 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL
17823 && reload_completed"
17824 [(set (match_dup 0)
17825 (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
17827 operands[0] = gen_lowpart (SImode, operands[0]);
17828 operands[2] = gen_lowpart (SImode, operands[2]);
17829 operands[3] = gen_lowpart (SImode, operands[3]);
17832 ;; Don't do conditional moves with memory inputs
17834 [(match_scratch:SWI248 4 "r")
17835 (set (match_operand:SWI248 0 "register_operand")
17836 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
17837 [(reg FLAGS_REG) (const_int 0)])
17838 (match_operand:SWI248 2 "nonimmediate_operand")
17839 (match_operand:SWI248 3 "nonimmediate_operand")))]
17840 "TARGET_CMOVE && TARGET_AVOID_MEM_OPND_FOR_CMOVE
17841 && (MEM_P (operands[2]) || MEM_P (operands[3]))
17842 && optimize_insn_for_speed_p ()"
17843 [(set (match_dup 4) (match_dup 5))
17845 (if_then_else:SWI248 (match_dup 1) (match_dup 2) (match_dup 3)))]
17847 if (MEM_P (operands[2]))
17849 operands[5] = operands[2];
17850 operands[2] = operands[4];
17852 else if (MEM_P (operands[3]))
17854 operands[5] = operands[3];
17855 operands[3] = operands[4];
17858 gcc_unreachable ();
17862 [(match_scratch:SI 4 "r")
17863 (set (match_operand:DI 0 "register_operand")
17864 (if_then_else:DI (match_operator 1 "ix86_comparison_operator"
17865 [(reg FLAGS_REG) (const_int 0)])
17867 (match_operand:SI 2 "nonimmediate_operand"))
17869 (match_operand:SI 3 "nonimmediate_operand"))))]
17871 && TARGET_CMOVE && TARGET_AVOID_MEM_OPND_FOR_CMOVE
17872 && (MEM_P (operands[2]) || MEM_P (operands[3]))
17873 && optimize_insn_for_speed_p ()"
17874 [(set (match_dup 4) (match_dup 5))
17876 (if_then_else:DI (match_dup 1)
17877 (zero_extend:DI (match_dup 2))
17878 (zero_extend:DI (match_dup 3))))]
17880 if (MEM_P (operands[2]))
17882 operands[5] = operands[2];
17883 operands[2] = operands[4];
17885 else if (MEM_P (operands[3]))
17887 operands[5] = operands[3];
17888 operands[3] = operands[4];
17891 gcc_unreachable ();
17894 (define_expand "mov<mode>cc"
17895 [(set (match_operand:X87MODEF 0 "register_operand")
17896 (if_then_else:X87MODEF
17897 (match_operand 1 "comparison_operator")
17898 (match_operand:X87MODEF 2 "register_operand")
17899 (match_operand:X87MODEF 3 "register_operand")))]
17900 "(TARGET_80387 && TARGET_CMOVE)
17901 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
17902 "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
17904 (define_insn "*movxfcc_1"
17905 [(set (match_operand:XF 0 "register_operand" "=f,f")
17906 (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
17907 [(reg FLAGS_REG) (const_int 0)])
17908 (match_operand:XF 2 "register_operand" "f,0")
17909 (match_operand:XF 3 "register_operand" "0,f")))]
17910 "TARGET_80387 && TARGET_CMOVE"
17912 fcmov%F1\t{%2, %0|%0, %2}
17913 fcmov%f1\t{%3, %0|%0, %3}"
17914 [(set_attr "type" "fcmov")
17915 (set_attr "mode" "XF")])
17917 (define_insn "*movdfcc_1"
17918 [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r,r ,r")
17919 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
17920 [(reg FLAGS_REG) (const_int 0)])
17921 (match_operand:DF 2 "nonimmediate_operand"
17923 (match_operand:DF 3 "nonimmediate_operand"
17924 "0 ,f,0 ,rm,0, rm")))]
17925 "TARGET_80387 && TARGET_CMOVE
17926 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
17928 fcmov%F1\t{%2, %0|%0, %2}
17929 fcmov%f1\t{%3, %0|%0, %3}
17932 cmov%O2%C1\t{%2, %0|%0, %2}
17933 cmov%O2%c1\t{%3, %0|%0, %3}"
17934 [(set_attr "isa" "*,*,nox64,nox64,x64,x64")
17935 (set_attr "type" "fcmov,fcmov,multi,multi,icmov,icmov")
17936 (set_attr "mode" "DF,DF,DI,DI,DI,DI")])
17939 [(set (match_operand:DF 0 "general_reg_operand")
17940 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
17941 [(reg FLAGS_REG) (const_int 0)])
17942 (match_operand:DF 2 "nonimmediate_operand")
17943 (match_operand:DF 3 "nonimmediate_operand")))]
17944 "!TARGET_64BIT && reload_completed"
17945 [(set (match_dup 2)
17946 (if_then_else:SI (match_dup 1) (match_dup 4) (match_dup 5)))
17948 (if_then_else:SI (match_dup 1) (match_dup 6) (match_dup 7)))]
17950 split_double_mode (DImode, &operands[2], 2, &operands[4], &operands[6]);
17951 split_double_mode (DImode, &operands[0], 1, &operands[2], &operands[3]);
17954 (define_insn "*movsfcc_1_387"
17955 [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
17956 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
17957 [(reg FLAGS_REG) (const_int 0)])
17958 (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
17959 (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
17960 "TARGET_80387 && TARGET_CMOVE
17961 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
17963 fcmov%F1\t{%2, %0|%0, %2}
17964 fcmov%f1\t{%3, %0|%0, %3}
17965 cmov%O2%C1\t{%2, %0|%0, %2}
17966 cmov%O2%c1\t{%3, %0|%0, %3}"
17967 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
17968 (set_attr "mode" "SF,SF,SI,SI")])
17970 ;; Don't do conditional moves with memory inputs. This splitter helps
17971 ;; register starved x86_32 by forcing inputs into registers before reload.
17973 [(set (match_operand:MODEF 0 "register_operand")
17974 (if_then_else:MODEF (match_operator 1 "ix86_comparison_operator"
17975 [(reg FLAGS_REG) (const_int 0)])
17976 (match_operand:MODEF 2 "nonimmediate_operand")
17977 (match_operand:MODEF 3 "nonimmediate_operand")))]
17978 "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
17979 && TARGET_AVOID_MEM_OPND_FOR_CMOVE
17980 && (MEM_P (operands[2]) || MEM_P (operands[3]))
17981 && can_create_pseudo_p ()
17982 && optimize_insn_for_speed_p ()"
17983 [(set (match_dup 0)
17984 (if_then_else:MODEF (match_dup 1) (match_dup 2) (match_dup 3)))]
17986 if (MEM_P (operands[2]))
17987 operands[2] = force_reg (<MODE>mode, operands[2]);
17988 if (MEM_P (operands[3]))
17989 operands[3] = force_reg (<MODE>mode, operands[3]);
17992 ;; Don't do conditional moves with memory inputs
17994 [(match_scratch:MODEF 4 "r")
17995 (set (match_operand:MODEF 0 "general_reg_operand")
17996 (if_then_else:MODEF (match_operator 1 "fcmov_comparison_operator"
17997 [(reg FLAGS_REG) (const_int 0)])
17998 (match_operand:MODEF 2 "nonimmediate_operand")
17999 (match_operand:MODEF 3 "nonimmediate_operand")))]
18000 "(<MODE>mode != DFmode || TARGET_64BIT)
18001 && TARGET_80387 && TARGET_CMOVE
18002 && TARGET_AVOID_MEM_OPND_FOR_CMOVE
18003 && (MEM_P (operands[2]) || MEM_P (operands[3]))
18004 && optimize_insn_for_speed_p ()"
18005 [(set (match_dup 4) (match_dup 5))
18007 (if_then_else:MODEF (match_dup 1) (match_dup 2) (match_dup 3)))]
18009 if (MEM_P (operands[2]))
18011 operands[5] = operands[2];
18012 operands[2] = operands[4];
18014 else if (MEM_P (operands[3]))
18016 operands[5] = operands[3];
18017 operands[3] = operands[4];
18020 gcc_unreachable ();
18023 ;; All moves in XOP pcmov instructions are 128 bits and hence we restrict
18024 ;; the scalar versions to have only XMM registers as operands.
18026 ;; XOP conditional move
18027 (define_insn "*xop_pcmov_<mode>"
18028 [(set (match_operand:MODEF 0 "register_operand" "=x")
18029 (if_then_else:MODEF
18030 (match_operand:MODEF 1 "register_operand" "x")
18031 (match_operand:MODEF 2 "register_operand" "x")
18032 (match_operand:MODEF 3 "register_operand" "x")))]
18034 "vpcmov\t{%1, %3, %2, %0|%0, %2, %3, %1}"
18035 [(set_attr "type" "sse4arg")])
18037 ;; These versions of the min/max patterns are intentionally ignorant of
18038 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
18039 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
18040 ;; are undefined in this condition, we're certain this is correct.
18042 (define_insn "<code><mode>3"
18043 [(set (match_operand:MODEF 0 "register_operand" "=x,v")
18045 (match_operand:MODEF 1 "nonimmediate_operand" "%0,v")
18046 (match_operand:MODEF 2 "nonimmediate_operand" "xm,vm")))]
18047 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
18049 <maxmin_float><ssemodesuffix>\t{%2, %0|%0, %2}
18050 v<maxmin_float><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
18051 [(set_attr "isa" "noavx,avx")
18052 (set_attr "prefix" "orig,vex")
18053 (set_attr "type" "sseadd")
18054 (set_attr "mode" "<MODE>")])
18056 ;; These versions of the min/max patterns implement exactly the operations
18057 ;; min = (op1 < op2 ? op1 : op2)
18058 ;; max = (!(op1 < op2) ? op1 : op2)
18059 ;; Their operands are not commutative, and thus they may be used in the
18060 ;; presence of -0.0 and NaN.
18062 (define_insn "*ieee_s<ieee_maxmin><mode>3"
18063 [(set (match_operand:MODEF 0 "register_operand" "=x,v")
18065 [(match_operand:MODEF 1 "register_operand" "0,v")
18066 (match_operand:MODEF 2 "nonimmediate_operand" "xm,vm")]
18068 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
18070 <ieee_maxmin><ssemodesuffix>\t{%2, %0|%0, %2}
18071 v<ieee_maxmin><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
18072 [(set_attr "isa" "noavx,avx")
18073 (set_attr "prefix" "orig,maybe_evex")
18074 (set_attr "type" "sseadd")
18075 (set_attr "mode" "<MODE>")])
18077 ;; Make two stack loads independent:
18079 ;; fld %st(0) -> fld bb
18080 ;; fmul bb fmul %st(1), %st
18082 ;; Actually we only match the last two instructions for simplicity.
18085 [(set (match_operand 0 "fp_register_operand")
18086 (match_operand 1 "fp_register_operand"))
18088 (match_operator 2 "binary_fp_operator"
18090 (match_operand 3 "memory_operand")]))]
18091 "REGNO (operands[0]) != REGNO (operands[1])"
18092 [(set (match_dup 0) (match_dup 3))
18095 [(match_dup 5) (match_dup 4)]))]
18097 operands[4] = operands[0];
18098 operands[5] = operands[1];
18100 /* The % modifier is not operational anymore in peephole2's, so we have to
18101 swap the operands manually in the case of addition and multiplication. */
18102 if (COMMUTATIVE_ARITH_P (operands[2]))
18103 std::swap (operands[4], operands[5]);
18107 [(set (match_operand 0 "fp_register_operand")
18108 (match_operand 1 "fp_register_operand"))
18110 (match_operator 2 "binary_fp_operator"
18111 [(match_operand 3 "memory_operand")
18113 "REGNO (operands[0]) != REGNO (operands[1])"
18114 [(set (match_dup 0) (match_dup 3))
18117 [(match_dup 4) (match_dup 5)]))]
18119 operands[4] = operands[0];
18120 operands[5] = operands[1];
18122 /* The % modifier is not operational anymore in peephole2's, so we have to
18123 swap the operands manually in the case of addition and multiplication. */
18124 if (COMMUTATIVE_ARITH_P (operands[2]))
18125 std::swap (operands[4], operands[5]);
18128 ;; Conditional addition patterns
18129 (define_expand "add<mode>cc"
18130 [(match_operand:SWI 0 "register_operand")
18131 (match_operand 1 "ordered_comparison_operator")
18132 (match_operand:SWI 2 "register_operand")
18133 (match_operand:SWI 3 "const_int_operand")]
18135 "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
18137 ;; Misc patterns (?)
18139 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
18140 ;; Otherwise there will be nothing to keep
18142 ;; [(set (reg ebp) (reg esp))]
18143 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
18144 ;; (clobber (eflags)]
18145 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
18147 ;; in proper program order.
18149 (define_insn "pro_epilogue_adjust_stack_<mode>_add"
18150 [(set (match_operand:P 0 "register_operand" "=r,r")
18151 (plus:P (match_operand:P 1 "register_operand" "0,r")
18152 (match_operand:P 2 "<nonmemory_operand>" "r<i>,l<i>")))
18153 (clobber (reg:CC FLAGS_REG))
18154 (clobber (mem:BLK (scratch)))]
18157 switch (get_attr_type (insn))
18160 return "mov{<imodesuffix>}\t{%1, %0|%0, %1}";
18163 gcc_assert (rtx_equal_p (operands[0], operands[1]));
18164 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
18165 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
18167 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
18170 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
18171 return "lea{<imodesuffix>}\t{%E2, %0|%0, %E2}";
18174 [(set (attr "type")
18175 (cond [(and (eq_attr "alternative" "0")
18176 (not (match_test "TARGET_OPT_AGU")))
18177 (const_string "alu")
18178 (match_operand:<MODE> 2 "const0_operand")
18179 (const_string "imov")
18181 (const_string "lea")))
18182 (set (attr "length_immediate")
18183 (cond [(eq_attr "type" "imov")
18185 (and (eq_attr "type" "alu")
18186 (match_operand 2 "const128_operand"))
18189 (const_string "*")))
18190 (set_attr "mode" "<MODE>")])
18192 (define_insn "pro_epilogue_adjust_stack_<mode>_sub"
18193 [(set (match_operand:P 0 "register_operand" "=r")
18194 (minus:P (match_operand:P 1 "register_operand" "0")
18195 (match_operand:P 2 "register_operand" "r")))
18196 (clobber (reg:CC FLAGS_REG))
18197 (clobber (mem:BLK (scratch)))]
18199 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
18200 [(set_attr "type" "alu")
18201 (set_attr "mode" "<MODE>")])
18203 (define_insn "allocate_stack_worker_probe_<mode>"
18204 [(set (match_operand:P 0 "register_operand" "=a")
18205 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
18206 UNSPECV_STACK_PROBE))
18207 (clobber (reg:CC FLAGS_REG))]
18208 "ix86_target_stack_probe ()"
18209 "call\t___chkstk_ms"
18210 [(set_attr "type" "multi")
18211 (set_attr "length" "5")])
18213 (define_expand "allocate_stack"
18214 [(match_operand 0 "register_operand")
18215 (match_operand 1 "general_operand")]
18216 "ix86_target_stack_probe ()"
18220 #ifndef CHECK_STACK_LIMIT
18221 #define CHECK_STACK_LIMIT 0
18224 if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
18225 && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
18229 rtx (*insn) (rtx, rtx);
18231 x = copy_to_mode_reg (Pmode, operands[1]);
18233 insn = (TARGET_64BIT
18234 ? gen_allocate_stack_worker_probe_di
18235 : gen_allocate_stack_worker_probe_si);
18237 emit_insn (insn (x, x));
18240 x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, x,
18241 stack_pointer_rtx, 0, OPTAB_DIRECT);
18243 if (x != stack_pointer_rtx)
18244 emit_move_insn (stack_pointer_rtx, x);
18246 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
18250 (define_expand "probe_stack"
18251 [(match_operand 0 "memory_operand")]
18254 rtx (*insn) (rtx, rtx)
18255 = (GET_MODE (operands[0]) == DImode
18256 ? gen_probe_stack_di : gen_probe_stack_si);
18258 emit_insn (insn (operands[0], const0_rtx));
18262 ;; Use OR for stack probes, this is shorter.
18263 (define_insn "probe_stack_<mode>"
18264 [(set (match_operand:W 0 "memory_operand" "=m")
18265 (unspec:W [(match_operand:W 1 "const0_operand")]
18266 UNSPEC_PROBE_STACK))
18267 (clobber (reg:CC FLAGS_REG))]
18269 "or{<imodesuffix>}\t{%1, %0|%0, %1}"
18270 [(set_attr "type" "alu1")
18271 (set_attr "mode" "<MODE>")
18272 (set_attr "length_immediate" "1")])
18274 (define_insn "adjust_stack_and_probe<mode>"
18275 [(set (match_operand:P 0 "register_operand" "=r")
18276 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
18277 UNSPECV_PROBE_STACK_RANGE))
18278 (set (reg:P SP_REG)
18279 (minus:P (reg:P SP_REG) (match_operand:P 2 "const_int_operand" "n")))
18280 (clobber (reg:CC FLAGS_REG))
18281 (clobber (mem:BLK (scratch)))]
18283 "* return output_adjust_stack_and_probe (operands[0]);"
18284 [(set_attr "type" "multi")])
18286 (define_insn "probe_stack_range<mode>"
18287 [(set (match_operand:P 0 "register_operand" "=r")
18288 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
18289 (match_operand:P 2 "const_int_operand" "n")]
18290 UNSPECV_PROBE_STACK_RANGE))
18291 (clobber (reg:CC FLAGS_REG))]
18293 "* return output_probe_stack_range (operands[0], operands[2]);"
18294 [(set_attr "type" "multi")])
18296 /* Additional processing for builtin_setjmp. Store the shadow stack pointer
18297 as a forth element in jmpbuf. */
18298 (define_expand "builtin_setjmp_setup"
18299 [(match_operand 0 "address_operand")]
18302 if (flag_cf_protection & CF_RETURN)
18306 mem = gen_rtx_MEM (Pmode, plus_constant (Pmode, operands[0],
18307 3 * GET_MODE_SIZE (Pmode)));
18308 reg_ssp = gen_reg_rtx (Pmode);
18309 emit_insn (gen_rtx_SET (reg_ssp, const0_rtx));
18310 emit_insn ((Pmode == SImode)
18311 ? gen_rdsspsi (reg_ssp, reg_ssp)
18312 : gen_rdsspdi (reg_ssp, reg_ssp));
18313 emit_move_insn (mem, reg_ssp);
18318 (define_expand "builtin_setjmp_receiver"
18319 [(label_ref (match_operand 0))]
18320 "!TARGET_64BIT && flag_pic"
18326 rtx_code_label *label_rtx = gen_label_rtx ();
18327 emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
18328 xops[0] = xops[1] = pic_offset_table_rtx;
18329 xops[2] = machopic_gen_offset (gen_rtx_LABEL_REF (SImode, label_rtx));
18330 ix86_expand_binary_operator (MINUS, SImode, xops);
18334 emit_insn (gen_set_got (pic_offset_table_rtx));
18338 (define_expand "builtin_longjmp"
18339 [(match_operand 0 "address_operand")]
18342 rtx fp, lab, stack;
18343 rtx jump, label, reg_adj, reg_ssp, reg_minus, mem_buf, tmp, clob;
18344 machine_mode sa_mode = STACK_SAVEAREA_MODE (SAVE_NONLOCAL);
18346 /* Adjust the shadow stack pointer (ssp) to the value saved in the
18347 jmp_buf. The saving was done in the builtin_setjmp_setup. */
18348 if (flag_cf_protection & CF_RETURN)
18350 /* Get current shadow stack pointer. The code below will check if
18351 SHSTK feature is enabled. If it's not enabled RDSSP instruction
18353 reg_ssp = gen_reg_rtx (Pmode);
18354 emit_insn (gen_rtx_SET (reg_ssp, const0_rtx));
18355 emit_insn ((Pmode == SImode)
18356 ? gen_rdsspsi (reg_ssp, reg_ssp)
18357 : gen_rdsspdi (reg_ssp, reg_ssp));
18358 mem_buf = gen_rtx_MEM (Pmode, plus_constant (Pmode, operands[0],
18359 3 * GET_MODE_SIZE (Pmode))),
18361 /* Compare through substraction the saved and the current ssp to decide
18362 if ssp has to be adjusted. */
18363 reg_minus = gen_reg_rtx (Pmode);
18364 tmp = gen_rtx_SET (reg_minus, gen_rtx_MINUS (Pmode, reg_ssp, mem_buf));
18365 clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
18366 tmp = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, tmp, clob));
18369 /* Jump over adjustment code. */
18370 label = gen_label_rtx ();
18371 tmp = gen_rtx_REG (CCmode, FLAGS_REG);
18372 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
18373 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
18374 gen_rtx_LABEL_REF (VOIDmode, label),
18376 jump = emit_jump_insn (gen_rtx_SET (pc_rtx, tmp));
18377 JUMP_LABEL (jump) = label;
18379 /* Adjust the ssp. */
18380 reg_adj = gen_reg_rtx (Pmode);
18381 tmp = gen_rtx_SET (reg_adj,
18382 gen_rtx_LSHIFTRT (Pmode, negate_rtx (Pmode, reg_minus),
18384 clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
18385 tmp = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, tmp, clob));
18387 emit_insn ((Pmode == SImode)
18388 ? gen_incsspsi (reg_adj)
18389 : gen_incsspdi (reg_adj));
18391 emit_label (label);
18392 LABEL_NUSES (label) = 1;
18395 /* This code is the same as in expand_buildin_longjmp. */
18396 fp = gen_rtx_MEM (Pmode, operands[0]);
18397 lab = gen_rtx_MEM (Pmode, plus_constant (Pmode, operands[0],
18398 GET_MODE_SIZE (Pmode)));
18399 stack = gen_rtx_MEM (sa_mode, plus_constant (Pmode, operands[0],
18400 2 * GET_MODE_SIZE (Pmode)));
18401 lab = copy_to_reg (lab);
18403 emit_clobber (gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (VOIDmode)));
18404 emit_clobber (gen_rtx_MEM (BLKmode, hard_frame_pointer_rtx));
18406 emit_move_insn (hard_frame_pointer_rtx, fp);
18407 emit_stack_restore (SAVE_NONLOCAL, stack);
18409 emit_use (hard_frame_pointer_rtx);
18410 emit_use (stack_pointer_rtx);
18411 emit_indirect_jump (lab);
18415 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
18416 ;; Do not split instructions with mask registers.
18418 [(set (match_operand 0 "general_reg_operand")
18419 (match_operator 3 "promotable_binary_operator"
18420 [(match_operand 1 "general_reg_operand")
18421 (match_operand 2 "aligned_operand")]))
18422 (clobber (reg:CC FLAGS_REG))]
18423 "! TARGET_PARTIAL_REG_STALL && reload_completed
18424 && ((GET_MODE (operands[0]) == HImode
18425 && ((optimize_function_for_speed_p (cfun) && !TARGET_FAST_PREFIX)
18426 /* ??? next two lines just !satisfies_constraint_K (...) */
18427 || !CONST_INT_P (operands[2])
18428 || satisfies_constraint_K (operands[2])))
18429 || (GET_MODE (operands[0]) == QImode
18430 && (TARGET_PROMOTE_QImode || optimize_function_for_size_p (cfun))))"
18431 [(parallel [(set (match_dup 0)
18432 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
18433 (clobber (reg:CC FLAGS_REG))])]
18435 operands[0] = gen_lowpart (SImode, operands[0]);
18436 operands[1] = gen_lowpart (SImode, operands[1]);
18437 if (GET_CODE (operands[3]) != ASHIFT)
18438 operands[2] = gen_lowpart (SImode, operands[2]);
18439 operands[3] = shallow_copy_rtx (operands[3]);
18440 PUT_MODE (operands[3], SImode);
18443 ; Promote the QImode tests, as i386 has encoding of the AND
18444 ; instruction with 32-bit sign-extended immediate and thus the
18445 ; instruction size is unchanged, except in the %eax case for
18446 ; which it is increased by one byte, hence the ! optimize_size.
18448 [(set (match_operand 0 "flags_reg_operand")
18449 (match_operator 2 "compare_operator"
18450 [(and (match_operand 3 "aligned_operand")
18451 (match_operand 4 "const_int_operand"))
18453 (set (match_operand 1 "register_operand")
18454 (and (match_dup 3) (match_dup 4)))]
18455 "! TARGET_PARTIAL_REG_STALL && reload_completed
18456 && optimize_insn_for_speed_p ()
18457 && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
18458 || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))
18459 /* Ensure that the operand will remain sign-extended immediate. */
18460 && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)"
18461 [(parallel [(set (match_dup 0)
18462 (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
18465 (and:SI (match_dup 3) (match_dup 4)))])]
18468 = gen_int_mode (INTVAL (operands[4])
18469 & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
18470 operands[1] = gen_lowpart (SImode, operands[1]);
18471 operands[3] = gen_lowpart (SImode, operands[3]);
18474 ; Don't promote the QImode tests, as i386 doesn't have encoding of
18475 ; the TEST instruction with 32-bit sign-extended immediate and thus
18476 ; the instruction size would at least double, which is not what we
18477 ; want even with ! optimize_size.
18479 [(set (match_operand 0 "flags_reg_operand")
18480 (match_operator 1 "compare_operator"
18481 [(and (match_operand:HI 2 "aligned_operand")
18482 (match_operand:HI 3 "const_int_operand"))
18484 "! TARGET_PARTIAL_REG_STALL && reload_completed
18485 && ! TARGET_FAST_PREFIX
18486 && optimize_insn_for_speed_p ()
18487 /* Ensure that the operand will remain sign-extended immediate. */
18488 && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)"
18489 [(set (match_dup 0)
18490 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
18494 = gen_int_mode (INTVAL (operands[3])
18495 & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
18496 operands[2] = gen_lowpart (SImode, operands[2]);
18500 [(set (match_operand 0 "register_operand")
18501 (neg (match_operand 1 "register_operand")))
18502 (clobber (reg:CC FLAGS_REG))]
18503 "! TARGET_PARTIAL_REG_STALL && reload_completed
18504 && (GET_MODE (operands[0]) == HImode
18505 || (GET_MODE (operands[0]) == QImode
18506 && (TARGET_PROMOTE_QImode
18507 || optimize_insn_for_size_p ())))"
18508 [(parallel [(set (match_dup 0)
18509 (neg:SI (match_dup 1)))
18510 (clobber (reg:CC FLAGS_REG))])]
18512 operands[0] = gen_lowpart (SImode, operands[0]);
18513 operands[1] = gen_lowpart (SImode, operands[1]);
18516 ;; Do not split instructions with mask regs.
18518 [(set (match_operand 0 "general_reg_operand")
18519 (not (match_operand 1 "general_reg_operand")))]
18520 "! TARGET_PARTIAL_REG_STALL && reload_completed
18521 && (GET_MODE (operands[0]) == HImode
18522 || (GET_MODE (operands[0]) == QImode
18523 && (TARGET_PROMOTE_QImode
18524 || optimize_insn_for_size_p ())))"
18525 [(set (match_dup 0)
18526 (not:SI (match_dup 1)))]
18528 operands[0] = gen_lowpart (SImode, operands[0]);
18529 operands[1] = gen_lowpart (SImode, operands[1]);
18532 ;; RTL Peephole optimizations, run before sched2. These primarily look to
18533 ;; transform a complex memory operation into two memory to register operations.
18535 ;; Don't push memory operands
18537 [(set (match_operand:SWI 0 "push_operand")
18538 (match_operand:SWI 1 "memory_operand"))
18539 (match_scratch:SWI 2 "<r>")]
18540 "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
18541 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
18542 [(set (match_dup 2) (match_dup 1))
18543 (set (match_dup 0) (match_dup 2))])
18545 ;; We need to handle SFmode only, because DFmode and XFmode are split to
18548 [(set (match_operand:SF 0 "push_operand")
18549 (match_operand:SF 1 "memory_operand"))
18550 (match_scratch:SF 2 "r")]
18551 "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
18552 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
18553 [(set (match_dup 2) (match_dup 1))
18554 (set (match_dup 0) (match_dup 2))])
18556 ;; Don't move an immediate directly to memory when the instruction
18557 ;; gets too big, or if LCP stalls are a problem for 16-bit moves.
18559 [(match_scratch:SWI124 1 "<r>")
18560 (set (match_operand:SWI124 0 "memory_operand")
18562 "optimize_insn_for_speed_p ()
18563 && ((<MODE>mode == HImode
18564 && TARGET_LCP_STALL)
18565 || (!TARGET_USE_MOV0
18566 && TARGET_SPLIT_LONG_MOVES
18567 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn))
18568 && peep2_regno_dead_p (0, FLAGS_REG)"
18569 [(parallel [(set (match_dup 2) (const_int 0))
18570 (clobber (reg:CC FLAGS_REG))])
18571 (set (match_dup 0) (match_dup 1))]
18572 "operands[2] = gen_lowpart (SImode, operands[1]);")
18575 [(match_scratch:SWI124 2 "<r>")
18576 (set (match_operand:SWI124 0 "memory_operand")
18577 (match_operand:SWI124 1 "immediate_operand"))]
18578 "optimize_insn_for_speed_p ()
18579 && ((<MODE>mode == HImode
18580 && TARGET_LCP_STALL)
18581 || (TARGET_SPLIT_LONG_MOVES
18582 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn))"
18583 [(set (match_dup 2) (match_dup 1))
18584 (set (match_dup 0) (match_dup 2))])
18586 ;; Don't compare memory with zero, load and use a test instead.
18588 [(set (match_operand 0 "flags_reg_operand")
18589 (match_operator 1 "compare_operator"
18590 [(match_operand:SI 2 "memory_operand")
18592 (match_scratch:SI 3 "r")]
18593 "optimize_insn_for_speed_p () && ix86_match_ccmode (insn, CCNOmode)"
18594 [(set (match_dup 3) (match_dup 2))
18595 (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))])
18597 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
18598 ;; Don't split NOTs with a displacement operand, because resulting XOR
18599 ;; will not be pairable anyway.
18601 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
18602 ;; represented using a modRM byte. The XOR replacement is long decoded,
18603 ;; so this split helps here as well.
18605 ;; Note: Can't do this as a regular split because we can't get proper
18606 ;; lifetime information then.
18609 [(set (match_operand:SWI124 0 "nonimmediate_gr_operand")
18610 (not:SWI124 (match_operand:SWI124 1 "nonimmediate_gr_operand")))]
18611 "optimize_insn_for_speed_p ()
18612 && ((TARGET_NOT_UNPAIRABLE
18613 && (!MEM_P (operands[0])
18614 || !memory_displacement_operand (operands[0], <MODE>mode)))
18615 || (TARGET_NOT_VECTORMODE
18616 && long_memory_operand (operands[0], <MODE>mode)))
18617 && peep2_regno_dead_p (0, FLAGS_REG)"
18618 [(parallel [(set (match_dup 0)
18619 (xor:SWI124 (match_dup 1) (const_int -1)))
18620 (clobber (reg:CC FLAGS_REG))])])
18622 ;; Non pairable "test imm, reg" instructions can be translated to
18623 ;; "and imm, reg" if reg dies. The "and" form is also shorter (one
18624 ;; byte opcode instead of two, have a short form for byte operands),
18625 ;; so do it for other CPUs as well. Given that the value was dead,
18626 ;; this should not create any new dependencies. Pass on the sub-word
18627 ;; versions if we're concerned about partial register stalls.
18630 [(set (match_operand 0 "flags_reg_operand")
18631 (match_operator 1 "compare_operator"
18632 [(and:SI (match_operand:SI 2 "register_operand")
18633 (match_operand:SI 3 "immediate_operand"))
18635 "ix86_match_ccmode (insn, CCNOmode)
18636 && (REGNO (operands[2]) != AX_REG
18637 || satisfies_constraint_K (operands[3]))
18638 && peep2_reg_dead_p (1, operands[2])"
18640 [(set (match_dup 0)
18641 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
18644 (and:SI (match_dup 2) (match_dup 3)))])])
18646 ;; We don't need to handle HImode case, because it will be promoted to SImode
18647 ;; on ! TARGET_PARTIAL_REG_STALL
18650 [(set (match_operand 0 "flags_reg_operand")
18651 (match_operator 1 "compare_operator"
18652 [(and:QI (match_operand:QI 2 "register_operand")
18653 (match_operand:QI 3 "immediate_operand"))
18655 "! TARGET_PARTIAL_REG_STALL
18656 && ix86_match_ccmode (insn, CCNOmode)
18657 && REGNO (operands[2]) != AX_REG
18658 && peep2_reg_dead_p (1, operands[2])"
18660 [(set (match_dup 0)
18661 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
18664 (and:QI (match_dup 2) (match_dup 3)))])])
18667 [(set (match_operand 0 "flags_reg_operand")
18668 (match_operator 1 "compare_operator"
18671 (zero_extract:SI (match_operand 2 "QIreg_operand")
18674 (match_operand 3 "const_int_operand"))
18676 "! TARGET_PARTIAL_REG_STALL
18677 && ix86_match_ccmode (insn, CCNOmode)
18678 && REGNO (operands[2]) != AX_REG
18679 && peep2_reg_dead_p (1, operands[2])"
18681 [(set (match_dup 0)
18685 (zero_extract:SI (match_dup 2)
18690 (set (zero_extract:SI (match_dup 2)
18696 (zero_extract:SI (match_dup 2)
18699 (match_dup 3)) 0))])])
18701 ;; Don't do logical operations with memory inputs.
18703 [(match_scratch:SWI 2 "<r>")
18704 (parallel [(set (match_operand:SWI 0 "register_operand")
18705 (match_operator:SWI 3 "arith_or_logical_operator"
18707 (match_operand:SWI 1 "memory_operand")]))
18708 (clobber (reg:CC FLAGS_REG))])]
18709 "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
18710 [(set (match_dup 2) (match_dup 1))
18711 (parallel [(set (match_dup 0)
18712 (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
18713 (clobber (reg:CC FLAGS_REG))])])
18716 [(match_scratch:SWI 2 "<r>")
18717 (parallel [(set (match_operand:SWI 0 "register_operand")
18718 (match_operator:SWI 3 "arith_or_logical_operator"
18719 [(match_operand:SWI 1 "memory_operand")
18721 (clobber (reg:CC FLAGS_REG))])]
18722 "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
18723 [(set (match_dup 2) (match_dup 1))
18724 (parallel [(set (match_dup 0)
18725 (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
18726 (clobber (reg:CC FLAGS_REG))])])
18728 ;; Prefer Load+RegOp to Mov+MemOp. Watch out for cases when
18729 ;; the memory address refers to the destination of the load!
18732 [(set (match_operand:SWI 0 "general_reg_operand")
18733 (match_operand:SWI 1 "general_reg_operand"))
18734 (parallel [(set (match_dup 0)
18735 (match_operator:SWI 3 "commutative_operator"
18737 (match_operand:SWI 2 "memory_operand")]))
18738 (clobber (reg:CC FLAGS_REG))])]
18739 "REGNO (operands[0]) != REGNO (operands[1])
18740 && (<MODE>mode != QImode
18741 || any_QIreg_operand (operands[1], QImode))"
18742 [(set (match_dup 0) (match_dup 4))
18743 (parallel [(set (match_dup 0)
18744 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))
18745 (clobber (reg:CC FLAGS_REG))])]
18746 "operands[4] = replace_rtx (operands[2], operands[0], operands[1], true);")
18749 [(set (match_operand 0 "mmx_reg_operand")
18750 (match_operand 1 "mmx_reg_operand"))
18752 (match_operator 3 "commutative_operator"
18754 (match_operand 2 "memory_operand")]))]
18755 "REGNO (operands[0]) != REGNO (operands[1])"
18756 [(set (match_dup 0) (match_dup 2))
18758 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))])
18761 [(set (match_operand 0 "sse_reg_operand")
18762 (match_operand 1 "sse_reg_operand"))
18764 (match_operator 3 "commutative_operator"
18766 (match_operand 2 "memory_operand")]))]
18767 "REGNO (operands[0]) != REGNO (operands[1])"
18768 [(set (match_dup 0) (match_dup 2))
18770 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))])
18772 ; Don't do logical operations with memory outputs
18774 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
18775 ; instruction into two 1-uop insns plus a 2-uop insn. That last has
18776 ; the same decoder scheduling characteristics as the original.
18779 [(match_scratch:SWI 2 "<r>")
18780 (parallel [(set (match_operand:SWI 0 "memory_operand")
18781 (match_operator:SWI 3 "arith_or_logical_operator"
18783 (match_operand:SWI 1 "<nonmemory_operand>")]))
18784 (clobber (reg:CC FLAGS_REG))])]
18785 "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())"
18786 [(set (match_dup 2) (match_dup 0))
18787 (parallel [(set (match_dup 2)
18788 (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
18789 (clobber (reg:CC FLAGS_REG))])
18790 (set (match_dup 0) (match_dup 2))])
18793 [(match_scratch:SWI 2 "<r>")
18794 (parallel [(set (match_operand:SWI 0 "memory_operand")
18795 (match_operator:SWI 3 "arith_or_logical_operator"
18796 [(match_operand:SWI 1 "<nonmemory_operand>")
18798 (clobber (reg:CC FLAGS_REG))])]
18799 "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())"
18800 [(set (match_dup 2) (match_dup 0))
18801 (parallel [(set (match_dup 2)
18802 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
18803 (clobber (reg:CC FLAGS_REG))])
18804 (set (match_dup 0) (match_dup 2))])
18806 ;; Attempt to use arith or logical operations with memory outputs with
18807 ;; setting of flags.
18809 [(set (match_operand:SWI 0 "register_operand")
18810 (match_operand:SWI 1 "memory_operand"))
18811 (parallel [(set (match_dup 0)
18812 (match_operator:SWI 3 "plusminuslogic_operator"
18814 (match_operand:SWI 2 "<nonmemory_operand>")]))
18815 (clobber (reg:CC FLAGS_REG))])
18816 (set (match_dup 1) (match_dup 0))
18817 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
18818 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
18819 && peep2_reg_dead_p (4, operands[0])
18820 && !reg_overlap_mentioned_p (operands[0], operands[1])
18821 && !reg_overlap_mentioned_p (operands[0], operands[2])
18822 && (<MODE>mode != QImode
18823 || immediate_operand (operands[2], QImode)
18824 || any_QIreg_operand (operands[2], QImode))
18825 && ix86_match_ccmode (peep2_next_insn (3),
18826 (GET_CODE (operands[3]) == PLUS
18827 || GET_CODE (operands[3]) == MINUS)
18828 ? CCGOCmode : CCNOmode)"
18829 [(parallel [(set (match_dup 4) (match_dup 6))
18830 (set (match_dup 1) (match_dup 5))])]
18832 operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
18834 = gen_rtx_fmt_ee (GET_CODE (operands[3]), GET_MODE (operands[3]),
18835 copy_rtx (operands[1]),
18838 = gen_rtx_COMPARE (GET_MODE (operands[4]),
18839 copy_rtx (operands[5]),
18843 ;; Likewise for instances where we have a lea pattern.
18845 [(set (match_operand:SWI 0 "register_operand")
18846 (match_operand:SWI 1 "memory_operand"))
18847 (set (match_operand:SWI 3 "register_operand")
18848 (plus:SWI (match_dup 0)
18849 (match_operand:SWI 2 "<nonmemory_operand>")))
18850 (set (match_dup 1) (match_dup 3))
18851 (set (reg FLAGS_REG) (compare (match_dup 3) (const_int 0)))]
18852 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
18853 && peep2_reg_dead_p (4, operands[3])
18854 && (rtx_equal_p (operands[0], operands[3])
18855 || peep2_reg_dead_p (2, operands[0]))
18856 && !reg_overlap_mentioned_p (operands[0], operands[1])
18857 && !reg_overlap_mentioned_p (operands[3], operands[1])
18858 && !reg_overlap_mentioned_p (operands[0], operands[2])
18859 && (<MODE>mode != QImode
18860 || immediate_operand (operands[2], QImode)
18861 || any_QIreg_operand (operands[2], QImode))
18862 && ix86_match_ccmode (peep2_next_insn (3), CCGOCmode)"
18863 [(parallel [(set (match_dup 4) (match_dup 6))
18864 (set (match_dup 1) (match_dup 5))])]
18866 operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
18868 = gen_rtx_PLUS (<MODE>mode,
18869 copy_rtx (operands[1]),
18872 = gen_rtx_COMPARE (GET_MODE (operands[4]),
18873 copy_rtx (operands[5]),
18878 [(parallel [(set (match_operand:SWI 0 "register_operand")
18879 (match_operator:SWI 2 "plusminuslogic_operator"
18881 (match_operand:SWI 1 "memory_operand")]))
18882 (clobber (reg:CC FLAGS_REG))])
18883 (set (match_dup 1) (match_dup 0))
18884 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
18885 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
18886 && GET_CODE (operands[2]) != MINUS
18887 && peep2_reg_dead_p (3, operands[0])
18888 && !reg_overlap_mentioned_p (operands[0], operands[1])
18889 && ix86_match_ccmode (peep2_next_insn (2),
18890 GET_CODE (operands[2]) == PLUS
18891 ? CCGOCmode : CCNOmode)"
18892 [(parallel [(set (match_dup 3) (match_dup 5))
18893 (set (match_dup 1) (match_dup 4))])]
18895 operands[3] = SET_DEST (PATTERN (peep2_next_insn (2)));
18897 = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
18898 copy_rtx (operands[1]),
18901 = gen_rtx_COMPARE (GET_MODE (operands[3]),
18902 copy_rtx (operands[4]),
18907 [(set (match_operand:SWI12 0 "register_operand")
18908 (match_operand:SWI12 1 "memory_operand"))
18909 (parallel [(set (match_operand:SI 4 "register_operand")
18910 (match_operator:SI 3 "plusminuslogic_operator"
18912 (match_operand:SI 2 "nonmemory_operand")]))
18913 (clobber (reg:CC FLAGS_REG))])
18914 (set (match_dup 1) (match_dup 0))
18915 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
18916 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
18917 && REGNO (operands[0]) == REGNO (operands[4])
18918 && peep2_reg_dead_p (4, operands[0])
18919 && (<MODE>mode != QImode
18920 || immediate_operand (operands[2], SImode)
18921 || any_QIreg_operand (operands[2], SImode))
18922 && !reg_overlap_mentioned_p (operands[0], operands[1])
18923 && !reg_overlap_mentioned_p (operands[0], operands[2])
18924 && ix86_match_ccmode (peep2_next_insn (3),
18925 (GET_CODE (operands[3]) == PLUS
18926 || GET_CODE (operands[3]) == MINUS)
18927 ? CCGOCmode : CCNOmode)"
18928 [(parallel [(set (match_dup 4) (match_dup 6))
18929 (set (match_dup 1) (match_dup 5))])]
18931 operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
18933 = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
18934 copy_rtx (operands[1]),
18935 gen_lowpart (<MODE>mode, operands[2]));
18937 = gen_rtx_COMPARE (GET_MODE (operands[4]),
18938 copy_rtx (operands[5]),
18942 ;; Attempt to always use XOR for zeroing registers (including FP modes).
18944 [(set (match_operand 0 "general_reg_operand")
18945 (match_operand 1 "const0_operand"))]
18946 "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
18947 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
18948 && peep2_regno_dead_p (0, FLAGS_REG)"
18949 [(parallel [(set (match_dup 0) (const_int 0))
18950 (clobber (reg:CC FLAGS_REG))])]
18951 "operands[0] = gen_lowpart (word_mode, operands[0]);")
18954 [(set (strict_low_part (match_operand:SWI12 0 "general_reg_operand"))
18956 "(! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
18957 && peep2_regno_dead_p (0, FLAGS_REG)"
18958 [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
18959 (clobber (reg:CC FLAGS_REG))])])
18961 ;; For HI, SI and DI modes, or $-1,reg is smaller than mov $-1,reg.
18963 [(set (match_operand:SWI248 0 "general_reg_operand")
18965 "(TARGET_MOVE_M1_VIA_OR || optimize_insn_for_size_p ())
18966 && peep2_regno_dead_p (0, FLAGS_REG)"
18967 [(parallel [(set (match_dup 0) (const_int -1))
18968 (clobber (reg:CC FLAGS_REG))])]
18970 if (<MODE_SIZE> < GET_MODE_SIZE (SImode))
18971 operands[0] = gen_lowpart (SImode, operands[0]);
18974 ;; Attempt to convert simple lea to add/shift.
18975 ;; These can be created by move expanders.
18976 ;; Disable PLUS peepholes on TARGET_OPT_AGU, since all
18977 ;; relevant lea instructions were already split.
18980 [(set (match_operand:SWI48 0 "register_operand")
18981 (plus:SWI48 (match_dup 0)
18982 (match_operand:SWI48 1 "<nonmemory_operand>")))]
18984 && peep2_regno_dead_p (0, FLAGS_REG)"
18985 [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1)))
18986 (clobber (reg:CC FLAGS_REG))])])
18989 [(set (match_operand:SWI48 0 "register_operand")
18990 (plus:SWI48 (match_operand:SWI48 1 "<nonmemory_operand>")
18993 && peep2_regno_dead_p (0, FLAGS_REG)"
18994 [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1)))
18995 (clobber (reg:CC FLAGS_REG))])])
18998 [(set (match_operand:DI 0 "register_operand")
19000 (plus:SI (match_operand:SI 1 "register_operand")
19001 (match_operand:SI 2 "nonmemory_operand"))))]
19002 "TARGET_64BIT && !TARGET_OPT_AGU
19003 && REGNO (operands[0]) == REGNO (operands[1])
19004 && peep2_regno_dead_p (0, FLAGS_REG)"
19005 [(parallel [(set (match_dup 0)
19006 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))
19007 (clobber (reg:CC FLAGS_REG))])])
19010 [(set (match_operand:DI 0 "register_operand")
19012 (plus:SI (match_operand:SI 1 "nonmemory_operand")
19013 (match_operand:SI 2 "register_operand"))))]
19014 "TARGET_64BIT && !TARGET_OPT_AGU
19015 && REGNO (operands[0]) == REGNO (operands[2])
19016 && peep2_regno_dead_p (0, FLAGS_REG)"
19017 [(parallel [(set (match_dup 0)
19018 (zero_extend:DI (plus:SI (match_dup 2) (match_dup 1))))
19019 (clobber (reg:CC FLAGS_REG))])])
19022 [(set (match_operand:SWI48 0 "register_operand")
19023 (mult:SWI48 (match_dup 0)
19024 (match_operand:SWI48 1 "const_int_operand")))]
19025 "pow2p_hwi (INTVAL (operands[1]))
19026 && peep2_regno_dead_p (0, FLAGS_REG)"
19027 [(parallel [(set (match_dup 0) (ashift:SWI48 (match_dup 0) (match_dup 1)))
19028 (clobber (reg:CC FLAGS_REG))])]
19029 "operands[1] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
19032 [(set (match_operand:DI 0 "register_operand")
19034 (mult:SI (match_operand:SI 1 "register_operand")
19035 (match_operand:SI 2 "const_int_operand"))))]
19037 && pow2p_hwi (INTVAL (operands[2]))
19038 && REGNO (operands[0]) == REGNO (operands[1])
19039 && peep2_regno_dead_p (0, FLAGS_REG)"
19040 [(parallel [(set (match_dup 0)
19041 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))
19042 (clobber (reg:CC FLAGS_REG))])]
19043 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
19045 ;; The ESP adjustments can be done by the push and pop instructions. Resulting
19046 ;; code is shorter, since push is only 1 byte, while add imm, %esp is 3 bytes.
19047 ;; On many CPUs it is also faster, since special hardware to avoid esp
19048 ;; dependencies is present.
19050 ;; While some of these conversions may be done using splitters, we use
19051 ;; peepholes in order to allow combine_stack_adjustments pass to see
19052 ;; nonobfuscated RTL.
19054 ;; Convert prologue esp subtractions to push.
19055 ;; We need register to push. In order to keep verify_flow_info happy we have
19057 ;; - use scratch and clobber it in order to avoid dependencies
19058 ;; - use already live register
19059 ;; We can't use the second way right now, since there is no reliable way how to
19060 ;; verify that given register is live. First choice will also most likely in
19061 ;; fewer dependencies. On the place of esp adjustments it is very likely that
19062 ;; call clobbered registers are dead. We may want to use base pointer as an
19063 ;; alternative when no register is available later.
19066 [(match_scratch:W 1 "r")
19067 (parallel [(set (reg:P SP_REG)
19068 (plus:P (reg:P SP_REG)
19069 (match_operand:P 0 "const_int_operand")))
19070 (clobber (reg:CC FLAGS_REG))
19071 (clobber (mem:BLK (scratch)))])]
19072 "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
19073 && INTVAL (operands[0]) == -GET_MODE_SIZE (word_mode)
19074 && ix86_red_zone_size == 0"
19075 [(clobber (match_dup 1))
19076 (parallel [(set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
19077 (clobber (mem:BLK (scratch)))])])
19080 [(match_scratch:W 1 "r")
19081 (parallel [(set (reg:P SP_REG)
19082 (plus:P (reg:P SP_REG)
19083 (match_operand:P 0 "const_int_operand")))
19084 (clobber (reg:CC FLAGS_REG))
19085 (clobber (mem:BLK (scratch)))])]
19086 "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
19087 && INTVAL (operands[0]) == -2*GET_MODE_SIZE (word_mode)
19088 && ix86_red_zone_size == 0"
19089 [(clobber (match_dup 1))
19090 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
19091 (parallel [(set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
19092 (clobber (mem:BLK (scratch)))])])
19094 ;; Convert esp subtractions to push.
19096 [(match_scratch:W 1 "r")
19097 (parallel [(set (reg:P SP_REG)
19098 (plus:P (reg:P SP_REG)
19099 (match_operand:P 0 "const_int_operand")))
19100 (clobber (reg:CC FLAGS_REG))])]
19101 "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
19102 && INTVAL (operands[0]) == -GET_MODE_SIZE (word_mode)
19103 && ix86_red_zone_size == 0"
19104 [(clobber (match_dup 1))
19105 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
19108 [(match_scratch:W 1 "r")
19109 (parallel [(set (reg:P SP_REG)
19110 (plus:P (reg:P SP_REG)
19111 (match_operand:P 0 "const_int_operand")))
19112 (clobber (reg:CC FLAGS_REG))])]
19113 "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
19114 && INTVAL (operands[0]) == -2*GET_MODE_SIZE (word_mode)
19115 && ix86_red_zone_size == 0"
19116 [(clobber (match_dup 1))
19117 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
19118 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
19120 ;; Convert epilogue deallocator to pop.
19122 [(match_scratch:W 1 "r")
19123 (parallel [(set (reg:P SP_REG)
19124 (plus:P (reg:P SP_REG)
19125 (match_operand:P 0 "const_int_operand")))
19126 (clobber (reg:CC FLAGS_REG))
19127 (clobber (mem:BLK (scratch)))])]
19128 "(TARGET_SINGLE_POP || optimize_insn_for_size_p ())
19129 && INTVAL (operands[0]) == GET_MODE_SIZE (word_mode)"
19130 [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
19131 (clobber (mem:BLK (scratch)))])])
19133 ;; Two pops case is tricky, since pop causes dependency
19134 ;; on destination register. We use two registers if available.
19136 [(match_scratch:W 1 "r")
19137 (match_scratch:W 2 "r")
19138 (parallel [(set (reg:P SP_REG)
19139 (plus:P (reg:P SP_REG)
19140 (match_operand:P 0 "const_int_operand")))
19141 (clobber (reg:CC FLAGS_REG))
19142 (clobber (mem:BLK (scratch)))])]
19143 "(TARGET_DOUBLE_POP || optimize_insn_for_size_p ())
19144 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
19145 [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
19146 (clobber (mem:BLK (scratch)))])
19147 (set (match_dup 2) (mem:W (post_inc:P (reg:P SP_REG))))])
19150 [(match_scratch:W 1 "r")
19151 (parallel [(set (reg:P SP_REG)
19152 (plus:P (reg:P SP_REG)
19153 (match_operand:P 0 "const_int_operand")))
19154 (clobber (reg:CC FLAGS_REG))
19155 (clobber (mem:BLK (scratch)))])]
19156 "optimize_insn_for_size_p ()
19157 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
19158 [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
19159 (clobber (mem:BLK (scratch)))])
19160 (set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
19162 ;; Convert esp additions to pop.
19164 [(match_scratch:W 1 "r")
19165 (parallel [(set (reg:P SP_REG)
19166 (plus:P (reg:P SP_REG)
19167 (match_operand:P 0 "const_int_operand")))
19168 (clobber (reg:CC FLAGS_REG))])]
19169 "INTVAL (operands[0]) == GET_MODE_SIZE (word_mode)"
19170 [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
19172 ;; Two pops case is tricky, since pop causes dependency
19173 ;; on destination register. We use two registers if available.
19175 [(match_scratch:W 1 "r")
19176 (match_scratch:W 2 "r")
19177 (parallel [(set (reg:P SP_REG)
19178 (plus:P (reg:P SP_REG)
19179 (match_operand:P 0 "const_int_operand")))
19180 (clobber (reg:CC FLAGS_REG))])]
19181 "INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
19182 [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
19183 (set (match_dup 2) (mem:W (post_inc:P (reg:P SP_REG))))])
19186 [(match_scratch:W 1 "r")
19187 (parallel [(set (reg:P SP_REG)
19188 (plus:P (reg:P SP_REG)
19189 (match_operand:P 0 "const_int_operand")))
19190 (clobber (reg:CC FLAGS_REG))])]
19191 "optimize_insn_for_size_p ()
19192 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
19193 [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
19194 (set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
19196 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
19197 ;; required and register dies. Similarly for 128 to -128.
19199 [(set (match_operand 0 "flags_reg_operand")
19200 (match_operator 1 "compare_operator"
19201 [(match_operand 2 "register_operand")
19202 (match_operand 3 "const_int_operand")]))]
19203 "(((!TARGET_FUSE_CMP_AND_BRANCH || optimize_insn_for_size_p ())
19204 && incdec_operand (operands[3], GET_MODE (operands[3])))
19205 || (!TARGET_FUSE_CMP_AND_BRANCH
19206 && INTVAL (operands[3]) == 128))
19207 && ix86_match_ccmode (insn, CCGCmode)
19208 && peep2_reg_dead_p (1, operands[2])"
19209 [(parallel [(set (match_dup 0)
19210 (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
19211 (clobber (match_dup 2))])])
19213 ;; Convert imul by three, five and nine into lea
19216 [(set (match_operand:SWI48 0 "register_operand")
19217 (mult:SWI48 (match_operand:SWI48 1 "register_operand")
19218 (match_operand:SWI48 2 "const359_operand")))
19219 (clobber (reg:CC FLAGS_REG))])]
19220 "!TARGET_PARTIAL_REG_STALL
19221 || <MODE>mode == SImode
19222 || optimize_function_for_size_p (cfun)"
19223 [(set (match_dup 0)
19224 (plus:SWI48 (mult:SWI48 (match_dup 1) (match_dup 2))
19226 "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
19230 [(set (match_operand:SWI48 0 "register_operand")
19231 (mult:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
19232 (match_operand:SWI48 2 "const359_operand")))
19233 (clobber (reg:CC FLAGS_REG))])]
19234 "optimize_insn_for_speed_p ()
19235 && (!TARGET_PARTIAL_REG_STALL || <MODE>mode == SImode)"
19236 [(set (match_dup 0) (match_dup 1))
19238 (plus:SWI48 (mult:SWI48 (match_dup 0) (match_dup 2))
19240 "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
19242 ;; imul $32bit_imm, mem, reg is vector decoded, while
19243 ;; imul $32bit_imm, reg, reg is direct decoded.
19245 [(match_scratch:SWI48 3 "r")
19246 (parallel [(set (match_operand:SWI48 0 "register_operand")
19247 (mult:SWI48 (match_operand:SWI48 1 "memory_operand")
19248 (match_operand:SWI48 2 "immediate_operand")))
19249 (clobber (reg:CC FLAGS_REG))])]
19250 "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
19251 && !satisfies_constraint_K (operands[2])"
19252 [(set (match_dup 3) (match_dup 1))
19253 (parallel [(set (match_dup 0) (mult:SWI48 (match_dup 3) (match_dup 2)))
19254 (clobber (reg:CC FLAGS_REG))])])
19257 [(match_scratch:SI 3 "r")
19258 (parallel [(set (match_operand:DI 0 "register_operand")
19260 (mult:SI (match_operand:SI 1 "memory_operand")
19261 (match_operand:SI 2 "immediate_operand"))))
19262 (clobber (reg:CC FLAGS_REG))])]
19264 && TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
19265 && !satisfies_constraint_K (operands[2])"
19266 [(set (match_dup 3) (match_dup 1))
19267 (parallel [(set (match_dup 0)
19268 (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
19269 (clobber (reg:CC FLAGS_REG))])])
19271 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
19272 ;; Convert it into imul reg, reg
19273 ;; It would be better to force assembler to encode instruction using long
19274 ;; immediate, but there is apparently no way to do so.
19276 [(parallel [(set (match_operand:SWI248 0 "register_operand")
19278 (match_operand:SWI248 1 "nonimmediate_operand")
19279 (match_operand:SWI248 2 "const_int_operand")))
19280 (clobber (reg:CC FLAGS_REG))])
19281 (match_scratch:SWI248 3 "r")]
19282 "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
19283 && satisfies_constraint_K (operands[2])"
19284 [(set (match_dup 3) (match_dup 2))
19285 (parallel [(set (match_dup 0) (mult:SWI248 (match_dup 0) (match_dup 3)))
19286 (clobber (reg:CC FLAGS_REG))])]
19288 if (!rtx_equal_p (operands[0], operands[1]))
19289 emit_move_insn (operands[0], operands[1]);
19292 ;; After splitting up read-modify operations, array accesses with memory
19293 ;; operands might end up in form:
19295 ;; movl 4(%esp), %edx
19297 ;; instead of pre-splitting:
19299 ;; addl 4(%esp), %eax
19301 ;; movl 4(%esp), %edx
19302 ;; leal (%edx,%eax,4), %eax
19305 [(match_scratch:W 5 "r")
19306 (parallel [(set (match_operand 0 "register_operand")
19307 (ashift (match_operand 1 "register_operand")
19308 (match_operand 2 "const_int_operand")))
19309 (clobber (reg:CC FLAGS_REG))])
19310 (parallel [(set (match_operand 3 "register_operand")
19311 (plus (match_dup 0)
19312 (match_operand 4 "x86_64_general_operand")))
19313 (clobber (reg:CC FLAGS_REG))])]
19314 "IN_RANGE (INTVAL (operands[2]), 1, 3)
19315 /* Validate MODE for lea. */
19316 && ((!TARGET_PARTIAL_REG_STALL
19317 && (GET_MODE (operands[0]) == QImode
19318 || GET_MODE (operands[0]) == HImode))
19319 || GET_MODE (operands[0]) == SImode
19320 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
19321 && (rtx_equal_p (operands[0], operands[3])
19322 || peep2_reg_dead_p (2, operands[0]))
19323 /* We reorder load and the shift. */
19324 && !reg_overlap_mentioned_p (operands[0], operands[4])"
19325 [(set (match_dup 5) (match_dup 4))
19326 (set (match_dup 0) (match_dup 1))]
19328 machine_mode op1mode = GET_MODE (operands[1]);
19329 machine_mode mode = op1mode == DImode ? DImode : SImode;
19330 int scale = 1 << INTVAL (operands[2]);
19331 rtx index = gen_lowpart (word_mode, operands[1]);
19332 rtx base = gen_lowpart (word_mode, operands[5]);
19333 rtx dest = gen_lowpart (mode, operands[3]);
19335 operands[1] = gen_rtx_PLUS (word_mode, base,
19336 gen_rtx_MULT (word_mode, index, GEN_INT (scale)));
19337 if (mode != word_mode)
19338 operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
19340 operands[5] = base;
19341 if (op1mode != word_mode)
19342 operands[5] = gen_lowpart (op1mode, operands[5]);
19344 operands[0] = dest;
19347 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
19348 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
19349 ;; caught for use by garbage collectors and the like. Using an insn that
19350 ;; maps to SIGILL makes it more likely the program will rightfully die.
19351 ;; Keeping with tradition, "6" is in honor of #UD.
19352 (define_insn "trap"
19353 [(trap_if (const_int 1) (const_int 6))]
19356 #ifdef HAVE_AS_IX86_UD2
19359 return ASM_SHORT "0x0b0f";
19362 [(set_attr "length" "2")])
19365 [(unspec_volatile [(const_int 0)] UNSPECV_UD2)]
19368 #ifdef HAVE_AS_IX86_UD2
19371 return ASM_SHORT "0x0b0f";
19374 [(set_attr "length" "2")])
19376 (define_expand "prefetch"
19377 [(prefetch (match_operand 0 "address_operand")
19378 (match_operand:SI 1 "const_int_operand")
19379 (match_operand:SI 2 "const_int_operand"))]
19380 "TARGET_3DNOW || TARGET_PREFETCH_SSE || TARGET_PRFCHW || TARGET_PREFETCHWT1"
19382 bool write = INTVAL (operands[1]) != 0;
19383 int locality = INTVAL (operands[2]);
19385 gcc_assert (IN_RANGE (locality, 0, 3));
19387 /* Use 3dNOW prefetch in case we are asking for write prefetch not
19388 supported by SSE counterpart (non-SSE2 athlon machines) or the
19389 SSE prefetch is not available (K6 machines). Otherwise use SSE
19390 prefetch as it allows specifying of locality. */
19394 if (TARGET_PREFETCHWT1)
19395 operands[2] = GEN_INT (MAX (locality, 2));
19396 else if (TARGET_PRFCHW)
19397 operands[2] = GEN_INT (3);
19398 else if (TARGET_3DNOW && !TARGET_SSE2)
19399 operands[2] = GEN_INT (3);
19400 else if (TARGET_PREFETCH_SSE)
19401 operands[1] = const0_rtx;
19404 gcc_assert (TARGET_3DNOW);
19405 operands[2] = GEN_INT (3);
19410 if (TARGET_PREFETCH_SSE)
19414 gcc_assert (TARGET_3DNOW);
19415 operands[2] = GEN_INT (3);
19420 (define_insn "*prefetch_sse"
19421 [(prefetch (match_operand 0 "address_operand" "p")
19423 (match_operand:SI 1 "const_int_operand"))]
19424 "TARGET_PREFETCH_SSE"
19426 static const char * const patterns[4] = {
19427 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
19430 int locality = INTVAL (operands[1]);
19431 gcc_assert (IN_RANGE (locality, 0, 3));
19433 return patterns[locality];
19435 [(set_attr "type" "sse")
19436 (set_attr "atom_sse_attr" "prefetch")
19437 (set (attr "length_address")
19438 (symbol_ref "memory_address_length (operands[0], false)"))
19439 (set_attr "memory" "none")])
19441 (define_insn "*prefetch_3dnow"
19442 [(prefetch (match_operand 0 "address_operand" "p")
19443 (match_operand:SI 1 "const_int_operand" "n")
19445 "TARGET_3DNOW || TARGET_PRFCHW || TARGET_PREFETCHWT1"
19447 if (INTVAL (operands[1]) == 0)
19448 return "prefetch\t%a0";
19450 return "prefetchw\t%a0";
19452 [(set_attr "type" "mmx")
19453 (set (attr "length_address")
19454 (symbol_ref "memory_address_length (operands[0], false)"))
19455 (set_attr "memory" "none")])
19457 (define_insn "*prefetch_prefetchwt1"
19458 [(prefetch (match_operand 0 "address_operand" "p")
19461 "TARGET_PREFETCHWT1"
19462 "prefetchwt1\t%a0";
19463 [(set_attr "type" "sse")
19464 (set (attr "length_address")
19465 (symbol_ref "memory_address_length (operands[0], false)"))
19466 (set_attr "memory" "none")])
19468 (define_expand "stack_protect_set"
19469 [(match_operand 0 "memory_operand")
19470 (match_operand 1 "memory_operand")]
19471 "TARGET_SSP_TLS_GUARD"
19473 rtx (*insn)(rtx, rtx);
19475 insn = (TARGET_LP64
19476 ? gen_stack_protect_set_di
19477 : gen_stack_protect_set_si);
19479 emit_insn (insn (operands[0], operands[1]));
19483 (define_insn "stack_protect_set_<mode>"
19484 [(set (match_operand:PTR 0 "memory_operand" "=m")
19485 (unspec:PTR [(match_operand:PTR 1 "memory_operand" "m")]
19487 (set (match_scratch:PTR 2 "=&r") (const_int 0))
19488 (clobber (reg:CC FLAGS_REG))]
19489 "TARGET_SSP_TLS_GUARD"
19490 "mov{<imodesuffix>}\t{%1, %2|%2, %1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
19491 [(set_attr "type" "multi")])
19493 (define_expand "stack_protect_test"
19494 [(match_operand 0 "memory_operand")
19495 (match_operand 1 "memory_operand")
19497 "TARGET_SSP_TLS_GUARD"
19499 rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
19501 rtx (*insn)(rtx, rtx, rtx);
19503 insn = (TARGET_LP64
19504 ? gen_stack_protect_test_di
19505 : gen_stack_protect_test_si);
19507 emit_insn (insn (flags, operands[0], operands[1]));
19509 emit_jump_insn (gen_cbranchcc4 (gen_rtx_EQ (VOIDmode, flags, const0_rtx),
19510 flags, const0_rtx, operands[2]));
19514 (define_insn "stack_protect_test_<mode>"
19515 [(set (match_operand:CCZ 0 "flags_reg_operand")
19516 (unspec:CCZ [(match_operand:PTR 1 "memory_operand" "m")
19517 (match_operand:PTR 2 "memory_operand" "m")]
19519 (clobber (match_scratch:PTR 3 "=&r"))]
19520 "TARGET_SSP_TLS_GUARD"
19521 "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%2, %3|%3, %2}"
19522 [(set_attr "type" "multi")])
19524 (define_insn "sse4_2_crc32<mode>"
19525 [(set (match_operand:SI 0 "register_operand" "=r")
19527 [(match_operand:SI 1 "register_operand" "0")
19528 (match_operand:SWI124 2 "nonimmediate_operand" "<r>m")]
19530 "TARGET_SSE4_2 || TARGET_CRC32"
19531 "crc32{<imodesuffix>}\t{%2, %0|%0, %2}"
19532 [(set_attr "type" "sselog1")
19533 (set_attr "prefix_rep" "1")
19534 (set_attr "prefix_extra" "1")
19535 (set (attr "prefix_data16")
19536 (if_then_else (match_operand:HI 2)
19538 (const_string "*")))
19539 (set (attr "prefix_rex")
19540 (if_then_else (match_operand:QI 2 "ext_QIreg_operand")
19542 (const_string "*")))
19543 (set_attr "mode" "SI")])
19545 (define_insn "sse4_2_crc32di"
19546 [(set (match_operand:DI 0 "register_operand" "=r")
19548 [(match_operand:DI 1 "register_operand" "0")
19549 (match_operand:DI 2 "nonimmediate_operand" "rm")]
19551 "TARGET_64BIT && (TARGET_SSE4_2 || TARGET_CRC32)"
19552 "crc32{q}\t{%2, %0|%0, %2}"
19553 [(set_attr "type" "sselog1")
19554 (set_attr "prefix_rep" "1")
19555 (set_attr "prefix_extra" "1")
19556 (set_attr "mode" "DI")])
19558 (define_insn "rdpmc"
19559 [(set (match_operand:DI 0 "register_operand" "=A")
19560 (unspec_volatile:DI [(match_operand:SI 1 "register_operand" "c")]
19564 [(set_attr "type" "other")
19565 (set_attr "length" "2")])
19567 (define_insn "rdpmc_rex64"
19568 [(set (match_operand:DI 0 "register_operand" "=a")
19569 (unspec_volatile:DI [(match_operand:SI 2 "register_operand" "c")]
19571 (set (match_operand:DI 1 "register_operand" "=d")
19572 (unspec_volatile:DI [(match_dup 2)] UNSPECV_RDPMC))]
19575 [(set_attr "type" "other")
19576 (set_attr "length" "2")])
19578 (define_insn "rdtsc"
19579 [(set (match_operand:DI 0 "register_operand" "=A")
19580 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
19583 [(set_attr "type" "other")
19584 (set_attr "length" "2")])
19586 (define_insn "rdtsc_rex64"
19587 [(set (match_operand:DI 0 "register_operand" "=a")
19588 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))
19589 (set (match_operand:DI 1 "register_operand" "=d")
19590 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
19593 [(set_attr "type" "other")
19594 (set_attr "length" "2")])
19596 (define_insn "rdtscp"
19597 [(set (match_operand:DI 0 "register_operand" "=A")
19598 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
19599 (set (match_operand:SI 1 "register_operand" "=c")
19600 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
19603 [(set_attr "type" "other")
19604 (set_attr "length" "3")])
19606 (define_insn "rdtscp_rex64"
19607 [(set (match_operand:DI 0 "register_operand" "=a")
19608 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
19609 (set (match_operand:DI 1 "register_operand" "=d")
19610 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
19611 (set (match_operand:SI 2 "register_operand" "=c")
19612 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
19615 [(set_attr "type" "other")
19616 (set_attr "length" "3")])
19618 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
19620 ;; FXSR, XSAVE and XSAVEOPT instructions
19622 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
19624 (define_insn "fxsave"
19625 [(set (match_operand:BLK 0 "memory_operand" "=m")
19626 (unspec_volatile:BLK [(const_int 0)] UNSPECV_FXSAVE))]
19629 [(set_attr "type" "other")
19630 (set_attr "memory" "store")
19631 (set (attr "length")
19632 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
19634 (define_insn "fxsave64"
19635 [(set (match_operand:BLK 0 "memory_operand" "=m")
19636 (unspec_volatile:BLK [(const_int 0)] UNSPECV_FXSAVE64))]
19637 "TARGET_64BIT && TARGET_FXSR"
19639 [(set_attr "type" "other")
19640 (set_attr "memory" "store")
19641 (set (attr "length")
19642 (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
19644 (define_insn "fxrstor"
19645 [(unspec_volatile [(match_operand:BLK 0 "memory_operand" "m")]
19649 [(set_attr "type" "other")
19650 (set_attr "memory" "load")
19651 (set (attr "length")
19652 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
19654 (define_insn "fxrstor64"
19655 [(unspec_volatile [(match_operand:BLK 0 "memory_operand" "m")]
19656 UNSPECV_FXRSTOR64)]
19657 "TARGET_64BIT && TARGET_FXSR"
19659 [(set_attr "type" "other")
19660 (set_attr "memory" "load")
19661 (set (attr "length")
19662 (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
19664 (define_int_iterator ANY_XSAVE
19666 (UNSPECV_XSAVEOPT "TARGET_XSAVEOPT")
19667 (UNSPECV_XSAVEC "TARGET_XSAVEC")
19668 (UNSPECV_XSAVES "TARGET_XSAVES")])
19670 (define_int_iterator ANY_XSAVE64
19672 (UNSPECV_XSAVEOPT64 "TARGET_XSAVEOPT")
19673 (UNSPECV_XSAVEC64 "TARGET_XSAVEC")
19674 (UNSPECV_XSAVES64 "TARGET_XSAVES")])
19676 (define_int_attr xsave
19677 [(UNSPECV_XSAVE "xsave")
19678 (UNSPECV_XSAVE64 "xsave64")
19679 (UNSPECV_XSAVEOPT "xsaveopt")
19680 (UNSPECV_XSAVEOPT64 "xsaveopt64")
19681 (UNSPECV_XSAVEC "xsavec")
19682 (UNSPECV_XSAVEC64 "xsavec64")
19683 (UNSPECV_XSAVES "xsaves")
19684 (UNSPECV_XSAVES64 "xsaves64")])
19686 (define_int_iterator ANY_XRSTOR
19688 (UNSPECV_XRSTORS "TARGET_XSAVES")])
19690 (define_int_iterator ANY_XRSTOR64
19692 (UNSPECV_XRSTORS64 "TARGET_XSAVES")])
19694 (define_int_attr xrstor
19695 [(UNSPECV_XRSTOR "xrstor")
19696 (UNSPECV_XRSTOR64 "xrstor")
19697 (UNSPECV_XRSTORS "xrstors")
19698 (UNSPECV_XRSTORS64 "xrstors")])
19700 (define_insn "<xsave>"
19701 [(set (match_operand:BLK 0 "memory_operand" "=m")
19702 (unspec_volatile:BLK
19703 [(match_operand:DI 1 "register_operand" "A")]
19705 "!TARGET_64BIT && TARGET_XSAVE"
19707 [(set_attr "type" "other")
19708 (set_attr "memory" "store")
19709 (set (attr "length")
19710 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
19712 (define_insn "<xsave>_rex64"
19713 [(set (match_operand:BLK 0 "memory_operand" "=m")
19714 (unspec_volatile:BLK
19715 [(match_operand:SI 1 "register_operand" "a")
19716 (match_operand:SI 2 "register_operand" "d")]
19718 "TARGET_64BIT && TARGET_XSAVE"
19720 [(set_attr "type" "other")
19721 (set_attr "memory" "store")
19722 (set (attr "length")
19723 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
19725 (define_insn "<xsave>"
19726 [(set (match_operand:BLK 0 "memory_operand" "=m")
19727 (unspec_volatile:BLK
19728 [(match_operand:SI 1 "register_operand" "a")
19729 (match_operand:SI 2 "register_operand" "d")]
19731 "TARGET_64BIT && TARGET_XSAVE"
19733 [(set_attr "type" "other")
19734 (set_attr "memory" "store")
19735 (set (attr "length")
19736 (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
19738 (define_insn "<xrstor>"
19739 [(unspec_volatile:BLK
19740 [(match_operand:BLK 0 "memory_operand" "m")
19741 (match_operand:DI 1 "register_operand" "A")]
19743 "!TARGET_64BIT && TARGET_XSAVE"
19745 [(set_attr "type" "other")
19746 (set_attr "memory" "load")
19747 (set (attr "length")
19748 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
19750 (define_insn "<xrstor>_rex64"
19751 [(unspec_volatile:BLK
19752 [(match_operand:BLK 0 "memory_operand" "m")
19753 (match_operand:SI 1 "register_operand" "a")
19754 (match_operand:SI 2 "register_operand" "d")]
19756 "TARGET_64BIT && TARGET_XSAVE"
19758 [(set_attr "type" "other")
19759 (set_attr "memory" "load")
19760 (set (attr "length")
19761 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
19763 (define_insn "<xrstor>64"
19764 [(unspec_volatile:BLK
19765 [(match_operand:BLK 0 "memory_operand" "m")
19766 (match_operand:SI 1 "register_operand" "a")
19767 (match_operand:SI 2 "register_operand" "d")]
19769 "TARGET_64BIT && TARGET_XSAVE"
19771 [(set_attr "type" "other")
19772 (set_attr "memory" "load")
19773 (set (attr "length")
19774 (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
19776 (define_insn "xsetbv"
19777 [(unspec_volatile:SI
19778 [(match_operand:SI 0 "register_operand" "c")
19779 (match_operand:DI 1 "register_operand" "A")]
19781 "!TARGET_64BIT && TARGET_XSAVE"
19783 [(set_attr "type" "other")])
19785 (define_insn "xsetbv_rex64"
19786 [(unspec_volatile:SI
19787 [(match_operand:SI 0 "register_operand" "c")
19788 (match_operand:SI 1 "register_operand" "a")
19789 (match_operand:SI 2 "register_operand" "d")]
19791 "TARGET_64BIT && TARGET_XSAVE"
19793 [(set_attr "type" "other")])
19795 (define_insn "xgetbv"
19796 [(set (match_operand:DI 0 "register_operand" "=A")
19797 (unspec_volatile:DI [(match_operand:SI 1 "register_operand" "c")]
19799 "!TARGET_64BIT && TARGET_XSAVE"
19801 [(set_attr "type" "other")])
19803 (define_insn "xgetbv_rex64"
19804 [(set (match_operand:DI 0 "register_operand" "=a")
19805 (unspec_volatile:DI [(match_operand:SI 2 "register_operand" "c")]
19807 (set (match_operand:DI 1 "register_operand" "=d")
19808 (unspec_volatile:DI [(match_dup 2)] UNSPECV_XGETBV))]
19809 "TARGET_64BIT && TARGET_XSAVE"
19811 [(set_attr "type" "other")])
19813 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
19815 ;; Floating-point instructions for atomic compound assignments
19817 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
19819 ; Clobber all floating-point registers on environment save and restore
19820 ; to ensure that the TOS value saved at fnstenv is valid after fldenv.
19821 (define_insn "fnstenv"
19822 [(set (match_operand:BLK 0 "memory_operand" "=m")
19823 (unspec_volatile:BLK [(const_int 0)] UNSPECV_FNSTENV))
19824 (clobber (reg:HI FPCR_REG))
19825 (clobber (reg:XF ST0_REG))
19826 (clobber (reg:XF ST1_REG))
19827 (clobber (reg:XF ST2_REG))
19828 (clobber (reg:XF ST3_REG))
19829 (clobber (reg:XF ST4_REG))
19830 (clobber (reg:XF ST5_REG))
19831 (clobber (reg:XF ST6_REG))
19832 (clobber (reg:XF ST7_REG))]
19835 [(set_attr "type" "other")
19836 (set_attr "memory" "store")
19837 (set (attr "length")
19838 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))])
19840 (define_insn "fldenv"
19841 [(unspec_volatile [(match_operand:BLK 0 "memory_operand" "m")]
19843 (clobber (reg:CCFP FPSR_REG))
19844 (clobber (reg:HI FPCR_REG))
19845 (clobber (reg:XF ST0_REG))
19846 (clobber (reg:XF ST1_REG))
19847 (clobber (reg:XF ST2_REG))
19848 (clobber (reg:XF ST3_REG))
19849 (clobber (reg:XF ST4_REG))
19850 (clobber (reg:XF ST5_REG))
19851 (clobber (reg:XF ST6_REG))
19852 (clobber (reg:XF ST7_REG))]
19855 [(set_attr "type" "other")
19856 (set_attr "memory" "load")
19857 (set (attr "length")
19858 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))])
19860 (define_insn "fnstsw"
19861 [(set (match_operand:HI 0 "nonimmediate_operand" "=a,m")
19862 (unspec_volatile:HI [(const_int 0)] UNSPECV_FNSTSW))]
19865 [(set_attr "type" "other,other")
19866 (set_attr "memory" "none,store")
19867 (set (attr "length")
19868 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))])
19870 (define_insn "fnclex"
19871 [(unspec_volatile [(const_int 0)] UNSPECV_FNCLEX)]
19874 [(set_attr "type" "other")
19875 (set_attr "memory" "none")
19876 (set_attr "length" "2")])
19878 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
19880 ;; LWP instructions
19882 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
19884 (define_expand "lwp_llwpcb"
19885 [(unspec_volatile [(match_operand 0 "register_operand")]
19886 UNSPECV_LLWP_INTRINSIC)]
19889 (define_insn "*lwp_llwpcb<mode>1"
19890 [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
19891 UNSPECV_LLWP_INTRINSIC)]
19894 [(set_attr "type" "lwp")
19895 (set_attr "mode" "<MODE>")
19896 (set_attr "length" "5")])
19898 (define_expand "lwp_slwpcb"
19899 [(set (match_operand 0 "register_operand")
19900 (unspec_volatile [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
19905 insn = (Pmode == DImode
19907 : gen_lwp_slwpcbsi);
19909 emit_insn (insn (operands[0]));
19913 (define_insn "lwp_slwpcb<mode>"
19914 [(set (match_operand:P 0 "register_operand" "=r")
19915 (unspec_volatile:P [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
19918 [(set_attr "type" "lwp")
19919 (set_attr "mode" "<MODE>")
19920 (set_attr "length" "5")])
19922 (define_expand "lwp_lwpval<mode>3"
19923 [(unspec_volatile [(match_operand:SWI48 1 "register_operand")
19924 (match_operand:SI 2 "nonimmediate_operand")
19925 (match_operand:SI 3 "const_int_operand")]
19926 UNSPECV_LWPVAL_INTRINSIC)]
19928 ;; Avoid unused variable warning.
19929 "(void) operands[0];")
19931 (define_insn "*lwp_lwpval<mode>3_1"
19932 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")
19933 (match_operand:SI 1 "nonimmediate_operand" "rm")
19934 (match_operand:SI 2 "const_int_operand" "i")]
19935 UNSPECV_LWPVAL_INTRINSIC)]
19937 "lwpval\t{%2, %1, %0|%0, %1, %2}"
19938 [(set_attr "type" "lwp")
19939 (set_attr "mode" "<MODE>")
19940 (set (attr "length")
19941 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
19943 (define_expand "lwp_lwpins<mode>3"
19944 [(set (reg:CCC FLAGS_REG)
19945 (unspec_volatile:CCC [(match_operand:SWI48 1 "register_operand")
19946 (match_operand:SI 2 "nonimmediate_operand")
19947 (match_operand:SI 3 "const_int_operand")]
19948 UNSPECV_LWPINS_INTRINSIC))
19949 (set (match_operand:QI 0 "nonimmediate_operand")
19950 (eq:QI (reg:CCC FLAGS_REG) (const_int 0)))]
19953 (define_insn "*lwp_lwpins<mode>3_1"
19954 [(set (reg:CCC FLAGS_REG)
19955 (unspec_volatile:CCC [(match_operand:SWI48 0 "register_operand" "r")
19956 (match_operand:SI 1 "nonimmediate_operand" "rm")
19957 (match_operand:SI 2 "const_int_operand" "i")]
19958 UNSPECV_LWPINS_INTRINSIC))]
19960 "lwpins\t{%2, %1, %0|%0, %1, %2}"
19961 [(set_attr "type" "lwp")
19962 (set_attr "mode" "<MODE>")
19963 (set (attr "length")
19964 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
19966 (define_int_iterator RDFSGSBASE
19970 (define_int_iterator WRFSGSBASE
19974 (define_int_attr fsgs
19975 [(UNSPECV_RDFSBASE "fs")
19976 (UNSPECV_RDGSBASE "gs")
19977 (UNSPECV_WRFSBASE "fs")
19978 (UNSPECV_WRGSBASE "gs")])
19980 (define_insn "rd<fsgs>base<mode>"
19981 [(set (match_operand:SWI48 0 "register_operand" "=r")
19982 (unspec_volatile:SWI48 [(const_int 0)] RDFSGSBASE))]
19983 "TARGET_64BIT && TARGET_FSGSBASE"
19985 [(set_attr "type" "other")
19986 (set_attr "prefix_extra" "2")])
19988 (define_insn "wr<fsgs>base<mode>"
19989 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
19991 "TARGET_64BIT && TARGET_FSGSBASE"
19993 [(set_attr "type" "other")
19994 (set_attr "prefix_extra" "2")])
19996 (define_insn "rdrand<mode>_1"
19997 [(set (match_operand:SWI248 0 "register_operand" "=r")
19998 (unspec_volatile:SWI248 [(const_int 0)] UNSPECV_RDRAND))
19999 (set (reg:CCC FLAGS_REG)
20000 (unspec_volatile:CCC [(const_int 0)] UNSPECV_RDRAND))]
20003 [(set_attr "type" "other")
20004 (set_attr "prefix_extra" "1")])
20006 (define_insn "rdseed<mode>_1"
20007 [(set (match_operand:SWI248 0 "register_operand" "=r")
20008 (unspec_volatile:SWI248 [(const_int 0)] UNSPECV_RDSEED))
20009 (set (reg:CCC FLAGS_REG)
20010 (unspec_volatile:CCC [(const_int 0)] UNSPECV_RDSEED))]
20013 [(set_attr "type" "other")
20014 (set_attr "prefix_extra" "1")])
20016 (define_expand "pause"
20017 [(set (match_dup 0)
20018 (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
20021 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
20022 MEM_VOLATILE_P (operands[0]) = 1;
20025 ;; Use "rep; nop", instead of "pause", to support older assemblers.
20026 ;; They have the same encoding.
20027 (define_insn "*pause"
20028 [(set (match_operand:BLK 0)
20029 (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
20032 [(set_attr "length" "2")
20033 (set_attr "memory" "unknown")])
20035 ;; CET instructions
20036 (define_insn "rdssp<mode>"
20037 [(set (match_operand:SWI48x 0 "register_operand" "=r")
20038 (unspec_volatile:SWI48x
20039 [(match_operand:SWI48x 1 "register_operand" "0")]
20040 UNSPECV_NOP_RDSSP))]
20042 "rdssp<mskmodesuffix>\t%0"
20043 [(set_attr "length" "4")
20044 (set_attr "type" "other")])
20046 (define_insn "incssp<mode>"
20047 [(unspec_volatile [(match_operand:SWI48x 0 "register_operand" "r")]
20050 "incssp<mskmodesuffix>\t%0"
20051 [(set_attr "length" "4")
20052 (set_attr "type" "other")])
20054 (define_insn "saveprevssp"
20055 [(unspec_volatile [(const_int 0)] UNSPECV_SAVEPREVSSP)]
20058 [(set_attr "length" "5")
20059 (set_attr "type" "other")])
20061 (define_insn "rstorssp"
20062 [(unspec_volatile [(match_operand 0 "memory_operand" "m")]
20066 [(set_attr "length" "5")
20067 (set_attr "type" "other")])
20069 (define_insn "wrss<mode>"
20070 [(unspec_volatile [(match_operand:SWI48x 0 "register_operand" "r")
20071 (match_operand:SWI48x 1 "memory_operand" "m")]
20074 "wrss<mskmodesuffix>\t%0, %1"
20075 [(set_attr "length" "3")
20076 (set_attr "type" "other")])
20078 (define_insn "wruss<mode>"
20079 [(unspec_volatile [(match_operand:SWI48x 0 "register_operand" "r")
20080 (match_operand:SWI48x 1 "memory_operand" "m")]
20083 "wruss<mskmodesuffix>\t%0, %1"
20084 [(set_attr "length" "4")
20085 (set_attr "type" "other")])
20087 (define_insn "setssbsy"
20088 [(unspec_volatile [(const_int 0)] UNSPECV_SETSSBSY)]
20091 [(set_attr "length" "4")
20092 (set_attr "type" "other")])
20094 (define_insn "clrssbsy"
20095 [(unspec_volatile [(match_operand 0 "memory_operand" "m")]
20099 [(set_attr "length" "4")
20100 (set_attr "type" "other")])
20102 (define_insn "nop_endbr"
20103 [(unspec_volatile [(const_int 0)] UNSPECV_NOP_ENDBR)]
20106 { return (TARGET_64BIT)? \"endbr64\" : \"endbr32\"; }"
20107 [(set_attr "length" "4")
20108 (set_attr "length_immediate" "0")
20109 (set_attr "modrm" "0")])
20112 (define_expand "xbegin"
20113 [(set (match_operand:SI 0 "register_operand")
20114 (unspec_volatile:SI [(const_int 0)] UNSPECV_XBEGIN))]
20117 rtx_code_label *label = gen_label_rtx ();
20119 /* xbegin is emitted as jump_insn, so reload won't be able
20120 to reload its operand. Force the value into AX hard register. */
20121 rtx ax_reg = gen_rtx_REG (SImode, AX_REG);
20122 emit_move_insn (ax_reg, constm1_rtx);
20124 emit_jump_insn (gen_xbegin_1 (ax_reg, label));
20126 emit_label (label);
20127 LABEL_NUSES (label) = 1;
20129 emit_move_insn (operands[0], ax_reg);
20134 (define_insn "xbegin_1"
20136 (if_then_else (ne (unspec [(const_int 0)] UNSPEC_XBEGIN_ABORT)
20138 (label_ref (match_operand 1))
20140 (set (match_operand:SI 0 "register_operand" "+a")
20141 (unspec_volatile:SI [(match_dup 0)] UNSPECV_XBEGIN))]
20144 [(set_attr "type" "other")
20145 (set_attr "length" "6")])
20147 (define_insn "xend"
20148 [(unspec_volatile [(const_int 0)] UNSPECV_XEND)]
20151 [(set_attr "type" "other")
20152 (set_attr "length" "3")])
20154 (define_insn "xabort"
20155 [(unspec_volatile [(match_operand:SI 0 "const_0_to_255_operand" "n")]
20159 [(set_attr "type" "other")
20160 (set_attr "length" "3")])
20162 (define_expand "xtest"
20163 [(set (match_operand:QI 0 "register_operand")
20164 (unspec_volatile:QI [(const_int 0)] UNSPECV_XTEST))]
20167 emit_insn (gen_xtest_1 ());
20169 ix86_expand_setcc (operands[0], NE,
20170 gen_rtx_REG (CCZmode, FLAGS_REG), const0_rtx);
20174 (define_insn "xtest_1"
20175 [(set (reg:CCZ FLAGS_REG)
20176 (unspec_volatile:CCZ [(const_int 0)] UNSPECV_XTEST))]
20179 [(set_attr "type" "other")
20180 (set_attr "length" "3")])
20182 (define_insn "clwb"
20183 [(unspec_volatile [(match_operand 0 "address_operand" "p")]
20187 [(set_attr "type" "sse")
20188 (set_attr "atom_sse_attr" "fence")
20189 (set_attr "memory" "unknown")])
20191 (define_insn "clflushopt"
20192 [(unspec_volatile [(match_operand 0 "address_operand" "p")]
20193 UNSPECV_CLFLUSHOPT)]
20194 "TARGET_CLFLUSHOPT"
20196 [(set_attr "type" "sse")
20197 (set_attr "atom_sse_attr" "fence")
20198 (set_attr "memory" "unknown")])
20200 ;; MONITORX and MWAITX
20201 (define_insn "mwaitx"
20202 [(unspec_volatile [(match_operand:SI 0 "register_operand" "c")
20203 (match_operand:SI 1 "register_operand" "a")
20204 (match_operand:SI 2 "register_operand" "b")]
20207 ;; 64bit version is "mwaitx %rax,%rcx,%rbx". But only lower 32bits are used.
20208 ;; Since 32bit register operands are implicitly zero extended to 64bit,
20209 ;; we only need to set up 32bit registers.
20211 [(set_attr "length" "3")])
20213 (define_insn "monitorx_<mode>"
20214 [(unspec_volatile [(match_operand:P 0 "register_operand" "a")
20215 (match_operand:SI 1 "register_operand" "c")
20216 (match_operand:SI 2 "register_operand" "d")]
20219 ;; 64bit version is "monitorx %rax,%rcx,%rdx". But only lower 32bits in
20220 ;; RCX and RDX are used. Since 32bit register operands are implicitly
20221 ;; zero extended to 64bit, we only need to set up 32bit registers.
20223 [(set (attr "length")
20224 (symbol_ref ("(Pmode != word_mode) + 3")))])
20227 (define_insn "clzero_<mode>"
20228 [(unspec_volatile [(match_operand: P 0 "register_operand" "a")]
20232 [(set_attr "length" "3")
20233 (set_attr "memory" "unknown")])
20235 ;; MPX instructions
20237 (define_expand "<mode>_mk"
20238 [(set (match_operand:BND 0 "register_operand")
20242 [(match_operand:<bnd_ptr> 1 "register_operand")
20243 (match_operand:<bnd_ptr> 2 "address_mpx_no_base_operand")]))]
20247 operands[3] = gen_rtx_UNSPEC (Pmode, gen_rtvec (2, operands[1],
20249 UNSPEC_BNDMK_ADDR);
20252 (define_insn "*<mode>_mk"
20253 [(set (match_operand:BND 0 "register_operand" "=w")
20255 [(match_operator:<bnd_ptr> 3 "bnd_mem_operator"
20257 [(match_operand:<bnd_ptr> 1 "register_operand" "r")
20258 (match_operand:<bnd_ptr> 2 "address_mpx_no_base_operand" "Tb")]
20259 UNSPEC_BNDMK_ADDR)])]
20262 "bndmk\t{%3, %0|%0, %3}"
20263 [(set_attr "type" "mpxmk")])
20265 (define_expand "mov<mode>"
20266 [(set (match_operand:BND 0 "general_operand")
20267 (match_operand:BND 1 "general_operand"))]
20269 "ix86_expand_move (<MODE>mode, operands); DONE;")
20271 (define_insn "*mov<mode>_internal_mpx"
20272 [(set (match_operand:BND 0 "nonimmediate_operand" "=w,m")
20273 (match_operand:BND 1 "general_operand" "wm,w"))]
20275 "bndmov\t{%1, %0|%0, %1}"
20276 [(set_attr "type" "mpxmov")])
20278 (define_expand "<mode>_<bndcheck>"
20281 [(match_operand:BND 0 "register_operand")
20282 (match_operand:<bnd_ptr> 1 "address_no_seg_operand")] BNDCHECK)
20284 (unspec:BLK [(match_dup 2)] UNSPEC_MPX_FENCE))])]
20287 operands[2] = gen_rtx_MEM (BLKmode, operands[1]);
20288 MEM_VOLATILE_P (operands[2]) = 1;
20291 (define_insn "*<mode>_<bndcheck>"
20293 [(match_operand:BND 0 "register_operand" "w")
20294 (match_operand:<bnd_ptr> 1 "address_no_seg_operand" "Ts")] BNDCHECK)
20295 (set (match_operand:BLK 2 "bnd_mem_operator")
20296 (unspec:BLK [(match_dup 2)] UNSPEC_MPX_FENCE))]
20298 "bnd<bndcheck>\t{%a1, %0|%0, %a1}"
20299 [(set_attr "type" "mpxchk")])
20301 (define_expand "<mode>_ldx"
20303 [(set (match_operand:BND 0 "register_operand")
20307 [(match_operand:<bnd_ptr> 1 "address_mpx_no_index_operand")
20308 (match_operand:<bnd_ptr> 2 "register_operand")]))]
20310 (use (mem:BLK (match_dup 1)))])]
20313 /* Avoid registers which cannot be used as index. */
20314 if (!index_register_operand (operands[2], Pmode))
20315 operands[2] = copy_addr_to_reg (operands[2]);
20317 operands[3] = gen_rtx_UNSPEC (Pmode, gen_rtvec (2, operands[1],
20319 UNSPEC_BNDLDX_ADDR);
20322 (define_insn "*<mode>_ldx"
20323 [(set (match_operand:BND 0 "register_operand" "=w")
20325 [(match_operator:<bnd_ptr> 3 "bnd_mem_operator"
20327 [(match_operand:<bnd_ptr> 1 "address_mpx_no_index_operand" "Ti")
20328 (match_operand:<bnd_ptr> 2 "register_operand" "l")]
20329 UNSPEC_BNDLDX_ADDR)])]
20331 (use (mem:BLK (match_dup 1)))]
20333 "bndldx\t{%3, %0|%0, %3}"
20334 [(set_attr "type" "mpxld")])
20336 (define_expand "<mode>_stx"
20341 [(match_operand:<bnd_ptr> 0 "address_mpx_no_index_operand")
20342 (match_operand:<bnd_ptr> 1 "register_operand")]))
20343 (match_operand:BND 2 "register_operand")]
20346 (unspec:BLK [(match_dup 4)] UNSPEC_MPX_FENCE))])]
20349 /* Avoid registers which cannot be used as index. */
20350 if (!index_register_operand (operands[1], Pmode))
20351 operands[1] = copy_addr_to_reg (operands[1]);
20353 operands[3] = gen_rtx_UNSPEC (Pmode, gen_rtvec (2, operands[0],
20355 UNSPEC_BNDLDX_ADDR);
20356 operands[4] = gen_rtx_MEM (BLKmode, operands[0]);
20357 MEM_VOLATILE_P (operands[4]) = 1;
20360 (define_insn "*<mode>_stx"
20362 [(match_operator:<bnd_ptr> 3 "bnd_mem_operator"
20364 [(match_operand:<bnd_ptr> 0 "address_mpx_no_index_operand" "Ti")
20365 (match_operand:<bnd_ptr> 1 "register_operand" "l")]
20366 UNSPEC_BNDLDX_ADDR)])
20367 (match_operand:BND 2 "register_operand" "w")]
20369 (set (match_operand:BLK 4 "bnd_mem_operator")
20370 (unspec:BLK [(match_dup 4)] UNSPEC_MPX_FENCE))]
20372 "bndstx\t{%2, %3|%3, %2}"
20373 [(set_attr "type" "mpxst")])
20375 (define_insn "move_size_reloc_<mode>"
20376 [(set (match_operand:SWI48 0 "register_operand" "=r")
20378 [(match_operand:SWI48 1 "symbol_operand")]
20382 if (x86_64_immediate_size_operand (operands[1], VOIDmode))
20383 return "mov{l}\t{%1@SIZE, %k0|%k0, %1@SIZE}";
20385 return "movabs{q}\t{%1@SIZE, %0|%0, %1@SIZE}";
20387 [(set_attr "type" "imov")
20388 (set_attr "mode" "<MODE>")])
20390 ;; RDPKRU and WRPKRU
20392 (define_expand "rdpkru"
20394 [(set (match_operand:SI 0 "register_operand")
20395 (unspec_volatile:SI [(match_dup 1)] UNSPECV_PKU))
20396 (set (match_dup 2) (const_int 0))])]
20399 operands[1] = force_reg (SImode, const0_rtx);
20400 operands[2] = gen_reg_rtx (SImode);
20403 (define_insn "*rdpkru"
20404 [(set (match_operand:SI 0 "register_operand" "=a")
20405 (unspec_volatile:SI [(match_operand:SI 2 "register_operand" "c")]
20407 (set (match_operand:SI 1 "register_operand" "=d")
20411 [(set_attr "type" "other")])
20413 (define_expand "wrpkru"
20414 [(unspec_volatile:SI
20415 [(match_operand:SI 0 "register_operand")
20416 (match_dup 1) (match_dup 2)] UNSPECV_PKU)]
20419 operands[1] = force_reg (SImode, const0_rtx);
20420 operands[2] = force_reg (SImode, const0_rtx);
20423 (define_insn "*wrpkru"
20424 [(unspec_volatile:SI
20425 [(match_operand:SI 0 "register_operand" "a")
20426 (match_operand:SI 1 "register_operand" "d")
20427 (match_operand:SI 2 "register_operand" "c")] UNSPECV_PKU)]
20430 [(set_attr "type" "other")])
20432 (define_insn "rdpid"
20433 [(set (match_operand:SI 0 "register_operand" "=r")
20434 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDPID))]
20437 [(set_attr "type" "other")])
20441 (include "sync.md")