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_overlap_mentioned_p (operands[3], operands[4])
12485 && ! reg_set_p (operands[3], operands[4])
12486 && peep2_regno_dead_p (0, FLAGS_REG)"
12487 [(parallel [(set (match_dup 5) (match_dup 0))
12489 (set (strict_low_part (match_dup 6))
12492 operands[5] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
12493 operands[6] = gen_lowpart (QImode, operands[3]);
12494 ix86_expand_clear (operands[3]);
12498 [(set (reg FLAGS_REG) (match_operand 0))
12499 (parallel [(set (reg FLAGS_REG) (match_operand 1))
12500 (match_operand 5)])
12501 (set (match_operand:QI 2 "register_operand")
12502 (match_operator:QI 3 "ix86_comparison_operator"
12503 [(reg FLAGS_REG) (const_int 0)]))
12504 (set (match_operand 4 "any_QIreg_operand")
12505 (zero_extend (match_dup 2)))]
12506 "(peep2_reg_dead_p (4, operands[2])
12507 || operands_match_p (operands[2], operands[4]))
12508 && ! reg_overlap_mentioned_p (operands[4], operands[0])
12509 && ! reg_overlap_mentioned_p (operands[4], operands[1])
12510 && ! reg_overlap_mentioned_p (operands[4], operands[5])
12511 && ! reg_set_p (operands[4], operands[5])
12512 && refers_to_regno_p (FLAGS_REG, operands[1], (rtx *)NULL)
12513 && peep2_regno_dead_p (0, FLAGS_REG)"
12514 [(set (match_dup 6) (match_dup 0))
12515 (parallel [(set (match_dup 7) (match_dup 1))
12517 (set (strict_low_part (match_dup 8))
12520 operands[6] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
12521 operands[7] = gen_rtx_REG (GET_MODE (operands[1]), FLAGS_REG);
12522 operands[8] = gen_lowpart (QImode, operands[4]);
12523 ix86_expand_clear (operands[4]);
12526 ;; Similar, but match zero extend with andsi3.
12529 [(set (reg FLAGS_REG) (match_operand 0))
12530 (set (match_operand:QI 1 "register_operand")
12531 (match_operator:QI 2 "ix86_comparison_operator"
12532 [(reg FLAGS_REG) (const_int 0)]))
12533 (parallel [(set (match_operand:SI 3 "any_QIreg_operand")
12534 (and:SI (match_dup 3) (const_int 255)))
12535 (clobber (reg:CC FLAGS_REG))])]
12536 "REGNO (operands[1]) == REGNO (operands[3])
12537 && ! reg_overlap_mentioned_p (operands[3], operands[0])
12538 && peep2_regno_dead_p (0, FLAGS_REG)"
12539 [(set (match_dup 4) (match_dup 0))
12540 (set (strict_low_part (match_dup 5))
12543 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
12544 operands[5] = gen_lowpart (QImode, operands[3]);
12545 ix86_expand_clear (operands[3]);
12549 [(parallel [(set (reg FLAGS_REG) (match_operand 0))
12550 (match_operand 4)])
12551 (set (match_operand:QI 1 "register_operand")
12552 (match_operator:QI 2 "ix86_comparison_operator"
12553 [(reg FLAGS_REG) (const_int 0)]))
12554 (parallel [(set (match_operand 3 "any_QIreg_operand")
12555 (zero_extend (match_dup 1)))
12556 (clobber (reg:CC FLAGS_REG))])]
12557 "(peep2_reg_dead_p (3, operands[1])
12558 || operands_match_p (operands[1], operands[3]))
12559 && ! reg_overlap_mentioned_p (operands[3], operands[0])
12560 && ! reg_overlap_mentioned_p (operands[3], operands[4])
12561 && ! reg_set_p (operands[3], operands[4])
12562 && peep2_regno_dead_p (0, FLAGS_REG)"
12563 [(parallel [(set (match_dup 5) (match_dup 0))
12565 (set (strict_low_part (match_dup 6))
12568 operands[5] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
12569 operands[6] = gen_lowpart (QImode, operands[3]);
12570 ix86_expand_clear (operands[3]);
12574 [(set (reg FLAGS_REG) (match_operand 0))
12575 (parallel [(set (reg FLAGS_REG) (match_operand 1))
12576 (match_operand 5)])
12577 (set (match_operand:QI 2 "register_operand")
12578 (match_operator:QI 3 "ix86_comparison_operator"
12579 [(reg FLAGS_REG) (const_int 0)]))
12580 (parallel [(set (match_operand 4 "any_QIreg_operand")
12581 (zero_extend (match_dup 2)))
12582 (clobber (reg:CC FLAGS_REG))])]
12583 "(peep2_reg_dead_p (4, operands[2])
12584 || operands_match_p (operands[2], operands[4]))
12585 && ! reg_overlap_mentioned_p (operands[4], operands[0])
12586 && ! reg_overlap_mentioned_p (operands[4], operands[1])
12587 && ! reg_overlap_mentioned_p (operands[4], operands[5])
12588 && ! reg_set_p (operands[4], operands[5])
12589 && refers_to_regno_p (FLAGS_REG, operands[1], (rtx *)NULL)
12590 && peep2_regno_dead_p (0, FLAGS_REG)"
12591 [(set (match_dup 6) (match_dup 0))
12592 (parallel [(set (match_dup 7) (match_dup 1))
12594 (set (strict_low_part (match_dup 8))
12597 operands[6] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
12598 operands[7] = gen_rtx_REG (GET_MODE (operands[1]), FLAGS_REG);
12599 operands[8] = gen_lowpart (QImode, operands[4]);
12600 ix86_expand_clear (operands[4]);
12603 ;; Call instructions.
12605 ;; The predicates normally associated with named expanders are not properly
12606 ;; checked for calls. This is a bug in the generic code, but it isn't that
12607 ;; easy to fix. Ignore it for now and be prepared to fix things up.
12609 ;; P6 processors will jump to the address after the decrement when %esp
12610 ;; is used as a call operand, so they will execute return address as a code.
12611 ;; See Pentium Pro errata 70, Pentium 2 errata A33 and Pentium 3 errata E17.
12613 ;; Register constraint for call instruction.
12614 (define_mode_attr c [(SI "l") (DI "r")])
12616 ;; Call subroutine returning no value.
12618 (define_expand "call"
12619 [(call (match_operand:QI 0)
12621 (use (match_operand 2))]
12624 ix86_expand_call (NULL, operands[0], operands[1],
12625 operands[2], NULL, false);
12629 (define_expand "sibcall"
12630 [(call (match_operand:QI 0)
12632 (use (match_operand 2))]
12635 ix86_expand_call (NULL, operands[0], operands[1],
12636 operands[2], NULL, true);
12640 (define_insn "*call"
12641 [(call (mem:QI (match_operand:W 0 "call_insn_operand" "<c>BwBz"))
12642 (match_operand 1))]
12643 "!SIBLING_CALL_P (insn)"
12644 "* return ix86_output_call_insn (insn, operands[0]);"
12645 [(set_attr "type" "call")])
12647 ;; This covers both call and sibcall since only GOT slot is allowed.
12648 (define_insn "*call_got_x32"
12649 [(call (mem:QI (zero_extend:DI
12650 (match_operand:SI 0 "GOT_memory_operand" "Bg")))
12651 (match_operand 1))]
12654 rtx fnaddr = gen_const_mem (DImode, XEXP (operands[0], 0));
12655 return ix86_output_call_insn (insn, fnaddr);
12657 [(set_attr "type" "call")])
12659 ;; Since sibcall never returns, we can only use call-clobbered register
12661 (define_insn "*sibcall_GOT_32"
12664 (match_operand:SI 0 "register_no_elim_operand" "U")
12665 (match_operand:SI 1 "GOT32_symbol_operand"))))
12666 (match_operand 2))]
12669 && !TARGET_INDIRECT_BRANCH_REGISTER
12670 && SIBLING_CALL_P (insn)"
12672 rtx fnaddr = gen_rtx_PLUS (SImode, operands[0], operands[1]);
12673 fnaddr = gen_const_mem (SImode, fnaddr);
12674 return ix86_output_call_insn (insn, fnaddr);
12676 [(set_attr "type" "call")])
12678 (define_insn "*sibcall"
12679 [(call (mem:QI (match_operand:W 0 "sibcall_insn_operand" "UBsBz"))
12680 (match_operand 1))]
12681 "SIBLING_CALL_P (insn)"
12682 "* return ix86_output_call_insn (insn, operands[0]);"
12683 [(set_attr "type" "call")])
12685 (define_insn "*sibcall_memory"
12686 [(call (mem:QI (match_operand:W 0 "memory_operand" "m"))
12688 (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
12689 "!TARGET_X32 && !TARGET_INDIRECT_BRANCH_REGISTER"
12690 "* return ix86_output_call_insn (insn, operands[0]);"
12691 [(set_attr "type" "call")])
12694 [(set (match_operand:W 0 "register_operand")
12695 (match_operand:W 1 "memory_operand"))
12696 (call (mem:QI (match_dup 0))
12697 (match_operand 3))]
12699 && !TARGET_INDIRECT_BRANCH_REGISTER
12700 && SIBLING_CALL_P (peep2_next_insn (1))
12701 && !reg_mentioned_p (operands[0],
12702 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (1)))"
12703 [(parallel [(call (mem:QI (match_dup 1))
12705 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
12708 [(set (match_operand:W 0 "register_operand")
12709 (match_operand:W 1 "memory_operand"))
12710 (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
12711 (call (mem:QI (match_dup 0))
12712 (match_operand 3))]
12714 && !TARGET_INDIRECT_BRANCH_REGISTER
12715 && SIBLING_CALL_P (peep2_next_insn (2))
12716 && !reg_mentioned_p (operands[0],
12717 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (2)))"
12718 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
12719 (parallel [(call (mem:QI (match_dup 1))
12721 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
12723 (define_expand "call_pop"
12724 [(parallel [(call (match_operand:QI 0)
12725 (match_operand:SI 1))
12726 (set (reg:SI SP_REG)
12727 (plus:SI (reg:SI SP_REG)
12728 (match_operand:SI 3)))])]
12731 ix86_expand_call (NULL, operands[0], operands[1],
12732 operands[2], operands[3], false);
12736 (define_insn "*call_pop"
12737 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lBwBz"))
12739 (set (reg:SI SP_REG)
12740 (plus:SI (reg:SI SP_REG)
12741 (match_operand:SI 2 "immediate_operand" "i")))]
12742 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
12743 "* return ix86_output_call_insn (insn, operands[0]);"
12744 [(set_attr "type" "call")])
12746 (define_insn "*sibcall_pop"
12747 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "UBsBz"))
12749 (set (reg:SI SP_REG)
12750 (plus:SI (reg:SI SP_REG)
12751 (match_operand:SI 2 "immediate_operand" "i")))]
12752 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
12753 "* return ix86_output_call_insn (insn, operands[0]);"
12754 [(set_attr "type" "call")])
12756 (define_insn "*sibcall_pop_memory"
12757 [(call (mem:QI (match_operand:SI 0 "memory_operand" "Bs"))
12759 (set (reg:SI SP_REG)
12760 (plus:SI (reg:SI SP_REG)
12761 (match_operand:SI 2 "immediate_operand" "i")))
12762 (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
12764 "* return ix86_output_call_insn (insn, operands[0]);"
12765 [(set_attr "type" "call")])
12768 [(set (match_operand:SI 0 "register_operand")
12769 (match_operand:SI 1 "memory_operand"))
12770 (parallel [(call (mem:QI (match_dup 0))
12772 (set (reg:SI SP_REG)
12773 (plus:SI (reg:SI SP_REG)
12774 (match_operand:SI 4 "immediate_operand")))])]
12775 "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (1))
12776 && !reg_mentioned_p (operands[0],
12777 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (1)))"
12778 [(parallel [(call (mem:QI (match_dup 1))
12780 (set (reg:SI SP_REG)
12781 (plus:SI (reg:SI SP_REG)
12783 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
12786 [(set (match_operand:SI 0 "register_operand")
12787 (match_operand:SI 1 "memory_operand"))
12788 (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
12789 (parallel [(call (mem:QI (match_dup 0))
12791 (set (reg:SI SP_REG)
12792 (plus:SI (reg:SI SP_REG)
12793 (match_operand:SI 4 "immediate_operand")))])]
12794 "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (2))
12795 && !reg_mentioned_p (operands[0],
12796 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (2)))"
12797 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
12798 (parallel [(call (mem:QI (match_dup 1))
12800 (set (reg:SI SP_REG)
12801 (plus:SI (reg:SI SP_REG)
12803 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
12805 ;; Combining simple memory jump instruction
12808 [(set (match_operand:W 0 "register_operand")
12809 (match_operand:W 1 "memory_operand"))
12810 (set (pc) (match_dup 0))]
12812 && !TARGET_INDIRECT_BRANCH_REGISTER
12813 && peep2_reg_dead_p (2, operands[0])"
12814 [(set (pc) (match_dup 1))])
12816 ;; Call subroutine, returning value in operand 0
12818 (define_expand "call_value"
12819 [(set (match_operand 0)
12820 (call (match_operand:QI 1)
12821 (match_operand 2)))
12822 (use (match_operand 3))]
12825 ix86_expand_call (operands[0], operands[1], operands[2],
12826 operands[3], NULL, false);
12830 (define_expand "sibcall_value"
12831 [(set (match_operand 0)
12832 (call (match_operand:QI 1)
12833 (match_operand 2)))
12834 (use (match_operand 3))]
12837 ix86_expand_call (operands[0], operands[1], operands[2],
12838 operands[3], NULL, true);
12842 (define_insn "*call_value"
12843 [(set (match_operand 0)
12844 (call (mem:QI (match_operand:W 1 "call_insn_operand" "<c>BwBz"))
12845 (match_operand 2)))]
12846 "!SIBLING_CALL_P (insn)"
12847 "* return ix86_output_call_insn (insn, operands[1]);"
12848 [(set_attr "type" "callv")])
12850 ;; This covers both call and sibcall since only GOT slot is allowed.
12851 (define_insn "*call_value_got_x32"
12852 [(set (match_operand 0)
12855 (match_operand:SI 1 "GOT_memory_operand" "Bg")))
12856 (match_operand 2)))]
12859 rtx fnaddr = gen_const_mem (DImode, XEXP (operands[1], 0));
12860 return ix86_output_call_insn (insn, fnaddr);
12862 [(set_attr "type" "callv")])
12864 ;; Since sibcall never returns, we can only use call-clobbered register
12866 (define_insn "*sibcall_value_GOT_32"
12867 [(set (match_operand 0)
12870 (match_operand:SI 1 "register_no_elim_operand" "U")
12871 (match_operand:SI 2 "GOT32_symbol_operand"))))
12872 (match_operand 3)))]
12875 && !TARGET_INDIRECT_BRANCH_REGISTER
12876 && SIBLING_CALL_P (insn)"
12878 rtx fnaddr = gen_rtx_PLUS (SImode, operands[1], operands[2]);
12879 fnaddr = gen_const_mem (SImode, fnaddr);
12880 return ix86_output_call_insn (insn, fnaddr);
12882 [(set_attr "type" "callv")])
12884 (define_insn "*sibcall_value"
12885 [(set (match_operand 0)
12886 (call (mem:QI (match_operand:W 1 "sibcall_insn_operand" "UBsBz"))
12887 (match_operand 2)))]
12888 "SIBLING_CALL_P (insn)"
12889 "* return ix86_output_call_insn (insn, operands[1]);"
12890 [(set_attr "type" "callv")])
12892 (define_insn "*sibcall_value_memory"
12893 [(set (match_operand 0)
12894 (call (mem:QI (match_operand:W 1 "memory_operand" "m"))
12895 (match_operand 2)))
12896 (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
12897 "!TARGET_X32 && !TARGET_INDIRECT_BRANCH_REGISTER"
12898 "* return ix86_output_call_insn (insn, operands[1]);"
12899 [(set_attr "type" "callv")])
12902 [(set (match_operand:W 0 "register_operand")
12903 (match_operand:W 1 "memory_operand"))
12904 (set (match_operand 2)
12905 (call (mem:QI (match_dup 0))
12906 (match_operand 3)))]
12908 && !TARGET_INDIRECT_BRANCH_REGISTER
12909 && SIBLING_CALL_P (peep2_next_insn (1))
12910 && !reg_mentioned_p (operands[0],
12911 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (1)))"
12912 [(parallel [(set (match_dup 2)
12913 (call (mem:QI (match_dup 1))
12915 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
12918 [(set (match_operand:W 0 "register_operand")
12919 (match_operand:W 1 "memory_operand"))
12920 (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
12921 (set (match_operand 2)
12922 (call (mem:QI (match_dup 0))
12923 (match_operand 3)))]
12925 && !TARGET_INDIRECT_BRANCH_REGISTER
12926 && SIBLING_CALL_P (peep2_next_insn (2))
12927 && !reg_mentioned_p (operands[0],
12928 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (2)))"
12929 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
12930 (parallel [(set (match_dup 2)
12931 (call (mem:QI (match_dup 1))
12933 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
12935 (define_expand "call_value_pop"
12936 [(parallel [(set (match_operand 0)
12937 (call (match_operand:QI 1)
12938 (match_operand:SI 2)))
12939 (set (reg:SI SP_REG)
12940 (plus:SI (reg:SI SP_REG)
12941 (match_operand:SI 4)))])]
12944 ix86_expand_call (operands[0], operands[1], operands[2],
12945 operands[3], operands[4], false);
12949 (define_insn "*call_value_pop"
12950 [(set (match_operand 0)
12951 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lBwBz"))
12952 (match_operand 2)))
12953 (set (reg:SI SP_REG)
12954 (plus:SI (reg:SI SP_REG)
12955 (match_operand:SI 3 "immediate_operand" "i")))]
12956 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
12957 "* return ix86_output_call_insn (insn, operands[1]);"
12958 [(set_attr "type" "callv")])
12960 (define_insn "*sibcall_value_pop"
12961 [(set (match_operand 0)
12962 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "UBsBz"))
12963 (match_operand 2)))
12964 (set (reg:SI SP_REG)
12965 (plus:SI (reg:SI SP_REG)
12966 (match_operand:SI 3 "immediate_operand" "i")))]
12967 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
12968 "* return ix86_output_call_insn (insn, operands[1]);"
12969 [(set_attr "type" "callv")])
12971 (define_insn "*sibcall_value_pop_memory"
12972 [(set (match_operand 0)
12973 (call (mem:QI (match_operand:SI 1 "memory_operand" "m"))
12974 (match_operand 2)))
12975 (set (reg:SI SP_REG)
12976 (plus:SI (reg:SI SP_REG)
12977 (match_operand:SI 3 "immediate_operand" "i")))
12978 (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
12980 "* return ix86_output_call_insn (insn, operands[1]);"
12981 [(set_attr "type" "callv")])
12984 [(set (match_operand:SI 0 "register_operand")
12985 (match_operand:SI 1 "memory_operand"))
12986 (parallel [(set (match_operand 2)
12987 (call (mem:QI (match_dup 0))
12988 (match_operand 3)))
12989 (set (reg:SI SP_REG)
12990 (plus:SI (reg:SI SP_REG)
12991 (match_operand:SI 4 "immediate_operand")))])]
12992 "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (1))
12993 && !reg_mentioned_p (operands[0],
12994 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (1)))"
12995 [(parallel [(set (match_dup 2)
12996 (call (mem:QI (match_dup 1))
12998 (set (reg:SI SP_REG)
12999 (plus:SI (reg:SI SP_REG)
13001 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
13004 [(set (match_operand:SI 0 "register_operand")
13005 (match_operand:SI 1 "memory_operand"))
13006 (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
13007 (parallel [(set (match_operand 2)
13008 (call (mem:QI (match_dup 0))
13009 (match_operand 3)))
13010 (set (reg:SI SP_REG)
13011 (plus:SI (reg:SI SP_REG)
13012 (match_operand:SI 4 "immediate_operand")))])]
13013 "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (2))
13014 && !reg_mentioned_p (operands[0],
13015 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (2)))"
13016 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
13017 (parallel [(set (match_dup 2)
13018 (call (mem:QI (match_dup 1))
13020 (set (reg:SI SP_REG)
13021 (plus:SI (reg:SI SP_REG)
13023 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
13025 ;; Call subroutine returning any type.
13027 (define_expand "untyped_call"
13028 [(parallel [(call (match_operand 0)
13031 (match_operand 2)])]
13036 /* In order to give reg-stack an easier job in validating two
13037 coprocessor registers as containing a possible return value,
13038 simply pretend the untyped call returns a complex long double
13041 We can't use SSE_REGPARM_MAX here since callee is unprototyped
13042 and should have the default ABI. */
13044 ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
13045 ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
13046 operands[0], const0_rtx,
13047 GEN_INT ((TARGET_64BIT
13048 ? (ix86_abi == SYSV_ABI
13049 ? X86_64_SSE_REGPARM_MAX
13050 : X86_64_MS_SSE_REGPARM_MAX)
13051 : X86_32_SSE_REGPARM_MAX)
13055 for (i = 0; i < XVECLEN (operands[2], 0); i++)
13057 rtx set = XVECEXP (operands[2], 0, i);
13058 emit_move_insn (SET_DEST (set), SET_SRC (set));
13061 /* The optimizer does not know that the call sets the function value
13062 registers we stored in the result block. We avoid problems by
13063 claiming that all hard registers are used and clobbered at this
13065 emit_insn (gen_blockage ());
13070 ;; Prologue and epilogue instructions
13072 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
13073 ;; all of memory. This blocks insns from being moved across this point.
13075 (define_insn "blockage"
13076 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
13079 [(set_attr "length" "0")])
13081 ;; Do not schedule instructions accessing memory across this point.
13083 (define_expand "memory_blockage"
13084 [(set (match_dup 0)
13085 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
13088 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
13089 MEM_VOLATILE_P (operands[0]) = 1;
13092 (define_insn "*memory_blockage"
13093 [(set (match_operand:BLK 0)
13094 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
13097 [(set_attr "length" "0")])
13099 ;; As USE insns aren't meaningful after reload, this is used instead
13100 ;; to prevent deleting instructions setting registers for PIC code
13101 (define_insn "prologue_use"
13102 [(unspec_volatile [(match_operand 0)] UNSPECV_PROLOGUE_USE)]
13105 [(set_attr "length" "0")])
13107 ;; Insn emitted into the body of a function to return from a function.
13108 ;; This is only done if the function's epilogue is known to be simple.
13109 ;; See comments for ix86_can_use_return_insn_p in i386.c.
13111 (define_expand "return"
13113 "ix86_can_use_return_insn_p ()"
13115 if (crtl->args.pops_args)
13117 rtx popc = GEN_INT (crtl->args.pops_args);
13118 emit_jump_insn (gen_simple_return_pop_internal (popc));
13123 ;; We need to disable this for TARGET_SEH, as otherwise
13124 ;; shrink-wrapped prologue gets enabled too. This might exceed
13125 ;; the maximum size of prologue in unwind information.
13126 ;; Also disallow shrink-wrapping if using stack slot to pass the
13127 ;; static chain pointer - the first instruction has to be pushl %esi
13128 ;; and it can't be moved around, as we use alternate entry points
13131 (define_expand "simple_return"
13133 "!TARGET_SEH && !ix86_static_chain_on_stack"
13135 if (crtl->args.pops_args)
13137 rtx popc = GEN_INT (crtl->args.pops_args);
13138 emit_jump_insn (gen_simple_return_pop_internal (popc));
13143 (define_insn "simple_return_internal"
13146 "* return ix86_output_function_return (false);"
13147 [(set_attr "length" "1")
13148 (set_attr "atom_unit" "jeu")
13149 (set_attr "length_immediate" "0")
13150 (set_attr "modrm" "0")
13151 (set_attr "maybe_prefix_bnd" "1")])
13153 (define_insn "interrupt_return"
13155 (unspec [(const_int 0)] UNSPEC_INTERRUPT_RETURN)]
13158 return TARGET_64BIT ? "iretq" : "iret";
13161 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
13162 ;; instruction Athlon and K8 have.
13164 (define_insn "simple_return_internal_long"
13166 (unspec [(const_int 0)] UNSPEC_REP)]
13168 "* return ix86_output_function_return (true);"
13169 [(set_attr "length" "2")
13170 (set_attr "atom_unit" "jeu")
13171 (set_attr "length_immediate" "0")
13172 (set_attr "prefix_rep" "1")
13173 (set_attr "modrm" "0")])
13175 (define_insn_and_split "simple_return_pop_internal"
13177 (use (match_operand:SI 0 "const_int_operand"))]
13180 "&& cfun->machine->function_return_type != indirect_branch_keep"
13182 "ix86_split_simple_return_pop_internal (operands[0]); DONE;"
13183 [(set_attr "length" "3")
13184 (set_attr "atom_unit" "jeu")
13185 (set_attr "length_immediate" "2")
13186 (set_attr "modrm" "0")
13187 (set_attr "maybe_prefix_bnd" "1")])
13189 (define_insn "simple_return_indirect_internal"
13191 (use (match_operand 0 "register_operand" "r"))]
13193 "* return ix86_output_indirect_function_return (operands[0]);"
13194 [(set (attr "type")
13195 (if_then_else (match_test "(cfun->machine->indirect_branch_type
13196 != indirect_branch_keep)")
13197 (const_string "multi")
13198 (const_string "ibr")))
13199 (set_attr "length_immediate" "0")
13200 (set_attr "maybe_prefix_bnd" "1")])
13206 [(set_attr "length" "1")
13207 (set_attr "length_immediate" "0")
13208 (set_attr "modrm" "0")])
13210 ;; Generate nops. Operand 0 is the number of nops, up to 8.
13211 (define_insn "nops"
13212 [(unspec_volatile [(match_operand 0 "const_int_operand")]
13216 int num = INTVAL (operands[0]);
13218 gcc_assert (IN_RANGE (num, 1, 8));
13221 fputs ("\tnop\n", asm_out_file);
13225 [(set (attr "length") (symbol_ref "INTVAL (operands[0])"))
13226 (set_attr "length_immediate" "0")
13227 (set_attr "modrm" "0")])
13229 ;; Pad to 16-byte boundary, max skip in op0. Used to avoid
13230 ;; branch prediction penalty for the third jump in a 16-byte
13234 [(unspec_volatile [(match_operand 0)] UNSPECV_ALIGN)]
13237 #ifdef ASM_OUTPUT_MAX_SKIP_PAD
13238 ASM_OUTPUT_MAX_SKIP_PAD (asm_out_file, 4, (int)INTVAL (operands[0]));
13240 /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
13241 The align insn is used to avoid 3 jump instructions in the row to improve
13242 branch prediction and the benefits hardly outweigh the cost of extra 8
13243 nops on the average inserted by full alignment pseudo operation. */
13247 [(set_attr "length" "16")])
13249 (define_expand "prologue"
13252 "ix86_expand_prologue (); DONE;")
13254 (define_expand "set_got"
13256 [(set (match_operand:SI 0 "register_operand")
13257 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
13258 (clobber (reg:CC FLAGS_REG))])]
13261 if (flag_pic && !TARGET_VXWORKS_RTP)
13262 ix86_pc_thunk_call_expanded = true;
13265 (define_insn "*set_got"
13266 [(set (match_operand:SI 0 "register_operand" "=r")
13267 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
13268 (clobber (reg:CC FLAGS_REG))]
13270 "* return output_set_got (operands[0], NULL_RTX);"
13271 [(set_attr "type" "multi")
13272 (set_attr "length" "12")])
13274 (define_expand "set_got_labelled"
13276 [(set (match_operand:SI 0 "register_operand")
13277 (unspec:SI [(label_ref (match_operand 1))]
13279 (clobber (reg:CC FLAGS_REG))])]
13282 if (flag_pic && !TARGET_VXWORKS_RTP)
13283 ix86_pc_thunk_call_expanded = true;
13286 (define_insn "*set_got_labelled"
13287 [(set (match_operand:SI 0 "register_operand" "=r")
13288 (unspec:SI [(label_ref (match_operand 1))]
13290 (clobber (reg:CC FLAGS_REG))]
13292 "* return output_set_got (operands[0], operands[1]);"
13293 [(set_attr "type" "multi")
13294 (set_attr "length" "12")])
13296 (define_insn "set_got_rex64"
13297 [(set (match_operand:DI 0 "register_operand" "=r")
13298 (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
13300 "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}"
13301 [(set_attr "type" "lea")
13302 (set_attr "length_address" "4")
13303 (set_attr "modrm_class" "unknown")
13304 (set_attr "mode" "DI")])
13306 (define_insn "set_rip_rex64"
13307 [(set (match_operand:DI 0 "register_operand" "=r")
13308 (unspec:DI [(label_ref (match_operand 1))] UNSPEC_SET_RIP))]
13310 "lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}"
13311 [(set_attr "type" "lea")
13312 (set_attr "length_address" "4")
13313 (set_attr "mode" "DI")])
13315 (define_insn "set_got_offset_rex64"
13316 [(set (match_operand:DI 0 "register_operand" "=r")
13318 [(label_ref (match_operand 1))]
13319 UNSPEC_SET_GOT_OFFSET))]
13321 "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}"
13322 [(set_attr "type" "imov")
13323 (set_attr "length_immediate" "0")
13324 (set_attr "length_address" "8")
13325 (set_attr "mode" "DI")])
13327 (define_expand "epilogue"
13330 "ix86_expand_epilogue (1); DONE;")
13332 (define_expand "sibcall_epilogue"
13335 "ix86_expand_epilogue (0); DONE;")
13337 (define_expand "eh_return"
13338 [(use (match_operand 0 "register_operand"))]
13341 rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
13343 /* Tricky bit: we write the address of the handler to which we will
13344 be returning into someone else's stack frame, one word below the
13345 stack address we wish to restore. */
13346 tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
13347 tmp = plus_constant (Pmode, tmp, -UNITS_PER_WORD);
13348 /* Return address is always in word_mode. */
13349 tmp = gen_rtx_MEM (word_mode, tmp);
13350 if (GET_MODE (ra) != word_mode)
13351 ra = convert_to_mode (word_mode, ra, 1);
13352 emit_move_insn (tmp, ra);
13354 emit_jump_insn (gen_eh_return_internal ());
13359 (define_insn_and_split "eh_return_internal"
13363 "epilogue_completed"
13365 "ix86_expand_epilogue (2); DONE;")
13367 (define_insn "leave"
13368 [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
13369 (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
13370 (clobber (mem:BLK (scratch)))]
13373 [(set_attr "type" "leave")])
13375 (define_insn "leave_rex64"
13376 [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
13377 (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
13378 (clobber (mem:BLK (scratch)))]
13381 [(set_attr "type" "leave")])
13383 ;; Handle -fsplit-stack.
13385 (define_expand "split_stack_prologue"
13389 ix86_expand_split_stack_prologue ();
13393 ;; In order to support the call/return predictor, we use a return
13394 ;; instruction which the middle-end doesn't see.
13395 (define_insn "split_stack_return"
13396 [(unspec_volatile [(match_operand:SI 0 "const_int_operand")]
13397 UNSPECV_SPLIT_STACK_RETURN)]
13400 if (operands[0] == const0_rtx)
13405 [(set_attr "atom_unit" "jeu")
13406 (set_attr "modrm" "0")
13407 (set (attr "length")
13408 (if_then_else (match_operand:SI 0 "const0_operand")
13411 (set (attr "length_immediate")
13412 (if_then_else (match_operand:SI 0 "const0_operand")
13416 ;; If there are operand 0 bytes available on the stack, jump to
13419 (define_expand "split_stack_space_check"
13420 [(set (pc) (if_then_else
13421 (ltu (minus (reg SP_REG)
13422 (match_operand 0 "register_operand"))
13424 (label_ref (match_operand 1))
13428 rtx reg = gen_reg_rtx (Pmode);
13430 emit_insn (gen_sub3_insn (reg, stack_pointer_rtx, operands[0]));
13432 operands[2] = ix86_split_stack_guard ();
13433 ix86_expand_branch (GEU, reg, operands[2], operands[1]);
13438 ;; Bit manipulation instructions.
13440 (define_expand "ffs<mode>2"
13441 [(set (match_dup 2) (const_int -1))
13442 (parallel [(set (match_dup 3) (match_dup 4))
13443 (set (match_operand:SWI48 0 "register_operand")
13445 (match_operand:SWI48 1 "nonimmediate_operand")))])
13446 (set (match_dup 0) (if_then_else:SWI48
13447 (eq (match_dup 3) (const_int 0))
13450 (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (const_int 1)))
13451 (clobber (reg:CC FLAGS_REG))])]
13454 machine_mode flags_mode;
13456 if (<MODE>mode == SImode && !TARGET_CMOVE)
13458 emit_insn (gen_ffssi2_no_cmove (operands[0], operands [1]));
13462 flags_mode = TARGET_BMI ? CCCmode : CCZmode;
13464 operands[2] = gen_reg_rtx (<MODE>mode);
13465 operands[3] = gen_rtx_REG (flags_mode, FLAGS_REG);
13466 operands[4] = gen_rtx_COMPARE (flags_mode, operands[1], const0_rtx);
13469 (define_insn_and_split "ffssi2_no_cmove"
13470 [(set (match_operand:SI 0 "register_operand" "=r")
13471 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
13472 (clobber (match_scratch:SI 2 "=&q"))
13473 (clobber (reg:CC FLAGS_REG))]
13476 "&& reload_completed"
13477 [(parallel [(set (match_dup 4) (match_dup 5))
13478 (set (match_dup 0) (ctz:SI (match_dup 1)))])
13479 (set (strict_low_part (match_dup 3))
13480 (eq:QI (match_dup 4) (const_int 0)))
13481 (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
13482 (clobber (reg:CC FLAGS_REG))])
13483 (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
13484 (clobber (reg:CC FLAGS_REG))])
13485 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
13486 (clobber (reg:CC FLAGS_REG))])]
13488 machine_mode flags_mode = TARGET_BMI ? CCCmode : CCZmode;
13490 operands[3] = gen_lowpart (QImode, operands[2]);
13491 operands[4] = gen_rtx_REG (flags_mode, FLAGS_REG);
13492 operands[5] = gen_rtx_COMPARE (flags_mode, operands[1], const0_rtx);
13494 ix86_expand_clear (operands[2]);
13497 (define_insn_and_split "*tzcnt<mode>_1"
13498 [(set (reg:CCC FLAGS_REG)
13499 (compare:CCC (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13501 (set (match_operand:SWI48 0 "register_operand" "=r")
13502 (ctz:SWI48 (match_dup 1)))]
13504 "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
13505 "&& TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
13506 && optimize_function_for_speed_p (cfun)
13507 && !reg_mentioned_p (operands[0], operands[1])"
13509 [(set (reg:CCC FLAGS_REG)
13510 (compare:CCC (match_dup 1) (const_int 0)))
13512 (ctz:SWI48 (match_dup 1)))
13513 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)])]
13514 "ix86_expand_clear (operands[0]);"
13515 [(set_attr "type" "alu1")
13516 (set_attr "prefix_0f" "1")
13517 (set_attr "prefix_rep" "1")
13518 (set_attr "btver2_decode" "double")
13519 (set_attr "mode" "<MODE>")])
13521 ; False dependency happens when destination is only updated by tzcnt,
13522 ; lzcnt or popcnt. There is no false dependency when destination is
13523 ; also used in source.
13524 (define_insn "*tzcnt<mode>_1_falsedep"
13525 [(set (reg:CCC FLAGS_REG)
13526 (compare:CCC (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13528 (set (match_operand:SWI48 0 "register_operand" "=r")
13529 (ctz:SWI48 (match_dup 1)))
13530 (unspec [(match_operand:SWI48 2 "register_operand" "0")]
13531 UNSPEC_INSN_FALSE_DEP)]
13533 "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
13534 [(set_attr "type" "alu1")
13535 (set_attr "prefix_0f" "1")
13536 (set_attr "prefix_rep" "1")
13537 (set_attr "btver2_decode" "double")
13538 (set_attr "mode" "<MODE>")])
13540 (define_insn "*bsf<mode>_1"
13541 [(set (reg:CCZ FLAGS_REG)
13542 (compare:CCZ (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13544 (set (match_operand:SWI48 0 "register_operand" "=r")
13545 (ctz:SWI48 (match_dup 1)))]
13547 "bsf{<imodesuffix>}\t{%1, %0|%0, %1}"
13548 [(set_attr "type" "alu1")
13549 (set_attr "prefix_0f" "1")
13550 (set_attr "btver2_decode" "double")
13551 (set_attr "znver1_decode" "vector")
13552 (set_attr "mode" "<MODE>")])
13554 (define_insn_and_split "ctz<mode>2"
13555 [(set (match_operand:SWI48 0 "register_operand" "=r")
13557 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
13558 (clobber (reg:CC FLAGS_REG))]
13562 return "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
13563 else if (optimize_function_for_size_p (cfun))
13565 else if (TARGET_GENERIC)
13566 /* tzcnt expands to 'rep bsf' and we can use it even if !TARGET_BMI. */
13567 return "rep%; bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
13569 return "bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
13571 "(TARGET_BMI || TARGET_GENERIC)
13572 && TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
13573 && optimize_function_for_speed_p (cfun)
13574 && !reg_mentioned_p (operands[0], operands[1])"
13576 [(set (match_dup 0)
13577 (ctz:SWI48 (match_dup 1)))
13578 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
13579 (clobber (reg:CC FLAGS_REG))])]
13580 "ix86_expand_clear (operands[0]);"
13581 [(set_attr "type" "alu1")
13582 (set_attr "prefix_0f" "1")
13583 (set (attr "prefix_rep")
13585 (ior (match_test "TARGET_BMI")
13586 (and (not (match_test "optimize_function_for_size_p (cfun)"))
13587 (match_test "TARGET_GENERIC")))
13589 (const_string "0")))
13590 (set_attr "mode" "<MODE>")])
13592 ; False dependency happens when destination is only updated by tzcnt,
13593 ; lzcnt or popcnt. There is no false dependency when destination is
13594 ; also used in source.
13595 (define_insn "*ctz<mode>2_falsedep"
13596 [(set (match_operand:SWI48 0 "register_operand" "=r")
13598 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
13599 (unspec [(match_operand:SWI48 2 "register_operand" "0")]
13600 UNSPEC_INSN_FALSE_DEP)
13601 (clobber (reg:CC FLAGS_REG))]
13605 return "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
13606 else if (TARGET_GENERIC)
13607 /* tzcnt expands to 'rep bsf' and we can use it even if !TARGET_BMI. */
13608 return "rep%; bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
13610 gcc_unreachable ();
13612 [(set_attr "type" "alu1")
13613 (set_attr "prefix_0f" "1")
13614 (set_attr "prefix_rep" "1")
13615 (set_attr "mode" "<MODE>")])
13617 (define_insn "bsr_rex64"
13618 [(set (match_operand:DI 0 "register_operand" "=r")
13619 (minus:DI (const_int 63)
13620 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
13621 (clobber (reg:CC FLAGS_REG))]
13623 "bsr{q}\t{%1, %0|%0, %1}"
13624 [(set_attr "type" "alu1")
13625 (set_attr "prefix_0f" "1")
13626 (set_attr "znver1_decode" "vector")
13627 (set_attr "mode" "DI")])
13630 [(set (match_operand:SI 0 "register_operand" "=r")
13631 (minus:SI (const_int 31)
13632 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
13633 (clobber (reg:CC FLAGS_REG))]
13635 "bsr{l}\t{%1, %0|%0, %1}"
13636 [(set_attr "type" "alu1")
13637 (set_attr "prefix_0f" "1")
13638 (set_attr "znver1_decode" "vector")
13639 (set_attr "mode" "SI")])
13641 (define_insn "*bsrhi"
13642 [(set (match_operand:HI 0 "register_operand" "=r")
13643 (minus:HI (const_int 15)
13644 (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
13645 (clobber (reg:CC FLAGS_REG))]
13647 "bsr{w}\t{%1, %0|%0, %1}"
13648 [(set_attr "type" "alu1")
13649 (set_attr "prefix_0f" "1")
13650 (set_attr "znver1_decode" "vector")
13651 (set_attr "mode" "HI")])
13653 (define_expand "clz<mode>2"
13655 [(set (match_operand:SWI48 0 "register_operand")
13658 (clz:SWI48 (match_operand:SWI48 1 "nonimmediate_operand"))))
13659 (clobber (reg:CC FLAGS_REG))])
13661 [(set (match_dup 0) (xor:SWI48 (match_dup 0) (match_dup 2)))
13662 (clobber (reg:CC FLAGS_REG))])]
13667 emit_insn (gen_clz<mode>2_lzcnt (operands[0], operands[1]));
13670 operands[2] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
13673 (define_insn_and_split "clz<mode>2_lzcnt"
13674 [(set (match_operand:SWI48 0 "register_operand" "=r")
13676 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
13677 (clobber (reg:CC FLAGS_REG))]
13679 "lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
13680 "&& TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
13681 && optimize_function_for_speed_p (cfun)
13682 && !reg_mentioned_p (operands[0], operands[1])"
13684 [(set (match_dup 0)
13685 (clz:SWI48 (match_dup 1)))
13686 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
13687 (clobber (reg:CC FLAGS_REG))])]
13688 "ix86_expand_clear (operands[0]);"
13689 [(set_attr "prefix_rep" "1")
13690 (set_attr "type" "bitmanip")
13691 (set_attr "mode" "<MODE>")])
13693 ; False dependency happens when destination is only updated by tzcnt,
13694 ; lzcnt or popcnt. There is no false dependency when destination is
13695 ; also used in source.
13696 (define_insn "*clz<mode>2_lzcnt_falsedep"
13697 [(set (match_operand:SWI48 0 "register_operand" "=r")
13699 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
13700 (unspec [(match_operand:SWI48 2 "register_operand" "0")]
13701 UNSPEC_INSN_FALSE_DEP)
13702 (clobber (reg:CC FLAGS_REG))]
13704 "lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
13705 [(set_attr "prefix_rep" "1")
13706 (set_attr "type" "bitmanip")
13707 (set_attr "mode" "<MODE>")])
13709 (define_int_iterator LT_ZCNT
13710 [(UNSPEC_TZCNT "TARGET_BMI")
13711 (UNSPEC_LZCNT "TARGET_LZCNT")])
13713 (define_int_attr lt_zcnt
13714 [(UNSPEC_TZCNT "tzcnt")
13715 (UNSPEC_LZCNT "lzcnt")])
13717 (define_int_attr lt_zcnt_type
13718 [(UNSPEC_TZCNT "alu1")
13719 (UNSPEC_LZCNT "bitmanip")])
13721 ;; Version of lzcnt/tzcnt that is expanded from intrinsics. This version
13722 ;; provides operand size as output when source operand is zero.
13724 (define_insn_and_split "<lt_zcnt>_<mode>"
13725 [(set (match_operand:SWI48 0 "register_operand" "=r")
13727 [(match_operand:SWI48 1 "nonimmediate_operand" "rm")] LT_ZCNT))
13728 (clobber (reg:CC FLAGS_REG))]
13730 "<lt_zcnt>{<imodesuffix>}\t{%1, %0|%0, %1}"
13731 "&& TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
13732 && optimize_function_for_speed_p (cfun)
13733 && !reg_mentioned_p (operands[0], operands[1])"
13735 [(set (match_dup 0)
13736 (unspec:SWI48 [(match_dup 1)] LT_ZCNT))
13737 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
13738 (clobber (reg:CC FLAGS_REG))])]
13739 "ix86_expand_clear (operands[0]);"
13740 [(set_attr "type" "<lt_zcnt_type>")
13741 (set_attr "prefix_0f" "1")
13742 (set_attr "prefix_rep" "1")
13743 (set_attr "mode" "<MODE>")])
13745 ; False dependency happens when destination is only updated by tzcnt,
13746 ; lzcnt or popcnt. There is no false dependency when destination is
13747 ; also used in source.
13748 (define_insn "*<lt_zcnt>_<mode>_falsedep"
13749 [(set (match_operand:SWI48 0 "register_operand" "=r")
13751 [(match_operand:SWI48 1 "nonimmediate_operand" "rm")] LT_ZCNT))
13752 (unspec [(match_operand:SWI48 2 "register_operand" "0")]
13753 UNSPEC_INSN_FALSE_DEP)
13754 (clobber (reg:CC FLAGS_REG))]
13756 "<lt_zcnt>{<imodesuffix>}\t{%1, %0|%0, %1}"
13757 [(set_attr "type" "<lt_zcnt_type>")
13758 (set_attr "prefix_0f" "1")
13759 (set_attr "prefix_rep" "1")
13760 (set_attr "mode" "<MODE>")])
13762 (define_insn "<lt_zcnt>_hi"
13763 [(set (match_operand:HI 0 "register_operand" "=r")
13765 [(match_operand:HI 1 "nonimmediate_operand" "rm")] LT_ZCNT))
13766 (clobber (reg:CC FLAGS_REG))]
13768 "<lt_zcnt>{w}\t{%1, %0|%0, %1}"
13769 [(set_attr "type" "<lt_zcnt_type>")
13770 (set_attr "prefix_0f" "1")
13771 (set_attr "prefix_rep" "1")
13772 (set_attr "mode" "HI")])
13774 ;; BMI instructions.
13776 (define_insn "bmi_bextr_<mode>"
13777 [(set (match_operand:SWI48 0 "register_operand" "=r,r")
13778 (unspec:SWI48 [(match_operand:SWI48 1 "nonimmediate_operand" "r,m")
13779 (match_operand:SWI48 2 "register_operand" "r,r")]
13781 (clobber (reg:CC FLAGS_REG))]
13783 "bextr\t{%2, %1, %0|%0, %1, %2}"
13784 [(set_attr "type" "bitmanip")
13785 (set_attr "btver2_decode" "direct, double")
13786 (set_attr "mode" "<MODE>")])
13788 (define_insn "*bmi_bextr_<mode>_ccz"
13789 [(set (reg:CCZ FLAGS_REG)
13791 (unspec:SWI48 [(match_operand:SWI48 1 "nonimmediate_operand" "r,m")
13792 (match_operand:SWI48 2 "register_operand" "r,r")]
13795 (clobber (match_scratch:SWI48 0 "=r,r"))]
13797 "bextr\t{%2, %1, %0|%0, %1, %2}"
13798 [(set_attr "type" "bitmanip")
13799 (set_attr "btver2_decode" "direct, double")
13800 (set_attr "mode" "<MODE>")])
13802 (define_insn "*bmi_blsi_<mode>"
13803 [(set (match_operand:SWI48 0 "register_operand" "=r")
13806 (match_operand:SWI48 1 "nonimmediate_operand" "rm"))
13808 (clobber (reg:CC FLAGS_REG))]
13810 "blsi\t{%1, %0|%0, %1}"
13811 [(set_attr "type" "bitmanip")
13812 (set_attr "btver2_decode" "double")
13813 (set_attr "mode" "<MODE>")])
13815 (define_insn "*bmi_blsmsk_<mode>"
13816 [(set (match_operand:SWI48 0 "register_operand" "=r")
13819 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13822 (clobber (reg:CC FLAGS_REG))]
13824 "blsmsk\t{%1, %0|%0, %1}"
13825 [(set_attr "type" "bitmanip")
13826 (set_attr "btver2_decode" "double")
13827 (set_attr "mode" "<MODE>")])
13829 (define_insn "*bmi_blsr_<mode>"
13830 [(set (match_operand:SWI48 0 "register_operand" "=r")
13833 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13836 (clobber (reg:CC FLAGS_REG))]
13838 "blsr\t{%1, %0|%0, %1}"
13839 [(set_attr "type" "bitmanip")
13840 (set_attr "btver2_decode" "double")
13841 (set_attr "mode" "<MODE>")])
13843 (define_insn "*bmi_blsr_<mode>_cmp"
13844 [(set (reg:CCZ FLAGS_REG)
13848 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13852 (set (match_operand:SWI48 0 "register_operand" "=r")
13859 "blsr\t{%1, %0|%0, %1}"
13860 [(set_attr "type" "bitmanip")
13861 (set_attr "btver2_decode" "double")
13862 (set_attr "mode" "<MODE>")])
13864 (define_insn "*bmi_blsr_<mode>_ccz"
13865 [(set (reg:CCZ FLAGS_REG)
13869 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13873 (clobber (match_scratch:SWI48 0 "=r"))]
13875 "blsr\t{%1, %0|%0, %1}"
13876 [(set_attr "type" "bitmanip")
13877 (set_attr "btver2_decode" "double")
13878 (set_attr "mode" "<MODE>")])
13880 ;; BMI2 instructions.
13881 (define_expand "bmi2_bzhi_<mode>3"
13883 [(set (match_operand:SWI48 0 "register_operand")
13884 (zero_extract:SWI48
13885 (match_operand:SWI48 1 "nonimmediate_operand")
13887 (and:SWI48 (match_operand:SWI48 2 "register_operand")
13891 (clobber (reg:CC FLAGS_REG))])]
13893 "operands[3] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT);")
13895 (define_insn "*bmi2_bzhi_<mode>3"
13896 [(set (match_operand:SWI48 0 "register_operand" "=r")
13897 (zero_extract:SWI48
13898 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13900 (and:SWI48 (match_operand:SWI48 2 "register_operand" "r")
13902 (match_operand:SWI48 3 "const_int_operand" "n"))
13904 (clobber (reg:CC FLAGS_REG))]
13905 "TARGET_BMI2 && INTVAL (operands[3]) == <MODE_SIZE> * BITS_PER_UNIT"
13906 "bzhi\t{%2, %1, %0|%0, %1, %2}"
13907 [(set_attr "type" "bitmanip")
13908 (set_attr "prefix" "vex")
13909 (set_attr "mode" "<MODE>")])
13911 (define_insn "*bmi2_bzhi_<mode>3_1"
13912 [(set (match_operand:SWI48 0 "register_operand" "=r")
13913 (zero_extract:SWI48
13914 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13916 (zero_extend:SWI48 (match_operand:QI 2 "register_operand" "r"))
13917 (match_operand:SWI48 3 "const_int_operand" "n"))
13919 (clobber (reg:CC FLAGS_REG))]
13920 "TARGET_BMI2 && INTVAL (operands[3]) == <MODE_SIZE> * BITS_PER_UNIT"
13921 "bzhi\t{%<k>2, %1, %0|%0, %1, %<k>2}"
13922 [(set_attr "type" "bitmanip")
13923 (set_attr "prefix" "vex")
13924 (set_attr "mode" "<MODE>")])
13926 (define_insn "*bmi2_bzhi_<mode>3_1_ccz"
13927 [(set (reg:CCZ FLAGS_REG)
13929 (zero_extract:SWI48
13930 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13932 (zero_extend:SWI48 (match_operand:QI 2 "register_operand" "r"))
13933 (match_operand:SWI48 3 "const_int_operand" "n"))
13936 (clobber (match_scratch:SWI48 0 "=r"))]
13937 "TARGET_BMI2 && INTVAL (operands[3]) == <MODE_SIZE> * BITS_PER_UNIT"
13938 "bzhi\t{%<k>2, %1, %0|%0, %1, %<k>2}"
13939 [(set_attr "type" "bitmanip")
13940 (set_attr "prefix" "vex")
13941 (set_attr "mode" "<MODE>")])
13943 (define_insn "bmi2_pdep_<mode>3"
13944 [(set (match_operand:SWI48 0 "register_operand" "=r")
13945 (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
13946 (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
13949 "pdep\t{%2, %1, %0|%0, %1, %2}"
13950 [(set_attr "type" "bitmanip")
13951 (set_attr "prefix" "vex")
13952 (set_attr "mode" "<MODE>")])
13954 (define_insn "bmi2_pext_<mode>3"
13955 [(set (match_operand:SWI48 0 "register_operand" "=r")
13956 (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
13957 (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
13960 "pext\t{%2, %1, %0|%0, %1, %2}"
13961 [(set_attr "type" "bitmanip")
13962 (set_attr "prefix" "vex")
13963 (set_attr "mode" "<MODE>")])
13965 ;; TBM instructions.
13966 (define_insn "tbm_bextri_<mode>"
13967 [(set (match_operand:SWI48 0 "register_operand" "=r")
13968 (zero_extract:SWI48
13969 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13970 (match_operand 2 "const_0_to_255_operand" "N")
13971 (match_operand 3 "const_0_to_255_operand" "N")))
13972 (clobber (reg:CC FLAGS_REG))]
13975 operands[2] = GEN_INT (INTVAL (operands[2]) << 8 | INTVAL (operands[3]));
13976 return "bextr\t{%2, %1, %0|%0, %1, %2}";
13978 [(set_attr "type" "bitmanip")
13979 (set_attr "mode" "<MODE>")])
13981 (define_insn "*tbm_blcfill_<mode>"
13982 [(set (match_operand:SWI48 0 "register_operand" "=r")
13985 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13988 (clobber (reg:CC FLAGS_REG))]
13990 "blcfill\t{%1, %0|%0, %1}"
13991 [(set_attr "type" "bitmanip")
13992 (set_attr "mode" "<MODE>")])
13994 (define_insn "*tbm_blci_<mode>"
13995 [(set (match_operand:SWI48 0 "register_operand" "=r")
13999 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
14002 (clobber (reg:CC FLAGS_REG))]
14004 "blci\t{%1, %0|%0, %1}"
14005 [(set_attr "type" "bitmanip")
14006 (set_attr "mode" "<MODE>")])
14008 (define_insn "*tbm_blcic_<mode>"
14009 [(set (match_operand:SWI48 0 "register_operand" "=r")
14012 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
14016 (clobber (reg:CC FLAGS_REG))]
14018 "blcic\t{%1, %0|%0, %1}"
14019 [(set_attr "type" "bitmanip")
14020 (set_attr "mode" "<MODE>")])
14022 (define_insn "*tbm_blcmsk_<mode>"
14023 [(set (match_operand:SWI48 0 "register_operand" "=r")
14026 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
14029 (clobber (reg:CC FLAGS_REG))]
14031 "blcmsk\t{%1, %0|%0, %1}"
14032 [(set_attr "type" "bitmanip")
14033 (set_attr "mode" "<MODE>")])
14035 (define_insn "*tbm_blcs_<mode>"
14036 [(set (match_operand:SWI48 0 "register_operand" "=r")
14039 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
14042 (clobber (reg:CC FLAGS_REG))]
14044 "blcs\t{%1, %0|%0, %1}"
14045 [(set_attr "type" "bitmanip")
14046 (set_attr "mode" "<MODE>")])
14048 (define_insn "*tbm_blsfill_<mode>"
14049 [(set (match_operand:SWI48 0 "register_operand" "=r")
14052 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
14055 (clobber (reg:CC FLAGS_REG))]
14057 "blsfill\t{%1, %0|%0, %1}"
14058 [(set_attr "type" "bitmanip")
14059 (set_attr "mode" "<MODE>")])
14061 (define_insn "*tbm_blsic_<mode>"
14062 [(set (match_operand:SWI48 0 "register_operand" "=r")
14065 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
14069 (clobber (reg:CC FLAGS_REG))]
14071 "blsic\t{%1, %0|%0, %1}"
14072 [(set_attr "type" "bitmanip")
14073 (set_attr "mode" "<MODE>")])
14075 (define_insn "*tbm_t1mskc_<mode>"
14076 [(set (match_operand:SWI48 0 "register_operand" "=r")
14079 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
14083 (clobber (reg:CC FLAGS_REG))]
14085 "t1mskc\t{%1, %0|%0, %1}"
14086 [(set_attr "type" "bitmanip")
14087 (set_attr "mode" "<MODE>")])
14089 (define_insn "*tbm_tzmsk_<mode>"
14090 [(set (match_operand:SWI48 0 "register_operand" "=r")
14093 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
14097 (clobber (reg:CC FLAGS_REG))]
14099 "tzmsk\t{%1, %0|%0, %1}"
14100 [(set_attr "type" "bitmanip")
14101 (set_attr "mode" "<MODE>")])
14103 (define_insn_and_split "popcount<mode>2"
14104 [(set (match_operand:SWI48 0 "register_operand" "=r")
14106 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
14107 (clobber (reg:CC FLAGS_REG))]
14111 return "popcnt\t{%1, %0|%0, %1}";
14113 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
14116 "&& TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
14117 && optimize_function_for_speed_p (cfun)
14118 && !reg_mentioned_p (operands[0], operands[1])"
14120 [(set (match_dup 0)
14121 (popcount:SWI48 (match_dup 1)))
14122 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
14123 (clobber (reg:CC FLAGS_REG))])]
14124 "ix86_expand_clear (operands[0]);"
14125 [(set_attr "prefix_rep" "1")
14126 (set_attr "type" "bitmanip")
14127 (set_attr "mode" "<MODE>")])
14129 ; False dependency happens when destination is only updated by tzcnt,
14130 ; lzcnt or popcnt. There is no false dependency when destination is
14131 ; also used in source.
14132 (define_insn "*popcount<mode>2_falsedep"
14133 [(set (match_operand:SWI48 0 "register_operand" "=r")
14135 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
14136 (unspec [(match_operand:SWI48 2 "register_operand" "0")]
14137 UNSPEC_INSN_FALSE_DEP)
14138 (clobber (reg:CC FLAGS_REG))]
14142 return "popcnt\t{%1, %0|%0, %1}";
14144 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
14147 [(set_attr "prefix_rep" "1")
14148 (set_attr "type" "bitmanip")
14149 (set_attr "mode" "<MODE>")])
14151 (define_insn_and_split "*popcounthi2_1"
14152 [(set (match_operand:SI 0 "register_operand")
14154 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand"))))
14155 (clobber (reg:CC FLAGS_REG))]
14157 && can_create_pseudo_p ()"
14162 rtx tmp = gen_reg_rtx (HImode);
14164 emit_insn (gen_popcounthi2 (tmp, operands[1]));
14165 emit_insn (gen_zero_extendhisi2 (operands[0], tmp));
14169 (define_insn "popcounthi2"
14170 [(set (match_operand:HI 0 "register_operand" "=r")
14172 (match_operand:HI 1 "nonimmediate_operand" "rm")))
14173 (clobber (reg:CC FLAGS_REG))]
14177 return "popcnt\t{%1, %0|%0, %1}";
14179 return "popcnt{w}\t{%1, %0|%0, %1}";
14182 [(set_attr "prefix_rep" "1")
14183 (set_attr "type" "bitmanip")
14184 (set_attr "mode" "HI")])
14186 (define_expand "bswapdi2"
14187 [(set (match_operand:DI 0 "register_operand")
14188 (bswap:DI (match_operand:DI 1 "nonimmediate_operand")))]
14192 operands[1] = force_reg (DImode, operands[1]);
14195 (define_expand "bswapsi2"
14196 [(set (match_operand:SI 0 "register_operand")
14197 (bswap:SI (match_operand:SI 1 "nonimmediate_operand")))]
14202 else if (TARGET_BSWAP)
14203 operands[1] = force_reg (SImode, operands[1]);
14206 rtx x = operands[0];
14208 emit_move_insn (x, operands[1]);
14209 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
14210 emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
14211 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
14216 (define_insn "*bswap<mode>2_movbe"
14217 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,r,m")
14218 (bswap:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,m,r")))]
14220 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
14223 movbe{<imodesuffix>}\t{%1, %0|%0, %1}
14224 movbe{<imodesuffix>}\t{%1, %0|%0, %1}"
14225 [(set_attr "type" "bitmanip,imov,imov")
14226 (set_attr "modrm" "0,1,1")
14227 (set_attr "prefix_0f" "*,1,1")
14228 (set_attr "prefix_extra" "*,1,1")
14229 (set_attr "mode" "<MODE>")])
14231 (define_insn "*bswap<mode>2"
14232 [(set (match_operand:SWI48 0 "register_operand" "=r")
14233 (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "0")))]
14236 [(set_attr "type" "bitmanip")
14237 (set_attr "modrm" "0")
14238 (set_attr "mode" "<MODE>")])
14240 (define_expand "bswaphi2"
14241 [(set (match_operand:HI 0 "register_operand")
14242 (bswap:HI (match_operand:HI 1 "nonimmediate_operand")))]
14245 (define_insn "*bswaphi2_movbe"
14246 [(set (match_operand:HI 0 "nonimmediate_operand" "=Q,r,m")
14247 (bswap:HI (match_operand:HI 1 "nonimmediate_operand" "0,m,r")))]
14249 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
14251 xchg{b}\t{%h0, %b0|%b0, %h0}
14252 movbe{w}\t{%1, %0|%0, %1}
14253 movbe{w}\t{%1, %0|%0, %1}"
14254 [(set_attr "type" "imov")
14255 (set_attr "modrm" "*,1,1")
14256 (set_attr "prefix_0f" "*,1,1")
14257 (set_attr "prefix_extra" "*,1,1")
14258 (set_attr "pent_pair" "np,*,*")
14259 (set_attr "athlon_decode" "vector,*,*")
14260 (set_attr "amdfam10_decode" "double,*,*")
14261 (set_attr "bdver1_decode" "double,*,*")
14262 (set_attr "mode" "QI,HI,HI")])
14265 [(set (match_operand:HI 0 "general_reg_operand")
14266 (bswap:HI (match_dup 0)))]
14268 && !(TARGET_USE_XCHGB || optimize_function_for_size_p (cfun))
14269 && peep2_regno_dead_p (0, FLAGS_REG)"
14270 [(parallel [(set (match_dup 0) (rotate:HI (match_dup 0) (const_int 8)))
14271 (clobber (reg:CC FLAGS_REG))])])
14273 (define_insn "bswaphi_lowpart"
14274 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
14275 (bswap:HI (match_dup 0)))
14276 (clobber (reg:CC FLAGS_REG))]
14279 xchg{b}\t{%h0, %b0|%b0, %h0}
14280 rol{w}\t{$8, %0|%0, 8}"
14281 [(set (attr "preferred_for_size")
14282 (cond [(eq_attr "alternative" "0")
14283 (symbol_ref "true")]
14284 (symbol_ref "false")))
14285 (set (attr "preferred_for_speed")
14286 (cond [(eq_attr "alternative" "0")
14287 (symbol_ref "TARGET_USE_XCHGB")]
14288 (symbol_ref "!TARGET_USE_XCHGB")))
14289 (set_attr "length" "2,4")
14290 (set_attr "mode" "QI,HI")])
14292 (define_expand "paritydi2"
14293 [(set (match_operand:DI 0 "register_operand")
14294 (parity:DI (match_operand:DI 1 "register_operand")))]
14297 rtx scratch = gen_reg_rtx (QImode);
14299 emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX,
14300 NULL_RTX, operands[1]));
14302 ix86_expand_setcc (scratch, ORDERED,
14303 gen_rtx_REG (CCmode, FLAGS_REG), const0_rtx);
14306 emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
14309 rtx tmp = gen_reg_rtx (SImode);
14311 emit_insn (gen_zero_extendqisi2 (tmp, scratch));
14312 emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
14317 (define_expand "paritysi2"
14318 [(set (match_operand:SI 0 "register_operand")
14319 (parity:SI (match_operand:SI 1 "register_operand")))]
14322 rtx scratch = gen_reg_rtx (QImode);
14324 emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1]));
14326 ix86_expand_setcc (scratch, ORDERED,
14327 gen_rtx_REG (CCmode, FLAGS_REG), const0_rtx);
14329 emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
14333 (define_insn_and_split "paritydi2_cmp"
14334 [(set (reg:CC FLAGS_REG)
14335 (unspec:CC [(match_operand:DI 3 "register_operand" "0")]
14337 (clobber (match_scratch:DI 0 "=r"))
14338 (clobber (match_scratch:SI 1 "=&r"))
14339 (clobber (match_scratch:HI 2 "=Q"))]
14342 "&& reload_completed"
14344 [(set (match_dup 1)
14345 (xor:SI (match_dup 1) (match_dup 4)))
14346 (clobber (reg:CC FLAGS_REG))])
14348 [(set (reg:CC FLAGS_REG)
14349 (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
14350 (clobber (match_dup 1))
14351 (clobber (match_dup 2))])]
14353 operands[4] = gen_lowpart (SImode, operands[3]);
14357 emit_move_insn (operands[1], gen_lowpart (SImode, operands[3]));
14358 emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32)));
14361 operands[1] = gen_highpart (SImode, operands[3]);
14364 (define_insn_and_split "paritysi2_cmp"
14365 [(set (reg:CC FLAGS_REG)
14366 (unspec:CC [(match_operand:SI 2 "register_operand" "0")]
14368 (clobber (match_scratch:SI 0 "=r"))
14369 (clobber (match_scratch:HI 1 "=&Q"))]
14372 "&& reload_completed"
14374 [(set (match_dup 1)
14375 (xor:HI (match_dup 1) (match_dup 3)))
14376 (clobber (reg:CC FLAGS_REG))])
14378 [(set (reg:CC FLAGS_REG)
14379 (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
14380 (clobber (match_dup 1))])]
14382 operands[3] = gen_lowpart (HImode, operands[2]);
14384 emit_move_insn (operands[1], gen_lowpart (HImode, operands[2]));
14385 emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16)));
14388 (define_insn "*parityhi2_cmp"
14389 [(set (reg:CC FLAGS_REG)
14390 (unspec:CC [(match_operand:HI 1 "register_operand" "0")]
14392 (clobber (match_scratch:HI 0 "=Q"))]
14394 "xor{b}\t{%h0, %b0|%b0, %h0}"
14395 [(set_attr "length" "2")
14396 (set_attr "mode" "HI")])
14399 ;; Thread-local storage patterns for ELF.
14401 ;; Note that these code sequences must appear exactly as shown
14402 ;; in order to allow linker relaxation.
14404 (define_insn "*tls_global_dynamic_32_gnu"
14405 [(set (match_operand:SI 0 "register_operand" "=a")
14407 [(match_operand:SI 1 "register_operand" "Yb")
14408 (match_operand 2 "tls_symbolic_operand")
14409 (match_operand 3 "constant_call_address_operand" "Bz")
14412 (clobber (match_scratch:SI 4 "=d"))
14413 (clobber (match_scratch:SI 5 "=c"))
14414 (clobber (reg:CC FLAGS_REG))]
14415 "!TARGET_64BIT && TARGET_GNU_TLS"
14417 if (TARGET_SUN_TLS || flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT)
14419 ("lea{l}\t{%E2@tlsgd(,%1,1), %0|%0, %E2@tlsgd[%1*1]}", operands);
14422 ("lea{l}\t{%E2@tlsgd(%1), %0|%0, %E2@tlsgd[%1]}", operands);
14423 if (TARGET_SUN_TLS)
14424 #ifdef HAVE_AS_IX86_TLSGDPLT
14425 return "call\t%a2@tlsgdplt";
14427 return "call\t%p3@plt";
14429 if (flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT)
14430 return "call\t%P3";
14431 return "call\t{*%p3@GOT(%1)|[DWORD PTR %p3@GOT[%1]]}";
14433 [(set_attr "type" "multi")
14434 (set_attr "length" "12")])
14436 (define_expand "tls_global_dynamic_32"
14438 [(set (match_operand:SI 0 "register_operand")
14439 (unspec:SI [(match_operand:SI 2 "register_operand")
14440 (match_operand 1 "tls_symbolic_operand")
14441 (match_operand 3 "constant_call_address_operand")
14444 (clobber (match_scratch:SI 4))
14445 (clobber (match_scratch:SI 5))
14446 (clobber (reg:CC FLAGS_REG))])]
14448 "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
14450 (define_insn "*tls_global_dynamic_64_<mode>"
14451 [(set (match_operand:P 0 "register_operand" "=a")
14453 (mem:QI (match_operand 2 "constant_call_address_operand" "Bz"))
14454 (match_operand 3)))
14455 (unspec:P [(match_operand 1 "tls_symbolic_operand")
14461 fputs (ASM_BYTE "0x66\n", asm_out_file);
14463 ("lea{q}\t{%E1@tlsgd(%%rip), %%rdi|rdi, %E1@tlsgd[rip]}", operands);
14464 if (TARGET_SUN_TLS || flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT)
14465 fputs (ASM_SHORT "0x6666\n", asm_out_file);
14467 fputs (ASM_BYTE "0x66\n", asm_out_file);
14468 fputs ("\trex64\n", asm_out_file);
14469 if (TARGET_SUN_TLS)
14470 return "call\t%p2@plt";
14471 if (flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT)
14472 return "call\t%P2";
14473 return "call\t{*%p2@GOTPCREL(%%rip)|[QWORD PTR %p2@GOTPCREL[rip]]}";
14475 [(set_attr "type" "multi")
14476 (set (attr "length")
14477 (symbol_ref "TARGET_X32 ? 15 : 16"))])
14479 (define_insn "*tls_global_dynamic_64_largepic"
14480 [(set (match_operand:DI 0 "register_operand" "=a")
14482 (mem:QI (plus:DI (match_operand:DI 2 "register_operand" "b")
14483 (match_operand:DI 3 "immediate_operand" "i")))
14484 (match_operand 4)))
14485 (unspec:DI [(match_operand 1 "tls_symbolic_operand")
14488 "TARGET_64BIT && ix86_cmodel == CM_LARGE_PIC && !TARGET_PECOFF
14489 && GET_CODE (operands[3]) == CONST
14490 && GET_CODE (XEXP (operands[3], 0)) == UNSPEC
14491 && XINT (XEXP (operands[3], 0), 1) == UNSPEC_PLTOFF"
14494 ("lea{q}\t{%E1@tlsgd(%%rip), %%rdi|rdi, %E1@tlsgd[rip]}", operands);
14495 output_asm_insn ("movabs{q}\t{%3, %%rax|rax, %3}", operands);
14496 output_asm_insn ("add{q}\t{%2, %%rax|rax, %2}", operands);
14497 return "call\t{*%%rax|rax}";
14499 [(set_attr "type" "multi")
14500 (set_attr "length" "22")])
14502 (define_expand "tls_global_dynamic_64_<mode>"
14504 [(set (match_operand:P 0 "register_operand")
14506 (mem:QI (match_operand 2))
14508 (unspec:P [(match_operand 1 "tls_symbolic_operand")
14512 "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
14514 (define_insn "*tls_local_dynamic_base_32_gnu"
14515 [(set (match_operand:SI 0 "register_operand" "=a")
14517 [(match_operand:SI 1 "register_operand" "Yb")
14518 (match_operand 2 "constant_call_address_operand" "Bz")
14520 UNSPEC_TLS_LD_BASE))
14521 (clobber (match_scratch:SI 3 "=d"))
14522 (clobber (match_scratch:SI 4 "=c"))
14523 (clobber (reg:CC FLAGS_REG))]
14524 "!TARGET_64BIT && TARGET_GNU_TLS"
14527 ("lea{l}\t{%&@tlsldm(%1), %0|%0, %&@tlsldm[%1]}", operands);
14528 if (TARGET_SUN_TLS)
14530 if (HAVE_AS_IX86_TLSLDMPLT)
14531 return "call\t%&@tlsldmplt";
14533 return "call\t%p2@plt";
14535 if (flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT)
14536 return "call\t%P2";
14537 return "call\t{*%p2@GOT(%1)|[DWORD PTR %p2@GOT[%1]]}";
14539 [(set_attr "type" "multi")
14540 (set_attr "length" "11")])
14542 (define_expand "tls_local_dynamic_base_32"
14544 [(set (match_operand:SI 0 "register_operand")
14546 [(match_operand:SI 1 "register_operand")
14547 (match_operand 2 "constant_call_address_operand")
14549 UNSPEC_TLS_LD_BASE))
14550 (clobber (match_scratch:SI 3))
14551 (clobber (match_scratch:SI 4))
14552 (clobber (reg:CC FLAGS_REG))])]
14554 "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
14556 (define_insn "*tls_local_dynamic_base_64_<mode>"
14557 [(set (match_operand:P 0 "register_operand" "=a")
14559 (mem:QI (match_operand 1 "constant_call_address_operand" "Bz"))
14560 (match_operand 2)))
14561 (unspec:P [(reg:P SP_REG)] UNSPEC_TLS_LD_BASE)]
14565 ("lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}", operands);
14566 if (TARGET_SUN_TLS)
14567 return "call\t%p1@plt";
14568 if (flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT)
14569 return "call\t%P1";
14570 return "call\t{*%p1@GOTPCREL(%%rip)|[QWORD PTR %p1@GOTPCREL[rip]]}";
14572 [(set_attr "type" "multi")
14573 (set_attr "length" "12")])
14575 (define_insn "*tls_local_dynamic_base_64_largepic"
14576 [(set (match_operand:DI 0 "register_operand" "=a")
14578 (mem:QI (plus:DI (match_operand:DI 1 "register_operand" "b")
14579 (match_operand:DI 2 "immediate_operand" "i")))
14580 (match_operand 3)))
14581 (unspec:DI [(reg:DI SP_REG)] UNSPEC_TLS_LD_BASE)]
14582 "TARGET_64BIT && ix86_cmodel == CM_LARGE_PIC && !TARGET_PECOFF
14583 && GET_CODE (operands[2]) == CONST
14584 && GET_CODE (XEXP (operands[2], 0)) == UNSPEC
14585 && XINT (XEXP (operands[2], 0), 1) == UNSPEC_PLTOFF"
14588 ("lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}", operands);
14589 output_asm_insn ("movabs{q}\t{%2, %%rax|rax, %2}", operands);
14590 output_asm_insn ("add{q}\t{%1, %%rax|rax, %1}", operands);
14591 return "call\t{*%%rax|rax}";
14593 [(set_attr "type" "multi")
14594 (set_attr "length" "22")])
14596 (define_expand "tls_local_dynamic_base_64_<mode>"
14598 [(set (match_operand:P 0 "register_operand")
14600 (mem:QI (match_operand 1))
14602 (unspec:P [(reg:P SP_REG)] UNSPEC_TLS_LD_BASE)])]
14604 "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
14606 ;; Local dynamic of a single variable is a lose. Show combine how
14607 ;; to convert that back to global dynamic.
14609 (define_insn_and_split "*tls_local_dynamic_32_once"
14610 [(set (match_operand:SI 0 "register_operand" "=a")
14612 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14613 (match_operand 2 "constant_call_address_operand" "Bz")
14615 UNSPEC_TLS_LD_BASE)
14616 (const:SI (unspec:SI
14617 [(match_operand 3 "tls_symbolic_operand")]
14619 (clobber (match_scratch:SI 4 "=d"))
14620 (clobber (match_scratch:SI 5 "=c"))
14621 (clobber (reg:CC FLAGS_REG))]
14626 [(set (match_dup 0)
14627 (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)
14630 (clobber (match_dup 4))
14631 (clobber (match_dup 5))
14632 (clobber (reg:CC FLAGS_REG))])])
14634 ;; Load and add the thread base pointer from %<tp_seg>:0.
14635 (define_insn_and_split "*load_tp_<mode>"
14636 [(set (match_operand:PTR 0 "register_operand" "=r")
14637 (unspec:PTR [(const_int 0)] UNSPEC_TP))]
14641 [(set (match_dup 0)
14644 addr_space_t as = DEFAULT_TLS_SEG_REG;
14646 operands[1] = gen_const_mem (<MODE>mode, const0_rtx);
14647 set_mem_addr_space (operands[1], as);
14650 (define_insn_and_split "*load_tp_x32_zext"
14651 [(set (match_operand:DI 0 "register_operand" "=r")
14653 (unspec:SI [(const_int 0)] UNSPEC_TP)))]
14657 [(set (match_dup 0)
14658 (zero_extend:DI (match_dup 1)))]
14660 addr_space_t as = DEFAULT_TLS_SEG_REG;
14662 operands[1] = gen_const_mem (SImode, const0_rtx);
14663 set_mem_addr_space (operands[1], as);
14666 (define_insn_and_split "*add_tp_<mode>"
14667 [(set (match_operand:PTR 0 "register_operand" "=r")
14669 (unspec:PTR [(const_int 0)] UNSPEC_TP)
14670 (match_operand:PTR 1 "register_operand" "0")))
14671 (clobber (reg:CC FLAGS_REG))]
14676 [(set (match_dup 0)
14677 (plus:PTR (match_dup 1) (match_dup 2)))
14678 (clobber (reg:CC FLAGS_REG))])]
14680 addr_space_t as = DEFAULT_TLS_SEG_REG;
14682 operands[2] = gen_const_mem (<MODE>mode, const0_rtx);
14683 set_mem_addr_space (operands[2], as);
14686 (define_insn_and_split "*add_tp_x32_zext"
14687 [(set (match_operand:DI 0 "register_operand" "=r")
14689 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
14690 (match_operand:SI 1 "register_operand" "0"))))
14691 (clobber (reg:CC FLAGS_REG))]
14696 [(set (match_dup 0)
14698 (plus:SI (match_dup 1) (match_dup 2))))
14699 (clobber (reg:CC FLAGS_REG))])]
14701 addr_space_t as = DEFAULT_TLS_SEG_REG;
14703 operands[2] = gen_const_mem (SImode, const0_rtx);
14704 set_mem_addr_space (operands[2], as);
14707 ;; The Sun linker took the AMD64 TLS spec literally and can only handle
14708 ;; %rax as destination of the initial executable code sequence.
14709 (define_insn "tls_initial_exec_64_sun"
14710 [(set (match_operand:DI 0 "register_operand" "=a")
14712 [(match_operand 1 "tls_symbolic_operand")]
14713 UNSPEC_TLS_IE_SUN))
14714 (clobber (reg:CC FLAGS_REG))]
14715 "TARGET_64BIT && TARGET_SUN_TLS"
14718 ("mov{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}", operands);
14719 return "add{q}\t{%a1@gottpoff(%%rip), %0|%0, %a1@gottpoff[rip]}";
14721 [(set_attr "type" "multi")])
14723 ;; GNU2 TLS patterns can be split.
14725 (define_expand "tls_dynamic_gnu2_32"
14726 [(set (match_dup 3)
14727 (plus:SI (match_operand:SI 2 "register_operand")
14729 (unspec:SI [(match_operand 1 "tls_symbolic_operand")]
14732 [(set (match_operand:SI 0 "register_operand")
14733 (unspec:SI [(match_dup 1) (match_dup 3)
14734 (match_dup 2) (reg:SI SP_REG)]
14736 (clobber (reg:CC FLAGS_REG))])]
14737 "!TARGET_64BIT && TARGET_GNU2_TLS"
14739 operands[3] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
14740 ix86_tls_descriptor_calls_expanded_in_cfun = true;
14743 (define_insn "*tls_dynamic_gnu2_lea_32"
14744 [(set (match_operand:SI 0 "register_operand" "=r")
14745 (plus:SI (match_operand:SI 1 "register_operand" "b")
14747 (unspec:SI [(match_operand 2 "tls_symbolic_operand")]
14748 UNSPEC_TLSDESC))))]
14749 "!TARGET_64BIT && TARGET_GNU2_TLS"
14750 "lea{l}\t{%E2@TLSDESC(%1), %0|%0, %E2@TLSDESC[%1]}"
14751 [(set_attr "type" "lea")
14752 (set_attr "mode" "SI")
14753 (set_attr "length" "6")
14754 (set_attr "length_address" "4")])
14756 (define_insn "*tls_dynamic_gnu2_call_32"
14757 [(set (match_operand:SI 0 "register_operand" "=a")
14758 (unspec:SI [(match_operand 1 "tls_symbolic_operand")
14759 (match_operand:SI 2 "register_operand" "0")
14760 ;; we have to make sure %ebx still points to the GOT
14761 (match_operand:SI 3 "register_operand" "b")
14764 (clobber (reg:CC FLAGS_REG))]
14765 "!TARGET_64BIT && TARGET_GNU2_TLS"
14766 "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
14767 [(set_attr "type" "call")
14768 (set_attr "length" "2")
14769 (set_attr "length_address" "0")])
14771 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
14772 [(set (match_operand:SI 0 "register_operand" "=&a")
14774 (unspec:SI [(match_operand 3 "tls_modbase_operand")
14775 (match_operand:SI 4)
14776 (match_operand:SI 2 "register_operand" "b")
14779 (const:SI (unspec:SI
14780 [(match_operand 1 "tls_symbolic_operand")]
14782 (clobber (reg:CC FLAGS_REG))]
14783 "!TARGET_64BIT && TARGET_GNU2_TLS"
14786 [(set (match_dup 0) (match_dup 5))]
14788 operands[5] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
14789 emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
14792 (define_expand "tls_dynamic_gnu2_64"
14793 [(set (match_dup 2)
14794 (unspec:DI [(match_operand 1 "tls_symbolic_operand")]
14797 [(set (match_operand:DI 0 "register_operand")
14798 (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
14800 (clobber (reg:CC FLAGS_REG))])]
14801 "TARGET_64BIT && TARGET_GNU2_TLS"
14803 operands[2] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
14804 ix86_tls_descriptor_calls_expanded_in_cfun = true;
14807 (define_insn "*tls_dynamic_gnu2_lea_64"
14808 [(set (match_operand:DI 0 "register_operand" "=r")
14809 (unspec:DI [(match_operand 1 "tls_symbolic_operand")]
14811 "TARGET_64BIT && TARGET_GNU2_TLS"
14812 "lea{q}\t{%E1@TLSDESC(%%rip), %0|%0, %E1@TLSDESC[rip]}"
14813 [(set_attr "type" "lea")
14814 (set_attr "mode" "DI")
14815 (set_attr "length" "7")
14816 (set_attr "length_address" "4")])
14818 (define_insn "*tls_dynamic_gnu2_call_64"
14819 [(set (match_operand:DI 0 "register_operand" "=a")
14820 (unspec:DI [(match_operand 1 "tls_symbolic_operand")
14821 (match_operand:DI 2 "register_operand" "0")
14824 (clobber (reg:CC FLAGS_REG))]
14825 "TARGET_64BIT && TARGET_GNU2_TLS"
14826 "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
14827 [(set_attr "type" "call")
14828 (set_attr "length" "2")
14829 (set_attr "length_address" "0")])
14831 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
14832 [(set (match_operand:DI 0 "register_operand" "=&a")
14834 (unspec:DI [(match_operand 2 "tls_modbase_operand")
14835 (match_operand:DI 3)
14838 (const:DI (unspec:DI
14839 [(match_operand 1 "tls_symbolic_operand")]
14841 (clobber (reg:CC FLAGS_REG))]
14842 "TARGET_64BIT && TARGET_GNU2_TLS"
14845 [(set (match_dup 0) (match_dup 4))]
14847 operands[4] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
14848 emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
14852 [(match_operand 0 "tls_address_pattern")]
14853 "TARGET_TLS_DIRECT_SEG_REFS"
14855 "operands[0] = ix86_rewrite_tls_address (operands[0]);")
14858 ;; These patterns match the binary 387 instructions for addM3, subM3,
14859 ;; mulM3 and divM3. There are three patterns for each of DFmode and
14860 ;; SFmode. The first is the normal insn, the second the same insn but
14861 ;; with one operand a conversion, and the third the same insn but with
14862 ;; the other operand a conversion. The conversion may be SFmode or
14863 ;; SImode if the target mode DFmode, but only SImode if the target mode
14866 ;; Gcc is slightly more smart about handling normal two address instructions
14867 ;; so use special patterns for add and mull.
14869 (define_insn "*fop_<mode>_comm"
14870 [(set (match_operand:MODEF 0 "register_operand" "=f,x,v")
14871 (match_operator:MODEF 3 "binary_fp_operator"
14872 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,0,v")
14873 (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm,vm")]))]
14874 "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14875 || (TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)))
14876 && COMMUTATIVE_ARITH_P (operands[3])
14877 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
14878 "* return output_387_binary_op (insn, operands);"
14879 [(set (attr "type")
14880 (if_then_else (eq_attr "alternative" "1,2")
14881 (if_then_else (match_operand:MODEF 3 "mult_operator")
14882 (const_string "ssemul")
14883 (const_string "sseadd"))
14884 (if_then_else (match_operand:MODEF 3 "mult_operator")
14885 (const_string "fmul")
14886 (const_string "fop"))))
14887 (set_attr "isa" "*,noavx,avx")
14888 (set_attr "prefix" "orig,orig,vex")
14889 (set_attr "mode" "<MODE>")
14890 (set (attr "enabled")
14892 (match_test ("SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"))
14894 (eq_attr "alternative" "0")
14895 (symbol_ref "TARGET_MIX_SSE_I387
14896 && X87_ENABLE_ARITH (<MODE>mode)")
14897 (const_string "*"))
14899 (eq_attr "alternative" "0")
14900 (symbol_ref "true")
14901 (symbol_ref "false"))))])
14903 (define_insn "*rcpsf2_sse"
14904 [(set (match_operand:SF 0 "register_operand" "=x")
14905 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
14907 "TARGET_SSE && TARGET_SSE_MATH"
14908 "%vrcpss\t{%1, %d0|%d0, %1}"
14909 [(set_attr "type" "sse")
14910 (set_attr "atom_sse_attr" "rcp")
14911 (set_attr "btver2_sse_attr" "rcp")
14912 (set_attr "prefix" "maybe_vex")
14913 (set_attr "mode" "SF")])
14915 (define_insn "*fop_<mode>_1"
14916 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,v")
14917 (match_operator:MODEF 3 "binary_fp_operator"
14918 [(match_operand:MODEF 1
14919 "x87nonimm_ssenomem_operand" "0,fm,0,v")
14920 (match_operand:MODEF 2
14921 "nonimmediate_operand" "fm,0,xm,vm")]))]
14922 "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14923 || (TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)))
14924 && !COMMUTATIVE_ARITH_P (operands[3])
14925 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
14926 "* return output_387_binary_op (insn, operands);"
14927 [(set (attr "type")
14928 (if_then_else (eq_attr "alternative" "2,3")
14929 (if_then_else (match_operand:MODEF 3 "div_operator")
14930 (const_string "ssediv")
14931 (const_string "sseadd"))
14932 (if_then_else (match_operand:MODEF 3 "div_operator")
14933 (const_string "fdiv")
14934 (const_string "fop"))))
14935 (set_attr "isa" "*,*,noavx,avx")
14936 (set_attr "prefix" "orig,orig,orig,vex")
14937 (set_attr "mode" "<MODE>")
14938 (set (attr "enabled")
14940 (match_test ("SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"))
14942 (eq_attr "alternative" "0,1")
14943 (symbol_ref "TARGET_MIX_SSE_I387
14944 && X87_ENABLE_ARITH (<MODE>mode)")
14945 (const_string "*"))
14947 (eq_attr "alternative" "0,1")
14948 (symbol_ref "true")
14949 (symbol_ref "false"))))])
14951 ;; ??? Add SSE splitters for these!
14952 (define_insn "*fop_<MODEF:mode>_2_i387"
14953 [(set (match_operand:MODEF 0 "register_operand" "=f")
14954 (match_operator:MODEF 3 "binary_fp_operator"
14956 (match_operand:SWI24 1 "nonimmediate_operand" "m"))
14957 (match_operand:MODEF 2 "register_operand" "0")]))]
14958 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI24:MODE>mode)
14959 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
14960 && (TARGET_USE_<SWI24:MODE>MODE_FIOP
14961 || optimize_function_for_size_p (cfun))"
14962 "* return output_387_binary_op (insn, operands);"
14963 [(set (attr "type")
14964 (cond [(match_operand:MODEF 3 "mult_operator")
14965 (const_string "fmul")
14966 (match_operand:MODEF 3 "div_operator")
14967 (const_string "fdiv")
14969 (const_string "fop")))
14970 (set_attr "fp_int_src" "true")
14971 (set_attr "mode" "<SWI24:MODE>")])
14973 (define_insn "*fop_<MODEF:mode>_3_i387"
14974 [(set (match_operand:MODEF 0 "register_operand" "=f")
14975 (match_operator:MODEF 3 "binary_fp_operator"
14976 [(match_operand:MODEF 1 "register_operand" "0")
14978 (match_operand:SWI24 2 "nonimmediate_operand" "m"))]))]
14979 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI24:MODE>mode)
14980 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
14981 && (TARGET_USE_<SWI24:MODE>MODE_FIOP
14982 || optimize_function_for_size_p (cfun))"
14983 "* return output_387_binary_op (insn, operands);"
14984 [(set (attr "type")
14985 (cond [(match_operand:MODEF 3 "mult_operator")
14986 (const_string "fmul")
14987 (match_operand:MODEF 3 "div_operator")
14988 (const_string "fdiv")
14990 (const_string "fop")))
14991 (set_attr "fp_int_src" "true")
14992 (set_attr "mode" "<MODE>")])
14994 (define_insn "*fop_df_4_i387"
14995 [(set (match_operand:DF 0 "register_operand" "=f,f")
14996 (match_operator:DF 3 "binary_fp_operator"
14998 (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
14999 (match_operand:DF 2 "register_operand" "0,f")]))]
15000 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
15001 && !(SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
15002 "* return output_387_binary_op (insn, operands);"
15003 [(set (attr "type")
15004 (cond [(match_operand:DF 3 "mult_operator")
15005 (const_string "fmul")
15006 (match_operand:DF 3 "div_operator")
15007 (const_string "fdiv")
15009 (const_string "fop")))
15010 (set_attr "mode" "SF")])
15012 (define_insn "*fop_df_5_i387"
15013 [(set (match_operand:DF 0 "register_operand" "=f,f")
15014 (match_operator:DF 3 "binary_fp_operator"
15015 [(match_operand:DF 1 "register_operand" "0,f")
15017 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
15018 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
15019 && !(SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
15020 "* return output_387_binary_op (insn, operands);"
15021 [(set (attr "type")
15022 (cond [(match_operand:DF 3 "mult_operator")
15023 (const_string "fmul")
15024 (match_operand:DF 3 "div_operator")
15025 (const_string "fdiv")
15027 (const_string "fop")))
15028 (set_attr "mode" "SF")])
15030 (define_insn "*fop_df_6_i387"
15031 [(set (match_operand:DF 0 "register_operand" "=f,f")
15032 (match_operator:DF 3 "binary_fp_operator"
15034 (match_operand:SF 1 "register_operand" "0,f"))
15036 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
15037 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
15038 && !(SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
15039 "* return output_387_binary_op (insn, operands);"
15040 [(set (attr "type")
15041 (cond [(match_operand:DF 3 "mult_operator")
15042 (const_string "fmul")
15043 (match_operand:DF 3 "div_operator")
15044 (const_string "fdiv")
15046 (const_string "fop")))
15047 (set_attr "mode" "SF")])
15049 (define_insn "*fop_xf_comm_i387"
15050 [(set (match_operand:XF 0 "register_operand" "=f")
15051 (match_operator:XF 3 "binary_fp_operator"
15052 [(match_operand:XF 1 "register_operand" "%0")
15053 (match_operand:XF 2 "register_operand" "f")]))]
15055 && COMMUTATIVE_ARITH_P (operands[3])"
15056 "* return output_387_binary_op (insn, operands);"
15057 [(set (attr "type")
15058 (if_then_else (match_operand:XF 3 "mult_operator")
15059 (const_string "fmul")
15060 (const_string "fop")))
15061 (set_attr "mode" "XF")])
15063 (define_insn "*fop_xf_1_i387"
15064 [(set (match_operand:XF 0 "register_operand" "=f,f")
15065 (match_operator:XF 3 "binary_fp_operator"
15066 [(match_operand:XF 1 "register_operand" "0,f")
15067 (match_operand:XF 2 "register_operand" "f,0")]))]
15069 && !COMMUTATIVE_ARITH_P (operands[3])"
15070 "* return output_387_binary_op (insn, operands);"
15071 [(set (attr "type")
15072 (if_then_else (match_operand:XF 3 "div_operator")
15073 (const_string "fdiv")
15074 (const_string "fop")))
15075 (set_attr "mode" "XF")])
15077 (define_insn "*fop_xf_2_i387"
15078 [(set (match_operand:XF 0 "register_operand" "=f")
15079 (match_operator:XF 3 "binary_fp_operator"
15081 (match_operand:SWI24 1 "nonimmediate_operand" "m"))
15082 (match_operand:XF 2 "register_operand" "0")]))]
15084 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
15085 "* return output_387_binary_op (insn, operands);"
15086 [(set (attr "type")
15087 (cond [(match_operand:XF 3 "mult_operator")
15088 (const_string "fmul")
15089 (match_operand:XF 3 "div_operator")
15090 (const_string "fdiv")
15092 (const_string "fop")))
15093 (set_attr "fp_int_src" "true")
15094 (set_attr "mode" "<MODE>")])
15096 (define_insn "*fop_xf_3_i387"
15097 [(set (match_operand:XF 0 "register_operand" "=f")
15098 (match_operator:XF 3 "binary_fp_operator"
15099 [(match_operand:XF 1 "register_operand" "0")
15101 (match_operand:SWI24 2 "nonimmediate_operand" "m"))]))]
15103 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
15104 "* return output_387_binary_op (insn, operands);"
15105 [(set (attr "type")
15106 (cond [(match_operand:XF 3 "mult_operator")
15107 (const_string "fmul")
15108 (match_operand:XF 3 "div_operator")
15109 (const_string "fdiv")
15111 (const_string "fop")))
15112 (set_attr "fp_int_src" "true")
15113 (set_attr "mode" "<MODE>")])
15115 (define_insn "*fop_xf_4_i387"
15116 [(set (match_operand:XF 0 "register_operand" "=f,f")
15117 (match_operator:XF 3 "binary_fp_operator"
15119 (match_operand:MODEF 1 "nonimmediate_operand" "fm,0"))
15120 (match_operand:XF 2 "register_operand" "0,f")]))]
15122 "* return output_387_binary_op (insn, operands);"
15123 [(set (attr "type")
15124 (cond [(match_operand:XF 3 "mult_operator")
15125 (const_string "fmul")
15126 (match_operand:XF 3 "div_operator")
15127 (const_string "fdiv")
15129 (const_string "fop")))
15130 (set_attr "mode" "<MODE>")])
15132 (define_insn "*fop_xf_5_i387"
15133 [(set (match_operand:XF 0 "register_operand" "=f,f")
15134 (match_operator:XF 3 "binary_fp_operator"
15135 [(match_operand:XF 1 "register_operand" "0,f")
15137 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
15139 "* return output_387_binary_op (insn, operands);"
15140 [(set (attr "type")
15141 (cond [(match_operand:XF 3 "mult_operator")
15142 (const_string "fmul")
15143 (match_operand:XF 3 "div_operator")
15144 (const_string "fdiv")
15146 (const_string "fop")))
15147 (set_attr "mode" "<MODE>")])
15149 (define_insn "*fop_xf_6_i387"
15150 [(set (match_operand:XF 0 "register_operand" "=f,f")
15151 (match_operator:XF 3 "binary_fp_operator"
15153 (match_operand:MODEF 1 "register_operand" "0,f"))
15155 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
15157 "* return output_387_binary_op (insn, operands);"
15158 [(set (attr "type")
15159 (cond [(match_operand:XF 3 "mult_operator")
15160 (const_string "fmul")
15161 (match_operand:XF 3 "div_operator")
15162 (const_string "fdiv")
15164 (const_string "fop")))
15165 (set_attr "mode" "<MODE>")])
15167 ;; FPU special functions.
15169 ;; This pattern implements a no-op XFmode truncation for
15170 ;; all fancy i386 XFmode math functions.
15172 (define_insn "truncxf<mode>2_i387_noop_unspec"
15173 [(set (match_operand:MODEF 0 "register_operand" "=f")
15174 (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")]
15175 UNSPEC_TRUNC_NOOP))]
15176 "TARGET_USE_FANCY_MATH_387"
15177 "* return output_387_reg_move (insn, operands);"
15178 [(set_attr "type" "fmov")
15179 (set_attr "mode" "<MODE>")])
15181 (define_insn "sqrtxf2"
15182 [(set (match_operand:XF 0 "register_operand" "=f")
15183 (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
15184 "TARGET_USE_FANCY_MATH_387"
15186 [(set_attr "type" "fpspc")
15187 (set_attr "mode" "XF")
15188 (set_attr "athlon_decode" "direct")
15189 (set_attr "amdfam10_decode" "direct")
15190 (set_attr "bdver1_decode" "direct")])
15192 (define_insn "sqrt_extend<mode>xf2_i387"
15193 [(set (match_operand:XF 0 "register_operand" "=f")
15196 (match_operand:MODEF 1 "register_operand" "0"))))]
15197 "TARGET_USE_FANCY_MATH_387"
15199 [(set_attr "type" "fpspc")
15200 (set_attr "mode" "XF")
15201 (set_attr "athlon_decode" "direct")
15202 (set_attr "amdfam10_decode" "direct")
15203 (set_attr "bdver1_decode" "direct")])
15205 (define_insn "*rsqrtsf2_sse"
15206 [(set (match_operand:SF 0 "register_operand" "=x")
15207 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
15209 "TARGET_SSE && TARGET_SSE_MATH"
15210 "%vrsqrtss\t{%1, %d0|%d0, %1}"
15211 [(set_attr "type" "sse")
15212 (set_attr "atom_sse_attr" "rcp")
15213 (set_attr "btver2_sse_attr" "rcp")
15214 (set_attr "prefix" "maybe_vex")
15215 (set_attr "mode" "SF")])
15217 (define_expand "rsqrtsf2"
15218 [(set (match_operand:SF 0 "register_operand")
15219 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand")]
15221 "TARGET_SSE && TARGET_SSE_MATH"
15223 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
15227 (define_insn "*sqrt<mode>2_sse"
15228 [(set (match_operand:MODEF 0 "register_operand" "=v")
15230 (match_operand:MODEF 1 "nonimmediate_operand" "vm")))]
15231 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
15232 "%vsqrt<ssemodesuffix>\t{%1, %d0|%d0, %1}"
15233 [(set_attr "type" "sse")
15234 (set_attr "atom_sse_attr" "sqrt")
15235 (set_attr "btver2_sse_attr" "sqrt")
15236 (set_attr "prefix" "maybe_vex")
15237 (set_attr "mode" "<MODE>")
15238 (set_attr "athlon_decode" "*")
15239 (set_attr "amdfam10_decode" "*")
15240 (set_attr "bdver1_decode" "*")])
15242 (define_expand "sqrt<mode>2"
15243 [(set (match_operand:MODEF 0 "register_operand")
15245 (match_operand:MODEF 1 "nonimmediate_operand")))]
15246 "(TARGET_USE_FANCY_MATH_387 && X87_ENABLE_ARITH (<MODE>mode))
15247 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
15249 if (<MODE>mode == SFmode
15250 && TARGET_SSE && TARGET_SSE_MATH
15251 && TARGET_RECIP_SQRT
15252 && !optimize_function_for_size_p (cfun)
15253 && flag_finite_math_only && !flag_trapping_math
15254 && flag_unsafe_math_optimizations)
15256 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
15260 if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
15262 rtx op0 = gen_reg_rtx (XFmode);
15263 rtx op1 = force_reg (<MODE>mode, operands[1]);
15265 emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
15266 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
15271 (define_insn "fpremxf4_i387"
15272 [(set (match_operand:XF 0 "register_operand" "=f")
15273 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15274 (match_operand:XF 3 "register_operand" "1")]
15276 (set (match_operand:XF 1 "register_operand" "=u")
15277 (unspec:XF [(match_dup 2) (match_dup 3)]
15279 (set (reg:CCFP FPSR_REG)
15280 (unspec:CCFP [(match_dup 2) (match_dup 3)]
15282 "TARGET_USE_FANCY_MATH_387
15283 && flag_finite_math_only"
15285 [(set_attr "type" "fpspc")
15286 (set_attr "znver1_decode" "vector")
15287 (set_attr "mode" "XF")])
15289 (define_expand "fmodxf3"
15290 [(use (match_operand:XF 0 "register_operand"))
15291 (use (match_operand:XF 1 "general_operand"))
15292 (use (match_operand:XF 2 "general_operand"))]
15293 "TARGET_USE_FANCY_MATH_387
15294 && flag_finite_math_only"
15296 rtx_code_label *label = gen_label_rtx ();
15298 rtx op1 = gen_reg_rtx (XFmode);
15299 rtx op2 = gen_reg_rtx (XFmode);
15301 emit_move_insn (op2, operands[2]);
15302 emit_move_insn (op1, operands[1]);
15304 emit_label (label);
15305 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
15306 ix86_emit_fp_unordered_jump (label);
15307 LABEL_NUSES (label) = 1;
15309 emit_move_insn (operands[0], op1);
15313 (define_expand "fmod<mode>3"
15314 [(use (match_operand:MODEF 0 "register_operand"))
15315 (use (match_operand:MODEF 1 "general_operand"))
15316 (use (match_operand:MODEF 2 "general_operand"))]
15317 "TARGET_USE_FANCY_MATH_387
15318 && flag_finite_math_only"
15320 rtx (*gen_truncxf) (rtx, rtx);
15322 rtx_code_label *label = gen_label_rtx ();
15324 rtx op1 = gen_reg_rtx (XFmode);
15325 rtx op2 = gen_reg_rtx (XFmode);
15327 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
15328 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15330 emit_label (label);
15331 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
15332 ix86_emit_fp_unordered_jump (label);
15333 LABEL_NUSES (label) = 1;
15335 /* Truncate the result properly for strict SSE math. */
15336 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15337 && !TARGET_MIX_SSE_I387)
15338 gen_truncxf = gen_truncxf<mode>2;
15340 gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
15342 emit_insn (gen_truncxf (operands[0], op1));
15346 (define_insn "fprem1xf4_i387"
15347 [(set (match_operand:XF 0 "register_operand" "=f")
15348 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15349 (match_operand:XF 3 "register_operand" "1")]
15351 (set (match_operand:XF 1 "register_operand" "=u")
15352 (unspec:XF [(match_dup 2) (match_dup 3)]
15354 (set (reg:CCFP FPSR_REG)
15355 (unspec:CCFP [(match_dup 2) (match_dup 3)]
15357 "TARGET_USE_FANCY_MATH_387
15358 && flag_finite_math_only"
15360 [(set_attr "type" "fpspc")
15361 (set_attr "znver1_decode" "vector")
15362 (set_attr "mode" "XF")])
15364 (define_expand "remainderxf3"
15365 [(use (match_operand:XF 0 "register_operand"))
15366 (use (match_operand:XF 1 "general_operand"))
15367 (use (match_operand:XF 2 "general_operand"))]
15368 "TARGET_USE_FANCY_MATH_387
15369 && flag_finite_math_only"
15371 rtx_code_label *label = gen_label_rtx ();
15373 rtx op1 = gen_reg_rtx (XFmode);
15374 rtx op2 = gen_reg_rtx (XFmode);
15376 emit_move_insn (op2, operands[2]);
15377 emit_move_insn (op1, operands[1]);
15379 emit_label (label);
15380 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
15381 ix86_emit_fp_unordered_jump (label);
15382 LABEL_NUSES (label) = 1;
15384 emit_move_insn (operands[0], op1);
15388 (define_expand "remainder<mode>3"
15389 [(use (match_operand:MODEF 0 "register_operand"))
15390 (use (match_operand:MODEF 1 "general_operand"))
15391 (use (match_operand:MODEF 2 "general_operand"))]
15392 "TARGET_USE_FANCY_MATH_387
15393 && flag_finite_math_only"
15395 rtx (*gen_truncxf) (rtx, rtx);
15397 rtx_code_label *label = gen_label_rtx ();
15399 rtx op1 = gen_reg_rtx (XFmode);
15400 rtx op2 = gen_reg_rtx (XFmode);
15402 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
15403 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15405 emit_label (label);
15407 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
15408 ix86_emit_fp_unordered_jump (label);
15409 LABEL_NUSES (label) = 1;
15411 /* Truncate the result properly for strict SSE math. */
15412 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15413 && !TARGET_MIX_SSE_I387)
15414 gen_truncxf = gen_truncxf<mode>2;
15416 gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
15418 emit_insn (gen_truncxf (operands[0], op1));
15422 (define_int_iterator SINCOS
15426 (define_int_attr sincos
15427 [(UNSPEC_SIN "sin")
15428 (UNSPEC_COS "cos")])
15430 (define_insn "*<sincos>xf2_i387"
15431 [(set (match_operand:XF 0 "register_operand" "=f")
15432 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15434 "TARGET_USE_FANCY_MATH_387
15435 && flag_unsafe_math_optimizations"
15437 [(set_attr "type" "fpspc")
15438 (set_attr "znver1_decode" "vector")
15439 (set_attr "mode" "XF")])
15441 (define_insn "*<sincos>_extend<mode>xf2_i387"
15442 [(set (match_operand:XF 0 "register_operand" "=f")
15443 (unspec:XF [(float_extend:XF
15444 (match_operand:MODEF 1 "register_operand" "0"))]
15446 "TARGET_USE_FANCY_MATH_387
15447 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15448 || TARGET_MIX_SSE_I387)
15449 && flag_unsafe_math_optimizations"
15451 [(set_attr "type" "fpspc")
15452 (set_attr "znver1_decode" "vector")
15453 (set_attr "mode" "XF")])
15455 ;; When sincos pattern is defined, sin and cos builtin functions will be
15456 ;; expanded to sincos pattern with one of its outputs left unused.
15457 ;; CSE pass will figure out if two sincos patterns can be combined,
15458 ;; otherwise sincos pattern will be split back to sin or cos pattern,
15459 ;; depending on the unused output.
15461 (define_insn "sincosxf3"
15462 [(set (match_operand:XF 0 "register_operand" "=f")
15463 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15464 UNSPEC_SINCOS_COS))
15465 (set (match_operand:XF 1 "register_operand" "=u")
15466 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15467 "TARGET_USE_FANCY_MATH_387
15468 && flag_unsafe_math_optimizations"
15470 [(set_attr "type" "fpspc")
15471 (set_attr "znver1_decode" "vector")
15472 (set_attr "mode" "XF")])
15475 [(set (match_operand:XF 0 "register_operand")
15476 (unspec:XF [(match_operand:XF 2 "register_operand")]
15477 UNSPEC_SINCOS_COS))
15478 (set (match_operand:XF 1 "register_operand")
15479 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15480 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15481 && can_create_pseudo_p ()"
15482 [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))])
15485 [(set (match_operand:XF 0 "register_operand")
15486 (unspec:XF [(match_operand:XF 2 "register_operand")]
15487 UNSPEC_SINCOS_COS))
15488 (set (match_operand:XF 1 "register_operand")
15489 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15490 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15491 && can_create_pseudo_p ()"
15492 [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))])
15494 (define_insn "sincos_extend<mode>xf3_i387"
15495 [(set (match_operand:XF 0 "register_operand" "=f")
15496 (unspec:XF [(float_extend:XF
15497 (match_operand:MODEF 2 "register_operand" "0"))]
15498 UNSPEC_SINCOS_COS))
15499 (set (match_operand:XF 1 "register_operand" "=u")
15500 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
15501 "TARGET_USE_FANCY_MATH_387
15502 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15503 || TARGET_MIX_SSE_I387)
15504 && flag_unsafe_math_optimizations"
15506 [(set_attr "type" "fpspc")
15507 (set_attr "znver1_decode" "vector")
15508 (set_attr "mode" "XF")])
15511 [(set (match_operand:XF 0 "register_operand")
15512 (unspec:XF [(float_extend:XF
15513 (match_operand:MODEF 2 "register_operand"))]
15514 UNSPEC_SINCOS_COS))
15515 (set (match_operand:XF 1 "register_operand")
15516 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
15517 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15518 && can_create_pseudo_p ()"
15519 [(set (match_dup 1)
15520 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))])
15523 [(set (match_operand:XF 0 "register_operand")
15524 (unspec:XF [(float_extend:XF
15525 (match_operand:MODEF 2 "register_operand"))]
15526 UNSPEC_SINCOS_COS))
15527 (set (match_operand:XF 1 "register_operand")
15528 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
15529 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15530 && can_create_pseudo_p ()"
15531 [(set (match_dup 0)
15532 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))])
15534 (define_expand "sincos<mode>3"
15535 [(use (match_operand:MODEF 0 "register_operand"))
15536 (use (match_operand:MODEF 1 "register_operand"))
15537 (use (match_operand:MODEF 2 "register_operand"))]
15538 "TARGET_USE_FANCY_MATH_387
15539 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15540 || TARGET_MIX_SSE_I387)
15541 && flag_unsafe_math_optimizations"
15543 rtx op0 = gen_reg_rtx (XFmode);
15544 rtx op1 = gen_reg_rtx (XFmode);
15546 emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
15547 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15548 emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
15552 (define_insn "fptanxf4_i387"
15553 [(set (match_operand:XF 0 "register_operand" "=f")
15554 (match_operand:XF 3 "const_double_operand" "F"))
15555 (set (match_operand:XF 1 "register_operand" "=u")
15556 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15558 "TARGET_USE_FANCY_MATH_387
15559 && flag_unsafe_math_optimizations
15560 && standard_80387_constant_p (operands[3]) == 2"
15562 [(set_attr "type" "fpspc")
15563 (set_attr "znver1_decode" "vector")
15564 (set_attr "mode" "XF")])
15566 (define_insn "fptan_extend<mode>xf4_i387"
15567 [(set (match_operand:MODEF 0 "register_operand" "=f")
15568 (match_operand:MODEF 3 "const_double_operand" "F"))
15569 (set (match_operand:XF 1 "register_operand" "=u")
15570 (unspec:XF [(float_extend:XF
15571 (match_operand:MODEF 2 "register_operand" "0"))]
15573 "TARGET_USE_FANCY_MATH_387
15574 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15575 || TARGET_MIX_SSE_I387)
15576 && flag_unsafe_math_optimizations
15577 && standard_80387_constant_p (operands[3]) == 2"
15579 [(set_attr "type" "fpspc")
15580 (set_attr "znver1_decode" "vector")
15581 (set_attr "mode" "XF")])
15583 (define_expand "tanxf2"
15584 [(use (match_operand:XF 0 "register_operand"))
15585 (use (match_operand:XF 1 "register_operand"))]
15586 "TARGET_USE_FANCY_MATH_387
15587 && flag_unsafe_math_optimizations"
15589 rtx one = gen_reg_rtx (XFmode);
15590 rtx op2 = CONST1_RTX (XFmode); /* fld1 */
15592 emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2));
15596 (define_expand "tan<mode>2"
15597 [(use (match_operand:MODEF 0 "register_operand"))
15598 (use (match_operand:MODEF 1 "register_operand"))]
15599 "TARGET_USE_FANCY_MATH_387
15600 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15601 || TARGET_MIX_SSE_I387)
15602 && flag_unsafe_math_optimizations"
15604 rtx op0 = gen_reg_rtx (XFmode);
15606 rtx one = gen_reg_rtx (<MODE>mode);
15607 rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */
15609 emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
15610 operands[1], op2));
15611 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15615 (define_insn "*fpatanxf3_i387"
15616 [(set (match_operand:XF 0 "register_operand" "=f")
15617 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
15618 (match_operand:XF 2 "register_operand" "u")]
15620 (clobber (match_scratch:XF 3 "=2"))]
15621 "TARGET_USE_FANCY_MATH_387
15622 && flag_unsafe_math_optimizations"
15624 [(set_attr "type" "fpspc")
15625 (set_attr "znver1_decode" "vector")
15626 (set_attr "mode" "XF")])
15628 (define_insn "fpatan_extend<mode>xf3_i387"
15629 [(set (match_operand:XF 0 "register_operand" "=f")
15630 (unspec:XF [(float_extend:XF
15631 (match_operand:MODEF 1 "register_operand" "0"))
15633 (match_operand:MODEF 2 "register_operand" "u"))]
15635 (clobber (match_scratch:XF 3 "=2"))]
15636 "TARGET_USE_FANCY_MATH_387
15637 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15638 || TARGET_MIX_SSE_I387)
15639 && flag_unsafe_math_optimizations"
15641 [(set_attr "type" "fpspc")
15642 (set_attr "znver1_decode" "vector")
15643 (set_attr "mode" "XF")])
15645 (define_expand "atan2xf3"
15646 [(parallel [(set (match_operand:XF 0 "register_operand")
15647 (unspec:XF [(match_operand:XF 2 "register_operand")
15648 (match_operand:XF 1 "register_operand")]
15650 (clobber (match_scratch:XF 3))])]
15651 "TARGET_USE_FANCY_MATH_387
15652 && flag_unsafe_math_optimizations")
15654 (define_expand "atan2<mode>3"
15655 [(use (match_operand:MODEF 0 "register_operand"))
15656 (use (match_operand:MODEF 1 "register_operand"))
15657 (use (match_operand:MODEF 2 "register_operand"))]
15658 "TARGET_USE_FANCY_MATH_387
15659 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15660 || TARGET_MIX_SSE_I387)
15661 && flag_unsafe_math_optimizations"
15663 rtx op0 = gen_reg_rtx (XFmode);
15665 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
15666 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15670 (define_expand "atanxf2"
15671 [(parallel [(set (match_operand:XF 0 "register_operand")
15672 (unspec:XF [(match_dup 2)
15673 (match_operand:XF 1 "register_operand")]
15675 (clobber (match_scratch:XF 3))])]
15676 "TARGET_USE_FANCY_MATH_387
15677 && flag_unsafe_math_optimizations"
15679 operands[2] = gen_reg_rtx (XFmode);
15680 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
15683 (define_expand "atan<mode>2"
15684 [(use (match_operand:MODEF 0 "register_operand"))
15685 (use (match_operand:MODEF 1 "register_operand"))]
15686 "TARGET_USE_FANCY_MATH_387
15687 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15688 || TARGET_MIX_SSE_I387)
15689 && flag_unsafe_math_optimizations"
15691 rtx op0 = gen_reg_rtx (XFmode);
15693 rtx op2 = gen_reg_rtx (<MODE>mode);
15694 emit_move_insn (op2, CONST1_RTX (<MODE>mode)); /* fld1 */
15696 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1]));
15697 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15701 (define_expand "asinxf2"
15702 [(set (match_dup 2)
15703 (mult:XF (match_operand:XF 1 "register_operand")
15705 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
15706 (set (match_dup 5) (sqrt:XF (match_dup 4)))
15707 (parallel [(set (match_operand:XF 0 "register_operand")
15708 (unspec:XF [(match_dup 5) (match_dup 1)]
15710 (clobber (match_scratch:XF 6))])]
15711 "TARGET_USE_FANCY_MATH_387
15712 && flag_unsafe_math_optimizations"
15716 for (i = 2; i < 6; i++)
15717 operands[i] = gen_reg_rtx (XFmode);
15719 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
15722 (define_expand "asin<mode>2"
15723 [(use (match_operand:MODEF 0 "register_operand"))
15724 (use (match_operand:MODEF 1 "general_operand"))]
15725 "TARGET_USE_FANCY_MATH_387
15726 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15727 || TARGET_MIX_SSE_I387)
15728 && flag_unsafe_math_optimizations"
15730 rtx op0 = gen_reg_rtx (XFmode);
15731 rtx op1 = gen_reg_rtx (XFmode);
15733 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15734 emit_insn (gen_asinxf2 (op0, op1));
15735 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15739 (define_expand "acosxf2"
15740 [(set (match_dup 2)
15741 (mult:XF (match_operand:XF 1 "register_operand")
15743 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
15744 (set (match_dup 5) (sqrt:XF (match_dup 4)))
15745 (parallel [(set (match_operand:XF 0 "register_operand")
15746 (unspec:XF [(match_dup 1) (match_dup 5)]
15748 (clobber (match_scratch:XF 6))])]
15749 "TARGET_USE_FANCY_MATH_387
15750 && flag_unsafe_math_optimizations"
15754 for (i = 2; i < 6; i++)
15755 operands[i] = gen_reg_rtx (XFmode);
15757 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
15760 (define_expand "acos<mode>2"
15761 [(use (match_operand:MODEF 0 "register_operand"))
15762 (use (match_operand:MODEF 1 "general_operand"))]
15763 "TARGET_USE_FANCY_MATH_387
15764 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15765 || TARGET_MIX_SSE_I387)
15766 && flag_unsafe_math_optimizations"
15768 rtx op0 = gen_reg_rtx (XFmode);
15769 rtx op1 = gen_reg_rtx (XFmode);
15771 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15772 emit_insn (gen_acosxf2 (op0, op1));
15773 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15777 (define_insn "fyl2xxf3_i387"
15778 [(set (match_operand:XF 0 "register_operand" "=f")
15779 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
15780 (match_operand:XF 2 "register_operand" "u")]
15782 (clobber (match_scratch:XF 3 "=2"))]
15783 "TARGET_USE_FANCY_MATH_387
15784 && flag_unsafe_math_optimizations"
15786 [(set_attr "type" "fpspc")
15787 (set_attr "znver1_decode" "vector")
15788 (set_attr "mode" "XF")])
15790 (define_insn "fyl2x_extend<mode>xf3_i387"
15791 [(set (match_operand:XF 0 "register_operand" "=f")
15792 (unspec:XF [(float_extend:XF
15793 (match_operand:MODEF 1 "register_operand" "0"))
15794 (match_operand:XF 2 "register_operand" "u")]
15796 (clobber (match_scratch:XF 3 "=2"))]
15797 "TARGET_USE_FANCY_MATH_387
15798 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15799 || TARGET_MIX_SSE_I387)
15800 && flag_unsafe_math_optimizations"
15802 [(set_attr "type" "fpspc")
15803 (set_attr "znver1_decode" "vector")
15804 (set_attr "mode" "XF")])
15806 (define_expand "logxf2"
15807 [(parallel [(set (match_operand:XF 0 "register_operand")
15808 (unspec:XF [(match_operand:XF 1 "register_operand")
15809 (match_dup 2)] UNSPEC_FYL2X))
15810 (clobber (match_scratch:XF 3))])]
15811 "TARGET_USE_FANCY_MATH_387
15812 && flag_unsafe_math_optimizations"
15814 operands[2] = gen_reg_rtx (XFmode);
15815 emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */
15818 (define_expand "log<mode>2"
15819 [(use (match_operand:MODEF 0 "register_operand"))
15820 (use (match_operand:MODEF 1 "register_operand"))]
15821 "TARGET_USE_FANCY_MATH_387
15822 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15823 || TARGET_MIX_SSE_I387)
15824 && flag_unsafe_math_optimizations"
15826 rtx op0 = gen_reg_rtx (XFmode);
15828 rtx op2 = gen_reg_rtx (XFmode);
15829 emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */
15831 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
15832 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15836 (define_expand "log10xf2"
15837 [(parallel [(set (match_operand:XF 0 "register_operand")
15838 (unspec:XF [(match_operand:XF 1 "register_operand")
15839 (match_dup 2)] UNSPEC_FYL2X))
15840 (clobber (match_scratch:XF 3))])]
15841 "TARGET_USE_FANCY_MATH_387
15842 && flag_unsafe_math_optimizations"
15844 operands[2] = gen_reg_rtx (XFmode);
15845 emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
15848 (define_expand "log10<mode>2"
15849 [(use (match_operand:MODEF 0 "register_operand"))
15850 (use (match_operand:MODEF 1 "register_operand"))]
15851 "TARGET_USE_FANCY_MATH_387
15852 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15853 || TARGET_MIX_SSE_I387)
15854 && flag_unsafe_math_optimizations"
15856 rtx op0 = gen_reg_rtx (XFmode);
15858 rtx op2 = gen_reg_rtx (XFmode);
15859 emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */
15861 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
15862 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15866 (define_expand "log2xf2"
15867 [(parallel [(set (match_operand:XF 0 "register_operand")
15868 (unspec:XF [(match_operand:XF 1 "register_operand")
15869 (match_dup 2)] UNSPEC_FYL2X))
15870 (clobber (match_scratch:XF 3))])]
15871 "TARGET_USE_FANCY_MATH_387
15872 && flag_unsafe_math_optimizations"
15874 operands[2] = gen_reg_rtx (XFmode);
15875 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
15878 (define_expand "log2<mode>2"
15879 [(use (match_operand:MODEF 0 "register_operand"))
15880 (use (match_operand:MODEF 1 "register_operand"))]
15881 "TARGET_USE_FANCY_MATH_387
15882 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15883 || TARGET_MIX_SSE_I387)
15884 && flag_unsafe_math_optimizations"
15886 rtx op0 = gen_reg_rtx (XFmode);
15888 rtx op2 = gen_reg_rtx (XFmode);
15889 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
15891 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
15892 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15896 (define_insn "fyl2xp1xf3_i387"
15897 [(set (match_operand:XF 0 "register_operand" "=f")
15898 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
15899 (match_operand:XF 2 "register_operand" "u")]
15901 (clobber (match_scratch:XF 3 "=2"))]
15902 "TARGET_USE_FANCY_MATH_387
15903 && flag_unsafe_math_optimizations"
15905 [(set_attr "type" "fpspc")
15906 (set_attr "znver1_decode" "vector")
15907 (set_attr "mode" "XF")])
15909 (define_insn "fyl2xp1_extend<mode>xf3_i387"
15910 [(set (match_operand:XF 0 "register_operand" "=f")
15911 (unspec:XF [(float_extend:XF
15912 (match_operand:MODEF 1 "register_operand" "0"))
15913 (match_operand:XF 2 "register_operand" "u")]
15915 (clobber (match_scratch:XF 3 "=2"))]
15916 "TARGET_USE_FANCY_MATH_387
15917 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15918 || TARGET_MIX_SSE_I387)
15919 && flag_unsafe_math_optimizations"
15921 [(set_attr "type" "fpspc")
15922 (set_attr "znver1_decode" "vector")
15923 (set_attr "mode" "XF")])
15925 (define_expand "log1pxf2"
15926 [(use (match_operand:XF 0 "register_operand"))
15927 (use (match_operand:XF 1 "register_operand"))]
15928 "TARGET_USE_FANCY_MATH_387
15929 && flag_unsafe_math_optimizations"
15931 ix86_emit_i387_log1p (operands[0], operands[1]);
15935 (define_expand "log1p<mode>2"
15936 [(use (match_operand:MODEF 0 "register_operand"))
15937 (use (match_operand:MODEF 1 "register_operand"))]
15938 "TARGET_USE_FANCY_MATH_387
15939 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15940 || TARGET_MIX_SSE_I387)
15941 && flag_unsafe_math_optimizations"
15945 op0 = gen_reg_rtx (XFmode);
15947 operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
15949 ix86_emit_i387_log1p (op0, operands[1]);
15950 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15954 (define_insn "fxtractxf3_i387"
15955 [(set (match_operand:XF 0 "register_operand" "=f")
15956 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15957 UNSPEC_XTRACT_FRACT))
15958 (set (match_operand:XF 1 "register_operand" "=u")
15959 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
15960 "TARGET_USE_FANCY_MATH_387
15961 && flag_unsafe_math_optimizations"
15963 [(set_attr "type" "fpspc")
15964 (set_attr "znver1_decode" "vector")
15965 (set_attr "mode" "XF")])
15967 (define_insn "fxtract_extend<mode>xf3_i387"
15968 [(set (match_operand:XF 0 "register_operand" "=f")
15969 (unspec:XF [(float_extend:XF
15970 (match_operand:MODEF 2 "register_operand" "0"))]
15971 UNSPEC_XTRACT_FRACT))
15972 (set (match_operand:XF 1 "register_operand" "=u")
15973 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
15974 "TARGET_USE_FANCY_MATH_387
15975 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15976 || TARGET_MIX_SSE_I387)
15977 && flag_unsafe_math_optimizations"
15979 [(set_attr "type" "fpspc")
15980 (set_attr "znver1_decode" "vector")
15981 (set_attr "mode" "XF")])
15983 (define_expand "logbxf2"
15984 [(parallel [(set (match_dup 2)
15985 (unspec:XF [(match_operand:XF 1 "register_operand")]
15986 UNSPEC_XTRACT_FRACT))
15987 (set (match_operand:XF 0 "register_operand")
15988 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
15989 "TARGET_USE_FANCY_MATH_387
15990 && flag_unsafe_math_optimizations"
15991 "operands[2] = gen_reg_rtx (XFmode);")
15993 (define_expand "logb<mode>2"
15994 [(use (match_operand:MODEF 0 "register_operand"))
15995 (use (match_operand:MODEF 1 "register_operand"))]
15996 "TARGET_USE_FANCY_MATH_387
15997 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15998 || TARGET_MIX_SSE_I387)
15999 && flag_unsafe_math_optimizations"
16001 rtx op0 = gen_reg_rtx (XFmode);
16002 rtx op1 = gen_reg_rtx (XFmode);
16004 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
16005 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1));
16009 (define_expand "ilogbxf2"
16010 [(use (match_operand:SI 0 "register_operand"))
16011 (use (match_operand:XF 1 "register_operand"))]
16012 "TARGET_USE_FANCY_MATH_387
16013 && flag_unsafe_math_optimizations"
16017 if (optimize_insn_for_size_p ())
16020 op0 = gen_reg_rtx (XFmode);
16021 op1 = gen_reg_rtx (XFmode);
16023 emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
16024 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
16028 (define_expand "ilogb<mode>2"
16029 [(use (match_operand:SI 0 "register_operand"))
16030 (use (match_operand:MODEF 1 "register_operand"))]
16031 "TARGET_USE_FANCY_MATH_387
16032 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16033 || TARGET_MIX_SSE_I387)
16034 && flag_unsafe_math_optimizations"
16038 if (optimize_insn_for_size_p ())
16041 op0 = gen_reg_rtx (XFmode);
16042 op1 = gen_reg_rtx (XFmode);
16044 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
16045 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
16049 (define_insn "*f2xm1xf2_i387"
16050 [(set (match_operand:XF 0 "register_operand" "=f")
16051 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16053 "TARGET_USE_FANCY_MATH_387
16054 && flag_unsafe_math_optimizations"
16056 [(set_attr "type" "fpspc")
16057 (set_attr "znver1_decode" "vector")
16058 (set_attr "mode" "XF")])
16060 (define_insn "fscalexf4_i387"
16061 [(set (match_operand:XF 0 "register_operand" "=f")
16062 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16063 (match_operand:XF 3 "register_operand" "1")]
16064 UNSPEC_FSCALE_FRACT))
16065 (set (match_operand:XF 1 "register_operand" "=u")
16066 (unspec:XF [(match_dup 2) (match_dup 3)]
16067 UNSPEC_FSCALE_EXP))]
16068 "TARGET_USE_FANCY_MATH_387
16069 && flag_unsafe_math_optimizations"
16071 [(set_attr "type" "fpspc")
16072 (set_attr "znver1_decode" "vector")
16073 (set_attr "mode" "XF")])
16075 (define_expand "expNcorexf3"
16076 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand")
16077 (match_operand:XF 2 "register_operand")))
16078 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16079 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16080 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16081 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
16082 (parallel [(set (match_operand:XF 0 "register_operand")
16083 (unspec:XF [(match_dup 8) (match_dup 4)]
16084 UNSPEC_FSCALE_FRACT))
16086 (unspec:XF [(match_dup 8) (match_dup 4)]
16087 UNSPEC_FSCALE_EXP))])]
16088 "TARGET_USE_FANCY_MATH_387
16089 && flag_unsafe_math_optimizations"
16093 for (i = 3; i < 10; i++)
16094 operands[i] = gen_reg_rtx (XFmode);
16096 emit_move_insn (operands[7], CONST1_RTX (XFmode)); /* fld1 */
16099 (define_expand "expxf2"
16100 [(use (match_operand:XF 0 "register_operand"))
16101 (use (match_operand:XF 1 "register_operand"))]
16102 "TARGET_USE_FANCY_MATH_387
16103 && flag_unsafe_math_optimizations"
16107 op2 = gen_reg_rtx (XFmode);
16108 emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */
16110 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
16114 (define_expand "exp<mode>2"
16115 [(use (match_operand:MODEF 0 "register_operand"))
16116 (use (match_operand:MODEF 1 "general_operand"))]
16117 "TARGET_USE_FANCY_MATH_387
16118 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16119 || TARGET_MIX_SSE_I387)
16120 && flag_unsafe_math_optimizations"
16124 op0 = gen_reg_rtx (XFmode);
16125 op1 = gen_reg_rtx (XFmode);
16127 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16128 emit_insn (gen_expxf2 (op0, op1));
16129 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16133 (define_expand "exp10xf2"
16134 [(use (match_operand:XF 0 "register_operand"))
16135 (use (match_operand:XF 1 "register_operand"))]
16136 "TARGET_USE_FANCY_MATH_387
16137 && flag_unsafe_math_optimizations"
16141 op2 = gen_reg_rtx (XFmode);
16142 emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */
16144 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
16148 (define_expand "exp10<mode>2"
16149 [(use (match_operand:MODEF 0 "register_operand"))
16150 (use (match_operand:MODEF 1 "general_operand"))]
16151 "TARGET_USE_FANCY_MATH_387
16152 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16153 || TARGET_MIX_SSE_I387)
16154 && flag_unsafe_math_optimizations"
16158 op0 = gen_reg_rtx (XFmode);
16159 op1 = gen_reg_rtx (XFmode);
16161 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16162 emit_insn (gen_exp10xf2 (op0, op1));
16163 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16167 (define_expand "exp2xf2"
16168 [(use (match_operand:XF 0 "register_operand"))
16169 (use (match_operand:XF 1 "register_operand"))]
16170 "TARGET_USE_FANCY_MATH_387
16171 && flag_unsafe_math_optimizations"
16175 op2 = gen_reg_rtx (XFmode);
16176 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
16178 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
16182 (define_expand "exp2<mode>2"
16183 [(use (match_operand:MODEF 0 "register_operand"))
16184 (use (match_operand:MODEF 1 "general_operand"))]
16185 "TARGET_USE_FANCY_MATH_387
16186 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16187 || TARGET_MIX_SSE_I387)
16188 && flag_unsafe_math_optimizations"
16192 op0 = gen_reg_rtx (XFmode);
16193 op1 = gen_reg_rtx (XFmode);
16195 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16196 emit_insn (gen_exp2xf2 (op0, op1));
16197 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16201 (define_expand "expm1xf2"
16202 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand")
16204 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16205 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16206 (set (match_dup 9) (float_extend:XF (match_dup 13)))
16207 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16208 (parallel [(set (match_dup 7)
16209 (unspec:XF [(match_dup 6) (match_dup 4)]
16210 UNSPEC_FSCALE_FRACT))
16212 (unspec:XF [(match_dup 6) (match_dup 4)]
16213 UNSPEC_FSCALE_EXP))])
16214 (parallel [(set (match_dup 10)
16215 (unspec:XF [(match_dup 9) (match_dup 8)]
16216 UNSPEC_FSCALE_FRACT))
16217 (set (match_dup 11)
16218 (unspec:XF [(match_dup 9) (match_dup 8)]
16219 UNSPEC_FSCALE_EXP))])
16220 (set (match_dup 12) (minus:XF (match_dup 10)
16221 (float_extend:XF (match_dup 13))))
16222 (set (match_operand:XF 0 "register_operand")
16223 (plus:XF (match_dup 12) (match_dup 7)))]
16224 "TARGET_USE_FANCY_MATH_387
16225 && flag_unsafe_math_optimizations"
16229 for (i = 2; i < 13; i++)
16230 operands[i] = gen_reg_rtx (XFmode);
16233 = validize_mem (force_const_mem (SFmode, CONST1_RTX (SFmode))); /* fld1 */
16235 emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
16238 (define_expand "expm1<mode>2"
16239 [(use (match_operand:MODEF 0 "register_operand"))
16240 (use (match_operand:MODEF 1 "general_operand"))]
16241 "TARGET_USE_FANCY_MATH_387
16242 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16243 || TARGET_MIX_SSE_I387)
16244 && flag_unsafe_math_optimizations"
16248 op0 = gen_reg_rtx (XFmode);
16249 op1 = gen_reg_rtx (XFmode);
16251 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16252 emit_insn (gen_expm1xf2 (op0, op1));
16253 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16257 (define_expand "ldexpxf3"
16258 [(match_operand:XF 0 "register_operand")
16259 (match_operand:XF 1 "register_operand")
16260 (match_operand:SI 2 "register_operand")]
16261 "TARGET_USE_FANCY_MATH_387
16262 && flag_unsafe_math_optimizations"
16266 tmp1 = gen_reg_rtx (XFmode);
16267 tmp2 = gen_reg_rtx (XFmode);
16269 emit_insn (gen_floatsixf2 (tmp1, operands[2]));
16270 emit_insn (gen_fscalexf4_i387 (operands[0], tmp2,
16271 operands[1], tmp1));
16275 (define_expand "ldexp<mode>3"
16276 [(use (match_operand:MODEF 0 "register_operand"))
16277 (use (match_operand:MODEF 1 "general_operand"))
16278 (use (match_operand:SI 2 "register_operand"))]
16279 "TARGET_USE_FANCY_MATH_387
16280 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16281 || TARGET_MIX_SSE_I387)
16282 && flag_unsafe_math_optimizations"
16286 op0 = gen_reg_rtx (XFmode);
16287 op1 = gen_reg_rtx (XFmode);
16289 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16290 emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
16291 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16295 (define_expand "scalbxf3"
16296 [(parallel [(set (match_operand:XF 0 " register_operand")
16297 (unspec:XF [(match_operand:XF 1 "register_operand")
16298 (match_operand:XF 2 "register_operand")]
16299 UNSPEC_FSCALE_FRACT))
16301 (unspec:XF [(match_dup 1) (match_dup 2)]
16302 UNSPEC_FSCALE_EXP))])]
16303 "TARGET_USE_FANCY_MATH_387
16304 && flag_unsafe_math_optimizations"
16306 operands[3] = gen_reg_rtx (XFmode);
16309 (define_expand "scalb<mode>3"
16310 [(use (match_operand:MODEF 0 "register_operand"))
16311 (use (match_operand:MODEF 1 "general_operand"))
16312 (use (match_operand:MODEF 2 "general_operand"))]
16313 "TARGET_USE_FANCY_MATH_387
16314 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16315 || TARGET_MIX_SSE_I387)
16316 && flag_unsafe_math_optimizations"
16320 op0 = gen_reg_rtx (XFmode);
16321 op1 = gen_reg_rtx (XFmode);
16322 op2 = gen_reg_rtx (XFmode);
16324 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16325 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
16326 emit_insn (gen_scalbxf3 (op0, op1, op2));
16327 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16331 (define_expand "significandxf2"
16332 [(parallel [(set (match_operand:XF 0 "register_operand")
16333 (unspec:XF [(match_operand:XF 1 "register_operand")]
16334 UNSPEC_XTRACT_FRACT))
16336 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
16337 "TARGET_USE_FANCY_MATH_387
16338 && flag_unsafe_math_optimizations"
16339 "operands[2] = gen_reg_rtx (XFmode);")
16341 (define_expand "significand<mode>2"
16342 [(use (match_operand:MODEF 0 "register_operand"))
16343 (use (match_operand:MODEF 1 "register_operand"))]
16344 "TARGET_USE_FANCY_MATH_387
16345 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16346 || TARGET_MIX_SSE_I387)
16347 && flag_unsafe_math_optimizations"
16349 rtx op0 = gen_reg_rtx (XFmode);
16350 rtx op1 = gen_reg_rtx (XFmode);
16352 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
16353 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16358 (define_insn "sse4_1_round<mode>2"
16359 [(set (match_operand:MODEF 0 "register_operand" "=x,v")
16360 (unspec:MODEF [(match_operand:MODEF 1 "nonimmediate_operand" "xm,vm")
16361 (match_operand:SI 2 "const_0_to_15_operand" "n,n")]
16365 %vround<ssemodesuffix>\t{%2, %1, %d0|%d0, %1, %2}
16366 vrndscale<ssemodesuffix>\t{%2, %1, %d0|%d0, %1, %2}"
16367 [(set_attr "type" "ssecvt")
16368 (set_attr "prefix_extra" "1,*")
16369 (set_attr "length_immediate" "*,1")
16370 (set_attr "prefix" "maybe_vex,evex")
16371 (set_attr "isa" "noavx512f,avx512f")
16372 (set_attr "mode" "<MODE>")])
16374 (define_insn "rintxf2"
16375 [(set (match_operand:XF 0 "register_operand" "=f")
16376 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16378 "TARGET_USE_FANCY_MATH_387"
16380 [(set_attr "type" "fpspc")
16381 (set_attr "znver1_decode" "vector")
16382 (set_attr "mode" "XF")])
16384 (define_insn "rint<mode>2_frndint"
16385 [(set (match_operand:MODEF 0 "register_operand" "=f")
16386 (unspec:MODEF [(match_operand:MODEF 1 "register_operand" "0")]
16388 "TARGET_USE_FANCY_MATH_387"
16390 [(set_attr "type" "fpspc")
16391 (set_attr "znver1_decode" "vector")
16392 (set_attr "mode" "<MODE>")])
16394 (define_expand "rint<mode>2"
16395 [(use (match_operand:MODEF 0 "register_operand"))
16396 (use (match_operand:MODEF 1 "register_operand"))]
16397 "(TARGET_USE_FANCY_MATH_387
16398 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16399 || TARGET_MIX_SSE_I387))
16400 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
16402 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16405 emit_insn (gen_sse4_1_round<mode>2
16406 (operands[0], operands[1], GEN_INT (ROUND_MXCSR)));
16408 ix86_expand_rint (operands[0], operands[1]);
16411 emit_insn (gen_rint<mode>2_frndint (operands[0], operands[1]));
16415 (define_expand "round<mode>2"
16416 [(match_operand:X87MODEF 0 "register_operand")
16417 (match_operand:X87MODEF 1 "nonimmediate_operand")]
16418 "(TARGET_USE_FANCY_MATH_387
16419 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16420 || TARGET_MIX_SSE_I387)
16421 && flag_unsafe_math_optimizations
16422 && (flag_fp_int_builtin_inexact || !flag_trapping_math))
16423 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16424 && !flag_trapping_math && !flag_rounding_math)"
16426 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16427 && !flag_trapping_math && !flag_rounding_math)
16431 operands[1] = force_reg (<MODE>mode, operands[1]);
16432 ix86_expand_round_sse4 (operands[0], operands[1]);
16434 else if (TARGET_64BIT || (<MODE>mode != DFmode))
16435 ix86_expand_round (operands[0], operands[1]);
16437 ix86_expand_rounddf_32 (operands[0], operands[1]);
16441 operands[1] = force_reg (<MODE>mode, operands[1]);
16442 ix86_emit_i387_round (operands[0], operands[1]);
16447 (define_insn_and_split "*fistdi2_1"
16448 [(set (match_operand:DI 0 "nonimmediate_operand")
16449 (unspec:DI [(match_operand:XF 1 "register_operand")]
16451 "TARGET_USE_FANCY_MATH_387
16452 && can_create_pseudo_p ()"
16457 if (memory_operand (operands[0], VOIDmode))
16458 emit_insn (gen_fistdi2 (operands[0], operands[1]));
16461 operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
16462 emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
16467 [(set_attr "type" "fpspc")
16468 (set_attr "mode" "DI")])
16470 (define_insn "fistdi2"
16471 [(set (match_operand:DI 0 "memory_operand" "=m")
16472 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
16474 (clobber (match_scratch:XF 2 "=&1f"))]
16475 "TARGET_USE_FANCY_MATH_387"
16476 "* return output_fix_trunc (insn, operands, false);"
16477 [(set_attr "type" "fpspc")
16478 (set_attr "mode" "DI")])
16480 (define_insn "fistdi2_with_temp"
16481 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
16482 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
16484 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))
16485 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
16486 "TARGET_USE_FANCY_MATH_387"
16488 [(set_attr "type" "fpspc")
16489 (set_attr "mode" "DI")])
16492 [(set (match_operand:DI 0 "register_operand")
16493 (unspec:DI [(match_operand:XF 1 "register_operand")]
16495 (clobber (match_operand:DI 2 "memory_operand"))
16496 (clobber (match_scratch 3))]
16498 [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
16499 (clobber (match_dup 3))])
16500 (set (match_dup 0) (match_dup 2))])
16503 [(set (match_operand:DI 0 "memory_operand")
16504 (unspec:DI [(match_operand:XF 1 "register_operand")]
16506 (clobber (match_operand:DI 2 "memory_operand"))
16507 (clobber (match_scratch 3))]
16509 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
16510 (clobber (match_dup 3))])])
16512 (define_insn_and_split "*fist<mode>2_1"
16513 [(set (match_operand:SWI24 0 "register_operand")
16514 (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
16516 "TARGET_USE_FANCY_MATH_387
16517 && can_create_pseudo_p ()"
16522 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
16523 emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
16527 [(set_attr "type" "fpspc")
16528 (set_attr "mode" "<MODE>")])
16530 (define_insn "fist<mode>2"
16531 [(set (match_operand:SWI24 0 "memory_operand" "=m")
16532 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
16534 "TARGET_USE_FANCY_MATH_387"
16535 "* return output_fix_trunc (insn, operands, false);"
16536 [(set_attr "type" "fpspc")
16537 (set_attr "mode" "<MODE>")])
16539 (define_insn "fist<mode>2_with_temp"
16540 [(set (match_operand:SWI24 0 "register_operand" "=r")
16541 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
16543 (clobber (match_operand:SWI24 2 "memory_operand" "=m"))]
16544 "TARGET_USE_FANCY_MATH_387"
16546 [(set_attr "type" "fpspc")
16547 (set_attr "mode" "<MODE>")])
16550 [(set (match_operand:SWI24 0 "register_operand")
16551 (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
16553 (clobber (match_operand:SWI24 2 "memory_operand"))]
16555 [(set (match_dup 2) (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST))
16556 (set (match_dup 0) (match_dup 2))])
16559 [(set (match_operand:SWI24 0 "memory_operand")
16560 (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
16562 (clobber (match_operand:SWI24 2 "memory_operand"))]
16564 [(set (match_dup 0) (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST))])
16566 (define_expand "lrintxf<mode>2"
16567 [(set (match_operand:SWI248x 0 "nonimmediate_operand")
16568 (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
16570 "TARGET_USE_FANCY_MATH_387")
16572 (define_expand "lrint<MODEF:mode><SWI48:mode>2"
16573 [(set (match_operand:SWI48 0 "nonimmediate_operand")
16574 (unspec:SWI48 [(match_operand:MODEF 1 "register_operand")]
16575 UNSPEC_FIX_NOTRUNC))]
16576 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH")
16578 (define_expand "lround<X87MODEF:mode><SWI248x:mode>2"
16579 [(match_operand:SWI248x 0 "nonimmediate_operand")
16580 (match_operand:X87MODEF 1 "register_operand")]
16581 "(TARGET_USE_FANCY_MATH_387
16582 && (!(SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
16583 || TARGET_MIX_SSE_I387)
16584 && flag_unsafe_math_optimizations)
16585 || (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
16586 && <SWI248x:MODE>mode != HImode
16587 && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT)
16588 && !flag_trapping_math && !flag_rounding_math)"
16590 if (optimize_insn_for_size_p ())
16593 if (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
16594 && <SWI248x:MODE>mode != HImode
16595 && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT)
16596 && !flag_trapping_math && !flag_rounding_math)
16597 ix86_expand_lround (operands[0], operands[1]);
16599 ix86_emit_i387_round (operands[0], operands[1]);
16603 (define_int_iterator FRNDINT_ROUNDING
16604 [UNSPEC_FRNDINT_FLOOR
16605 UNSPEC_FRNDINT_CEIL
16606 UNSPEC_FRNDINT_TRUNC])
16608 (define_int_iterator FIST_ROUNDING
16612 ;; Base name for define_insn
16613 (define_int_attr rounding_insn
16614 [(UNSPEC_FRNDINT_FLOOR "floor")
16615 (UNSPEC_FRNDINT_CEIL "ceil")
16616 (UNSPEC_FRNDINT_TRUNC "btrunc")
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 (define_int_attr ROUNDING
16628 [(UNSPEC_FRNDINT_FLOOR "FLOOR")
16629 (UNSPEC_FRNDINT_CEIL "CEIL")
16630 (UNSPEC_FRNDINT_TRUNC "TRUNC")
16631 (UNSPEC_FIST_FLOOR "FLOOR")
16632 (UNSPEC_FIST_CEIL "CEIL")])
16634 ;; Rounding mode control word calculation could clobber FLAGS_REG.
16635 (define_insn_and_split "frndint<mode>2_<rounding>"
16636 [(set (match_operand:X87MODEF 0 "register_operand")
16637 (unspec:X87MODEF [(match_operand:X87MODEF 1 "register_operand")]
16639 (clobber (reg:CC FLAGS_REG))]
16640 "TARGET_USE_FANCY_MATH_387
16641 && (flag_fp_int_builtin_inexact || !flag_trapping_math)
16642 && can_create_pseudo_p ()"
16647 ix86_optimize_mode_switching[I387_<ROUNDING>] = 1;
16649 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
16650 operands[3] = assign_386_stack_local (HImode, SLOT_CW_<ROUNDING>);
16652 emit_insn (gen_frndint<mode>2_<rounding>_i387 (operands[0], operands[1],
16653 operands[2], operands[3]));
16656 [(set_attr "type" "frndint")
16657 (set_attr "i387_cw" "<rounding>")
16658 (set_attr "mode" "<MODE>")])
16660 (define_insn "frndint<mode>2_<rounding>_i387"
16661 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
16662 (unspec:X87MODEF [(match_operand:X87MODEF 1 "register_operand" "0")]
16664 (use (match_operand:HI 2 "memory_operand" "m"))
16665 (use (match_operand:HI 3 "memory_operand" "m"))]
16666 "TARGET_USE_FANCY_MATH_387
16667 && (flag_fp_int_builtin_inexact || !flag_trapping_math)"
16668 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
16669 [(set_attr "type" "frndint")
16670 (set_attr "i387_cw" "<rounding>")
16671 (set_attr "mode" "<MODE>")])
16673 (define_expand "<rounding_insn>xf2"
16674 [(parallel [(set (match_operand:XF 0 "register_operand")
16675 (unspec:XF [(match_operand:XF 1 "register_operand")]
16677 (clobber (reg:CC FLAGS_REG))])]
16678 "TARGET_USE_FANCY_MATH_387
16679 && (flag_fp_int_builtin_inexact || !flag_trapping_math)")
16681 (define_expand "<rounding_insn><mode>2"
16682 [(parallel [(set (match_operand:MODEF 0 "register_operand")
16683 (unspec:MODEF [(match_operand:MODEF 1 "register_operand")]
16685 (clobber (reg:CC FLAGS_REG))])]
16686 "(TARGET_USE_FANCY_MATH_387
16687 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16688 || TARGET_MIX_SSE_I387)
16689 && (flag_fp_int_builtin_inexact || !flag_trapping_math))
16690 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16691 && (TARGET_SSE4_1 || !flag_trapping_math
16692 || flag_fp_int_builtin_inexact))"
16694 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16695 && (TARGET_SSE4_1 || !flag_trapping_math || flag_fp_int_builtin_inexact))
16698 emit_insn (gen_sse4_1_round<mode>2
16699 (operands[0], operands[1], GEN_INT (ROUND_<ROUNDING>
16701 else if (TARGET_64BIT || (<MODE>mode != DFmode))
16703 if (ROUND_<ROUNDING> == ROUND_FLOOR)
16704 ix86_expand_floorceil (operands[0], operands[1], true);
16705 else if (ROUND_<ROUNDING> == ROUND_CEIL)
16706 ix86_expand_floorceil (operands[0], operands[1], false);
16707 else if (ROUND_<ROUNDING> == ROUND_TRUNC)
16708 ix86_expand_trunc (operands[0], operands[1]);
16710 gcc_unreachable ();
16714 if (ROUND_<ROUNDING> == ROUND_FLOOR)
16715 ix86_expand_floorceildf_32 (operands[0], operands[1], true);
16716 else if (ROUND_<ROUNDING> == ROUND_CEIL)
16717 ix86_expand_floorceildf_32 (operands[0], operands[1], false);
16718 else if (ROUND_<ROUNDING> == ROUND_TRUNC)
16719 ix86_expand_truncdf_32 (operands[0], operands[1]);
16721 gcc_unreachable ();
16725 emit_insn (gen_frndint<mode>2_<rounding> (operands[0], operands[1]));
16729 ;; Rounding mode control word calculation could clobber FLAGS_REG.
16730 (define_insn_and_split "frndintxf2_mask_pm"
16731 [(set (match_operand:XF 0 "register_operand")
16732 (unspec:XF [(match_operand:XF 1 "register_operand")]
16733 UNSPEC_FRNDINT_MASK_PM))
16734 (clobber (reg:CC FLAGS_REG))]
16735 "TARGET_USE_FANCY_MATH_387
16736 && flag_unsafe_math_optimizations
16737 && can_create_pseudo_p ()"
16742 ix86_optimize_mode_switching[I387_MASK_PM] = 1;
16744 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
16745 operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
16747 emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
16748 operands[2], operands[3]));
16751 [(set_attr "type" "frndint")
16752 (set_attr "i387_cw" "mask_pm")
16753 (set_attr "mode" "XF")])
16755 (define_insn "frndintxf2_mask_pm_i387"
16756 [(set (match_operand:XF 0 "register_operand" "=f")
16757 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16758 UNSPEC_FRNDINT_MASK_PM))
16759 (use (match_operand:HI 2 "memory_operand" "m"))
16760 (use (match_operand:HI 3 "memory_operand" "m"))]
16761 "TARGET_USE_FANCY_MATH_387
16762 && flag_unsafe_math_optimizations"
16763 "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
16764 [(set_attr "type" "frndint")
16765 (set_attr "i387_cw" "mask_pm")
16766 (set_attr "mode" "XF")])
16768 (define_expand "nearbyintxf2"
16769 [(parallel [(set (match_operand:XF 0 "register_operand")
16770 (unspec:XF [(match_operand:XF 1 "register_operand")]
16771 UNSPEC_FRNDINT_MASK_PM))
16772 (clobber (reg:CC FLAGS_REG))])]
16773 "TARGET_USE_FANCY_MATH_387
16774 && flag_unsafe_math_optimizations")
16776 (define_expand "nearbyint<mode>2"
16777 [(use (match_operand:MODEF 0 "register_operand"))
16778 (use (match_operand:MODEF 1 "register_operand"))]
16779 "TARGET_USE_FANCY_MATH_387
16780 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16781 || TARGET_MIX_SSE_I387)
16782 && flag_unsafe_math_optimizations"
16784 rtx op0 = gen_reg_rtx (XFmode);
16785 rtx op1 = gen_reg_rtx (XFmode);
16787 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16788 emit_insn (gen_frndintxf2_mask_pm (op0, op1));
16790 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16794 ;; Rounding mode control word calculation could clobber FLAGS_REG.
16795 (define_insn_and_split "*fist<mode>2_<rounding>_1"
16796 [(set (match_operand:SWI248x 0 "nonimmediate_operand")
16797 (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
16799 (clobber (reg:CC FLAGS_REG))]
16800 "TARGET_USE_FANCY_MATH_387
16801 && flag_unsafe_math_optimizations
16802 && can_create_pseudo_p ()"
16807 ix86_optimize_mode_switching[I387_<ROUNDING>] = 1;
16809 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
16810 operands[3] = assign_386_stack_local (HImode, SLOT_CW_<ROUNDING>);
16811 if (memory_operand (operands[0], VOIDmode))
16812 emit_insn (gen_fist<mode>2_<rounding> (operands[0], operands[1],
16813 operands[2], operands[3]));
16816 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
16817 emit_insn (gen_fist<mode>2_<rounding>_with_temp
16818 (operands[0], operands[1], operands[2],
16819 operands[3], operands[4]));
16823 [(set_attr "type" "fistp")
16824 (set_attr "i387_cw" "<rounding>")
16825 (set_attr "mode" "<MODE>")])
16827 (define_insn "fistdi2_<rounding>"
16828 [(set (match_operand:DI 0 "memory_operand" "=m")
16829 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
16831 (use (match_operand:HI 2 "memory_operand" "m"))
16832 (use (match_operand:HI 3 "memory_operand" "m"))
16833 (clobber (match_scratch:XF 4 "=&1f"))]
16834 "TARGET_USE_FANCY_MATH_387
16835 && flag_unsafe_math_optimizations"
16836 "* return output_fix_trunc (insn, operands, false);"
16837 [(set_attr "type" "fistp")
16838 (set_attr "i387_cw" "<rounding>")
16839 (set_attr "mode" "DI")])
16841 (define_insn "fistdi2_<rounding>_with_temp"
16842 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
16843 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
16845 (use (match_operand:HI 2 "memory_operand" "m,m"))
16846 (use (match_operand:HI 3 "memory_operand" "m,m"))
16847 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
16848 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
16849 "TARGET_USE_FANCY_MATH_387
16850 && flag_unsafe_math_optimizations"
16852 [(set_attr "type" "fistp")
16853 (set_attr "i387_cw" "<rounding>")
16854 (set_attr "mode" "DI")])
16857 [(set (match_operand:DI 0 "register_operand")
16858 (unspec:DI [(match_operand:XF 1 "register_operand")]
16860 (use (match_operand:HI 2 "memory_operand"))
16861 (use (match_operand:HI 3 "memory_operand"))
16862 (clobber (match_operand:DI 4 "memory_operand"))
16863 (clobber (match_scratch 5))]
16865 [(parallel [(set (match_dup 4)
16866 (unspec:DI [(match_dup 1)] FIST_ROUNDING))
16867 (use (match_dup 2))
16868 (use (match_dup 3))
16869 (clobber (match_dup 5))])
16870 (set (match_dup 0) (match_dup 4))])
16873 [(set (match_operand:DI 0 "memory_operand")
16874 (unspec:DI [(match_operand:XF 1 "register_operand")]
16876 (use (match_operand:HI 2 "memory_operand"))
16877 (use (match_operand:HI 3 "memory_operand"))
16878 (clobber (match_operand:DI 4 "memory_operand"))
16879 (clobber (match_scratch 5))]
16881 [(parallel [(set (match_dup 0)
16882 (unspec:DI [(match_dup 1)] FIST_ROUNDING))
16883 (use (match_dup 2))
16884 (use (match_dup 3))
16885 (clobber (match_dup 5))])])
16887 (define_insn "fist<mode>2_<rounding>"
16888 [(set (match_operand:SWI24 0 "memory_operand" "=m")
16889 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
16891 (use (match_operand:HI 2 "memory_operand" "m"))
16892 (use (match_operand:HI 3 "memory_operand" "m"))]
16893 "TARGET_USE_FANCY_MATH_387
16894 && flag_unsafe_math_optimizations"
16895 "* return output_fix_trunc (insn, operands, false);"
16896 [(set_attr "type" "fistp")
16897 (set_attr "i387_cw" "<rounding>")
16898 (set_attr "mode" "<MODE>")])
16900 (define_insn "fist<mode>2_<rounding>_with_temp"
16901 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
16902 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f,f")]
16904 (use (match_operand:HI 2 "memory_operand" "m,m"))
16905 (use (match_operand:HI 3 "memory_operand" "m,m"))
16906 (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
16907 "TARGET_USE_FANCY_MATH_387
16908 && flag_unsafe_math_optimizations"
16910 [(set_attr "type" "fistp")
16911 (set_attr "i387_cw" "<rounding>")
16912 (set_attr "mode" "<MODE>")])
16915 [(set (match_operand:SWI24 0 "register_operand")
16916 (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
16918 (use (match_operand:HI 2 "memory_operand"))
16919 (use (match_operand:HI 3 "memory_operand"))
16920 (clobber (match_operand:SWI24 4 "memory_operand"))]
16922 [(parallel [(set (match_dup 4)
16923 (unspec:SWI24 [(match_dup 1)] FIST_ROUNDING))
16924 (use (match_dup 2))
16925 (use (match_dup 3))])
16926 (set (match_dup 0) (match_dup 4))])
16929 [(set (match_operand:SWI24 0 "memory_operand")
16930 (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
16932 (use (match_operand:HI 2 "memory_operand"))
16933 (use (match_operand:HI 3 "memory_operand"))
16934 (clobber (match_operand:SWI24 4 "memory_operand"))]
16936 [(parallel [(set (match_dup 0)
16937 (unspec:SWI24 [(match_dup 1)] FIST_ROUNDING))
16938 (use (match_dup 2))
16939 (use (match_dup 3))])])
16941 (define_expand "l<rounding_insn>xf<mode>2"
16942 [(parallel [(set (match_operand:SWI248x 0 "nonimmediate_operand")
16943 (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
16945 (clobber (reg:CC FLAGS_REG))])]
16946 "TARGET_USE_FANCY_MATH_387
16947 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16948 && flag_unsafe_math_optimizations")
16950 (define_expand "l<rounding_insn><MODEF:mode><SWI48:mode>2"
16951 [(parallel [(set (match_operand:SWI48 0 "nonimmediate_operand")
16952 (unspec:SWI48 [(match_operand:MODEF 1 "register_operand")]
16954 (clobber (reg:CC FLAGS_REG))])]
16955 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
16956 && (TARGET_SSE4_1 || !flag_trapping_math)"
16960 rtx tmp = gen_reg_rtx (<MODEF:MODE>mode);
16962 emit_insn (gen_sse4_1_round<mode>2
16963 (tmp, operands[1], GEN_INT (ROUND_<ROUNDING>
16965 emit_insn (gen_fix_trunc<MODEF:mode><SWI48:mode>2
16966 (operands[0], tmp));
16968 else if (ROUND_<ROUNDING> == ROUND_FLOOR)
16969 ix86_expand_lfloorceil (operands[0], operands[1], true);
16970 else if (ROUND_<ROUNDING> == ROUND_CEIL)
16971 ix86_expand_lfloorceil (operands[0], operands[1], false);
16973 gcc_unreachable ();
16978 (define_insn "fxam<mode>2_i387"
16979 [(set (match_operand:HI 0 "register_operand" "=a")
16981 [(match_operand:X87MODEF 1 "register_operand" "f")]
16983 "TARGET_USE_FANCY_MATH_387"
16984 "fxam\n\tfnstsw\t%0"
16985 [(set_attr "type" "multi")
16986 (set_attr "length" "4")
16987 (set_attr "unit" "i387")
16988 (set_attr "mode" "<MODE>")])
16990 (define_insn_and_split "fxam<mode>2_i387_with_temp"
16991 [(set (match_operand:HI 0 "register_operand")
16993 [(match_operand:MODEF 1 "memory_operand")]
16995 "TARGET_USE_FANCY_MATH_387
16996 && can_create_pseudo_p ()"
16999 [(set (match_dup 2)(match_dup 1))
17001 (unspec:HI [(match_dup 2)] UNSPEC_FXAM))]
17003 operands[2] = gen_reg_rtx (<MODE>mode);
17005 MEM_VOLATILE_P (operands[1]) = 1;
17007 [(set_attr "type" "multi")
17008 (set_attr "unit" "i387")
17009 (set_attr "mode" "<MODE>")])
17011 (define_expand "isinfxf2"
17012 [(use (match_operand:SI 0 "register_operand"))
17013 (use (match_operand:XF 1 "register_operand"))]
17014 "TARGET_USE_FANCY_MATH_387
17015 && ix86_libc_has_function (function_c99_misc)"
17017 rtx mask = GEN_INT (0x45);
17018 rtx val = GEN_INT (0x05);
17020 rtx scratch = gen_reg_rtx (HImode);
17021 rtx res = gen_reg_rtx (QImode);
17023 emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
17025 emit_insn (gen_andqi_ext_1 (scratch, scratch, mask));
17026 emit_insn (gen_cmpqi_ext_3 (scratch, val));
17027 ix86_expand_setcc (res, EQ,
17028 gen_rtx_REG (CCmode, FLAGS_REG), const0_rtx);
17029 emit_insn (gen_zero_extendqisi2 (operands[0], res));
17033 (define_expand "isinf<mode>2"
17034 [(use (match_operand:SI 0 "register_operand"))
17035 (use (match_operand:MODEF 1 "nonimmediate_operand"))]
17036 "TARGET_USE_FANCY_MATH_387
17037 && ix86_libc_has_function (function_c99_misc)
17038 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
17040 rtx mask = GEN_INT (0x45);
17041 rtx val = GEN_INT (0x05);
17043 rtx scratch = gen_reg_rtx (HImode);
17044 rtx res = gen_reg_rtx (QImode);
17046 /* Remove excess precision by forcing value through memory. */
17047 if (memory_operand (operands[1], VOIDmode))
17048 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, operands[1]));
17051 rtx temp = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17053 emit_move_insn (temp, operands[1]);
17054 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, temp));
17057 emit_insn (gen_andqi_ext_1 (scratch, scratch, mask));
17058 emit_insn (gen_cmpqi_ext_3 (scratch, val));
17059 ix86_expand_setcc (res, EQ,
17060 gen_rtx_REG (CCmode, FLAGS_REG), const0_rtx);
17061 emit_insn (gen_zero_extendqisi2 (operands[0], res));
17065 (define_expand "signbittf2"
17066 [(use (match_operand:SI 0 "register_operand"))
17067 (use (match_operand:TF 1 "register_operand"))]
17072 rtx mask = ix86_build_signbit_mask (TFmode, 0, 0);
17073 rtx scratch = gen_reg_rtx (QImode);
17075 emit_insn (gen_ptesttf2 (operands[1], mask));
17076 ix86_expand_setcc (scratch, NE,
17077 gen_rtx_REG (CCZmode, FLAGS_REG), const0_rtx);
17079 emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
17083 emit_insn (gen_sse_movmskps (operands[0],
17084 gen_lowpart (V4SFmode, operands[1])));
17085 emit_insn (gen_andsi3 (operands[0], operands[0], GEN_INT (0x8)));
17090 (define_expand "signbitxf2"
17091 [(use (match_operand:SI 0 "register_operand"))
17092 (use (match_operand:XF 1 "register_operand"))]
17093 "TARGET_USE_FANCY_MATH_387"
17095 rtx scratch = gen_reg_rtx (HImode);
17097 emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
17098 emit_insn (gen_andsi3 (operands[0],
17099 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
17103 (define_insn "movmsk_df"
17104 [(set (match_operand:SI 0 "register_operand" "=r")
17106 [(match_operand:DF 1 "register_operand" "x")]
17108 "SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH"
17109 "%vmovmskpd\t{%1, %0|%0, %1}"
17110 [(set_attr "type" "ssemov")
17111 (set_attr "prefix" "maybe_vex")
17112 (set_attr "mode" "DF")])
17114 ;; Use movmskpd in SSE mode to avoid store forwarding stall
17115 ;; for 32bit targets and movq+shrq sequence for 64bit targets.
17116 (define_expand "signbitdf2"
17117 [(use (match_operand:SI 0 "register_operand"))
17118 (use (match_operand:DF 1 "register_operand"))]
17119 "TARGET_USE_FANCY_MATH_387
17120 || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
17122 if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)
17124 emit_insn (gen_movmsk_df (operands[0], operands[1]));
17125 emit_insn (gen_andsi3 (operands[0], operands[0], const1_rtx));
17129 rtx scratch = gen_reg_rtx (HImode);
17131 emit_insn (gen_fxamdf2_i387 (scratch, operands[1]));
17132 emit_insn (gen_andsi3 (operands[0],
17133 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
17138 (define_expand "signbitsf2"
17139 [(use (match_operand:SI 0 "register_operand"))
17140 (use (match_operand:SF 1 "register_operand"))]
17141 "TARGET_USE_FANCY_MATH_387
17142 && !(SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH)"
17144 rtx scratch = gen_reg_rtx (HImode);
17146 emit_insn (gen_fxamsf2_i387 (scratch, operands[1]));
17147 emit_insn (gen_andsi3 (operands[0],
17148 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
17152 ;; Block operation instructions
17155 [(unspec_volatile [(const_int 0)] UNSPECV_CLD)]
17158 [(set_attr "length" "1")
17159 (set_attr "length_immediate" "0")
17160 (set_attr "modrm" "0")])
17162 (define_expand "movmem<mode>"
17163 [(use (match_operand:BLK 0 "memory_operand"))
17164 (use (match_operand:BLK 1 "memory_operand"))
17165 (use (match_operand:SWI48 2 "nonmemory_operand"))
17166 (use (match_operand:SWI48 3 "const_int_operand"))
17167 (use (match_operand:SI 4 "const_int_operand"))
17168 (use (match_operand:SI 5 "const_int_operand"))
17169 (use (match_operand:SI 6 ""))
17170 (use (match_operand:SI 7 ""))
17171 (use (match_operand:SI 8 ""))]
17174 if (ix86_expand_set_or_movmem (operands[0], operands[1],
17175 operands[2], NULL, operands[3],
17176 operands[4], operands[5],
17177 operands[6], operands[7],
17178 operands[8], false))
17184 ;; Most CPUs don't like single string operations
17185 ;; Handle this case here to simplify previous expander.
17187 (define_expand "strmov"
17188 [(set (match_dup 4) (match_operand 3 "memory_operand"))
17189 (set (match_operand 1 "memory_operand") (match_dup 4))
17190 (parallel [(set (match_operand 0 "register_operand") (match_dup 5))
17191 (clobber (reg:CC FLAGS_REG))])
17192 (parallel [(set (match_operand 2 "register_operand") (match_dup 6))
17193 (clobber (reg:CC FLAGS_REG))])]
17196 /* Can't use this for non-default address spaces. */
17197 if (!ADDR_SPACE_GENERIC_P (MEM_ADDR_SPACE (operands[3])))
17200 rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
17202 /* If .md ever supports :P for Pmode, these can be directly
17203 in the pattern above. */
17204 operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
17205 operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
17207 /* Can't use this if the user has appropriated esi or edi. */
17208 if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
17209 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG]))
17211 emit_insn (gen_strmov_singleop (operands[0], operands[1],
17212 operands[2], operands[3],
17213 operands[5], operands[6]));
17217 operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
17220 (define_expand "strmov_singleop"
17221 [(parallel [(set (match_operand 1 "memory_operand")
17222 (match_operand 3 "memory_operand"))
17223 (set (match_operand 0 "register_operand")
17225 (set (match_operand 2 "register_operand")
17226 (match_operand 5))])]
17230 ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
17233 (define_insn "*strmovdi_rex_1"
17234 [(set (mem:DI (match_operand:P 2 "register_operand" "0"))
17235 (mem:DI (match_operand:P 3 "register_operand" "1")))
17236 (set (match_operand:P 0 "register_operand" "=D")
17237 (plus:P (match_dup 2)
17239 (set (match_operand:P 1 "register_operand" "=S")
17240 (plus:P (match_dup 3)
17243 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG])
17244 && ix86_check_no_addr_space (insn)"
17246 [(set_attr "type" "str")
17247 (set_attr "memory" "both")
17248 (set_attr "mode" "DI")])
17250 (define_insn "*strmovsi_1"
17251 [(set (mem:SI (match_operand:P 2 "register_operand" "0"))
17252 (mem:SI (match_operand:P 3 "register_operand" "1")))
17253 (set (match_operand:P 0 "register_operand" "=D")
17254 (plus:P (match_dup 2)
17256 (set (match_operand:P 1 "register_operand" "=S")
17257 (plus:P (match_dup 3)
17259 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])
17260 && ix86_check_no_addr_space (insn)"
17262 [(set_attr "type" "str")
17263 (set_attr "memory" "both")
17264 (set_attr "mode" "SI")])
17266 (define_insn "*strmovhi_1"
17267 [(set (mem:HI (match_operand:P 2 "register_operand" "0"))
17268 (mem:HI (match_operand:P 3 "register_operand" "1")))
17269 (set (match_operand:P 0 "register_operand" "=D")
17270 (plus:P (match_dup 2)
17272 (set (match_operand:P 1 "register_operand" "=S")
17273 (plus:P (match_dup 3)
17275 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])
17276 && ix86_check_no_addr_space (insn)"
17278 [(set_attr "type" "str")
17279 (set_attr "memory" "both")
17280 (set_attr "mode" "HI")])
17282 (define_insn "*strmovqi_1"
17283 [(set (mem:QI (match_operand:P 2 "register_operand" "0"))
17284 (mem:QI (match_operand:P 3 "register_operand" "1")))
17285 (set (match_operand:P 0 "register_operand" "=D")
17286 (plus:P (match_dup 2)
17288 (set (match_operand:P 1 "register_operand" "=S")
17289 (plus:P (match_dup 3)
17291 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])
17292 && ix86_check_no_addr_space (insn)"
17294 [(set_attr "type" "str")
17295 (set_attr "memory" "both")
17296 (set (attr "prefix_rex")
17298 (match_test "<P:MODE>mode == DImode")
17300 (const_string "*")))
17301 (set_attr "mode" "QI")])
17303 (define_expand "rep_mov"
17304 [(parallel [(set (match_operand 4 "register_operand") (const_int 0))
17305 (set (match_operand 0 "register_operand")
17307 (set (match_operand 2 "register_operand")
17309 (set (match_operand 1 "memory_operand")
17310 (match_operand 3 "memory_operand"))
17311 (use (match_dup 4))])]
17315 ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
17318 (define_insn "*rep_movdi_rex64"
17319 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
17320 (set (match_operand:P 0 "register_operand" "=D")
17321 (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
17323 (match_operand:P 3 "register_operand" "0")))
17324 (set (match_operand:P 1 "register_operand" "=S")
17325 (plus:P (ashift:P (match_dup 5) (const_int 3))
17326 (match_operand:P 4 "register_operand" "1")))
17327 (set (mem:BLK (match_dup 3))
17328 (mem:BLK (match_dup 4)))
17329 (use (match_dup 5))]
17331 && !(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
17332 && ix86_check_no_addr_space (insn)"
17334 [(set_attr "type" "str")
17335 (set_attr "prefix_rep" "1")
17336 (set_attr "memory" "both")
17337 (set_attr "mode" "DI")])
17339 (define_insn "*rep_movsi"
17340 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
17341 (set (match_operand:P 0 "register_operand" "=D")
17342 (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
17344 (match_operand:P 3 "register_operand" "0")))
17345 (set (match_operand:P 1 "register_operand" "=S")
17346 (plus:P (ashift:P (match_dup 5) (const_int 2))
17347 (match_operand:P 4 "register_operand" "1")))
17348 (set (mem:BLK (match_dup 3))
17349 (mem:BLK (match_dup 4)))
17350 (use (match_dup 5))]
17351 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
17352 && ix86_check_no_addr_space (insn)"
17353 "%^rep{%;} movs{l|d}"
17354 [(set_attr "type" "str")
17355 (set_attr "prefix_rep" "1")
17356 (set_attr "memory" "both")
17357 (set_attr "mode" "SI")])
17359 (define_insn "*rep_movqi"
17360 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
17361 (set (match_operand:P 0 "register_operand" "=D")
17362 (plus:P (match_operand:P 3 "register_operand" "0")
17363 (match_operand:P 5 "register_operand" "2")))
17364 (set (match_operand:P 1 "register_operand" "=S")
17365 (plus:P (match_operand:P 4 "register_operand" "1") (match_dup 5)))
17366 (set (mem:BLK (match_dup 3))
17367 (mem:BLK (match_dup 4)))
17368 (use (match_dup 5))]
17369 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
17370 && ix86_check_no_addr_space (insn)"
17372 [(set_attr "type" "str")
17373 (set_attr "prefix_rep" "1")
17374 (set_attr "memory" "both")
17375 (set_attr "mode" "QI")])
17377 (define_expand "setmem<mode>"
17378 [(use (match_operand:BLK 0 "memory_operand"))
17379 (use (match_operand:SWI48 1 "nonmemory_operand"))
17380 (use (match_operand:QI 2 "nonmemory_operand"))
17381 (use (match_operand 3 "const_int_operand"))
17382 (use (match_operand:SI 4 "const_int_operand"))
17383 (use (match_operand:SI 5 "const_int_operand"))
17384 (use (match_operand:SI 6 ""))
17385 (use (match_operand:SI 7 ""))
17386 (use (match_operand:SI 8 ""))]
17389 if (ix86_expand_set_or_movmem (operands[0], NULL,
17390 operands[1], operands[2],
17391 operands[3], operands[4],
17392 operands[5], operands[6],
17393 operands[7], operands[8], true))
17399 ;; Most CPUs don't like single string operations
17400 ;; Handle this case here to simplify previous expander.
17402 (define_expand "strset"
17403 [(set (match_operand 1 "memory_operand")
17404 (match_operand 2 "register_operand"))
17405 (parallel [(set (match_operand 0 "register_operand")
17407 (clobber (reg:CC FLAGS_REG))])]
17410 /* Can't use this for non-default address spaces. */
17411 if (!ADDR_SPACE_GENERIC_P (MEM_ADDR_SPACE (operands[1])))
17414 if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
17415 operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
17417 /* If .md ever supports :P for Pmode, this can be directly
17418 in the pattern above. */
17419 operands[3] = gen_rtx_PLUS (Pmode, operands[0],
17420 GEN_INT (GET_MODE_SIZE (GET_MODE
17422 /* Can't use this if the user has appropriated eax or edi. */
17423 if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
17424 && !(fixed_regs[AX_REG] || fixed_regs[DI_REG]))
17426 emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
17432 (define_expand "strset_singleop"
17433 [(parallel [(set (match_operand 1 "memory_operand")
17434 (match_operand 2 "register_operand"))
17435 (set (match_operand 0 "register_operand")
17437 (unspec [(const_int 0)] UNSPEC_STOS)])]
17441 ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
17444 (define_insn "*strsetdi_rex_1"
17445 [(set (mem:DI (match_operand:P 1 "register_operand" "0"))
17446 (match_operand:DI 2 "register_operand" "a"))
17447 (set (match_operand:P 0 "register_operand" "=D")
17448 (plus:P (match_dup 1)
17450 (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" "DI")])
17459 (define_insn "*strsetsi_1"
17460 [(set (mem:SI (match_operand:P 1 "register_operand" "0"))
17461 (match_operand:SI 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" "SI")])
17473 (define_insn "*strsethi_1"
17474 [(set (mem:HI (match_operand:P 1 "register_operand" "0"))
17475 (match_operand:HI 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 "mode" "HI")])
17487 (define_insn "*strsetqi_1"
17488 [(set (mem:QI (match_operand:P 1 "register_operand" "0"))
17489 (match_operand:QI 2 "register_operand" "a"))
17490 (set (match_operand:P 0 "register_operand" "=D")
17491 (plus:P (match_dup 1)
17493 (unspec [(const_int 0)] UNSPEC_STOS)]
17494 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])
17495 && ix86_check_no_addr_space (insn)"
17497 [(set_attr "type" "str")
17498 (set_attr "memory" "store")
17499 (set (attr "prefix_rex")
17501 (match_test "<P:MODE>mode == DImode")
17503 (const_string "*")))
17504 (set_attr "mode" "QI")])
17506 (define_expand "rep_stos"
17507 [(parallel [(set (match_operand 1 "register_operand") (const_int 0))
17508 (set (match_operand 0 "register_operand")
17510 (set (match_operand 2 "memory_operand") (const_int 0))
17511 (use (match_operand 3 "register_operand"))
17512 (use (match_dup 1))])]
17516 ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
17519 (define_insn "*rep_stosdi_rex64"
17520 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
17521 (set (match_operand:P 0 "register_operand" "=D")
17522 (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
17524 (match_operand:P 3 "register_operand" "0")))
17525 (set (mem:BLK (match_dup 3))
17527 (use (match_operand:DI 2 "register_operand" "a"))
17528 (use (match_dup 4))]
17530 && !(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])
17531 && ix86_check_no_addr_space (insn)"
17533 [(set_attr "type" "str")
17534 (set_attr "prefix_rep" "1")
17535 (set_attr "memory" "store")
17536 (set_attr "mode" "DI")])
17538 (define_insn "*rep_stossi"
17539 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
17540 (set (match_operand:P 0 "register_operand" "=D")
17541 (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
17543 (match_operand:P 3 "register_operand" "0")))
17544 (set (mem:BLK (match_dup 3))
17546 (use (match_operand:SI 2 "register_operand" "a"))
17547 (use (match_dup 4))]
17548 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])
17549 && ix86_check_no_addr_space (insn)"
17550 "%^rep{%;} stos{l|d}"
17551 [(set_attr "type" "str")
17552 (set_attr "prefix_rep" "1")
17553 (set_attr "memory" "store")
17554 (set_attr "mode" "SI")])
17556 (define_insn "*rep_stosqi"
17557 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
17558 (set (match_operand:P 0 "register_operand" "=D")
17559 (plus:P (match_operand:P 3 "register_operand" "0")
17560 (match_operand:P 4 "register_operand" "1")))
17561 (set (mem:BLK (match_dup 3))
17563 (use (match_operand:QI 2 "register_operand" "a"))
17564 (use (match_dup 4))]
17565 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])
17566 && ix86_check_no_addr_space (insn)"
17568 [(set_attr "type" "str")
17569 (set_attr "prefix_rep" "1")
17570 (set_attr "memory" "store")
17571 (set (attr "prefix_rex")
17573 (match_test "<P:MODE>mode == DImode")
17575 (const_string "*")))
17576 (set_attr "mode" "QI")])
17578 (define_expand "cmpstrnsi"
17579 [(set (match_operand:SI 0 "register_operand")
17580 (compare:SI (match_operand:BLK 1 "general_operand")
17581 (match_operand:BLK 2 "general_operand")))
17582 (use (match_operand 3 "general_operand"))
17583 (use (match_operand 4 "immediate_operand"))]
17586 rtx addr1, addr2, out, outlow, count, countreg, align;
17588 if (optimize_insn_for_size_p () && !TARGET_INLINE_ALL_STRINGOPS)
17591 /* Can't use this if the user has appropriated ecx, esi or edi. */
17592 if (fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
17595 /* One of the strings must be a constant. If so, expand_builtin_strncmp()
17596 will have rewritten the length arg to be the minimum of the const string
17597 length and the actual length arg. If both strings are the same and
17598 shorter than the length arg, repz cmpsb will not stop at the 0 byte and
17599 will incorrectly base the results on chars past the 0 byte. */
17600 tree t1 = MEM_EXPR (operands[1]);
17601 tree t2 = MEM_EXPR (operands[2]);
17602 if (!((t1 && TREE_CODE (t1) == MEM_REF
17603 && TREE_CODE (TREE_OPERAND (t1, 0)) == ADDR_EXPR
17604 && TREE_CODE (TREE_OPERAND (TREE_OPERAND (t1, 0), 0)) == STRING_CST)
17605 || (t2 && TREE_CODE (t2) == MEM_REF
17606 && TREE_CODE (TREE_OPERAND (t2, 0)) == ADDR_EXPR
17607 && TREE_CODE (TREE_OPERAND (TREE_OPERAND (t2, 0), 0)) == STRING_CST)))
17612 out = gen_reg_rtx (SImode);
17614 addr1 = copy_addr_to_reg (XEXP (operands[1], 0));
17615 addr2 = copy_addr_to_reg (XEXP (operands[2], 0));
17616 if (addr1 != XEXP (operands[1], 0))
17617 operands[1] = replace_equiv_address_nv (operands[1], addr1);
17618 if (addr2 != XEXP (operands[2], 0))
17619 operands[2] = replace_equiv_address_nv (operands[2], addr2);
17621 count = operands[3];
17622 countreg = ix86_zero_extend_to_Pmode (count);
17624 /* %%% Iff we are testing strict equality, we can use known alignment
17625 to good advantage. This may be possible with combine, particularly
17626 once cc0 is dead. */
17627 align = operands[4];
17629 if (CONST_INT_P (count))
17631 if (INTVAL (count) == 0)
17633 emit_move_insn (operands[0], const0_rtx);
17636 emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
17637 operands[1], operands[2]));
17641 rtx (*gen_cmp) (rtx, rtx);
17643 gen_cmp = (TARGET_64BIT
17644 ? gen_cmpdi_1 : gen_cmpsi_1);
17646 emit_insn (gen_cmp (countreg, countreg));
17647 emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
17648 operands[1], operands[2]));
17651 outlow = gen_lowpart (QImode, out);
17652 emit_insn (gen_cmpintqi (outlow));
17653 emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
17655 if (operands[0] != out)
17656 emit_move_insn (operands[0], out);
17661 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
17663 (define_expand "cmpintqi"
17664 [(set (match_dup 1)
17665 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
17667 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
17668 (parallel [(set (match_operand:QI 0 "register_operand")
17669 (minus:QI (match_dup 1)
17671 (clobber (reg:CC FLAGS_REG))])]
17674 operands[1] = gen_reg_rtx (QImode);
17675 operands[2] = gen_reg_rtx (QImode);
17678 ;; memcmp recognizers. The `cmpsb' opcode does nothing if the count is
17679 ;; zero. Emit extra code to make sure that a zero-length compare is EQ.
17681 (define_expand "cmpstrnqi_nz_1"
17682 [(parallel [(set (reg:CC FLAGS_REG)
17683 (compare:CC (match_operand 4 "memory_operand")
17684 (match_operand 5 "memory_operand")))
17685 (use (match_operand 2 "register_operand"))
17686 (use (match_operand:SI 3 "immediate_operand"))
17687 (clobber (match_operand 0 "register_operand"))
17688 (clobber (match_operand 1 "register_operand"))
17689 (clobber (match_dup 2))])]
17693 ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
17696 (define_insn "*cmpstrnqi_nz_1"
17697 [(set (reg:CC FLAGS_REG)
17698 (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
17699 (mem:BLK (match_operand:P 5 "register_operand" "1"))))
17700 (use (match_operand:P 6 "register_operand" "2"))
17701 (use (match_operand:SI 3 "immediate_operand" "i"))
17702 (clobber (match_operand:P 0 "register_operand" "=S"))
17703 (clobber (match_operand:P 1 "register_operand" "=D"))
17704 (clobber (match_operand:P 2 "register_operand" "=c"))]
17705 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
17706 && ix86_check_no_addr_space (insn)"
17708 [(set_attr "type" "str")
17709 (set_attr "mode" "QI")
17710 (set (attr "prefix_rex")
17712 (match_test "<P:MODE>mode == DImode")
17714 (const_string "*")))
17715 (set_attr "prefix_rep" "1")])
17717 ;; The same, but the count is not known to not be zero.
17719 (define_expand "cmpstrnqi_1"
17720 [(parallel [(set (reg:CC FLAGS_REG)
17721 (if_then_else:CC (ne (match_operand 2 "register_operand")
17723 (compare:CC (match_operand 4 "memory_operand")
17724 (match_operand 5 "memory_operand"))
17726 (use (match_operand:SI 3 "immediate_operand"))
17727 (use (reg:CC FLAGS_REG))
17728 (clobber (match_operand 0 "register_operand"))
17729 (clobber (match_operand 1 "register_operand"))
17730 (clobber (match_dup 2))])]
17734 ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
17737 (define_insn "*cmpstrnqi_1"
17738 [(set (reg:CC FLAGS_REG)
17739 (if_then_else:CC (ne (match_operand:P 6 "register_operand" "2")
17741 (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
17742 (mem:BLK (match_operand:P 5 "register_operand" "1")))
17744 (use (match_operand:SI 3 "immediate_operand" "i"))
17745 (use (reg:CC FLAGS_REG))
17746 (clobber (match_operand:P 0 "register_operand" "=S"))
17747 (clobber (match_operand:P 1 "register_operand" "=D"))
17748 (clobber (match_operand:P 2 "register_operand" "=c"))]
17749 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
17750 && ix86_check_no_addr_space (insn)"
17752 [(set_attr "type" "str")
17753 (set_attr "mode" "QI")
17754 (set (attr "prefix_rex")
17756 (match_test "<P:MODE>mode == DImode")
17758 (const_string "*")))
17759 (set_attr "prefix_rep" "1")])
17761 (define_expand "strlen<mode>"
17762 [(set (match_operand:P 0 "register_operand")
17763 (unspec:P [(match_operand:BLK 1 "general_operand")
17764 (match_operand:QI 2 "immediate_operand")
17765 (match_operand 3 "immediate_operand")]
17769 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
17775 (define_expand "strlenqi_1"
17776 [(parallel [(set (match_operand 0 "register_operand")
17778 (clobber (match_operand 1 "register_operand"))
17779 (clobber (reg:CC FLAGS_REG))])]
17783 ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
17786 (define_insn "*strlenqi_1"
17787 [(set (match_operand:P 0 "register_operand" "=&c")
17788 (unspec:P [(mem:BLK (match_operand:P 5 "register_operand" "1"))
17789 (match_operand:QI 2 "register_operand" "a")
17790 (match_operand:P 3 "immediate_operand" "i")
17791 (match_operand:P 4 "register_operand" "0")] UNSPEC_SCAS))
17792 (clobber (match_operand:P 1 "register_operand" "=D"))
17793 (clobber (reg:CC FLAGS_REG))]
17794 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])
17795 && ix86_check_no_addr_space (insn)"
17796 "%^repnz{%;} scasb"
17797 [(set_attr "type" "str")
17798 (set_attr "mode" "QI")
17799 (set (attr "prefix_rex")
17801 (match_test "<P:MODE>mode == DImode")
17803 (const_string "*")))
17804 (set_attr "prefix_rep" "1")])
17806 ;; Peephole optimizations to clean up after cmpstrn*. This should be
17807 ;; handled in combine, but it is not currently up to the task.
17808 ;; When used for their truth value, the cmpstrn* expanders generate
17817 ;; The intermediate three instructions are unnecessary.
17819 ;; This one handles cmpstrn*_nz_1...
17822 (set (reg:CC FLAGS_REG)
17823 (compare:CC (mem:BLK (match_operand 4 "register_operand"))
17824 (mem:BLK (match_operand 5 "register_operand"))))
17825 (use (match_operand 6 "register_operand"))
17826 (use (match_operand:SI 3 "immediate_operand"))
17827 (clobber (match_operand 0 "register_operand"))
17828 (clobber (match_operand 1 "register_operand"))
17829 (clobber (match_operand 2 "register_operand"))])
17830 (set (match_operand:QI 7 "register_operand")
17831 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
17832 (set (match_operand:QI 8 "register_operand")
17833 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
17834 (set (reg FLAGS_REG)
17835 (compare (match_dup 7) (match_dup 8)))
17837 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
17839 (set (reg:CC FLAGS_REG)
17840 (compare:CC (mem:BLK (match_dup 4))
17841 (mem:BLK (match_dup 5))))
17842 (use (match_dup 6))
17843 (use (match_dup 3))
17844 (clobber (match_dup 0))
17845 (clobber (match_dup 1))
17846 (clobber (match_dup 2))])])
17848 ;; ...and this one handles cmpstrn*_1.
17851 (set (reg:CC FLAGS_REG)
17852 (if_then_else:CC (ne (match_operand 6 "register_operand")
17854 (compare:CC (mem:BLK (match_operand 4 "register_operand"))
17855 (mem:BLK (match_operand 5 "register_operand")))
17857 (use (match_operand:SI 3 "immediate_operand"))
17858 (use (reg:CC FLAGS_REG))
17859 (clobber (match_operand 0 "register_operand"))
17860 (clobber (match_operand 1 "register_operand"))
17861 (clobber (match_operand 2 "register_operand"))])
17862 (set (match_operand:QI 7 "register_operand")
17863 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
17864 (set (match_operand:QI 8 "register_operand")
17865 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
17866 (set (reg FLAGS_REG)
17867 (compare (match_dup 7) (match_dup 8)))
17869 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
17871 (set (reg:CC FLAGS_REG)
17872 (if_then_else:CC (ne (match_dup 6)
17874 (compare:CC (mem:BLK (match_dup 4))
17875 (mem:BLK (match_dup 5)))
17877 (use (match_dup 3))
17878 (use (reg:CC FLAGS_REG))
17879 (clobber (match_dup 0))
17880 (clobber (match_dup 1))
17881 (clobber (match_dup 2))])])
17883 ;; Conditional move instructions.
17885 (define_expand "mov<mode>cc"
17886 [(set (match_operand:SWIM 0 "register_operand")
17887 (if_then_else:SWIM (match_operand 1 "comparison_operator")
17888 (match_operand:SWIM 2 "<general_operand>")
17889 (match_operand:SWIM 3 "<general_operand>")))]
17891 "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
17893 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
17894 ;; the register first winds up with `sbbl $0,reg', which is also weird.
17895 ;; So just document what we're doing explicitly.
17897 (define_expand "x86_mov<mode>cc_0_m1"
17899 [(set (match_operand:SWI48 0 "register_operand")
17900 (if_then_else:SWI48
17901 (match_operator:SWI48 2 "ix86_carry_flag_operator"
17902 [(match_operand 1 "flags_reg_operand")
17906 (clobber (reg:CC FLAGS_REG))])])
17908 (define_insn "*x86_mov<mode>cc_0_m1"
17909 [(set (match_operand:SWI48 0 "register_operand" "=r")
17910 (if_then_else:SWI48 (match_operator 1 "ix86_carry_flag_operator"
17911 [(reg FLAGS_REG) (const_int 0)])
17914 (clobber (reg:CC FLAGS_REG))]
17916 "sbb{<imodesuffix>}\t%0, %0"
17917 ; Since we don't have the proper number of operands for an alu insn,
17918 ; fill in all the blanks.
17919 [(set_attr "type" "alu")
17920 (set_attr "modrm_class" "op0")
17921 (set_attr "use_carry" "1")
17922 (set_attr "pent_pair" "pu")
17923 (set_attr "memory" "none")
17924 (set_attr "imm_disp" "false")
17925 (set_attr "mode" "<MODE>")
17926 (set_attr "length_immediate" "0")])
17928 (define_insn "*x86_mov<mode>cc_0_m1_se"
17929 [(set (match_operand:SWI48 0 "register_operand" "=r")
17930 (sign_extract:SWI48 (match_operator 1 "ix86_carry_flag_operator"
17931 [(reg FLAGS_REG) (const_int 0)])
17934 (clobber (reg:CC FLAGS_REG))]
17936 "sbb{<imodesuffix>}\t%0, %0"
17937 [(set_attr "type" "alu")
17938 (set_attr "modrm_class" "op0")
17939 (set_attr "use_carry" "1")
17940 (set_attr "pent_pair" "pu")
17941 (set_attr "memory" "none")
17942 (set_attr "imm_disp" "false")
17943 (set_attr "mode" "<MODE>")
17944 (set_attr "length_immediate" "0")])
17946 (define_insn "*x86_mov<mode>cc_0_m1_neg"
17947 [(set (match_operand:SWI48 0 "register_operand" "=r")
17948 (neg:SWI48 (match_operator 1 "ix86_carry_flag_operator"
17949 [(reg FLAGS_REG) (const_int 0)])))
17950 (clobber (reg:CC FLAGS_REG))]
17952 "sbb{<imodesuffix>}\t%0, %0"
17953 [(set_attr "type" "alu")
17954 (set_attr "modrm_class" "op0")
17955 (set_attr "use_carry" "1")
17956 (set_attr "pent_pair" "pu")
17957 (set_attr "memory" "none")
17958 (set_attr "imm_disp" "false")
17959 (set_attr "mode" "<MODE>")
17960 (set_attr "length_immediate" "0")])
17962 (define_insn "*mov<mode>cc_noc"
17963 [(set (match_operand:SWI248 0 "register_operand" "=r,r")
17964 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
17965 [(reg FLAGS_REG) (const_int 0)])
17966 (match_operand:SWI248 2 "nonimmediate_operand" "rm,0")
17967 (match_operand:SWI248 3 "nonimmediate_operand" "0,rm")))]
17968 "TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
17970 cmov%O2%C1\t{%2, %0|%0, %2}
17971 cmov%O2%c1\t{%3, %0|%0, %3}"
17972 [(set_attr "type" "icmov")
17973 (set_attr "mode" "<MODE>")])
17975 (define_insn "*movsicc_noc_zext"
17976 [(set (match_operand:DI 0 "register_operand" "=r,r")
17977 (if_then_else:DI (match_operator 1 "ix86_comparison_operator"
17978 [(reg FLAGS_REG) (const_int 0)])
17980 (match_operand:SI 2 "nonimmediate_operand" "rm,0"))
17982 (match_operand:SI 3 "nonimmediate_operand" "0,rm"))))]
17984 && TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
17986 cmov%O2%C1\t{%2, %k0|%k0, %2}
17987 cmov%O2%c1\t{%3, %k0|%k0, %3}"
17988 [(set_attr "type" "icmov")
17989 (set_attr "mode" "SI")])
17991 ;; Don't do conditional moves with memory inputs. This splitter helps
17992 ;; register starved x86_32 by forcing inputs into registers before reload.
17994 [(set (match_operand:SWI248 0 "register_operand")
17995 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
17996 [(reg FLAGS_REG) (const_int 0)])
17997 (match_operand:SWI248 2 "nonimmediate_operand")
17998 (match_operand:SWI248 3 "nonimmediate_operand")))]
17999 "!TARGET_64BIT && TARGET_CMOVE
18000 && TARGET_AVOID_MEM_OPND_FOR_CMOVE
18001 && (MEM_P (operands[2]) || MEM_P (operands[3]))
18002 && can_create_pseudo_p ()
18003 && optimize_insn_for_speed_p ()"
18004 [(set (match_dup 0)
18005 (if_then_else:SWI248 (match_dup 1) (match_dup 2) (match_dup 3)))]
18007 if (MEM_P (operands[2]))
18008 operands[2] = force_reg (<MODE>mode, operands[2]);
18009 if (MEM_P (operands[3]))
18010 operands[3] = force_reg (<MODE>mode, operands[3]);
18013 (define_insn "*movqicc_noc"
18014 [(set (match_operand:QI 0 "register_operand" "=r,r")
18015 (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
18016 [(reg FLAGS_REG) (const_int 0)])
18017 (match_operand:QI 2 "register_operand" "r,0")
18018 (match_operand:QI 3 "register_operand" "0,r")))]
18019 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
18021 [(set_attr "type" "icmov")
18022 (set_attr "mode" "QI")])
18025 [(set (match_operand:SWI12 0 "register_operand")
18026 (if_then_else:SWI12 (match_operator 1 "ix86_comparison_operator"
18027 [(reg FLAGS_REG) (const_int 0)])
18028 (match_operand:SWI12 2 "register_operand")
18029 (match_operand:SWI12 3 "register_operand")))]
18030 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL
18031 && reload_completed"
18032 [(set (match_dup 0)
18033 (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
18035 operands[0] = gen_lowpart (SImode, operands[0]);
18036 operands[2] = gen_lowpart (SImode, operands[2]);
18037 operands[3] = gen_lowpart (SImode, operands[3]);
18040 ;; Don't do conditional moves with memory inputs
18042 [(match_scratch:SWI248 4 "r")
18043 (set (match_operand:SWI248 0 "register_operand")
18044 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
18045 [(reg FLAGS_REG) (const_int 0)])
18046 (match_operand:SWI248 2 "nonimmediate_operand")
18047 (match_operand:SWI248 3 "nonimmediate_operand")))]
18048 "TARGET_CMOVE && TARGET_AVOID_MEM_OPND_FOR_CMOVE
18049 && (MEM_P (operands[2]) || MEM_P (operands[3]))
18050 && optimize_insn_for_speed_p ()"
18051 [(set (match_dup 4) (match_dup 5))
18053 (if_then_else:SWI248 (match_dup 1) (match_dup 2) (match_dup 3)))]
18055 if (MEM_P (operands[2]))
18057 operands[5] = operands[2];
18058 operands[2] = operands[4];
18060 else if (MEM_P (operands[3]))
18062 operands[5] = operands[3];
18063 operands[3] = operands[4];
18066 gcc_unreachable ();
18070 [(match_scratch:SI 4 "r")
18071 (set (match_operand:DI 0 "register_operand")
18072 (if_then_else:DI (match_operator 1 "ix86_comparison_operator"
18073 [(reg FLAGS_REG) (const_int 0)])
18075 (match_operand:SI 2 "nonimmediate_operand"))
18077 (match_operand:SI 3 "nonimmediate_operand"))))]
18079 && TARGET_CMOVE && TARGET_AVOID_MEM_OPND_FOR_CMOVE
18080 && (MEM_P (operands[2]) || MEM_P (operands[3]))
18081 && optimize_insn_for_speed_p ()"
18082 [(set (match_dup 4) (match_dup 5))
18084 (if_then_else:DI (match_dup 1)
18085 (zero_extend:DI (match_dup 2))
18086 (zero_extend:DI (match_dup 3))))]
18088 if (MEM_P (operands[2]))
18090 operands[5] = operands[2];
18091 operands[2] = operands[4];
18093 else if (MEM_P (operands[3]))
18095 operands[5] = operands[3];
18096 operands[3] = operands[4];
18099 gcc_unreachable ();
18102 (define_expand "mov<mode>cc"
18103 [(set (match_operand:X87MODEF 0 "register_operand")
18104 (if_then_else:X87MODEF
18105 (match_operand 1 "comparison_operator")
18106 (match_operand:X87MODEF 2 "register_operand")
18107 (match_operand:X87MODEF 3 "register_operand")))]
18108 "(TARGET_80387 && TARGET_CMOVE)
18109 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
18110 "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
18112 (define_insn "*movxfcc_1"
18113 [(set (match_operand:XF 0 "register_operand" "=f,f")
18114 (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
18115 [(reg FLAGS_REG) (const_int 0)])
18116 (match_operand:XF 2 "register_operand" "f,0")
18117 (match_operand:XF 3 "register_operand" "0,f")))]
18118 "TARGET_80387 && TARGET_CMOVE"
18120 fcmov%F1\t{%2, %0|%0, %2}
18121 fcmov%f1\t{%3, %0|%0, %3}"
18122 [(set_attr "type" "fcmov")
18123 (set_attr "mode" "XF")])
18125 (define_insn "*movdfcc_1"
18126 [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r,r ,r")
18127 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
18128 [(reg FLAGS_REG) (const_int 0)])
18129 (match_operand:DF 2 "nonimmediate_operand"
18131 (match_operand:DF 3 "nonimmediate_operand"
18132 "0 ,f,0 ,rm,0, rm")))]
18133 "TARGET_80387 && TARGET_CMOVE
18134 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
18136 fcmov%F1\t{%2, %0|%0, %2}
18137 fcmov%f1\t{%3, %0|%0, %3}
18140 cmov%O2%C1\t{%2, %0|%0, %2}
18141 cmov%O2%c1\t{%3, %0|%0, %3}"
18142 [(set_attr "isa" "*,*,nox64,nox64,x64,x64")
18143 (set_attr "type" "fcmov,fcmov,multi,multi,icmov,icmov")
18144 (set_attr "mode" "DF,DF,DI,DI,DI,DI")])
18147 [(set (match_operand:DF 0 "general_reg_operand")
18148 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
18149 [(reg FLAGS_REG) (const_int 0)])
18150 (match_operand:DF 2 "nonimmediate_operand")
18151 (match_operand:DF 3 "nonimmediate_operand")))]
18152 "!TARGET_64BIT && reload_completed"
18153 [(set (match_dup 2)
18154 (if_then_else:SI (match_dup 1) (match_dup 4) (match_dup 5)))
18156 (if_then_else:SI (match_dup 1) (match_dup 6) (match_dup 7)))]
18158 split_double_mode (DImode, &operands[2], 2, &operands[4], &operands[6]);
18159 split_double_mode (DImode, &operands[0], 1, &operands[2], &operands[3]);
18162 (define_insn "*movsfcc_1_387"
18163 [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
18164 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
18165 [(reg FLAGS_REG) (const_int 0)])
18166 (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
18167 (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
18168 "TARGET_80387 && TARGET_CMOVE
18169 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
18171 fcmov%F1\t{%2, %0|%0, %2}
18172 fcmov%f1\t{%3, %0|%0, %3}
18173 cmov%O2%C1\t{%2, %0|%0, %2}
18174 cmov%O2%c1\t{%3, %0|%0, %3}"
18175 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
18176 (set_attr "mode" "SF,SF,SI,SI")])
18178 ;; Don't do conditional moves with memory inputs. This splitter helps
18179 ;; register starved x86_32 by forcing inputs into registers before reload.
18181 [(set (match_operand:MODEF 0 "register_operand")
18182 (if_then_else:MODEF (match_operator 1 "ix86_comparison_operator"
18183 [(reg FLAGS_REG) (const_int 0)])
18184 (match_operand:MODEF 2 "nonimmediate_operand")
18185 (match_operand:MODEF 3 "nonimmediate_operand")))]
18186 "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
18187 && TARGET_AVOID_MEM_OPND_FOR_CMOVE
18188 && (MEM_P (operands[2]) || MEM_P (operands[3]))
18189 && can_create_pseudo_p ()
18190 && optimize_insn_for_speed_p ()"
18191 [(set (match_dup 0)
18192 (if_then_else:MODEF (match_dup 1) (match_dup 2) (match_dup 3)))]
18194 if (MEM_P (operands[2]))
18195 operands[2] = force_reg (<MODE>mode, operands[2]);
18196 if (MEM_P (operands[3]))
18197 operands[3] = force_reg (<MODE>mode, operands[3]);
18200 ;; Don't do conditional moves with memory inputs
18202 [(match_scratch:MODEF 4 "r")
18203 (set (match_operand:MODEF 0 "general_reg_operand")
18204 (if_then_else:MODEF (match_operator 1 "fcmov_comparison_operator"
18205 [(reg FLAGS_REG) (const_int 0)])
18206 (match_operand:MODEF 2 "nonimmediate_operand")
18207 (match_operand:MODEF 3 "nonimmediate_operand")))]
18208 "(<MODE>mode != DFmode || TARGET_64BIT)
18209 && TARGET_80387 && TARGET_CMOVE
18210 && TARGET_AVOID_MEM_OPND_FOR_CMOVE
18211 && (MEM_P (operands[2]) || MEM_P (operands[3]))
18212 && optimize_insn_for_speed_p ()"
18213 [(set (match_dup 4) (match_dup 5))
18215 (if_then_else:MODEF (match_dup 1) (match_dup 2) (match_dup 3)))]
18217 if (MEM_P (operands[2]))
18219 operands[5] = operands[2];
18220 operands[2] = operands[4];
18222 else if (MEM_P (operands[3]))
18224 operands[5] = operands[3];
18225 operands[3] = operands[4];
18228 gcc_unreachable ();
18231 ;; All moves in XOP pcmov instructions are 128 bits and hence we restrict
18232 ;; the scalar versions to have only XMM registers as operands.
18234 ;; XOP conditional move
18235 (define_insn "*xop_pcmov_<mode>"
18236 [(set (match_operand:MODEF 0 "register_operand" "=x")
18237 (if_then_else:MODEF
18238 (match_operand:MODEF 1 "register_operand" "x")
18239 (match_operand:MODEF 2 "register_operand" "x")
18240 (match_operand:MODEF 3 "register_operand" "x")))]
18242 "vpcmov\t{%1, %3, %2, %0|%0, %2, %3, %1}"
18243 [(set_attr "type" "sse4arg")])
18245 ;; These versions of the min/max patterns are intentionally ignorant of
18246 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
18247 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
18248 ;; are undefined in this condition, we're certain this is correct.
18250 (define_insn "<code><mode>3"
18251 [(set (match_operand:MODEF 0 "register_operand" "=x,v")
18253 (match_operand:MODEF 1 "nonimmediate_operand" "%0,v")
18254 (match_operand:MODEF 2 "nonimmediate_operand" "xm,vm")))]
18255 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
18257 <maxmin_float><ssemodesuffix>\t{%2, %0|%0, %2}
18258 v<maxmin_float><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
18259 [(set_attr "isa" "noavx,avx")
18260 (set_attr "prefix" "orig,vex")
18261 (set_attr "type" "sseadd")
18262 (set_attr "mode" "<MODE>")])
18264 ;; These versions of the min/max patterns implement exactly the operations
18265 ;; min = (op1 < op2 ? op1 : op2)
18266 ;; max = (!(op1 < op2) ? op1 : op2)
18267 ;; Their operands are not commutative, and thus they may be used in the
18268 ;; presence of -0.0 and NaN.
18270 (define_insn "*ieee_s<ieee_maxmin><mode>3"
18271 [(set (match_operand:MODEF 0 "register_operand" "=x,v")
18273 [(match_operand:MODEF 1 "register_operand" "0,v")
18274 (match_operand:MODEF 2 "nonimmediate_operand" "xm,vm")]
18276 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
18278 <ieee_maxmin><ssemodesuffix>\t{%2, %0|%0, %2}
18279 v<ieee_maxmin><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
18280 [(set_attr "isa" "noavx,avx")
18281 (set_attr "prefix" "orig,maybe_evex")
18282 (set_attr "type" "sseadd")
18283 (set_attr "mode" "<MODE>")])
18285 ;; Make two stack loads independent:
18287 ;; fld %st(0) -> fld bb
18288 ;; fmul bb fmul %st(1), %st
18290 ;; Actually we only match the last two instructions for simplicity.
18293 [(set (match_operand 0 "fp_register_operand")
18294 (match_operand 1 "fp_register_operand"))
18296 (match_operator 2 "binary_fp_operator"
18298 (match_operand 3 "memory_operand")]))]
18299 "REGNO (operands[0]) != REGNO (operands[1])"
18300 [(set (match_dup 0) (match_dup 3))
18303 [(match_dup 5) (match_dup 4)]))]
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]);
18315 [(set (match_operand 0 "fp_register_operand")
18316 (match_operand 1 "fp_register_operand"))
18318 (match_operator 2 "binary_fp_operator"
18319 [(match_operand 3 "memory_operand")
18321 "REGNO (operands[0]) != REGNO (operands[1])"
18322 [(set (match_dup 0) (match_dup 3))
18325 [(match_dup 4) (match_dup 5)]))]
18327 operands[4] = operands[0];
18328 operands[5] = operands[1];
18330 /* The % modifier is not operational anymore in peephole2's, so we have to
18331 swap the operands manually in the case of addition and multiplication. */
18332 if (COMMUTATIVE_ARITH_P (operands[2]))
18333 std::swap (operands[4], operands[5]);
18336 ;; Conditional addition patterns
18337 (define_expand "add<mode>cc"
18338 [(match_operand:SWI 0 "register_operand")
18339 (match_operand 1 "ordered_comparison_operator")
18340 (match_operand:SWI 2 "register_operand")
18341 (match_operand:SWI 3 "const_int_operand")]
18343 "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
18345 ;; Misc patterns (?)
18347 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
18348 ;; Otherwise there will be nothing to keep
18350 ;; [(set (reg ebp) (reg esp))]
18351 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
18352 ;; (clobber (eflags)]
18353 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
18355 ;; in proper program order.
18357 (define_insn "pro_epilogue_adjust_stack_<mode>_add"
18358 [(set (match_operand:P 0 "register_operand" "=r,r")
18359 (plus:P (match_operand:P 1 "register_operand" "0,r")
18360 (match_operand:P 2 "<nonmemory_operand>" "r<i>,l<i>")))
18361 (clobber (reg:CC FLAGS_REG))
18362 (clobber (mem:BLK (scratch)))]
18365 switch (get_attr_type (insn))
18368 return "mov{<imodesuffix>}\t{%1, %0|%0, %1}";
18371 gcc_assert (rtx_equal_p (operands[0], operands[1]));
18372 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
18373 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
18375 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
18378 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
18379 return "lea{<imodesuffix>}\t{%E2, %0|%0, %E2}";
18382 [(set (attr "type")
18383 (cond [(and (eq_attr "alternative" "0")
18384 (not (match_test "TARGET_OPT_AGU")))
18385 (const_string "alu")
18386 (match_operand:<MODE> 2 "const0_operand")
18387 (const_string "imov")
18389 (const_string "lea")))
18390 (set (attr "length_immediate")
18391 (cond [(eq_attr "type" "imov")
18393 (and (eq_attr "type" "alu")
18394 (match_operand 2 "const128_operand"))
18397 (const_string "*")))
18398 (set_attr "mode" "<MODE>")])
18400 (define_insn "pro_epilogue_adjust_stack_<mode>_sub"
18401 [(set (match_operand:P 0 "register_operand" "=r")
18402 (minus:P (match_operand:P 1 "register_operand" "0")
18403 (match_operand:P 2 "register_operand" "r")))
18404 (clobber (reg:CC FLAGS_REG))
18405 (clobber (mem:BLK (scratch)))]
18407 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
18408 [(set_attr "type" "alu")
18409 (set_attr "mode" "<MODE>")])
18411 (define_insn "allocate_stack_worker_probe_<mode>"
18412 [(set (match_operand:P 0 "register_operand" "=a")
18413 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
18414 UNSPECV_STACK_PROBE))
18415 (clobber (reg:CC FLAGS_REG))]
18416 "ix86_target_stack_probe ()"
18417 "call\t___chkstk_ms"
18418 [(set_attr "type" "multi")
18419 (set_attr "length" "5")])
18421 (define_expand "allocate_stack"
18422 [(match_operand 0 "register_operand")
18423 (match_operand 1 "general_operand")]
18424 "ix86_target_stack_probe ()"
18428 #ifndef CHECK_STACK_LIMIT
18429 #define CHECK_STACK_LIMIT 0
18432 if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
18433 && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
18437 rtx (*insn) (rtx, rtx);
18439 x = copy_to_mode_reg (Pmode, operands[1]);
18441 insn = (TARGET_64BIT
18442 ? gen_allocate_stack_worker_probe_di
18443 : gen_allocate_stack_worker_probe_si);
18445 emit_insn (insn (x, x));
18448 x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, x,
18449 stack_pointer_rtx, 0, OPTAB_DIRECT);
18451 if (x != stack_pointer_rtx)
18452 emit_move_insn (stack_pointer_rtx, x);
18454 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
18458 (define_expand "probe_stack"
18459 [(match_operand 0 "memory_operand")]
18462 rtx (*insn) (rtx, rtx)
18463 = (GET_MODE (operands[0]) == DImode
18464 ? gen_probe_stack_di : gen_probe_stack_si);
18466 emit_insn (insn (operands[0], const0_rtx));
18470 ;; Use OR for stack probes, this is shorter.
18471 (define_insn "probe_stack_<mode>"
18472 [(set (match_operand:W 0 "memory_operand" "=m")
18473 (unspec:W [(match_operand:W 1 "const0_operand")]
18474 UNSPEC_PROBE_STACK))
18475 (clobber (reg:CC FLAGS_REG))]
18477 "or{<imodesuffix>}\t{%1, %0|%0, %1}"
18478 [(set_attr "type" "alu1")
18479 (set_attr "mode" "<MODE>")
18480 (set_attr "length_immediate" "1")])
18482 (define_insn "adjust_stack_and_probe<mode>"
18483 [(set (match_operand:P 0 "register_operand" "=r")
18484 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
18485 UNSPECV_PROBE_STACK_RANGE))
18486 (set (reg:P SP_REG)
18487 (minus:P (reg:P SP_REG) (match_operand:P 2 "const_int_operand" "n")))
18488 (clobber (reg:CC FLAGS_REG))
18489 (clobber (mem:BLK (scratch)))]
18491 "* return output_adjust_stack_and_probe (operands[0]);"
18492 [(set_attr "type" "multi")])
18494 (define_insn "probe_stack_range<mode>"
18495 [(set (match_operand:P 0 "register_operand" "=r")
18496 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
18497 (match_operand:P 2 "const_int_operand" "n")]
18498 UNSPECV_PROBE_STACK_RANGE))
18499 (clobber (reg:CC FLAGS_REG))]
18501 "* return output_probe_stack_range (operands[0], operands[2]);"
18502 [(set_attr "type" "multi")])
18504 (define_expand "builtin_setjmp_receiver"
18505 [(label_ref (match_operand 0))]
18506 "!TARGET_64BIT && flag_pic"
18512 rtx_code_label *label_rtx = gen_label_rtx ();
18513 emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
18514 xops[0] = xops[1] = pic_offset_table_rtx;
18515 xops[2] = machopic_gen_offset (gen_rtx_LABEL_REF (SImode, label_rtx));
18516 ix86_expand_binary_operator (MINUS, SImode, xops);
18520 emit_insn (gen_set_got (pic_offset_table_rtx));
18524 (define_expand "save_stack_nonlocal"
18525 [(set (match_operand 0 "memory_operand")
18526 (match_operand 1 "register_operand"))]
18530 if ((flag_cf_protection & CF_RETURN))
18532 /* Copy shadow stack pointer to the first slot and stack ppointer
18533 to the second slot. */
18534 rtx ssp_slot = adjust_address (operands[0], word_mode, 0);
18535 stack_slot = adjust_address (operands[0], Pmode, UNITS_PER_WORD);
18536 rtx ssp = gen_reg_rtx (word_mode);
18537 emit_insn ((word_mode == SImode)
18538 ? gen_rdsspsi (ssp)
18539 : gen_rdsspdi (ssp));
18540 emit_move_insn (ssp_slot, ssp);
18543 stack_slot = adjust_address (operands[0], Pmode, 0);
18544 emit_move_insn (stack_slot, operands[1]);
18548 (define_expand "restore_stack_nonlocal"
18549 [(set (match_operand 0 "register_operand" "")
18550 (match_operand 1 "memory_operand" ""))]
18554 if ((flag_cf_protection & CF_RETURN))
18556 /* Restore shadow stack pointer from the first slot and stack
18557 pointer from the second slot. */
18558 rtx ssp_slot = adjust_address (operands[1], word_mode, 0);
18559 stack_slot = adjust_address (operands[1], Pmode, UNITS_PER_WORD);
18561 rtx flags, jump, noadj_label, inc_label, loop_label;
18562 rtx reg_adj, reg_ssp, tmp, clob;
18564 /* Get the current shadow stack pointer. The code below will check if
18565 SHSTK feature is enabled. If it is not enabled the RDSSP instruction
18567 reg_ssp = gen_reg_rtx (word_mode);
18568 emit_insn (gen_rtx_SET (reg_ssp, const0_rtx));
18569 emit_insn ((word_mode == SImode)
18570 ? gen_rdsspsi (reg_ssp)
18571 : gen_rdsspdi (reg_ssp));
18573 /* Compare through substraction the saved and the current ssp to decide
18574 if ssp has to be adjusted. */
18575 tmp = gen_rtx_SET (reg_ssp, gen_rtx_MINUS (word_mode, reg_ssp,
18577 clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
18578 tmp = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, tmp, clob));
18581 /* Compare and jump over adjustment code. */
18582 noadj_label = gen_label_rtx ();
18583 flags = gen_rtx_REG (CCZmode, FLAGS_REG);
18584 tmp = gen_rtx_EQ (VOIDmode, flags, const0_rtx);
18585 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
18586 gen_rtx_LABEL_REF (VOIDmode, noadj_label),
18588 jump = emit_jump_insn (gen_rtx_SET (pc_rtx, tmp));
18589 JUMP_LABEL (jump) = noadj_label;
18591 /* Compute the numebr of frames to adjust. */
18592 reg_adj = gen_lowpart (ptr_mode, reg_ssp);
18593 tmp = gen_rtx_SET (reg_adj,
18594 gen_rtx_LSHIFTRT (ptr_mode,
18595 negate_rtx (ptr_mode, reg_adj),
18596 GEN_INT ((word_mode == SImode)
18599 clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
18600 tmp = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, tmp, clob));
18603 /* Check if number of frames <= 255 so no loop is needed. */
18604 tmp = gen_rtx_COMPARE (CCmode, reg_adj, GEN_INT (255));
18605 flags = gen_rtx_REG (CCmode, FLAGS_REG);
18606 emit_insn (gen_rtx_SET (flags, tmp));
18608 inc_label = gen_label_rtx ();
18609 tmp = gen_rtx_LEU (VOIDmode, flags, const0_rtx);
18610 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
18611 gen_rtx_LABEL_REF (VOIDmode, inc_label),
18613 jump = emit_jump_insn (gen_rtx_SET (pc_rtx, tmp));
18614 JUMP_LABEL (jump) = inc_label;
18616 rtx reg_255 = gen_reg_rtx (word_mode);
18617 emit_move_insn (reg_255, GEN_INT (255));
18619 /* Adjust the ssp in a loop. */
18620 loop_label = gen_label_rtx ();
18621 emit_label (loop_label);
18622 LABEL_NUSES (loop_label) = 1;
18624 emit_insn ((word_mode == SImode)
18625 ? gen_incsspsi (reg_255)
18626 : gen_incsspdi (reg_255));
18627 tmp = gen_rtx_SET (reg_adj, gen_rtx_MINUS (ptr_mode,
18630 clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
18631 tmp = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, tmp, clob));
18634 tmp = gen_rtx_COMPARE (CCmode, reg_adj, GEN_INT (255));
18635 flags = gen_rtx_REG (CCmode, FLAGS_REG);
18636 emit_insn (gen_rtx_SET (flags, tmp));
18638 /* Jump to the loop label. */
18639 tmp = gen_rtx_GTU (VOIDmode, flags, const0_rtx);
18640 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
18641 gen_rtx_LABEL_REF (VOIDmode, loop_label),
18643 jump = emit_jump_insn (gen_rtx_SET (pc_rtx, tmp));
18644 JUMP_LABEL (jump) = loop_label;
18646 emit_label (inc_label);
18647 LABEL_NUSES (inc_label) = 1;
18648 emit_insn ((word_mode == SImode)
18649 ? gen_incsspsi (reg_ssp)
18650 : gen_incsspdi (reg_ssp));
18652 emit_label (noadj_label);
18653 LABEL_NUSES (noadj_label) = 1;
18656 stack_slot = adjust_address (operands[1], Pmode, 0);
18657 emit_move_insn (operands[0], stack_slot);
18662 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
18663 ;; Do not split instructions with mask registers.
18665 [(set (match_operand 0 "general_reg_operand")
18666 (match_operator 3 "promotable_binary_operator"
18667 [(match_operand 1 "general_reg_operand")
18668 (match_operand 2 "aligned_operand")]))
18669 (clobber (reg:CC FLAGS_REG))]
18670 "! TARGET_PARTIAL_REG_STALL && reload_completed
18671 && ((GET_MODE (operands[0]) == HImode
18672 && ((optimize_function_for_speed_p (cfun) && !TARGET_FAST_PREFIX)
18673 /* ??? next two lines just !satisfies_constraint_K (...) */
18674 || !CONST_INT_P (operands[2])
18675 || satisfies_constraint_K (operands[2])))
18676 || (GET_MODE (operands[0]) == QImode
18677 && (TARGET_PROMOTE_QImode || optimize_function_for_size_p (cfun))))"
18678 [(parallel [(set (match_dup 0)
18679 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
18680 (clobber (reg:CC FLAGS_REG))])]
18682 operands[0] = gen_lowpart (SImode, operands[0]);
18683 operands[1] = gen_lowpart (SImode, operands[1]);
18684 if (GET_CODE (operands[3]) != ASHIFT)
18685 operands[2] = gen_lowpart (SImode, operands[2]);
18686 operands[3] = shallow_copy_rtx (operands[3]);
18687 PUT_MODE (operands[3], SImode);
18690 ; Promote the QImode tests, as i386 has encoding of the AND
18691 ; instruction with 32-bit sign-extended immediate and thus the
18692 ; instruction size is unchanged, except in the %eax case for
18693 ; which it is increased by one byte, hence the ! optimize_size.
18695 [(set (match_operand 0 "flags_reg_operand")
18696 (match_operator 2 "compare_operator"
18697 [(and (match_operand 3 "aligned_operand")
18698 (match_operand 4 "const_int_operand"))
18700 (set (match_operand 1 "register_operand")
18701 (and (match_dup 3) (match_dup 4)))]
18702 "! TARGET_PARTIAL_REG_STALL && reload_completed
18703 && optimize_insn_for_speed_p ()
18704 && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
18705 || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))
18706 /* Ensure that the operand will remain sign-extended immediate. */
18707 && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)"
18708 [(parallel [(set (match_dup 0)
18709 (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
18712 (and:SI (match_dup 3) (match_dup 4)))])]
18715 = gen_int_mode (INTVAL (operands[4])
18716 & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
18717 operands[1] = gen_lowpart (SImode, operands[1]);
18718 operands[3] = gen_lowpart (SImode, operands[3]);
18721 ; Don't promote the QImode tests, as i386 doesn't have encoding of
18722 ; the TEST instruction with 32-bit sign-extended immediate and thus
18723 ; the instruction size would at least double, which is not what we
18724 ; want even with ! optimize_size.
18726 [(set (match_operand 0 "flags_reg_operand")
18727 (match_operator 1 "compare_operator"
18728 [(and (match_operand:HI 2 "aligned_operand")
18729 (match_operand:HI 3 "const_int_operand"))
18731 "! TARGET_PARTIAL_REG_STALL && reload_completed
18732 && ! TARGET_FAST_PREFIX
18733 && optimize_insn_for_speed_p ()
18734 /* Ensure that the operand will remain sign-extended immediate. */
18735 && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)"
18736 [(set (match_dup 0)
18737 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
18741 = gen_int_mode (INTVAL (operands[3])
18742 & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
18743 operands[2] = gen_lowpart (SImode, operands[2]);
18747 [(set (match_operand 0 "register_operand")
18748 (neg (match_operand 1 "register_operand")))
18749 (clobber (reg:CC FLAGS_REG))]
18750 "! TARGET_PARTIAL_REG_STALL && reload_completed
18751 && (GET_MODE (operands[0]) == HImode
18752 || (GET_MODE (operands[0]) == QImode
18753 && (TARGET_PROMOTE_QImode
18754 || optimize_insn_for_size_p ())))"
18755 [(parallel [(set (match_dup 0)
18756 (neg:SI (match_dup 1)))
18757 (clobber (reg:CC FLAGS_REG))])]
18759 operands[0] = gen_lowpart (SImode, operands[0]);
18760 operands[1] = gen_lowpart (SImode, operands[1]);
18763 ;; Do not split instructions with mask regs.
18765 [(set (match_operand 0 "general_reg_operand")
18766 (not (match_operand 1 "general_reg_operand")))]
18767 "! TARGET_PARTIAL_REG_STALL && reload_completed
18768 && (GET_MODE (operands[0]) == HImode
18769 || (GET_MODE (operands[0]) == QImode
18770 && (TARGET_PROMOTE_QImode
18771 || optimize_insn_for_size_p ())))"
18772 [(set (match_dup 0)
18773 (not:SI (match_dup 1)))]
18775 operands[0] = gen_lowpart (SImode, operands[0]);
18776 operands[1] = gen_lowpart (SImode, operands[1]);
18779 ;; RTL Peephole optimizations, run before sched2. These primarily look to
18780 ;; transform a complex memory operation into two memory to register operations.
18782 ;; Don't push memory operands
18784 [(set (match_operand:SWI 0 "push_operand")
18785 (match_operand:SWI 1 "memory_operand"))
18786 (match_scratch:SWI 2 "<r>")]
18787 "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
18788 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
18789 [(set (match_dup 2) (match_dup 1))
18790 (set (match_dup 0) (match_dup 2))])
18792 ;; We need to handle SFmode only, because DFmode and XFmode are split to
18795 [(set (match_operand:SF 0 "push_operand")
18796 (match_operand:SF 1 "memory_operand"))
18797 (match_scratch:SF 2 "r")]
18798 "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
18799 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
18800 [(set (match_dup 2) (match_dup 1))
18801 (set (match_dup 0) (match_dup 2))])
18803 ;; Don't move an immediate directly to memory when the instruction
18804 ;; gets too big, or if LCP stalls are a problem for 16-bit moves.
18806 [(match_scratch:SWI124 1 "<r>")
18807 (set (match_operand:SWI124 0 "memory_operand")
18809 "optimize_insn_for_speed_p ()
18810 && ((<MODE>mode == HImode
18811 && TARGET_LCP_STALL)
18812 || (!TARGET_USE_MOV0
18813 && TARGET_SPLIT_LONG_MOVES
18814 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn))
18815 && peep2_regno_dead_p (0, FLAGS_REG)"
18816 [(parallel [(set (match_dup 2) (const_int 0))
18817 (clobber (reg:CC FLAGS_REG))])
18818 (set (match_dup 0) (match_dup 1))]
18819 "operands[2] = gen_lowpart (SImode, operands[1]);")
18822 [(match_scratch:SWI124 2 "<r>")
18823 (set (match_operand:SWI124 0 "memory_operand")
18824 (match_operand:SWI124 1 "immediate_operand"))]
18825 "optimize_insn_for_speed_p ()
18826 && ((<MODE>mode == HImode
18827 && TARGET_LCP_STALL)
18828 || (TARGET_SPLIT_LONG_MOVES
18829 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn))"
18830 [(set (match_dup 2) (match_dup 1))
18831 (set (match_dup 0) (match_dup 2))])
18833 ;; Don't compare memory with zero, load and use a test instead.
18835 [(set (match_operand 0 "flags_reg_operand")
18836 (match_operator 1 "compare_operator"
18837 [(match_operand:SI 2 "memory_operand")
18839 (match_scratch:SI 3 "r")]
18840 "optimize_insn_for_speed_p () && ix86_match_ccmode (insn, CCNOmode)"
18841 [(set (match_dup 3) (match_dup 2))
18842 (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))])
18844 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
18845 ;; Don't split NOTs with a displacement operand, because resulting XOR
18846 ;; will not be pairable anyway.
18848 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
18849 ;; represented using a modRM byte. The XOR replacement is long decoded,
18850 ;; so this split helps here as well.
18852 ;; Note: Can't do this as a regular split because we can't get proper
18853 ;; lifetime information then.
18856 [(set (match_operand:SWI124 0 "nonimmediate_gr_operand")
18857 (not:SWI124 (match_operand:SWI124 1 "nonimmediate_gr_operand")))]
18858 "optimize_insn_for_speed_p ()
18859 && ((TARGET_NOT_UNPAIRABLE
18860 && (!MEM_P (operands[0])
18861 || !memory_displacement_operand (operands[0], <MODE>mode)))
18862 || (TARGET_NOT_VECTORMODE
18863 && long_memory_operand (operands[0], <MODE>mode)))
18864 && peep2_regno_dead_p (0, FLAGS_REG)"
18865 [(parallel [(set (match_dup 0)
18866 (xor:SWI124 (match_dup 1) (const_int -1)))
18867 (clobber (reg:CC FLAGS_REG))])])
18869 ;; Non pairable "test imm, reg" instructions can be translated to
18870 ;; "and imm, reg" if reg dies. The "and" form is also shorter (one
18871 ;; byte opcode instead of two, have a short form for byte operands),
18872 ;; so do it for other CPUs as well. Given that the value was dead,
18873 ;; this should not create any new dependencies. Pass on the sub-word
18874 ;; versions if we're concerned about partial register stalls.
18877 [(set (match_operand 0 "flags_reg_operand")
18878 (match_operator 1 "compare_operator"
18879 [(and:SI (match_operand:SI 2 "register_operand")
18880 (match_operand:SI 3 "immediate_operand"))
18882 "ix86_match_ccmode (insn, CCNOmode)
18883 && (REGNO (operands[2]) != AX_REG
18884 || satisfies_constraint_K (operands[3]))
18885 && peep2_reg_dead_p (1, operands[2])"
18887 [(set (match_dup 0)
18888 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
18891 (and:SI (match_dup 2) (match_dup 3)))])])
18893 ;; We don't need to handle HImode case, because it will be promoted to SImode
18894 ;; on ! TARGET_PARTIAL_REG_STALL
18897 [(set (match_operand 0 "flags_reg_operand")
18898 (match_operator 1 "compare_operator"
18899 [(and:QI (match_operand:QI 2 "register_operand")
18900 (match_operand:QI 3 "immediate_operand"))
18902 "! TARGET_PARTIAL_REG_STALL
18903 && ix86_match_ccmode (insn, CCNOmode)
18904 && REGNO (operands[2]) != AX_REG
18905 && peep2_reg_dead_p (1, operands[2])"
18907 [(set (match_dup 0)
18908 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
18911 (and:QI (match_dup 2) (match_dup 3)))])])
18914 [(set (match_operand 0 "flags_reg_operand")
18915 (match_operator 1 "compare_operator"
18918 (zero_extract:SI (match_operand 2 "QIreg_operand")
18921 (match_operand 3 "const_int_operand"))
18923 "! TARGET_PARTIAL_REG_STALL
18924 && ix86_match_ccmode (insn, CCNOmode)
18925 && REGNO (operands[2]) != AX_REG
18926 && peep2_reg_dead_p (1, operands[2])"
18928 [(set (match_dup 0)
18932 (zero_extract:SI (match_dup 2)
18937 (set (zero_extract:SI (match_dup 2)
18943 (zero_extract:SI (match_dup 2)
18946 (match_dup 3)) 0))])])
18948 ;; Don't do logical operations with memory inputs.
18950 [(match_scratch:SWI 2 "<r>")
18951 (parallel [(set (match_operand:SWI 0 "register_operand")
18952 (match_operator:SWI 3 "arith_or_logical_operator"
18954 (match_operand:SWI 1 "memory_operand")]))
18955 (clobber (reg:CC FLAGS_REG))])]
18956 "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
18957 [(set (match_dup 2) (match_dup 1))
18958 (parallel [(set (match_dup 0)
18959 (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
18960 (clobber (reg:CC FLAGS_REG))])])
18963 [(match_scratch:SWI 2 "<r>")
18964 (parallel [(set (match_operand:SWI 0 "register_operand")
18965 (match_operator:SWI 3 "arith_or_logical_operator"
18966 [(match_operand:SWI 1 "memory_operand")
18968 (clobber (reg:CC FLAGS_REG))])]
18969 "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
18970 [(set (match_dup 2) (match_dup 1))
18971 (parallel [(set (match_dup 0)
18972 (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
18973 (clobber (reg:CC FLAGS_REG))])])
18975 ;; Prefer Load+RegOp to Mov+MemOp. Watch out for cases when
18976 ;; the memory address refers to the destination of the load!
18979 [(set (match_operand:SWI 0 "general_reg_operand")
18980 (match_operand:SWI 1 "general_reg_operand"))
18981 (parallel [(set (match_dup 0)
18982 (match_operator:SWI 3 "commutative_operator"
18984 (match_operand:SWI 2 "memory_operand")]))
18985 (clobber (reg:CC FLAGS_REG))])]
18986 "REGNO (operands[0]) != REGNO (operands[1])
18987 && (<MODE>mode != QImode
18988 || any_QIreg_operand (operands[1], QImode))"
18989 [(set (match_dup 0) (match_dup 4))
18990 (parallel [(set (match_dup 0)
18991 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))
18992 (clobber (reg:CC FLAGS_REG))])]
18993 "operands[4] = replace_rtx (operands[2], operands[0], operands[1], true);")
18996 [(set (match_operand 0 "mmx_reg_operand")
18997 (match_operand 1 "mmx_reg_operand"))
18999 (match_operator 3 "commutative_operator"
19001 (match_operand 2 "memory_operand")]))]
19002 "REGNO (operands[0]) != REGNO (operands[1])"
19003 [(set (match_dup 0) (match_dup 2))
19005 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))])
19008 [(set (match_operand 0 "sse_reg_operand")
19009 (match_operand 1 "sse_reg_operand"))
19011 (match_operator 3 "commutative_operator"
19013 (match_operand 2 "memory_operand")]))]
19014 "REGNO (operands[0]) != REGNO (operands[1])"
19015 [(set (match_dup 0) (match_dup 2))
19017 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))])
19019 ; Don't do logical operations with memory outputs
19021 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
19022 ; instruction into two 1-uop insns plus a 2-uop insn. That last has
19023 ; the same decoder scheduling characteristics as the original.
19026 [(match_scratch:SWI 2 "<r>")
19027 (parallel [(set (match_operand:SWI 0 "memory_operand")
19028 (match_operator:SWI 3 "arith_or_logical_operator"
19030 (match_operand:SWI 1 "<nonmemory_operand>")]))
19031 (clobber (reg:CC FLAGS_REG))])]
19032 "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())"
19033 [(set (match_dup 2) (match_dup 0))
19034 (parallel [(set (match_dup 2)
19035 (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
19036 (clobber (reg:CC FLAGS_REG))])
19037 (set (match_dup 0) (match_dup 2))])
19040 [(match_scratch:SWI 2 "<r>")
19041 (parallel [(set (match_operand:SWI 0 "memory_operand")
19042 (match_operator:SWI 3 "arith_or_logical_operator"
19043 [(match_operand:SWI 1 "<nonmemory_operand>")
19045 (clobber (reg:CC FLAGS_REG))])]
19046 "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())"
19047 [(set (match_dup 2) (match_dup 0))
19048 (parallel [(set (match_dup 2)
19049 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
19050 (clobber (reg:CC FLAGS_REG))])
19051 (set (match_dup 0) (match_dup 2))])
19053 ;; Attempt to use arith or logical operations with memory outputs with
19054 ;; setting of flags.
19056 [(set (match_operand:SWI 0 "register_operand")
19057 (match_operand:SWI 1 "memory_operand"))
19058 (parallel [(set (match_dup 0)
19059 (match_operator:SWI 3 "plusminuslogic_operator"
19061 (match_operand:SWI 2 "<nonmemory_operand>")]))
19062 (clobber (reg:CC FLAGS_REG))])
19063 (set (match_dup 1) (match_dup 0))
19064 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
19065 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
19066 && peep2_reg_dead_p (4, operands[0])
19067 && !reg_overlap_mentioned_p (operands[0], operands[1])
19068 && !reg_overlap_mentioned_p (operands[0], operands[2])
19069 && (<MODE>mode != QImode
19070 || immediate_operand (operands[2], QImode)
19071 || any_QIreg_operand (operands[2], QImode))
19072 && ix86_match_ccmode (peep2_next_insn (3),
19073 (GET_CODE (operands[3]) == PLUS
19074 || GET_CODE (operands[3]) == MINUS)
19075 ? CCGOCmode : CCNOmode)"
19076 [(parallel [(set (match_dup 4) (match_dup 6))
19077 (set (match_dup 1) (match_dup 5))])]
19079 operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
19081 = gen_rtx_fmt_ee (GET_CODE (operands[3]), GET_MODE (operands[3]),
19082 copy_rtx (operands[1]),
19085 = gen_rtx_COMPARE (GET_MODE (operands[4]),
19086 copy_rtx (operands[5]),
19090 ;; Likewise for cmpelim optimized pattern.
19092 [(set (match_operand:SWI 0 "register_operand")
19093 (match_operand:SWI 1 "memory_operand"))
19094 (parallel [(set (reg FLAGS_REG)
19095 (compare (match_operator:SWI 3 "plusminuslogic_operator"
19097 (match_operand:SWI 2 "<nonmemory_operand>")])
19099 (set (match_dup 0) (match_dup 3))])
19100 (set (match_dup 1) (match_dup 0))]
19101 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
19102 && peep2_reg_dead_p (3, operands[0])
19103 && !reg_overlap_mentioned_p (operands[0], operands[1])
19104 && !reg_overlap_mentioned_p (operands[0], operands[2])
19105 && ix86_match_ccmode (peep2_next_insn (1),
19106 (GET_CODE (operands[3]) == PLUS
19107 || GET_CODE (operands[3]) == MINUS)
19108 ? CCGOCmode : CCNOmode)"
19109 [(parallel [(set (match_dup 4) (match_dup 6))
19110 (set (match_dup 1) (match_dup 5))])]
19112 operands[4] = SET_DEST (XVECEXP (PATTERN (peep2_next_insn (1)), 0, 0));
19114 = gen_rtx_fmt_ee (GET_CODE (operands[3]), GET_MODE (operands[3]),
19115 copy_rtx (operands[1]), operands[2]);
19117 = gen_rtx_COMPARE (GET_MODE (operands[4]), copy_rtx (operands[5]),
19121 ;; Likewise for instances where we have a lea pattern.
19123 [(set (match_operand:SWI 0 "register_operand")
19124 (match_operand:SWI 1 "memory_operand"))
19125 (set (match_operand:SWI 3 "register_operand")
19126 (plus:SWI (match_dup 0)
19127 (match_operand:SWI 2 "<nonmemory_operand>")))
19128 (set (match_dup 1) (match_dup 3))
19129 (set (reg FLAGS_REG) (compare (match_dup 3) (const_int 0)))]
19130 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
19131 && peep2_reg_dead_p (4, operands[3])
19132 && (rtx_equal_p (operands[0], operands[3])
19133 || peep2_reg_dead_p (2, operands[0]))
19134 && !reg_overlap_mentioned_p (operands[0], operands[1])
19135 && !reg_overlap_mentioned_p (operands[3], operands[1])
19136 && !reg_overlap_mentioned_p (operands[0], operands[2])
19137 && (<MODE>mode != QImode
19138 || immediate_operand (operands[2], QImode)
19139 || any_QIreg_operand (operands[2], QImode))
19140 && ix86_match_ccmode (peep2_next_insn (3), CCGOCmode)"
19141 [(parallel [(set (match_dup 4) (match_dup 6))
19142 (set (match_dup 1) (match_dup 5))])]
19144 operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
19146 = gen_rtx_PLUS (<MODE>mode,
19147 copy_rtx (operands[1]),
19150 = gen_rtx_COMPARE (GET_MODE (operands[4]),
19151 copy_rtx (operands[5]),
19156 [(parallel [(set (match_operand:SWI 0 "register_operand")
19157 (match_operator:SWI 2 "plusminuslogic_operator"
19159 (match_operand:SWI 1 "memory_operand")]))
19160 (clobber (reg:CC FLAGS_REG))])
19161 (set (match_dup 1) (match_dup 0))
19162 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
19163 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
19164 && COMMUTATIVE_ARITH_P (operands[2])
19165 && peep2_reg_dead_p (3, operands[0])
19166 && !reg_overlap_mentioned_p (operands[0], operands[1])
19167 && ix86_match_ccmode (peep2_next_insn (2),
19168 GET_CODE (operands[2]) == PLUS
19169 ? CCGOCmode : CCNOmode)"
19170 [(parallel [(set (match_dup 3) (match_dup 5))
19171 (set (match_dup 1) (match_dup 4))])]
19173 operands[3] = SET_DEST (PATTERN (peep2_next_insn (2)));
19175 = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
19176 copy_rtx (operands[1]),
19179 = gen_rtx_COMPARE (GET_MODE (operands[3]),
19180 copy_rtx (operands[4]),
19184 ;; Likewise for cmpelim optimized pattern.
19186 [(parallel [(set (reg FLAGS_REG)
19187 (compare (match_operator:SWI 2 "plusminuslogic_operator"
19188 [(match_operand:SWI 0 "register_operand")
19189 (match_operand:SWI 1 "memory_operand")])
19191 (set (match_dup 0) (match_dup 2))])
19192 (set (match_dup 1) (match_dup 0))]
19193 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
19194 && COMMUTATIVE_ARITH_P (operands[2])
19195 && peep2_reg_dead_p (2, operands[0])
19196 && !reg_overlap_mentioned_p (operands[0], operands[1])
19197 && ix86_match_ccmode (peep2_next_insn (0),
19198 GET_CODE (operands[2]) == PLUS
19199 ? CCGOCmode : CCNOmode)"
19200 [(parallel [(set (match_dup 3) (match_dup 5))
19201 (set (match_dup 1) (match_dup 4))])]
19203 operands[3] = SET_DEST (XVECEXP (PATTERN (peep2_next_insn (0)), 0, 0));
19205 = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
19206 copy_rtx (operands[1]), operands[0]);
19208 = gen_rtx_COMPARE (GET_MODE (operands[3]), copy_rtx (operands[4]),
19213 [(set (match_operand:SWI12 0 "register_operand")
19214 (match_operand:SWI12 1 "memory_operand"))
19215 (parallel [(set (match_operand:SI 4 "register_operand")
19216 (match_operator:SI 3 "plusminuslogic_operator"
19218 (match_operand:SI 2 "nonmemory_operand")]))
19219 (clobber (reg:CC FLAGS_REG))])
19220 (set (match_dup 1) (match_dup 0))
19221 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
19222 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
19223 && REGNO (operands[0]) == REGNO (operands[4])
19224 && peep2_reg_dead_p (4, operands[0])
19225 && (<MODE>mode != QImode
19226 || immediate_operand (operands[2], SImode)
19227 || any_QIreg_operand (operands[2], SImode))
19228 && !reg_overlap_mentioned_p (operands[0], operands[1])
19229 && !reg_overlap_mentioned_p (operands[0], operands[2])
19230 && ix86_match_ccmode (peep2_next_insn (3),
19231 (GET_CODE (operands[3]) == PLUS
19232 || GET_CODE (operands[3]) == MINUS)
19233 ? CCGOCmode : CCNOmode)"
19234 [(parallel [(set (match_dup 4) (match_dup 6))
19235 (set (match_dup 1) (match_dup 5))])]
19237 operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
19239 = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
19240 copy_rtx (operands[1]),
19241 gen_lowpart (<MODE>mode, operands[2]));
19243 = gen_rtx_COMPARE (GET_MODE (operands[4]),
19244 copy_rtx (operands[5]),
19248 ;; Attempt to always use XOR for zeroing registers (including FP modes).
19250 [(set (match_operand 0 "general_reg_operand")
19251 (match_operand 1 "const0_operand"))]
19252 "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
19253 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
19254 && peep2_regno_dead_p (0, FLAGS_REG)"
19255 [(parallel [(set (match_dup 0) (const_int 0))
19256 (clobber (reg:CC FLAGS_REG))])]
19257 "operands[0] = gen_lowpart (word_mode, operands[0]);")
19260 [(set (strict_low_part (match_operand:SWI12 0 "general_reg_operand"))
19262 "(! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
19263 && peep2_regno_dead_p (0, FLAGS_REG)"
19264 [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
19265 (clobber (reg:CC FLAGS_REG))])])
19267 ;; For HI, SI and DI modes, or $-1,reg is smaller than mov $-1,reg.
19269 [(set (match_operand:SWI248 0 "general_reg_operand")
19271 "(TARGET_MOVE_M1_VIA_OR || optimize_insn_for_size_p ())
19272 && peep2_regno_dead_p (0, FLAGS_REG)"
19273 [(parallel [(set (match_dup 0) (const_int -1))
19274 (clobber (reg:CC FLAGS_REG))])]
19276 if (<MODE_SIZE> < GET_MODE_SIZE (SImode))
19277 operands[0] = gen_lowpart (SImode, operands[0]);
19280 ;; Attempt to convert simple lea to add/shift.
19281 ;; These can be created by move expanders.
19282 ;; Disable PLUS peepholes on TARGET_OPT_AGU, since all
19283 ;; relevant lea instructions were already split.
19286 [(set (match_operand:SWI48 0 "register_operand")
19287 (plus:SWI48 (match_dup 0)
19288 (match_operand:SWI48 1 "<nonmemory_operand>")))]
19290 && peep2_regno_dead_p (0, FLAGS_REG)"
19291 [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1)))
19292 (clobber (reg:CC FLAGS_REG))])])
19295 [(set (match_operand:SWI48 0 "register_operand")
19296 (plus:SWI48 (match_operand:SWI48 1 "<nonmemory_operand>")
19299 && peep2_regno_dead_p (0, FLAGS_REG)"
19300 [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1)))
19301 (clobber (reg:CC FLAGS_REG))])])
19304 [(set (match_operand:DI 0 "register_operand")
19306 (plus:SI (match_operand:SI 1 "register_operand")
19307 (match_operand:SI 2 "nonmemory_operand"))))]
19308 "TARGET_64BIT && !TARGET_OPT_AGU
19309 && REGNO (operands[0]) == REGNO (operands[1])
19310 && peep2_regno_dead_p (0, FLAGS_REG)"
19311 [(parallel [(set (match_dup 0)
19312 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))
19313 (clobber (reg:CC FLAGS_REG))])])
19316 [(set (match_operand:DI 0 "register_operand")
19318 (plus:SI (match_operand:SI 1 "nonmemory_operand")
19319 (match_operand:SI 2 "register_operand"))))]
19320 "TARGET_64BIT && !TARGET_OPT_AGU
19321 && REGNO (operands[0]) == REGNO (operands[2])
19322 && peep2_regno_dead_p (0, FLAGS_REG)"
19323 [(parallel [(set (match_dup 0)
19324 (zero_extend:DI (plus:SI (match_dup 2) (match_dup 1))))
19325 (clobber (reg:CC FLAGS_REG))])])
19328 [(set (match_operand:SWI48 0 "register_operand")
19329 (mult:SWI48 (match_dup 0)
19330 (match_operand:SWI48 1 "const_int_operand")))]
19331 "pow2p_hwi (INTVAL (operands[1]))
19332 && peep2_regno_dead_p (0, FLAGS_REG)"
19333 [(parallel [(set (match_dup 0) (ashift:SWI48 (match_dup 0) (match_dup 1)))
19334 (clobber (reg:CC FLAGS_REG))])]
19335 "operands[1] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
19338 [(set (match_operand:DI 0 "register_operand")
19340 (mult:SI (match_operand:SI 1 "register_operand")
19341 (match_operand:SI 2 "const_int_operand"))))]
19343 && pow2p_hwi (INTVAL (operands[2]))
19344 && REGNO (operands[0]) == REGNO (operands[1])
19345 && peep2_regno_dead_p (0, FLAGS_REG)"
19346 [(parallel [(set (match_dup 0)
19347 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))
19348 (clobber (reg:CC FLAGS_REG))])]
19349 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
19351 ;; The ESP adjustments can be done by the push and pop instructions. Resulting
19352 ;; code is shorter, since push is only 1 byte, while add imm, %esp is 3 bytes.
19353 ;; On many CPUs it is also faster, since special hardware to avoid esp
19354 ;; dependencies is present.
19356 ;; While some of these conversions may be done using splitters, we use
19357 ;; peepholes in order to allow combine_stack_adjustments pass to see
19358 ;; nonobfuscated RTL.
19360 ;; Convert prologue esp subtractions to push.
19361 ;; We need register to push. In order to keep verify_flow_info happy we have
19363 ;; - use scratch and clobber it in order to avoid dependencies
19364 ;; - use already live register
19365 ;; We can't use the second way right now, since there is no reliable way how to
19366 ;; verify that given register is live. First choice will also most likely in
19367 ;; fewer dependencies. On the place of esp adjustments it is very likely that
19368 ;; call clobbered registers are dead. We may want to use base pointer as an
19369 ;; alternative when no register is available later.
19372 [(match_scratch:W 1 "r")
19373 (parallel [(set (reg:P SP_REG)
19374 (plus:P (reg:P SP_REG)
19375 (match_operand:P 0 "const_int_operand")))
19376 (clobber (reg:CC FLAGS_REG))
19377 (clobber (mem:BLK (scratch)))])]
19378 "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
19379 && INTVAL (operands[0]) == -GET_MODE_SIZE (word_mode)
19380 && ix86_red_zone_size == 0"
19381 [(clobber (match_dup 1))
19382 (parallel [(set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
19383 (clobber (mem:BLK (scratch)))])])
19386 [(match_scratch:W 1 "r")
19387 (parallel [(set (reg:P SP_REG)
19388 (plus:P (reg:P SP_REG)
19389 (match_operand:P 0 "const_int_operand")))
19390 (clobber (reg:CC FLAGS_REG))
19391 (clobber (mem:BLK (scratch)))])]
19392 "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
19393 && INTVAL (operands[0]) == -2*GET_MODE_SIZE (word_mode)
19394 && ix86_red_zone_size == 0"
19395 [(clobber (match_dup 1))
19396 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
19397 (parallel [(set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
19398 (clobber (mem:BLK (scratch)))])])
19400 ;; Convert esp subtractions to push.
19402 [(match_scratch:W 1 "r")
19403 (parallel [(set (reg:P SP_REG)
19404 (plus:P (reg:P SP_REG)
19405 (match_operand:P 0 "const_int_operand")))
19406 (clobber (reg:CC FLAGS_REG))])]
19407 "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
19408 && INTVAL (operands[0]) == -GET_MODE_SIZE (word_mode)
19409 && ix86_red_zone_size == 0"
19410 [(clobber (match_dup 1))
19411 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
19414 [(match_scratch:W 1 "r")
19415 (parallel [(set (reg:P SP_REG)
19416 (plus:P (reg:P SP_REG)
19417 (match_operand:P 0 "const_int_operand")))
19418 (clobber (reg:CC FLAGS_REG))])]
19419 "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
19420 && INTVAL (operands[0]) == -2*GET_MODE_SIZE (word_mode)
19421 && ix86_red_zone_size == 0"
19422 [(clobber (match_dup 1))
19423 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
19424 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
19426 ;; Convert epilogue deallocator to pop.
19428 [(match_scratch:W 1 "r")
19429 (parallel [(set (reg:P SP_REG)
19430 (plus:P (reg:P SP_REG)
19431 (match_operand:P 0 "const_int_operand")))
19432 (clobber (reg:CC FLAGS_REG))
19433 (clobber (mem:BLK (scratch)))])]
19434 "(TARGET_SINGLE_POP || optimize_insn_for_size_p ())
19435 && INTVAL (operands[0]) == GET_MODE_SIZE (word_mode)"
19436 [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
19437 (clobber (mem:BLK (scratch)))])])
19439 ;; Two pops case is tricky, since pop causes dependency
19440 ;; on destination register. We use two registers if available.
19442 [(match_scratch:W 1 "r")
19443 (match_scratch:W 2 "r")
19444 (parallel [(set (reg:P SP_REG)
19445 (plus:P (reg:P SP_REG)
19446 (match_operand:P 0 "const_int_operand")))
19447 (clobber (reg:CC FLAGS_REG))
19448 (clobber (mem:BLK (scratch)))])]
19449 "(TARGET_DOUBLE_POP || optimize_insn_for_size_p ())
19450 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
19451 [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
19452 (clobber (mem:BLK (scratch)))])
19453 (set (match_dup 2) (mem:W (post_inc:P (reg:P SP_REG))))])
19456 [(match_scratch:W 1 "r")
19457 (parallel [(set (reg:P SP_REG)
19458 (plus:P (reg:P SP_REG)
19459 (match_operand:P 0 "const_int_operand")))
19460 (clobber (reg:CC FLAGS_REG))
19461 (clobber (mem:BLK (scratch)))])]
19462 "optimize_insn_for_size_p ()
19463 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
19464 [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
19465 (clobber (mem:BLK (scratch)))])
19466 (set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
19468 ;; Convert esp additions to pop.
19470 [(match_scratch:W 1 "r")
19471 (parallel [(set (reg:P SP_REG)
19472 (plus:P (reg:P SP_REG)
19473 (match_operand:P 0 "const_int_operand")))
19474 (clobber (reg:CC FLAGS_REG))])]
19475 "INTVAL (operands[0]) == GET_MODE_SIZE (word_mode)"
19476 [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
19478 ;; Two pops case is tricky, since pop causes dependency
19479 ;; on destination register. We use two registers if available.
19481 [(match_scratch:W 1 "r")
19482 (match_scratch:W 2 "r")
19483 (parallel [(set (reg:P SP_REG)
19484 (plus:P (reg:P SP_REG)
19485 (match_operand:P 0 "const_int_operand")))
19486 (clobber (reg:CC FLAGS_REG))])]
19487 "INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
19488 [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
19489 (set (match_dup 2) (mem:W (post_inc:P (reg:P SP_REG))))])
19492 [(match_scratch:W 1 "r")
19493 (parallel [(set (reg:P SP_REG)
19494 (plus:P (reg:P SP_REG)
19495 (match_operand:P 0 "const_int_operand")))
19496 (clobber (reg:CC FLAGS_REG))])]
19497 "optimize_insn_for_size_p ()
19498 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
19499 [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
19500 (set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
19502 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
19503 ;; required and register dies. Similarly for 128 to -128.
19505 [(set (match_operand 0 "flags_reg_operand")
19506 (match_operator 1 "compare_operator"
19507 [(match_operand 2 "register_operand")
19508 (match_operand 3 "const_int_operand")]))]
19509 "(((!TARGET_FUSE_CMP_AND_BRANCH || optimize_insn_for_size_p ())
19510 && incdec_operand (operands[3], GET_MODE (operands[3])))
19511 || (!TARGET_FUSE_CMP_AND_BRANCH
19512 && INTVAL (operands[3]) == 128))
19513 && ix86_match_ccmode (insn, CCGCmode)
19514 && peep2_reg_dead_p (1, operands[2])"
19515 [(parallel [(set (match_dup 0)
19516 (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
19517 (clobber (match_dup 2))])])
19519 ;; Convert imul by three, five and nine into lea
19522 [(set (match_operand:SWI48 0 "register_operand")
19523 (mult:SWI48 (match_operand:SWI48 1 "register_operand")
19524 (match_operand:SWI48 2 "const359_operand")))
19525 (clobber (reg:CC FLAGS_REG))])]
19526 "!TARGET_PARTIAL_REG_STALL
19527 || <MODE>mode == SImode
19528 || optimize_function_for_size_p (cfun)"
19529 [(set (match_dup 0)
19530 (plus:SWI48 (mult:SWI48 (match_dup 1) (match_dup 2))
19532 "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
19536 [(set (match_operand:SWI48 0 "register_operand")
19537 (mult:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
19538 (match_operand:SWI48 2 "const359_operand")))
19539 (clobber (reg:CC FLAGS_REG))])]
19540 "optimize_insn_for_speed_p ()
19541 && (!TARGET_PARTIAL_REG_STALL || <MODE>mode == SImode)"
19542 [(set (match_dup 0) (match_dup 1))
19544 (plus:SWI48 (mult:SWI48 (match_dup 0) (match_dup 2))
19546 "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
19548 ;; imul $32bit_imm, mem, reg is vector decoded, while
19549 ;; imul $32bit_imm, reg, reg is direct decoded.
19551 [(match_scratch:SWI48 3 "r")
19552 (parallel [(set (match_operand:SWI48 0 "register_operand")
19553 (mult:SWI48 (match_operand:SWI48 1 "memory_operand")
19554 (match_operand:SWI48 2 "immediate_operand")))
19555 (clobber (reg:CC FLAGS_REG))])]
19556 "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
19557 && !satisfies_constraint_K (operands[2])"
19558 [(set (match_dup 3) (match_dup 1))
19559 (parallel [(set (match_dup 0) (mult:SWI48 (match_dup 3) (match_dup 2)))
19560 (clobber (reg:CC FLAGS_REG))])])
19563 [(match_scratch:SI 3 "r")
19564 (parallel [(set (match_operand:DI 0 "register_operand")
19566 (mult:SI (match_operand:SI 1 "memory_operand")
19567 (match_operand:SI 2 "immediate_operand"))))
19568 (clobber (reg:CC FLAGS_REG))])]
19570 && TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
19571 && !satisfies_constraint_K (operands[2])"
19572 [(set (match_dup 3) (match_dup 1))
19573 (parallel [(set (match_dup 0)
19574 (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
19575 (clobber (reg:CC FLAGS_REG))])])
19577 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
19578 ;; Convert it into imul reg, reg
19579 ;; It would be better to force assembler to encode instruction using long
19580 ;; immediate, but there is apparently no way to do so.
19582 [(parallel [(set (match_operand:SWI248 0 "register_operand")
19584 (match_operand:SWI248 1 "nonimmediate_operand")
19585 (match_operand:SWI248 2 "const_int_operand")))
19586 (clobber (reg:CC FLAGS_REG))])
19587 (match_scratch:SWI248 3 "r")]
19588 "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
19589 && satisfies_constraint_K (operands[2])"
19590 [(set (match_dup 3) (match_dup 2))
19591 (parallel [(set (match_dup 0) (mult:SWI248 (match_dup 0) (match_dup 3)))
19592 (clobber (reg:CC FLAGS_REG))])]
19594 if (!rtx_equal_p (operands[0], operands[1]))
19595 emit_move_insn (operands[0], operands[1]);
19598 ;; After splitting up read-modify operations, array accesses with memory
19599 ;; operands might end up in form:
19601 ;; movl 4(%esp), %edx
19603 ;; instead of pre-splitting:
19605 ;; addl 4(%esp), %eax
19607 ;; movl 4(%esp), %edx
19608 ;; leal (%edx,%eax,4), %eax
19611 [(match_scratch:W 5 "r")
19612 (parallel [(set (match_operand 0 "register_operand")
19613 (ashift (match_operand 1 "register_operand")
19614 (match_operand 2 "const_int_operand")))
19615 (clobber (reg:CC FLAGS_REG))])
19616 (parallel [(set (match_operand 3 "register_operand")
19617 (plus (match_dup 0)
19618 (match_operand 4 "x86_64_general_operand")))
19619 (clobber (reg:CC FLAGS_REG))])]
19620 "IN_RANGE (INTVAL (operands[2]), 1, 3)
19621 /* Validate MODE for lea. */
19622 && ((!TARGET_PARTIAL_REG_STALL
19623 && (GET_MODE (operands[0]) == QImode
19624 || GET_MODE (operands[0]) == HImode))
19625 || GET_MODE (operands[0]) == SImode
19626 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
19627 && (rtx_equal_p (operands[0], operands[3])
19628 || peep2_reg_dead_p (2, operands[0]))
19629 /* We reorder load and the shift. */
19630 && !reg_overlap_mentioned_p (operands[0], operands[4])"
19631 [(set (match_dup 5) (match_dup 4))
19632 (set (match_dup 0) (match_dup 1))]
19634 machine_mode op1mode = GET_MODE (operands[1]);
19635 machine_mode mode = op1mode == DImode ? DImode : SImode;
19636 int scale = 1 << INTVAL (operands[2]);
19637 rtx index = gen_lowpart (word_mode, operands[1]);
19638 rtx base = gen_lowpart (word_mode, operands[5]);
19639 rtx dest = gen_lowpart (mode, operands[3]);
19641 operands[1] = gen_rtx_PLUS (word_mode, base,
19642 gen_rtx_MULT (word_mode, index, GEN_INT (scale)));
19643 if (mode != word_mode)
19644 operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
19646 operands[5] = base;
19647 if (op1mode != word_mode)
19648 operands[5] = gen_lowpart (op1mode, operands[5]);
19650 operands[0] = dest;
19653 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
19654 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
19655 ;; caught for use by garbage collectors and the like. Using an insn that
19656 ;; maps to SIGILL makes it more likely the program will rightfully die.
19657 ;; Keeping with tradition, "6" is in honor of #UD.
19658 (define_insn "trap"
19659 [(trap_if (const_int 1) (const_int 6))]
19662 #ifdef HAVE_AS_IX86_UD2
19665 return ASM_SHORT "0x0b0f";
19668 [(set_attr "length" "2")])
19671 [(unspec_volatile [(const_int 0)] UNSPECV_UD2)]
19674 #ifdef HAVE_AS_IX86_UD2
19677 return ASM_SHORT "0x0b0f";
19680 [(set_attr "length" "2")])
19682 (define_expand "prefetch"
19683 [(prefetch (match_operand 0 "address_operand")
19684 (match_operand:SI 1 "const_int_operand")
19685 (match_operand:SI 2 "const_int_operand"))]
19686 "TARGET_3DNOW || TARGET_PREFETCH_SSE || TARGET_PRFCHW || TARGET_PREFETCHWT1"
19688 bool write = INTVAL (operands[1]) != 0;
19689 int locality = INTVAL (operands[2]);
19691 gcc_assert (IN_RANGE (locality, 0, 3));
19693 /* Use 3dNOW prefetch in case we are asking for write prefetch not
19694 supported by SSE counterpart (non-SSE2 athlon machines) or the
19695 SSE prefetch is not available (K6 machines). Otherwise use SSE
19696 prefetch as it allows specifying of locality. */
19700 if (TARGET_PREFETCHWT1)
19701 operands[2] = GEN_INT (MAX (locality, 2));
19702 else if (TARGET_PRFCHW)
19703 operands[2] = GEN_INT (3);
19704 else if (TARGET_3DNOW && !TARGET_SSE2)
19705 operands[2] = GEN_INT (3);
19706 else if (TARGET_PREFETCH_SSE)
19707 operands[1] = const0_rtx;
19710 gcc_assert (TARGET_3DNOW);
19711 operands[2] = GEN_INT (3);
19716 if (TARGET_PREFETCH_SSE)
19720 gcc_assert (TARGET_3DNOW);
19721 operands[2] = GEN_INT (3);
19726 (define_insn "*prefetch_sse"
19727 [(prefetch (match_operand 0 "address_operand" "p")
19729 (match_operand:SI 1 "const_int_operand"))]
19730 "TARGET_PREFETCH_SSE"
19732 static const char * const patterns[4] = {
19733 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
19736 int locality = INTVAL (operands[1]);
19737 gcc_assert (IN_RANGE (locality, 0, 3));
19739 return patterns[locality];
19741 [(set_attr "type" "sse")
19742 (set_attr "atom_sse_attr" "prefetch")
19743 (set (attr "length_address")
19744 (symbol_ref "memory_address_length (operands[0], false)"))
19745 (set_attr "memory" "none")])
19747 (define_insn "*prefetch_3dnow"
19748 [(prefetch (match_operand 0 "address_operand" "p")
19749 (match_operand:SI 1 "const_int_operand" "n")
19751 "TARGET_3DNOW || TARGET_PRFCHW || TARGET_PREFETCHWT1"
19753 if (INTVAL (operands[1]) == 0)
19754 return "prefetch\t%a0";
19756 return "prefetchw\t%a0";
19758 [(set_attr "type" "mmx")
19759 (set (attr "length_address")
19760 (symbol_ref "memory_address_length (operands[0], false)"))
19761 (set_attr "memory" "none")])
19763 (define_insn "*prefetch_prefetchwt1"
19764 [(prefetch (match_operand 0 "address_operand" "p")
19767 "TARGET_PREFETCHWT1"
19768 "prefetchwt1\t%a0";
19769 [(set_attr "type" "sse")
19770 (set (attr "length_address")
19771 (symbol_ref "memory_address_length (operands[0], false)"))
19772 (set_attr "memory" "none")])
19774 (define_expand "stack_protect_set"
19775 [(match_operand 0 "memory_operand")
19776 (match_operand 1 "memory_operand")]
19779 rtx (*insn)(rtx, rtx);
19781 insn = (TARGET_LP64
19782 ? gen_stack_protect_set_di
19783 : gen_stack_protect_set_si);
19785 emit_insn (insn (operands[0], operands[1]));
19789 (define_insn "stack_protect_set_<mode>"
19790 [(set (match_operand:PTR 0 "memory_operand" "=m")
19791 (unspec:PTR [(match_operand:PTR 1 "memory_operand" "m")]
19793 (set (match_scratch:PTR 2 "=&r") (const_int 0))
19794 (clobber (reg:CC FLAGS_REG))]
19796 "mov{<imodesuffix>}\t{%1, %2|%2, %1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
19797 [(set_attr "type" "multi")])
19799 (define_expand "stack_protect_test"
19800 [(match_operand 0 "memory_operand")
19801 (match_operand 1 "memory_operand")
19805 rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
19807 rtx (*insn)(rtx, rtx, rtx);
19809 insn = (TARGET_LP64
19810 ? gen_stack_protect_test_di
19811 : gen_stack_protect_test_si);
19813 emit_insn (insn (flags, operands[0], operands[1]));
19815 emit_jump_insn (gen_cbranchcc4 (gen_rtx_EQ (VOIDmode, flags, const0_rtx),
19816 flags, const0_rtx, operands[2]));
19820 (define_insn "stack_protect_test_<mode>"
19821 [(set (match_operand:CCZ 0 "flags_reg_operand")
19822 (unspec:CCZ [(match_operand:PTR 1 "memory_operand" "m")
19823 (match_operand:PTR 2 "memory_operand" "m")]
19825 (clobber (match_scratch:PTR 3 "=&r"))]
19827 "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%2, %3|%3, %2}"
19828 [(set_attr "type" "multi")])
19830 (define_insn "sse4_2_crc32<mode>"
19831 [(set (match_operand:SI 0 "register_operand" "=r")
19833 [(match_operand:SI 1 "register_operand" "0")
19834 (match_operand:SWI124 2 "nonimmediate_operand" "<r>m")]
19836 "TARGET_SSE4_2 || TARGET_CRC32"
19837 "crc32{<imodesuffix>}\t{%2, %0|%0, %2}"
19838 [(set_attr "type" "sselog1")
19839 (set_attr "prefix_rep" "1")
19840 (set_attr "prefix_extra" "1")
19841 (set (attr "prefix_data16")
19842 (if_then_else (match_operand:HI 2)
19844 (const_string "*")))
19845 (set (attr "prefix_rex")
19846 (if_then_else (match_operand:QI 2 "ext_QIreg_operand")
19848 (const_string "*")))
19849 (set_attr "mode" "SI")])
19851 (define_insn "sse4_2_crc32di"
19852 [(set (match_operand:DI 0 "register_operand" "=r")
19854 [(match_operand:DI 1 "register_operand" "0")
19855 (match_operand:DI 2 "nonimmediate_operand" "rm")]
19857 "TARGET_64BIT && (TARGET_SSE4_2 || TARGET_CRC32)"
19858 "crc32{q}\t{%2, %0|%0, %2}"
19859 [(set_attr "type" "sselog1")
19860 (set_attr "prefix_rep" "1")
19861 (set_attr "prefix_extra" "1")
19862 (set_attr "mode" "DI")])
19864 (define_insn "rdpmc"
19865 [(set (match_operand:DI 0 "register_operand" "=A")
19866 (unspec_volatile:DI [(match_operand:SI 1 "register_operand" "c")]
19870 [(set_attr "type" "other")
19871 (set_attr "length" "2")])
19873 (define_insn "rdpmc_rex64"
19874 [(set (match_operand:DI 0 "register_operand" "=a")
19875 (unspec_volatile:DI [(match_operand:SI 2 "register_operand" "c")]
19877 (set (match_operand:DI 1 "register_operand" "=d")
19878 (unspec_volatile:DI [(match_dup 2)] UNSPECV_RDPMC))]
19881 [(set_attr "type" "other")
19882 (set_attr "length" "2")])
19884 (define_insn "rdtsc"
19885 [(set (match_operand:DI 0 "register_operand" "=A")
19886 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
19889 [(set_attr "type" "other")
19890 (set_attr "length" "2")])
19892 (define_insn "rdtsc_rex64"
19893 [(set (match_operand:DI 0 "register_operand" "=a")
19894 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))
19895 (set (match_operand:DI 1 "register_operand" "=d")
19896 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
19899 [(set_attr "type" "other")
19900 (set_attr "length" "2")])
19902 (define_insn "rdtscp"
19903 [(set (match_operand:DI 0 "register_operand" "=A")
19904 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
19905 (set (match_operand:SI 1 "register_operand" "=c")
19906 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
19909 [(set_attr "type" "other")
19910 (set_attr "length" "3")])
19912 (define_insn "rdtscp_rex64"
19913 [(set (match_operand:DI 0 "register_operand" "=a")
19914 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
19915 (set (match_operand:DI 1 "register_operand" "=d")
19916 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
19917 (set (match_operand:SI 2 "register_operand" "=c")
19918 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
19921 [(set_attr "type" "other")
19922 (set_attr "length" "3")])
19924 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
19926 ;; FXSR, XSAVE and XSAVEOPT instructions
19928 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
19930 (define_insn "fxsave"
19931 [(set (match_operand:BLK 0 "memory_operand" "=m")
19932 (unspec_volatile:BLK [(const_int 0)] UNSPECV_FXSAVE))]
19935 [(set_attr "type" "other")
19936 (set_attr "memory" "store")
19937 (set (attr "length")
19938 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
19940 (define_insn "fxsave64"
19941 [(set (match_operand:BLK 0 "memory_operand" "=m")
19942 (unspec_volatile:BLK [(const_int 0)] UNSPECV_FXSAVE64))]
19943 "TARGET_64BIT && TARGET_FXSR"
19945 [(set_attr "type" "other")
19946 (set_attr "memory" "store")
19947 (set (attr "length")
19948 (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
19950 (define_insn "fxrstor"
19951 [(unspec_volatile [(match_operand:BLK 0 "memory_operand" "m")]
19955 [(set_attr "type" "other")
19956 (set_attr "memory" "load")
19957 (set (attr "length")
19958 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
19960 (define_insn "fxrstor64"
19961 [(unspec_volatile [(match_operand:BLK 0 "memory_operand" "m")]
19962 UNSPECV_FXRSTOR64)]
19963 "TARGET_64BIT && TARGET_FXSR"
19965 [(set_attr "type" "other")
19966 (set_attr "memory" "load")
19967 (set (attr "length")
19968 (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
19970 (define_int_iterator ANY_XSAVE
19972 (UNSPECV_XSAVEOPT "TARGET_XSAVEOPT")
19973 (UNSPECV_XSAVEC "TARGET_XSAVEC")
19974 (UNSPECV_XSAVES "TARGET_XSAVES")])
19976 (define_int_iterator ANY_XSAVE64
19978 (UNSPECV_XSAVEOPT64 "TARGET_XSAVEOPT")
19979 (UNSPECV_XSAVEC64 "TARGET_XSAVEC")
19980 (UNSPECV_XSAVES64 "TARGET_XSAVES")])
19982 (define_int_attr xsave
19983 [(UNSPECV_XSAVE "xsave")
19984 (UNSPECV_XSAVE64 "xsave64")
19985 (UNSPECV_XSAVEOPT "xsaveopt")
19986 (UNSPECV_XSAVEOPT64 "xsaveopt64")
19987 (UNSPECV_XSAVEC "xsavec")
19988 (UNSPECV_XSAVEC64 "xsavec64")
19989 (UNSPECV_XSAVES "xsaves")
19990 (UNSPECV_XSAVES64 "xsaves64")])
19992 (define_int_iterator ANY_XRSTOR
19994 (UNSPECV_XRSTORS "TARGET_XSAVES")])
19996 (define_int_iterator ANY_XRSTOR64
19998 (UNSPECV_XRSTORS64 "TARGET_XSAVES")])
20000 (define_int_attr xrstor
20001 [(UNSPECV_XRSTOR "xrstor")
20002 (UNSPECV_XRSTOR64 "xrstor")
20003 (UNSPECV_XRSTORS "xrstors")
20004 (UNSPECV_XRSTORS64 "xrstors")])
20006 (define_insn "<xsave>"
20007 [(set (match_operand:BLK 0 "memory_operand" "=m")
20008 (unspec_volatile:BLK
20009 [(match_operand:DI 1 "register_operand" "A")]
20011 "!TARGET_64BIT && TARGET_XSAVE"
20013 [(set_attr "type" "other")
20014 (set_attr "memory" "store")
20015 (set (attr "length")
20016 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
20018 (define_insn "<xsave>_rex64"
20019 [(set (match_operand:BLK 0 "memory_operand" "=m")
20020 (unspec_volatile:BLK
20021 [(match_operand:SI 1 "register_operand" "a")
20022 (match_operand:SI 2 "register_operand" "d")]
20024 "TARGET_64BIT && TARGET_XSAVE"
20026 [(set_attr "type" "other")
20027 (set_attr "memory" "store")
20028 (set (attr "length")
20029 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
20031 (define_insn "<xsave>"
20032 [(set (match_operand:BLK 0 "memory_operand" "=m")
20033 (unspec_volatile:BLK
20034 [(match_operand:SI 1 "register_operand" "a")
20035 (match_operand:SI 2 "register_operand" "d")]
20037 "TARGET_64BIT && TARGET_XSAVE"
20039 [(set_attr "type" "other")
20040 (set_attr "memory" "store")
20041 (set (attr "length")
20042 (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
20044 (define_insn "<xrstor>"
20045 [(unspec_volatile:BLK
20046 [(match_operand:BLK 0 "memory_operand" "m")
20047 (match_operand:DI 1 "register_operand" "A")]
20049 "!TARGET_64BIT && TARGET_XSAVE"
20051 [(set_attr "type" "other")
20052 (set_attr "memory" "load")
20053 (set (attr "length")
20054 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
20056 (define_insn "<xrstor>_rex64"
20057 [(unspec_volatile:BLK
20058 [(match_operand:BLK 0 "memory_operand" "m")
20059 (match_operand:SI 1 "register_operand" "a")
20060 (match_operand:SI 2 "register_operand" "d")]
20062 "TARGET_64BIT && TARGET_XSAVE"
20064 [(set_attr "type" "other")
20065 (set_attr "memory" "load")
20066 (set (attr "length")
20067 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
20069 (define_insn "<xrstor>64"
20070 [(unspec_volatile:BLK
20071 [(match_operand:BLK 0 "memory_operand" "m")
20072 (match_operand:SI 1 "register_operand" "a")
20073 (match_operand:SI 2 "register_operand" "d")]
20075 "TARGET_64BIT && TARGET_XSAVE"
20077 [(set_attr "type" "other")
20078 (set_attr "memory" "load")
20079 (set (attr "length")
20080 (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
20082 (define_insn "xsetbv"
20083 [(unspec_volatile:SI
20084 [(match_operand:SI 0 "register_operand" "c")
20085 (match_operand:DI 1 "register_operand" "A")]
20087 "!TARGET_64BIT && TARGET_XSAVE"
20089 [(set_attr "type" "other")])
20091 (define_insn "xsetbv_rex64"
20092 [(unspec_volatile:SI
20093 [(match_operand:SI 0 "register_operand" "c")
20094 (match_operand:SI 1 "register_operand" "a")
20095 (match_operand:SI 2 "register_operand" "d")]
20097 "TARGET_64BIT && TARGET_XSAVE"
20099 [(set_attr "type" "other")])
20101 (define_insn "xgetbv"
20102 [(set (match_operand:DI 0 "register_operand" "=A")
20103 (unspec_volatile:DI [(match_operand:SI 1 "register_operand" "c")]
20105 "!TARGET_64BIT && TARGET_XSAVE"
20107 [(set_attr "type" "other")])
20109 (define_insn "xgetbv_rex64"
20110 [(set (match_operand:DI 0 "register_operand" "=a")
20111 (unspec_volatile:DI [(match_operand:SI 2 "register_operand" "c")]
20113 (set (match_operand:DI 1 "register_operand" "=d")
20114 (unspec_volatile:DI [(match_dup 2)] UNSPECV_XGETBV))]
20115 "TARGET_64BIT && TARGET_XSAVE"
20117 [(set_attr "type" "other")])
20119 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
20121 ;; Floating-point instructions for atomic compound assignments
20123 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
20125 ; Clobber all floating-point registers on environment save and restore
20126 ; to ensure that the TOS value saved at fnstenv is valid after fldenv.
20127 (define_insn "fnstenv"
20128 [(set (match_operand:BLK 0 "memory_operand" "=m")
20129 (unspec_volatile:BLK [(const_int 0)] UNSPECV_FNSTENV))
20130 (clobber (reg:HI FPCR_REG))
20131 (clobber (reg:XF ST0_REG))
20132 (clobber (reg:XF ST1_REG))
20133 (clobber (reg:XF ST2_REG))
20134 (clobber (reg:XF ST3_REG))
20135 (clobber (reg:XF ST4_REG))
20136 (clobber (reg:XF ST5_REG))
20137 (clobber (reg:XF ST6_REG))
20138 (clobber (reg:XF ST7_REG))]
20141 [(set_attr "type" "other")
20142 (set_attr "memory" "store")
20143 (set (attr "length")
20144 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))])
20146 (define_insn "fldenv"
20147 [(unspec_volatile [(match_operand:BLK 0 "memory_operand" "m")]
20149 (clobber (reg:CCFP FPSR_REG))
20150 (clobber (reg:HI FPCR_REG))
20151 (clobber (reg:XF ST0_REG))
20152 (clobber (reg:XF ST1_REG))
20153 (clobber (reg:XF ST2_REG))
20154 (clobber (reg:XF ST3_REG))
20155 (clobber (reg:XF ST4_REG))
20156 (clobber (reg:XF ST5_REG))
20157 (clobber (reg:XF ST6_REG))
20158 (clobber (reg:XF ST7_REG))]
20161 [(set_attr "type" "other")
20162 (set_attr "memory" "load")
20163 (set (attr "length")
20164 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))])
20166 (define_insn "fnstsw"
20167 [(set (match_operand:HI 0 "nonimmediate_operand" "=a,m")
20168 (unspec_volatile:HI [(const_int 0)] UNSPECV_FNSTSW))]
20171 [(set_attr "type" "other,other")
20172 (set_attr "memory" "none,store")
20173 (set (attr "length")
20174 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))])
20176 (define_insn "fnclex"
20177 [(unspec_volatile [(const_int 0)] UNSPECV_FNCLEX)]
20180 [(set_attr "type" "other")
20181 (set_attr "memory" "none")
20182 (set_attr "length" "2")])
20184 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
20186 ;; LWP instructions
20188 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
20190 (define_expand "lwp_llwpcb"
20191 [(unspec_volatile [(match_operand 0 "register_operand")]
20192 UNSPECV_LLWP_INTRINSIC)]
20195 (define_insn "*lwp_llwpcb<mode>1"
20196 [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
20197 UNSPECV_LLWP_INTRINSIC)]
20200 [(set_attr "type" "lwp")
20201 (set_attr "mode" "<MODE>")
20202 (set_attr "length" "5")])
20204 (define_expand "lwp_slwpcb"
20205 [(set (match_operand 0 "register_operand")
20206 (unspec_volatile [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
20211 insn = (Pmode == DImode
20213 : gen_lwp_slwpcbsi);
20215 emit_insn (insn (operands[0]));
20219 (define_insn "lwp_slwpcb<mode>"
20220 [(set (match_operand:P 0 "register_operand" "=r")
20221 (unspec_volatile:P [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
20224 [(set_attr "type" "lwp")
20225 (set_attr "mode" "<MODE>")
20226 (set_attr "length" "5")])
20228 (define_expand "lwp_lwpval<mode>3"
20229 [(unspec_volatile [(match_operand:SWI48 1 "register_operand")
20230 (match_operand:SI 2 "nonimmediate_operand")
20231 (match_operand:SI 3 "const_int_operand")]
20232 UNSPECV_LWPVAL_INTRINSIC)]
20234 ;; Avoid unused variable warning.
20235 "(void) operands[0];")
20237 (define_insn "*lwp_lwpval<mode>3_1"
20238 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")
20239 (match_operand:SI 1 "nonimmediate_operand" "rm")
20240 (match_operand:SI 2 "const_int_operand" "i")]
20241 UNSPECV_LWPVAL_INTRINSIC)]
20243 "lwpval\t{%2, %1, %0|%0, %1, %2}"
20244 [(set_attr "type" "lwp")
20245 (set_attr "mode" "<MODE>")
20246 (set (attr "length")
20247 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
20249 (define_expand "lwp_lwpins<mode>3"
20250 [(set (reg:CCC FLAGS_REG)
20251 (unspec_volatile:CCC [(match_operand:SWI48 1 "register_operand")
20252 (match_operand:SI 2 "nonimmediate_operand")
20253 (match_operand:SI 3 "const_int_operand")]
20254 UNSPECV_LWPINS_INTRINSIC))
20255 (set (match_operand:QI 0 "nonimmediate_operand")
20256 (eq:QI (reg:CCC FLAGS_REG) (const_int 0)))]
20259 (define_insn "*lwp_lwpins<mode>3_1"
20260 [(set (reg:CCC FLAGS_REG)
20261 (unspec_volatile:CCC [(match_operand:SWI48 0 "register_operand" "r")
20262 (match_operand:SI 1 "nonimmediate_operand" "rm")
20263 (match_operand:SI 2 "const_int_operand" "i")]
20264 UNSPECV_LWPINS_INTRINSIC))]
20266 "lwpins\t{%2, %1, %0|%0, %1, %2}"
20267 [(set_attr "type" "lwp")
20268 (set_attr "mode" "<MODE>")
20269 (set (attr "length")
20270 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
20272 (define_int_iterator RDFSGSBASE
20276 (define_int_iterator WRFSGSBASE
20280 (define_int_attr fsgs
20281 [(UNSPECV_RDFSBASE "fs")
20282 (UNSPECV_RDGSBASE "gs")
20283 (UNSPECV_WRFSBASE "fs")
20284 (UNSPECV_WRGSBASE "gs")])
20286 (define_insn "rd<fsgs>base<mode>"
20287 [(set (match_operand:SWI48 0 "register_operand" "=r")
20288 (unspec_volatile:SWI48 [(const_int 0)] RDFSGSBASE))]
20289 "TARGET_64BIT && TARGET_FSGSBASE"
20291 [(set_attr "type" "other")
20292 (set_attr "prefix_extra" "2")])
20294 (define_insn "wr<fsgs>base<mode>"
20295 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
20297 "TARGET_64BIT && TARGET_FSGSBASE"
20299 [(set_attr "type" "other")
20300 (set_attr "prefix_extra" "2")])
20302 (define_insn "rdrand<mode>_1"
20303 [(set (match_operand:SWI248 0 "register_operand" "=r")
20304 (unspec_volatile:SWI248 [(const_int 0)] UNSPECV_RDRAND))
20305 (set (reg:CCC FLAGS_REG)
20306 (unspec_volatile:CCC [(const_int 0)] UNSPECV_RDRAND))]
20309 [(set_attr "type" "other")
20310 (set_attr "prefix_extra" "1")])
20312 (define_insn "rdseed<mode>_1"
20313 [(set (match_operand:SWI248 0 "register_operand" "=r")
20314 (unspec_volatile:SWI248 [(const_int 0)] UNSPECV_RDSEED))
20315 (set (reg:CCC FLAGS_REG)
20316 (unspec_volatile:CCC [(const_int 0)] UNSPECV_RDSEED))]
20319 [(set_attr "type" "other")
20320 (set_attr "prefix_extra" "1")])
20322 (define_expand "pause"
20323 [(set (match_dup 0)
20324 (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
20327 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
20328 MEM_VOLATILE_P (operands[0]) = 1;
20331 ;; Use "rep; nop", instead of "pause", to support older assemblers.
20332 ;; They have the same encoding.
20333 (define_insn "*pause"
20334 [(set (match_operand:BLK 0)
20335 (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
20338 [(set_attr "length" "2")
20339 (set_attr "memory" "unknown")])
20341 ;; CET instructions
20342 (define_insn "rdssp<mode>"
20343 [(set (match_operand:SWI48x 0 "register_operand" "=r")
20344 (unspec_volatile:SWI48x [(const_int 0)] UNSPECV_NOP_RDSSP))]
20345 "TARGET_SHSTK || (flag_cf_protection & CF_RETURN)"
20346 "xor{l}\t%k0, %k0\n\trdssp<mskmodesuffix>\t%0"
20347 [(set_attr "length" "6")
20348 (set_attr "type" "other")])
20350 (define_insn "incssp<mode>"
20351 [(unspec_volatile [(match_operand:SWI48x 0 "register_operand" "r")]
20353 "TARGET_SHSTK || (flag_cf_protection & CF_RETURN)"
20354 "incssp<mskmodesuffix>\t%0"
20355 [(set_attr "length" "4")
20356 (set_attr "type" "other")])
20358 (define_insn "saveprevssp"
20359 [(unspec_volatile [(const_int 0)] UNSPECV_SAVEPREVSSP)]
20362 [(set_attr "length" "5")
20363 (set_attr "type" "other")])
20365 (define_insn "rstorssp"
20366 [(unspec_volatile [(match_operand 0 "memory_operand" "m")]
20370 [(set_attr "length" "5")
20371 (set_attr "type" "other")])
20373 (define_insn "wrss<mode>"
20374 [(unspec_volatile [(match_operand:SWI48x 0 "register_operand" "r")
20375 (match_operand:SWI48x 1 "memory_operand" "m")]
20378 "wrss<mskmodesuffix>\t%0, %1"
20379 [(set_attr "length" "3")
20380 (set_attr "type" "other")])
20382 (define_insn "wruss<mode>"
20383 [(unspec_volatile [(match_operand:SWI48x 0 "register_operand" "r")
20384 (match_operand:SWI48x 1 "memory_operand" "m")]
20387 "wruss<mskmodesuffix>\t%0, %1"
20388 [(set_attr "length" "4")
20389 (set_attr "type" "other")])
20391 (define_insn "setssbsy"
20392 [(unspec_volatile [(const_int 0)] UNSPECV_SETSSBSY)]
20395 [(set_attr "length" "4")
20396 (set_attr "type" "other")])
20398 (define_insn "clrssbsy"
20399 [(unspec_volatile [(match_operand 0 "memory_operand" "m")]
20403 [(set_attr "length" "4")
20404 (set_attr "type" "other")])
20406 (define_insn "nop_endbr"
20407 [(unspec_volatile [(const_int 0)] UNSPECV_NOP_ENDBR)]
20408 "(flag_cf_protection & CF_BRANCH)"
20410 { return (TARGET_64BIT)? \"endbr64\" : \"endbr32\"; }"
20411 [(set_attr "length" "4")
20412 (set_attr "length_immediate" "0")
20413 (set_attr "modrm" "0")])
20416 (define_expand "xbegin"
20417 [(set (match_operand:SI 0 "register_operand")
20418 (unspec_volatile:SI [(const_int 0)] UNSPECV_XBEGIN))]
20421 rtx_code_label *label = gen_label_rtx ();
20423 /* xbegin is emitted as jump_insn, so reload won't be able
20424 to reload its operand. Force the value into AX hard register. */
20425 rtx ax_reg = gen_rtx_REG (SImode, AX_REG);
20426 emit_move_insn (ax_reg, constm1_rtx);
20428 emit_jump_insn (gen_xbegin_1 (ax_reg, label));
20430 emit_label (label);
20431 LABEL_NUSES (label) = 1;
20433 emit_move_insn (operands[0], ax_reg);
20438 (define_insn "xbegin_1"
20440 (if_then_else (ne (unspec [(const_int 0)] UNSPEC_XBEGIN_ABORT)
20442 (label_ref (match_operand 1))
20444 (set (match_operand:SI 0 "register_operand" "+a")
20445 (unspec_volatile:SI [(match_dup 0)] UNSPECV_XBEGIN))]
20448 [(set_attr "type" "other")
20449 (set_attr "length" "6")])
20451 (define_insn "xend"
20452 [(unspec_volatile [(const_int 0)] UNSPECV_XEND)]
20455 [(set_attr "type" "other")
20456 (set_attr "length" "3")])
20458 (define_insn "xabort"
20459 [(unspec_volatile [(match_operand:SI 0 "const_0_to_255_operand" "n")]
20463 [(set_attr "type" "other")
20464 (set_attr "length" "3")])
20466 (define_expand "xtest"
20467 [(set (match_operand:QI 0 "register_operand")
20468 (unspec_volatile:QI [(const_int 0)] UNSPECV_XTEST))]
20471 emit_insn (gen_xtest_1 ());
20473 ix86_expand_setcc (operands[0], NE,
20474 gen_rtx_REG (CCZmode, FLAGS_REG), const0_rtx);
20478 (define_insn "xtest_1"
20479 [(set (reg:CCZ FLAGS_REG)
20480 (unspec_volatile:CCZ [(const_int 0)] UNSPECV_XTEST))]
20483 [(set_attr "type" "other")
20484 (set_attr "length" "3")])
20486 (define_insn "clwb"
20487 [(unspec_volatile [(match_operand 0 "address_operand" "p")]
20491 [(set_attr "type" "sse")
20492 (set_attr "atom_sse_attr" "fence")
20493 (set_attr "memory" "unknown")])
20495 (define_insn "clflushopt"
20496 [(unspec_volatile [(match_operand 0 "address_operand" "p")]
20497 UNSPECV_CLFLUSHOPT)]
20498 "TARGET_CLFLUSHOPT"
20500 [(set_attr "type" "sse")
20501 (set_attr "atom_sse_attr" "fence")
20502 (set_attr "memory" "unknown")])
20504 ;; MONITORX and MWAITX
20505 (define_insn "mwaitx"
20506 [(unspec_volatile [(match_operand:SI 0 "register_operand" "c")
20507 (match_operand:SI 1 "register_operand" "a")
20508 (match_operand:SI 2 "register_operand" "b")]
20511 ;; 64bit version is "mwaitx %rax,%rcx,%rbx". But only lower 32bits are used.
20512 ;; Since 32bit register operands are implicitly zero extended to 64bit,
20513 ;; we only need to set up 32bit registers.
20515 [(set_attr "length" "3")])
20517 (define_insn "monitorx_<mode>"
20518 [(unspec_volatile [(match_operand:P 0 "register_operand" "a")
20519 (match_operand:SI 1 "register_operand" "c")
20520 (match_operand:SI 2 "register_operand" "d")]
20523 ;; 64bit version is "monitorx %rax,%rcx,%rdx". But only lower 32bits in
20524 ;; RCX and RDX are used. Since 32bit register operands are implicitly
20525 ;; zero extended to 64bit, we only need to set up 32bit registers.
20527 [(set (attr "length")
20528 (symbol_ref ("(Pmode != word_mode) + 3")))])
20531 (define_insn "clzero_<mode>"
20532 [(unspec_volatile [(match_operand: P 0 "register_operand" "a")]
20536 [(set_attr "length" "3")
20537 (set_attr "memory" "unknown")])
20539 ;; MPX instructions
20541 (define_expand "<mode>_mk"
20542 [(set (match_operand:BND 0 "register_operand")
20546 [(match_operand:<bnd_ptr> 1 "register_operand")
20547 (match_operand:<bnd_ptr> 2 "address_mpx_no_base_operand")]))]
20551 operands[3] = gen_rtx_UNSPEC (Pmode, gen_rtvec (2, operands[1],
20553 UNSPEC_BNDMK_ADDR);
20556 (define_insn "*<mode>_mk"
20557 [(set (match_operand:BND 0 "register_operand" "=w")
20559 [(match_operator:<bnd_ptr> 3 "bnd_mem_operator"
20561 [(match_operand:<bnd_ptr> 1 "register_operand" "r")
20562 (match_operand:<bnd_ptr> 2 "address_mpx_no_base_operand" "Tb")]
20563 UNSPEC_BNDMK_ADDR)])]
20566 "bndmk\t{%3, %0|%0, %3}"
20567 [(set_attr "type" "mpxmk")])
20569 (define_expand "mov<mode>"
20570 [(set (match_operand:BND 0 "general_operand")
20571 (match_operand:BND 1 "general_operand"))]
20573 "ix86_expand_move (<MODE>mode, operands); DONE;")
20575 (define_insn "*mov<mode>_internal_mpx"
20576 [(set (match_operand:BND 0 "nonimmediate_operand" "=w,m")
20577 (match_operand:BND 1 "general_operand" "wm,w"))]
20579 "bndmov\t{%1, %0|%0, %1}"
20580 [(set_attr "type" "mpxmov")])
20582 (define_expand "<mode>_<bndcheck>"
20585 [(match_operand:BND 0 "register_operand")
20586 (match_operand:<bnd_ptr> 1 "address_no_seg_operand")] BNDCHECK)
20588 (unspec:BLK [(match_dup 2)] UNSPEC_MPX_FENCE))])]
20591 operands[2] = gen_rtx_MEM (BLKmode, operands[1]);
20592 MEM_VOLATILE_P (operands[2]) = 1;
20595 (define_insn "*<mode>_<bndcheck>"
20597 [(match_operand:BND 0 "register_operand" "w")
20598 (match_operand:<bnd_ptr> 1 "address_no_seg_operand" "Ts")] BNDCHECK)
20599 (set (match_operand:BLK 2 "bnd_mem_operator")
20600 (unspec:BLK [(match_dup 2)] UNSPEC_MPX_FENCE))]
20602 "bnd<bndcheck>\t{%a1, %0|%0, %a1}"
20603 [(set_attr "type" "mpxchk")])
20605 (define_expand "<mode>_ldx"
20607 [(set (match_operand:BND 0 "register_operand")
20611 [(match_operand:<bnd_ptr> 1 "address_mpx_no_index_operand")
20612 (match_operand:<bnd_ptr> 2 "register_operand")]))]
20614 (use (mem:BLK (match_dup 1)))])]
20617 /* Avoid registers which cannot be used as index. */
20618 if (!index_register_operand (operands[2], Pmode))
20619 operands[2] = copy_addr_to_reg (operands[2]);
20621 operands[3] = gen_rtx_UNSPEC (Pmode, gen_rtvec (2, operands[1],
20623 UNSPEC_BNDLDX_ADDR);
20626 (define_insn "*<mode>_ldx"
20627 [(set (match_operand:BND 0 "register_operand" "=w")
20629 [(match_operator:<bnd_ptr> 3 "bnd_mem_operator"
20631 [(match_operand:<bnd_ptr> 1 "address_mpx_no_index_operand" "Ti")
20632 (match_operand:<bnd_ptr> 2 "register_operand" "l")]
20633 UNSPEC_BNDLDX_ADDR)])]
20635 (use (mem:BLK (match_dup 1)))]
20637 "bndldx\t{%3, %0|%0, %3}"
20638 [(set_attr "type" "mpxld")])
20640 (define_expand "<mode>_stx"
20645 [(match_operand:<bnd_ptr> 0 "address_mpx_no_index_operand")
20646 (match_operand:<bnd_ptr> 1 "register_operand")]))
20647 (match_operand:BND 2 "register_operand")]
20650 (unspec:BLK [(match_dup 4)] UNSPEC_MPX_FENCE))])]
20653 /* Avoid registers which cannot be used as index. */
20654 if (!index_register_operand (operands[1], Pmode))
20655 operands[1] = copy_addr_to_reg (operands[1]);
20657 operands[3] = gen_rtx_UNSPEC (Pmode, gen_rtvec (2, operands[0],
20659 UNSPEC_BNDLDX_ADDR);
20660 operands[4] = gen_rtx_MEM (BLKmode, operands[0]);
20661 MEM_VOLATILE_P (operands[4]) = 1;
20664 (define_insn "*<mode>_stx"
20666 [(match_operator:<bnd_ptr> 3 "bnd_mem_operator"
20668 [(match_operand:<bnd_ptr> 0 "address_mpx_no_index_operand" "Ti")
20669 (match_operand:<bnd_ptr> 1 "register_operand" "l")]
20670 UNSPEC_BNDLDX_ADDR)])
20671 (match_operand:BND 2 "register_operand" "w")]
20673 (set (match_operand:BLK 4 "bnd_mem_operator")
20674 (unspec:BLK [(match_dup 4)] UNSPEC_MPX_FENCE))]
20676 "bndstx\t{%2, %3|%3, %2}"
20677 [(set_attr "type" "mpxst")])
20679 (define_insn "move_size_reloc_<mode>"
20680 [(set (match_operand:SWI48 0 "register_operand" "=r")
20682 [(match_operand:SWI48 1 "symbol_operand")]
20686 if (x86_64_immediate_size_operand (operands[1], VOIDmode))
20687 return "mov{l}\t{%1@SIZE, %k0|%k0, %1@SIZE}";
20689 return "movabs{q}\t{%1@SIZE, %0|%0, %1@SIZE}";
20691 [(set_attr "type" "imov")
20692 (set_attr "mode" "<MODE>")])
20694 ;; RDPKRU and WRPKRU
20696 (define_expand "rdpkru"
20698 [(set (match_operand:SI 0 "register_operand")
20699 (unspec_volatile:SI [(match_dup 1)] UNSPECV_PKU))
20700 (set (match_dup 2) (const_int 0))])]
20703 operands[1] = force_reg (SImode, const0_rtx);
20704 operands[2] = gen_reg_rtx (SImode);
20707 (define_insn "*rdpkru"
20708 [(set (match_operand:SI 0 "register_operand" "=a")
20709 (unspec_volatile:SI [(match_operand:SI 2 "register_operand" "c")]
20711 (set (match_operand:SI 1 "register_operand" "=d")
20715 [(set_attr "type" "other")])
20717 (define_expand "wrpkru"
20718 [(unspec_volatile:SI
20719 [(match_operand:SI 0 "register_operand")
20720 (match_dup 1) (match_dup 2)] UNSPECV_PKU)]
20723 operands[1] = force_reg (SImode, const0_rtx);
20724 operands[2] = force_reg (SImode, const0_rtx);
20727 (define_insn "*wrpkru"
20728 [(unspec_volatile:SI
20729 [(match_operand:SI 0 "register_operand" "a")
20730 (match_operand:SI 1 "register_operand" "d")
20731 (match_operand:SI 2 "register_operand" "c")] UNSPECV_PKU)]
20734 [(set_attr "type" "other")])
20736 (define_insn "rdpid"
20737 [(set (match_operand:SI 0 "register_operand" "=r")
20738 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDPID))]
20739 "!TARGET_64BIT && TARGET_RDPID"
20741 [(set_attr "type" "other")])
20743 (define_insn "rdpid_rex64"
20744 [(set (match_operand:DI 0 "register_operand" "=r")
20745 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDPID))]
20746 "TARGET_64BIT && TARGET_RDPID"
20748 [(set_attr "type" "other")])
20750 ;; Intirinsics for > i486
20752 (define_insn "wbinvd"
20753 [(unspec_volatile [(const_int 0)] UNSPECV_WBINVD)]
20756 [(set_attr "type" "other")])
20758 (define_insn "wbnoinvd"
20759 [(unspec_volatile [(const_int 0)] UNSPECV_WBNOINVD)]
20762 [(set_attr "type" "other")])
20764 (define_insn "movdiri<mode>"
20765 [(unspec_volatile:SWI48[(match_operand:SWI48 0 "memory_operand" "m")
20766 (match_operand:SWI48 1 "register_operand" "r")]
20769 "movdiri\t{%1, %0|%0, %1}"
20770 [(set_attr "type" "other")])
20772 (define_insn "movdir64b_<mode>"
20773 [(unspec_volatile:XI[(match_operand:P 0 "register_operand" "r")
20774 (match_operand:XI 1 "memory_operand")]
20775 UNSPECV_MOVDIR64B)]
20777 "movdir64b\t{%1, %0|%0, %1}"
20778 [(set_attr "type" "other")])
20782 (include "sync.md")