1 ;; GCC machine description for IA-32 and x86-64.
2 ;; Copyright (C) 1988-2018 Free Software Foundation, Inc.
3 ;; Mostly by William Schelter.
4 ;; x86_64 support added by Jan Hubicka
6 ;; This file is part of GCC.
8 ;; GCC is free software; you can redistribute it and/or modify
9 ;; it under the terms of the GNU General Public License as published by
10 ;; the Free Software Foundation; either version 3, or (at your option)
13 ;; GCC is distributed in the hope that it will be useful,
14 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
15 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 ;; GNU General Public License for more details.
18 ;; You should have received a copy of the GNU General Public License
19 ;; along with GCC; see the file COPYING3. If not see
20 ;; <http://www.gnu.org/licenses/>. */
22 ;; The original PO technology requires these to be ordered by speed,
23 ;; so that assigner will pick the fastest.
25 ;; See file "rtl.def" for documentation on define_insn, match_*, et. al.
27 ;; The special asm out single letter directives following a '%' are:
28 ;; L,W,B,Q,S,T -- print the opcode suffix for specified size of operand.
29 ;; C -- print opcode suffix for set/cmov insn.
30 ;; c -- like C, but print reversed condition
31 ;; F,f -- likewise, but for floating-point.
32 ;; O -- if HAVE_AS_IX86_CMOV_SUN_SYNTAX, expand to "w.", "l." or "q.",
34 ;; R -- print the prefix for register names.
35 ;; z -- print the opcode suffix for the size of the current operand.
36 ;; Z -- likewise, with special suffixes for x87 instructions.
37 ;; * -- print a star (in certain assembler syntax)
38 ;; A -- print an absolute memory reference.
39 ;; E -- print address with DImode register names if TARGET_64BIT.
40 ;; w -- print the operand as if it's a "word" (HImode) even if it isn't.
41 ;; s -- print a shift double count, followed by the assemblers argument
43 ;; b -- print the QImode name of the register for the indicated operand.
44 ;; %b0 would print %al if operands[0] is reg 0.
45 ;; w -- likewise, print the HImode name of the register.
46 ;; k -- likewise, print the SImode name of the register.
47 ;; q -- likewise, print the DImode name of the register.
48 ;; x -- likewise, print the V4SFmode name of the register.
49 ;; t -- likewise, print the V8SFmode name of the register.
50 ;; h -- print the QImode name for a "high" register, either ah, bh, ch or dh.
51 ;; y -- print "st(0)" instead of "st" as a register.
52 ;; d -- print duplicated register operand for AVX instruction.
53 ;; D -- print condition for SSE cmp instruction.
54 ;; P -- if PIC, print an @PLT suffix.
55 ;; p -- print raw symbol name.
56 ;; X -- don't print any sort of PIC '@' suffix for a symbol.
57 ;; & -- print some in-use local-dynamic symbol name.
58 ;; H -- print a memory address offset by 8; used for sse high-parts
59 ;; K -- print HLE lock prefix
60 ;; Y -- print condition for XOP pcom* instruction.
61 ;; + -- print a branch hint as 'cs' or 'ds' prefix
62 ;; ; -- print a semicolon (after prefixes due to bug in older gas).
63 ;; ~ -- print "i" if TARGET_AVX2, "f" otherwise.
64 ;; ^ -- print addr32 prefix if TARGET_64BIT and Pmode != word_mode
65 ;; ! -- print MPX or NOTRACK prefix for jxx/call/ret instructions if required.
67 (define_c_enum "unspec" [
68 ;; Relocation specifiers
79 UNSPEC_MACHOPIC_OFFSET
88 UNSPEC_MEMORY_BLOCKAGE
98 ;; Other random patterns
107 UNSPEC_LD_MPIC ; load_macho_picbase
109 UNSPEC_DIV_ALREADY_SPLIT
115 UNSPEC_INSN_FALSE_DEP
118 ;; For SSE/MMX support:
126 ;; Generic math support
128 UNSPEC_IEEE_MIN ; not commutative
129 UNSPEC_IEEE_MAX ; not commutative
131 ;; x87 Floating point
147 UNSPEC_FRNDINT_MASK_PM
151 ;; x87 Double output FP
176 ;; For LZCNT suppoprt
198 UNSPEC_INTERRUPT_RETURN
201 (define_c_enum "unspecv" [
205 UNSPECV_PROBE_STACK_RANGE
208 UNSPECV_SPLIT_STACK_RETURN
214 UNSPECV_LLWP_INTRINSIC
215 UNSPECV_SLWP_INTRINSIC
216 UNSPECV_LWPVAL_INTRINSIC
217 UNSPECV_LWPINS_INTRINSIC
243 ;; For atomic compound assignments.
249 ;; For RDRAND support
252 ;; For RDSEED support
266 ;; For CLFLUSHOPT support
269 ;; For MONITORX and MWAITX support
273 ;; For CLZERO support
276 ;; For RDPKRU and WRPKRU support
296 ;; Constants to represent rounding modes in the ROUND instruction
305 ;; Constants to represent AVX512F embeded rounding
307 [(ROUND_NEAREST_INT 0)
315 ;; Constants to represent pcomtrue/pcomfalse variants
325 ;; Constants used in the XOP pperm instruction
327 [(PPERM_SRC 0x00) /* copy source */
328 (PPERM_INVERT 0x20) /* invert source */
329 (PPERM_REVERSE 0x40) /* bit reverse source */
330 (PPERM_REV_INV 0x60) /* bit reverse & invert src */
331 (PPERM_ZERO 0x80) /* all 0's */
332 (PPERM_ONES 0xa0) /* all 1's */
333 (PPERM_SIGN 0xc0) /* propagate sign bit */
334 (PPERM_INV_SIGN 0xe0) /* invert & propagate sign */
335 (PPERM_SRC1 0x00) /* use first source byte */
336 (PPERM_SRC2 0x10) /* use second source byte */
339 ;; Registers by name.
422 (FIRST_PSEUDO_REG 81)
425 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
428 ;; In C guard expressions, put expressions which may be compile-time
429 ;; constants first. This allows for better optimization. For
430 ;; example, write "TARGET_64BIT && reload_completed", not
431 ;; "reload_completed && TARGET_64BIT".
435 (define_attr "cpu" "none,pentium,pentiumpro,geode,k6,athlon,k8,core2,nehalem,
436 atom,slm,haswell,generic,amdfam10,bdver1,bdver2,bdver3,
437 bdver4,btver2,znver1"
438 (const (symbol_ref "ix86_schedule")))
440 ;; A basic instruction type. Refinements due to arguments to be
441 ;; provided in other attributes.
444 alu,alu1,negnot,imov,imovx,lea,
445 incdec,ishift,ishiftx,ishift1,rotate,rotatex,rotate1,
446 imul,imulx,idiv,icmp,test,ibr,setcc,icmov,
447 push,pop,call,callv,leave,
449 fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,
450 fxch,fistp,fisttp,frndint,
451 sse,ssemov,sseadd,sseadd1,sseiadd,sseiadd1,
452 ssemul,sseimul,ssediv,sselog,sselog1,
453 sseishft,sseishft1,ssecmp,ssecomi,
454 ssecvt,ssecvt1,sseicvt,sseins,
455 sseshuf,sseshuf1,ssemuladd,sse4arg,
457 mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft,
458 mpxmov,mpxmk,mpxchk,mpxld,mpxst"
459 (const_string "other"))
461 ;; Main data type used by the insn
463 "unknown,none,QI,HI,SI,DI,TI,OI,XI,SF,DF,XF,TF,V16SF,V8SF,V4DF,V4SF,
465 (const_string "unknown"))
467 ;; The CPU unit operations uses.
468 (define_attr "unit" "integer,i387,sse,mmx,unknown"
469 (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,
470 fxch,fistp,fisttp,frndint")
471 (const_string "i387")
472 (eq_attr "type" "sse,ssemov,sseadd,sseadd1,sseiadd,sseiadd1,
473 ssemul,sseimul,ssediv,sselog,sselog1,
474 sseishft,sseishft1,ssecmp,ssecomi,
475 ssecvt,ssecvt1,sseicvt,sseins,
476 sseshuf,sseshuf1,ssemuladd,sse4arg,mskmov")
478 (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
480 (eq_attr "type" "other")
481 (const_string "unknown")]
482 (const_string "integer")))
484 ;; The (bounding maximum) length of an instruction immediate.
485 (define_attr "length_immediate" ""
486 (cond [(eq_attr "type" "incdec,setcc,icmov,str,lea,other,multi,idiv,leave,
487 bitmanip,imulx,msklog,mskmov,mpxmk,mpxmov,mpxchk,
490 (eq_attr "unit" "i387,sse,mmx")
492 (eq_attr "type" "alu,alu1,negnot,imovx,ishift,ishiftx,ishift1,
493 rotate,rotatex,rotate1,imul,icmp,push,pop")
494 (symbol_ref "ix86_attr_length_immediate_default (insn, true)")
495 (eq_attr "type" "imov,test")
496 (symbol_ref "ix86_attr_length_immediate_default (insn, false)")
497 (eq_attr "type" "call")
498 (if_then_else (match_operand 0 "constant_call_address_operand")
501 (eq_attr "type" "callv")
502 (if_then_else (match_operand 1 "constant_call_address_operand")
505 ;; We don't know the size before shorten_branches. Expect
506 ;; the instruction to fit for better scheduling.
507 (eq_attr "type" "ibr")
510 (symbol_ref "/* Update immediate_length and other attributes! */
511 gcc_unreachable (),1")))
513 ;; The (bounding maximum) length of an instruction address.
514 (define_attr "length_address" ""
515 (cond [(eq_attr "type" "str,other,multi,fxch")
517 (and (eq_attr "type" "call")
518 (match_operand 0 "constant_call_address_operand"))
520 (and (eq_attr "type" "callv")
521 (match_operand 1 "constant_call_address_operand"))
524 (symbol_ref "ix86_attr_length_address_default (insn)")))
526 ;; Set when length prefix is used.
527 (define_attr "prefix_data16" ""
528 (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
530 (eq_attr "mode" "HI")
532 (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF,TI"))
537 ;; Set when string REP prefix is used.
538 (define_attr "prefix_rep" ""
539 (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
541 (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
543 (and (eq_attr "type" "ibr,call,callv")
544 (match_test "ix86_bnd_prefixed_insn_p (insn)"))
549 ;; Set when 0f opcode prefix is used.
550 (define_attr "prefix_0f" ""
552 (ior (eq_attr "type" "imovx,setcc,icmov,bitmanip,msklog,mskmov,
553 mpxmk,mpxmov,mpxchk,mpxld,mpxst")
554 (eq_attr "unit" "sse,mmx"))
558 ;; Set when REX opcode prefix is used.
559 (define_attr "prefix_rex" ""
560 (cond [(not (match_test "TARGET_64BIT"))
562 (and (eq_attr "mode" "DI")
563 (and (eq_attr "type" "!push,pop,call,callv,leave,ibr")
564 (eq_attr "unit" "!mmx")))
566 (and (eq_attr "mode" "QI")
567 (match_test "x86_extended_QIreg_mentioned_p (insn)"))
569 (match_test "x86_extended_reg_mentioned_p (insn)")
571 (and (eq_attr "type" "imovx")
572 (match_operand:QI 1 "ext_QIreg_operand"))
577 ;; There are also additional prefixes in 3DNOW, SSSE3.
578 ;; ssemuladd,sse4arg default to 0f24/0f25 and DREX byte,
579 ;; sseiadd1,ssecvt1 to 0f7a with no DREX byte.
580 ;; 3DNOW has 0f0f prefix, SSSE3 and SSE4_{1,2} 0f38/0f3a.
581 (define_attr "prefix_extra" ""
582 (cond [(eq_attr "type" "ssemuladd,sse4arg")
584 (eq_attr "type" "sseiadd1,ssecvt1")
589 ;; Set when BND opcode prefix may be used.
590 (define_attr "maybe_prefix_bnd" "" (const_int 0))
592 ;; Prefix used: original, VEX or maybe VEX.
593 (define_attr "prefix" "orig,vex,maybe_vex,evex,maybe_evex"
594 (cond [(eq_attr "mode" "OI,V8SF,V4DF")
596 (eq_attr "mode" "XI,V16SF,V8DF")
597 (const_string "evex")
599 (const_string "orig")))
601 ;; VEX W bit is used.
602 (define_attr "prefix_vex_w" "" (const_int 0))
604 ;; The length of VEX prefix
605 ;; Only instructions with 0f prefix can have 2 byte VEX prefix,
606 ;; 0f38/0f3a prefixes can't. In i386.md 0f3[8a] is
607 ;; still prefix_0f 1, with prefix_extra 1.
608 (define_attr "length_vex" ""
609 (if_then_else (and (eq_attr "prefix_0f" "1")
610 (eq_attr "prefix_extra" "0"))
611 (if_then_else (eq_attr "prefix_vex_w" "1")
612 (symbol_ref "ix86_attr_length_vex_default (insn, true, true)")
613 (symbol_ref "ix86_attr_length_vex_default (insn, true, false)"))
614 (if_then_else (eq_attr "prefix_vex_w" "1")
615 (symbol_ref "ix86_attr_length_vex_default (insn, false, true)")
616 (symbol_ref "ix86_attr_length_vex_default (insn, false, false)"))))
618 ;; 4-bytes evex prefix and 1 byte opcode.
619 (define_attr "length_evex" "" (const_int 5))
621 ;; Set when modrm byte is used.
622 (define_attr "modrm" ""
623 (cond [(eq_attr "type" "str,leave")
625 (eq_attr "unit" "i387")
627 (and (eq_attr "type" "incdec")
628 (and (not (match_test "TARGET_64BIT"))
629 (ior (match_operand:SI 1 "register_operand")
630 (match_operand:HI 1 "register_operand"))))
632 (and (eq_attr "type" "push")
633 (not (match_operand 1 "memory_operand")))
635 (and (eq_attr "type" "pop")
636 (not (match_operand 0 "memory_operand")))
638 (and (eq_attr "type" "imov")
639 (and (not (eq_attr "mode" "DI"))
640 (ior (and (match_operand 0 "register_operand")
641 (match_operand 1 "immediate_operand"))
642 (ior (and (match_operand 0 "ax_reg_operand")
643 (match_operand 1 "memory_displacement_only_operand"))
644 (and (match_operand 0 "memory_displacement_only_operand")
645 (match_operand 1 "ax_reg_operand"))))))
647 (and (eq_attr "type" "call")
648 (match_operand 0 "constant_call_address_operand"))
650 (and (eq_attr "type" "callv")
651 (match_operand 1 "constant_call_address_operand"))
653 (and (eq_attr "type" "alu,alu1,icmp,test")
654 (match_operand 0 "ax_reg_operand"))
655 (symbol_ref "(get_attr_length_immediate (insn) <= (get_attr_mode (insn) != MODE_QI))")
659 (define_attr "modrm_class" "none,incdec,op0,op01,op02,pushpop,unknown"
660 (cond [(eq_attr "modrm" "0")
661 (const_string "none")
662 (eq_attr "type" "alu,imul,ishift")
663 (const_string "op02")
664 (eq_attr "type" "imov,imovx,lea,alu1,icmp")
665 (const_string "op01")
666 (eq_attr "type" "incdec")
667 (const_string "incdec")
668 (eq_attr "type" "push,pop")
669 (const_string "pushpop")]
670 (const_string "unknown")))
672 ;; The (bounding maximum) length of an instruction in bytes.
673 ;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
674 ;; Later we may want to split them and compute proper length as for
676 (define_attr "length" ""
677 (cond [(eq_attr "type" "other,multi,fistp,frndint")
679 (eq_attr "type" "fcmp")
681 (eq_attr "unit" "i387")
683 (plus (attr "prefix_data16")
684 (attr "length_address")))
685 (ior (eq_attr "prefix" "evex")
686 (and (ior (eq_attr "prefix" "maybe_evex")
687 (eq_attr "prefix" "maybe_vex"))
688 (match_test "TARGET_AVX512F")))
689 (plus (attr "length_evex")
690 (plus (attr "length_immediate")
692 (attr "length_address"))))
693 (ior (eq_attr "prefix" "vex")
694 (and (ior (eq_attr "prefix" "maybe_vex")
695 (eq_attr "prefix" "maybe_evex"))
696 (match_test "TARGET_AVX")))
697 (plus (attr "length_vex")
698 (plus (attr "length_immediate")
700 (attr "length_address"))))]
701 (plus (plus (attr "modrm")
702 (plus (attr "prefix_0f")
703 (plus (attr "prefix_rex")
704 (plus (attr "prefix_extra")
706 (plus (attr "prefix_rep")
707 (plus (attr "prefix_data16")
708 (plus (attr "length_immediate")
709 (attr "length_address")))))))
711 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
712 ;; `store' if there is a simple memory reference therein, or `unknown'
713 ;; if the instruction is complex.
715 (define_attr "memory" "none,load,store,both,unknown"
716 (cond [(eq_attr "type" "other,multi,str,lwp")
717 (const_string "unknown")
718 (eq_attr "type" "lea,fcmov,fpspc,mpxmk,mpxchk")
719 (const_string "none")
720 (eq_attr "type" "fistp,leave")
721 (const_string "both")
722 (eq_attr "type" "frndint")
723 (const_string "load")
724 (eq_attr "type" "mpxld")
725 (const_string "load")
726 (eq_attr "type" "mpxst")
727 (const_string "store")
728 (eq_attr "type" "push")
729 (if_then_else (match_operand 1 "memory_operand")
730 (const_string "both")
731 (const_string "store"))
732 (eq_attr "type" "pop")
733 (if_then_else (match_operand 0 "memory_operand")
734 (const_string "both")
735 (const_string "load"))
736 (eq_attr "type" "setcc")
737 (if_then_else (match_operand 0 "memory_operand")
738 (const_string "store")
739 (const_string "none"))
740 (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
741 (if_then_else (ior (match_operand 0 "memory_operand")
742 (match_operand 1 "memory_operand"))
743 (const_string "load")
744 (const_string "none"))
745 (eq_attr "type" "ibr")
746 (if_then_else (match_operand 0 "memory_operand")
747 (const_string "load")
748 (const_string "none"))
749 (eq_attr "type" "call")
750 (if_then_else (match_operand 0 "constant_call_address_operand")
751 (const_string "none")
752 (const_string "load"))
753 (eq_attr "type" "callv")
754 (if_then_else (match_operand 1 "constant_call_address_operand")
755 (const_string "none")
756 (const_string "load"))
757 (and (eq_attr "type" "alu1,negnot,ishift1,rotate1,sselog1,sseshuf1")
758 (match_operand 1 "memory_operand"))
759 (const_string "both")
760 (and (match_operand 0 "memory_operand")
761 (match_operand 1 "memory_operand"))
762 (const_string "both")
763 (match_operand 0 "memory_operand")
764 (const_string "store")
765 (match_operand 1 "memory_operand")
766 (const_string "load")
768 "!alu1,negnot,ishift1,rotate1,
769 imov,imovx,icmp,test,bitmanip,
771 sse,ssemov,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,
772 sselog1,sseshuf1,sseadd1,sseiadd1,sseishft1,
773 mmx,mmxmov,mmxcmp,mmxcvt,mskmov,msklog,mpxmov")
774 (match_operand 2 "memory_operand"))
775 (const_string "load")
776 (and (eq_attr "type" "icmov,ssemuladd,sse4arg")
777 (match_operand 3 "memory_operand"))
778 (const_string "load")
780 (const_string "none")))
782 ;; Indicates if an instruction has both an immediate and a displacement.
784 (define_attr "imm_disp" "false,true,unknown"
785 (cond [(eq_attr "type" "other,multi")
786 (const_string "unknown")
787 (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
788 (and (match_operand 0 "memory_displacement_operand")
789 (match_operand 1 "immediate_operand")))
790 (const_string "true")
791 (and (eq_attr "type" "alu,ishift,ishiftx,rotate,rotatex,imul,idiv")
792 (and (match_operand 0 "memory_displacement_operand")
793 (match_operand 2 "immediate_operand")))
794 (const_string "true")
796 (const_string "false")))
798 ;; Indicates if an FP operation has an integer source.
800 (define_attr "fp_int_src" "false,true"
801 (const_string "false"))
803 ;; Defines rounding mode of an FP operation.
805 (define_attr "i387_cw" "trunc,floor,ceil,mask_pm,uninitialized,any"
806 (const_string "any"))
808 ;; Define attribute to classify add/sub insns that consumes carry flag (CF)
809 (define_attr "use_carry" "0,1" (const_string "0"))
811 ;; Define attribute to indicate unaligned ssemov insns
812 (define_attr "movu" "0,1" (const_string "0"))
814 ;; Used to control the "enabled" attribute on a per-instruction basis.
815 (define_attr "isa" "base,x64,x64_sse4,x64_sse4_noavx,x64_avx,nox64,
816 sse2,sse2_noavx,sse3,sse4,sse4_noavx,avx,noavx,
817 avx2,noavx2,bmi,bmi2,fma4,fma,avx512f,noavx512f,
818 avx512bw,noavx512bw,avx512dq,noavx512dq,
819 avx512vl,noavx512vl,x64_avx512dq,x64_avx512bw"
820 (const_string "base"))
822 (define_attr "enabled" ""
823 (cond [(eq_attr "isa" "x64") (symbol_ref "TARGET_64BIT")
824 (eq_attr "isa" "x64_sse4")
825 (symbol_ref "TARGET_64BIT && TARGET_SSE4_1")
826 (eq_attr "isa" "x64_sse4_noavx")
827 (symbol_ref "TARGET_64BIT && TARGET_SSE4_1 && !TARGET_AVX")
828 (eq_attr "isa" "x64_avx")
829 (symbol_ref "TARGET_64BIT && TARGET_AVX")
830 (eq_attr "isa" "x64_avx512dq")
831 (symbol_ref "TARGET_64BIT && TARGET_AVX512DQ")
832 (eq_attr "isa" "x64_avx512bw")
833 (symbol_ref "TARGET_64BIT && TARGET_AVX512BW")
834 (eq_attr "isa" "nox64") (symbol_ref "!TARGET_64BIT")
835 (eq_attr "isa" "sse2") (symbol_ref "TARGET_SSE2")
836 (eq_attr "isa" "sse2_noavx")
837 (symbol_ref "TARGET_SSE2 && !TARGET_AVX")
838 (eq_attr "isa" "sse3") (symbol_ref "TARGET_SSE3")
839 (eq_attr "isa" "sse4") (symbol_ref "TARGET_SSE4_1")
840 (eq_attr "isa" "sse4_noavx")
841 (symbol_ref "TARGET_SSE4_1 && !TARGET_AVX")
842 (eq_attr "isa" "avx") (symbol_ref "TARGET_AVX")
843 (eq_attr "isa" "noavx") (symbol_ref "!TARGET_AVX")
844 (eq_attr "isa" "avx2") (symbol_ref "TARGET_AVX2")
845 (eq_attr "isa" "noavx2") (symbol_ref "!TARGET_AVX2")
846 (eq_attr "isa" "bmi") (symbol_ref "TARGET_BMI")
847 (eq_attr "isa" "bmi2") (symbol_ref "TARGET_BMI2")
848 (eq_attr "isa" "fma4") (symbol_ref "TARGET_FMA4")
849 (eq_attr "isa" "fma") (symbol_ref "TARGET_FMA")
850 (eq_attr "isa" "avx512f") (symbol_ref "TARGET_AVX512F")
851 (eq_attr "isa" "noavx512f") (symbol_ref "!TARGET_AVX512F")
852 (eq_attr "isa" "avx512bw") (symbol_ref "TARGET_AVX512BW")
853 (eq_attr "isa" "noavx512bw") (symbol_ref "!TARGET_AVX512BW")
854 (eq_attr "isa" "avx512dq") (symbol_ref "TARGET_AVX512DQ")
855 (eq_attr "isa" "noavx512dq") (symbol_ref "!TARGET_AVX512DQ")
856 (eq_attr "isa" "avx512vl") (symbol_ref "TARGET_AVX512VL")
857 (eq_attr "isa" "noavx512vl") (symbol_ref "!TARGET_AVX512VL")
861 (define_attr "preferred_for_size" "" (const_int 1))
862 (define_attr "preferred_for_speed" "" (const_int 1))
864 ;; Describe a user's asm statement.
865 (define_asm_attributes
866 [(set_attr "length" "128")
867 (set_attr "type" "multi")])
869 (define_code_iterator plusminus [plus minus])
871 (define_code_iterator sat_plusminus [ss_plus us_plus ss_minus us_minus])
873 (define_code_iterator multdiv [mult div])
875 ;; Base name for define_insn
876 (define_code_attr plusminus_insn
877 [(plus "add") (ss_plus "ssadd") (us_plus "usadd")
878 (minus "sub") (ss_minus "sssub") (us_minus "ussub")])
880 ;; Base name for insn mnemonic.
881 (define_code_attr plusminus_mnemonic
882 [(plus "add") (ss_plus "adds") (us_plus "addus")
883 (minus "sub") (ss_minus "subs") (us_minus "subus")])
884 (define_code_attr multdiv_mnemonic
885 [(mult "mul") (div "div")])
887 ;; Mark commutative operators as such in constraints.
888 (define_code_attr comm [(plus "%") (ss_plus "%") (us_plus "%")
889 (minus "") (ss_minus "") (us_minus "")])
891 ;; Mapping of max and min
892 (define_code_iterator maxmin [smax smin umax umin])
894 ;; Mapping of signed max and min
895 (define_code_iterator smaxmin [smax smin])
897 ;; Mapping of unsigned max and min
898 (define_code_iterator umaxmin [umax umin])
900 ;; Base name for integer and FP insn mnemonic
901 (define_code_attr maxmin_int [(smax "maxs") (smin "mins")
902 (umax "maxu") (umin "minu")])
903 (define_code_attr maxmin_float [(smax "max") (smin "min")])
905 (define_int_iterator IEEE_MAXMIN
909 (define_int_attr ieee_maxmin
910 [(UNSPEC_IEEE_MAX "max")
911 (UNSPEC_IEEE_MIN "min")])
913 ;; Mapping of logic operators
914 (define_code_iterator any_logic [and ior xor])
915 (define_code_iterator any_or [ior xor])
916 (define_code_iterator fpint_logic [and xor])
918 ;; Base name for insn mnemonic.
919 (define_code_attr logic [(and "and") (ior "or") (xor "xor")])
921 ;; Mapping of logic-shift operators
922 (define_code_iterator any_lshift [ashift lshiftrt])
924 ;; Mapping of shift-right operators
925 (define_code_iterator any_shiftrt [lshiftrt ashiftrt])
927 ;; Mapping of all shift operators
928 (define_code_iterator any_shift [ashift lshiftrt ashiftrt])
930 ;; Base name for define_insn
931 (define_code_attr shift_insn
932 [(ashift "ashl") (lshiftrt "lshr") (ashiftrt "ashr")])
934 ;; Base name for insn mnemonic.
935 (define_code_attr shift [(ashift "sll") (lshiftrt "shr") (ashiftrt "sar")])
936 (define_code_attr vshift [(ashift "sll") (lshiftrt "srl") (ashiftrt "sra")])
938 ;; Mapping of rotate operators
939 (define_code_iterator any_rotate [rotate rotatert])
941 ;; Base name for define_insn
942 (define_code_attr rotate_insn [(rotate "rotl") (rotatert "rotr")])
944 ;; Base name for insn mnemonic.
945 (define_code_attr rotate [(rotate "rol") (rotatert "ror")])
947 ;; Mapping of abs neg operators
948 (define_code_iterator absneg [abs neg])
950 ;; Base name for x87 insn mnemonic.
951 (define_code_attr absneg_mnemonic [(abs "abs") (neg "chs")])
953 ;; Used in signed and unsigned widening multiplications.
954 (define_code_iterator any_extend [sign_extend zero_extend])
956 ;; Prefix for insn menmonic.
957 (define_code_attr sgnprefix [(sign_extend "i") (zero_extend "")])
959 ;; Prefix for define_insn
960 (define_code_attr u [(sign_extend "") (zero_extend "u")])
961 (define_code_attr s [(sign_extend "s") (zero_extend "u")])
962 (define_code_attr u_bool [(sign_extend "false") (zero_extend "true")])
964 ;; Used in signed and unsigned truncations.
965 (define_code_iterator any_truncate [ss_truncate truncate us_truncate])
966 ;; Instruction suffix for truncations.
967 (define_code_attr trunsuffix [(ss_truncate "s") (truncate "") (us_truncate "us")])
969 ;; Used in signed and unsigned fix.
970 (define_code_iterator any_fix [fix unsigned_fix])
971 (define_code_attr fixsuffix [(fix "") (unsigned_fix "u")])
973 ;; Used in signed and unsigned float.
974 (define_code_iterator any_float [float unsigned_float])
975 (define_code_attr floatsuffix [(float "") (unsigned_float "u")])
977 ;; All integer modes.
978 (define_mode_iterator SWI1248x [QI HI SI DI])
980 ;; All integer modes without QImode.
981 (define_mode_iterator SWI248x [HI SI DI])
983 ;; All integer modes without QImode and HImode.
984 (define_mode_iterator SWI48x [SI DI])
986 ;; All integer modes without SImode and DImode.
987 (define_mode_iterator SWI12 [QI HI])
989 ;; All integer modes without DImode.
990 (define_mode_iterator SWI124 [QI HI SI])
992 ;; All integer modes without QImode and DImode.
993 (define_mode_iterator SWI24 [HI SI])
995 ;; Single word integer modes.
996 (define_mode_iterator SWI [QI HI SI (DI "TARGET_64BIT")])
998 ;; Single word integer modes without QImode.
999 (define_mode_iterator SWI248 [HI SI (DI "TARGET_64BIT")])
1001 ;; Single word integer modes without QImode and HImode.
1002 (define_mode_iterator SWI48 [SI (DI "TARGET_64BIT")])
1004 ;; All math-dependant single and double word integer modes.
1005 (define_mode_iterator SDWIM [(QI "TARGET_QIMODE_MATH")
1006 (HI "TARGET_HIMODE_MATH")
1007 SI DI (TI "TARGET_64BIT")])
1009 ;; Math-dependant single word integer modes.
1010 (define_mode_iterator SWIM [(QI "TARGET_QIMODE_MATH")
1011 (HI "TARGET_HIMODE_MATH")
1012 SI (DI "TARGET_64BIT")])
1014 ;; Math-dependant integer modes without DImode.
1015 (define_mode_iterator SWIM124 [(QI "TARGET_QIMODE_MATH")
1016 (HI "TARGET_HIMODE_MATH")
1019 ;; Math-dependant integer modes with DImode.
1020 (define_mode_iterator SWIM1248x [(QI "TARGET_QIMODE_MATH")
1021 (HI "TARGET_HIMODE_MATH")
1022 SI (DI "(TARGET_STV && TARGET_SSE2) || TARGET_64BIT")])
1024 ;; Math-dependant single word integer modes without QImode.
1025 (define_mode_iterator SWIM248 [(HI "TARGET_HIMODE_MATH")
1026 SI (DI "TARGET_64BIT")])
1028 ;; Double word integer modes.
1029 (define_mode_iterator DWI [(DI "!TARGET_64BIT")
1030 (TI "TARGET_64BIT")])
1032 ;; GET_MODE_SIZE for selected modes. As GET_MODE_SIZE is not
1033 ;; compile time constant, it is faster to use <MODE_SIZE> than
1034 ;; GET_MODE_SIZE (<MODE>mode). For XFmode which depends on
1035 ;; command line options just use GET_MODE_SIZE macro.
1036 (define_mode_attr MODE_SIZE [(QI "1") (HI "2") (SI "4") (DI "8") (TI "16")
1037 (SF "4") (DF "8") (XF "GET_MODE_SIZE (XFmode)")
1038 (V16QI "16") (V32QI "32") (V64QI "64")
1039 (V8HI "16") (V16HI "32") (V32HI "64")
1040 (V4SI "16") (V8SI "32") (V16SI "64")
1041 (V2DI "16") (V4DI "32") (V8DI "64")
1042 (V1TI "16") (V2TI "32") (V4TI "64")
1043 (V2DF "16") (V4DF "32") (V8DF "64")
1044 (V4SF "16") (V8SF "32") (V16SF "64")])
1046 ;; Double word integer modes as mode attribute.
1047 (define_mode_attr DWI [(QI "HI") (HI "SI") (SI "DI") (DI "TI")])
1048 (define_mode_attr dwi [(QI "hi") (HI "si") (SI "di") (DI "ti")])
1050 ;; LEA mode corresponding to an integer mode
1051 (define_mode_attr LEAMODE [(QI "SI") (HI "SI") (SI "SI") (DI "DI")])
1053 ;; Half mode for double word integer modes.
1054 (define_mode_iterator DWIH [(SI "!TARGET_64BIT")
1055 (DI "TARGET_64BIT")])
1058 (define_mode_iterator BND [(BND32 "!TARGET_LP64")
1059 (BND64 "TARGET_LP64")])
1061 ;; Pointer mode corresponding to bound mode.
1062 (define_mode_attr bnd_ptr [(BND32 "SI") (BND64 "DI")])
1065 (define_int_iterator BNDCHECK [UNSPEC_BNDCL UNSPEC_BNDCU UNSPEC_BNDCN])
1068 (define_int_attr bndcheck [(UNSPEC_BNDCL "cl")
1070 (UNSPEC_BNDCN "cn")])
1072 ;; Instruction suffix for integer modes.
1073 (define_mode_attr imodesuffix [(QI "b") (HI "w") (SI "l") (DI "q")])
1075 ;; Instruction suffix for masks.
1076 (define_mode_attr mskmodesuffix [(QI "b") (HI "w") (SI "d") (DI "q")])
1078 ;; Pointer size prefix for integer modes (Intel asm dialect)
1079 (define_mode_attr iptrsize [(QI "BYTE")
1084 ;; Register class for integer modes.
1085 (define_mode_attr r [(QI "q") (HI "r") (SI "r") (DI "r")])
1087 ;; Immediate operand constraint for integer modes.
1088 (define_mode_attr i [(QI "n") (HI "n") (SI "e") (DI "e")])
1090 ;; General operand constraint for word modes.
1091 (define_mode_attr g [(QI "qmn") (HI "rmn") (SI "rme") (DI "rme")])
1093 ;; Immediate operand constraint for double integer modes.
1094 (define_mode_attr di [(SI "nF") (DI "Wd")])
1096 ;; Immediate operand constraint for shifts.
1097 (define_mode_attr S [(QI "I") (HI "I") (SI "I") (DI "J") (TI "O")])
1099 ;; Print register name in the specified mode.
1100 (define_mode_attr k [(QI "b") (HI "w") (SI "k") (DI "q")])
1102 ;; General operand predicate for integer modes.
1103 (define_mode_attr general_operand
1104 [(QI "general_operand")
1105 (HI "general_operand")
1106 (SI "x86_64_general_operand")
1107 (DI "x86_64_general_operand")
1108 (TI "x86_64_general_operand")])
1110 ;; General operand predicate for integer modes, where for TImode
1111 ;; we need both words of the operand to be general operands.
1112 (define_mode_attr general_hilo_operand
1113 [(QI "general_operand")
1114 (HI "general_operand")
1115 (SI "x86_64_general_operand")
1116 (DI "x86_64_general_operand")
1117 (TI "x86_64_hilo_general_operand")])
1119 ;; General sign extend operand predicate for integer modes,
1120 ;; which disallows VOIDmode operands and thus it is suitable
1121 ;; for use inside sign_extend.
1122 (define_mode_attr general_sext_operand
1123 [(QI "sext_operand")
1125 (SI "x86_64_sext_operand")
1126 (DI "x86_64_sext_operand")])
1128 ;; General sign/zero extend operand predicate for integer modes.
1129 (define_mode_attr general_szext_operand
1130 [(QI "general_operand")
1131 (HI "general_operand")
1132 (SI "x86_64_szext_general_operand")
1133 (DI "x86_64_szext_general_operand")])
1135 ;; Immediate operand predicate for integer modes.
1136 (define_mode_attr immediate_operand
1137 [(QI "immediate_operand")
1138 (HI "immediate_operand")
1139 (SI "x86_64_immediate_operand")
1140 (DI "x86_64_immediate_operand")])
1142 ;; Nonmemory operand predicate for integer modes.
1143 (define_mode_attr nonmemory_operand
1144 [(QI "nonmemory_operand")
1145 (HI "nonmemory_operand")
1146 (SI "x86_64_nonmemory_operand")
1147 (DI "x86_64_nonmemory_operand")])
1149 ;; Operand predicate for shifts.
1150 (define_mode_attr shift_operand
1151 [(QI "nonimmediate_operand")
1152 (HI "nonimmediate_operand")
1153 (SI "nonimmediate_operand")
1154 (DI "shiftdi_operand")
1155 (TI "register_operand")])
1157 ;; Operand predicate for shift argument.
1158 (define_mode_attr shift_immediate_operand
1159 [(QI "const_1_to_31_operand")
1160 (HI "const_1_to_31_operand")
1161 (SI "const_1_to_31_operand")
1162 (DI "const_1_to_63_operand")])
1164 ;; Input operand predicate for arithmetic left shifts.
1165 (define_mode_attr ashl_input_operand
1166 [(QI "nonimmediate_operand")
1167 (HI "nonimmediate_operand")
1168 (SI "nonimmediate_operand")
1169 (DI "ashldi_input_operand")
1170 (TI "reg_or_pm1_operand")])
1172 ;; SSE and x87 SFmode and DFmode floating point modes
1173 (define_mode_iterator MODEF [SF DF])
1175 ;; All x87 floating point modes
1176 (define_mode_iterator X87MODEF [SF DF XF])
1178 ;; SSE instruction suffix for various modes
1179 (define_mode_attr ssemodesuffix
1180 [(SF "ss") (DF "sd")
1181 (V16SF "ps") (V8DF "pd")
1182 (V8SF "ps") (V4DF "pd")
1183 (V4SF "ps") (V2DF "pd")
1184 (V16QI "b") (V8HI "w") (V4SI "d") (V2DI "q")
1185 (V32QI "b") (V16HI "w") (V8SI "d") (V4DI "q")
1186 (V64QI "b") (V32HI "w") (V16SI "d") (V8DI "q")])
1188 ;; SSE vector suffix for floating point modes
1189 (define_mode_attr ssevecmodesuffix [(SF "ps") (DF "pd")])
1191 ;; SSE vector mode corresponding to a scalar mode
1192 (define_mode_attr ssevecmode
1193 [(QI "V16QI") (HI "V8HI") (SI "V4SI") (DI "V2DI") (SF "V4SF") (DF "V2DF")])
1194 (define_mode_attr ssevecmodelower
1195 [(QI "v16qi") (HI "v8hi") (SI "v4si") (DI "v2di") (SF "v4sf") (DF "v2df")])
1197 ;; AVX512F vector mode corresponding to a scalar mode
1198 (define_mode_attr avx512fvecmode
1199 [(QI "V64QI") (HI "V32HI") (SI "V16SI") (DI "V8DI") (SF "V16SF") (DF "V8DF")])
1201 ;; Instruction suffix for REX 64bit operators.
1202 (define_mode_attr rex64suffix [(SI "") (DI "{q}")])
1204 ;; This mode iterator allows :P to be used for patterns that operate on
1205 ;; pointer-sized quantities. Exactly one of the two alternatives will match.
1206 (define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
1208 ;; This mode iterator allows :W to be used for patterns that operate on
1209 ;; word_mode sized quantities.
1210 (define_mode_iterator W
1211 [(SI "word_mode == SImode") (DI "word_mode == DImode")])
1213 ;; This mode iterator allows :PTR to be used for patterns that operate on
1214 ;; ptr_mode sized quantities.
1215 (define_mode_iterator PTR
1216 [(SI "ptr_mode == SImode") (DI "ptr_mode == DImode")])
1218 ;; Scheduling descriptions
1220 (include "pentium.md")
1223 (include "athlon.md")
1224 (include "bdver1.md")
1225 (include "bdver3.md")
1226 (include "btver2.md")
1227 (include "znver1.md")
1228 (include "geode.md")
1231 (include "core2.md")
1232 (include "haswell.md")
1235 ;; Operand and operator predicates and constraints
1237 (include "predicates.md")
1238 (include "constraints.md")
1241 ;; Compare and branch/compare and store instructions.
1243 (define_expand "cbranch<mode>4"
1244 [(set (reg:CC FLAGS_REG)
1245 (compare:CC (match_operand:SDWIM 1 "nonimmediate_operand")
1246 (match_operand:SDWIM 2 "<general_operand>")))
1247 (set (pc) (if_then_else
1248 (match_operator 0 "ordered_comparison_operator"
1249 [(reg:CC FLAGS_REG) (const_int 0)])
1250 (label_ref (match_operand 3))
1254 if (MEM_P (operands[1]) && MEM_P (operands[2]))
1255 operands[1] = force_reg (<MODE>mode, operands[1]);
1256 ix86_expand_branch (GET_CODE (operands[0]),
1257 operands[1], operands[2], operands[3]);
1261 (define_expand "cstore<mode>4"
1262 [(set (reg:CC FLAGS_REG)
1263 (compare:CC (match_operand:SWIM 2 "nonimmediate_operand")
1264 (match_operand:SWIM 3 "<general_operand>")))
1265 (set (match_operand:QI 0 "register_operand")
1266 (match_operator 1 "ordered_comparison_operator"
1267 [(reg:CC FLAGS_REG) (const_int 0)]))]
1270 if (MEM_P (operands[2]) && MEM_P (operands[3]))
1271 operands[2] = force_reg (<MODE>mode, operands[2]);
1272 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1273 operands[2], operands[3]);
1277 (define_expand "cmp<mode>_1"
1278 [(set (reg:CC FLAGS_REG)
1279 (compare:CC (match_operand:SWI48 0 "nonimmediate_operand")
1280 (match_operand:SWI48 1 "<general_operand>")))])
1282 (define_mode_iterator SWI1248_AVX512BWDQ2_64
1283 [(QI "TARGET_AVX512DQ") (HI "TARGET_AVX512DQ")
1284 (SI "TARGET_AVX512BW") (DI "TARGET_AVX512BW && TARGET_64BIT")])
1286 (define_insn "*cmp<mode>_ccz_1"
1287 [(set (reg FLAGS_REG)
1288 (compare (match_operand:SWI1248_AVX512BWDQ2_64 0
1289 "nonimmediate_operand" "<r>,?m<r>,$k")
1290 (match_operand:SWI1248_AVX512BWDQ2_64 1 "const0_operand")))]
1291 "ix86_match_ccmode (insn, CCZmode)"
1293 test{<imodesuffix>}\t%0, %0
1294 cmp{<imodesuffix>}\t{%1, %0|%0, %1}
1295 ktest<mskmodesuffix>\t%0, %0"
1296 [(set_attr "type" "test,icmp,msklog")
1297 (set_attr "length_immediate" "0,1,*")
1298 (set_attr "modrm_class" "op0,unknown,*")
1299 (set_attr "prefix" "*,*,vex")
1300 (set_attr "mode" "<MODE>")])
1302 (define_insn "*cmp<mode>_ccno_1"
1303 [(set (reg FLAGS_REG)
1304 (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>,?m<r>")
1305 (match_operand:SWI 1 "const0_operand")))]
1306 "ix86_match_ccmode (insn, CCNOmode)"
1308 test{<imodesuffix>}\t%0, %0
1309 cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1310 [(set_attr "type" "test,icmp")
1311 (set_attr "length_immediate" "0,1")
1312 (set_attr "modrm_class" "op0,unknown")
1313 (set_attr "mode" "<MODE>")])
1315 (define_insn "*cmp<mode>_1"
1316 [(set (reg FLAGS_REG)
1317 (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
1318 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m")))]
1319 "ix86_match_ccmode (insn, CCmode)"
1320 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1321 [(set_attr "type" "icmp")
1322 (set_attr "mode" "<MODE>")])
1324 (define_insn "*cmp<mode>_minus_1"
1325 [(set (reg FLAGS_REG)
1327 (minus:SWI (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
1328 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
1330 "ix86_match_ccmode (insn, CCGOCmode)"
1331 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1332 [(set_attr "type" "icmp")
1333 (set_attr "mode" "<MODE>")])
1335 (define_insn "*cmpqi_ext_1"
1336 [(set (reg FLAGS_REG)
1338 (match_operand:QI 0 "nonimmediate_operand" "QBc,m")
1341 (match_operand 1 "ext_register_operand" "Q,Q")
1343 (const_int 8)) 0)))]
1344 "ix86_match_ccmode (insn, CCmode)"
1345 "cmp{b}\t{%h1, %0|%0, %h1}"
1346 [(set_attr "isa" "*,nox64")
1347 (set_attr "type" "icmp")
1348 (set_attr "mode" "QI")])
1350 (define_insn "*cmpqi_ext_2"
1351 [(set (reg FLAGS_REG)
1355 (match_operand 0 "ext_register_operand" "Q")
1358 (match_operand:QI 1 "const0_operand")))]
1359 "ix86_match_ccmode (insn, CCNOmode)"
1361 [(set_attr "type" "test")
1362 (set_attr "length_immediate" "0")
1363 (set_attr "mode" "QI")])
1365 (define_expand "cmpqi_ext_3"
1366 [(set (reg:CC FLAGS_REG)
1370 (match_operand 0 "ext_register_operand")
1373 (match_operand:QI 1 "const_int_operand")))])
1375 (define_insn "*cmpqi_ext_3"
1376 [(set (reg FLAGS_REG)
1380 (match_operand 0 "ext_register_operand" "Q,Q")
1383 (match_operand:QI 1 "general_operand" "QnBc,m")))]
1384 "ix86_match_ccmode (insn, CCmode)"
1385 "cmp{b}\t{%1, %h0|%h0, %1}"
1386 [(set_attr "isa" "*,nox64")
1387 (set_attr "type" "icmp")
1388 (set_attr "mode" "QI")])
1390 (define_insn "*cmpqi_ext_4"
1391 [(set (reg FLAGS_REG)
1395 (match_operand 0 "ext_register_operand" "Q")
1400 (match_operand 1 "ext_register_operand" "Q")
1402 (const_int 8)) 0)))]
1403 "ix86_match_ccmode (insn, CCmode)"
1404 "cmp{b}\t{%h1, %h0|%h0, %h1}"
1405 [(set_attr "type" "icmp")
1406 (set_attr "mode" "QI")])
1408 ;; These implement float point compares.
1409 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
1410 ;; which would allow mix and match FP modes on the compares. Which is what
1411 ;; the old patterns did, but with many more of them.
1413 (define_expand "cbranchxf4"
1414 [(set (reg:CC FLAGS_REG)
1415 (compare:CC (match_operand:XF 1 "nonmemory_operand")
1416 (match_operand:XF 2 "nonmemory_operand")))
1417 (set (pc) (if_then_else
1418 (match_operator 0 "ix86_fp_comparison_operator"
1421 (label_ref (match_operand 3))
1425 ix86_expand_branch (GET_CODE (operands[0]),
1426 operands[1], operands[2], operands[3]);
1430 (define_expand "cstorexf4"
1431 [(set (reg:CC FLAGS_REG)
1432 (compare:CC (match_operand:XF 2 "nonmemory_operand")
1433 (match_operand:XF 3 "nonmemory_operand")))
1434 (set (match_operand:QI 0 "register_operand")
1435 (match_operator 1 "ix86_fp_comparison_operator"
1440 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1441 operands[2], operands[3]);
1445 (define_expand "cbranch<mode>4"
1446 [(set (reg:CC FLAGS_REG)
1447 (compare:CC (match_operand:MODEF 1 "cmp_fp_expander_operand")
1448 (match_operand:MODEF 2 "cmp_fp_expander_operand")))
1449 (set (pc) (if_then_else
1450 (match_operator 0 "ix86_fp_comparison_operator"
1453 (label_ref (match_operand 3))
1455 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1457 ix86_expand_branch (GET_CODE (operands[0]),
1458 operands[1], operands[2], operands[3]);
1462 (define_expand "cstore<mode>4"
1463 [(set (reg:CC FLAGS_REG)
1464 (compare:CC (match_operand:MODEF 2 "cmp_fp_expander_operand")
1465 (match_operand:MODEF 3 "cmp_fp_expander_operand")))
1466 (set (match_operand:QI 0 "register_operand")
1467 (match_operator 1 "ix86_fp_comparison_operator"
1470 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1472 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1473 operands[2], operands[3]);
1477 (define_expand "cbranchcc4"
1478 [(set (pc) (if_then_else
1479 (match_operator 0 "comparison_operator"
1480 [(match_operand 1 "flags_reg_operand")
1481 (match_operand 2 "const0_operand")])
1482 (label_ref (match_operand 3))
1486 ix86_expand_branch (GET_CODE (operands[0]),
1487 operands[1], operands[2], operands[3]);
1491 (define_expand "cstorecc4"
1492 [(set (match_operand:QI 0 "register_operand")
1493 (match_operator 1 "comparison_operator"
1494 [(match_operand 2 "flags_reg_operand")
1495 (match_operand 3 "const0_operand")]))]
1498 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1499 operands[2], operands[3]);
1504 ;; FP compares, step 1:
1505 ;; Set the FP condition codes.
1507 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
1508 ;; used to manage the reg stack popping would not be preserved.
1510 (define_insn "*cmp<mode>_0_i387"
1511 [(set (match_operand:HI 0 "register_operand" "=a")
1514 (match_operand:X87MODEF 1 "register_operand" "f")
1515 (match_operand:X87MODEF 2 "const0_operand"))]
1518 "* return output_fp_compare (insn, operands, false, false);"
1519 [(set_attr "type" "multi")
1520 (set_attr "unit" "i387")
1521 (set_attr "mode" "<MODE>")])
1523 (define_insn_and_split "*cmp<mode>_0_cc_i387"
1524 [(set (reg:CCFP FLAGS_REG)
1526 (match_operand:X87MODEF 1 "register_operand" "f")
1527 (match_operand:X87MODEF 2 "const0_operand")))
1528 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1529 "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE"
1531 "&& reload_completed"
1534 [(compare:CCFP (match_dup 1)(match_dup 2))]
1536 (set (reg:CC FLAGS_REG)
1537 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1539 [(set_attr "type" "multi")
1540 (set_attr "unit" "i387")
1541 (set_attr "mode" "<MODE>")])
1543 (define_insn "*cmpxf_i387"
1544 [(set (match_operand:HI 0 "register_operand" "=a")
1547 (match_operand:XF 1 "register_operand" "f")
1548 (match_operand:XF 2 "register_operand" "f"))]
1551 "* return output_fp_compare (insn, operands, false, false);"
1552 [(set_attr "type" "multi")
1553 (set_attr "unit" "i387")
1554 (set_attr "mode" "XF")])
1556 (define_insn_and_split "*cmpxf_cc_i387"
1557 [(set (reg:CCFP FLAGS_REG)
1559 (match_operand:XF 1 "register_operand" "f")
1560 (match_operand:XF 2 "register_operand" "f")))
1561 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1562 "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE"
1564 "&& reload_completed"
1567 [(compare:CCFP (match_dup 1)(match_dup 2))]
1569 (set (reg:CC FLAGS_REG)
1570 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1572 [(set_attr "type" "multi")
1573 (set_attr "unit" "i387")
1574 (set_attr "mode" "XF")])
1576 (define_insn "*cmp<mode>_i387"
1577 [(set (match_operand:HI 0 "register_operand" "=a")
1580 (match_operand:MODEF 1 "register_operand" "f")
1581 (match_operand:MODEF 2 "nonimmediate_operand" "fm"))]
1584 "* return output_fp_compare (insn, operands, false, false);"
1585 [(set_attr "type" "multi")
1586 (set_attr "unit" "i387")
1587 (set_attr "mode" "<MODE>")])
1589 (define_insn_and_split "*cmp<mode>_cc_i387"
1590 [(set (reg:CCFP FLAGS_REG)
1592 (match_operand:MODEF 1 "register_operand" "f")
1593 (match_operand:MODEF 2 "nonimmediate_operand" "fm")))
1594 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1595 "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE"
1597 "&& reload_completed"
1600 [(compare:CCFP (match_dup 1)(match_dup 2))]
1602 (set (reg:CC FLAGS_REG)
1603 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1605 [(set_attr "type" "multi")
1606 (set_attr "unit" "i387")
1607 (set_attr "mode" "<MODE>")])
1609 (define_insn "*cmpu<mode>_i387"
1610 [(set (match_operand:HI 0 "register_operand" "=a")
1614 (match_operand:X87MODEF 1 "register_operand" "f")
1615 (match_operand:X87MODEF 2 "register_operand" "f"))]
1619 "* return output_fp_compare (insn, operands, false, true);"
1620 [(set_attr "type" "multi")
1621 (set_attr "unit" "i387")
1622 (set_attr "mode" "<MODE>")])
1624 (define_insn_and_split "*cmpu<mode>_cc_i387"
1625 [(set (reg:CCFP FLAGS_REG)
1628 (match_operand:X87MODEF 1 "register_operand" "f")
1629 (match_operand:X87MODEF 2 "register_operand" "f"))]
1631 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1632 "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE"
1634 "&& reload_completed"
1638 [(compare:CCFP (match_dup 1)(match_dup 2))]
1641 (set (reg:CC FLAGS_REG)
1642 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1644 [(set_attr "type" "multi")
1645 (set_attr "unit" "i387")
1646 (set_attr "mode" "<MODE>")])
1648 (define_insn "*cmp<X87MODEF:mode>_<SWI24:mode>_i387"
1649 [(set (match_operand:HI 0 "register_operand" "=a")
1652 (match_operand:X87MODEF 1 "register_operand" "f")
1654 (match_operand:SWI24 2 "memory_operand" "m")))]
1657 && (TARGET_USE_<SWI24:MODE>MODE_FIOP
1658 || optimize_function_for_size_p (cfun))"
1659 "* return output_fp_compare (insn, operands, false, false);"
1660 [(set_attr "type" "multi")
1661 (set_attr "unit" "i387")
1662 (set_attr "fp_int_src" "true")
1663 (set_attr "mode" "<SWI24:MODE>")])
1665 (define_insn_and_split "*cmp<X87MODEF:mode>_<SWI24:mode>_cc_i387"
1666 [(set (reg:CCFP FLAGS_REG)
1668 (match_operand:X87MODEF 1 "register_operand" "f")
1670 (match_operand:SWI24 2 "memory_operand" "m"))))
1671 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1672 "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE
1673 && (TARGET_USE_<SWI24:MODE>MODE_FIOP
1674 || optimize_function_for_size_p (cfun))"
1676 "&& reload_completed"
1681 (float:X87MODEF (match_dup 2)))]
1683 (set (reg:CC FLAGS_REG)
1684 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1686 [(set_attr "type" "multi")
1687 (set_attr "unit" "i387")
1688 (set_attr "fp_int_src" "true")
1689 (set_attr "mode" "<SWI24:MODE>")])
1691 ;; FP compares, step 2
1692 ;; Move the fpsw to ax.
1694 (define_insn "x86_fnstsw_1"
1695 [(set (match_operand:HI 0 "register_operand" "=a")
1696 (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
1699 [(set_attr "length" "2")
1700 (set_attr "mode" "SI")
1701 (set_attr "unit" "i387")])
1703 ;; FP compares, step 3
1704 ;; Get ax into flags, general case.
1706 (define_insn "x86_sahf_1"
1707 [(set (reg:CC FLAGS_REG)
1708 (unspec:CC [(match_operand:HI 0 "register_operand" "a")]
1712 #ifndef HAVE_AS_IX86_SAHF
1714 return ASM_BYTE "0x9e";
1719 [(set_attr "length" "1")
1720 (set_attr "athlon_decode" "vector")
1721 (set_attr "amdfam10_decode" "direct")
1722 (set_attr "bdver1_decode" "direct")
1723 (set_attr "mode" "SI")])
1725 ;; Pentium Pro can do steps 1 through 3 in one go.
1726 ;; (these instructions set flags directly)
1728 (define_subst_attr "unord" "unord_subst" "" "u")
1729 (define_subst_attr "unordered" "unord_subst" "false" "true")
1731 (define_subst "unord_subst"
1732 [(set (match_operand:CCFP 0)
1733 (match_operand:CCFP 1))]
1740 (define_insn "*cmpi<unord><MODEF:mode>"
1741 [(set (reg:CCFP FLAGS_REG)
1743 (match_operand:MODEF 0 "register_operand" "f,v")
1744 (match_operand:MODEF 1 "register_ssemem_operand" "f,vm")))]
1745 "(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
1746 || (TARGET_80387 && TARGET_CMOVE)"
1748 * return output_fp_compare (insn, operands, true, <unordered>);
1749 %v<unord>comi<MODEF:ssemodesuffix>\t{%1, %0|%0, %1}"
1750 [(set_attr "type" "fcmp,ssecomi")
1751 (set_attr "prefix" "orig,maybe_vex")
1752 (set_attr "mode" "<MODEF:MODE>")
1753 (set_attr "prefix_rep" "*,0")
1754 (set (attr "prefix_data16")
1755 (cond [(eq_attr "alternative" "0")
1757 (eq_attr "mode" "DF")
1760 (const_string "0")))
1761 (set_attr "athlon_decode" "vector")
1762 (set_attr "amdfam10_decode" "direct")
1763 (set_attr "bdver1_decode" "double")
1764 (set_attr "znver1_decode" "double")
1765 (set (attr "enabled")
1767 (match_test ("SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"))
1769 (eq_attr "alternative" "0")
1770 (symbol_ref "TARGET_MIX_SSE_I387")
1771 (symbol_ref "true"))
1773 (eq_attr "alternative" "0")
1775 (symbol_ref "false"))))])
1777 (define_insn "*cmpi<unord>xf_i387"
1778 [(set (reg:CCFP FLAGS_REG)
1780 (match_operand:XF 0 "register_operand" "f")
1781 (match_operand:XF 1 "register_operand" "f")))]
1782 "TARGET_80387 && TARGET_CMOVE"
1783 "* return output_fp_compare (insn, operands, true, <unordered>);"
1784 [(set_attr "type" "fcmp")
1785 (set_attr "mode" "XF")
1786 (set_attr "athlon_decode" "vector")
1787 (set_attr "amdfam10_decode" "direct")
1788 (set_attr "bdver1_decode" "double")
1789 (set_attr "znver1_decode" "double")])
1791 ;; Push/pop instructions.
1793 (define_insn "*push<mode>2"
1794 [(set (match_operand:DWI 0 "push_operand" "=<")
1795 (match_operand:DWI 1 "general_no_elim_operand" "riF*o"))]
1798 [(set_attr "type" "multi")
1799 (set_attr "mode" "<MODE>")])
1802 [(set (match_operand:DWI 0 "push_operand")
1803 (match_operand:DWI 1 "general_gr_operand"))]
1806 "ix86_split_long_move (operands); DONE;")
1808 (define_insn "*pushdi2_rex64"
1809 [(set (match_operand:DI 0 "push_operand" "=<,!<")
1810 (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1815 [(set_attr "type" "push,multi")
1816 (set_attr "mode" "DI")])
1818 ;; Convert impossible pushes of immediate to existing instructions.
1819 ;; First try to get scratch register and go through it. In case this
1820 ;; fails, push sign extended lower part first and then overwrite
1821 ;; upper part by 32bit move.
1823 [(match_scratch:DI 2 "r")
1824 (set (match_operand:DI 0 "push_operand")
1825 (match_operand:DI 1 "immediate_operand"))]
1826 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1827 && !x86_64_immediate_operand (operands[1], DImode)"
1828 [(set (match_dup 2) (match_dup 1))
1829 (set (match_dup 0) (match_dup 2))])
1831 ;; We need to define this as both peepholer and splitter for case
1832 ;; peephole2 pass is not run.
1833 ;; "&& 1" is needed to keep it from matching the previous pattern.
1835 [(set (match_operand:DI 0 "push_operand")
1836 (match_operand:DI 1 "immediate_operand"))]
1837 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1838 && !x86_64_immediate_operand (operands[1], DImode) && 1"
1839 [(set (match_dup 0) (match_dup 1))
1840 (set (match_dup 2) (match_dup 3))]
1842 split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1844 operands[1] = gen_lowpart (DImode, operands[2]);
1845 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (Pmode, stack_pointer_rtx,
1850 [(set (match_operand:DI 0 "push_operand")
1851 (match_operand:DI 1 "immediate_operand"))]
1852 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
1853 ? epilogue_completed : reload_completed)
1854 && !symbolic_operand (operands[1], DImode)
1855 && !x86_64_immediate_operand (operands[1], DImode)"
1856 [(set (match_dup 0) (match_dup 1))
1857 (set (match_dup 2) (match_dup 3))]
1859 split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1861 operands[1] = gen_lowpart (DImode, operands[2]);
1862 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (Pmode, stack_pointer_rtx,
1866 (define_insn "*pushsi2"
1867 [(set (match_operand:SI 0 "push_operand" "=<")
1868 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1871 [(set_attr "type" "push")
1872 (set_attr "mode" "SI")])
1874 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1875 ;; "push a byte/word". But actually we use pushl, which has the effect
1876 ;; of rounding the amount pushed up to a word.
1878 ;; For TARGET_64BIT we always round up to 8 bytes.
1879 (define_insn "*push<mode>2_rex64"
1880 [(set (match_operand:SWI124 0 "push_operand" "=X")
1881 (match_operand:SWI124 1 "nonmemory_no_elim_operand" "r<i>"))]
1884 [(set_attr "type" "push")
1885 (set_attr "mode" "DI")])
1887 (define_insn "*push<mode>2"
1888 [(set (match_operand:SWI12 0 "push_operand" "=X")
1889 (match_operand:SWI12 1 "nonmemory_no_elim_operand" "rn"))]
1892 [(set_attr "type" "push")
1893 (set_attr "mode" "SI")])
1895 (define_insn "*push<mode>2_prologue"
1896 [(set (match_operand:W 0 "push_operand" "=<")
1897 (match_operand:W 1 "general_no_elim_operand" "r<i>*m"))
1898 (clobber (mem:BLK (scratch)))]
1900 "push{<imodesuffix>}\t%1"
1901 [(set_attr "type" "push")
1902 (set_attr "mode" "<MODE>")])
1904 (define_insn "*pop<mode>1"
1905 [(set (match_operand:W 0 "nonimmediate_operand" "=r*m")
1906 (match_operand:W 1 "pop_operand" ">"))]
1908 "pop{<imodesuffix>}\t%0"
1909 [(set_attr "type" "pop")
1910 (set_attr "mode" "<MODE>")])
1912 (define_insn "*pop<mode>1_epilogue"
1913 [(set (match_operand:W 0 "nonimmediate_operand" "=r*m")
1914 (match_operand:W 1 "pop_operand" ">"))
1915 (clobber (mem:BLK (scratch)))]
1917 "pop{<imodesuffix>}\t%0"
1918 [(set_attr "type" "pop")
1919 (set_attr "mode" "<MODE>")])
1921 (define_insn "*pushfl<mode>2"
1922 [(set (match_operand:W 0 "push_operand" "=<")
1923 (match_operand:W 1 "flags_reg_operand"))]
1925 "pushf{<imodesuffix>}"
1926 [(set_attr "type" "push")
1927 (set_attr "mode" "<MODE>")])
1929 (define_insn "*popfl<mode>1"
1930 [(set (match_operand:W 0 "flags_reg_operand")
1931 (match_operand:W 1 "pop_operand" ">"))]
1933 "popf{<imodesuffix>}"
1934 [(set_attr "type" "pop")
1935 (set_attr "mode" "<MODE>")])
1938 ;; Reload patterns to support multi-word load/store
1939 ;; with non-offsetable address.
1940 (define_expand "reload_noff_store"
1941 [(parallel [(match_operand 0 "memory_operand" "=m")
1942 (match_operand 1 "register_operand" "r")
1943 (match_operand:DI 2 "register_operand" "=&r")])]
1946 rtx mem = operands[0];
1947 rtx addr = XEXP (mem, 0);
1949 emit_move_insn (operands[2], addr);
1950 mem = replace_equiv_address_nv (mem, operands[2]);
1952 emit_insn (gen_rtx_SET (mem, operands[1]));
1956 (define_expand "reload_noff_load"
1957 [(parallel [(match_operand 0 "register_operand" "=r")
1958 (match_operand 1 "memory_operand" "m")
1959 (match_operand:DI 2 "register_operand" "=r")])]
1962 rtx mem = operands[1];
1963 rtx addr = XEXP (mem, 0);
1965 emit_move_insn (operands[2], addr);
1966 mem = replace_equiv_address_nv (mem, operands[2]);
1968 emit_insn (gen_rtx_SET (operands[0], mem));
1972 ;; Move instructions.
1974 (define_expand "movxi"
1975 [(set (match_operand:XI 0 "nonimmediate_operand")
1976 (match_operand:XI 1 "general_operand"))]
1978 "ix86_expand_vector_move (XImode, operands); DONE;")
1980 (define_expand "movoi"
1981 [(set (match_operand:OI 0 "nonimmediate_operand")
1982 (match_operand:OI 1 "general_operand"))]
1984 "ix86_expand_vector_move (OImode, operands); DONE;")
1986 (define_expand "movti"
1987 [(set (match_operand:TI 0 "nonimmediate_operand")
1988 (match_operand:TI 1 "general_operand"))]
1989 "TARGET_64BIT || TARGET_SSE"
1992 ix86_expand_move (TImode, operands);
1994 ix86_expand_vector_move (TImode, operands);
1998 ;; This expands to what emit_move_complex would generate if we didn't
1999 ;; have a movti pattern. Having this avoids problems with reload on
2000 ;; 32-bit targets when SSE is present, but doesn't seem to be harmful
2001 ;; to have around all the time.
2002 (define_expand "movcdi"
2003 [(set (match_operand:CDI 0 "nonimmediate_operand")
2004 (match_operand:CDI 1 "general_operand"))]
2007 if (push_operand (operands[0], CDImode))
2008 emit_move_complex_push (CDImode, operands[0], operands[1]);
2010 emit_move_complex_parts (operands[0], operands[1]);
2014 (define_expand "mov<mode>"
2015 [(set (match_operand:SWI1248x 0 "nonimmediate_operand")
2016 (match_operand:SWI1248x 1 "general_operand"))]
2018 "ix86_expand_move (<MODE>mode, operands); DONE;")
2020 (define_insn "*mov<mode>_xor"
2021 [(set (match_operand:SWI48 0 "register_operand" "=r")
2022 (match_operand:SWI48 1 "const0_operand"))
2023 (clobber (reg:CC FLAGS_REG))]
2026 [(set_attr "type" "alu1")
2027 (set_attr "modrm_class" "op0")
2028 (set_attr "mode" "SI")
2029 (set_attr "length_immediate" "0")])
2031 (define_insn "*mov<mode>_or"
2032 [(set (match_operand:SWI48 0 "register_operand" "=r")
2033 (match_operand:SWI48 1 "constm1_operand"))
2034 (clobber (reg:CC FLAGS_REG))]
2036 "or{<imodesuffix>}\t{%1, %0|%0, %1}"
2037 [(set_attr "type" "alu1")
2038 (set_attr "mode" "<MODE>")
2039 (set_attr "length_immediate" "1")])
2041 (define_insn "*movxi_internal_avx512f"
2042 [(set (match_operand:XI 0 "nonimmediate_operand" "=v,v ,v ,m")
2043 (match_operand:XI 1 "nonimmediate_or_sse_const_operand" " C,BC,vm,v"))]
2045 && (register_operand (operands[0], XImode)
2046 || register_operand (operands[1], XImode))"
2048 switch (get_attr_type (insn))
2051 return standard_sse_constant_opcode (insn, operands);
2054 if (misaligned_operand (operands[0], XImode)
2055 || misaligned_operand (operands[1], XImode))
2056 return "vmovdqu32\t{%1, %0|%0, %1}";
2058 return "vmovdqa32\t{%1, %0|%0, %1}";
2064 [(set_attr "type" "sselog1,sselog1,ssemov,ssemov")
2065 (set_attr "prefix" "evex")
2066 (set_attr "mode" "XI")])
2068 (define_insn "*movoi_internal_avx"
2069 [(set (match_operand:OI 0 "nonimmediate_operand" "=v,v ,v ,m")
2070 (match_operand:OI 1 "nonimmediate_or_sse_const_operand" " C,BC,vm,v"))]
2072 && (register_operand (operands[0], OImode)
2073 || register_operand (operands[1], OImode))"
2075 switch (get_attr_type (insn))
2078 return standard_sse_constant_opcode (insn, operands);
2081 if (misaligned_operand (operands[0], OImode)
2082 || misaligned_operand (operands[1], OImode))
2084 if (get_attr_mode (insn) == MODE_V8SF)
2085 return "vmovups\t{%1, %0|%0, %1}";
2086 else if (get_attr_mode (insn) == MODE_XI)
2087 return "vmovdqu32\t{%1, %0|%0, %1}";
2089 return "vmovdqu\t{%1, %0|%0, %1}";
2093 if (get_attr_mode (insn) == MODE_V8SF)
2094 return "vmovaps\t{%1, %0|%0, %1}";
2095 else if (get_attr_mode (insn) == MODE_XI)
2096 return "vmovdqa32\t{%1, %0|%0, %1}";
2098 return "vmovdqa\t{%1, %0|%0, %1}";
2105 [(set_attr "isa" "*,avx2,*,*")
2106 (set_attr "type" "sselog1,sselog1,ssemov,ssemov")
2107 (set_attr "prefix" "vex")
2109 (cond [(ior (match_operand 0 "ext_sse_reg_operand")
2110 (match_operand 1 "ext_sse_reg_operand"))
2112 (and (eq_attr "alternative" "1")
2113 (match_test "TARGET_AVX512VL"))
2115 (ior (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
2116 (and (eq_attr "alternative" "3")
2117 (match_test "TARGET_SSE_TYPELESS_STORES")))
2118 (const_string "V8SF")
2120 (const_string "OI")))])
2122 (define_insn "*movti_internal"
2123 [(set (match_operand:TI 0 "nonimmediate_operand" "=!r ,o ,v,v ,v ,m,?r,?Yd")
2124 (match_operand:TI 1 "general_operand" "riFo,re,C,BC,vm,v,Ye,r"))]
2126 && !(MEM_P (operands[0]) && MEM_P (operands[1])))
2128 && nonimmediate_or_sse_const_operand (operands[1], TImode)
2129 && (register_operand (operands[0], TImode)
2130 || register_operand (operands[1], TImode)))"
2132 switch (get_attr_type (insn))
2138 return standard_sse_constant_opcode (insn, operands);
2141 /* TDmode values are passed as TImode on the stack. Moving them
2142 to stack may result in unaligned memory access. */
2143 if (misaligned_operand (operands[0], TImode)
2144 || misaligned_operand (operands[1], TImode))
2146 if (get_attr_mode (insn) == MODE_V4SF)
2147 return "%vmovups\t{%1, %0|%0, %1}";
2148 else if (get_attr_mode (insn) == MODE_XI)
2149 return "vmovdqu32\t{%1, %0|%0, %1}";
2151 return "%vmovdqu\t{%1, %0|%0, %1}";
2155 if (get_attr_mode (insn) == MODE_V4SF)
2156 return "%vmovaps\t{%1, %0|%0, %1}";
2157 else if (get_attr_mode (insn) == MODE_XI)
2158 return "vmovdqa32\t{%1, %0|%0, %1}";
2160 return "%vmovdqa\t{%1, %0|%0, %1}";
2168 (cond [(eq_attr "alternative" "0,1,6,7")
2169 (const_string "x64")
2170 (eq_attr "alternative" "3")
2171 (const_string "sse2")
2173 (const_string "*")))
2175 (cond [(eq_attr "alternative" "0,1,6,7")
2176 (const_string "multi")
2177 (eq_attr "alternative" "2,3")
2178 (const_string "sselog1")
2180 (const_string "ssemov")))
2181 (set (attr "prefix")
2182 (if_then_else (eq_attr "type" "sselog1,ssemov")
2183 (const_string "maybe_vex")
2184 (const_string "orig")))
2186 (cond [(eq_attr "alternative" "0,1")
2188 (ior (match_operand 0 "ext_sse_reg_operand")
2189 (match_operand 1 "ext_sse_reg_operand"))
2191 (and (eq_attr "alternative" "3")
2192 (match_test "TARGET_AVX512VL"))
2194 (ior (not (match_test "TARGET_SSE2"))
2195 (ior (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
2196 (and (eq_attr "alternative" "5")
2197 (match_test "TARGET_SSE_TYPELESS_STORES"))))
2198 (const_string "V4SF")
2199 (match_test "TARGET_AVX")
2201 (match_test "optimize_function_for_size_p (cfun)")
2202 (const_string "V4SF")
2204 (const_string "TI")))])
2207 [(set (match_operand:TI 0 "sse_reg_operand")
2208 (match_operand:TI 1 "general_reg_operand"))]
2209 "TARGET_64BIT && TARGET_SSE4_1 && TARGET_INTER_UNIT_MOVES_TO_VEC
2210 && reload_completed"
2213 (vec_duplicate:V2DI (match_dup 3))
2217 operands[2] = lowpart_subreg (V2DImode, operands[0], TImode);
2218 operands[3] = gen_highpart (DImode, operands[1]);
2220 emit_move_insn (gen_lowpart (DImode, operands[0]),
2221 gen_lowpart (DImode, operands[1]));
2224 (define_insn "*movdi_internal"
2225 [(set (match_operand:DI 0 "nonimmediate_operand"
2226 "=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")
2227 (match_operand:DI 1 "general_operand"
2228 "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"))]
2229 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2231 switch (get_attr_type (insn))
2234 return "kmovq\t{%1, %0|%0, %1}";
2240 return "pxor\t%0, %0";
2243 /* Handle broken assemblers that require movd instead of movq. */
2244 if (!HAVE_AS_IX86_INTERUNIT_MOVQ
2245 && (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1])))
2246 return "movd\t{%1, %0|%0, %1}";
2247 return "movq\t{%1, %0|%0, %1}";
2250 return standard_sse_constant_opcode (insn, operands);
2253 switch (get_attr_mode (insn))
2256 /* Handle broken assemblers that require movd instead of movq. */
2257 if (!HAVE_AS_IX86_INTERUNIT_MOVQ
2258 && (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1])))
2259 return "%vmovd\t{%1, %0|%0, %1}";
2260 return "%vmovq\t{%1, %0|%0, %1}";
2263 /* Handle AVX512 registers set. */
2264 if (EXT_REX_SSE_REG_P (operands[0])
2265 || EXT_REX_SSE_REG_P (operands[1]))
2266 return "vmovdqa64\t{%1, %0|%0, %1}";
2267 return "%vmovdqa\t{%1, %0|%0, %1}";
2270 gcc_assert (!TARGET_AVX);
2271 return "movlps\t{%1, %0|%0, %1}";
2273 return "%vmovaps\t{%1, %0|%0, %1}";
2280 if (SSE_REG_P (operands[0]))
2281 return "movq2dq\t{%1, %0|%0, %1}";
2283 return "movdq2q\t{%1, %0|%0, %1}";
2286 return "lea{q}\t{%E1, %0|%0, %E1}";
2289 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2290 if (get_attr_mode (insn) == MODE_SI)
2291 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2292 else if (which_alternative == 4)
2293 return "movabs{q}\t{%1, %0|%0, %1}";
2294 else if (ix86_use_lea_for_mov (insn, operands))
2295 return "lea{q}\t{%E1, %0|%0, %E1}";
2297 return "mov{q}\t{%1, %0|%0, %1}";
2304 (cond [(eq_attr "alternative" "0,1,17,18")
2305 (const_string "nox64")
2306 (eq_attr "alternative" "2,3,4,5,10,11,19,20,23,25")
2307 (const_string "x64")
2309 (const_string "*")))
2311 (cond [(eq_attr "alternative" "0,1,17,18")
2312 (const_string "multi")
2313 (eq_attr "alternative" "6")
2314 (const_string "mmx")
2315 (eq_attr "alternative" "7,8,9,10,11")
2316 (const_string "mmxmov")
2317 (eq_attr "alternative" "12")
2318 (const_string "sselog1")
2319 (eq_attr "alternative" "13,14,15,16,19,20")
2320 (const_string "ssemov")
2321 (eq_attr "alternative" "21,22")
2322 (const_string "ssecvt")
2323 (eq_attr "alternative" "23,24,25,26")
2324 (const_string "mskmov")
2325 (and (match_operand 0 "register_operand")
2326 (match_operand 1 "pic_32bit_operand"))
2327 (const_string "lea")
2329 (const_string "imov")))
2332 (and (eq_attr "alternative" "4") (eq_attr "type" "imov"))
2334 (const_string "*")))
2335 (set (attr "length_immediate")
2337 (and (eq_attr "alternative" "4") (eq_attr "type" "imov"))
2339 (const_string "*")))
2340 (set (attr "prefix_rex")
2342 (eq_attr "alternative" "10,11,19,20")
2344 (const_string "*")))
2345 (set (attr "prefix")
2346 (if_then_else (eq_attr "type" "sselog1,ssemov")
2347 (const_string "maybe_vex")
2348 (const_string "orig")))
2349 (set (attr "prefix_data16")
2350 (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "DI"))
2352 (const_string "*")))
2354 (cond [(eq_attr "alternative" "2")
2356 (eq_attr "alternative" "12,13")
2357 (cond [(ior (match_operand 0 "ext_sse_reg_operand")
2358 (match_operand 1 "ext_sse_reg_operand"))
2360 (ior (not (match_test "TARGET_SSE2"))
2361 (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL"))
2362 (const_string "V4SF")
2363 (match_test "TARGET_AVX")
2365 (match_test "optimize_function_for_size_p (cfun)")
2366 (const_string "V4SF")
2368 (const_string "TI"))
2370 (and (eq_attr "alternative" "14,15,16")
2371 (not (match_test "TARGET_SSE2")))
2372 (const_string "V2SF")
2374 (const_string "DI")))
2375 (set (attr "enabled")
2376 (cond [(eq_attr "alternative" "15")
2378 (match_test "TARGET_STV && TARGET_SSE2")
2379 (symbol_ref "false")
2381 (eq_attr "alternative" "16")
2383 (match_test "TARGET_STV && TARGET_SSE2")
2385 (symbol_ref "false"))
2387 (const_string "*")))])
2390 [(set (match_operand:<DWI> 0 "general_reg_operand")
2391 (match_operand:<DWI> 1 "sse_reg_operand"))]
2392 "TARGET_SSE4_1 && TARGET_INTER_UNIT_MOVES_FROM_VEC
2393 && reload_completed"
2397 (parallel [(const_int 1)])))]
2399 operands[2] = gen_highpart (<MODE>mode, operands[0]);
2400 operands[3] = lowpart_subreg (<ssevecmode>mode, operands[1], <DWI>mode);
2402 emit_move_insn (gen_lowpart (<MODE>mode, operands[0]),
2403 gen_lowpart (<MODE>mode, operands[1]));
2407 [(set (match_operand:DWI 0 "nonimmediate_gr_operand")
2408 (match_operand:DWI 1 "general_gr_operand"))]
2411 "ix86_split_long_move (operands); DONE;")
2414 [(set (match_operand:DI 0 "sse_reg_operand")
2415 (match_operand:DI 1 "general_reg_operand"))]
2416 "!TARGET_64BIT && TARGET_SSE4_1 && TARGET_INTER_UNIT_MOVES_TO_VEC
2417 && reload_completed"
2420 (vec_duplicate:V4SI (match_dup 3))
2424 operands[2] = lowpart_subreg (V4SImode, operands[0], DImode);
2425 operands[3] = gen_highpart (SImode, operands[1]);
2427 emit_move_insn (gen_lowpart (SImode, operands[0]),
2428 gen_lowpart (SImode, operands[1]));
2431 ;; movabsq $0x0012345678000000, %rax is longer
2432 ;; than movl $0x12345678, %eax; shlq $24, %rax.
2434 [(set (match_operand:DI 0 "register_operand")
2435 (match_operand:DI 1 "const_int_operand"))]
2437 && optimize_insn_for_size_p ()
2438 && LEGACY_INT_REG_P (operands[0])
2439 && !x86_64_immediate_operand (operands[1], DImode)
2440 && !x86_64_zext_immediate_operand (operands[1], DImode)
2441 && !((UINTVAL (operands[1]) >> ctz_hwi (UINTVAL (operands[1])))
2442 & ~(HOST_WIDE_INT) 0xffffffff)
2443 && peep2_regno_dead_p (0, FLAGS_REG)"
2444 [(set (match_dup 0) (match_dup 1))
2445 (parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
2446 (clobber (reg:CC FLAGS_REG))])]
2448 int shift = ctz_hwi (UINTVAL (operands[1]));
2449 operands[1] = gen_int_mode (UINTVAL (operands[1]) >> shift, DImode);
2450 operands[2] = gen_int_mode (shift, QImode);
2453 (define_insn "*movsi_internal"
2454 [(set (match_operand:SI 0 "nonimmediate_operand"
2455 "=r,m ,*y,*y,?*y,?m,?r ,?*Ym,*v,*v,*v,m ,?r ,?*Yi,*k,*k ,*rm")
2456 (match_operand:SI 1 "general_operand"
2457 "g ,re,C ,*y,m ,*y,*Yn,r ,C ,*v,m ,*v,*Yj,r ,*r,*km,*k"))]
2458 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2460 switch (get_attr_type (insn))
2463 return standard_sse_constant_opcode (insn, operands);
2466 return "kmovd\t{%1, %0|%0, %1}";
2469 switch (get_attr_mode (insn))
2472 return "%vmovd\t{%1, %0|%0, %1}";
2474 return "%vmovdqa\t{%1, %0|%0, %1}";
2476 return "vmovdqa32\t{%g1, %g0|%g0, %g1}";
2479 return "%vmovaps\t{%1, %0|%0, %1}";
2482 gcc_assert (!TARGET_AVX);
2483 return "movss\t{%1, %0|%0, %1}";
2490 return "pxor\t%0, %0";
2493 switch (get_attr_mode (insn))
2496 return "movq\t{%1, %0|%0, %1}";
2498 return "movd\t{%1, %0|%0, %1}";
2505 return "lea{l}\t{%E1, %0|%0, %E1}";
2508 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2509 if (ix86_use_lea_for_mov (insn, operands))
2510 return "lea{l}\t{%E1, %0|%0, %E1}";
2512 return "mov{l}\t{%1, %0|%0, %1}";
2519 (cond [(eq_attr "alternative" "2")
2520 (const_string "mmx")
2521 (eq_attr "alternative" "3,4,5,6,7")
2522 (const_string "mmxmov")
2523 (eq_attr "alternative" "8")
2524 (const_string "sselog1")
2525 (eq_attr "alternative" "9,10,11,12,13")
2526 (const_string "ssemov")
2527 (eq_attr "alternative" "14,15,16")
2528 (const_string "mskmov")
2529 (and (match_operand 0 "register_operand")
2530 (match_operand 1 "pic_32bit_operand"))
2531 (const_string "lea")
2533 (const_string "imov")))
2534 (set (attr "prefix")
2535 (if_then_else (eq_attr "type" "sselog1,ssemov")
2536 (const_string "maybe_vex")
2537 (const_string "orig")))
2538 (set (attr "prefix_data16")
2539 (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
2541 (const_string "*")))
2543 (cond [(eq_attr "alternative" "2,3")
2545 (eq_attr "alternative" "8,9")
2546 (cond [(ior (match_operand 0 "ext_sse_reg_operand")
2547 (match_operand 1 "ext_sse_reg_operand"))
2549 (ior (not (match_test "TARGET_SSE2"))
2550 (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL"))
2551 (const_string "V4SF")
2552 (match_test "TARGET_AVX")
2554 (match_test "optimize_function_for_size_p (cfun)")
2555 (const_string "V4SF")
2557 (const_string "TI"))
2559 (and (eq_attr "alternative" "10,11")
2560 (not (match_test "TARGET_SSE2")))
2563 (const_string "SI")))])
2565 (define_insn "*movhi_internal"
2566 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r ,r ,m ,k,k ,r,m")
2567 (match_operand:HI 1 "general_operand" "r ,rn,rm,rn,r,km,k,k"))]
2568 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2570 switch (get_attr_type (insn))
2573 /* movzwl is faster than movw on p2 due to partial word stalls,
2574 though not as fast as an aligned movl. */
2575 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
2578 switch (which_alternative)
2581 return "kmovw\t{%k1, %0|%0, %k1}";
2583 return "kmovw\t{%1, %k0|%k0, %1}";
2586 return "kmovw\t{%1, %0|%0, %1}";
2592 if (get_attr_mode (insn) == MODE_SI)
2593 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2595 return "mov{w}\t{%1, %0|%0, %1}";
2599 (cond [(eq_attr "alternative" "4,5,6,7")
2600 (const_string "mskmov")
2601 (match_test "optimize_function_for_size_p (cfun)")
2602 (const_string "imov")
2603 (and (eq_attr "alternative" "0")
2604 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2605 (not (match_test "TARGET_HIMODE_MATH"))))
2606 (const_string "imov")
2607 (and (eq_attr "alternative" "1,2")
2608 (match_operand:HI 1 "aligned_operand"))
2609 (const_string "imov")
2610 (and (match_test "TARGET_MOVX")
2611 (eq_attr "alternative" "0,2"))
2612 (const_string "imovx")
2614 (const_string "imov")))
2615 (set (attr "prefix")
2616 (if_then_else (eq_attr "alternative" "4,5,6,7")
2617 (const_string "vex")
2618 (const_string "orig")))
2620 (cond [(eq_attr "type" "imovx")
2622 (and (eq_attr "alternative" "1,2")
2623 (match_operand:HI 1 "aligned_operand"))
2625 (and (eq_attr "alternative" "0")
2626 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2627 (not (match_test "TARGET_HIMODE_MATH"))))
2630 (const_string "HI")))])
2632 ;; Situation is quite tricky about when to choose full sized (SImode) move
2633 ;; over QImode moves. For Q_REG -> Q_REG move we use full size only for
2634 ;; partial register dependency machines (such as AMD Athlon), where QImode
2635 ;; moves issue extra dependency and for partial register stalls machines
2636 ;; that don't use QImode patterns (and QImode move cause stall on the next
2639 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
2640 ;; register stall machines with, where we use QImode instructions, since
2641 ;; partial register stall can be caused there. Then we use movzx.
2643 (define_insn "*movqi_internal"
2644 [(set (match_operand:QI 0 "nonimmediate_operand"
2645 "=Q,R,r,q,q,r,r ,?r,m ,k,k,r,m,k")
2646 (match_operand:QI 1 "general_operand"
2647 "Q ,R,r,n,m,q,rn, m,qn,r,k,k,k,m"))]
2648 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2650 static char buf[128];
2654 switch (get_attr_type (insn))
2657 gcc_assert (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]));
2658 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
2661 switch (which_alternative)
2664 ops = "kmov%s\t{%%k1, %%0|%%0, %%k1}";
2667 ops = "kmov%s\t{%%1, %%k0|%%k0, %%1}";
2671 gcc_assert (TARGET_AVX512DQ);
2674 ops = "kmov%s\t{%%1, %%0|%%0, %%1}";
2680 suffix = (get_attr_mode (insn) == MODE_HI) ? "w" : "b";
2682 snprintf (buf, sizeof (buf), ops, suffix);
2686 if (get_attr_mode (insn) == MODE_SI)
2687 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2689 return "mov{b}\t{%1, %0|%0, %1}";
2693 (cond [(eq_attr "alternative" "1,2")
2694 (const_string "x64")
2695 (eq_attr "alternative" "12,13")
2696 (const_string "avx512dq")
2698 (const_string "*")))
2700 (cond [(eq_attr "alternative" "9,10,11,12,13")
2701 (const_string "mskmov")
2702 (and (eq_attr "alternative" "7")
2703 (not (match_operand:QI 1 "aligned_operand")))
2704 (const_string "imovx")
2705 (match_test "optimize_function_for_size_p (cfun)")
2706 (const_string "imov")
2707 (and (eq_attr "alternative" "5")
2708 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2709 (not (match_test "TARGET_QIMODE_MATH"))))
2710 (const_string "imov")
2711 (eq_attr "alternative" "5,7")
2712 (const_string "imovx")
2713 (and (match_test "TARGET_MOVX")
2714 (eq_attr "alternative" "4"))
2715 (const_string "imovx")
2717 (const_string "imov")))
2718 (set (attr "prefix")
2719 (if_then_else (eq_attr "alternative" "9,10,11")
2720 (const_string "vex")
2721 (const_string "orig")))
2723 (cond [(eq_attr "alternative" "5,6,7")
2725 (eq_attr "alternative" "8")
2727 (and (eq_attr "alternative" "9,10,11")
2728 (not (match_test "TARGET_AVX512DQ")))
2730 (eq_attr "type" "imovx")
2732 ;; For -Os, 8-bit immediates are always shorter than 32-bit
2734 (and (eq_attr "type" "imov")
2735 (and (eq_attr "alternative" "3")
2736 (match_test "optimize_function_for_size_p (cfun)")))
2738 ;; For -Os, movl where one or both operands are NON_Q_REGS
2739 ;; and both are LEGACY_REGS is shorter than movb.
2740 ;; Otherwise movb and movl sizes are the same, so decide purely
2741 ;; based on speed factors.
2742 (and (eq_attr "type" "imov")
2743 (and (eq_attr "alternative" "1")
2744 (match_test "optimize_function_for_size_p (cfun)")))
2746 (and (eq_attr "type" "imov")
2747 (and (eq_attr "alternative" "0,1,2,3")
2748 (and (match_test "TARGET_PARTIAL_REG_DEPENDENCY")
2749 (not (match_test "TARGET_PARTIAL_REG_STALL")))))
2751 ;; Avoid partial register stalls when not using QImode arithmetic
2752 (and (eq_attr "type" "imov")
2753 (and (eq_attr "alternative" "0,1,2,3")
2754 (and (match_test "TARGET_PARTIAL_REG_STALL")
2755 (not (match_test "TARGET_QIMODE_MATH")))))
2758 (const_string "QI")))])
2760 ;; Stores and loads of ax to arbitrary constant address.
2761 ;; We fake an second form of instruction to force reload to load address
2762 ;; into register when rax is not available
2763 (define_insn "*movabs<mode>_1"
2764 [(set (mem:SWI1248x (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2765 (match_operand:SWI1248x 1 "nonmemory_operand" "a,r<i>"))]
2766 "TARGET_LP64 && ix86_check_movabs (insn, 0)"
2768 /* Recover the full memory rtx. */
2769 operands[0] = SET_DEST (PATTERN (insn));
2770 switch (which_alternative)
2773 return "movabs{<imodesuffix>}\t{%1, %P0|<iptrsize> PTR [%P0], %1}";
2775 return "mov{<imodesuffix>}\t{%1, %0|%0, %1}";
2780 [(set_attr "type" "imov")
2781 (set_attr "modrm" "0,*")
2782 (set_attr "length_address" "8,0")
2783 (set_attr "length_immediate" "0,*")
2784 (set_attr "memory" "store")
2785 (set_attr "mode" "<MODE>")])
2787 (define_insn "*movabs<mode>_2"
2788 [(set (match_operand:SWI1248x 0 "register_operand" "=a,r")
2789 (mem:SWI1248x (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2790 "TARGET_LP64 && ix86_check_movabs (insn, 1)"
2792 /* Recover the full memory rtx. */
2793 operands[1] = SET_SRC (PATTERN (insn));
2794 switch (which_alternative)
2797 return "movabs{<imodesuffix>}\t{%P1, %0|%0, <iptrsize> PTR [%P1]}";
2799 return "mov{<imodesuffix>}\t{%1, %0|%0, %1}";
2804 [(set_attr "type" "imov")
2805 (set_attr "modrm" "0,*")
2806 (set_attr "length_address" "8,0")
2807 (set_attr "length_immediate" "0")
2808 (set_attr "memory" "load")
2809 (set_attr "mode" "<MODE>")])
2811 (define_insn "*swap<mode>"
2812 [(set (match_operand:SWI48 0 "register_operand" "+r")
2813 (match_operand:SWI48 1 "register_operand" "+r"))
2817 "xchg{<imodesuffix>}\t%1, %0"
2818 [(set_attr "type" "imov")
2819 (set_attr "mode" "<MODE>")
2820 (set_attr "pent_pair" "np")
2821 (set_attr "athlon_decode" "vector")
2822 (set_attr "amdfam10_decode" "double")
2823 (set_attr "bdver1_decode" "double")])
2825 (define_insn "*swap<mode>"
2826 [(set (match_operand:SWI12 0 "register_operand" "+<r>,r")
2827 (match_operand:SWI12 1 "register_operand" "+<r>,r"))
2832 xchg{<imodesuffix>}\t%1, %0
2834 [(set_attr "type" "imov")
2835 (set_attr "mode" "<MODE>,SI")
2836 (set (attr "preferred_for_size")
2837 (cond [(eq_attr "alternative" "0")
2838 (symbol_ref "false")]
2839 (symbol_ref "true")))
2840 ;; Potential partial reg stall on alternative 1.
2841 (set (attr "preferred_for_speed")
2842 (cond [(eq_attr "alternative" "1")
2843 (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
2844 (symbol_ref "true")))
2845 (set_attr "pent_pair" "np")
2846 (set_attr "athlon_decode" "vector")
2847 (set_attr "amdfam10_decode" "double")
2848 (set_attr "bdver1_decode" "double")])
2850 (define_expand "movstrict<mode>"
2851 [(set (strict_low_part (match_operand:SWI12 0 "nonimmediate_operand"))
2852 (match_operand:SWI12 1 "general_operand"))]
2855 if (TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun))
2857 if (SUBREG_P (operands[0])
2858 && GET_MODE_CLASS (GET_MODE (SUBREG_REG (operands[0]))) != MODE_INT)
2860 /* Don't generate memory->memory moves, go through a register */
2861 if (MEM_P (operands[0]) && MEM_P (operands[1]))
2862 operands[1] = force_reg (<MODE>mode, operands[1]);
2865 (define_insn "*movstrict<mode>_1"
2866 [(set (strict_low_part
2867 (match_operand:SWI12 0 "nonimmediate_operand" "+<r>m,<r>"))
2868 (match_operand:SWI12 1 "general_operand" "<r>n,m"))]
2869 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
2870 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2871 "mov{<imodesuffix>}\t{%1, %0|%0, %1}"
2872 [(set_attr "type" "imov")
2873 (set_attr "mode" "<MODE>")])
2875 (define_insn "*movstrict<mode>_xor"
2876 [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>"))
2877 (match_operand:SWI12 1 "const0_operand"))
2878 (clobber (reg:CC FLAGS_REG))]
2880 "xor{<imodesuffix>}\t%0, %0"
2881 [(set_attr "type" "alu1")
2882 (set_attr "modrm_class" "op0")
2883 (set_attr "mode" "<MODE>")
2884 (set_attr "length_immediate" "0")])
2886 (define_expand "extv<mode>"
2887 [(set (match_operand:SWI24 0 "register_operand")
2888 (sign_extract:SWI24 (match_operand:SWI24 1 "register_operand")
2889 (match_operand:SI 2 "const_int_operand")
2890 (match_operand:SI 3 "const_int_operand")))]
2893 /* Handle extractions from %ah et al. */
2894 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
2897 unsigned int regno = reg_or_subregno (operands[1]);
2899 /* Be careful to expand only with registers having upper parts. */
2900 if (regno <= LAST_VIRTUAL_REGISTER && !QI_REGNO_P (regno))
2901 operands[1] = copy_to_reg (operands[1]);
2904 (define_insn "*extv<mode>"
2905 [(set (match_operand:SWI24 0 "register_operand" "=R")
2906 (sign_extract:SWI24 (match_operand 1 "ext_register_operand" "Q")
2910 "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
2911 [(set_attr "type" "imovx")
2912 (set_attr "mode" "SI")])
2914 (define_expand "extzv<mode>"
2915 [(set (match_operand:SWI248 0 "register_operand")
2916 (zero_extract:SWI248 (match_operand:SWI248 1 "register_operand")
2917 (match_operand:SI 2 "const_int_operand")
2918 (match_operand:SI 3 "const_int_operand")))]
2921 if (ix86_expand_pextr (operands))
2924 /* Handle extractions from %ah et al. */
2925 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
2928 unsigned int regno = reg_or_subregno (operands[1]);
2930 /* Be careful to expand only with registers having upper parts. */
2931 if (regno <= LAST_VIRTUAL_REGISTER && !QI_REGNO_P (regno))
2932 operands[1] = copy_to_reg (operands[1]);
2935 (define_insn "*extzvqi_mem_rex64"
2936 [(set (match_operand:QI 0 "norex_memory_operand" "=Bn")
2938 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q")
2941 "TARGET_64BIT && reload_completed"
2942 "mov{b}\t{%h1, %0|%0, %h1}"
2943 [(set_attr "type" "imov")
2944 (set_attr "mode" "QI")])
2946 (define_insn "*extzv<mode>"
2947 [(set (match_operand:SWI248 0 "register_operand" "=R")
2948 (zero_extract:SWI248 (match_operand 1 "ext_register_operand" "Q")
2952 "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
2953 [(set_attr "type" "imovx")
2954 (set_attr "mode" "SI")])
2956 (define_insn "*extzvqi"
2957 [(set (match_operand:QI 0 "nonimmediate_operand" "=QBc,?R,m")
2959 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q,Q")
2964 switch (get_attr_type (insn))
2967 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2969 return "mov{b}\t{%h1, %0|%0, %h1}";
2972 [(set_attr "isa" "*,*,nox64")
2974 (if_then_else (and (match_operand:QI 0 "register_operand")
2975 (ior (not (match_operand:QI 0 "QIreg_operand"))
2976 (match_test "TARGET_MOVX")))
2977 (const_string "imovx")
2978 (const_string "imov")))
2980 (if_then_else (eq_attr "type" "imovx")
2982 (const_string "QI")))])
2985 [(set (match_operand:QI 0 "register_operand")
2987 (zero_extract:SI (match_operand 1 "ext_register_operand")
2990 (set (match_operand:QI 2 "norex_memory_operand") (match_dup 0))]
2992 && peep2_reg_dead_p (2, operands[0])"
2995 (zero_extract:SI (match_dup 1)
2997 (const_int 8)) 0))])
2999 (define_expand "insv<mode>"
3000 [(set (zero_extract:SWI248 (match_operand:SWI248 0 "register_operand")
3001 (match_operand:SI 1 "const_int_operand")
3002 (match_operand:SI 2 "const_int_operand"))
3003 (match_operand:SWI248 3 "register_operand"))]
3008 if (ix86_expand_pinsr (operands))
3011 /* Handle insertions to %ah et al. */
3012 if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
3015 unsigned int regno = reg_or_subregno (operands[0]);
3017 /* Be careful to expand only with registers having upper parts. */
3018 if (regno <= LAST_VIRTUAL_REGISTER && !QI_REGNO_P (regno))
3019 dst = copy_to_reg (operands[0]);
3023 emit_insn (gen_insv<mode>_1 (dst, operands[3]));
3025 /* Fix up the destination if needed. */
3026 if (dst != operands[0])
3027 emit_move_insn (operands[0], dst);
3032 (define_insn "*insvqi_1_mem_rex64"
3033 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
3037 (match_operand:QI 1 "norex_memory_operand" "Bn") 0))]
3038 "TARGET_64BIT && reload_completed"
3039 "mov{b}\t{%1, %h0|%h0, %1}"
3040 [(set_attr "type" "imov")
3041 (set_attr "mode" "QI")])
3043 (define_insn "insv<mode>_1"
3044 [(set (zero_extract:SWI248 (match_operand 0 "ext_register_operand" "+Q,Q")
3047 (match_operand:SWI248 1 "general_operand" "QnBc,m"))]
3050 if (CONST_INT_P (operands[1]))
3051 operands[1] = gen_int_mode (INTVAL (operands[1]), QImode);
3052 return "mov{b}\t{%b1, %h0|%h0, %b1}";
3054 [(set_attr "isa" "*,nox64")
3055 (set_attr "type" "imov")
3056 (set_attr "mode" "QI")])
3058 (define_insn "*insvqi_1"
3059 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q,Q")
3063 (match_operand:QI 1 "general_operand" "QnBc,m") 0))]
3065 "mov{b}\t{%1, %h0|%h0, %1}"
3066 [(set_attr "isa" "*,nox64")
3067 (set_attr "type" "imov")
3068 (set_attr "mode" "QI")])
3071 [(set (match_operand:QI 0 "register_operand")
3072 (match_operand:QI 1 "norex_memory_operand"))
3073 (set (zero_extract:SI (match_operand 2 "ext_register_operand")
3076 (subreg:SI (match_dup 0) 0))]
3078 && peep2_reg_dead_p (2, operands[0])"
3079 [(set (zero_extract:SI (match_dup 2)
3082 (subreg:SI (match_dup 1) 0))])
3084 (define_code_iterator any_extract [sign_extract zero_extract])
3086 (define_insn "*insvqi_2"
3087 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
3090 (any_extract:SI (match_operand 1 "ext_register_operand" "Q")
3094 "mov{b}\t{%h1, %h0|%h0, %h1}"
3095 [(set_attr "type" "imov")
3096 (set_attr "mode" "QI")])
3098 (define_insn "*insvqi_3"
3099 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
3102 (any_shiftrt:SI (match_operand:SI 1 "register_operand" "Q")
3105 "mov{b}\t{%h1, %h0|%h0, %h1}"
3106 [(set_attr "type" "imov")
3107 (set_attr "mode" "QI")])
3109 ;; Floating point push instructions.
3111 (define_insn "*pushtf"
3112 [(set (match_operand:TF 0 "push_operand" "=<,<")
3113 (match_operand:TF 1 "general_no_elim_operand" "v,*roC"))]
3114 "TARGET_64BIT || TARGET_SSE"
3116 /* This insn should be already split before reg-stack. */
3119 [(set_attr "isa" "*,x64")
3120 (set_attr "type" "multi")
3121 (set_attr "unit" "sse,*")
3122 (set_attr "mode" "TF,DI")])
3124 ;; %%% Kill this when call knows how to work this out.
3126 [(set (match_operand:TF 0 "push_operand")
3127 (match_operand:TF 1 "sse_reg_operand"))]
3128 "TARGET_SSE && reload_completed"
3129 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -16)))
3130 (set (match_dup 0) (match_dup 1))]
3132 /* Preserve memory attributes. */
3133 operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
3136 (define_insn_and_split "*pushxf_rounded"
3140 (plus:P (reg:P SP_REG) (const_int -16))))
3141 (match_operand:XF 0 "nonmemory_no_elim_operand" "f,r,*r,C"))]
3145 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -16)))
3146 (set (match_dup 1) (match_dup 0))]
3148 rtx pat = PATTERN (curr_insn);
3149 operands[1] = SET_DEST (pat);
3151 /* Preserve memory attributes. */
3152 operands[1] = replace_equiv_address (operands[1], stack_pointer_rtx);
3154 [(set_attr "type" "multi")
3155 (set_attr "unit" "i387,*,*,*")
3157 (cond [(eq_attr "alternative" "1,2,3")
3160 (const_string "XF")))
3161 (set (attr "preferred_for_size")
3162 (cond [(eq_attr "alternative" "1")
3163 (symbol_ref "false")]
3164 (symbol_ref "true")))])
3166 (define_insn "*pushxf"
3167 [(set (match_operand:XF 0 "push_operand" "=<,<,<,<,<")
3168 (match_operand:XF 1 "general_no_elim_operand" "f,r,*r,oF,oC"))]
3171 /* This insn should be already split before reg-stack. */
3174 [(set_attr "isa" "*,*,*,nox64,x64")
3175 (set_attr "type" "multi")
3176 (set_attr "unit" "i387,*,*,*,*")
3178 (cond [(eq_attr "alternative" "1,2,3,4")
3179 (if_then_else (match_test "TARGET_64BIT")
3181 (const_string "SI"))
3183 (const_string "XF")))
3184 (set (attr "preferred_for_size")
3185 (cond [(eq_attr "alternative" "1")
3186 (symbol_ref "false")]
3187 (symbol_ref "true")))])
3189 ;; %%% Kill this when call knows how to work this out.
3191 [(set (match_operand:XF 0 "push_operand")
3192 (match_operand:XF 1 "fp_register_operand"))]
3194 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
3195 (set (match_dup 0) (match_dup 1))]
3197 operands[2] = GEN_INT (-PUSH_ROUNDING (GET_MODE_SIZE (XFmode)));
3198 /* Preserve memory attributes. */
3199 operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
3202 (define_insn "*pushdf"
3203 [(set (match_operand:DF 0 "push_operand" "=<,<,<,<,<,<")
3204 (match_operand:DF 1 "general_no_elim_operand" "f,r,*r,oF,rmC,x"))]
3207 /* This insn should be already split before reg-stack. */
3210 [(set_attr "isa" "*,nox64,nox64,nox64,x64,sse2")
3211 (set_attr "type" "multi")
3212 (set_attr "unit" "i387,*,*,*,*,sse")
3213 (set_attr "mode" "DF,SI,SI,SI,DI,DF")
3214 (set (attr "preferred_for_size")
3215 (cond [(eq_attr "alternative" "1")
3216 (symbol_ref "false")]
3217 (symbol_ref "true")))
3218 (set (attr "preferred_for_speed")
3219 (cond [(eq_attr "alternative" "1")
3220 (symbol_ref "TARGET_INTEGER_DFMODE_MOVES")]
3221 (symbol_ref "true")))])
3223 ;; %%% Kill this when call knows how to work this out.
3225 [(set (match_operand:DF 0 "push_operand")
3226 (match_operand:DF 1 "any_fp_register_operand"))]
3228 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
3229 (set (match_dup 0) (match_dup 1))]
3231 /* Preserve memory attributes. */
3232 operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
3235 (define_insn "*pushsf_rex64"
3236 [(set (match_operand:SF 0 "push_operand" "=X,X,X")
3237 (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
3240 /* Anything else should be already split before reg-stack. */
3241 gcc_assert (which_alternative == 1);
3242 return "push{q}\t%q1";
3244 [(set_attr "type" "multi,push,multi")
3245 (set_attr "unit" "i387,*,*")
3246 (set_attr "mode" "SF,DI,SF")])
3248 (define_insn "*pushsf"
3249 [(set (match_operand:SF 0 "push_operand" "=<,<,<")
3250 (match_operand:SF 1 "general_no_elim_operand" "f,rmF,x"))]
3253 /* Anything else should be already split before reg-stack. */
3254 gcc_assert (which_alternative == 1);
3255 return "push{l}\t%1";
3257 [(set_attr "type" "multi,push,multi")
3258 (set_attr "unit" "i387,*,*")
3259 (set_attr "mode" "SF,SI,SF")])
3261 ;; %%% Kill this when call knows how to work this out.
3263 [(set (match_operand:SF 0 "push_operand")
3264 (match_operand:SF 1 "any_fp_register_operand"))]
3266 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
3267 (set (match_dup 0) (match_dup 1))]
3269 rtx op = XEXP (operands[0], 0);
3270 if (GET_CODE (op) == PRE_DEC)
3272 gcc_assert (!TARGET_64BIT);
3277 op = XEXP (XEXP (op, 1), 1);
3278 gcc_assert (CONST_INT_P (op));
3281 /* Preserve memory attributes. */
3282 operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
3286 [(set (match_operand:SF 0 "push_operand")
3287 (match_operand:SF 1 "memory_operand"))]
3289 && find_constant_src (insn)"
3290 [(set (match_dup 0) (match_dup 2))]
3291 "operands[2] = find_constant_src (curr_insn);")
3294 [(set (match_operand 0 "push_operand")
3295 (match_operand 1 "general_gr_operand"))]
3297 && (GET_MODE (operands[0]) == TFmode
3298 || GET_MODE (operands[0]) == XFmode
3299 || GET_MODE (operands[0]) == DFmode)"
3301 "ix86_split_long_move (operands); DONE;")
3303 ;; Floating point move instructions.
3305 (define_expand "movtf"
3306 [(set (match_operand:TF 0 "nonimmediate_operand")
3307 (match_operand:TF 1 "nonimmediate_operand"))]
3308 "TARGET_64BIT || TARGET_SSE"
3309 "ix86_expand_move (TFmode, operands); DONE;")
3311 (define_expand "mov<mode>"
3312 [(set (match_operand:X87MODEF 0 "nonimmediate_operand")
3313 (match_operand:X87MODEF 1 "general_operand"))]
3315 "ix86_expand_move (<MODE>mode, operands); DONE;")
3317 (define_insn "*movtf_internal"
3318 [(set (match_operand:TF 0 "nonimmediate_operand" "=v,v ,m,?*r ,!o")
3319 (match_operand:TF 1 "general_operand" "C ,vm,v,*roF,*rC"))]
3320 "(TARGET_64BIT || TARGET_SSE)
3321 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3322 && (lra_in_progress || reload_completed
3323 || !CONST_DOUBLE_P (operands[1])
3324 || ((optimize_function_for_size_p (cfun)
3325 || (ix86_cmodel == CM_LARGE || ix86_cmodel == CM_LARGE_PIC))
3326 && standard_sse_constant_p (operands[1], TFmode) == 1
3327 && !memory_operand (operands[0], TFmode))
3328 || (!TARGET_MEMORY_MISMATCH_STALL
3329 && memory_operand (operands[0], TFmode)))"
3331 switch (get_attr_type (insn))
3334 return standard_sse_constant_opcode (insn, operands);
3337 /* Handle misaligned load/store since we
3338 don't have movmisaligntf pattern. */
3339 if (misaligned_operand (operands[0], TFmode)
3340 || misaligned_operand (operands[1], TFmode))
3342 if (get_attr_mode (insn) == MODE_V4SF)
3343 return "%vmovups\t{%1, %0|%0, %1}";
3344 else if (TARGET_AVX512VL
3345 && (EXT_REX_SSE_REG_P (operands[0])
3346 || EXT_REX_SSE_REG_P (operands[1])))
3347 return "vmovdqu64\t{%1, %0|%0, %1}";
3349 return "%vmovdqu\t{%1, %0|%0, %1}";
3353 if (get_attr_mode (insn) == MODE_V4SF)
3354 return "%vmovaps\t{%1, %0|%0, %1}";
3355 else if (TARGET_AVX512VL
3356 && (EXT_REX_SSE_REG_P (operands[0])
3357 || EXT_REX_SSE_REG_P (operands[1])))
3358 return "vmovdqa64\t{%1, %0|%0, %1}";
3360 return "%vmovdqa\t{%1, %0|%0, %1}";
3370 [(set_attr "isa" "*,*,*,x64,x64")
3371 (set_attr "type" "sselog1,ssemov,ssemov,multi,multi")
3372 (set (attr "prefix")
3373 (if_then_else (eq_attr "type" "sselog1,ssemov")
3374 (const_string "maybe_vex")
3375 (const_string "orig")))
3377 (cond [(eq_attr "alternative" "3,4")
3379 (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
3380 (const_string "V4SF")
3381 (and (eq_attr "alternative" "2")
3382 (match_test "TARGET_SSE_TYPELESS_STORES"))
3383 (const_string "V4SF")
3384 (match_test "TARGET_AVX")
3386 (ior (not (match_test "TARGET_SSE2"))
3387 (match_test "optimize_function_for_size_p (cfun)"))
3388 (const_string "V4SF")
3390 (const_string "TI")))])
3393 [(set (match_operand:TF 0 "nonimmediate_gr_operand")
3394 (match_operand:TF 1 "general_gr_operand"))]
3397 "ix86_split_long_move (operands); DONE;")
3399 ;; Possible store forwarding (partial memory) stall
3400 ;; in alternatives 4, 6, 7 and 8.
3401 (define_insn "*movxf_internal"
3402 [(set (match_operand:XF 0 "nonimmediate_operand"
3403 "=f,m,f,?r ,!o,?*r ,!o,!o,!o,r ,o ,o")
3404 (match_operand:XF 1 "general_operand"
3405 "fm,f,G,roF,r ,*roF,*r,F ,C ,roF,rF,rC"))]
3406 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3407 && (lra_in_progress || reload_completed
3408 || !CONST_DOUBLE_P (operands[1])
3409 || ((optimize_function_for_size_p (cfun)
3410 || (ix86_cmodel == CM_LARGE || ix86_cmodel == CM_LARGE_PIC))
3411 && standard_80387_constant_p (operands[1]) > 0
3412 && !memory_operand (operands[0], XFmode))
3413 || (!TARGET_MEMORY_MISMATCH_STALL
3414 && memory_operand (operands[0], XFmode))
3415 || !TARGET_HARD_XF_REGS)"
3417 switch (get_attr_type (insn))
3420 if (which_alternative == 2)
3421 return standard_80387_constant_opcode (operands[1]);
3422 return output_387_reg_move (insn, operands);
3432 (cond [(eq_attr "alternative" "7,10")
3433 (const_string "nox64")
3434 (eq_attr "alternative" "8,11")
3435 (const_string "x64")
3437 (const_string "*")))
3439 (cond [(eq_attr "alternative" "3,4,5,6,7,8,9,10,11")
3440 (const_string "multi")
3442 (const_string "fmov")))
3444 (cond [(eq_attr "alternative" "3,4,5,6,7,8,9,10,11")
3445 (if_then_else (match_test "TARGET_64BIT")
3447 (const_string "SI"))
3449 (const_string "XF")))
3450 (set (attr "preferred_for_size")
3451 (cond [(eq_attr "alternative" "3,4")
3452 (symbol_ref "false")]
3453 (symbol_ref "true")))
3454 (set (attr "enabled")
3455 (cond [(eq_attr "alternative" "9,10,11")
3457 (match_test "TARGET_HARD_XF_REGS")
3458 (symbol_ref "false")
3460 (not (match_test "TARGET_HARD_XF_REGS"))
3461 (symbol_ref "false")
3463 (const_string "*")))])
3466 [(set (match_operand:XF 0 "nonimmediate_gr_operand")
3467 (match_operand:XF 1 "general_gr_operand"))]
3470 "ix86_split_long_move (operands); DONE;")
3472 ;; Possible store forwarding (partial memory) stall in alternatives 4, 6 and 7.
3473 (define_insn "*movdf_internal"
3474 [(set (match_operand:DF 0 "nonimmediate_operand"
3475 "=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")
3476 (match_operand:DF 1 "general_operand"
3477 "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"))]
3478 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3479 && (lra_in_progress || reload_completed
3480 || !CONST_DOUBLE_P (operands[1])
3481 || ((optimize_function_for_size_p (cfun)
3482 || (ix86_cmodel == CM_LARGE || ix86_cmodel == CM_LARGE_PIC))
3483 && ((IS_STACK_MODE (DFmode)
3484 && standard_80387_constant_p (operands[1]) > 0)
3485 || (TARGET_SSE2 && TARGET_SSE_MATH
3486 && standard_sse_constant_p (operands[1], DFmode) == 1))
3487 && !memory_operand (operands[0], DFmode))
3488 || ((TARGET_64BIT || !TARGET_MEMORY_MISMATCH_STALL)
3489 && memory_operand (operands[0], DFmode))
3490 || !TARGET_HARD_DF_REGS)"
3492 switch (get_attr_type (insn))
3495 if (which_alternative == 2)
3496 return standard_80387_constant_opcode (operands[1]);
3497 return output_387_reg_move (insn, operands);
3503 if (get_attr_mode (insn) == MODE_SI)
3504 return "mov{l}\t{%1, %k0|%k0, %1}";
3505 else if (which_alternative == 11)
3506 return "movabs{q}\t{%1, %0|%0, %1}";
3508 return "mov{q}\t{%1, %0|%0, %1}";
3511 return standard_sse_constant_opcode (insn, operands);
3514 switch (get_attr_mode (insn))
3517 if (TARGET_AVX && REG_P (operands[0]) && REG_P (operands[1]))
3518 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
3519 return "%vmovsd\t{%1, %0|%0, %1}";
3522 return "%vmovaps\t{%1, %0|%0, %1}";
3524 return "vmovapd\t{%g1, %g0|%g0, %g1}";
3526 return "%vmovapd\t{%1, %0|%0, %1}";
3529 gcc_assert (!TARGET_AVX);
3530 return "movlps\t{%1, %0|%0, %1}";
3532 gcc_assert (!TARGET_AVX);
3533 return "movlpd\t{%1, %0|%0, %1}";
3536 /* Handle broken assemblers that require movd instead of movq. */
3537 if (!HAVE_AS_IX86_INTERUNIT_MOVQ
3538 && (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1])))
3539 return "%vmovd\t{%1, %0|%0, %1}";
3540 return "%vmovq\t{%1, %0|%0, %1}";
3551 (cond [(eq_attr "alternative" "3,4,5,6,7,22,23")
3552 (const_string "nox64")
3553 (eq_attr "alternative" "8,9,10,11,20,21,24,25")
3554 (const_string "x64")
3555 (eq_attr "alternative" "12,13,14,15")
3556 (const_string "sse2")
3558 (const_string "*")))
3560 (cond [(eq_attr "alternative" "0,1,2")
3561 (const_string "fmov")
3562 (eq_attr "alternative" "3,4,5,6,7,22,23")
3563 (const_string "multi")
3564 (eq_attr "alternative" "8,9,10,11,24,25")
3565 (const_string "imov")
3566 (eq_attr "alternative" "12,16")
3567 (const_string "sselog1")
3569 (const_string "ssemov")))
3571 (if_then_else (eq_attr "alternative" "11")
3573 (const_string "*")))
3574 (set (attr "length_immediate")
3575 (if_then_else (eq_attr "alternative" "11")
3577 (const_string "*")))
3578 (set (attr "prefix")
3579 (if_then_else (eq_attr "type" "sselog1,ssemov")
3580 (const_string "maybe_vex")
3581 (const_string "orig")))
3582 (set (attr "prefix_data16")
3584 (ior (and (eq_attr "type" "ssemov") (eq_attr "mode" "DI"))
3585 (eq_attr "mode" "V1DF"))
3587 (const_string "*")))
3589 (cond [(eq_attr "alternative" "3,4,5,6,7,10,22,23")
3591 (eq_attr "alternative" "8,9,11,20,21,24,25")
3594 /* xorps is one byte shorter for non-AVX targets. */
3595 (eq_attr "alternative" "12,16")
3596 (cond [(not (match_test "TARGET_SSE2"))
3597 (const_string "V4SF")
3598 (and (match_test "TARGET_AVX512F")
3599 (not (match_test "TARGET_PREFER_AVX256")))
3601 (match_test "TARGET_AVX")
3602 (const_string "V2DF")
3603 (match_test "optimize_function_for_size_p (cfun)")
3604 (const_string "V4SF")
3605 (match_test "TARGET_SSE_LOAD0_BY_PXOR")
3608 (const_string "V2DF"))
3610 /* For architectures resolving dependencies on
3611 whole SSE registers use movapd to break dependency
3612 chains, otherwise use short move to avoid extra work. */
3614 /* movaps is one byte shorter for non-AVX targets. */
3615 (eq_attr "alternative" "13,17")
3616 (cond [(and (ior (not (match_test "TARGET_PREFER_AVX256"))
3617 (not (match_test "TARGET_AVX512VL")))
3618 (ior (match_operand 0 "ext_sse_reg_operand")
3619 (match_operand 1 "ext_sse_reg_operand")))
3620 (const_string "V8DF")
3621 (ior (not (match_test "TARGET_SSE2"))
3622 (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL"))
3623 (const_string "V4SF")
3624 (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3625 (const_string "V2DF")
3626 (match_test "TARGET_AVX")
3628 (match_test "optimize_function_for_size_p (cfun)")
3629 (const_string "V4SF")
3631 (const_string "DF"))
3633 /* For architectures resolving dependencies on register
3634 parts we may avoid extra work to zero out upper part
3636 (eq_attr "alternative" "14,18")
3637 (cond [(not (match_test "TARGET_SSE2"))
3638 (const_string "V2SF")
3639 (match_test "TARGET_AVX")
3641 (match_test "TARGET_SSE_SPLIT_REGS")
3642 (const_string "V1DF")
3644 (const_string "DF"))
3646 (and (eq_attr "alternative" "15,19")
3647 (not (match_test "TARGET_SSE2")))
3648 (const_string "V2SF")
3650 (const_string "DF")))
3651 (set (attr "preferred_for_size")
3652 (cond [(eq_attr "alternative" "3,4")
3653 (symbol_ref "false")]
3654 (symbol_ref "true")))
3655 (set (attr "preferred_for_speed")
3656 (cond [(eq_attr "alternative" "3,4")
3657 (symbol_ref "TARGET_INTEGER_DFMODE_MOVES")]
3658 (symbol_ref "true")))
3659 (set (attr "enabled")
3660 (cond [(eq_attr "alternative" "22,23,24,25")
3662 (match_test "TARGET_HARD_DF_REGS")
3663 (symbol_ref "false")
3665 (not (match_test "TARGET_HARD_DF_REGS"))
3666 (symbol_ref "false")
3668 (const_string "*")))])
3671 [(set (match_operand:DF 0 "nonimmediate_gr_operand")
3672 (match_operand:DF 1 "general_gr_operand"))]
3673 "!TARGET_64BIT && reload_completed"
3675 "ix86_split_long_move (operands); DONE;")
3677 (define_insn "*movsf_internal"
3678 [(set (match_operand:SF 0 "nonimmediate_operand"
3679 "=Yf*f,m ,Yf*f,?r ,?m,v,v,v,m,?r,?Yi,!*y,!*y,!m,!r ,!*Ym,r ,m")
3680 (match_operand:SF 1 "general_operand"
3681 "Yf*fm,Yf*f,G ,rmF,rF,C,v,m,v,Yj,r ,*y ,m ,*y,*Yn,r ,rmF,rF"))]
3682 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3683 && (lra_in_progress || reload_completed
3684 || !CONST_DOUBLE_P (operands[1])
3685 || ((optimize_function_for_size_p (cfun)
3686 || (ix86_cmodel == CM_LARGE || ix86_cmodel == CM_LARGE_PIC))
3687 && ((IS_STACK_MODE (SFmode)
3688 && standard_80387_constant_p (operands[1]) > 0)
3689 || (TARGET_SSE && TARGET_SSE_MATH
3690 && standard_sse_constant_p (operands[1], SFmode) == 1)))
3691 || memory_operand (operands[0], SFmode)
3692 || !TARGET_HARD_SF_REGS)"
3694 switch (get_attr_type (insn))
3697 if (which_alternative == 2)
3698 return standard_80387_constant_opcode (operands[1]);
3699 return output_387_reg_move (insn, operands);
3702 return "mov{l}\t{%1, %0|%0, %1}";
3705 return standard_sse_constant_opcode (insn, operands);
3708 switch (get_attr_mode (insn))
3711 if (TARGET_AVX && REG_P (operands[0]) && REG_P (operands[1]))
3712 return "vmovss\t{%1, %0, %0|%0, %0, %1}";
3713 return "%vmovss\t{%1, %0|%0, %1}";
3716 return "vmovaps\t{%g1, %g0|%g0, %g1}";
3718 return "%vmovaps\t{%1, %0|%0, %1}";
3721 return "%vmovd\t{%1, %0|%0, %1}";
3728 switch (get_attr_mode (insn))
3731 return "movq\t{%1, %0|%0, %1}";
3733 return "movd\t{%1, %0|%0, %1}";
3744 (cond [(eq_attr "alternative" "0,1,2")
3745 (const_string "fmov")
3746 (eq_attr "alternative" "3,4,16,17")
3747 (const_string "imov")
3748 (eq_attr "alternative" "5")
3749 (const_string "sselog1")
3750 (eq_attr "alternative" "11,12,13,14,15")
3751 (const_string "mmxmov")
3753 (const_string "ssemov")))
3754 (set (attr "prefix")
3755 (if_then_else (eq_attr "type" "sselog1,ssemov")
3756 (const_string "maybe_vex")
3757 (const_string "orig")))
3758 (set (attr "prefix_data16")
3759 (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
3761 (const_string "*")))
3763 (cond [(eq_attr "alternative" "3,4,9,10,12,13,14,15,16,17")
3765 (eq_attr "alternative" "11")
3767 (eq_attr "alternative" "5")
3768 (cond [(not (match_test "TARGET_SSE2"))
3769 (const_string "V4SF")
3770 (and (match_test "TARGET_AVX512F")
3771 (not (match_test "TARGET_PREFER_AVX256")))
3772 (const_string "V16SF")
3773 (match_test "TARGET_AVX")
3774 (const_string "V4SF")
3775 (match_test "optimize_function_for_size_p (cfun)")
3776 (const_string "V4SF")
3777 (match_test "TARGET_SSE_LOAD0_BY_PXOR")
3780 (const_string "V4SF"))
3782 /* For architectures resolving dependencies on
3783 whole SSE registers use APS move to break dependency
3784 chains, otherwise use short move to avoid extra work.
3786 Do the same for architectures resolving dependencies on
3787 the parts. While in DF mode it is better to always handle
3788 just register parts, the SF mode is different due to lack
3789 of instructions to load just part of the register. It is
3790 better to maintain the whole registers in single format
3791 to avoid problems on using packed logical operations. */
3792 (eq_attr "alternative" "6")
3793 (cond [(and (ior (not (match_test "TARGET_PREFER_AVX256"))
3794 (not (match_test "TARGET_AVX512VL")))
3795 (ior (match_operand 0 "ext_sse_reg_operand")
3796 (match_operand 1 "ext_sse_reg_operand")))
3797 (const_string "V16SF")
3798 (ior (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3799 (match_test "TARGET_SSE_SPLIT_REGS"))
3800 (const_string "V4SF")
3802 (const_string "SF"))
3804 (const_string "SF")))
3805 (set (attr "enabled")
3806 (cond [(eq_attr "alternative" "16,17")
3808 (match_test "TARGET_HARD_SF_REGS")
3809 (symbol_ref "false")
3811 (not (match_test "TARGET_HARD_SF_REGS"))
3812 (symbol_ref "false")
3814 (const_string "*")))])
3817 [(set (match_operand 0 "any_fp_register_operand")
3818 (match_operand 1 "nonimmediate_operand"))]
3820 && (GET_MODE (operands[0]) == TFmode
3821 || GET_MODE (operands[0]) == XFmode
3822 || GET_MODE (operands[0]) == DFmode
3823 || GET_MODE (operands[0]) == SFmode)
3824 && ix86_standard_x87sse_constant_load_p (insn, operands[0])"
3825 [(set (match_dup 0) (match_dup 2))]
3826 "operands[2] = find_constant_src (curr_insn);")
3829 [(set (match_operand 0 "any_fp_register_operand")
3830 (float_extend (match_operand 1 "nonimmediate_operand")))]
3832 && (GET_MODE (operands[0]) == TFmode
3833 || GET_MODE (operands[0]) == XFmode
3834 || GET_MODE (operands[0]) == DFmode)
3835 && ix86_standard_x87sse_constant_load_p (insn, operands[0])"
3836 [(set (match_dup 0) (match_dup 2))]
3837 "operands[2] = find_constant_src (curr_insn);")
3839 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
3841 [(set (match_operand:X87MODEF 0 "fp_register_operand")
3842 (match_operand:X87MODEF 1 "immediate_operand"))]
3844 && (standard_80387_constant_p (operands[1]) == 8
3845 || standard_80387_constant_p (operands[1]) == 9)"
3846 [(set (match_dup 0)(match_dup 1))
3848 (neg:X87MODEF (match_dup 0)))]
3850 if (real_isnegzero (CONST_DOUBLE_REAL_VALUE (operands[1])))
3851 operands[1] = CONST0_RTX (<MODE>mode);
3853 operands[1] = CONST1_RTX (<MODE>mode);
3856 (define_insn "swapxf"
3857 [(set (match_operand:XF 0 "register_operand" "+f")
3858 (match_operand:XF 1 "register_operand" "+f"))
3863 if (STACK_TOP_P (operands[0]))
3868 [(set_attr "type" "fxch")
3869 (set_attr "mode" "XF")])
3871 (define_insn "*swap<mode>"
3872 [(set (match_operand:MODEF 0 "fp_register_operand" "+f")
3873 (match_operand:MODEF 1 "fp_register_operand" "+f"))
3876 "TARGET_80387 || reload_completed"
3878 if (STACK_TOP_P (operands[0]))
3883 [(set_attr "type" "fxch")
3884 (set_attr "mode" "<MODE>")])
3886 ;; Zero extension instructions
3888 (define_expand "zero_extendsidi2"
3889 [(set (match_operand:DI 0 "nonimmediate_operand")
3890 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand")))])
3892 (define_insn "*zero_extendsidi2"
3893 [(set (match_operand:DI 0 "nonimmediate_operand"
3894 "=r,?r,?o,r ,o,?*Ym,?!*y,$r,$Yi,$x,*x,*v,*r")
3896 (match_operand:SI 1 "x86_64_zext_operand"
3897 "0 ,rm,r ,rmWz,0,r ,m ,Yj,r ,m ,*x,*v,*k")))]
3900 switch (get_attr_type (insn))
3903 if (ix86_use_lea_for_mov (insn, operands))
3904 return "lea{l}\t{%E1, %k0|%k0, %E1}";
3906 return "mov{l}\t{%1, %k0|%k0, %1}";
3912 return "movd\t{%1, %0|%0, %1}";
3915 if (SSE_REG_P (operands[0]) && SSE_REG_P (operands[1]))
3917 if (EXT_REX_SSE_REG_P (operands[0])
3918 || EXT_REX_SSE_REG_P (operands[1]))
3919 return "vpmovzxdq\t{%t1, %g0|%g0, %t1}";
3921 return "%vpmovzxdq\t{%1, %0|%0, %1}";
3924 if (GENERAL_REG_P (operands[0]))
3925 return "%vmovd\t{%1, %k0|%k0, %1}";
3927 return "%vmovd\t{%1, %0|%0, %1}";
3930 return "kmovd\t{%1, %k0|%k0, %1}";
3937 (cond [(eq_attr "alternative" "0,1,2")
3938 (const_string "nox64")
3939 (eq_attr "alternative" "3")
3940 (const_string "x64")
3941 (eq_attr "alternative" "9")
3942 (const_string "sse2")
3943 (eq_attr "alternative" "10")
3944 (const_string "sse4")
3945 (eq_attr "alternative" "11")
3946 (const_string "avx512f")
3947 (eq_attr "alternative" "12")
3948 (const_string "x64_avx512bw")
3950 (const_string "*")))
3952 (cond [(eq_attr "alternative" "0,1,2,4")
3953 (const_string "multi")
3954 (eq_attr "alternative" "5,6")
3955 (const_string "mmxmov")
3956 (eq_attr "alternative" "7")
3957 (if_then_else (match_test "TARGET_64BIT")
3958 (const_string "ssemov")
3959 (const_string "multi"))
3960 (eq_attr "alternative" "8,9,10,11")
3961 (const_string "ssemov")
3962 (eq_attr "alternative" "12")
3963 (const_string "mskmov")
3965 (const_string "imovx")))
3966 (set (attr "prefix_extra")
3967 (if_then_else (eq_attr "alternative" "10,11")
3969 (const_string "*")))
3970 (set (attr "prefix")
3971 (if_then_else (eq_attr "type" "ssemov")
3972 (const_string "maybe_vex")
3973 (const_string "orig")))
3974 (set (attr "prefix_0f")
3975 (if_then_else (eq_attr "type" "imovx")
3977 (const_string "*")))
3979 (cond [(eq_attr "alternative" "5,6")
3981 (and (eq_attr "alternative" "7")
3982 (match_test "TARGET_64BIT"))
3984 (eq_attr "alternative" "8,10,11")
3987 (const_string "SI")))])
3990 [(set (match_operand:DI 0 "memory_operand")
3991 (zero_extend:DI (match_operand:SI 1 "memory_operand")))]
3993 [(set (match_dup 4) (const_int 0))]
3994 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3997 [(set (match_operand:DI 0 "general_reg_operand")
3998 (zero_extend:DI (match_operand:SI 1 "general_reg_operand")))]
3999 "!TARGET_64BIT && reload_completed
4000 && REGNO (operands[0]) == REGNO (operands[1])"
4001 [(set (match_dup 4) (const_int 0))]
4002 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
4005 [(set (match_operand:DI 0 "nonimmediate_gr_operand")
4006 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand")))]
4007 "!TARGET_64BIT && reload_completed
4008 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
4009 [(set (match_dup 3) (match_dup 1))
4010 (set (match_dup 4) (const_int 0))]
4011 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
4013 (define_mode_attr kmov_isa
4014 [(QI "avx512dq") (HI "avx512f") (SI "avx512bw") (DI "avx512bw")])
4016 (define_insn "zero_extend<mode>di2"
4017 [(set (match_operand:DI 0 "register_operand" "=r,*r")
4019 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m,*k")))]
4022 movz{<imodesuffix>l|x}\t{%1, %k0|%k0, %1}
4023 kmov<mskmodesuffix>\t{%1, %k0|%k0, %1}"
4024 [(set_attr "isa" "*,<kmov_isa>")
4025 (set_attr "type" "imovx,mskmov")
4026 (set_attr "mode" "SI,<MODE>")])
4028 (define_expand "zero_extend<mode>si2"
4029 [(set (match_operand:SI 0 "register_operand")
4030 (zero_extend:SI (match_operand:SWI12 1 "nonimmediate_operand")))]
4033 if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
4035 operands[1] = force_reg (<MODE>mode, operands[1]);
4036 emit_insn (gen_zero_extend<mode>si2_and (operands[0], operands[1]));
4041 (define_insn_and_split "zero_extend<mode>si2_and"
4042 [(set (match_operand:SI 0 "register_operand" "=r,?&<r>")
4044 (match_operand:SWI12 1 "nonimmediate_operand" "0,<r>m")))
4045 (clobber (reg:CC FLAGS_REG))]
4046 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
4048 "&& reload_completed"
4049 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (match_dup 2)))
4050 (clobber (reg:CC FLAGS_REG))])]
4052 if (!REG_P (operands[1])
4053 || REGNO (operands[0]) != REGNO (operands[1]))
4055 ix86_expand_clear (operands[0]);
4057 gcc_assert (!TARGET_PARTIAL_REG_STALL);
4058 emit_insn (gen_movstrict<mode>
4059 (gen_lowpart (<MODE>mode, operands[0]), operands[1]));
4063 operands[2] = GEN_INT (GET_MODE_MASK (<MODE>mode));
4065 [(set_attr "type" "alu1")
4066 (set_attr "mode" "SI")])
4068 (define_insn "*zero_extend<mode>si2"
4069 [(set (match_operand:SI 0 "register_operand" "=r,*r")
4071 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m,*k")))]
4072 "!(TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))"
4074 movz{<imodesuffix>l|x}\t{%1, %0|%0, %1}
4075 kmov<mskmodesuffix>\t{%1, %0|%0, %1}"
4076 [(set_attr "isa" "*,<kmov_isa>")
4077 (set_attr "type" "imovx,mskmov")
4078 (set_attr "mode" "SI,<MODE>")])
4080 (define_expand "zero_extendqihi2"
4081 [(set (match_operand:HI 0 "register_operand")
4082 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand")))]
4085 if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
4087 operands[1] = force_reg (QImode, operands[1]);
4088 emit_insn (gen_zero_extendqihi2_and (operands[0], operands[1]));
4093 (define_insn_and_split "zero_extendqihi2_and"
4094 [(set (match_operand:HI 0 "register_operand" "=r,?&q")
4095 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
4096 (clobber (reg:CC FLAGS_REG))]
4097 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
4099 "&& reload_completed"
4100 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
4101 (clobber (reg:CC FLAGS_REG))])]
4103 if (!REG_P (operands[1])
4104 || REGNO (operands[0]) != REGNO (operands[1]))
4106 ix86_expand_clear (operands[0]);
4108 gcc_assert (!TARGET_PARTIAL_REG_STALL);
4109 emit_insn (gen_movstrictqi
4110 (gen_lowpart (QImode, operands[0]), operands[1]));
4114 operands[0] = gen_lowpart (SImode, operands[0]);
4116 [(set_attr "type" "alu1")
4117 (set_attr "mode" "SI")])
4119 ; zero extend to SImode to avoid partial register stalls
4120 (define_insn "*zero_extendqihi2"
4121 [(set (match_operand:HI 0 "register_operand" "=r,*r")
4122 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,*k")))]
4123 "!(TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))"
4125 movz{bl|x}\t{%1, %k0|%k0, %1}
4126 kmovb\t{%1, %k0|%k0, %1}"
4127 [(set_attr "isa" "*,avx512dq")
4128 (set_attr "type" "imovx,mskmov")
4129 (set_attr "mode" "SI,QI")])
4131 (define_insn_and_split "*zext<mode>_doubleword_and"
4132 [(set (match_operand:DI 0 "register_operand" "=&<r>")
4133 (zero_extend:DI (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
4134 "!TARGET_64BIT && TARGET_STV && TARGET_SSE2
4135 && TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
4137 "&& reload_completed && GENERAL_REG_P (operands[0])"
4138 [(set (match_dup 2) (const_int 0))]
4140 split_double_mode (DImode, &operands[0], 1, &operands[0], &operands[2]);
4142 emit_move_insn (operands[0], const0_rtx);
4144 gcc_assert (!TARGET_PARTIAL_REG_STALL);
4145 emit_insn (gen_movstrict<mode>
4146 (gen_lowpart (<MODE>mode, operands[0]), operands[1]));
4149 (define_insn_and_split "*zext<mode>_doubleword"
4150 [(set (match_operand:DI 0 "register_operand" "=r")
4151 (zero_extend:DI (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
4152 "!TARGET_64BIT && TARGET_STV && TARGET_SSE2
4153 && !(TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))"
4155 "&& reload_completed && GENERAL_REG_P (operands[0])"
4156 [(set (match_dup 0) (zero_extend:SI (match_dup 1)))
4157 (set (match_dup 2) (const_int 0))]
4158 "split_double_mode (DImode, &operands[0], 1, &operands[0], &operands[2]);")
4160 (define_insn_and_split "*zextsi_doubleword"
4161 [(set (match_operand:DI 0 "register_operand" "=r")
4162 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm")))]
4163 "!TARGET_64BIT && TARGET_STV && TARGET_SSE2"
4165 "&& reload_completed && GENERAL_REG_P (operands[0])"
4166 [(set (match_dup 0) (match_dup 1))
4167 (set (match_dup 2) (const_int 0))]
4168 "split_double_mode (DImode, &operands[0], 1, &operands[0], &operands[2]);")
4170 ;; Sign extension instructions
4172 (define_expand "extendsidi2"
4173 [(set (match_operand:DI 0 "register_operand")
4174 (sign_extend:DI (match_operand:SI 1 "register_operand")))]
4179 emit_insn (gen_extendsidi2_1 (operands[0], operands[1]));
4184 (define_insn "*extendsidi2_rex64"
4185 [(set (match_operand:DI 0 "register_operand" "=*a,r")
4186 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
4190 movs{lq|x}\t{%1, %0|%0, %1}"
4191 [(set_attr "type" "imovx")
4192 (set_attr "mode" "DI")
4193 (set_attr "prefix_0f" "0")
4194 (set_attr "modrm" "0,1")])
4196 (define_insn "extendsidi2_1"
4197 [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
4198 (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
4199 (clobber (reg:CC FLAGS_REG))
4200 (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
4204 ;; Split the memory case. If the source register doesn't die, it will stay
4205 ;; this way, if it does die, following peephole2s take care of it.
4207 [(set (match_operand:DI 0 "memory_operand")
4208 (sign_extend:DI (match_operand:SI 1 "register_operand")))
4209 (clobber (reg:CC FLAGS_REG))
4210 (clobber (match_operand:SI 2 "register_operand"))]
4214 split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
4216 emit_move_insn (operands[3], operands[1]);
4218 /* Generate a cltd if possible and doing so it profitable. */
4219 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
4220 && REGNO (operands[1]) == AX_REG
4221 && REGNO (operands[2]) == DX_REG)
4223 emit_insn (gen_ashrsi3_cvt (operands[2], operands[1], GEN_INT (31)));
4227 emit_move_insn (operands[2], operands[1]);
4228 emit_insn (gen_ashrsi3_cvt (operands[2], operands[2], GEN_INT (31)));
4230 emit_move_insn (operands[4], operands[2]);
4234 ;; Peepholes for the case where the source register does die, after
4235 ;; being split with the above splitter.
4237 [(set (match_operand:SI 0 "memory_operand")
4238 (match_operand:SI 1 "general_reg_operand"))
4239 (set (match_operand:SI 2 "general_reg_operand") (match_dup 1))
4240 (parallel [(set (match_dup 2)
4241 (ashiftrt:SI (match_dup 2) (const_int 31)))
4242 (clobber (reg:CC FLAGS_REG))])
4243 (set (match_operand:SI 3 "memory_operand") (match_dup 2))]
4244 "REGNO (operands[1]) != REGNO (operands[2])
4245 && peep2_reg_dead_p (2, operands[1])
4246 && peep2_reg_dead_p (4, operands[2])
4247 && !reg_mentioned_p (operands[2], operands[3])"
4248 [(set (match_dup 0) (match_dup 1))
4249 (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
4250 (clobber (reg:CC FLAGS_REG))])
4251 (set (match_dup 3) (match_dup 1))])
4254 [(set (match_operand:SI 0 "memory_operand")
4255 (match_operand:SI 1 "general_reg_operand"))
4256 (parallel [(set (match_operand:SI 2 "general_reg_operand")
4257 (ashiftrt:SI (match_dup 1) (const_int 31)))
4258 (clobber (reg:CC FLAGS_REG))])
4259 (set (match_operand:SI 3 "memory_operand") (match_dup 2))]
4260 "/* cltd is shorter than sarl $31, %eax */
4261 !optimize_function_for_size_p (cfun)
4262 && REGNO (operands[1]) == AX_REG
4263 && REGNO (operands[2]) == DX_REG
4264 && peep2_reg_dead_p (2, operands[1])
4265 && peep2_reg_dead_p (3, operands[2])
4266 && !reg_mentioned_p (operands[2], operands[3])"
4267 [(set (match_dup 0) (match_dup 1))
4268 (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
4269 (clobber (reg:CC FLAGS_REG))])
4270 (set (match_dup 3) (match_dup 1))])
4272 ;; Extend to register case. Optimize case where source and destination
4273 ;; registers match and cases where we can use cltd.
4275 [(set (match_operand:DI 0 "register_operand")
4276 (sign_extend:DI (match_operand:SI 1 "register_operand")))
4277 (clobber (reg:CC FLAGS_REG))
4278 (clobber (match_scratch:SI 2))]
4282 split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
4284 if (REGNO (operands[3]) != REGNO (operands[1]))
4285 emit_move_insn (operands[3], operands[1]);
4287 /* Generate a cltd if possible and doing so it profitable. */
4288 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
4289 && REGNO (operands[3]) == AX_REG
4290 && REGNO (operands[4]) == DX_REG)
4292 emit_insn (gen_ashrsi3_cvt (operands[4], operands[3], GEN_INT (31)));
4296 if (REGNO (operands[4]) != REGNO (operands[1]))
4297 emit_move_insn (operands[4], operands[1]);
4299 emit_insn (gen_ashrsi3_cvt (operands[4], operands[4], GEN_INT (31)));
4303 (define_insn "extend<mode>di2"
4304 [(set (match_operand:DI 0 "register_operand" "=r")
4306 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
4308 "movs{<imodesuffix>q|x}\t{%1, %0|%0, %1}"
4309 [(set_attr "type" "imovx")
4310 (set_attr "mode" "DI")])
4312 (define_insn "extendhisi2"
4313 [(set (match_operand:SI 0 "register_operand" "=*a,r")
4314 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
4317 switch (get_attr_prefix_0f (insn))
4320 return "{cwtl|cwde}";
4322 return "movs{wl|x}\t{%1, %0|%0, %1}";
4325 [(set_attr "type" "imovx")
4326 (set_attr "mode" "SI")
4327 (set (attr "prefix_0f")
4328 ;; movsx is short decodable while cwtl is vector decoded.
4329 (if_then_else (and (eq_attr "cpu" "!k6")
4330 (eq_attr "alternative" "0"))
4332 (const_string "1")))
4333 (set (attr "znver1_decode")
4334 (if_then_else (eq_attr "prefix_0f" "0")
4335 (const_string "double")
4336 (const_string "direct")))
4338 (if_then_else (eq_attr "prefix_0f" "0")
4340 (const_string "1")))])
4342 (define_insn "*extendhisi2_zext"
4343 [(set (match_operand:DI 0 "register_operand" "=*a,r")
4346 (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
4349 switch (get_attr_prefix_0f (insn))
4352 return "{cwtl|cwde}";
4354 return "movs{wl|x}\t{%1, %k0|%k0, %1}";
4357 [(set_attr "type" "imovx")
4358 (set_attr "mode" "SI")
4359 (set (attr "prefix_0f")
4360 ;; movsx is short decodable while cwtl is vector decoded.
4361 (if_then_else (and (eq_attr "cpu" "!k6")
4362 (eq_attr "alternative" "0"))
4364 (const_string "1")))
4366 (if_then_else (eq_attr "prefix_0f" "0")
4368 (const_string "1")))])
4370 (define_insn "extendqisi2"
4371 [(set (match_operand:SI 0 "register_operand" "=r")
4372 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
4374 "movs{bl|x}\t{%1, %0|%0, %1}"
4375 [(set_attr "type" "imovx")
4376 (set_attr "mode" "SI")])
4378 (define_insn "*extendqisi2_zext"
4379 [(set (match_operand:DI 0 "register_operand" "=r")
4381 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
4383 "movs{bl|x}\t{%1, %k0|%k0, %1}"
4384 [(set_attr "type" "imovx")
4385 (set_attr "mode" "SI")])
4387 (define_insn "extendqihi2"
4388 [(set (match_operand:HI 0 "register_operand" "=*a,r")
4389 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
4392 switch (get_attr_prefix_0f (insn))
4395 return "{cbtw|cbw}";
4397 return "movs{bw|x}\t{%1, %0|%0, %1}";
4400 [(set_attr "type" "imovx")
4401 (set_attr "mode" "HI")
4402 (set (attr "prefix_0f")
4403 ;; movsx is short decodable while cwtl is vector decoded.
4404 (if_then_else (and (eq_attr "cpu" "!k6")
4405 (eq_attr "alternative" "0"))
4407 (const_string "1")))
4409 (if_then_else (eq_attr "prefix_0f" "0")
4411 (const_string "1")))])
4413 ;; Conversions between float and double.
4415 ;; These are all no-ops in the model used for the 80387.
4416 ;; So just emit moves.
4418 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
4420 [(set (match_operand:DF 0 "push_operand")
4421 (float_extend:DF (match_operand:SF 1 "fp_register_operand")))]
4423 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
4424 (set (mem:DF (reg:P SP_REG)) (float_extend:DF (match_dup 1)))])
4427 [(set (match_operand:XF 0 "push_operand")
4428 (float_extend:XF (match_operand:MODEF 1 "fp_register_operand")))]
4430 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
4431 (set (mem:XF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
4432 "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
4434 (define_expand "extendsfdf2"
4435 [(set (match_operand:DF 0 "nonimm_ssenomem_operand")
4436 (float_extend:DF (match_operand:SF 1 "general_operand")))]
4437 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4439 /* ??? Needed for compress_float_constant since all fp constants
4440 are TARGET_LEGITIMATE_CONSTANT_P. */
4441 if (CONST_DOUBLE_P (operands[1]))
4443 if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
4444 && standard_80387_constant_p (operands[1]) > 0)
4446 operands[1] = simplify_const_unary_operation
4447 (FLOAT_EXTEND, DFmode, operands[1], SFmode);
4448 emit_move_insn_1 (operands[0], operands[1]);
4451 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
4455 /* For converting SF(xmm2) to DF(xmm1), use the following code instead of
4457 unpcklps xmm2,xmm2 ; packed conversion might crash on signaling NaNs
4459 We do the conversion post reload to avoid producing of 128bit spills
4460 that might lead to ICE on 32bit target. The sequence unlikely combine
4463 [(set (match_operand:DF 0 "sse_reg_operand")
4465 (match_operand:SF 1 "nonimmediate_operand")))]
4466 "TARGET_USE_VECTOR_FP_CONVERTS
4467 && optimize_insn_for_speed_p ()
4469 && (!EXT_REX_SSE_REG_P (operands[0])
4470 || TARGET_AVX512VL)"
4475 (parallel [(const_int 0) (const_int 1)]))))]
4477 operands[2] = lowpart_subreg (V2DFmode, operands[0], DFmode);
4478 operands[3] = lowpart_subreg (V4SFmode, operands[0], DFmode);
4479 /* Use movss for loading from memory, unpcklps reg, reg for registers.
4480 Try to avoid move when unpacking can be done in source. */
4481 if (REG_P (operands[1]))
4483 /* If it is unsafe to overwrite upper half of source, we need
4484 to move to destination and unpack there. */
4485 if (REGNO (operands[0]) != REGNO (operands[1])
4486 || (EXT_REX_SSE_REG_P (operands[1])
4487 && !TARGET_AVX512VL))
4489 rtx tmp = lowpart_subreg (SFmode, operands[0], DFmode);
4490 emit_move_insn (tmp, operands[1]);
4493 operands[3] = lowpart_subreg (V4SFmode, operands[1], SFmode);
4494 /* FIXME: vec_interleave_lowv4sf for AVX512VL should allow
4495 =v, v, then vbroadcastss will be only needed for AVX512F without
4497 if (!EXT_REX_SSE_REGNO_P (REGNO (operands[3])))
4498 emit_insn (gen_vec_interleave_lowv4sf (operands[3], operands[3],
4502 rtx tmp = lowpart_subreg (V16SFmode, operands[3], V4SFmode);
4503 emit_insn (gen_avx512f_vec_dupv16sf_1 (tmp, tmp));
4507 emit_insn (gen_vec_setv4sf_0 (operands[3],
4508 CONST0_RTX (V4SFmode), operands[1]));
4511 ;; It's more profitable to split and then extend in the same register.
4513 [(set (match_operand:DF 0 "sse_reg_operand")
4515 (match_operand:SF 1 "memory_operand")))]
4516 "TARGET_SPLIT_MEM_OPND_FOR_FP_CONVERTS
4517 && optimize_insn_for_speed_p ()"
4518 [(set (match_dup 2) (match_dup 1))
4519 (set (match_dup 0) (float_extend:DF (match_dup 2)))]
4520 "operands[2] = lowpart_subreg (SFmode, operands[0], DFmode);")
4522 (define_insn "*extendsfdf2"
4523 [(set (match_operand:DF 0 "nonimm_ssenomem_operand" "=f,m,v")
4525 (match_operand:SF 1 "nonimmediate_operand" "fm,f,vm")))]
4526 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4528 switch (which_alternative)
4532 return output_387_reg_move (insn, operands);
4535 return "%vcvtss2sd\t{%1, %d0|%d0, %1}";
4541 [(set_attr "type" "fmov,fmov,ssecvt")
4542 (set_attr "prefix" "orig,orig,maybe_vex")
4543 (set_attr "mode" "SF,XF,DF")
4544 (set (attr "enabled")
4546 (match_test ("TARGET_SSE2 && TARGET_SSE_MATH"))
4548 (eq_attr "alternative" "0,1")
4549 (symbol_ref "TARGET_MIX_SSE_I387")
4550 (symbol_ref "true"))
4552 (eq_attr "alternative" "0,1")
4554 (symbol_ref "false"))))])
4556 (define_expand "extend<mode>xf2"
4557 [(set (match_operand:XF 0 "nonimmediate_operand")
4558 (float_extend:XF (match_operand:MODEF 1 "general_operand")))]
4561 /* ??? Needed for compress_float_constant since all fp constants
4562 are TARGET_LEGITIMATE_CONSTANT_P. */
4563 if (CONST_DOUBLE_P (operands[1]))
4565 if (standard_80387_constant_p (operands[1]) > 0)
4567 operands[1] = simplify_const_unary_operation
4568 (FLOAT_EXTEND, XFmode, operands[1], <MODE>mode);
4569 emit_move_insn_1 (operands[0], operands[1]);
4572 operands[1] = validize_mem (force_const_mem (<MODE>mode, operands[1]));
4576 (define_insn "*extend<mode>xf2_i387"
4577 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
4579 (match_operand:MODEF 1 "nonimmediate_operand" "fm,f")))]
4581 "* return output_387_reg_move (insn, operands);"
4582 [(set_attr "type" "fmov")
4583 (set_attr "mode" "<MODE>,XF")])
4585 ;; %%% This seems like bad news.
4586 ;; This cannot output into an f-reg because there is no way to be sure
4587 ;; of truncating in that case. Otherwise this is just like a simple move
4588 ;; insn. So we pretend we can output to a reg in order to get better
4589 ;; register preferencing, but we really use a stack slot.
4591 ;; Conversion from DFmode to SFmode.
4593 (define_expand "truncdfsf2"
4594 [(set (match_operand:SF 0 "nonimmediate_operand")
4596 (match_operand:DF 1 "nonimmediate_operand")))]
4597 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4599 if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
4601 else if (flag_unsafe_math_optimizations)
4605 rtx temp = assign_386_stack_local (SFmode, SLOT_TEMP);
4606 emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
4611 /* For converting DF(xmm2) to SF(xmm1), use the following code instead of
4613 unpcklpd xmm2,xmm2 ; packed conversion might crash on signaling NaNs
4615 We do the conversion post reload to avoid producing of 128bit spills
4616 that might lead to ICE on 32bit target. The sequence unlikely combine
4619 [(set (match_operand:SF 0 "sse_reg_operand")
4621 (match_operand:DF 1 "nonimmediate_operand")))]
4622 "TARGET_USE_VECTOR_FP_CONVERTS
4623 && optimize_insn_for_speed_p ()
4625 && (!EXT_REX_SSE_REG_P (operands[0])
4626 || TARGET_AVX512VL)"
4629 (float_truncate:V2SF
4633 operands[2] = lowpart_subreg (V4SFmode, operands[0], SFmode);
4634 operands[3] = CONST0_RTX (V2SFmode);
4635 operands[4] = lowpart_subreg (V2DFmode, operands[0], SFmode);
4636 /* Use movsd for loading from memory, unpcklpd for registers.
4637 Try to avoid move when unpacking can be done in source, or SSE3
4638 movddup is available. */
4639 if (REG_P (operands[1]))
4642 && REGNO (operands[0]) != REGNO (operands[1]))
4644 rtx tmp = lowpart_subreg (DFmode, operands[0], SFmode);
4645 emit_move_insn (tmp, operands[1]);
4648 else if (!TARGET_SSE3)
4649 operands[4] = lowpart_subreg (V2DFmode, operands[1], DFmode);
4650 emit_insn (gen_vec_dupv2df (operands[4], operands[1]));
4653 emit_insn (gen_vec_concatv2df (operands[4], operands[1],
4654 CONST0_RTX (DFmode)));
4657 ;; It's more profitable to split and then extend in the same register.
4659 [(set (match_operand:SF 0 "sse_reg_operand")
4661 (match_operand:DF 1 "memory_operand")))]
4662 "TARGET_SPLIT_MEM_OPND_FOR_FP_CONVERTS
4663 && optimize_insn_for_speed_p ()"
4664 [(set (match_dup 2) (match_dup 1))
4665 (set (match_dup 0) (float_truncate:SF (match_dup 2)))]
4666 "operands[2] = lowpart_subreg (DFmode, operands[0], SFmode);")
4668 (define_expand "truncdfsf2_with_temp"
4669 [(parallel [(set (match_operand:SF 0)
4670 (float_truncate:SF (match_operand:DF 1)))
4671 (clobber (match_operand:SF 2))])])
4673 ;; SSE alternative doesn't depend on flag_unsafe_math_optimizations,
4674 ;; because nothing we do there is unsafe.
4675 (define_insn "*truncdfsf_fast_mixed"
4676 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm,v")
4678 (match_operand:DF 1 "nonimmediate_operand" "f ,vm")))]
4679 "TARGET_SSE2 && TARGET_SSE_MATH"
4681 switch (which_alternative)
4684 return output_387_reg_move (insn, operands);
4686 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4691 [(set_attr "type" "fmov,ssecvt")
4692 (set_attr "prefix" "orig,maybe_vex")
4693 (set_attr "mode" "SF")
4694 (set (attr "enabled")
4695 (cond [(eq_attr "alternative" "0")
4696 (symbol_ref "TARGET_MIX_SSE_I387
4697 && flag_unsafe_math_optimizations")
4699 (symbol_ref "true")))])
4701 (define_insn "*truncdfsf_fast_i387"
4702 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm")
4704 (match_operand:DF 1 "nonimmediate_operand" "f")))]
4705 "TARGET_80387 && flag_unsafe_math_optimizations"
4706 "* return output_387_reg_move (insn, operands);"
4707 [(set_attr "type" "fmov")
4708 (set_attr "mode" "SF")])
4710 (define_insn "*truncdfsf_mixed"
4711 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,v ,?f,?v,?*r")
4713 (match_operand:DF 1 "nonimmediate_operand" "f ,vm,f ,f ,f")))
4714 (clobber (match_operand:SF 2 "memory_operand" "=X,X ,m ,m ,m"))]
4715 "TARGET_MIX_SSE_I387"
4717 switch (which_alternative)
4720 return output_387_reg_move (insn, operands);
4722 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4728 [(set_attr "isa" "*,sse2,*,*,*")
4729 (set_attr "type" "fmov,ssecvt,multi,multi,multi")
4730 (set_attr "unit" "*,*,i387,i387,i387")
4731 (set_attr "prefix" "orig,maybe_vex,orig,orig,orig")
4732 (set_attr "mode" "SF")])
4734 (define_insn "*truncdfsf_i387"
4735 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?v,?*r")
4737 (match_operand:DF 1 "nonimmediate_operand" "f ,f ,f ,f")))
4738 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,m ,m"))]
4741 switch (which_alternative)
4744 return output_387_reg_move (insn, operands);
4750 [(set_attr "type" "fmov,multi,multi,multi")
4751 (set_attr "unit" "*,i387,i387,i387")
4752 (set_attr "mode" "SF")])
4754 (define_insn "*truncdfsf2_i387_1"
4755 [(set (match_operand:SF 0 "memory_operand" "=m")
4757 (match_operand:DF 1 "register_operand" "f")))]
4759 && !(TARGET_SSE2 && TARGET_SSE_MATH)
4760 && !TARGET_MIX_SSE_I387"
4761 "* return output_387_reg_move (insn, operands);"
4762 [(set_attr "type" "fmov")
4763 (set_attr "mode" "SF")])
4766 [(set (match_operand:SF 0 "register_operand")
4768 (match_operand:DF 1 "fp_register_operand")))
4769 (clobber (match_operand 2))]
4771 [(set (match_dup 2) (match_dup 1))
4772 (set (match_dup 0) (match_dup 2))]
4773 "operands[1] = gen_rtx_REG (SFmode, REGNO (operands[1]));")
4775 ;; Conversion from XFmode to {SF,DF}mode
4777 (define_expand "truncxf<mode>2"
4778 [(parallel [(set (match_operand:MODEF 0 "nonimmediate_operand")
4779 (float_truncate:MODEF
4780 (match_operand:XF 1 "register_operand")))
4781 (clobber (match_dup 2))])]
4784 if (flag_unsafe_math_optimizations)
4786 rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (<MODE>mode);
4787 emit_insn (gen_truncxf<mode>2_i387_noop (reg, operands[1]));
4788 if (reg != operands[0])
4789 emit_move_insn (operands[0], reg);
4793 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4796 (define_insn "*truncxfsf2_mixed"
4797 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?v,?*r")
4799 (match_operand:XF 1 "register_operand" "f ,f ,f ,f")))
4800 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,m ,m"))]
4803 gcc_assert (!which_alternative);
4804 return output_387_reg_move (insn, operands);
4806 [(set_attr "type" "fmov,multi,multi,multi")
4807 (set_attr "unit" "*,i387,i387,i387")
4808 (set_attr "mode" "SF")])
4810 (define_insn "*truncxfdf2_mixed"
4811 [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?v,?*r")
4813 (match_operand:XF 1 "register_operand" "f ,f ,f ,f")))
4814 (clobber (match_operand:DF 2 "memory_operand" "=X,m ,m ,m"))]
4817 gcc_assert (!which_alternative);
4818 return output_387_reg_move (insn, operands);
4820 [(set_attr "isa" "*,*,sse2,*")
4821 (set_attr "type" "fmov,multi,multi,multi")
4822 (set_attr "unit" "*,i387,i387,i387")
4823 (set_attr "mode" "DF")])
4825 (define_insn "truncxf<mode>2_i387_noop"
4826 [(set (match_operand:MODEF 0 "register_operand" "=f")
4827 (float_truncate:MODEF
4828 (match_operand:XF 1 "register_operand" "f")))]
4829 "TARGET_80387 && flag_unsafe_math_optimizations"
4830 "* return output_387_reg_move (insn, operands);"
4831 [(set_attr "type" "fmov")
4832 (set_attr "mode" "<MODE>")])
4834 (define_insn "*truncxf<mode>2_i387"
4835 [(set (match_operand:MODEF 0 "memory_operand" "=m")
4836 (float_truncate:MODEF
4837 (match_operand:XF 1 "register_operand" "f")))]
4839 "* return output_387_reg_move (insn, operands);"
4840 [(set_attr "type" "fmov")
4841 (set_attr "mode" "<MODE>")])
4844 [(set (match_operand:MODEF 0 "register_operand")
4845 (float_truncate:MODEF
4846 (match_operand:XF 1 "register_operand")))
4847 (clobber (match_operand:MODEF 2 "memory_operand"))]
4848 "TARGET_80387 && reload_completed"
4849 [(set (match_dup 2) (float_truncate:MODEF (match_dup 1)))
4850 (set (match_dup 0) (match_dup 2))])
4853 [(set (match_operand:MODEF 0 "memory_operand")
4854 (float_truncate:MODEF
4855 (match_operand:XF 1 "register_operand")))
4856 (clobber (match_operand:MODEF 2 "memory_operand"))]
4858 [(set (match_dup 0) (float_truncate:MODEF (match_dup 1)))])
4860 ;; Signed conversion to DImode.
4862 (define_expand "fix_truncxfdi2"
4863 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand")
4864 (fix:DI (match_operand:XF 1 "register_operand")))
4865 (clobber (reg:CC FLAGS_REG))])]
4870 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4875 (define_expand "fix_trunc<mode>di2"
4876 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand")
4877 (fix:DI (match_operand:MODEF 1 "register_operand")))
4878 (clobber (reg:CC FLAGS_REG))])]
4879 "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4882 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4884 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4887 if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4889 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4890 emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4891 if (out != operands[0])
4892 emit_move_insn (operands[0], out);
4897 ;; Signed conversion to SImode.
4899 (define_expand "fix_truncxfsi2"
4900 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand")
4901 (fix:SI (match_operand:XF 1 "register_operand")))
4902 (clobber (reg:CC FLAGS_REG))])]
4907 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4912 (define_expand "fix_trunc<mode>si2"
4913 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand")
4914 (fix:SI (match_operand:MODEF 1 "register_operand")))
4915 (clobber (reg:CC FLAGS_REG))])]
4916 "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4919 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4921 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4924 if (SSE_FLOAT_MODE_P (<MODE>mode))
4926 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4927 emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4928 if (out != operands[0])
4929 emit_move_insn (operands[0], out);
4934 ;; Signed conversion to HImode.
4936 (define_expand "fix_trunc<mode>hi2"
4937 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand")
4938 (fix:HI (match_operand:X87MODEF 1 "register_operand")))
4939 (clobber (reg:CC FLAGS_REG))])]
4941 && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4945 emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4950 ;; Unsigned conversion to SImode.
4952 (define_expand "fixuns_trunc<mode>si2"
4954 [(set (match_operand:SI 0 "register_operand")
4956 (match_operand:MODEF 1 "nonimmediate_operand")))
4958 (clobber (match_scratch:<ssevecmode> 3))
4959 (clobber (match_scratch:<ssevecmode> 4))])]
4960 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4962 machine_mode mode = <MODE>mode;
4963 machine_mode vecmode = <ssevecmode>mode;
4964 REAL_VALUE_TYPE TWO31r;
4967 if (optimize_insn_for_size_p ())
4970 real_ldexp (&TWO31r, &dconst1, 31);
4971 two31 = const_double_from_real_value (TWO31r, mode);
4972 two31 = ix86_build_const_vector (vecmode, true, two31);
4973 operands[2] = force_reg (vecmode, two31);
4976 (define_insn_and_split "*fixuns_trunc<mode>_1"
4977 [(set (match_operand:SI 0 "register_operand" "=&x,&x")
4979 (match_operand:MODEF 3 "nonimmediate_operand" "xm,xm")))
4980 (use (match_operand:<ssevecmode> 4 "nonimmediate_operand" "m,x"))
4981 (clobber (match_scratch:<ssevecmode> 1 "=x,&x"))
4982 (clobber (match_scratch:<ssevecmode> 2 "=x,x"))]
4983 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH
4984 && optimize_function_for_speed_p (cfun)"
4986 "&& reload_completed"
4989 ix86_split_convert_uns_si_sse (operands);
4993 ;; Unsigned conversion to HImode.
4994 ;; Without these patterns, we'll try the unsigned SI conversion which
4995 ;; is complex for SSE, rather than the signed SI conversion, which isn't.
4997 (define_expand "fixuns_trunc<mode>hi2"
4999 (fix:SI (match_operand:MODEF 1 "nonimmediate_operand")))
5000 (set (match_operand:HI 0 "nonimmediate_operand")
5001 (subreg:HI (match_dup 2) 0))]
5002 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
5003 "operands[2] = gen_reg_rtx (SImode);")
5005 ;; When SSE is available, it is always faster to use it!
5006 (define_insn "fix_trunc<MODEF:mode><SWI48:mode>_sse"
5007 [(set (match_operand:SWI48 0 "register_operand" "=r,r")
5008 (fix:SWI48 (match_operand:MODEF 1 "nonimmediate_operand" "v,m")))]
5009 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode)
5010 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
5011 "%vcvtt<MODEF:ssemodesuffix>2si<SWI48:rex64suffix>\t{%1, %0|%0, %1}"
5012 [(set_attr "type" "sseicvt")
5013 (set_attr "prefix" "maybe_vex")
5014 (set (attr "prefix_rex")
5016 (match_test "<SWI48:MODE>mode == DImode")
5018 (const_string "*")))
5019 (set_attr "mode" "<MODEF:MODE>")
5020 (set_attr "athlon_decode" "double,vector")
5021 (set_attr "amdfam10_decode" "double,double")
5022 (set_attr "bdver1_decode" "double,double")])
5024 ;; Avoid vector decoded forms of the instruction.
5026 [(match_scratch:MODEF 2 "x")
5027 (set (match_operand:SWI48 0 "register_operand")
5028 (fix:SWI48 (match_operand:MODEF 1 "memory_operand")))]
5029 "TARGET_AVOID_VECTOR_DECODE
5030 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode)
5031 && optimize_insn_for_speed_p ()"
5032 [(set (match_dup 2) (match_dup 1))
5033 (set (match_dup 0) (fix:SWI48 (match_dup 2)))])
5035 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
5036 [(set (match_operand:SWI248x 0 "nonimmediate_operand")
5037 (fix:SWI248x (match_operand 1 "register_operand")))]
5038 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5040 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
5041 && (TARGET_64BIT || <MODE>mode != DImode))
5043 && can_create_pseudo_p ()"
5048 if (memory_operand (operands[0], VOIDmode))
5049 emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
5052 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
5053 emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
5059 [(set_attr "type" "fisttp")
5060 (set_attr "mode" "<MODE>")])
5062 (define_insn "fix_trunc<mode>_i387_fisttp"
5063 [(set (match_operand:SWI248x 0 "memory_operand" "=m")
5064 (fix:SWI248x (match_operand 1 "register_operand" "f")))
5065 (clobber (match_scratch:XF 2 "=&1f"))]
5066 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5068 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
5069 && (TARGET_64BIT || <MODE>mode != DImode))
5070 && TARGET_SSE_MATH)"
5071 "* return output_fix_trunc (insn, operands, true);"
5072 [(set_attr "type" "fisttp")
5073 (set_attr "mode" "<MODE>")])
5075 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
5076 [(set (match_operand:SWI248x 0 "nonimmediate_operand" "=m,?r")
5077 (fix:SWI248x (match_operand 1 "register_operand" "f,f")))
5078 (clobber (match_operand:SWI248x 2 "memory_operand" "=X,m"))
5079 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
5080 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5082 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
5083 && (TARGET_64BIT || <MODE>mode != DImode))
5084 && TARGET_SSE_MATH)"
5086 [(set_attr "type" "fisttp")
5087 (set_attr "mode" "<MODE>")])
5090 [(set (match_operand:SWI248x 0 "register_operand")
5091 (fix:SWI248x (match_operand 1 "register_operand")))
5092 (clobber (match_operand:SWI248x 2 "memory_operand"))
5093 (clobber (match_scratch 3))]
5095 [(parallel [(set (match_dup 2) (fix:SWI248x (match_dup 1)))
5096 (clobber (match_dup 3))])
5097 (set (match_dup 0) (match_dup 2))])
5100 [(set (match_operand:SWI248x 0 "memory_operand")
5101 (fix:SWI248x (match_operand 1 "register_operand")))
5102 (clobber (match_operand:SWI248x 2 "memory_operand"))
5103 (clobber (match_scratch 3))]
5105 [(parallel [(set (match_dup 0) (fix:SWI248x (match_dup 1)))
5106 (clobber (match_dup 3))])])
5108 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
5109 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
5110 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
5111 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
5112 ;; function in i386.c.
5113 (define_insn_and_split "*fix_trunc<mode>_i387_1"
5114 [(set (match_operand:SWI248x 0 "nonimmediate_operand")
5115 (fix:SWI248x (match_operand 1 "register_operand")))
5116 (clobber (reg:CC FLAGS_REG))]
5117 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5119 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
5120 && (TARGET_64BIT || <MODE>mode != DImode))
5121 && can_create_pseudo_p ()"
5126 ix86_optimize_mode_switching[I387_TRUNC] = 1;
5128 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
5129 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
5130 if (memory_operand (operands[0], VOIDmode))
5131 emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
5132 operands[2], operands[3]));
5135 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
5136 emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
5137 operands[2], operands[3],
5142 [(set_attr "type" "fistp")
5143 (set_attr "i387_cw" "trunc")
5144 (set_attr "mode" "<MODE>")])
5146 (define_insn "fix_truncdi_i387"
5147 [(set (match_operand:DI 0 "memory_operand" "=m")
5148 (fix:DI (match_operand 1 "register_operand" "f")))
5149 (use (match_operand:HI 2 "memory_operand" "m"))
5150 (use (match_operand:HI 3 "memory_operand" "m"))
5151 (clobber (match_scratch:XF 4 "=&1f"))]
5152 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5154 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
5155 "* return output_fix_trunc (insn, operands, false);"
5156 [(set_attr "type" "fistp")
5157 (set_attr "i387_cw" "trunc")
5158 (set_attr "mode" "DI")])
5160 (define_insn "fix_truncdi_i387_with_temp"
5161 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
5162 (fix:DI (match_operand 1 "register_operand" "f,f")))
5163 (use (match_operand:HI 2 "memory_operand" "m,m"))
5164 (use (match_operand:HI 3 "memory_operand" "m,m"))
5165 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
5166 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
5167 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5169 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
5171 [(set_attr "type" "fistp")
5172 (set_attr "i387_cw" "trunc")
5173 (set_attr "mode" "DI")])
5176 [(set (match_operand:DI 0 "register_operand")
5177 (fix:DI (match_operand 1 "register_operand")))
5178 (use (match_operand:HI 2 "memory_operand"))
5179 (use (match_operand:HI 3 "memory_operand"))
5180 (clobber (match_operand:DI 4 "memory_operand"))
5181 (clobber (match_scratch 5))]
5183 [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
5186 (clobber (match_dup 5))])
5187 (set (match_dup 0) (match_dup 4))])
5190 [(set (match_operand:DI 0 "memory_operand")
5191 (fix:DI (match_operand 1 "register_operand")))
5192 (use (match_operand:HI 2 "memory_operand"))
5193 (use (match_operand:HI 3 "memory_operand"))
5194 (clobber (match_operand:DI 4 "memory_operand"))
5195 (clobber (match_scratch 5))]
5197 [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
5200 (clobber (match_dup 5))])])
5202 (define_insn "fix_trunc<mode>_i387"
5203 [(set (match_operand:SWI24 0 "memory_operand" "=m")
5204 (fix:SWI24 (match_operand 1 "register_operand" "f")))
5205 (use (match_operand:HI 2 "memory_operand" "m"))
5206 (use (match_operand:HI 3 "memory_operand" "m"))]
5207 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5209 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
5210 "* return output_fix_trunc (insn, operands, false);"
5211 [(set_attr "type" "fistp")
5212 (set_attr "i387_cw" "trunc")
5213 (set_attr "mode" "<MODE>")])
5215 (define_insn "fix_trunc<mode>_i387_with_temp"
5216 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
5217 (fix:SWI24 (match_operand 1 "register_operand" "f,f")))
5218 (use (match_operand:HI 2 "memory_operand" "m,m"))
5219 (use (match_operand:HI 3 "memory_operand" "m,m"))
5220 (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
5221 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5223 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
5225 [(set_attr "type" "fistp")
5226 (set_attr "i387_cw" "trunc")
5227 (set_attr "mode" "<MODE>")])
5230 [(set (match_operand:SWI24 0 "register_operand")
5231 (fix:SWI24 (match_operand 1 "register_operand")))
5232 (use (match_operand:HI 2 "memory_operand"))
5233 (use (match_operand:HI 3 "memory_operand"))
5234 (clobber (match_operand:SWI24 4 "memory_operand"))]
5236 [(parallel [(set (match_dup 4) (fix:SWI24 (match_dup 1)))
5238 (use (match_dup 3))])
5239 (set (match_dup 0) (match_dup 4))])
5242 [(set (match_operand:SWI24 0 "memory_operand")
5243 (fix:SWI24 (match_operand 1 "register_operand")))
5244 (use (match_operand:HI 2 "memory_operand"))
5245 (use (match_operand:HI 3 "memory_operand"))
5246 (clobber (match_operand:SWI24 4 "memory_operand"))]
5248 [(parallel [(set (match_dup 0) (fix:SWI24 (match_dup 1)))
5250 (use (match_dup 3))])])
5252 (define_insn "x86_fnstcw_1"
5253 [(set (match_operand:HI 0 "memory_operand" "=m")
5254 (unspec:HI [(reg:HI FPCR_REG)] UNSPEC_FSTCW))]
5257 [(set (attr "length")
5258 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
5259 (set_attr "mode" "HI")
5260 (set_attr "unit" "i387")
5261 (set_attr "bdver1_decode" "vector")])
5263 (define_insn "x86_fldcw_1"
5264 [(set (reg:HI FPCR_REG)
5265 (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
5268 [(set (attr "length")
5269 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
5270 (set_attr "mode" "HI")
5271 (set_attr "unit" "i387")
5272 (set_attr "athlon_decode" "vector")
5273 (set_attr "amdfam10_decode" "vector")
5274 (set_attr "bdver1_decode" "vector")])
5276 ;; Conversion between fixed point and floating point.
5278 ;; Even though we only accept memory inputs, the backend _really_
5279 ;; wants to be able to do this between registers. Thankfully, LRA
5280 ;; will fix this up for us during register allocation.
5282 (define_insn "floathi<mode>2"
5283 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5284 (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "m")))]
5286 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5287 || TARGET_MIX_SSE_I387)"
5289 [(set_attr "type" "fmov")
5290 (set_attr "mode" "<MODE>")
5291 (set_attr "znver1_decode" "double")
5292 (set_attr "fp_int_src" "true")])
5294 (define_insn "float<SWI48x:mode>xf2"
5295 [(set (match_operand:XF 0 "register_operand" "=f")
5296 (float:XF (match_operand:SWI48x 1 "nonimmediate_operand" "m")))]
5299 [(set_attr "type" "fmov")
5300 (set_attr "mode" "XF")
5301 (set_attr "znver1_decode" "double")
5302 (set_attr "fp_int_src" "true")])
5304 (define_expand "float<SWI48:mode><MODEF:mode>2"
5305 [(set (match_operand:MODEF 0 "register_operand")
5306 (float:MODEF (match_operand:SWI48 1 "nonimmediate_operand")))]
5307 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)"
5309 if (!(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
5310 && !X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI48:MODE>mode))
5312 rtx reg = gen_reg_rtx (XFmode);
5313 rtx (*insn)(rtx, rtx);
5315 emit_insn (gen_float<SWI48:mode>xf2 (reg, operands[1]));
5317 if (<MODEF:MODE>mode == SFmode)
5318 insn = gen_truncxfsf2;
5319 else if (<MODEF:MODE>mode == DFmode)
5320 insn = gen_truncxfdf2;
5324 emit_insn (insn (operands[0], reg));
5329 (define_insn "*float<SWI48:mode><MODEF:mode>2_mixed"
5330 [(set (match_operand:MODEF 0 "register_operand" "=f,v,v")
5332 (match_operand:SWI48 1 "nonimmediate_operand" "m,r,m")))]
5333 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
5336 %vcvtsi2<MODEF:ssemodesuffix><SWI48:rex64suffix>\t{%1, %d0|%d0, %1}
5337 %vcvtsi2<MODEF:ssemodesuffix><SWI48:rex64suffix>\t{%1, %d0|%d0, %1}"
5338 [(set_attr "type" "fmov,sseicvt,sseicvt")
5339 (set_attr "prefix" "orig,maybe_vex,maybe_vex")
5340 (set_attr "mode" "<MODEF:MODE>")
5341 (set (attr "prefix_rex")
5343 (and (eq_attr "prefix" "maybe_vex")
5344 (match_test "<SWI48:MODE>mode == DImode"))
5346 (const_string "*")))
5347 (set_attr "unit" "i387,*,*")
5348 (set_attr "athlon_decode" "*,double,direct")
5349 (set_attr "amdfam10_decode" "*,vector,double")
5350 (set_attr "bdver1_decode" "*,double,direct")
5351 (set_attr "znver1_decode" "double,*,*")
5352 (set_attr "fp_int_src" "true")
5353 (set (attr "enabled")
5354 (cond [(eq_attr "alternative" "0")
5355 (symbol_ref "TARGET_MIX_SSE_I387
5356 && X87_ENABLE_FLOAT (<MODEF:MODE>mode,
5359 (symbol_ref "true")))
5360 (set (attr "preferred_for_speed")
5361 (cond [(eq_attr "alternative" "1")
5362 (symbol_ref "TARGET_INTER_UNIT_CONVERSIONS")]
5363 (symbol_ref "true")))])
5365 (define_insn "*float<SWI48x:mode><MODEF:mode>2_i387"
5366 [(set (match_operand:MODEF 0 "register_operand" "=f")
5367 (float:MODEF (match_operand:SWI48x 1 "nonimmediate_operand" "m")))]
5368 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI48x:MODE>mode)"
5370 [(set_attr "type" "fmov")
5371 (set_attr "mode" "<MODEF:MODE>")
5372 (set_attr "znver1_decode" "double")
5373 (set_attr "fp_int_src" "true")])
5375 ;; Try TARGET_USE_VECTOR_CONVERTS, but not so hard as to require extra memory
5376 ;; slots when !TARGET_INTER_UNIT_MOVES_TO_VEC disables the general_regs
5377 ;; alternative in sse2_loadld.
5379 [(set (match_operand:MODEF 0 "sse_reg_operand")
5380 (float:MODEF (match_operand:SI 1 "nonimmediate_operand")))]
5382 && TARGET_USE_VECTOR_CONVERTS
5383 && optimize_function_for_speed_p (cfun)
5385 && (MEM_P (operands[1]) || TARGET_INTER_UNIT_MOVES_TO_VEC)
5386 && (!EXT_REX_SSE_REG_P (operands[0])
5387 || TARGET_AVX512VL)"
5390 operands[3] = lowpart_subreg (<ssevecmode>mode, operands[0], <MODE>mode);
5391 operands[4] = lowpart_subreg (V4SImode, operands[0], <MODE>mode);
5393 emit_insn (gen_sse2_loadld (operands[4],
5394 CONST0_RTX (V4SImode), operands[1]));
5396 if (<ssevecmode>mode == V4SFmode)
5397 emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
5399 emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
5403 ;; Avoid partial SSE register dependency stalls. This splitter should split
5404 ;; late in the pass sequence (after register rename pass), so allocated
5405 ;; registers won't change anymore
5408 [(set (match_operand:MODEF 0 "sse_reg_operand")
5409 (float:MODEF (match_operand:SWI48 1 "nonimmediate_operand")))]
5410 "TARGET_SSE_PARTIAL_REG_DEPENDENCY && epilogue_completed
5411 && optimize_function_for_speed_p (cfun)
5412 && (!EXT_REX_SSE_REG_P (operands[0])
5413 || TARGET_AVX512VL)"
5415 (vec_merge:<MODEF:ssevecmode>
5416 (vec_duplicate:<MODEF:ssevecmode>
5422 const machine_mode vmode = <MODEF:ssevecmode>mode;
5424 operands[0] = lowpart_subreg (vmode, operands[0], <MODEF:MODE>mode);
5425 emit_move_insn (operands[0], CONST0_RTX (vmode));
5428 ;; Break partial reg stall for cvtsd2ss. This splitter should split
5429 ;; late in the pass sequence (after register rename pass),
5430 ;; so allocated registers won't change anymore.
5433 [(set (match_operand:SF 0 "sse_reg_operand")
5435 (match_operand:DF 1 "nonimmediate_operand")))]
5436 "TARGET_SSE_PARTIAL_REG_DEPENDENCY && epilogue_completed
5437 && optimize_function_for_speed_p (cfun)
5438 && (!REG_P (operands[1])
5439 || REGNO (operands[0]) != REGNO (operands[1]))
5440 && (!EXT_REX_SSE_REG_P (operands[0])
5441 || TARGET_AVX512VL)"
5450 operands[0] = lowpart_subreg (V4SFmode, operands[0], SFmode);
5451 emit_move_insn (operands[0], CONST0_RTX (V4SFmode));
5454 ;; Break partial reg stall for cvtss2sd. This splitter should split
5455 ;; late in the pass sequence (after register rename pass),
5456 ;; so allocated registers won't change anymore.
5459 [(set (match_operand:DF 0 "sse_reg_operand")
5461 (match_operand:SF 1 "nonimmediate_operand")))]
5462 "TARGET_SSE_PARTIAL_REG_DEPENDENCY && epilogue_completed
5463 && optimize_function_for_speed_p (cfun)
5464 && (!REG_P (operands[1])
5465 || REGNO (operands[0]) != REGNO (operands[1]))
5466 && (!EXT_REX_SSE_REG_P (operands[0])
5467 || TARGET_AVX512VL)"
5476 operands[0] = lowpart_subreg (V2DFmode, operands[0], DFmode);
5477 emit_move_insn (operands[0], CONST0_RTX (V2DFmode));
5480 ;; Avoid store forwarding (partial memory) stall penalty
5481 ;; by passing DImode value through XMM registers. */
5483 (define_insn "floatdi<X87MODEF:mode>2_i387_with_xmm"
5484 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5486 (match_operand:DI 1 "nonimmediate_operand" "m,?r")))
5487 (clobber (match_scratch:V4SI 3 "=X,x"))
5488 (clobber (match_scratch:V4SI 4 "=X,x"))
5489 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))]
5490 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5491 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC
5492 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)"
5494 [(set_attr "type" "multi")
5495 (set_attr "mode" "<X87MODEF:MODE>")
5496 (set_attr "unit" "i387")
5497 (set_attr "fp_int_src" "true")])
5500 [(set (match_operand:X87MODEF 0 "fp_register_operand")
5501 (float:X87MODEF (match_operand:DI 1 "register_operand")))
5502 (clobber (match_scratch:V4SI 3))
5503 (clobber (match_scratch:V4SI 4))
5504 (clobber (match_operand:DI 2 "memory_operand"))]
5505 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5506 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC
5507 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5508 && reload_completed"
5509 [(set (match_dup 2) (match_dup 3))
5510 (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5512 /* The DImode arrived in a pair of integral registers (e.g. %edx:%eax).
5513 Assemble the 64-bit DImode value in an xmm register. */
5514 emit_insn (gen_sse2_loadld (operands[3], CONST0_RTX (V4SImode),
5515 gen_lowpart (SImode, operands[1])));
5516 emit_insn (gen_sse2_loadld (operands[4], CONST0_RTX (V4SImode),
5517 gen_highpart (SImode, operands[1])));
5518 emit_insn (gen_vec_interleave_lowv4si (operands[3], operands[3],
5521 operands[3] = gen_lowpart (DImode, operands[3]);
5525 [(set (match_operand:X87MODEF 0 "fp_register_operand")
5526 (float:X87MODEF (match_operand:DI 1 "memory_operand")))
5527 (clobber (match_scratch:V4SI 3))
5528 (clobber (match_scratch:V4SI 4))
5529 (clobber (match_operand:DI 2 "memory_operand"))]
5530 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5531 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC
5532 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5533 && reload_completed"
5534 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
5536 (define_expand "floatuns<SWI12:mode><MODEF:mode>2"
5537 [(set (match_operand:MODEF 0 "register_operand")
5538 (unsigned_float:MODEF
5539 (match_operand:SWI12 1 "nonimmediate_operand")))]
5541 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
5543 operands[1] = convert_to_mode (SImode, operands[1], 1);
5544 emit_insn (gen_floatsi<MODEF:mode>2 (operands[0], operands[1]));
5548 ;; Avoid store forwarding (partial memory) stall penalty by extending
5549 ;; SImode value to DImode through XMM register instead of pushing two
5550 ;; SImode values to stack. Also note that fild loads from memory only.
5552 (define_insn_and_split "*floatunssi<mode>2_i387_with_xmm"
5553 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5554 (unsigned_float:X87MODEF
5555 (match_operand:SI 1 "nonimmediate_operand" "rm")))
5556 (clobber (match_scratch:DI 3 "=x"))
5557 (clobber (match_operand:DI 2 "memory_operand" "=m"))]
5559 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5560 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC"
5562 "&& reload_completed"
5563 [(set (match_dup 3) (zero_extend:DI (match_dup 1)))
5564 (set (match_dup 2) (match_dup 3))
5566 (float:X87MODEF (match_dup 2)))]
5568 [(set_attr "type" "multi")
5569 (set_attr "mode" "<MODE>")])
5571 (define_expand "floatunssi<mode>2"
5573 [(set (match_operand:X87MODEF 0 "register_operand")
5574 (unsigned_float:X87MODEF
5575 (match_operand:SI 1 "nonimmediate_operand")))
5576 (clobber (match_scratch:DI 3))
5577 (clobber (match_dup 2))])]
5579 && ((TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5580 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC)
5581 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
5583 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5585 ix86_expand_convert_uns_si<mode>_sse (operands[0], operands[1]);
5589 operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
5592 (define_expand "floatunsdisf2"
5593 [(use (match_operand:SF 0 "register_operand"))
5594 (use (match_operand:DI 1 "nonimmediate_operand"))]
5595 "TARGET_64BIT && TARGET_SSE && TARGET_SSE_MATH"
5596 "x86_emit_floatuns (operands); DONE;")
5598 (define_expand "floatunsdidf2"
5599 [(use (match_operand:DF 0 "register_operand"))
5600 (use (match_operand:DI 1 "nonimmediate_operand"))]
5601 "(TARGET_64BIT || TARGET_KEEPS_VECTOR_ALIGNED_STACK)
5602 && TARGET_SSE2 && TARGET_SSE_MATH"
5605 x86_emit_floatuns (operands);
5607 ix86_expand_convert_uns_didf_sse (operands[0], operands[1]);
5611 ;; Load effective address instructions
5613 (define_insn_and_split "*lea<mode>"
5614 [(set (match_operand:SWI48 0 "register_operand" "=r")
5615 (match_operand:SWI48 1 "address_no_seg_operand" "Ts"))]
5618 if (SImode_address_operand (operands[1], VOIDmode))
5620 gcc_assert (TARGET_64BIT);
5621 return "lea{l}\t{%E1, %k0|%k0, %E1}";
5624 return "lea{<imodesuffix>}\t{%E1, %0|%0, %E1}";
5626 "reload_completed && ix86_avoid_lea_for_addr (insn, operands)"
5629 machine_mode mode = <MODE>mode;
5632 /* ix86_avoid_lea_for_addr re-recognizes insn and may
5633 change operands[] array behind our back. */
5634 pat = PATTERN (curr_insn);
5636 operands[0] = SET_DEST (pat);
5637 operands[1] = SET_SRC (pat);
5639 /* Emit all operations in SImode for zero-extended addresses. */
5640 if (SImode_address_operand (operands[1], VOIDmode))
5643 ix86_split_lea_for_addr (curr_insn, operands, mode);
5645 /* Zero-extend return register to DImode for zero-extended addresses. */
5646 if (mode != <MODE>mode)
5647 emit_insn (gen_zero_extendsidi2
5648 (operands[0], gen_lowpart (mode, operands[0])));
5652 [(set_attr "type" "lea")
5655 (match_operand 1 "SImode_address_operand")
5657 (const_string "<MODE>")))])
5661 (define_expand "add<mode>3"
5662 [(set (match_operand:SDWIM 0 "nonimmediate_operand")
5663 (plus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")
5664 (match_operand:SDWIM 2 "<general_hilo_operand>")))]
5666 "ix86_expand_binary_operator (PLUS, <MODE>mode, operands); DONE;")
5668 (define_insn_and_split "*add<dwi>3_doubleword"
5669 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
5671 (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0")
5672 (match_operand:<DWI> 2 "x86_64_hilo_general_operand"
5674 (clobber (reg:CC FLAGS_REG))]
5675 "ix86_binary_operator_ok (PLUS, <DWI>mode, operands)"
5678 [(parallel [(set (reg:CCC FLAGS_REG)
5680 (plus:DWIH (match_dup 1) (match_dup 2))
5683 (plus:DWIH (match_dup 1) (match_dup 2)))])
5684 (parallel [(set (match_dup 3)
5687 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
5690 (clobber (reg:CC FLAGS_REG))])]
5692 split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
5693 if (operands[2] == const0_rtx)
5695 ix86_expand_binary_operator (PLUS, <MODE>mode, &operands[3]);
5700 (define_insn "*add<mode>_1"
5701 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,rm,r,r")
5703 (match_operand:SWI48 1 "nonimmediate_operand" "%0,0,r,r")
5704 (match_operand:SWI48 2 "x86_64_general_operand" "rme,re,0,le")))
5705 (clobber (reg:CC FLAGS_REG))]
5706 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5708 switch (get_attr_type (insn))
5714 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5715 if (operands[2] == const1_rtx)
5716 return "inc{<imodesuffix>}\t%0";
5719 gcc_assert (operands[2] == constm1_rtx);
5720 return "dec{<imodesuffix>}\t%0";
5724 /* For most processors, ADD is faster than LEA. This alternative
5725 was added to use ADD as much as possible. */
5726 if (which_alternative == 2)
5727 std::swap (operands[1], operands[2]);
5729 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5730 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5731 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5733 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5737 (cond [(eq_attr "alternative" "3")
5738 (const_string "lea")
5739 (match_operand:SWI48 2 "incdec_operand")
5740 (const_string "incdec")
5742 (const_string "alu")))
5743 (set (attr "length_immediate")
5745 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5747 (const_string "*")))
5748 (set_attr "mode" "<MODE>")])
5750 ;; It may seem that nonimmediate operand is proper one for operand 1.
5751 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5752 ;; we take care in ix86_binary_operator_ok to not allow two memory
5753 ;; operands so proper swapping will be done in reload. This allow
5754 ;; patterns constructed from addsi_1 to match.
5756 (define_insn "addsi_1_zext"
5757 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
5759 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r,r")
5760 (match_operand:SI 2 "x86_64_general_operand" "rme,0,le"))))
5761 (clobber (reg:CC FLAGS_REG))]
5762 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5764 switch (get_attr_type (insn))
5770 if (operands[2] == const1_rtx)
5771 return "inc{l}\t%k0";
5774 gcc_assert (operands[2] == constm1_rtx);
5775 return "dec{l}\t%k0";
5779 /* For most processors, ADD is faster than LEA. This alternative
5780 was added to use ADD as much as possible. */
5781 if (which_alternative == 1)
5782 std::swap (operands[1], operands[2]);
5784 if (x86_maybe_negate_const_int (&operands[2], SImode))
5785 return "sub{l}\t{%2, %k0|%k0, %2}";
5787 return "add{l}\t{%2, %k0|%k0, %2}";
5791 (cond [(eq_attr "alternative" "2")
5792 (const_string "lea")
5793 (match_operand:SI 2 "incdec_operand")
5794 (const_string "incdec")
5796 (const_string "alu")))
5797 (set (attr "length_immediate")
5799 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5801 (const_string "*")))
5802 (set_attr "mode" "SI")])
5804 (define_insn "*addhi_1"
5805 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r,Yp")
5806 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r,Yp")
5807 (match_operand:HI 2 "general_operand" "rn,rm,0,ln")))
5808 (clobber (reg:CC FLAGS_REG))]
5809 "ix86_binary_operator_ok (PLUS, HImode, operands)"
5811 switch (get_attr_type (insn))
5817 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5818 if (operands[2] == const1_rtx)
5819 return "inc{w}\t%0";
5822 gcc_assert (operands[2] == constm1_rtx);
5823 return "dec{w}\t%0";
5827 /* For most processors, ADD is faster than LEA. This alternative
5828 was added to use ADD as much as possible. */
5829 if (which_alternative == 2)
5830 std::swap (operands[1], operands[2]);
5832 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5833 if (x86_maybe_negate_const_int (&operands[2], HImode))
5834 return "sub{w}\t{%2, %0|%0, %2}";
5836 return "add{w}\t{%2, %0|%0, %2}";
5840 (cond [(eq_attr "alternative" "3")
5841 (const_string "lea")
5842 (match_operand:HI 2 "incdec_operand")
5843 (const_string "incdec")
5845 (const_string "alu")))
5846 (set (attr "length_immediate")
5848 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5850 (const_string "*")))
5851 (set_attr "mode" "HI,HI,HI,SI")])
5853 (define_insn "*addqi_1"
5854 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,q,r,r,Yp")
5855 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,q,0,r,Yp")
5856 (match_operand:QI 2 "general_operand" "qn,qm,0,rn,0,ln")))
5857 (clobber (reg:CC FLAGS_REG))]
5858 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5860 bool widen = (get_attr_mode (insn) != MODE_QI);
5862 switch (get_attr_type (insn))
5868 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5869 if (operands[2] == const1_rtx)
5870 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
5873 gcc_assert (operands[2] == constm1_rtx);
5874 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
5878 /* For most processors, ADD is faster than LEA. These alternatives
5879 were added to use ADD as much as possible. */
5880 if (which_alternative == 2 || which_alternative == 4)
5881 std::swap (operands[1], operands[2]);
5883 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5884 if (x86_maybe_negate_const_int (&operands[2], QImode))
5887 return "sub{l}\t{%2, %k0|%k0, %2}";
5889 return "sub{b}\t{%2, %0|%0, %2}";
5892 return "add{l}\t{%k2, %k0|%k0, %k2}";
5894 return "add{b}\t{%2, %0|%0, %2}";
5898 (cond [(eq_attr "alternative" "5")
5899 (const_string "lea")
5900 (match_operand:QI 2 "incdec_operand")
5901 (const_string "incdec")
5903 (const_string "alu")))
5904 (set (attr "length_immediate")
5906 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5908 (const_string "*")))
5909 (set_attr "mode" "QI,QI,QI,SI,SI,SI")
5910 ;; Potential partial reg stall on alternatives 3 and 4.
5911 (set (attr "preferred_for_speed")
5912 (cond [(eq_attr "alternative" "3,4")
5913 (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
5914 (symbol_ref "true")))])
5916 (define_insn "*addqi_1_slp"
5917 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
5918 (plus:QI (match_dup 0)
5919 (match_operand:QI 1 "general_operand" "qn,qm")))
5920 (clobber (reg:CC FLAGS_REG))]
5921 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
5922 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
5924 switch (get_attr_type (insn))
5927 if (operands[1] == const1_rtx)
5928 return "inc{b}\t%0";
5931 gcc_assert (operands[1] == constm1_rtx);
5932 return "dec{b}\t%0";
5936 if (x86_maybe_negate_const_int (&operands[1], QImode))
5937 return "sub{b}\t{%1, %0|%0, %1}";
5939 return "add{b}\t{%1, %0|%0, %1}";
5943 (if_then_else (match_operand:QI 1 "incdec_operand")
5944 (const_string "incdec")
5945 (const_string "alu1")))
5946 (set (attr "memory")
5947 (if_then_else (match_operand 1 "memory_operand")
5948 (const_string "load")
5949 (const_string "none")))
5950 (set_attr "mode" "QI")])
5952 ;; Split non destructive adds if we cannot use lea.
5954 [(set (match_operand:SWI48 0 "register_operand")
5955 (plus:SWI48 (match_operand:SWI48 1 "register_operand")
5956 (match_operand:SWI48 2 "x86_64_nonmemory_operand")))
5957 (clobber (reg:CC FLAGS_REG))]
5958 "reload_completed && ix86_avoid_lea_for_add (insn, operands)"
5959 [(set (match_dup 0) (match_dup 1))
5960 (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 2)))
5961 (clobber (reg:CC FLAGS_REG))])])
5963 ;; Split non destructive adds if we cannot use lea.
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))]
5971 && reload_completed && ix86_avoid_lea_for_add (insn, operands)"
5972 [(set (match_dup 3) (match_dup 1))
5973 (parallel [(set (match_dup 0)
5974 (zero_extend:DI (plus:SI (match_dup 3) (match_dup 2))))
5975 (clobber (reg:CC FLAGS_REG))])]
5976 "operands[3] = gen_lowpart (SImode, operands[0]);")
5978 ;; Convert add to the lea pattern to avoid flags dependency.
5980 [(set (match_operand:SWI 0 "register_operand")
5981 (plus:SWI (match_operand:SWI 1 "register_operand")
5982 (match_operand:SWI 2 "<nonmemory_operand>")))
5983 (clobber (reg:CC FLAGS_REG))]
5984 "reload_completed && ix86_lea_for_add_ok (insn, operands)"
5986 (plus:<LEAMODE> (match_dup 1) (match_dup 2)))]
5988 if (<MODE>mode != <LEAMODE>mode)
5990 operands[0] = gen_lowpart (<LEAMODE>mode, operands[0]);
5991 operands[1] = gen_lowpart (<LEAMODE>mode, operands[1]);
5992 operands[2] = gen_lowpart (<LEAMODE>mode, operands[2]);
5996 ;; Convert add to the lea pattern to avoid flags dependency.
5998 [(set (match_operand:DI 0 "register_operand")
6000 (plus:SI (match_operand:SI 1 "register_operand")
6001 (match_operand:SI 2 "x86_64_nonmemory_operand"))))
6002 (clobber (reg:CC FLAGS_REG))]
6003 "TARGET_64BIT && reload_completed && ix86_lea_for_add_ok (insn, operands)"
6005 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))])
6007 (define_insn "*add<mode>_2"
6008 [(set (reg FLAGS_REG)
6011 (match_operand:SWI 1 "nonimmediate_operand" "%0,0,<r>")
6012 (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>,0"))
6014 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m,<r>")
6015 (plus:SWI (match_dup 1) (match_dup 2)))]
6016 "ix86_match_ccmode (insn, CCGOCmode)
6017 && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6019 switch (get_attr_type (insn))
6022 if (operands[2] == const1_rtx)
6023 return "inc{<imodesuffix>}\t%0";
6026 gcc_assert (operands[2] == constm1_rtx);
6027 return "dec{<imodesuffix>}\t%0";
6031 if (which_alternative == 2)
6032 std::swap (operands[1], operands[2]);
6034 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6035 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6036 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6038 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6042 (if_then_else (match_operand:SWI 2 "incdec_operand")
6043 (const_string "incdec")
6044 (const_string "alu")))
6045 (set (attr "length_immediate")
6047 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6049 (const_string "*")))
6050 (set_attr "mode" "<MODE>")])
6052 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6053 (define_insn "*addsi_2_zext"
6054 [(set (reg FLAGS_REG)
6056 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
6057 (match_operand:SI 2 "x86_64_general_operand" "rme,0"))
6059 (set (match_operand:DI 0 "register_operand" "=r,r")
6060 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6061 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6062 && ix86_binary_operator_ok (PLUS, SImode, operands)"
6064 switch (get_attr_type (insn))
6067 if (operands[2] == const1_rtx)
6068 return "inc{l}\t%k0";
6071 gcc_assert (operands[2] == constm1_rtx);
6072 return "dec{l}\t%k0";
6076 if (which_alternative == 1)
6077 std::swap (operands[1], operands[2]);
6079 if (x86_maybe_negate_const_int (&operands[2], SImode))
6080 return "sub{l}\t{%2, %k0|%k0, %2}";
6082 return "add{l}\t{%2, %k0|%k0, %2}";
6086 (if_then_else (match_operand:SI 2 "incdec_operand")
6087 (const_string "incdec")
6088 (const_string "alu")))
6089 (set (attr "length_immediate")
6091 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6093 (const_string "*")))
6094 (set_attr "mode" "SI")])
6096 (define_insn "*add<mode>_3"
6097 [(set (reg FLAGS_REG)
6099 (neg:SWI (match_operand:SWI 2 "<general_operand>" "<g>,0"))
6100 (match_operand:SWI 1 "nonimmediate_operand" "%0,<r>")))
6101 (clobber (match_scratch:SWI 0 "=<r>,<r>"))]
6102 "ix86_match_ccmode (insn, CCZmode)
6103 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6105 switch (get_attr_type (insn))
6108 if (operands[2] == const1_rtx)
6109 return "inc{<imodesuffix>}\t%0";
6112 gcc_assert (operands[2] == constm1_rtx);
6113 return "dec{<imodesuffix>}\t%0";
6117 if (which_alternative == 1)
6118 std::swap (operands[1], operands[2]);
6120 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6121 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6122 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6124 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6128 (if_then_else (match_operand:SWI 2 "incdec_operand")
6129 (const_string "incdec")
6130 (const_string "alu")))
6131 (set (attr "length_immediate")
6133 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6135 (const_string "*")))
6136 (set_attr "mode" "<MODE>")])
6138 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6139 (define_insn "*addsi_3_zext"
6140 [(set (reg FLAGS_REG)
6142 (neg:SI (match_operand:SI 2 "x86_64_general_operand" "rme,0"))
6143 (match_operand:SI 1 "nonimmediate_operand" "%0,r")))
6144 (set (match_operand:DI 0 "register_operand" "=r,r")
6145 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6146 "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
6147 && ix86_binary_operator_ok (PLUS, SImode, operands)"
6149 switch (get_attr_type (insn))
6152 if (operands[2] == const1_rtx)
6153 return "inc{l}\t%k0";
6156 gcc_assert (operands[2] == constm1_rtx);
6157 return "dec{l}\t%k0";
6161 if (which_alternative == 1)
6162 std::swap (operands[1], operands[2]);
6164 if (x86_maybe_negate_const_int (&operands[2], SImode))
6165 return "sub{l}\t{%2, %k0|%k0, %2}";
6167 return "add{l}\t{%2, %k0|%k0, %2}";
6171 (if_then_else (match_operand:SI 2 "incdec_operand")
6172 (const_string "incdec")
6173 (const_string "alu")))
6174 (set (attr "length_immediate")
6176 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6178 (const_string "*")))
6179 (set_attr "mode" "SI")])
6181 ; For comparisons against 1, -1 and 128, we may generate better code
6182 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
6183 ; is matched then. We can't accept general immediate, because for
6184 ; case of overflows, the result is messed up.
6185 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6186 ; only for comparisons not depending on it.
6188 (define_insn "*adddi_4"
6189 [(set (reg FLAGS_REG)
6191 (match_operand:DI 1 "nonimmediate_operand" "0")
6192 (match_operand:DI 2 "x86_64_immediate_operand" "e")))
6193 (clobber (match_scratch:DI 0 "=rm"))]
6195 && ix86_match_ccmode (insn, CCGCmode)"
6197 switch (get_attr_type (insn))
6200 if (operands[2] == constm1_rtx)
6201 return "inc{q}\t%0";
6204 gcc_assert (operands[2] == const1_rtx);
6205 return "dec{q}\t%0";
6209 if (x86_maybe_negate_const_int (&operands[2], DImode))
6210 return "add{q}\t{%2, %0|%0, %2}";
6212 return "sub{q}\t{%2, %0|%0, %2}";
6216 (if_then_else (match_operand:DI 2 "incdec_operand")
6217 (const_string "incdec")
6218 (const_string "alu")))
6219 (set (attr "length_immediate")
6221 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6223 (const_string "*")))
6224 (set_attr "mode" "DI")])
6226 ; For comparisons against 1, -1 and 128, we may generate better code
6227 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
6228 ; is matched then. We can't accept general immediate, because for
6229 ; case of overflows, the result is messed up.
6230 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6231 ; only for comparisons not depending on it.
6233 (define_insn "*add<mode>_4"
6234 [(set (reg FLAGS_REG)
6236 (match_operand:SWI124 1 "nonimmediate_operand" "0")
6237 (match_operand:SWI124 2 "const_int_operand" "n")))
6238 (clobber (match_scratch:SWI124 0 "=<r>m"))]
6239 "ix86_match_ccmode (insn, CCGCmode)"
6241 switch (get_attr_type (insn))
6244 if (operands[2] == constm1_rtx)
6245 return "inc{<imodesuffix>}\t%0";
6248 gcc_assert (operands[2] == const1_rtx);
6249 return "dec{<imodesuffix>}\t%0";
6253 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6254 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6256 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6260 (if_then_else (match_operand:<MODE> 2 "incdec_operand")
6261 (const_string "incdec")
6262 (const_string "alu")))
6263 (set (attr "length_immediate")
6265 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6267 (const_string "*")))
6268 (set_attr "mode" "<MODE>")])
6270 (define_insn "*add<mode>_5"
6271 [(set (reg FLAGS_REG)
6274 (match_operand:SWI 1 "nonimmediate_operand" "%0,<r>")
6275 (match_operand:SWI 2 "<general_operand>" "<g>,0"))
6277 (clobber (match_scratch:SWI 0 "=<r>,<r>"))]
6278 "ix86_match_ccmode (insn, CCGOCmode)
6279 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6281 switch (get_attr_type (insn))
6284 if (operands[2] == const1_rtx)
6285 return "inc{<imodesuffix>}\t%0";
6288 gcc_assert (operands[2] == constm1_rtx);
6289 return "dec{<imodesuffix>}\t%0";
6293 if (which_alternative == 1)
6294 std::swap (operands[1], operands[2]);
6296 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6297 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6298 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6300 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6304 (if_then_else (match_operand:SWI 2 "incdec_operand")
6305 (const_string "incdec")
6306 (const_string "alu")))
6307 (set (attr "length_immediate")
6309 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6311 (const_string "*")))
6312 (set_attr "mode" "<MODE>")])
6314 (define_insn "addqi_ext_1"
6315 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q,Q")
6321 (zero_extract:SI (match_operand 1 "ext_register_operand" "0,0")
6324 (match_operand:QI 2 "general_operand" "QnBc,m")) 0))
6325 (clobber (reg:CC FLAGS_REG))]
6326 "/* FIXME: without this LRA can't reload this pattern, see PR82524. */
6327 rtx_equal_p (operands[0], operands[1])"
6329 switch (get_attr_type (insn))
6332 if (operands[2] == const1_rtx)
6333 return "inc{b}\t%h0";
6336 gcc_assert (operands[2] == constm1_rtx);
6337 return "dec{b}\t%h0";
6341 return "add{b}\t{%2, %h0|%h0, %2}";
6344 [(set_attr "isa" "*,nox64")
6346 (if_then_else (match_operand:QI 2 "incdec_operand")
6347 (const_string "incdec")
6348 (const_string "alu")))
6349 (set_attr "mode" "QI")])
6351 (define_insn "*addqi_ext_2"
6352 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
6358 (zero_extract:SI (match_operand 1 "ext_register_operand" "%0")
6362 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
6364 (const_int 8)) 0)) 0))
6365 (clobber (reg:CC FLAGS_REG))]
6366 "/* FIXME: without this LRA can't reload this pattern, see PR82524. */
6367 rtx_equal_p (operands[0], operands[1])
6368 || rtx_equal_p (operands[0], operands[2])"
6369 "add{b}\t{%h2, %h0|%h0, %h2}"
6370 [(set_attr "type" "alu")
6371 (set_attr "mode" "QI")])
6373 ;; Add with jump on overflow.
6374 (define_expand "addv<mode>4"
6375 [(parallel [(set (reg:CCO FLAGS_REG)
6378 (match_operand:SWI 1 "nonimmediate_operand"))
6381 (plus:SWI (match_dup 1)
6382 (match_operand:SWI 2
6383 "<general_operand>")))))
6384 (set (match_operand:SWI 0 "register_operand")
6385 (plus:SWI (match_dup 1) (match_dup 2)))])
6386 (set (pc) (if_then_else
6387 (eq (reg:CCO FLAGS_REG) (const_int 0))
6388 (label_ref (match_operand 3))
6392 ix86_fixup_binary_operands_no_copy (PLUS, <MODE>mode, operands);
6393 if (CONST_INT_P (operands[2]))
6394 operands[4] = operands[2];
6396 operands[4] = gen_rtx_SIGN_EXTEND (<DWI>mode, operands[2]);
6399 (define_insn "*addv<mode>4"
6400 [(set (reg:CCO FLAGS_REG)
6403 (match_operand:SWI 1 "nonimmediate_operand" "%0,0"))
6405 (match_operand:SWI 2 "<general_sext_operand>"
6408 (plus:SWI (match_dup 1) (match_dup 2)))))
6409 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
6410 (plus:SWI (match_dup 1) (match_dup 2)))]
6411 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6412 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6413 [(set_attr "type" "alu")
6414 (set_attr "mode" "<MODE>")])
6416 (define_insn "*addv<mode>4_1"
6417 [(set (reg:CCO FLAGS_REG)
6420 (match_operand:SWI 1 "nonimmediate_operand" "0"))
6421 (match_operand:<DWI> 3 "const_int_operand" "i"))
6423 (plus:SWI (match_dup 1)
6424 (match_operand:SWI 2 "x86_64_immediate_operand"
6426 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
6427 (plus:SWI (match_dup 1) (match_dup 2)))]
6428 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)
6429 && CONST_INT_P (operands[2])
6430 && INTVAL (operands[2]) == INTVAL (operands[3])"
6431 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6432 [(set_attr "type" "alu")
6433 (set_attr "mode" "<MODE>")
6434 (set (attr "length_immediate")
6435 (cond [(match_test "IN_RANGE (INTVAL (operands[2]), -128, 127)")
6437 (match_test "<MODE_SIZE> == 8")
6439 (const_string "<MODE_SIZE>")))])
6441 (define_expand "uaddv<mode>4"
6442 [(parallel [(set (reg:CCC FLAGS_REG)
6445 (match_operand:SWI 1 "nonimmediate_operand")
6446 (match_operand:SWI 2 "<general_operand>"))
6448 (set (match_operand:SWI 0 "register_operand")
6449 (plus:SWI (match_dup 1) (match_dup 2)))])
6450 (set (pc) (if_then_else
6451 (ltu (reg:CCC FLAGS_REG) (const_int 0))
6452 (label_ref (match_operand 3))
6455 "ix86_fixup_binary_operands_no_copy (PLUS, <MODE>mode, operands);")
6457 ;; The lea patterns for modes less than 32 bits need to be matched by
6458 ;; several insns converted to real lea by splitters.
6460 (define_insn_and_split "*lea<mode>_general_1"
6461 [(set (match_operand:SWI12 0 "register_operand" "=r")
6463 (plus:SWI12 (match_operand:SWI12 1 "index_register_operand" "l")
6464 (match_operand:SWI12 2 "register_operand" "r"))
6465 (match_operand:SWI12 3 "immediate_operand" "i")))]
6466 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
6468 "&& reload_completed"
6471 (plus:SI (match_dup 1) (match_dup 2))
6474 operands[0] = gen_lowpart (SImode, operands[0]);
6475 operands[1] = gen_lowpart (SImode, operands[1]);
6476 operands[2] = gen_lowpart (SImode, operands[2]);
6477 operands[3] = gen_lowpart (SImode, operands[3]);
6479 [(set_attr "type" "lea")
6480 (set_attr "mode" "SI")])
6482 (define_insn_and_split "*lea<mode>_general_2"
6483 [(set (match_operand:SWI12 0 "register_operand" "=r")
6485 (mult:SWI12 (match_operand:SWI12 1 "index_register_operand" "l")
6486 (match_operand 2 "const248_operand" "n"))
6487 (match_operand:SWI12 3 "nonmemory_operand" "ri")))]
6488 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
6490 "&& reload_completed"
6493 (mult:SI (match_dup 1) (match_dup 2))
6496 operands[0] = gen_lowpart (SImode, operands[0]);
6497 operands[1] = gen_lowpart (SImode, operands[1]);
6498 operands[3] = gen_lowpart (SImode, operands[3]);
6500 [(set_attr "type" "lea")
6501 (set_attr "mode" "SI")])
6503 (define_insn_and_split "*lea<mode>_general_2b"
6504 [(set (match_operand:SWI12 0 "register_operand" "=r")
6506 (ashift:SWI12 (match_operand:SWI12 1 "index_register_operand" "l")
6507 (match_operand 2 "const123_operand" "n"))
6508 (match_operand:SWI12 3 "nonmemory_operand" "ri")))]
6509 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
6511 "&& reload_completed"
6514 (ashift:SI (match_dup 1) (match_dup 2))
6517 operands[0] = gen_lowpart (SImode, operands[0]);
6518 operands[1] = gen_lowpart (SImode, operands[1]);
6519 operands[3] = gen_lowpart (SImode, operands[3]);
6521 [(set_attr "type" "lea")
6522 (set_attr "mode" "SI")])
6524 (define_insn_and_split "*lea<mode>_general_3"
6525 [(set (match_operand:SWI12 0 "register_operand" "=r")
6528 (mult:SWI12 (match_operand:SWI12 1 "index_register_operand" "l")
6529 (match_operand 2 "const248_operand" "n"))
6530 (match_operand:SWI12 3 "register_operand" "r"))
6531 (match_operand:SWI12 4 "immediate_operand" "i")))]
6532 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
6534 "&& reload_completed"
6538 (mult:SI (match_dup 1) (match_dup 2))
6542 operands[0] = gen_lowpart (SImode, operands[0]);
6543 operands[1] = gen_lowpart (SImode, operands[1]);
6544 operands[3] = gen_lowpart (SImode, operands[3]);
6545 operands[4] = gen_lowpart (SImode, operands[4]);
6547 [(set_attr "type" "lea")
6548 (set_attr "mode" "SI")])
6550 (define_insn_and_split "*lea<mode>_general_3b"
6551 [(set (match_operand:SWI12 0 "register_operand" "=r")
6554 (ashift:SWI12 (match_operand:SWI12 1 "index_register_operand" "l")
6555 (match_operand 2 "const123_operand" "n"))
6556 (match_operand:SWI12 3 "register_operand" "r"))
6557 (match_operand:SWI12 4 "immediate_operand" "i")))]
6558 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
6560 "&& reload_completed"
6564 (ashift:SI (match_dup 1) (match_dup 2))
6568 operands[0] = gen_lowpart (SImode, operands[0]);
6569 operands[1] = gen_lowpart (SImode, operands[1]);
6570 operands[3] = gen_lowpart (SImode, operands[3]);
6571 operands[4] = gen_lowpart (SImode, operands[4]);
6573 [(set_attr "type" "lea")
6574 (set_attr "mode" "SI")])
6576 (define_insn_and_split "*lea<mode>_general_4"
6577 [(set (match_operand:SWI12 0 "register_operand" "=r")
6580 (match_operand:SWI12 1 "index_register_operand" "l")
6581 (match_operand 2 "const_0_to_3_operand" "n"))
6582 (match_operand 3 "const_int_operand" "n")))]
6583 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6584 && ((unsigned HOST_WIDE_INT) INTVAL (operands[3])
6585 < (HOST_WIDE_INT_1U << INTVAL (operands[2])))"
6587 "&& reload_completed"
6590 (mult:SI (match_dup 1) (match_dup 2))
6593 operands[0] = gen_lowpart (SImode, operands[0]);
6594 operands[1] = gen_lowpart (SImode, operands[1]);
6595 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
6597 [(set_attr "type" "lea")
6598 (set_attr "mode" "SI")])
6600 (define_insn_and_split "*lea<mode>_general_4"
6601 [(set (match_operand:SWI48 0 "register_operand" "=r")
6604 (match_operand:SWI48 1 "index_register_operand" "l")
6605 (match_operand 2 "const_0_to_3_operand" "n"))
6606 (match_operand 3 "const_int_operand" "n")))]
6607 "(unsigned HOST_WIDE_INT) INTVAL (operands[3])
6608 < (HOST_WIDE_INT_1U << INTVAL (operands[2]))"
6610 "&& reload_completed"
6613 (mult:SWI48 (match_dup 1) (match_dup 2))
6615 "operands[2] = GEN_INT (1 << INTVAL (operands[2]));"
6616 [(set_attr "type" "lea")
6617 (set_attr "mode" "<MODE>")])
6619 ;; Subtract instructions
6621 (define_expand "sub<mode>3"
6622 [(set (match_operand:SDWIM 0 "nonimmediate_operand")
6623 (minus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")
6624 (match_operand:SDWIM 2 "<general_hilo_operand>")))]
6626 "ix86_expand_binary_operator (MINUS, <MODE>mode, operands); DONE;")
6628 (define_insn_and_split "*sub<dwi>3_doubleword"
6629 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
6631 (match_operand:<DWI> 1 "nonimmediate_operand" "0,0")
6632 (match_operand:<DWI> 2 "x86_64_hilo_general_operand"
6634 (clobber (reg:CC FLAGS_REG))]
6635 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6638 [(parallel [(set (reg:CC FLAGS_REG)
6639 (compare:CC (match_dup 1) (match_dup 2)))
6641 (minus:DWIH (match_dup 1) (match_dup 2)))])
6642 (parallel [(set (match_dup 3)
6646 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0)))
6648 (clobber (reg:CC FLAGS_REG))])]
6650 split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
6651 if (operands[2] == const0_rtx)
6653 ix86_expand_binary_operator (MINUS, <MODE>mode, &operands[3]);
6658 (define_insn "*sub<mode>_1"
6659 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6661 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6662 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6663 (clobber (reg:CC FLAGS_REG))]
6664 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6665 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6666 [(set_attr "type" "alu")
6667 (set_attr "mode" "<MODE>")])
6669 (define_insn "*subsi_1_zext"
6670 [(set (match_operand:DI 0 "register_operand" "=r")
6672 (minus:SI (match_operand:SI 1 "register_operand" "0")
6673 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
6674 (clobber (reg:CC FLAGS_REG))]
6675 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6676 "sub{l}\t{%2, %k0|%k0, %2}"
6677 [(set_attr "type" "alu")
6678 (set_attr "mode" "SI")])
6680 (define_insn "*subqi_1_slp"
6681 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6682 (minus:QI (match_dup 0)
6683 (match_operand:QI 1 "general_operand" "qn,qm")))
6684 (clobber (reg:CC FLAGS_REG))]
6685 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6686 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
6687 "sub{b}\t{%1, %0|%0, %1}"
6688 [(set_attr "type" "alu1")
6689 (set_attr "mode" "QI")])
6691 (define_insn "*sub<mode>_2"
6692 [(set (reg FLAGS_REG)
6695 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6696 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6698 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6699 (minus:SWI (match_dup 1) (match_dup 2)))]
6700 "ix86_match_ccmode (insn, CCGOCmode)
6701 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6702 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6703 [(set_attr "type" "alu")
6704 (set_attr "mode" "<MODE>")])
6706 (define_insn "*subsi_2_zext"
6707 [(set (reg FLAGS_REG)
6709 (minus:SI (match_operand:SI 1 "register_operand" "0")
6710 (match_operand:SI 2 "x86_64_general_operand" "rme"))
6712 (set (match_operand:DI 0 "register_operand" "=r")
6714 (minus:SI (match_dup 1)
6716 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6717 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6718 "sub{l}\t{%2, %k0|%k0, %2}"
6719 [(set_attr "type" "alu")
6720 (set_attr "mode" "SI")])
6722 ;; Subtract with jump on overflow.
6723 (define_expand "subv<mode>4"
6724 [(parallel [(set (reg:CCO FLAGS_REG)
6725 (eq:CCO (minus:<DWI>
6727 (match_operand:SWI 1 "nonimmediate_operand"))
6730 (minus:SWI (match_dup 1)
6731 (match_operand:SWI 2
6732 "<general_operand>")))))
6733 (set (match_operand:SWI 0 "register_operand")
6734 (minus:SWI (match_dup 1) (match_dup 2)))])
6735 (set (pc) (if_then_else
6736 (eq (reg:CCO FLAGS_REG) (const_int 0))
6737 (label_ref (match_operand 3))
6741 ix86_fixup_binary_operands_no_copy (MINUS, <MODE>mode, operands);
6742 if (CONST_INT_P (operands[2]))
6743 operands[4] = operands[2];
6745 operands[4] = gen_rtx_SIGN_EXTEND (<DWI>mode, operands[2]);
6748 (define_insn "*subv<mode>4"
6749 [(set (reg:CCO FLAGS_REG)
6750 (eq:CCO (minus:<DWI>
6752 (match_operand:SWI 1 "nonimmediate_operand" "0,0"))
6754 (match_operand:SWI 2 "<general_sext_operand>"
6757 (minus:SWI (match_dup 1) (match_dup 2)))))
6758 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6759 (minus:SWI (match_dup 1) (match_dup 2)))]
6760 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6761 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6762 [(set_attr "type" "alu")
6763 (set_attr "mode" "<MODE>")])
6765 (define_insn "*subv<mode>4_1"
6766 [(set (reg:CCO FLAGS_REG)
6767 (eq:CCO (minus:<DWI>
6769 (match_operand:SWI 1 "nonimmediate_operand" "0"))
6770 (match_operand:<DWI> 3 "const_int_operand" "i"))
6772 (minus:SWI (match_dup 1)
6773 (match_operand:SWI 2 "x86_64_immediate_operand"
6775 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
6776 (minus:SWI (match_dup 1) (match_dup 2)))]
6777 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)
6778 && CONST_INT_P (operands[2])
6779 && INTVAL (operands[2]) == INTVAL (operands[3])"
6780 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6781 [(set_attr "type" "alu")
6782 (set_attr "mode" "<MODE>")
6783 (set (attr "length_immediate")
6784 (cond [(match_test "IN_RANGE (INTVAL (operands[2]), -128, 127)")
6786 (match_test "<MODE_SIZE> == 8")
6788 (const_string "<MODE_SIZE>")))])
6790 (define_expand "usubv<mode>4"
6791 [(parallel [(set (reg:CC FLAGS_REG)
6793 (match_operand:SWI 1 "nonimmediate_operand")
6794 (match_operand:SWI 2 "<general_operand>")))
6795 (set (match_operand:SWI 0 "register_operand")
6796 (minus:SWI (match_dup 1) (match_dup 2)))])
6797 (set (pc) (if_then_else
6798 (ltu (reg:CC FLAGS_REG) (const_int 0))
6799 (label_ref (match_operand 3))
6802 "ix86_fixup_binary_operands_no_copy (MINUS, <MODE>mode, operands);")
6804 (define_insn "*sub<mode>_3"
6805 [(set (reg FLAGS_REG)
6806 (compare (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6807 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6808 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6809 (minus:SWI (match_dup 1) (match_dup 2)))]
6810 "ix86_match_ccmode (insn, CCmode)
6811 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6812 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6813 [(set_attr "type" "alu")
6814 (set_attr "mode" "<MODE>")])
6818 [(set (reg:CC FLAGS_REG)
6819 (compare:CC (match_operand:SWI 0 "general_reg_operand")
6820 (match_operand:SWI 1 "general_gr_operand")))
6822 (minus:SWI (match_dup 0) (match_dup 1)))])]
6823 "find_regno_note (peep2_next_insn (0), REG_UNUSED, REGNO (operands[0])) != 0"
6824 [(set (reg:CC FLAGS_REG)
6825 (compare:CC (match_dup 0) (match_dup 1)))])
6827 (define_insn "*subsi_3_zext"
6828 [(set (reg FLAGS_REG)
6829 (compare (match_operand:SI 1 "register_operand" "0")
6830 (match_operand:SI 2 "x86_64_general_operand" "rme")))
6831 (set (match_operand:DI 0 "register_operand" "=r")
6833 (minus:SI (match_dup 1)
6835 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6836 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6837 "sub{l}\t{%2, %1|%1, %2}"
6838 [(set_attr "type" "alu")
6839 (set_attr "mode" "SI")])
6841 ;; Add with carry and subtract with borrow
6843 (define_insn "add<mode>3_carry"
6844 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6847 (match_operator:SWI 4 "ix86_carry_flag_operator"
6848 [(match_operand 3 "flags_reg_operand") (const_int 0)])
6849 (match_operand:SWI 1 "nonimmediate_operand" "%0,0"))
6850 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6851 (clobber (reg:CC FLAGS_REG))]
6852 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6853 "adc{<imodesuffix>}\t{%2, %0|%0, %2}"
6854 [(set_attr "type" "alu")
6855 (set_attr "use_carry" "1")
6856 (set_attr "pent_pair" "pu")
6857 (set_attr "mode" "<MODE>")])
6859 (define_insn "*add<mode>3_carry_0"
6860 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
6862 (match_operator:SWI 3 "ix86_carry_flag_operator"
6863 [(match_operand 2 "flags_reg_operand") (const_int 0)])
6864 (match_operand:SWI 1 "nonimmediate_operand" "0")))
6865 (clobber (reg:CC FLAGS_REG))]
6866 "ix86_unary_operator_ok (PLUS, <MODE>mode, operands)"
6867 "adc{<imodesuffix>}\t{$0, %0|%0, 0}"
6868 [(set_attr "type" "alu")
6869 (set_attr "use_carry" "1")
6870 (set_attr "pent_pair" "pu")
6871 (set_attr "mode" "<MODE>")])
6873 (define_insn "*addsi3_carry_zext"
6874 [(set (match_operand:DI 0 "register_operand" "=r")
6877 (plus:SI (match_operator:SI 3 "ix86_carry_flag_operator"
6878 [(reg FLAGS_REG) (const_int 0)])
6879 (match_operand:SI 1 "register_operand" "%0"))
6880 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
6881 (clobber (reg:CC FLAGS_REG))]
6882 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6883 "adc{l}\t{%2, %k0|%k0, %2}"
6884 [(set_attr "type" "alu")
6885 (set_attr "use_carry" "1")
6886 (set_attr "pent_pair" "pu")
6887 (set_attr "mode" "SI")])
6889 (define_insn "*addsi3_carry_zext_0"
6890 [(set (match_operand:DI 0 "register_operand" "=r")
6892 (plus:SI (match_operator:SI 2 "ix86_carry_flag_operator"
6893 [(reg FLAGS_REG) (const_int 0)])
6894 (match_operand:SI 1 "register_operand" "0"))))
6895 (clobber (reg:CC FLAGS_REG))]
6897 "adc{l}\t{$0, %k0|%k0, 0}"
6898 [(set_attr "type" "alu")
6899 (set_attr "use_carry" "1")
6900 (set_attr "pent_pair" "pu")
6901 (set_attr "mode" "SI")])
6903 ;; There is no point to generate ADCX instruction. ADC is shorter and faster.
6905 (define_insn "addcarry<mode>"
6906 [(set (reg:CCC FLAGS_REG)
6911 (match_operator:SWI48 5 "ix86_carry_flag_operator"
6912 [(match_operand 3 "flags_reg_operand") (const_int 0)])
6913 (match_operand:SWI48 1 "nonimmediate_operand" "%0"))
6914 (match_operand:SWI48 2 "nonimmediate_operand" "rm")))
6916 (zero_extend:<DWI> (match_dup 2))
6917 (match_operator:<DWI> 4 "ix86_carry_flag_operator"
6918 [(match_dup 3) (const_int 0)]))))
6919 (set (match_operand:SWI48 0 "register_operand" "=r")
6920 (plus:SWI48 (plus:SWI48 (match_op_dup 5
6921 [(match_dup 3) (const_int 0)])
6924 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6925 "adc{<imodesuffix>}\t{%2, %0|%0, %2}"
6926 [(set_attr "type" "alu")
6927 (set_attr "use_carry" "1")
6928 (set_attr "pent_pair" "pu")
6929 (set_attr "mode" "<MODE>")])
6931 (define_expand "addcarry<mode>_0"
6933 [(set (reg:CCC FLAGS_REG)
6936 (match_operand:SWI48 1 "nonimmediate_operand")
6937 (match_operand:SWI48 2 "x86_64_general_operand"))
6939 (set (match_operand:SWI48 0 "register_operand")
6940 (plus:SWI48 (match_dup 1) (match_dup 2)))])]
6941 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)")
6943 (define_insn "sub<mode>3_carry"
6944 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6947 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6948 (match_operator:SWI 4 "ix86_carry_flag_operator"
6949 [(match_operand 3 "flags_reg_operand") (const_int 0)]))
6950 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6951 (clobber (reg:CC FLAGS_REG))]
6952 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6953 "sbb{<imodesuffix>}\t{%2, %0|%0, %2}"
6954 [(set_attr "type" "alu")
6955 (set_attr "use_carry" "1")
6956 (set_attr "pent_pair" "pu")
6957 (set_attr "mode" "<MODE>")])
6959 (define_insn "*sub<mode>3_carry_0"
6960 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
6962 (match_operand:SWI 1 "nonimmediate_operand" "0")
6963 (match_operator:SWI 3 "ix86_carry_flag_operator"
6964 [(match_operand 2 "flags_reg_operand") (const_int 0)])))
6965 (clobber (reg:CC FLAGS_REG))]
6966 "ix86_unary_operator_ok (MINUS, <MODE>mode, operands)"
6967 "sbb{<imodesuffix>}\t{$0, %0|%0, 0}"
6968 [(set_attr "type" "alu")
6969 (set_attr "use_carry" "1")
6970 (set_attr "pent_pair" "pu")
6971 (set_attr "mode" "<MODE>")])
6973 (define_insn "*subsi3_carry_zext"
6974 [(set (match_operand:DI 0 "register_operand" "=r")
6978 (match_operand:SI 1 "register_operand" "0")
6979 (match_operator:SI 3 "ix86_carry_flag_operator"
6980 [(reg FLAGS_REG) (const_int 0)]))
6981 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
6982 (clobber (reg:CC FLAGS_REG))]
6983 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6984 "sbb{l}\t{%2, %k0|%k0, %2}"
6985 [(set_attr "type" "alu")
6986 (set_attr "use_carry" "1")
6987 (set_attr "pent_pair" "pu")
6988 (set_attr "mode" "SI")])
6990 (define_insn "*subsi3_carry_zext_0"
6991 [(set (match_operand:DI 0 "register_operand" "=r")
6994 (match_operand:SI 1 "register_operand" "0")
6995 (match_operator:SI 2 "ix86_carry_flag_operator"
6996 [(reg FLAGS_REG) (const_int 0)]))))
6997 (clobber (reg:CC FLAGS_REG))]
6999 "sbb{l}\t{$0, %k0|%k0, 0}"
7000 [(set_attr "type" "alu")
7001 (set_attr "use_carry" "1")
7002 (set_attr "pent_pair" "pu")
7003 (set_attr "mode" "SI")])
7005 (define_insn "sub<mode>3_carry_ccc"
7006 [(set (reg:CCC FLAGS_REG)
7008 (zero_extend:<DWI> (match_operand:DWIH 1 "register_operand" "0"))
7010 (ltu:<DWI> (reg:CC FLAGS_REG) (const_int 0))
7012 (match_operand:DWIH 2 "x86_64_sext_operand" "rmWe")))))
7013 (clobber (match_scratch:DWIH 0 "=r"))]
7015 "sbb{<imodesuffix>}\t{%2, %0|%0, %2}"
7016 [(set_attr "type" "alu")
7017 (set_attr "mode" "<MODE>")])
7019 (define_insn "*sub<mode>3_carry_ccc_1"
7020 [(set (reg:CCC FLAGS_REG)
7022 (zero_extend:<DWI> (match_operand:DWIH 1 "register_operand" "0"))
7024 (ltu:<DWI> (reg:CC FLAGS_REG) (const_int 0))
7025 (match_operand:<DWI> 2 "x86_64_dwzext_immediate_operand" "Wf"))))
7026 (clobber (match_scratch:DWIH 0 "=r"))]
7029 operands[3] = simplify_subreg (<MODE>mode, operands[2], <DWI>mode, 0);
7030 return "sbb{<imodesuffix>}\t{%3, %0|%0, %3}";
7032 [(set_attr "type" "alu")
7033 (set_attr "mode" "<MODE>")])
7035 ;; The sign flag is set from the
7036 ;; (compare (match_dup 1) (plus:DWIH (ltu:DWIH ...) (match_dup 2)))
7037 ;; result, the overflow flag likewise, but the overflow flag is also
7038 ;; set if the (plus:DWIH (ltu:DWIH ...) (match_dup 2)) overflows.
7039 (define_insn "sub<mode>3_carry_ccgz"
7040 [(set (reg:CCGZ FLAGS_REG)
7041 (unspec:CCGZ [(match_operand:DWIH 1 "register_operand" "0")
7042 (match_operand:DWIH 2 "x86_64_general_operand" "rme")
7043 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))]
7045 (clobber (match_scratch:DWIH 0 "=r"))]
7047 "sbb{<imodesuffix>}\t{%2, %0|%0, %2}"
7048 [(set_attr "type" "alu")
7049 (set_attr "mode" "<MODE>")])
7051 (define_insn "subborrow<mode>"
7052 [(set (reg:CCC FLAGS_REG)
7055 (match_operand:SWI48 1 "nonimmediate_operand" "0"))
7057 (match_operator:<DWI> 4 "ix86_carry_flag_operator"
7058 [(match_operand 3 "flags_reg_operand") (const_int 0)])
7060 (match_operand:SWI48 2 "nonimmediate_operand" "rm")))))
7061 (set (match_operand:SWI48 0 "register_operand" "=r")
7062 (minus:SWI48 (minus:SWI48
7064 (match_operator:SWI48 5 "ix86_carry_flag_operator"
7065 [(match_dup 3) (const_int 0)]))
7067 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
7068 "sbb{<imodesuffix>}\t{%2, %0|%0, %2}"
7069 [(set_attr "type" "alu")
7070 (set_attr "use_carry" "1")
7071 (set_attr "pent_pair" "pu")
7072 (set_attr "mode" "<MODE>")])
7074 (define_expand "subborrow<mode>_0"
7076 [(set (reg:CC FLAGS_REG)
7078 (match_operand:SWI48 1 "nonimmediate_operand")
7079 (match_operand:SWI48 2 "<general_operand>")))
7080 (set (match_operand:SWI48 0 "register_operand")
7081 (minus:SWI48 (match_dup 1) (match_dup 2)))])]
7082 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)")
7084 ;; Overflow setting add instructions
7086 (define_expand "addqi3_cconly_overflow"
7088 [(set (reg:CCC FLAGS_REG)
7091 (match_operand:QI 0 "nonimmediate_operand")
7092 (match_operand:QI 1 "general_operand"))
7094 (clobber (match_scratch:QI 2))])]
7095 "!(MEM_P (operands[0]) && MEM_P (operands[1]))")
7097 (define_insn "*add<mode>3_cconly_overflow_1"
7098 [(set (reg:CCC FLAGS_REG)
7101 (match_operand:SWI 1 "nonimmediate_operand" "%0")
7102 (match_operand:SWI 2 "<general_operand>" "<g>"))
7104 (clobber (match_scratch:SWI 0 "=<r>"))]
7105 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7106 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
7107 [(set_attr "type" "alu")
7108 (set_attr "mode" "<MODE>")])
7110 (define_insn "*add<mode>3_cc_overflow_1"
7111 [(set (reg:CCC FLAGS_REG)
7114 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
7115 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
7117 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
7118 (plus:SWI (match_dup 1) (match_dup 2)))]
7119 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
7120 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
7121 [(set_attr "type" "alu")
7122 (set_attr "mode" "<MODE>")])
7124 (define_insn "*addsi3_zext_cc_overflow_1"
7125 [(set (reg:CCC FLAGS_REG)
7128 (match_operand:SI 1 "nonimmediate_operand" "%0")
7129 (match_operand:SI 2 "x86_64_general_operand" "rme"))
7131 (set (match_operand:DI 0 "register_operand" "=r")
7132 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
7133 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
7134 "add{l}\t{%2, %k0|%k0, %2}"
7135 [(set_attr "type" "alu")
7136 (set_attr "mode" "SI")])
7138 (define_insn "*add<mode>3_cconly_overflow_2"
7139 [(set (reg:CCC FLAGS_REG)
7142 (match_operand:SWI 1 "nonimmediate_operand" "%0")
7143 (match_operand:SWI 2 "<general_operand>" "<g>"))
7145 (clobber (match_scratch:SWI 0 "=<r>"))]
7146 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7147 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
7148 [(set_attr "type" "alu")
7149 (set_attr "mode" "<MODE>")])
7151 (define_insn "*add<mode>3_cc_overflow_2"
7152 [(set (reg:CCC FLAGS_REG)
7155 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
7156 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
7158 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
7159 (plus:SWI (match_dup 1) (match_dup 2)))]
7160 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
7161 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
7162 [(set_attr "type" "alu")
7163 (set_attr "mode" "<MODE>")])
7165 (define_insn "*addsi3_zext_cc_overflow_2"
7166 [(set (reg:CCC FLAGS_REG)
7169 (match_operand:SI 1 "nonimmediate_operand" "%0")
7170 (match_operand:SI 2 "x86_64_general_operand" "rme"))
7172 (set (match_operand:DI 0 "register_operand" "=r")
7173 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
7174 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
7175 "add{l}\t{%2, %k0|%k0, %2}"
7176 [(set_attr "type" "alu")
7177 (set_attr "mode" "SI")])
7179 ;; The patterns that match these are at the end of this file.
7181 (define_expand "<plusminus_insn>xf3"
7182 [(set (match_operand:XF 0 "register_operand")
7184 (match_operand:XF 1 "register_operand")
7185 (match_operand:XF 2 "register_operand")))]
7188 (define_expand "<plusminus_insn><mode>3"
7189 [(set (match_operand:MODEF 0 "register_operand")
7191 (match_operand:MODEF 1 "register_operand")
7192 (match_operand:MODEF 2 "nonimmediate_operand")))]
7193 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
7194 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
7196 ;; Multiply instructions
7198 (define_expand "mul<mode>3"
7199 [(parallel [(set (match_operand:SWIM248 0 "register_operand")
7201 (match_operand:SWIM248 1 "register_operand")
7202 (match_operand:SWIM248 2 "<general_operand>")))
7203 (clobber (reg:CC FLAGS_REG))])])
7205 (define_expand "mulqi3"
7206 [(parallel [(set (match_operand:QI 0 "register_operand")
7208 (match_operand:QI 1 "register_operand")
7209 (match_operand:QI 2 "nonimmediate_operand")))
7210 (clobber (reg:CC FLAGS_REG))])]
7211 "TARGET_QIMODE_MATH")
7214 ;; IMUL reg32/64, reg32/64, imm8 Direct
7215 ;; IMUL reg32/64, mem32/64, imm8 VectorPath
7216 ;; IMUL reg32/64, reg32/64, imm32 Direct
7217 ;; IMUL reg32/64, mem32/64, imm32 VectorPath
7218 ;; IMUL reg32/64, reg32/64 Direct
7219 ;; IMUL reg32/64, mem32/64 Direct
7221 ;; On BDVER1, all above IMULs use DirectPath
7224 ;; IMUL reg16, reg16, imm8 VectorPath
7225 ;; IMUL reg16, mem16, imm8 VectorPath
7226 ;; IMUL reg16, reg16, imm16 VectorPath
7227 ;; IMUL reg16, mem16, imm16 VectorPath
7228 ;; IMUL reg16, reg16 Direct
7229 ;; IMUL reg16, mem16 Direct
7231 ;; On BDVER1, all HI MULs use DoublePath
7233 (define_insn "*mul<mode>3_1"
7234 [(set (match_operand:SWIM248 0 "register_operand" "=r,r,r")
7236 (match_operand:SWIM248 1 "nonimmediate_operand" "%rm,rm,0")
7237 (match_operand:SWIM248 2 "<general_operand>" "K,<i>,mr")))
7238 (clobber (reg:CC FLAGS_REG))]
7239 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7241 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
7242 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
7243 imul{<imodesuffix>}\t{%2, %0|%0, %2}"
7244 [(set_attr "type" "imul")
7245 (set_attr "prefix_0f" "0,0,1")
7246 (set (attr "athlon_decode")
7247 (cond [(eq_attr "cpu" "athlon")
7248 (const_string "vector")
7249 (eq_attr "alternative" "1")
7250 (const_string "vector")
7251 (and (eq_attr "alternative" "2")
7252 (ior (match_test "<MODE>mode == HImode")
7253 (match_operand 1 "memory_operand")))
7254 (const_string "vector")]
7255 (const_string "direct")))
7256 (set (attr "amdfam10_decode")
7257 (cond [(and (eq_attr "alternative" "0,1")
7258 (ior (match_test "<MODE>mode == HImode")
7259 (match_operand 1 "memory_operand")))
7260 (const_string "vector")]
7261 (const_string "direct")))
7262 (set (attr "bdver1_decode")
7264 (match_test "<MODE>mode == HImode")
7265 (const_string "double")
7266 (const_string "direct")))
7267 (set_attr "mode" "<MODE>")])
7269 (define_insn "*mulsi3_1_zext"
7270 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
7272 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
7273 (match_operand:SI 2 "x86_64_general_operand" "K,e,mr"))))
7274 (clobber (reg:CC FLAGS_REG))]
7276 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7278 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7279 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7280 imul{l}\t{%2, %k0|%k0, %2}"
7281 [(set_attr "type" "imul")
7282 (set_attr "prefix_0f" "0,0,1")
7283 (set (attr "athlon_decode")
7284 (cond [(eq_attr "cpu" "athlon")
7285 (const_string "vector")
7286 (eq_attr "alternative" "1")
7287 (const_string "vector")
7288 (and (eq_attr "alternative" "2")
7289 (match_operand 1 "memory_operand"))
7290 (const_string "vector")]
7291 (const_string "direct")))
7292 (set (attr "amdfam10_decode")
7293 (cond [(and (eq_attr "alternative" "0,1")
7294 (match_operand 1 "memory_operand"))
7295 (const_string "vector")]
7296 (const_string "direct")))
7297 (set_attr "bdver1_decode" "direct")
7298 (set_attr "mode" "SI")])
7300 ;;On AMDFAM10 and BDVER1
7304 (define_insn "*mulqi3_1"
7305 [(set (match_operand:QI 0 "register_operand" "=a")
7306 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
7307 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7308 (clobber (reg:CC FLAGS_REG))]
7310 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7312 [(set_attr "type" "imul")
7313 (set_attr "length_immediate" "0")
7314 (set (attr "athlon_decode")
7315 (if_then_else (eq_attr "cpu" "athlon")
7316 (const_string "vector")
7317 (const_string "direct")))
7318 (set_attr "amdfam10_decode" "direct")
7319 (set_attr "bdver1_decode" "direct")
7320 (set_attr "mode" "QI")])
7322 ;; Multiply with jump on overflow.
7323 (define_expand "mulv<mode>4"
7324 [(parallel [(set (reg:CCO FLAGS_REG)
7327 (match_operand:SWI248 1 "register_operand"))
7330 (mult:SWI248 (match_dup 1)
7331 (match_operand:SWI248 2
7332 "<general_operand>")))))
7333 (set (match_operand:SWI248 0 "register_operand")
7334 (mult:SWI248 (match_dup 1) (match_dup 2)))])
7335 (set (pc) (if_then_else
7336 (eq (reg:CCO FLAGS_REG) (const_int 0))
7337 (label_ref (match_operand 3))
7341 if (CONST_INT_P (operands[2]))
7342 operands[4] = operands[2];
7344 operands[4] = gen_rtx_SIGN_EXTEND (<DWI>mode, operands[2]);
7347 (define_insn "*mulv<mode>4"
7348 [(set (reg:CCO FLAGS_REG)
7351 (match_operand:SWI48 1 "nonimmediate_operand" "%rm,0"))
7353 (match_operand:SWI48 2 "x86_64_sext_operand" "We,mr")))
7355 (mult:SWI48 (match_dup 1) (match_dup 2)))))
7356 (set (match_operand:SWI48 0 "register_operand" "=r,r")
7357 (mult:SWI48 (match_dup 1) (match_dup 2)))]
7358 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7360 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
7361 imul{<imodesuffix>}\t{%2, %0|%0, %2}"
7362 [(set_attr "type" "imul")
7363 (set_attr "prefix_0f" "0,1")
7364 (set (attr "athlon_decode")
7365 (cond [(eq_attr "cpu" "athlon")
7366 (const_string "vector")
7367 (eq_attr "alternative" "0")
7368 (const_string "vector")
7369 (and (eq_attr "alternative" "1")
7370 (match_operand 1 "memory_operand"))
7371 (const_string "vector")]
7372 (const_string "direct")))
7373 (set (attr "amdfam10_decode")
7374 (cond [(and (eq_attr "alternative" "1")
7375 (match_operand 1 "memory_operand"))
7376 (const_string "vector")]
7377 (const_string "direct")))
7378 (set_attr "bdver1_decode" "direct")
7379 (set_attr "mode" "<MODE>")])
7381 (define_insn "*mulvhi4"
7382 [(set (reg:CCO FLAGS_REG)
7385 (match_operand:HI 1 "nonimmediate_operand" "%0"))
7387 (match_operand:HI 2 "nonimmediate_operand" "mr")))
7389 (mult:HI (match_dup 1) (match_dup 2)))))
7390 (set (match_operand:HI 0 "register_operand" "=r")
7391 (mult:HI (match_dup 1) (match_dup 2)))]
7392 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7393 "imul{w}\t{%2, %0|%0, %2}"
7394 [(set_attr "type" "imul")
7395 (set_attr "prefix_0f" "1")
7396 (set_attr "athlon_decode" "vector")
7397 (set_attr "amdfam10_decode" "direct")
7398 (set_attr "bdver1_decode" "double")
7399 (set_attr "mode" "HI")])
7401 (define_insn "*mulv<mode>4_1"
7402 [(set (reg:CCO FLAGS_REG)
7405 (match_operand:SWI248 1 "nonimmediate_operand" "rm,rm"))
7406 (match_operand:<DWI> 3 "const_int_operand" "K,i"))
7408 (mult:SWI248 (match_dup 1)
7409 (match_operand:SWI248 2
7410 "<immediate_operand>" "K,<i>")))))
7411 (set (match_operand:SWI248 0 "register_operand" "=r,r")
7412 (mult:SWI248 (match_dup 1) (match_dup 2)))]
7413 "!(MEM_P (operands[1]) && MEM_P (operands[2]))
7414 && CONST_INT_P (operands[2])
7415 && INTVAL (operands[2]) == INTVAL (operands[3])"
7416 "imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}"
7417 [(set_attr "type" "imul")
7418 (set (attr "prefix_0f")
7420 (match_test "<MODE>mode == HImode")
7422 (const_string "*")))
7423 (set (attr "athlon_decode")
7424 (cond [(eq_attr "cpu" "athlon")
7425 (const_string "vector")
7426 (eq_attr "alternative" "1")
7427 (const_string "vector")]
7428 (const_string "direct")))
7429 (set (attr "amdfam10_decode")
7430 (cond [(ior (match_test "<MODE>mode == HImode")
7431 (match_operand 1 "memory_operand"))
7432 (const_string "vector")]
7433 (const_string "direct")))
7434 (set (attr "bdver1_decode")
7436 (match_test "<MODE>mode == HImode")
7437 (const_string "double")
7438 (const_string "direct")))
7439 (set_attr "mode" "<MODE>")
7440 (set (attr "length_immediate")
7441 (cond [(eq_attr "alternative" "0")
7443 (match_test "<MODE_SIZE> == 8")
7445 (const_string "<MODE_SIZE>")))])
7447 (define_expand "umulv<mode>4"
7448 [(parallel [(set (reg:CCO FLAGS_REG)
7451 (match_operand:SWI248 1
7452 "nonimmediate_operand"))
7454 (match_operand:SWI248 2
7455 "nonimmediate_operand")))
7457 (mult:SWI248 (match_dup 1) (match_dup 2)))))
7458 (set (match_operand:SWI248 0 "register_operand")
7459 (mult:SWI248 (match_dup 1) (match_dup 2)))
7460 (clobber (match_scratch:SWI248 4))])
7461 (set (pc) (if_then_else
7462 (eq (reg:CCO FLAGS_REG) (const_int 0))
7463 (label_ref (match_operand 3))
7467 if (MEM_P (operands[1]) && MEM_P (operands[2]))
7468 operands[1] = force_reg (<MODE>mode, operands[1]);
7471 (define_insn "*umulv<mode>4"
7472 [(set (reg:CCO FLAGS_REG)
7475 (match_operand:SWI248 1 "nonimmediate_operand" "%0"))
7477 (match_operand:SWI248 2 "nonimmediate_operand" "rm")))
7479 (mult:SWI248 (match_dup 1) (match_dup 2)))))
7480 (set (match_operand:SWI248 0 "register_operand" "=a")
7481 (mult:SWI248 (match_dup 1) (match_dup 2)))
7482 (clobber (match_scratch:SWI248 3 "=d"))]
7483 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7484 "mul{<imodesuffix>}\t%2"
7485 [(set_attr "type" "imul")
7486 (set_attr "length_immediate" "0")
7487 (set (attr "athlon_decode")
7488 (if_then_else (eq_attr "cpu" "athlon")
7489 (const_string "vector")
7490 (const_string "double")))
7491 (set_attr "amdfam10_decode" "double")
7492 (set_attr "bdver1_decode" "direct")
7493 (set_attr "mode" "<MODE>")])
7495 (define_expand "<u>mulvqi4"
7496 [(parallel [(set (reg:CCO FLAGS_REG)
7499 (match_operand:QI 1 "nonimmediate_operand"))
7501 (match_operand:QI 2 "nonimmediate_operand")))
7503 (mult:QI (match_dup 1) (match_dup 2)))))
7504 (set (match_operand:QI 0 "register_operand")
7505 (mult:QI (match_dup 1) (match_dup 2)))])
7506 (set (pc) (if_then_else
7507 (eq (reg:CCO FLAGS_REG) (const_int 0))
7508 (label_ref (match_operand 3))
7510 "TARGET_QIMODE_MATH"
7512 if (MEM_P (operands[1]) && MEM_P (operands[2]))
7513 operands[1] = force_reg (QImode, operands[1]);
7516 (define_insn "*<u>mulvqi4"
7517 [(set (reg:CCO FLAGS_REG)
7520 (match_operand:QI 1 "nonimmediate_operand" "%0"))
7522 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7524 (mult:QI (match_dup 1) (match_dup 2)))))
7525 (set (match_operand:QI 0 "register_operand" "=a")
7526 (mult:QI (match_dup 1) (match_dup 2)))]
7528 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7529 "<sgnprefix>mul{b}\t%2"
7530 [(set_attr "type" "imul")
7531 (set_attr "length_immediate" "0")
7532 (set (attr "athlon_decode")
7533 (if_then_else (eq_attr "cpu" "athlon")
7534 (const_string "vector")
7535 (const_string "direct")))
7536 (set_attr "amdfam10_decode" "direct")
7537 (set_attr "bdver1_decode" "direct")
7538 (set_attr "mode" "QI")])
7540 (define_expand "<u>mul<mode><dwi>3"
7541 [(parallel [(set (match_operand:<DWI> 0 "register_operand")
7544 (match_operand:DWIH 1 "nonimmediate_operand"))
7546 (match_operand:DWIH 2 "register_operand"))))
7547 (clobber (reg:CC FLAGS_REG))])])
7549 (define_expand "<u>mulqihi3"
7550 [(parallel [(set (match_operand:HI 0 "register_operand")
7553 (match_operand:QI 1 "nonimmediate_operand"))
7555 (match_operand:QI 2 "register_operand"))))
7556 (clobber (reg:CC FLAGS_REG))])]
7557 "TARGET_QIMODE_MATH")
7559 (define_insn "*bmi2_umul<mode><dwi>3_1"
7560 [(set (match_operand:DWIH 0 "register_operand" "=r")
7562 (match_operand:DWIH 2 "nonimmediate_operand" "%d")
7563 (match_operand:DWIH 3 "nonimmediate_operand" "rm")))
7564 (set (match_operand:DWIH 1 "register_operand" "=r")
7567 (mult:<DWI> (zero_extend:<DWI> (match_dup 2))
7568 (zero_extend:<DWI> (match_dup 3)))
7569 (match_operand:QI 4 "const_int_operand" "n"))))]
7570 "TARGET_BMI2 && INTVAL (operands[4]) == <MODE_SIZE> * BITS_PER_UNIT
7571 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7572 "mulx\t{%3, %0, %1|%1, %0, %3}"
7573 [(set_attr "type" "imulx")
7574 (set_attr "prefix" "vex")
7575 (set_attr "mode" "<MODE>")])
7577 (define_insn "*umul<mode><dwi>3_1"
7578 [(set (match_operand:<DWI> 0 "register_operand" "=r,A")
7581 (match_operand:DWIH 1 "nonimmediate_operand" "%d,0"))
7583 (match_operand:DWIH 2 "nonimmediate_operand" "rm,rm"))))
7584 (clobber (reg:CC FLAGS_REG))]
7585 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7588 mul{<imodesuffix>}\t%2"
7589 [(set_attr "isa" "bmi2,*")
7590 (set_attr "type" "imulx,imul")
7591 (set_attr "length_immediate" "*,0")
7592 (set (attr "athlon_decode")
7593 (cond [(eq_attr "alternative" "1")
7594 (if_then_else (eq_attr "cpu" "athlon")
7595 (const_string "vector")
7596 (const_string "double"))]
7597 (const_string "*")))
7598 (set_attr "amdfam10_decode" "*,double")
7599 (set_attr "bdver1_decode" "*,direct")
7600 (set_attr "prefix" "vex,orig")
7601 (set_attr "mode" "<MODE>")])
7603 ;; Convert mul to the mulx pattern to avoid flags dependency.
7605 [(set (match_operand:<DWI> 0 "register_operand")
7608 (match_operand:DWIH 1 "register_operand"))
7610 (match_operand:DWIH 2 "nonimmediate_operand"))))
7611 (clobber (reg:CC FLAGS_REG))]
7612 "TARGET_BMI2 && reload_completed
7613 && REGNO (operands[1]) == DX_REG"
7614 [(parallel [(set (match_dup 3)
7615 (mult:DWIH (match_dup 1) (match_dup 2)))
7619 (mult:<DWI> (zero_extend:<DWI> (match_dup 1))
7620 (zero_extend:<DWI> (match_dup 2)))
7623 split_double_mode (<DWI>mode, &operands[0], 1, &operands[3], &operands[4]);
7625 operands[5] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT);
7628 (define_insn "*mul<mode><dwi>3_1"
7629 [(set (match_operand:<DWI> 0 "register_operand" "=A")
7632 (match_operand:DWIH 1 "nonimmediate_operand" "%0"))
7634 (match_operand:DWIH 2 "nonimmediate_operand" "rm"))))
7635 (clobber (reg:CC FLAGS_REG))]
7636 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7637 "imul{<imodesuffix>}\t%2"
7638 [(set_attr "type" "imul")
7639 (set_attr "length_immediate" "0")
7640 (set (attr "athlon_decode")
7641 (if_then_else (eq_attr "cpu" "athlon")
7642 (const_string "vector")
7643 (const_string "double")))
7644 (set_attr "amdfam10_decode" "double")
7645 (set_attr "bdver1_decode" "direct")
7646 (set_attr "mode" "<MODE>")])
7648 (define_insn "*<u>mulqihi3_1"
7649 [(set (match_operand:HI 0 "register_operand" "=a")
7652 (match_operand:QI 1 "nonimmediate_operand" "%0"))
7654 (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7655 (clobber (reg:CC FLAGS_REG))]
7657 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7658 "<sgnprefix>mul{b}\t%2"
7659 [(set_attr "type" "imul")
7660 (set_attr "length_immediate" "0")
7661 (set (attr "athlon_decode")
7662 (if_then_else (eq_attr "cpu" "athlon")
7663 (const_string "vector")
7664 (const_string "direct")))
7665 (set_attr "amdfam10_decode" "direct")
7666 (set_attr "bdver1_decode" "direct")
7667 (set_attr "mode" "QI")])
7669 (define_expand "<s>mul<mode>3_highpart"
7670 [(parallel [(set (match_operand:SWI48 0 "register_operand")
7675 (match_operand:SWI48 1 "nonimmediate_operand"))
7677 (match_operand:SWI48 2 "register_operand")))
7679 (clobber (match_scratch:SWI48 4))
7680 (clobber (reg:CC FLAGS_REG))])]
7682 "operands[3] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
7684 (define_insn "*<s>muldi3_highpart_1"
7685 [(set (match_operand:DI 0 "register_operand" "=d")
7690 (match_operand:DI 1 "nonimmediate_operand" "%a"))
7692 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7694 (clobber (match_scratch:DI 3 "=1"))
7695 (clobber (reg:CC FLAGS_REG))]
7697 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7698 "<sgnprefix>mul{q}\t%2"
7699 [(set_attr "type" "imul")
7700 (set_attr "length_immediate" "0")
7701 (set (attr "athlon_decode")
7702 (if_then_else (eq_attr "cpu" "athlon")
7703 (const_string "vector")
7704 (const_string "double")))
7705 (set_attr "amdfam10_decode" "double")
7706 (set_attr "bdver1_decode" "direct")
7707 (set_attr "mode" "DI")])
7709 (define_insn "*<s>mulsi3_highpart_zext"
7710 [(set (match_operand:DI 0 "register_operand" "=d")
7711 (zero_extend:DI (truncate:SI
7713 (mult:DI (any_extend:DI
7714 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7716 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7718 (clobber (match_scratch:SI 3 "=1"))
7719 (clobber (reg:CC FLAGS_REG))]
7721 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7722 "<sgnprefix>mul{l}\t%2"
7723 [(set_attr "type" "imul")
7724 (set_attr "length_immediate" "0")
7725 (set (attr "athlon_decode")
7726 (if_then_else (eq_attr "cpu" "athlon")
7727 (const_string "vector")
7728 (const_string "double")))
7729 (set_attr "amdfam10_decode" "double")
7730 (set_attr "bdver1_decode" "direct")
7731 (set_attr "mode" "SI")])
7733 (define_insn "*<s>mulsi3_highpart_1"
7734 [(set (match_operand:SI 0 "register_operand" "=d")
7739 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7741 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7743 (clobber (match_scratch:SI 3 "=1"))
7744 (clobber (reg:CC FLAGS_REG))]
7745 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7746 "<sgnprefix>mul{l}\t%2"
7747 [(set_attr "type" "imul")
7748 (set_attr "length_immediate" "0")
7749 (set (attr "athlon_decode")
7750 (if_then_else (eq_attr "cpu" "athlon")
7751 (const_string "vector")
7752 (const_string "double")))
7753 (set_attr "amdfam10_decode" "double")
7754 (set_attr "bdver1_decode" "direct")
7755 (set_attr "mode" "SI")])
7757 ;; The patterns that match these are at the end of this file.
7759 (define_expand "mulxf3"
7760 [(set (match_operand:XF 0 "register_operand")
7761 (mult:XF (match_operand:XF 1 "register_operand")
7762 (match_operand:XF 2 "register_operand")))]
7765 (define_expand "mul<mode>3"
7766 [(set (match_operand:MODEF 0 "register_operand")
7767 (mult:MODEF (match_operand:MODEF 1 "register_operand")
7768 (match_operand:MODEF 2 "nonimmediate_operand")))]
7769 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
7770 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
7772 ;; Divide instructions
7774 ;; The patterns that match these are at the end of this file.
7776 (define_expand "divxf3"
7777 [(set (match_operand:XF 0 "register_operand")
7778 (div:XF (match_operand:XF 1 "register_operand")
7779 (match_operand:XF 2 "register_operand")))]
7782 (define_expand "div<mode>3"
7783 [(set (match_operand:MODEF 0 "register_operand")
7784 (div:MODEF (match_operand:MODEF 1 "register_operand")
7785 (match_operand:MODEF 2 "nonimmediate_operand")))]
7786 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
7787 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
7789 if (<MODE>mode == SFmode
7790 && TARGET_SSE && TARGET_SSE_MATH
7792 && optimize_insn_for_speed_p ()
7793 && flag_finite_math_only && !flag_trapping_math
7794 && flag_unsafe_math_optimizations)
7796 ix86_emit_swdivsf (operands[0], operands[1],
7797 operands[2], SFmode);
7802 ;; Divmod instructions.
7804 (define_expand "divmod<mode>4"
7805 [(parallel [(set (match_operand:SWIM248 0 "register_operand")
7807 (match_operand:SWIM248 1 "register_operand")
7808 (match_operand:SWIM248 2 "nonimmediate_operand")))
7809 (set (match_operand:SWIM248 3 "register_operand")
7810 (mod:SWIM248 (match_dup 1) (match_dup 2)))
7811 (clobber (reg:CC FLAGS_REG))])])
7813 ;; Split with 8bit unsigned divide:
7814 ;; if (dividend an divisor are in [0-255])
7815 ;; use 8bit unsigned integer divide
7817 ;; use original integer divide
7819 [(set (match_operand:SWI48 0 "register_operand")
7820 (div:SWI48 (match_operand:SWI48 2 "register_operand")
7821 (match_operand:SWI48 3 "nonimmediate_operand")))
7822 (set (match_operand:SWI48 1 "register_operand")
7823 (mod:SWI48 (match_dup 2) (match_dup 3)))
7824 (clobber (reg:CC FLAGS_REG))]
7825 "TARGET_USE_8BIT_IDIV
7826 && TARGET_QIMODE_MATH
7827 && can_create_pseudo_p ()
7828 && !optimize_insn_for_size_p ()"
7830 "ix86_split_idivmod (<MODE>mode, operands, true); DONE;")
7833 [(set (match_operand:DI 0 "register_operand")
7835 (div:SI (match_operand:SI 2 "register_operand")
7836 (match_operand:SI 3 "nonimmediate_operand"))))
7837 (set (match_operand:SI 1 "register_operand")
7838 (mod:SI (match_dup 2) (match_dup 3)))
7839 (clobber (reg:CC FLAGS_REG))]
7840 "TARGET_USE_8BIT_IDIV
7841 && TARGET_QIMODE_MATH
7842 && can_create_pseudo_p ()
7843 && !optimize_insn_for_size_p ()"
7845 "ix86_split_idivmod (SImode, operands, true); DONE;")
7848 [(set (match_operand:DI 1 "register_operand")
7850 (mod:SI (match_operand:SI 2 "register_operand")
7851 (match_operand:SI 3 "nonimmediate_operand"))))
7852 (set (match_operand:SI 0 "register_operand")
7853 (div:SI (match_dup 2) (match_dup 3)))
7854 (clobber (reg:CC FLAGS_REG))]
7855 "TARGET_USE_8BIT_IDIV
7856 && TARGET_QIMODE_MATH
7857 && can_create_pseudo_p ()
7858 && !optimize_insn_for_size_p ()"
7860 "ix86_split_idivmod (SImode, operands, true); DONE;")
7862 (define_insn_and_split "divmod<mode>4_1"
7863 [(set (match_operand:SWI48 0 "register_operand" "=a")
7864 (div:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7865 (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
7866 (set (match_operand:SWI48 1 "register_operand" "=&d")
7867 (mod:SWI48 (match_dup 2) (match_dup 3)))
7868 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7869 (clobber (reg:CC FLAGS_REG))]
7873 [(parallel [(set (match_dup 1)
7874 (ashiftrt:SWI48 (match_dup 4) (match_dup 5)))
7875 (clobber (reg:CC FLAGS_REG))])
7876 (parallel [(set (match_dup 0)
7877 (div:SWI48 (match_dup 2) (match_dup 3)))
7879 (mod:SWI48 (match_dup 2) (match_dup 3)))
7881 (clobber (reg:CC FLAGS_REG))])]
7883 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7885 if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
7886 operands[4] = operands[2];
7889 /* Avoid use of cltd in favor of a mov+shift. */
7890 emit_move_insn (operands[1], operands[2]);
7891 operands[4] = operands[1];
7894 [(set_attr "type" "multi")
7895 (set_attr "mode" "<MODE>")])
7897 (define_insn_and_split "divmodsi4_zext_1"
7898 [(set (match_operand:DI 0 "register_operand" "=a")
7900 (div:SI (match_operand:SI 2 "register_operand" "0")
7901 (match_operand:SI 3 "nonimmediate_operand" "rm"))))
7902 (set (match_operand:SI 1 "register_operand" "=&d")
7903 (mod:SI (match_dup 2) (match_dup 3)))
7904 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7905 (clobber (reg:CC FLAGS_REG))]
7909 [(parallel [(set (match_dup 1)
7910 (ashiftrt:SI (match_dup 4) (match_dup 5)))
7911 (clobber (reg:CC FLAGS_REG))])
7912 (parallel [(set (match_dup 0)
7913 (zero_extend:DI (div:SI (match_dup 2) (match_dup 3))))
7915 (mod:SI (match_dup 2) (match_dup 3)))
7917 (clobber (reg:CC FLAGS_REG))])]
7919 operands[5] = GEN_INT (GET_MODE_BITSIZE (SImode)-1);
7921 if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
7922 operands[4] = operands[2];
7925 /* Avoid use of cltd in favor of a mov+shift. */
7926 emit_move_insn (operands[1], operands[2]);
7927 operands[4] = operands[1];
7930 [(set_attr "type" "multi")
7931 (set_attr "mode" "SI")])
7933 (define_insn_and_split "divmodsi4_zext_2"
7934 [(set (match_operand:DI 1 "register_operand" "=&d")
7936 (mod:SI (match_operand:SI 2 "register_operand" "0")
7937 (match_operand:SI 3 "nonimmediate_operand" "rm"))))
7938 (set (match_operand:SI 0 "register_operand" "=a")
7939 (div:SI (match_dup 2) (match_dup 3)))
7940 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7941 (clobber (reg:CC FLAGS_REG))]
7945 [(parallel [(set (match_dup 6)
7946 (ashiftrt:SI (match_dup 4) (match_dup 5)))
7947 (clobber (reg:CC FLAGS_REG))])
7948 (parallel [(set (match_dup 1)
7949 (zero_extend:DI (mod:SI (match_dup 2) (match_dup 3))))
7951 (div:SI (match_dup 2) (match_dup 3)))
7953 (clobber (reg:CC FLAGS_REG))])]
7955 operands[5] = GEN_INT (GET_MODE_BITSIZE (SImode)-1);
7956 operands[6] = gen_lowpart (SImode, operands[1]);
7958 if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
7959 operands[4] = operands[2];
7962 /* Avoid use of cltd in favor of a mov+shift. */
7963 emit_move_insn (operands[6], operands[2]);
7964 operands[4] = operands[6];
7967 [(set_attr "type" "multi")
7968 (set_attr "mode" "SI")])
7970 (define_insn_and_split "*divmod<mode>4"
7971 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7972 (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7973 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7974 (set (match_operand:SWIM248 1 "register_operand" "=&d")
7975 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7976 (clobber (reg:CC FLAGS_REG))]
7980 [(parallel [(set (match_dup 1)
7981 (ashiftrt:SWIM248 (match_dup 4) (match_dup 5)))
7982 (clobber (reg:CC FLAGS_REG))])
7983 (parallel [(set (match_dup 0)
7984 (div:SWIM248 (match_dup 2) (match_dup 3)))
7986 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7988 (clobber (reg:CC FLAGS_REG))])]
7990 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7992 if (<MODE>mode != HImode
7993 && (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD))
7994 operands[4] = operands[2];
7997 /* Avoid use of cltd in favor of a mov+shift. */
7998 emit_move_insn (operands[1], operands[2]);
7999 operands[4] = operands[1];
8002 [(set_attr "type" "multi")
8003 (set_attr "mode" "<MODE>")])
8005 (define_insn_and_split "*divmodsi4_zext_1"
8006 [(set (match_operand:DI 0 "register_operand" "=a")
8008 (div:SI (match_operand:SI 2 "register_operand" "0")
8009 (match_operand:SI 3 "nonimmediate_operand" "rm"))))
8010 (set (match_operand:SI 1 "register_operand" "=&d")
8011 (mod:SI (match_dup 2) (match_dup 3)))
8012 (clobber (reg:CC FLAGS_REG))]
8016 [(parallel [(set (match_dup 1)
8017 (ashiftrt:SI (match_dup 4) (match_dup 5)))
8018 (clobber (reg:CC FLAGS_REG))])
8019 (parallel [(set (match_dup 0)
8020 (zero_extend:DI (div:SI (match_dup 2) (match_dup 3))))
8022 (mod:SI (match_dup 2) (match_dup 3)))
8024 (clobber (reg:CC FLAGS_REG))])]
8026 operands[5] = GEN_INT (GET_MODE_BITSIZE (SImode)-1);
8028 if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
8029 operands[4] = operands[2];
8032 /* Avoid use of cltd in favor of a mov+shift. */
8033 emit_move_insn (operands[1], operands[2]);
8034 operands[4] = operands[1];
8037 [(set_attr "type" "multi")
8038 (set_attr "mode" "SI")])
8040 (define_insn_and_split "*divmodsi4_zext_2"
8041 [(set (match_operand:DI 1 "register_operand" "=&d")
8043 (mod:SI (match_operand:SI 2 "register_operand" "0")
8044 (match_operand:SI 3 "nonimmediate_operand" "rm"))))
8045 (set (match_operand:SI 0 "register_operand" "=a")
8046 (div:SI (match_dup 2) (match_dup 3)))
8047 (clobber (reg:CC FLAGS_REG))]
8051 [(parallel [(set (match_dup 6)
8052 (ashiftrt:SI (match_dup 4) (match_dup 5)))
8053 (clobber (reg:CC FLAGS_REG))])
8054 (parallel [(set (match_dup 1)
8055 (zero_extend:DI (mod:SI (match_dup 2) (match_dup 3))))
8057 (div:SI (match_dup 2) (match_dup 3)))
8059 (clobber (reg:CC FLAGS_REG))])]
8061 operands[5] = GEN_INT (GET_MODE_BITSIZE (SImode)-1);
8062 operands[6] = gen_lowpart (SImode, operands[1]);
8064 if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
8065 operands[4] = operands[2];
8068 /* Avoid use of cltd in favor of a mov+shift. */
8069 emit_move_insn (operands[6], operands[2]);
8070 operands[4] = operands[6];
8073 [(set_attr "type" "multi")
8074 (set_attr "mode" "SI")])
8076 (define_insn "*divmod<mode>4_noext"
8077 [(set (match_operand:SWIM248 0 "register_operand" "=a")
8078 (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
8079 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
8080 (set (match_operand:SWIM248 1 "register_operand" "=d")
8081 (mod:SWIM248 (match_dup 2) (match_dup 3)))
8082 (use (match_operand:SWIM248 4 "register_operand" "1"))
8083 (clobber (reg:CC FLAGS_REG))]
8085 "idiv{<imodesuffix>}\t%3"
8086 [(set_attr "type" "idiv")
8087 (set_attr "mode" "<MODE>")])
8089 (define_insn "*divmodsi4_noext_zext_1"
8090 [(set (match_operand:DI 0 "register_operand" "=a")
8092 (div:SI (match_operand:SI 2 "register_operand" "0")
8093 (match_operand:SI 3 "nonimmediate_operand" "rm"))))
8094 (set (match_operand:SI 1 "register_operand" "=d")
8095 (mod:SI (match_dup 2) (match_dup 3)))
8096 (use (match_operand:SI 4 "register_operand" "1"))
8097 (clobber (reg:CC FLAGS_REG))]
8100 [(set_attr "type" "idiv")
8101 (set_attr "mode" "SI")])
8103 (define_insn "*divmodsi4_noext_zext_2"
8104 [(set (match_operand:DI 1 "register_operand" "=d")
8106 (mod:SI (match_operand:SI 2 "register_operand" "0")
8107 (match_operand:SI 3 "nonimmediate_operand" "rm"))))
8108 (set (match_operand:SI 0 "register_operand" "=a")
8109 (div:SI (match_dup 2) (match_dup 3)))
8110 (use (match_operand:SI 4 "register_operand" "1"))
8111 (clobber (reg:CC FLAGS_REG))]
8114 [(set_attr "type" "idiv")
8115 (set_attr "mode" "SI")])
8117 (define_expand "divmodqi4"
8118 [(parallel [(set (match_operand:QI 0 "register_operand")
8120 (match_operand:QI 1 "register_operand")
8121 (match_operand:QI 2 "nonimmediate_operand")))
8122 (set (match_operand:QI 3 "register_operand")
8123 (mod:QI (match_dup 1) (match_dup 2)))
8124 (clobber (reg:CC FLAGS_REG))])]
8125 "TARGET_QIMODE_MATH"
8130 tmp0 = gen_reg_rtx (HImode);
8131 tmp1 = gen_reg_rtx (HImode);
8133 /* Extend operands[1] to HImode. Generate 8bit divide. Result is in AX. */
8134 emit_insn (gen_extendqihi2 (tmp1, operands[1]));
8135 emit_insn (gen_divmodhiqi3 (tmp0, tmp1, operands[2]));
8137 /* Extract remainder from AH. */
8138 tmp1 = gen_rtx_ZERO_EXTRACT (SImode, tmp0, GEN_INT (8), GEN_INT (8));
8139 tmp1 = lowpart_subreg (QImode, tmp1, SImode);
8140 rtx_insn *insn = emit_move_insn (operands[3], tmp1);
8142 mod = gen_rtx_MOD (QImode, operands[1], operands[2]);
8143 set_unique_reg_note (insn, REG_EQUAL, mod);
8145 /* Extract quotient from AL. */
8146 insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
8148 div = gen_rtx_DIV (QImode, operands[1], operands[2]);
8149 set_unique_reg_note (insn, REG_EQUAL, div);
8154 ;; Divide AX by r/m8, with result stored in
8157 ;; Change div/mod to HImode and extend the second argument to HImode
8158 ;; so that mode of div/mod matches with mode of arguments. Otherwise
8159 ;; combine may fail.
8160 (define_insn "divmodhiqi3"
8161 [(set (match_operand:HI 0 "register_operand" "=a")
8166 (mod:HI (match_operand:HI 1 "register_operand" "0")
8168 (match_operand:QI 2 "nonimmediate_operand" "qm")))))
8172 (div:HI (match_dup 1) (sign_extend:HI (match_dup 2)))))))
8173 (clobber (reg:CC FLAGS_REG))]
8174 "TARGET_QIMODE_MATH"
8176 [(set_attr "type" "idiv")
8177 (set_attr "mode" "QI")])
8179 (define_expand "udivmod<mode>4"
8180 [(parallel [(set (match_operand:SWIM248 0 "register_operand")
8182 (match_operand:SWIM248 1 "register_operand")
8183 (match_operand:SWIM248 2 "nonimmediate_operand")))
8184 (set (match_operand:SWIM248 3 "register_operand")
8185 (umod:SWIM248 (match_dup 1) (match_dup 2)))
8186 (clobber (reg:CC FLAGS_REG))])])
8188 ;; Split with 8bit unsigned divide:
8189 ;; if (dividend an divisor are in [0-255])
8190 ;; use 8bit unsigned integer divide
8192 ;; use original integer divide
8194 [(set (match_operand:SWI48 0 "register_operand")
8195 (udiv:SWI48 (match_operand:SWI48 2 "register_operand")
8196 (match_operand:SWI48 3 "nonimmediate_operand")))
8197 (set (match_operand:SWI48 1 "register_operand")
8198 (umod:SWI48 (match_dup 2) (match_dup 3)))
8199 (clobber (reg:CC FLAGS_REG))]
8200 "TARGET_USE_8BIT_IDIV
8201 && TARGET_QIMODE_MATH
8202 && can_create_pseudo_p ()
8203 && !optimize_insn_for_size_p ()"
8205 "ix86_split_idivmod (<MODE>mode, operands, false); DONE;")
8208 [(set (match_operand:DI 0 "register_operand")
8210 (udiv:SI (match_operand:SI 2 "register_operand")
8211 (match_operand:SI 3 "nonimmediate_operand"))))
8212 (set (match_operand:SI 1 "register_operand")
8213 (umod:SI (match_dup 2) (match_dup 3)))
8214 (clobber (reg:CC FLAGS_REG))]
8216 && TARGET_USE_8BIT_IDIV
8217 && TARGET_QIMODE_MATH
8218 && can_create_pseudo_p ()
8219 && !optimize_insn_for_size_p ()"
8221 "ix86_split_idivmod (SImode, operands, false); DONE;")
8224 [(set (match_operand:DI 1 "register_operand")
8226 (umod:SI (match_operand:SI 2 "register_operand")
8227 (match_operand:SI 3 "nonimmediate_operand"))))
8228 (set (match_operand:SI 0 "register_operand")
8229 (udiv:SI (match_dup 2) (match_dup 3)))
8230 (clobber (reg:CC FLAGS_REG))]
8232 && TARGET_USE_8BIT_IDIV
8233 && TARGET_QIMODE_MATH
8234 && can_create_pseudo_p ()
8235 && !optimize_insn_for_size_p ()"
8237 "ix86_split_idivmod (SImode, operands, false); DONE;")
8239 (define_insn_and_split "udivmod<mode>4_1"
8240 [(set (match_operand:SWI48 0 "register_operand" "=a")
8241 (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "0")
8242 (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
8243 (set (match_operand:SWI48 1 "register_operand" "=&d")
8244 (umod:SWI48 (match_dup 2) (match_dup 3)))
8245 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
8246 (clobber (reg:CC FLAGS_REG))]
8250 [(set (match_dup 1) (const_int 0))
8251 (parallel [(set (match_dup 0)
8252 (udiv:SWI48 (match_dup 2) (match_dup 3)))
8254 (umod:SWI48 (match_dup 2) (match_dup 3)))
8256 (clobber (reg:CC FLAGS_REG))])]
8258 [(set_attr "type" "multi")
8259 (set_attr "mode" "<MODE>")])
8261 (define_insn_and_split "udivmodsi4_zext_1"
8262 [(set (match_operand:DI 0 "register_operand" "=a")
8264 (udiv:SI (match_operand:SI 2 "register_operand" "0")
8265 (match_operand:SI 3 "nonimmediate_operand" "rm"))))
8266 (set (match_operand:SI 1 "register_operand" "=&d")
8267 (umod:SI (match_dup 2) (match_dup 3)))
8268 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
8269 (clobber (reg:CC FLAGS_REG))]
8273 [(set (match_dup 1) (const_int 0))
8274 (parallel [(set (match_dup 0)
8275 (zero_extend:DI (udiv:SI (match_dup 2) (match_dup 3))))
8277 (umod:SI (match_dup 2) (match_dup 3)))
8279 (clobber (reg:CC FLAGS_REG))])]
8281 [(set_attr "type" "multi")
8282 (set_attr "mode" "SI")])
8284 (define_insn_and_split "udivmodsi4_zext_2"
8285 [(set (match_operand:DI 1 "register_operand" "=&d")
8287 (umod:SI (match_operand:SI 2 "register_operand" "0")
8288 (match_operand:SI 3 "nonimmediate_operand" "rm"))))
8289 (set (match_operand:SI 0 "register_operand" "=a")
8290 (udiv:SI (match_dup 2) (match_dup 3)))
8291 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
8292 (clobber (reg:CC FLAGS_REG))]
8296 [(set (match_dup 4) (const_int 0))
8297 (parallel [(set (match_dup 1)
8298 (zero_extend:DI (umod:SI (match_dup 2) (match_dup 3))))
8300 (udiv:SI (match_dup 2) (match_dup 3)))
8302 (clobber (reg:CC FLAGS_REG))])]
8303 "operands[4] = gen_lowpart (SImode, operands[1]);"
8304 [(set_attr "type" "multi")
8305 (set_attr "mode" "SI")])
8307 (define_insn_and_split "*udivmod<mode>4"
8308 [(set (match_operand:SWIM248 0 "register_operand" "=a")
8309 (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
8310 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
8311 (set (match_operand:SWIM248 1 "register_operand" "=&d")
8312 (umod:SWIM248 (match_dup 2) (match_dup 3)))
8313 (clobber (reg:CC FLAGS_REG))]
8317 [(set (match_dup 1) (const_int 0))
8318 (parallel [(set (match_dup 0)
8319 (udiv:SWIM248 (match_dup 2) (match_dup 3)))
8321 (umod:SWIM248 (match_dup 2) (match_dup 3)))
8323 (clobber (reg:CC FLAGS_REG))])]
8325 [(set_attr "type" "multi")
8326 (set_attr "mode" "<MODE>")])
8328 (define_insn_and_split "*udivmodsi4_zext_1"
8329 [(set (match_operand:DI 0 "register_operand" "=a")
8331 (udiv:SI (match_operand:SI 2 "register_operand" "0")
8332 (match_operand:SI 3 "nonimmediate_operand" "rm"))))
8333 (set (match_operand:SI 1 "register_operand" "=&d")
8334 (umod:SI (match_dup 2) (match_dup 3)))
8335 (clobber (reg:CC FLAGS_REG))]
8339 [(set (match_dup 1) (const_int 0))
8340 (parallel [(set (match_dup 0)
8341 (zero_extend:DI (udiv:SI (match_dup 2) (match_dup 3))))
8343 (umod:SI (match_dup 2) (match_dup 3)))
8345 (clobber (reg:CC FLAGS_REG))])]
8347 [(set_attr "type" "multi")
8348 (set_attr "mode" "SI")])
8350 (define_insn_and_split "*udivmodsi4_zext_2"
8351 [(set (match_operand:DI 1 "register_operand" "=&d")
8353 (umod:SI (match_operand:SI 2 "register_operand" "0")
8354 (match_operand:SI 3 "nonimmediate_operand" "rm"))))
8355 (set (match_operand:SI 0 "register_operand" "=a")
8356 (udiv:SI (match_dup 2) (match_dup 3)))
8357 (clobber (reg:CC FLAGS_REG))]
8361 [(set (match_dup 4) (const_int 0))
8362 (parallel [(set (match_dup 1)
8363 (zero_extend:DI (umod:SI (match_dup 2) (match_dup 3))))
8365 (udiv:SI (match_dup 2) (match_dup 3)))
8367 (clobber (reg:CC FLAGS_REG))])]
8368 "operands[4] = gen_lowpart (SImode, operands[1]);"
8369 [(set_attr "type" "multi")
8370 (set_attr "mode" "SI")])
8372 ;; Optimize division or modulo by constant power of 2, if the constant
8373 ;; materializes only after expansion.
8374 (define_insn_and_split "*udivmod<mode>4_pow2"
8375 [(set (match_operand:SWI48 0 "register_operand" "=r")
8376 (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "0")
8377 (match_operand:SWI48 3 "const_int_operand" "n")))
8378 (set (match_operand:SWI48 1 "register_operand" "=r")
8379 (umod:SWI48 (match_dup 2) (match_dup 3)))
8380 (clobber (reg:CC FLAGS_REG))]
8381 "IN_RANGE (INTVAL (operands[3]), 2, HOST_WIDE_INT_UC (0x80000000))
8382 && (UINTVAL (operands[3]) & (UINTVAL (operands[3]) - 1)) == 0"
8385 [(set (match_dup 1) (match_dup 2))
8386 (parallel [(set (match_dup 0) (lshiftrt:<MODE> (match_dup 2) (match_dup 4)))
8387 (clobber (reg:CC FLAGS_REG))])
8388 (parallel [(set (match_dup 1) (and:<MODE> (match_dup 1) (match_dup 5)))
8389 (clobber (reg:CC FLAGS_REG))])]
8391 int v = exact_log2 (UINTVAL (operands[3]));
8392 operands[4] = GEN_INT (v);
8393 operands[5] = GEN_INT ((HOST_WIDE_INT_1U << v) - 1);
8395 [(set_attr "type" "multi")
8396 (set_attr "mode" "<MODE>")])
8398 (define_insn_and_split "*udivmodsi4_pow2_zext_1"
8399 [(set (match_operand:DI 0 "register_operand" "=r")
8401 (udiv:SI (match_operand:SI 2 "register_operand" "0")
8402 (match_operand:SI 3 "const_int_operand" "n"))))
8403 (set (match_operand:SI 1 "register_operand" "=r")
8404 (umod:SI (match_dup 2) (match_dup 3)))
8405 (clobber (reg:CC FLAGS_REG))]
8407 && IN_RANGE (INTVAL (operands[3]), 2, HOST_WIDE_INT_UC (0x80000000))
8408 && (UINTVAL (operands[3]) & (UINTVAL (operands[3]) - 1)) == 0"
8411 [(set (match_dup 1) (match_dup 2))
8412 (parallel [(set (match_dup 0)
8413 (zero_extend:DI (lshiftrt:SI (match_dup 2) (match_dup 4))))
8414 (clobber (reg:CC FLAGS_REG))])
8415 (parallel [(set (match_dup 1) (and:SI (match_dup 1) (match_dup 5)))
8416 (clobber (reg:CC FLAGS_REG))])]
8418 int v = exact_log2 (UINTVAL (operands[3]));
8419 operands[4] = GEN_INT (v);
8420 operands[5] = GEN_INT ((HOST_WIDE_INT_1U << v) - 1);
8422 [(set_attr "type" "multi")
8423 (set_attr "mode" "SI")])
8425 (define_insn_and_split "*udivmodsi4_pow2_zext_2"
8426 [(set (match_operand:DI 1 "register_operand" "=r")
8428 (umod:SI (match_operand:SI 2 "register_operand" "0")
8429 (match_operand:SI 3 "const_int_operand" "n"))))
8430 (set (match_operand:SI 0 "register_operand" "=r")
8431 (umod:SI (match_dup 2) (match_dup 3)))
8432 (clobber (reg:CC FLAGS_REG))]
8434 && IN_RANGE (INTVAL (operands[3]), 2, HOST_WIDE_INT_UC (0x80000000))
8435 && (UINTVAL (operands[3]) & (UINTVAL (operands[3]) - 1)) == 0"
8438 [(set (match_dup 1) (match_dup 2))
8439 (parallel [(set (match_dup 0) (lshiftrt:SI (match_dup 2) (match_dup 4)))
8440 (clobber (reg:CC FLAGS_REG))])
8441 (parallel [(set (match_dup 1)
8442 (zero_extend:DI (and:SI (match_dup 1) (match_dup 5))))
8443 (clobber (reg:CC FLAGS_REG))])]
8445 int v = exact_log2 (UINTVAL (operands[3]));
8446 operands[4] = GEN_INT (v);
8447 operands[5] = GEN_INT ((HOST_WIDE_INT_1U << v) - 1);
8449 [(set_attr "type" "multi")
8450 (set_attr "mode" "SI")])
8452 (define_insn "*udivmod<mode>4_noext"
8453 [(set (match_operand:SWIM248 0 "register_operand" "=a")
8454 (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
8455 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
8456 (set (match_operand:SWIM248 1 "register_operand" "=d")
8457 (umod:SWIM248 (match_dup 2) (match_dup 3)))
8458 (use (match_operand:SWIM248 4 "register_operand" "1"))
8459 (clobber (reg:CC FLAGS_REG))]
8461 "div{<imodesuffix>}\t%3"
8462 [(set_attr "type" "idiv")
8463 (set_attr "mode" "<MODE>")])
8465 (define_insn "*udivmodsi4_noext_zext_1"
8466 [(set (match_operand:DI 0 "register_operand" "=a")
8468 (udiv:SI (match_operand:SI 2 "register_operand" "0")
8469 (match_operand:SI 3 "nonimmediate_operand" "rm"))))
8470 (set (match_operand:SI 1 "register_operand" "=d")
8471 (umod:SI (match_dup 2) (match_dup 3)))
8472 (use (match_operand:SI 4 "register_operand" "1"))
8473 (clobber (reg:CC FLAGS_REG))]
8476 [(set_attr "type" "idiv")
8477 (set_attr "mode" "SI")])
8479 (define_insn "*udivmodsi4_noext_zext_2"
8480 [(set (match_operand:DI 1 "register_operand" "=d")
8482 (umod:SI (match_operand:SI 2 "register_operand" "0")
8483 (match_operand:SI 3 "nonimmediate_operand" "rm"))))
8484 (set (match_operand:SI 0 "register_operand" "=a")
8485 (udiv:SI (match_dup 2) (match_dup 3)))
8486 (use (match_operand:SI 4 "register_operand" "1"))
8487 (clobber (reg:CC FLAGS_REG))]
8490 [(set_attr "type" "idiv")
8491 (set_attr "mode" "SI")])
8493 (define_expand "udivmodqi4"
8494 [(parallel [(set (match_operand:QI 0 "register_operand")
8496 (match_operand:QI 1 "register_operand")
8497 (match_operand:QI 2 "nonimmediate_operand")))
8498 (set (match_operand:QI 3 "register_operand")
8499 (umod:QI (match_dup 1) (match_dup 2)))
8500 (clobber (reg:CC FLAGS_REG))])]
8501 "TARGET_QIMODE_MATH"
8506 tmp0 = gen_reg_rtx (HImode);
8507 tmp1 = gen_reg_rtx (HImode);
8509 /* Extend operands[1] to HImode. Generate 8bit divide. Result is in AX. */
8510 emit_insn (gen_zero_extendqihi2 (tmp1, operands[1]));
8511 emit_insn (gen_udivmodhiqi3 (tmp0, tmp1, operands[2]));
8513 /* Extract remainder from AH. */
8514 tmp1 = gen_rtx_ZERO_EXTRACT (SImode, tmp0, GEN_INT (8), GEN_INT (8));
8515 tmp1 = lowpart_subreg (QImode, tmp1, SImode);
8516 rtx_insn *insn = emit_move_insn (operands[3], tmp1);
8518 mod = gen_rtx_UMOD (QImode, operands[1], operands[2]);
8519 set_unique_reg_note (insn, REG_EQUAL, mod);
8521 /* Extract quotient from AL. */
8522 insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
8524 div = gen_rtx_UDIV (QImode, operands[1], operands[2]);
8525 set_unique_reg_note (insn, REG_EQUAL, div);
8530 (define_insn "udivmodhiqi3"
8531 [(set (match_operand:HI 0 "register_operand" "=a")
8536 (mod:HI (match_operand:HI 1 "register_operand" "0")
8538 (match_operand:QI 2 "nonimmediate_operand" "qm")))))
8542 (div:HI (match_dup 1) (zero_extend:HI (match_dup 2)))))))
8543 (clobber (reg:CC FLAGS_REG))]
8544 "TARGET_QIMODE_MATH"
8546 [(set_attr "type" "idiv")
8547 (set_attr "mode" "QI")])
8549 ;; We cannot use div/idiv for double division, because it causes
8550 ;; "division by zero" on the overflow and that's not what we expect
8551 ;; from truncate. Because true (non truncating) double division is
8552 ;; never generated, we can't create this insn anyway.
8555 ; [(set (match_operand:SI 0 "register_operand" "=a")
8557 ; (udiv:DI (match_operand:DI 1 "register_operand" "A")
8559 ; (match_operand:SI 2 "nonimmediate_operand" "rm")))))
8560 ; (set (match_operand:SI 3 "register_operand" "=d")
8562 ; (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
8563 ; (clobber (reg:CC FLAGS_REG))]
8565 ; "div{l}\t{%2, %0|%0, %2}"
8566 ; [(set_attr "type" "idiv")])
8568 ;;- Logical AND instructions
8570 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
8571 ;; Note that this excludes ah.
8573 (define_expand "testsi_ccno_1"
8574 [(set (reg:CCNO FLAGS_REG)
8576 (and:SI (match_operand:SI 0 "nonimmediate_operand")
8577 (match_operand:SI 1 "x86_64_nonmemory_operand"))
8580 (define_expand "testqi_ccz_1"
8581 [(set (reg:CCZ FLAGS_REG)
8582 (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand")
8583 (match_operand:QI 1 "nonmemory_operand"))
8586 (define_expand "testdi_ccno_1"
8587 [(set (reg:CCNO FLAGS_REG)
8589 (and:DI (match_operand:DI 0 "nonimmediate_operand")
8590 (match_operand:DI 1 "x86_64_szext_general_operand"))
8592 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))")
8594 (define_insn "*testdi_1"
8595 [(set (reg FLAGS_REG)
8598 (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
8599 (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
8601 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8602 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8604 test{l}\t{%k1, %k0|%k0, %k1}
8605 test{l}\t{%k1, %k0|%k0, %k1}
8606 test{q}\t{%1, %0|%0, %1}
8607 test{q}\t{%1, %0|%0, %1}
8608 test{q}\t{%1, %0|%0, %1}"
8609 [(set_attr "type" "test")
8610 (set_attr "modrm" "0,1,0,1,1")
8611 (set_attr "mode" "SI,SI,DI,DI,DI")])
8613 (define_insn "*testqi_1_maybe_si"
8614 [(set (reg FLAGS_REG)
8617 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
8618 (match_operand:QI 1 "general_operand" "n,n,qn,n"))
8620 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
8621 && ix86_match_ccmode (insn,
8622 CONST_INT_P (operands[1])
8623 && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
8625 if (which_alternative == 3)
8627 if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
8628 operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
8629 return "test{l}\t{%1, %k0|%k0, %1}";
8631 return "test{b}\t{%1, %0|%0, %1}";
8633 [(set_attr "type" "test")
8634 (set_attr "modrm" "0,1,1,1")
8635 (set_attr "mode" "QI,QI,QI,SI")
8636 (set_attr "pent_pair" "uv,np,uv,np")])
8638 (define_insn "*test<mode>_1"
8639 [(set (reg FLAGS_REG)
8642 (match_operand:SWI124 0 "nonimmediate_operand" "%!*a,<r>,<r>m")
8643 (match_operand:SWI124 1 "<general_operand>" "<i>,<i>,<r><i>"))
8645 "ix86_match_ccmode (insn, CCNOmode)
8646 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8647 "test{<imodesuffix>}\t{%1, %0|%0, %1}"
8648 [(set_attr "type" "test")
8649 (set_attr "modrm" "0,1,1")
8650 (set_attr "mode" "<MODE>")
8651 (set_attr "pent_pair" "uv,np,uv")])
8653 (define_expand "testqi_ext_1_ccno"
8654 [(set (reg:CCNO FLAGS_REG)
8658 (zero_extract:SI (match_operand 0 "ext_register_operand")
8661 (match_operand 1 "const_int_operand"))
8664 (define_insn "*testqi_ext_1"
8665 [(set (reg FLAGS_REG)
8669 (zero_extract:SI (match_operand 0 "ext_register_operand" "Q,Q")
8672 (match_operand:QI 1 "general_operand" "QnBc,m"))
8674 "ix86_match_ccmode (insn, CCNOmode)"
8675 "test{b}\t{%1, %h0|%h0, %1}"
8676 [(set_attr "isa" "*,nox64")
8677 (set_attr "type" "test")
8678 (set_attr "mode" "QI")])
8680 (define_insn "*testqi_ext_2"
8681 [(set (reg FLAGS_REG)
8685 (zero_extract:SI (match_operand 0 "ext_register_operand" "Q")
8689 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q")
8693 "ix86_match_ccmode (insn, CCNOmode)"
8694 "test{b}\t{%h1, %h0|%h0, %h1}"
8695 [(set_attr "type" "test")
8696 (set_attr "mode" "QI")])
8698 ;; Combine likes to form bit extractions for some tests. Humor it.
8699 (define_insn_and_split "*testqi_ext_3"
8700 [(set (match_operand 0 "flags_reg_operand")
8701 (match_operator 1 "compare_operator"
8702 [(zero_extract:SWI248
8703 (match_operand 2 "nonimmediate_operand" "rm")
8704 (match_operand 3 "const_int_operand" "n")
8705 (match_operand 4 "const_int_operand" "n"))
8707 "ix86_match_ccmode (insn, CCNOmode)
8708 && ((TARGET_64BIT && GET_MODE (operands[2]) == DImode)
8709 || GET_MODE (operands[2]) == SImode
8710 || GET_MODE (operands[2]) == HImode
8711 || GET_MODE (operands[2]) == QImode)
8712 /* Ensure that resulting mask is zero or sign extended operand. */
8713 && INTVAL (operands[4]) >= 0
8714 && ((INTVAL (operands[3]) > 0
8715 && INTVAL (operands[3]) + INTVAL (operands[4]) <= 32)
8716 || (<MODE>mode == DImode
8717 && INTVAL (operands[3]) > 32
8718 && INTVAL (operands[3]) + INTVAL (operands[4]) == 64))"
8721 [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
8723 rtx val = operands[2];
8724 HOST_WIDE_INT len = INTVAL (operands[3]);
8725 HOST_WIDE_INT pos = INTVAL (operands[4]);
8726 machine_mode mode = GET_MODE (val);
8730 machine_mode submode = GET_MODE (SUBREG_REG (val));
8732 /* Narrow paradoxical subregs to prevent partial register stalls. */
8733 if (GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode)
8734 && GET_MODE_CLASS (submode) == MODE_INT)
8736 val = SUBREG_REG (val);
8741 /* Small HImode tests can be converted to QImode. */
8742 if (register_operand (val, HImode) && pos + len <= 8)
8744 val = gen_lowpart (QImode, val);
8748 gcc_assert (pos + len <= GET_MODE_PRECISION (mode));
8751 = wi::shifted_mask (pos, len, false, GET_MODE_PRECISION (mode));
8753 operands[2] = gen_rtx_AND (mode, val, immed_wide_int_const (mask, mode));
8756 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
8757 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
8758 ;; this is relatively important trick.
8759 ;; Do the conversion only post-reload to avoid limiting of the register class
8762 [(set (match_operand 0 "flags_reg_operand")
8763 (match_operator 1 "compare_operator"
8764 [(and (match_operand 2 "QIreg_operand")
8765 (match_operand 3 "const_int_operand"))
8768 && GET_MODE (operands[2]) != QImode
8769 && ((ix86_match_ccmode (insn, CCZmode)
8770 && !(INTVAL (operands[3]) & ~(255 << 8)))
8771 || (ix86_match_ccmode (insn, CCNOmode)
8772 && !(INTVAL (operands[3]) & ~(127 << 8))))"
8777 (zero_extract:SI (match_dup 2)
8783 operands[2] = gen_lowpart (SImode, operands[2]);
8784 operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, QImode);
8788 [(set (match_operand 0 "flags_reg_operand")
8789 (match_operator 1 "compare_operator"
8790 [(and (match_operand 2 "nonimmediate_operand")
8791 (match_operand 3 "const_int_operand"))
8794 && GET_MODE (operands[2]) != QImode
8795 && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
8796 && ((ix86_match_ccmode (insn, CCZmode)
8797 && !(INTVAL (operands[3]) & ~255))
8798 || (ix86_match_ccmode (insn, CCNOmode)
8799 && !(INTVAL (operands[3]) & ~127)))"
8801 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
8804 operands[2] = gen_lowpart (QImode, operands[2]);
8805 operands[3] = gen_int_mode (INTVAL (operands[3]), QImode);
8808 ;; %%% This used to optimize known byte-wide and operations to memory,
8809 ;; and sometimes to QImode registers. If this is considered useful,
8810 ;; it should be done with splitters.
8812 (define_expand "and<mode>3"
8813 [(set (match_operand:SWIM1248x 0 "nonimmediate_operand")
8814 (and:SWIM1248x (match_operand:SWIM1248x 1 "nonimmediate_operand")
8815 (match_operand:SWIM1248x 2 "<general_szext_operand>")))]
8818 machine_mode mode = <MODE>mode;
8819 rtx (*insn) (rtx, rtx);
8821 if (CONST_INT_P (operands[2]) && REG_P (operands[0]))
8823 HOST_WIDE_INT ival = INTVAL (operands[2]);
8825 if (ival == (HOST_WIDE_INT) 0xffffffff)
8827 else if (ival == 0xffff)
8829 else if (ival == 0xff)
8833 if (mode == <MODE>mode)
8835 ix86_expand_binary_operator (AND, <MODE>mode, operands);
8839 if (<MODE>mode == DImode)
8840 insn = (mode == SImode)
8841 ? gen_zero_extendsidi2
8843 ? gen_zero_extendhidi2
8844 : gen_zero_extendqidi2;
8845 else if (<MODE>mode == SImode)
8846 insn = (mode == HImode)
8847 ? gen_zero_extendhisi2
8848 : gen_zero_extendqisi2;
8849 else if (<MODE>mode == HImode)
8850 insn = gen_zero_extendqihi2;
8854 emit_insn (insn (operands[0], gen_lowpart (mode, operands[1])));
8858 (define_insn_and_split "*anddi3_doubleword"
8859 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r")
8861 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8862 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm")))
8863 (clobber (reg:CC FLAGS_REG))]
8864 "!TARGET_64BIT && TARGET_STV && TARGET_SSE2
8865 && ix86_binary_operator_ok (AND, DImode, operands)"
8867 "&& reload_completed"
8870 split_double_mode (DImode, &operands[0], 3, &operands[0], &operands[3]);
8871 if (operands[2] == const0_rtx)
8873 operands[1] = const0_rtx;
8874 ix86_expand_move (SImode, &operands[0]);
8876 else if (operands[2] != constm1_rtx)
8877 ix86_expand_binary_operator (AND, SImode, &operands[0]);
8878 else if (operands[5] == constm1_rtx)
8879 emit_note (NOTE_INSN_DELETED);
8880 if (operands[5] == const0_rtx)
8882 operands[4] = const0_rtx;
8883 ix86_expand_move (SImode, &operands[3]);
8885 else if (operands[5] != constm1_rtx)
8886 ix86_expand_binary_operator (AND, SImode, &operands[3]);
8890 (define_insn "*anddi_1"
8891 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
8893 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
8894 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
8895 (clobber (reg:CC FLAGS_REG))]
8896 "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
8898 and{l}\t{%k2, %k0|%k0, %k2}
8899 and{q}\t{%2, %0|%0, %2}
8900 and{q}\t{%2, %0|%0, %2}
8902 [(set_attr "type" "alu,alu,alu,imovx")
8903 (set_attr "length_immediate" "*,*,*,0")
8904 (set (attr "prefix_rex")
8906 (and (eq_attr "type" "imovx")
8907 (and (match_test "INTVAL (operands[2]) == 0xff")
8908 (match_operand 1 "ext_QIreg_operand")))
8910 (const_string "*")))
8911 (set_attr "mode" "SI,DI,DI,SI")])
8913 (define_insn_and_split "*anddi_1_btr"
8914 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
8916 (match_operand:DI 1 "nonimmediate_operand" "%0")
8917 (match_operand:DI 2 "const_int_operand" "n")))
8918 (clobber (reg:CC FLAGS_REG))]
8919 "TARGET_64BIT && TARGET_USE_BT
8920 && ix86_binary_operator_ok (AND, DImode, operands)
8921 && IN_RANGE (exact_log2 (~INTVAL (operands[2])), 31, 63)"
8923 "&& reload_completed"
8924 [(parallel [(set (zero_extract:DI (match_dup 0)
8928 (clobber (reg:CC FLAGS_REG))])]
8929 "operands[3] = GEN_INT (exact_log2 (~INTVAL (operands[2])));"
8930 [(set_attr "type" "alu1")
8931 (set_attr "prefix_0f" "1")
8932 (set_attr "znver1_decode" "double")
8933 (set_attr "mode" "DI")])
8935 ;; Turn *anddi_1 into *andsi_1_zext if possible.
8937 [(set (match_operand:DI 0 "register_operand")
8938 (and:DI (subreg:DI (match_operand:SI 1 "register_operand") 0)
8939 (match_operand:DI 2 "x86_64_zext_immediate_operand")))
8940 (clobber (reg:CC FLAGS_REG))]
8942 [(parallel [(set (match_dup 0)
8943 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))
8944 (clobber (reg:CC FLAGS_REG))])]
8945 "operands[2] = gen_lowpart (SImode, operands[2]);")
8947 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8948 (define_insn "*andsi_1_zext"
8949 [(set (match_operand:DI 0 "register_operand" "=r")
8951 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8952 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
8953 (clobber (reg:CC FLAGS_REG))]
8954 "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
8955 "and{l}\t{%2, %k0|%k0, %2}"
8956 [(set_attr "type" "alu")
8957 (set_attr "mode" "SI")])
8959 (define_insn "*and<mode>_1"
8960 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=rm,r,Ya")
8961 (and:SWI24 (match_operand:SWI24 1 "nonimmediate_operand" "%0,0,qm")
8962 (match_operand:SWI24 2 "<general_operand>" "r<i>,rm,L")))
8963 (clobber (reg:CC FLAGS_REG))]
8964 "ix86_binary_operator_ok (AND, <MODE>mode, operands)"
8966 and{<imodesuffix>}\t{%2, %0|%0, %2}
8967 and{<imodesuffix>}\t{%2, %0|%0, %2}
8969 [(set_attr "type" "alu,alu,imovx")
8970 (set_attr "length_immediate" "*,*,0")
8971 (set (attr "prefix_rex")
8973 (and (eq_attr "type" "imovx")
8974 (and (match_test "INTVAL (operands[2]) == 0xff")
8975 (match_operand 1 "ext_QIreg_operand")))
8977 (const_string "*")))
8978 (set_attr "mode" "<MODE>,<MODE>,SI")])
8980 (define_insn "*andqi_1"
8981 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
8982 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8983 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
8984 (clobber (reg:CC FLAGS_REG))]
8985 "ix86_binary_operator_ok (AND, QImode, operands)"
8987 and{b}\t{%2, %0|%0, %2}
8988 and{b}\t{%2, %0|%0, %2}
8989 and{l}\t{%k2, %k0|%k0, %k2}"
8990 [(set_attr "type" "alu")
8991 (set_attr "mode" "QI,QI,SI")
8992 ;; Potential partial reg stall on alternative 2.
8993 (set (attr "preferred_for_speed")
8994 (cond [(eq_attr "alternative" "2")
8995 (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
8996 (symbol_ref "true")))])
8998 (define_insn "*andqi_1_slp"
8999 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
9000 (and:QI (match_dup 0)
9001 (match_operand:QI 1 "general_operand" "qn,qmn")))
9002 (clobber (reg:CC FLAGS_REG))]
9003 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9004 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9005 "and{b}\t{%1, %0|%0, %1}"
9006 [(set_attr "type" "alu1")
9007 (set_attr "mode" "QI")])
9010 [(set (match_operand:SWI248 0 "register_operand")
9011 (and:SWI248 (match_operand:SWI248 1 "nonimmediate_operand")
9012 (match_operand:SWI248 2 "const_int_operand")))
9013 (clobber (reg:CC FLAGS_REG))]
9015 && (!REG_P (operands[1])
9016 || REGNO (operands[0]) != REGNO (operands[1]))"
9019 HOST_WIDE_INT ival = INTVAL (operands[2]);
9021 rtx (*insn) (rtx, rtx);
9023 if (ival == (HOST_WIDE_INT) 0xffffffff)
9025 else if (ival == 0xffff)
9029 gcc_assert (ival == 0xff);
9033 if (<MODE>mode == DImode)
9034 insn = (mode == SImode)
9035 ? gen_zero_extendsidi2
9037 ? gen_zero_extendhidi2
9038 : gen_zero_extendqidi2;
9041 if (<MODE>mode != SImode)
9042 /* Zero extend to SImode to avoid partial register stalls. */
9043 operands[0] = gen_lowpart (SImode, operands[0]);
9045 insn = (mode == HImode)
9046 ? gen_zero_extendhisi2
9047 : gen_zero_extendqisi2;
9049 emit_insn (insn (operands[0], gen_lowpart (mode, operands[1])));
9054 [(set (match_operand:SWI48 0 "register_operand")
9055 (and:SWI48 (match_dup 0)
9056 (const_int -65536)))
9057 (clobber (reg:CC FLAGS_REG))]
9058 "(TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)
9059 || optimize_function_for_size_p (cfun)"
9060 [(set (strict_low_part (match_dup 1)) (const_int 0))]
9061 "operands[1] = gen_lowpart (HImode, operands[0]);")
9064 [(set (match_operand:SWI248 0 "any_QIreg_operand")
9065 (and:SWI248 (match_dup 0)
9067 (clobber (reg:CC FLAGS_REG))]
9068 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9069 && reload_completed"
9070 [(set (strict_low_part (match_dup 1)) (const_int 0))]
9071 "operands[1] = gen_lowpart (QImode, operands[0]);")
9074 [(set (match_operand:SWI248 0 "QIreg_operand")
9075 (and:SWI248 (match_dup 0)
9076 (const_int -65281)))
9077 (clobber (reg:CC FLAGS_REG))]
9078 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9079 && reload_completed"
9081 [(set (zero_extract:SI (match_dup 0)
9087 (zero_extract:SI (match_dup 0)
9091 (zero_extract:SI (match_dup 0)
9093 (const_int 8)) 0)) 0))
9094 (clobber (reg:CC FLAGS_REG))])]
9095 "operands[0] = gen_lowpart (SImode, operands[0]);")
9097 (define_insn "*anddi_2"
9098 [(set (reg FLAGS_REG)
9101 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
9102 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
9104 (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
9105 (and:DI (match_dup 1) (match_dup 2)))]
9107 && ix86_match_ccmode
9109 /* If we are going to emit andl instead of andq, and the operands[2]
9110 constant might have the SImode sign bit set, make sure the sign
9111 flag isn't tested, because the instruction will set the sign flag
9112 based on bit 31 rather than bit 63. If it isn't CONST_INT,
9113 conservatively assume it might have bit 31 set. */
9114 (satisfies_constraint_Z (operands[2])
9115 && (!CONST_INT_P (operands[2])
9116 || val_signbit_known_set_p (SImode, INTVAL (operands[2]))))
9117 ? CCZmode : CCNOmode)
9118 && ix86_binary_operator_ok (AND, DImode, operands)"
9120 and{l}\t{%k2, %k0|%k0, %k2}
9121 and{q}\t{%2, %0|%0, %2}
9122 and{q}\t{%2, %0|%0, %2}"
9123 [(set_attr "type" "alu")
9124 (set_attr "mode" "SI,DI,DI")])
9126 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9127 (define_insn "*andsi_2_zext"
9128 [(set (reg FLAGS_REG)
9130 (match_operand:SI 1 "nonimmediate_operand" "%0")
9131 (match_operand:SI 2 "x86_64_general_operand" "rme"))
9133 (set (match_operand:DI 0 "register_operand" "=r")
9134 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
9135 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9136 && ix86_binary_operator_ok (AND, SImode, operands)"
9137 "and{l}\t{%2, %k0|%k0, %2}"
9138 [(set_attr "type" "alu")
9139 (set_attr "mode" "SI")])
9141 (define_insn "*andqi_2_maybe_si"
9142 [(set (reg FLAGS_REG)
9144 (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9145 (match_operand:QI 2 "general_operand" "qmn,qn,n"))
9147 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
9148 (and:QI (match_dup 1) (match_dup 2)))]
9149 "ix86_binary_operator_ok (AND, QImode, operands)
9150 && ix86_match_ccmode (insn,
9151 CONST_INT_P (operands[2])
9152 && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
9154 if (which_alternative == 2)
9156 if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
9157 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
9158 return "and{l}\t{%2, %k0|%k0, %2}";
9160 return "and{b}\t{%2, %0|%0, %2}";
9162 [(set_attr "type" "alu")
9163 (set_attr "mode" "QI,QI,SI")])
9165 (define_insn "*and<mode>_2"
9166 [(set (reg FLAGS_REG)
9167 (compare (and:SWI124
9168 (match_operand:SWI124 1 "nonimmediate_operand" "%0,0")
9169 (match_operand:SWI124 2 "<general_operand>" "<g>,<r><i>"))
9171 (set (match_operand:SWI124 0 "nonimmediate_operand" "=<r>,<r>m")
9172 (and:SWI124 (match_dup 1) (match_dup 2)))]
9173 "ix86_match_ccmode (insn, CCNOmode)
9174 && ix86_binary_operator_ok (AND, <MODE>mode, operands)"
9175 "and{<imodesuffix>}\t{%2, %0|%0, %2}"
9176 [(set_attr "type" "alu")
9177 (set_attr "mode" "<MODE>")])
9179 (define_insn "*andqi_2_slp"
9180 [(set (reg FLAGS_REG)
9182 (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9183 (match_operand:QI 1 "nonimmediate_operand" "qmn,qn"))
9185 (set (strict_low_part (match_dup 0))
9186 (and:QI (match_dup 0) (match_dup 1)))]
9187 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9188 && ix86_match_ccmode (insn, CCNOmode)
9189 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9190 "and{b}\t{%1, %0|%0, %1}"
9191 [(set_attr "type" "alu1")
9192 (set_attr "mode" "QI")])
9194 (define_insn "andqi_ext_1"
9195 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q,Q")
9201 (zero_extract:SI (match_operand 1 "ext_register_operand" "0,0")
9204 (match_operand:QI 2 "general_operand" "QnBc,m")) 0))
9205 (clobber (reg:CC FLAGS_REG))]
9206 "/* FIXME: without this LRA can't reload this pattern, see PR82524. */
9207 rtx_equal_p (operands[0], operands[1])"
9208 "and{b}\t{%2, %h0|%h0, %2}"
9209 [(set_attr "isa" "*,nox64")
9210 (set_attr "type" "alu")
9211 (set_attr "mode" "QI")])
9213 ;; Generated by peephole translating test to and. This shows up
9214 ;; often in fp comparisons.
9215 (define_insn "*andqi_ext_1_cc"
9216 [(set (reg FLAGS_REG)
9220 (zero_extract:SI (match_operand 1 "ext_register_operand" "0,0")
9223 (match_operand:QI 2 "general_operand" "QnBc,m"))
9225 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q,Q")
9231 (zero_extract:SI (match_dup 1)
9235 "ix86_match_ccmode (insn, CCNOmode)
9236 /* FIXME: without this LRA can't reload this pattern, see PR82524. */
9237 && rtx_equal_p (operands[0], operands[1])"
9238 "and{b}\t{%2, %h0|%h0, %2}"
9239 [(set_attr "isa" "*,nox64")
9240 (set_attr "type" "alu")
9241 (set_attr "mode" "QI")])
9243 (define_insn "*andqi_ext_2"
9244 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
9250 (zero_extract:SI (match_operand 1 "ext_register_operand" "%0")
9254 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9256 (const_int 8)) 0)) 0))
9257 (clobber (reg:CC FLAGS_REG))]
9258 "/* FIXME: without this LRA can't reload this pattern, see PR82524. */
9259 rtx_equal_p (operands[0], operands[1])
9260 || rtx_equal_p (operands[0], operands[2])"
9261 "and{b}\t{%h2, %h0|%h0, %h2}"
9262 [(set_attr "type" "alu")
9263 (set_attr "mode" "QI")])
9265 ;; Convert wide AND instructions with immediate operand to shorter QImode
9266 ;; equivalents when possible.
9267 ;; Don't do the splitting with memory operands, since it introduces risk
9268 ;; of memory mismatch stalls. We may want to do the splitting for optimizing
9269 ;; for size, but that can (should?) be handled by generic code instead.
9271 [(set (match_operand:SWI248 0 "QIreg_operand")
9272 (and:SWI248 (match_operand:SWI248 1 "register_operand")
9273 (match_operand:SWI248 2 "const_int_operand")))
9274 (clobber (reg:CC FLAGS_REG))]
9276 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9277 && !(~INTVAL (operands[2]) & ~(255 << 8))"
9279 [(set (zero_extract:SI (match_dup 0)
9285 (zero_extract:SI (match_dup 1)
9289 (clobber (reg:CC FLAGS_REG))])]
9291 operands[0] = gen_lowpart (SImode, operands[0]);
9292 operands[1] = gen_lowpart (SImode, operands[1]);
9293 operands[2] = gen_int_mode (INTVAL (operands[2]) >> 8, QImode);
9296 ;; Since AND can be encoded with sign extended immediate, this is only
9297 ;; profitable when 7th bit is not set.
9299 [(set (match_operand:SWI248 0 "any_QIreg_operand")
9300 (and:SWI248 (match_operand:SWI248 1 "general_operand")
9301 (match_operand:SWI248 2 "const_int_operand")))
9302 (clobber (reg:CC FLAGS_REG))]
9304 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9305 && !(~INTVAL (operands[2]) & ~255)
9306 && !(INTVAL (operands[2]) & 128)"
9307 [(parallel [(set (strict_low_part (match_dup 0))
9308 (and:QI (match_dup 1)
9310 (clobber (reg:CC FLAGS_REG))])]
9312 operands[0] = gen_lowpart (QImode, operands[0]);
9313 operands[1] = gen_lowpart (QImode, operands[1]);
9314 operands[2] = gen_int_mode (INTVAL (operands[2]), QImode);
9317 (define_insn "*andndi3_doubleword"
9318 [(set (match_operand:DI 0 "register_operand" "=&r,r,r,&r")
9320 (not:DI (match_operand:DI 1 "register_operand" "r,0,r,0"))
9321 (match_operand:DI 2 "nonimmediate_operand" "rm,rm,0,rm")))
9322 (clobber (reg:CC FLAGS_REG))]
9323 "!TARGET_64BIT && TARGET_STV && TARGET_SSE2"
9325 [(set_attr "isa" "bmi,bmi,bmi,*")])
9328 [(set (match_operand:DI 0 "register_operand")
9330 (not:DI (match_operand:DI 1 "register_operand"))
9331 (match_operand:DI 2 "nonimmediate_operand")))
9332 (clobber (reg:CC FLAGS_REG))]
9333 "!TARGET_64BIT && TARGET_BMI && TARGET_STV && TARGET_SSE2
9334 && reload_completed"
9335 [(parallel [(set (match_dup 0)
9336 (and:SI (not:SI (match_dup 1)) (match_dup 2)))
9337 (clobber (reg:CC FLAGS_REG))])
9338 (parallel [(set (match_dup 3)
9339 (and:SI (not:SI (match_dup 4)) (match_dup 5)))
9340 (clobber (reg:CC FLAGS_REG))])]
9341 "split_double_mode (DImode, &operands[0], 3, &operands[0], &operands[3]);")
9344 [(set (match_operand:DI 0 "register_operand")
9346 (not:DI (match_dup 0))
9347 (match_operand:DI 1 "nonimmediate_operand")))
9348 (clobber (reg:CC FLAGS_REG))]
9349 "!TARGET_64BIT && !TARGET_BMI && TARGET_STV && TARGET_SSE2
9350 && reload_completed"
9351 [(set (match_dup 0) (not:SI (match_dup 0)))
9352 (parallel [(set (match_dup 0)
9353 (and:SI (match_dup 0) (match_dup 1)))
9354 (clobber (reg:CC FLAGS_REG))])
9355 (set (match_dup 2) (not:SI (match_dup 2)))
9356 (parallel [(set (match_dup 2)
9357 (and:SI (match_dup 2) (match_dup 3)))
9358 (clobber (reg:CC FLAGS_REG))])]
9359 "split_double_mode (DImode, &operands[0], 2, &operands[0], &operands[2]);")
9361 (define_insn "*andn<mode>_1"
9362 [(set (match_operand:SWI48 0 "register_operand" "=r,r")
9364 (not:SWI48 (match_operand:SWI48 1 "register_operand" "r,r"))
9365 (match_operand:SWI48 2 "nonimmediate_operand" "r,m")))
9366 (clobber (reg:CC FLAGS_REG))]
9368 "andn\t{%2, %1, %0|%0, %1, %2}"
9369 [(set_attr "type" "bitmanip")
9370 (set_attr "btver2_decode" "direct, double")
9371 (set_attr "mode" "<MODE>")])
9373 (define_insn "*andn<mode>_1"
9374 [(set (match_operand:SWI12 0 "register_operand" "=r")
9376 (not:SWI12 (match_operand:SWI12 1 "register_operand" "r"))
9377 (match_operand:SWI12 2 "register_operand" "r")))
9378 (clobber (reg:CC FLAGS_REG))]
9380 "andn\t{%k2, %k1, %k0|%k0, %k1, %k2}"
9381 [(set_attr "type" "bitmanip")
9382 (set_attr "btver2_decode" "direct")
9383 (set_attr "mode" "SI")])
9385 (define_insn "*andn_<mode>_ccno"
9386 [(set (reg FLAGS_REG)
9389 (not:SWI48 (match_operand:SWI48 1 "register_operand" "r,r"))
9390 (match_operand:SWI48 2 "nonimmediate_operand" "r,m"))
9392 (clobber (match_scratch:SWI48 0 "=r,r"))]
9393 "TARGET_BMI && ix86_match_ccmode (insn, CCNOmode)"
9394 "andn\t{%2, %1, %0|%0, %1, %2}"
9395 [(set_attr "type" "bitmanip")
9396 (set_attr "btver2_decode" "direct, double")
9397 (set_attr "mode" "<MODE>")])
9399 ;; Logical inclusive and exclusive OR instructions
9401 ;; %%% This used to optimize known byte-wide and operations to memory.
9402 ;; If this is considered useful, it should be done with splitters.
9404 (define_expand "<code><mode>3"
9405 [(set (match_operand:SWIM1248x 0 "nonimmediate_operand")
9406 (any_or:SWIM1248x (match_operand:SWIM1248x 1 "nonimmediate_operand")
9407 (match_operand:SWIM1248x 2 "<general_operand>")))]
9409 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
9411 (define_insn_and_split "*<code>di3_doubleword"
9412 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r")
9414 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
9415 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm")))
9416 (clobber (reg:CC FLAGS_REG))]
9417 "!TARGET_64BIT && TARGET_STV && TARGET_SSE2
9418 && ix86_binary_operator_ok (<CODE>, DImode, operands)"
9420 "&& reload_completed"
9423 split_double_mode (DImode, &operands[0], 3, &operands[0], &operands[3]);
9424 if (operands[2] == constm1_rtx)
9428 operands[1] = constm1_rtx;
9429 ix86_expand_move (SImode, &operands[0]);
9432 ix86_expand_unary_operator (NOT, SImode, &operands[0]);
9434 else if (operands[2] != const0_rtx)
9435 ix86_expand_binary_operator (<CODE>, SImode, &operands[0]);
9436 else if (operands[5] == const0_rtx)
9437 emit_note (NOTE_INSN_DELETED);
9438 if (operands[5] == constm1_rtx)
9442 operands[4] = constm1_rtx;
9443 ix86_expand_move (SImode, &operands[3]);
9446 ix86_expand_unary_operator (NOT, SImode, &operands[3]);
9448 else if (operands[5] != const0_rtx)
9449 ix86_expand_binary_operator (<CODE>, SImode, &operands[3]);
9453 (define_insn "*<code><mode>_1"
9454 [(set (match_operand:SWI248 0 "nonimmediate_operand" "=r,rm")
9456 (match_operand:SWI248 1 "nonimmediate_operand" "%0,0")
9457 (match_operand:SWI248 2 "<general_operand>" "<g>,r<i>")))
9458 (clobber (reg:CC FLAGS_REG))]
9459 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9460 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
9461 [(set_attr "type" "alu")
9462 (set_attr "mode" "<MODE>")])
9464 (define_insn_and_split "*iordi_1_bts"
9465 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9467 (match_operand:DI 1 "nonimmediate_operand" "%0")
9468 (match_operand:DI 2 "const_int_operand" "n")))
9469 (clobber (reg:CC FLAGS_REG))]
9470 "TARGET_64BIT && TARGET_USE_BT
9471 && ix86_binary_operator_ok (IOR, DImode, operands)
9472 && IN_RANGE (exact_log2 (INTVAL (operands[2])), 31, 63)"
9474 "&& reload_completed"
9475 [(parallel [(set (zero_extract:DI (match_dup 0)
9479 (clobber (reg:CC FLAGS_REG))])]
9480 "operands[3] = GEN_INT (exact_log2 (INTVAL (operands[2])));"
9481 [(set_attr "type" "alu1")
9482 (set_attr "prefix_0f" "1")
9483 (set_attr "znver1_decode" "double")
9484 (set_attr "mode" "DI")])
9486 (define_insn_and_split "*xordi_1_btc"
9487 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9489 (match_operand:DI 1 "nonimmediate_operand" "%0")
9490 (match_operand:DI 2 "const_int_operand" "n")))
9491 (clobber (reg:CC FLAGS_REG))]
9492 "TARGET_64BIT && TARGET_USE_BT
9493 && ix86_binary_operator_ok (XOR, DImode, operands)
9494 && IN_RANGE (exact_log2 (INTVAL (operands[2])), 31, 63)"
9496 "&& reload_completed"
9497 [(parallel [(set (zero_extract:DI (match_dup 0)
9500 (not:DI (zero_extract:DI (match_dup 0)
9503 (clobber (reg:CC FLAGS_REG))])]
9504 "operands[3] = GEN_INT (exact_log2 (INTVAL (operands[2])));"
9505 [(set_attr "type" "alu1")
9506 (set_attr "prefix_0f" "1")
9507 (set_attr "znver1_decode" "double")
9508 (set_attr "mode" "DI")])
9510 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9511 (define_insn "*<code>si_1_zext"
9512 [(set (match_operand:DI 0 "register_operand" "=r")
9514 (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9515 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
9516 (clobber (reg:CC FLAGS_REG))]
9517 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
9518 "<logic>{l}\t{%2, %k0|%k0, %2}"
9519 [(set_attr "type" "alu")
9520 (set_attr "mode" "SI")])
9522 (define_insn "*<code>si_1_zext_imm"
9523 [(set (match_operand:DI 0 "register_operand" "=r")
9525 (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
9526 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
9527 (clobber (reg:CC FLAGS_REG))]
9528 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
9529 "<logic>{l}\t{%2, %k0|%k0, %2}"
9530 [(set_attr "type" "alu")
9531 (set_attr "mode" "SI")])
9533 (define_insn "*<code>qi_1"
9534 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
9535 (any_or:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9536 (match_operand:QI 2 "general_operand" "qmn,qn,rn")))
9537 (clobber (reg:CC FLAGS_REG))]
9538 "ix86_binary_operator_ok (<CODE>, QImode, operands)"
9540 <logic>{b}\t{%2, %0|%0, %2}
9541 <logic>{b}\t{%2, %0|%0, %2}
9542 <logic>{l}\t{%k2, %k0|%k0, %k2}"
9543 [(set_attr "type" "alu")
9544 (set_attr "mode" "QI,QI,SI")
9545 ;; Potential partial reg stall on alternative 2.
9546 (set (attr "preferred_for_speed")
9547 (cond [(eq_attr "alternative" "2")
9548 (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
9549 (symbol_ref "true")))])
9551 (define_insn "*<code>qi_1_slp"
9552 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
9553 (any_or:QI (match_dup 0)
9554 (match_operand:QI 1 "general_operand" "qmn,qn")))
9555 (clobber (reg:CC FLAGS_REG))]
9556 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9557 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9558 "<logic>{b}\t{%1, %0|%0, %1}"
9559 [(set_attr "type" "alu1")
9560 (set_attr "mode" "QI")])
9562 (define_insn "*<code><mode>_2"
9563 [(set (reg FLAGS_REG)
9564 (compare (any_or:SWI
9565 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
9566 (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>"))
9568 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
9569 (any_or:SWI (match_dup 1) (match_dup 2)))]
9570 "ix86_match_ccmode (insn, CCNOmode)
9571 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9572 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
9573 [(set_attr "type" "alu")
9574 (set_attr "mode" "<MODE>")])
9576 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9577 ;; ??? Special case for immediate operand is missing - it is tricky.
9578 (define_insn "*<code>si_2_zext"
9579 [(set (reg FLAGS_REG)
9580 (compare (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9581 (match_operand:SI 2 "x86_64_general_operand" "rme"))
9583 (set (match_operand:DI 0 "register_operand" "=r")
9584 (zero_extend:DI (any_or:SI (match_dup 1) (match_dup 2))))]
9585 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9586 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
9587 "<logic>{l}\t{%2, %k0|%k0, %2}"
9588 [(set_attr "type" "alu")
9589 (set_attr "mode" "SI")])
9591 (define_insn "*<code>si_2_zext_imm"
9592 [(set (reg FLAGS_REG)
9594 (match_operand:SI 1 "nonimmediate_operand" "%0")
9595 (match_operand:SI 2 "x86_64_zext_immediate_operand" "Z"))
9597 (set (match_operand:DI 0 "register_operand" "=r")
9598 (any_or:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
9599 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9600 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
9601 "<logic>{l}\t{%2, %k0|%k0, %2}"
9602 [(set_attr "type" "alu")
9603 (set_attr "mode" "SI")])
9605 (define_insn "*<code>qi_2_slp"
9606 [(set (reg FLAGS_REG)
9607 (compare (any_or:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9608 (match_operand:QI 1 "general_operand" "qmn,qn"))
9610 (set (strict_low_part (match_dup 0))
9611 (any_or:QI (match_dup 0) (match_dup 1)))]
9612 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9613 && ix86_match_ccmode (insn, CCNOmode)
9614 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9615 "<logic>{b}\t{%1, %0|%0, %1}"
9616 [(set_attr "type" "alu1")
9617 (set_attr "mode" "QI")])
9619 (define_insn "*<code><mode>_3"
9620 [(set (reg FLAGS_REG)
9621 (compare (any_or:SWI
9622 (match_operand:SWI 1 "nonimmediate_operand" "%0")
9623 (match_operand:SWI 2 "<general_operand>" "<g>"))
9625 (clobber (match_scratch:SWI 0 "=<r>"))]
9626 "ix86_match_ccmode (insn, CCNOmode)
9627 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9628 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
9629 [(set_attr "type" "alu")
9630 (set_attr "mode" "<MODE>")])
9632 (define_insn "*<code>qi_ext_1"
9633 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q,Q")
9639 (zero_extract:SI (match_operand 1 "ext_register_operand" "0,0")
9642 (match_operand:QI 2 "general_operand" "QnBc,m")) 0))
9643 (clobber (reg:CC FLAGS_REG))]
9644 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9645 /* FIXME: without this LRA can't reload this pattern, see PR82524. */
9646 && rtx_equal_p (operands[0], operands[1])"
9647 "<logic>{b}\t{%2, %h0|%h0, %2}"
9648 [(set_attr "isa" "*,nox64")
9649 (set_attr "type" "alu")
9650 (set_attr "mode" "QI")])
9652 (define_insn "*<code>qi_ext_2"
9653 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
9659 (zero_extract:SI (match_operand 1 "ext_register_operand" "%0")
9663 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9665 (const_int 8)) 0)) 0))
9666 (clobber (reg:CC FLAGS_REG))]
9667 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9668 /* FIXME: without this LRA can't reload this pattern, see PR82524. */
9669 && (rtx_equal_p (operands[0], operands[1])
9670 || rtx_equal_p (operands[0], operands[2]))"
9671 "<logic>{b}\t{%h2, %h0|%h0, %h2}"
9672 [(set_attr "type" "alu")
9673 (set_attr "mode" "QI")])
9675 ;; Convert wide OR instructions with immediate operand to shorter QImode
9676 ;; equivalents when possible.
9677 ;; Don't do the splitting with memory operands, since it introduces risk
9678 ;; of memory mismatch stalls. We may want to do the splitting for optimizing
9679 ;; for size, but that can (should?) be handled by generic code instead.
9681 [(set (match_operand:SWI248 0 "QIreg_operand")
9682 (any_or:SWI248 (match_operand:SWI248 1 "register_operand")
9683 (match_operand:SWI248 2 "const_int_operand")))
9684 (clobber (reg:CC FLAGS_REG))]
9686 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9687 && !(INTVAL (operands[2]) & ~(255 << 8))"
9689 [(set (zero_extract:SI (match_dup 0)
9695 (zero_extract:SI (match_dup 1)
9699 (clobber (reg:CC FLAGS_REG))])]
9701 operands[0] = gen_lowpart (SImode, operands[0]);
9702 operands[1] = gen_lowpart (SImode, operands[1]);
9703 operands[2] = gen_int_mode (INTVAL (operands[2]) >> 8, QImode);
9706 ;; Since OR can be encoded with sign extended immediate, this is only
9707 ;; profitable when 7th bit is set.
9709 [(set (match_operand:SWI248 0 "any_QIreg_operand")
9710 (any_or:SWI248 (match_operand:SWI248 1 "general_operand")
9711 (match_operand:SWI248 2 "const_int_operand")))
9712 (clobber (reg:CC FLAGS_REG))]
9714 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9715 && !(INTVAL (operands[2]) & ~255)
9716 && (INTVAL (operands[2]) & 128)"
9717 [(parallel [(set (strict_low_part (match_dup 0))
9718 (any_or:QI (match_dup 1)
9720 (clobber (reg:CC FLAGS_REG))])]
9722 operands[0] = gen_lowpart (QImode, operands[0]);
9723 operands[1] = gen_lowpart (QImode, operands[1]);
9724 operands[2] = gen_int_mode (INTVAL (operands[2]), QImode);
9727 (define_expand "xorqi_ext_1_cc"
9729 (set (reg:CCNO FLAGS_REG)
9733 (zero_extract:SI (match_operand 1 "ext_register_operand")
9736 (match_operand 2 "const_int_operand"))
9738 (set (zero_extract:SI (match_operand 0 "ext_register_operand")
9744 (zero_extract:SI (match_dup 1)
9747 (match_dup 2)) 0))])])
9749 (define_insn "*xorqi_ext_1_cc"
9750 [(set (reg FLAGS_REG)
9754 (zero_extract:SI (match_operand 1 "ext_register_operand" "0,0")
9757 (match_operand:QI 2 "general_operand" "QnBc,m"))
9759 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q,Q")
9765 (zero_extract:SI (match_dup 1)
9769 "ix86_match_ccmode (insn, CCNOmode)
9770 /* FIXME: without this LRA can't reload this pattern, see PR82524. */
9771 && rtx_equal_p (operands[0], operands[1])"
9772 "xor{b}\t{%2, %h0|%h0, %2}"
9773 [(set_attr "isa" "*,nox64")
9774 (set_attr "type" "alu")
9775 (set_attr "mode" "QI")])
9777 ;; Negation instructions
9779 (define_expand "neg<mode>2"
9780 [(set (match_operand:SDWIM 0 "nonimmediate_operand")
9781 (neg:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")))]
9783 "ix86_expand_unary_operator (NEG, <MODE>mode, operands); DONE;")
9785 (define_insn_and_split "*neg<dwi>2_doubleword"
9786 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro")
9787 (neg:<DWI> (match_operand:<DWI> 1 "nonimmediate_operand" "0")))
9788 (clobber (reg:CC FLAGS_REG))]
9789 "ix86_unary_operator_ok (NEG, <DWI>mode, operands)"
9793 [(set (reg:CCZ FLAGS_REG)
9794 (compare:CCZ (neg:DWIH (match_dup 1)) (const_int 0)))
9795 (set (match_dup 0) (neg:DWIH (match_dup 1)))])
9798 (plus:DWIH (plus:DWIH (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
9801 (clobber (reg:CC FLAGS_REG))])
9804 (neg:DWIH (match_dup 2)))
9805 (clobber (reg:CC FLAGS_REG))])]
9806 "split_double_mode (<DWI>mode, &operands[0], 2, &operands[0], &operands[2]);")
9808 (define_insn "*neg<mode>2_1"
9809 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9810 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")))
9811 (clobber (reg:CC FLAGS_REG))]
9812 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
9813 "neg{<imodesuffix>}\t%0"
9814 [(set_attr "type" "negnot")
9815 (set_attr "mode" "<MODE>")])
9817 ;; Combine is quite creative about this pattern.
9818 (define_insn "*negsi2_1_zext"
9819 [(set (match_operand:DI 0 "register_operand" "=r")
9821 (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
9824 (clobber (reg:CC FLAGS_REG))]
9825 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9827 [(set_attr "type" "negnot")
9828 (set_attr "mode" "SI")])
9830 ;; The problem with neg is that it does not perform (compare x 0),
9831 ;; it really performs (compare 0 x), which leaves us with the zero
9832 ;; flag being the only useful item.
9834 (define_insn "*neg<mode>2_cmpz"
9835 [(set (reg:CCZ FLAGS_REG)
9837 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
9839 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9840 (neg:SWI (match_dup 1)))]
9841 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
9842 "neg{<imodesuffix>}\t%0"
9843 [(set_attr "type" "negnot")
9844 (set_attr "mode" "<MODE>")])
9846 (define_insn "*negsi2_cmpz_zext"
9847 [(set (reg:CCZ FLAGS_REG)
9851 (match_operand:DI 1 "register_operand" "0")
9855 (set (match_operand:DI 0 "register_operand" "=r")
9856 (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
9859 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9861 [(set_attr "type" "negnot")
9862 (set_attr "mode" "SI")])
9864 ;; Negate with jump on overflow.
9865 (define_expand "negv<mode>3"
9866 [(parallel [(set (reg:CCO FLAGS_REG)
9867 (ne:CCO (match_operand:SWI 1 "register_operand")
9869 (set (match_operand:SWI 0 "register_operand")
9870 (neg:SWI (match_dup 1)))])
9871 (set (pc) (if_then_else
9872 (eq (reg:CCO FLAGS_REG) (const_int 0))
9873 (label_ref (match_operand 2))
9878 = gen_int_mode (HOST_WIDE_INT_1U << (GET_MODE_BITSIZE (<MODE>mode) - 1),
9882 (define_insn "*negv<mode>3"
9883 [(set (reg:CCO FLAGS_REG)
9884 (ne:CCO (match_operand:SWI 1 "nonimmediate_operand" "0")
9885 (match_operand:SWI 2 "const_int_operand")))
9886 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9887 (neg:SWI (match_dup 1)))]
9888 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)
9889 && mode_signbit_p (<MODE>mode, operands[2])"
9890 "neg{<imodesuffix>}\t%0"
9891 [(set_attr "type" "negnot")
9892 (set_attr "mode" "<MODE>")])
9894 ;; Changing of sign for FP values is doable using integer unit too.
9896 (define_expand "<code><mode>2"
9897 [(set (match_operand:X87MODEF 0 "register_operand")
9898 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand")))]
9899 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
9900 "ix86_expand_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
9902 (define_insn "*absneg<mode>2"
9903 [(set (match_operand:MODEF 0 "register_operand" "=Yv,Yv,f,!r")
9904 (match_operator:MODEF 3 "absneg_operator"
9905 [(match_operand:MODEF 1 "register_operand" "0,Yv,0,0")]))
9906 (use (match_operand:<ssevecmode> 2 "nonimmediate_operand" "Yvm,0,X,X"))
9907 (clobber (reg:CC FLAGS_REG))]
9908 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
9910 [(set (attr "enabled")
9912 (match_test ("SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"))
9914 (eq_attr "alternative" "2")
9915 (symbol_ref "TARGET_MIX_SSE_I387")
9916 (symbol_ref "true"))
9918 (eq_attr "alternative" "2,3")
9920 (symbol_ref "false"))))])
9922 (define_insn "*absnegxf2_i387"
9923 [(set (match_operand:XF 0 "register_operand" "=f,!r")
9924 (match_operator:XF 3 "absneg_operator"
9925 [(match_operand:XF 1 "register_operand" "0,0")]))
9926 (use (match_operand 2))
9927 (clobber (reg:CC FLAGS_REG))]
9931 (define_expand "<code>tf2"
9932 [(set (match_operand:TF 0 "register_operand")
9933 (absneg:TF (match_operand:TF 1 "register_operand")))]
9935 "ix86_expand_fp_absneg_operator (<CODE>, TFmode, operands); DONE;")
9937 (define_insn "*absnegtf2_sse"
9938 [(set (match_operand:TF 0 "register_operand" "=Yv,Yv")
9939 (match_operator:TF 3 "absneg_operator"
9940 [(match_operand:TF 1 "register_operand" "0,Yv")]))
9941 (use (match_operand:TF 2 "nonimmediate_operand" "Yvm,0"))
9942 (clobber (reg:CC FLAGS_REG))]
9946 ;; Splitters for fp abs and neg.
9949 [(set (match_operand 0 "fp_register_operand")
9950 (match_operator 1 "absneg_operator" [(match_dup 0)]))
9951 (use (match_operand 2))
9952 (clobber (reg:CC FLAGS_REG))]
9954 [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
9957 [(set (match_operand 0 "sse_reg_operand")
9958 (match_operator 3 "absneg_operator"
9959 [(match_operand 1 "register_operand")]))
9960 (use (match_operand 2 "nonimmediate_operand"))
9961 (clobber (reg:CC FLAGS_REG))]
9963 [(set (match_dup 0) (match_dup 3))]
9965 machine_mode mode = GET_MODE (operands[0]);
9966 machine_mode vmode = GET_MODE (operands[2]);
9969 operands[0] = lowpart_subreg (vmode, operands[0], mode);
9970 operands[1] = lowpart_subreg (vmode, operands[1], mode);
9971 if (operands_match_p (operands[0], operands[2]))
9972 std::swap (operands[1], operands[2]);
9973 if (GET_CODE (operands[3]) == ABS)
9974 tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
9976 tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
9981 [(set (match_operand:SF 0 "general_reg_operand")
9982 (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
9983 (use (match_operand:V4SF 2))
9984 (clobber (reg:CC FLAGS_REG))]
9986 [(parallel [(set (match_dup 0) (match_dup 1))
9987 (clobber (reg:CC FLAGS_REG))])]
9990 operands[0] = gen_lowpart (SImode, operands[0]);
9991 if (GET_CODE (operands[1]) == ABS)
9993 tmp = gen_int_mode (0x7fffffff, SImode);
9994 tmp = gen_rtx_AND (SImode, operands[0], tmp);
9998 tmp = gen_int_mode (0x80000000, SImode);
9999 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
10005 [(set (match_operand:DF 0 "general_reg_operand")
10006 (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
10007 (use (match_operand 2))
10008 (clobber (reg:CC FLAGS_REG))]
10010 [(parallel [(set (match_dup 0) (match_dup 1))
10011 (clobber (reg:CC FLAGS_REG))])]
10016 tmp = gen_lowpart (DImode, operands[0]);
10017 tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
10020 if (GET_CODE (operands[1]) == ABS)
10023 tmp = gen_rtx_NOT (DImode, tmp);
10027 operands[0] = gen_highpart (SImode, operands[0]);
10028 if (GET_CODE (operands[1]) == ABS)
10030 tmp = gen_int_mode (0x7fffffff, SImode);
10031 tmp = gen_rtx_AND (SImode, operands[0], tmp);
10035 tmp = gen_int_mode (0x80000000, SImode);
10036 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
10043 [(set (match_operand:XF 0 "general_reg_operand")
10044 (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
10045 (use (match_operand 2))
10046 (clobber (reg:CC FLAGS_REG))]
10048 [(parallel [(set (match_dup 0) (match_dup 1))
10049 (clobber (reg:CC FLAGS_REG))])]
10052 operands[0] = gen_rtx_REG (SImode,
10053 REGNO (operands[0]) + (TARGET_64BIT ? 1 : 2));
10054 if (GET_CODE (operands[1]) == ABS)
10056 tmp = GEN_INT (0x7fff);
10057 tmp = gen_rtx_AND (SImode, operands[0], tmp);
10061 tmp = GEN_INT (0x8000);
10062 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
10067 ;; Conditionalize these after reload. If they match before reload, we
10068 ;; lose the clobber and ability to use integer instructions.
10070 (define_insn "*<code><mode>2_1"
10071 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
10072 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "0")))]
10074 && (reload_completed
10075 || !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
10076 "f<absneg_mnemonic>"
10077 [(set_attr "type" "fsgn")
10078 (set_attr "mode" "<MODE>")])
10080 (define_insn "*<code>extendsfdf2"
10081 [(set (match_operand:DF 0 "register_operand" "=f")
10082 (absneg:DF (float_extend:DF
10083 (match_operand:SF 1 "register_operand" "0"))))]
10084 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
10085 "f<absneg_mnemonic>"
10086 [(set_attr "type" "fsgn")
10087 (set_attr "mode" "DF")])
10089 (define_insn "*<code>extendsfxf2"
10090 [(set (match_operand:XF 0 "register_operand" "=f")
10091 (absneg:XF (float_extend:XF
10092 (match_operand:SF 1 "register_operand" "0"))))]
10094 "f<absneg_mnemonic>"
10095 [(set_attr "type" "fsgn")
10096 (set_attr "mode" "XF")])
10098 (define_insn "*<code>extenddfxf2"
10099 [(set (match_operand:XF 0 "register_operand" "=f")
10100 (absneg:XF (float_extend:XF
10101 (match_operand:DF 1 "register_operand" "0"))))]
10103 "f<absneg_mnemonic>"
10104 [(set_attr "type" "fsgn")
10105 (set_attr "mode" "XF")])
10107 ;; Copysign instructions
10109 (define_mode_iterator CSGNMODE [SF DF TF])
10110 (define_mode_attr CSGNVMODE [(SF "V4SF") (DF "V2DF") (TF "TF")])
10112 (define_expand "copysign<mode>3"
10113 [(match_operand:CSGNMODE 0 "register_operand")
10114 (match_operand:CSGNMODE 1 "nonmemory_operand")
10115 (match_operand:CSGNMODE 2 "register_operand")]
10116 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10117 || (TARGET_SSE && (<MODE>mode == TFmode))"
10118 "ix86_expand_copysign (operands); DONE;")
10120 (define_insn_and_split "copysign<mode>3_const"
10121 [(set (match_operand:CSGNMODE 0 "register_operand" "=Yv")
10123 [(match_operand:<CSGNVMODE> 1 "vector_move_operand" "YvmC")
10124 (match_operand:CSGNMODE 2 "register_operand" "0")
10125 (match_operand:<CSGNVMODE> 3 "nonimmediate_operand" "Yvm")]
10127 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10128 || (TARGET_SSE && (<MODE>mode == TFmode))"
10130 "&& reload_completed"
10132 "ix86_split_copysign_const (operands); DONE;")
10134 (define_insn "copysign<mode>3_var"
10135 [(set (match_operand:CSGNMODE 0 "register_operand" "=Yv,Yv,Yv,Yv,Yv")
10137 [(match_operand:CSGNMODE 2 "register_operand" "Yv,0,0,Yv,Yv")
10138 (match_operand:CSGNMODE 3 "register_operand" "1,1,Yv,1,Yv")
10139 (match_operand:<CSGNVMODE> 4
10140 "nonimmediate_operand" "X,Yvm,Yvm,0,0")
10141 (match_operand:<CSGNVMODE> 5
10142 "nonimmediate_operand" "0,Yvm,1,Yvm,1")]
10144 (clobber (match_scratch:<CSGNVMODE> 1 "=Yv,Yv,Yv,Yv,Yv"))]
10145 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10146 || (TARGET_SSE && (<MODE>mode == TFmode))"
10150 [(set (match_operand:CSGNMODE 0 "register_operand")
10152 [(match_operand:CSGNMODE 2 "register_operand")
10153 (match_operand:CSGNMODE 3 "register_operand")
10154 (match_operand:<CSGNVMODE> 4)
10155 (match_operand:<CSGNVMODE> 5)]
10157 (clobber (match_scratch:<CSGNVMODE> 1))]
10158 "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10159 || (TARGET_SSE && (<MODE>mode == TFmode)))
10160 && reload_completed"
10162 "ix86_split_copysign_var (operands); DONE;")
10164 ;; One complement instructions
10166 (define_expand "one_cmpl<mode>2"
10167 [(set (match_operand:SWIM1248x 0 "nonimmediate_operand")
10168 (not:SWIM1248x (match_operand:SWIM1248x 1 "nonimmediate_operand")))]
10170 "ix86_expand_unary_operator (NOT, <MODE>mode, operands); DONE;")
10172 (define_insn_and_split "*one_cmpldi2_doubleword"
10173 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10174 (not:DI (match_operand:DI 1 "nonimmediate_operand" "0")))]
10175 "!TARGET_64BIT && TARGET_STV && TARGET_SSE2
10176 && ix86_unary_operator_ok (NOT, DImode, operands)"
10178 "&& reload_completed"
10179 [(set (match_dup 0)
10180 (not:SI (match_dup 1)))
10182 (not:SI (match_dup 3)))]
10183 "split_double_mode (DImode, &operands[0], 2, &operands[0], &operands[2]);")
10185 (define_insn "*one_cmpl<mode>2_1"
10186 [(set (match_operand:SWI248 0 "nonimmediate_operand" "=rm")
10187 (not:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "0")))]
10188 "ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
10189 "not{<imodesuffix>}\t%0"
10190 [(set_attr "type" "negnot")
10191 (set_attr "mode" "<MODE>")])
10193 ;; ??? Currently never generated - xor is used instead.
10194 (define_insn "*one_cmplsi2_1_zext"
10195 [(set (match_operand:DI 0 "register_operand" "=r")
10197 (not:SI (match_operand:SI 1 "register_operand" "0"))))]
10198 "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
10200 [(set_attr "type" "negnot")
10201 (set_attr "mode" "SI")])
10203 (define_insn "*one_cmplqi2_1"
10204 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
10205 (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
10206 "ix86_unary_operator_ok (NOT, QImode, operands)"
10210 [(set_attr "type" "negnot")
10211 (set_attr "mode" "QI,SI")
10212 ;; Potential partial reg stall on alternative 1.
10213 (set (attr "preferred_for_speed")
10214 (cond [(eq_attr "alternative" "1")
10215 (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
10216 (symbol_ref "true")))])
10218 (define_insn "*one_cmpl<mode>2_2"
10219 [(set (reg FLAGS_REG)
10220 (compare (not:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
10222 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
10223 (not:SWI (match_dup 1)))]
10224 "ix86_match_ccmode (insn, CCNOmode)
10225 && ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
10227 [(set_attr "type" "alu1")
10228 (set_attr "mode" "<MODE>")])
10231 [(set (match_operand 0 "flags_reg_operand")
10232 (match_operator 2 "compare_operator"
10233 [(not:SWI (match_operand:SWI 3 "nonimmediate_operand"))
10235 (set (match_operand:SWI 1 "nonimmediate_operand")
10236 (not:SWI (match_dup 3)))]
10237 "ix86_match_ccmode (insn, CCNOmode)"
10238 [(parallel [(set (match_dup 0)
10239 (match_op_dup 2 [(xor:SWI (match_dup 3) (const_int -1))
10242 (xor:SWI (match_dup 3) (const_int -1)))])])
10244 ;; ??? Currently never generated - xor is used instead.
10245 (define_insn "*one_cmplsi2_2_zext"
10246 [(set (reg FLAGS_REG)
10247 (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
10249 (set (match_operand:DI 0 "register_operand" "=r")
10250 (zero_extend:DI (not:SI (match_dup 1))))]
10251 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10252 && ix86_unary_operator_ok (NOT, SImode, operands)"
10254 [(set_attr "type" "alu1")
10255 (set_attr "mode" "SI")])
10258 [(set (match_operand 0 "flags_reg_operand")
10259 (match_operator 2 "compare_operator"
10260 [(not:SI (match_operand:SI 3 "register_operand"))
10262 (set (match_operand:DI 1 "register_operand")
10263 (zero_extend:DI (not:SI (match_dup 3))))]
10264 "ix86_match_ccmode (insn, CCNOmode)"
10265 [(parallel [(set (match_dup 0)
10266 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10269 (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])])
10271 ;; Shift instructions
10273 ;; DImode shifts are implemented using the i386 "shift double" opcode,
10274 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem". If the shift count
10275 ;; is variable, then the count is in %cl and the "imm" operand is dropped
10276 ;; from the assembler input.
10278 ;; This instruction shifts the target reg/mem as usual, but instead of
10279 ;; shifting in zeros, bits are shifted in from reg operand. If the insn
10280 ;; is a left shift double, bits are taken from the high order bits of
10281 ;; reg, else if the insn is a shift right double, bits are taken from the
10282 ;; low order bits of reg. So if %eax is "1234" and %edx is "5678",
10283 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
10285 ;; Since sh[lr]d does not change the `reg' operand, that is done
10286 ;; separately, making all shifts emit pairs of shift double and normal
10287 ;; shift. Since sh[lr]d does not shift more than 31 bits, and we wish to
10288 ;; support a 63 bit shift, each shift where the count is in a reg expands
10289 ;; to a pair of shifts, a branch, a shift by 32 and a label.
10291 ;; If the shift count is a constant, we need never emit more than one
10292 ;; shift pair, instead using moves and sign extension for counts greater
10295 (define_expand "ashl<mode>3"
10296 [(set (match_operand:SDWIM 0 "<shift_operand>")
10297 (ashift:SDWIM (match_operand:SDWIM 1 "<ashl_input_operand>")
10298 (match_operand:QI 2 "nonmemory_operand")))]
10300 "ix86_expand_binary_operator (ASHIFT, <MODE>mode, operands); DONE;")
10302 (define_insn "*ashl<mode>3_doubleword"
10303 [(set (match_operand:DWI 0 "register_operand" "=&r")
10304 (ashift:DWI (match_operand:DWI 1 "reg_or_pm1_operand" "0n")
10305 (match_operand:QI 2 "nonmemory_operand" "<S>c")))
10306 (clobber (reg:CC FLAGS_REG))]
10309 [(set_attr "type" "multi")])
10312 [(set (match_operand:DWI 0 "register_operand")
10313 (ashift:DWI (match_operand:DWI 1 "nonmemory_operand")
10314 (match_operand:QI 2 "nonmemory_operand")))
10315 (clobber (reg:CC FLAGS_REG))]
10316 "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
10318 "ix86_split_ashl (operands, NULL_RTX, <MODE>mode); DONE;")
10320 ;; By default we don't ask for a scratch register, because when DWImode
10321 ;; values are manipulated, registers are already at a premium. But if
10322 ;; we have one handy, we won't turn it away.
10325 [(match_scratch:DWIH 3 "r")
10326 (parallel [(set (match_operand:<DWI> 0 "register_operand")
10328 (match_operand:<DWI> 1 "nonmemory_operand")
10329 (match_operand:QI 2 "nonmemory_operand")))
10330 (clobber (reg:CC FLAGS_REG))])
10334 "ix86_split_ashl (operands, operands[3], <DWI>mode); DONE;")
10336 (define_insn "x86_64_shld"
10337 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
10338 (ior:DI (ashift:DI (match_dup 0)
10339 (match_operand:QI 2 "nonmemory_operand" "Jc"))
10340 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
10341 (minus:QI (const_int 64) (match_dup 2)))))
10342 (clobber (reg:CC FLAGS_REG))]
10344 "shld{q}\t{%s2%1, %0|%0, %1, %2}"
10345 [(set_attr "type" "ishift")
10346 (set_attr "prefix_0f" "1")
10347 (set_attr "mode" "DI")
10348 (set_attr "athlon_decode" "vector")
10349 (set_attr "amdfam10_decode" "vector")
10350 (set_attr "bdver1_decode" "vector")])
10352 (define_insn "x86_shld"
10353 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
10354 (ior:SI (ashift:SI (match_dup 0)
10355 (match_operand:QI 2 "nonmemory_operand" "Ic"))
10356 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
10357 (minus:QI (const_int 32) (match_dup 2)))))
10358 (clobber (reg:CC FLAGS_REG))]
10360 "shld{l}\t{%s2%1, %0|%0, %1, %2}"
10361 [(set_attr "type" "ishift")
10362 (set_attr "prefix_0f" "1")
10363 (set_attr "mode" "SI")
10364 (set_attr "pent_pair" "np")
10365 (set_attr "athlon_decode" "vector")
10366 (set_attr "amdfam10_decode" "vector")
10367 (set_attr "bdver1_decode" "vector")])
10369 (define_expand "x86_shift<mode>_adj_1"
10370 [(set (reg:CCZ FLAGS_REG)
10371 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand")
10374 (set (match_operand:SWI48 0 "register_operand")
10375 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
10376 (match_operand:SWI48 1 "register_operand")
10379 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
10380 (match_operand:SWI48 3 "register_operand")
10383 "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
10385 (define_expand "x86_shift<mode>_adj_2"
10386 [(use (match_operand:SWI48 0 "register_operand"))
10387 (use (match_operand:SWI48 1 "register_operand"))
10388 (use (match_operand:QI 2 "register_operand"))]
10391 rtx_code_label *label = gen_label_rtx ();
10394 emit_insn (gen_testqi_ccz_1 (operands[2],
10395 GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
10397 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
10398 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
10399 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
10400 gen_rtx_LABEL_REF (VOIDmode, label),
10402 tmp = emit_jump_insn (gen_rtx_SET (pc_rtx, tmp));
10403 JUMP_LABEL (tmp) = label;
10405 emit_move_insn (operands[0], operands[1]);
10406 ix86_expand_clear (operands[1]);
10408 emit_label (label);
10409 LABEL_NUSES (label) = 1;
10414 ;; Avoid useless masking of count operand.
10415 (define_insn_and_split "*ashl<mode>3_mask"
10416 [(set (match_operand:SWI48 0 "nonimmediate_operand")
10418 (match_operand:SWI48 1 "nonimmediate_operand")
10421 (match_operand:SI 2 "register_operand" "c,r")
10422 (match_operand:SI 3 "const_int_operand")) 0)))
10423 (clobber (reg:CC FLAGS_REG))]
10424 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)
10425 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10426 == GET_MODE_BITSIZE (<MODE>mode)-1
10427 && can_create_pseudo_p ()"
10431 [(set (match_dup 0)
10432 (ashift:SWI48 (match_dup 1)
10434 (clobber (reg:CC FLAGS_REG))])]
10435 "operands[2] = gen_lowpart (QImode, operands[2]);"
10436 [(set_attr "isa" "*,bmi2")])
10438 (define_insn_and_split "*ashl<mode>3_mask_1"
10439 [(set (match_operand:SWI48 0 "nonimmediate_operand")
10441 (match_operand:SWI48 1 "nonimmediate_operand")
10443 (match_operand:QI 2 "register_operand" "c,r")
10444 (match_operand:QI 3 "const_int_operand"))))
10445 (clobber (reg:CC FLAGS_REG))]
10446 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)
10447 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10448 == GET_MODE_BITSIZE (<MODE>mode)-1
10449 && can_create_pseudo_p ()"
10453 [(set (match_dup 0)
10454 (ashift:SWI48 (match_dup 1)
10456 (clobber (reg:CC FLAGS_REG))])]
10458 [(set_attr "isa" "*,bmi2")])
10460 (define_insn "*bmi2_ashl<mode>3_1"
10461 [(set (match_operand:SWI48 0 "register_operand" "=r")
10462 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
10463 (match_operand:SWI48 2 "register_operand" "r")))]
10465 "shlx\t{%2, %1, %0|%0, %1, %2}"
10466 [(set_attr "type" "ishiftx")
10467 (set_attr "mode" "<MODE>")])
10469 (define_insn "*ashl<mode>3_1"
10470 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r,r")
10471 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,l,rm")
10472 (match_operand:QI 2 "nonmemory_operand" "c<S>,M,r")))
10473 (clobber (reg:CC FLAGS_REG))]
10474 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
10476 switch (get_attr_type (insn))
10483 gcc_assert (operands[2] == const1_rtx);
10484 gcc_assert (rtx_equal_p (operands[0], operands[1]));
10485 return "add{<imodesuffix>}\t%0, %0";
10488 if (operands[2] == const1_rtx
10489 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10490 return "sal{<imodesuffix>}\t%0";
10492 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
10495 [(set_attr "isa" "*,*,bmi2")
10497 (cond [(eq_attr "alternative" "1")
10498 (const_string "lea")
10499 (eq_attr "alternative" "2")
10500 (const_string "ishiftx")
10501 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
10502 (match_operand 0 "register_operand"))
10503 (match_operand 2 "const1_operand"))
10504 (const_string "alu")
10506 (const_string "ishift")))
10507 (set (attr "length_immediate")
10509 (ior (eq_attr "type" "alu")
10510 (and (eq_attr "type" "ishift")
10511 (and (match_operand 2 "const1_operand")
10512 (ior (match_test "TARGET_SHIFT1")
10513 (match_test "optimize_function_for_size_p (cfun)")))))
10515 (const_string "*")))
10516 (set_attr "mode" "<MODE>")])
10518 ;; Convert shift to the shiftx pattern to avoid flags dependency.
10520 [(set (match_operand:SWI48 0 "register_operand")
10521 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
10522 (match_operand:QI 2 "register_operand")))
10523 (clobber (reg:CC FLAGS_REG))]
10524 "TARGET_BMI2 && reload_completed"
10525 [(set (match_dup 0)
10526 (ashift:SWI48 (match_dup 1) (match_dup 2)))]
10527 "operands[2] = gen_lowpart (<MODE>mode, operands[2]);")
10529 (define_insn "*bmi2_ashlsi3_1_zext"
10530 [(set (match_operand:DI 0 "register_operand" "=r")
10532 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
10533 (match_operand:SI 2 "register_operand" "r"))))]
10534 "TARGET_64BIT && TARGET_BMI2"
10535 "shlx\t{%2, %1, %k0|%k0, %1, %2}"
10536 [(set_attr "type" "ishiftx")
10537 (set_attr "mode" "SI")])
10539 (define_insn "*ashlsi3_1_zext"
10540 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
10542 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l,rm")
10543 (match_operand:QI 2 "nonmemory_operand" "cI,M,r"))))
10544 (clobber (reg:CC FLAGS_REG))]
10545 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10547 switch (get_attr_type (insn))
10554 gcc_assert (operands[2] == const1_rtx);
10555 return "add{l}\t%k0, %k0";
10558 if (operands[2] == const1_rtx
10559 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10560 return "sal{l}\t%k0";
10562 return "sal{l}\t{%2, %k0|%k0, %2}";
10565 [(set_attr "isa" "*,*,bmi2")
10567 (cond [(eq_attr "alternative" "1")
10568 (const_string "lea")
10569 (eq_attr "alternative" "2")
10570 (const_string "ishiftx")
10571 (and (match_test "TARGET_DOUBLE_WITH_ADD")
10572 (match_operand 2 "const1_operand"))
10573 (const_string "alu")
10575 (const_string "ishift")))
10576 (set (attr "length_immediate")
10578 (ior (eq_attr "type" "alu")
10579 (and (eq_attr "type" "ishift")
10580 (and (match_operand 2 "const1_operand")
10581 (ior (match_test "TARGET_SHIFT1")
10582 (match_test "optimize_function_for_size_p (cfun)")))))
10584 (const_string "*")))
10585 (set_attr "mode" "SI")])
10587 ;; Convert shift to the shiftx pattern to avoid flags dependency.
10589 [(set (match_operand:DI 0 "register_operand")
10591 (ashift:SI (match_operand:SI 1 "nonimmediate_operand")
10592 (match_operand:QI 2 "register_operand"))))
10593 (clobber (reg:CC FLAGS_REG))]
10594 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
10595 [(set (match_dup 0)
10596 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
10597 "operands[2] = gen_lowpart (SImode, operands[2]);")
10599 (define_insn "*ashlhi3_1"
10600 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,Yp")
10601 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
10602 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10603 (clobber (reg:CC FLAGS_REG))]
10604 "ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10606 switch (get_attr_type (insn))
10612 gcc_assert (operands[2] == const1_rtx);
10613 return "add{w}\t%0, %0";
10616 if (operands[2] == const1_rtx
10617 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10618 return "sal{w}\t%0";
10620 return "sal{w}\t{%2, %0|%0, %2}";
10623 [(set (attr "type")
10624 (cond [(eq_attr "alternative" "1")
10625 (const_string "lea")
10626 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
10627 (match_operand 0 "register_operand"))
10628 (match_operand 2 "const1_operand"))
10629 (const_string "alu")
10631 (const_string "ishift")))
10632 (set (attr "length_immediate")
10634 (ior (eq_attr "type" "alu")
10635 (and (eq_attr "type" "ishift")
10636 (and (match_operand 2 "const1_operand")
10637 (ior (match_test "TARGET_SHIFT1")
10638 (match_test "optimize_function_for_size_p (cfun)")))))
10640 (const_string "*")))
10641 (set_attr "mode" "HI,SI")])
10643 (define_insn "*ashlqi3_1"
10644 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,Yp")
10645 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
10646 (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
10647 (clobber (reg:CC FLAGS_REG))]
10648 "ix86_binary_operator_ok (ASHIFT, QImode, operands)"
10650 switch (get_attr_type (insn))
10656 gcc_assert (operands[2] == const1_rtx);
10657 if (REG_P (operands[1]) && !ANY_QI_REGNO_P (REGNO (operands[1])))
10658 return "add{l}\t%k0, %k0";
10660 return "add{b}\t%0, %0";
10663 if (operands[2] == const1_rtx
10664 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10666 if (get_attr_mode (insn) == MODE_SI)
10667 return "sal{l}\t%k0";
10669 return "sal{b}\t%0";
10673 if (get_attr_mode (insn) == MODE_SI)
10674 return "sal{l}\t{%2, %k0|%k0, %2}";
10676 return "sal{b}\t{%2, %0|%0, %2}";
10680 [(set (attr "type")
10681 (cond [(eq_attr "alternative" "2")
10682 (const_string "lea")
10683 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
10684 (match_operand 0 "register_operand"))
10685 (match_operand 2 "const1_operand"))
10686 (const_string "alu")
10688 (const_string "ishift")))
10689 (set (attr "length_immediate")
10691 (ior (eq_attr "type" "alu")
10692 (and (eq_attr "type" "ishift")
10693 (and (match_operand 2 "const1_operand")
10694 (ior (match_test "TARGET_SHIFT1")
10695 (match_test "optimize_function_for_size_p (cfun)")))))
10697 (const_string "*")))
10698 (set_attr "mode" "QI,SI,SI")
10699 ;; Potential partial reg stall on alternative 1.
10700 (set (attr "preferred_for_speed")
10701 (cond [(eq_attr "alternative" "1")
10702 (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
10703 (symbol_ref "true")))])
10705 (define_insn "*ashlqi3_1_slp"
10706 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10707 (ashift:QI (match_dup 0)
10708 (match_operand:QI 1 "nonmemory_operand" "cI")))
10709 (clobber (reg:CC FLAGS_REG))]
10710 "(optimize_function_for_size_p (cfun)
10711 || !TARGET_PARTIAL_FLAG_REG_STALL
10712 || (operands[1] == const1_rtx
10714 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
10716 switch (get_attr_type (insn))
10719 gcc_assert (operands[1] == const1_rtx);
10720 return "add{b}\t%0, %0";
10723 if (operands[1] == const1_rtx
10724 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10725 return "sal{b}\t%0";
10727 return "sal{b}\t{%1, %0|%0, %1}";
10730 [(set (attr "type")
10731 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
10732 (match_operand 0 "register_operand"))
10733 (match_operand 1 "const1_operand"))
10734 (const_string "alu1")
10736 (const_string "ishift1")))
10737 (set (attr "length_immediate")
10739 (ior (eq_attr "type" "alu1")
10740 (and (eq_attr "type" "ishift1")
10741 (and (match_operand 1 "const1_operand")
10742 (ior (match_test "TARGET_SHIFT1")
10743 (match_test "optimize_function_for_size_p (cfun)")))))
10745 (const_string "*")))
10746 (set_attr "mode" "QI")])
10748 ;; Convert ashift to the lea pattern to avoid flags dependency.
10750 [(set (match_operand:SWI 0 "register_operand")
10751 (ashift:SWI (match_operand:SWI 1 "index_register_operand")
10752 (match_operand 2 "const_0_to_3_operand")))
10753 (clobber (reg:CC FLAGS_REG))]
10755 && REGNO (operands[0]) != REGNO (operands[1])"
10756 [(set (match_dup 0)
10757 (mult:<LEAMODE> (match_dup 1) (match_dup 2)))]
10759 if (<MODE>mode != <LEAMODE>mode)
10761 operands[0] = gen_lowpart (<LEAMODE>mode, operands[0]);
10762 operands[1] = gen_lowpart (<LEAMODE>mode, operands[1]);
10764 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
10767 ;; Convert ashift to the lea pattern to avoid flags dependency.
10769 [(set (match_operand:DI 0 "register_operand")
10771 (ashift:SI (match_operand:SI 1 "index_register_operand")
10772 (match_operand 2 "const_0_to_3_operand"))))
10773 (clobber (reg:CC FLAGS_REG))]
10774 "TARGET_64BIT && reload_completed
10775 && REGNO (operands[0]) != REGNO (operands[1])"
10776 [(set (match_dup 0)
10777 (zero_extend:DI (mult:SI (match_dup 1) (match_dup 2))))]
10779 operands[1] = gen_lowpart (SImode, operands[1]);
10780 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
10783 ;; This pattern can't accept a variable shift count, since shifts by
10784 ;; zero don't affect the flags. We assume that shifts by constant
10785 ;; zero are optimized away.
10786 (define_insn "*ashl<mode>3_cmp"
10787 [(set (reg FLAGS_REG)
10789 (ashift:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
10790 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
10792 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
10793 (ashift:SWI (match_dup 1) (match_dup 2)))]
10794 "(optimize_function_for_size_p (cfun)
10795 || !TARGET_PARTIAL_FLAG_REG_STALL
10796 || (operands[2] == const1_rtx
10798 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
10799 && ix86_match_ccmode (insn, CCGOCmode)
10800 && ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
10802 switch (get_attr_type (insn))
10805 gcc_assert (operands[2] == const1_rtx);
10806 return "add{<imodesuffix>}\t%0, %0";
10809 if (operands[2] == const1_rtx
10810 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10811 return "sal{<imodesuffix>}\t%0";
10813 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
10816 [(set (attr "type")
10817 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
10818 (match_operand 0 "register_operand"))
10819 (match_operand 2 "const1_operand"))
10820 (const_string "alu")
10822 (const_string "ishift")))
10823 (set (attr "length_immediate")
10825 (ior (eq_attr "type" "alu")
10826 (and (eq_attr "type" "ishift")
10827 (and (match_operand 2 "const1_operand")
10828 (ior (match_test "TARGET_SHIFT1")
10829 (match_test "optimize_function_for_size_p (cfun)")))))
10831 (const_string "*")))
10832 (set_attr "mode" "<MODE>")])
10834 (define_insn "*ashlsi3_cmp_zext"
10835 [(set (reg FLAGS_REG)
10837 (ashift:SI (match_operand:SI 1 "register_operand" "0")
10838 (match_operand:QI 2 "const_1_to_31_operand" "I"))
10840 (set (match_operand:DI 0 "register_operand" "=r")
10841 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
10843 && (optimize_function_for_size_p (cfun)
10844 || !TARGET_PARTIAL_FLAG_REG_STALL
10845 || (operands[2] == const1_rtx
10847 || TARGET_DOUBLE_WITH_ADD)))
10848 && ix86_match_ccmode (insn, CCGOCmode)
10849 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10851 switch (get_attr_type (insn))
10854 gcc_assert (operands[2] == const1_rtx);
10855 return "add{l}\t%k0, %k0";
10858 if (operands[2] == const1_rtx
10859 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10860 return "sal{l}\t%k0";
10862 return "sal{l}\t{%2, %k0|%k0, %2}";
10865 [(set (attr "type")
10866 (cond [(and (match_test "TARGET_DOUBLE_WITH_ADD")
10867 (match_operand 2 "const1_operand"))
10868 (const_string "alu")
10870 (const_string "ishift")))
10871 (set (attr "length_immediate")
10873 (ior (eq_attr "type" "alu")
10874 (and (eq_attr "type" "ishift")
10875 (and (match_operand 2 "const1_operand")
10876 (ior (match_test "TARGET_SHIFT1")
10877 (match_test "optimize_function_for_size_p (cfun)")))))
10879 (const_string "*")))
10880 (set_attr "mode" "SI")])
10882 (define_insn "*ashl<mode>3_cconly"
10883 [(set (reg FLAGS_REG)
10885 (ashift:SWI (match_operand:SWI 1 "register_operand" "0")
10886 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
10888 (clobber (match_scratch:SWI 0 "=<r>"))]
10889 "(optimize_function_for_size_p (cfun)
10890 || !TARGET_PARTIAL_FLAG_REG_STALL
10891 || (operands[2] == const1_rtx
10893 || TARGET_DOUBLE_WITH_ADD)))
10894 && ix86_match_ccmode (insn, CCGOCmode)"
10896 switch (get_attr_type (insn))
10899 gcc_assert (operands[2] == const1_rtx);
10900 return "add{<imodesuffix>}\t%0, %0";
10903 if (operands[2] == const1_rtx
10904 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10905 return "sal{<imodesuffix>}\t%0";
10907 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
10910 [(set (attr "type")
10911 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
10912 (match_operand 0 "register_operand"))
10913 (match_operand 2 "const1_operand"))
10914 (const_string "alu")
10916 (const_string "ishift")))
10917 (set (attr "length_immediate")
10919 (ior (eq_attr "type" "alu")
10920 (and (eq_attr "type" "ishift")
10921 (and (match_operand 2 "const1_operand")
10922 (ior (match_test "TARGET_SHIFT1")
10923 (match_test "optimize_function_for_size_p (cfun)")))))
10925 (const_string "*")))
10926 (set_attr "mode" "<MODE>")])
10928 ;; See comment above `ashl<mode>3' about how this works.
10930 (define_expand "<shift_insn><mode>3"
10931 [(set (match_operand:SDWIM 0 "<shift_operand>")
10932 (any_shiftrt:SDWIM (match_operand:SDWIM 1 "<shift_operand>")
10933 (match_operand:QI 2 "nonmemory_operand")))]
10935 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
10937 ;; Avoid useless masking of count operand.
10938 (define_insn_and_split "*<shift_insn><mode>3_mask"
10939 [(set (match_operand:SWI48 0 "nonimmediate_operand")
10941 (match_operand:SWI48 1 "nonimmediate_operand")
10944 (match_operand:SI 2 "register_operand" "c,r")
10945 (match_operand:SI 3 "const_int_operand")) 0)))
10946 (clobber (reg:CC FLAGS_REG))]
10947 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
10948 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10949 == GET_MODE_BITSIZE (<MODE>mode)-1
10950 && can_create_pseudo_p ()"
10954 [(set (match_dup 0)
10955 (any_shiftrt:SWI48 (match_dup 1)
10957 (clobber (reg:CC FLAGS_REG))])]
10958 "operands[2] = gen_lowpart (QImode, operands[2]);"
10959 [(set_attr "isa" "*,bmi2")])
10961 (define_insn_and_split "*<shift_insn><mode>3_mask_1"
10962 [(set (match_operand:SWI48 0 "nonimmediate_operand")
10964 (match_operand:SWI48 1 "nonimmediate_operand")
10966 (match_operand:QI 2 "register_operand" "c,r")
10967 (match_operand:QI 3 "const_int_operand"))))
10968 (clobber (reg:CC FLAGS_REG))]
10969 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
10970 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10971 == GET_MODE_BITSIZE (<MODE>mode)-1
10972 && can_create_pseudo_p ()"
10976 [(set (match_dup 0)
10977 (any_shiftrt:SWI48 (match_dup 1)
10979 (clobber (reg:CC FLAGS_REG))])]
10981 [(set_attr "isa" "*,bmi2")])
10983 (define_insn_and_split "*<shift_insn><mode>3_doubleword"
10984 [(set (match_operand:DWI 0 "register_operand" "=&r")
10985 (any_shiftrt:DWI (match_operand:DWI 1 "register_operand" "0")
10986 (match_operand:QI 2 "nonmemory_operand" "<S>c")))
10987 (clobber (reg:CC FLAGS_REG))]
10990 "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
10992 "ix86_split_<shift_insn> (operands, NULL_RTX, <MODE>mode); DONE;"
10993 [(set_attr "type" "multi")])
10995 ;; By default we don't ask for a scratch register, because when DWImode
10996 ;; values are manipulated, registers are already at a premium. But if
10997 ;; we have one handy, we won't turn it away.
11000 [(match_scratch:DWIH 3 "r")
11001 (parallel [(set (match_operand:<DWI> 0 "register_operand")
11003 (match_operand:<DWI> 1 "register_operand")
11004 (match_operand:QI 2 "nonmemory_operand")))
11005 (clobber (reg:CC FLAGS_REG))])
11009 "ix86_split_<shift_insn> (operands, operands[3], <DWI>mode); DONE;")
11011 (define_insn "x86_64_shrd"
11012 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
11013 (ior:DI (lshiftrt:DI (match_dup 0)
11014 (match_operand:QI 2 "nonmemory_operand" "Jc"))
11015 (ashift:DI (match_operand:DI 1 "register_operand" "r")
11016 (minus:QI (const_int 64) (match_dup 2)))))
11017 (clobber (reg:CC FLAGS_REG))]
11019 "shrd{q}\t{%s2%1, %0|%0, %1, %2}"
11020 [(set_attr "type" "ishift")
11021 (set_attr "prefix_0f" "1")
11022 (set_attr "mode" "DI")
11023 (set_attr "athlon_decode" "vector")
11024 (set_attr "amdfam10_decode" "vector")
11025 (set_attr "bdver1_decode" "vector")])
11027 (define_insn "x86_shrd"
11028 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
11029 (ior:SI (lshiftrt:SI (match_dup 0)
11030 (match_operand:QI 2 "nonmemory_operand" "Ic"))
11031 (ashift:SI (match_operand:SI 1 "register_operand" "r")
11032 (minus:QI (const_int 32) (match_dup 2)))))
11033 (clobber (reg:CC FLAGS_REG))]
11035 "shrd{l}\t{%s2%1, %0|%0, %1, %2}"
11036 [(set_attr "type" "ishift")
11037 (set_attr "prefix_0f" "1")
11038 (set_attr "mode" "SI")
11039 (set_attr "pent_pair" "np")
11040 (set_attr "athlon_decode" "vector")
11041 (set_attr "amdfam10_decode" "vector")
11042 (set_attr "bdver1_decode" "vector")])
11044 (define_insn "ashrdi3_cvt"
11045 [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
11046 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
11047 (match_operand:QI 2 "const_int_operand")))
11048 (clobber (reg:CC FLAGS_REG))]
11049 "TARGET_64BIT && INTVAL (operands[2]) == 63
11050 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
11051 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11054 sar{q}\t{%2, %0|%0, %2}"
11055 [(set_attr "type" "imovx,ishift")
11056 (set_attr "prefix_0f" "0,*")
11057 (set_attr "length_immediate" "0,*")
11058 (set_attr "modrm" "0,1")
11059 (set_attr "mode" "DI")])
11061 (define_insn "*ashrsi3_cvt_zext"
11062 [(set (match_operand:DI 0 "register_operand" "=*d,r")
11064 (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
11065 (match_operand:QI 2 "const_int_operand"))))
11066 (clobber (reg:CC FLAGS_REG))]
11067 "TARGET_64BIT && INTVAL (operands[2]) == 31
11068 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
11069 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11072 sar{l}\t{%2, %k0|%k0, %2}"
11073 [(set_attr "type" "imovx,ishift")
11074 (set_attr "prefix_0f" "0,*")
11075 (set_attr "length_immediate" "0,*")
11076 (set_attr "modrm" "0,1")
11077 (set_attr "mode" "SI")])
11079 (define_insn "ashrsi3_cvt"
11080 [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
11081 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
11082 (match_operand:QI 2 "const_int_operand")))
11083 (clobber (reg:CC FLAGS_REG))]
11084 "INTVAL (operands[2]) == 31
11085 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
11086 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11089 sar{l}\t{%2, %0|%0, %2}"
11090 [(set_attr "type" "imovx,ishift")
11091 (set_attr "prefix_0f" "0,*")
11092 (set_attr "length_immediate" "0,*")
11093 (set_attr "modrm" "0,1")
11094 (set_attr "mode" "SI")])
11096 (define_expand "x86_shift<mode>_adj_3"
11097 [(use (match_operand:SWI48 0 "register_operand"))
11098 (use (match_operand:SWI48 1 "register_operand"))
11099 (use (match_operand:QI 2 "register_operand"))]
11102 rtx_code_label *label = gen_label_rtx ();
11105 emit_insn (gen_testqi_ccz_1 (operands[2],
11106 GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
11108 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
11109 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
11110 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
11111 gen_rtx_LABEL_REF (VOIDmode, label),
11113 tmp = emit_jump_insn (gen_rtx_SET (pc_rtx, tmp));
11114 JUMP_LABEL (tmp) = label;
11116 emit_move_insn (operands[0], operands[1]);
11117 emit_insn (gen_ashr<mode>3_cvt (operands[1], operands[1],
11118 GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1)));
11119 emit_label (label);
11120 LABEL_NUSES (label) = 1;
11125 (define_insn "*bmi2_<shift_insn><mode>3_1"
11126 [(set (match_operand:SWI48 0 "register_operand" "=r")
11127 (any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11128 (match_operand:SWI48 2 "register_operand" "r")))]
11130 "<shift>x\t{%2, %1, %0|%0, %1, %2}"
11131 [(set_attr "type" "ishiftx")
11132 (set_attr "mode" "<MODE>")])
11134 (define_insn "*<shift_insn><mode>3_1"
11135 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
11137 (match_operand:SWI48 1 "nonimmediate_operand" "0,rm")
11138 (match_operand:QI 2 "nonmemory_operand" "c<S>,r")))
11139 (clobber (reg:CC FLAGS_REG))]
11140 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
11142 switch (get_attr_type (insn))
11148 if (operands[2] == const1_rtx
11149 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11150 return "<shift>{<imodesuffix>}\t%0";
11152 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
11155 [(set_attr "isa" "*,bmi2")
11156 (set_attr "type" "ishift,ishiftx")
11157 (set (attr "length_immediate")
11159 (and (match_operand 2 "const1_operand")
11160 (ior (match_test "TARGET_SHIFT1")
11161 (match_test "optimize_function_for_size_p (cfun)")))
11163 (const_string "*")))
11164 (set_attr "mode" "<MODE>")])
11166 ;; Convert shift to the shiftx pattern to avoid flags dependency.
11168 [(set (match_operand:SWI48 0 "register_operand")
11169 (any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
11170 (match_operand:QI 2 "register_operand")))
11171 (clobber (reg:CC FLAGS_REG))]
11172 "TARGET_BMI2 && reload_completed"
11173 [(set (match_dup 0)
11174 (any_shiftrt:SWI48 (match_dup 1) (match_dup 2)))]
11175 "operands[2] = gen_lowpart (<MODE>mode, operands[2]);")
11177 (define_insn "*bmi2_<shift_insn>si3_1_zext"
11178 [(set (match_operand:DI 0 "register_operand" "=r")
11180 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
11181 (match_operand:SI 2 "register_operand" "r"))))]
11182 "TARGET_64BIT && TARGET_BMI2"
11183 "<shift>x\t{%2, %1, %k0|%k0, %1, %2}"
11184 [(set_attr "type" "ishiftx")
11185 (set_attr "mode" "SI")])
11187 (define_insn "*<shift_insn>si3_1_zext"
11188 [(set (match_operand:DI 0 "register_operand" "=r,r")
11190 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm")
11191 (match_operand:QI 2 "nonmemory_operand" "cI,r"))))
11192 (clobber (reg:CC FLAGS_REG))]
11193 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
11195 switch (get_attr_type (insn))
11201 if (operands[2] == const1_rtx
11202 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11203 return "<shift>{l}\t%k0";
11205 return "<shift>{l}\t{%2, %k0|%k0, %2}";
11208 [(set_attr "isa" "*,bmi2")
11209 (set_attr "type" "ishift,ishiftx")
11210 (set (attr "length_immediate")
11212 (and (match_operand 2 "const1_operand")
11213 (ior (match_test "TARGET_SHIFT1")
11214 (match_test "optimize_function_for_size_p (cfun)")))
11216 (const_string "*")))
11217 (set_attr "mode" "SI")])
11219 ;; Convert shift to the shiftx pattern to avoid flags dependency.
11221 [(set (match_operand:DI 0 "register_operand")
11223 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand")
11224 (match_operand:QI 2 "register_operand"))))
11225 (clobber (reg:CC FLAGS_REG))]
11226 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
11227 [(set (match_dup 0)
11228 (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
11229 "operands[2] = gen_lowpart (SImode, operands[2]);")
11231 (define_insn "*<shift_insn><mode>3_1"
11232 [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m")
11234 (match_operand:SWI12 1 "nonimmediate_operand" "0")
11235 (match_operand:QI 2 "nonmemory_operand" "c<S>")))
11236 (clobber (reg:CC FLAGS_REG))]
11237 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
11239 if (operands[2] == const1_rtx
11240 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11241 return "<shift>{<imodesuffix>}\t%0";
11243 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
11245 [(set_attr "type" "ishift")
11246 (set (attr "length_immediate")
11248 (and (match_operand 2 "const1_operand")
11249 (ior (match_test "TARGET_SHIFT1")
11250 (match_test "optimize_function_for_size_p (cfun)")))
11252 (const_string "*")))
11253 (set_attr "mode" "<MODE>")])
11255 (define_insn "*<shift_insn>qi3_1_slp"
11256 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
11257 (any_shiftrt:QI (match_dup 0)
11258 (match_operand:QI 1 "nonmemory_operand" "cI")))
11259 (clobber (reg:CC FLAGS_REG))]
11260 "(optimize_function_for_size_p (cfun)
11261 || !TARGET_PARTIAL_REG_STALL
11262 || (operands[1] == const1_rtx
11263 && TARGET_SHIFT1))"
11265 if (operands[1] == const1_rtx
11266 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11267 return "<shift>{b}\t%0";
11269 return "<shift>{b}\t{%1, %0|%0, %1}";
11271 [(set_attr "type" "ishift1")
11272 (set (attr "length_immediate")
11274 (and (match_operand 1 "const1_operand")
11275 (ior (match_test "TARGET_SHIFT1")
11276 (match_test "optimize_function_for_size_p (cfun)")))
11278 (const_string "*")))
11279 (set_attr "mode" "QI")])
11281 ;; This pattern can't accept a variable shift count, since shifts by
11282 ;; zero don't affect the flags. We assume that shifts by constant
11283 ;; zero are optimized away.
11284 (define_insn "*<shift_insn><mode>3_cmp"
11285 [(set (reg FLAGS_REG)
11288 (match_operand:SWI 1 "nonimmediate_operand" "0")
11289 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
11291 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
11292 (any_shiftrt:SWI (match_dup 1) (match_dup 2)))]
11293 "(optimize_function_for_size_p (cfun)
11294 || !TARGET_PARTIAL_FLAG_REG_STALL
11295 || (operands[2] == const1_rtx
11297 && ix86_match_ccmode (insn, CCGOCmode)
11298 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
11300 if (operands[2] == const1_rtx
11301 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11302 return "<shift>{<imodesuffix>}\t%0";
11304 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
11306 [(set_attr "type" "ishift")
11307 (set (attr "length_immediate")
11309 (and (match_operand 2 "const1_operand")
11310 (ior (match_test "TARGET_SHIFT1")
11311 (match_test "optimize_function_for_size_p (cfun)")))
11313 (const_string "*")))
11314 (set_attr "mode" "<MODE>")])
11316 (define_insn "*<shift_insn>si3_cmp_zext"
11317 [(set (reg FLAGS_REG)
11319 (any_shiftrt:SI (match_operand:SI 1 "register_operand" "0")
11320 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11322 (set (match_operand:DI 0 "register_operand" "=r")
11323 (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
11325 && (optimize_function_for_size_p (cfun)
11326 || !TARGET_PARTIAL_FLAG_REG_STALL
11327 || (operands[2] == const1_rtx
11329 && ix86_match_ccmode (insn, CCGOCmode)
11330 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
11332 if (operands[2] == const1_rtx
11333 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11334 return "<shift>{l}\t%k0";
11336 return "<shift>{l}\t{%2, %k0|%k0, %2}";
11338 [(set_attr "type" "ishift")
11339 (set (attr "length_immediate")
11341 (and (match_operand 2 "const1_operand")
11342 (ior (match_test "TARGET_SHIFT1")
11343 (match_test "optimize_function_for_size_p (cfun)")))
11345 (const_string "*")))
11346 (set_attr "mode" "SI")])
11348 (define_insn "*<shift_insn><mode>3_cconly"
11349 [(set (reg FLAGS_REG)
11352 (match_operand:SWI 1 "register_operand" "0")
11353 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
11355 (clobber (match_scratch:SWI 0 "=<r>"))]
11356 "(optimize_function_for_size_p (cfun)
11357 || !TARGET_PARTIAL_FLAG_REG_STALL
11358 || (operands[2] == const1_rtx
11360 && ix86_match_ccmode (insn, CCGOCmode)"
11362 if (operands[2] == const1_rtx
11363 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11364 return "<shift>{<imodesuffix>}\t%0";
11366 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
11368 [(set_attr "type" "ishift")
11369 (set (attr "length_immediate")
11371 (and (match_operand 2 "const1_operand")
11372 (ior (match_test "TARGET_SHIFT1")
11373 (match_test "optimize_function_for_size_p (cfun)")))
11375 (const_string "*")))
11376 (set_attr "mode" "<MODE>")])
11378 ;; Rotate instructions
11380 (define_expand "<rotate_insn>ti3"
11381 [(set (match_operand:TI 0 "register_operand")
11382 (any_rotate:TI (match_operand:TI 1 "register_operand")
11383 (match_operand:QI 2 "nonmemory_operand")))]
11386 if (const_1_to_63_operand (operands[2], VOIDmode))
11387 emit_insn (gen_ix86_<rotate_insn>ti3_doubleword
11388 (operands[0], operands[1], operands[2]));
11395 (define_expand "<rotate_insn>di3"
11396 [(set (match_operand:DI 0 "shiftdi_operand")
11397 (any_rotate:DI (match_operand:DI 1 "shiftdi_operand")
11398 (match_operand:QI 2 "nonmemory_operand")))]
11402 ix86_expand_binary_operator (<CODE>, DImode, operands);
11403 else if (const_1_to_31_operand (operands[2], VOIDmode))
11404 emit_insn (gen_ix86_<rotate_insn>di3_doubleword
11405 (operands[0], operands[1], operands[2]));
11412 (define_expand "<rotate_insn><mode>3"
11413 [(set (match_operand:SWIM124 0 "nonimmediate_operand")
11414 (any_rotate:SWIM124 (match_operand:SWIM124 1 "nonimmediate_operand")
11415 (match_operand:QI 2 "nonmemory_operand")))]
11417 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
11419 ;; Avoid useless masking of count operand.
11420 (define_insn_and_split "*<rotate_insn><mode>3_mask"
11421 [(set (match_operand:SWI48 0 "nonimmediate_operand")
11423 (match_operand:SWI48 1 "nonimmediate_operand")
11426 (match_operand:SI 2 "register_operand" "c")
11427 (match_operand:SI 3 "const_int_operand")) 0)))
11428 (clobber (reg:CC FLAGS_REG))]
11429 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
11430 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
11431 == GET_MODE_BITSIZE (<MODE>mode)-1
11432 && can_create_pseudo_p ()"
11436 [(set (match_dup 0)
11437 (any_rotate:SWI48 (match_dup 1)
11439 (clobber (reg:CC FLAGS_REG))])]
11440 "operands[2] = gen_lowpart (QImode, operands[2]);")
11442 (define_insn_and_split "*<rotate_insn><mode>3_mask_1"
11443 [(set (match_operand:SWI48 0 "nonimmediate_operand")
11445 (match_operand:SWI48 1 "nonimmediate_operand")
11447 (match_operand:QI 2 "register_operand" "c")
11448 (match_operand:QI 3 "const_int_operand"))))
11449 (clobber (reg:CC FLAGS_REG))]
11450 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
11451 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
11452 == GET_MODE_BITSIZE (<MODE>mode)-1
11453 && can_create_pseudo_p ()"
11457 [(set (match_dup 0)
11458 (any_rotate:SWI48 (match_dup 1)
11460 (clobber (reg:CC FLAGS_REG))])])
11462 ;; Implement rotation using two double-precision
11463 ;; shift instructions and a scratch register.
11465 (define_insn_and_split "ix86_rotl<dwi>3_doubleword"
11466 [(set (match_operand:<DWI> 0 "register_operand" "=r")
11467 (rotate:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
11468 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
11469 (clobber (reg:CC FLAGS_REG))
11470 (clobber (match_scratch:DWIH 3 "=&r"))]
11474 [(set (match_dup 3) (match_dup 4))
11476 [(set (match_dup 4)
11477 (ior:DWIH (ashift:DWIH (match_dup 4) (match_dup 2))
11478 (lshiftrt:DWIH (match_dup 5)
11479 (minus:QI (match_dup 6) (match_dup 2)))))
11480 (clobber (reg:CC FLAGS_REG))])
11482 [(set (match_dup 5)
11483 (ior:DWIH (ashift:DWIH (match_dup 5) (match_dup 2))
11484 (lshiftrt:DWIH (match_dup 3)
11485 (minus:QI (match_dup 6) (match_dup 2)))))
11486 (clobber (reg:CC FLAGS_REG))])]
11488 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
11490 split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
11493 (define_insn_and_split "ix86_rotr<dwi>3_doubleword"
11494 [(set (match_operand:<DWI> 0 "register_operand" "=r")
11495 (rotatert:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
11496 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
11497 (clobber (reg:CC FLAGS_REG))
11498 (clobber (match_scratch:DWIH 3 "=&r"))]
11502 [(set (match_dup 3) (match_dup 4))
11504 [(set (match_dup 4)
11505 (ior:DWIH (lshiftrt:DWIH (match_dup 4) (match_dup 2))
11506 (ashift:DWIH (match_dup 5)
11507 (minus:QI (match_dup 6) (match_dup 2)))))
11508 (clobber (reg:CC FLAGS_REG))])
11510 [(set (match_dup 5)
11511 (ior:DWIH (lshiftrt:DWIH (match_dup 5) (match_dup 2))
11512 (ashift:DWIH (match_dup 3)
11513 (minus:QI (match_dup 6) (match_dup 2)))))
11514 (clobber (reg:CC FLAGS_REG))])]
11516 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
11518 split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
11521 (define_mode_attr rorx_immediate_operand
11522 [(SI "const_0_to_31_operand")
11523 (DI "const_0_to_63_operand")])
11525 (define_insn "*bmi2_rorx<mode>3_1"
11526 [(set (match_operand:SWI48 0 "register_operand" "=r")
11528 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11529 (match_operand:QI 2 "<rorx_immediate_operand>" "<S>")))]
11531 "rorx\t{%2, %1, %0|%0, %1, %2}"
11532 [(set_attr "type" "rotatex")
11533 (set_attr "mode" "<MODE>")])
11535 (define_insn "*<rotate_insn><mode>3_1"
11536 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
11538 (match_operand:SWI48 1 "nonimmediate_operand" "0,rm")
11539 (match_operand:QI 2 "nonmemory_operand" "c<S>,<S>")))
11540 (clobber (reg:CC FLAGS_REG))]
11541 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
11543 switch (get_attr_type (insn))
11549 if (operands[2] == const1_rtx
11550 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11551 return "<rotate>{<imodesuffix>}\t%0";
11553 return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
11556 [(set_attr "isa" "*,bmi2")
11557 (set_attr "type" "rotate,rotatex")
11558 (set (attr "length_immediate")
11560 (and (eq_attr "type" "rotate")
11561 (and (match_operand 2 "const1_operand")
11562 (ior (match_test "TARGET_SHIFT1")
11563 (match_test "optimize_function_for_size_p (cfun)"))))
11565 (const_string "*")))
11566 (set_attr "mode" "<MODE>")])
11568 ;; Convert rotate to the rotatex pattern to avoid flags dependency.
11570 [(set (match_operand:SWI48 0 "register_operand")
11571 (rotate:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
11572 (match_operand:QI 2 "const_int_operand")))
11573 (clobber (reg:CC FLAGS_REG))]
11574 "TARGET_BMI2 && reload_completed"
11575 [(set (match_dup 0)
11576 (rotatert:SWI48 (match_dup 1) (match_dup 2)))]
11578 int bitsize = GET_MODE_BITSIZE (<MODE>mode);
11580 operands[2] = GEN_INT ((bitsize - INTVAL (operands[2])) % bitsize);
11584 [(set (match_operand:SWI48 0 "register_operand")
11585 (rotatert:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
11586 (match_operand:QI 2 "const_int_operand")))
11587 (clobber (reg:CC FLAGS_REG))]
11588 "TARGET_BMI2 && reload_completed"
11589 [(set (match_dup 0)
11590 (rotatert:SWI48 (match_dup 1) (match_dup 2)))])
11592 (define_insn "*bmi2_rorxsi3_1_zext"
11593 [(set (match_operand:DI 0 "register_operand" "=r")
11595 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
11596 (match_operand:QI 2 "const_0_to_31_operand" "I"))))]
11597 "TARGET_64BIT && TARGET_BMI2"
11598 "rorx\t{%2, %1, %k0|%k0, %1, %2}"
11599 [(set_attr "type" "rotatex")
11600 (set_attr "mode" "SI")])
11602 (define_insn "*<rotate_insn>si3_1_zext"
11603 [(set (match_operand:DI 0 "register_operand" "=r,r")
11605 (any_rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm")
11606 (match_operand:QI 2 "nonmemory_operand" "cI,I"))))
11607 (clobber (reg:CC FLAGS_REG))]
11608 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
11610 switch (get_attr_type (insn))
11616 if (operands[2] == const1_rtx
11617 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11618 return "<rotate>{l}\t%k0";
11620 return "<rotate>{l}\t{%2, %k0|%k0, %2}";
11623 [(set_attr "isa" "*,bmi2")
11624 (set_attr "type" "rotate,rotatex")
11625 (set (attr "length_immediate")
11627 (and (eq_attr "type" "rotate")
11628 (and (match_operand 2 "const1_operand")
11629 (ior (match_test "TARGET_SHIFT1")
11630 (match_test "optimize_function_for_size_p (cfun)"))))
11632 (const_string "*")))
11633 (set_attr "mode" "SI")])
11635 ;; Convert rotate to the rotatex pattern to avoid flags dependency.
11637 [(set (match_operand:DI 0 "register_operand")
11639 (rotate:SI (match_operand:SI 1 "nonimmediate_operand")
11640 (match_operand:QI 2 "const_int_operand"))))
11641 (clobber (reg:CC FLAGS_REG))]
11642 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
11643 [(set (match_dup 0)
11644 (zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))]
11646 int bitsize = GET_MODE_BITSIZE (SImode);
11648 operands[2] = GEN_INT ((bitsize - INTVAL (operands[2])) % bitsize);
11652 [(set (match_operand:DI 0 "register_operand")
11654 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand")
11655 (match_operand:QI 2 "const_int_operand"))))
11656 (clobber (reg:CC FLAGS_REG))]
11657 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
11658 [(set (match_dup 0)
11659 (zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))])
11661 (define_insn "*<rotate_insn><mode>3_1"
11662 [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m")
11663 (any_rotate:SWI12 (match_operand:SWI12 1 "nonimmediate_operand" "0")
11664 (match_operand:QI 2 "nonmemory_operand" "c<S>")))
11665 (clobber (reg:CC FLAGS_REG))]
11666 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
11668 if (operands[2] == const1_rtx
11669 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11670 return "<rotate>{<imodesuffix>}\t%0";
11672 return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
11674 [(set_attr "type" "rotate")
11675 (set (attr "length_immediate")
11677 (and (match_operand 2 "const1_operand")
11678 (ior (match_test "TARGET_SHIFT1")
11679 (match_test "optimize_function_for_size_p (cfun)")))
11681 (const_string "*")))
11682 (set_attr "mode" "<MODE>")])
11684 (define_insn "*<rotate_insn>qi3_1_slp"
11685 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
11686 (any_rotate:QI (match_dup 0)
11687 (match_operand:QI 1 "nonmemory_operand" "cI")))
11688 (clobber (reg:CC FLAGS_REG))]
11689 "(optimize_function_for_size_p (cfun)
11690 || !TARGET_PARTIAL_REG_STALL
11691 || (operands[1] == const1_rtx
11692 && TARGET_SHIFT1))"
11694 if (operands[1] == const1_rtx
11695 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11696 return "<rotate>{b}\t%0";
11698 return "<rotate>{b}\t{%1, %0|%0, %1}";
11700 [(set_attr "type" "rotate1")
11701 (set (attr "length_immediate")
11703 (and (match_operand 1 "const1_operand")
11704 (ior (match_test "TARGET_SHIFT1")
11705 (match_test "optimize_function_for_size_p (cfun)")))
11707 (const_string "*")))
11708 (set_attr "mode" "QI")])
11711 [(set (match_operand:HI 0 "QIreg_operand")
11712 (any_rotate:HI (match_dup 0) (const_int 8)))
11713 (clobber (reg:CC FLAGS_REG))]
11715 && (TARGET_USE_XCHGB || optimize_function_for_size_p (cfun))"
11716 [(parallel [(set (strict_low_part (match_dup 0))
11717 (bswap:HI (match_dup 0)))
11718 (clobber (reg:CC FLAGS_REG))])])
11720 ;; Bit set / bit test instructions
11722 ;; %%% bts, btr, btc
11724 ;; These instructions are *slow* when applied to memory.
11726 (define_code_attr btsc [(ior "bts") (xor "btc")])
11728 (define_insn "*<btsc><mode>"
11729 [(set (match_operand:SWI48 0 "register_operand" "=r")
11731 (ashift:SWI48 (const_int 1)
11732 (match_operand:QI 2 "register_operand" "r"))
11733 (match_operand:SWI48 1 "register_operand" "0")))
11734 (clobber (reg:CC FLAGS_REG))]
11736 "<btsc>{<imodesuffix>}\t{%<k>2, %0|%0, %<k>2}"
11737 [(set_attr "type" "alu1")
11738 (set_attr "prefix_0f" "1")
11739 (set_attr "znver1_decode" "double")
11740 (set_attr "mode" "<MODE>")])
11742 ;; Avoid useless masking of count operand.
11743 (define_insn_and_split "*<btsc><mode>_mask"
11744 [(set (match_operand:SWI48 0 "register_operand")
11750 (match_operand:SI 1 "register_operand")
11751 (match_operand:SI 2 "const_int_operand")) 0))
11752 (match_operand:SWI48 3 "register_operand")))
11753 (clobber (reg:CC FLAGS_REG))]
11755 && (INTVAL (operands[2]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
11756 == GET_MODE_BITSIZE (<MODE>mode)-1
11757 && can_create_pseudo_p ()"
11761 [(set (match_dup 0)
11763 (ashift:SWI48 (const_int 1)
11766 (clobber (reg:CC FLAGS_REG))])]
11767 "operands[1] = gen_lowpart (QImode, operands[1]);")
11769 (define_insn_and_split "*<btsc><mode>_mask_1"
11770 [(set (match_operand:SWI48 0 "register_operand")
11775 (match_operand:QI 1 "register_operand")
11776 (match_operand:QI 2 "const_int_operand")))
11777 (match_operand:SWI48 3 "register_operand")))
11778 (clobber (reg:CC FLAGS_REG))]
11780 && (INTVAL (operands[2]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
11781 == GET_MODE_BITSIZE (<MODE>mode)-1
11782 && can_create_pseudo_p ()"
11786 [(set (match_dup 0)
11788 (ashift:SWI48 (const_int 1)
11791 (clobber (reg:CC FLAGS_REG))])])
11793 (define_insn "*btr<mode>"
11794 [(set (match_operand:SWI48 0 "register_operand" "=r")
11796 (rotate:SWI48 (const_int -2)
11797 (match_operand:QI 2 "register_operand" "r"))
11798 (match_operand:SWI48 1 "register_operand" "0")))
11799 (clobber (reg:CC FLAGS_REG))]
11801 "btr{<imodesuffix>}\t{%<k>2, %0|%0, %<k>2}"
11802 [(set_attr "type" "alu1")
11803 (set_attr "prefix_0f" "1")
11804 (set_attr "znver1_decode" "double")
11805 (set_attr "mode" "<MODE>")])
11807 ;; Avoid useless masking of count operand.
11808 (define_insn_and_split "*btr<mode>_mask"
11809 [(set (match_operand:SWI48 0 "register_operand")
11815 (match_operand:SI 1 "register_operand")
11816 (match_operand:SI 2 "const_int_operand")) 0))
11817 (match_operand:SWI48 3 "register_operand")))
11818 (clobber (reg:CC FLAGS_REG))]
11820 && (INTVAL (operands[2]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
11821 == GET_MODE_BITSIZE (<MODE>mode)-1
11822 && can_create_pseudo_p ()"
11826 [(set (match_dup 0)
11828 (rotate:SWI48 (const_int -2)
11831 (clobber (reg:CC FLAGS_REG))])]
11832 "operands[1] = gen_lowpart (QImode, operands[1]);")
11834 (define_insn_and_split "*btr<mode>_mask_1"
11835 [(set (match_operand:SWI48 0 "register_operand")
11840 (match_operand:QI 1 "register_operand")
11841 (match_operand:QI 2 "const_int_operand")))
11842 (match_operand:SWI48 3 "register_operand")))
11843 (clobber (reg:CC FLAGS_REG))]
11845 && (INTVAL (operands[2]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
11846 == GET_MODE_BITSIZE (<MODE>mode)-1
11847 && can_create_pseudo_p ()"
11851 [(set (match_dup 0)
11853 (rotate:SWI48 (const_int -2)
11856 (clobber (reg:CC FLAGS_REG))])])
11858 ;; These instructions are never faster than the corresponding
11859 ;; and/ior/xor operations when using immediate operand, so with
11860 ;; 32-bit there's no point. But in 64-bit, we can't hold the
11861 ;; relevant immediates within the instruction itself, so operating
11862 ;; on bits in the high 32-bits of a register becomes easier.
11864 ;; These are slow on Nocona, but fast on Athlon64. We do require the use
11865 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
11866 ;; negdf respectively, so they can never be disabled entirely.
11868 (define_insn "*btsq_imm"
11869 [(set (zero_extract:DI (match_operand:DI 0 "nonimmediate_operand" "+rm")
11871 (match_operand 1 "const_0_to_63_operand" "J"))
11873 (clobber (reg:CC FLAGS_REG))]
11874 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
11875 "bts{q}\t{%1, %0|%0, %1}"
11876 [(set_attr "type" "alu1")
11877 (set_attr "prefix_0f" "1")
11878 (set_attr "znver1_decode" "double")
11879 (set_attr "mode" "DI")])
11881 (define_insn "*btrq_imm"
11882 [(set (zero_extract:DI (match_operand:DI 0 "nonimmediate_operand" "+rm")
11884 (match_operand 1 "const_0_to_63_operand" "J"))
11886 (clobber (reg:CC FLAGS_REG))]
11887 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
11888 "btr{q}\t{%1, %0|%0, %1}"
11889 [(set_attr "type" "alu1")
11890 (set_attr "prefix_0f" "1")
11891 (set_attr "znver1_decode" "double")
11892 (set_attr "mode" "DI")])
11894 (define_insn "*btcq_imm"
11895 [(set (zero_extract:DI (match_operand:DI 0 "nonimmediate_operand" "+rm")
11897 (match_operand 1 "const_0_to_63_operand" "J"))
11898 (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
11899 (clobber (reg:CC FLAGS_REG))]
11900 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
11901 "btc{q}\t{%1, %0|%0, %1}"
11902 [(set_attr "type" "alu1")
11903 (set_attr "prefix_0f" "1")
11904 (set_attr "znver1_decode" "double")
11905 (set_attr "mode" "DI")])
11907 ;; Allow Nocona to avoid these instructions if a register is available.
11910 [(match_scratch:DI 2 "r")
11911 (parallel [(set (zero_extract:DI
11912 (match_operand:DI 0 "nonimmediate_operand")
11914 (match_operand 1 "const_0_to_63_operand"))
11916 (clobber (reg:CC FLAGS_REG))])]
11917 "TARGET_64BIT && !TARGET_USE_BT"
11918 [(parallel [(set (match_dup 0)
11919 (ior:DI (match_dup 0) (match_dup 3)))
11920 (clobber (reg:CC FLAGS_REG))])]
11922 int i = INTVAL (operands[1]);
11924 operands[3] = gen_int_mode (HOST_WIDE_INT_1U << i, DImode);
11926 if (!x86_64_immediate_operand (operands[3], DImode))
11928 emit_move_insn (operands[2], operands[3]);
11929 operands[3] = operands[2];
11934 [(match_scratch:DI 2 "r")
11935 (parallel [(set (zero_extract:DI
11936 (match_operand:DI 0 "nonimmediate_operand")
11938 (match_operand 1 "const_0_to_63_operand"))
11940 (clobber (reg:CC FLAGS_REG))])]
11941 "TARGET_64BIT && !TARGET_USE_BT"
11942 [(parallel [(set (match_dup 0)
11943 (and:DI (match_dup 0) (match_dup 3)))
11944 (clobber (reg:CC FLAGS_REG))])]
11946 int i = INTVAL (operands[1]);
11948 operands[3] = gen_int_mode (~(HOST_WIDE_INT_1U << i), DImode);
11950 if (!x86_64_immediate_operand (operands[3], DImode))
11952 emit_move_insn (operands[2], operands[3]);
11953 operands[3] = operands[2];
11958 [(match_scratch:DI 2 "r")
11959 (parallel [(set (zero_extract:DI
11960 (match_operand:DI 0 "nonimmediate_operand")
11962 (match_operand 1 "const_0_to_63_operand"))
11963 (not:DI (zero_extract:DI
11964 (match_dup 0) (const_int 1) (match_dup 1))))
11965 (clobber (reg:CC FLAGS_REG))])]
11966 "TARGET_64BIT && !TARGET_USE_BT"
11967 [(parallel [(set (match_dup 0)
11968 (xor:DI (match_dup 0) (match_dup 3)))
11969 (clobber (reg:CC FLAGS_REG))])]
11971 int i = INTVAL (operands[1]);
11973 operands[3] = gen_int_mode (HOST_WIDE_INT_1U << i, DImode);
11975 if (!x86_64_immediate_operand (operands[3], DImode))
11977 emit_move_insn (operands[2], operands[3]);
11978 operands[3] = operands[2];
11984 (define_insn "*bt<mode>"
11985 [(set (reg:CCC FLAGS_REG)
11987 (zero_extract:SWI48
11988 (match_operand:SWI48 0 "nonimmediate_operand" "r,m")
11990 (match_operand:SI 1 "nonmemory_operand" "r<S>,<S>"))
11994 switch (get_attr_mode (insn))
11997 return "bt{l}\t{%1, %k0|%k0, %1}";
12000 return "bt{q}\t{%q1, %0|%0, %q1}";
12003 gcc_unreachable ();
12006 [(set_attr "type" "alu1")
12007 (set_attr "prefix_0f" "1")
12010 (and (match_test "CONST_INT_P (operands[1])")
12011 (match_test "INTVAL (operands[1]) < 32"))
12012 (const_string "SI")
12013 (const_string "<MODE>")))])
12015 (define_insn_and_split "*jcc_bt<mode>"
12017 (if_then_else (match_operator 0 "bt_comparison_operator"
12018 [(zero_extract:SWI48
12019 (match_operand:SWI48 1 "nonimmediate_operand")
12021 (match_operand:SI 2 "nonmemory_operand"))
12023 (label_ref (match_operand 3))
12025 (clobber (reg:CC FLAGS_REG))]
12026 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
12027 && (CONST_INT_P (operands[2])
12028 ? (INTVAL (operands[2]) < GET_MODE_BITSIZE (<MODE>mode)
12029 && INTVAL (operands[2])
12030 >= (optimize_function_for_size_p (cfun) ? 8 : 32))
12031 : !memory_operand (operands[1], <MODE>mode))
12032 && can_create_pseudo_p ()"
12035 [(set (reg:CCC FLAGS_REG)
12037 (zero_extract:SWI48
12043 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
12044 (label_ref (match_dup 3))
12047 operands[0] = shallow_copy_rtx (operands[0]);
12048 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
12051 (define_insn_and_split "*jcc_bt<mode>_1"
12053 (if_then_else (match_operator 0 "bt_comparison_operator"
12054 [(zero_extract:SWI48
12055 (match_operand:SWI48 1 "register_operand")
12058 (match_operand:QI 2 "register_operand")))
12060 (label_ref (match_operand 3))
12062 (clobber (reg:CC FLAGS_REG))]
12063 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
12064 && can_create_pseudo_p ()"
12067 [(set (reg:CCC FLAGS_REG)
12069 (zero_extract:SWI48
12075 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
12076 (label_ref (match_dup 3))
12079 operands[2] = lowpart_subreg (SImode, operands[2], QImode);
12080 operands[0] = shallow_copy_rtx (operands[0]);
12081 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
12084 ;; Avoid useless masking of bit offset operand.
12085 (define_insn_and_split "*jcc_bt<mode>_mask"
12087 (if_then_else (match_operator 0 "bt_comparison_operator"
12088 [(zero_extract:SWI48
12089 (match_operand:SWI48 1 "register_operand")
12092 (match_operand:SI 2 "register_operand")
12093 (match_operand 3 "const_int_operand")))])
12094 (label_ref (match_operand 4))
12096 (clobber (reg:CC FLAGS_REG))]
12097 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
12098 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
12099 == GET_MODE_BITSIZE (<MODE>mode)-1
12100 && can_create_pseudo_p ()"
12103 [(set (reg:CCC FLAGS_REG)
12105 (zero_extract:SWI48
12111 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
12112 (label_ref (match_dup 4))
12115 operands[0] = shallow_copy_rtx (operands[0]);
12116 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
12119 ;; Store-flag instructions.
12121 ;; For all sCOND expanders, also expand the compare or test insn that
12122 ;; generates cc0. Generate an equality comparison if `seq' or `sne'.
12124 (define_insn_and_split "*setcc_di_1"
12125 [(set (match_operand:DI 0 "register_operand" "=q")
12126 (match_operator:DI 1 "ix86_comparison_operator"
12127 [(reg FLAGS_REG) (const_int 0)]))]
12128 "TARGET_64BIT && !TARGET_PARTIAL_REG_STALL"
12130 "&& reload_completed"
12131 [(set (match_dup 2) (match_dup 1))
12132 (set (match_dup 0) (zero_extend:DI (match_dup 2)))]
12134 operands[1] = shallow_copy_rtx (operands[1]);
12135 PUT_MODE (operands[1], QImode);
12136 operands[2] = gen_lowpart (QImode, operands[0]);
12139 (define_insn_and_split "*setcc_si_1_and"
12140 [(set (match_operand:SI 0 "register_operand" "=q")
12141 (match_operator:SI 1 "ix86_comparison_operator"
12142 [(reg FLAGS_REG) (const_int 0)]))
12143 (clobber (reg:CC FLAGS_REG))]
12144 "!TARGET_PARTIAL_REG_STALL
12145 && TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
12147 "&& reload_completed"
12148 [(set (match_dup 2) (match_dup 1))
12149 (parallel [(set (match_dup 0) (zero_extend:SI (match_dup 2)))
12150 (clobber (reg:CC FLAGS_REG))])]
12152 operands[1] = shallow_copy_rtx (operands[1]);
12153 PUT_MODE (operands[1], QImode);
12154 operands[2] = gen_lowpart (QImode, operands[0]);
12157 (define_insn_and_split "*setcc_si_1_movzbl"
12158 [(set (match_operand:SI 0 "register_operand" "=q")
12159 (match_operator:SI 1 "ix86_comparison_operator"
12160 [(reg FLAGS_REG) (const_int 0)]))]
12161 "!TARGET_PARTIAL_REG_STALL
12162 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
12164 "&& reload_completed"
12165 [(set (match_dup 2) (match_dup 1))
12166 (set (match_dup 0) (zero_extend:SI (match_dup 2)))]
12168 operands[1] = shallow_copy_rtx (operands[1]);
12169 PUT_MODE (operands[1], QImode);
12170 operands[2] = gen_lowpart (QImode, operands[0]);
12173 (define_insn "*setcc_qi"
12174 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12175 (match_operator:QI 1 "ix86_comparison_operator"
12176 [(reg FLAGS_REG) (const_int 0)]))]
12179 [(set_attr "type" "setcc")
12180 (set_attr "mode" "QI")])
12182 (define_insn "*setcc_qi_slp"
12183 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12184 (match_operator:QI 1 "ix86_comparison_operator"
12185 [(reg FLAGS_REG) (const_int 0)]))]
12188 [(set_attr "type" "setcc")
12189 (set_attr "mode" "QI")])
12191 ;; In general it is not safe to assume too much about CCmode registers,
12192 ;; so simplify-rtx stops when it sees a second one. Under certain
12193 ;; conditions this is safe on x86, so help combine not create
12200 [(set (match_operand:QI 0 "nonimmediate_operand")
12201 (ne:QI (match_operator 1 "ix86_comparison_operator"
12202 [(reg FLAGS_REG) (const_int 0)])
12205 [(set (match_dup 0) (match_dup 1))]
12207 operands[1] = shallow_copy_rtx (operands[1]);
12208 PUT_MODE (operands[1], QImode);
12212 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand"))
12213 (ne:QI (match_operator 1 "ix86_comparison_operator"
12214 [(reg FLAGS_REG) (const_int 0)])
12217 [(set (match_dup 0) (match_dup 1))]
12219 operands[1] = shallow_copy_rtx (operands[1]);
12220 PUT_MODE (operands[1], QImode);
12224 [(set (match_operand:QI 0 "nonimmediate_operand")
12225 (eq:QI (match_operator 1 "ix86_comparison_operator"
12226 [(reg FLAGS_REG) (const_int 0)])
12229 [(set (match_dup 0) (match_dup 1))]
12231 operands[1] = shallow_copy_rtx (operands[1]);
12232 PUT_MODE (operands[1], QImode);
12233 PUT_CODE (operands[1],
12234 ix86_reverse_condition (GET_CODE (operands[1]),
12235 GET_MODE (XEXP (operands[1], 0))));
12237 /* Make sure that (a) the CCmode we have for the flags is strong
12238 enough for the reversed compare or (b) we have a valid FP compare. */
12239 if (! ix86_comparison_operator (operands[1], VOIDmode))
12244 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand"))
12245 (eq:QI (match_operator 1 "ix86_comparison_operator"
12246 [(reg FLAGS_REG) (const_int 0)])
12249 [(set (match_dup 0) (match_dup 1))]
12251 operands[1] = shallow_copy_rtx (operands[1]);
12252 PUT_MODE (operands[1], QImode);
12253 PUT_CODE (operands[1],
12254 ix86_reverse_condition (GET_CODE (operands[1]),
12255 GET_MODE (XEXP (operands[1], 0))));
12257 /* Make sure that (a) the CCmode we have for the flags is strong
12258 enough for the reversed compare or (b) we have a valid FP compare. */
12259 if (! ix86_comparison_operator (operands[1], VOIDmode))
12263 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
12264 ;; subsequent logical operations are used to imitate conditional moves.
12265 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
12268 (define_insn "setcc_<mode>_sse"
12269 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
12270 (match_operator:MODEF 3 "sse_comparison_operator"
12271 [(match_operand:MODEF 1 "register_operand" "0,x")
12272 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
12273 "SSE_FLOAT_MODE_P (<MODE>mode)"
12275 cmp%D3<ssemodesuffix>\t{%2, %0|%0, %2}
12276 vcmp%D3<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
12277 [(set_attr "isa" "noavx,avx")
12278 (set_attr "type" "ssecmp")
12279 (set_attr "length_immediate" "1")
12280 (set_attr "prefix" "orig,vex")
12281 (set_attr "mode" "<MODE>")])
12283 ;; Basic conditional jump instructions.
12284 ;; We ignore the overflow flag for signed branch instructions.
12286 (define_insn "*jcc"
12288 (if_then_else (match_operator 1 "ix86_comparison_operator"
12289 [(reg FLAGS_REG) (const_int 0)])
12290 (label_ref (match_operand 0))
12294 [(set_attr "type" "ibr")
12295 (set_attr "modrm" "0")
12296 (set (attr "length")
12298 (and (ge (minus (match_dup 0) (pc))
12300 (lt (minus (match_dup 0) (pc))
12304 (set_attr "maybe_prefix_bnd" "1")])
12306 ;; In general it is not safe to assume too much about CCmode registers,
12307 ;; so simplify-rtx stops when it sees a second one. Under certain
12308 ;; conditions this is safe on x86, so help combine not create
12316 (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
12317 [(reg FLAGS_REG) (const_int 0)])
12319 (label_ref (match_operand 1))
12323 (if_then_else (match_dup 0)
12324 (label_ref (match_dup 1))
12327 operands[0] = shallow_copy_rtx (operands[0]);
12328 PUT_MODE (operands[0], VOIDmode);
12333 (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
12334 [(reg FLAGS_REG) (const_int 0)])
12336 (label_ref (match_operand 1))
12340 (if_then_else (match_dup 0)
12341 (label_ref (match_dup 1))
12344 operands[0] = shallow_copy_rtx (operands[0]);
12345 PUT_MODE (operands[0], VOIDmode);
12346 PUT_CODE (operands[0],
12347 ix86_reverse_condition (GET_CODE (operands[0]),
12348 GET_MODE (XEXP (operands[0], 0))));
12350 /* Make sure that (a) the CCmode we have for the flags is strong
12351 enough for the reversed compare or (b) we have a valid FP compare. */
12352 if (! ix86_comparison_operator (operands[0], VOIDmode))
12356 ;; Unconditional and other jump instructions
12358 (define_insn "jump"
12360 (label_ref (match_operand 0)))]
12363 [(set_attr "type" "ibr")
12364 (set_attr "modrm" "0")
12365 (set (attr "length")
12367 (and (ge (minus (match_dup 0) (pc))
12369 (lt (minus (match_dup 0) (pc))
12373 (set_attr "maybe_prefix_bnd" "1")])
12375 (define_expand "indirect_jump"
12376 [(set (pc) (match_operand 0 "indirect_branch_operand"))]
12379 if (TARGET_X32 || TARGET_INDIRECT_BRANCH_REGISTER)
12380 operands[0] = convert_memory_address (word_mode, operands[0]);
12381 cfun->machine->has_local_indirect_jump = true;
12384 (define_insn "*indirect_jump"
12385 [(set (pc) (match_operand:W 0 "indirect_branch_operand" "rBw"))]
12387 "* return ix86_output_indirect_jmp (operands[0]);"
12388 [(set (attr "type")
12389 (if_then_else (match_test "(cfun->machine->indirect_branch_type
12390 != indirect_branch_keep)")
12391 (const_string "multi")
12392 (const_string "ibr")))
12393 (set_attr "length_immediate" "0")
12394 (set_attr "maybe_prefix_bnd" "1")])
12396 (define_expand "tablejump"
12397 [(parallel [(set (pc) (match_operand 0 "indirect_branch_operand"))
12398 (use (label_ref (match_operand 1)))])]
12401 /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
12402 relative. Convert the relative address to an absolute address. */
12406 enum rtx_code code;
12408 /* We can't use @GOTOFF for text labels on VxWorks;
12409 see gotoff_operand. */
12410 if (TARGET_64BIT || TARGET_VXWORKS_RTP)
12414 op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
12416 else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
12420 op1 = pic_offset_table_rtx;
12425 op0 = pic_offset_table_rtx;
12429 operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
12433 if (TARGET_X32 || TARGET_INDIRECT_BRANCH_REGISTER)
12434 operands[0] = convert_memory_address (word_mode, operands[0]);
12435 cfun->machine->has_local_indirect_jump = true;
12438 (define_insn "*tablejump_1"
12439 [(set (pc) (match_operand:W 0 "indirect_branch_operand" "rBw"))
12440 (use (label_ref (match_operand 1)))]
12442 "* return ix86_output_indirect_jmp (operands[0]);"
12443 [(set (attr "type")
12444 (if_then_else (match_test "(cfun->machine->indirect_branch_type
12445 != indirect_branch_keep)")
12446 (const_string "multi")
12447 (const_string "ibr")))
12448 (set_attr "length_immediate" "0")
12449 (set_attr "maybe_prefix_bnd" "1")])
12451 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
12454 [(set (reg FLAGS_REG) (match_operand 0))
12455 (set (match_operand:QI 1 "register_operand")
12456 (match_operator:QI 2 "ix86_comparison_operator"
12457 [(reg FLAGS_REG) (const_int 0)]))
12458 (set (match_operand 3 "any_QIreg_operand")
12459 (zero_extend (match_dup 1)))]
12460 "(peep2_reg_dead_p (3, operands[1])
12461 || operands_match_p (operands[1], operands[3]))
12462 && ! reg_overlap_mentioned_p (operands[3], operands[0])
12463 && peep2_regno_dead_p (0, FLAGS_REG)"
12464 [(set (match_dup 4) (match_dup 0))
12465 (set (strict_low_part (match_dup 5))
12468 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
12469 operands[5] = gen_lowpart (QImode, operands[3]);
12470 ix86_expand_clear (operands[3]);
12474 [(parallel [(set (reg FLAGS_REG) (match_operand 0))
12475 (match_operand 4)])
12476 (set (match_operand:QI 1 "register_operand")
12477 (match_operator:QI 2 "ix86_comparison_operator"
12478 [(reg FLAGS_REG) (const_int 0)]))
12479 (set (match_operand 3 "any_QIreg_operand")
12480 (zero_extend (match_dup 1)))]
12481 "(peep2_reg_dead_p (3, operands[1])
12482 || operands_match_p (operands[1], operands[3]))
12483 && ! reg_overlap_mentioned_p (operands[3], operands[0])
12484 && ! reg_set_p (operands[3], operands[4])
12485 && peep2_regno_dead_p (0, FLAGS_REG)"
12486 [(parallel [(set (match_dup 5) (match_dup 0))
12488 (set (strict_low_part (match_dup 6))
12491 operands[5] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
12492 operands[6] = gen_lowpart (QImode, operands[3]);
12493 ix86_expand_clear (operands[3]);
12497 [(set (reg FLAGS_REG) (match_operand 0))
12498 (parallel [(set (reg FLAGS_REG) (match_operand 1))
12499 (match_operand 5)])
12500 (set (match_operand:QI 2 "register_operand")
12501 (match_operator:QI 3 "ix86_comparison_operator"
12502 [(reg FLAGS_REG) (const_int 0)]))
12503 (set (match_operand 4 "any_QIreg_operand")
12504 (zero_extend (match_dup 2)))]
12505 "(peep2_reg_dead_p (4, operands[2])
12506 || operands_match_p (operands[2], operands[4]))
12507 && ! reg_overlap_mentioned_p (operands[4], operands[0])
12508 && ! reg_overlap_mentioned_p (operands[4], operands[1])
12509 && ! reg_set_p (operands[4], operands[5])
12510 && refers_to_regno_p (FLAGS_REG, operands[1], (rtx *)NULL)
12511 && peep2_regno_dead_p (0, FLAGS_REG)"
12512 [(set (match_dup 6) (match_dup 0))
12513 (parallel [(set (match_dup 7) (match_dup 1))
12515 (set (strict_low_part (match_dup 8))
12518 operands[6] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
12519 operands[7] = gen_rtx_REG (GET_MODE (operands[1]), FLAGS_REG);
12520 operands[8] = gen_lowpart (QImode, operands[4]);
12521 ix86_expand_clear (operands[4]);
12524 ;; Similar, but match zero extend with andsi3.
12527 [(set (reg FLAGS_REG) (match_operand 0))
12528 (set (match_operand:QI 1 "register_operand")
12529 (match_operator:QI 2 "ix86_comparison_operator"
12530 [(reg FLAGS_REG) (const_int 0)]))
12531 (parallel [(set (match_operand:SI 3 "any_QIreg_operand")
12532 (and:SI (match_dup 3) (const_int 255)))
12533 (clobber (reg:CC FLAGS_REG))])]
12534 "REGNO (operands[1]) == REGNO (operands[3])
12535 && ! reg_overlap_mentioned_p (operands[3], operands[0])
12536 && peep2_regno_dead_p (0, FLAGS_REG)"
12537 [(set (match_dup 4) (match_dup 0))
12538 (set (strict_low_part (match_dup 5))
12541 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
12542 operands[5] = gen_lowpart (QImode, operands[3]);
12543 ix86_expand_clear (operands[3]);
12547 [(parallel [(set (reg FLAGS_REG) (match_operand 0))
12548 (match_operand 4)])
12549 (set (match_operand:QI 1 "register_operand")
12550 (match_operator:QI 2 "ix86_comparison_operator"
12551 [(reg FLAGS_REG) (const_int 0)]))
12552 (parallel [(set (match_operand 3 "any_QIreg_operand")
12553 (zero_extend (match_dup 1)))
12554 (clobber (reg:CC FLAGS_REG))])]
12555 "(peep2_reg_dead_p (3, operands[1])
12556 || operands_match_p (operands[1], operands[3]))
12557 && ! reg_overlap_mentioned_p (operands[3], operands[0])
12558 && ! reg_set_p (operands[3], operands[4])
12559 && peep2_regno_dead_p (0, FLAGS_REG)"
12560 [(parallel [(set (match_dup 5) (match_dup 0))
12562 (set (strict_low_part (match_dup 6))
12565 operands[5] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
12566 operands[6] = gen_lowpart (QImode, operands[3]);
12567 ix86_expand_clear (operands[3]);
12571 [(set (reg FLAGS_REG) (match_operand 0))
12572 (parallel [(set (reg FLAGS_REG) (match_operand 1))
12573 (match_operand 5)])
12574 (set (match_operand:QI 2 "register_operand")
12575 (match_operator:QI 3 "ix86_comparison_operator"
12576 [(reg FLAGS_REG) (const_int 0)]))
12577 (parallel [(set (match_operand 4 "any_QIreg_operand")
12578 (zero_extend (match_dup 2)))
12579 (clobber (reg:CC FLAGS_REG))])]
12580 "(peep2_reg_dead_p (4, operands[2])
12581 || operands_match_p (operands[2], operands[4]))
12582 && ! reg_overlap_mentioned_p (operands[4], operands[0])
12583 && ! reg_overlap_mentioned_p (operands[4], operands[1])
12584 && ! reg_set_p (operands[4], operands[5])
12585 && refers_to_regno_p (FLAGS_REG, operands[1], (rtx *)NULL)
12586 && peep2_regno_dead_p (0, FLAGS_REG)"
12587 [(set (match_dup 6) (match_dup 0))
12588 (parallel [(set (match_dup 7) (match_dup 1))
12590 (set (strict_low_part (match_dup 8))
12593 operands[6] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
12594 operands[7] = gen_rtx_REG (GET_MODE (operands[1]), FLAGS_REG);
12595 operands[8] = gen_lowpart (QImode, operands[4]);
12596 ix86_expand_clear (operands[4]);
12599 ;; Call instructions.
12601 ;; The predicates normally associated with named expanders are not properly
12602 ;; checked for calls. This is a bug in the generic code, but it isn't that
12603 ;; easy to fix. Ignore it for now and be prepared to fix things up.
12605 ;; P6 processors will jump to the address after the decrement when %esp
12606 ;; is used as a call operand, so they will execute return address as a code.
12607 ;; See Pentium Pro errata 70, Pentium 2 errata A33 and Pentium 3 errata E17.
12609 ;; Register constraint for call instruction.
12610 (define_mode_attr c [(SI "l") (DI "r")])
12612 ;; Call subroutine returning no value.
12614 (define_expand "call"
12615 [(call (match_operand:QI 0)
12617 (use (match_operand 2))]
12620 ix86_expand_call (NULL, operands[0], operands[1],
12621 operands[2], NULL, false);
12625 (define_expand "sibcall"
12626 [(call (match_operand:QI 0)
12628 (use (match_operand 2))]
12631 ix86_expand_call (NULL, operands[0], operands[1],
12632 operands[2], NULL, true);
12636 (define_insn "*call"
12637 [(call (mem:QI (match_operand:W 0 "call_insn_operand" "<c>BwBz"))
12638 (match_operand 1))]
12639 "!SIBLING_CALL_P (insn)"
12640 "* return ix86_output_call_insn (insn, operands[0]);"
12641 [(set_attr "type" "call")])
12643 ;; This covers both call and sibcall since only GOT slot is allowed.
12644 (define_insn "*call_got_x32"
12645 [(call (mem:QI (zero_extend:DI
12646 (match_operand:SI 0 "GOT_memory_operand" "Bg")))
12647 (match_operand 1))]
12650 rtx fnaddr = gen_const_mem (DImode, XEXP (operands[0], 0));
12651 return ix86_output_call_insn (insn, fnaddr);
12653 [(set_attr "type" "call")])
12655 ;; Since sibcall never returns, we can only use call-clobbered register
12657 (define_insn "*sibcall_GOT_32"
12660 (match_operand:SI 0 "register_no_elim_operand" "U")
12661 (match_operand:SI 1 "GOT32_symbol_operand"))))
12662 (match_operand 2))]
12665 && !TARGET_INDIRECT_BRANCH_REGISTER
12666 && SIBLING_CALL_P (insn)"
12668 rtx fnaddr = gen_rtx_PLUS (SImode, operands[0], operands[1]);
12669 fnaddr = gen_const_mem (SImode, fnaddr);
12670 return ix86_output_call_insn (insn, fnaddr);
12672 [(set_attr "type" "call")])
12674 (define_insn "*sibcall"
12675 [(call (mem:QI (match_operand:W 0 "sibcall_insn_operand" "UBsBz"))
12676 (match_operand 1))]
12677 "SIBLING_CALL_P (insn)"
12678 "* return ix86_output_call_insn (insn, operands[0]);"
12679 [(set_attr "type" "call")])
12681 (define_insn "*sibcall_memory"
12682 [(call (mem:QI (match_operand:W 0 "memory_operand" "m"))
12684 (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
12685 "!TARGET_X32 && !TARGET_INDIRECT_BRANCH_REGISTER"
12686 "* return ix86_output_call_insn (insn, operands[0]);"
12687 [(set_attr "type" "call")])
12690 [(set (match_operand:W 0 "register_operand")
12691 (match_operand:W 1 "memory_operand"))
12692 (call (mem:QI (match_dup 0))
12693 (match_operand 3))]
12695 && !TARGET_INDIRECT_BRANCH_REGISTER
12696 && SIBLING_CALL_P (peep2_next_insn (1))
12697 && !reg_mentioned_p (operands[0],
12698 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (1)))"
12699 [(parallel [(call (mem:QI (match_dup 1))
12701 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
12704 [(set (match_operand:W 0 "register_operand")
12705 (match_operand:W 1 "memory_operand"))
12706 (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
12707 (call (mem:QI (match_dup 0))
12708 (match_operand 3))]
12710 && !TARGET_INDIRECT_BRANCH_REGISTER
12711 && SIBLING_CALL_P (peep2_next_insn (2))
12712 && !reg_mentioned_p (operands[0],
12713 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (2)))"
12714 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
12715 (parallel [(call (mem:QI (match_dup 1))
12717 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
12719 (define_expand "call_pop"
12720 [(parallel [(call (match_operand:QI 0)
12721 (match_operand:SI 1))
12722 (set (reg:SI SP_REG)
12723 (plus:SI (reg:SI SP_REG)
12724 (match_operand:SI 3)))])]
12727 ix86_expand_call (NULL, operands[0], operands[1],
12728 operands[2], operands[3], false);
12732 (define_insn "*call_pop"
12733 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lBwBz"))
12735 (set (reg:SI SP_REG)
12736 (plus:SI (reg:SI SP_REG)
12737 (match_operand:SI 2 "immediate_operand" "i")))]
12738 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
12739 "* return ix86_output_call_insn (insn, operands[0]);"
12740 [(set_attr "type" "call")])
12742 (define_insn "*sibcall_pop"
12743 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "UBsBz"))
12745 (set (reg:SI SP_REG)
12746 (plus:SI (reg:SI SP_REG)
12747 (match_operand:SI 2 "immediate_operand" "i")))]
12748 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
12749 "* return ix86_output_call_insn (insn, operands[0]);"
12750 [(set_attr "type" "call")])
12752 (define_insn "*sibcall_pop_memory"
12753 [(call (mem:QI (match_operand:SI 0 "memory_operand" "Bs"))
12755 (set (reg:SI SP_REG)
12756 (plus:SI (reg:SI SP_REG)
12757 (match_operand:SI 2 "immediate_operand" "i")))
12758 (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
12760 "* return ix86_output_call_insn (insn, operands[0]);"
12761 [(set_attr "type" "call")])
12764 [(set (match_operand:SI 0 "register_operand")
12765 (match_operand:SI 1 "memory_operand"))
12766 (parallel [(call (mem:QI (match_dup 0))
12768 (set (reg:SI SP_REG)
12769 (plus:SI (reg:SI SP_REG)
12770 (match_operand:SI 4 "immediate_operand")))])]
12771 "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (1))
12772 && !reg_mentioned_p (operands[0],
12773 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (1)))"
12774 [(parallel [(call (mem:QI (match_dup 1))
12776 (set (reg:SI SP_REG)
12777 (plus:SI (reg:SI SP_REG)
12779 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
12782 [(set (match_operand:SI 0 "register_operand")
12783 (match_operand:SI 1 "memory_operand"))
12784 (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
12785 (parallel [(call (mem:QI (match_dup 0))
12787 (set (reg:SI SP_REG)
12788 (plus:SI (reg:SI SP_REG)
12789 (match_operand:SI 4 "immediate_operand")))])]
12790 "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (2))
12791 && !reg_mentioned_p (operands[0],
12792 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (2)))"
12793 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
12794 (parallel [(call (mem:QI (match_dup 1))
12796 (set (reg:SI SP_REG)
12797 (plus:SI (reg:SI SP_REG)
12799 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
12801 ;; Combining simple memory jump instruction
12804 [(set (match_operand:W 0 "register_operand")
12805 (match_operand:W 1 "memory_operand"))
12806 (set (pc) (match_dup 0))]
12808 && !TARGET_INDIRECT_BRANCH_REGISTER
12809 && peep2_reg_dead_p (2, operands[0])"
12810 [(set (pc) (match_dup 1))])
12812 ;; Call subroutine, returning value in operand 0
12814 (define_expand "call_value"
12815 [(set (match_operand 0)
12816 (call (match_operand:QI 1)
12817 (match_operand 2)))
12818 (use (match_operand 3))]
12821 ix86_expand_call (operands[0], operands[1], operands[2],
12822 operands[3], NULL, false);
12826 (define_expand "sibcall_value"
12827 [(set (match_operand 0)
12828 (call (match_operand:QI 1)
12829 (match_operand 2)))
12830 (use (match_operand 3))]
12833 ix86_expand_call (operands[0], operands[1], operands[2],
12834 operands[3], NULL, true);
12838 (define_insn "*call_value"
12839 [(set (match_operand 0)
12840 (call (mem:QI (match_operand:W 1 "call_insn_operand" "<c>BwBz"))
12841 (match_operand 2)))]
12842 "!SIBLING_CALL_P (insn)"
12843 "* return ix86_output_call_insn (insn, operands[1]);"
12844 [(set_attr "type" "callv")])
12846 ;; This covers both call and sibcall since only GOT slot is allowed.
12847 (define_insn "*call_value_got_x32"
12848 [(set (match_operand 0)
12851 (match_operand:SI 1 "GOT_memory_operand" "Bg")))
12852 (match_operand 2)))]
12855 rtx fnaddr = gen_const_mem (DImode, XEXP (operands[1], 0));
12856 return ix86_output_call_insn (insn, fnaddr);
12858 [(set_attr "type" "callv")])
12860 ;; Since sibcall never returns, we can only use call-clobbered register
12862 (define_insn "*sibcall_value_GOT_32"
12863 [(set (match_operand 0)
12866 (match_operand:SI 1 "register_no_elim_operand" "U")
12867 (match_operand:SI 2 "GOT32_symbol_operand"))))
12868 (match_operand 3)))]
12871 && !TARGET_INDIRECT_BRANCH_REGISTER
12872 && SIBLING_CALL_P (insn)"
12874 rtx fnaddr = gen_rtx_PLUS (SImode, operands[1], operands[2]);
12875 fnaddr = gen_const_mem (SImode, fnaddr);
12876 return ix86_output_call_insn (insn, fnaddr);
12878 [(set_attr "type" "callv")])
12880 (define_insn "*sibcall_value"
12881 [(set (match_operand 0)
12882 (call (mem:QI (match_operand:W 1 "sibcall_insn_operand" "UBsBz"))
12883 (match_operand 2)))]
12884 "SIBLING_CALL_P (insn)"
12885 "* return ix86_output_call_insn (insn, operands[1]);"
12886 [(set_attr "type" "callv")])
12888 (define_insn "*sibcall_value_memory"
12889 [(set (match_operand 0)
12890 (call (mem:QI (match_operand:W 1 "memory_operand" "m"))
12891 (match_operand 2)))
12892 (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
12893 "!TARGET_X32 && !TARGET_INDIRECT_BRANCH_REGISTER"
12894 "* return ix86_output_call_insn (insn, operands[1]);"
12895 [(set_attr "type" "callv")])
12898 [(set (match_operand:W 0 "register_operand")
12899 (match_operand:W 1 "memory_operand"))
12900 (set (match_operand 2)
12901 (call (mem:QI (match_dup 0))
12902 (match_operand 3)))]
12904 && !TARGET_INDIRECT_BRANCH_REGISTER
12905 && SIBLING_CALL_P (peep2_next_insn (1))
12906 && !reg_mentioned_p (operands[0],
12907 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (1)))"
12908 [(parallel [(set (match_dup 2)
12909 (call (mem:QI (match_dup 1))
12911 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
12914 [(set (match_operand:W 0 "register_operand")
12915 (match_operand:W 1 "memory_operand"))
12916 (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
12917 (set (match_operand 2)
12918 (call (mem:QI (match_dup 0))
12919 (match_operand 3)))]
12921 && !TARGET_INDIRECT_BRANCH_REGISTER
12922 && SIBLING_CALL_P (peep2_next_insn (2))
12923 && !reg_mentioned_p (operands[0],
12924 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (2)))"
12925 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
12926 (parallel [(set (match_dup 2)
12927 (call (mem:QI (match_dup 1))
12929 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
12931 (define_expand "call_value_pop"
12932 [(parallel [(set (match_operand 0)
12933 (call (match_operand:QI 1)
12934 (match_operand:SI 2)))
12935 (set (reg:SI SP_REG)
12936 (plus:SI (reg:SI SP_REG)
12937 (match_operand:SI 4)))])]
12940 ix86_expand_call (operands[0], operands[1], operands[2],
12941 operands[3], operands[4], false);
12945 (define_insn "*call_value_pop"
12946 [(set (match_operand 0)
12947 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lBwBz"))
12948 (match_operand 2)))
12949 (set (reg:SI SP_REG)
12950 (plus:SI (reg:SI SP_REG)
12951 (match_operand:SI 3 "immediate_operand" "i")))]
12952 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
12953 "* return ix86_output_call_insn (insn, operands[1]);"
12954 [(set_attr "type" "callv")])
12956 (define_insn "*sibcall_value_pop"
12957 [(set (match_operand 0)
12958 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "UBsBz"))
12959 (match_operand 2)))
12960 (set (reg:SI SP_REG)
12961 (plus:SI (reg:SI SP_REG)
12962 (match_operand:SI 3 "immediate_operand" "i")))]
12963 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
12964 "* return ix86_output_call_insn (insn, operands[1]);"
12965 [(set_attr "type" "callv")])
12967 (define_insn "*sibcall_value_pop_memory"
12968 [(set (match_operand 0)
12969 (call (mem:QI (match_operand:SI 1 "memory_operand" "m"))
12970 (match_operand 2)))
12971 (set (reg:SI SP_REG)
12972 (plus:SI (reg:SI SP_REG)
12973 (match_operand:SI 3 "immediate_operand" "i")))
12974 (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
12976 "* return ix86_output_call_insn (insn, operands[1]);"
12977 [(set_attr "type" "callv")])
12980 [(set (match_operand:SI 0 "register_operand")
12981 (match_operand:SI 1 "memory_operand"))
12982 (parallel [(set (match_operand 2)
12983 (call (mem:QI (match_dup 0))
12984 (match_operand 3)))
12985 (set (reg:SI SP_REG)
12986 (plus:SI (reg:SI SP_REG)
12987 (match_operand:SI 4 "immediate_operand")))])]
12988 "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (1))
12989 && !reg_mentioned_p (operands[0],
12990 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (1)))"
12991 [(parallel [(set (match_dup 2)
12992 (call (mem:QI (match_dup 1))
12994 (set (reg:SI SP_REG)
12995 (plus:SI (reg:SI SP_REG)
12997 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
13000 [(set (match_operand:SI 0 "register_operand")
13001 (match_operand:SI 1 "memory_operand"))
13002 (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
13003 (parallel [(set (match_operand 2)
13004 (call (mem:QI (match_dup 0))
13005 (match_operand 3)))
13006 (set (reg:SI SP_REG)
13007 (plus:SI (reg:SI SP_REG)
13008 (match_operand:SI 4 "immediate_operand")))])]
13009 "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (2))
13010 && !reg_mentioned_p (operands[0],
13011 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (2)))"
13012 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
13013 (parallel [(set (match_dup 2)
13014 (call (mem:QI (match_dup 1))
13016 (set (reg:SI SP_REG)
13017 (plus:SI (reg:SI SP_REG)
13019 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
13021 ;; Call subroutine returning any type.
13023 (define_expand "untyped_call"
13024 [(parallel [(call (match_operand 0)
13027 (match_operand 2)])]
13032 /* In order to give reg-stack an easier job in validating two
13033 coprocessor registers as containing a possible return value,
13034 simply pretend the untyped call returns a complex long double
13037 We can't use SSE_REGPARM_MAX here since callee is unprototyped
13038 and should have the default ABI. */
13040 ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
13041 ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
13042 operands[0], const0_rtx,
13043 GEN_INT ((TARGET_64BIT
13044 ? (ix86_abi == SYSV_ABI
13045 ? X86_64_SSE_REGPARM_MAX
13046 : X86_64_MS_SSE_REGPARM_MAX)
13047 : X86_32_SSE_REGPARM_MAX)
13051 for (i = 0; i < XVECLEN (operands[2], 0); i++)
13053 rtx set = XVECEXP (operands[2], 0, i);
13054 emit_move_insn (SET_DEST (set), SET_SRC (set));
13057 /* The optimizer does not know that the call sets the function value
13058 registers we stored in the result block. We avoid problems by
13059 claiming that all hard registers are used and clobbered at this
13061 emit_insn (gen_blockage ());
13066 ;; Prologue and epilogue instructions
13068 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
13069 ;; all of memory. This blocks insns from being moved across this point.
13071 (define_insn "blockage"
13072 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
13075 [(set_attr "length" "0")])
13077 ;; Do not schedule instructions accessing memory across this point.
13079 (define_expand "memory_blockage"
13080 [(set (match_dup 0)
13081 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
13084 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
13085 MEM_VOLATILE_P (operands[0]) = 1;
13088 (define_insn "*memory_blockage"
13089 [(set (match_operand:BLK 0)
13090 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
13093 [(set_attr "length" "0")])
13095 ;; As USE insns aren't meaningful after reload, this is used instead
13096 ;; to prevent deleting instructions setting registers for PIC code
13097 (define_insn "prologue_use"
13098 [(unspec_volatile [(match_operand 0)] UNSPECV_PROLOGUE_USE)]
13101 [(set_attr "length" "0")])
13103 ;; Insn emitted into the body of a function to return from a function.
13104 ;; This is only done if the function's epilogue is known to be simple.
13105 ;; See comments for ix86_can_use_return_insn_p in i386.c.
13107 (define_expand "return"
13109 "ix86_can_use_return_insn_p ()"
13111 if (crtl->args.pops_args)
13113 rtx popc = GEN_INT (crtl->args.pops_args);
13114 emit_jump_insn (gen_simple_return_pop_internal (popc));
13119 ;; We need to disable this for TARGET_SEH, as otherwise
13120 ;; shrink-wrapped prologue gets enabled too. This might exceed
13121 ;; the maximum size of prologue in unwind information.
13122 ;; Also disallow shrink-wrapping if using stack slot to pass the
13123 ;; static chain pointer - the first instruction has to be pushl %esi
13124 ;; and it can't be moved around, as we use alternate entry points
13127 (define_expand "simple_return"
13129 "!TARGET_SEH && !ix86_static_chain_on_stack"
13131 if (crtl->args.pops_args)
13133 rtx popc = GEN_INT (crtl->args.pops_args);
13134 emit_jump_insn (gen_simple_return_pop_internal (popc));
13139 (define_insn "simple_return_internal"
13142 "* return ix86_output_function_return (false);"
13143 [(set_attr "length" "1")
13144 (set_attr "atom_unit" "jeu")
13145 (set_attr "length_immediate" "0")
13146 (set_attr "modrm" "0")
13147 (set_attr "maybe_prefix_bnd" "1")])
13149 (define_insn "interrupt_return"
13151 (unspec [(const_int 0)] UNSPEC_INTERRUPT_RETURN)]
13154 return TARGET_64BIT ? "iretq" : "iret";
13157 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
13158 ;; instruction Athlon and K8 have.
13160 (define_insn "simple_return_internal_long"
13162 (unspec [(const_int 0)] UNSPEC_REP)]
13164 "* return ix86_output_function_return (true);"
13165 [(set_attr "length" "2")
13166 (set_attr "atom_unit" "jeu")
13167 (set_attr "length_immediate" "0")
13168 (set_attr "prefix_rep" "1")
13169 (set_attr "modrm" "0")])
13171 (define_insn_and_split "simple_return_pop_internal"
13173 (use (match_operand:SI 0 "const_int_operand"))]
13176 "&& cfun->machine->function_return_type != indirect_branch_keep"
13178 "ix86_split_simple_return_pop_internal (operands[0]); DONE;"
13179 [(set_attr "length" "3")
13180 (set_attr "atom_unit" "jeu")
13181 (set_attr "length_immediate" "2")
13182 (set_attr "modrm" "0")
13183 (set_attr "maybe_prefix_bnd" "1")])
13185 (define_insn "simple_return_indirect_internal"
13187 (use (match_operand 0 "register_operand" "r"))]
13189 "* return ix86_output_indirect_function_return (operands[0]);"
13190 [(set (attr "type")
13191 (if_then_else (match_test "(cfun->machine->indirect_branch_type
13192 != indirect_branch_keep)")
13193 (const_string "multi")
13194 (const_string "ibr")))
13195 (set_attr "length_immediate" "0")
13196 (set_attr "maybe_prefix_bnd" "1")])
13202 [(set_attr "length" "1")
13203 (set_attr "length_immediate" "0")
13204 (set_attr "modrm" "0")])
13206 ;; Generate nops. Operand 0 is the number of nops, up to 8.
13207 (define_insn "nops"
13208 [(unspec_volatile [(match_operand 0 "const_int_operand")]
13212 int num = INTVAL (operands[0]);
13214 gcc_assert (IN_RANGE (num, 1, 8));
13217 fputs ("\tnop\n", asm_out_file);
13221 [(set (attr "length") (symbol_ref "INTVAL (operands[0])"))
13222 (set_attr "length_immediate" "0")
13223 (set_attr "modrm" "0")])
13225 ;; Pad to 16-byte boundary, max skip in op0. Used to avoid
13226 ;; branch prediction penalty for the third jump in a 16-byte
13230 [(unspec_volatile [(match_operand 0)] UNSPECV_ALIGN)]
13233 #ifdef ASM_OUTPUT_MAX_SKIP_PAD
13234 ASM_OUTPUT_MAX_SKIP_PAD (asm_out_file, 4, (int)INTVAL (operands[0]));
13236 /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
13237 The align insn is used to avoid 3 jump instructions in the row to improve
13238 branch prediction and the benefits hardly outweigh the cost of extra 8
13239 nops on the average inserted by full alignment pseudo operation. */
13243 [(set_attr "length" "16")])
13245 (define_expand "prologue"
13248 "ix86_expand_prologue (); DONE;")
13250 (define_expand "set_got"
13252 [(set (match_operand:SI 0 "register_operand")
13253 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
13254 (clobber (reg:CC FLAGS_REG))])]
13257 if (flag_pic && !TARGET_VXWORKS_RTP)
13258 ix86_pc_thunk_call_expanded = true;
13261 (define_insn "*set_got"
13262 [(set (match_operand:SI 0 "register_operand" "=r")
13263 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
13264 (clobber (reg:CC FLAGS_REG))]
13266 "* return output_set_got (operands[0], NULL_RTX);"
13267 [(set_attr "type" "multi")
13268 (set_attr "length" "12")])
13270 (define_expand "set_got_labelled"
13272 [(set (match_operand:SI 0 "register_operand")
13273 (unspec:SI [(label_ref (match_operand 1))]
13275 (clobber (reg:CC FLAGS_REG))])]
13278 if (flag_pic && !TARGET_VXWORKS_RTP)
13279 ix86_pc_thunk_call_expanded = true;
13282 (define_insn "*set_got_labelled"
13283 [(set (match_operand:SI 0 "register_operand" "=r")
13284 (unspec:SI [(label_ref (match_operand 1))]
13286 (clobber (reg:CC FLAGS_REG))]
13288 "* return output_set_got (operands[0], operands[1]);"
13289 [(set_attr "type" "multi")
13290 (set_attr "length" "12")])
13292 (define_insn "set_got_rex64"
13293 [(set (match_operand:DI 0 "register_operand" "=r")
13294 (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
13296 "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}"
13297 [(set_attr "type" "lea")
13298 (set_attr "length_address" "4")
13299 (set_attr "modrm_class" "unknown")
13300 (set_attr "mode" "DI")])
13302 (define_insn "set_rip_rex64"
13303 [(set (match_operand:DI 0 "register_operand" "=r")
13304 (unspec:DI [(label_ref (match_operand 1))] UNSPEC_SET_RIP))]
13306 "lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}"
13307 [(set_attr "type" "lea")
13308 (set_attr "length_address" "4")
13309 (set_attr "mode" "DI")])
13311 (define_insn "set_got_offset_rex64"
13312 [(set (match_operand:DI 0 "register_operand" "=r")
13314 [(label_ref (match_operand 1))]
13315 UNSPEC_SET_GOT_OFFSET))]
13317 "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}"
13318 [(set_attr "type" "imov")
13319 (set_attr "length_immediate" "0")
13320 (set_attr "length_address" "8")
13321 (set_attr "mode" "DI")])
13323 (define_expand "epilogue"
13326 "ix86_expand_epilogue (1); DONE;")
13328 (define_expand "sibcall_epilogue"
13331 "ix86_expand_epilogue (0); DONE;")
13333 (define_expand "eh_return"
13334 [(use (match_operand 0 "register_operand"))]
13337 rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
13339 /* Tricky bit: we write the address of the handler to which we will
13340 be returning into someone else's stack frame, one word below the
13341 stack address we wish to restore. */
13342 tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
13343 tmp = plus_constant (Pmode, tmp, -UNITS_PER_WORD);
13344 tmp = gen_rtx_MEM (Pmode, tmp);
13345 emit_move_insn (tmp, ra);
13347 emit_jump_insn (gen_eh_return_internal ());
13352 (define_insn_and_split "eh_return_internal"
13356 "epilogue_completed"
13358 "ix86_expand_epilogue (2); DONE;")
13360 (define_insn "leave"
13361 [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
13362 (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
13363 (clobber (mem:BLK (scratch)))]
13366 [(set_attr "type" "leave")])
13368 (define_insn "leave_rex64"
13369 [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
13370 (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
13371 (clobber (mem:BLK (scratch)))]
13374 [(set_attr "type" "leave")])
13376 ;; Handle -fsplit-stack.
13378 (define_expand "split_stack_prologue"
13382 ix86_expand_split_stack_prologue ();
13386 ;; In order to support the call/return predictor, we use a return
13387 ;; instruction which the middle-end doesn't see.
13388 (define_insn "split_stack_return"
13389 [(unspec_volatile [(match_operand:SI 0 "const_int_operand")]
13390 UNSPECV_SPLIT_STACK_RETURN)]
13393 if (operands[0] == const0_rtx)
13398 [(set_attr "atom_unit" "jeu")
13399 (set_attr "modrm" "0")
13400 (set (attr "length")
13401 (if_then_else (match_operand:SI 0 "const0_operand")
13404 (set (attr "length_immediate")
13405 (if_then_else (match_operand:SI 0 "const0_operand")
13409 ;; If there are operand 0 bytes available on the stack, jump to
13412 (define_expand "split_stack_space_check"
13413 [(set (pc) (if_then_else
13414 (ltu (minus (reg SP_REG)
13415 (match_operand 0 "register_operand"))
13417 (label_ref (match_operand 1))
13421 rtx reg = gen_reg_rtx (Pmode);
13423 emit_insn (gen_sub3_insn (reg, stack_pointer_rtx, operands[0]));
13425 operands[2] = ix86_split_stack_guard ();
13426 ix86_expand_branch (GEU, reg, operands[2], operands[1]);
13431 ;; Bit manipulation instructions.
13433 (define_expand "ffs<mode>2"
13434 [(set (match_dup 2) (const_int -1))
13435 (parallel [(set (match_dup 3) (match_dup 4))
13436 (set (match_operand:SWI48 0 "register_operand")
13438 (match_operand:SWI48 1 "nonimmediate_operand")))])
13439 (set (match_dup 0) (if_then_else:SWI48
13440 (eq (match_dup 3) (const_int 0))
13443 (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (const_int 1)))
13444 (clobber (reg:CC FLAGS_REG))])]
13447 machine_mode flags_mode;
13449 if (<MODE>mode == SImode && !TARGET_CMOVE)
13451 emit_insn (gen_ffssi2_no_cmove (operands[0], operands [1]));
13455 flags_mode = TARGET_BMI ? CCCmode : CCZmode;
13457 operands[2] = gen_reg_rtx (<MODE>mode);
13458 operands[3] = gen_rtx_REG (flags_mode, FLAGS_REG);
13459 operands[4] = gen_rtx_COMPARE (flags_mode, operands[1], const0_rtx);
13462 (define_insn_and_split "ffssi2_no_cmove"
13463 [(set (match_operand:SI 0 "register_operand" "=r")
13464 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
13465 (clobber (match_scratch:SI 2 "=&q"))
13466 (clobber (reg:CC FLAGS_REG))]
13469 "&& reload_completed"
13470 [(parallel [(set (match_dup 4) (match_dup 5))
13471 (set (match_dup 0) (ctz:SI (match_dup 1)))])
13472 (set (strict_low_part (match_dup 3))
13473 (eq:QI (match_dup 4) (const_int 0)))
13474 (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
13475 (clobber (reg:CC FLAGS_REG))])
13476 (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
13477 (clobber (reg:CC FLAGS_REG))])
13478 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
13479 (clobber (reg:CC FLAGS_REG))])]
13481 machine_mode flags_mode = TARGET_BMI ? CCCmode : CCZmode;
13483 operands[3] = gen_lowpart (QImode, operands[2]);
13484 operands[4] = gen_rtx_REG (flags_mode, FLAGS_REG);
13485 operands[5] = gen_rtx_COMPARE (flags_mode, operands[1], const0_rtx);
13487 ix86_expand_clear (operands[2]);
13490 (define_insn_and_split "*tzcnt<mode>_1"
13491 [(set (reg:CCC FLAGS_REG)
13492 (compare:CCC (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13494 (set (match_operand:SWI48 0 "register_operand" "=r")
13495 (ctz:SWI48 (match_dup 1)))]
13497 "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
13498 "&& TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
13499 && optimize_function_for_speed_p (cfun)
13500 && !reg_mentioned_p (operands[0], operands[1])"
13502 [(set (reg:CCC FLAGS_REG)
13503 (compare:CCC (match_dup 1) (const_int 0)))
13505 (ctz:SWI48 (match_dup 1)))
13506 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)])]
13507 "ix86_expand_clear (operands[0]);"
13508 [(set_attr "type" "alu1")
13509 (set_attr "prefix_0f" "1")
13510 (set_attr "prefix_rep" "1")
13511 (set_attr "btver2_decode" "double")
13512 (set_attr "mode" "<MODE>")])
13514 ; False dependency happens when destination is only updated by tzcnt,
13515 ; lzcnt or popcnt. There is no false dependency when destination is
13516 ; also used in source.
13517 (define_insn "*tzcnt<mode>_1_falsedep"
13518 [(set (reg:CCC FLAGS_REG)
13519 (compare:CCC (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13521 (set (match_operand:SWI48 0 "register_operand" "=r")
13522 (ctz:SWI48 (match_dup 1)))
13523 (unspec [(match_operand:SWI48 2 "register_operand" "0")]
13524 UNSPEC_INSN_FALSE_DEP)]
13526 "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
13527 [(set_attr "type" "alu1")
13528 (set_attr "prefix_0f" "1")
13529 (set_attr "prefix_rep" "1")
13530 (set_attr "btver2_decode" "double")
13531 (set_attr "mode" "<MODE>")])
13533 (define_insn "*bsf<mode>_1"
13534 [(set (reg:CCZ FLAGS_REG)
13535 (compare:CCZ (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13537 (set (match_operand:SWI48 0 "register_operand" "=r")
13538 (ctz:SWI48 (match_dup 1)))]
13540 "bsf{<imodesuffix>}\t{%1, %0|%0, %1}"
13541 [(set_attr "type" "alu1")
13542 (set_attr "prefix_0f" "1")
13543 (set_attr "btver2_decode" "double")
13544 (set_attr "znver1_decode" "vector")
13545 (set_attr "mode" "<MODE>")])
13547 (define_insn_and_split "ctz<mode>2"
13548 [(set (match_operand:SWI48 0 "register_operand" "=r")
13550 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
13551 (clobber (reg:CC FLAGS_REG))]
13555 return "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
13556 else if (optimize_function_for_size_p (cfun))
13558 else if (TARGET_GENERIC)
13559 /* tzcnt expands to 'rep bsf' and we can use it even if !TARGET_BMI. */
13560 return "rep%; bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
13562 return "bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
13564 "(TARGET_BMI || TARGET_GENERIC)
13565 && TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
13566 && optimize_function_for_speed_p (cfun)
13567 && !reg_mentioned_p (operands[0], operands[1])"
13569 [(set (match_dup 0)
13570 (ctz:SWI48 (match_dup 1)))
13571 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
13572 (clobber (reg:CC FLAGS_REG))])]
13573 "ix86_expand_clear (operands[0]);"
13574 [(set_attr "type" "alu1")
13575 (set_attr "prefix_0f" "1")
13576 (set (attr "prefix_rep")
13578 (ior (match_test "TARGET_BMI")
13579 (and (not (match_test "optimize_function_for_size_p (cfun)"))
13580 (match_test "TARGET_GENERIC")))
13582 (const_string "0")))
13583 (set_attr "mode" "<MODE>")])
13585 ; False dependency happens when destination is only updated by tzcnt,
13586 ; lzcnt or popcnt. There is no false dependency when destination is
13587 ; also used in source.
13588 (define_insn "*ctz<mode>2_falsedep"
13589 [(set (match_operand:SWI48 0 "register_operand" "=r")
13591 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
13592 (unspec [(match_operand:SWI48 2 "register_operand" "0")]
13593 UNSPEC_INSN_FALSE_DEP)
13594 (clobber (reg:CC FLAGS_REG))]
13598 return "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
13599 else if (TARGET_GENERIC)
13600 /* tzcnt expands to 'rep bsf' and we can use it even if !TARGET_BMI. */
13601 return "rep%; bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
13603 gcc_unreachable ();
13605 [(set_attr "type" "alu1")
13606 (set_attr "prefix_0f" "1")
13607 (set_attr "prefix_rep" "1")
13608 (set_attr "mode" "<MODE>")])
13610 (define_insn "bsr_rex64"
13611 [(set (match_operand:DI 0 "register_operand" "=r")
13612 (minus:DI (const_int 63)
13613 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
13614 (clobber (reg:CC FLAGS_REG))]
13616 "bsr{q}\t{%1, %0|%0, %1}"
13617 [(set_attr "type" "alu1")
13618 (set_attr "prefix_0f" "1")
13619 (set_attr "znver1_decode" "vector")
13620 (set_attr "mode" "DI")])
13623 [(set (match_operand:SI 0 "register_operand" "=r")
13624 (minus:SI (const_int 31)
13625 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
13626 (clobber (reg:CC FLAGS_REG))]
13628 "bsr{l}\t{%1, %0|%0, %1}"
13629 [(set_attr "type" "alu1")
13630 (set_attr "prefix_0f" "1")
13631 (set_attr "znver1_decode" "vector")
13632 (set_attr "mode" "SI")])
13634 (define_insn "*bsrhi"
13635 [(set (match_operand:HI 0 "register_operand" "=r")
13636 (minus:HI (const_int 15)
13637 (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
13638 (clobber (reg:CC FLAGS_REG))]
13640 "bsr{w}\t{%1, %0|%0, %1}"
13641 [(set_attr "type" "alu1")
13642 (set_attr "prefix_0f" "1")
13643 (set_attr "znver1_decode" "vector")
13644 (set_attr "mode" "HI")])
13646 (define_expand "clz<mode>2"
13648 [(set (match_operand:SWI48 0 "register_operand")
13651 (clz:SWI48 (match_operand:SWI48 1 "nonimmediate_operand"))))
13652 (clobber (reg:CC FLAGS_REG))])
13654 [(set (match_dup 0) (xor:SWI48 (match_dup 0) (match_dup 2)))
13655 (clobber (reg:CC FLAGS_REG))])]
13660 emit_insn (gen_clz<mode>2_lzcnt (operands[0], operands[1]));
13663 operands[2] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
13666 (define_insn_and_split "clz<mode>2_lzcnt"
13667 [(set (match_operand:SWI48 0 "register_operand" "=r")
13669 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
13670 (clobber (reg:CC FLAGS_REG))]
13672 "lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
13673 "&& TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
13674 && optimize_function_for_speed_p (cfun)
13675 && !reg_mentioned_p (operands[0], operands[1])"
13677 [(set (match_dup 0)
13678 (clz:SWI48 (match_dup 1)))
13679 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
13680 (clobber (reg:CC FLAGS_REG))])]
13681 "ix86_expand_clear (operands[0]);"
13682 [(set_attr "prefix_rep" "1")
13683 (set_attr "type" "bitmanip")
13684 (set_attr "mode" "<MODE>")])
13686 ; False dependency happens when destination is only updated by tzcnt,
13687 ; lzcnt or popcnt. There is no false dependency when destination is
13688 ; also used in source.
13689 (define_insn "*clz<mode>2_lzcnt_falsedep"
13690 [(set (match_operand:SWI48 0 "register_operand" "=r")
13692 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
13693 (unspec [(match_operand:SWI48 2 "register_operand" "0")]
13694 UNSPEC_INSN_FALSE_DEP)
13695 (clobber (reg:CC FLAGS_REG))]
13697 "lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
13698 [(set_attr "prefix_rep" "1")
13699 (set_attr "type" "bitmanip")
13700 (set_attr "mode" "<MODE>")])
13702 (define_int_iterator LT_ZCNT
13703 [(UNSPEC_TZCNT "TARGET_BMI")
13704 (UNSPEC_LZCNT "TARGET_LZCNT")])
13706 (define_int_attr lt_zcnt
13707 [(UNSPEC_TZCNT "tzcnt")
13708 (UNSPEC_LZCNT "lzcnt")])
13710 (define_int_attr lt_zcnt_type
13711 [(UNSPEC_TZCNT "alu1")
13712 (UNSPEC_LZCNT "bitmanip")])
13714 ;; Version of lzcnt/tzcnt that is expanded from intrinsics. This version
13715 ;; provides operand size as output when source operand is zero.
13717 (define_insn_and_split "<lt_zcnt>_<mode>"
13718 [(set (match_operand:SWI48 0 "register_operand" "=r")
13720 [(match_operand:SWI48 1 "nonimmediate_operand" "rm")] LT_ZCNT))
13721 (clobber (reg:CC FLAGS_REG))]
13723 "<lt_zcnt>{<imodesuffix>}\t{%1, %0|%0, %1}"
13724 "&& TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
13725 && optimize_function_for_speed_p (cfun)
13726 && !reg_mentioned_p (operands[0], operands[1])"
13728 [(set (match_dup 0)
13729 (unspec:SWI48 [(match_dup 1)] LT_ZCNT))
13730 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
13731 (clobber (reg:CC FLAGS_REG))])]
13732 "ix86_expand_clear (operands[0]);"
13733 [(set_attr "type" "<lt_zcnt_type>")
13734 (set_attr "prefix_0f" "1")
13735 (set_attr "prefix_rep" "1")
13736 (set_attr "mode" "<MODE>")])
13738 ; False dependency happens when destination is only updated by tzcnt,
13739 ; lzcnt or popcnt. There is no false dependency when destination is
13740 ; also used in source.
13741 (define_insn "*<lt_zcnt>_<mode>_falsedep"
13742 [(set (match_operand:SWI48 0 "register_operand" "=r")
13744 [(match_operand:SWI48 1 "nonimmediate_operand" "rm")] LT_ZCNT))
13745 (unspec [(match_operand:SWI48 2 "register_operand" "0")]
13746 UNSPEC_INSN_FALSE_DEP)
13747 (clobber (reg:CC FLAGS_REG))]
13749 "<lt_zcnt>{<imodesuffix>}\t{%1, %0|%0, %1}"
13750 [(set_attr "type" "<lt_zcnt_type>")
13751 (set_attr "prefix_0f" "1")
13752 (set_attr "prefix_rep" "1")
13753 (set_attr "mode" "<MODE>")])
13755 (define_insn "<lt_zcnt>_hi"
13756 [(set (match_operand:HI 0 "register_operand" "=r")
13758 [(match_operand:HI 1 "nonimmediate_operand" "rm")] LT_ZCNT))
13759 (clobber (reg:CC FLAGS_REG))]
13761 "<lt_zcnt>{w}\t{%1, %0|%0, %1}"
13762 [(set_attr "type" "<lt_zcnt_type>")
13763 (set_attr "prefix_0f" "1")
13764 (set_attr "prefix_rep" "1")
13765 (set_attr "mode" "HI")])
13767 ;; BMI instructions.
13769 (define_insn "bmi_bextr_<mode>"
13770 [(set (match_operand:SWI48 0 "register_operand" "=r,r")
13771 (unspec:SWI48 [(match_operand:SWI48 1 "nonimmediate_operand" "r,m")
13772 (match_operand:SWI48 2 "register_operand" "r,r")]
13774 (clobber (reg:CC FLAGS_REG))]
13776 "bextr\t{%2, %1, %0|%0, %1, %2}"
13777 [(set_attr "type" "bitmanip")
13778 (set_attr "btver2_decode" "direct, double")
13779 (set_attr "mode" "<MODE>")])
13781 (define_insn "*bmi_bextr_<mode>_ccz"
13782 [(set (reg:CCZ FLAGS_REG)
13784 (unspec:SWI48 [(match_operand:SWI48 1 "nonimmediate_operand" "r,m")
13785 (match_operand:SWI48 2 "register_operand" "r,r")]
13788 (clobber (match_scratch:SWI48 0 "=r,r"))]
13790 "bextr\t{%2, %1, %0|%0, %1, %2}"
13791 [(set_attr "type" "bitmanip")
13792 (set_attr "btver2_decode" "direct, double")
13793 (set_attr "mode" "<MODE>")])
13795 (define_insn "*bmi_blsi_<mode>"
13796 [(set (match_operand:SWI48 0 "register_operand" "=r")
13799 (match_operand:SWI48 1 "nonimmediate_operand" "rm"))
13801 (clobber (reg:CC FLAGS_REG))]
13803 "blsi\t{%1, %0|%0, %1}"
13804 [(set_attr "type" "bitmanip")
13805 (set_attr "btver2_decode" "double")
13806 (set_attr "mode" "<MODE>")])
13808 (define_insn "*bmi_blsmsk_<mode>"
13809 [(set (match_operand:SWI48 0 "register_operand" "=r")
13812 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13815 (clobber (reg:CC FLAGS_REG))]
13817 "blsmsk\t{%1, %0|%0, %1}"
13818 [(set_attr "type" "bitmanip")
13819 (set_attr "btver2_decode" "double")
13820 (set_attr "mode" "<MODE>")])
13822 (define_insn "*bmi_blsr_<mode>"
13823 [(set (match_operand:SWI48 0 "register_operand" "=r")
13826 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13829 (clobber (reg:CC FLAGS_REG))]
13831 "blsr\t{%1, %0|%0, %1}"
13832 [(set_attr "type" "bitmanip")
13833 (set_attr "btver2_decode" "double")
13834 (set_attr "mode" "<MODE>")])
13836 (define_insn "*bmi_blsr_<mode>_cmp"
13837 [(set (reg:CCZ FLAGS_REG)
13841 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13845 (set (match_operand:SWI48 0 "register_operand" "=r")
13852 "blsr\t{%1, %0|%0, %1}"
13853 [(set_attr "type" "bitmanip")
13854 (set_attr "btver2_decode" "double")
13855 (set_attr "mode" "<MODE>")])
13857 (define_insn "*bmi_blsr_<mode>_ccz"
13858 [(set (reg:CCZ FLAGS_REG)
13862 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13866 (clobber (match_scratch:SWI48 0 "=r"))]
13868 "blsr\t{%1, %0|%0, %1}"
13869 [(set_attr "type" "bitmanip")
13870 (set_attr "btver2_decode" "double")
13871 (set_attr "mode" "<MODE>")])
13873 ;; BMI2 instructions.
13874 (define_expand "bmi2_bzhi_<mode>3"
13876 [(set (match_operand:SWI48 0 "register_operand")
13877 (zero_extract:SWI48
13878 (match_operand:SWI48 1 "nonimmediate_operand")
13880 (and:SWI48 (match_operand:SWI48 2 "register_operand")
13884 (clobber (reg:CC FLAGS_REG))])]
13886 "operands[3] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT);")
13888 (define_insn "*bmi2_bzhi_<mode>3"
13889 [(set (match_operand:SWI48 0 "register_operand" "=r")
13890 (zero_extract:SWI48
13891 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13893 (and:SWI48 (match_operand:SWI48 2 "register_operand" "r")
13895 (match_operand:SWI48 3 "const_int_operand" "n"))
13897 (clobber (reg:CC FLAGS_REG))]
13898 "TARGET_BMI2 && INTVAL (operands[3]) == <MODE_SIZE> * BITS_PER_UNIT"
13899 "bzhi\t{%2, %1, %0|%0, %1, %2}"
13900 [(set_attr "type" "bitmanip")
13901 (set_attr "prefix" "vex")
13902 (set_attr "mode" "<MODE>")])
13904 (define_insn "*bmi2_bzhi_<mode>3_1"
13905 [(set (match_operand:SWI48 0 "register_operand" "=r")
13906 (zero_extract:SWI48
13907 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13909 (zero_extend:SWI48 (match_operand:QI 2 "register_operand" "r"))
13910 (match_operand:SWI48 3 "const_int_operand" "n"))
13912 (clobber (reg:CC FLAGS_REG))]
13913 "TARGET_BMI2 && INTVAL (operands[3]) == <MODE_SIZE> * BITS_PER_UNIT"
13914 "bzhi\t{%<k>2, %1, %0|%0, %1, %<k>2}"
13915 [(set_attr "type" "bitmanip")
13916 (set_attr "prefix" "vex")
13917 (set_attr "mode" "<MODE>")])
13919 (define_insn "*bmi2_bzhi_<mode>3_1_ccz"
13920 [(set (reg:CCZ FLAGS_REG)
13922 (zero_extract:SWI48
13923 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13925 (zero_extend:SWI48 (match_operand:QI 2 "register_operand" "r"))
13926 (match_operand:SWI48 3 "const_int_operand" "n"))
13929 (clobber (match_scratch:SWI48 0 "=r"))]
13930 "TARGET_BMI2 && INTVAL (operands[3]) == <MODE_SIZE> * BITS_PER_UNIT"
13931 "bzhi\t{%<k>2, %1, %0|%0, %1, %<k>2}"
13932 [(set_attr "type" "bitmanip")
13933 (set_attr "prefix" "vex")
13934 (set_attr "mode" "<MODE>")])
13936 (define_insn "bmi2_pdep_<mode>3"
13937 [(set (match_operand:SWI48 0 "register_operand" "=r")
13938 (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
13939 (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
13942 "pdep\t{%2, %1, %0|%0, %1, %2}"
13943 [(set_attr "type" "bitmanip")
13944 (set_attr "prefix" "vex")
13945 (set_attr "mode" "<MODE>")])
13947 (define_insn "bmi2_pext_<mode>3"
13948 [(set (match_operand:SWI48 0 "register_operand" "=r")
13949 (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
13950 (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
13953 "pext\t{%2, %1, %0|%0, %1, %2}"
13954 [(set_attr "type" "bitmanip")
13955 (set_attr "prefix" "vex")
13956 (set_attr "mode" "<MODE>")])
13958 ;; TBM instructions.
13959 (define_insn "tbm_bextri_<mode>"
13960 [(set (match_operand:SWI48 0 "register_operand" "=r")
13961 (zero_extract:SWI48
13962 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13963 (match_operand 2 "const_0_to_255_operand" "N")
13964 (match_operand 3 "const_0_to_255_operand" "N")))
13965 (clobber (reg:CC FLAGS_REG))]
13968 operands[2] = GEN_INT (INTVAL (operands[2]) << 8 | INTVAL (operands[3]));
13969 return "bextr\t{%2, %1, %0|%0, %1, %2}";
13971 [(set_attr "type" "bitmanip")
13972 (set_attr "mode" "<MODE>")])
13974 (define_insn "*tbm_blcfill_<mode>"
13975 [(set (match_operand:SWI48 0 "register_operand" "=r")
13978 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13981 (clobber (reg:CC FLAGS_REG))]
13983 "blcfill\t{%1, %0|%0, %1}"
13984 [(set_attr "type" "bitmanip")
13985 (set_attr "mode" "<MODE>")])
13987 (define_insn "*tbm_blci_<mode>"
13988 [(set (match_operand:SWI48 0 "register_operand" "=r")
13992 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13995 (clobber (reg:CC FLAGS_REG))]
13997 "blci\t{%1, %0|%0, %1}"
13998 [(set_attr "type" "bitmanip")
13999 (set_attr "mode" "<MODE>")])
14001 (define_insn "*tbm_blcic_<mode>"
14002 [(set (match_operand:SWI48 0 "register_operand" "=r")
14005 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
14009 (clobber (reg:CC FLAGS_REG))]
14011 "blcic\t{%1, %0|%0, %1}"
14012 [(set_attr "type" "bitmanip")
14013 (set_attr "mode" "<MODE>")])
14015 (define_insn "*tbm_blcmsk_<mode>"
14016 [(set (match_operand:SWI48 0 "register_operand" "=r")
14019 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
14022 (clobber (reg:CC FLAGS_REG))]
14024 "blcmsk\t{%1, %0|%0, %1}"
14025 [(set_attr "type" "bitmanip")
14026 (set_attr "mode" "<MODE>")])
14028 (define_insn "*tbm_blcs_<mode>"
14029 [(set (match_operand:SWI48 0 "register_operand" "=r")
14032 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
14035 (clobber (reg:CC FLAGS_REG))]
14037 "blcs\t{%1, %0|%0, %1}"
14038 [(set_attr "type" "bitmanip")
14039 (set_attr "mode" "<MODE>")])
14041 (define_insn "*tbm_blsfill_<mode>"
14042 [(set (match_operand:SWI48 0 "register_operand" "=r")
14045 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
14048 (clobber (reg:CC FLAGS_REG))]
14050 "blsfill\t{%1, %0|%0, %1}"
14051 [(set_attr "type" "bitmanip")
14052 (set_attr "mode" "<MODE>")])
14054 (define_insn "*tbm_blsic_<mode>"
14055 [(set (match_operand:SWI48 0 "register_operand" "=r")
14058 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
14062 (clobber (reg:CC FLAGS_REG))]
14064 "blsic\t{%1, %0|%0, %1}"
14065 [(set_attr "type" "bitmanip")
14066 (set_attr "mode" "<MODE>")])
14068 (define_insn "*tbm_t1mskc_<mode>"
14069 [(set (match_operand:SWI48 0 "register_operand" "=r")
14072 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
14076 (clobber (reg:CC FLAGS_REG))]
14078 "t1mskc\t{%1, %0|%0, %1}"
14079 [(set_attr "type" "bitmanip")
14080 (set_attr "mode" "<MODE>")])
14082 (define_insn "*tbm_tzmsk_<mode>"
14083 [(set (match_operand:SWI48 0 "register_operand" "=r")
14086 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
14090 (clobber (reg:CC FLAGS_REG))]
14092 "tzmsk\t{%1, %0|%0, %1}"
14093 [(set_attr "type" "bitmanip")
14094 (set_attr "mode" "<MODE>")])
14096 (define_insn_and_split "popcount<mode>2"
14097 [(set (match_operand:SWI48 0 "register_operand" "=r")
14099 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
14100 (clobber (reg:CC FLAGS_REG))]
14104 return "popcnt\t{%1, %0|%0, %1}";
14106 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
14109 "&& TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
14110 && optimize_function_for_speed_p (cfun)
14111 && !reg_mentioned_p (operands[0], operands[1])"
14113 [(set (match_dup 0)
14114 (popcount:SWI48 (match_dup 1)))
14115 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
14116 (clobber (reg:CC FLAGS_REG))])]
14117 "ix86_expand_clear (operands[0]);"
14118 [(set_attr "prefix_rep" "1")
14119 (set_attr "type" "bitmanip")
14120 (set_attr "mode" "<MODE>")])
14122 ; False dependency happens when destination is only updated by tzcnt,
14123 ; lzcnt or popcnt. There is no false dependency when destination is
14124 ; also used in source.
14125 (define_insn "*popcount<mode>2_falsedep"
14126 [(set (match_operand:SWI48 0 "register_operand" "=r")
14128 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
14129 (unspec [(match_operand:SWI48 2 "register_operand" "0")]
14130 UNSPEC_INSN_FALSE_DEP)
14131 (clobber (reg:CC FLAGS_REG))]
14135 return "popcnt\t{%1, %0|%0, %1}";
14137 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
14140 [(set_attr "prefix_rep" "1")
14141 (set_attr "type" "bitmanip")
14142 (set_attr "mode" "<MODE>")])
14144 (define_insn_and_split "*popcounthi2_1"
14145 [(set (match_operand:SI 0 "register_operand")
14147 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand"))))
14148 (clobber (reg:CC FLAGS_REG))]
14150 && can_create_pseudo_p ()"
14155 rtx tmp = gen_reg_rtx (HImode);
14157 emit_insn (gen_popcounthi2 (tmp, operands[1]));
14158 emit_insn (gen_zero_extendhisi2 (operands[0], tmp));
14162 (define_insn "popcounthi2"
14163 [(set (match_operand:HI 0 "register_operand" "=r")
14165 (match_operand:HI 1 "nonimmediate_operand" "rm")))
14166 (clobber (reg:CC FLAGS_REG))]
14170 return "popcnt\t{%1, %0|%0, %1}";
14172 return "popcnt{w}\t{%1, %0|%0, %1}";
14175 [(set_attr "prefix_rep" "1")
14176 (set_attr "type" "bitmanip")
14177 (set_attr "mode" "HI")])
14179 (define_expand "bswapdi2"
14180 [(set (match_operand:DI 0 "register_operand")
14181 (bswap:DI (match_operand:DI 1 "nonimmediate_operand")))]
14185 operands[1] = force_reg (DImode, operands[1]);
14188 (define_expand "bswapsi2"
14189 [(set (match_operand:SI 0 "register_operand")
14190 (bswap:SI (match_operand:SI 1 "nonimmediate_operand")))]
14195 else if (TARGET_BSWAP)
14196 operands[1] = force_reg (SImode, operands[1]);
14199 rtx x = operands[0];
14201 emit_move_insn (x, operands[1]);
14202 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
14203 emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
14204 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
14209 (define_insn "*bswap<mode>2_movbe"
14210 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,r,m")
14211 (bswap:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,m,r")))]
14213 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
14216 movbe{<imodesuffix>}\t{%1, %0|%0, %1}
14217 movbe{<imodesuffix>}\t{%1, %0|%0, %1}"
14218 [(set_attr "type" "bitmanip,imov,imov")
14219 (set_attr "modrm" "0,1,1")
14220 (set_attr "prefix_0f" "*,1,1")
14221 (set_attr "prefix_extra" "*,1,1")
14222 (set_attr "mode" "<MODE>")])
14224 (define_insn "*bswap<mode>2"
14225 [(set (match_operand:SWI48 0 "register_operand" "=r")
14226 (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "0")))]
14229 [(set_attr "type" "bitmanip")
14230 (set_attr "modrm" "0")
14231 (set_attr "mode" "<MODE>")])
14233 (define_expand "bswaphi2"
14234 [(set (match_operand:HI 0 "register_operand")
14235 (bswap:HI (match_operand:HI 1 "nonimmediate_operand")))]
14238 (define_insn "*bswaphi2_movbe"
14239 [(set (match_operand:HI 0 "nonimmediate_operand" "=Q,r,m")
14240 (bswap:HI (match_operand:HI 1 "nonimmediate_operand" "0,m,r")))]
14242 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
14244 xchg{b}\t{%h0, %b0|%b0, %h0}
14245 movbe{w}\t{%1, %0|%0, %1}
14246 movbe{w}\t{%1, %0|%0, %1}"
14247 [(set_attr "type" "imov")
14248 (set_attr "modrm" "*,1,1")
14249 (set_attr "prefix_0f" "*,1,1")
14250 (set_attr "prefix_extra" "*,1,1")
14251 (set_attr "pent_pair" "np,*,*")
14252 (set_attr "athlon_decode" "vector,*,*")
14253 (set_attr "amdfam10_decode" "double,*,*")
14254 (set_attr "bdver1_decode" "double,*,*")
14255 (set_attr "mode" "QI,HI,HI")])
14258 [(set (match_operand:HI 0 "general_reg_operand")
14259 (bswap:HI (match_dup 0)))]
14261 && !(TARGET_USE_XCHGB || optimize_function_for_size_p (cfun))
14262 && peep2_regno_dead_p (0, FLAGS_REG)"
14263 [(parallel [(set (match_dup 0) (rotate:HI (match_dup 0) (const_int 8)))
14264 (clobber (reg:CC FLAGS_REG))])])
14266 (define_insn "bswaphi_lowpart"
14267 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
14268 (bswap:HI (match_dup 0)))
14269 (clobber (reg:CC FLAGS_REG))]
14272 xchg{b}\t{%h0, %b0|%b0, %h0}
14273 rol{w}\t{$8, %0|%0, 8}"
14274 [(set (attr "preferred_for_size")
14275 (cond [(eq_attr "alternative" "0")
14276 (symbol_ref "true")]
14277 (symbol_ref "false")))
14278 (set (attr "preferred_for_speed")
14279 (cond [(eq_attr "alternative" "0")
14280 (symbol_ref "TARGET_USE_XCHGB")]
14281 (symbol_ref "!TARGET_USE_XCHGB")))
14282 (set_attr "length" "2,4")
14283 (set_attr "mode" "QI,HI")])
14285 (define_expand "paritydi2"
14286 [(set (match_operand:DI 0 "register_operand")
14287 (parity:DI (match_operand:DI 1 "register_operand")))]
14290 rtx scratch = gen_reg_rtx (QImode);
14292 emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX,
14293 NULL_RTX, operands[1]));
14295 ix86_expand_setcc (scratch, ORDERED,
14296 gen_rtx_REG (CCmode, FLAGS_REG), const0_rtx);
14299 emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
14302 rtx tmp = gen_reg_rtx (SImode);
14304 emit_insn (gen_zero_extendqisi2 (tmp, scratch));
14305 emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
14310 (define_expand "paritysi2"
14311 [(set (match_operand:SI 0 "register_operand")
14312 (parity:SI (match_operand:SI 1 "register_operand")))]
14315 rtx scratch = gen_reg_rtx (QImode);
14317 emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1]));
14319 ix86_expand_setcc (scratch, ORDERED,
14320 gen_rtx_REG (CCmode, FLAGS_REG), const0_rtx);
14322 emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
14326 (define_insn_and_split "paritydi2_cmp"
14327 [(set (reg:CC FLAGS_REG)
14328 (unspec:CC [(match_operand:DI 3 "register_operand" "0")]
14330 (clobber (match_scratch:DI 0 "=r"))
14331 (clobber (match_scratch:SI 1 "=&r"))
14332 (clobber (match_scratch:HI 2 "=Q"))]
14335 "&& reload_completed"
14337 [(set (match_dup 1)
14338 (xor:SI (match_dup 1) (match_dup 4)))
14339 (clobber (reg:CC FLAGS_REG))])
14341 [(set (reg:CC FLAGS_REG)
14342 (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
14343 (clobber (match_dup 1))
14344 (clobber (match_dup 2))])]
14346 operands[4] = gen_lowpart (SImode, operands[3]);
14350 emit_move_insn (operands[1], gen_lowpart (SImode, operands[3]));
14351 emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32)));
14354 operands[1] = gen_highpart (SImode, operands[3]);
14357 (define_insn_and_split "paritysi2_cmp"
14358 [(set (reg:CC FLAGS_REG)
14359 (unspec:CC [(match_operand:SI 2 "register_operand" "0")]
14361 (clobber (match_scratch:SI 0 "=r"))
14362 (clobber (match_scratch:HI 1 "=&Q"))]
14365 "&& reload_completed"
14367 [(set (match_dup 1)
14368 (xor:HI (match_dup 1) (match_dup 3)))
14369 (clobber (reg:CC FLAGS_REG))])
14371 [(set (reg:CC FLAGS_REG)
14372 (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
14373 (clobber (match_dup 1))])]
14375 operands[3] = gen_lowpart (HImode, operands[2]);
14377 emit_move_insn (operands[1], gen_lowpart (HImode, operands[2]));
14378 emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16)));
14381 (define_insn "*parityhi2_cmp"
14382 [(set (reg:CC FLAGS_REG)
14383 (unspec:CC [(match_operand:HI 1 "register_operand" "0")]
14385 (clobber (match_scratch:HI 0 "=Q"))]
14387 "xor{b}\t{%h0, %b0|%b0, %h0}"
14388 [(set_attr "length" "2")
14389 (set_attr "mode" "HI")])
14392 ;; Thread-local storage patterns for ELF.
14394 ;; Note that these code sequences must appear exactly as shown
14395 ;; in order to allow linker relaxation.
14397 (define_insn "*tls_global_dynamic_32_gnu"
14398 [(set (match_operand:SI 0 "register_operand" "=a")
14400 [(match_operand:SI 1 "register_operand" "Yb")
14401 (match_operand 2 "tls_symbolic_operand")
14402 (match_operand 3 "constant_call_address_operand" "Bz")
14405 (clobber (match_scratch:SI 4 "=d"))
14406 (clobber (match_scratch:SI 5 "=c"))
14407 (clobber (reg:CC FLAGS_REG))]
14408 "!TARGET_64BIT && TARGET_GNU_TLS"
14410 if (TARGET_SUN_TLS || flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT)
14412 ("lea{l}\t{%E2@tlsgd(,%1,1), %0|%0, %E2@tlsgd[%1*1]}", operands);
14415 ("lea{l}\t{%E2@tlsgd(%1), %0|%0, %E2@tlsgd[%1]}", operands);
14416 if (TARGET_SUN_TLS)
14417 #ifdef HAVE_AS_IX86_TLSGDPLT
14418 return "call\t%a2@tlsgdplt";
14420 return "call\t%p3@plt";
14422 if (flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT)
14423 return "call\t%P3";
14424 return "call\t{*%p3@GOT(%1)|[DWORD PTR %p3@GOT[%1]]}";
14426 [(set_attr "type" "multi")
14427 (set_attr "length" "12")])
14429 (define_expand "tls_global_dynamic_32"
14431 [(set (match_operand:SI 0 "register_operand")
14432 (unspec:SI [(match_operand:SI 2 "register_operand")
14433 (match_operand 1 "tls_symbolic_operand")
14434 (match_operand 3 "constant_call_address_operand")
14437 (clobber (match_scratch:SI 4))
14438 (clobber (match_scratch:SI 5))
14439 (clobber (reg:CC FLAGS_REG))])]
14441 "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
14443 (define_insn "*tls_global_dynamic_64_<mode>"
14444 [(set (match_operand:P 0 "register_operand" "=a")
14446 (mem:QI (match_operand 2 "constant_call_address_operand" "Bz"))
14447 (match_operand 3)))
14448 (unspec:P [(match_operand 1 "tls_symbolic_operand")
14454 fputs (ASM_BYTE "0x66\n", asm_out_file);
14456 ("lea{q}\t{%E1@tlsgd(%%rip), %%rdi|rdi, %E1@tlsgd[rip]}", operands);
14457 if (TARGET_SUN_TLS || flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT)
14458 fputs (ASM_SHORT "0x6666\n", asm_out_file);
14460 fputs (ASM_BYTE "0x66\n", asm_out_file);
14461 fputs ("\trex64\n", asm_out_file);
14462 if (TARGET_SUN_TLS)
14463 return "call\t%p2@plt";
14464 if (flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT)
14465 return "call\t%P2";
14466 return "call\t{*%p2@GOTPCREL(%%rip)|[QWORD PTR %p2@GOTPCREL[rip]]}";
14468 [(set_attr "type" "multi")
14469 (set (attr "length")
14470 (symbol_ref "TARGET_X32 ? 15 : 16"))])
14472 (define_insn "*tls_global_dynamic_64_largepic"
14473 [(set (match_operand:DI 0 "register_operand" "=a")
14475 (mem:QI (plus:DI (match_operand:DI 2 "register_operand" "b")
14476 (match_operand:DI 3 "immediate_operand" "i")))
14477 (match_operand 4)))
14478 (unspec:DI [(match_operand 1 "tls_symbolic_operand")
14481 "TARGET_64BIT && ix86_cmodel == CM_LARGE_PIC && !TARGET_PECOFF
14482 && GET_CODE (operands[3]) == CONST
14483 && GET_CODE (XEXP (operands[3], 0)) == UNSPEC
14484 && XINT (XEXP (operands[3], 0), 1) == UNSPEC_PLTOFF"
14487 ("lea{q}\t{%E1@tlsgd(%%rip), %%rdi|rdi, %E1@tlsgd[rip]}", operands);
14488 output_asm_insn ("movabs{q}\t{%3, %%rax|rax, %3}", operands);
14489 output_asm_insn ("add{q}\t{%2, %%rax|rax, %2}", operands);
14490 return "call\t{*%%rax|rax}";
14492 [(set_attr "type" "multi")
14493 (set_attr "length" "22")])
14495 (define_expand "tls_global_dynamic_64_<mode>"
14497 [(set (match_operand:P 0 "register_operand")
14499 (mem:QI (match_operand 2))
14501 (unspec:P [(match_operand 1 "tls_symbolic_operand")
14505 "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
14507 (define_insn "*tls_local_dynamic_base_32_gnu"
14508 [(set (match_operand:SI 0 "register_operand" "=a")
14510 [(match_operand:SI 1 "register_operand" "Yb")
14511 (match_operand 2 "constant_call_address_operand" "Bz")
14513 UNSPEC_TLS_LD_BASE))
14514 (clobber (match_scratch:SI 3 "=d"))
14515 (clobber (match_scratch:SI 4 "=c"))
14516 (clobber (reg:CC FLAGS_REG))]
14517 "!TARGET_64BIT && TARGET_GNU_TLS"
14520 ("lea{l}\t{%&@tlsldm(%1), %0|%0, %&@tlsldm[%1]}", operands);
14521 if (TARGET_SUN_TLS)
14523 if (HAVE_AS_IX86_TLSLDMPLT)
14524 return "call\t%&@tlsldmplt";
14526 return "call\t%p2@plt";
14528 if (flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT)
14529 return "call\t%P2";
14530 return "call\t{*%p2@GOT(%1)|[DWORD PTR %p2@GOT[%1]]}";
14532 [(set_attr "type" "multi")
14533 (set_attr "length" "11")])
14535 (define_expand "tls_local_dynamic_base_32"
14537 [(set (match_operand:SI 0 "register_operand")
14539 [(match_operand:SI 1 "register_operand")
14540 (match_operand 2 "constant_call_address_operand")
14542 UNSPEC_TLS_LD_BASE))
14543 (clobber (match_scratch:SI 3))
14544 (clobber (match_scratch:SI 4))
14545 (clobber (reg:CC FLAGS_REG))])]
14547 "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
14549 (define_insn "*tls_local_dynamic_base_64_<mode>"
14550 [(set (match_operand:P 0 "register_operand" "=a")
14552 (mem:QI (match_operand 1 "constant_call_address_operand" "Bz"))
14553 (match_operand 2)))
14554 (unspec:P [(reg:P SP_REG)] UNSPEC_TLS_LD_BASE)]
14558 ("lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}", operands);
14559 if (TARGET_SUN_TLS)
14560 return "call\t%p1@plt";
14561 if (flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT)
14562 return "call\t%P1";
14563 return "call\t{*%p1@GOTPCREL(%%rip)|[QWORD PTR %p1@GOTPCREL[rip]]}";
14565 [(set_attr "type" "multi")
14566 (set_attr "length" "12")])
14568 (define_insn "*tls_local_dynamic_base_64_largepic"
14569 [(set (match_operand:DI 0 "register_operand" "=a")
14571 (mem:QI (plus:DI (match_operand:DI 1 "register_operand" "b")
14572 (match_operand:DI 2 "immediate_operand" "i")))
14573 (match_operand 3)))
14574 (unspec:DI [(reg:DI SP_REG)] UNSPEC_TLS_LD_BASE)]
14575 "TARGET_64BIT && ix86_cmodel == CM_LARGE_PIC && !TARGET_PECOFF
14576 && GET_CODE (operands[2]) == CONST
14577 && GET_CODE (XEXP (operands[2], 0)) == UNSPEC
14578 && XINT (XEXP (operands[2], 0), 1) == UNSPEC_PLTOFF"
14581 ("lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}", operands);
14582 output_asm_insn ("movabs{q}\t{%2, %%rax|rax, %2}", operands);
14583 output_asm_insn ("add{q}\t{%1, %%rax|rax, %1}", operands);
14584 return "call\t{*%%rax|rax}";
14586 [(set_attr "type" "multi")
14587 (set_attr "length" "22")])
14589 (define_expand "tls_local_dynamic_base_64_<mode>"
14591 [(set (match_operand:P 0 "register_operand")
14593 (mem:QI (match_operand 1))
14595 (unspec:P [(reg:P SP_REG)] UNSPEC_TLS_LD_BASE)])]
14597 "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
14599 ;; Local dynamic of a single variable is a lose. Show combine how
14600 ;; to convert that back to global dynamic.
14602 (define_insn_and_split "*tls_local_dynamic_32_once"
14603 [(set (match_operand:SI 0 "register_operand" "=a")
14605 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14606 (match_operand 2 "constant_call_address_operand" "Bz")
14608 UNSPEC_TLS_LD_BASE)
14609 (const:SI (unspec:SI
14610 [(match_operand 3 "tls_symbolic_operand")]
14612 (clobber (match_scratch:SI 4 "=d"))
14613 (clobber (match_scratch:SI 5 "=c"))
14614 (clobber (reg:CC FLAGS_REG))]
14619 [(set (match_dup 0)
14620 (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)
14623 (clobber (match_dup 4))
14624 (clobber (match_dup 5))
14625 (clobber (reg:CC FLAGS_REG))])])
14627 ;; Load and add the thread base pointer from %<tp_seg>:0.
14628 (define_insn_and_split "*load_tp_<mode>"
14629 [(set (match_operand:PTR 0 "register_operand" "=r")
14630 (unspec:PTR [(const_int 0)] UNSPEC_TP))]
14634 [(set (match_dup 0)
14637 addr_space_t as = DEFAULT_TLS_SEG_REG;
14639 operands[1] = gen_const_mem (<MODE>mode, const0_rtx);
14640 set_mem_addr_space (operands[1], as);
14643 (define_insn_and_split "*load_tp_x32_zext"
14644 [(set (match_operand:DI 0 "register_operand" "=r")
14646 (unspec:SI [(const_int 0)] UNSPEC_TP)))]
14650 [(set (match_dup 0)
14651 (zero_extend:DI (match_dup 1)))]
14653 addr_space_t as = DEFAULT_TLS_SEG_REG;
14655 operands[1] = gen_const_mem (SImode, const0_rtx);
14656 set_mem_addr_space (operands[1], as);
14659 (define_insn_and_split "*add_tp_<mode>"
14660 [(set (match_operand:PTR 0 "register_operand" "=r")
14662 (unspec:PTR [(const_int 0)] UNSPEC_TP)
14663 (match_operand:PTR 1 "register_operand" "0")))
14664 (clobber (reg:CC FLAGS_REG))]
14669 [(set (match_dup 0)
14670 (plus:PTR (match_dup 1) (match_dup 2)))
14671 (clobber (reg:CC FLAGS_REG))])]
14673 addr_space_t as = DEFAULT_TLS_SEG_REG;
14675 operands[2] = gen_const_mem (<MODE>mode, const0_rtx);
14676 set_mem_addr_space (operands[2], as);
14679 (define_insn_and_split "*add_tp_x32_zext"
14680 [(set (match_operand:DI 0 "register_operand" "=r")
14682 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
14683 (match_operand:SI 1 "register_operand" "0"))))
14684 (clobber (reg:CC FLAGS_REG))]
14689 [(set (match_dup 0)
14691 (plus:SI (match_dup 1) (match_dup 2))))
14692 (clobber (reg:CC FLAGS_REG))])]
14694 addr_space_t as = DEFAULT_TLS_SEG_REG;
14696 operands[2] = gen_const_mem (SImode, const0_rtx);
14697 set_mem_addr_space (operands[2], as);
14700 ;; The Sun linker took the AMD64 TLS spec literally and can only handle
14701 ;; %rax as destination of the initial executable code sequence.
14702 (define_insn "tls_initial_exec_64_sun"
14703 [(set (match_operand:DI 0 "register_operand" "=a")
14705 [(match_operand 1 "tls_symbolic_operand")]
14706 UNSPEC_TLS_IE_SUN))
14707 (clobber (reg:CC FLAGS_REG))]
14708 "TARGET_64BIT && TARGET_SUN_TLS"
14711 ("mov{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}", operands);
14712 return "add{q}\t{%a1@gottpoff(%%rip), %0|%0, %a1@gottpoff[rip]}";
14714 [(set_attr "type" "multi")])
14716 ;; GNU2 TLS patterns can be split.
14718 (define_expand "tls_dynamic_gnu2_32"
14719 [(set (match_dup 3)
14720 (plus:SI (match_operand:SI 2 "register_operand")
14722 (unspec:SI [(match_operand 1 "tls_symbolic_operand")]
14725 [(set (match_operand:SI 0 "register_operand")
14726 (unspec:SI [(match_dup 1) (match_dup 3)
14727 (match_dup 2) (reg:SI SP_REG)]
14729 (clobber (reg:CC FLAGS_REG))])]
14730 "!TARGET_64BIT && TARGET_GNU2_TLS"
14732 operands[3] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
14733 ix86_tls_descriptor_calls_expanded_in_cfun = true;
14736 (define_insn "*tls_dynamic_gnu2_lea_32"
14737 [(set (match_operand:SI 0 "register_operand" "=r")
14738 (plus:SI (match_operand:SI 1 "register_operand" "b")
14740 (unspec:SI [(match_operand 2 "tls_symbolic_operand")]
14741 UNSPEC_TLSDESC))))]
14742 "!TARGET_64BIT && TARGET_GNU2_TLS"
14743 "lea{l}\t{%E2@TLSDESC(%1), %0|%0, %E2@TLSDESC[%1]}"
14744 [(set_attr "type" "lea")
14745 (set_attr "mode" "SI")
14746 (set_attr "length" "6")
14747 (set_attr "length_address" "4")])
14749 (define_insn "*tls_dynamic_gnu2_call_32"
14750 [(set (match_operand:SI 0 "register_operand" "=a")
14751 (unspec:SI [(match_operand 1 "tls_symbolic_operand")
14752 (match_operand:SI 2 "register_operand" "0")
14753 ;; we have to make sure %ebx still points to the GOT
14754 (match_operand:SI 3 "register_operand" "b")
14757 (clobber (reg:CC FLAGS_REG))]
14758 "!TARGET_64BIT && TARGET_GNU2_TLS"
14759 "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
14760 [(set_attr "type" "call")
14761 (set_attr "length" "2")
14762 (set_attr "length_address" "0")])
14764 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
14765 [(set (match_operand:SI 0 "register_operand" "=&a")
14767 (unspec:SI [(match_operand 3 "tls_modbase_operand")
14768 (match_operand:SI 4)
14769 (match_operand:SI 2 "register_operand" "b")
14772 (const:SI (unspec:SI
14773 [(match_operand 1 "tls_symbolic_operand")]
14775 (clobber (reg:CC FLAGS_REG))]
14776 "!TARGET_64BIT && TARGET_GNU2_TLS"
14779 [(set (match_dup 0) (match_dup 5))]
14781 operands[5] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
14782 emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
14785 (define_expand "tls_dynamic_gnu2_64"
14786 [(set (match_dup 2)
14787 (unspec:DI [(match_operand 1 "tls_symbolic_operand")]
14790 [(set (match_operand:DI 0 "register_operand")
14791 (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
14793 (clobber (reg:CC FLAGS_REG))])]
14794 "TARGET_64BIT && TARGET_GNU2_TLS"
14796 operands[2] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
14797 ix86_tls_descriptor_calls_expanded_in_cfun = true;
14800 (define_insn "*tls_dynamic_gnu2_lea_64"
14801 [(set (match_operand:DI 0 "register_operand" "=r")
14802 (unspec:DI [(match_operand 1 "tls_symbolic_operand")]
14804 "TARGET_64BIT && TARGET_GNU2_TLS"
14805 "lea{q}\t{%E1@TLSDESC(%%rip), %0|%0, %E1@TLSDESC[rip]}"
14806 [(set_attr "type" "lea")
14807 (set_attr "mode" "DI")
14808 (set_attr "length" "7")
14809 (set_attr "length_address" "4")])
14811 (define_insn "*tls_dynamic_gnu2_call_64"
14812 [(set (match_operand:DI 0 "register_operand" "=a")
14813 (unspec:DI [(match_operand 1 "tls_symbolic_operand")
14814 (match_operand:DI 2 "register_operand" "0")
14817 (clobber (reg:CC FLAGS_REG))]
14818 "TARGET_64BIT && TARGET_GNU2_TLS"
14819 "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
14820 [(set_attr "type" "call")
14821 (set_attr "length" "2")
14822 (set_attr "length_address" "0")])
14824 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
14825 [(set (match_operand:DI 0 "register_operand" "=&a")
14827 (unspec:DI [(match_operand 2 "tls_modbase_operand")
14828 (match_operand:DI 3)
14831 (const:DI (unspec:DI
14832 [(match_operand 1 "tls_symbolic_operand")]
14834 (clobber (reg:CC FLAGS_REG))]
14835 "TARGET_64BIT && TARGET_GNU2_TLS"
14838 [(set (match_dup 0) (match_dup 4))]
14840 operands[4] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
14841 emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
14845 [(match_operand 0 "tls_address_pattern")]
14846 "TARGET_TLS_DIRECT_SEG_REFS"
14848 "operands[0] = ix86_rewrite_tls_address (operands[0]);")
14851 ;; These patterns match the binary 387 instructions for addM3, subM3,
14852 ;; mulM3 and divM3. There are three patterns for each of DFmode and
14853 ;; SFmode. The first is the normal insn, the second the same insn but
14854 ;; with one operand a conversion, and the third the same insn but with
14855 ;; the other operand a conversion. The conversion may be SFmode or
14856 ;; SImode if the target mode DFmode, but only SImode if the target mode
14859 ;; Gcc is slightly more smart about handling normal two address instructions
14860 ;; so use special patterns for add and mull.
14862 (define_insn "*fop_<mode>_comm"
14863 [(set (match_operand:MODEF 0 "register_operand" "=f,x,v")
14864 (match_operator:MODEF 3 "binary_fp_operator"
14865 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,0,v")
14866 (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm,vm")]))]
14867 "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14868 || (TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)))
14869 && COMMUTATIVE_ARITH_P (operands[3])
14870 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
14871 "* return output_387_binary_op (insn, operands);"
14872 [(set (attr "type")
14873 (if_then_else (eq_attr "alternative" "1,2")
14874 (if_then_else (match_operand:MODEF 3 "mult_operator")
14875 (const_string "ssemul")
14876 (const_string "sseadd"))
14877 (if_then_else (match_operand:MODEF 3 "mult_operator")
14878 (const_string "fmul")
14879 (const_string "fop"))))
14880 (set_attr "isa" "*,noavx,avx")
14881 (set_attr "prefix" "orig,orig,vex")
14882 (set_attr "mode" "<MODE>")
14883 (set (attr "enabled")
14885 (match_test ("SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"))
14887 (eq_attr "alternative" "0")
14888 (symbol_ref "TARGET_MIX_SSE_I387
14889 && X87_ENABLE_ARITH (<MODE>mode)")
14890 (const_string "*"))
14892 (eq_attr "alternative" "0")
14893 (symbol_ref "true")
14894 (symbol_ref "false"))))])
14896 (define_insn "*rcpsf2_sse"
14897 [(set (match_operand:SF 0 "register_operand" "=x")
14898 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
14900 "TARGET_SSE && TARGET_SSE_MATH"
14901 "%vrcpss\t{%1, %d0|%d0, %1}"
14902 [(set_attr "type" "sse")
14903 (set_attr "atom_sse_attr" "rcp")
14904 (set_attr "btver2_sse_attr" "rcp")
14905 (set_attr "prefix" "maybe_vex")
14906 (set_attr "mode" "SF")])
14908 (define_insn "*fop_<mode>_1"
14909 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,v")
14910 (match_operator:MODEF 3 "binary_fp_operator"
14911 [(match_operand:MODEF 1
14912 "x87nonimm_ssenomem_operand" "0,fm,0,v")
14913 (match_operand:MODEF 2
14914 "nonimmediate_operand" "fm,0,xm,vm")]))]
14915 "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14916 || (TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)))
14917 && !COMMUTATIVE_ARITH_P (operands[3])
14918 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
14919 "* return output_387_binary_op (insn, operands);"
14920 [(set (attr "type")
14921 (if_then_else (eq_attr "alternative" "2,3")
14922 (if_then_else (match_operand:MODEF 3 "div_operator")
14923 (const_string "ssediv")
14924 (const_string "sseadd"))
14925 (if_then_else (match_operand:MODEF 3 "div_operator")
14926 (const_string "fdiv")
14927 (const_string "fop"))))
14928 (set_attr "isa" "*,*,noavx,avx")
14929 (set_attr "prefix" "orig,orig,orig,vex")
14930 (set_attr "mode" "<MODE>")
14931 (set (attr "enabled")
14933 (match_test ("SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"))
14935 (eq_attr "alternative" "0,1")
14936 (symbol_ref "TARGET_MIX_SSE_I387
14937 && X87_ENABLE_ARITH (<MODE>mode)")
14938 (const_string "*"))
14940 (eq_attr "alternative" "0,1")
14941 (symbol_ref "true")
14942 (symbol_ref "false"))))])
14944 ;; ??? Add SSE splitters for these!
14945 (define_insn "*fop_<MODEF:mode>_2_i387"
14946 [(set (match_operand:MODEF 0 "register_operand" "=f")
14947 (match_operator:MODEF 3 "binary_fp_operator"
14949 (match_operand:SWI24 1 "nonimmediate_operand" "m"))
14950 (match_operand:MODEF 2 "register_operand" "0")]))]
14951 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI24:MODE>mode)
14952 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
14953 && (TARGET_USE_<SWI24:MODE>MODE_FIOP
14954 || optimize_function_for_size_p (cfun))"
14955 "* return output_387_binary_op (insn, operands);"
14956 [(set (attr "type")
14957 (cond [(match_operand:MODEF 3 "mult_operator")
14958 (const_string "fmul")
14959 (match_operand:MODEF 3 "div_operator")
14960 (const_string "fdiv")
14962 (const_string "fop")))
14963 (set_attr "fp_int_src" "true")
14964 (set_attr "mode" "<SWI24:MODE>")])
14966 (define_insn "*fop_<MODEF:mode>_3_i387"
14967 [(set (match_operand:MODEF 0 "register_operand" "=f")
14968 (match_operator:MODEF 3 "binary_fp_operator"
14969 [(match_operand:MODEF 1 "register_operand" "0")
14971 (match_operand:SWI24 2 "nonimmediate_operand" "m"))]))]
14972 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI24:MODE>mode)
14973 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
14974 && (TARGET_USE_<SWI24:MODE>MODE_FIOP
14975 || optimize_function_for_size_p (cfun))"
14976 "* return output_387_binary_op (insn, operands);"
14977 [(set (attr "type")
14978 (cond [(match_operand:MODEF 3 "mult_operator")
14979 (const_string "fmul")
14980 (match_operand:MODEF 3 "div_operator")
14981 (const_string "fdiv")
14983 (const_string "fop")))
14984 (set_attr "fp_int_src" "true")
14985 (set_attr "mode" "<MODE>")])
14987 (define_insn "*fop_df_4_i387"
14988 [(set (match_operand:DF 0 "register_operand" "=f,f")
14989 (match_operator:DF 3 "binary_fp_operator"
14991 (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
14992 (match_operand:DF 2 "register_operand" "0,f")]))]
14993 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
14994 && !(SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
14995 "* return output_387_binary_op (insn, operands);"
14996 [(set (attr "type")
14997 (cond [(match_operand:DF 3 "mult_operator")
14998 (const_string "fmul")
14999 (match_operand:DF 3 "div_operator")
15000 (const_string "fdiv")
15002 (const_string "fop")))
15003 (set_attr "mode" "SF")])
15005 (define_insn "*fop_df_5_i387"
15006 [(set (match_operand:DF 0 "register_operand" "=f,f")
15007 (match_operator:DF 3 "binary_fp_operator"
15008 [(match_operand:DF 1 "register_operand" "0,f")
15010 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
15011 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
15012 && !(SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
15013 "* return output_387_binary_op (insn, operands);"
15014 [(set (attr "type")
15015 (cond [(match_operand:DF 3 "mult_operator")
15016 (const_string "fmul")
15017 (match_operand:DF 3 "div_operator")
15018 (const_string "fdiv")
15020 (const_string "fop")))
15021 (set_attr "mode" "SF")])
15023 (define_insn "*fop_df_6_i387"
15024 [(set (match_operand:DF 0 "register_operand" "=f,f")
15025 (match_operator:DF 3 "binary_fp_operator"
15027 (match_operand:SF 1 "register_operand" "0,f"))
15029 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
15030 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
15031 && !(SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
15032 "* return output_387_binary_op (insn, operands);"
15033 [(set (attr "type")
15034 (cond [(match_operand:DF 3 "mult_operator")
15035 (const_string "fmul")
15036 (match_operand:DF 3 "div_operator")
15037 (const_string "fdiv")
15039 (const_string "fop")))
15040 (set_attr "mode" "SF")])
15042 (define_insn "*fop_xf_comm_i387"
15043 [(set (match_operand:XF 0 "register_operand" "=f")
15044 (match_operator:XF 3 "binary_fp_operator"
15045 [(match_operand:XF 1 "register_operand" "%0")
15046 (match_operand:XF 2 "register_operand" "f")]))]
15048 && COMMUTATIVE_ARITH_P (operands[3])"
15049 "* return output_387_binary_op (insn, operands);"
15050 [(set (attr "type")
15051 (if_then_else (match_operand:XF 3 "mult_operator")
15052 (const_string "fmul")
15053 (const_string "fop")))
15054 (set_attr "mode" "XF")])
15056 (define_insn "*fop_xf_1_i387"
15057 [(set (match_operand:XF 0 "register_operand" "=f,f")
15058 (match_operator:XF 3 "binary_fp_operator"
15059 [(match_operand:XF 1 "register_operand" "0,f")
15060 (match_operand:XF 2 "register_operand" "f,0")]))]
15062 && !COMMUTATIVE_ARITH_P (operands[3])"
15063 "* return output_387_binary_op (insn, operands);"
15064 [(set (attr "type")
15065 (if_then_else (match_operand:XF 3 "div_operator")
15066 (const_string "fdiv")
15067 (const_string "fop")))
15068 (set_attr "mode" "XF")])
15070 (define_insn "*fop_xf_2_i387"
15071 [(set (match_operand:XF 0 "register_operand" "=f")
15072 (match_operator:XF 3 "binary_fp_operator"
15074 (match_operand:SWI24 1 "nonimmediate_operand" "m"))
15075 (match_operand:XF 2 "register_operand" "0")]))]
15077 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
15078 "* return output_387_binary_op (insn, operands);"
15079 [(set (attr "type")
15080 (cond [(match_operand:XF 3 "mult_operator")
15081 (const_string "fmul")
15082 (match_operand:XF 3 "div_operator")
15083 (const_string "fdiv")
15085 (const_string "fop")))
15086 (set_attr "fp_int_src" "true")
15087 (set_attr "mode" "<MODE>")])
15089 (define_insn "*fop_xf_3_i387"
15090 [(set (match_operand:XF 0 "register_operand" "=f")
15091 (match_operator:XF 3 "binary_fp_operator"
15092 [(match_operand:XF 1 "register_operand" "0")
15094 (match_operand:SWI24 2 "nonimmediate_operand" "m"))]))]
15096 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
15097 "* return output_387_binary_op (insn, operands);"
15098 [(set (attr "type")
15099 (cond [(match_operand:XF 3 "mult_operator")
15100 (const_string "fmul")
15101 (match_operand:XF 3 "div_operator")
15102 (const_string "fdiv")
15104 (const_string "fop")))
15105 (set_attr "fp_int_src" "true")
15106 (set_attr "mode" "<MODE>")])
15108 (define_insn "*fop_xf_4_i387"
15109 [(set (match_operand:XF 0 "register_operand" "=f,f")
15110 (match_operator:XF 3 "binary_fp_operator"
15112 (match_operand:MODEF 1 "nonimmediate_operand" "fm,0"))
15113 (match_operand:XF 2 "register_operand" "0,f")]))]
15115 "* return output_387_binary_op (insn, operands);"
15116 [(set (attr "type")
15117 (cond [(match_operand:XF 3 "mult_operator")
15118 (const_string "fmul")
15119 (match_operand:XF 3 "div_operator")
15120 (const_string "fdiv")
15122 (const_string "fop")))
15123 (set_attr "mode" "<MODE>")])
15125 (define_insn "*fop_xf_5_i387"
15126 [(set (match_operand:XF 0 "register_operand" "=f,f")
15127 (match_operator:XF 3 "binary_fp_operator"
15128 [(match_operand:XF 1 "register_operand" "0,f")
15130 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
15132 "* return output_387_binary_op (insn, operands);"
15133 [(set (attr "type")
15134 (cond [(match_operand:XF 3 "mult_operator")
15135 (const_string "fmul")
15136 (match_operand:XF 3 "div_operator")
15137 (const_string "fdiv")
15139 (const_string "fop")))
15140 (set_attr "mode" "<MODE>")])
15142 (define_insn "*fop_xf_6_i387"
15143 [(set (match_operand:XF 0 "register_operand" "=f,f")
15144 (match_operator:XF 3 "binary_fp_operator"
15146 (match_operand:MODEF 1 "register_operand" "0,f"))
15148 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
15150 "* return output_387_binary_op (insn, operands);"
15151 [(set (attr "type")
15152 (cond [(match_operand:XF 3 "mult_operator")
15153 (const_string "fmul")
15154 (match_operand:XF 3 "div_operator")
15155 (const_string "fdiv")
15157 (const_string "fop")))
15158 (set_attr "mode" "<MODE>")])
15160 ;; FPU special functions.
15162 ;; This pattern implements a no-op XFmode truncation for
15163 ;; all fancy i386 XFmode math functions.
15165 (define_insn "truncxf<mode>2_i387_noop_unspec"
15166 [(set (match_operand:MODEF 0 "register_operand" "=f")
15167 (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")]
15168 UNSPEC_TRUNC_NOOP))]
15169 "TARGET_USE_FANCY_MATH_387"
15170 "* return output_387_reg_move (insn, operands);"
15171 [(set_attr "type" "fmov")
15172 (set_attr "mode" "<MODE>")])
15174 (define_insn "sqrtxf2"
15175 [(set (match_operand:XF 0 "register_operand" "=f")
15176 (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
15177 "TARGET_USE_FANCY_MATH_387"
15179 [(set_attr "type" "fpspc")
15180 (set_attr "mode" "XF")
15181 (set_attr "athlon_decode" "direct")
15182 (set_attr "amdfam10_decode" "direct")
15183 (set_attr "bdver1_decode" "direct")])
15185 (define_insn "sqrt_extend<mode>xf2_i387"
15186 [(set (match_operand:XF 0 "register_operand" "=f")
15189 (match_operand:MODEF 1 "register_operand" "0"))))]
15190 "TARGET_USE_FANCY_MATH_387"
15192 [(set_attr "type" "fpspc")
15193 (set_attr "mode" "XF")
15194 (set_attr "athlon_decode" "direct")
15195 (set_attr "amdfam10_decode" "direct")
15196 (set_attr "bdver1_decode" "direct")])
15198 (define_insn "*rsqrtsf2_sse"
15199 [(set (match_operand:SF 0 "register_operand" "=x")
15200 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
15202 "TARGET_SSE && TARGET_SSE_MATH"
15203 "%vrsqrtss\t{%1, %d0|%d0, %1}"
15204 [(set_attr "type" "sse")
15205 (set_attr "atom_sse_attr" "rcp")
15206 (set_attr "btver2_sse_attr" "rcp")
15207 (set_attr "prefix" "maybe_vex")
15208 (set_attr "mode" "SF")])
15210 (define_expand "rsqrtsf2"
15211 [(set (match_operand:SF 0 "register_operand")
15212 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand")]
15214 "TARGET_SSE && TARGET_SSE_MATH"
15216 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
15220 (define_insn "*sqrt<mode>2_sse"
15221 [(set (match_operand:MODEF 0 "register_operand" "=v")
15223 (match_operand:MODEF 1 "nonimmediate_operand" "vm")))]
15224 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
15225 "%vsqrt<ssemodesuffix>\t{%1, %d0|%d0, %1}"
15226 [(set_attr "type" "sse")
15227 (set_attr "atom_sse_attr" "sqrt")
15228 (set_attr "btver2_sse_attr" "sqrt")
15229 (set_attr "prefix" "maybe_vex")
15230 (set_attr "mode" "<MODE>")
15231 (set_attr "athlon_decode" "*")
15232 (set_attr "amdfam10_decode" "*")
15233 (set_attr "bdver1_decode" "*")])
15235 (define_expand "sqrt<mode>2"
15236 [(set (match_operand:MODEF 0 "register_operand")
15238 (match_operand:MODEF 1 "nonimmediate_operand")))]
15239 "(TARGET_USE_FANCY_MATH_387 && X87_ENABLE_ARITH (<MODE>mode))
15240 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
15242 if (<MODE>mode == SFmode
15243 && TARGET_SSE && TARGET_SSE_MATH
15244 && TARGET_RECIP_SQRT
15245 && !optimize_function_for_size_p (cfun)
15246 && flag_finite_math_only && !flag_trapping_math
15247 && flag_unsafe_math_optimizations)
15249 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
15253 if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
15255 rtx op0 = gen_reg_rtx (XFmode);
15256 rtx op1 = force_reg (<MODE>mode, operands[1]);
15258 emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
15259 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
15264 (define_insn "fpremxf4_i387"
15265 [(set (match_operand:XF 0 "register_operand" "=f")
15266 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15267 (match_operand:XF 3 "register_operand" "1")]
15269 (set (match_operand:XF 1 "register_operand" "=u")
15270 (unspec:XF [(match_dup 2) (match_dup 3)]
15272 (set (reg:CCFP FPSR_REG)
15273 (unspec:CCFP [(match_dup 2) (match_dup 3)]
15275 "TARGET_USE_FANCY_MATH_387
15276 && flag_finite_math_only"
15278 [(set_attr "type" "fpspc")
15279 (set_attr "znver1_decode" "vector")
15280 (set_attr "mode" "XF")])
15282 (define_expand "fmodxf3"
15283 [(use (match_operand:XF 0 "register_operand"))
15284 (use (match_operand:XF 1 "general_operand"))
15285 (use (match_operand:XF 2 "general_operand"))]
15286 "TARGET_USE_FANCY_MATH_387
15287 && flag_finite_math_only"
15289 rtx_code_label *label = gen_label_rtx ();
15291 rtx op1 = gen_reg_rtx (XFmode);
15292 rtx op2 = gen_reg_rtx (XFmode);
15294 emit_move_insn (op2, operands[2]);
15295 emit_move_insn (op1, operands[1]);
15297 emit_label (label);
15298 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
15299 ix86_emit_fp_unordered_jump (label);
15300 LABEL_NUSES (label) = 1;
15302 emit_move_insn (operands[0], op1);
15306 (define_expand "fmod<mode>3"
15307 [(use (match_operand:MODEF 0 "register_operand"))
15308 (use (match_operand:MODEF 1 "general_operand"))
15309 (use (match_operand:MODEF 2 "general_operand"))]
15310 "TARGET_USE_FANCY_MATH_387
15311 && flag_finite_math_only"
15313 rtx (*gen_truncxf) (rtx, rtx);
15315 rtx_code_label *label = gen_label_rtx ();
15317 rtx op1 = gen_reg_rtx (XFmode);
15318 rtx op2 = gen_reg_rtx (XFmode);
15320 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
15321 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15323 emit_label (label);
15324 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
15325 ix86_emit_fp_unordered_jump (label);
15326 LABEL_NUSES (label) = 1;
15328 /* Truncate the result properly for strict SSE math. */
15329 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15330 && !TARGET_MIX_SSE_I387)
15331 gen_truncxf = gen_truncxf<mode>2;
15333 gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
15335 emit_insn (gen_truncxf (operands[0], op1));
15339 (define_insn "fprem1xf4_i387"
15340 [(set (match_operand:XF 0 "register_operand" "=f")
15341 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15342 (match_operand:XF 3 "register_operand" "1")]
15344 (set (match_operand:XF 1 "register_operand" "=u")
15345 (unspec:XF [(match_dup 2) (match_dup 3)]
15347 (set (reg:CCFP FPSR_REG)
15348 (unspec:CCFP [(match_dup 2) (match_dup 3)]
15350 "TARGET_USE_FANCY_MATH_387
15351 && flag_finite_math_only"
15353 [(set_attr "type" "fpspc")
15354 (set_attr "znver1_decode" "vector")
15355 (set_attr "mode" "XF")])
15357 (define_expand "remainderxf3"
15358 [(use (match_operand:XF 0 "register_operand"))
15359 (use (match_operand:XF 1 "general_operand"))
15360 (use (match_operand:XF 2 "general_operand"))]
15361 "TARGET_USE_FANCY_MATH_387
15362 && flag_finite_math_only"
15364 rtx_code_label *label = gen_label_rtx ();
15366 rtx op1 = gen_reg_rtx (XFmode);
15367 rtx op2 = gen_reg_rtx (XFmode);
15369 emit_move_insn (op2, operands[2]);
15370 emit_move_insn (op1, operands[1]);
15372 emit_label (label);
15373 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
15374 ix86_emit_fp_unordered_jump (label);
15375 LABEL_NUSES (label) = 1;
15377 emit_move_insn (operands[0], op1);
15381 (define_expand "remainder<mode>3"
15382 [(use (match_operand:MODEF 0 "register_operand"))
15383 (use (match_operand:MODEF 1 "general_operand"))
15384 (use (match_operand:MODEF 2 "general_operand"))]
15385 "TARGET_USE_FANCY_MATH_387
15386 && flag_finite_math_only"
15388 rtx (*gen_truncxf) (rtx, rtx);
15390 rtx_code_label *label = gen_label_rtx ();
15392 rtx op1 = gen_reg_rtx (XFmode);
15393 rtx op2 = gen_reg_rtx (XFmode);
15395 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
15396 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15398 emit_label (label);
15400 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
15401 ix86_emit_fp_unordered_jump (label);
15402 LABEL_NUSES (label) = 1;
15404 /* Truncate the result properly for strict SSE math. */
15405 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15406 && !TARGET_MIX_SSE_I387)
15407 gen_truncxf = gen_truncxf<mode>2;
15409 gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
15411 emit_insn (gen_truncxf (operands[0], op1));
15415 (define_int_iterator SINCOS
15419 (define_int_attr sincos
15420 [(UNSPEC_SIN "sin")
15421 (UNSPEC_COS "cos")])
15423 (define_insn "*<sincos>xf2_i387"
15424 [(set (match_operand:XF 0 "register_operand" "=f")
15425 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15427 "TARGET_USE_FANCY_MATH_387
15428 && flag_unsafe_math_optimizations"
15430 [(set_attr "type" "fpspc")
15431 (set_attr "znver1_decode" "vector")
15432 (set_attr "mode" "XF")])
15434 (define_insn "*<sincos>_extend<mode>xf2_i387"
15435 [(set (match_operand:XF 0 "register_operand" "=f")
15436 (unspec:XF [(float_extend:XF
15437 (match_operand:MODEF 1 "register_operand" "0"))]
15439 "TARGET_USE_FANCY_MATH_387
15440 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15441 || TARGET_MIX_SSE_I387)
15442 && flag_unsafe_math_optimizations"
15444 [(set_attr "type" "fpspc")
15445 (set_attr "znver1_decode" "vector")
15446 (set_attr "mode" "XF")])
15448 ;; When sincos pattern is defined, sin and cos builtin functions will be
15449 ;; expanded to sincos pattern with one of its outputs left unused.
15450 ;; CSE pass will figure out if two sincos patterns can be combined,
15451 ;; otherwise sincos pattern will be split back to sin or cos pattern,
15452 ;; depending on the unused output.
15454 (define_insn "sincosxf3"
15455 [(set (match_operand:XF 0 "register_operand" "=f")
15456 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15457 UNSPEC_SINCOS_COS))
15458 (set (match_operand:XF 1 "register_operand" "=u")
15459 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15460 "TARGET_USE_FANCY_MATH_387
15461 && flag_unsafe_math_optimizations"
15463 [(set_attr "type" "fpspc")
15464 (set_attr "znver1_decode" "vector")
15465 (set_attr "mode" "XF")])
15468 [(set (match_operand:XF 0 "register_operand")
15469 (unspec:XF [(match_operand:XF 2 "register_operand")]
15470 UNSPEC_SINCOS_COS))
15471 (set (match_operand:XF 1 "register_operand")
15472 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15473 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15474 && can_create_pseudo_p ()"
15475 [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))])
15478 [(set (match_operand:XF 0 "register_operand")
15479 (unspec:XF [(match_operand:XF 2 "register_operand")]
15480 UNSPEC_SINCOS_COS))
15481 (set (match_operand:XF 1 "register_operand")
15482 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15483 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15484 && can_create_pseudo_p ()"
15485 [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))])
15487 (define_insn "sincos_extend<mode>xf3_i387"
15488 [(set (match_operand:XF 0 "register_operand" "=f")
15489 (unspec:XF [(float_extend:XF
15490 (match_operand:MODEF 2 "register_operand" "0"))]
15491 UNSPEC_SINCOS_COS))
15492 (set (match_operand:XF 1 "register_operand" "=u")
15493 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
15494 "TARGET_USE_FANCY_MATH_387
15495 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15496 || TARGET_MIX_SSE_I387)
15497 && flag_unsafe_math_optimizations"
15499 [(set_attr "type" "fpspc")
15500 (set_attr "znver1_decode" "vector")
15501 (set_attr "mode" "XF")])
15504 [(set (match_operand:XF 0 "register_operand")
15505 (unspec:XF [(float_extend:XF
15506 (match_operand:MODEF 2 "register_operand"))]
15507 UNSPEC_SINCOS_COS))
15508 (set (match_operand:XF 1 "register_operand")
15509 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
15510 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15511 && can_create_pseudo_p ()"
15512 [(set (match_dup 1)
15513 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))])
15516 [(set (match_operand:XF 0 "register_operand")
15517 (unspec:XF [(float_extend:XF
15518 (match_operand:MODEF 2 "register_operand"))]
15519 UNSPEC_SINCOS_COS))
15520 (set (match_operand:XF 1 "register_operand")
15521 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
15522 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15523 && can_create_pseudo_p ()"
15524 [(set (match_dup 0)
15525 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))])
15527 (define_expand "sincos<mode>3"
15528 [(use (match_operand:MODEF 0 "register_operand"))
15529 (use (match_operand:MODEF 1 "register_operand"))
15530 (use (match_operand:MODEF 2 "register_operand"))]
15531 "TARGET_USE_FANCY_MATH_387
15532 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15533 || TARGET_MIX_SSE_I387)
15534 && flag_unsafe_math_optimizations"
15536 rtx op0 = gen_reg_rtx (XFmode);
15537 rtx op1 = gen_reg_rtx (XFmode);
15539 emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
15540 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15541 emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
15545 (define_insn "fptanxf4_i387"
15546 [(set (match_operand:XF 0 "register_operand" "=f")
15547 (match_operand:XF 3 "const_double_operand" "F"))
15548 (set (match_operand:XF 1 "register_operand" "=u")
15549 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15551 "TARGET_USE_FANCY_MATH_387
15552 && flag_unsafe_math_optimizations
15553 && standard_80387_constant_p (operands[3]) == 2"
15555 [(set_attr "type" "fpspc")
15556 (set_attr "znver1_decode" "vector")
15557 (set_attr "mode" "XF")])
15559 (define_insn "fptan_extend<mode>xf4_i387"
15560 [(set (match_operand:MODEF 0 "register_operand" "=f")
15561 (match_operand:MODEF 3 "const_double_operand" "F"))
15562 (set (match_operand:XF 1 "register_operand" "=u")
15563 (unspec:XF [(float_extend:XF
15564 (match_operand:MODEF 2 "register_operand" "0"))]
15566 "TARGET_USE_FANCY_MATH_387
15567 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15568 || TARGET_MIX_SSE_I387)
15569 && flag_unsafe_math_optimizations
15570 && standard_80387_constant_p (operands[3]) == 2"
15572 [(set_attr "type" "fpspc")
15573 (set_attr "znver1_decode" "vector")
15574 (set_attr "mode" "XF")])
15576 (define_expand "tanxf2"
15577 [(use (match_operand:XF 0 "register_operand"))
15578 (use (match_operand:XF 1 "register_operand"))]
15579 "TARGET_USE_FANCY_MATH_387
15580 && flag_unsafe_math_optimizations"
15582 rtx one = gen_reg_rtx (XFmode);
15583 rtx op2 = CONST1_RTX (XFmode); /* fld1 */
15585 emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2));
15589 (define_expand "tan<mode>2"
15590 [(use (match_operand:MODEF 0 "register_operand"))
15591 (use (match_operand:MODEF 1 "register_operand"))]
15592 "TARGET_USE_FANCY_MATH_387
15593 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15594 || TARGET_MIX_SSE_I387)
15595 && flag_unsafe_math_optimizations"
15597 rtx op0 = gen_reg_rtx (XFmode);
15599 rtx one = gen_reg_rtx (<MODE>mode);
15600 rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */
15602 emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
15603 operands[1], op2));
15604 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15608 (define_insn "*fpatanxf3_i387"
15609 [(set (match_operand:XF 0 "register_operand" "=f")
15610 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
15611 (match_operand:XF 2 "register_operand" "u")]
15613 (clobber (match_scratch:XF 3 "=2"))]
15614 "TARGET_USE_FANCY_MATH_387
15615 && flag_unsafe_math_optimizations"
15617 [(set_attr "type" "fpspc")
15618 (set_attr "znver1_decode" "vector")
15619 (set_attr "mode" "XF")])
15621 (define_insn "fpatan_extend<mode>xf3_i387"
15622 [(set (match_operand:XF 0 "register_operand" "=f")
15623 (unspec:XF [(float_extend:XF
15624 (match_operand:MODEF 1 "register_operand" "0"))
15626 (match_operand:MODEF 2 "register_operand" "u"))]
15628 (clobber (match_scratch:XF 3 "=2"))]
15629 "TARGET_USE_FANCY_MATH_387
15630 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15631 || TARGET_MIX_SSE_I387)
15632 && flag_unsafe_math_optimizations"
15634 [(set_attr "type" "fpspc")
15635 (set_attr "znver1_decode" "vector")
15636 (set_attr "mode" "XF")])
15638 (define_expand "atan2xf3"
15639 [(parallel [(set (match_operand:XF 0 "register_operand")
15640 (unspec:XF [(match_operand:XF 2 "register_operand")
15641 (match_operand:XF 1 "register_operand")]
15643 (clobber (match_scratch:XF 3))])]
15644 "TARGET_USE_FANCY_MATH_387
15645 && flag_unsafe_math_optimizations")
15647 (define_expand "atan2<mode>3"
15648 [(use (match_operand:MODEF 0 "register_operand"))
15649 (use (match_operand:MODEF 1 "register_operand"))
15650 (use (match_operand:MODEF 2 "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 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
15659 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15663 (define_expand "atanxf2"
15664 [(parallel [(set (match_operand:XF 0 "register_operand")
15665 (unspec:XF [(match_dup 2)
15666 (match_operand:XF 1 "register_operand")]
15668 (clobber (match_scratch:XF 3))])]
15669 "TARGET_USE_FANCY_MATH_387
15670 && flag_unsafe_math_optimizations"
15672 operands[2] = gen_reg_rtx (XFmode);
15673 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
15676 (define_expand "atan<mode>2"
15677 [(use (match_operand:MODEF 0 "register_operand"))
15678 (use (match_operand:MODEF 1 "register_operand"))]
15679 "TARGET_USE_FANCY_MATH_387
15680 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15681 || TARGET_MIX_SSE_I387)
15682 && flag_unsafe_math_optimizations"
15684 rtx op0 = gen_reg_rtx (XFmode);
15686 rtx op2 = gen_reg_rtx (<MODE>mode);
15687 emit_move_insn (op2, CONST1_RTX (<MODE>mode)); /* fld1 */
15689 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1]));
15690 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15694 (define_expand "asinxf2"
15695 [(set (match_dup 2)
15696 (mult:XF (match_operand:XF 1 "register_operand")
15698 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
15699 (set (match_dup 5) (sqrt:XF (match_dup 4)))
15700 (parallel [(set (match_operand:XF 0 "register_operand")
15701 (unspec:XF [(match_dup 5) (match_dup 1)]
15703 (clobber (match_scratch:XF 6))])]
15704 "TARGET_USE_FANCY_MATH_387
15705 && flag_unsafe_math_optimizations"
15709 for (i = 2; i < 6; i++)
15710 operands[i] = gen_reg_rtx (XFmode);
15712 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
15715 (define_expand "asin<mode>2"
15716 [(use (match_operand:MODEF 0 "register_operand"))
15717 (use (match_operand:MODEF 1 "general_operand"))]
15718 "TARGET_USE_FANCY_MATH_387
15719 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15720 || TARGET_MIX_SSE_I387)
15721 && flag_unsafe_math_optimizations"
15723 rtx op0 = gen_reg_rtx (XFmode);
15724 rtx op1 = gen_reg_rtx (XFmode);
15726 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15727 emit_insn (gen_asinxf2 (op0, op1));
15728 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15732 (define_expand "acosxf2"
15733 [(set (match_dup 2)
15734 (mult:XF (match_operand:XF 1 "register_operand")
15736 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
15737 (set (match_dup 5) (sqrt:XF (match_dup 4)))
15738 (parallel [(set (match_operand:XF 0 "register_operand")
15739 (unspec:XF [(match_dup 1) (match_dup 5)]
15741 (clobber (match_scratch:XF 6))])]
15742 "TARGET_USE_FANCY_MATH_387
15743 && flag_unsafe_math_optimizations"
15747 for (i = 2; i < 6; i++)
15748 operands[i] = gen_reg_rtx (XFmode);
15750 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
15753 (define_expand "acos<mode>2"
15754 [(use (match_operand:MODEF 0 "register_operand"))
15755 (use (match_operand:MODEF 1 "general_operand"))]
15756 "TARGET_USE_FANCY_MATH_387
15757 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15758 || TARGET_MIX_SSE_I387)
15759 && flag_unsafe_math_optimizations"
15761 rtx op0 = gen_reg_rtx (XFmode);
15762 rtx op1 = gen_reg_rtx (XFmode);
15764 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15765 emit_insn (gen_acosxf2 (op0, op1));
15766 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15770 (define_insn "fyl2xxf3_i387"
15771 [(set (match_operand:XF 0 "register_operand" "=f")
15772 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
15773 (match_operand:XF 2 "register_operand" "u")]
15775 (clobber (match_scratch:XF 3 "=2"))]
15776 "TARGET_USE_FANCY_MATH_387
15777 && flag_unsafe_math_optimizations"
15779 [(set_attr "type" "fpspc")
15780 (set_attr "znver1_decode" "vector")
15781 (set_attr "mode" "XF")])
15783 (define_insn "fyl2x_extend<mode>xf3_i387"
15784 [(set (match_operand:XF 0 "register_operand" "=f")
15785 (unspec:XF [(float_extend:XF
15786 (match_operand:MODEF 1 "register_operand" "0"))
15787 (match_operand:XF 2 "register_operand" "u")]
15789 (clobber (match_scratch:XF 3 "=2"))]
15790 "TARGET_USE_FANCY_MATH_387
15791 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15792 || TARGET_MIX_SSE_I387)
15793 && flag_unsafe_math_optimizations"
15795 [(set_attr "type" "fpspc")
15796 (set_attr "znver1_decode" "vector")
15797 (set_attr "mode" "XF")])
15799 (define_expand "logxf2"
15800 [(parallel [(set (match_operand:XF 0 "register_operand")
15801 (unspec:XF [(match_operand:XF 1 "register_operand")
15802 (match_dup 2)] UNSPEC_FYL2X))
15803 (clobber (match_scratch:XF 3))])]
15804 "TARGET_USE_FANCY_MATH_387
15805 && flag_unsafe_math_optimizations"
15807 operands[2] = gen_reg_rtx (XFmode);
15808 emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */
15811 (define_expand "log<mode>2"
15812 [(use (match_operand:MODEF 0 "register_operand"))
15813 (use (match_operand:MODEF 1 "register_operand"))]
15814 "TARGET_USE_FANCY_MATH_387
15815 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15816 || TARGET_MIX_SSE_I387)
15817 && flag_unsafe_math_optimizations"
15819 rtx op0 = gen_reg_rtx (XFmode);
15821 rtx op2 = gen_reg_rtx (XFmode);
15822 emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */
15824 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
15825 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15829 (define_expand "log10xf2"
15830 [(parallel [(set (match_operand:XF 0 "register_operand")
15831 (unspec:XF [(match_operand:XF 1 "register_operand")
15832 (match_dup 2)] UNSPEC_FYL2X))
15833 (clobber (match_scratch:XF 3))])]
15834 "TARGET_USE_FANCY_MATH_387
15835 && flag_unsafe_math_optimizations"
15837 operands[2] = gen_reg_rtx (XFmode);
15838 emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
15841 (define_expand "log10<mode>2"
15842 [(use (match_operand:MODEF 0 "register_operand"))
15843 (use (match_operand:MODEF 1 "register_operand"))]
15844 "TARGET_USE_FANCY_MATH_387
15845 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15846 || TARGET_MIX_SSE_I387)
15847 && flag_unsafe_math_optimizations"
15849 rtx op0 = gen_reg_rtx (XFmode);
15851 rtx op2 = gen_reg_rtx (XFmode);
15852 emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */
15854 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
15855 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15859 (define_expand "log2xf2"
15860 [(parallel [(set (match_operand:XF 0 "register_operand")
15861 (unspec:XF [(match_operand:XF 1 "register_operand")
15862 (match_dup 2)] UNSPEC_FYL2X))
15863 (clobber (match_scratch:XF 3))])]
15864 "TARGET_USE_FANCY_MATH_387
15865 && flag_unsafe_math_optimizations"
15867 operands[2] = gen_reg_rtx (XFmode);
15868 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
15871 (define_expand "log2<mode>2"
15872 [(use (match_operand:MODEF 0 "register_operand"))
15873 (use (match_operand:MODEF 1 "register_operand"))]
15874 "TARGET_USE_FANCY_MATH_387
15875 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15876 || TARGET_MIX_SSE_I387)
15877 && flag_unsafe_math_optimizations"
15879 rtx op0 = gen_reg_rtx (XFmode);
15881 rtx op2 = gen_reg_rtx (XFmode);
15882 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
15884 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
15885 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15889 (define_insn "fyl2xp1xf3_i387"
15890 [(set (match_operand:XF 0 "register_operand" "=f")
15891 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
15892 (match_operand:XF 2 "register_operand" "u")]
15894 (clobber (match_scratch:XF 3 "=2"))]
15895 "TARGET_USE_FANCY_MATH_387
15896 && flag_unsafe_math_optimizations"
15898 [(set_attr "type" "fpspc")
15899 (set_attr "znver1_decode" "vector")
15900 (set_attr "mode" "XF")])
15902 (define_insn "fyl2xp1_extend<mode>xf3_i387"
15903 [(set (match_operand:XF 0 "register_operand" "=f")
15904 (unspec:XF [(float_extend:XF
15905 (match_operand:MODEF 1 "register_operand" "0"))
15906 (match_operand:XF 2 "register_operand" "u")]
15908 (clobber (match_scratch:XF 3 "=2"))]
15909 "TARGET_USE_FANCY_MATH_387
15910 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15911 || TARGET_MIX_SSE_I387)
15912 && flag_unsafe_math_optimizations"
15914 [(set_attr "type" "fpspc")
15915 (set_attr "znver1_decode" "vector")
15916 (set_attr "mode" "XF")])
15918 (define_expand "log1pxf2"
15919 [(use (match_operand:XF 0 "register_operand"))
15920 (use (match_operand:XF 1 "register_operand"))]
15921 "TARGET_USE_FANCY_MATH_387
15922 && flag_unsafe_math_optimizations"
15924 ix86_emit_i387_log1p (operands[0], operands[1]);
15928 (define_expand "log1p<mode>2"
15929 [(use (match_operand:MODEF 0 "register_operand"))
15930 (use (match_operand:MODEF 1 "register_operand"))]
15931 "TARGET_USE_FANCY_MATH_387
15932 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15933 || TARGET_MIX_SSE_I387)
15934 && flag_unsafe_math_optimizations"
15938 op0 = gen_reg_rtx (XFmode);
15940 operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
15942 ix86_emit_i387_log1p (op0, operands[1]);
15943 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15947 (define_insn "fxtractxf3_i387"
15948 [(set (match_operand:XF 0 "register_operand" "=f")
15949 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15950 UNSPEC_XTRACT_FRACT))
15951 (set (match_operand:XF 1 "register_operand" "=u")
15952 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
15953 "TARGET_USE_FANCY_MATH_387
15954 && flag_unsafe_math_optimizations"
15956 [(set_attr "type" "fpspc")
15957 (set_attr "znver1_decode" "vector")
15958 (set_attr "mode" "XF")])
15960 (define_insn "fxtract_extend<mode>xf3_i387"
15961 [(set (match_operand:XF 0 "register_operand" "=f")
15962 (unspec:XF [(float_extend:XF
15963 (match_operand:MODEF 2 "register_operand" "0"))]
15964 UNSPEC_XTRACT_FRACT))
15965 (set (match_operand:XF 1 "register_operand" "=u")
15966 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
15967 "TARGET_USE_FANCY_MATH_387
15968 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15969 || TARGET_MIX_SSE_I387)
15970 && flag_unsafe_math_optimizations"
15972 [(set_attr "type" "fpspc")
15973 (set_attr "znver1_decode" "vector")
15974 (set_attr "mode" "XF")])
15976 (define_expand "logbxf2"
15977 [(parallel [(set (match_dup 2)
15978 (unspec:XF [(match_operand:XF 1 "register_operand")]
15979 UNSPEC_XTRACT_FRACT))
15980 (set (match_operand:XF 0 "register_operand")
15981 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
15982 "TARGET_USE_FANCY_MATH_387
15983 && flag_unsafe_math_optimizations"
15984 "operands[2] = gen_reg_rtx (XFmode);")
15986 (define_expand "logb<mode>2"
15987 [(use (match_operand:MODEF 0 "register_operand"))
15988 (use (match_operand:MODEF 1 "register_operand"))]
15989 "TARGET_USE_FANCY_MATH_387
15990 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15991 || TARGET_MIX_SSE_I387)
15992 && flag_unsafe_math_optimizations"
15994 rtx op0 = gen_reg_rtx (XFmode);
15995 rtx op1 = gen_reg_rtx (XFmode);
15997 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
15998 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1));
16002 (define_expand "ilogbxf2"
16003 [(use (match_operand:SI 0 "register_operand"))
16004 (use (match_operand:XF 1 "register_operand"))]
16005 "TARGET_USE_FANCY_MATH_387
16006 && flag_unsafe_math_optimizations"
16010 if (optimize_insn_for_size_p ())
16013 op0 = gen_reg_rtx (XFmode);
16014 op1 = gen_reg_rtx (XFmode);
16016 emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
16017 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
16021 (define_expand "ilogb<mode>2"
16022 [(use (match_operand:SI 0 "register_operand"))
16023 (use (match_operand:MODEF 1 "register_operand"))]
16024 "TARGET_USE_FANCY_MATH_387
16025 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16026 || TARGET_MIX_SSE_I387)
16027 && flag_unsafe_math_optimizations"
16031 if (optimize_insn_for_size_p ())
16034 op0 = gen_reg_rtx (XFmode);
16035 op1 = gen_reg_rtx (XFmode);
16037 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
16038 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
16042 (define_insn "*f2xm1xf2_i387"
16043 [(set (match_operand:XF 0 "register_operand" "=f")
16044 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16046 "TARGET_USE_FANCY_MATH_387
16047 && flag_unsafe_math_optimizations"
16049 [(set_attr "type" "fpspc")
16050 (set_attr "znver1_decode" "vector")
16051 (set_attr "mode" "XF")])
16053 (define_insn "fscalexf4_i387"
16054 [(set (match_operand:XF 0 "register_operand" "=f")
16055 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16056 (match_operand:XF 3 "register_operand" "1")]
16057 UNSPEC_FSCALE_FRACT))
16058 (set (match_operand:XF 1 "register_operand" "=u")
16059 (unspec:XF [(match_dup 2) (match_dup 3)]
16060 UNSPEC_FSCALE_EXP))]
16061 "TARGET_USE_FANCY_MATH_387
16062 && flag_unsafe_math_optimizations"
16064 [(set_attr "type" "fpspc")
16065 (set_attr "znver1_decode" "vector")
16066 (set_attr "mode" "XF")])
16068 (define_expand "expNcorexf3"
16069 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand")
16070 (match_operand:XF 2 "register_operand")))
16071 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16072 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16073 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16074 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
16075 (parallel [(set (match_operand:XF 0 "register_operand")
16076 (unspec:XF [(match_dup 8) (match_dup 4)]
16077 UNSPEC_FSCALE_FRACT))
16079 (unspec:XF [(match_dup 8) (match_dup 4)]
16080 UNSPEC_FSCALE_EXP))])]
16081 "TARGET_USE_FANCY_MATH_387
16082 && flag_unsafe_math_optimizations"
16086 for (i = 3; i < 10; i++)
16087 operands[i] = gen_reg_rtx (XFmode);
16089 emit_move_insn (operands[7], CONST1_RTX (XFmode)); /* fld1 */
16092 (define_expand "expxf2"
16093 [(use (match_operand:XF 0 "register_operand"))
16094 (use (match_operand:XF 1 "register_operand"))]
16095 "TARGET_USE_FANCY_MATH_387
16096 && flag_unsafe_math_optimizations"
16100 op2 = gen_reg_rtx (XFmode);
16101 emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */
16103 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
16107 (define_expand "exp<mode>2"
16108 [(use (match_operand:MODEF 0 "register_operand"))
16109 (use (match_operand:MODEF 1 "general_operand"))]
16110 "TARGET_USE_FANCY_MATH_387
16111 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16112 || TARGET_MIX_SSE_I387)
16113 && flag_unsafe_math_optimizations"
16117 op0 = gen_reg_rtx (XFmode);
16118 op1 = gen_reg_rtx (XFmode);
16120 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16121 emit_insn (gen_expxf2 (op0, op1));
16122 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16126 (define_expand "exp10xf2"
16127 [(use (match_operand:XF 0 "register_operand"))
16128 (use (match_operand:XF 1 "register_operand"))]
16129 "TARGET_USE_FANCY_MATH_387
16130 && flag_unsafe_math_optimizations"
16134 op2 = gen_reg_rtx (XFmode);
16135 emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */
16137 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
16141 (define_expand "exp10<mode>2"
16142 [(use (match_operand:MODEF 0 "register_operand"))
16143 (use (match_operand:MODEF 1 "general_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"
16151 op0 = gen_reg_rtx (XFmode);
16152 op1 = gen_reg_rtx (XFmode);
16154 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16155 emit_insn (gen_exp10xf2 (op0, op1));
16156 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16160 (define_expand "exp2xf2"
16161 [(use (match_operand:XF 0 "register_operand"))
16162 (use (match_operand:XF 1 "register_operand"))]
16163 "TARGET_USE_FANCY_MATH_387
16164 && flag_unsafe_math_optimizations"
16168 op2 = gen_reg_rtx (XFmode);
16169 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
16171 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
16175 (define_expand "exp2<mode>2"
16176 [(use (match_operand:MODEF 0 "register_operand"))
16177 (use (match_operand:MODEF 1 "general_operand"))]
16178 "TARGET_USE_FANCY_MATH_387
16179 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16180 || TARGET_MIX_SSE_I387)
16181 && flag_unsafe_math_optimizations"
16185 op0 = gen_reg_rtx (XFmode);
16186 op1 = gen_reg_rtx (XFmode);
16188 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16189 emit_insn (gen_exp2xf2 (op0, op1));
16190 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16194 (define_expand "expm1xf2"
16195 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand")
16197 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16198 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16199 (set (match_dup 9) (float_extend:XF (match_dup 13)))
16200 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16201 (parallel [(set (match_dup 7)
16202 (unspec:XF [(match_dup 6) (match_dup 4)]
16203 UNSPEC_FSCALE_FRACT))
16205 (unspec:XF [(match_dup 6) (match_dup 4)]
16206 UNSPEC_FSCALE_EXP))])
16207 (parallel [(set (match_dup 10)
16208 (unspec:XF [(match_dup 9) (match_dup 8)]
16209 UNSPEC_FSCALE_FRACT))
16210 (set (match_dup 11)
16211 (unspec:XF [(match_dup 9) (match_dup 8)]
16212 UNSPEC_FSCALE_EXP))])
16213 (set (match_dup 12) (minus:XF (match_dup 10)
16214 (float_extend:XF (match_dup 13))))
16215 (set (match_operand:XF 0 "register_operand")
16216 (plus:XF (match_dup 12) (match_dup 7)))]
16217 "TARGET_USE_FANCY_MATH_387
16218 && flag_unsafe_math_optimizations"
16222 for (i = 2; i < 13; i++)
16223 operands[i] = gen_reg_rtx (XFmode);
16226 = validize_mem (force_const_mem (SFmode, CONST1_RTX (SFmode))); /* fld1 */
16228 emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
16231 (define_expand "expm1<mode>2"
16232 [(use (match_operand:MODEF 0 "register_operand"))
16233 (use (match_operand:MODEF 1 "general_operand"))]
16234 "TARGET_USE_FANCY_MATH_387
16235 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16236 || TARGET_MIX_SSE_I387)
16237 && flag_unsafe_math_optimizations"
16241 op0 = gen_reg_rtx (XFmode);
16242 op1 = gen_reg_rtx (XFmode);
16244 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16245 emit_insn (gen_expm1xf2 (op0, op1));
16246 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16250 (define_expand "ldexpxf3"
16251 [(match_operand:XF 0 "register_operand")
16252 (match_operand:XF 1 "register_operand")
16253 (match_operand:SI 2 "register_operand")]
16254 "TARGET_USE_FANCY_MATH_387
16255 && flag_unsafe_math_optimizations"
16259 tmp1 = gen_reg_rtx (XFmode);
16260 tmp2 = gen_reg_rtx (XFmode);
16262 emit_insn (gen_floatsixf2 (tmp1, operands[2]));
16263 emit_insn (gen_fscalexf4_i387 (operands[0], tmp2,
16264 operands[1], tmp1));
16268 (define_expand "ldexp<mode>3"
16269 [(use (match_operand:MODEF 0 "register_operand"))
16270 (use (match_operand:MODEF 1 "general_operand"))
16271 (use (match_operand:SI 2 "register_operand"))]
16272 "TARGET_USE_FANCY_MATH_387
16273 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16274 || TARGET_MIX_SSE_I387)
16275 && flag_unsafe_math_optimizations"
16279 op0 = gen_reg_rtx (XFmode);
16280 op1 = gen_reg_rtx (XFmode);
16282 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16283 emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
16284 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16288 (define_expand "scalbxf3"
16289 [(parallel [(set (match_operand:XF 0 " register_operand")
16290 (unspec:XF [(match_operand:XF 1 "register_operand")
16291 (match_operand:XF 2 "register_operand")]
16292 UNSPEC_FSCALE_FRACT))
16294 (unspec:XF [(match_dup 1) (match_dup 2)]
16295 UNSPEC_FSCALE_EXP))])]
16296 "TARGET_USE_FANCY_MATH_387
16297 && flag_unsafe_math_optimizations"
16299 operands[3] = gen_reg_rtx (XFmode);
16302 (define_expand "scalb<mode>3"
16303 [(use (match_operand:MODEF 0 "register_operand"))
16304 (use (match_operand:MODEF 1 "general_operand"))
16305 (use (match_operand:MODEF 2 "general_operand"))]
16306 "TARGET_USE_FANCY_MATH_387
16307 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16308 || TARGET_MIX_SSE_I387)
16309 && flag_unsafe_math_optimizations"
16313 op0 = gen_reg_rtx (XFmode);
16314 op1 = gen_reg_rtx (XFmode);
16315 op2 = gen_reg_rtx (XFmode);
16317 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16318 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
16319 emit_insn (gen_scalbxf3 (op0, op1, op2));
16320 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16324 (define_expand "significandxf2"
16325 [(parallel [(set (match_operand:XF 0 "register_operand")
16326 (unspec:XF [(match_operand:XF 1 "register_operand")]
16327 UNSPEC_XTRACT_FRACT))
16329 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
16330 "TARGET_USE_FANCY_MATH_387
16331 && flag_unsafe_math_optimizations"
16332 "operands[2] = gen_reg_rtx (XFmode);")
16334 (define_expand "significand<mode>2"
16335 [(use (match_operand:MODEF 0 "register_operand"))
16336 (use (match_operand:MODEF 1 "register_operand"))]
16337 "TARGET_USE_FANCY_MATH_387
16338 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16339 || TARGET_MIX_SSE_I387)
16340 && flag_unsafe_math_optimizations"
16342 rtx op0 = gen_reg_rtx (XFmode);
16343 rtx op1 = gen_reg_rtx (XFmode);
16345 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
16346 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16351 (define_insn "sse4_1_round<mode>2"
16352 [(set (match_operand:MODEF 0 "register_operand" "=x,v")
16353 (unspec:MODEF [(match_operand:MODEF 1 "register_operand" "x,v")
16354 (match_operand:SI 2 "const_0_to_15_operand" "n,n")]
16358 %vround<ssemodesuffix>\t{%2, %1, %d0|%d0, %1, %2}
16359 vrndscale<ssemodesuffix>\t{%2, %1, %d0|%d0, %1, %2}"
16360 [(set_attr "type" "ssecvt")
16361 (set_attr "prefix_extra" "1,*")
16362 (set_attr "length_immediate" "*,1")
16363 (set_attr "prefix" "maybe_vex,evex")
16364 (set_attr "isa" "noavx512f,avx512f")
16365 (set_attr "mode" "<MODE>")])
16367 (define_insn "rintxf2"
16368 [(set (match_operand:XF 0 "register_operand" "=f")
16369 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16371 "TARGET_USE_FANCY_MATH_387"
16373 [(set_attr "type" "fpspc")
16374 (set_attr "znver1_decode" "vector")
16375 (set_attr "mode" "XF")])
16377 (define_insn "rint<mode>2_frndint"
16378 [(set (match_operand:MODEF 0 "register_operand" "=f")
16379 (unspec:MODEF [(match_operand:MODEF 1 "register_operand" "0")]
16381 "TARGET_USE_FANCY_MATH_387"
16383 [(set_attr "type" "fpspc")
16384 (set_attr "znver1_decode" "vector")
16385 (set_attr "mode" "<MODE>")])
16387 (define_expand "rint<mode>2"
16388 [(use (match_operand:MODEF 0 "register_operand"))
16389 (use (match_operand:MODEF 1 "register_operand"))]
16390 "(TARGET_USE_FANCY_MATH_387
16391 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16392 || TARGET_MIX_SSE_I387))
16393 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
16395 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16398 emit_insn (gen_sse4_1_round<mode>2
16399 (operands[0], operands[1], GEN_INT (ROUND_MXCSR)));
16401 ix86_expand_rint (operands[0], operands[1]);
16404 emit_insn (gen_rint<mode>2_frndint (operands[0], operands[1]));
16408 (define_expand "round<mode>2"
16409 [(match_operand:X87MODEF 0 "register_operand")
16410 (match_operand:X87MODEF 1 "nonimmediate_operand")]
16411 "(TARGET_USE_FANCY_MATH_387
16412 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16413 || TARGET_MIX_SSE_I387)
16414 && flag_unsafe_math_optimizations
16415 && (flag_fp_int_builtin_inexact || !flag_trapping_math))
16416 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16417 && !flag_trapping_math && !flag_rounding_math)"
16419 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16420 && !flag_trapping_math && !flag_rounding_math)
16424 operands[1] = force_reg (<MODE>mode, operands[1]);
16425 ix86_expand_round_sse4 (operands[0], operands[1]);
16427 else if (TARGET_64BIT || (<MODE>mode != DFmode))
16428 ix86_expand_round (operands[0], operands[1]);
16430 ix86_expand_rounddf_32 (operands[0], operands[1]);
16434 operands[1] = force_reg (<MODE>mode, operands[1]);
16435 ix86_emit_i387_round (operands[0], operands[1]);
16440 (define_insn_and_split "*fistdi2_1"
16441 [(set (match_operand:DI 0 "nonimmediate_operand")
16442 (unspec:DI [(match_operand:XF 1 "register_operand")]
16444 "TARGET_USE_FANCY_MATH_387
16445 && can_create_pseudo_p ()"
16450 if (memory_operand (operands[0], VOIDmode))
16451 emit_insn (gen_fistdi2 (operands[0], operands[1]));
16454 operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
16455 emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
16460 [(set_attr "type" "fpspc")
16461 (set_attr "mode" "DI")])
16463 (define_insn "fistdi2"
16464 [(set (match_operand:DI 0 "memory_operand" "=m")
16465 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
16467 (clobber (match_scratch:XF 2 "=&1f"))]
16468 "TARGET_USE_FANCY_MATH_387"
16469 "* return output_fix_trunc (insn, operands, false);"
16470 [(set_attr "type" "fpspc")
16471 (set_attr "mode" "DI")])
16473 (define_insn "fistdi2_with_temp"
16474 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
16475 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
16477 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))
16478 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
16479 "TARGET_USE_FANCY_MATH_387"
16481 [(set_attr "type" "fpspc")
16482 (set_attr "mode" "DI")])
16485 [(set (match_operand:DI 0 "register_operand")
16486 (unspec:DI [(match_operand:XF 1 "register_operand")]
16488 (clobber (match_operand:DI 2 "memory_operand"))
16489 (clobber (match_scratch 3))]
16491 [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
16492 (clobber (match_dup 3))])
16493 (set (match_dup 0) (match_dup 2))])
16496 [(set (match_operand:DI 0 "memory_operand")
16497 (unspec:DI [(match_operand:XF 1 "register_operand")]
16499 (clobber (match_operand:DI 2 "memory_operand"))
16500 (clobber (match_scratch 3))]
16502 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
16503 (clobber (match_dup 3))])])
16505 (define_insn_and_split "*fist<mode>2_1"
16506 [(set (match_operand:SWI24 0 "register_operand")
16507 (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
16509 "TARGET_USE_FANCY_MATH_387
16510 && can_create_pseudo_p ()"
16515 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
16516 emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
16520 [(set_attr "type" "fpspc")
16521 (set_attr "mode" "<MODE>")])
16523 (define_insn "fist<mode>2"
16524 [(set (match_operand:SWI24 0 "memory_operand" "=m")
16525 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
16527 "TARGET_USE_FANCY_MATH_387"
16528 "* return output_fix_trunc (insn, operands, false);"
16529 [(set_attr "type" "fpspc")
16530 (set_attr "mode" "<MODE>")])
16532 (define_insn "fist<mode>2_with_temp"
16533 [(set (match_operand:SWI24 0 "register_operand" "=r")
16534 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
16536 (clobber (match_operand:SWI24 2 "memory_operand" "=m"))]
16537 "TARGET_USE_FANCY_MATH_387"
16539 [(set_attr "type" "fpspc")
16540 (set_attr "mode" "<MODE>")])
16543 [(set (match_operand:SWI24 0 "register_operand")
16544 (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
16546 (clobber (match_operand:SWI24 2 "memory_operand"))]
16548 [(set (match_dup 2) (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST))
16549 (set (match_dup 0) (match_dup 2))])
16552 [(set (match_operand:SWI24 0 "memory_operand")
16553 (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
16555 (clobber (match_operand:SWI24 2 "memory_operand"))]
16557 [(set (match_dup 0) (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST))])
16559 (define_expand "lrintxf<mode>2"
16560 [(set (match_operand:SWI248x 0 "nonimmediate_operand")
16561 (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
16563 "TARGET_USE_FANCY_MATH_387")
16565 (define_expand "lrint<MODEF:mode><SWI48:mode>2"
16566 [(set (match_operand:SWI48 0 "nonimmediate_operand")
16567 (unspec:SWI48 [(match_operand:MODEF 1 "register_operand")]
16568 UNSPEC_FIX_NOTRUNC))]
16569 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH")
16571 (define_expand "lround<X87MODEF:mode><SWI248x:mode>2"
16572 [(match_operand:SWI248x 0 "nonimmediate_operand")
16573 (match_operand:X87MODEF 1 "register_operand")]
16574 "(TARGET_USE_FANCY_MATH_387
16575 && (!(SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
16576 || TARGET_MIX_SSE_I387)
16577 && flag_unsafe_math_optimizations)
16578 || (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
16579 && <SWI248x:MODE>mode != HImode
16580 && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT)
16581 && !flag_trapping_math && !flag_rounding_math)"
16583 if (optimize_insn_for_size_p ())
16586 if (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
16587 && <SWI248x:MODE>mode != HImode
16588 && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT)
16589 && !flag_trapping_math && !flag_rounding_math)
16590 ix86_expand_lround (operands[0], operands[1]);
16592 ix86_emit_i387_round (operands[0], operands[1]);
16596 (define_int_iterator FRNDINT_ROUNDING
16597 [UNSPEC_FRNDINT_FLOOR
16598 UNSPEC_FRNDINT_CEIL
16599 UNSPEC_FRNDINT_TRUNC])
16601 (define_int_iterator FIST_ROUNDING
16605 ;; Base name for define_insn
16606 (define_int_attr rounding_insn
16607 [(UNSPEC_FRNDINT_FLOOR "floor")
16608 (UNSPEC_FRNDINT_CEIL "ceil")
16609 (UNSPEC_FRNDINT_TRUNC "btrunc")
16610 (UNSPEC_FIST_FLOOR "floor")
16611 (UNSPEC_FIST_CEIL "ceil")])
16613 (define_int_attr rounding
16614 [(UNSPEC_FRNDINT_FLOOR "floor")
16615 (UNSPEC_FRNDINT_CEIL "ceil")
16616 (UNSPEC_FRNDINT_TRUNC "trunc")
16617 (UNSPEC_FIST_FLOOR "floor")
16618 (UNSPEC_FIST_CEIL "ceil")])
16620 (define_int_attr ROUNDING
16621 [(UNSPEC_FRNDINT_FLOOR "FLOOR")
16622 (UNSPEC_FRNDINT_CEIL "CEIL")
16623 (UNSPEC_FRNDINT_TRUNC "TRUNC")
16624 (UNSPEC_FIST_FLOOR "FLOOR")
16625 (UNSPEC_FIST_CEIL "CEIL")])
16627 ;; Rounding mode control word calculation could clobber FLAGS_REG.
16628 (define_insn_and_split "frndint<mode>2_<rounding>"
16629 [(set (match_operand:X87MODEF 0 "register_operand")
16630 (unspec:X87MODEF [(match_operand:X87MODEF 1 "register_operand")]
16632 (clobber (reg:CC FLAGS_REG))]
16633 "TARGET_USE_FANCY_MATH_387
16634 && (flag_fp_int_builtin_inexact || !flag_trapping_math)
16635 && can_create_pseudo_p ()"
16640 ix86_optimize_mode_switching[I387_<ROUNDING>] = 1;
16642 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
16643 operands[3] = assign_386_stack_local (HImode, SLOT_CW_<ROUNDING>);
16645 emit_insn (gen_frndint<mode>2_<rounding>_i387 (operands[0], operands[1],
16646 operands[2], operands[3]));
16649 [(set_attr "type" "frndint")
16650 (set_attr "i387_cw" "<rounding>")
16651 (set_attr "mode" "<MODE>")])
16653 (define_insn "frndint<mode>2_<rounding>_i387"
16654 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
16655 (unspec:X87MODEF [(match_operand:X87MODEF 1 "register_operand" "0")]
16657 (use (match_operand:HI 2 "memory_operand" "m"))
16658 (use (match_operand:HI 3 "memory_operand" "m"))]
16659 "TARGET_USE_FANCY_MATH_387
16660 && (flag_fp_int_builtin_inexact || !flag_trapping_math)"
16661 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
16662 [(set_attr "type" "frndint")
16663 (set_attr "i387_cw" "<rounding>")
16664 (set_attr "mode" "<MODE>")])
16666 (define_expand "<rounding_insn>xf2"
16667 [(parallel [(set (match_operand:XF 0 "register_operand")
16668 (unspec:XF [(match_operand:XF 1 "register_operand")]
16670 (clobber (reg:CC FLAGS_REG))])]
16671 "TARGET_USE_FANCY_MATH_387
16672 && (flag_fp_int_builtin_inexact || !flag_trapping_math)")
16674 (define_expand "<rounding_insn><mode>2"
16675 [(parallel [(set (match_operand:MODEF 0 "register_operand")
16676 (unspec:MODEF [(match_operand:MODEF 1 "register_operand")]
16678 (clobber (reg:CC FLAGS_REG))])]
16679 "(TARGET_USE_FANCY_MATH_387
16680 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16681 || TARGET_MIX_SSE_I387)
16682 && (flag_fp_int_builtin_inexact || !flag_trapping_math))
16683 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16684 && (TARGET_SSE4_1 || !flag_trapping_math
16685 || flag_fp_int_builtin_inexact))"
16687 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16688 && (TARGET_SSE4_1 || !flag_trapping_math || flag_fp_int_builtin_inexact))
16691 emit_insn (gen_sse4_1_round<mode>2
16692 (operands[0], operands[1], GEN_INT (ROUND_<ROUNDING>
16694 else if (TARGET_64BIT || (<MODE>mode != DFmode))
16696 if (ROUND_<ROUNDING> == ROUND_FLOOR)
16697 ix86_expand_floorceil (operands[0], operands[1], true);
16698 else if (ROUND_<ROUNDING> == ROUND_CEIL)
16699 ix86_expand_floorceil (operands[0], operands[1], false);
16700 else if (ROUND_<ROUNDING> == ROUND_TRUNC)
16701 ix86_expand_trunc (operands[0], operands[1]);
16703 gcc_unreachable ();
16707 if (ROUND_<ROUNDING> == ROUND_FLOOR)
16708 ix86_expand_floorceildf_32 (operands[0], operands[1], true);
16709 else if (ROUND_<ROUNDING> == ROUND_CEIL)
16710 ix86_expand_floorceildf_32 (operands[0], operands[1], false);
16711 else if (ROUND_<ROUNDING> == ROUND_TRUNC)
16712 ix86_expand_truncdf_32 (operands[0], operands[1]);
16714 gcc_unreachable ();
16718 emit_insn (gen_frndint<mode>2_<rounding> (operands[0], operands[1]));
16722 ;; Rounding mode control word calculation could clobber FLAGS_REG.
16723 (define_insn_and_split "frndintxf2_mask_pm"
16724 [(set (match_operand:XF 0 "register_operand")
16725 (unspec:XF [(match_operand:XF 1 "register_operand")]
16726 UNSPEC_FRNDINT_MASK_PM))
16727 (clobber (reg:CC FLAGS_REG))]
16728 "TARGET_USE_FANCY_MATH_387
16729 && flag_unsafe_math_optimizations
16730 && can_create_pseudo_p ()"
16735 ix86_optimize_mode_switching[I387_MASK_PM] = 1;
16737 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
16738 operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
16740 emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
16741 operands[2], operands[3]));
16744 [(set_attr "type" "frndint")
16745 (set_attr "i387_cw" "mask_pm")
16746 (set_attr "mode" "XF")])
16748 (define_insn "frndintxf2_mask_pm_i387"
16749 [(set (match_operand:XF 0 "register_operand" "=f")
16750 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16751 UNSPEC_FRNDINT_MASK_PM))
16752 (use (match_operand:HI 2 "memory_operand" "m"))
16753 (use (match_operand:HI 3 "memory_operand" "m"))]
16754 "TARGET_USE_FANCY_MATH_387
16755 && flag_unsafe_math_optimizations"
16756 "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
16757 [(set_attr "type" "frndint")
16758 (set_attr "i387_cw" "mask_pm")
16759 (set_attr "mode" "XF")])
16761 (define_expand "nearbyintxf2"
16762 [(parallel [(set (match_operand:XF 0 "register_operand")
16763 (unspec:XF [(match_operand:XF 1 "register_operand")]
16764 UNSPEC_FRNDINT_MASK_PM))
16765 (clobber (reg:CC FLAGS_REG))])]
16766 "TARGET_USE_FANCY_MATH_387
16767 && flag_unsafe_math_optimizations")
16769 (define_expand "nearbyint<mode>2"
16770 [(use (match_operand:MODEF 0 "register_operand"))
16771 (use (match_operand:MODEF 1 "register_operand"))]
16772 "TARGET_USE_FANCY_MATH_387
16773 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16774 || TARGET_MIX_SSE_I387)
16775 && flag_unsafe_math_optimizations"
16777 rtx op0 = gen_reg_rtx (XFmode);
16778 rtx op1 = gen_reg_rtx (XFmode);
16780 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16781 emit_insn (gen_frndintxf2_mask_pm (op0, op1));
16783 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16787 ;; Rounding mode control word calculation could clobber FLAGS_REG.
16788 (define_insn_and_split "*fist<mode>2_<rounding>_1"
16789 [(set (match_operand:SWI248x 0 "nonimmediate_operand")
16790 (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
16792 (clobber (reg:CC FLAGS_REG))]
16793 "TARGET_USE_FANCY_MATH_387
16794 && flag_unsafe_math_optimizations
16795 && can_create_pseudo_p ()"
16800 ix86_optimize_mode_switching[I387_<ROUNDING>] = 1;
16802 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
16803 operands[3] = assign_386_stack_local (HImode, SLOT_CW_<ROUNDING>);
16804 if (memory_operand (operands[0], VOIDmode))
16805 emit_insn (gen_fist<mode>2_<rounding> (operands[0], operands[1],
16806 operands[2], operands[3]));
16809 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
16810 emit_insn (gen_fist<mode>2_<rounding>_with_temp
16811 (operands[0], operands[1], operands[2],
16812 operands[3], operands[4]));
16816 [(set_attr "type" "fistp")
16817 (set_attr "i387_cw" "<rounding>")
16818 (set_attr "mode" "<MODE>")])
16820 (define_insn "fistdi2_<rounding>"
16821 [(set (match_operand:DI 0 "memory_operand" "=m")
16822 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
16824 (use (match_operand:HI 2 "memory_operand" "m"))
16825 (use (match_operand:HI 3 "memory_operand" "m"))
16826 (clobber (match_scratch:XF 4 "=&1f"))]
16827 "TARGET_USE_FANCY_MATH_387
16828 && flag_unsafe_math_optimizations"
16829 "* return output_fix_trunc (insn, operands, false);"
16830 [(set_attr "type" "fistp")
16831 (set_attr "i387_cw" "<rounding>")
16832 (set_attr "mode" "DI")])
16834 (define_insn "fistdi2_<rounding>_with_temp"
16835 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
16836 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
16838 (use (match_operand:HI 2 "memory_operand" "m,m"))
16839 (use (match_operand:HI 3 "memory_operand" "m,m"))
16840 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
16841 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
16842 "TARGET_USE_FANCY_MATH_387
16843 && flag_unsafe_math_optimizations"
16845 [(set_attr "type" "fistp")
16846 (set_attr "i387_cw" "<rounding>")
16847 (set_attr "mode" "DI")])
16850 [(set (match_operand:DI 0 "register_operand")
16851 (unspec:DI [(match_operand:XF 1 "register_operand")]
16853 (use (match_operand:HI 2 "memory_operand"))
16854 (use (match_operand:HI 3 "memory_operand"))
16855 (clobber (match_operand:DI 4 "memory_operand"))
16856 (clobber (match_scratch 5))]
16858 [(parallel [(set (match_dup 4)
16859 (unspec:DI [(match_dup 1)] FIST_ROUNDING))
16860 (use (match_dup 2))
16861 (use (match_dup 3))
16862 (clobber (match_dup 5))])
16863 (set (match_dup 0) (match_dup 4))])
16866 [(set (match_operand:DI 0 "memory_operand")
16867 (unspec:DI [(match_operand:XF 1 "register_operand")]
16869 (use (match_operand:HI 2 "memory_operand"))
16870 (use (match_operand:HI 3 "memory_operand"))
16871 (clobber (match_operand:DI 4 "memory_operand"))
16872 (clobber (match_scratch 5))]
16874 [(parallel [(set (match_dup 0)
16875 (unspec:DI [(match_dup 1)] FIST_ROUNDING))
16876 (use (match_dup 2))
16877 (use (match_dup 3))
16878 (clobber (match_dup 5))])])
16880 (define_insn "fist<mode>2_<rounding>"
16881 [(set (match_operand:SWI24 0 "memory_operand" "=m")
16882 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
16884 (use (match_operand:HI 2 "memory_operand" "m"))
16885 (use (match_operand:HI 3 "memory_operand" "m"))]
16886 "TARGET_USE_FANCY_MATH_387
16887 && flag_unsafe_math_optimizations"
16888 "* return output_fix_trunc (insn, operands, false);"
16889 [(set_attr "type" "fistp")
16890 (set_attr "i387_cw" "<rounding>")
16891 (set_attr "mode" "<MODE>")])
16893 (define_insn "fist<mode>2_<rounding>_with_temp"
16894 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
16895 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f,f")]
16897 (use (match_operand:HI 2 "memory_operand" "m,m"))
16898 (use (match_operand:HI 3 "memory_operand" "m,m"))
16899 (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
16900 "TARGET_USE_FANCY_MATH_387
16901 && flag_unsafe_math_optimizations"
16903 [(set_attr "type" "fistp")
16904 (set_attr "i387_cw" "<rounding>")
16905 (set_attr "mode" "<MODE>")])
16908 [(set (match_operand:SWI24 0 "register_operand")
16909 (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
16911 (use (match_operand:HI 2 "memory_operand"))
16912 (use (match_operand:HI 3 "memory_operand"))
16913 (clobber (match_operand:SWI24 4 "memory_operand"))]
16915 [(parallel [(set (match_dup 4)
16916 (unspec:SWI24 [(match_dup 1)] FIST_ROUNDING))
16917 (use (match_dup 2))
16918 (use (match_dup 3))])
16919 (set (match_dup 0) (match_dup 4))])
16922 [(set (match_operand:SWI24 0 "memory_operand")
16923 (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
16925 (use (match_operand:HI 2 "memory_operand"))
16926 (use (match_operand:HI 3 "memory_operand"))
16927 (clobber (match_operand:SWI24 4 "memory_operand"))]
16929 [(parallel [(set (match_dup 0)
16930 (unspec:SWI24 [(match_dup 1)] FIST_ROUNDING))
16931 (use (match_dup 2))
16932 (use (match_dup 3))])])
16934 (define_expand "l<rounding_insn>xf<mode>2"
16935 [(parallel [(set (match_operand:SWI248x 0 "nonimmediate_operand")
16936 (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
16938 (clobber (reg:CC FLAGS_REG))])]
16939 "TARGET_USE_FANCY_MATH_387
16940 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16941 && flag_unsafe_math_optimizations")
16943 (define_expand "l<rounding_insn><MODEF:mode><SWI48:mode>2"
16944 [(parallel [(set (match_operand:SWI48 0 "nonimmediate_operand")
16945 (unspec:SWI48 [(match_operand:MODEF 1 "register_operand")]
16947 (clobber (reg:CC FLAGS_REG))])]
16948 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
16949 && !flag_trapping_math"
16951 if (TARGET_64BIT && optimize_insn_for_size_p ())
16954 if (ROUND_<ROUNDING> == ROUND_FLOOR)
16955 ix86_expand_lfloorceil (operands[0], operands[1], true);
16956 else if (ROUND_<ROUNDING> == ROUND_CEIL)
16957 ix86_expand_lfloorceil (operands[0], operands[1], false);
16959 gcc_unreachable ();
16964 (define_insn "fxam<mode>2_i387"
16965 [(set (match_operand:HI 0 "register_operand" "=a")
16967 [(match_operand:X87MODEF 1 "register_operand" "f")]
16969 "TARGET_USE_FANCY_MATH_387"
16970 "fxam\n\tfnstsw\t%0"
16971 [(set_attr "type" "multi")
16972 (set_attr "length" "4")
16973 (set_attr "unit" "i387")
16974 (set_attr "mode" "<MODE>")])
16976 (define_insn_and_split "fxam<mode>2_i387_with_temp"
16977 [(set (match_operand:HI 0 "register_operand")
16979 [(match_operand:MODEF 1 "memory_operand")]
16981 "TARGET_USE_FANCY_MATH_387
16982 && can_create_pseudo_p ()"
16985 [(set (match_dup 2)(match_dup 1))
16987 (unspec:HI [(match_dup 2)] UNSPEC_FXAM))]
16989 operands[2] = gen_reg_rtx (<MODE>mode);
16991 MEM_VOLATILE_P (operands[1]) = 1;
16993 [(set_attr "type" "multi")
16994 (set_attr "unit" "i387")
16995 (set_attr "mode" "<MODE>")])
16997 (define_expand "isinfxf2"
16998 [(use (match_operand:SI 0 "register_operand"))
16999 (use (match_operand:XF 1 "register_operand"))]
17000 "TARGET_USE_FANCY_MATH_387
17001 && ix86_libc_has_function (function_c99_misc)"
17003 rtx mask = GEN_INT (0x45);
17004 rtx val = GEN_INT (0x05);
17006 rtx scratch = gen_reg_rtx (HImode);
17007 rtx res = gen_reg_rtx (QImode);
17009 emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
17011 emit_insn (gen_andqi_ext_1 (scratch, scratch, mask));
17012 emit_insn (gen_cmpqi_ext_3 (scratch, val));
17013 ix86_expand_setcc (res, EQ,
17014 gen_rtx_REG (CCmode, FLAGS_REG), const0_rtx);
17015 emit_insn (gen_zero_extendqisi2 (operands[0], res));
17019 (define_expand "isinf<mode>2"
17020 [(use (match_operand:SI 0 "register_operand"))
17021 (use (match_operand:MODEF 1 "nonimmediate_operand"))]
17022 "TARGET_USE_FANCY_MATH_387
17023 && ix86_libc_has_function (function_c99_misc)
17024 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
17026 rtx mask = GEN_INT (0x45);
17027 rtx val = GEN_INT (0x05);
17029 rtx scratch = gen_reg_rtx (HImode);
17030 rtx res = gen_reg_rtx (QImode);
17032 /* Remove excess precision by forcing value through memory. */
17033 if (memory_operand (operands[1], VOIDmode))
17034 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, operands[1]));
17037 rtx temp = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17039 emit_move_insn (temp, operands[1]);
17040 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, temp));
17043 emit_insn (gen_andqi_ext_1 (scratch, scratch, mask));
17044 emit_insn (gen_cmpqi_ext_3 (scratch, val));
17045 ix86_expand_setcc (res, EQ,
17046 gen_rtx_REG (CCmode, FLAGS_REG), const0_rtx);
17047 emit_insn (gen_zero_extendqisi2 (operands[0], res));
17051 (define_expand "signbittf2"
17052 [(use (match_operand:SI 0 "register_operand"))
17053 (use (match_operand:TF 1 "register_operand"))]
17058 rtx mask = ix86_build_signbit_mask (TFmode, 0, 0);
17059 rtx scratch = gen_reg_rtx (QImode);
17061 emit_insn (gen_ptesttf2 (operands[1], mask));
17062 ix86_expand_setcc (scratch, NE,
17063 gen_rtx_REG (CCZmode, FLAGS_REG), const0_rtx);
17065 emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
17069 emit_insn (gen_sse_movmskps (operands[0],
17070 gen_lowpart (V4SFmode, operands[1])));
17071 emit_insn (gen_andsi3 (operands[0], operands[0], GEN_INT (0x8)));
17076 (define_expand "signbitxf2"
17077 [(use (match_operand:SI 0 "register_operand"))
17078 (use (match_operand:XF 1 "register_operand"))]
17079 "TARGET_USE_FANCY_MATH_387"
17081 rtx scratch = gen_reg_rtx (HImode);
17083 emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
17084 emit_insn (gen_andsi3 (operands[0],
17085 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
17089 (define_insn "movmsk_df"
17090 [(set (match_operand:SI 0 "register_operand" "=r")
17092 [(match_operand:DF 1 "register_operand" "x")]
17094 "SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH"
17095 "%vmovmskpd\t{%1, %0|%0, %1}"
17096 [(set_attr "type" "ssemov")
17097 (set_attr "prefix" "maybe_vex")
17098 (set_attr "mode" "DF")])
17100 ;; Use movmskpd in SSE mode to avoid store forwarding stall
17101 ;; for 32bit targets and movq+shrq sequence for 64bit targets.
17102 (define_expand "signbitdf2"
17103 [(use (match_operand:SI 0 "register_operand"))
17104 (use (match_operand:DF 1 "register_operand"))]
17105 "TARGET_USE_FANCY_MATH_387
17106 || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
17108 if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)
17110 emit_insn (gen_movmsk_df (operands[0], operands[1]));
17111 emit_insn (gen_andsi3 (operands[0], operands[0], const1_rtx));
17115 rtx scratch = gen_reg_rtx (HImode);
17117 emit_insn (gen_fxamdf2_i387 (scratch, operands[1]));
17118 emit_insn (gen_andsi3 (operands[0],
17119 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
17124 (define_expand "signbitsf2"
17125 [(use (match_operand:SI 0 "register_operand"))
17126 (use (match_operand:SF 1 "register_operand"))]
17127 "TARGET_USE_FANCY_MATH_387
17128 && !(SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH)"
17130 rtx scratch = gen_reg_rtx (HImode);
17132 emit_insn (gen_fxamsf2_i387 (scratch, operands[1]));
17133 emit_insn (gen_andsi3 (operands[0],
17134 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
17138 ;; Block operation instructions
17141 [(unspec_volatile [(const_int 0)] UNSPECV_CLD)]
17144 [(set_attr "length" "1")
17145 (set_attr "length_immediate" "0")
17146 (set_attr "modrm" "0")])
17148 (define_expand "movmem<mode>"
17149 [(use (match_operand:BLK 0 "memory_operand"))
17150 (use (match_operand:BLK 1 "memory_operand"))
17151 (use (match_operand:SWI48 2 "nonmemory_operand"))
17152 (use (match_operand:SWI48 3 "const_int_operand"))
17153 (use (match_operand:SI 4 "const_int_operand"))
17154 (use (match_operand:SI 5 "const_int_operand"))
17155 (use (match_operand:SI 6 ""))
17156 (use (match_operand:SI 7 ""))
17157 (use (match_operand:SI 8 ""))]
17160 if (ix86_expand_set_or_movmem (operands[0], operands[1],
17161 operands[2], NULL, operands[3],
17162 operands[4], operands[5],
17163 operands[6], operands[7],
17164 operands[8], false))
17170 ;; Most CPUs don't like single string operations
17171 ;; Handle this case here to simplify previous expander.
17173 (define_expand "strmov"
17174 [(set (match_dup 4) (match_operand 3 "memory_operand"))
17175 (set (match_operand 1 "memory_operand") (match_dup 4))
17176 (parallel [(set (match_operand 0 "register_operand") (match_dup 5))
17177 (clobber (reg:CC FLAGS_REG))])
17178 (parallel [(set (match_operand 2 "register_operand") (match_dup 6))
17179 (clobber (reg:CC FLAGS_REG))])]
17182 /* Can't use this for non-default address spaces. */
17183 if (!ADDR_SPACE_GENERIC_P (MEM_ADDR_SPACE (operands[3])))
17186 rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
17188 /* If .md ever supports :P for Pmode, these can be directly
17189 in the pattern above. */
17190 operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
17191 operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
17193 /* Can't use this if the user has appropriated esi or edi. */
17194 if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
17195 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG]))
17197 emit_insn (gen_strmov_singleop (operands[0], operands[1],
17198 operands[2], operands[3],
17199 operands[5], operands[6]));
17203 operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
17206 (define_expand "strmov_singleop"
17207 [(parallel [(set (match_operand 1 "memory_operand")
17208 (match_operand 3 "memory_operand"))
17209 (set (match_operand 0 "register_operand")
17211 (set (match_operand 2 "register_operand")
17212 (match_operand 5))])]
17216 ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
17219 (define_insn "*strmovdi_rex_1"
17220 [(set (mem:DI (match_operand:P 2 "register_operand" "0"))
17221 (mem:DI (match_operand:P 3 "register_operand" "1")))
17222 (set (match_operand:P 0 "register_operand" "=D")
17223 (plus:P (match_dup 2)
17225 (set (match_operand:P 1 "register_operand" "=S")
17226 (plus:P (match_dup 3)
17229 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG])
17230 && ix86_check_no_addr_space (insn)"
17232 [(set_attr "type" "str")
17233 (set_attr "memory" "both")
17234 (set_attr "mode" "DI")])
17236 (define_insn "*strmovsi_1"
17237 [(set (mem:SI (match_operand:P 2 "register_operand" "0"))
17238 (mem:SI (match_operand:P 3 "register_operand" "1")))
17239 (set (match_operand:P 0 "register_operand" "=D")
17240 (plus:P (match_dup 2)
17242 (set (match_operand:P 1 "register_operand" "=S")
17243 (plus:P (match_dup 3)
17245 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])
17246 && ix86_check_no_addr_space (insn)"
17248 [(set_attr "type" "str")
17249 (set_attr "memory" "both")
17250 (set_attr "mode" "SI")])
17252 (define_insn "*strmovhi_1"
17253 [(set (mem:HI (match_operand:P 2 "register_operand" "0"))
17254 (mem:HI (match_operand:P 3 "register_operand" "1")))
17255 (set (match_operand:P 0 "register_operand" "=D")
17256 (plus:P (match_dup 2)
17258 (set (match_operand:P 1 "register_operand" "=S")
17259 (plus:P (match_dup 3)
17261 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])
17262 && ix86_check_no_addr_space (insn)"
17264 [(set_attr "type" "str")
17265 (set_attr "memory" "both")
17266 (set_attr "mode" "HI")])
17268 (define_insn "*strmovqi_1"
17269 [(set (mem:QI (match_operand:P 2 "register_operand" "0"))
17270 (mem:QI (match_operand:P 3 "register_operand" "1")))
17271 (set (match_operand:P 0 "register_operand" "=D")
17272 (plus:P (match_dup 2)
17274 (set (match_operand:P 1 "register_operand" "=S")
17275 (plus:P (match_dup 3)
17277 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])
17278 && ix86_check_no_addr_space (insn)"
17280 [(set_attr "type" "str")
17281 (set_attr "memory" "both")
17282 (set (attr "prefix_rex")
17284 (match_test "<P:MODE>mode == DImode")
17286 (const_string "*")))
17287 (set_attr "mode" "QI")])
17289 (define_expand "rep_mov"
17290 [(parallel [(set (match_operand 4 "register_operand") (const_int 0))
17291 (set (match_operand 0 "register_operand")
17293 (set (match_operand 2 "register_operand")
17295 (set (match_operand 1 "memory_operand")
17296 (match_operand 3 "memory_operand"))
17297 (use (match_dup 4))])]
17301 ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
17304 (define_insn "*rep_movdi_rex64"
17305 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
17306 (set (match_operand:P 0 "register_operand" "=D")
17307 (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
17309 (match_operand:P 3 "register_operand" "0")))
17310 (set (match_operand:P 1 "register_operand" "=S")
17311 (plus:P (ashift:P (match_dup 5) (const_int 3))
17312 (match_operand:P 4 "register_operand" "1")))
17313 (set (mem:BLK (match_dup 3))
17314 (mem:BLK (match_dup 4)))
17315 (use (match_dup 5))]
17317 && !(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
17318 && ix86_check_no_addr_space (insn)"
17320 [(set_attr "type" "str")
17321 (set_attr "prefix_rep" "1")
17322 (set_attr "memory" "both")
17323 (set_attr "mode" "DI")])
17325 (define_insn "*rep_movsi"
17326 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
17327 (set (match_operand:P 0 "register_operand" "=D")
17328 (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
17330 (match_operand:P 3 "register_operand" "0")))
17331 (set (match_operand:P 1 "register_operand" "=S")
17332 (plus:P (ashift:P (match_dup 5) (const_int 2))
17333 (match_operand:P 4 "register_operand" "1")))
17334 (set (mem:BLK (match_dup 3))
17335 (mem:BLK (match_dup 4)))
17336 (use (match_dup 5))]
17337 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
17338 && ix86_check_no_addr_space (insn)"
17339 "%^rep{%;} movs{l|d}"
17340 [(set_attr "type" "str")
17341 (set_attr "prefix_rep" "1")
17342 (set_attr "memory" "both")
17343 (set_attr "mode" "SI")])
17345 (define_insn "*rep_movqi"
17346 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
17347 (set (match_operand:P 0 "register_operand" "=D")
17348 (plus:P (match_operand:P 3 "register_operand" "0")
17349 (match_operand:P 5 "register_operand" "2")))
17350 (set (match_operand:P 1 "register_operand" "=S")
17351 (plus:P (match_operand:P 4 "register_operand" "1") (match_dup 5)))
17352 (set (mem:BLK (match_dup 3))
17353 (mem:BLK (match_dup 4)))
17354 (use (match_dup 5))]
17355 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
17356 && ix86_check_no_addr_space (insn)"
17358 [(set_attr "type" "str")
17359 (set_attr "prefix_rep" "1")
17360 (set_attr "memory" "both")
17361 (set_attr "mode" "QI")])
17363 (define_expand "setmem<mode>"
17364 [(use (match_operand:BLK 0 "memory_operand"))
17365 (use (match_operand:SWI48 1 "nonmemory_operand"))
17366 (use (match_operand:QI 2 "nonmemory_operand"))
17367 (use (match_operand 3 "const_int_operand"))
17368 (use (match_operand:SI 4 "const_int_operand"))
17369 (use (match_operand:SI 5 "const_int_operand"))
17370 (use (match_operand:SI 6 ""))
17371 (use (match_operand:SI 7 ""))
17372 (use (match_operand:SI 8 ""))]
17375 if (ix86_expand_set_or_movmem (operands[0], NULL,
17376 operands[1], operands[2],
17377 operands[3], operands[4],
17378 operands[5], operands[6],
17379 operands[7], operands[8], true))
17385 ;; Most CPUs don't like single string operations
17386 ;; Handle this case here to simplify previous expander.
17388 (define_expand "strset"
17389 [(set (match_operand 1 "memory_operand")
17390 (match_operand 2 "register_operand"))
17391 (parallel [(set (match_operand 0 "register_operand")
17393 (clobber (reg:CC FLAGS_REG))])]
17396 /* Can't use this for non-default address spaces. */
17397 if (!ADDR_SPACE_GENERIC_P (MEM_ADDR_SPACE (operands[1])))
17400 if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
17401 operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
17403 /* If .md ever supports :P for Pmode, this can be directly
17404 in the pattern above. */
17405 operands[3] = gen_rtx_PLUS (Pmode, operands[0],
17406 GEN_INT (GET_MODE_SIZE (GET_MODE
17408 /* Can't use this if the user has appropriated eax or edi. */
17409 if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
17410 && !(fixed_regs[AX_REG] || fixed_regs[DI_REG]))
17412 emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
17418 (define_expand "strset_singleop"
17419 [(parallel [(set (match_operand 1 "memory_operand")
17420 (match_operand 2 "register_operand"))
17421 (set (match_operand 0 "register_operand")
17423 (unspec [(const_int 0)] UNSPEC_STOS)])]
17427 ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
17430 (define_insn "*strsetdi_rex_1"
17431 [(set (mem:DI (match_operand:P 1 "register_operand" "0"))
17432 (match_operand:DI 2 "register_operand" "a"))
17433 (set (match_operand:P 0 "register_operand" "=D")
17434 (plus:P (match_dup 1)
17436 (unspec [(const_int 0)] UNSPEC_STOS)]
17438 && !(fixed_regs[AX_REG] || fixed_regs[DI_REG])
17439 && ix86_check_no_addr_space (insn)"
17441 [(set_attr "type" "str")
17442 (set_attr "memory" "store")
17443 (set_attr "mode" "DI")])
17445 (define_insn "*strsetsi_1"
17446 [(set (mem:SI (match_operand:P 1 "register_operand" "0"))
17447 (match_operand:SI 2 "register_operand" "a"))
17448 (set (match_operand:P 0 "register_operand" "=D")
17449 (plus:P (match_dup 1)
17451 (unspec [(const_int 0)] UNSPEC_STOS)]
17452 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])
17453 && ix86_check_no_addr_space (insn)"
17455 [(set_attr "type" "str")
17456 (set_attr "memory" "store")
17457 (set_attr "mode" "SI")])
17459 (define_insn "*strsethi_1"
17460 [(set (mem:HI (match_operand:P 1 "register_operand" "0"))
17461 (match_operand:HI 2 "register_operand" "a"))
17462 (set (match_operand:P 0 "register_operand" "=D")
17463 (plus:P (match_dup 1)
17465 (unspec [(const_int 0)] UNSPEC_STOS)]
17466 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])
17467 && ix86_check_no_addr_space (insn)"
17469 [(set_attr "type" "str")
17470 (set_attr "memory" "store")
17471 (set_attr "mode" "HI")])
17473 (define_insn "*strsetqi_1"
17474 [(set (mem:QI (match_operand:P 1 "register_operand" "0"))
17475 (match_operand:QI 2 "register_operand" "a"))
17476 (set (match_operand:P 0 "register_operand" "=D")
17477 (plus:P (match_dup 1)
17479 (unspec [(const_int 0)] UNSPEC_STOS)]
17480 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])
17481 && ix86_check_no_addr_space (insn)"
17483 [(set_attr "type" "str")
17484 (set_attr "memory" "store")
17485 (set (attr "prefix_rex")
17487 (match_test "<P:MODE>mode == DImode")
17489 (const_string "*")))
17490 (set_attr "mode" "QI")])
17492 (define_expand "rep_stos"
17493 [(parallel [(set (match_operand 1 "register_operand") (const_int 0))
17494 (set (match_operand 0 "register_operand")
17496 (set (match_operand 2 "memory_operand") (const_int 0))
17497 (use (match_operand 3 "register_operand"))
17498 (use (match_dup 1))])]
17502 ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
17505 (define_insn "*rep_stosdi_rex64"
17506 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
17507 (set (match_operand:P 0 "register_operand" "=D")
17508 (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
17510 (match_operand:P 3 "register_operand" "0")))
17511 (set (mem:BLK (match_dup 3))
17513 (use (match_operand:DI 2 "register_operand" "a"))
17514 (use (match_dup 4))]
17516 && !(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])
17517 && ix86_check_no_addr_space (insn)"
17519 [(set_attr "type" "str")
17520 (set_attr "prefix_rep" "1")
17521 (set_attr "memory" "store")
17522 (set_attr "mode" "DI")])
17524 (define_insn "*rep_stossi"
17525 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
17526 (set (match_operand:P 0 "register_operand" "=D")
17527 (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
17529 (match_operand:P 3 "register_operand" "0")))
17530 (set (mem:BLK (match_dup 3))
17532 (use (match_operand:SI 2 "register_operand" "a"))
17533 (use (match_dup 4))]
17534 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])
17535 && ix86_check_no_addr_space (insn)"
17536 "%^rep{%;} stos{l|d}"
17537 [(set_attr "type" "str")
17538 (set_attr "prefix_rep" "1")
17539 (set_attr "memory" "store")
17540 (set_attr "mode" "SI")])
17542 (define_insn "*rep_stosqi"
17543 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
17544 (set (match_operand:P 0 "register_operand" "=D")
17545 (plus:P (match_operand:P 3 "register_operand" "0")
17546 (match_operand:P 4 "register_operand" "1")))
17547 (set (mem:BLK (match_dup 3))
17549 (use (match_operand:QI 2 "register_operand" "a"))
17550 (use (match_dup 4))]
17551 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])
17552 && ix86_check_no_addr_space (insn)"
17554 [(set_attr "type" "str")
17555 (set_attr "prefix_rep" "1")
17556 (set_attr "memory" "store")
17557 (set (attr "prefix_rex")
17559 (match_test "<P:MODE>mode == DImode")
17561 (const_string "*")))
17562 (set_attr "mode" "QI")])
17564 (define_expand "cmpstrnsi"
17565 [(set (match_operand:SI 0 "register_operand")
17566 (compare:SI (match_operand:BLK 1 "general_operand")
17567 (match_operand:BLK 2 "general_operand")))
17568 (use (match_operand 3 "general_operand"))
17569 (use (match_operand 4 "immediate_operand"))]
17572 rtx addr1, addr2, out, outlow, count, countreg, align;
17574 if (optimize_insn_for_size_p () && !TARGET_INLINE_ALL_STRINGOPS)
17577 /* Can't use this if the user has appropriated ecx, esi or edi. */
17578 if (fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
17581 /* One of the strings must be a constant. If so, expand_builtin_strncmp()
17582 will have rewritten the length arg to be the minimum of the const string
17583 length and the actual length arg. If both strings are the same and
17584 shorter than the length arg, repz cmpsb will not stop at the 0 byte and
17585 will incorrectly base the results on chars past the 0 byte. */
17586 tree t1 = MEM_EXPR (operands[1]);
17587 tree t2 = MEM_EXPR (operands[2]);
17588 if (!((t1 && TREE_CODE (t1) == MEM_REF
17589 && TREE_CODE (TREE_OPERAND (t1, 0)) == ADDR_EXPR
17590 && TREE_CODE (TREE_OPERAND (TREE_OPERAND (t1, 0), 0)) == STRING_CST)
17591 || (t2 && TREE_CODE (t2) == MEM_REF
17592 && TREE_CODE (TREE_OPERAND (t2, 0)) == ADDR_EXPR
17593 && TREE_CODE (TREE_OPERAND (TREE_OPERAND (t2, 0), 0)) == STRING_CST)))
17598 out = gen_reg_rtx (SImode);
17600 addr1 = copy_addr_to_reg (XEXP (operands[1], 0));
17601 addr2 = copy_addr_to_reg (XEXP (operands[2], 0));
17602 if (addr1 != XEXP (operands[1], 0))
17603 operands[1] = replace_equiv_address_nv (operands[1], addr1);
17604 if (addr2 != XEXP (operands[2], 0))
17605 operands[2] = replace_equiv_address_nv (operands[2], addr2);
17607 count = operands[3];
17608 countreg = ix86_zero_extend_to_Pmode (count);
17610 /* %%% Iff we are testing strict equality, we can use known alignment
17611 to good advantage. This may be possible with combine, particularly
17612 once cc0 is dead. */
17613 align = operands[4];
17615 if (CONST_INT_P (count))
17617 if (INTVAL (count) == 0)
17619 emit_move_insn (operands[0], const0_rtx);
17622 emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
17623 operands[1], operands[2]));
17627 rtx (*gen_cmp) (rtx, rtx);
17629 gen_cmp = (TARGET_64BIT
17630 ? gen_cmpdi_1 : gen_cmpsi_1);
17632 emit_insn (gen_cmp (countreg, countreg));
17633 emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
17634 operands[1], operands[2]));
17637 outlow = gen_lowpart (QImode, out);
17638 emit_insn (gen_cmpintqi (outlow));
17639 emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
17641 if (operands[0] != out)
17642 emit_move_insn (operands[0], out);
17647 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
17649 (define_expand "cmpintqi"
17650 [(set (match_dup 1)
17651 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
17653 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
17654 (parallel [(set (match_operand:QI 0 "register_operand")
17655 (minus:QI (match_dup 1)
17657 (clobber (reg:CC FLAGS_REG))])]
17660 operands[1] = gen_reg_rtx (QImode);
17661 operands[2] = gen_reg_rtx (QImode);
17664 ;; memcmp recognizers. The `cmpsb' opcode does nothing if the count is
17665 ;; zero. Emit extra code to make sure that a zero-length compare is EQ.
17667 (define_expand "cmpstrnqi_nz_1"
17668 [(parallel [(set (reg:CC FLAGS_REG)
17669 (compare:CC (match_operand 4 "memory_operand")
17670 (match_operand 5 "memory_operand")))
17671 (use (match_operand 2 "register_operand"))
17672 (use (match_operand:SI 3 "immediate_operand"))
17673 (clobber (match_operand 0 "register_operand"))
17674 (clobber (match_operand 1 "register_operand"))
17675 (clobber (match_dup 2))])]
17679 ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
17682 (define_insn "*cmpstrnqi_nz_1"
17683 [(set (reg:CC FLAGS_REG)
17684 (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
17685 (mem:BLK (match_operand:P 5 "register_operand" "1"))))
17686 (use (match_operand:P 6 "register_operand" "2"))
17687 (use (match_operand:SI 3 "immediate_operand" "i"))
17688 (clobber (match_operand:P 0 "register_operand" "=S"))
17689 (clobber (match_operand:P 1 "register_operand" "=D"))
17690 (clobber (match_operand:P 2 "register_operand" "=c"))]
17691 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
17692 && ix86_check_no_addr_space (insn)"
17694 [(set_attr "type" "str")
17695 (set_attr "mode" "QI")
17696 (set (attr "prefix_rex")
17698 (match_test "<P:MODE>mode == DImode")
17700 (const_string "*")))
17701 (set_attr "prefix_rep" "1")])
17703 ;; The same, but the count is not known to not be zero.
17705 (define_expand "cmpstrnqi_1"
17706 [(parallel [(set (reg:CC FLAGS_REG)
17707 (if_then_else:CC (ne (match_operand 2 "register_operand")
17709 (compare:CC (match_operand 4 "memory_operand")
17710 (match_operand 5 "memory_operand"))
17712 (use (match_operand:SI 3 "immediate_operand"))
17713 (use (reg:CC FLAGS_REG))
17714 (clobber (match_operand 0 "register_operand"))
17715 (clobber (match_operand 1 "register_operand"))
17716 (clobber (match_dup 2))])]
17720 ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
17723 (define_insn "*cmpstrnqi_1"
17724 [(set (reg:CC FLAGS_REG)
17725 (if_then_else:CC (ne (match_operand:P 6 "register_operand" "2")
17727 (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
17728 (mem:BLK (match_operand:P 5 "register_operand" "1")))
17730 (use (match_operand:SI 3 "immediate_operand" "i"))
17731 (use (reg:CC FLAGS_REG))
17732 (clobber (match_operand:P 0 "register_operand" "=S"))
17733 (clobber (match_operand:P 1 "register_operand" "=D"))
17734 (clobber (match_operand:P 2 "register_operand" "=c"))]
17735 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
17736 && ix86_check_no_addr_space (insn)"
17738 [(set_attr "type" "str")
17739 (set_attr "mode" "QI")
17740 (set (attr "prefix_rex")
17742 (match_test "<P:MODE>mode == DImode")
17744 (const_string "*")))
17745 (set_attr "prefix_rep" "1")])
17747 (define_expand "strlen<mode>"
17748 [(set (match_operand:P 0 "register_operand")
17749 (unspec:P [(match_operand:BLK 1 "general_operand")
17750 (match_operand:QI 2 "immediate_operand")
17751 (match_operand 3 "immediate_operand")]
17755 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
17761 (define_expand "strlenqi_1"
17762 [(parallel [(set (match_operand 0 "register_operand")
17764 (clobber (match_operand 1 "register_operand"))
17765 (clobber (reg:CC FLAGS_REG))])]
17769 ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
17772 (define_insn "*strlenqi_1"
17773 [(set (match_operand:P 0 "register_operand" "=&c")
17774 (unspec:P [(mem:BLK (match_operand:P 5 "register_operand" "1"))
17775 (match_operand:QI 2 "register_operand" "a")
17776 (match_operand:P 3 "immediate_operand" "i")
17777 (match_operand:P 4 "register_operand" "0")] UNSPEC_SCAS))
17778 (clobber (match_operand:P 1 "register_operand" "=D"))
17779 (clobber (reg:CC FLAGS_REG))]
17780 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])
17781 && ix86_check_no_addr_space (insn)"
17782 "%^repnz{%;} scasb"
17783 [(set_attr "type" "str")
17784 (set_attr "mode" "QI")
17785 (set (attr "prefix_rex")
17787 (match_test "<P:MODE>mode == DImode")
17789 (const_string "*")))
17790 (set_attr "prefix_rep" "1")])
17792 ;; Peephole optimizations to clean up after cmpstrn*. This should be
17793 ;; handled in combine, but it is not currently up to the task.
17794 ;; When used for their truth value, the cmpstrn* expanders generate
17803 ;; The intermediate three instructions are unnecessary.
17805 ;; This one handles cmpstrn*_nz_1...
17808 (set (reg:CC FLAGS_REG)
17809 (compare:CC (mem:BLK (match_operand 4 "register_operand"))
17810 (mem:BLK (match_operand 5 "register_operand"))))
17811 (use (match_operand 6 "register_operand"))
17812 (use (match_operand:SI 3 "immediate_operand"))
17813 (clobber (match_operand 0 "register_operand"))
17814 (clobber (match_operand 1 "register_operand"))
17815 (clobber (match_operand 2 "register_operand"))])
17816 (set (match_operand:QI 7 "register_operand")
17817 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
17818 (set (match_operand:QI 8 "register_operand")
17819 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
17820 (set (reg FLAGS_REG)
17821 (compare (match_dup 7) (match_dup 8)))
17823 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
17825 (set (reg:CC FLAGS_REG)
17826 (compare:CC (mem:BLK (match_dup 4))
17827 (mem:BLK (match_dup 5))))
17828 (use (match_dup 6))
17829 (use (match_dup 3))
17830 (clobber (match_dup 0))
17831 (clobber (match_dup 1))
17832 (clobber (match_dup 2))])])
17834 ;; ...and this one handles cmpstrn*_1.
17837 (set (reg:CC FLAGS_REG)
17838 (if_then_else:CC (ne (match_operand 6 "register_operand")
17840 (compare:CC (mem:BLK (match_operand 4 "register_operand"))
17841 (mem:BLK (match_operand 5 "register_operand")))
17843 (use (match_operand:SI 3 "immediate_operand"))
17844 (use (reg:CC FLAGS_REG))
17845 (clobber (match_operand 0 "register_operand"))
17846 (clobber (match_operand 1 "register_operand"))
17847 (clobber (match_operand 2 "register_operand"))])
17848 (set (match_operand:QI 7 "register_operand")
17849 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
17850 (set (match_operand:QI 8 "register_operand")
17851 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
17852 (set (reg FLAGS_REG)
17853 (compare (match_dup 7) (match_dup 8)))
17855 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
17857 (set (reg:CC FLAGS_REG)
17858 (if_then_else:CC (ne (match_dup 6)
17860 (compare:CC (mem:BLK (match_dup 4))
17861 (mem:BLK (match_dup 5)))
17863 (use (match_dup 3))
17864 (use (reg:CC FLAGS_REG))
17865 (clobber (match_dup 0))
17866 (clobber (match_dup 1))
17867 (clobber (match_dup 2))])])
17869 ;; Conditional move instructions.
17871 (define_expand "mov<mode>cc"
17872 [(set (match_operand:SWIM 0 "register_operand")
17873 (if_then_else:SWIM (match_operand 1 "comparison_operator")
17874 (match_operand:SWIM 2 "<general_operand>")
17875 (match_operand:SWIM 3 "<general_operand>")))]
17877 "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
17879 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
17880 ;; the register first winds up with `sbbl $0,reg', which is also weird.
17881 ;; So just document what we're doing explicitly.
17883 (define_expand "x86_mov<mode>cc_0_m1"
17885 [(set (match_operand:SWI48 0 "register_operand")
17886 (if_then_else:SWI48
17887 (match_operator:SWI48 2 "ix86_carry_flag_operator"
17888 [(match_operand 1 "flags_reg_operand")
17892 (clobber (reg:CC FLAGS_REG))])])
17894 (define_insn "*x86_mov<mode>cc_0_m1"
17895 [(set (match_operand:SWI48 0 "register_operand" "=r")
17896 (if_then_else:SWI48 (match_operator 1 "ix86_carry_flag_operator"
17897 [(reg FLAGS_REG) (const_int 0)])
17900 (clobber (reg:CC FLAGS_REG))]
17902 "sbb{<imodesuffix>}\t%0, %0"
17903 [(set_attr "type" "alu1")
17904 (set_attr "modrm_class" "op0")
17905 (set_attr "use_carry" "1")
17906 (set_attr "pent_pair" "pu")
17907 (set_attr "mode" "<MODE>")
17908 (set_attr "length_immediate" "0")])
17910 (define_insn "*x86_mov<mode>cc_0_m1_se"
17911 [(set (match_operand:SWI48 0 "register_operand" "=r")
17912 (sign_extract:SWI48 (match_operator 1 "ix86_carry_flag_operator"
17913 [(reg FLAGS_REG) (const_int 0)])
17916 (clobber (reg:CC FLAGS_REG))]
17918 "sbb{<imodesuffix>}\t%0, %0"
17919 [(set_attr "type" "alu1")
17920 (set_attr "modrm_class" "op0")
17921 (set_attr "use_carry" "1")
17922 (set_attr "pent_pair" "pu")
17923 (set_attr "mode" "<MODE>")
17924 (set_attr "length_immediate" "0")])
17926 (define_insn "*x86_mov<mode>cc_0_m1_neg"
17927 [(set (match_operand:SWI48 0 "register_operand" "=r")
17928 (neg:SWI48 (match_operator 1 "ix86_carry_flag_operator"
17929 [(reg FLAGS_REG) (const_int 0)])))
17930 (clobber (reg:CC FLAGS_REG))]
17932 "sbb{<imodesuffix>}\t%0, %0"
17933 [(set_attr "type" "alu1")
17934 (set_attr "modrm_class" "op0")
17935 (set_attr "use_carry" "1")
17936 (set_attr "pent_pair" "pu")
17937 (set_attr "mode" "<MODE>")
17938 (set_attr "length_immediate" "0")])
17940 (define_insn "*mov<mode>cc_noc"
17941 [(set (match_operand:SWI248 0 "register_operand" "=r,r")
17942 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
17943 [(reg FLAGS_REG) (const_int 0)])
17944 (match_operand:SWI248 2 "nonimmediate_operand" "rm,0")
17945 (match_operand:SWI248 3 "nonimmediate_operand" "0,rm")))]
17946 "TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
17948 cmov%O2%C1\t{%2, %0|%0, %2}
17949 cmov%O2%c1\t{%3, %0|%0, %3}"
17950 [(set_attr "type" "icmov")
17951 (set_attr "mode" "<MODE>")])
17953 (define_insn "*movsicc_noc_zext"
17954 [(set (match_operand:DI 0 "register_operand" "=r,r")
17955 (if_then_else:DI (match_operator 1 "ix86_comparison_operator"
17956 [(reg FLAGS_REG) (const_int 0)])
17958 (match_operand:SI 2 "nonimmediate_operand" "rm,0"))
17960 (match_operand:SI 3 "nonimmediate_operand" "0,rm"))))]
17962 && TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
17964 cmov%O2%C1\t{%2, %k0|%k0, %2}
17965 cmov%O2%c1\t{%3, %k0|%k0, %3}"
17966 [(set_attr "type" "icmov")
17967 (set_attr "mode" "SI")])
17969 ;; Don't do conditional moves with memory inputs. This splitter helps
17970 ;; register starved x86_32 by forcing inputs into registers before reload.
17972 [(set (match_operand:SWI248 0 "register_operand")
17973 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
17974 [(reg FLAGS_REG) (const_int 0)])
17975 (match_operand:SWI248 2 "nonimmediate_operand")
17976 (match_operand:SWI248 3 "nonimmediate_operand")))]
17977 "!TARGET_64BIT && TARGET_CMOVE
17978 && TARGET_AVOID_MEM_OPND_FOR_CMOVE
17979 && (MEM_P (operands[2]) || MEM_P (operands[3]))
17980 && can_create_pseudo_p ()
17981 && optimize_insn_for_speed_p ()"
17982 [(set (match_dup 0)
17983 (if_then_else:SWI248 (match_dup 1) (match_dup 2) (match_dup 3)))]
17985 if (MEM_P (operands[2]))
17986 operands[2] = force_reg (<MODE>mode, operands[2]);
17987 if (MEM_P (operands[3]))
17988 operands[3] = force_reg (<MODE>mode, operands[3]);
17991 (define_insn "*movqicc_noc"
17992 [(set (match_operand:QI 0 "register_operand" "=r,r")
17993 (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
17994 [(reg FLAGS_REG) (const_int 0)])
17995 (match_operand:QI 2 "register_operand" "r,0")
17996 (match_operand:QI 3 "register_operand" "0,r")))]
17997 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
17999 [(set_attr "type" "icmov")
18000 (set_attr "mode" "QI")])
18003 [(set (match_operand:SWI12 0 "register_operand")
18004 (if_then_else:SWI12 (match_operator 1 "ix86_comparison_operator"
18005 [(reg FLAGS_REG) (const_int 0)])
18006 (match_operand:SWI12 2 "register_operand")
18007 (match_operand:SWI12 3 "register_operand")))]
18008 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL
18009 && reload_completed"
18010 [(set (match_dup 0)
18011 (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
18013 operands[0] = gen_lowpart (SImode, operands[0]);
18014 operands[2] = gen_lowpart (SImode, operands[2]);
18015 operands[3] = gen_lowpart (SImode, operands[3]);
18018 ;; Don't do conditional moves with memory inputs
18020 [(match_scratch:SWI248 4 "r")
18021 (set (match_operand:SWI248 0 "register_operand")
18022 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
18023 [(reg FLAGS_REG) (const_int 0)])
18024 (match_operand:SWI248 2 "nonimmediate_operand")
18025 (match_operand:SWI248 3 "nonimmediate_operand")))]
18026 "TARGET_CMOVE && TARGET_AVOID_MEM_OPND_FOR_CMOVE
18027 && (MEM_P (operands[2]) || MEM_P (operands[3]))
18028 && optimize_insn_for_speed_p ()"
18029 [(set (match_dup 4) (match_dup 5))
18031 (if_then_else:SWI248 (match_dup 1) (match_dup 2) (match_dup 3)))]
18033 if (MEM_P (operands[2]))
18035 operands[5] = operands[2];
18036 operands[2] = operands[4];
18038 else if (MEM_P (operands[3]))
18040 operands[5] = operands[3];
18041 operands[3] = operands[4];
18044 gcc_unreachable ();
18048 [(match_scratch:SI 4 "r")
18049 (set (match_operand:DI 0 "register_operand")
18050 (if_then_else:DI (match_operator 1 "ix86_comparison_operator"
18051 [(reg FLAGS_REG) (const_int 0)])
18053 (match_operand:SI 2 "nonimmediate_operand"))
18055 (match_operand:SI 3 "nonimmediate_operand"))))]
18057 && TARGET_CMOVE && TARGET_AVOID_MEM_OPND_FOR_CMOVE
18058 && (MEM_P (operands[2]) || MEM_P (operands[3]))
18059 && optimize_insn_for_speed_p ()"
18060 [(set (match_dup 4) (match_dup 5))
18062 (if_then_else:DI (match_dup 1)
18063 (zero_extend:DI (match_dup 2))
18064 (zero_extend:DI (match_dup 3))))]
18066 if (MEM_P (operands[2]))
18068 operands[5] = operands[2];
18069 operands[2] = operands[4];
18071 else if (MEM_P (operands[3]))
18073 operands[5] = operands[3];
18074 operands[3] = operands[4];
18077 gcc_unreachable ();
18080 (define_expand "mov<mode>cc"
18081 [(set (match_operand:X87MODEF 0 "register_operand")
18082 (if_then_else:X87MODEF
18083 (match_operand 1 "comparison_operator")
18084 (match_operand:X87MODEF 2 "register_operand")
18085 (match_operand:X87MODEF 3 "register_operand")))]
18086 "(TARGET_80387 && TARGET_CMOVE)
18087 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
18088 "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
18090 (define_insn "*movxfcc_1"
18091 [(set (match_operand:XF 0 "register_operand" "=f,f")
18092 (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
18093 [(reg FLAGS_REG) (const_int 0)])
18094 (match_operand:XF 2 "register_operand" "f,0")
18095 (match_operand:XF 3 "register_operand" "0,f")))]
18096 "TARGET_80387 && TARGET_CMOVE"
18098 fcmov%F1\t{%2, %0|%0, %2}
18099 fcmov%f1\t{%3, %0|%0, %3}"
18100 [(set_attr "type" "fcmov")
18101 (set_attr "mode" "XF")])
18103 (define_insn "*movdfcc_1"
18104 [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r,r ,r")
18105 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
18106 [(reg FLAGS_REG) (const_int 0)])
18107 (match_operand:DF 2 "nonimmediate_operand"
18109 (match_operand:DF 3 "nonimmediate_operand"
18110 "0 ,f,0 ,rm,0, rm")))]
18111 "TARGET_80387 && TARGET_CMOVE
18112 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
18114 fcmov%F1\t{%2, %0|%0, %2}
18115 fcmov%f1\t{%3, %0|%0, %3}
18118 cmov%O2%C1\t{%2, %0|%0, %2}
18119 cmov%O2%c1\t{%3, %0|%0, %3}"
18120 [(set_attr "isa" "*,*,nox64,nox64,x64,x64")
18121 (set_attr "type" "fcmov,fcmov,multi,multi,icmov,icmov")
18122 (set_attr "mode" "DF,DF,DI,DI,DI,DI")])
18125 [(set (match_operand:DF 0 "general_reg_operand")
18126 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
18127 [(reg FLAGS_REG) (const_int 0)])
18128 (match_operand:DF 2 "nonimmediate_operand")
18129 (match_operand:DF 3 "nonimmediate_operand")))]
18130 "!TARGET_64BIT && reload_completed"
18131 [(set (match_dup 2)
18132 (if_then_else:SI (match_dup 1) (match_dup 4) (match_dup 5)))
18134 (if_then_else:SI (match_dup 1) (match_dup 6) (match_dup 7)))]
18136 split_double_mode (DImode, &operands[2], 2, &operands[4], &operands[6]);
18137 split_double_mode (DImode, &operands[0], 1, &operands[2], &operands[3]);
18140 (define_insn "*movsfcc_1_387"
18141 [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
18142 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
18143 [(reg FLAGS_REG) (const_int 0)])
18144 (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
18145 (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
18146 "TARGET_80387 && TARGET_CMOVE
18147 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
18149 fcmov%F1\t{%2, %0|%0, %2}
18150 fcmov%f1\t{%3, %0|%0, %3}
18151 cmov%O2%C1\t{%2, %0|%0, %2}
18152 cmov%O2%c1\t{%3, %0|%0, %3}"
18153 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
18154 (set_attr "mode" "SF,SF,SI,SI")])
18156 ;; Don't do conditional moves with memory inputs. This splitter helps
18157 ;; register starved x86_32 by forcing inputs into registers before reload.
18159 [(set (match_operand:MODEF 0 "register_operand")
18160 (if_then_else:MODEF (match_operator 1 "ix86_comparison_operator"
18161 [(reg FLAGS_REG) (const_int 0)])
18162 (match_operand:MODEF 2 "nonimmediate_operand")
18163 (match_operand:MODEF 3 "nonimmediate_operand")))]
18164 "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
18165 && TARGET_AVOID_MEM_OPND_FOR_CMOVE
18166 && (MEM_P (operands[2]) || MEM_P (operands[3]))
18167 && can_create_pseudo_p ()
18168 && optimize_insn_for_speed_p ()"
18169 [(set (match_dup 0)
18170 (if_then_else:MODEF (match_dup 1) (match_dup 2) (match_dup 3)))]
18172 if (MEM_P (operands[2]))
18173 operands[2] = force_reg (<MODE>mode, operands[2]);
18174 if (MEM_P (operands[3]))
18175 operands[3] = force_reg (<MODE>mode, operands[3]);
18178 ;; Don't do conditional moves with memory inputs
18180 [(match_scratch:MODEF 4 "r")
18181 (set (match_operand:MODEF 0 "general_reg_operand")
18182 (if_then_else:MODEF (match_operator 1 "fcmov_comparison_operator"
18183 [(reg FLAGS_REG) (const_int 0)])
18184 (match_operand:MODEF 2 "nonimmediate_operand")
18185 (match_operand:MODEF 3 "nonimmediate_operand")))]
18186 "(<MODE>mode != DFmode || TARGET_64BIT)
18187 && TARGET_80387 && TARGET_CMOVE
18188 && TARGET_AVOID_MEM_OPND_FOR_CMOVE
18189 && (MEM_P (operands[2]) || MEM_P (operands[3]))
18190 && optimize_insn_for_speed_p ()"
18191 [(set (match_dup 4) (match_dup 5))
18193 (if_then_else:MODEF (match_dup 1) (match_dup 2) (match_dup 3)))]
18195 if (MEM_P (operands[2]))
18197 operands[5] = operands[2];
18198 operands[2] = operands[4];
18200 else if (MEM_P (operands[3]))
18202 operands[5] = operands[3];
18203 operands[3] = operands[4];
18206 gcc_unreachable ();
18209 ;; All moves in XOP pcmov instructions are 128 bits and hence we restrict
18210 ;; the scalar versions to have only XMM registers as operands.
18212 ;; XOP conditional move
18213 (define_insn "*xop_pcmov_<mode>"
18214 [(set (match_operand:MODEF 0 "register_operand" "=x")
18215 (if_then_else:MODEF
18216 (match_operand:MODEF 1 "register_operand" "x")
18217 (match_operand:MODEF 2 "register_operand" "x")
18218 (match_operand:MODEF 3 "register_operand" "x")))]
18220 "vpcmov\t{%1, %3, %2, %0|%0, %2, %3, %1}"
18221 [(set_attr "type" "sse4arg")])
18223 ;; These versions of the min/max patterns are intentionally ignorant of
18224 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
18225 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
18226 ;; are undefined in this condition, we're certain this is correct.
18228 (define_insn "<code><mode>3"
18229 [(set (match_operand:MODEF 0 "register_operand" "=x,v")
18231 (match_operand:MODEF 1 "nonimmediate_operand" "%0,v")
18232 (match_operand:MODEF 2 "nonimmediate_operand" "xm,vm")))]
18233 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
18235 <maxmin_float><ssemodesuffix>\t{%2, %0|%0, %2}
18236 v<maxmin_float><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
18237 [(set_attr "isa" "noavx,avx")
18238 (set_attr "prefix" "orig,vex")
18239 (set_attr "type" "sseadd")
18240 (set_attr "mode" "<MODE>")])
18242 ;; These versions of the min/max patterns implement exactly the operations
18243 ;; min = (op1 < op2 ? op1 : op2)
18244 ;; max = (!(op1 < op2) ? op1 : op2)
18245 ;; Their operands are not commutative, and thus they may be used in the
18246 ;; presence of -0.0 and NaN.
18248 (define_insn "*ieee_s<ieee_maxmin><mode>3"
18249 [(set (match_operand:MODEF 0 "register_operand" "=x,v")
18251 [(match_operand:MODEF 1 "register_operand" "0,v")
18252 (match_operand:MODEF 2 "nonimmediate_operand" "xm,vm")]
18254 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
18256 <ieee_maxmin><ssemodesuffix>\t{%2, %0|%0, %2}
18257 v<ieee_maxmin><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
18258 [(set_attr "isa" "noavx,avx")
18259 (set_attr "prefix" "orig,maybe_evex")
18260 (set_attr "type" "sseadd")
18261 (set_attr "mode" "<MODE>")])
18263 ;; Make two stack loads independent:
18265 ;; fld %st(0) -> fld bb
18266 ;; fmul bb fmul %st(1), %st
18268 ;; Actually we only match the last two instructions for simplicity.
18271 [(set (match_operand 0 "fp_register_operand")
18272 (match_operand 1 "fp_register_operand"))
18274 (match_operator 2 "binary_fp_operator"
18276 (match_operand 3 "memory_operand")]))]
18277 "REGNO (operands[0]) != REGNO (operands[1])"
18278 [(set (match_dup 0) (match_dup 3))
18281 [(match_dup 5) (match_dup 4)]))]
18283 operands[4] = operands[0];
18284 operands[5] = operands[1];
18286 /* The % modifier is not operational anymore in peephole2's, so we have to
18287 swap the operands manually in the case of addition and multiplication. */
18288 if (COMMUTATIVE_ARITH_P (operands[2]))
18289 std::swap (operands[4], operands[5]);
18293 [(set (match_operand 0 "fp_register_operand")
18294 (match_operand 1 "fp_register_operand"))
18296 (match_operator 2 "binary_fp_operator"
18297 [(match_operand 3 "memory_operand")
18299 "REGNO (operands[0]) != REGNO (operands[1])"
18300 [(set (match_dup 0) (match_dup 3))
18303 [(match_dup 4) (match_dup 5)]))]
18305 operands[4] = operands[0];
18306 operands[5] = operands[1];
18308 /* The % modifier is not operational anymore in peephole2's, so we have to
18309 swap the operands manually in the case of addition and multiplication. */
18310 if (COMMUTATIVE_ARITH_P (operands[2]))
18311 std::swap (operands[4], operands[5]);
18314 ;; Conditional addition patterns
18315 (define_expand "add<mode>cc"
18316 [(match_operand:SWI 0 "register_operand")
18317 (match_operand 1 "ordered_comparison_operator")
18318 (match_operand:SWI 2 "register_operand")
18319 (match_operand:SWI 3 "const_int_operand")]
18321 "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
18323 ;; Misc patterns (?)
18325 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
18326 ;; Otherwise there will be nothing to keep
18328 ;; [(set (reg ebp) (reg esp))]
18329 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
18330 ;; (clobber (eflags)]
18331 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
18333 ;; in proper program order.
18335 (define_insn "pro_epilogue_adjust_stack_<mode>_add"
18336 [(set (match_operand:P 0 "register_operand" "=r,r")
18337 (plus:P (match_operand:P 1 "register_operand" "0,r")
18338 (match_operand:P 2 "<nonmemory_operand>" "r<i>,l<i>")))
18339 (clobber (reg:CC FLAGS_REG))
18340 (clobber (mem:BLK (scratch)))]
18343 switch (get_attr_type (insn))
18346 return "mov{<imodesuffix>}\t{%1, %0|%0, %1}";
18349 gcc_assert (rtx_equal_p (operands[0], operands[1]));
18350 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
18351 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
18353 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
18356 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
18357 return "lea{<imodesuffix>}\t{%E2, %0|%0, %E2}";
18360 [(set (attr "type")
18361 (cond [(and (eq_attr "alternative" "0")
18362 (not (match_test "TARGET_OPT_AGU")))
18363 (const_string "alu")
18364 (match_operand:<MODE> 2 "const0_operand")
18365 (const_string "imov")
18367 (const_string "lea")))
18368 (set (attr "length_immediate")
18369 (cond [(eq_attr "type" "imov")
18371 (and (eq_attr "type" "alu")
18372 (match_operand 2 "const128_operand"))
18375 (const_string "*")))
18376 (set_attr "mode" "<MODE>")])
18378 (define_insn "pro_epilogue_adjust_stack_<mode>_sub"
18379 [(set (match_operand:P 0 "register_operand" "=r")
18380 (minus:P (match_operand:P 1 "register_operand" "0")
18381 (match_operand:P 2 "register_operand" "r")))
18382 (clobber (reg:CC FLAGS_REG))
18383 (clobber (mem:BLK (scratch)))]
18385 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
18386 [(set_attr "type" "alu")
18387 (set_attr "mode" "<MODE>")])
18389 (define_insn "allocate_stack_worker_probe_<mode>"
18390 [(set (match_operand:P 0 "register_operand" "=a")
18391 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
18392 UNSPECV_STACK_PROBE))
18393 (clobber (reg:CC FLAGS_REG))]
18394 "ix86_target_stack_probe ()"
18395 "call\t___chkstk_ms"
18396 [(set_attr "type" "multi")
18397 (set_attr "length" "5")])
18399 (define_expand "allocate_stack"
18400 [(match_operand 0 "register_operand")
18401 (match_operand 1 "general_operand")]
18402 "ix86_target_stack_probe ()"
18406 #ifndef CHECK_STACK_LIMIT
18407 #define CHECK_STACK_LIMIT 0
18410 if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
18411 && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
18415 rtx (*insn) (rtx, rtx);
18417 x = copy_to_mode_reg (Pmode, operands[1]);
18419 insn = (TARGET_64BIT
18420 ? gen_allocate_stack_worker_probe_di
18421 : gen_allocate_stack_worker_probe_si);
18423 emit_insn (insn (x, x));
18426 x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, x,
18427 stack_pointer_rtx, 0, OPTAB_DIRECT);
18429 if (x != stack_pointer_rtx)
18430 emit_move_insn (stack_pointer_rtx, x);
18432 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
18436 (define_expand "probe_stack"
18437 [(match_operand 0 "memory_operand")]
18440 rtx (*insn) (rtx, rtx)
18441 = (GET_MODE (operands[0]) == DImode
18442 ? gen_probe_stack_di : gen_probe_stack_si);
18444 emit_insn (insn (operands[0], const0_rtx));
18448 ;; Use OR for stack probes, this is shorter.
18449 (define_insn "probe_stack_<mode>"
18450 [(set (match_operand:W 0 "memory_operand" "=m")
18451 (unspec:W [(match_operand:W 1 "const0_operand")]
18452 UNSPEC_PROBE_STACK))
18453 (clobber (reg:CC FLAGS_REG))]
18455 "or{<imodesuffix>}\t{%1, %0|%0, %1}"
18456 [(set_attr "type" "alu1")
18457 (set_attr "mode" "<MODE>")
18458 (set_attr "length_immediate" "1")])
18460 (define_insn "adjust_stack_and_probe<mode>"
18461 [(set (match_operand:P 0 "register_operand" "=r")
18462 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
18463 UNSPECV_PROBE_STACK_RANGE))
18464 (set (reg:P SP_REG)
18465 (minus:P (reg:P SP_REG) (match_operand:P 2 "const_int_operand" "n")))
18466 (clobber (reg:CC FLAGS_REG))
18467 (clobber (mem:BLK (scratch)))]
18469 "* return output_adjust_stack_and_probe (operands[0]);"
18470 [(set_attr "type" "multi")])
18472 (define_insn "probe_stack_range<mode>"
18473 [(set (match_operand:P 0 "register_operand" "=r")
18474 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
18475 (match_operand:P 2 "const_int_operand" "n")]
18476 UNSPECV_PROBE_STACK_RANGE))
18477 (clobber (reg:CC FLAGS_REG))]
18479 "* return output_probe_stack_range (operands[0], operands[2]);"
18480 [(set_attr "type" "multi")])
18482 (define_expand "builtin_setjmp_receiver"
18483 [(label_ref (match_operand 0))]
18484 "!TARGET_64BIT && flag_pic"
18490 rtx_code_label *label_rtx = gen_label_rtx ();
18491 emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
18492 xops[0] = xops[1] = pic_offset_table_rtx;
18493 xops[2] = machopic_gen_offset (gen_rtx_LABEL_REF (SImode, label_rtx));
18494 ix86_expand_binary_operator (MINUS, SImode, xops);
18498 emit_insn (gen_set_got (pic_offset_table_rtx));
18502 (define_expand "save_stack_nonlocal"
18503 [(set (match_operand 0 "memory_operand")
18504 (match_operand 1 "register_operand"))]
18508 if ((flag_cf_protection & CF_RETURN))
18510 /* Copy shadow stack pointer to the first slot and stack ppointer
18511 to the second slot. */
18512 rtx ssp_slot = adjust_address (operands[0], word_mode, 0);
18513 stack_slot = adjust_address (operands[0], Pmode, UNITS_PER_WORD);
18514 rtx ssp = gen_reg_rtx (word_mode);
18515 emit_insn ((word_mode == SImode)
18516 ? gen_rdsspsi (ssp)
18517 : gen_rdsspdi (ssp));
18518 emit_move_insn (ssp_slot, ssp);
18521 stack_slot = adjust_address (operands[0], Pmode, 0);
18522 emit_move_insn (stack_slot, operands[1]);
18526 (define_expand "restore_stack_nonlocal"
18527 [(set (match_operand 0 "register_operand" "")
18528 (match_operand 1 "memory_operand" ""))]
18532 if ((flag_cf_protection & CF_RETURN))
18534 /* Restore shadow stack pointer from the first slot and stack
18535 pointer from the second slot. */
18536 rtx ssp_slot = adjust_address (operands[1], word_mode, 0);
18537 stack_slot = adjust_address (operands[1], Pmode, UNITS_PER_WORD);
18539 rtx flags, jump, noadj_label, inc_label, loop_label;
18540 rtx reg_adj, reg_ssp, tmp, clob;
18542 /* Get the current shadow stack pointer. The code below will check if
18543 SHSTK feature is enabled. If it is not enabled the RDSSP instruction
18545 reg_ssp = gen_reg_rtx (word_mode);
18546 emit_insn (gen_rtx_SET (reg_ssp, const0_rtx));
18547 emit_insn ((word_mode == SImode)
18548 ? gen_rdsspsi (reg_ssp)
18549 : gen_rdsspdi (reg_ssp));
18551 /* Compare through substraction the saved and the current ssp to decide
18552 if ssp has to be adjusted. */
18553 tmp = gen_rtx_SET (reg_ssp, gen_rtx_MINUS (word_mode, reg_ssp,
18555 clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
18556 tmp = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, tmp, clob));
18559 /* Compare and jump over adjustment code. */
18560 noadj_label = gen_label_rtx ();
18561 flags = gen_rtx_REG (CCZmode, FLAGS_REG);
18562 tmp = gen_rtx_EQ (VOIDmode, flags, const0_rtx);
18563 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
18564 gen_rtx_LABEL_REF (VOIDmode, noadj_label),
18566 jump = emit_jump_insn (gen_rtx_SET (pc_rtx, tmp));
18567 JUMP_LABEL (jump) = noadj_label;
18569 /* Compute the numebr of frames to adjust. */
18570 reg_adj = gen_lowpart (ptr_mode, reg_ssp);
18571 tmp = gen_rtx_SET (reg_adj,
18572 gen_rtx_LSHIFTRT (ptr_mode,
18573 negate_rtx (ptr_mode, reg_adj),
18574 GEN_INT ((word_mode == SImode)
18577 clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
18578 tmp = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, tmp, clob));
18581 /* Check if number of frames <= 255 so no loop is needed. */
18582 tmp = gen_rtx_COMPARE (CCmode, reg_adj, GEN_INT (255));
18583 flags = gen_rtx_REG (CCmode, FLAGS_REG);
18584 emit_insn (gen_rtx_SET (flags, tmp));
18586 inc_label = gen_label_rtx ();
18587 tmp = gen_rtx_LEU (VOIDmode, flags, const0_rtx);
18588 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
18589 gen_rtx_LABEL_REF (VOIDmode, inc_label),
18591 jump = emit_jump_insn (gen_rtx_SET (pc_rtx, tmp));
18592 JUMP_LABEL (jump) = inc_label;
18594 rtx reg_255 = gen_reg_rtx (word_mode);
18595 emit_move_insn (reg_255, GEN_INT (255));
18597 /* Adjust the ssp in a loop. */
18598 loop_label = gen_label_rtx ();
18599 emit_label (loop_label);
18600 LABEL_NUSES (loop_label) = 1;
18602 emit_insn ((word_mode == SImode)
18603 ? gen_incsspsi (reg_255)
18604 : gen_incsspdi (reg_255));
18605 tmp = gen_rtx_SET (reg_adj, gen_rtx_MINUS (ptr_mode,
18608 clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
18609 tmp = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, tmp, clob));
18612 tmp = gen_rtx_COMPARE (CCmode, reg_adj, GEN_INT (255));
18613 flags = gen_rtx_REG (CCmode, FLAGS_REG);
18614 emit_insn (gen_rtx_SET (flags, tmp));
18616 /* Jump to the loop label. */
18617 tmp = gen_rtx_GTU (VOIDmode, flags, const0_rtx);
18618 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
18619 gen_rtx_LABEL_REF (VOIDmode, loop_label),
18621 jump = emit_jump_insn (gen_rtx_SET (pc_rtx, tmp));
18622 JUMP_LABEL (jump) = loop_label;
18624 emit_label (inc_label);
18625 LABEL_NUSES (inc_label) = 1;
18626 emit_insn ((word_mode == SImode)
18627 ? gen_incsspsi (reg_ssp)
18628 : gen_incsspdi (reg_ssp));
18630 emit_label (noadj_label);
18631 LABEL_NUSES (noadj_label) = 1;
18634 stack_slot = adjust_address (operands[1], Pmode, 0);
18635 emit_move_insn (operands[0], stack_slot);
18640 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
18641 ;; Do not split instructions with mask registers.
18643 [(set (match_operand 0 "general_reg_operand")
18644 (match_operator 3 "promotable_binary_operator"
18645 [(match_operand 1 "general_reg_operand")
18646 (match_operand 2 "aligned_operand")]))
18647 (clobber (reg:CC FLAGS_REG))]
18648 "! TARGET_PARTIAL_REG_STALL && reload_completed
18649 && ((GET_MODE (operands[0]) == HImode
18650 && ((optimize_function_for_speed_p (cfun) && !TARGET_FAST_PREFIX)
18651 /* ??? next two lines just !satisfies_constraint_K (...) */
18652 || !CONST_INT_P (operands[2])
18653 || satisfies_constraint_K (operands[2])))
18654 || (GET_MODE (operands[0]) == QImode
18655 && (TARGET_PROMOTE_QImode || optimize_function_for_size_p (cfun))))"
18656 [(parallel [(set (match_dup 0)
18657 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
18658 (clobber (reg:CC FLAGS_REG))])]
18660 operands[0] = gen_lowpart (SImode, operands[0]);
18661 operands[1] = gen_lowpart (SImode, operands[1]);
18662 if (GET_CODE (operands[3]) != ASHIFT)
18663 operands[2] = gen_lowpart (SImode, operands[2]);
18664 operands[3] = shallow_copy_rtx (operands[3]);
18665 PUT_MODE (operands[3], SImode);
18668 ; Promote the QImode tests, as i386 has encoding of the AND
18669 ; instruction with 32-bit sign-extended immediate and thus the
18670 ; instruction size is unchanged, except in the %eax case for
18671 ; which it is increased by one byte, hence the ! optimize_size.
18673 [(set (match_operand 0 "flags_reg_operand")
18674 (match_operator 2 "compare_operator"
18675 [(and (match_operand 3 "aligned_operand")
18676 (match_operand 4 "const_int_operand"))
18678 (set (match_operand 1 "register_operand")
18679 (and (match_dup 3) (match_dup 4)))]
18680 "! TARGET_PARTIAL_REG_STALL && reload_completed
18681 && optimize_insn_for_speed_p ()
18682 && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
18683 || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))
18684 /* Ensure that the operand will remain sign-extended immediate. */
18685 && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)"
18686 [(parallel [(set (match_dup 0)
18687 (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
18690 (and:SI (match_dup 3) (match_dup 4)))])]
18693 = gen_int_mode (INTVAL (operands[4])
18694 & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
18695 operands[1] = gen_lowpart (SImode, operands[1]);
18696 operands[3] = gen_lowpart (SImode, operands[3]);
18699 ; Don't promote the QImode tests, as i386 doesn't have encoding of
18700 ; the TEST instruction with 32-bit sign-extended immediate and thus
18701 ; the instruction size would at least double, which is not what we
18702 ; want even with ! optimize_size.
18704 [(set (match_operand 0 "flags_reg_operand")
18705 (match_operator 1 "compare_operator"
18706 [(and (match_operand:HI 2 "aligned_operand")
18707 (match_operand:HI 3 "const_int_operand"))
18709 "! TARGET_PARTIAL_REG_STALL && reload_completed
18710 && ! TARGET_FAST_PREFIX
18711 && optimize_insn_for_speed_p ()
18712 /* Ensure that the operand will remain sign-extended immediate. */
18713 && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)"
18714 [(set (match_dup 0)
18715 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
18719 = gen_int_mode (INTVAL (operands[3])
18720 & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
18721 operands[2] = gen_lowpart (SImode, operands[2]);
18725 [(set (match_operand 0 "register_operand")
18726 (neg (match_operand 1 "register_operand")))
18727 (clobber (reg:CC FLAGS_REG))]
18728 "! TARGET_PARTIAL_REG_STALL && reload_completed
18729 && (GET_MODE (operands[0]) == HImode
18730 || (GET_MODE (operands[0]) == QImode
18731 && (TARGET_PROMOTE_QImode
18732 || optimize_insn_for_size_p ())))"
18733 [(parallel [(set (match_dup 0)
18734 (neg:SI (match_dup 1)))
18735 (clobber (reg:CC FLAGS_REG))])]
18737 operands[0] = gen_lowpart (SImode, operands[0]);
18738 operands[1] = gen_lowpart (SImode, operands[1]);
18741 ;; Do not split instructions with mask regs.
18743 [(set (match_operand 0 "general_reg_operand")
18744 (not (match_operand 1 "general_reg_operand")))]
18745 "! TARGET_PARTIAL_REG_STALL && reload_completed
18746 && (GET_MODE (operands[0]) == HImode
18747 || (GET_MODE (operands[0]) == QImode
18748 && (TARGET_PROMOTE_QImode
18749 || optimize_insn_for_size_p ())))"
18750 [(set (match_dup 0)
18751 (not:SI (match_dup 1)))]
18753 operands[0] = gen_lowpart (SImode, operands[0]);
18754 operands[1] = gen_lowpart (SImode, operands[1]);
18757 ;; RTL Peephole optimizations, run before sched2. These primarily look to
18758 ;; transform a complex memory operation into two memory to register operations.
18760 ;; Don't push memory operands
18762 [(set (match_operand:SWI 0 "push_operand")
18763 (match_operand:SWI 1 "memory_operand"))
18764 (match_scratch:SWI 2 "<r>")]
18765 "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
18766 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
18767 [(set (match_dup 2) (match_dup 1))
18768 (set (match_dup 0) (match_dup 2))])
18770 ;; We need to handle SFmode only, because DFmode and XFmode are split to
18773 [(set (match_operand:SF 0 "push_operand")
18774 (match_operand:SF 1 "memory_operand"))
18775 (match_scratch:SF 2 "r")]
18776 "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
18777 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
18778 [(set (match_dup 2) (match_dup 1))
18779 (set (match_dup 0) (match_dup 2))])
18781 ;; Don't move an immediate directly to memory when the instruction
18782 ;; gets too big, or if LCP stalls are a problem for 16-bit moves.
18784 [(match_scratch:SWI124 1 "<r>")
18785 (set (match_operand:SWI124 0 "memory_operand")
18787 "optimize_insn_for_speed_p ()
18788 && ((<MODE>mode == HImode
18789 && TARGET_LCP_STALL)
18790 || (!TARGET_USE_MOV0
18791 && TARGET_SPLIT_LONG_MOVES
18792 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn))
18793 && peep2_regno_dead_p (0, FLAGS_REG)"
18794 [(parallel [(set (match_dup 2) (const_int 0))
18795 (clobber (reg:CC FLAGS_REG))])
18796 (set (match_dup 0) (match_dup 1))]
18797 "operands[2] = gen_lowpart (SImode, operands[1]);")
18800 [(match_scratch:SWI124 2 "<r>")
18801 (set (match_operand:SWI124 0 "memory_operand")
18802 (match_operand:SWI124 1 "immediate_operand"))]
18803 "optimize_insn_for_speed_p ()
18804 && ((<MODE>mode == HImode
18805 && TARGET_LCP_STALL)
18806 || (TARGET_SPLIT_LONG_MOVES
18807 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn))"
18808 [(set (match_dup 2) (match_dup 1))
18809 (set (match_dup 0) (match_dup 2))])
18811 ;; Don't compare memory with zero, load and use a test instead.
18813 [(set (match_operand 0 "flags_reg_operand")
18814 (match_operator 1 "compare_operator"
18815 [(match_operand:SI 2 "memory_operand")
18817 (match_scratch:SI 3 "r")]
18818 "optimize_insn_for_speed_p () && ix86_match_ccmode (insn, CCNOmode)"
18819 [(set (match_dup 3) (match_dup 2))
18820 (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))])
18822 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
18823 ;; Don't split NOTs with a displacement operand, because resulting XOR
18824 ;; will not be pairable anyway.
18826 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
18827 ;; represented using a modRM byte. The XOR replacement is long decoded,
18828 ;; so this split helps here as well.
18830 ;; Note: Can't do this as a regular split because we can't get proper
18831 ;; lifetime information then.
18834 [(set (match_operand:SWI124 0 "nonimmediate_gr_operand")
18835 (not:SWI124 (match_operand:SWI124 1 "nonimmediate_gr_operand")))]
18836 "optimize_insn_for_speed_p ()
18837 && ((TARGET_NOT_UNPAIRABLE
18838 && (!MEM_P (operands[0])
18839 || !memory_displacement_operand (operands[0], <MODE>mode)))
18840 || (TARGET_NOT_VECTORMODE
18841 && long_memory_operand (operands[0], <MODE>mode)))
18842 && peep2_regno_dead_p (0, FLAGS_REG)"
18843 [(parallel [(set (match_dup 0)
18844 (xor:SWI124 (match_dup 1) (const_int -1)))
18845 (clobber (reg:CC FLAGS_REG))])])
18847 ;; Non pairable "test imm, reg" instructions can be translated to
18848 ;; "and imm, reg" if reg dies. The "and" form is also shorter (one
18849 ;; byte opcode instead of two, have a short form for byte operands),
18850 ;; so do it for other CPUs as well. Given that the value was dead,
18851 ;; this should not create any new dependencies. Pass on the sub-word
18852 ;; versions if we're concerned about partial register stalls.
18855 [(set (match_operand 0 "flags_reg_operand")
18856 (match_operator 1 "compare_operator"
18857 [(and:SI (match_operand:SI 2 "register_operand")
18858 (match_operand:SI 3 "immediate_operand"))
18860 "ix86_match_ccmode (insn, CCNOmode)
18861 && (REGNO (operands[2]) != AX_REG
18862 || satisfies_constraint_K (operands[3]))
18863 && peep2_reg_dead_p (1, operands[2])"
18865 [(set (match_dup 0)
18866 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
18869 (and:SI (match_dup 2) (match_dup 3)))])])
18871 ;; We don't need to handle HImode case, because it will be promoted to SImode
18872 ;; on ! TARGET_PARTIAL_REG_STALL
18875 [(set (match_operand 0 "flags_reg_operand")
18876 (match_operator 1 "compare_operator"
18877 [(and:QI (match_operand:QI 2 "register_operand")
18878 (match_operand:QI 3 "immediate_operand"))
18880 "! TARGET_PARTIAL_REG_STALL
18881 && ix86_match_ccmode (insn, CCNOmode)
18882 && REGNO (operands[2]) != AX_REG
18883 && peep2_reg_dead_p (1, operands[2])"
18885 [(set (match_dup 0)
18886 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
18889 (and:QI (match_dup 2) (match_dup 3)))])])
18892 [(set (match_operand 0 "flags_reg_operand")
18893 (match_operator 1 "compare_operator"
18896 (zero_extract:SI (match_operand 2 "QIreg_operand")
18899 (match_operand 3 "const_int_operand"))
18901 "! TARGET_PARTIAL_REG_STALL
18902 && ix86_match_ccmode (insn, CCNOmode)
18903 && REGNO (operands[2]) != AX_REG
18904 && peep2_reg_dead_p (1, operands[2])"
18906 [(set (match_dup 0)
18910 (zero_extract:SI (match_dup 2)
18915 (set (zero_extract:SI (match_dup 2)
18921 (zero_extract:SI (match_dup 2)
18924 (match_dup 3)) 0))])])
18926 ;; Don't do logical operations with memory inputs.
18928 [(match_scratch:SWI 2 "<r>")
18929 (parallel [(set (match_operand:SWI 0 "register_operand")
18930 (match_operator:SWI 3 "arith_or_logical_operator"
18932 (match_operand:SWI 1 "memory_operand")]))
18933 (clobber (reg:CC FLAGS_REG))])]
18934 "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
18935 [(set (match_dup 2) (match_dup 1))
18936 (parallel [(set (match_dup 0)
18937 (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
18938 (clobber (reg:CC FLAGS_REG))])])
18941 [(match_scratch:SWI 2 "<r>")
18942 (parallel [(set (match_operand:SWI 0 "register_operand")
18943 (match_operator:SWI 3 "arith_or_logical_operator"
18944 [(match_operand:SWI 1 "memory_operand")
18946 (clobber (reg:CC FLAGS_REG))])]
18947 "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
18948 [(set (match_dup 2) (match_dup 1))
18949 (parallel [(set (match_dup 0)
18950 (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
18951 (clobber (reg:CC FLAGS_REG))])])
18953 ;; Prefer Load+RegOp to Mov+MemOp. Watch out for cases when
18954 ;; the memory address refers to the destination of the load!
18957 [(set (match_operand:SWI 0 "general_reg_operand")
18958 (match_operand:SWI 1 "general_reg_operand"))
18959 (parallel [(set (match_dup 0)
18960 (match_operator:SWI 3 "commutative_operator"
18962 (match_operand:SWI 2 "memory_operand")]))
18963 (clobber (reg:CC FLAGS_REG))])]
18964 "REGNO (operands[0]) != REGNO (operands[1])
18965 && (<MODE>mode != QImode
18966 || any_QIreg_operand (operands[1], QImode))"
18967 [(set (match_dup 0) (match_dup 4))
18968 (parallel [(set (match_dup 0)
18969 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))
18970 (clobber (reg:CC FLAGS_REG))])]
18971 "operands[4] = replace_rtx (operands[2], operands[0], operands[1], true);")
18974 [(set (match_operand 0 "mmx_reg_operand")
18975 (match_operand 1 "mmx_reg_operand"))
18977 (match_operator 3 "commutative_operator"
18979 (match_operand 2 "memory_operand")]))]
18980 "REGNO (operands[0]) != REGNO (operands[1])"
18981 [(set (match_dup 0) (match_dup 2))
18983 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))])
18986 [(set (match_operand 0 "sse_reg_operand")
18987 (match_operand 1 "sse_reg_operand"))
18989 (match_operator 3 "commutative_operator"
18991 (match_operand 2 "memory_operand")]))]
18992 "REGNO (operands[0]) != REGNO (operands[1])"
18993 [(set (match_dup 0) (match_dup 2))
18995 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))])
18997 ; Don't do logical operations with memory outputs
18999 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
19000 ; instruction into two 1-uop insns plus a 2-uop insn. That last has
19001 ; the same decoder scheduling characteristics as the original.
19004 [(match_scratch:SWI 2 "<r>")
19005 (parallel [(set (match_operand:SWI 0 "memory_operand")
19006 (match_operator:SWI 3 "arith_or_logical_operator"
19008 (match_operand:SWI 1 "<nonmemory_operand>")]))
19009 (clobber (reg:CC FLAGS_REG))])]
19010 "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())"
19011 [(set (match_dup 2) (match_dup 0))
19012 (parallel [(set (match_dup 2)
19013 (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
19014 (clobber (reg:CC FLAGS_REG))])
19015 (set (match_dup 0) (match_dup 2))])
19018 [(match_scratch:SWI 2 "<r>")
19019 (parallel [(set (match_operand:SWI 0 "memory_operand")
19020 (match_operator:SWI 3 "arith_or_logical_operator"
19021 [(match_operand:SWI 1 "<nonmemory_operand>")
19023 (clobber (reg:CC FLAGS_REG))])]
19024 "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())"
19025 [(set (match_dup 2) (match_dup 0))
19026 (parallel [(set (match_dup 2)
19027 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
19028 (clobber (reg:CC FLAGS_REG))])
19029 (set (match_dup 0) (match_dup 2))])
19031 ;; Attempt to use arith or logical operations with memory outputs with
19032 ;; setting of flags.
19034 [(set (match_operand:SWI 0 "register_operand")
19035 (match_operand:SWI 1 "memory_operand"))
19036 (parallel [(set (match_dup 0)
19037 (match_operator:SWI 3 "plusminuslogic_operator"
19039 (match_operand:SWI 2 "<nonmemory_operand>")]))
19040 (clobber (reg:CC FLAGS_REG))])
19041 (set (match_dup 1) (match_dup 0))
19042 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
19043 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
19044 && peep2_reg_dead_p (4, operands[0])
19045 && !reg_overlap_mentioned_p (operands[0], operands[1])
19046 && !reg_overlap_mentioned_p (operands[0], operands[2])
19047 && (<MODE>mode != QImode
19048 || immediate_operand (operands[2], QImode)
19049 || any_QIreg_operand (operands[2], QImode))
19050 && ix86_match_ccmode (peep2_next_insn (3),
19051 (GET_CODE (operands[3]) == PLUS
19052 || GET_CODE (operands[3]) == MINUS)
19053 ? CCGOCmode : CCNOmode)"
19054 [(parallel [(set (match_dup 4) (match_dup 6))
19055 (set (match_dup 1) (match_dup 5))])]
19057 operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
19059 = gen_rtx_fmt_ee (GET_CODE (operands[3]), GET_MODE (operands[3]),
19060 copy_rtx (operands[1]),
19063 = gen_rtx_COMPARE (GET_MODE (operands[4]),
19064 copy_rtx (operands[5]),
19068 ;; Likewise for instances where we have a lea pattern.
19070 [(set (match_operand:SWI 0 "register_operand")
19071 (match_operand:SWI 1 "memory_operand"))
19072 (set (match_operand:SWI 3 "register_operand")
19073 (plus:SWI (match_dup 0)
19074 (match_operand:SWI 2 "<nonmemory_operand>")))
19075 (set (match_dup 1) (match_dup 3))
19076 (set (reg FLAGS_REG) (compare (match_dup 3) (const_int 0)))]
19077 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
19078 && peep2_reg_dead_p (4, operands[3])
19079 && (rtx_equal_p (operands[0], operands[3])
19080 || peep2_reg_dead_p (2, operands[0]))
19081 && !reg_overlap_mentioned_p (operands[0], operands[1])
19082 && !reg_overlap_mentioned_p (operands[3], operands[1])
19083 && !reg_overlap_mentioned_p (operands[0], operands[2])
19084 && (<MODE>mode != QImode
19085 || immediate_operand (operands[2], QImode)
19086 || any_QIreg_operand (operands[2], QImode))
19087 && ix86_match_ccmode (peep2_next_insn (3), CCGOCmode)"
19088 [(parallel [(set (match_dup 4) (match_dup 6))
19089 (set (match_dup 1) (match_dup 5))])]
19091 operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
19093 = gen_rtx_PLUS (<MODE>mode,
19094 copy_rtx (operands[1]),
19097 = gen_rtx_COMPARE (GET_MODE (operands[4]),
19098 copy_rtx (operands[5]),
19103 [(parallel [(set (match_operand:SWI 0 "register_operand")
19104 (match_operator:SWI 2 "plusminuslogic_operator"
19106 (match_operand:SWI 1 "memory_operand")]))
19107 (clobber (reg:CC FLAGS_REG))])
19108 (set (match_dup 1) (match_dup 0))
19109 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
19110 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
19111 && GET_CODE (operands[2]) != MINUS
19112 && peep2_reg_dead_p (3, operands[0])
19113 && !reg_overlap_mentioned_p (operands[0], operands[1])
19114 && ix86_match_ccmode (peep2_next_insn (2),
19115 GET_CODE (operands[2]) == PLUS
19116 ? CCGOCmode : CCNOmode)"
19117 [(parallel [(set (match_dup 3) (match_dup 5))
19118 (set (match_dup 1) (match_dup 4))])]
19120 operands[3] = SET_DEST (PATTERN (peep2_next_insn (2)));
19122 = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
19123 copy_rtx (operands[1]),
19126 = gen_rtx_COMPARE (GET_MODE (operands[3]),
19127 copy_rtx (operands[4]),
19132 [(set (match_operand:SWI12 0 "register_operand")
19133 (match_operand:SWI12 1 "memory_operand"))
19134 (parallel [(set (match_operand:SI 4 "register_operand")
19135 (match_operator:SI 3 "plusminuslogic_operator"
19137 (match_operand:SI 2 "nonmemory_operand")]))
19138 (clobber (reg:CC FLAGS_REG))])
19139 (set (match_dup 1) (match_dup 0))
19140 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
19141 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
19142 && REGNO (operands[0]) == REGNO (operands[4])
19143 && peep2_reg_dead_p (4, operands[0])
19144 && (<MODE>mode != QImode
19145 || immediate_operand (operands[2], SImode)
19146 || any_QIreg_operand (operands[2], SImode))
19147 && !reg_overlap_mentioned_p (operands[0], operands[1])
19148 && !reg_overlap_mentioned_p (operands[0], operands[2])
19149 && ix86_match_ccmode (peep2_next_insn (3),
19150 (GET_CODE (operands[3]) == PLUS
19151 || GET_CODE (operands[3]) == MINUS)
19152 ? CCGOCmode : CCNOmode)"
19153 [(parallel [(set (match_dup 4) (match_dup 6))
19154 (set (match_dup 1) (match_dup 5))])]
19156 operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
19158 = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
19159 copy_rtx (operands[1]),
19160 gen_lowpart (<MODE>mode, operands[2]));
19162 = gen_rtx_COMPARE (GET_MODE (operands[4]),
19163 copy_rtx (operands[5]),
19167 ;; Attempt to always use XOR for zeroing registers (including FP modes).
19169 [(set (match_operand 0 "general_reg_operand")
19170 (match_operand 1 "const0_operand"))]
19171 "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
19172 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
19173 && peep2_regno_dead_p (0, FLAGS_REG)"
19174 [(parallel [(set (match_dup 0) (const_int 0))
19175 (clobber (reg:CC FLAGS_REG))])]
19176 "operands[0] = gen_lowpart (word_mode, operands[0]);")
19179 [(set (strict_low_part (match_operand:SWI12 0 "general_reg_operand"))
19181 "(! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
19182 && peep2_regno_dead_p (0, FLAGS_REG)"
19183 [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
19184 (clobber (reg:CC FLAGS_REG))])])
19186 ;; For HI, SI and DI modes, or $-1,reg is smaller than mov $-1,reg.
19188 [(set (match_operand:SWI248 0 "general_reg_operand")
19190 "(TARGET_MOVE_M1_VIA_OR || optimize_insn_for_size_p ())
19191 && peep2_regno_dead_p (0, FLAGS_REG)"
19192 [(parallel [(set (match_dup 0) (const_int -1))
19193 (clobber (reg:CC FLAGS_REG))])]
19195 if (<MODE_SIZE> < GET_MODE_SIZE (SImode))
19196 operands[0] = gen_lowpart (SImode, operands[0]);
19199 ;; Attempt to convert simple lea to add/shift.
19200 ;; These can be created by move expanders.
19201 ;; Disable PLUS peepholes on TARGET_OPT_AGU, since all
19202 ;; relevant lea instructions were already split.
19205 [(set (match_operand:SWI48 0 "register_operand")
19206 (plus:SWI48 (match_dup 0)
19207 (match_operand:SWI48 1 "<nonmemory_operand>")))]
19209 && peep2_regno_dead_p (0, FLAGS_REG)"
19210 [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1)))
19211 (clobber (reg:CC FLAGS_REG))])])
19214 [(set (match_operand:SWI48 0 "register_operand")
19215 (plus:SWI48 (match_operand:SWI48 1 "<nonmemory_operand>")
19218 && peep2_regno_dead_p (0, FLAGS_REG)"
19219 [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1)))
19220 (clobber (reg:CC FLAGS_REG))])])
19223 [(set (match_operand:DI 0 "register_operand")
19225 (plus:SI (match_operand:SI 1 "register_operand")
19226 (match_operand:SI 2 "nonmemory_operand"))))]
19227 "TARGET_64BIT && !TARGET_OPT_AGU
19228 && REGNO (operands[0]) == REGNO (operands[1])
19229 && peep2_regno_dead_p (0, FLAGS_REG)"
19230 [(parallel [(set (match_dup 0)
19231 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))
19232 (clobber (reg:CC FLAGS_REG))])])
19235 [(set (match_operand:DI 0 "register_operand")
19237 (plus:SI (match_operand:SI 1 "nonmemory_operand")
19238 (match_operand:SI 2 "register_operand"))))]
19239 "TARGET_64BIT && !TARGET_OPT_AGU
19240 && REGNO (operands[0]) == REGNO (operands[2])
19241 && peep2_regno_dead_p (0, FLAGS_REG)"
19242 [(parallel [(set (match_dup 0)
19243 (zero_extend:DI (plus:SI (match_dup 2) (match_dup 1))))
19244 (clobber (reg:CC FLAGS_REG))])])
19247 [(set (match_operand:SWI48 0 "register_operand")
19248 (mult:SWI48 (match_dup 0)
19249 (match_operand:SWI48 1 "const_int_operand")))]
19250 "pow2p_hwi (INTVAL (operands[1]))
19251 && peep2_regno_dead_p (0, FLAGS_REG)"
19252 [(parallel [(set (match_dup 0) (ashift:SWI48 (match_dup 0) (match_dup 1)))
19253 (clobber (reg:CC FLAGS_REG))])]
19254 "operands[1] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
19257 [(set (match_operand:DI 0 "register_operand")
19259 (mult:SI (match_operand:SI 1 "register_operand")
19260 (match_operand:SI 2 "const_int_operand"))))]
19262 && pow2p_hwi (INTVAL (operands[2]))
19263 && REGNO (operands[0]) == REGNO (operands[1])
19264 && peep2_regno_dead_p (0, FLAGS_REG)"
19265 [(parallel [(set (match_dup 0)
19266 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))
19267 (clobber (reg:CC FLAGS_REG))])]
19268 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
19270 ;; The ESP adjustments can be done by the push and pop instructions. Resulting
19271 ;; code is shorter, since push is only 1 byte, while add imm, %esp is 3 bytes.
19272 ;; On many CPUs it is also faster, since special hardware to avoid esp
19273 ;; dependencies is present.
19275 ;; While some of these conversions may be done using splitters, we use
19276 ;; peepholes in order to allow combine_stack_adjustments pass to see
19277 ;; nonobfuscated RTL.
19279 ;; Convert prologue esp subtractions to push.
19280 ;; We need register to push. In order to keep verify_flow_info happy we have
19282 ;; - use scratch and clobber it in order to avoid dependencies
19283 ;; - use already live register
19284 ;; We can't use the second way right now, since there is no reliable way how to
19285 ;; verify that given register is live. First choice will also most likely in
19286 ;; fewer dependencies. On the place of esp adjustments it is very likely that
19287 ;; call clobbered registers are dead. We may want to use base pointer as an
19288 ;; alternative when no register is available later.
19291 [(match_scratch:W 1 "r")
19292 (parallel [(set (reg:P SP_REG)
19293 (plus:P (reg:P SP_REG)
19294 (match_operand:P 0 "const_int_operand")))
19295 (clobber (reg:CC FLAGS_REG))
19296 (clobber (mem:BLK (scratch)))])]
19297 "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
19298 && INTVAL (operands[0]) == -GET_MODE_SIZE (word_mode)
19299 && ix86_red_zone_size == 0"
19300 [(clobber (match_dup 1))
19301 (parallel [(set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
19302 (clobber (mem:BLK (scratch)))])])
19305 [(match_scratch:W 1 "r")
19306 (parallel [(set (reg:P SP_REG)
19307 (plus:P (reg:P SP_REG)
19308 (match_operand:P 0 "const_int_operand")))
19309 (clobber (reg:CC FLAGS_REG))
19310 (clobber (mem:BLK (scratch)))])]
19311 "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
19312 && INTVAL (operands[0]) == -2*GET_MODE_SIZE (word_mode)
19313 && ix86_red_zone_size == 0"
19314 [(clobber (match_dup 1))
19315 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
19316 (parallel [(set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
19317 (clobber (mem:BLK (scratch)))])])
19319 ;; Convert esp subtractions to push.
19321 [(match_scratch:W 1 "r")
19322 (parallel [(set (reg:P SP_REG)
19323 (plus:P (reg:P SP_REG)
19324 (match_operand:P 0 "const_int_operand")))
19325 (clobber (reg:CC FLAGS_REG))])]
19326 "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
19327 && INTVAL (operands[0]) == -GET_MODE_SIZE (word_mode)
19328 && ix86_red_zone_size == 0"
19329 [(clobber (match_dup 1))
19330 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
19333 [(match_scratch:W 1 "r")
19334 (parallel [(set (reg:P SP_REG)
19335 (plus:P (reg:P SP_REG)
19336 (match_operand:P 0 "const_int_operand")))
19337 (clobber (reg:CC FLAGS_REG))])]
19338 "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
19339 && INTVAL (operands[0]) == -2*GET_MODE_SIZE (word_mode)
19340 && ix86_red_zone_size == 0"
19341 [(clobber (match_dup 1))
19342 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
19343 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
19345 ;; Convert epilogue deallocator to pop.
19347 [(match_scratch:W 1 "r")
19348 (parallel [(set (reg:P SP_REG)
19349 (plus:P (reg:P SP_REG)
19350 (match_operand:P 0 "const_int_operand")))
19351 (clobber (reg:CC FLAGS_REG))
19352 (clobber (mem:BLK (scratch)))])]
19353 "(TARGET_SINGLE_POP || optimize_insn_for_size_p ())
19354 && INTVAL (operands[0]) == GET_MODE_SIZE (word_mode)"
19355 [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
19356 (clobber (mem:BLK (scratch)))])])
19358 ;; Two pops case is tricky, since pop causes dependency
19359 ;; on destination register. We use two registers if available.
19361 [(match_scratch:W 1 "r")
19362 (match_scratch:W 2 "r")
19363 (parallel [(set (reg:P SP_REG)
19364 (plus:P (reg:P SP_REG)
19365 (match_operand:P 0 "const_int_operand")))
19366 (clobber (reg:CC FLAGS_REG))
19367 (clobber (mem:BLK (scratch)))])]
19368 "(TARGET_DOUBLE_POP || optimize_insn_for_size_p ())
19369 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
19370 [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
19371 (clobber (mem:BLK (scratch)))])
19372 (set (match_dup 2) (mem:W (post_inc:P (reg:P SP_REG))))])
19375 [(match_scratch:W 1 "r")
19376 (parallel [(set (reg:P SP_REG)
19377 (plus:P (reg:P SP_REG)
19378 (match_operand:P 0 "const_int_operand")))
19379 (clobber (reg:CC FLAGS_REG))
19380 (clobber (mem:BLK (scratch)))])]
19381 "optimize_insn_for_size_p ()
19382 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
19383 [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
19384 (clobber (mem:BLK (scratch)))])
19385 (set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
19387 ;; Convert esp additions to pop.
19389 [(match_scratch:W 1 "r")
19390 (parallel [(set (reg:P SP_REG)
19391 (plus:P (reg:P SP_REG)
19392 (match_operand:P 0 "const_int_operand")))
19393 (clobber (reg:CC FLAGS_REG))])]
19394 "INTVAL (operands[0]) == GET_MODE_SIZE (word_mode)"
19395 [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
19397 ;; Two pops case is tricky, since pop causes dependency
19398 ;; on destination register. We use two registers if available.
19400 [(match_scratch:W 1 "r")
19401 (match_scratch:W 2 "r")
19402 (parallel [(set (reg:P SP_REG)
19403 (plus:P (reg:P SP_REG)
19404 (match_operand:P 0 "const_int_operand")))
19405 (clobber (reg:CC FLAGS_REG))])]
19406 "INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
19407 [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
19408 (set (match_dup 2) (mem:W (post_inc:P (reg:P SP_REG))))])
19411 [(match_scratch:W 1 "r")
19412 (parallel [(set (reg:P SP_REG)
19413 (plus:P (reg:P SP_REG)
19414 (match_operand:P 0 "const_int_operand")))
19415 (clobber (reg:CC FLAGS_REG))])]
19416 "optimize_insn_for_size_p ()
19417 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
19418 [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
19419 (set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
19421 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
19422 ;; required and register dies. Similarly for 128 to -128.
19424 [(set (match_operand 0 "flags_reg_operand")
19425 (match_operator 1 "compare_operator"
19426 [(match_operand 2 "register_operand")
19427 (match_operand 3 "const_int_operand")]))]
19428 "(((!TARGET_FUSE_CMP_AND_BRANCH || optimize_insn_for_size_p ())
19429 && incdec_operand (operands[3], GET_MODE (operands[3])))
19430 || (!TARGET_FUSE_CMP_AND_BRANCH
19431 && INTVAL (operands[3]) == 128))
19432 && ix86_match_ccmode (insn, CCGCmode)
19433 && peep2_reg_dead_p (1, operands[2])"
19434 [(parallel [(set (match_dup 0)
19435 (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
19436 (clobber (match_dup 2))])])
19438 ;; Convert imul by three, five and nine into lea
19441 [(set (match_operand:SWI48 0 "register_operand")
19442 (mult:SWI48 (match_operand:SWI48 1 "register_operand")
19443 (match_operand:SWI48 2 "const359_operand")))
19444 (clobber (reg:CC FLAGS_REG))])]
19445 "!TARGET_PARTIAL_REG_STALL
19446 || <MODE>mode == SImode
19447 || optimize_function_for_size_p (cfun)"
19448 [(set (match_dup 0)
19449 (plus:SWI48 (mult:SWI48 (match_dup 1) (match_dup 2))
19451 "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
19455 [(set (match_operand:SWI48 0 "register_operand")
19456 (mult:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
19457 (match_operand:SWI48 2 "const359_operand")))
19458 (clobber (reg:CC FLAGS_REG))])]
19459 "optimize_insn_for_speed_p ()
19460 && (!TARGET_PARTIAL_REG_STALL || <MODE>mode == SImode)"
19461 [(set (match_dup 0) (match_dup 1))
19463 (plus:SWI48 (mult:SWI48 (match_dup 0) (match_dup 2))
19465 "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
19467 ;; imul $32bit_imm, mem, reg is vector decoded, while
19468 ;; imul $32bit_imm, reg, reg is direct decoded.
19470 [(match_scratch:SWI48 3 "r")
19471 (parallel [(set (match_operand:SWI48 0 "register_operand")
19472 (mult:SWI48 (match_operand:SWI48 1 "memory_operand")
19473 (match_operand:SWI48 2 "immediate_operand")))
19474 (clobber (reg:CC FLAGS_REG))])]
19475 "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
19476 && !satisfies_constraint_K (operands[2])"
19477 [(set (match_dup 3) (match_dup 1))
19478 (parallel [(set (match_dup 0) (mult:SWI48 (match_dup 3) (match_dup 2)))
19479 (clobber (reg:CC FLAGS_REG))])])
19482 [(match_scratch:SI 3 "r")
19483 (parallel [(set (match_operand:DI 0 "register_operand")
19485 (mult:SI (match_operand:SI 1 "memory_operand")
19486 (match_operand:SI 2 "immediate_operand"))))
19487 (clobber (reg:CC FLAGS_REG))])]
19489 && TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
19490 && !satisfies_constraint_K (operands[2])"
19491 [(set (match_dup 3) (match_dup 1))
19492 (parallel [(set (match_dup 0)
19493 (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
19494 (clobber (reg:CC FLAGS_REG))])])
19496 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
19497 ;; Convert it into imul reg, reg
19498 ;; It would be better to force assembler to encode instruction using long
19499 ;; immediate, but there is apparently no way to do so.
19501 [(parallel [(set (match_operand:SWI248 0 "register_operand")
19503 (match_operand:SWI248 1 "nonimmediate_operand")
19504 (match_operand:SWI248 2 "const_int_operand")))
19505 (clobber (reg:CC FLAGS_REG))])
19506 (match_scratch:SWI248 3 "r")]
19507 "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
19508 && satisfies_constraint_K (operands[2])"
19509 [(set (match_dup 3) (match_dup 2))
19510 (parallel [(set (match_dup 0) (mult:SWI248 (match_dup 0) (match_dup 3)))
19511 (clobber (reg:CC FLAGS_REG))])]
19513 if (!rtx_equal_p (operands[0], operands[1]))
19514 emit_move_insn (operands[0], operands[1]);
19517 ;; After splitting up read-modify operations, array accesses with memory
19518 ;; operands might end up in form:
19520 ;; movl 4(%esp), %edx
19522 ;; instead of pre-splitting:
19524 ;; addl 4(%esp), %eax
19526 ;; movl 4(%esp), %edx
19527 ;; leal (%edx,%eax,4), %eax
19530 [(match_scratch:W 5 "r")
19531 (parallel [(set (match_operand 0 "register_operand")
19532 (ashift (match_operand 1 "register_operand")
19533 (match_operand 2 "const_int_operand")))
19534 (clobber (reg:CC FLAGS_REG))])
19535 (parallel [(set (match_operand 3 "register_operand")
19536 (plus (match_dup 0)
19537 (match_operand 4 "x86_64_general_operand")))
19538 (clobber (reg:CC FLAGS_REG))])]
19539 "IN_RANGE (INTVAL (operands[2]), 1, 3)
19540 /* Validate MODE for lea. */
19541 && ((!TARGET_PARTIAL_REG_STALL
19542 && (GET_MODE (operands[0]) == QImode
19543 || GET_MODE (operands[0]) == HImode))
19544 || GET_MODE (operands[0]) == SImode
19545 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
19546 && (rtx_equal_p (operands[0], operands[3])
19547 || peep2_reg_dead_p (2, operands[0]))
19548 /* We reorder load and the shift. */
19549 && !reg_overlap_mentioned_p (operands[0], operands[4])"
19550 [(set (match_dup 5) (match_dup 4))
19551 (set (match_dup 0) (match_dup 1))]
19553 machine_mode op1mode = GET_MODE (operands[1]);
19554 machine_mode mode = op1mode == DImode ? DImode : SImode;
19555 int scale = 1 << INTVAL (operands[2]);
19556 rtx index = gen_lowpart (word_mode, operands[1]);
19557 rtx base = gen_lowpart (word_mode, operands[5]);
19558 rtx dest = gen_lowpart (mode, operands[3]);
19560 operands[1] = gen_rtx_PLUS (word_mode, base,
19561 gen_rtx_MULT (word_mode, index, GEN_INT (scale)));
19562 if (mode != word_mode)
19563 operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
19565 operands[5] = base;
19566 if (op1mode != word_mode)
19567 operands[5] = gen_lowpart (op1mode, operands[5]);
19569 operands[0] = dest;
19572 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
19573 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
19574 ;; caught for use by garbage collectors and the like. Using an insn that
19575 ;; maps to SIGILL makes it more likely the program will rightfully die.
19576 ;; Keeping with tradition, "6" is in honor of #UD.
19577 (define_insn "trap"
19578 [(trap_if (const_int 1) (const_int 6))]
19581 #ifdef HAVE_AS_IX86_UD2
19584 return ASM_SHORT "0x0b0f";
19587 [(set_attr "length" "2")])
19590 [(unspec_volatile [(const_int 0)] UNSPECV_UD2)]
19593 #ifdef HAVE_AS_IX86_UD2
19596 return ASM_SHORT "0x0b0f";
19599 [(set_attr "length" "2")])
19601 (define_expand "prefetch"
19602 [(prefetch (match_operand 0 "address_operand")
19603 (match_operand:SI 1 "const_int_operand")
19604 (match_operand:SI 2 "const_int_operand"))]
19605 "TARGET_3DNOW || TARGET_PREFETCH_SSE || TARGET_PRFCHW || TARGET_PREFETCHWT1"
19607 bool write = INTVAL (operands[1]) != 0;
19608 int locality = INTVAL (operands[2]);
19610 gcc_assert (IN_RANGE (locality, 0, 3));
19612 /* Use 3dNOW prefetch in case we are asking for write prefetch not
19613 supported by SSE counterpart (non-SSE2 athlon machines) or the
19614 SSE prefetch is not available (K6 machines). Otherwise use SSE
19615 prefetch as it allows specifying of locality. */
19619 if (TARGET_PREFETCHWT1)
19620 operands[2] = GEN_INT (MAX (locality, 2));
19621 else if (TARGET_PRFCHW)
19622 operands[2] = GEN_INT (3);
19623 else if (TARGET_3DNOW && !TARGET_SSE2)
19624 operands[2] = GEN_INT (3);
19625 else if (TARGET_PREFETCH_SSE)
19626 operands[1] = const0_rtx;
19629 gcc_assert (TARGET_3DNOW);
19630 operands[2] = GEN_INT (3);
19635 if (TARGET_PREFETCH_SSE)
19639 gcc_assert (TARGET_3DNOW);
19640 operands[2] = GEN_INT (3);
19645 (define_insn "*prefetch_sse"
19646 [(prefetch (match_operand 0 "address_operand" "p")
19648 (match_operand:SI 1 "const_int_operand"))]
19649 "TARGET_PREFETCH_SSE"
19651 static const char * const patterns[4] = {
19652 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
19655 int locality = INTVAL (operands[1]);
19656 gcc_assert (IN_RANGE (locality, 0, 3));
19658 return patterns[locality];
19660 [(set_attr "type" "sse")
19661 (set_attr "atom_sse_attr" "prefetch")
19662 (set (attr "length_address")
19663 (symbol_ref "memory_address_length (operands[0], false)"))
19664 (set_attr "memory" "none")])
19666 (define_insn "*prefetch_3dnow"
19667 [(prefetch (match_operand 0 "address_operand" "p")
19668 (match_operand:SI 1 "const_int_operand" "n")
19670 "TARGET_3DNOW || TARGET_PRFCHW || TARGET_PREFETCHWT1"
19672 if (INTVAL (operands[1]) == 0)
19673 return "prefetch\t%a0";
19675 return "prefetchw\t%a0";
19677 [(set_attr "type" "mmx")
19678 (set (attr "length_address")
19679 (symbol_ref "memory_address_length (operands[0], false)"))
19680 (set_attr "memory" "none")])
19682 (define_insn "*prefetch_prefetchwt1"
19683 [(prefetch (match_operand 0 "address_operand" "p")
19686 "TARGET_PREFETCHWT1"
19687 "prefetchwt1\t%a0";
19688 [(set_attr "type" "sse")
19689 (set (attr "length_address")
19690 (symbol_ref "memory_address_length (operands[0], false)"))
19691 (set_attr "memory" "none")])
19693 (define_expand "stack_protect_set"
19694 [(match_operand 0 "memory_operand")
19695 (match_operand 1 "memory_operand")]
19696 "TARGET_SSP_TLS_GUARD"
19698 rtx (*insn)(rtx, rtx);
19700 insn = (TARGET_LP64
19701 ? gen_stack_protect_set_di
19702 : gen_stack_protect_set_si);
19704 emit_insn (insn (operands[0], operands[1]));
19708 (define_insn "stack_protect_set_<mode>"
19709 [(set (match_operand:PTR 0 "memory_operand" "=m")
19710 (unspec:PTR [(match_operand:PTR 1 "memory_operand" "m")]
19712 (set (match_scratch:PTR 2 "=&r") (const_int 0))
19713 (clobber (reg:CC FLAGS_REG))]
19714 "TARGET_SSP_TLS_GUARD"
19715 "mov{<imodesuffix>}\t{%1, %2|%2, %1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
19716 [(set_attr "type" "multi")])
19718 (define_expand "stack_protect_test"
19719 [(match_operand 0 "memory_operand")
19720 (match_operand 1 "memory_operand")
19722 "TARGET_SSP_TLS_GUARD"
19724 rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
19726 rtx (*insn)(rtx, rtx, rtx);
19728 insn = (TARGET_LP64
19729 ? gen_stack_protect_test_di
19730 : gen_stack_protect_test_si);
19732 emit_insn (insn (flags, operands[0], operands[1]));
19734 emit_jump_insn (gen_cbranchcc4 (gen_rtx_EQ (VOIDmode, flags, const0_rtx),
19735 flags, const0_rtx, operands[2]));
19739 (define_insn "stack_protect_test_<mode>"
19740 [(set (match_operand:CCZ 0 "flags_reg_operand")
19741 (unspec:CCZ [(match_operand:PTR 1 "memory_operand" "m")
19742 (match_operand:PTR 2 "memory_operand" "m")]
19744 (clobber (match_scratch:PTR 3 "=&r"))]
19745 "TARGET_SSP_TLS_GUARD"
19746 "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%2, %3|%3, %2}"
19747 [(set_attr "type" "multi")])
19749 (define_insn "sse4_2_crc32<mode>"
19750 [(set (match_operand:SI 0 "register_operand" "=r")
19752 [(match_operand:SI 1 "register_operand" "0")
19753 (match_operand:SWI124 2 "nonimmediate_operand" "<r>m")]
19755 "TARGET_SSE4_2 || TARGET_CRC32"
19756 "crc32{<imodesuffix>}\t{%2, %0|%0, %2}"
19757 [(set_attr "type" "sselog1")
19758 (set_attr "prefix_rep" "1")
19759 (set_attr "prefix_extra" "1")
19760 (set (attr "prefix_data16")
19761 (if_then_else (match_operand:HI 2)
19763 (const_string "*")))
19764 (set (attr "prefix_rex")
19765 (if_then_else (match_operand:QI 2 "ext_QIreg_operand")
19767 (const_string "*")))
19768 (set_attr "mode" "SI")])
19770 (define_insn "sse4_2_crc32di"
19771 [(set (match_operand:DI 0 "register_operand" "=r")
19773 [(match_operand:DI 1 "register_operand" "0")
19774 (match_operand:DI 2 "nonimmediate_operand" "rm")]
19776 "TARGET_64BIT && (TARGET_SSE4_2 || TARGET_CRC32)"
19777 "crc32{q}\t{%2, %0|%0, %2}"
19778 [(set_attr "type" "sselog1")
19779 (set_attr "prefix_rep" "1")
19780 (set_attr "prefix_extra" "1")
19781 (set_attr "mode" "DI")])
19783 (define_insn "rdpmc"
19784 [(set (match_operand:DI 0 "register_operand" "=A")
19785 (unspec_volatile:DI [(match_operand:SI 1 "register_operand" "c")]
19789 [(set_attr "type" "other")
19790 (set_attr "length" "2")])
19792 (define_insn "rdpmc_rex64"
19793 [(set (match_operand:DI 0 "register_operand" "=a")
19794 (unspec_volatile:DI [(match_operand:SI 2 "register_operand" "c")]
19796 (set (match_operand:DI 1 "register_operand" "=d")
19797 (unspec_volatile:DI [(match_dup 2)] UNSPECV_RDPMC))]
19800 [(set_attr "type" "other")
19801 (set_attr "length" "2")])
19803 (define_insn "rdtsc"
19804 [(set (match_operand:DI 0 "register_operand" "=A")
19805 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
19808 [(set_attr "type" "other")
19809 (set_attr "length" "2")])
19811 (define_insn "rdtsc_rex64"
19812 [(set (match_operand:DI 0 "register_operand" "=a")
19813 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))
19814 (set (match_operand:DI 1 "register_operand" "=d")
19815 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
19818 [(set_attr "type" "other")
19819 (set_attr "length" "2")])
19821 (define_insn "rdtscp"
19822 [(set (match_operand:DI 0 "register_operand" "=A")
19823 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
19824 (set (match_operand:SI 1 "register_operand" "=c")
19825 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
19828 [(set_attr "type" "other")
19829 (set_attr "length" "3")])
19831 (define_insn "rdtscp_rex64"
19832 [(set (match_operand:DI 0 "register_operand" "=a")
19833 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
19834 (set (match_operand:DI 1 "register_operand" "=d")
19835 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
19836 (set (match_operand:SI 2 "register_operand" "=c")
19837 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
19840 [(set_attr "type" "other")
19841 (set_attr "length" "3")])
19843 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
19845 ;; FXSR, XSAVE and XSAVEOPT instructions
19847 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
19849 (define_insn "fxsave"
19850 [(set (match_operand:BLK 0 "memory_operand" "=m")
19851 (unspec_volatile:BLK [(const_int 0)] UNSPECV_FXSAVE))]
19854 [(set_attr "type" "other")
19855 (set_attr "memory" "store")
19856 (set (attr "length")
19857 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
19859 (define_insn "fxsave64"
19860 [(set (match_operand:BLK 0 "memory_operand" "=m")
19861 (unspec_volatile:BLK [(const_int 0)] UNSPECV_FXSAVE64))]
19862 "TARGET_64BIT && TARGET_FXSR"
19864 [(set_attr "type" "other")
19865 (set_attr "memory" "store")
19866 (set (attr "length")
19867 (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
19869 (define_insn "fxrstor"
19870 [(unspec_volatile [(match_operand:BLK 0 "memory_operand" "m")]
19874 [(set_attr "type" "other")
19875 (set_attr "memory" "load")
19876 (set (attr "length")
19877 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
19879 (define_insn "fxrstor64"
19880 [(unspec_volatile [(match_operand:BLK 0 "memory_operand" "m")]
19881 UNSPECV_FXRSTOR64)]
19882 "TARGET_64BIT && TARGET_FXSR"
19884 [(set_attr "type" "other")
19885 (set_attr "memory" "load")
19886 (set (attr "length")
19887 (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
19889 (define_int_iterator ANY_XSAVE
19891 (UNSPECV_XSAVEOPT "TARGET_XSAVEOPT")
19892 (UNSPECV_XSAVEC "TARGET_XSAVEC")
19893 (UNSPECV_XSAVES "TARGET_XSAVES")])
19895 (define_int_iterator ANY_XSAVE64
19897 (UNSPECV_XSAVEOPT64 "TARGET_XSAVEOPT")
19898 (UNSPECV_XSAVEC64 "TARGET_XSAVEC")
19899 (UNSPECV_XSAVES64 "TARGET_XSAVES")])
19901 (define_int_attr xsave
19902 [(UNSPECV_XSAVE "xsave")
19903 (UNSPECV_XSAVE64 "xsave64")
19904 (UNSPECV_XSAVEOPT "xsaveopt")
19905 (UNSPECV_XSAVEOPT64 "xsaveopt64")
19906 (UNSPECV_XSAVEC "xsavec")
19907 (UNSPECV_XSAVEC64 "xsavec64")
19908 (UNSPECV_XSAVES "xsaves")
19909 (UNSPECV_XSAVES64 "xsaves64")])
19911 (define_int_iterator ANY_XRSTOR
19913 (UNSPECV_XRSTORS "TARGET_XSAVES")])
19915 (define_int_iterator ANY_XRSTOR64
19917 (UNSPECV_XRSTORS64 "TARGET_XSAVES")])
19919 (define_int_attr xrstor
19920 [(UNSPECV_XRSTOR "xrstor")
19921 (UNSPECV_XRSTOR64 "xrstor")
19922 (UNSPECV_XRSTORS "xrstors")
19923 (UNSPECV_XRSTORS64 "xrstors")])
19925 (define_insn "<xsave>"
19926 [(set (match_operand:BLK 0 "memory_operand" "=m")
19927 (unspec_volatile:BLK
19928 [(match_operand:DI 1 "register_operand" "A")]
19930 "!TARGET_64BIT && TARGET_XSAVE"
19932 [(set_attr "type" "other")
19933 (set_attr "memory" "store")
19934 (set (attr "length")
19935 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
19937 (define_insn "<xsave>_rex64"
19938 [(set (match_operand:BLK 0 "memory_operand" "=m")
19939 (unspec_volatile:BLK
19940 [(match_operand:SI 1 "register_operand" "a")
19941 (match_operand:SI 2 "register_operand" "d")]
19943 "TARGET_64BIT && TARGET_XSAVE"
19945 [(set_attr "type" "other")
19946 (set_attr "memory" "store")
19947 (set (attr "length")
19948 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
19950 (define_insn "<xsave>"
19951 [(set (match_operand:BLK 0 "memory_operand" "=m")
19952 (unspec_volatile:BLK
19953 [(match_operand:SI 1 "register_operand" "a")
19954 (match_operand:SI 2 "register_operand" "d")]
19956 "TARGET_64BIT && TARGET_XSAVE"
19958 [(set_attr "type" "other")
19959 (set_attr "memory" "store")
19960 (set (attr "length")
19961 (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
19963 (define_insn "<xrstor>"
19964 [(unspec_volatile:BLK
19965 [(match_operand:BLK 0 "memory_operand" "m")
19966 (match_operand:DI 1 "register_operand" "A")]
19968 "!TARGET_64BIT && TARGET_XSAVE"
19970 [(set_attr "type" "other")
19971 (set_attr "memory" "load")
19972 (set (attr "length")
19973 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
19975 (define_insn "<xrstor>_rex64"
19976 [(unspec_volatile:BLK
19977 [(match_operand:BLK 0 "memory_operand" "m")
19978 (match_operand:SI 1 "register_operand" "a")
19979 (match_operand:SI 2 "register_operand" "d")]
19981 "TARGET_64BIT && TARGET_XSAVE"
19983 [(set_attr "type" "other")
19984 (set_attr "memory" "load")
19985 (set (attr "length")
19986 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
19988 (define_insn "<xrstor>64"
19989 [(unspec_volatile:BLK
19990 [(match_operand:BLK 0 "memory_operand" "m")
19991 (match_operand:SI 1 "register_operand" "a")
19992 (match_operand:SI 2 "register_operand" "d")]
19994 "TARGET_64BIT && TARGET_XSAVE"
19996 [(set_attr "type" "other")
19997 (set_attr "memory" "load")
19998 (set (attr "length")
19999 (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
20001 (define_insn "xsetbv"
20002 [(unspec_volatile:SI
20003 [(match_operand:SI 0 "register_operand" "c")
20004 (match_operand:DI 1 "register_operand" "A")]
20006 "!TARGET_64BIT && TARGET_XSAVE"
20008 [(set_attr "type" "other")])
20010 (define_insn "xsetbv_rex64"
20011 [(unspec_volatile:SI
20012 [(match_operand:SI 0 "register_operand" "c")
20013 (match_operand:SI 1 "register_operand" "a")
20014 (match_operand:SI 2 "register_operand" "d")]
20016 "TARGET_64BIT && TARGET_XSAVE"
20018 [(set_attr "type" "other")])
20020 (define_insn "xgetbv"
20021 [(set (match_operand:DI 0 "register_operand" "=A")
20022 (unspec_volatile:DI [(match_operand:SI 1 "register_operand" "c")]
20024 "!TARGET_64BIT && TARGET_XSAVE"
20026 [(set_attr "type" "other")])
20028 (define_insn "xgetbv_rex64"
20029 [(set (match_operand:DI 0 "register_operand" "=a")
20030 (unspec_volatile:DI [(match_operand:SI 2 "register_operand" "c")]
20032 (set (match_operand:DI 1 "register_operand" "=d")
20033 (unspec_volatile:DI [(match_dup 2)] UNSPECV_XGETBV))]
20034 "TARGET_64BIT && TARGET_XSAVE"
20036 [(set_attr "type" "other")])
20038 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
20040 ;; Floating-point instructions for atomic compound assignments
20042 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
20044 ; Clobber all floating-point registers on environment save and restore
20045 ; to ensure that the TOS value saved at fnstenv is valid after fldenv.
20046 (define_insn "fnstenv"
20047 [(set (match_operand:BLK 0 "memory_operand" "=m")
20048 (unspec_volatile:BLK [(const_int 0)] UNSPECV_FNSTENV))
20049 (clobber (reg:HI FPCR_REG))
20050 (clobber (reg:XF ST0_REG))
20051 (clobber (reg:XF ST1_REG))
20052 (clobber (reg:XF ST2_REG))
20053 (clobber (reg:XF ST3_REG))
20054 (clobber (reg:XF ST4_REG))
20055 (clobber (reg:XF ST5_REG))
20056 (clobber (reg:XF ST6_REG))
20057 (clobber (reg:XF ST7_REG))]
20060 [(set_attr "type" "other")
20061 (set_attr "memory" "store")
20062 (set (attr "length")
20063 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))])
20065 (define_insn "fldenv"
20066 [(unspec_volatile [(match_operand:BLK 0 "memory_operand" "m")]
20068 (clobber (reg:CCFP FPSR_REG))
20069 (clobber (reg:HI FPCR_REG))
20070 (clobber (reg:XF ST0_REG))
20071 (clobber (reg:XF ST1_REG))
20072 (clobber (reg:XF ST2_REG))
20073 (clobber (reg:XF ST3_REG))
20074 (clobber (reg:XF ST4_REG))
20075 (clobber (reg:XF ST5_REG))
20076 (clobber (reg:XF ST6_REG))
20077 (clobber (reg:XF ST7_REG))]
20080 [(set_attr "type" "other")
20081 (set_attr "memory" "load")
20082 (set (attr "length")
20083 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))])
20085 (define_insn "fnstsw"
20086 [(set (match_operand:HI 0 "nonimmediate_operand" "=a,m")
20087 (unspec_volatile:HI [(const_int 0)] UNSPECV_FNSTSW))]
20090 [(set_attr "type" "other,other")
20091 (set_attr "memory" "none,store")
20092 (set (attr "length")
20093 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))])
20095 (define_insn "fnclex"
20096 [(unspec_volatile [(const_int 0)] UNSPECV_FNCLEX)]
20099 [(set_attr "type" "other")
20100 (set_attr "memory" "none")
20101 (set_attr "length" "2")])
20103 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
20105 ;; LWP instructions
20107 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
20109 (define_expand "lwp_llwpcb"
20110 [(unspec_volatile [(match_operand 0 "register_operand")]
20111 UNSPECV_LLWP_INTRINSIC)]
20114 (define_insn "*lwp_llwpcb<mode>1"
20115 [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
20116 UNSPECV_LLWP_INTRINSIC)]
20119 [(set_attr "type" "lwp")
20120 (set_attr "mode" "<MODE>")
20121 (set_attr "length" "5")])
20123 (define_expand "lwp_slwpcb"
20124 [(set (match_operand 0 "register_operand")
20125 (unspec_volatile [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
20130 insn = (Pmode == DImode
20132 : gen_lwp_slwpcbsi);
20134 emit_insn (insn (operands[0]));
20138 (define_insn "lwp_slwpcb<mode>"
20139 [(set (match_operand:P 0 "register_operand" "=r")
20140 (unspec_volatile:P [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
20143 [(set_attr "type" "lwp")
20144 (set_attr "mode" "<MODE>")
20145 (set_attr "length" "5")])
20147 (define_expand "lwp_lwpval<mode>3"
20148 [(unspec_volatile [(match_operand:SWI48 1 "register_operand")
20149 (match_operand:SI 2 "nonimmediate_operand")
20150 (match_operand:SI 3 "const_int_operand")]
20151 UNSPECV_LWPVAL_INTRINSIC)]
20153 ;; Avoid unused variable warning.
20154 "(void) operands[0];")
20156 (define_insn "*lwp_lwpval<mode>3_1"
20157 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")
20158 (match_operand:SI 1 "nonimmediate_operand" "rm")
20159 (match_operand:SI 2 "const_int_operand" "i")]
20160 UNSPECV_LWPVAL_INTRINSIC)]
20162 "lwpval\t{%2, %1, %0|%0, %1, %2}"
20163 [(set_attr "type" "lwp")
20164 (set_attr "mode" "<MODE>")
20165 (set (attr "length")
20166 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
20168 (define_expand "lwp_lwpins<mode>3"
20169 [(set (reg:CCC FLAGS_REG)
20170 (unspec_volatile:CCC [(match_operand:SWI48 1 "register_operand")
20171 (match_operand:SI 2 "nonimmediate_operand")
20172 (match_operand:SI 3 "const_int_operand")]
20173 UNSPECV_LWPINS_INTRINSIC))
20174 (set (match_operand:QI 0 "nonimmediate_operand")
20175 (eq:QI (reg:CCC FLAGS_REG) (const_int 0)))]
20178 (define_insn "*lwp_lwpins<mode>3_1"
20179 [(set (reg:CCC FLAGS_REG)
20180 (unspec_volatile:CCC [(match_operand:SWI48 0 "register_operand" "r")
20181 (match_operand:SI 1 "nonimmediate_operand" "rm")
20182 (match_operand:SI 2 "const_int_operand" "i")]
20183 UNSPECV_LWPINS_INTRINSIC))]
20185 "lwpins\t{%2, %1, %0|%0, %1, %2}"
20186 [(set_attr "type" "lwp")
20187 (set_attr "mode" "<MODE>")
20188 (set (attr "length")
20189 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
20191 (define_int_iterator RDFSGSBASE
20195 (define_int_iterator WRFSGSBASE
20199 (define_int_attr fsgs
20200 [(UNSPECV_RDFSBASE "fs")
20201 (UNSPECV_RDGSBASE "gs")
20202 (UNSPECV_WRFSBASE "fs")
20203 (UNSPECV_WRGSBASE "gs")])
20205 (define_insn "rd<fsgs>base<mode>"
20206 [(set (match_operand:SWI48 0 "register_operand" "=r")
20207 (unspec_volatile:SWI48 [(const_int 0)] RDFSGSBASE))]
20208 "TARGET_64BIT && TARGET_FSGSBASE"
20210 [(set_attr "type" "other")
20211 (set_attr "prefix_extra" "2")])
20213 (define_insn "wr<fsgs>base<mode>"
20214 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
20216 "TARGET_64BIT && TARGET_FSGSBASE"
20218 [(set_attr "type" "other")
20219 (set_attr "prefix_extra" "2")])
20221 (define_insn "rdrand<mode>_1"
20222 [(set (match_operand:SWI248 0 "register_operand" "=r")
20223 (unspec_volatile:SWI248 [(const_int 0)] UNSPECV_RDRAND))
20224 (set (reg:CCC FLAGS_REG)
20225 (unspec_volatile:CCC [(const_int 0)] UNSPECV_RDRAND))]
20228 [(set_attr "type" "other")
20229 (set_attr "prefix_extra" "1")])
20231 (define_insn "rdseed<mode>_1"
20232 [(set (match_operand:SWI248 0 "register_operand" "=r")
20233 (unspec_volatile:SWI248 [(const_int 0)] UNSPECV_RDSEED))
20234 (set (reg:CCC FLAGS_REG)
20235 (unspec_volatile:CCC [(const_int 0)] UNSPECV_RDSEED))]
20238 [(set_attr "type" "other")
20239 (set_attr "prefix_extra" "1")])
20241 (define_expand "pause"
20242 [(set (match_dup 0)
20243 (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
20246 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
20247 MEM_VOLATILE_P (operands[0]) = 1;
20250 ;; Use "rep; nop", instead of "pause", to support older assemblers.
20251 ;; They have the same encoding.
20252 (define_insn "*pause"
20253 [(set (match_operand:BLK 0)
20254 (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
20257 [(set_attr "length" "2")
20258 (set_attr "memory" "unknown")])
20260 ;; CET instructions
20261 (define_insn "rdssp<mode>"
20262 [(set (match_operand:SWI48x 0 "register_operand" "=r")
20263 (unspec_volatile:SWI48x [(const_int 0)] UNSPECV_NOP_RDSSP))]
20264 "TARGET_SHSTK || (flag_cf_protection & CF_RETURN)"
20265 "xor{l}\t%k0, %k0\n\trdssp<mskmodesuffix>\t%0"
20266 [(set_attr "length" "6")
20267 (set_attr "type" "other")])
20269 (define_insn "incssp<mode>"
20270 [(unspec_volatile [(match_operand:SWI48x 0 "register_operand" "r")]
20272 "TARGET_SHSTK || (flag_cf_protection & CF_RETURN)"
20273 "incssp<mskmodesuffix>\t%0"
20274 [(set_attr "length" "4")
20275 (set_attr "type" "other")])
20277 (define_insn "saveprevssp"
20278 [(unspec_volatile [(const_int 0)] UNSPECV_SAVEPREVSSP)]
20281 [(set_attr "length" "5")
20282 (set_attr "type" "other")])
20284 (define_insn "rstorssp"
20285 [(unspec_volatile [(match_operand 0 "memory_operand" "m")]
20289 [(set_attr "length" "5")
20290 (set_attr "type" "other")])
20292 (define_insn "wrss<mode>"
20293 [(unspec_volatile [(match_operand:SWI48x 0 "register_operand" "r")
20294 (match_operand:SWI48x 1 "memory_operand" "m")]
20297 "wrss<mskmodesuffix>\t%0, %1"
20298 [(set_attr "length" "3")
20299 (set_attr "type" "other")])
20301 (define_insn "wruss<mode>"
20302 [(unspec_volatile [(match_operand:SWI48x 0 "register_operand" "r")
20303 (match_operand:SWI48x 1 "memory_operand" "m")]
20306 "wruss<mskmodesuffix>\t%0, %1"
20307 [(set_attr "length" "4")
20308 (set_attr "type" "other")])
20310 (define_insn "setssbsy"
20311 [(unspec_volatile [(const_int 0)] UNSPECV_SETSSBSY)]
20314 [(set_attr "length" "4")
20315 (set_attr "type" "other")])
20317 (define_insn "clrssbsy"
20318 [(unspec_volatile [(match_operand 0 "memory_operand" "m")]
20322 [(set_attr "length" "4")
20323 (set_attr "type" "other")])
20325 (define_insn "nop_endbr"
20326 [(unspec_volatile [(const_int 0)] UNSPECV_NOP_ENDBR)]
20327 "(flag_cf_protection & CF_BRANCH)"
20329 { return (TARGET_64BIT)? \"endbr64\" : \"endbr32\"; }"
20330 [(set_attr "length" "4")
20331 (set_attr "length_immediate" "0")
20332 (set_attr "modrm" "0")])
20335 (define_expand "xbegin"
20336 [(set (match_operand:SI 0 "register_operand")
20337 (unspec_volatile:SI [(const_int 0)] UNSPECV_XBEGIN))]
20340 rtx_code_label *label = gen_label_rtx ();
20342 /* xbegin is emitted as jump_insn, so reload won't be able
20343 to reload its operand. Force the value into AX hard register. */
20344 rtx ax_reg = gen_rtx_REG (SImode, AX_REG);
20345 emit_move_insn (ax_reg, constm1_rtx);
20347 emit_jump_insn (gen_xbegin_1 (ax_reg, label));
20349 emit_label (label);
20350 LABEL_NUSES (label) = 1;
20352 emit_move_insn (operands[0], ax_reg);
20357 (define_insn "xbegin_1"
20359 (if_then_else (ne (unspec [(const_int 0)] UNSPEC_XBEGIN_ABORT)
20361 (label_ref (match_operand 1))
20363 (set (match_operand:SI 0 "register_operand" "+a")
20364 (unspec_volatile:SI [(match_dup 0)] UNSPECV_XBEGIN))]
20367 [(set_attr "type" "other")
20368 (set_attr "length" "6")])
20370 (define_insn "xend"
20371 [(unspec_volatile [(const_int 0)] UNSPECV_XEND)]
20374 [(set_attr "type" "other")
20375 (set_attr "length" "3")])
20377 (define_insn "xabort"
20378 [(unspec_volatile [(match_operand:SI 0 "const_0_to_255_operand" "n")]
20382 [(set_attr "type" "other")
20383 (set_attr "length" "3")])
20385 (define_expand "xtest"
20386 [(set (match_operand:QI 0 "register_operand")
20387 (unspec_volatile:QI [(const_int 0)] UNSPECV_XTEST))]
20390 emit_insn (gen_xtest_1 ());
20392 ix86_expand_setcc (operands[0], NE,
20393 gen_rtx_REG (CCZmode, FLAGS_REG), const0_rtx);
20397 (define_insn "xtest_1"
20398 [(set (reg:CCZ FLAGS_REG)
20399 (unspec_volatile:CCZ [(const_int 0)] UNSPECV_XTEST))]
20402 [(set_attr "type" "other")
20403 (set_attr "length" "3")])
20405 (define_insn "clwb"
20406 [(unspec_volatile [(match_operand 0 "address_operand" "p")]
20410 [(set_attr "type" "sse")
20411 (set_attr "atom_sse_attr" "fence")
20412 (set_attr "memory" "unknown")])
20414 (define_insn "clflushopt"
20415 [(unspec_volatile [(match_operand 0 "address_operand" "p")]
20416 UNSPECV_CLFLUSHOPT)]
20417 "TARGET_CLFLUSHOPT"
20419 [(set_attr "type" "sse")
20420 (set_attr "atom_sse_attr" "fence")
20421 (set_attr "memory" "unknown")])
20423 ;; MONITORX and MWAITX
20424 (define_insn "mwaitx"
20425 [(unspec_volatile [(match_operand:SI 0 "register_operand" "c")
20426 (match_operand:SI 1 "register_operand" "a")
20427 (match_operand:SI 2 "register_operand" "b")]
20430 ;; 64bit version is "mwaitx %rax,%rcx,%rbx". But only lower 32bits are used.
20431 ;; Since 32bit register operands are implicitly zero extended to 64bit,
20432 ;; we only need to set up 32bit registers.
20434 [(set_attr "length" "3")])
20436 (define_insn "monitorx_<mode>"
20437 [(unspec_volatile [(match_operand:P 0 "register_operand" "a")
20438 (match_operand:SI 1 "register_operand" "c")
20439 (match_operand:SI 2 "register_operand" "d")]
20442 ;; 64bit version is "monitorx %rax,%rcx,%rdx". But only lower 32bits in
20443 ;; RCX and RDX are used. Since 32bit register operands are implicitly
20444 ;; zero extended to 64bit, we only need to set up 32bit registers.
20446 [(set (attr "length")
20447 (symbol_ref ("(Pmode != word_mode) + 3")))])
20450 (define_insn "clzero_<mode>"
20451 [(unspec_volatile [(match_operand: P 0 "register_operand" "a")]
20455 [(set_attr "length" "3")
20456 (set_attr "memory" "unknown")])
20458 ;; MPX instructions
20460 (define_expand "<mode>_mk"
20461 [(set (match_operand:BND 0 "register_operand")
20465 [(match_operand:<bnd_ptr> 1 "register_operand")
20466 (match_operand:<bnd_ptr> 2 "address_mpx_no_base_operand")]))]
20470 operands[3] = gen_rtx_UNSPEC (Pmode, gen_rtvec (2, operands[1],
20472 UNSPEC_BNDMK_ADDR);
20475 (define_insn "*<mode>_mk"
20476 [(set (match_operand:BND 0 "register_operand" "=w")
20478 [(match_operator:<bnd_ptr> 3 "bnd_mem_operator"
20480 [(match_operand:<bnd_ptr> 1 "register_operand" "r")
20481 (match_operand:<bnd_ptr> 2 "address_mpx_no_base_operand" "Tb")]
20482 UNSPEC_BNDMK_ADDR)])]
20485 "bndmk\t{%3, %0|%0, %3}"
20486 [(set_attr "type" "mpxmk")])
20488 (define_expand "mov<mode>"
20489 [(set (match_operand:BND 0 "general_operand")
20490 (match_operand:BND 1 "general_operand"))]
20492 "ix86_expand_move (<MODE>mode, operands); DONE;")
20494 (define_insn "*mov<mode>_internal_mpx"
20495 [(set (match_operand:BND 0 "nonimmediate_operand" "=w,m")
20496 (match_operand:BND 1 "general_operand" "wm,w"))]
20498 "bndmov\t{%1, %0|%0, %1}"
20499 [(set_attr "type" "mpxmov")])
20501 (define_expand "<mode>_<bndcheck>"
20504 [(match_operand:BND 0 "register_operand")
20505 (match_operand:<bnd_ptr> 1 "address_no_seg_operand")] BNDCHECK)
20507 (unspec:BLK [(match_dup 2)] UNSPEC_MPX_FENCE))])]
20510 operands[2] = gen_rtx_MEM (BLKmode, operands[1]);
20511 MEM_VOLATILE_P (operands[2]) = 1;
20514 (define_insn "*<mode>_<bndcheck>"
20516 [(match_operand:BND 0 "register_operand" "w")
20517 (match_operand:<bnd_ptr> 1 "address_no_seg_operand" "Ts")] BNDCHECK)
20518 (set (match_operand:BLK 2 "bnd_mem_operator")
20519 (unspec:BLK [(match_dup 2)] UNSPEC_MPX_FENCE))]
20521 "bnd<bndcheck>\t{%a1, %0|%0, %a1}"
20522 [(set_attr "type" "mpxchk")])
20524 (define_expand "<mode>_ldx"
20526 [(set (match_operand:BND 0 "register_operand")
20530 [(match_operand:<bnd_ptr> 1 "address_mpx_no_index_operand")
20531 (match_operand:<bnd_ptr> 2 "register_operand")]))]
20533 (use (mem:BLK (match_dup 1)))])]
20536 /* Avoid registers which cannot be used as index. */
20537 if (!index_register_operand (operands[2], Pmode))
20538 operands[2] = copy_addr_to_reg (operands[2]);
20540 operands[3] = gen_rtx_UNSPEC (Pmode, gen_rtvec (2, operands[1],
20542 UNSPEC_BNDLDX_ADDR);
20545 (define_insn "*<mode>_ldx"
20546 [(set (match_operand:BND 0 "register_operand" "=w")
20548 [(match_operator:<bnd_ptr> 3 "bnd_mem_operator"
20550 [(match_operand:<bnd_ptr> 1 "address_mpx_no_index_operand" "Ti")
20551 (match_operand:<bnd_ptr> 2 "register_operand" "l")]
20552 UNSPEC_BNDLDX_ADDR)])]
20554 (use (mem:BLK (match_dup 1)))]
20556 "bndldx\t{%3, %0|%0, %3}"
20557 [(set_attr "type" "mpxld")])
20559 (define_expand "<mode>_stx"
20564 [(match_operand:<bnd_ptr> 0 "address_mpx_no_index_operand")
20565 (match_operand:<bnd_ptr> 1 "register_operand")]))
20566 (match_operand:BND 2 "register_operand")]
20569 (unspec:BLK [(match_dup 4)] UNSPEC_MPX_FENCE))])]
20572 /* Avoid registers which cannot be used as index. */
20573 if (!index_register_operand (operands[1], Pmode))
20574 operands[1] = copy_addr_to_reg (operands[1]);
20576 operands[3] = gen_rtx_UNSPEC (Pmode, gen_rtvec (2, operands[0],
20578 UNSPEC_BNDLDX_ADDR);
20579 operands[4] = gen_rtx_MEM (BLKmode, operands[0]);
20580 MEM_VOLATILE_P (operands[4]) = 1;
20583 (define_insn "*<mode>_stx"
20585 [(match_operator:<bnd_ptr> 3 "bnd_mem_operator"
20587 [(match_operand:<bnd_ptr> 0 "address_mpx_no_index_operand" "Ti")
20588 (match_operand:<bnd_ptr> 1 "register_operand" "l")]
20589 UNSPEC_BNDLDX_ADDR)])
20590 (match_operand:BND 2 "register_operand" "w")]
20592 (set (match_operand:BLK 4 "bnd_mem_operator")
20593 (unspec:BLK [(match_dup 4)] UNSPEC_MPX_FENCE))]
20595 "bndstx\t{%2, %3|%3, %2}"
20596 [(set_attr "type" "mpxst")])
20598 (define_insn "move_size_reloc_<mode>"
20599 [(set (match_operand:SWI48 0 "register_operand" "=r")
20601 [(match_operand:SWI48 1 "symbol_operand")]
20605 if (x86_64_immediate_size_operand (operands[1], VOIDmode))
20606 return "mov{l}\t{%1@SIZE, %k0|%k0, %1@SIZE}";
20608 return "movabs{q}\t{%1@SIZE, %0|%0, %1@SIZE}";
20610 [(set_attr "type" "imov")
20611 (set_attr "mode" "<MODE>")])
20613 ;; RDPKRU and WRPKRU
20615 (define_expand "rdpkru"
20617 [(set (match_operand:SI 0 "register_operand")
20618 (unspec_volatile:SI [(match_dup 1)] UNSPECV_PKU))
20619 (set (match_dup 2) (const_int 0))])]
20622 operands[1] = force_reg (SImode, const0_rtx);
20623 operands[2] = gen_reg_rtx (SImode);
20626 (define_insn "*rdpkru"
20627 [(set (match_operand:SI 0 "register_operand" "=a")
20628 (unspec_volatile:SI [(match_operand:SI 2 "register_operand" "c")]
20630 (set (match_operand:SI 1 "register_operand" "=d")
20634 [(set_attr "type" "other")])
20636 (define_expand "wrpkru"
20637 [(unspec_volatile:SI
20638 [(match_operand:SI 0 "register_operand")
20639 (match_dup 1) (match_dup 2)] UNSPECV_PKU)]
20642 operands[1] = force_reg (SImode, const0_rtx);
20643 operands[2] = force_reg (SImode, const0_rtx);
20646 (define_insn "*wrpkru"
20647 [(unspec_volatile:SI
20648 [(match_operand:SI 0 "register_operand" "a")
20649 (match_operand:SI 1 "register_operand" "d")
20650 (match_operand:SI 2 "register_operand" "c")] UNSPECV_PKU)]
20653 [(set_attr "type" "other")])
20655 (define_insn "rdpid"
20656 [(set (match_operand:SI 0 "register_operand" "=r")
20657 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDPID))]
20658 "!TARGET_64BIT && TARGET_RDPID"
20660 [(set_attr "type" "other")])
20662 (define_insn "rdpid_rex64"
20663 [(set (match_operand:DI 0 "register_operand" "=r")
20664 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDPID))]
20665 "TARGET_64BIT && TARGET_RDPID"
20667 [(set_attr "type" "other")])
20669 ;; Intirinsics for > i486
20671 (define_insn "wbinvd"
20672 [(unspec_volatile [(const_int 0)] UNSPECV_WBINVD)]
20675 [(set_attr "type" "other")])
20677 (define_insn "wbnoinvd"
20678 [(unspec_volatile [(const_int 0)] UNSPECV_WBNOINVD)]
20681 [(set_attr "type" "other")])
20683 (define_insn "movdiri<mode>"
20684 [(unspec_volatile:SWI48[(match_operand:SWI48 0 "memory_operand" "m")
20685 (match_operand:SWI48 1 "register_operand" "r")]
20688 "movdiri\t{%1, %0|%0, %1}"
20689 [(set_attr "type" "other")])
20691 (define_insn "movdir64b_<mode>"
20692 [(unspec_volatile:XI[(match_operand:P 0 "register_operand" "r")
20693 (match_operand:XI 1 "memory_operand")]
20694 UNSPECV_MOVDIR64B)]
20696 "movdir64b\t{%1, %0|%0, %1}"
20697 [(set_attr "type" "other")])
20701 (include "sync.md")