1 ;; GCC machine description for IA-32 and x86-64.
2 ;; Copyright (C) 1988-2018 Free Software Foundation, Inc.
3 ;; Mostly by William Schelter.
4 ;; x86_64 support added by Jan Hubicka
6 ;; This file is part of GCC.
8 ;; GCC is free software; you can redistribute it and/or modify
9 ;; it under the terms of the GNU General Public License as published by
10 ;; the Free Software Foundation; either version 3, or (at your option)
13 ;; GCC is distributed in the hope that it will be useful,
14 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
15 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 ;; GNU General Public License for more details.
18 ;; You should have received a copy of the GNU General Public License
19 ;; along with GCC; see the file COPYING3. If not see
20 ;; <http://www.gnu.org/licenses/>. */
22 ;; The original PO technology requires these to be ordered by speed,
23 ;; so that assigner will pick the fastest.
25 ;; See file "rtl.def" for documentation on define_insn, match_*, et. al.
27 ;; The special asm out single letter directives following a '%' are:
28 ;; L,W,B,Q,S,T -- print the opcode suffix for specified size of operand.
29 ;; C -- print opcode suffix for set/cmov insn.
30 ;; c -- like C, but print reversed condition
31 ;; F,f -- likewise, but for floating-point.
32 ;; O -- if HAVE_AS_IX86_CMOV_SUN_SYNTAX, expand to "w.", "l." or "q.",
34 ;; R -- print the prefix for register names.
35 ;; z -- print the opcode suffix for the size of the current operand.
36 ;; Z -- likewise, with special suffixes for x87 instructions.
37 ;; * -- print a star (in certain assembler syntax)
38 ;; A -- print an absolute memory reference.
39 ;; E -- print address with DImode register names if TARGET_64BIT.
40 ;; w -- print the operand as if it's a "word" (HImode) even if it isn't.
41 ;; s -- print a shift double count, followed by the assemblers argument
43 ;; b -- print the QImode name of the register for the indicated operand.
44 ;; %b0 would print %al if operands[0] is reg 0.
45 ;; w -- likewise, print the HImode name of the register.
46 ;; k -- likewise, print the SImode name of the register.
47 ;; q -- likewise, print the DImode name of the register.
48 ;; x -- likewise, print the V4SFmode name of the register.
49 ;; t -- likewise, print the V8SFmode name of the register.
50 ;; h -- print the QImode name for a "high" register, either ah, bh, ch or dh.
51 ;; y -- print "st(0)" instead of "st" as a register.
52 ;; d -- print duplicated register operand for AVX instruction.
53 ;; D -- print condition for SSE cmp instruction.
54 ;; P -- if PIC, print an @PLT suffix.
55 ;; p -- print raw symbol name.
56 ;; X -- don't print any sort of PIC '@' suffix for a symbol.
57 ;; & -- print some in-use local-dynamic symbol name.
58 ;; H -- print a memory address offset by 8; used for sse high-parts
59 ;; K -- print HLE lock prefix
60 ;; Y -- print condition for XOP pcom* instruction.
61 ;; + -- print a branch hint as 'cs' or 'ds' prefix
62 ;; ; -- print a semicolon (after prefixes due to bug in older gas).
63 ;; ~ -- print "i" if TARGET_AVX2, "f" otherwise.
64 ;; ^ -- print addr32 prefix if TARGET_64BIT and Pmode != word_mode
65 ;; ! -- print NOTRACK prefix for jxx/call/ret instructions if required.
67 (define_c_enum "unspec" [
68 ;; Relocation specifiers
79 UNSPEC_MACHOPIC_OFFSET
88 UNSPEC_MEMORY_BLOCKAGE
98 ;; Other random patterns
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
293 ;; For MOVDIRI and MOVDIR64B support
297 ;; For WAITPKG support
302 ;; For CLDEMOTE support
306 ;; Constants to represent rounding modes in the ROUND instruction
315 ;; Constants to represent AVX512F embeded rounding
317 [(ROUND_NEAREST_INT 0)
325 ;; Constants to represent pcomtrue/pcomfalse variants
335 ;; Constants used in the XOP pperm instruction
337 [(PPERM_SRC 0x00) /* copy source */
338 (PPERM_INVERT 0x20) /* invert source */
339 (PPERM_REVERSE 0x40) /* bit reverse source */
340 (PPERM_REV_INV 0x60) /* bit reverse & invert src */
341 (PPERM_ZERO 0x80) /* all 0's */
342 (PPERM_ONES 0xa0) /* all 1's */
343 (PPERM_SIGN 0xc0) /* propagate sign bit */
344 (PPERM_INV_SIGN 0xe0) /* invert & propagate sign */
345 (PPERM_SRC1 0x00) /* use first source byte */
346 (PPERM_SRC2 0x10) /* use second source byte */
349 ;; Registers by name.
432 (FIRST_PSEUDO_REG 81)
435 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
438 ;; In C guard expressions, put expressions which may be compile-time
439 ;; constants first. This allows for better optimization. For
440 ;; example, write "TARGET_64BIT && reload_completed", not
441 ;; "reload_completed && TARGET_64BIT".
445 (define_attr "cpu" "none,pentium,pentiumpro,geode,k6,athlon,k8,core2,nehalem,
446 atom,slm,glm,haswell,generic,amdfam10,bdver1,bdver2,bdver3,
447 bdver4,btver2,znver1"
448 (const (symbol_ref "ix86_schedule")))
450 ;; A basic instruction type. Refinements due to arguments to be
451 ;; provided in other attributes.
454 alu,alu1,negnot,imov,imovx,lea,
455 incdec,ishift,ishiftx,ishift1,rotate,rotatex,rotate1,
456 imul,imulx,idiv,icmp,test,ibr,setcc,icmov,
457 push,pop,call,callv,leave,
459 fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,
460 fxch,fistp,fisttp,frndint,
461 sse,ssemov,sseadd,sseadd1,sseiadd,sseiadd1,
462 ssemul,sseimul,ssediv,sselog,sselog1,
463 sseishft,sseishft1,ssecmp,ssecomi,
464 ssecvt,ssecvt1,sseicvt,sseins,
465 sseshuf,sseshuf1,ssemuladd,sse4arg,
467 mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft,
468 mpxmov,mpxmk,mpxchk,mpxld,mpxst"
469 (const_string "other"))
471 ;; Main data type used by the insn
473 "unknown,none,QI,HI,SI,DI,TI,OI,XI,SF,DF,XF,TF,V16SF,V8SF,V4DF,V4SF,
475 (const_string "unknown"))
477 ;; The CPU unit operations uses.
478 (define_attr "unit" "integer,i387,sse,mmx,unknown"
479 (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,
480 fxch,fistp,fisttp,frndint")
481 (const_string "i387")
482 (eq_attr "type" "sse,ssemov,sseadd,sseadd1,sseiadd,sseiadd1,
483 ssemul,sseimul,ssediv,sselog,sselog1,
484 sseishft,sseishft1,ssecmp,ssecomi,
485 ssecvt,ssecvt1,sseicvt,sseins,
486 sseshuf,sseshuf1,ssemuladd,sse4arg,mskmov")
488 (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
490 (eq_attr "type" "other")
491 (const_string "unknown")]
492 (const_string "integer")))
494 ;; The (bounding maximum) length of an instruction immediate.
495 (define_attr "length_immediate" ""
496 (cond [(eq_attr "type" "incdec,setcc,icmov,str,lea,other,multi,idiv,leave,
497 bitmanip,imulx,msklog,mskmov,mpxmk,mpxmov,mpxchk,
500 (eq_attr "unit" "i387,sse,mmx")
502 (eq_attr "type" "alu,alu1,negnot,imovx,ishift,ishiftx,ishift1,
503 rotate,rotatex,rotate1,imul,icmp,push,pop")
504 (symbol_ref "ix86_attr_length_immediate_default (insn, true)")
505 (eq_attr "type" "imov,test")
506 (symbol_ref "ix86_attr_length_immediate_default (insn, false)")
507 (eq_attr "type" "call")
508 (if_then_else (match_operand 0 "constant_call_address_operand")
511 (eq_attr "type" "callv")
512 (if_then_else (match_operand 1 "constant_call_address_operand")
515 ;; We don't know the size before shorten_branches. Expect
516 ;; the instruction to fit for better scheduling.
517 (eq_attr "type" "ibr")
520 (symbol_ref "/* Update immediate_length and other attributes! */
521 gcc_unreachable (),1")))
523 ;; The (bounding maximum) length of an instruction address.
524 (define_attr "length_address" ""
525 (cond [(eq_attr "type" "str,other,multi,fxch")
527 (and (eq_attr "type" "call")
528 (match_operand 0 "constant_call_address_operand"))
530 (and (eq_attr "type" "callv")
531 (match_operand 1 "constant_call_address_operand"))
534 (symbol_ref "ix86_attr_length_address_default (insn)")))
536 ;; Set when length prefix is used.
537 (define_attr "prefix_data16" ""
538 (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
540 (eq_attr "mode" "HI")
542 (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF,TI"))
547 ;; Set when string REP prefix is used.
548 (define_attr "prefix_rep" ""
549 (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
551 (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
556 ;; Set when 0f opcode prefix is used.
557 (define_attr "prefix_0f" ""
559 (ior (eq_attr "type" "imovx,setcc,icmov,bitmanip,msklog,mskmov,
560 mpxmk,mpxmov,mpxchk,mpxld,mpxst")
561 (eq_attr "unit" "sse,mmx"))
565 ;; Set when REX opcode prefix is used.
566 (define_attr "prefix_rex" ""
567 (cond [(not (match_test "TARGET_64BIT"))
569 (and (eq_attr "mode" "DI")
570 (and (eq_attr "type" "!push,pop,call,callv,leave,ibr")
571 (eq_attr "unit" "!mmx")))
573 (and (eq_attr "mode" "QI")
574 (match_test "x86_extended_QIreg_mentioned_p (insn)"))
576 (match_test "x86_extended_reg_mentioned_p (insn)")
578 (and (eq_attr "type" "imovx")
579 (match_operand:QI 1 "ext_QIreg_operand"))
584 ;; There are also additional prefixes in 3DNOW, SSSE3.
585 ;; ssemuladd,sse4arg default to 0f24/0f25 and DREX byte,
586 ;; sseiadd1,ssecvt1 to 0f7a with no DREX byte.
587 ;; 3DNOW has 0f0f prefix, SSSE3 and SSE4_{1,2} 0f38/0f3a.
588 (define_attr "prefix_extra" ""
589 (cond [(eq_attr "type" "ssemuladd,sse4arg")
591 (eq_attr "type" "sseiadd1,ssecvt1")
596 ;; Prefix used: original, VEX or maybe VEX.
597 (define_attr "prefix" "orig,vex,maybe_vex,evex,maybe_evex"
598 (cond [(eq_attr "mode" "OI,V8SF,V4DF")
600 (eq_attr "mode" "XI,V16SF,V8DF")
601 (const_string "evex")
603 (const_string "orig")))
605 ;; VEX W bit is used.
606 (define_attr "prefix_vex_w" "" (const_int 0))
608 ;; The length of VEX prefix
609 ;; Only instructions with 0f prefix can have 2 byte VEX prefix,
610 ;; 0f38/0f3a prefixes can't. In i386.md 0f3[8a] is
611 ;; still prefix_0f 1, with prefix_extra 1.
612 (define_attr "length_vex" ""
613 (if_then_else (and (eq_attr "prefix_0f" "1")
614 (eq_attr "prefix_extra" "0"))
615 (if_then_else (eq_attr "prefix_vex_w" "1")
616 (symbol_ref "ix86_attr_length_vex_default (insn, true, true)")
617 (symbol_ref "ix86_attr_length_vex_default (insn, true, false)"))
618 (if_then_else (eq_attr "prefix_vex_w" "1")
619 (symbol_ref "ix86_attr_length_vex_default (insn, false, true)")
620 (symbol_ref "ix86_attr_length_vex_default (insn, false, false)"))))
622 ;; 4-bytes evex prefix and 1 byte opcode.
623 (define_attr "length_evex" "" (const_int 5))
625 ;; Set when modrm byte is used.
626 (define_attr "modrm" ""
627 (cond [(eq_attr "type" "str,leave")
629 (eq_attr "unit" "i387")
631 (and (eq_attr "type" "incdec")
632 (and (not (match_test "TARGET_64BIT"))
633 (ior (match_operand:SI 1 "register_operand")
634 (match_operand:HI 1 "register_operand"))))
636 (and (eq_attr "type" "push")
637 (not (match_operand 1 "memory_operand")))
639 (and (eq_attr "type" "pop")
640 (not (match_operand 0 "memory_operand")))
642 (and (eq_attr "type" "imov")
643 (and (not (eq_attr "mode" "DI"))
644 (ior (and (match_operand 0 "register_operand")
645 (match_operand 1 "immediate_operand"))
646 (ior (and (match_operand 0 "ax_reg_operand")
647 (match_operand 1 "memory_displacement_only_operand"))
648 (and (match_operand 0 "memory_displacement_only_operand")
649 (match_operand 1 "ax_reg_operand"))))))
651 (and (eq_attr "type" "call")
652 (match_operand 0 "constant_call_address_operand"))
654 (and (eq_attr "type" "callv")
655 (match_operand 1 "constant_call_address_operand"))
657 (and (eq_attr "type" "alu,alu1,icmp,test")
658 (match_operand 0 "ax_reg_operand"))
659 (symbol_ref "(get_attr_length_immediate (insn) <= (get_attr_mode (insn) != MODE_QI))")
663 (define_attr "modrm_class" "none,incdec,op0,op01,op02,pushpop,unknown"
664 (cond [(eq_attr "modrm" "0")
665 (const_string "none")
666 (eq_attr "type" "alu,imul,ishift")
667 (const_string "op02")
668 (eq_attr "type" "imov,imovx,lea,alu1,icmp")
669 (const_string "op01")
670 (eq_attr "type" "incdec")
671 (const_string "incdec")
672 (eq_attr "type" "push,pop")
673 (const_string "pushpop")]
674 (const_string "unknown")))
676 ;; The (bounding maximum) length of an instruction in bytes.
677 ;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
678 ;; Later we may want to split them and compute proper length as for
680 (define_attr "length" ""
681 (cond [(eq_attr "type" "other,multi,fistp,frndint")
683 (eq_attr "type" "fcmp")
685 (eq_attr "unit" "i387")
687 (plus (attr "prefix_data16")
688 (attr "length_address")))
689 (ior (eq_attr "prefix" "evex")
690 (and (ior (eq_attr "prefix" "maybe_evex")
691 (eq_attr "prefix" "maybe_vex"))
692 (match_test "TARGET_AVX512F")))
693 (plus (attr "length_evex")
694 (plus (attr "length_immediate")
696 (attr "length_address"))))
697 (ior (eq_attr "prefix" "vex")
698 (and (ior (eq_attr "prefix" "maybe_vex")
699 (eq_attr "prefix" "maybe_evex"))
700 (match_test "TARGET_AVX")))
701 (plus (attr "length_vex")
702 (plus (attr "length_immediate")
704 (attr "length_address"))))]
705 (plus (plus (attr "modrm")
706 (plus (attr "prefix_0f")
707 (plus (attr "prefix_rex")
708 (plus (attr "prefix_extra")
710 (plus (attr "prefix_rep")
711 (plus (attr "prefix_data16")
712 (plus (attr "length_immediate")
713 (attr "length_address")))))))
715 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
716 ;; `store' if there is a simple memory reference therein, or `unknown'
717 ;; if the instruction is complex.
719 (define_attr "memory" "none,load,store,both,unknown"
720 (cond [(eq_attr "type" "other,multi,str,lwp")
721 (const_string "unknown")
722 (eq_attr "type" "lea,fcmov,fpspc,mpxmk,mpxchk")
723 (const_string "none")
724 (eq_attr "type" "fistp,leave")
725 (const_string "both")
726 (eq_attr "type" "frndint")
727 (const_string "load")
728 (eq_attr "type" "mpxld")
729 (const_string "load")
730 (eq_attr "type" "mpxst")
731 (const_string "store")
732 (eq_attr "type" "push")
733 (if_then_else (match_operand 1 "memory_operand")
734 (const_string "both")
735 (const_string "store"))
736 (eq_attr "type" "pop")
737 (if_then_else (match_operand 0 "memory_operand")
738 (const_string "both")
739 (const_string "load"))
740 (eq_attr "type" "setcc")
741 (if_then_else (match_operand 0 "memory_operand")
742 (const_string "store")
743 (const_string "none"))
744 (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
745 (if_then_else (ior (match_operand 0 "memory_operand")
746 (match_operand 1 "memory_operand"))
747 (const_string "load")
748 (const_string "none"))
749 (eq_attr "type" "ibr")
750 (if_then_else (match_operand 0 "memory_operand")
751 (const_string "load")
752 (const_string "none"))
753 (eq_attr "type" "call")
754 (if_then_else (match_operand 0 "constant_call_address_operand")
755 (const_string "none")
756 (const_string "load"))
757 (eq_attr "type" "callv")
758 (if_then_else (match_operand 1 "constant_call_address_operand")
759 (const_string "none")
760 (const_string "load"))
761 (and (eq_attr "type" "alu1,negnot,ishift1,rotate1,sselog1,sseshuf1")
762 (match_operand 1 "memory_operand"))
763 (const_string "both")
764 (and (match_operand 0 "memory_operand")
765 (match_operand 1 "memory_operand"))
766 (const_string "both")
767 (match_operand 0 "memory_operand")
768 (const_string "store")
769 (match_operand 1 "memory_operand")
770 (const_string "load")
772 "!alu1,negnot,ishift1,rotate1,
773 imov,imovx,icmp,test,bitmanip,
775 sse,ssemov,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,
776 sselog1,sseshuf1,sseadd1,sseiadd1,sseishft1,
777 mmx,mmxmov,mmxcmp,mmxcvt,mskmov,msklog,mpxmov")
778 (match_operand 2 "memory_operand"))
779 (const_string "load")
780 (and (eq_attr "type" "icmov,ssemuladd,sse4arg")
781 (match_operand 3 "memory_operand"))
782 (const_string "load")
784 (const_string "none")))
786 ;; Indicates if an instruction has both an immediate and a displacement.
788 (define_attr "imm_disp" "false,true,unknown"
789 (cond [(eq_attr "type" "other,multi")
790 (const_string "unknown")
791 (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
792 (and (match_operand 0 "memory_displacement_operand")
793 (match_operand 1 "immediate_operand")))
794 (const_string "true")
795 (and (eq_attr "type" "alu,ishift,ishiftx,rotate,rotatex,imul,idiv")
796 (and (match_operand 0 "memory_displacement_operand")
797 (match_operand 2 "immediate_operand")))
798 (const_string "true")
800 (const_string "false")))
802 ;; Indicates if an FP operation has an integer source.
804 (define_attr "fp_int_src" "false,true"
805 (const_string "false"))
807 ;; Defines rounding mode of an FP operation.
809 (define_attr "i387_cw" "trunc,floor,ceil,mask_pm,uninitialized,any"
810 (const_string "any"))
812 ;; Define attribute to classify add/sub insns that consumes carry flag (CF)
813 (define_attr "use_carry" "0,1" (const_string "0"))
815 ;; Define attribute to indicate unaligned ssemov insns
816 (define_attr "movu" "0,1" (const_string "0"))
818 ;; Used to control the "enabled" attribute on a per-instruction basis.
819 (define_attr "isa" "base,x64,x64_sse2,x64_sse4,x64_sse4_noavx,x64_avx,nox64,
820 sse2,sse2_noavx,sse3,sse4,sse4_noavx,avx,noavx,
821 avx2,noavx2,bmi,bmi2,fma4,fma,avx512f,noavx512f,
822 avx512bw,noavx512bw,avx512dq,noavx512dq,
823 avx512vl,noavx512vl,x64_avx512dq,x64_avx512bw"
824 (const_string "base"))
826 (define_attr "enabled" ""
827 (cond [(eq_attr "isa" "x64") (symbol_ref "TARGET_64BIT")
828 (eq_attr "isa" "x64_sse2")
829 (symbol_ref "TARGET_64BIT && TARGET_SSE2")
830 (eq_attr "isa" "x64_sse4")
831 (symbol_ref "TARGET_64BIT && TARGET_SSE4_1")
832 (eq_attr "isa" "x64_sse4_noavx")
833 (symbol_ref "TARGET_64BIT && TARGET_SSE4_1 && !TARGET_AVX")
834 (eq_attr "isa" "x64_avx")
835 (symbol_ref "TARGET_64BIT && TARGET_AVX")
836 (eq_attr "isa" "x64_avx512dq")
837 (symbol_ref "TARGET_64BIT && TARGET_AVX512DQ")
838 (eq_attr "isa" "x64_avx512bw")
839 (symbol_ref "TARGET_64BIT && TARGET_AVX512BW")
840 (eq_attr "isa" "nox64") (symbol_ref "!TARGET_64BIT")
841 (eq_attr "isa" "sse2") (symbol_ref "TARGET_SSE2")
842 (eq_attr "isa" "sse2_noavx")
843 (symbol_ref "TARGET_SSE2 && !TARGET_AVX")
844 (eq_attr "isa" "sse3") (symbol_ref "TARGET_SSE3")
845 (eq_attr "isa" "sse4") (symbol_ref "TARGET_SSE4_1")
846 (eq_attr "isa" "sse4_noavx")
847 (symbol_ref "TARGET_SSE4_1 && !TARGET_AVX")
848 (eq_attr "isa" "avx") (symbol_ref "TARGET_AVX")
849 (eq_attr "isa" "noavx") (symbol_ref "!TARGET_AVX")
850 (eq_attr "isa" "avx2") (symbol_ref "TARGET_AVX2")
851 (eq_attr "isa" "noavx2") (symbol_ref "!TARGET_AVX2")
852 (eq_attr "isa" "bmi") (symbol_ref "TARGET_BMI")
853 (eq_attr "isa" "bmi2") (symbol_ref "TARGET_BMI2")
854 (eq_attr "isa" "fma4") (symbol_ref "TARGET_FMA4")
855 (eq_attr "isa" "fma") (symbol_ref "TARGET_FMA")
856 (eq_attr "isa" "avx512f") (symbol_ref "TARGET_AVX512F")
857 (eq_attr "isa" "noavx512f") (symbol_ref "!TARGET_AVX512F")
858 (eq_attr "isa" "avx512bw") (symbol_ref "TARGET_AVX512BW")
859 (eq_attr "isa" "noavx512bw") (symbol_ref "!TARGET_AVX512BW")
860 (eq_attr "isa" "avx512dq") (symbol_ref "TARGET_AVX512DQ")
861 (eq_attr "isa" "noavx512dq") (symbol_ref "!TARGET_AVX512DQ")
862 (eq_attr "isa" "avx512vl") (symbol_ref "TARGET_AVX512VL")
863 (eq_attr "isa" "noavx512vl") (symbol_ref "!TARGET_AVX512VL")
867 (define_attr "preferred_for_size" "" (const_int 1))
868 (define_attr "preferred_for_speed" "" (const_int 1))
870 ;; Describe a user's asm statement.
871 (define_asm_attributes
872 [(set_attr "length" "128")
873 (set_attr "type" "multi")])
875 (define_code_iterator plusminus [plus minus])
877 (define_code_iterator sat_plusminus [ss_plus us_plus ss_minus us_minus])
879 (define_code_iterator multdiv [mult div])
881 ;; Base name for define_insn
882 (define_code_attr plusminus_insn
883 [(plus "add") (ss_plus "ssadd") (us_plus "usadd")
884 (minus "sub") (ss_minus "sssub") (us_minus "ussub")])
886 ;; Base name for insn mnemonic.
887 (define_code_attr plusminus_mnemonic
888 [(plus "add") (ss_plus "adds") (us_plus "addus")
889 (minus "sub") (ss_minus "subs") (us_minus "subus")])
890 (define_code_attr multdiv_mnemonic
891 [(mult "mul") (div "div")])
893 ;; Mark commutative operators as such in constraints.
894 (define_code_attr comm [(plus "%") (ss_plus "%") (us_plus "%")
895 (minus "") (ss_minus "") (us_minus "")])
897 ;; Mapping of max and min
898 (define_code_iterator maxmin [smax smin umax umin])
900 ;; Mapping of signed max and min
901 (define_code_iterator smaxmin [smax smin])
903 ;; Mapping of unsigned max and min
904 (define_code_iterator umaxmin [umax umin])
906 ;; Base name for integer and FP insn mnemonic
907 (define_code_attr maxmin_int [(smax "maxs") (smin "mins")
908 (umax "maxu") (umin "minu")])
909 (define_code_attr maxmin_float [(smax "max") (smin "min")])
911 (define_int_iterator IEEE_MAXMIN
915 (define_int_attr ieee_maxmin
916 [(UNSPEC_IEEE_MAX "max")
917 (UNSPEC_IEEE_MIN "min")])
919 ;; Mapping of logic operators
920 (define_code_iterator any_logic [and ior xor])
921 (define_code_iterator any_or [ior xor])
922 (define_code_iterator fpint_logic [and xor])
924 ;; Base name for insn mnemonic.
925 (define_code_attr logic [(and "and") (ior "or") (xor "xor")])
927 ;; Mapping of logic-shift operators
928 (define_code_iterator any_lshift [ashift lshiftrt])
930 ;; Mapping of shift-right operators
931 (define_code_iterator any_shiftrt [lshiftrt ashiftrt])
933 ;; Mapping of all shift operators
934 (define_code_iterator any_shift [ashift lshiftrt ashiftrt])
936 ;; Base name for define_insn
937 (define_code_attr shift_insn
938 [(ashift "ashl") (lshiftrt "lshr") (ashiftrt "ashr")])
940 ;; Base name for insn mnemonic.
941 (define_code_attr shift [(ashift "sll") (lshiftrt "shr") (ashiftrt "sar")])
942 (define_code_attr vshift [(ashift "sll") (lshiftrt "srl") (ashiftrt "sra")])
944 ;; Mapping of rotate operators
945 (define_code_iterator any_rotate [rotate rotatert])
947 ;; Base name for define_insn
948 (define_code_attr rotate_insn [(rotate "rotl") (rotatert "rotr")])
950 ;; Base name for insn mnemonic.
951 (define_code_attr rotate [(rotate "rol") (rotatert "ror")])
953 ;; Mapping of abs neg operators
954 (define_code_iterator absneg [abs neg])
956 ;; Base name for x87 insn mnemonic.
957 (define_code_attr absneg_mnemonic [(abs "abs") (neg "chs")])
959 ;; Used in signed and unsigned widening multiplications.
960 (define_code_iterator any_extend [sign_extend zero_extend])
962 ;; Prefix for insn menmonic.
963 (define_code_attr sgnprefix [(sign_extend "i") (zero_extend "")])
965 ;; Prefix for define_insn
966 (define_code_attr u [(sign_extend "") (zero_extend "u")])
967 (define_code_attr s [(sign_extend "s") (zero_extend "u")])
968 (define_code_attr u_bool [(sign_extend "false") (zero_extend "true")])
970 ;; Used in signed and unsigned truncations.
971 (define_code_iterator any_truncate [ss_truncate truncate us_truncate])
972 ;; Instruction suffix for truncations.
973 (define_code_attr trunsuffix [(ss_truncate "s") (truncate "") (us_truncate "us")])
975 ;; Used in signed and unsigned fix.
976 (define_code_iterator any_fix [fix unsigned_fix])
977 (define_code_attr fixsuffix [(fix "") (unsigned_fix "u")])
978 (define_code_attr fixunssuffix [(fix "") (unsigned_fix "uns")])
979 (define_code_attr fixprefix [(fix "s") (unsigned_fix "u")])
981 ;; Used in signed and unsigned float.
982 (define_code_iterator any_float [float unsigned_float])
983 (define_code_attr floatsuffix [(float "") (unsigned_float "u")])
984 (define_code_attr floatunssuffix [(float "") (unsigned_float "uns")])
985 (define_code_attr floatprefix [(float "s") (unsigned_float "u")])
987 ;; All integer modes.
988 (define_mode_iterator SWI1248x [QI HI SI DI])
990 ;; All integer modes without QImode.
991 (define_mode_iterator SWI248x [HI SI DI])
993 ;; All integer modes without QImode and HImode.
994 (define_mode_iterator SWI48x [SI DI])
996 ;; All integer modes without SImode and DImode.
997 (define_mode_iterator SWI12 [QI HI])
999 ;; All integer modes without DImode.
1000 (define_mode_iterator SWI124 [QI HI SI])
1002 ;; All integer modes without QImode and DImode.
1003 (define_mode_iterator SWI24 [HI SI])
1005 ;; Single word integer modes.
1006 (define_mode_iterator SWI [QI HI SI (DI "TARGET_64BIT")])
1008 ;; Single word integer modes without QImode.
1009 (define_mode_iterator SWI248 [HI SI (DI "TARGET_64BIT")])
1011 ;; Single word integer modes without QImode and HImode.
1012 (define_mode_iterator SWI48 [SI (DI "TARGET_64BIT")])
1014 ;; All math-dependant single and double word integer modes.
1015 (define_mode_iterator SDWIM [(QI "TARGET_QIMODE_MATH")
1016 (HI "TARGET_HIMODE_MATH")
1017 SI DI (TI "TARGET_64BIT")])
1019 ;; Math-dependant single word integer modes.
1020 (define_mode_iterator SWIM [(QI "TARGET_QIMODE_MATH")
1021 (HI "TARGET_HIMODE_MATH")
1022 SI (DI "TARGET_64BIT")])
1024 ;; Math-dependant integer modes without DImode.
1025 (define_mode_iterator SWIM124 [(QI "TARGET_QIMODE_MATH")
1026 (HI "TARGET_HIMODE_MATH")
1029 ;; Math-dependant integer modes with DImode.
1030 (define_mode_iterator SWIM1248x [(QI "TARGET_QIMODE_MATH")
1031 (HI "TARGET_HIMODE_MATH")
1032 SI (DI "(TARGET_STV && TARGET_SSE2) || TARGET_64BIT")])
1034 ;; Math-dependant single word integer modes without QImode.
1035 (define_mode_iterator SWIM248 [(HI "TARGET_HIMODE_MATH")
1036 SI (DI "TARGET_64BIT")])
1038 ;; Double word integer modes.
1039 (define_mode_iterator DWI [(DI "!TARGET_64BIT")
1040 (TI "TARGET_64BIT")])
1042 ;; GET_MODE_SIZE for selected modes. As GET_MODE_SIZE is not
1043 ;; compile time constant, it is faster to use <MODE_SIZE> than
1044 ;; GET_MODE_SIZE (<MODE>mode). For XFmode which depends on
1045 ;; command line options just use GET_MODE_SIZE macro.
1046 (define_mode_attr MODE_SIZE [(QI "1") (HI "2") (SI "4") (DI "8") (TI "16")
1047 (SF "4") (DF "8") (XF "GET_MODE_SIZE (XFmode)")
1048 (V16QI "16") (V32QI "32") (V64QI "64")
1049 (V8HI "16") (V16HI "32") (V32HI "64")
1050 (V4SI "16") (V8SI "32") (V16SI "64")
1051 (V2DI "16") (V4DI "32") (V8DI "64")
1052 (V1TI "16") (V2TI "32") (V4TI "64")
1053 (V2DF "16") (V4DF "32") (V8DF "64")
1054 (V4SF "16") (V8SF "32") (V16SF "64")])
1056 ;; Double word integer modes as mode attribute.
1057 (define_mode_attr DWI [(QI "HI") (HI "SI") (SI "DI") (DI "TI")])
1058 (define_mode_attr dwi [(QI "hi") (HI "si") (SI "di") (DI "ti")])
1060 ;; LEA mode corresponding to an integer mode
1061 (define_mode_attr LEAMODE [(QI "SI") (HI "SI") (SI "SI") (DI "DI")])
1063 ;; Half mode for double word integer modes.
1064 (define_mode_iterator DWIH [(SI "!TARGET_64BIT")
1065 (DI "TARGET_64BIT")])
1068 (define_mode_iterator BND [(BND32 "!TARGET_LP64")
1069 (BND64 "TARGET_LP64")])
1071 ;; Instruction suffix for integer modes.
1072 (define_mode_attr imodesuffix [(QI "b") (HI "w") (SI "l") (DI "q")])
1074 ;; Instruction suffix for masks.
1075 (define_mode_attr mskmodesuffix [(QI "b") (HI "w") (SI "d") (DI "q")])
1077 ;; Pointer size prefix for integer modes (Intel asm dialect)
1078 (define_mode_attr iptrsize [(QI "BYTE")
1083 ;; Register class for integer modes.
1084 (define_mode_attr r [(QI "q") (HI "r") (SI "r") (DI "r")])
1086 ;; Immediate operand constraint for integer modes.
1087 (define_mode_attr i [(QI "n") (HI "n") (SI "e") (DI "e")])
1089 ;; General operand constraint for word modes.
1090 (define_mode_attr g [(QI "qmn") (HI "rmn") (SI "rme") (DI "rme")])
1092 ;; Immediate operand constraint for double integer modes.
1093 (define_mode_attr di [(SI "nF") (DI "Wd")])
1095 ;; Immediate operand constraint for shifts.
1096 (define_mode_attr S [(QI "I") (HI "I") (SI "I") (DI "J") (TI "O")])
1098 ;; Print register name in the specified mode.
1099 (define_mode_attr k [(QI "b") (HI "w") (SI "k") (DI "q")])
1101 ;; General operand predicate for integer modes.
1102 (define_mode_attr general_operand
1103 [(QI "general_operand")
1104 (HI "general_operand")
1105 (SI "x86_64_general_operand")
1106 (DI "x86_64_general_operand")
1107 (TI "x86_64_general_operand")])
1109 ;; General operand predicate for integer modes, where for TImode
1110 ;; we need both words of the operand to be general operands.
1111 (define_mode_attr general_hilo_operand
1112 [(QI "general_operand")
1113 (HI "general_operand")
1114 (SI "x86_64_general_operand")
1115 (DI "x86_64_general_operand")
1116 (TI "x86_64_hilo_general_operand")])
1118 ;; General sign extend operand predicate for integer modes,
1119 ;; which disallows VOIDmode operands and thus it is suitable
1120 ;; for use inside sign_extend.
1121 (define_mode_attr general_sext_operand
1122 [(QI "sext_operand")
1124 (SI "x86_64_sext_operand")
1125 (DI "x86_64_sext_operand")])
1127 ;; General sign/zero extend operand predicate for integer modes.
1128 (define_mode_attr general_szext_operand
1129 [(QI "general_operand")
1130 (HI "general_operand")
1131 (SI "x86_64_szext_general_operand")
1132 (DI "x86_64_szext_general_operand")])
1134 ;; Immediate operand predicate for integer modes.
1135 (define_mode_attr immediate_operand
1136 [(QI "immediate_operand")
1137 (HI "immediate_operand")
1138 (SI "x86_64_immediate_operand")
1139 (DI "x86_64_immediate_operand")])
1141 ;; Nonmemory operand predicate for integer modes.
1142 (define_mode_attr nonmemory_operand
1143 [(QI "nonmemory_operand")
1144 (HI "nonmemory_operand")
1145 (SI "x86_64_nonmemory_operand")
1146 (DI "x86_64_nonmemory_operand")])
1148 ;; Operand predicate for shifts.
1149 (define_mode_attr shift_operand
1150 [(QI "nonimmediate_operand")
1151 (HI "nonimmediate_operand")
1152 (SI "nonimmediate_operand")
1153 (DI "shiftdi_operand")
1154 (TI "register_operand")])
1156 ;; Operand predicate for shift argument.
1157 (define_mode_attr shift_immediate_operand
1158 [(QI "const_1_to_31_operand")
1159 (HI "const_1_to_31_operand")
1160 (SI "const_1_to_31_operand")
1161 (DI "const_1_to_63_operand")])
1163 ;; Input operand predicate for arithmetic left shifts.
1164 (define_mode_attr ashl_input_operand
1165 [(QI "nonimmediate_operand")
1166 (HI "nonimmediate_operand")
1167 (SI "nonimmediate_operand")
1168 (DI "ashldi_input_operand")
1169 (TI "reg_or_pm1_operand")])
1171 ;; SSE and x87 SFmode and DFmode floating point modes
1172 (define_mode_iterator MODEF [SF DF])
1174 ;; All x87 floating point modes
1175 (define_mode_iterator X87MODEF [SF DF XF])
1177 ;; SSE instruction suffix for various modes
1178 (define_mode_attr ssemodesuffix
1179 [(SF "ss") (DF "sd")
1180 (V16SF "ps") (V8DF "pd")
1181 (V8SF "ps") (V4DF "pd")
1182 (V4SF "ps") (V2DF "pd")
1183 (V16QI "b") (V8HI "w") (V4SI "d") (V2DI "q")
1184 (V32QI "b") (V16HI "w") (V8SI "d") (V4DI "q")
1185 (V64QI "b") (V32HI "w") (V16SI "d") (V8DI "q")])
1187 ;; SSE vector suffix for floating point modes
1188 (define_mode_attr ssevecmodesuffix [(SF "ps") (DF "pd")])
1190 ;; SSE vector mode corresponding to a scalar mode
1191 (define_mode_attr ssevecmode
1192 [(QI "V16QI") (HI "V8HI") (SI "V4SI") (DI "V2DI") (SF "V4SF") (DF "V2DF")])
1193 (define_mode_attr ssevecmodelower
1194 [(QI "v16qi") (HI "v8hi") (SI "v4si") (DI "v2di") (SF "v4sf") (DF "v2df")])
1196 ;; AVX512F vector mode corresponding to a scalar mode
1197 (define_mode_attr avx512fvecmode
1198 [(QI "V64QI") (HI "V32HI") (SI "V16SI") (DI "V8DI") (SF "V16SF") (DF "V8DF")])
1200 ;; Instruction suffix for REX 64bit operators.
1201 (define_mode_attr rex64suffix [(SI "") (DI "{q}")])
1202 (define_mode_attr rex64namesuffix [(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")
1232 (include "core2.md")
1233 (include "haswell.md")
1236 ;; Operand and operator predicates and constraints
1238 (include "predicates.md")
1239 (include "constraints.md")
1242 ;; Compare and branch/compare and store instructions.
1244 (define_expand "cbranch<mode>4"
1245 [(set (reg:CC FLAGS_REG)
1246 (compare:CC (match_operand:SDWIM 1 "nonimmediate_operand")
1247 (match_operand:SDWIM 2 "<general_operand>")))
1248 (set (pc) (if_then_else
1249 (match_operator 0 "ordered_comparison_operator"
1250 [(reg:CC FLAGS_REG) (const_int 0)])
1251 (label_ref (match_operand 3))
1255 if (MEM_P (operands[1]) && MEM_P (operands[2]))
1256 operands[1] = force_reg (<MODE>mode, operands[1]);
1257 ix86_expand_branch (GET_CODE (operands[0]),
1258 operands[1], operands[2], operands[3]);
1262 (define_expand "cstore<mode>4"
1263 [(set (reg:CC FLAGS_REG)
1264 (compare:CC (match_operand:SWIM 2 "nonimmediate_operand")
1265 (match_operand:SWIM 3 "<general_operand>")))
1266 (set (match_operand:QI 0 "register_operand")
1267 (match_operator 1 "ordered_comparison_operator"
1268 [(reg:CC FLAGS_REG) (const_int 0)]))]
1271 if (MEM_P (operands[2]) && MEM_P (operands[3]))
1272 operands[2] = force_reg (<MODE>mode, operands[2]);
1273 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1274 operands[2], operands[3]);
1278 (define_expand "cmp<mode>_1"
1279 [(set (reg:CC FLAGS_REG)
1280 (compare:CC (match_operand:SWI48 0 "nonimmediate_operand")
1281 (match_operand:SWI48 1 "<general_operand>")))])
1283 (define_mode_iterator SWI1248_AVX512BWDQ2_64
1284 [(QI "TARGET_AVX512DQ") (HI "TARGET_AVX512DQ")
1285 (SI "TARGET_AVX512BW") (DI "TARGET_AVX512BW && TARGET_64BIT")])
1287 (define_insn "*cmp<mode>_ccz_1"
1288 [(set (reg FLAGS_REG)
1289 (compare (match_operand:SWI1248_AVX512BWDQ2_64 0
1290 "nonimmediate_operand" "<r>,?m<r>,$k")
1291 (match_operand:SWI1248_AVX512BWDQ2_64 1 "const0_operand")))]
1292 "ix86_match_ccmode (insn, CCZmode)"
1294 test{<imodesuffix>}\t%0, %0
1295 cmp{<imodesuffix>}\t{%1, %0|%0, %1}
1296 ktest<mskmodesuffix>\t%0, %0"
1297 [(set_attr "type" "test,icmp,msklog")
1298 (set_attr "length_immediate" "0,1,*")
1299 (set_attr "modrm_class" "op0,unknown,*")
1300 (set_attr "prefix" "*,*,vex")
1301 (set_attr "mode" "<MODE>")])
1303 (define_insn "*cmp<mode>_ccno_1"
1304 [(set (reg FLAGS_REG)
1305 (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>,?m<r>")
1306 (match_operand:SWI 1 "const0_operand")))]
1307 "ix86_match_ccmode (insn, CCNOmode)"
1309 test{<imodesuffix>}\t%0, %0
1310 cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1311 [(set_attr "type" "test,icmp")
1312 (set_attr "length_immediate" "0,1")
1313 (set_attr "modrm_class" "op0,unknown")
1314 (set_attr "mode" "<MODE>")])
1316 (define_insn "*cmp<mode>_1"
1317 [(set (reg FLAGS_REG)
1318 (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
1319 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m")))]
1320 "ix86_match_ccmode (insn, CCmode)"
1321 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1322 [(set_attr "type" "icmp")
1323 (set_attr "mode" "<MODE>")])
1325 (define_insn "*cmp<mode>_minus_1"
1326 [(set (reg FLAGS_REG)
1328 (minus:SWI (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
1329 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
1331 "ix86_match_ccmode (insn, CCGOCmode)"
1332 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1333 [(set_attr "type" "icmp")
1334 (set_attr "mode" "<MODE>")])
1336 (define_insn "*cmpqi_ext_1"
1337 [(set (reg FLAGS_REG)
1339 (match_operand:QI 0 "nonimmediate_operand" "QBc,m")
1342 (match_operand 1 "ext_register_operand" "Q,Q")
1344 (const_int 8)) 0)))]
1345 "ix86_match_ccmode (insn, CCmode)"
1346 "cmp{b}\t{%h1, %0|%0, %h1}"
1347 [(set_attr "isa" "*,nox64")
1348 (set_attr "type" "icmp")
1349 (set_attr "mode" "QI")])
1351 (define_insn "*cmpqi_ext_2"
1352 [(set (reg FLAGS_REG)
1356 (match_operand 0 "ext_register_operand" "Q")
1359 (match_operand:QI 1 "const0_operand")))]
1360 "ix86_match_ccmode (insn, CCNOmode)"
1362 [(set_attr "type" "test")
1363 (set_attr "length_immediate" "0")
1364 (set_attr "mode" "QI")])
1366 (define_expand "cmpqi_ext_3"
1367 [(set (reg:CC FLAGS_REG)
1371 (match_operand 0 "ext_register_operand")
1374 (match_operand:QI 1 "const_int_operand")))])
1376 (define_insn "*cmpqi_ext_3"
1377 [(set (reg FLAGS_REG)
1381 (match_operand 0 "ext_register_operand" "Q,Q")
1384 (match_operand:QI 1 "general_operand" "QnBc,m")))]
1385 "ix86_match_ccmode (insn, CCmode)"
1386 "cmp{b}\t{%1, %h0|%h0, %1}"
1387 [(set_attr "isa" "*,nox64")
1388 (set_attr "type" "icmp")
1389 (set_attr "mode" "QI")])
1391 (define_insn "*cmpqi_ext_4"
1392 [(set (reg FLAGS_REG)
1396 (match_operand 0 "ext_register_operand" "Q")
1401 (match_operand 1 "ext_register_operand" "Q")
1403 (const_int 8)) 0)))]
1404 "ix86_match_ccmode (insn, CCmode)"
1405 "cmp{b}\t{%h1, %h0|%h0, %h1}"
1406 [(set_attr "type" "icmp")
1407 (set_attr "mode" "QI")])
1409 ;; These implement float point compares.
1410 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
1411 ;; which would allow mix and match FP modes on the compares. Which is what
1412 ;; the old patterns did, but with many more of them.
1414 (define_expand "cbranchxf4"
1415 [(set (reg:CC FLAGS_REG)
1416 (compare:CC (match_operand:XF 1 "nonmemory_operand")
1417 (match_operand:XF 2 "nonmemory_operand")))
1418 (set (pc) (if_then_else
1419 (match_operator 0 "ix86_fp_comparison_operator"
1422 (label_ref (match_operand 3))
1426 ix86_expand_branch (GET_CODE (operands[0]),
1427 operands[1], operands[2], operands[3]);
1431 (define_expand "cstorexf4"
1432 [(set (reg:CC FLAGS_REG)
1433 (compare:CC (match_operand:XF 2 "nonmemory_operand")
1434 (match_operand:XF 3 "nonmemory_operand")))
1435 (set (match_operand:QI 0 "register_operand")
1436 (match_operator 1 "ix86_fp_comparison_operator"
1441 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1442 operands[2], operands[3]);
1446 (define_expand "cbranch<mode>4"
1447 [(set (reg:CC FLAGS_REG)
1448 (compare:CC (match_operand:MODEF 1 "cmp_fp_expander_operand")
1449 (match_operand:MODEF 2 "cmp_fp_expander_operand")))
1450 (set (pc) (if_then_else
1451 (match_operator 0 "ix86_fp_comparison_operator"
1454 (label_ref (match_operand 3))
1456 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1458 ix86_expand_branch (GET_CODE (operands[0]),
1459 operands[1], operands[2], operands[3]);
1463 (define_expand "cstore<mode>4"
1464 [(set (reg:CC FLAGS_REG)
1465 (compare:CC (match_operand:MODEF 2 "cmp_fp_expander_operand")
1466 (match_operand:MODEF 3 "cmp_fp_expander_operand")))
1467 (set (match_operand:QI 0 "register_operand")
1468 (match_operator 1 "ix86_fp_comparison_operator"
1471 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1473 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1474 operands[2], operands[3]);
1478 (define_expand "cbranchcc4"
1479 [(set (pc) (if_then_else
1480 (match_operator 0 "comparison_operator"
1481 [(match_operand 1 "flags_reg_operand")
1482 (match_operand 2 "const0_operand")])
1483 (label_ref (match_operand 3))
1487 ix86_expand_branch (GET_CODE (operands[0]),
1488 operands[1], operands[2], operands[3]);
1492 (define_expand "cstorecc4"
1493 [(set (match_operand:QI 0 "register_operand")
1494 (match_operator 1 "comparison_operator"
1495 [(match_operand 2 "flags_reg_operand")
1496 (match_operand 3 "const0_operand")]))]
1499 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1500 operands[2], operands[3]);
1505 ;; FP compares, step 1:
1506 ;; Set the FP condition codes.
1508 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
1509 ;; used to manage the reg stack popping would not be preserved.
1511 (define_insn "*cmp<mode>_0_i387"
1512 [(set (match_operand:HI 0 "register_operand" "=a")
1515 (match_operand:X87MODEF 1 "register_operand" "f")
1516 (match_operand:X87MODEF 2 "const0_operand"))]
1519 "* return output_fp_compare (insn, operands, false, false);"
1520 [(set_attr "type" "multi")
1521 (set_attr "unit" "i387")
1522 (set_attr "mode" "<MODE>")])
1524 (define_insn_and_split "*cmp<mode>_0_cc_i387"
1525 [(set (reg:CCFP FLAGS_REG)
1527 (match_operand:X87MODEF 1 "register_operand" "f")
1528 (match_operand:X87MODEF 2 "const0_operand")))
1529 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1530 "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE"
1532 "&& reload_completed"
1535 [(compare:CCFP (match_dup 1)(match_dup 2))]
1537 (set (reg:CC FLAGS_REG)
1538 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1540 [(set_attr "type" "multi")
1541 (set_attr "unit" "i387")
1542 (set_attr "mode" "<MODE>")])
1544 (define_insn "*cmpxf_i387"
1545 [(set (match_operand:HI 0 "register_operand" "=a")
1548 (match_operand:XF 1 "register_operand" "f")
1549 (match_operand:XF 2 "register_operand" "f"))]
1552 "* return output_fp_compare (insn, operands, false, false);"
1553 [(set_attr "type" "multi")
1554 (set_attr "unit" "i387")
1555 (set_attr "mode" "XF")])
1557 (define_insn_and_split "*cmpxf_cc_i387"
1558 [(set (reg:CCFP FLAGS_REG)
1560 (match_operand:XF 1 "register_operand" "f")
1561 (match_operand:XF 2 "register_operand" "f")))
1562 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1563 "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE"
1565 "&& reload_completed"
1568 [(compare:CCFP (match_dup 1)(match_dup 2))]
1570 (set (reg:CC FLAGS_REG)
1571 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1573 [(set_attr "type" "multi")
1574 (set_attr "unit" "i387")
1575 (set_attr "mode" "XF")])
1577 (define_insn "*cmp<mode>_i387"
1578 [(set (match_operand:HI 0 "register_operand" "=a")
1581 (match_operand:MODEF 1 "register_operand" "f")
1582 (match_operand:MODEF 2 "nonimmediate_operand" "fm"))]
1585 "* return output_fp_compare (insn, operands, false, false);"
1586 [(set_attr "type" "multi")
1587 (set_attr "unit" "i387")
1588 (set_attr "mode" "<MODE>")])
1590 (define_insn_and_split "*cmp<mode>_cc_i387"
1591 [(set (reg:CCFP FLAGS_REG)
1593 (match_operand:MODEF 1 "register_operand" "f")
1594 (match_operand:MODEF 2 "nonimmediate_operand" "fm")))
1595 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1596 "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE"
1598 "&& reload_completed"
1601 [(compare:CCFP (match_dup 1)(match_dup 2))]
1603 (set (reg:CC FLAGS_REG)
1604 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1606 [(set_attr "type" "multi")
1607 (set_attr "unit" "i387")
1608 (set_attr "mode" "<MODE>")])
1610 (define_insn "*cmpu<mode>_i387"
1611 [(set (match_operand:HI 0 "register_operand" "=a")
1615 (match_operand:X87MODEF 1 "register_operand" "f")
1616 (match_operand:X87MODEF 2 "register_operand" "f"))]
1620 "* return output_fp_compare (insn, operands, false, true);"
1621 [(set_attr "type" "multi")
1622 (set_attr "unit" "i387")
1623 (set_attr "mode" "<MODE>")])
1625 (define_insn_and_split "*cmpu<mode>_cc_i387"
1626 [(set (reg:CCFP FLAGS_REG)
1629 (match_operand:X87MODEF 1 "register_operand" "f")
1630 (match_operand:X87MODEF 2 "register_operand" "f"))]
1632 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1633 "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE"
1635 "&& reload_completed"
1639 [(compare:CCFP (match_dup 1)(match_dup 2))]
1642 (set (reg:CC FLAGS_REG)
1643 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1645 [(set_attr "type" "multi")
1646 (set_attr "unit" "i387")
1647 (set_attr "mode" "<MODE>")])
1649 (define_insn "*cmp<X87MODEF:mode>_<SWI24:mode>_i387"
1650 [(set (match_operand:HI 0 "register_operand" "=a")
1653 (match_operand:X87MODEF 1 "register_operand" "f")
1655 (match_operand:SWI24 2 "memory_operand" "m")))]
1658 && (TARGET_USE_<SWI24:MODE>MODE_FIOP
1659 || optimize_function_for_size_p (cfun))"
1660 "* return output_fp_compare (insn, operands, false, false);"
1661 [(set_attr "type" "multi")
1662 (set_attr "unit" "i387")
1663 (set_attr "fp_int_src" "true")
1664 (set_attr "mode" "<SWI24:MODE>")])
1666 (define_insn_and_split "*cmp<X87MODEF:mode>_<SWI24:mode>_cc_i387"
1667 [(set (reg:CCFP FLAGS_REG)
1669 (match_operand:X87MODEF 1 "register_operand" "f")
1671 (match_operand:SWI24 2 "memory_operand" "m"))))
1672 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1673 "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE
1674 && (TARGET_USE_<SWI24:MODE>MODE_FIOP
1675 || optimize_function_for_size_p (cfun))"
1677 "&& reload_completed"
1682 (float:X87MODEF (match_dup 2)))]
1684 (set (reg:CC FLAGS_REG)
1685 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1687 [(set_attr "type" "multi")
1688 (set_attr "unit" "i387")
1689 (set_attr "fp_int_src" "true")
1690 (set_attr "mode" "<SWI24:MODE>")])
1692 ;; FP compares, step 2
1693 ;; Move the fpsw to ax.
1695 (define_insn "x86_fnstsw_1"
1696 [(set (match_operand:HI 0 "register_operand" "=a")
1697 (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
1700 [(set_attr "length" "2")
1701 (set_attr "mode" "SI")
1702 (set_attr "unit" "i387")])
1704 ;; FP compares, step 3
1705 ;; Get ax into flags, general case.
1707 (define_insn "x86_sahf_1"
1708 [(set (reg:CC FLAGS_REG)
1709 (unspec:CC [(match_operand:HI 0 "register_operand" "a")]
1713 #ifndef HAVE_AS_IX86_SAHF
1715 return ASM_BYTE "0x9e";
1720 [(set_attr "length" "1")
1721 (set_attr "athlon_decode" "vector")
1722 (set_attr "amdfam10_decode" "direct")
1723 (set_attr "bdver1_decode" "direct")
1724 (set_attr "mode" "SI")])
1726 ;; Pentium Pro can do steps 1 through 3 in one go.
1727 ;; (these instructions set flags directly)
1729 (define_subst_attr "unord" "unord_subst" "" "u")
1730 (define_subst_attr "unordered" "unord_subst" "false" "true")
1732 (define_subst "unord_subst"
1733 [(set (match_operand:CCFP 0)
1734 (match_operand:CCFP 1))]
1741 (define_insn "*cmpi<unord><MODEF:mode>"
1742 [(set (reg:CCFP FLAGS_REG)
1744 (match_operand:MODEF 0 "register_operand" "f,v")
1745 (match_operand:MODEF 1 "register_ssemem_operand" "f,vm")))]
1746 "(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
1747 || (TARGET_80387 && TARGET_CMOVE)"
1749 * return output_fp_compare (insn, operands, true, <unordered>);
1750 %v<unord>comi<MODEF:ssemodesuffix>\t{%1, %0|%0, %1}"
1751 [(set_attr "type" "fcmp,ssecomi")
1752 (set_attr "prefix" "orig,maybe_vex")
1753 (set_attr "mode" "<MODEF:MODE>")
1754 (set_attr "prefix_rep" "*,0")
1755 (set (attr "prefix_data16")
1756 (cond [(eq_attr "alternative" "0")
1758 (eq_attr "mode" "DF")
1761 (const_string "0")))
1762 (set_attr "athlon_decode" "vector")
1763 (set_attr "amdfam10_decode" "direct")
1764 (set_attr "bdver1_decode" "double")
1765 (set_attr "znver1_decode" "double")
1766 (set (attr "enabled")
1768 (match_test ("SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"))
1770 (eq_attr "alternative" "0")
1771 (symbol_ref "TARGET_MIX_SSE_I387")
1772 (symbol_ref "true"))
1774 (eq_attr "alternative" "0")
1776 (symbol_ref "false"))))])
1778 (define_insn "*cmpi<unord>xf_i387"
1779 [(set (reg:CCFP FLAGS_REG)
1781 (match_operand:XF 0 "register_operand" "f")
1782 (match_operand:XF 1 "register_operand" "f")))]
1783 "TARGET_80387 && TARGET_CMOVE"
1784 "* return output_fp_compare (insn, operands, true, <unordered>);"
1785 [(set_attr "type" "fcmp")
1786 (set_attr "mode" "XF")
1787 (set_attr "athlon_decode" "vector")
1788 (set_attr "amdfam10_decode" "direct")
1789 (set_attr "bdver1_decode" "double")
1790 (set_attr "znver1_decode" "double")])
1792 ;; Push/pop instructions.
1794 (define_insn "*push<mode>2"
1795 [(set (match_operand:DWI 0 "push_operand" "=<")
1796 (match_operand:DWI 1 "general_no_elim_operand" "riF*o"))]
1799 [(set_attr "type" "multi")
1800 (set_attr "mode" "<MODE>")])
1803 [(set (match_operand:DWI 0 "push_operand")
1804 (match_operand:DWI 1 "general_gr_operand"))]
1807 "ix86_split_long_move (operands); DONE;")
1809 (define_insn "*pushdi2_rex64"
1810 [(set (match_operand:DI 0 "push_operand" "=<,!<")
1811 (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1816 [(set_attr "type" "push,multi")
1817 (set_attr "mode" "DI")])
1819 ;; Convert impossible pushes of immediate to existing instructions.
1820 ;; First try to get scratch register and go through it. In case this
1821 ;; fails, push sign extended lower part first and then overwrite
1822 ;; upper part by 32bit move.
1824 [(match_scratch:DI 2 "r")
1825 (set (match_operand:DI 0 "push_operand")
1826 (match_operand:DI 1 "immediate_operand"))]
1827 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1828 && !x86_64_immediate_operand (operands[1], DImode)"
1829 [(set (match_dup 2) (match_dup 1))
1830 (set (match_dup 0) (match_dup 2))])
1832 ;; We need to define this as both peepholer and splitter for case
1833 ;; peephole2 pass is not run.
1834 ;; "&& 1" is needed to keep it from matching the previous pattern.
1836 [(set (match_operand:DI 0 "push_operand")
1837 (match_operand:DI 1 "immediate_operand"))]
1838 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1839 && !x86_64_immediate_operand (operands[1], DImode) && 1"
1840 [(set (match_dup 0) (match_dup 1))
1841 (set (match_dup 2) (match_dup 3))]
1843 split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1845 operands[1] = gen_lowpart (DImode, operands[2]);
1846 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (Pmode, stack_pointer_rtx,
1851 [(set (match_operand:DI 0 "push_operand")
1852 (match_operand:DI 1 "immediate_operand"))]
1853 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
1854 ? epilogue_completed : reload_completed)
1855 && !symbolic_operand (operands[1], DImode)
1856 && !x86_64_immediate_operand (operands[1], DImode)"
1857 [(set (match_dup 0) (match_dup 1))
1858 (set (match_dup 2) (match_dup 3))]
1860 split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1862 operands[1] = gen_lowpart (DImode, operands[2]);
1863 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (Pmode, stack_pointer_rtx,
1867 (define_insn "*pushsi2"
1868 [(set (match_operand:SI 0 "push_operand" "=<")
1869 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1872 [(set_attr "type" "push")
1873 (set_attr "mode" "SI")])
1875 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1876 ;; "push a byte/word". But actually we use pushl, which has the effect
1877 ;; of rounding the amount pushed up to a word.
1879 ;; For TARGET_64BIT we always round up to 8 bytes.
1880 (define_insn "*push<mode>2_rex64"
1881 [(set (match_operand:SWI124 0 "push_operand" "=X")
1882 (match_operand:SWI124 1 "nonmemory_no_elim_operand" "r<i>"))]
1885 [(set_attr "type" "push")
1886 (set_attr "mode" "DI")])
1888 (define_insn "*push<mode>2"
1889 [(set (match_operand:SWI12 0 "push_operand" "=X")
1890 (match_operand:SWI12 1 "nonmemory_no_elim_operand" "rn"))]
1893 [(set_attr "type" "push")
1894 (set_attr "mode" "SI")])
1896 (define_insn "*push<mode>2_prologue"
1897 [(set (match_operand:W 0 "push_operand" "=<")
1898 (match_operand:W 1 "general_no_elim_operand" "r<i>*m"))
1899 (clobber (mem:BLK (scratch)))]
1901 "push{<imodesuffix>}\t%1"
1902 [(set_attr "type" "push")
1903 (set_attr "mode" "<MODE>")])
1905 (define_insn "*pop<mode>1"
1906 [(set (match_operand:W 0 "nonimmediate_operand" "=r*m")
1907 (match_operand:W 1 "pop_operand" ">"))]
1909 "pop{<imodesuffix>}\t%0"
1910 [(set_attr "type" "pop")
1911 (set_attr "mode" "<MODE>")])
1913 (define_insn "*pop<mode>1_epilogue"
1914 [(set (match_operand:W 0 "nonimmediate_operand" "=r*m")
1915 (match_operand:W 1 "pop_operand" ">"))
1916 (clobber (mem:BLK (scratch)))]
1918 "pop{<imodesuffix>}\t%0"
1919 [(set_attr "type" "pop")
1920 (set_attr "mode" "<MODE>")])
1922 (define_insn "*pushfl<mode>2"
1923 [(set (match_operand:W 0 "push_operand" "=<")
1924 (match_operand:W 1 "flags_reg_operand"))]
1926 "pushf{<imodesuffix>}"
1927 [(set_attr "type" "push")
1928 (set_attr "mode" "<MODE>")])
1930 (define_insn "*popfl<mode>1"
1931 [(set (match_operand:W 0 "flags_reg_operand")
1932 (match_operand:W 1 "pop_operand" ">"))]
1934 "popf{<imodesuffix>}"
1935 [(set_attr "type" "pop")
1936 (set_attr "mode" "<MODE>")])
1939 ;; Reload patterns to support multi-word load/store
1940 ;; with non-offsetable address.
1941 (define_expand "reload_noff_store"
1942 [(parallel [(match_operand 0 "memory_operand" "=m")
1943 (match_operand 1 "register_operand" "r")
1944 (match_operand:DI 2 "register_operand" "=&r")])]
1947 rtx mem = operands[0];
1948 rtx addr = XEXP (mem, 0);
1950 emit_move_insn (operands[2], addr);
1951 mem = replace_equiv_address_nv (mem, operands[2]);
1953 emit_insn (gen_rtx_SET (mem, operands[1]));
1957 (define_expand "reload_noff_load"
1958 [(parallel [(match_operand 0 "register_operand" "=r")
1959 (match_operand 1 "memory_operand" "m")
1960 (match_operand:DI 2 "register_operand" "=r")])]
1963 rtx mem = operands[1];
1964 rtx addr = XEXP (mem, 0);
1966 emit_move_insn (operands[2], addr);
1967 mem = replace_equiv_address_nv (mem, operands[2]);
1969 emit_insn (gen_rtx_SET (operands[0], mem));
1973 ;; Move instructions.
1975 (define_expand "movxi"
1976 [(set (match_operand:XI 0 "nonimmediate_operand")
1977 (match_operand:XI 1 "general_operand"))]
1979 "ix86_expand_vector_move (XImode, operands); DONE;")
1981 (define_expand "movoi"
1982 [(set (match_operand:OI 0 "nonimmediate_operand")
1983 (match_operand:OI 1 "general_operand"))]
1985 "ix86_expand_vector_move (OImode, operands); DONE;")
1987 (define_expand "movti"
1988 [(set (match_operand:TI 0 "nonimmediate_operand")
1989 (match_operand:TI 1 "general_operand"))]
1990 "TARGET_64BIT || TARGET_SSE"
1993 ix86_expand_move (TImode, operands);
1995 ix86_expand_vector_move (TImode, operands);
1999 ;; This expands to what emit_move_complex would generate if we didn't
2000 ;; have a movti pattern. Having this avoids problems with reload on
2001 ;; 32-bit targets when SSE is present, but doesn't seem to be harmful
2002 ;; to have around all the time.
2003 (define_expand "movcdi"
2004 [(set (match_operand:CDI 0 "nonimmediate_operand")
2005 (match_operand:CDI 1 "general_operand"))]
2008 if (push_operand (operands[0], CDImode))
2009 emit_move_complex_push (CDImode, operands[0], operands[1]);
2011 emit_move_complex_parts (operands[0], operands[1]);
2015 (define_expand "mov<mode>"
2016 [(set (match_operand:SWI1248x 0 "nonimmediate_operand")
2017 (match_operand:SWI1248x 1 "general_operand"))]
2019 "ix86_expand_move (<MODE>mode, operands); DONE;")
2021 (define_insn "*mov<mode>_xor"
2022 [(set (match_operand:SWI48 0 "register_operand" "=r")
2023 (match_operand:SWI48 1 "const0_operand"))
2024 (clobber (reg:CC FLAGS_REG))]
2027 [(set_attr "type" "alu1")
2028 (set_attr "modrm_class" "op0")
2029 (set_attr "mode" "SI")
2030 (set_attr "length_immediate" "0")])
2032 (define_insn "*mov<mode>_or"
2033 [(set (match_operand:SWI48 0 "register_operand" "=r")
2034 (match_operand:SWI48 1 "constm1_operand"))
2035 (clobber (reg:CC FLAGS_REG))]
2037 "or{<imodesuffix>}\t{%1, %0|%0, %1}"
2038 [(set_attr "type" "alu1")
2039 (set_attr "mode" "<MODE>")
2040 (set_attr "length_immediate" "1")])
2042 (define_insn "*movxi_internal_avx512f"
2043 [(set (match_operand:XI 0 "nonimmediate_operand" "=v,v ,v ,m")
2044 (match_operand:XI 1 "nonimmediate_or_sse_const_operand" " C,BC,vm,v"))]
2046 && (register_operand (operands[0], XImode)
2047 || register_operand (operands[1], XImode))"
2049 switch (get_attr_type (insn))
2052 return standard_sse_constant_opcode (insn, operands);
2055 if (misaligned_operand (operands[0], XImode)
2056 || misaligned_operand (operands[1], XImode))
2057 return "vmovdqu32\t{%1, %0|%0, %1}";
2059 return "vmovdqa32\t{%1, %0|%0, %1}";
2065 [(set_attr "type" "sselog1,sselog1,ssemov,ssemov")
2066 (set_attr "prefix" "evex")
2067 (set_attr "mode" "XI")])
2069 (define_insn "*movoi_internal_avx"
2070 [(set (match_operand:OI 0 "nonimmediate_operand" "=v,v ,v ,m")
2071 (match_operand:OI 1 "nonimmediate_or_sse_const_operand" " C,BC,vm,v"))]
2073 && (register_operand (operands[0], OImode)
2074 || register_operand (operands[1], OImode))"
2076 switch (get_attr_type (insn))
2079 return standard_sse_constant_opcode (insn, operands);
2082 if (misaligned_operand (operands[0], OImode)
2083 || misaligned_operand (operands[1], OImode))
2085 if (get_attr_mode (insn) == MODE_V8SF)
2086 return "vmovups\t{%1, %0|%0, %1}";
2087 else if (get_attr_mode (insn) == MODE_XI)
2088 return "vmovdqu32\t{%1, %0|%0, %1}";
2090 return "vmovdqu\t{%1, %0|%0, %1}";
2094 if (get_attr_mode (insn) == MODE_V8SF)
2095 return "vmovaps\t{%1, %0|%0, %1}";
2096 else if (get_attr_mode (insn) == MODE_XI)
2097 return "vmovdqa32\t{%1, %0|%0, %1}";
2099 return "vmovdqa\t{%1, %0|%0, %1}";
2106 [(set_attr "isa" "*,avx2,*,*")
2107 (set_attr "type" "sselog1,sselog1,ssemov,ssemov")
2108 (set_attr "prefix" "vex")
2110 (cond [(ior (match_operand 0 "ext_sse_reg_operand")
2111 (match_operand 1 "ext_sse_reg_operand"))
2113 (and (eq_attr "alternative" "1")
2114 (match_test "TARGET_AVX512VL"))
2116 (ior (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
2117 (and (eq_attr "alternative" "3")
2118 (match_test "TARGET_SSE_TYPELESS_STORES")))
2119 (const_string "V8SF")
2121 (const_string "OI")))])
2123 (define_insn "*movti_internal"
2124 [(set (match_operand:TI 0 "nonimmediate_operand" "=!r ,o ,v,v ,v ,m,?r,?Yd")
2125 (match_operand:TI 1 "general_operand" "riFo,re,C,BC,vm,v,Yd,r"))]
2127 && !(MEM_P (operands[0]) && MEM_P (operands[1])))
2129 && nonimmediate_or_sse_const_operand (operands[1], TImode)
2130 && (register_operand (operands[0], TImode)
2131 || register_operand (operands[1], TImode)))"
2133 switch (get_attr_type (insn))
2139 return standard_sse_constant_opcode (insn, operands);
2142 /* TDmode values are passed as TImode on the stack. Moving them
2143 to stack may result in unaligned memory access. */
2144 if (misaligned_operand (operands[0], TImode)
2145 || misaligned_operand (operands[1], TImode))
2147 if (get_attr_mode (insn) == MODE_V4SF)
2148 return "%vmovups\t{%1, %0|%0, %1}";
2149 else if (get_attr_mode (insn) == MODE_XI)
2150 return "vmovdqu32\t{%1, %0|%0, %1}";
2152 return "%vmovdqu\t{%1, %0|%0, %1}";
2156 if (get_attr_mode (insn) == MODE_V4SF)
2157 return "%vmovaps\t{%1, %0|%0, %1}";
2158 else if (get_attr_mode (insn) == MODE_XI)
2159 return "vmovdqa32\t{%1, %0|%0, %1}";
2161 return "%vmovdqa\t{%1, %0|%0, %1}";
2169 (cond [(eq_attr "alternative" "0,1,6,7")
2170 (const_string "x64")
2171 (eq_attr "alternative" "3")
2172 (const_string "sse2")
2174 (const_string "*")))
2176 (cond [(eq_attr "alternative" "0,1,6,7")
2177 (const_string "multi")
2178 (eq_attr "alternative" "2,3")
2179 (const_string "sselog1")
2181 (const_string "ssemov")))
2182 (set (attr "prefix")
2183 (if_then_else (eq_attr "type" "sselog1,ssemov")
2184 (const_string "maybe_vex")
2185 (const_string "orig")))
2187 (cond [(eq_attr "alternative" "0,1")
2189 (ior (match_operand 0 "ext_sse_reg_operand")
2190 (match_operand 1 "ext_sse_reg_operand"))
2192 (and (eq_attr "alternative" "3")
2193 (match_test "TARGET_AVX512VL"))
2195 (ior (not (match_test "TARGET_SSE2"))
2196 (ior (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
2197 (and (eq_attr "alternative" "5")
2198 (match_test "TARGET_SSE_TYPELESS_STORES"))))
2199 (const_string "V4SF")
2200 (match_test "TARGET_AVX")
2202 (match_test "optimize_function_for_size_p (cfun)")
2203 (const_string "V4SF")
2205 (const_string "TI")))
2206 (set (attr "preferred_for_speed")
2207 (cond [(eq_attr "alternative" "6")
2208 (symbol_ref "TARGET_INTER_UNIT_MOVES_FROM_VEC")
2209 (eq_attr "alternative" "7")
2210 (symbol_ref "TARGET_INTER_UNIT_MOVES_TO_VEC")
2212 (symbol_ref "true")))])
2215 [(set (match_operand:TI 0 "sse_reg_operand")
2216 (match_operand:TI 1 "general_reg_operand"))]
2217 "TARGET_64BIT && TARGET_SSE4_1
2218 && reload_completed"
2221 (vec_duplicate:V2DI (match_dup 3))
2225 operands[2] = lowpart_subreg (V2DImode, operands[0], TImode);
2226 operands[3] = gen_highpart (DImode, operands[1]);
2228 emit_move_insn (gen_lowpart (DImode, operands[0]),
2229 gen_lowpart (DImode, operands[1]));
2232 (define_insn "*movdi_internal"
2233 [(set (match_operand:DI 0 "nonimmediate_operand"
2234 "=r ,o ,r,r ,r,m ,*y,*y,?*y,?m,?r,?*y,*v,*v,*v,m ,m,?r ,?*Yd,?r,?*v,?*y,?*x,*k,*k ,*r,*m")
2235 (match_operand:DI 1 "general_operand"
2236 "riFo,riF,Z,rem,i,re,C ,*y,m ,*y,*y,r ,C ,*v,m ,*v,v,*Yd,r ,*v,r ,*x ,*y ,*r,*km,*k,*k"))]
2237 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2239 switch (get_attr_type (insn))
2242 return "kmovq\t{%1, %0|%0, %1}";
2248 return "pxor\t%0, %0";
2251 /* Handle broken assemblers that require movd instead of movq. */
2252 if (!HAVE_AS_IX86_INTERUNIT_MOVQ
2253 && (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1])))
2254 return "movd\t{%1, %0|%0, %1}";
2255 return "movq\t{%1, %0|%0, %1}";
2258 return standard_sse_constant_opcode (insn, operands);
2261 switch (get_attr_mode (insn))
2264 /* Handle broken assemblers that require movd instead of movq. */
2265 if (!HAVE_AS_IX86_INTERUNIT_MOVQ
2266 && (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1])))
2267 return "%vmovd\t{%1, %0|%0, %1}";
2268 return "%vmovq\t{%1, %0|%0, %1}";
2271 /* Handle AVX512 registers set. */
2272 if (EXT_REX_SSE_REG_P (operands[0])
2273 || EXT_REX_SSE_REG_P (operands[1]))
2274 return "vmovdqa64\t{%1, %0|%0, %1}";
2275 return "%vmovdqa\t{%1, %0|%0, %1}";
2278 gcc_assert (!TARGET_AVX);
2279 return "movlps\t{%1, %0|%0, %1}";
2281 return "%vmovaps\t{%1, %0|%0, %1}";
2288 if (SSE_REG_P (operands[0]))
2289 return "movq2dq\t{%1, %0|%0, %1}";
2291 return "movdq2q\t{%1, %0|%0, %1}";
2294 return "lea{q}\t{%E1, %0|%0, %E1}";
2297 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2298 if (get_attr_mode (insn) == MODE_SI)
2299 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2300 else if (which_alternative == 4)
2301 return "movabs{q}\t{%1, %0|%0, %1}";
2302 else if (ix86_use_lea_for_mov (insn, operands))
2303 return "lea{q}\t{%E1, %0|%0, %E1}";
2305 return "mov{q}\t{%1, %0|%0, %1}";
2312 (cond [(eq_attr "alternative" "0,1,17,18")
2313 (const_string "nox64")
2314 (eq_attr "alternative" "2,3,4,5,10,11,23,25")
2315 (const_string "x64")
2316 (eq_attr "alternative" "19,20")
2317 (const_string "x64_sse2")
2318 (eq_attr "alternative" "21,22")
2319 (const_string "sse2")
2321 (const_string "*")))
2323 (cond [(eq_attr "alternative" "0,1,17,18")
2324 (const_string "multi")
2325 (eq_attr "alternative" "6")
2326 (const_string "mmx")
2327 (eq_attr "alternative" "7,8,9,10,11")
2328 (const_string "mmxmov")
2329 (eq_attr "alternative" "12")
2330 (const_string "sselog1")
2331 (eq_attr "alternative" "13,14,15,16,19,20")
2332 (const_string "ssemov")
2333 (eq_attr "alternative" "21,22")
2334 (const_string "ssecvt")
2335 (eq_attr "alternative" "23,24,25,26")
2336 (const_string "mskmov")
2337 (and (match_operand 0 "register_operand")
2338 (match_operand 1 "pic_32bit_operand"))
2339 (const_string "lea")
2341 (const_string "imov")))
2344 (and (eq_attr "alternative" "4") (eq_attr "type" "imov"))
2346 (const_string "*")))
2347 (set (attr "length_immediate")
2349 (and (eq_attr "alternative" "4") (eq_attr "type" "imov"))
2351 (const_string "*")))
2352 (set (attr "prefix_rex")
2354 (eq_attr "alternative" "10,11,19,20")
2356 (const_string "*")))
2357 (set (attr "prefix")
2358 (if_then_else (eq_attr "type" "sselog1,ssemov")
2359 (const_string "maybe_vex")
2360 (const_string "orig")))
2361 (set (attr "prefix_data16")
2362 (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "DI"))
2364 (const_string "*")))
2366 (cond [(eq_attr "alternative" "2")
2368 (eq_attr "alternative" "12,13")
2369 (cond [(ior (match_operand 0 "ext_sse_reg_operand")
2370 (match_operand 1 "ext_sse_reg_operand"))
2372 (ior (not (match_test "TARGET_SSE2"))
2373 (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL"))
2374 (const_string "V4SF")
2375 (match_test "TARGET_AVX")
2377 (match_test "optimize_function_for_size_p (cfun)")
2378 (const_string "V4SF")
2380 (const_string "TI"))
2382 (and (eq_attr "alternative" "14,15,16")
2383 (not (match_test "TARGET_SSE2")))
2384 (const_string "V2SF")
2386 (const_string "DI")))
2387 (set (attr "preferred_for_speed")
2388 (cond [(eq_attr "alternative" "10,17,19")
2389 (symbol_ref "TARGET_INTER_UNIT_MOVES_FROM_VEC")
2390 (eq_attr "alternative" "11,18,20")
2391 (symbol_ref "TARGET_INTER_UNIT_MOVES_TO_VEC")
2393 (symbol_ref "true")))
2394 (set (attr "enabled")
2395 (cond [(eq_attr "alternative" "15")
2397 (match_test "TARGET_STV && TARGET_SSE2")
2398 (symbol_ref "false")
2400 (eq_attr "alternative" "16")
2402 (match_test "TARGET_STV && TARGET_SSE2")
2404 (symbol_ref "false"))
2406 (const_string "*")))])
2409 [(set (match_operand:<DWI> 0 "general_reg_operand")
2410 (match_operand:<DWI> 1 "sse_reg_operand"))]
2412 && reload_completed"
2416 (parallel [(const_int 1)])))]
2418 operands[2] = gen_highpart (<MODE>mode, operands[0]);
2419 operands[3] = lowpart_subreg (<ssevecmode>mode, operands[1], <DWI>mode);
2421 emit_move_insn (gen_lowpart (<MODE>mode, operands[0]),
2422 gen_lowpart (<MODE>mode, operands[1]));
2426 [(set (match_operand:DWI 0 "nonimmediate_gr_operand")
2427 (match_operand:DWI 1 "general_gr_operand"))]
2430 "ix86_split_long_move (operands); DONE;")
2433 [(set (match_operand:DI 0 "sse_reg_operand")
2434 (match_operand:DI 1 "general_reg_operand"))]
2435 "!TARGET_64BIT && TARGET_SSE4_1
2436 && reload_completed"
2439 (vec_duplicate:V4SI (match_dup 3))
2443 operands[2] = lowpart_subreg (V4SImode, operands[0], DImode);
2444 operands[3] = gen_highpart (SImode, operands[1]);
2446 emit_move_insn (gen_lowpart (SImode, operands[0]),
2447 gen_lowpart (SImode, operands[1]));
2450 ;; movabsq $0x0012345678000000, %rax is longer
2451 ;; than movl $0x12345678, %eax; shlq $24, %rax.
2453 [(set (match_operand:DI 0 "register_operand")
2454 (match_operand:DI 1 "const_int_operand"))]
2456 && optimize_insn_for_size_p ()
2457 && LEGACY_INT_REG_P (operands[0])
2458 && !x86_64_immediate_operand (operands[1], DImode)
2459 && !x86_64_zext_immediate_operand (operands[1], DImode)
2460 && !((UINTVAL (operands[1]) >> ctz_hwi (UINTVAL (operands[1])))
2461 & ~(HOST_WIDE_INT) 0xffffffff)
2462 && peep2_regno_dead_p (0, FLAGS_REG)"
2463 [(set (match_dup 0) (match_dup 1))
2464 (parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
2465 (clobber (reg:CC FLAGS_REG))])]
2467 int shift = ctz_hwi (UINTVAL (operands[1]));
2468 operands[1] = gen_int_mode (UINTVAL (operands[1]) >> shift, DImode);
2469 operands[2] = gen_int_mode (shift, QImode);
2472 (define_insn "*movsi_internal"
2473 [(set (match_operand:SI 0 "nonimmediate_operand"
2474 "=r,m ,*y,*y,?*y,?m,?r,?*y,*v,*v,*v,m ,?r,?*v,*k,*k ,*rm")
2475 (match_operand:SI 1 "general_operand"
2476 "g ,re,C ,*y,m ,*y,*y,r ,C ,*v,m ,*v,*v,r ,*r,*km,*k"))]
2477 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2479 switch (get_attr_type (insn))
2482 return standard_sse_constant_opcode (insn, operands);
2485 return "kmovd\t{%1, %0|%0, %1}";
2488 switch (get_attr_mode (insn))
2491 return "%vmovd\t{%1, %0|%0, %1}";
2493 return "%vmovdqa\t{%1, %0|%0, %1}";
2495 return "vmovdqa32\t{%g1, %g0|%g0, %g1}";
2498 return "%vmovaps\t{%1, %0|%0, %1}";
2501 gcc_assert (!TARGET_AVX);
2502 return "movss\t{%1, %0|%0, %1}";
2509 return "pxor\t%0, %0";
2512 switch (get_attr_mode (insn))
2515 return "movq\t{%1, %0|%0, %1}";
2517 return "movd\t{%1, %0|%0, %1}";
2524 return "lea{l}\t{%E1, %0|%0, %E1}";
2527 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2528 if (ix86_use_lea_for_mov (insn, operands))
2529 return "lea{l}\t{%E1, %0|%0, %E1}";
2531 return "mov{l}\t{%1, %0|%0, %1}";
2538 (cond [(eq_attr "alternative" "12,13")
2539 (const_string "sse2")
2541 (const_string "*")))
2543 (cond [(eq_attr "alternative" "2")
2544 (const_string "mmx")
2545 (eq_attr "alternative" "3,4,5,6,7")
2546 (const_string "mmxmov")
2547 (eq_attr "alternative" "8")
2548 (const_string "sselog1")
2549 (eq_attr "alternative" "9,10,11,12,13")
2550 (const_string "ssemov")
2551 (eq_attr "alternative" "14,15,16")
2552 (const_string "mskmov")
2553 (and (match_operand 0 "register_operand")
2554 (match_operand 1 "pic_32bit_operand"))
2555 (const_string "lea")
2557 (const_string "imov")))
2558 (set (attr "prefix")
2559 (if_then_else (eq_attr "type" "sselog1,ssemov")
2560 (const_string "maybe_vex")
2561 (const_string "orig")))
2562 (set (attr "prefix_data16")
2563 (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
2565 (const_string "*")))
2567 (cond [(eq_attr "alternative" "2,3")
2569 (eq_attr "alternative" "8,9")
2570 (cond [(ior (match_operand 0 "ext_sse_reg_operand")
2571 (match_operand 1 "ext_sse_reg_operand"))
2573 (ior (not (match_test "TARGET_SSE2"))
2574 (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL"))
2575 (const_string "V4SF")
2576 (match_test "TARGET_AVX")
2578 (match_test "optimize_function_for_size_p (cfun)")
2579 (const_string "V4SF")
2581 (const_string "TI"))
2583 (and (eq_attr "alternative" "10,11")
2584 (not (match_test "TARGET_SSE2")))
2587 (const_string "SI")))
2588 (set (attr "preferred_for_speed")
2589 (cond [(eq_attr "alternative" "6,12")
2590 (symbol_ref "TARGET_INTER_UNIT_MOVES_FROM_VEC")
2591 (eq_attr "alternative" "7,13")
2592 (symbol_ref "TARGET_INTER_UNIT_MOVES_TO_VEC")
2594 (symbol_ref "true")))])
2596 (define_insn "*movhi_internal"
2597 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r ,r ,m ,k,k ,r,m")
2598 (match_operand:HI 1 "general_operand" "r ,rn,rm,rn,r,km,k,k"))]
2599 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2601 switch (get_attr_type (insn))
2604 /* movzwl is faster than movw on p2 due to partial word stalls,
2605 though not as fast as an aligned movl. */
2606 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
2609 switch (which_alternative)
2612 return "kmovw\t{%k1, %0|%0, %k1}";
2614 return "kmovw\t{%1, %k0|%k0, %1}";
2617 return "kmovw\t{%1, %0|%0, %1}";
2623 if (get_attr_mode (insn) == MODE_SI)
2624 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2626 return "mov{w}\t{%1, %0|%0, %1}";
2630 (cond [(eq_attr "alternative" "4,5,6,7")
2631 (const_string "mskmov")
2632 (match_test "optimize_function_for_size_p (cfun)")
2633 (const_string "imov")
2634 (and (eq_attr "alternative" "0")
2635 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2636 (not (match_test "TARGET_HIMODE_MATH"))))
2637 (const_string "imov")
2638 (and (eq_attr "alternative" "1,2")
2639 (match_operand:HI 1 "aligned_operand"))
2640 (const_string "imov")
2641 (and (match_test "TARGET_MOVX")
2642 (eq_attr "alternative" "0,2"))
2643 (const_string "imovx")
2645 (const_string "imov")))
2646 (set (attr "prefix")
2647 (if_then_else (eq_attr "alternative" "4,5,6,7")
2648 (const_string "vex")
2649 (const_string "orig")))
2651 (cond [(eq_attr "type" "imovx")
2653 (and (eq_attr "alternative" "1,2")
2654 (match_operand:HI 1 "aligned_operand"))
2656 (and (eq_attr "alternative" "0")
2657 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2658 (not (match_test "TARGET_HIMODE_MATH"))))
2661 (const_string "HI")))])
2663 ;; Situation is quite tricky about when to choose full sized (SImode) move
2664 ;; over QImode moves. For Q_REG -> Q_REG move we use full size only for
2665 ;; partial register dependency machines (such as AMD Athlon), where QImode
2666 ;; moves issue extra dependency and for partial register stalls machines
2667 ;; that don't use QImode patterns (and QImode move cause stall on the next
2670 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
2671 ;; register stall machines with, where we use QImode instructions, since
2672 ;; partial register stall can be caused there. Then we use movzx.
2674 (define_insn "*movqi_internal"
2675 [(set (match_operand:QI 0 "nonimmediate_operand"
2676 "=Q,R,r,q,q,r,r ,?r,m ,k,k,r,m,k")
2677 (match_operand:QI 1 "general_operand"
2678 "Q ,R,r,n,m,q,rn, m,qn,r,k,k,k,m"))]
2679 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2681 static char buf[128];
2685 switch (get_attr_type (insn))
2688 gcc_assert (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]));
2689 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
2692 switch (which_alternative)
2695 ops = "kmov%s\t{%%k1, %%0|%%0, %%k1}";
2698 ops = "kmov%s\t{%%1, %%k0|%%k0, %%1}";
2702 gcc_assert (TARGET_AVX512DQ);
2705 ops = "kmov%s\t{%%1, %%0|%%0, %%1}";
2711 suffix = (get_attr_mode (insn) == MODE_HI) ? "w" : "b";
2713 snprintf (buf, sizeof (buf), ops, suffix);
2717 if (get_attr_mode (insn) == MODE_SI)
2718 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2720 return "mov{b}\t{%1, %0|%0, %1}";
2724 (cond [(eq_attr "alternative" "1,2")
2725 (const_string "x64")
2726 (eq_attr "alternative" "12,13")
2727 (const_string "avx512dq")
2729 (const_string "*")))
2731 (cond [(eq_attr "alternative" "9,10,11,12,13")
2732 (const_string "mskmov")
2733 (and (eq_attr "alternative" "7")
2734 (not (match_operand:QI 1 "aligned_operand")))
2735 (const_string "imovx")
2736 (match_test "optimize_function_for_size_p (cfun)")
2737 (const_string "imov")
2738 (and (eq_attr "alternative" "5")
2739 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2740 (not (match_test "TARGET_QIMODE_MATH"))))
2741 (const_string "imov")
2742 (eq_attr "alternative" "5,7")
2743 (const_string "imovx")
2744 (and (match_test "TARGET_MOVX")
2745 (eq_attr "alternative" "4"))
2746 (const_string "imovx")
2748 (const_string "imov")))
2749 (set (attr "prefix")
2750 (if_then_else (eq_attr "alternative" "9,10,11")
2751 (const_string "vex")
2752 (const_string "orig")))
2754 (cond [(eq_attr "alternative" "5,6,7")
2756 (eq_attr "alternative" "8")
2758 (and (eq_attr "alternative" "9,10,11")
2759 (not (match_test "TARGET_AVX512DQ")))
2761 (eq_attr "type" "imovx")
2763 ;; For -Os, 8-bit immediates are always shorter than 32-bit
2765 (and (eq_attr "type" "imov")
2766 (and (eq_attr "alternative" "3")
2767 (match_test "optimize_function_for_size_p (cfun)")))
2769 ;; For -Os, movl where one or both operands are NON_Q_REGS
2770 ;; and both are LEGACY_REGS is shorter than movb.
2771 ;; Otherwise movb and movl sizes are the same, so decide purely
2772 ;; based on speed factors.
2773 (and (eq_attr "type" "imov")
2774 (and (eq_attr "alternative" "1")
2775 (match_test "optimize_function_for_size_p (cfun)")))
2777 (and (eq_attr "type" "imov")
2778 (and (eq_attr "alternative" "0,1,2,3")
2779 (and (match_test "TARGET_PARTIAL_REG_DEPENDENCY")
2780 (not (match_test "TARGET_PARTIAL_REG_STALL")))))
2782 ;; Avoid partial register stalls when not using QImode arithmetic
2783 (and (eq_attr "type" "imov")
2784 (and (eq_attr "alternative" "0,1,2,3")
2785 (and (match_test "TARGET_PARTIAL_REG_STALL")
2786 (not (match_test "TARGET_QIMODE_MATH")))))
2789 (const_string "QI")))])
2791 ;; Stores and loads of ax to arbitrary constant address.
2792 ;; We fake an second form of instruction to force reload to load address
2793 ;; into register when rax is not available
2794 (define_insn "*movabs<mode>_1"
2795 [(set (mem:SWI1248x (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2796 (match_operand:SWI1248x 1 "nonmemory_operand" "a,r<i>"))]
2797 "TARGET_LP64 && ix86_check_movabs (insn, 0)"
2799 /* Recover the full memory rtx. */
2800 operands[0] = SET_DEST (PATTERN (insn));
2801 switch (which_alternative)
2804 return "movabs{<imodesuffix>}\t{%1, %P0|<iptrsize> PTR [%P0], %1}";
2806 return "mov{<imodesuffix>}\t{%1, %0|%0, %1}";
2811 [(set_attr "type" "imov")
2812 (set_attr "modrm" "0,*")
2813 (set_attr "length_address" "8,0")
2814 (set_attr "length_immediate" "0,*")
2815 (set_attr "memory" "store")
2816 (set_attr "mode" "<MODE>")])
2818 (define_insn "*movabs<mode>_2"
2819 [(set (match_operand:SWI1248x 0 "register_operand" "=a,r")
2820 (mem:SWI1248x (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2821 "TARGET_LP64 && ix86_check_movabs (insn, 1)"
2823 /* Recover the full memory rtx. */
2824 operands[1] = SET_SRC (PATTERN (insn));
2825 switch (which_alternative)
2828 return "movabs{<imodesuffix>}\t{%P1, %0|%0, <iptrsize> PTR [%P1]}";
2830 return "mov{<imodesuffix>}\t{%1, %0|%0, %1}";
2835 [(set_attr "type" "imov")
2836 (set_attr "modrm" "0,*")
2837 (set_attr "length_address" "8,0")
2838 (set_attr "length_immediate" "0")
2839 (set_attr "memory" "load")
2840 (set_attr "mode" "<MODE>")])
2842 (define_insn "*swap<mode>"
2843 [(set (match_operand:SWI48 0 "register_operand" "+r")
2844 (match_operand:SWI48 1 "register_operand" "+r"))
2848 "xchg{<imodesuffix>}\t%1, %0"
2849 [(set_attr "type" "imov")
2850 (set_attr "mode" "<MODE>")
2851 (set_attr "pent_pair" "np")
2852 (set_attr "athlon_decode" "vector")
2853 (set_attr "amdfam10_decode" "double")
2854 (set_attr "bdver1_decode" "double")])
2856 (define_insn "*swap<mode>"
2857 [(set (match_operand:SWI12 0 "register_operand" "+<r>,r")
2858 (match_operand:SWI12 1 "register_operand" "+<r>,r"))
2863 xchg{<imodesuffix>}\t%1, %0
2865 [(set_attr "type" "imov")
2866 (set_attr "mode" "<MODE>,SI")
2867 (set (attr "preferred_for_size")
2868 (cond [(eq_attr "alternative" "0")
2869 (symbol_ref "false")]
2870 (symbol_ref "true")))
2871 ;; Potential partial reg stall on alternative 1.
2872 (set (attr "preferred_for_speed")
2873 (cond [(eq_attr "alternative" "1")
2874 (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
2875 (symbol_ref "true")))
2876 (set_attr "pent_pair" "np")
2877 (set_attr "athlon_decode" "vector")
2878 (set_attr "amdfam10_decode" "double")
2879 (set_attr "bdver1_decode" "double")])
2881 (define_expand "movstrict<mode>"
2882 [(set (strict_low_part (match_operand:SWI12 0 "nonimmediate_operand"))
2883 (match_operand:SWI12 1 "general_operand"))]
2886 if (TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun))
2888 if (SUBREG_P (operands[0])
2889 && GET_MODE_CLASS (GET_MODE (SUBREG_REG (operands[0]))) != MODE_INT)
2891 /* Don't generate memory->memory moves, go through a register */
2892 if (MEM_P (operands[0]) && MEM_P (operands[1]))
2893 operands[1] = force_reg (<MODE>mode, operands[1]);
2896 (define_insn "*movstrict<mode>_1"
2897 [(set (strict_low_part
2898 (match_operand:SWI12 0 "nonimmediate_operand" "+<r>m,<r>"))
2899 (match_operand:SWI12 1 "general_operand" "<r>n,m"))]
2900 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
2901 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2902 "mov{<imodesuffix>}\t{%1, %0|%0, %1}"
2903 [(set_attr "type" "imov")
2904 (set_attr "mode" "<MODE>")])
2906 (define_insn "*movstrict<mode>_xor"
2907 [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>"))
2908 (match_operand:SWI12 1 "const0_operand"))
2909 (clobber (reg:CC FLAGS_REG))]
2911 "xor{<imodesuffix>}\t%0, %0"
2912 [(set_attr "type" "alu1")
2913 (set_attr "modrm_class" "op0")
2914 (set_attr "mode" "<MODE>")
2915 (set_attr "length_immediate" "0")])
2917 (define_expand "extv<mode>"
2918 [(set (match_operand:SWI24 0 "register_operand")
2919 (sign_extract:SWI24 (match_operand:SWI24 1 "register_operand")
2920 (match_operand:SI 2 "const_int_operand")
2921 (match_operand:SI 3 "const_int_operand")))]
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 "*extv<mode>"
2936 [(set (match_operand:SWI24 0 "register_operand" "=R")
2937 (sign_extract:SWI24 (match_operand 1 "ext_register_operand" "Q")
2941 "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
2942 [(set_attr "type" "imovx")
2943 (set_attr "mode" "SI")])
2945 (define_expand "extzv<mode>"
2946 [(set (match_operand:SWI248 0 "register_operand")
2947 (zero_extract:SWI248 (match_operand:SWI248 1 "register_operand")
2948 (match_operand:SI 2 "const_int_operand")
2949 (match_operand:SI 3 "const_int_operand")))]
2952 if (ix86_expand_pextr (operands))
2955 /* Handle extractions from %ah et al. */
2956 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
2959 unsigned int regno = reg_or_subregno (operands[1]);
2961 /* Be careful to expand only with registers having upper parts. */
2962 if (regno <= LAST_VIRTUAL_REGISTER && !QI_REGNO_P (regno))
2963 operands[1] = copy_to_reg (operands[1]);
2966 (define_insn "*extzvqi_mem_rex64"
2967 [(set (match_operand:QI 0 "norex_memory_operand" "=Bn")
2969 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q")
2972 "TARGET_64BIT && reload_completed"
2973 "mov{b}\t{%h1, %0|%0, %h1}"
2974 [(set_attr "type" "imov")
2975 (set_attr "mode" "QI")])
2977 (define_insn "*extzv<mode>"
2978 [(set (match_operand:SWI248 0 "register_operand" "=R")
2979 (zero_extract:SWI248 (match_operand 1 "ext_register_operand" "Q")
2983 "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
2984 [(set_attr "type" "imovx")
2985 (set_attr "mode" "SI")])
2987 (define_insn "*extzvqi"
2988 [(set (match_operand:QI 0 "nonimmediate_operand" "=QBc,?R,m")
2990 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q,Q")
2995 switch (get_attr_type (insn))
2998 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
3000 return "mov{b}\t{%h1, %0|%0, %h1}";
3003 [(set_attr "isa" "*,*,nox64")
3005 (if_then_else (and (match_operand:QI 0 "register_operand")
3006 (ior (not (match_operand:QI 0 "QIreg_operand"))
3007 (match_test "TARGET_MOVX")))
3008 (const_string "imovx")
3009 (const_string "imov")))
3011 (if_then_else (eq_attr "type" "imovx")
3013 (const_string "QI")))])
3016 [(set (match_operand:QI 0 "register_operand")
3018 (zero_extract:SI (match_operand 1 "ext_register_operand")
3021 (set (match_operand:QI 2 "norex_memory_operand") (match_dup 0))]
3023 && peep2_reg_dead_p (2, operands[0])"
3026 (zero_extract:SI (match_dup 1)
3028 (const_int 8)) 0))])
3030 (define_expand "insv<mode>"
3031 [(set (zero_extract:SWI248 (match_operand:SWI248 0 "register_operand")
3032 (match_operand:SI 1 "const_int_operand")
3033 (match_operand:SI 2 "const_int_operand"))
3034 (match_operand:SWI248 3 "register_operand"))]
3039 if (ix86_expand_pinsr (operands))
3042 /* Handle insertions to %ah et al. */
3043 if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
3046 unsigned int regno = reg_or_subregno (operands[0]);
3048 /* Be careful to expand only with registers having upper parts. */
3049 if (regno <= LAST_VIRTUAL_REGISTER && !QI_REGNO_P (regno))
3050 dst = copy_to_reg (operands[0]);
3054 emit_insn (gen_insv<mode>_1 (dst, operands[3]));
3056 /* Fix up the destination if needed. */
3057 if (dst != operands[0])
3058 emit_move_insn (operands[0], dst);
3063 (define_insn "*insvqi_1_mem_rex64"
3064 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
3068 (match_operand:QI 1 "norex_memory_operand" "Bn") 0))]
3069 "TARGET_64BIT && reload_completed"
3070 "mov{b}\t{%1, %h0|%h0, %1}"
3071 [(set_attr "type" "imov")
3072 (set_attr "mode" "QI")])
3074 (define_insn "insv<mode>_1"
3075 [(set (zero_extract:SWI248 (match_operand 0 "ext_register_operand" "+Q,Q")
3078 (match_operand:SWI248 1 "general_operand" "QnBc,m"))]
3081 if (CONST_INT_P (operands[1]))
3082 operands[1] = gen_int_mode (INTVAL (operands[1]), QImode);
3083 return "mov{b}\t{%b1, %h0|%h0, %b1}";
3085 [(set_attr "isa" "*,nox64")
3086 (set_attr "type" "imov")
3087 (set_attr "mode" "QI")])
3089 (define_insn "*insvqi_1"
3090 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q,Q")
3094 (match_operand:QI 1 "general_operand" "QnBc,m") 0))]
3096 "mov{b}\t{%1, %h0|%h0, %1}"
3097 [(set_attr "isa" "*,nox64")
3098 (set_attr "type" "imov")
3099 (set_attr "mode" "QI")])
3102 [(set (match_operand:QI 0 "register_operand")
3103 (match_operand:QI 1 "norex_memory_operand"))
3104 (set (zero_extract:SI (match_operand 2 "ext_register_operand")
3107 (subreg:SI (match_dup 0) 0))]
3109 && peep2_reg_dead_p (2, operands[0])"
3110 [(set (zero_extract:SI (match_dup 2)
3113 (subreg:SI (match_dup 1) 0))])
3115 (define_code_iterator any_extract [sign_extract zero_extract])
3117 (define_insn "*insvqi_2"
3118 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
3121 (any_extract:SI (match_operand 1 "ext_register_operand" "Q")
3125 "mov{b}\t{%h1, %h0|%h0, %h1}"
3126 [(set_attr "type" "imov")
3127 (set_attr "mode" "QI")])
3129 (define_insn "*insvqi_3"
3130 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
3133 (any_shiftrt:SI (match_operand:SI 1 "register_operand" "Q")
3136 "mov{b}\t{%h1, %h0|%h0, %h1}"
3137 [(set_attr "type" "imov")
3138 (set_attr "mode" "QI")])
3140 ;; Floating point push instructions.
3142 (define_insn "*pushtf"
3143 [(set (match_operand:TF 0 "push_operand" "=<,<")
3144 (match_operand:TF 1 "general_no_elim_operand" "v,*roC"))]
3145 "TARGET_64BIT || TARGET_SSE"
3147 /* This insn should be already split before reg-stack. */
3150 [(set_attr "isa" "*,x64")
3151 (set_attr "type" "multi")
3152 (set_attr "unit" "sse,*")
3153 (set_attr "mode" "TF,DI")])
3155 ;; %%% Kill this when call knows how to work this out.
3157 [(set (match_operand:TF 0 "push_operand")
3158 (match_operand:TF 1 "sse_reg_operand"))]
3159 "TARGET_SSE && reload_completed"
3160 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -16)))
3161 (set (match_dup 0) (match_dup 1))]
3163 /* Preserve memory attributes. */
3164 operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
3167 (define_insn_and_split "*pushxf_rounded"
3171 (plus:P (reg:P SP_REG) (const_int -16))))
3172 (match_operand:XF 0 "nonmemory_no_elim_operand" "f,r,*r,C"))]
3176 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -16)))
3177 (set (match_dup 1) (match_dup 0))]
3179 rtx pat = PATTERN (curr_insn);
3180 operands[1] = SET_DEST (pat);
3182 /* Preserve memory attributes. */
3183 operands[1] = replace_equiv_address (operands[1], stack_pointer_rtx);
3185 [(set_attr "type" "multi")
3186 (set_attr "unit" "i387,*,*,*")
3188 (cond [(eq_attr "alternative" "1,2,3")
3191 (const_string "XF")))
3192 (set (attr "preferred_for_size")
3193 (cond [(eq_attr "alternative" "1")
3194 (symbol_ref "false")]
3195 (symbol_ref "true")))])
3197 (define_insn "*pushxf"
3198 [(set (match_operand:XF 0 "push_operand" "=<,<,<,<,<")
3199 (match_operand:XF 1 "general_no_elim_operand" "f,r,*r,oF,oC"))]
3202 /* This insn should be already split before reg-stack. */
3205 [(set_attr "isa" "*,*,*,nox64,x64")
3206 (set_attr "type" "multi")
3207 (set_attr "unit" "i387,*,*,*,*")
3209 (cond [(eq_attr "alternative" "1,2,3,4")
3210 (if_then_else (match_test "TARGET_64BIT")
3212 (const_string "SI"))
3214 (const_string "XF")))
3215 (set (attr "preferred_for_size")
3216 (cond [(eq_attr "alternative" "1")
3217 (symbol_ref "false")]
3218 (symbol_ref "true")))])
3220 ;; %%% Kill this when call knows how to work this out.
3222 [(set (match_operand:XF 0 "push_operand")
3223 (match_operand:XF 1 "fp_register_operand"))]
3225 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
3226 (set (match_dup 0) (match_dup 1))]
3228 operands[2] = GEN_INT (-PUSH_ROUNDING (GET_MODE_SIZE (XFmode)));
3229 /* Preserve memory attributes. */
3230 operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
3233 (define_insn "*pushdf"
3234 [(set (match_operand:DF 0 "push_operand" "=<,<,<,<,<,<")
3235 (match_operand:DF 1 "general_no_elim_operand" "f,r,*r,oF,rmC,x"))]
3238 /* This insn should be already split before reg-stack. */
3241 [(set_attr "isa" "*,nox64,nox64,nox64,x64,sse2")
3242 (set_attr "type" "multi")
3243 (set_attr "unit" "i387,*,*,*,*,sse")
3244 (set_attr "mode" "DF,SI,SI,SI,DI,DF")
3245 (set (attr "preferred_for_size")
3246 (cond [(eq_attr "alternative" "1")
3247 (symbol_ref "false")]
3248 (symbol_ref "true")))
3249 (set (attr "preferred_for_speed")
3250 (cond [(eq_attr "alternative" "1")
3251 (symbol_ref "TARGET_INTEGER_DFMODE_MOVES")]
3252 (symbol_ref "true")))])
3254 ;; %%% Kill this when call knows how to work this out.
3256 [(set (match_operand:DF 0 "push_operand")
3257 (match_operand:DF 1 "any_fp_register_operand"))]
3259 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
3260 (set (match_dup 0) (match_dup 1))]
3262 /* Preserve memory attributes. */
3263 operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
3266 (define_insn "*pushsf_rex64"
3267 [(set (match_operand:SF 0 "push_operand" "=X,X,X")
3268 (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
3271 /* Anything else should be already split before reg-stack. */
3272 gcc_assert (which_alternative == 1);
3273 return "push{q}\t%q1";
3275 [(set_attr "type" "multi,push,multi")
3276 (set_attr "unit" "i387,*,*")
3277 (set_attr "mode" "SF,DI,SF")])
3279 (define_insn "*pushsf"
3280 [(set (match_operand:SF 0 "push_operand" "=<,<,<")
3281 (match_operand:SF 1 "general_no_elim_operand" "f,rmF,x"))]
3284 /* Anything else should be already split before reg-stack. */
3285 gcc_assert (which_alternative == 1);
3286 return "push{l}\t%1";
3288 [(set_attr "type" "multi,push,multi")
3289 (set_attr "unit" "i387,*,*")
3290 (set_attr "mode" "SF,SI,SF")])
3292 ;; %%% Kill this when call knows how to work this out.
3294 [(set (match_operand:SF 0 "push_operand")
3295 (match_operand:SF 1 "any_fp_register_operand"))]
3297 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
3298 (set (match_dup 0) (match_dup 1))]
3300 rtx op = XEXP (operands[0], 0);
3301 if (GET_CODE (op) == PRE_DEC)
3303 gcc_assert (!TARGET_64BIT);
3308 op = XEXP (XEXP (op, 1), 1);
3309 gcc_assert (CONST_INT_P (op));
3312 /* Preserve memory attributes. */
3313 operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
3317 [(set (match_operand:SF 0 "push_operand")
3318 (match_operand:SF 1 "memory_operand"))]
3320 && find_constant_src (insn)"
3321 [(set (match_dup 0) (match_dup 2))]
3322 "operands[2] = find_constant_src (curr_insn);")
3325 [(set (match_operand 0 "push_operand")
3326 (match_operand 1 "general_gr_operand"))]
3328 && (GET_MODE (operands[0]) == TFmode
3329 || GET_MODE (operands[0]) == XFmode
3330 || GET_MODE (operands[0]) == DFmode)"
3332 "ix86_split_long_move (operands); DONE;")
3334 ;; Floating point move instructions.
3336 (define_expand "movtf"
3337 [(set (match_operand:TF 0 "nonimmediate_operand")
3338 (match_operand:TF 1 "nonimmediate_operand"))]
3339 "TARGET_64BIT || TARGET_SSE"
3340 "ix86_expand_move (TFmode, operands); DONE;")
3342 (define_expand "mov<mode>"
3343 [(set (match_operand:X87MODEF 0 "nonimmediate_operand")
3344 (match_operand:X87MODEF 1 "general_operand"))]
3346 "ix86_expand_move (<MODE>mode, operands); DONE;")
3348 (define_insn "*movtf_internal"
3349 [(set (match_operand:TF 0 "nonimmediate_operand" "=v,v ,m,?*r ,!o")
3350 (match_operand:TF 1 "general_operand" "C ,vm,v,*roF,*rC"))]
3351 "(TARGET_64BIT || TARGET_SSE)
3352 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3353 && (lra_in_progress || reload_completed
3354 || !CONST_DOUBLE_P (operands[1])
3355 || ((optimize_function_for_size_p (cfun)
3356 || (ix86_cmodel == CM_LARGE || ix86_cmodel == CM_LARGE_PIC))
3357 && standard_sse_constant_p (operands[1], TFmode) == 1
3358 && !memory_operand (operands[0], TFmode))
3359 || (!TARGET_MEMORY_MISMATCH_STALL
3360 && memory_operand (operands[0], TFmode)))"
3362 switch (get_attr_type (insn))
3365 return standard_sse_constant_opcode (insn, operands);
3368 /* Handle misaligned load/store since we
3369 don't have movmisaligntf pattern. */
3370 if (misaligned_operand (operands[0], TFmode)
3371 || misaligned_operand (operands[1], TFmode))
3373 if (get_attr_mode (insn) == MODE_V4SF)
3374 return "%vmovups\t{%1, %0|%0, %1}";
3375 else if (TARGET_AVX512VL
3376 && (EXT_REX_SSE_REG_P (operands[0])
3377 || EXT_REX_SSE_REG_P (operands[1])))
3378 return "vmovdqu64\t{%1, %0|%0, %1}";
3380 return "%vmovdqu\t{%1, %0|%0, %1}";
3384 if (get_attr_mode (insn) == MODE_V4SF)
3385 return "%vmovaps\t{%1, %0|%0, %1}";
3386 else if (TARGET_AVX512VL
3387 && (EXT_REX_SSE_REG_P (operands[0])
3388 || EXT_REX_SSE_REG_P (operands[1])))
3389 return "vmovdqa64\t{%1, %0|%0, %1}";
3391 return "%vmovdqa\t{%1, %0|%0, %1}";
3401 [(set_attr "isa" "*,*,*,x64,x64")
3402 (set_attr "type" "sselog1,ssemov,ssemov,multi,multi")
3403 (set (attr "prefix")
3404 (if_then_else (eq_attr "type" "sselog1,ssemov")
3405 (const_string "maybe_vex")
3406 (const_string "orig")))
3408 (cond [(eq_attr "alternative" "3,4")
3410 (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
3411 (const_string "V4SF")
3412 (and (eq_attr "alternative" "2")
3413 (match_test "TARGET_SSE_TYPELESS_STORES"))
3414 (const_string "V4SF")
3415 (match_test "TARGET_AVX")
3417 (ior (not (match_test "TARGET_SSE2"))
3418 (match_test "optimize_function_for_size_p (cfun)"))
3419 (const_string "V4SF")
3421 (const_string "TI")))])
3424 [(set (match_operand:TF 0 "nonimmediate_gr_operand")
3425 (match_operand:TF 1 "general_gr_operand"))]
3428 "ix86_split_long_move (operands); DONE;")
3430 ;; Possible store forwarding (partial memory) stall
3431 ;; in alternatives 4, 6, 7 and 8.
3432 (define_insn "*movxf_internal"
3433 [(set (match_operand:XF 0 "nonimmediate_operand"
3434 "=f,m,f,?r ,!o,?*r ,!o,!o,!o,r ,o ,o")
3435 (match_operand:XF 1 "general_operand"
3436 "fm,f,G,roF,r ,*roF,*r,F ,C ,roF,rF,rC"))]
3437 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3438 && (lra_in_progress || reload_completed
3439 || !CONST_DOUBLE_P (operands[1])
3440 || ((optimize_function_for_size_p (cfun)
3441 || (ix86_cmodel == CM_LARGE || ix86_cmodel == CM_LARGE_PIC))
3442 && standard_80387_constant_p (operands[1]) > 0
3443 && !memory_operand (operands[0], XFmode))
3444 || (!TARGET_MEMORY_MISMATCH_STALL
3445 && memory_operand (operands[0], XFmode))
3446 || !TARGET_HARD_XF_REGS)"
3448 switch (get_attr_type (insn))
3451 if (which_alternative == 2)
3452 return standard_80387_constant_opcode (operands[1]);
3453 return output_387_reg_move (insn, operands);
3463 (cond [(eq_attr "alternative" "7,10")
3464 (const_string "nox64")
3465 (eq_attr "alternative" "8,11")
3466 (const_string "x64")
3468 (const_string "*")))
3470 (cond [(eq_attr "alternative" "3,4,5,6,7,8,9,10,11")
3471 (const_string "multi")
3473 (const_string "fmov")))
3475 (cond [(eq_attr "alternative" "3,4,5,6,7,8,9,10,11")
3476 (if_then_else (match_test "TARGET_64BIT")
3478 (const_string "SI"))
3480 (const_string "XF")))
3481 (set (attr "preferred_for_size")
3482 (cond [(eq_attr "alternative" "3,4")
3483 (symbol_ref "false")]
3484 (symbol_ref "true")))
3485 (set (attr "enabled")
3486 (cond [(eq_attr "alternative" "9,10,11")
3488 (match_test "TARGET_HARD_XF_REGS")
3489 (symbol_ref "false")
3491 (not (match_test "TARGET_HARD_XF_REGS"))
3492 (symbol_ref "false")
3494 (const_string "*")))])
3497 [(set (match_operand:XF 0 "nonimmediate_gr_operand")
3498 (match_operand:XF 1 "general_gr_operand"))]
3501 "ix86_split_long_move (operands); DONE;")
3503 ;; Possible store forwarding (partial memory) stall in alternatives 4, 6 and 7.
3504 (define_insn "*movdf_internal"
3505 [(set (match_operand:DF 0 "nonimmediate_operand"
3506 "=Yf*f,m ,Yf*f,?r ,!o,?*r ,!o,!o,?r,?m,?r,?r,v,v,v,m,*x,*x,*x,m ,r ,v,r ,o ,r ,m")
3507 (match_operand:DF 1 "general_operand"
3508 "Yf*fm,Yf*f,G ,roF,r ,*roF,*r,F ,rm,rC,C ,F ,C,v,m,v,C ,*x,m ,*x,v,r ,roF,rF,rmF,rC"))]
3509 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3510 && (lra_in_progress || reload_completed
3511 || !CONST_DOUBLE_P (operands[1])
3512 || ((optimize_function_for_size_p (cfun)
3513 || (ix86_cmodel == CM_LARGE || ix86_cmodel == CM_LARGE_PIC))
3514 && ((IS_STACK_MODE (DFmode)
3515 && standard_80387_constant_p (operands[1]) > 0)
3516 || (TARGET_SSE2 && TARGET_SSE_MATH
3517 && standard_sse_constant_p (operands[1], DFmode) == 1))
3518 && !memory_operand (operands[0], DFmode))
3519 || ((TARGET_64BIT || !TARGET_MEMORY_MISMATCH_STALL)
3520 && memory_operand (operands[0], DFmode))
3521 || !TARGET_HARD_DF_REGS)"
3523 switch (get_attr_type (insn))
3526 if (which_alternative == 2)
3527 return standard_80387_constant_opcode (operands[1]);
3528 return output_387_reg_move (insn, operands);
3534 if (get_attr_mode (insn) == MODE_SI)
3535 return "mov{l}\t{%1, %k0|%k0, %1}";
3536 else if (which_alternative == 11)
3537 return "movabs{q}\t{%1, %0|%0, %1}";
3539 return "mov{q}\t{%1, %0|%0, %1}";
3542 return standard_sse_constant_opcode (insn, operands);
3545 switch (get_attr_mode (insn))
3548 if (TARGET_AVX && REG_P (operands[0]) && REG_P (operands[1]))
3549 return "vmovsd\t{%d1, %0|%0, %d1}";
3550 return "%vmovsd\t{%1, %0|%0, %1}";
3553 return "%vmovaps\t{%1, %0|%0, %1}";
3555 return "vmovapd\t{%g1, %g0|%g0, %g1}";
3557 return "%vmovapd\t{%1, %0|%0, %1}";
3560 gcc_assert (!TARGET_AVX);
3561 return "movlps\t{%1, %0|%0, %1}";
3563 gcc_assert (!TARGET_AVX);
3564 return "movlpd\t{%1, %0|%0, %1}";
3567 /* Handle broken assemblers that require movd instead of movq. */
3568 if (!HAVE_AS_IX86_INTERUNIT_MOVQ
3569 && (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1])))
3570 return "%vmovd\t{%1, %0|%0, %1}";
3571 return "%vmovq\t{%1, %0|%0, %1}";
3582 (cond [(eq_attr "alternative" "3,4,5,6,7,22,23")
3583 (const_string "nox64")
3584 (eq_attr "alternative" "8,9,10,11,24,25")
3585 (const_string "x64")
3586 (eq_attr "alternative" "12,13,14,15")
3587 (const_string "sse2")
3588 (eq_attr "alternative" "20,21")
3589 (const_string "x64_sse2")
3591 (const_string "*")))
3593 (cond [(eq_attr "alternative" "0,1,2")
3594 (const_string "fmov")
3595 (eq_attr "alternative" "3,4,5,6,7,22,23")
3596 (const_string "multi")
3597 (eq_attr "alternative" "8,9,10,11,24,25")
3598 (const_string "imov")
3599 (eq_attr "alternative" "12,16")
3600 (const_string "sselog1")
3602 (const_string "ssemov")))
3604 (if_then_else (eq_attr "alternative" "11")
3606 (const_string "*")))
3607 (set (attr "length_immediate")
3608 (if_then_else (eq_attr "alternative" "11")
3610 (const_string "*")))
3611 (set (attr "prefix")
3612 (if_then_else (eq_attr "type" "sselog1,ssemov")
3613 (const_string "maybe_vex")
3614 (const_string "orig")))
3615 (set (attr "prefix_data16")
3617 (ior (and (eq_attr "type" "ssemov") (eq_attr "mode" "DI"))
3618 (eq_attr "mode" "V1DF"))
3620 (const_string "*")))
3622 (cond [(eq_attr "alternative" "3,4,5,6,7,10,22,23")
3624 (eq_attr "alternative" "8,9,11,20,21,24,25")
3627 /* xorps is one byte shorter for non-AVX targets. */
3628 (eq_attr "alternative" "12,16")
3629 (cond [(not (match_test "TARGET_SSE2"))
3630 (const_string "V4SF")
3631 (and (match_test "TARGET_AVX512F")
3632 (not (match_test "TARGET_PREFER_AVX256")))
3634 (match_test "TARGET_AVX")
3635 (const_string "V2DF")
3636 (match_test "optimize_function_for_size_p (cfun)")
3637 (const_string "V4SF")
3638 (match_test "TARGET_SSE_LOAD0_BY_PXOR")
3641 (const_string "V2DF"))
3643 /* For architectures resolving dependencies on
3644 whole SSE registers use movapd to break dependency
3645 chains, otherwise use short move to avoid extra work. */
3647 /* movaps is one byte shorter for non-AVX targets. */
3648 (eq_attr "alternative" "13,17")
3649 (cond [(and (ior (not (match_test "TARGET_PREFER_AVX256"))
3650 (not (match_test "TARGET_AVX512VL")))
3651 (ior (match_operand 0 "ext_sse_reg_operand")
3652 (match_operand 1 "ext_sse_reg_operand")))
3653 (const_string "V8DF")
3654 (ior (not (match_test "TARGET_SSE2"))
3655 (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL"))
3656 (const_string "V4SF")
3657 (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3658 (const_string "V2DF")
3659 (match_test "TARGET_AVX")
3661 (match_test "optimize_function_for_size_p (cfun)")
3662 (const_string "V4SF")
3664 (const_string "DF"))
3666 /* For architectures resolving dependencies on register
3667 parts we may avoid extra work to zero out upper part
3669 (eq_attr "alternative" "14,18")
3670 (cond [(not (match_test "TARGET_SSE2"))
3671 (const_string "V2SF")
3672 (match_test "TARGET_AVX")
3674 (match_test "TARGET_SSE_SPLIT_REGS")
3675 (const_string "V1DF")
3677 (const_string "DF"))
3679 (and (eq_attr "alternative" "15,19")
3680 (not (match_test "TARGET_SSE2")))
3681 (const_string "V2SF")
3683 (const_string "DF")))
3684 (set (attr "preferred_for_size")
3685 (cond [(eq_attr "alternative" "3,4")
3686 (symbol_ref "false")]
3687 (symbol_ref "true")))
3688 (set (attr "preferred_for_speed")
3689 (cond [(eq_attr "alternative" "3,4")
3690 (symbol_ref "TARGET_INTEGER_DFMODE_MOVES")
3691 (eq_attr "alternative" "20")
3692 (symbol_ref "TARGET_INTER_UNIT_MOVES_FROM_VEC")
3693 (eq_attr "alternative" "21")
3694 (symbol_ref "TARGET_INTER_UNIT_MOVES_TO_VEC")
3696 (symbol_ref "true")))
3697 (set (attr "enabled")
3698 (cond [(eq_attr "alternative" "22,23,24,25")
3700 (match_test "TARGET_HARD_DF_REGS")
3701 (symbol_ref "false")
3703 (not (match_test "TARGET_HARD_DF_REGS"))
3704 (symbol_ref "false")
3706 (const_string "*")))])
3709 [(set (match_operand:DF 0 "nonimmediate_gr_operand")
3710 (match_operand:DF 1 "general_gr_operand"))]
3711 "!TARGET_64BIT && reload_completed"
3713 "ix86_split_long_move (operands); DONE;")
3715 (define_insn "*movsf_internal"
3716 [(set (match_operand:SF 0 "nonimmediate_operand"
3717 "=Yf*f,m ,Yf*f,?r ,?m,v,v,v,m,?r,?v,!*y,!*y,!m,!r,!*y,r ,m")
3718 (match_operand:SF 1 "general_operand"
3719 "Yf*fm,Yf*f,G ,rmF,rF,C,v,m,v,v ,r ,*y ,m ,*y,*y,r ,rmF,rF"))]
3720 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3721 && (lra_in_progress || reload_completed
3722 || !CONST_DOUBLE_P (operands[1])
3723 || ((optimize_function_for_size_p (cfun)
3724 || (ix86_cmodel == CM_LARGE || ix86_cmodel == CM_LARGE_PIC))
3725 && ((IS_STACK_MODE (SFmode)
3726 && standard_80387_constant_p (operands[1]) > 0)
3727 || (TARGET_SSE && TARGET_SSE_MATH
3728 && standard_sse_constant_p (operands[1], SFmode) == 1)))
3729 || memory_operand (operands[0], SFmode)
3730 || !TARGET_HARD_SF_REGS)"
3732 switch (get_attr_type (insn))
3735 if (which_alternative == 2)
3736 return standard_80387_constant_opcode (operands[1]);
3737 return output_387_reg_move (insn, operands);
3740 return "mov{l}\t{%1, %0|%0, %1}";
3743 return standard_sse_constant_opcode (insn, operands);
3746 switch (get_attr_mode (insn))
3749 if (TARGET_AVX && REG_P (operands[0]) && REG_P (operands[1]))
3750 return "vmovss\t{%d1, %0|%0, %d1}";
3751 return "%vmovss\t{%1, %0|%0, %1}";
3754 return "vmovaps\t{%g1, %g0|%g0, %g1}";
3756 return "%vmovaps\t{%1, %0|%0, %1}";
3759 return "%vmovd\t{%1, %0|%0, %1}";
3766 switch (get_attr_mode (insn))
3769 return "movq\t{%1, %0|%0, %1}";
3771 return "movd\t{%1, %0|%0, %1}";
3782 (cond [(eq_attr "alternative" "14,15")
3783 (const_string "sse2")
3785 (const_string "*")))
3787 (cond [(eq_attr "alternative" "0,1,2")
3788 (const_string "fmov")
3789 (eq_attr "alternative" "3,4,16,17")
3790 (const_string "imov")
3791 (eq_attr "alternative" "5")
3792 (const_string "sselog1")
3793 (eq_attr "alternative" "11,12,13,14,15")
3794 (const_string "mmxmov")
3796 (const_string "ssemov")))
3797 (set (attr "prefix")
3798 (if_then_else (eq_attr "type" "sselog1,ssemov")
3799 (const_string "maybe_vex")
3800 (const_string "orig")))
3801 (set (attr "prefix_data16")
3802 (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
3804 (const_string "*")))
3806 (cond [(eq_attr "alternative" "3,4,9,10,12,13,14,15,16,17")
3808 (eq_attr "alternative" "11")
3810 (eq_attr "alternative" "5")
3811 (cond [(not (match_test "TARGET_SSE2"))
3812 (const_string "V4SF")
3813 (and (match_test "TARGET_AVX512F")
3814 (not (match_test "TARGET_PREFER_AVX256")))
3815 (const_string "V16SF")
3816 (match_test "TARGET_AVX")
3817 (const_string "V4SF")
3818 (match_test "optimize_function_for_size_p (cfun)")
3819 (const_string "V4SF")
3820 (match_test "TARGET_SSE_LOAD0_BY_PXOR")
3823 (const_string "V4SF"))
3825 /* For architectures resolving dependencies on
3826 whole SSE registers use APS move to break dependency
3827 chains, otherwise use short move to avoid extra work.
3829 Do the same for architectures resolving dependencies on
3830 the parts. While in DF mode it is better to always handle
3831 just register parts, the SF mode is different due to lack
3832 of instructions to load just part of the register. It is
3833 better to maintain the whole registers in single format
3834 to avoid problems on using packed logical operations. */
3835 (eq_attr "alternative" "6")
3836 (cond [(and (ior (not (match_test "TARGET_PREFER_AVX256"))
3837 (not (match_test "TARGET_AVX512VL")))
3838 (ior (match_operand 0 "ext_sse_reg_operand")
3839 (match_operand 1 "ext_sse_reg_operand")))
3840 (const_string "V16SF")
3841 (ior (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3842 (match_test "TARGET_SSE_SPLIT_REGS"))
3843 (const_string "V4SF")
3845 (const_string "SF"))
3847 (const_string "SF")))
3848 (set (attr "preferred_for_speed")
3849 (cond [(eq_attr "alternative" "9,14")
3850 (symbol_ref "TARGET_INTER_UNIT_MOVES_FROM_VEC")
3851 (eq_attr "alternative" "10,15")
3852 (symbol_ref "TARGET_INTER_UNIT_MOVES_TO_VEC")
3854 (symbol_ref "true")))
3855 (set (attr "enabled")
3856 (cond [(eq_attr "alternative" "16,17")
3858 (match_test "TARGET_HARD_SF_REGS")
3859 (symbol_ref "false")
3861 (not (match_test "TARGET_HARD_SF_REGS"))
3862 (symbol_ref "false")
3864 (const_string "*")))])
3867 [(set (match_operand 0 "any_fp_register_operand")
3868 (match_operand 1 "nonimmediate_operand"))]
3870 && (GET_MODE (operands[0]) == TFmode
3871 || GET_MODE (operands[0]) == XFmode
3872 || GET_MODE (operands[0]) == DFmode
3873 || GET_MODE (operands[0]) == SFmode)
3874 && ix86_standard_x87sse_constant_load_p (insn, operands[0])"
3875 [(set (match_dup 0) (match_dup 2))]
3876 "operands[2] = find_constant_src (curr_insn);")
3879 [(set (match_operand 0 "any_fp_register_operand")
3880 (float_extend (match_operand 1 "nonimmediate_operand")))]
3882 && (GET_MODE (operands[0]) == TFmode
3883 || GET_MODE (operands[0]) == XFmode
3884 || GET_MODE (operands[0]) == DFmode)
3885 && ix86_standard_x87sse_constant_load_p (insn, operands[0])"
3886 [(set (match_dup 0) (match_dup 2))]
3887 "operands[2] = find_constant_src (curr_insn);")
3889 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
3891 [(set (match_operand:X87MODEF 0 "fp_register_operand")
3892 (match_operand:X87MODEF 1 "immediate_operand"))]
3894 && (standard_80387_constant_p (operands[1]) == 8
3895 || standard_80387_constant_p (operands[1]) == 9)"
3896 [(set (match_dup 0)(match_dup 1))
3898 (neg:X87MODEF (match_dup 0)))]
3900 if (real_isnegzero (CONST_DOUBLE_REAL_VALUE (operands[1])))
3901 operands[1] = CONST0_RTX (<MODE>mode);
3903 operands[1] = CONST1_RTX (<MODE>mode);
3906 (define_insn "swapxf"
3907 [(set (match_operand:XF 0 "register_operand" "+f")
3908 (match_operand:XF 1 "register_operand" "+f"))
3913 if (STACK_TOP_P (operands[0]))
3918 [(set_attr "type" "fxch")
3919 (set_attr "mode" "XF")])
3921 (define_insn "*swap<mode>"
3922 [(set (match_operand:MODEF 0 "fp_register_operand" "+f")
3923 (match_operand:MODEF 1 "fp_register_operand" "+f"))
3926 "TARGET_80387 || reload_completed"
3928 if (STACK_TOP_P (operands[0]))
3933 [(set_attr "type" "fxch")
3934 (set_attr "mode" "<MODE>")])
3936 ;; Zero extension instructions
3938 (define_expand "zero_extendsidi2"
3939 [(set (match_operand:DI 0 "nonimmediate_operand")
3940 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand")))])
3942 (define_insn "*zero_extendsidi2"
3943 [(set (match_operand:DI 0 "nonimmediate_operand"
3944 "=r,?r,?o,r ,o,?*y,?!*y,$r,$v,$x,*x,*v,*r")
3946 (match_operand:SI 1 "x86_64_zext_operand"
3947 "0 ,rm,r ,rmWz,0,r ,m ,v ,r ,m ,*x,*v,*k")))]
3950 switch (get_attr_type (insn))
3953 if (ix86_use_lea_for_mov (insn, operands))
3954 return "lea{l}\t{%E1, %k0|%k0, %E1}";
3956 return "mov{l}\t{%1, %k0|%k0, %1}";
3962 return "movd\t{%1, %0|%0, %1}";
3965 if (SSE_REG_P (operands[0]) && SSE_REG_P (operands[1]))
3967 if (EXT_REX_SSE_REG_P (operands[0])
3968 || EXT_REX_SSE_REG_P (operands[1]))
3969 return "vpmovzxdq\t{%t1, %g0|%g0, %t1}";
3971 return "%vpmovzxdq\t{%1, %0|%0, %1}";
3974 if (GENERAL_REG_P (operands[0]))
3975 return "%vmovd\t{%1, %k0|%k0, %1}";
3977 return "%vmovd\t{%1, %0|%0, %1}";
3980 return "kmovd\t{%1, %k0|%k0, %1}";
3987 (cond [(eq_attr "alternative" "0,1,2")
3988 (const_string "nox64")
3989 (eq_attr "alternative" "3")
3990 (const_string "x64")
3991 (eq_attr "alternative" "7,8,9")
3992 (const_string "sse2")
3993 (eq_attr "alternative" "10")
3994 (const_string "sse4")
3995 (eq_attr "alternative" "11")
3996 (const_string "avx512f")
3997 (eq_attr "alternative" "12")
3998 (const_string "x64_avx512bw")
4000 (const_string "*")))
4002 (cond [(eq_attr "alternative" "0,1,2,4")
4003 (const_string "multi")
4004 (eq_attr "alternative" "5,6")
4005 (const_string "mmxmov")
4006 (eq_attr "alternative" "7")
4007 (if_then_else (match_test "TARGET_64BIT")
4008 (const_string "ssemov")
4009 (const_string "multi"))
4010 (eq_attr "alternative" "8,9,10,11")
4011 (const_string "ssemov")
4012 (eq_attr "alternative" "12")
4013 (const_string "mskmov")
4015 (const_string "imovx")))
4016 (set (attr "prefix_extra")
4017 (if_then_else (eq_attr "alternative" "10,11")
4019 (const_string "*")))
4020 (set (attr "prefix")
4021 (if_then_else (eq_attr "type" "ssemov")
4022 (const_string "maybe_vex")
4023 (const_string "orig")))
4024 (set (attr "prefix_0f")
4025 (if_then_else (eq_attr "type" "imovx")
4027 (const_string "*")))
4029 (cond [(eq_attr "alternative" "5,6")
4031 (and (eq_attr "alternative" "7")
4032 (match_test "TARGET_64BIT"))
4034 (eq_attr "alternative" "8,10,11")
4037 (const_string "SI")))
4038 (set (attr "preferred_for_speed")
4039 (cond [(eq_attr "alternative" "7")
4040 (symbol_ref "TARGET_INTER_UNIT_MOVES_FROM_VEC")
4041 (eq_attr "alternative" "5,8")
4042 (symbol_ref "TARGET_INTER_UNIT_MOVES_TO_VEC")
4044 (symbol_ref "true")))])
4047 [(set (match_operand:DI 0 "memory_operand")
4048 (zero_extend:DI (match_operand:SI 1 "memory_operand")))]
4050 [(set (match_dup 4) (const_int 0))]
4051 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
4054 [(set (match_operand:DI 0 "general_reg_operand")
4055 (zero_extend:DI (match_operand:SI 1 "general_reg_operand")))]
4056 "!TARGET_64BIT && reload_completed
4057 && REGNO (operands[0]) == REGNO (operands[1])"
4058 [(set (match_dup 4) (const_int 0))]
4059 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
4062 [(set (match_operand:DI 0 "nonimmediate_gr_operand")
4063 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand")))]
4064 "!TARGET_64BIT && reload_completed
4065 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
4066 [(set (match_dup 3) (match_dup 1))
4067 (set (match_dup 4) (const_int 0))]
4068 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
4070 (define_mode_attr kmov_isa
4071 [(QI "avx512dq") (HI "avx512f") (SI "avx512bw") (DI "avx512bw")])
4073 (define_insn "zero_extend<mode>di2"
4074 [(set (match_operand:DI 0 "register_operand" "=r,*r")
4076 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m,*k")))]
4079 movz{<imodesuffix>l|x}\t{%1, %k0|%k0, %1}
4080 kmov<mskmodesuffix>\t{%1, %k0|%k0, %1}"
4081 [(set_attr "isa" "*,<kmov_isa>")
4082 (set_attr "type" "imovx,mskmov")
4083 (set_attr "mode" "SI,<MODE>")])
4085 (define_expand "zero_extend<mode>si2"
4086 [(set (match_operand:SI 0 "register_operand")
4087 (zero_extend:SI (match_operand:SWI12 1 "nonimmediate_operand")))]
4090 if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
4092 operands[1] = force_reg (<MODE>mode, operands[1]);
4093 emit_insn (gen_zero_extend<mode>si2_and (operands[0], operands[1]));
4098 (define_insn_and_split "zero_extend<mode>si2_and"
4099 [(set (match_operand:SI 0 "register_operand" "=r,?&<r>")
4101 (match_operand:SWI12 1 "nonimmediate_operand" "0,<r>m")))
4102 (clobber (reg:CC FLAGS_REG))]
4103 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
4105 "&& reload_completed"
4106 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (match_dup 2)))
4107 (clobber (reg:CC FLAGS_REG))])]
4109 if (!REG_P (operands[1])
4110 || REGNO (operands[0]) != REGNO (operands[1]))
4112 ix86_expand_clear (operands[0]);
4114 gcc_assert (!TARGET_PARTIAL_REG_STALL);
4115 emit_insn (gen_movstrict<mode>
4116 (gen_lowpart (<MODE>mode, operands[0]), operands[1]));
4120 operands[2] = GEN_INT (GET_MODE_MASK (<MODE>mode));
4122 [(set_attr "type" "alu1")
4123 (set_attr "mode" "SI")])
4125 (define_insn "*zero_extend<mode>si2"
4126 [(set (match_operand:SI 0 "register_operand" "=r,*r")
4128 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m,*k")))]
4129 "!(TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))"
4131 movz{<imodesuffix>l|x}\t{%1, %0|%0, %1}
4132 kmov<mskmodesuffix>\t{%1, %0|%0, %1}"
4133 [(set_attr "isa" "*,<kmov_isa>")
4134 (set_attr "type" "imovx,mskmov")
4135 (set_attr "mode" "SI,<MODE>")])
4137 (define_expand "zero_extendqihi2"
4138 [(set (match_operand:HI 0 "register_operand")
4139 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand")))]
4142 if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
4144 operands[1] = force_reg (QImode, operands[1]);
4145 emit_insn (gen_zero_extendqihi2_and (operands[0], operands[1]));
4150 (define_insn_and_split "zero_extendqihi2_and"
4151 [(set (match_operand:HI 0 "register_operand" "=r,?&q")
4152 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
4153 (clobber (reg:CC FLAGS_REG))]
4154 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
4156 "&& reload_completed"
4157 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
4158 (clobber (reg:CC FLAGS_REG))])]
4160 if (!REG_P (operands[1])
4161 || REGNO (operands[0]) != REGNO (operands[1]))
4163 ix86_expand_clear (operands[0]);
4165 gcc_assert (!TARGET_PARTIAL_REG_STALL);
4166 emit_insn (gen_movstrictqi
4167 (gen_lowpart (QImode, operands[0]), operands[1]));
4171 operands[0] = gen_lowpart (SImode, operands[0]);
4173 [(set_attr "type" "alu1")
4174 (set_attr "mode" "SI")])
4176 ; zero extend to SImode to avoid partial register stalls
4177 (define_insn "*zero_extendqihi2"
4178 [(set (match_operand:HI 0 "register_operand" "=r,*r")
4179 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,*k")))]
4180 "!(TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))"
4182 movz{bl|x}\t{%1, %k0|%k0, %1}
4183 kmovb\t{%1, %k0|%k0, %1}"
4184 [(set_attr "isa" "*,avx512dq")
4185 (set_attr "type" "imovx,mskmov")
4186 (set_attr "mode" "SI,QI")])
4188 (define_insn_and_split "*zext<mode>_doubleword_and"
4189 [(set (match_operand:DI 0 "register_operand" "=&<r>")
4190 (zero_extend:DI (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
4191 "!TARGET_64BIT && TARGET_STV && TARGET_SSE2
4192 && TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
4194 "&& reload_completed && GENERAL_REG_P (operands[0])"
4195 [(set (match_dup 2) (const_int 0))]
4197 split_double_mode (DImode, &operands[0], 1, &operands[0], &operands[2]);
4199 emit_move_insn (operands[0], const0_rtx);
4201 gcc_assert (!TARGET_PARTIAL_REG_STALL);
4202 emit_insn (gen_movstrict<mode>
4203 (gen_lowpart (<MODE>mode, operands[0]), operands[1]));
4206 (define_insn_and_split "*zext<mode>_doubleword"
4207 [(set (match_operand:DI 0 "register_operand" "=r")
4208 (zero_extend:DI (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
4209 "!TARGET_64BIT && TARGET_STV && TARGET_SSE2
4210 && !(TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))"
4212 "&& reload_completed && GENERAL_REG_P (operands[0])"
4213 [(set (match_dup 0) (zero_extend:SI (match_dup 1)))
4214 (set (match_dup 2) (const_int 0))]
4215 "split_double_mode (DImode, &operands[0], 1, &operands[0], &operands[2]);")
4217 (define_insn_and_split "*zextsi_doubleword"
4218 [(set (match_operand:DI 0 "register_operand" "=r")
4219 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm")))]
4220 "!TARGET_64BIT && TARGET_STV && TARGET_SSE2"
4222 "&& reload_completed && GENERAL_REG_P (operands[0])"
4223 [(set (match_dup 0) (match_dup 1))
4224 (set (match_dup 2) (const_int 0))]
4225 "split_double_mode (DImode, &operands[0], 1, &operands[0], &operands[2]);")
4227 ;; Sign extension instructions
4229 (define_expand "extendsidi2"
4230 [(set (match_operand:DI 0 "register_operand")
4231 (sign_extend:DI (match_operand:SI 1 "register_operand")))]
4236 emit_insn (gen_extendsidi2_1 (operands[0], operands[1]));
4241 (define_insn "*extendsidi2_rex64"
4242 [(set (match_operand:DI 0 "register_operand" "=*a,r")
4243 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
4247 movs{lq|x}\t{%1, %0|%0, %1}"
4248 [(set_attr "type" "imovx")
4249 (set_attr "mode" "DI")
4250 (set_attr "prefix_0f" "0")
4251 (set_attr "modrm" "0,1")])
4253 (define_insn "extendsidi2_1"
4254 [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
4255 (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
4256 (clobber (reg:CC FLAGS_REG))
4257 (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
4261 ;; Split the memory case. If the source register doesn't die, it will stay
4262 ;; this way, if it does die, following peephole2s take care of it.
4264 [(set (match_operand:DI 0 "memory_operand")
4265 (sign_extend:DI (match_operand:SI 1 "register_operand")))
4266 (clobber (reg:CC FLAGS_REG))
4267 (clobber (match_operand:SI 2 "register_operand"))]
4271 split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
4273 emit_move_insn (operands[3], operands[1]);
4275 /* Generate a cltd if possible and doing so it profitable. */
4276 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
4277 && REGNO (operands[1]) == AX_REG
4278 && REGNO (operands[2]) == DX_REG)
4280 emit_insn (gen_ashrsi3_cvt (operands[2], operands[1], GEN_INT (31)));
4284 emit_move_insn (operands[2], operands[1]);
4285 emit_insn (gen_ashrsi3_cvt (operands[2], operands[2], GEN_INT (31)));
4287 emit_move_insn (operands[4], operands[2]);
4291 ;; Peepholes for the case where the source register does die, after
4292 ;; being split with the above splitter.
4294 [(set (match_operand:SI 0 "memory_operand")
4295 (match_operand:SI 1 "general_reg_operand"))
4296 (set (match_operand:SI 2 "general_reg_operand") (match_dup 1))
4297 (parallel [(set (match_dup 2)
4298 (ashiftrt:SI (match_dup 2) (const_int 31)))
4299 (clobber (reg:CC FLAGS_REG))])
4300 (set (match_operand:SI 3 "memory_operand") (match_dup 2))]
4301 "REGNO (operands[1]) != REGNO (operands[2])
4302 && peep2_reg_dead_p (2, operands[1])
4303 && peep2_reg_dead_p (4, operands[2])
4304 && !reg_mentioned_p (operands[2], operands[3])"
4305 [(set (match_dup 0) (match_dup 1))
4306 (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
4307 (clobber (reg:CC FLAGS_REG))])
4308 (set (match_dup 3) (match_dup 1))])
4311 [(set (match_operand:SI 0 "memory_operand")
4312 (match_operand:SI 1 "general_reg_operand"))
4313 (parallel [(set (match_operand:SI 2 "general_reg_operand")
4314 (ashiftrt:SI (match_dup 1) (const_int 31)))
4315 (clobber (reg:CC FLAGS_REG))])
4316 (set (match_operand:SI 3 "memory_operand") (match_dup 2))]
4317 "/* cltd is shorter than sarl $31, %eax */
4318 !optimize_function_for_size_p (cfun)
4319 && REGNO (operands[1]) == AX_REG
4320 && REGNO (operands[2]) == DX_REG
4321 && peep2_reg_dead_p (2, operands[1])
4322 && peep2_reg_dead_p (3, operands[2])
4323 && !reg_mentioned_p (operands[2], operands[3])"
4324 [(set (match_dup 0) (match_dup 1))
4325 (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
4326 (clobber (reg:CC FLAGS_REG))])
4327 (set (match_dup 3) (match_dup 1))])
4329 ;; Extend to register case. Optimize case where source and destination
4330 ;; registers match and cases where we can use cltd.
4332 [(set (match_operand:DI 0 "register_operand")
4333 (sign_extend:DI (match_operand:SI 1 "register_operand")))
4334 (clobber (reg:CC FLAGS_REG))
4335 (clobber (match_scratch:SI 2))]
4339 split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
4341 if (REGNO (operands[3]) != REGNO (operands[1]))
4342 emit_move_insn (operands[3], operands[1]);
4344 /* Generate a cltd if possible and doing so it profitable. */
4345 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
4346 && REGNO (operands[3]) == AX_REG
4347 && REGNO (operands[4]) == DX_REG)
4349 emit_insn (gen_ashrsi3_cvt (operands[4], operands[3], GEN_INT (31)));
4353 if (REGNO (operands[4]) != REGNO (operands[1]))
4354 emit_move_insn (operands[4], operands[1]);
4356 emit_insn (gen_ashrsi3_cvt (operands[4], operands[4], GEN_INT (31)));
4360 (define_insn "extend<mode>di2"
4361 [(set (match_operand:DI 0 "register_operand" "=r")
4363 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
4365 "movs{<imodesuffix>q|x}\t{%1, %0|%0, %1}"
4366 [(set_attr "type" "imovx")
4367 (set_attr "mode" "DI")])
4369 (define_insn "extendhisi2"
4370 [(set (match_operand:SI 0 "register_operand" "=*a,r")
4371 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
4374 switch (get_attr_prefix_0f (insn))
4377 return "{cwtl|cwde}";
4379 return "movs{wl|x}\t{%1, %0|%0, %1}";
4382 [(set_attr "type" "imovx")
4383 (set_attr "mode" "SI")
4384 (set (attr "prefix_0f")
4385 ;; movsx is short decodable while cwtl is vector decoded.
4386 (if_then_else (and (eq_attr "cpu" "!k6")
4387 (eq_attr "alternative" "0"))
4389 (const_string "1")))
4390 (set (attr "znver1_decode")
4391 (if_then_else (eq_attr "prefix_0f" "0")
4392 (const_string "double")
4393 (const_string "direct")))
4395 (if_then_else (eq_attr "prefix_0f" "0")
4397 (const_string "1")))])
4399 (define_insn "*extendhisi2_zext"
4400 [(set (match_operand:DI 0 "register_operand" "=*a,r")
4403 (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
4406 switch (get_attr_prefix_0f (insn))
4409 return "{cwtl|cwde}";
4411 return "movs{wl|x}\t{%1, %k0|%k0, %1}";
4414 [(set_attr "type" "imovx")
4415 (set_attr "mode" "SI")
4416 (set (attr "prefix_0f")
4417 ;; movsx is short decodable while cwtl is vector decoded.
4418 (if_then_else (and (eq_attr "cpu" "!k6")
4419 (eq_attr "alternative" "0"))
4421 (const_string "1")))
4423 (if_then_else (eq_attr "prefix_0f" "0")
4425 (const_string "1")))])
4427 (define_insn "extendqisi2"
4428 [(set (match_operand:SI 0 "register_operand" "=r")
4429 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
4431 "movs{bl|x}\t{%1, %0|%0, %1}"
4432 [(set_attr "type" "imovx")
4433 (set_attr "mode" "SI")])
4435 (define_insn "*extendqisi2_zext"
4436 [(set (match_operand:DI 0 "register_operand" "=r")
4438 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
4440 "movs{bl|x}\t{%1, %k0|%k0, %1}"
4441 [(set_attr "type" "imovx")
4442 (set_attr "mode" "SI")])
4444 (define_insn "extendqihi2"
4445 [(set (match_operand:HI 0 "register_operand" "=*a,r")
4446 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
4449 switch (get_attr_prefix_0f (insn))
4452 return "{cbtw|cbw}";
4454 return "movs{bw|x}\t{%1, %0|%0, %1}";
4457 [(set_attr "type" "imovx")
4458 (set_attr "mode" "HI")
4459 (set (attr "prefix_0f")
4460 ;; movsx is short decodable while cwtl is vector decoded.
4461 (if_then_else (and (eq_attr "cpu" "!k6")
4462 (eq_attr "alternative" "0"))
4464 (const_string "1")))
4466 (if_then_else (eq_attr "prefix_0f" "0")
4468 (const_string "1")))])
4470 ;; Conversions between float and double.
4472 ;; These are all no-ops in the model used for the 80387.
4473 ;; So just emit moves.
4475 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
4477 [(set (match_operand:DF 0 "push_operand")
4478 (float_extend:DF (match_operand:SF 1 "fp_register_operand")))]
4480 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
4481 (set (mem:DF (reg:P SP_REG)) (float_extend:DF (match_dup 1)))])
4484 [(set (match_operand:XF 0 "push_operand")
4485 (float_extend:XF (match_operand:MODEF 1 "fp_register_operand")))]
4487 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
4488 (set (mem:XF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
4489 "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
4491 (define_expand "extendsfdf2"
4492 [(set (match_operand:DF 0 "nonimm_ssenomem_operand")
4493 (float_extend:DF (match_operand:SF 1 "general_operand")))]
4494 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4496 /* ??? Needed for compress_float_constant since all fp constants
4497 are TARGET_LEGITIMATE_CONSTANT_P. */
4498 if (CONST_DOUBLE_P (operands[1]))
4500 if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
4501 && standard_80387_constant_p (operands[1]) > 0)
4503 operands[1] = simplify_const_unary_operation
4504 (FLOAT_EXTEND, DFmode, operands[1], SFmode);
4505 emit_move_insn_1 (operands[0], operands[1]);
4508 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
4512 /* For converting SF(xmm2) to DF(xmm1), use the following code instead of
4514 unpcklps xmm2,xmm2 ; packed conversion might crash on signaling NaNs
4516 We do the conversion post reload to avoid producing of 128bit spills
4517 that might lead to ICE on 32bit target. The sequence unlikely combine
4520 [(set (match_operand:DF 0 "sse_reg_operand")
4522 (match_operand:SF 1 "nonimmediate_operand")))]
4523 "TARGET_USE_VECTOR_FP_CONVERTS
4524 && optimize_insn_for_speed_p ()
4526 && (!EXT_REX_SSE_REG_P (operands[0])
4527 || TARGET_AVX512VL)"
4532 (parallel [(const_int 0) (const_int 1)]))))]
4534 operands[2] = lowpart_subreg (V2DFmode, operands[0], DFmode);
4535 operands[3] = lowpart_subreg (V4SFmode, operands[0], DFmode);
4536 /* Use movss for loading from memory, unpcklps reg, reg for registers.
4537 Try to avoid move when unpacking can be done in source. */
4538 if (REG_P (operands[1]))
4540 /* If it is unsafe to overwrite upper half of source, we need
4541 to move to destination and unpack there. */
4542 if (REGNO (operands[0]) != REGNO (operands[1])
4543 || (EXT_REX_SSE_REG_P (operands[1])
4544 && !TARGET_AVX512VL))
4546 rtx tmp = lowpart_subreg (SFmode, operands[0], DFmode);
4547 emit_move_insn (tmp, operands[1]);
4550 operands[3] = lowpart_subreg (V4SFmode, operands[1], SFmode);
4551 /* FIXME: vec_interleave_lowv4sf for AVX512VL should allow
4552 =v, v, then vbroadcastss will be only needed for AVX512F without
4554 if (!EXT_REX_SSE_REGNO_P (REGNO (operands[3])))
4555 emit_insn (gen_vec_interleave_lowv4sf (operands[3], operands[3],
4559 rtx tmp = lowpart_subreg (V16SFmode, operands[3], V4SFmode);
4560 emit_insn (gen_avx512f_vec_dupv16sf_1 (tmp, tmp));
4564 emit_insn (gen_vec_setv4sf_0 (operands[3],
4565 CONST0_RTX (V4SFmode), operands[1]));
4568 ;; It's more profitable to split and then extend in the same register.
4570 [(set (match_operand:DF 0 "sse_reg_operand")
4572 (match_operand:SF 1 "memory_operand")))]
4573 "TARGET_SPLIT_MEM_OPND_FOR_FP_CONVERTS
4574 && optimize_insn_for_speed_p ()"
4575 [(set (match_dup 2) (match_dup 1))
4576 (set (match_dup 0) (float_extend:DF (match_dup 2)))]
4577 "operands[2] = lowpart_subreg (SFmode, operands[0], DFmode);")
4579 (define_insn "*extendsfdf2"
4580 [(set (match_operand:DF 0 "nonimm_ssenomem_operand" "=f,m,v")
4582 (match_operand:SF 1 "nonimmediate_operand" "fm,f,vm")))]
4583 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4585 switch (which_alternative)
4589 return output_387_reg_move (insn, operands);
4592 return "%vcvtss2sd\t{%1, %d0|%d0, %1}";
4598 [(set_attr "type" "fmov,fmov,ssecvt")
4599 (set_attr "prefix" "orig,orig,maybe_vex")
4600 (set_attr "mode" "SF,XF,DF")
4601 (set (attr "enabled")
4603 (match_test ("TARGET_SSE2 && TARGET_SSE_MATH"))
4605 (eq_attr "alternative" "0,1")
4606 (symbol_ref "TARGET_MIX_SSE_I387")
4607 (symbol_ref "true"))
4609 (eq_attr "alternative" "0,1")
4611 (symbol_ref "false"))))])
4613 (define_expand "extend<mode>xf2"
4614 [(set (match_operand:XF 0 "nonimmediate_operand")
4615 (float_extend:XF (match_operand:MODEF 1 "general_operand")))]
4618 /* ??? Needed for compress_float_constant since all fp constants
4619 are TARGET_LEGITIMATE_CONSTANT_P. */
4620 if (CONST_DOUBLE_P (operands[1]))
4622 if (standard_80387_constant_p (operands[1]) > 0)
4624 operands[1] = simplify_const_unary_operation
4625 (FLOAT_EXTEND, XFmode, operands[1], <MODE>mode);
4626 emit_move_insn_1 (operands[0], operands[1]);
4629 operands[1] = validize_mem (force_const_mem (<MODE>mode, operands[1]));
4633 (define_insn "*extend<mode>xf2_i387"
4634 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
4636 (match_operand:MODEF 1 "nonimmediate_operand" "fm,f")))]
4638 "* return output_387_reg_move (insn, operands);"
4639 [(set_attr "type" "fmov")
4640 (set_attr "mode" "<MODE>,XF")])
4642 ;; %%% This seems like bad news.
4643 ;; This cannot output into an f-reg because there is no way to be sure
4644 ;; of truncating in that case. Otherwise this is just like a simple move
4645 ;; insn. So we pretend we can output to a reg in order to get better
4646 ;; register preferencing, but we really use a stack slot.
4648 ;; Conversion from DFmode to SFmode.
4650 (define_expand "truncdfsf2"
4651 [(set (match_operand:SF 0 "nonimmediate_operand")
4653 (match_operand:DF 1 "nonimmediate_operand")))]
4654 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4656 if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
4658 else if (flag_unsafe_math_optimizations)
4662 rtx temp = assign_386_stack_local (SFmode, SLOT_TEMP);
4663 emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
4668 /* For converting DF(xmm2) to SF(xmm1), use the following code instead of
4670 unpcklpd xmm2,xmm2 ; packed conversion might crash on signaling NaNs
4672 We do the conversion post reload to avoid producing of 128bit spills
4673 that might lead to ICE on 32bit target. The sequence unlikely combine
4676 [(set (match_operand:SF 0 "sse_reg_operand")
4678 (match_operand:DF 1 "nonimmediate_operand")))]
4679 "TARGET_USE_VECTOR_FP_CONVERTS
4680 && optimize_insn_for_speed_p ()
4682 && (!EXT_REX_SSE_REG_P (operands[0])
4683 || TARGET_AVX512VL)"
4686 (float_truncate:V2SF
4690 operands[2] = lowpart_subreg (V4SFmode, operands[0], SFmode);
4691 operands[3] = CONST0_RTX (V2SFmode);
4692 operands[4] = lowpart_subreg (V2DFmode, operands[0], SFmode);
4693 /* Use movsd for loading from memory, unpcklpd for registers.
4694 Try to avoid move when unpacking can be done in source, or SSE3
4695 movddup is available. */
4696 if (REG_P (operands[1]))
4699 && REGNO (operands[0]) != REGNO (operands[1]))
4701 rtx tmp = lowpart_subreg (DFmode, operands[0], SFmode);
4702 emit_move_insn (tmp, operands[1]);
4705 else if (!TARGET_SSE3)
4706 operands[4] = lowpart_subreg (V2DFmode, operands[1], DFmode);
4707 emit_insn (gen_vec_dupv2df (operands[4], operands[1]));
4710 emit_insn (gen_vec_concatv2df (operands[4], operands[1],
4711 CONST0_RTX (DFmode)));
4714 ;; It's more profitable to split and then extend in the same register.
4716 [(set (match_operand:SF 0 "sse_reg_operand")
4718 (match_operand:DF 1 "memory_operand")))]
4719 "TARGET_SPLIT_MEM_OPND_FOR_FP_CONVERTS
4720 && optimize_insn_for_speed_p ()"
4721 [(set (match_dup 2) (match_dup 1))
4722 (set (match_dup 0) (float_truncate:SF (match_dup 2)))]
4723 "operands[2] = lowpart_subreg (DFmode, operands[0], SFmode);")
4725 (define_expand "truncdfsf2_with_temp"
4726 [(parallel [(set (match_operand:SF 0)
4727 (float_truncate:SF (match_operand:DF 1)))
4728 (clobber (match_operand:SF 2))])])
4730 ;; SSE alternative doesn't depend on flag_unsafe_math_optimizations,
4731 ;; because nothing we do there is unsafe.
4732 (define_insn "*truncdfsf_fast_mixed"
4733 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm,v")
4735 (match_operand:DF 1 "nonimmediate_operand" "f ,vm")))]
4736 "TARGET_SSE2 && TARGET_SSE_MATH"
4738 switch (which_alternative)
4741 return output_387_reg_move (insn, operands);
4743 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4748 [(set_attr "type" "fmov,ssecvt")
4749 (set_attr "prefix" "orig,maybe_vex")
4750 (set_attr "mode" "SF")
4751 (set (attr "enabled")
4752 (cond [(eq_attr "alternative" "0")
4753 (symbol_ref "TARGET_MIX_SSE_I387
4754 && flag_unsafe_math_optimizations")
4756 (symbol_ref "true")))])
4758 (define_insn "*truncdfsf_fast_i387"
4759 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm")
4761 (match_operand:DF 1 "nonimmediate_operand" "f")))]
4762 "TARGET_80387 && flag_unsafe_math_optimizations"
4763 "* return output_387_reg_move (insn, operands);"
4764 [(set_attr "type" "fmov")
4765 (set_attr "mode" "SF")])
4767 (define_insn "*truncdfsf_mixed"
4768 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,v ,?f,?v,?*r")
4770 (match_operand:DF 1 "nonimmediate_operand" "f ,vm,f ,f ,f")))
4771 (clobber (match_operand:SF 2 "memory_operand" "=X,X ,m ,m ,m"))]
4772 "TARGET_MIX_SSE_I387"
4774 switch (which_alternative)
4777 return output_387_reg_move (insn, operands);
4779 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4785 [(set_attr "isa" "*,sse2,*,*,*")
4786 (set_attr "type" "fmov,ssecvt,multi,multi,multi")
4787 (set_attr "unit" "*,*,i387,i387,i387")
4788 (set_attr "prefix" "orig,maybe_vex,orig,orig,orig")
4789 (set_attr "mode" "SF")])
4791 (define_insn "*truncdfsf_i387"
4792 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?v,?*r")
4794 (match_operand:DF 1 "nonimmediate_operand" "f ,f ,f ,f")))
4795 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,m ,m"))]
4798 switch (which_alternative)
4801 return output_387_reg_move (insn, operands);
4807 [(set_attr "type" "fmov,multi,multi,multi")
4808 (set_attr "unit" "*,i387,i387,i387")
4809 (set_attr "mode" "SF")])
4811 (define_insn "*truncdfsf2_i387_1"
4812 [(set (match_operand:SF 0 "memory_operand" "=m")
4814 (match_operand:DF 1 "register_operand" "f")))]
4816 && !(TARGET_SSE2 && TARGET_SSE_MATH)
4817 && !TARGET_MIX_SSE_I387"
4818 "* return output_387_reg_move (insn, operands);"
4819 [(set_attr "type" "fmov")
4820 (set_attr "mode" "SF")])
4823 [(set (match_operand:SF 0 "register_operand")
4825 (match_operand:DF 1 "fp_register_operand")))
4826 (clobber (match_operand 2))]
4828 [(set (match_dup 2) (match_dup 1))
4829 (set (match_dup 0) (match_dup 2))]
4830 "operands[1] = gen_rtx_REG (SFmode, REGNO (operands[1]));")
4832 ;; Conversion from XFmode to {SF,DF}mode
4834 (define_expand "truncxf<mode>2"
4835 [(parallel [(set (match_operand:MODEF 0 "nonimmediate_operand")
4836 (float_truncate:MODEF
4837 (match_operand:XF 1 "register_operand")))
4838 (clobber (match_dup 2))])]
4841 if (flag_unsafe_math_optimizations)
4843 rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (<MODE>mode);
4844 emit_insn (gen_truncxf<mode>2_i387_noop (reg, operands[1]));
4845 if (reg != operands[0])
4846 emit_move_insn (operands[0], reg);
4850 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4853 (define_insn "*truncxfsf2_mixed"
4854 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?v,?*r")
4856 (match_operand:XF 1 "register_operand" "f ,f ,f ,f")))
4857 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,m ,m"))]
4860 gcc_assert (!which_alternative);
4861 return output_387_reg_move (insn, operands);
4863 [(set_attr "type" "fmov,multi,multi,multi")
4864 (set_attr "unit" "*,i387,i387,i387")
4865 (set_attr "mode" "SF")])
4867 (define_insn "*truncxfdf2_mixed"
4868 [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?v,?*r")
4870 (match_operand:XF 1 "register_operand" "f ,f ,f ,f")))
4871 (clobber (match_operand:DF 2 "memory_operand" "=X,m ,m ,m"))]
4874 gcc_assert (!which_alternative);
4875 return output_387_reg_move (insn, operands);
4877 [(set_attr "isa" "*,*,sse2,*")
4878 (set_attr "type" "fmov,multi,multi,multi")
4879 (set_attr "unit" "*,i387,i387,i387")
4880 (set_attr "mode" "DF")])
4882 (define_insn "truncxf<mode>2_i387_noop"
4883 [(set (match_operand:MODEF 0 "register_operand" "=f")
4884 (float_truncate:MODEF
4885 (match_operand:XF 1 "register_operand" "f")))]
4886 "TARGET_80387 && flag_unsafe_math_optimizations"
4887 "* return output_387_reg_move (insn, operands);"
4888 [(set_attr "type" "fmov")
4889 (set_attr "mode" "<MODE>")])
4891 (define_insn "*truncxf<mode>2_i387"
4892 [(set (match_operand:MODEF 0 "memory_operand" "=m")
4893 (float_truncate:MODEF
4894 (match_operand:XF 1 "register_operand" "f")))]
4896 "* return output_387_reg_move (insn, operands);"
4897 [(set_attr "type" "fmov")
4898 (set_attr "mode" "<MODE>")])
4901 [(set (match_operand:MODEF 0 "register_operand")
4902 (float_truncate:MODEF
4903 (match_operand:XF 1 "register_operand")))
4904 (clobber (match_operand:MODEF 2 "memory_operand"))]
4905 "TARGET_80387 && reload_completed"
4906 [(set (match_dup 2) (float_truncate:MODEF (match_dup 1)))
4907 (set (match_dup 0) (match_dup 2))])
4910 [(set (match_operand:MODEF 0 "memory_operand")
4911 (float_truncate:MODEF
4912 (match_operand:XF 1 "register_operand")))
4913 (clobber (match_operand:MODEF 2 "memory_operand"))]
4915 [(set (match_dup 0) (float_truncate:MODEF (match_dup 1)))])
4917 ;; Signed conversion to DImode.
4919 (define_expand "fix_truncxfdi2"
4920 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand")
4921 (fix:DI (match_operand:XF 1 "register_operand")))
4922 (clobber (reg:CC FLAGS_REG))])]
4927 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4932 (define_expand "fix_trunc<mode>di2"
4933 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand")
4934 (fix:DI (match_operand:MODEF 1 "register_operand")))
4935 (clobber (reg:CC FLAGS_REG))])]
4936 "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4939 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4941 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4944 if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4946 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4947 emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4948 if (out != operands[0])
4949 emit_move_insn (operands[0], out);
4954 ;; Signed conversion to SImode.
4956 (define_expand "fix_truncxfsi2"
4957 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand")
4958 (fix:SI (match_operand:XF 1 "register_operand")))
4959 (clobber (reg:CC FLAGS_REG))])]
4964 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4969 (define_expand "fix_trunc<mode>si2"
4970 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand")
4971 (fix:SI (match_operand:MODEF 1 "register_operand")))
4972 (clobber (reg:CC FLAGS_REG))])]
4973 "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4976 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4978 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4981 if (SSE_FLOAT_MODE_P (<MODE>mode))
4983 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4984 emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4985 if (out != operands[0])
4986 emit_move_insn (operands[0], out);
4991 ;; Signed conversion to HImode.
4993 (define_expand "fix_trunc<mode>hi2"
4994 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand")
4995 (fix:HI (match_operand:X87MODEF 1 "register_operand")))
4996 (clobber (reg:CC FLAGS_REG))])]
4998 && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
5002 emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
5007 ;; Unsigned conversion to DImode
5009 (define_insn "fixuns_trunc<mode>di2"
5010 [(set (match_operand:DI 0 "register_operand" "=r")
5012 (match_operand:MODEF 1 "nonimmediate_operand" "vm")))]
5013 "TARGET_64BIT && TARGET_AVX512F && TARGET_SSE_MATH"
5014 "vcvtt<ssemodesuffix>2usi\t{%1, %0|%0, %1}"
5015 [(set_attr "type" "sseicvt")
5016 (set_attr "prefix" "evex")
5017 (set_attr "mode" "DI")])
5019 ;; Unsigned conversion to SImode.
5021 (define_expand "fixuns_trunc<mode>si2"
5023 [(set (match_operand:SI 0 "register_operand")
5025 (match_operand:MODEF 1 "nonimmediate_operand")))
5027 (clobber (match_scratch:<ssevecmode> 3))
5028 (clobber (match_scratch:<ssevecmode> 4))])]
5029 "(!TARGET_64BIT || TARGET_AVX512F) && TARGET_SSE2 && TARGET_SSE_MATH"
5031 machine_mode mode = <MODE>mode;
5032 machine_mode vecmode = <ssevecmode>mode;
5033 REAL_VALUE_TYPE TWO31r;
5038 emit_insn (gen_fixuns_trunc<mode>si2_avx512f (operands[0], operands[1]));
5042 if (optimize_insn_for_size_p ())
5045 real_ldexp (&TWO31r, &dconst1, 31);
5046 two31 = const_double_from_real_value (TWO31r, mode);
5047 two31 = ix86_build_const_vector (vecmode, true, two31);
5048 operands[2] = force_reg (vecmode, two31);
5051 (define_insn "fixuns_trunc<mode>si2_avx512f"
5052 [(set (match_operand:SI 0 "register_operand" "=r")
5054 (match_operand:MODEF 1 "nonimmediate_operand" "vm")))]
5055 "TARGET_AVX512F && TARGET_SSE_MATH"
5056 "vcvtt<ssemodesuffix>2usi\t{%1, %0|%0, %1}"
5057 [(set_attr "type" "sseicvt")
5058 (set_attr "prefix" "evex")
5059 (set_attr "mode" "SI")])
5061 (define_insn "*fixuns_trunc<mode>si2_avx512f_zext"
5062 [(set (match_operand:DI 0 "register_operand" "=r")
5065 (match_operand:MODEF 1 "nonimmediate_operand" "vm"))))]
5066 "TARGET_64BIT && TARGET_AVX512F"
5067 "vcvtt<ssemodesuffix>2usi\t{%1, %k0|%k0, %1}"
5068 [(set_attr "type" "sseicvt")
5069 (set_attr "prefix" "evex")
5070 (set_attr "mode" "SI")])
5072 (define_insn_and_split "*fixuns_trunc<mode>_1"
5073 [(set (match_operand:SI 0 "register_operand" "=&x,&x")
5075 (match_operand:MODEF 3 "nonimmediate_operand" "xm,xm")))
5076 (use (match_operand:<ssevecmode> 4 "nonimmediate_operand" "m,x"))
5077 (clobber (match_scratch:<ssevecmode> 1 "=x,&x"))
5078 (clobber (match_scratch:<ssevecmode> 2 "=x,x"))]
5079 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH
5080 && optimize_function_for_speed_p (cfun)"
5082 "&& reload_completed"
5085 ix86_split_convert_uns_si_sse (operands);
5089 ;; Unsigned conversion to HImode.
5090 ;; Without these patterns, we'll try the unsigned SI conversion which
5091 ;; is complex for SSE, rather than the signed SI conversion, which isn't.
5093 (define_expand "fixuns_trunc<mode>hi2"
5095 (fix:SI (match_operand:MODEF 1 "nonimmediate_operand")))
5096 (set (match_operand:HI 0 "nonimmediate_operand")
5097 (subreg:HI (match_dup 2) 0))]
5098 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
5099 "operands[2] = gen_reg_rtx (SImode);")
5101 ;; When SSE is available, it is always faster to use it!
5102 (define_insn "fix_trunc<MODEF:mode><SWI48:mode>_sse"
5103 [(set (match_operand:SWI48 0 "register_operand" "=r,r")
5104 (fix:SWI48 (match_operand:MODEF 1 "nonimmediate_operand" "v,m")))]
5105 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode)
5106 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
5107 "%vcvtt<MODEF:ssemodesuffix>2si<SWI48:rex64suffix>\t{%1, %0|%0, %1}"
5108 [(set_attr "type" "sseicvt")
5109 (set_attr "prefix" "maybe_vex")
5110 (set (attr "prefix_rex")
5112 (match_test "<SWI48:MODE>mode == DImode")
5114 (const_string "*")))
5115 (set_attr "mode" "<MODEF:MODE>")
5116 (set_attr "athlon_decode" "double,vector")
5117 (set_attr "amdfam10_decode" "double,double")
5118 (set_attr "bdver1_decode" "double,double")])
5120 ;; Avoid vector decoded forms of the instruction.
5122 [(match_scratch:MODEF 2 "x")
5123 (set (match_operand:SWI48 0 "register_operand")
5124 (fix:SWI48 (match_operand:MODEF 1 "memory_operand")))]
5125 "TARGET_AVOID_VECTOR_DECODE
5126 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode)
5127 && optimize_insn_for_speed_p ()"
5128 [(set (match_dup 2) (match_dup 1))
5129 (set (match_dup 0) (fix:SWI48 (match_dup 2)))])
5131 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
5132 [(set (match_operand:SWI248x 0 "nonimmediate_operand")
5133 (fix:SWI248x (match_operand 1 "register_operand")))]
5134 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5136 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
5137 && (TARGET_64BIT || <MODE>mode != DImode))
5139 && can_create_pseudo_p ()"
5144 if (memory_operand (operands[0], VOIDmode))
5145 emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
5148 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
5149 emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
5155 [(set_attr "type" "fisttp")
5156 (set_attr "mode" "<MODE>")])
5158 (define_insn "fix_trunc<mode>_i387_fisttp"
5159 [(set (match_operand:SWI248x 0 "memory_operand" "=m")
5160 (fix:SWI248x (match_operand 1 "register_operand" "f")))
5161 (clobber (match_scratch:XF 2 "=&1f"))]
5162 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5164 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
5165 && (TARGET_64BIT || <MODE>mode != DImode))
5166 && TARGET_SSE_MATH)"
5167 "* return output_fix_trunc (insn, operands, true);"
5168 [(set_attr "type" "fisttp")
5169 (set_attr "mode" "<MODE>")])
5171 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
5172 [(set (match_operand:SWI248x 0 "nonimmediate_operand" "=m,?r")
5173 (fix:SWI248x (match_operand 1 "register_operand" "f,f")))
5174 (clobber (match_operand:SWI248x 2 "memory_operand" "=X,m"))
5175 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
5176 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5178 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
5179 && (TARGET_64BIT || <MODE>mode != DImode))
5180 && TARGET_SSE_MATH)"
5182 [(set_attr "type" "fisttp")
5183 (set_attr "mode" "<MODE>")])
5186 [(set (match_operand:SWI248x 0 "register_operand")
5187 (fix:SWI248x (match_operand 1 "register_operand")))
5188 (clobber (match_operand:SWI248x 2 "memory_operand"))
5189 (clobber (match_scratch 3))]
5191 [(parallel [(set (match_dup 2) (fix:SWI248x (match_dup 1)))
5192 (clobber (match_dup 3))])
5193 (set (match_dup 0) (match_dup 2))])
5196 [(set (match_operand:SWI248x 0 "memory_operand")
5197 (fix:SWI248x (match_operand 1 "register_operand")))
5198 (clobber (match_operand:SWI248x 2 "memory_operand"))
5199 (clobber (match_scratch 3))]
5201 [(parallel [(set (match_dup 0) (fix:SWI248x (match_dup 1)))
5202 (clobber (match_dup 3))])])
5204 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
5205 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
5206 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
5207 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
5208 ;; function in i386.c.
5209 (define_insn_and_split "*fix_trunc<mode>_i387_1"
5210 [(set (match_operand:SWI248x 0 "nonimmediate_operand")
5211 (fix:SWI248x (match_operand 1 "register_operand")))
5212 (clobber (reg:CC FLAGS_REG))]
5213 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5215 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
5216 && (TARGET_64BIT || <MODE>mode != DImode))
5217 && can_create_pseudo_p ()"
5222 ix86_optimize_mode_switching[I387_TRUNC] = 1;
5224 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
5225 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
5226 if (memory_operand (operands[0], VOIDmode))
5227 emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
5228 operands[2], operands[3]));
5231 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
5232 emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
5233 operands[2], operands[3],
5238 [(set_attr "type" "fistp")
5239 (set_attr "i387_cw" "trunc")
5240 (set_attr "mode" "<MODE>")])
5242 (define_insn "fix_truncdi_i387"
5243 [(set (match_operand:DI 0 "memory_operand" "=m")
5244 (fix:DI (match_operand 1 "register_operand" "f")))
5245 (use (match_operand:HI 2 "memory_operand" "m"))
5246 (use (match_operand:HI 3 "memory_operand" "m"))
5247 (clobber (match_scratch:XF 4 "=&1f"))]
5248 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5250 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
5251 "* return output_fix_trunc (insn, operands, false);"
5252 [(set_attr "type" "fistp")
5253 (set_attr "i387_cw" "trunc")
5254 (set_attr "mode" "DI")])
5256 (define_insn "fix_truncdi_i387_with_temp"
5257 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
5258 (fix:DI (match_operand 1 "register_operand" "f,f")))
5259 (use (match_operand:HI 2 "memory_operand" "m,m"))
5260 (use (match_operand:HI 3 "memory_operand" "m,m"))
5261 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
5262 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
5263 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5265 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
5267 [(set_attr "type" "fistp")
5268 (set_attr "i387_cw" "trunc")
5269 (set_attr "mode" "DI")])
5272 [(set (match_operand:DI 0 "register_operand")
5273 (fix:DI (match_operand 1 "register_operand")))
5274 (use (match_operand:HI 2 "memory_operand"))
5275 (use (match_operand:HI 3 "memory_operand"))
5276 (clobber (match_operand:DI 4 "memory_operand"))
5277 (clobber (match_scratch 5))]
5279 [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
5282 (clobber (match_dup 5))])
5283 (set (match_dup 0) (match_dup 4))])
5286 [(set (match_operand:DI 0 "memory_operand")
5287 (fix:DI (match_operand 1 "register_operand")))
5288 (use (match_operand:HI 2 "memory_operand"))
5289 (use (match_operand:HI 3 "memory_operand"))
5290 (clobber (match_operand:DI 4 "memory_operand"))
5291 (clobber (match_scratch 5))]
5293 [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
5296 (clobber (match_dup 5))])])
5298 (define_insn "fix_trunc<mode>_i387"
5299 [(set (match_operand:SWI24 0 "memory_operand" "=m")
5300 (fix:SWI24 (match_operand 1 "register_operand" "f")))
5301 (use (match_operand:HI 2 "memory_operand" "m"))
5302 (use (match_operand:HI 3 "memory_operand" "m"))]
5303 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5305 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
5306 "* return output_fix_trunc (insn, operands, false);"
5307 [(set_attr "type" "fistp")
5308 (set_attr "i387_cw" "trunc")
5309 (set_attr "mode" "<MODE>")])
5311 (define_insn "fix_trunc<mode>_i387_with_temp"
5312 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
5313 (fix:SWI24 (match_operand 1 "register_operand" "f,f")))
5314 (use (match_operand:HI 2 "memory_operand" "m,m"))
5315 (use (match_operand:HI 3 "memory_operand" "m,m"))
5316 (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
5317 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5319 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
5321 [(set_attr "type" "fistp")
5322 (set_attr "i387_cw" "trunc")
5323 (set_attr "mode" "<MODE>")])
5326 [(set (match_operand:SWI24 0 "register_operand")
5327 (fix:SWI24 (match_operand 1 "register_operand")))
5328 (use (match_operand:HI 2 "memory_operand"))
5329 (use (match_operand:HI 3 "memory_operand"))
5330 (clobber (match_operand:SWI24 4 "memory_operand"))]
5332 [(parallel [(set (match_dup 4) (fix:SWI24 (match_dup 1)))
5334 (use (match_dup 3))])
5335 (set (match_dup 0) (match_dup 4))])
5338 [(set (match_operand:SWI24 0 "memory_operand")
5339 (fix:SWI24 (match_operand 1 "register_operand")))
5340 (use (match_operand:HI 2 "memory_operand"))
5341 (use (match_operand:HI 3 "memory_operand"))
5342 (clobber (match_operand:SWI24 4 "memory_operand"))]
5344 [(parallel [(set (match_dup 0) (fix:SWI24 (match_dup 1)))
5346 (use (match_dup 3))])])
5348 (define_insn "x86_fnstcw_1"
5349 [(set (match_operand:HI 0 "memory_operand" "=m")
5350 (unspec:HI [(reg:HI FPCR_REG)] UNSPEC_FSTCW))]
5353 [(set (attr "length")
5354 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
5355 (set_attr "mode" "HI")
5356 (set_attr "unit" "i387")
5357 (set_attr "bdver1_decode" "vector")])
5359 (define_insn "x86_fldcw_1"
5360 [(set (reg:HI FPCR_REG)
5361 (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
5364 [(set (attr "length")
5365 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
5366 (set_attr "mode" "HI")
5367 (set_attr "unit" "i387")
5368 (set_attr "athlon_decode" "vector")
5369 (set_attr "amdfam10_decode" "vector")
5370 (set_attr "bdver1_decode" "vector")])
5372 ;; Conversion between fixed point and floating point.
5374 ;; Even though we only accept memory inputs, the backend _really_
5375 ;; wants to be able to do this between registers. Thankfully, LRA
5376 ;; will fix this up for us during register allocation.
5378 (define_insn "floathi<mode>2"
5379 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5380 (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "m")))]
5382 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5383 || TARGET_MIX_SSE_I387)"
5385 [(set_attr "type" "fmov")
5386 (set_attr "mode" "<MODE>")
5387 (set_attr "znver1_decode" "double")
5388 (set_attr "fp_int_src" "true")])
5390 (define_insn "float<SWI48x:mode>xf2"
5391 [(set (match_operand:XF 0 "register_operand" "=f")
5392 (float:XF (match_operand:SWI48x 1 "nonimmediate_operand" "m")))]
5395 [(set_attr "type" "fmov")
5396 (set_attr "mode" "XF")
5397 (set_attr "znver1_decode" "double")
5398 (set_attr "fp_int_src" "true")])
5400 (define_expand "float<SWI48:mode><MODEF:mode>2"
5401 [(set (match_operand:MODEF 0 "register_operand")
5402 (float:MODEF (match_operand:SWI48 1 "nonimmediate_operand")))]
5403 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)"
5405 if (!(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
5406 && !X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI48:MODE>mode))
5408 rtx reg = gen_reg_rtx (XFmode);
5409 rtx (*insn)(rtx, rtx);
5411 emit_insn (gen_float<SWI48:mode>xf2 (reg, operands[1]));
5413 if (<MODEF:MODE>mode == SFmode)
5414 insn = gen_truncxfsf2;
5415 else if (<MODEF:MODE>mode == DFmode)
5416 insn = gen_truncxfdf2;
5420 emit_insn (insn (operands[0], reg));
5425 (define_insn "*float<SWI48:mode><MODEF:mode>2_mixed"
5426 [(set (match_operand:MODEF 0 "register_operand" "=f,v,v")
5428 (match_operand:SWI48 1 "nonimmediate_operand" "m,r,m")))]
5429 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
5432 %vcvtsi2<MODEF:ssemodesuffix><SWI48:rex64suffix>\t{%1, %d0|%d0, %1}
5433 %vcvtsi2<MODEF:ssemodesuffix><SWI48:rex64suffix>\t{%1, %d0|%d0, %1}"
5434 [(set_attr "type" "fmov,sseicvt,sseicvt")
5435 (set_attr "prefix" "orig,maybe_vex,maybe_vex")
5436 (set_attr "mode" "<MODEF:MODE>")
5437 (set (attr "prefix_rex")
5439 (and (eq_attr "prefix" "maybe_vex")
5440 (match_test "<SWI48:MODE>mode == DImode"))
5442 (const_string "*")))
5443 (set_attr "unit" "i387,*,*")
5444 (set_attr "athlon_decode" "*,double,direct")
5445 (set_attr "amdfam10_decode" "*,vector,double")
5446 (set_attr "bdver1_decode" "*,double,direct")
5447 (set_attr "znver1_decode" "double,*,*")
5448 (set_attr "fp_int_src" "true")
5449 (set (attr "enabled")
5450 (cond [(eq_attr "alternative" "0")
5451 (symbol_ref "TARGET_MIX_SSE_I387
5452 && X87_ENABLE_FLOAT (<MODEF:MODE>mode,
5455 (symbol_ref "true")))
5456 (set (attr "preferred_for_speed")
5457 (cond [(eq_attr "alternative" "1")
5458 (symbol_ref "TARGET_INTER_UNIT_CONVERSIONS")]
5459 (symbol_ref "true")))])
5461 (define_insn "*float<SWI48x:mode><MODEF:mode>2_i387"
5462 [(set (match_operand:MODEF 0 "register_operand" "=f")
5463 (float:MODEF (match_operand:SWI48x 1 "nonimmediate_operand" "m")))]
5464 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI48x:MODE>mode)"
5466 [(set_attr "type" "fmov")
5467 (set_attr "mode" "<MODEF:MODE>")
5468 (set_attr "znver1_decode" "double")
5469 (set_attr "fp_int_src" "true")])
5471 ;; Try TARGET_USE_VECTOR_CONVERTS, but not so hard as to require extra memory
5472 ;; slots when !TARGET_INTER_UNIT_MOVES_TO_VEC disables the general_regs
5473 ;; alternative in sse2_loadld.
5475 [(set (match_operand:MODEF 0 "sse_reg_operand")
5476 (float:MODEF (match_operand:SI 1 "nonimmediate_operand")))]
5478 && TARGET_USE_VECTOR_CONVERTS
5479 && optimize_function_for_speed_p (cfun)
5481 && (MEM_P (operands[1]) || TARGET_INTER_UNIT_MOVES_TO_VEC)
5482 && (!EXT_REX_SSE_REG_P (operands[0])
5483 || TARGET_AVX512VL)"
5486 operands[3] = lowpart_subreg (<ssevecmode>mode, operands[0], <MODE>mode);
5487 operands[4] = lowpart_subreg (V4SImode, operands[0], <MODE>mode);
5489 emit_insn (gen_sse2_loadld (operands[4],
5490 CONST0_RTX (V4SImode), operands[1]));
5492 if (<ssevecmode>mode == V4SFmode)
5493 emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
5495 emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
5499 ;; Avoid partial SSE register dependency stalls. This splitter should split
5500 ;; late in the pass sequence (after register rename pass), so allocated
5501 ;; registers won't change anymore
5504 [(set (match_operand:MODEF 0 "sse_reg_operand")
5505 (float:MODEF (match_operand:SWI48 1 "nonimmediate_operand")))]
5506 "TARGET_SSE_PARTIAL_REG_DEPENDENCY && epilogue_completed
5507 && optimize_function_for_speed_p (cfun)
5508 && (!EXT_REX_SSE_REG_P (operands[0])
5509 || TARGET_AVX512VL)"
5511 (vec_merge:<MODEF:ssevecmode>
5512 (vec_duplicate:<MODEF:ssevecmode>
5518 const machine_mode vmode = <MODEF:ssevecmode>mode;
5520 operands[0] = lowpart_subreg (vmode, operands[0], <MODEF:MODE>mode);
5521 emit_move_insn (operands[0], CONST0_RTX (vmode));
5524 ;; Break partial reg stall for cvtsd2ss. This splitter should split
5525 ;; late in the pass sequence (after register rename pass),
5526 ;; so allocated registers won't change anymore.
5529 [(set (match_operand:SF 0 "sse_reg_operand")
5531 (match_operand:DF 1 "nonimmediate_operand")))]
5532 "TARGET_SSE_PARTIAL_REG_DEPENDENCY && epilogue_completed
5533 && optimize_function_for_speed_p (cfun)
5534 && (!REG_P (operands[1])
5535 || REGNO (operands[0]) != REGNO (operands[1]))
5536 && (!EXT_REX_SSE_REG_P (operands[0])
5537 || TARGET_AVX512VL)"
5546 operands[0] = lowpart_subreg (V4SFmode, operands[0], SFmode);
5547 emit_move_insn (operands[0], CONST0_RTX (V4SFmode));
5550 ;; Break partial reg stall for cvtss2sd. This splitter should split
5551 ;; late in the pass sequence (after register rename pass),
5552 ;; so allocated registers won't change anymore.
5555 [(set (match_operand:DF 0 "sse_reg_operand")
5557 (match_operand:SF 1 "nonimmediate_operand")))]
5558 "TARGET_SSE_PARTIAL_REG_DEPENDENCY && epilogue_completed
5559 && optimize_function_for_speed_p (cfun)
5560 && (!REG_P (operands[1])
5561 || REGNO (operands[0]) != REGNO (operands[1]))
5562 && (!EXT_REX_SSE_REG_P (operands[0])
5563 || TARGET_AVX512VL)"
5572 operands[0] = lowpart_subreg (V2DFmode, operands[0], DFmode);
5573 emit_move_insn (operands[0], CONST0_RTX (V2DFmode));
5576 ;; Avoid store forwarding (partial memory) stall penalty
5577 ;; by passing DImode value through XMM registers. */
5579 (define_insn "floatdi<X87MODEF:mode>2_i387_with_xmm"
5580 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5582 (match_operand:DI 1 "nonimmediate_operand" "m,?r")))
5583 (clobber (match_scratch:V4SI 3 "=X,x"))
5584 (clobber (match_scratch:V4SI 4 "=X,x"))
5585 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))]
5586 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5587 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC
5588 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)"
5590 [(set_attr "type" "multi")
5591 (set_attr "mode" "<X87MODEF:MODE>")
5592 (set_attr "unit" "i387")
5593 (set_attr "fp_int_src" "true")])
5596 [(set (match_operand:X87MODEF 0 "fp_register_operand")
5597 (float:X87MODEF (match_operand:DI 1 "register_operand")))
5598 (clobber (match_scratch:V4SI 3))
5599 (clobber (match_scratch:V4SI 4))
5600 (clobber (match_operand:DI 2 "memory_operand"))]
5601 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5602 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC
5603 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5604 && reload_completed"
5605 [(set (match_dup 2) (match_dup 3))
5606 (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5608 /* The DImode arrived in a pair of integral registers (e.g. %edx:%eax).
5609 Assemble the 64-bit DImode value in an xmm register. */
5610 emit_insn (gen_sse2_loadld (operands[3], CONST0_RTX (V4SImode),
5611 gen_lowpart (SImode, operands[1])));
5612 emit_insn (gen_sse2_loadld (operands[4], CONST0_RTX (V4SImode),
5613 gen_highpart (SImode, operands[1])));
5614 emit_insn (gen_vec_interleave_lowv4si (operands[3], operands[3],
5617 operands[3] = gen_lowpart (DImode, operands[3]);
5621 [(set (match_operand:X87MODEF 0 "fp_register_operand")
5622 (float:X87MODEF (match_operand:DI 1 "memory_operand")))
5623 (clobber (match_scratch:V4SI 3))
5624 (clobber (match_scratch:V4SI 4))
5625 (clobber (match_operand:DI 2 "memory_operand"))]
5626 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5627 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC
5628 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5629 && reload_completed"
5630 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
5632 (define_expand "floatuns<SWI12:mode><MODEF:mode>2"
5633 [(set (match_operand:MODEF 0 "register_operand")
5634 (unsigned_float:MODEF
5635 (match_operand:SWI12 1 "nonimmediate_operand")))]
5637 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
5639 operands[1] = convert_to_mode (SImode, operands[1], 1);
5640 emit_insn (gen_floatsi<MODEF:mode>2 (operands[0], operands[1]));
5644 (define_insn "*floatuns<SWI48:mode><MODEF:mode>2_avx512"
5645 [(set (match_operand:MODEF 0 "register_operand" "=v")
5646 (unsigned_float:MODEF
5647 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))]
5648 "TARGET_AVX512F && TARGET_SSE_MATH"
5649 "vcvtusi2<MODEF:ssemodesuffix><SWI48:rex64suffix>\t{%1, %0, %0|%0, %0, %1}"
5650 [(set_attr "type" "sseicvt")
5651 (set_attr "prefix" "evex")
5652 (set_attr "mode" "<MODEF:MODE>")])
5654 ;; Avoid store forwarding (partial memory) stall penalty by extending
5655 ;; SImode value to DImode through XMM register instead of pushing two
5656 ;; SImode values to stack. Also note that fild loads from memory only.
5658 (define_insn_and_split "floatunssi<mode>2_i387_with_xmm"
5659 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5660 (unsigned_float:X87MODEF
5661 (match_operand:SI 1 "nonimmediate_operand" "rm")))
5662 (clobber (match_operand:DI 2 "memory_operand" "=m"))
5663 (clobber (match_scratch:DI 3 "=x"))]
5665 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5666 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC"
5668 "&& reload_completed"
5669 [(set (match_dup 3) (zero_extend:DI (match_dup 1)))
5670 (set (match_dup 2) (match_dup 3))
5672 (float:X87MODEF (match_dup 2)))]
5674 [(set_attr "type" "multi")
5675 (set_attr "mode" "<MODE>")])
5677 (define_expand "floatunssi<mode>2"
5678 [(set (match_operand:X87MODEF 0 "register_operand")
5679 (unsigned_float:X87MODEF
5680 (match_operand:SI 1 "nonimmediate_operand")))]
5682 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5683 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC)
5684 || ((!TARGET_64BIT || TARGET_AVX512F)
5685 && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
5687 if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
5689 emit_insn (gen_floatunssi<mode>2_i387_with_xmm
5690 (operands[0], operands[1],
5691 assign_386_stack_local (DImode, SLOT_TEMP)));
5694 if (!TARGET_AVX512F)
5696 ix86_expand_convert_uns_si<mode>_sse (operands[0], operands[1]);
5701 (define_expand "floatunsdisf2"
5702 [(set (match_operand:SF 0 "register_operand")
5704 (match_operand:DI 1 "nonimmediate_operand")))]
5705 "TARGET_64BIT && TARGET_SSE && TARGET_SSE_MATH"
5707 if (!TARGET_AVX512F)
5709 x86_emit_floatuns (operands);
5714 (define_expand "floatunsdidf2"
5715 [(set (match_operand:DF 0 "register_operand")
5717 (match_operand:DI 1 "nonimmediate_operand")))]
5718 "(TARGET_KEEPS_VECTOR_ALIGNED_STACK || TARGET_AVX512F)
5719 && TARGET_SSE2 && TARGET_SSE_MATH"
5723 ix86_expand_convert_uns_didf_sse (operands[0], operands[1]);
5726 if (!TARGET_AVX512F)
5728 x86_emit_floatuns (operands);
5733 ;; Load effective address instructions
5735 (define_insn_and_split "*lea<mode>"
5736 [(set (match_operand:SWI48 0 "register_operand" "=r")
5737 (match_operand:SWI48 1 "address_no_seg_operand" "Ts"))]
5740 if (SImode_address_operand (operands[1], VOIDmode))
5742 gcc_assert (TARGET_64BIT);
5743 return "lea{l}\t{%E1, %k0|%k0, %E1}";
5746 return "lea{<imodesuffix>}\t{%E1, %0|%0, %E1}";
5748 "reload_completed && ix86_avoid_lea_for_addr (insn, operands)"
5751 machine_mode mode = <MODE>mode;
5754 /* ix86_avoid_lea_for_addr re-recognizes insn and may
5755 change operands[] array behind our back. */
5756 pat = PATTERN (curr_insn);
5758 operands[0] = SET_DEST (pat);
5759 operands[1] = SET_SRC (pat);
5761 /* Emit all operations in SImode for zero-extended addresses. */
5762 if (SImode_address_operand (operands[1], VOIDmode))
5765 ix86_split_lea_for_addr (curr_insn, operands, mode);
5767 /* Zero-extend return register to DImode for zero-extended addresses. */
5768 if (mode != <MODE>mode)
5769 emit_insn (gen_zero_extendsidi2
5770 (operands[0], gen_lowpart (mode, operands[0])));
5774 [(set_attr "type" "lea")
5777 (match_operand 1 "SImode_address_operand")
5779 (const_string "<MODE>")))])
5783 (define_expand "add<mode>3"
5784 [(set (match_operand:SDWIM 0 "nonimmediate_operand")
5785 (plus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")
5786 (match_operand:SDWIM 2 "<general_hilo_operand>")))]
5788 "ix86_expand_binary_operator (PLUS, <MODE>mode, operands); DONE;")
5790 (define_insn_and_split "*add<dwi>3_doubleword"
5791 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
5793 (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0")
5794 (match_operand:<DWI> 2 "x86_64_hilo_general_operand"
5796 (clobber (reg:CC FLAGS_REG))]
5797 "ix86_binary_operator_ok (PLUS, <DWI>mode, operands)"
5800 [(parallel [(set (reg:CCC FLAGS_REG)
5802 (plus:DWIH (match_dup 1) (match_dup 2))
5805 (plus:DWIH (match_dup 1) (match_dup 2)))])
5806 (parallel [(set (match_dup 3)
5809 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
5812 (clobber (reg:CC FLAGS_REG))])]
5814 split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
5815 if (operands[2] == const0_rtx)
5817 ix86_expand_binary_operator (PLUS, <MODE>mode, &operands[3]);
5822 (define_insn "*add<mode>_1"
5823 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,rm,r,r")
5825 (match_operand:SWI48 1 "nonimmediate_operand" "%0,0,r,r")
5826 (match_operand:SWI48 2 "x86_64_general_operand" "rme,re,0,le")))
5827 (clobber (reg:CC FLAGS_REG))]
5828 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5830 switch (get_attr_type (insn))
5836 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5837 if (operands[2] == const1_rtx)
5838 return "inc{<imodesuffix>}\t%0";
5841 gcc_assert (operands[2] == constm1_rtx);
5842 return "dec{<imodesuffix>}\t%0";
5846 /* For most processors, ADD is faster than LEA. This alternative
5847 was added to use ADD as much as possible. */
5848 if (which_alternative == 2)
5849 std::swap (operands[1], operands[2]);
5851 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5852 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5853 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5855 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5859 (cond [(eq_attr "alternative" "3")
5860 (const_string "lea")
5861 (match_operand:SWI48 2 "incdec_operand")
5862 (const_string "incdec")
5864 (const_string "alu")))
5865 (set (attr "length_immediate")
5867 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5869 (const_string "*")))
5870 (set_attr "mode" "<MODE>")])
5872 ;; It may seem that nonimmediate operand is proper one for operand 1.
5873 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5874 ;; we take care in ix86_binary_operator_ok to not allow two memory
5875 ;; operands so proper swapping will be done in reload. This allow
5876 ;; patterns constructed from addsi_1 to match.
5878 (define_insn "addsi_1_zext"
5879 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
5881 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r,r")
5882 (match_operand:SI 2 "x86_64_general_operand" "rme,0,le"))))
5883 (clobber (reg:CC FLAGS_REG))]
5884 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5886 switch (get_attr_type (insn))
5892 if (operands[2] == const1_rtx)
5893 return "inc{l}\t%k0";
5896 gcc_assert (operands[2] == constm1_rtx);
5897 return "dec{l}\t%k0";
5901 /* For most processors, ADD is faster than LEA. This alternative
5902 was added to use ADD as much as possible. */
5903 if (which_alternative == 1)
5904 std::swap (operands[1], operands[2]);
5906 if (x86_maybe_negate_const_int (&operands[2], SImode))
5907 return "sub{l}\t{%2, %k0|%k0, %2}";
5909 return "add{l}\t{%2, %k0|%k0, %2}";
5913 (cond [(eq_attr "alternative" "2")
5914 (const_string "lea")
5915 (match_operand:SI 2 "incdec_operand")
5916 (const_string "incdec")
5918 (const_string "alu")))
5919 (set (attr "length_immediate")
5921 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5923 (const_string "*")))
5924 (set_attr "mode" "SI")])
5926 (define_insn "*addhi_1"
5927 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r,Yp")
5928 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r,Yp")
5929 (match_operand:HI 2 "general_operand" "rn,rm,0,ln")))
5930 (clobber (reg:CC FLAGS_REG))]
5931 "ix86_binary_operator_ok (PLUS, HImode, operands)"
5933 switch (get_attr_type (insn))
5939 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5940 if (operands[2] == const1_rtx)
5941 return "inc{w}\t%0";
5944 gcc_assert (operands[2] == constm1_rtx);
5945 return "dec{w}\t%0";
5949 /* For most processors, ADD is faster than LEA. This alternative
5950 was added to use ADD as much as possible. */
5951 if (which_alternative == 2)
5952 std::swap (operands[1], operands[2]);
5954 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5955 if (x86_maybe_negate_const_int (&operands[2], HImode))
5956 return "sub{w}\t{%2, %0|%0, %2}";
5958 return "add{w}\t{%2, %0|%0, %2}";
5962 (cond [(eq_attr "alternative" "3")
5963 (const_string "lea")
5964 (match_operand:HI 2 "incdec_operand")
5965 (const_string "incdec")
5967 (const_string "alu")))
5968 (set (attr "length_immediate")
5970 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5972 (const_string "*")))
5973 (set_attr "mode" "HI,HI,HI,SI")])
5975 (define_insn "*addqi_1"
5976 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,q,r,r,Yp")
5977 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,q,0,r,Yp")
5978 (match_operand:QI 2 "general_operand" "qn,qm,0,rn,0,ln")))
5979 (clobber (reg:CC FLAGS_REG))]
5980 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5982 bool widen = (get_attr_mode (insn) != MODE_QI);
5984 switch (get_attr_type (insn))
5990 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5991 if (operands[2] == const1_rtx)
5992 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
5995 gcc_assert (operands[2] == constm1_rtx);
5996 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6000 /* For most processors, ADD is faster than LEA. These alternatives
6001 were added to use ADD as much as possible. */
6002 if (which_alternative == 2 || which_alternative == 4)
6003 std::swap (operands[1], operands[2]);
6005 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6006 if (x86_maybe_negate_const_int (&operands[2], QImode))
6009 return "sub{l}\t{%2, %k0|%k0, %2}";
6011 return "sub{b}\t{%2, %0|%0, %2}";
6014 return "add{l}\t{%k2, %k0|%k0, %k2}";
6016 return "add{b}\t{%2, %0|%0, %2}";
6020 (cond [(eq_attr "alternative" "5")
6021 (const_string "lea")
6022 (match_operand:QI 2 "incdec_operand")
6023 (const_string "incdec")
6025 (const_string "alu")))
6026 (set (attr "length_immediate")
6028 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6030 (const_string "*")))
6031 (set_attr "mode" "QI,QI,QI,SI,SI,SI")
6032 ;; Potential partial reg stall on alternatives 3 and 4.
6033 (set (attr "preferred_for_speed")
6034 (cond [(eq_attr "alternative" "3,4")
6035 (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
6036 (symbol_ref "true")))])
6038 (define_insn "*addqi_1_slp"
6039 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6040 (plus:QI (match_dup 0)
6041 (match_operand:QI 1 "general_operand" "qn,qm")))
6042 (clobber (reg:CC FLAGS_REG))]
6043 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6044 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
6046 switch (get_attr_type (insn))
6049 if (operands[1] == const1_rtx)
6050 return "inc{b}\t%0";
6053 gcc_assert (operands[1] == constm1_rtx);
6054 return "dec{b}\t%0";
6058 if (x86_maybe_negate_const_int (&operands[1], QImode))
6059 return "sub{b}\t{%1, %0|%0, %1}";
6061 return "add{b}\t{%1, %0|%0, %1}";
6065 (if_then_else (match_operand:QI 1 "incdec_operand")
6066 (const_string "incdec")
6067 (const_string "alu1")))
6068 (set (attr "memory")
6069 (if_then_else (match_operand 1 "memory_operand")
6070 (const_string "load")
6071 (const_string "none")))
6072 (set_attr "mode" "QI")])
6074 ;; Split non destructive adds if we cannot use lea.
6076 [(set (match_operand:SWI48 0 "register_operand")
6077 (plus:SWI48 (match_operand:SWI48 1 "register_operand")
6078 (match_operand:SWI48 2 "x86_64_nonmemory_operand")))
6079 (clobber (reg:CC FLAGS_REG))]
6080 "reload_completed && ix86_avoid_lea_for_add (insn, operands)"
6081 [(set (match_dup 0) (match_dup 1))
6082 (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 2)))
6083 (clobber (reg:CC FLAGS_REG))])])
6085 ;; Split non destructive adds if we cannot use lea.
6087 [(set (match_operand:DI 0 "register_operand")
6089 (plus:SI (match_operand:SI 1 "register_operand")
6090 (match_operand:SI 2 "x86_64_nonmemory_operand"))))
6091 (clobber (reg:CC FLAGS_REG))]
6093 && reload_completed && ix86_avoid_lea_for_add (insn, operands)"
6094 [(set (match_dup 3) (match_dup 1))
6095 (parallel [(set (match_dup 0)
6096 (zero_extend:DI (plus:SI (match_dup 3) (match_dup 2))))
6097 (clobber (reg:CC FLAGS_REG))])]
6098 "operands[3] = gen_lowpart (SImode, operands[0]);")
6100 ;; Convert add to the lea pattern to avoid flags dependency.
6102 [(set (match_operand:SWI 0 "register_operand")
6103 (plus:SWI (match_operand:SWI 1 "register_operand")
6104 (match_operand:SWI 2 "<nonmemory_operand>")))
6105 (clobber (reg:CC FLAGS_REG))]
6106 "reload_completed && ix86_lea_for_add_ok (insn, operands)"
6108 (plus:<LEAMODE> (match_dup 1) (match_dup 2)))]
6110 if (<MODE>mode != <LEAMODE>mode)
6112 operands[0] = gen_lowpart (<LEAMODE>mode, operands[0]);
6113 operands[1] = gen_lowpart (<LEAMODE>mode, operands[1]);
6114 operands[2] = gen_lowpart (<LEAMODE>mode, operands[2]);
6118 ;; Convert add to the lea pattern to avoid flags dependency.
6120 [(set (match_operand:DI 0 "register_operand")
6122 (plus:SI (match_operand:SI 1 "register_operand")
6123 (match_operand:SI 2 "x86_64_nonmemory_operand"))))
6124 (clobber (reg:CC FLAGS_REG))]
6125 "TARGET_64BIT && reload_completed && ix86_lea_for_add_ok (insn, operands)"
6127 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))])
6129 (define_insn "*add<mode>_2"
6130 [(set (reg FLAGS_REG)
6133 (match_operand:SWI 1 "nonimmediate_operand" "%0,0,<r>")
6134 (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>,0"))
6136 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m,<r>")
6137 (plus:SWI (match_dup 1) (match_dup 2)))]
6138 "ix86_match_ccmode (insn, CCGOCmode)
6139 && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6141 switch (get_attr_type (insn))
6144 if (operands[2] == const1_rtx)
6145 return "inc{<imodesuffix>}\t%0";
6148 gcc_assert (operands[2] == constm1_rtx);
6149 return "dec{<imodesuffix>}\t%0";
6153 if (which_alternative == 2)
6154 std::swap (operands[1], operands[2]);
6156 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6157 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6158 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6160 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6164 (if_then_else (match_operand:SWI 2 "incdec_operand")
6165 (const_string "incdec")
6166 (const_string "alu")))
6167 (set (attr "length_immediate")
6169 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6171 (const_string "*")))
6172 (set_attr "mode" "<MODE>")])
6174 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6175 (define_insn "*addsi_2_zext"
6176 [(set (reg FLAGS_REG)
6178 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
6179 (match_operand:SI 2 "x86_64_general_operand" "rme,0"))
6181 (set (match_operand:DI 0 "register_operand" "=r,r")
6182 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6183 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6184 && ix86_binary_operator_ok (PLUS, SImode, operands)"
6186 switch (get_attr_type (insn))
6189 if (operands[2] == const1_rtx)
6190 return "inc{l}\t%k0";
6193 gcc_assert (operands[2] == constm1_rtx);
6194 return "dec{l}\t%k0";
6198 if (which_alternative == 1)
6199 std::swap (operands[1], operands[2]);
6201 if (x86_maybe_negate_const_int (&operands[2], SImode))
6202 return "sub{l}\t{%2, %k0|%k0, %2}";
6204 return "add{l}\t{%2, %k0|%k0, %2}";
6208 (if_then_else (match_operand:SI 2 "incdec_operand")
6209 (const_string "incdec")
6210 (const_string "alu")))
6211 (set (attr "length_immediate")
6213 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6215 (const_string "*")))
6216 (set_attr "mode" "SI")])
6218 (define_insn "*add<mode>_3"
6219 [(set (reg FLAGS_REG)
6221 (neg:SWI (match_operand:SWI 2 "<general_operand>" "<g>,0"))
6222 (match_operand:SWI 1 "nonimmediate_operand" "%0,<r>")))
6223 (clobber (match_scratch:SWI 0 "=<r>,<r>"))]
6224 "ix86_match_ccmode (insn, CCZmode)
6225 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6227 switch (get_attr_type (insn))
6230 if (operands[2] == const1_rtx)
6231 return "inc{<imodesuffix>}\t%0";
6234 gcc_assert (operands[2] == constm1_rtx);
6235 return "dec{<imodesuffix>}\t%0";
6239 if (which_alternative == 1)
6240 std::swap (operands[1], operands[2]);
6242 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6243 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6244 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6246 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6250 (if_then_else (match_operand:SWI 2 "incdec_operand")
6251 (const_string "incdec")
6252 (const_string "alu")))
6253 (set (attr "length_immediate")
6255 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6257 (const_string "*")))
6258 (set_attr "mode" "<MODE>")])
6260 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6261 (define_insn "*addsi_3_zext"
6262 [(set (reg FLAGS_REG)
6264 (neg:SI (match_operand:SI 2 "x86_64_general_operand" "rme,0"))
6265 (match_operand:SI 1 "nonimmediate_operand" "%0,r")))
6266 (set (match_operand:DI 0 "register_operand" "=r,r")
6267 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6268 "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
6269 && ix86_binary_operator_ok (PLUS, SImode, operands)"
6271 switch (get_attr_type (insn))
6274 if (operands[2] == const1_rtx)
6275 return "inc{l}\t%k0";
6278 gcc_assert (operands[2] == constm1_rtx);
6279 return "dec{l}\t%k0";
6283 if (which_alternative == 1)
6284 std::swap (operands[1], operands[2]);
6286 if (x86_maybe_negate_const_int (&operands[2], SImode))
6287 return "sub{l}\t{%2, %k0|%k0, %2}";
6289 return "add{l}\t{%2, %k0|%k0, %2}";
6293 (if_then_else (match_operand:SI 2 "incdec_operand")
6294 (const_string "incdec")
6295 (const_string "alu")))
6296 (set (attr "length_immediate")
6298 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6300 (const_string "*")))
6301 (set_attr "mode" "SI")])
6303 ; For comparisons against 1, -1 and 128, we may generate better code
6304 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
6305 ; is matched then. We can't accept general immediate, because for
6306 ; case of overflows, the result is messed up.
6307 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6308 ; only for comparisons not depending on it.
6310 (define_insn "*adddi_4"
6311 [(set (reg FLAGS_REG)
6313 (match_operand:DI 1 "nonimmediate_operand" "0")
6314 (match_operand:DI 2 "x86_64_immediate_operand" "e")))
6315 (clobber (match_scratch:DI 0 "=rm"))]
6317 && ix86_match_ccmode (insn, CCGCmode)"
6319 switch (get_attr_type (insn))
6322 if (operands[2] == constm1_rtx)
6323 return "inc{q}\t%0";
6326 gcc_assert (operands[2] == const1_rtx);
6327 return "dec{q}\t%0";
6331 if (x86_maybe_negate_const_int (&operands[2], DImode))
6332 return "add{q}\t{%2, %0|%0, %2}";
6334 return "sub{q}\t{%2, %0|%0, %2}";
6338 (if_then_else (match_operand:DI 2 "incdec_operand")
6339 (const_string "incdec")
6340 (const_string "alu")))
6341 (set (attr "length_immediate")
6343 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6345 (const_string "*")))
6346 (set_attr "mode" "DI")])
6348 ; For comparisons against 1, -1 and 128, we may generate better code
6349 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
6350 ; is matched then. We can't accept general immediate, because for
6351 ; case of overflows, the result is messed up.
6352 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6353 ; only for comparisons not depending on it.
6355 (define_insn "*add<mode>_4"
6356 [(set (reg FLAGS_REG)
6358 (match_operand:SWI124 1 "nonimmediate_operand" "0")
6359 (match_operand:SWI124 2 "const_int_operand" "n")))
6360 (clobber (match_scratch:SWI124 0 "=<r>m"))]
6361 "ix86_match_ccmode (insn, CCGCmode)"
6363 switch (get_attr_type (insn))
6366 if (operands[2] == constm1_rtx)
6367 return "inc{<imodesuffix>}\t%0";
6370 gcc_assert (operands[2] == const1_rtx);
6371 return "dec{<imodesuffix>}\t%0";
6375 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6376 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6378 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6382 (if_then_else (match_operand:<MODE> 2 "incdec_operand")
6383 (const_string "incdec")
6384 (const_string "alu")))
6385 (set (attr "length_immediate")
6387 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6389 (const_string "*")))
6390 (set_attr "mode" "<MODE>")])
6392 (define_insn "*add<mode>_5"
6393 [(set (reg FLAGS_REG)
6396 (match_operand:SWI 1 "nonimmediate_operand" "%0,<r>")
6397 (match_operand:SWI 2 "<general_operand>" "<g>,0"))
6399 (clobber (match_scratch:SWI 0 "=<r>,<r>"))]
6400 "ix86_match_ccmode (insn, CCGOCmode)
6401 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6403 switch (get_attr_type (insn))
6406 if (operands[2] == const1_rtx)
6407 return "inc{<imodesuffix>}\t%0";
6410 gcc_assert (operands[2] == constm1_rtx);
6411 return "dec{<imodesuffix>}\t%0";
6415 if (which_alternative == 1)
6416 std::swap (operands[1], operands[2]);
6418 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6419 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6420 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6422 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6426 (if_then_else (match_operand:SWI 2 "incdec_operand")
6427 (const_string "incdec")
6428 (const_string "alu")))
6429 (set (attr "length_immediate")
6431 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6433 (const_string "*")))
6434 (set_attr "mode" "<MODE>")])
6436 (define_insn "addqi_ext_1"
6437 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q,Q")
6443 (zero_extract:SI (match_operand 1 "ext_register_operand" "0,0")
6446 (match_operand:QI 2 "general_operand" "QnBc,m")) 0))
6447 (clobber (reg:CC FLAGS_REG))]
6448 "/* FIXME: without this LRA can't reload this pattern, see PR82524. */
6449 rtx_equal_p (operands[0], operands[1])"
6451 switch (get_attr_type (insn))
6454 if (operands[2] == const1_rtx)
6455 return "inc{b}\t%h0";
6458 gcc_assert (operands[2] == constm1_rtx);
6459 return "dec{b}\t%h0";
6463 return "add{b}\t{%2, %h0|%h0, %2}";
6466 [(set_attr "isa" "*,nox64")
6468 (if_then_else (match_operand:QI 2 "incdec_operand")
6469 (const_string "incdec")
6470 (const_string "alu")))
6471 (set_attr "mode" "QI")])
6473 (define_insn "*addqi_ext_2"
6474 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
6480 (zero_extract:SI (match_operand 1 "ext_register_operand" "%0")
6484 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
6486 (const_int 8)) 0)) 0))
6487 (clobber (reg:CC FLAGS_REG))]
6488 "/* FIXME: without this LRA can't reload this pattern, see PR82524. */
6489 rtx_equal_p (operands[0], operands[1])
6490 || rtx_equal_p (operands[0], operands[2])"
6491 "add{b}\t{%h2, %h0|%h0, %h2}"
6492 [(set_attr "type" "alu")
6493 (set_attr "mode" "QI")])
6495 ;; Add with jump on overflow.
6496 (define_expand "addv<mode>4"
6497 [(parallel [(set (reg:CCO FLAGS_REG)
6500 (match_operand:SWI 1 "nonimmediate_operand"))
6503 (plus:SWI (match_dup 1)
6504 (match_operand:SWI 2
6505 "<general_operand>")))))
6506 (set (match_operand:SWI 0 "register_operand")
6507 (plus:SWI (match_dup 1) (match_dup 2)))])
6508 (set (pc) (if_then_else
6509 (eq (reg:CCO FLAGS_REG) (const_int 0))
6510 (label_ref (match_operand 3))
6514 ix86_fixup_binary_operands_no_copy (PLUS, <MODE>mode, operands);
6515 if (CONST_INT_P (operands[2]))
6516 operands[4] = operands[2];
6518 operands[4] = gen_rtx_SIGN_EXTEND (<DWI>mode, operands[2]);
6521 (define_insn "*addv<mode>4"
6522 [(set (reg:CCO FLAGS_REG)
6525 (match_operand:SWI 1 "nonimmediate_operand" "%0,0"))
6527 (match_operand:SWI 2 "<general_sext_operand>"
6530 (plus:SWI (match_dup 1) (match_dup 2)))))
6531 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
6532 (plus:SWI (match_dup 1) (match_dup 2)))]
6533 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6534 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6535 [(set_attr "type" "alu")
6536 (set_attr "mode" "<MODE>")])
6538 (define_insn "*addv<mode>4_1"
6539 [(set (reg:CCO FLAGS_REG)
6542 (match_operand:SWI 1 "nonimmediate_operand" "0"))
6543 (match_operand:<DWI> 3 "const_int_operand" "i"))
6545 (plus:SWI (match_dup 1)
6546 (match_operand:SWI 2 "x86_64_immediate_operand"
6548 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
6549 (plus:SWI (match_dup 1) (match_dup 2)))]
6550 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)
6551 && CONST_INT_P (operands[2])
6552 && INTVAL (operands[2]) == INTVAL (operands[3])"
6553 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6554 [(set_attr "type" "alu")
6555 (set_attr "mode" "<MODE>")
6556 (set (attr "length_immediate")
6557 (cond [(match_test "IN_RANGE (INTVAL (operands[2]), -128, 127)")
6559 (match_test "<MODE_SIZE> == 8")
6561 (const_string "<MODE_SIZE>")))])
6563 (define_expand "uaddv<mode>4"
6564 [(parallel [(set (reg:CCC FLAGS_REG)
6567 (match_operand:SWI 1 "nonimmediate_operand")
6568 (match_operand:SWI 2 "<general_operand>"))
6570 (set (match_operand:SWI 0 "register_operand")
6571 (plus:SWI (match_dup 1) (match_dup 2)))])
6572 (set (pc) (if_then_else
6573 (ltu (reg:CCC FLAGS_REG) (const_int 0))
6574 (label_ref (match_operand 3))
6577 "ix86_fixup_binary_operands_no_copy (PLUS, <MODE>mode, operands);")
6579 ;; The lea patterns for modes less than 32 bits need to be matched by
6580 ;; several insns converted to real lea by splitters.
6582 (define_insn_and_split "*lea<mode>_general_1"
6583 [(set (match_operand:SWI12 0 "register_operand" "=r")
6585 (plus:SWI12 (match_operand:SWI12 1 "index_register_operand" "l")
6586 (match_operand:SWI12 2 "register_operand" "r"))
6587 (match_operand:SWI12 3 "immediate_operand" "i")))]
6588 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
6590 "&& reload_completed"
6593 (plus:SI (match_dup 1) (match_dup 2))
6596 operands[0] = gen_lowpart (SImode, operands[0]);
6597 operands[1] = gen_lowpart (SImode, operands[1]);
6598 operands[2] = gen_lowpart (SImode, operands[2]);
6599 operands[3] = gen_lowpart (SImode, operands[3]);
6601 [(set_attr "type" "lea")
6602 (set_attr "mode" "SI")])
6604 (define_insn_and_split "*lea<mode>_general_2"
6605 [(set (match_operand:SWI12 0 "register_operand" "=r")
6607 (mult:SWI12 (match_operand:SWI12 1 "index_register_operand" "l")
6608 (match_operand 2 "const248_operand" "n"))
6609 (match_operand:SWI12 3 "nonmemory_operand" "ri")))]
6610 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
6612 "&& reload_completed"
6615 (mult:SI (match_dup 1) (match_dup 2))
6618 operands[0] = gen_lowpart (SImode, operands[0]);
6619 operands[1] = gen_lowpart (SImode, operands[1]);
6620 operands[3] = gen_lowpart (SImode, operands[3]);
6622 [(set_attr "type" "lea")
6623 (set_attr "mode" "SI")])
6625 (define_insn_and_split "*lea<mode>_general_2b"
6626 [(set (match_operand:SWI12 0 "register_operand" "=r")
6628 (ashift:SWI12 (match_operand:SWI12 1 "index_register_operand" "l")
6629 (match_operand 2 "const123_operand" "n"))
6630 (match_operand:SWI12 3 "nonmemory_operand" "ri")))]
6631 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
6633 "&& reload_completed"
6636 (ashift:SI (match_dup 1) (match_dup 2))
6639 operands[0] = gen_lowpart (SImode, operands[0]);
6640 operands[1] = gen_lowpart (SImode, operands[1]);
6641 operands[3] = gen_lowpart (SImode, operands[3]);
6643 [(set_attr "type" "lea")
6644 (set_attr "mode" "SI")])
6646 (define_insn_and_split "*lea<mode>_general_3"
6647 [(set (match_operand:SWI12 0 "register_operand" "=r")
6650 (mult:SWI12 (match_operand:SWI12 1 "index_register_operand" "l")
6651 (match_operand 2 "const248_operand" "n"))
6652 (match_operand:SWI12 3 "register_operand" "r"))
6653 (match_operand:SWI12 4 "immediate_operand" "i")))]
6654 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
6656 "&& reload_completed"
6660 (mult:SI (match_dup 1) (match_dup 2))
6664 operands[0] = gen_lowpart (SImode, operands[0]);
6665 operands[1] = gen_lowpart (SImode, operands[1]);
6666 operands[3] = gen_lowpart (SImode, operands[3]);
6667 operands[4] = gen_lowpart (SImode, operands[4]);
6669 [(set_attr "type" "lea")
6670 (set_attr "mode" "SI")])
6672 (define_insn_and_split "*lea<mode>_general_3b"
6673 [(set (match_operand:SWI12 0 "register_operand" "=r")
6676 (ashift:SWI12 (match_operand:SWI12 1 "index_register_operand" "l")
6677 (match_operand 2 "const123_operand" "n"))
6678 (match_operand:SWI12 3 "register_operand" "r"))
6679 (match_operand:SWI12 4 "immediate_operand" "i")))]
6680 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
6682 "&& reload_completed"
6686 (ashift:SI (match_dup 1) (match_dup 2))
6690 operands[0] = gen_lowpart (SImode, operands[0]);
6691 operands[1] = gen_lowpart (SImode, operands[1]);
6692 operands[3] = gen_lowpart (SImode, operands[3]);
6693 operands[4] = gen_lowpart (SImode, operands[4]);
6695 [(set_attr "type" "lea")
6696 (set_attr "mode" "SI")])
6698 (define_insn_and_split "*lea<mode>_general_4"
6699 [(set (match_operand:SWI12 0 "register_operand" "=r")
6702 (match_operand:SWI12 1 "index_register_operand" "l")
6703 (match_operand 2 "const_0_to_3_operand" "n"))
6704 (match_operand 3 "const_int_operand" "n")))]
6705 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6706 && ((unsigned HOST_WIDE_INT) INTVAL (operands[3])
6707 < (HOST_WIDE_INT_1U << INTVAL (operands[2])))"
6709 "&& reload_completed"
6712 (mult:SI (match_dup 1) (match_dup 2))
6715 operands[0] = gen_lowpart (SImode, operands[0]);
6716 operands[1] = gen_lowpart (SImode, operands[1]);
6717 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
6719 [(set_attr "type" "lea")
6720 (set_attr "mode" "SI")])
6722 (define_insn_and_split "*lea<mode>_general_4"
6723 [(set (match_operand:SWI48 0 "register_operand" "=r")
6726 (match_operand:SWI48 1 "index_register_operand" "l")
6727 (match_operand 2 "const_0_to_3_operand" "n"))
6728 (match_operand 3 "const_int_operand" "n")))]
6729 "(unsigned HOST_WIDE_INT) INTVAL (operands[3])
6730 < (HOST_WIDE_INT_1U << INTVAL (operands[2]))"
6732 "&& reload_completed"
6735 (mult:SWI48 (match_dup 1) (match_dup 2))
6737 "operands[2] = GEN_INT (1 << INTVAL (operands[2]));"
6738 [(set_attr "type" "lea")
6739 (set_attr "mode" "<MODE>")])
6741 ;; Subtract instructions
6743 (define_expand "sub<mode>3"
6744 [(set (match_operand:SDWIM 0 "nonimmediate_operand")
6745 (minus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")
6746 (match_operand:SDWIM 2 "<general_hilo_operand>")))]
6748 "ix86_expand_binary_operator (MINUS, <MODE>mode, operands); DONE;")
6750 (define_insn_and_split "*sub<dwi>3_doubleword"
6751 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
6753 (match_operand:<DWI> 1 "nonimmediate_operand" "0,0")
6754 (match_operand:<DWI> 2 "x86_64_hilo_general_operand"
6756 (clobber (reg:CC FLAGS_REG))]
6757 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6760 [(parallel [(set (reg:CC FLAGS_REG)
6761 (compare:CC (match_dup 1) (match_dup 2)))
6763 (minus:DWIH (match_dup 1) (match_dup 2)))])
6764 (parallel [(set (match_dup 3)
6768 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0)))
6770 (clobber (reg:CC FLAGS_REG))])]
6772 split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
6773 if (operands[2] == const0_rtx)
6775 ix86_expand_binary_operator (MINUS, <MODE>mode, &operands[3]);
6780 (define_insn "*sub<mode>_1"
6781 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6783 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6784 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6785 (clobber (reg:CC FLAGS_REG))]
6786 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6787 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6788 [(set_attr "type" "alu")
6789 (set_attr "mode" "<MODE>")])
6791 (define_insn "*subsi_1_zext"
6792 [(set (match_operand:DI 0 "register_operand" "=r")
6794 (minus:SI (match_operand:SI 1 "register_operand" "0")
6795 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
6796 (clobber (reg:CC FLAGS_REG))]
6797 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6798 "sub{l}\t{%2, %k0|%k0, %2}"
6799 [(set_attr "type" "alu")
6800 (set_attr "mode" "SI")])
6802 (define_insn "*subqi_1_slp"
6803 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6804 (minus:QI (match_dup 0)
6805 (match_operand:QI 1 "general_operand" "qn,qm")))
6806 (clobber (reg:CC FLAGS_REG))]
6807 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6808 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
6809 "sub{b}\t{%1, %0|%0, %1}"
6810 [(set_attr "type" "alu1")
6811 (set_attr "mode" "QI")])
6813 (define_insn "*sub<mode>_2"
6814 [(set (reg FLAGS_REG)
6817 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6818 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6820 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6821 (minus:SWI (match_dup 1) (match_dup 2)))]
6822 "ix86_match_ccmode (insn, CCGOCmode)
6823 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6824 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6825 [(set_attr "type" "alu")
6826 (set_attr "mode" "<MODE>")])
6828 (define_insn "*subsi_2_zext"
6829 [(set (reg FLAGS_REG)
6831 (minus:SI (match_operand:SI 1 "register_operand" "0")
6832 (match_operand:SI 2 "x86_64_general_operand" "rme"))
6834 (set (match_operand:DI 0 "register_operand" "=r")
6836 (minus:SI (match_dup 1)
6838 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6839 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6840 "sub{l}\t{%2, %k0|%k0, %2}"
6841 [(set_attr "type" "alu")
6842 (set_attr "mode" "SI")])
6844 ;; Subtract with jump on overflow.
6845 (define_expand "subv<mode>4"
6846 [(parallel [(set (reg:CCO FLAGS_REG)
6847 (eq:CCO (minus:<DWI>
6849 (match_operand:SWI 1 "nonimmediate_operand"))
6852 (minus:SWI (match_dup 1)
6853 (match_operand:SWI 2
6854 "<general_operand>")))))
6855 (set (match_operand:SWI 0 "register_operand")
6856 (minus:SWI (match_dup 1) (match_dup 2)))])
6857 (set (pc) (if_then_else
6858 (eq (reg:CCO FLAGS_REG) (const_int 0))
6859 (label_ref (match_operand 3))
6863 ix86_fixup_binary_operands_no_copy (MINUS, <MODE>mode, operands);
6864 if (CONST_INT_P (operands[2]))
6865 operands[4] = operands[2];
6867 operands[4] = gen_rtx_SIGN_EXTEND (<DWI>mode, operands[2]);
6870 (define_insn "*subv<mode>4"
6871 [(set (reg:CCO FLAGS_REG)
6872 (eq:CCO (minus:<DWI>
6874 (match_operand:SWI 1 "nonimmediate_operand" "0,0"))
6876 (match_operand:SWI 2 "<general_sext_operand>"
6879 (minus:SWI (match_dup 1) (match_dup 2)))))
6880 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6881 (minus:SWI (match_dup 1) (match_dup 2)))]
6882 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6883 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6884 [(set_attr "type" "alu")
6885 (set_attr "mode" "<MODE>")])
6887 (define_insn "*subv<mode>4_1"
6888 [(set (reg:CCO FLAGS_REG)
6889 (eq:CCO (minus:<DWI>
6891 (match_operand:SWI 1 "nonimmediate_operand" "0"))
6892 (match_operand:<DWI> 3 "const_int_operand" "i"))
6894 (minus:SWI (match_dup 1)
6895 (match_operand:SWI 2 "x86_64_immediate_operand"
6897 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
6898 (minus:SWI (match_dup 1) (match_dup 2)))]
6899 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)
6900 && CONST_INT_P (operands[2])
6901 && INTVAL (operands[2]) == INTVAL (operands[3])"
6902 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6903 [(set_attr "type" "alu")
6904 (set_attr "mode" "<MODE>")
6905 (set (attr "length_immediate")
6906 (cond [(match_test "IN_RANGE (INTVAL (operands[2]), -128, 127)")
6908 (match_test "<MODE_SIZE> == 8")
6910 (const_string "<MODE_SIZE>")))])
6912 (define_expand "usubv<mode>4"
6913 [(parallel [(set (reg:CC FLAGS_REG)
6915 (match_operand:SWI 1 "nonimmediate_operand")
6916 (match_operand:SWI 2 "<general_operand>")))
6917 (set (match_operand:SWI 0 "register_operand")
6918 (minus:SWI (match_dup 1) (match_dup 2)))])
6919 (set (pc) (if_then_else
6920 (ltu (reg:CC FLAGS_REG) (const_int 0))
6921 (label_ref (match_operand 3))
6924 "ix86_fixup_binary_operands_no_copy (MINUS, <MODE>mode, operands);")
6926 (define_insn "*sub<mode>_3"
6927 [(set (reg FLAGS_REG)
6928 (compare (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6929 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6930 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6931 (minus:SWI (match_dup 1) (match_dup 2)))]
6932 "ix86_match_ccmode (insn, CCmode)
6933 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6934 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6935 [(set_attr "type" "alu")
6936 (set_attr "mode" "<MODE>")])
6940 [(set (reg:CC FLAGS_REG)
6941 (compare:CC (match_operand:SWI 0 "general_reg_operand")
6942 (match_operand:SWI 1 "general_gr_operand")))
6944 (minus:SWI (match_dup 0) (match_dup 1)))])]
6945 "find_regno_note (peep2_next_insn (0), REG_UNUSED, REGNO (operands[0])) != 0"
6946 [(set (reg:CC FLAGS_REG)
6947 (compare:CC (match_dup 0) (match_dup 1)))])
6949 (define_insn "*subsi_3_zext"
6950 [(set (reg FLAGS_REG)
6951 (compare (match_operand:SI 1 "register_operand" "0")
6952 (match_operand:SI 2 "x86_64_general_operand" "rme")))
6953 (set (match_operand:DI 0 "register_operand" "=r")
6955 (minus:SI (match_dup 1)
6957 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6958 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6959 "sub{l}\t{%2, %1|%1, %2}"
6960 [(set_attr "type" "alu")
6961 (set_attr "mode" "SI")])
6963 ;; Add with carry and subtract with borrow
6965 (define_insn "add<mode>3_carry"
6966 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6969 (match_operator:SWI 4 "ix86_carry_flag_operator"
6970 [(match_operand 3 "flags_reg_operand") (const_int 0)])
6971 (match_operand:SWI 1 "nonimmediate_operand" "%0,0"))
6972 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6973 (clobber (reg:CC FLAGS_REG))]
6974 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6975 "adc{<imodesuffix>}\t{%2, %0|%0, %2}"
6976 [(set_attr "type" "alu")
6977 (set_attr "use_carry" "1")
6978 (set_attr "pent_pair" "pu")
6979 (set_attr "mode" "<MODE>")])
6981 (define_insn "*add<mode>3_carry_0"
6982 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
6984 (match_operator:SWI 3 "ix86_carry_flag_operator"
6985 [(match_operand 2 "flags_reg_operand") (const_int 0)])
6986 (match_operand:SWI 1 "nonimmediate_operand" "0")))
6987 (clobber (reg:CC FLAGS_REG))]
6988 "ix86_unary_operator_ok (PLUS, <MODE>mode, operands)"
6989 "adc{<imodesuffix>}\t{$0, %0|%0, 0}"
6990 [(set_attr "type" "alu")
6991 (set_attr "use_carry" "1")
6992 (set_attr "pent_pair" "pu")
6993 (set_attr "mode" "<MODE>")])
6995 (define_insn "*addsi3_carry_zext"
6996 [(set (match_operand:DI 0 "register_operand" "=r")
6999 (plus:SI (match_operator:SI 3 "ix86_carry_flag_operator"
7000 [(reg FLAGS_REG) (const_int 0)])
7001 (match_operand:SI 1 "register_operand" "%0"))
7002 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
7003 (clobber (reg:CC FLAGS_REG))]
7004 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
7005 "adc{l}\t{%2, %k0|%k0, %2}"
7006 [(set_attr "type" "alu")
7007 (set_attr "use_carry" "1")
7008 (set_attr "pent_pair" "pu")
7009 (set_attr "mode" "SI")])
7011 (define_insn "*addsi3_carry_zext_0"
7012 [(set (match_operand:DI 0 "register_operand" "=r")
7014 (plus:SI (match_operator:SI 2 "ix86_carry_flag_operator"
7015 [(reg FLAGS_REG) (const_int 0)])
7016 (match_operand:SI 1 "register_operand" "0"))))
7017 (clobber (reg:CC FLAGS_REG))]
7019 "adc{l}\t{$0, %k0|%k0, 0}"
7020 [(set_attr "type" "alu")
7021 (set_attr "use_carry" "1")
7022 (set_attr "pent_pair" "pu")
7023 (set_attr "mode" "SI")])
7025 ;; There is no point to generate ADCX instruction. ADC is shorter and faster.
7027 (define_insn "addcarry<mode>"
7028 [(set (reg:CCC FLAGS_REG)
7033 (match_operator:SWI48 5 "ix86_carry_flag_operator"
7034 [(match_operand 3 "flags_reg_operand") (const_int 0)])
7035 (match_operand:SWI48 1 "nonimmediate_operand" "%0"))
7036 (match_operand:SWI48 2 "nonimmediate_operand" "rm")))
7038 (zero_extend:<DWI> (match_dup 2))
7039 (match_operator:<DWI> 4 "ix86_carry_flag_operator"
7040 [(match_dup 3) (const_int 0)]))))
7041 (set (match_operand:SWI48 0 "register_operand" "=r")
7042 (plus:SWI48 (plus:SWI48 (match_op_dup 5
7043 [(match_dup 3) (const_int 0)])
7046 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
7047 "adc{<imodesuffix>}\t{%2, %0|%0, %2}"
7048 [(set_attr "type" "alu")
7049 (set_attr "use_carry" "1")
7050 (set_attr "pent_pair" "pu")
7051 (set_attr "mode" "<MODE>")])
7053 (define_expand "addcarry<mode>_0"
7055 [(set (reg:CCC FLAGS_REG)
7058 (match_operand:SWI48 1 "nonimmediate_operand")
7059 (match_operand:SWI48 2 "x86_64_general_operand"))
7061 (set (match_operand:SWI48 0 "register_operand")
7062 (plus:SWI48 (match_dup 1) (match_dup 2)))])]
7063 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)")
7065 (define_insn "sub<mode>3_carry"
7066 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
7069 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
7070 (match_operator:SWI 4 "ix86_carry_flag_operator"
7071 [(match_operand 3 "flags_reg_operand") (const_int 0)]))
7072 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
7073 (clobber (reg:CC FLAGS_REG))]
7074 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
7075 "sbb{<imodesuffix>}\t{%2, %0|%0, %2}"
7076 [(set_attr "type" "alu")
7077 (set_attr "use_carry" "1")
7078 (set_attr "pent_pair" "pu")
7079 (set_attr "mode" "<MODE>")])
7081 (define_insn "*sub<mode>3_carry_0"
7082 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
7084 (match_operand:SWI 1 "nonimmediate_operand" "0")
7085 (match_operator:SWI 3 "ix86_carry_flag_operator"
7086 [(match_operand 2 "flags_reg_operand") (const_int 0)])))
7087 (clobber (reg:CC FLAGS_REG))]
7088 "ix86_unary_operator_ok (MINUS, <MODE>mode, operands)"
7089 "sbb{<imodesuffix>}\t{$0, %0|%0, 0}"
7090 [(set_attr "type" "alu")
7091 (set_attr "use_carry" "1")
7092 (set_attr "pent_pair" "pu")
7093 (set_attr "mode" "<MODE>")])
7095 (define_insn "*subsi3_carry_zext"
7096 [(set (match_operand:DI 0 "register_operand" "=r")
7100 (match_operand:SI 1 "register_operand" "0")
7101 (match_operator:SI 3 "ix86_carry_flag_operator"
7102 [(reg FLAGS_REG) (const_int 0)]))
7103 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
7104 (clobber (reg:CC FLAGS_REG))]
7105 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
7106 "sbb{l}\t{%2, %k0|%k0, %2}"
7107 [(set_attr "type" "alu")
7108 (set_attr "use_carry" "1")
7109 (set_attr "pent_pair" "pu")
7110 (set_attr "mode" "SI")])
7112 (define_insn "*subsi3_carry_zext_0"
7113 [(set (match_operand:DI 0 "register_operand" "=r")
7116 (match_operand:SI 1 "register_operand" "0")
7117 (match_operator:SI 2 "ix86_carry_flag_operator"
7118 [(reg FLAGS_REG) (const_int 0)]))))
7119 (clobber (reg:CC FLAGS_REG))]
7121 "sbb{l}\t{$0, %k0|%k0, 0}"
7122 [(set_attr "type" "alu")
7123 (set_attr "use_carry" "1")
7124 (set_attr "pent_pair" "pu")
7125 (set_attr "mode" "SI")])
7127 (define_insn "sub<mode>3_carry_ccc"
7128 [(set (reg:CCC FLAGS_REG)
7130 (zero_extend:<DWI> (match_operand:DWIH 1 "register_operand" "0"))
7132 (ltu:<DWI> (reg:CC FLAGS_REG) (const_int 0))
7134 (match_operand:DWIH 2 "x86_64_sext_operand" "rmWe")))))
7135 (clobber (match_scratch:DWIH 0 "=r"))]
7137 "sbb{<imodesuffix>}\t{%2, %0|%0, %2}"
7138 [(set_attr "type" "alu")
7139 (set_attr "mode" "<MODE>")])
7141 (define_insn "*sub<mode>3_carry_ccc_1"
7142 [(set (reg:CCC FLAGS_REG)
7144 (zero_extend:<DWI> (match_operand:DWIH 1 "register_operand" "0"))
7146 (ltu:<DWI> (reg:CC FLAGS_REG) (const_int 0))
7147 (match_operand:<DWI> 2 "x86_64_dwzext_immediate_operand" "Wf"))))
7148 (clobber (match_scratch:DWIH 0 "=r"))]
7151 operands[3] = simplify_subreg (<MODE>mode, operands[2], <DWI>mode, 0);
7152 return "sbb{<imodesuffix>}\t{%3, %0|%0, %3}";
7154 [(set_attr "type" "alu")
7155 (set_attr "mode" "<MODE>")])
7157 ;; The sign flag is set from the
7158 ;; (compare (match_dup 1) (plus:DWIH (ltu:DWIH ...) (match_dup 2)))
7159 ;; result, the overflow flag likewise, but the overflow flag is also
7160 ;; set if the (plus:DWIH (ltu:DWIH ...) (match_dup 2)) overflows.
7161 (define_insn "sub<mode>3_carry_ccgz"
7162 [(set (reg:CCGZ FLAGS_REG)
7163 (unspec:CCGZ [(match_operand:DWIH 1 "register_operand" "0")
7164 (match_operand:DWIH 2 "x86_64_general_operand" "rme")
7165 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))]
7167 (clobber (match_scratch:DWIH 0 "=r"))]
7169 "sbb{<imodesuffix>}\t{%2, %0|%0, %2}"
7170 [(set_attr "type" "alu")
7171 (set_attr "mode" "<MODE>")])
7173 (define_insn "subborrow<mode>"
7174 [(set (reg:CCC FLAGS_REG)
7177 (match_operand:SWI48 1 "nonimmediate_operand" "0"))
7179 (match_operator:<DWI> 4 "ix86_carry_flag_operator"
7180 [(match_operand 3 "flags_reg_operand") (const_int 0)])
7182 (match_operand:SWI48 2 "nonimmediate_operand" "rm")))))
7183 (set (match_operand:SWI48 0 "register_operand" "=r")
7184 (minus:SWI48 (minus:SWI48
7186 (match_operator:SWI48 5 "ix86_carry_flag_operator"
7187 [(match_dup 3) (const_int 0)]))
7189 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
7190 "sbb{<imodesuffix>}\t{%2, %0|%0, %2}"
7191 [(set_attr "type" "alu")
7192 (set_attr "use_carry" "1")
7193 (set_attr "pent_pair" "pu")
7194 (set_attr "mode" "<MODE>")])
7196 (define_expand "subborrow<mode>_0"
7198 [(set (reg:CC FLAGS_REG)
7200 (match_operand:SWI48 1 "nonimmediate_operand")
7201 (match_operand:SWI48 2 "<general_operand>")))
7202 (set (match_operand:SWI48 0 "register_operand")
7203 (minus:SWI48 (match_dup 1) (match_dup 2)))])]
7204 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)")
7206 ;; Overflow setting add instructions
7208 (define_expand "addqi3_cconly_overflow"
7210 [(set (reg:CCC FLAGS_REG)
7213 (match_operand:QI 0 "nonimmediate_operand")
7214 (match_operand:QI 1 "general_operand"))
7216 (clobber (match_scratch:QI 2))])]
7217 "!(MEM_P (operands[0]) && MEM_P (operands[1]))")
7219 (define_insn "*add<mode>3_cconly_overflow_1"
7220 [(set (reg:CCC FLAGS_REG)
7223 (match_operand:SWI 1 "nonimmediate_operand" "%0")
7224 (match_operand:SWI 2 "<general_operand>" "<g>"))
7226 (clobber (match_scratch:SWI 0 "=<r>"))]
7227 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7228 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
7229 [(set_attr "type" "alu")
7230 (set_attr "mode" "<MODE>")])
7232 (define_insn "*add<mode>3_cc_overflow_1"
7233 [(set (reg:CCC FLAGS_REG)
7236 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
7237 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
7239 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
7240 (plus:SWI (match_dup 1) (match_dup 2)))]
7241 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
7242 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
7243 [(set_attr "type" "alu")
7244 (set_attr "mode" "<MODE>")])
7246 (define_insn "*addsi3_zext_cc_overflow_1"
7247 [(set (reg:CCC FLAGS_REG)
7250 (match_operand:SI 1 "nonimmediate_operand" "%0")
7251 (match_operand:SI 2 "x86_64_general_operand" "rme"))
7253 (set (match_operand:DI 0 "register_operand" "=r")
7254 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
7255 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
7256 "add{l}\t{%2, %k0|%k0, %2}"
7257 [(set_attr "type" "alu")
7258 (set_attr "mode" "SI")])
7260 (define_insn "*add<mode>3_cconly_overflow_2"
7261 [(set (reg:CCC FLAGS_REG)
7264 (match_operand:SWI 1 "nonimmediate_operand" "%0")
7265 (match_operand:SWI 2 "<general_operand>" "<g>"))
7267 (clobber (match_scratch:SWI 0 "=<r>"))]
7268 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7269 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
7270 [(set_attr "type" "alu")
7271 (set_attr "mode" "<MODE>")])
7273 (define_insn "*add<mode>3_cc_overflow_2"
7274 [(set (reg:CCC FLAGS_REG)
7277 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
7278 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
7280 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
7281 (plus:SWI (match_dup 1) (match_dup 2)))]
7282 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
7283 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
7284 [(set_attr "type" "alu")
7285 (set_attr "mode" "<MODE>")])
7287 (define_insn "*addsi3_zext_cc_overflow_2"
7288 [(set (reg:CCC FLAGS_REG)
7291 (match_operand:SI 1 "nonimmediate_operand" "%0")
7292 (match_operand:SI 2 "x86_64_general_operand" "rme"))
7294 (set (match_operand:DI 0 "register_operand" "=r")
7295 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
7296 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
7297 "add{l}\t{%2, %k0|%k0, %2}"
7298 [(set_attr "type" "alu")
7299 (set_attr "mode" "SI")])
7301 ;; The patterns that match these are at the end of this file.
7303 (define_expand "<plusminus_insn>xf3"
7304 [(set (match_operand:XF 0 "register_operand")
7306 (match_operand:XF 1 "register_operand")
7307 (match_operand:XF 2 "register_operand")))]
7310 (define_expand "<plusminus_insn><mode>3"
7311 [(set (match_operand:MODEF 0 "register_operand")
7313 (match_operand:MODEF 1 "register_operand")
7314 (match_operand:MODEF 2 "nonimmediate_operand")))]
7315 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
7316 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
7318 ;; Multiply instructions
7320 (define_expand "mul<mode>3"
7321 [(parallel [(set (match_operand:SWIM248 0 "register_operand")
7323 (match_operand:SWIM248 1 "register_operand")
7324 (match_operand:SWIM248 2 "<general_operand>")))
7325 (clobber (reg:CC FLAGS_REG))])])
7327 (define_expand "mulqi3"
7328 [(parallel [(set (match_operand:QI 0 "register_operand")
7330 (match_operand:QI 1 "register_operand")
7331 (match_operand:QI 2 "nonimmediate_operand")))
7332 (clobber (reg:CC FLAGS_REG))])]
7333 "TARGET_QIMODE_MATH")
7336 ;; IMUL reg32/64, reg32/64, imm8 Direct
7337 ;; IMUL reg32/64, mem32/64, imm8 VectorPath
7338 ;; IMUL reg32/64, reg32/64, imm32 Direct
7339 ;; IMUL reg32/64, mem32/64, imm32 VectorPath
7340 ;; IMUL reg32/64, reg32/64 Direct
7341 ;; IMUL reg32/64, mem32/64 Direct
7343 ;; On BDVER1, all above IMULs use DirectPath
7346 ;; IMUL reg16, reg16, imm8 VectorPath
7347 ;; IMUL reg16, mem16, imm8 VectorPath
7348 ;; IMUL reg16, reg16, imm16 VectorPath
7349 ;; IMUL reg16, mem16, imm16 VectorPath
7350 ;; IMUL reg16, reg16 Direct
7351 ;; IMUL reg16, mem16 Direct
7353 ;; On BDVER1, all HI MULs use DoublePath
7355 (define_insn "*mul<mode>3_1"
7356 [(set (match_operand:SWIM248 0 "register_operand" "=r,r,r")
7358 (match_operand:SWIM248 1 "nonimmediate_operand" "%rm,rm,0")
7359 (match_operand:SWIM248 2 "<general_operand>" "K,<i>,mr")))
7360 (clobber (reg:CC FLAGS_REG))]
7361 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7363 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
7364 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
7365 imul{<imodesuffix>}\t{%2, %0|%0, %2}"
7366 [(set_attr "type" "imul")
7367 (set_attr "prefix_0f" "0,0,1")
7368 (set (attr "athlon_decode")
7369 (cond [(eq_attr "cpu" "athlon")
7370 (const_string "vector")
7371 (eq_attr "alternative" "1")
7372 (const_string "vector")
7373 (and (eq_attr "alternative" "2")
7374 (ior (match_test "<MODE>mode == HImode")
7375 (match_operand 1 "memory_operand")))
7376 (const_string "vector")]
7377 (const_string "direct")))
7378 (set (attr "amdfam10_decode")
7379 (cond [(and (eq_attr "alternative" "0,1")
7380 (ior (match_test "<MODE>mode == HImode")
7381 (match_operand 1 "memory_operand")))
7382 (const_string "vector")]
7383 (const_string "direct")))
7384 (set (attr "bdver1_decode")
7386 (match_test "<MODE>mode == HImode")
7387 (const_string "double")
7388 (const_string "direct")))
7389 (set_attr "mode" "<MODE>")])
7391 (define_insn "*mulsi3_1_zext"
7392 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
7394 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
7395 (match_operand:SI 2 "x86_64_general_operand" "K,e,mr"))))
7396 (clobber (reg:CC FLAGS_REG))]
7398 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7400 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7401 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7402 imul{l}\t{%2, %k0|%k0, %2}"
7403 [(set_attr "type" "imul")
7404 (set_attr "prefix_0f" "0,0,1")
7405 (set (attr "athlon_decode")
7406 (cond [(eq_attr "cpu" "athlon")
7407 (const_string "vector")
7408 (eq_attr "alternative" "1")
7409 (const_string "vector")
7410 (and (eq_attr "alternative" "2")
7411 (match_operand 1 "memory_operand"))
7412 (const_string "vector")]
7413 (const_string "direct")))
7414 (set (attr "amdfam10_decode")
7415 (cond [(and (eq_attr "alternative" "0,1")
7416 (match_operand 1 "memory_operand"))
7417 (const_string "vector")]
7418 (const_string "direct")))
7419 (set_attr "bdver1_decode" "direct")
7420 (set_attr "mode" "SI")])
7422 ;;On AMDFAM10 and BDVER1
7426 (define_insn "*mulqi3_1"
7427 [(set (match_operand:QI 0 "register_operand" "=a")
7428 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
7429 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7430 (clobber (reg:CC FLAGS_REG))]
7432 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7434 [(set_attr "type" "imul")
7435 (set_attr "length_immediate" "0")
7436 (set (attr "athlon_decode")
7437 (if_then_else (eq_attr "cpu" "athlon")
7438 (const_string "vector")
7439 (const_string "direct")))
7440 (set_attr "amdfam10_decode" "direct")
7441 (set_attr "bdver1_decode" "direct")
7442 (set_attr "mode" "QI")])
7444 ;; Multiply with jump on overflow.
7445 (define_expand "mulv<mode>4"
7446 [(parallel [(set (reg:CCO FLAGS_REG)
7449 (match_operand:SWI248 1 "register_operand"))
7452 (mult:SWI248 (match_dup 1)
7453 (match_operand:SWI248 2
7454 "<general_operand>")))))
7455 (set (match_operand:SWI248 0 "register_operand")
7456 (mult:SWI248 (match_dup 1) (match_dup 2)))])
7457 (set (pc) (if_then_else
7458 (eq (reg:CCO FLAGS_REG) (const_int 0))
7459 (label_ref (match_operand 3))
7463 if (CONST_INT_P (operands[2]))
7464 operands[4] = operands[2];
7466 operands[4] = gen_rtx_SIGN_EXTEND (<DWI>mode, operands[2]);
7469 (define_insn "*mulv<mode>4"
7470 [(set (reg:CCO FLAGS_REG)
7473 (match_operand:SWI48 1 "nonimmediate_operand" "%rm,0"))
7475 (match_operand:SWI48 2 "x86_64_sext_operand" "We,mr")))
7477 (mult:SWI48 (match_dup 1) (match_dup 2)))))
7478 (set (match_operand:SWI48 0 "register_operand" "=r,r")
7479 (mult:SWI48 (match_dup 1) (match_dup 2)))]
7480 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7482 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
7483 imul{<imodesuffix>}\t{%2, %0|%0, %2}"
7484 [(set_attr "type" "imul")
7485 (set_attr "prefix_0f" "0,1")
7486 (set (attr "athlon_decode")
7487 (cond [(eq_attr "cpu" "athlon")
7488 (const_string "vector")
7489 (eq_attr "alternative" "0")
7490 (const_string "vector")
7491 (and (eq_attr "alternative" "1")
7492 (match_operand 1 "memory_operand"))
7493 (const_string "vector")]
7494 (const_string "direct")))
7495 (set (attr "amdfam10_decode")
7496 (cond [(and (eq_attr "alternative" "1")
7497 (match_operand 1 "memory_operand"))
7498 (const_string "vector")]
7499 (const_string "direct")))
7500 (set_attr "bdver1_decode" "direct")
7501 (set_attr "mode" "<MODE>")])
7503 (define_insn "*mulvhi4"
7504 [(set (reg:CCO FLAGS_REG)
7507 (match_operand:HI 1 "nonimmediate_operand" "%0"))
7509 (match_operand:HI 2 "nonimmediate_operand" "mr")))
7511 (mult:HI (match_dup 1) (match_dup 2)))))
7512 (set (match_operand:HI 0 "register_operand" "=r")
7513 (mult:HI (match_dup 1) (match_dup 2)))]
7514 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7515 "imul{w}\t{%2, %0|%0, %2}"
7516 [(set_attr "type" "imul")
7517 (set_attr "prefix_0f" "1")
7518 (set_attr "athlon_decode" "vector")
7519 (set_attr "amdfam10_decode" "direct")
7520 (set_attr "bdver1_decode" "double")
7521 (set_attr "mode" "HI")])
7523 (define_insn "*mulv<mode>4_1"
7524 [(set (reg:CCO FLAGS_REG)
7527 (match_operand:SWI248 1 "nonimmediate_operand" "rm,rm"))
7528 (match_operand:<DWI> 3 "const_int_operand" "K,i"))
7530 (mult:SWI248 (match_dup 1)
7531 (match_operand:SWI248 2
7532 "<immediate_operand>" "K,<i>")))))
7533 (set (match_operand:SWI248 0 "register_operand" "=r,r")
7534 (mult:SWI248 (match_dup 1) (match_dup 2)))]
7535 "!(MEM_P (operands[1]) && MEM_P (operands[2]))
7536 && CONST_INT_P (operands[2])
7537 && INTVAL (operands[2]) == INTVAL (operands[3])"
7538 "imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}"
7539 [(set_attr "type" "imul")
7540 (set (attr "prefix_0f")
7542 (match_test "<MODE>mode == HImode")
7544 (const_string "*")))
7545 (set (attr "athlon_decode")
7546 (cond [(eq_attr "cpu" "athlon")
7547 (const_string "vector")
7548 (eq_attr "alternative" "1")
7549 (const_string "vector")]
7550 (const_string "direct")))
7551 (set (attr "amdfam10_decode")
7552 (cond [(ior (match_test "<MODE>mode == HImode")
7553 (match_operand 1 "memory_operand"))
7554 (const_string "vector")]
7555 (const_string "direct")))
7556 (set (attr "bdver1_decode")
7558 (match_test "<MODE>mode == HImode")
7559 (const_string "double")
7560 (const_string "direct")))
7561 (set_attr "mode" "<MODE>")
7562 (set (attr "length_immediate")
7563 (cond [(eq_attr "alternative" "0")
7565 (match_test "<MODE_SIZE> == 8")
7567 (const_string "<MODE_SIZE>")))])
7569 (define_expand "umulv<mode>4"
7570 [(parallel [(set (reg:CCO FLAGS_REG)
7573 (match_operand:SWI248 1
7574 "nonimmediate_operand"))
7576 (match_operand:SWI248 2
7577 "nonimmediate_operand")))
7579 (mult:SWI248 (match_dup 1) (match_dup 2)))))
7580 (set (match_operand:SWI248 0 "register_operand")
7581 (mult:SWI248 (match_dup 1) (match_dup 2)))
7582 (clobber (match_scratch:SWI248 4))])
7583 (set (pc) (if_then_else
7584 (eq (reg:CCO FLAGS_REG) (const_int 0))
7585 (label_ref (match_operand 3))
7589 if (MEM_P (operands[1]) && MEM_P (operands[2]))
7590 operands[1] = force_reg (<MODE>mode, operands[1]);
7593 (define_insn "*umulv<mode>4"
7594 [(set (reg:CCO FLAGS_REG)
7597 (match_operand:SWI248 1 "nonimmediate_operand" "%0"))
7599 (match_operand:SWI248 2 "nonimmediate_operand" "rm")))
7601 (mult:SWI248 (match_dup 1) (match_dup 2)))))
7602 (set (match_operand:SWI248 0 "register_operand" "=a")
7603 (mult:SWI248 (match_dup 1) (match_dup 2)))
7604 (clobber (match_scratch:SWI248 3 "=d"))]
7605 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7606 "mul{<imodesuffix>}\t%2"
7607 [(set_attr "type" "imul")
7608 (set_attr "length_immediate" "0")
7609 (set (attr "athlon_decode")
7610 (if_then_else (eq_attr "cpu" "athlon")
7611 (const_string "vector")
7612 (const_string "double")))
7613 (set_attr "amdfam10_decode" "double")
7614 (set_attr "bdver1_decode" "direct")
7615 (set_attr "mode" "<MODE>")])
7617 (define_expand "<u>mulvqi4"
7618 [(parallel [(set (reg:CCO FLAGS_REG)
7621 (match_operand:QI 1 "nonimmediate_operand"))
7623 (match_operand:QI 2 "nonimmediate_operand")))
7625 (mult:QI (match_dup 1) (match_dup 2)))))
7626 (set (match_operand:QI 0 "register_operand")
7627 (mult:QI (match_dup 1) (match_dup 2)))])
7628 (set (pc) (if_then_else
7629 (eq (reg:CCO FLAGS_REG) (const_int 0))
7630 (label_ref (match_operand 3))
7632 "TARGET_QIMODE_MATH"
7634 if (MEM_P (operands[1]) && MEM_P (operands[2]))
7635 operands[1] = force_reg (QImode, operands[1]);
7638 (define_insn "*<u>mulvqi4"
7639 [(set (reg:CCO FLAGS_REG)
7642 (match_operand:QI 1 "nonimmediate_operand" "%0"))
7644 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7646 (mult:QI (match_dup 1) (match_dup 2)))))
7647 (set (match_operand:QI 0 "register_operand" "=a")
7648 (mult:QI (match_dup 1) (match_dup 2)))]
7650 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7651 "<sgnprefix>mul{b}\t%2"
7652 [(set_attr "type" "imul")
7653 (set_attr "length_immediate" "0")
7654 (set (attr "athlon_decode")
7655 (if_then_else (eq_attr "cpu" "athlon")
7656 (const_string "vector")
7657 (const_string "direct")))
7658 (set_attr "amdfam10_decode" "direct")
7659 (set_attr "bdver1_decode" "direct")
7660 (set_attr "mode" "QI")])
7662 (define_expand "<u>mul<mode><dwi>3"
7663 [(parallel [(set (match_operand:<DWI> 0 "register_operand")
7666 (match_operand:DWIH 1 "nonimmediate_operand"))
7668 (match_operand:DWIH 2 "register_operand"))))
7669 (clobber (reg:CC FLAGS_REG))])])
7671 (define_expand "<u>mulqihi3"
7672 [(parallel [(set (match_operand:HI 0 "register_operand")
7675 (match_operand:QI 1 "nonimmediate_operand"))
7677 (match_operand:QI 2 "register_operand"))))
7678 (clobber (reg:CC FLAGS_REG))])]
7679 "TARGET_QIMODE_MATH")
7681 (define_insn "*bmi2_umul<mode><dwi>3_1"
7682 [(set (match_operand:DWIH 0 "register_operand" "=r")
7684 (match_operand:DWIH 2 "nonimmediate_operand" "%d")
7685 (match_operand:DWIH 3 "nonimmediate_operand" "rm")))
7686 (set (match_operand:DWIH 1 "register_operand" "=r")
7689 (mult:<DWI> (zero_extend:<DWI> (match_dup 2))
7690 (zero_extend:<DWI> (match_dup 3)))
7691 (match_operand:QI 4 "const_int_operand" "n"))))]
7692 "TARGET_BMI2 && INTVAL (operands[4]) == <MODE_SIZE> * BITS_PER_UNIT
7693 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7694 "mulx\t{%3, %0, %1|%1, %0, %3}"
7695 [(set_attr "type" "imulx")
7696 (set_attr "prefix" "vex")
7697 (set_attr "mode" "<MODE>")])
7699 (define_insn "*umul<mode><dwi>3_1"
7700 [(set (match_operand:<DWI> 0 "register_operand" "=r,A")
7703 (match_operand:DWIH 1 "nonimmediate_operand" "%d,0"))
7705 (match_operand:DWIH 2 "nonimmediate_operand" "rm,rm"))))
7706 (clobber (reg:CC FLAGS_REG))]
7707 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7710 mul{<imodesuffix>}\t%2"
7711 [(set_attr "isa" "bmi2,*")
7712 (set_attr "type" "imulx,imul")
7713 (set_attr "length_immediate" "*,0")
7714 (set (attr "athlon_decode")
7715 (cond [(eq_attr "alternative" "1")
7716 (if_then_else (eq_attr "cpu" "athlon")
7717 (const_string "vector")
7718 (const_string "double"))]
7719 (const_string "*")))
7720 (set_attr "amdfam10_decode" "*,double")
7721 (set_attr "bdver1_decode" "*,direct")
7722 (set_attr "prefix" "vex,orig")
7723 (set_attr "mode" "<MODE>")])
7725 ;; Convert mul to the mulx pattern to avoid flags dependency.
7727 [(set (match_operand:<DWI> 0 "register_operand")
7730 (match_operand:DWIH 1 "register_operand"))
7732 (match_operand:DWIH 2 "nonimmediate_operand"))))
7733 (clobber (reg:CC FLAGS_REG))]
7734 "TARGET_BMI2 && reload_completed
7735 && REGNO (operands[1]) == DX_REG"
7736 [(parallel [(set (match_dup 3)
7737 (mult:DWIH (match_dup 1) (match_dup 2)))
7741 (mult:<DWI> (zero_extend:<DWI> (match_dup 1))
7742 (zero_extend:<DWI> (match_dup 2)))
7745 split_double_mode (<DWI>mode, &operands[0], 1, &operands[3], &operands[4]);
7747 operands[5] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT);
7750 (define_insn "*mul<mode><dwi>3_1"
7751 [(set (match_operand:<DWI> 0 "register_operand" "=A")
7754 (match_operand:DWIH 1 "nonimmediate_operand" "%0"))
7756 (match_operand:DWIH 2 "nonimmediate_operand" "rm"))))
7757 (clobber (reg:CC FLAGS_REG))]
7758 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7759 "imul{<imodesuffix>}\t%2"
7760 [(set_attr "type" "imul")
7761 (set_attr "length_immediate" "0")
7762 (set (attr "athlon_decode")
7763 (if_then_else (eq_attr "cpu" "athlon")
7764 (const_string "vector")
7765 (const_string "double")))
7766 (set_attr "amdfam10_decode" "double")
7767 (set_attr "bdver1_decode" "direct")
7768 (set_attr "mode" "<MODE>")])
7770 (define_insn "*<u>mulqihi3_1"
7771 [(set (match_operand:HI 0 "register_operand" "=a")
7774 (match_operand:QI 1 "nonimmediate_operand" "%0"))
7776 (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7777 (clobber (reg:CC FLAGS_REG))]
7779 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7780 "<sgnprefix>mul{b}\t%2"
7781 [(set_attr "type" "imul")
7782 (set_attr "length_immediate" "0")
7783 (set (attr "athlon_decode")
7784 (if_then_else (eq_attr "cpu" "athlon")
7785 (const_string "vector")
7786 (const_string "direct")))
7787 (set_attr "amdfam10_decode" "direct")
7788 (set_attr "bdver1_decode" "direct")
7789 (set_attr "mode" "QI")])
7791 (define_expand "<s>mul<mode>3_highpart"
7792 [(parallel [(set (match_operand:SWI48 0 "register_operand")
7797 (match_operand:SWI48 1 "nonimmediate_operand"))
7799 (match_operand:SWI48 2 "register_operand")))
7801 (clobber (match_scratch:SWI48 4))
7802 (clobber (reg:CC FLAGS_REG))])]
7804 "operands[3] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
7806 (define_insn "*<s>muldi3_highpart_1"
7807 [(set (match_operand:DI 0 "register_operand" "=d")
7812 (match_operand:DI 1 "nonimmediate_operand" "%a"))
7814 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7816 (clobber (match_scratch:DI 3 "=1"))
7817 (clobber (reg:CC FLAGS_REG))]
7819 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7820 "<sgnprefix>mul{q}\t%2"
7821 [(set_attr "type" "imul")
7822 (set_attr "length_immediate" "0")
7823 (set (attr "athlon_decode")
7824 (if_then_else (eq_attr "cpu" "athlon")
7825 (const_string "vector")
7826 (const_string "double")))
7827 (set_attr "amdfam10_decode" "double")
7828 (set_attr "bdver1_decode" "direct")
7829 (set_attr "mode" "DI")])
7831 (define_insn "*<s>mulsi3_highpart_zext"
7832 [(set (match_operand:DI 0 "register_operand" "=d")
7833 (zero_extend:DI (truncate:SI
7835 (mult:DI (any_extend:DI
7836 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7838 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7840 (clobber (match_scratch:SI 3 "=1"))
7841 (clobber (reg:CC FLAGS_REG))]
7843 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7844 "<sgnprefix>mul{l}\t%2"
7845 [(set_attr "type" "imul")
7846 (set_attr "length_immediate" "0")
7847 (set (attr "athlon_decode")
7848 (if_then_else (eq_attr "cpu" "athlon")
7849 (const_string "vector")
7850 (const_string "double")))
7851 (set_attr "amdfam10_decode" "double")
7852 (set_attr "bdver1_decode" "direct")
7853 (set_attr "mode" "SI")])
7855 (define_insn "*<s>mulsi3_highpart_1"
7856 [(set (match_operand:SI 0 "register_operand" "=d")
7861 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7863 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7865 (clobber (match_scratch:SI 3 "=1"))
7866 (clobber (reg:CC FLAGS_REG))]
7867 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7868 "<sgnprefix>mul{l}\t%2"
7869 [(set_attr "type" "imul")
7870 (set_attr "length_immediate" "0")
7871 (set (attr "athlon_decode")
7872 (if_then_else (eq_attr "cpu" "athlon")
7873 (const_string "vector")
7874 (const_string "double")))
7875 (set_attr "amdfam10_decode" "double")
7876 (set_attr "bdver1_decode" "direct")
7877 (set_attr "mode" "SI")])
7879 ;; The patterns that match these are at the end of this file.
7881 (define_expand "mulxf3"
7882 [(set (match_operand:XF 0 "register_operand")
7883 (mult:XF (match_operand:XF 1 "register_operand")
7884 (match_operand:XF 2 "register_operand")))]
7887 (define_expand "mul<mode>3"
7888 [(set (match_operand:MODEF 0 "register_operand")
7889 (mult:MODEF (match_operand:MODEF 1 "register_operand")
7890 (match_operand:MODEF 2 "nonimmediate_operand")))]
7891 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
7892 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
7894 ;; Divide instructions
7896 ;; The patterns that match these are at the end of this file.
7898 (define_expand "divxf3"
7899 [(set (match_operand:XF 0 "register_operand")
7900 (div:XF (match_operand:XF 1 "register_operand")
7901 (match_operand:XF 2 "register_operand")))]
7904 (define_expand "div<mode>3"
7905 [(set (match_operand:MODEF 0 "register_operand")
7906 (div:MODEF (match_operand:MODEF 1 "register_operand")
7907 (match_operand:MODEF 2 "nonimmediate_operand")))]
7908 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
7909 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
7911 if (<MODE>mode == SFmode
7912 && TARGET_SSE && TARGET_SSE_MATH
7914 && optimize_insn_for_speed_p ()
7915 && flag_finite_math_only && !flag_trapping_math
7916 && flag_unsafe_math_optimizations)
7918 ix86_emit_swdivsf (operands[0], operands[1],
7919 operands[2], SFmode);
7924 ;; Divmod instructions.
7926 (define_expand "divmod<mode>4"
7927 [(parallel [(set (match_operand:SWIM248 0 "register_operand")
7929 (match_operand:SWIM248 1 "register_operand")
7930 (match_operand:SWIM248 2 "nonimmediate_operand")))
7931 (set (match_operand:SWIM248 3 "register_operand")
7932 (mod:SWIM248 (match_dup 1) (match_dup 2)))
7933 (clobber (reg:CC FLAGS_REG))])])
7935 ;; Split with 8bit unsigned divide:
7936 ;; if (dividend an divisor are in [0-255])
7937 ;; use 8bit unsigned integer divide
7939 ;; use original integer divide
7941 [(set (match_operand:SWI48 0 "register_operand")
7942 (div:SWI48 (match_operand:SWI48 2 "register_operand")
7943 (match_operand:SWI48 3 "nonimmediate_operand")))
7944 (set (match_operand:SWI48 1 "register_operand")
7945 (mod:SWI48 (match_dup 2) (match_dup 3)))
7946 (clobber (reg:CC FLAGS_REG))]
7947 "TARGET_USE_8BIT_IDIV
7948 && TARGET_QIMODE_MATH
7949 && can_create_pseudo_p ()
7950 && !optimize_insn_for_size_p ()"
7952 "ix86_split_idivmod (<MODE>mode, operands, true); DONE;")
7955 [(set (match_operand:DI 0 "register_operand")
7957 (div:SI (match_operand:SI 2 "register_operand")
7958 (match_operand:SI 3 "nonimmediate_operand"))))
7959 (set (match_operand:SI 1 "register_operand")
7960 (mod:SI (match_dup 2) (match_dup 3)))
7961 (clobber (reg:CC FLAGS_REG))]
7962 "TARGET_USE_8BIT_IDIV
7963 && TARGET_QIMODE_MATH
7964 && can_create_pseudo_p ()
7965 && !optimize_insn_for_size_p ()"
7967 "ix86_split_idivmod (SImode, operands, true); DONE;")
7970 [(set (match_operand:DI 1 "register_operand")
7972 (mod:SI (match_operand:SI 2 "register_operand")
7973 (match_operand:SI 3 "nonimmediate_operand"))))
7974 (set (match_operand:SI 0 "register_operand")
7975 (div:SI (match_dup 2) (match_dup 3)))
7976 (clobber (reg:CC FLAGS_REG))]
7977 "TARGET_USE_8BIT_IDIV
7978 && TARGET_QIMODE_MATH
7979 && can_create_pseudo_p ()
7980 && !optimize_insn_for_size_p ()"
7982 "ix86_split_idivmod (SImode, operands, true); DONE;")
7984 (define_insn_and_split "divmod<mode>4_1"
7985 [(set (match_operand:SWI48 0 "register_operand" "=a")
7986 (div:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7987 (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
7988 (set (match_operand:SWI48 1 "register_operand" "=&d")
7989 (mod:SWI48 (match_dup 2) (match_dup 3)))
7990 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7991 (clobber (reg:CC FLAGS_REG))]
7995 [(parallel [(set (match_dup 1)
7996 (ashiftrt:SWI48 (match_dup 4) (match_dup 5)))
7997 (clobber (reg:CC FLAGS_REG))])
7998 (parallel [(set (match_dup 0)
7999 (div:SWI48 (match_dup 2) (match_dup 3)))
8001 (mod:SWI48 (match_dup 2) (match_dup 3)))
8003 (clobber (reg:CC FLAGS_REG))])]
8005 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
8007 if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
8008 operands[4] = operands[2];
8011 /* Avoid use of cltd in favor of a mov+shift. */
8012 emit_move_insn (operands[1], operands[2]);
8013 operands[4] = operands[1];
8016 [(set_attr "type" "multi")
8017 (set_attr "mode" "<MODE>")])
8019 (define_insn_and_split "divmodsi4_zext_1"
8020 [(set (match_operand:DI 0 "register_operand" "=a")
8022 (div:SI (match_operand:SI 2 "register_operand" "0")
8023 (match_operand:SI 3 "nonimmediate_operand" "rm"))))
8024 (set (match_operand:SI 1 "register_operand" "=&d")
8025 (mod:SI (match_dup 2) (match_dup 3)))
8026 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
8027 (clobber (reg:CC FLAGS_REG))]
8031 [(parallel [(set (match_dup 1)
8032 (ashiftrt:SI (match_dup 4) (match_dup 5)))
8033 (clobber (reg:CC FLAGS_REG))])
8034 (parallel [(set (match_dup 0)
8035 (zero_extend:DI (div:SI (match_dup 2) (match_dup 3))))
8037 (mod:SI (match_dup 2) (match_dup 3)))
8039 (clobber (reg:CC FLAGS_REG))])]
8041 operands[5] = GEN_INT (GET_MODE_BITSIZE (SImode)-1);
8043 if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
8044 operands[4] = operands[2];
8047 /* Avoid use of cltd in favor of a mov+shift. */
8048 emit_move_insn (operands[1], operands[2]);
8049 operands[4] = operands[1];
8052 [(set_attr "type" "multi")
8053 (set_attr "mode" "SI")])
8055 (define_insn_and_split "divmodsi4_zext_2"
8056 [(set (match_operand:DI 1 "register_operand" "=&d")
8058 (mod:SI (match_operand:SI 2 "register_operand" "0")
8059 (match_operand:SI 3 "nonimmediate_operand" "rm"))))
8060 (set (match_operand:SI 0 "register_operand" "=a")
8061 (div:SI (match_dup 2) (match_dup 3)))
8062 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
8063 (clobber (reg:CC FLAGS_REG))]
8067 [(parallel [(set (match_dup 6)
8068 (ashiftrt:SI (match_dup 4) (match_dup 5)))
8069 (clobber (reg:CC FLAGS_REG))])
8070 (parallel [(set (match_dup 1)
8071 (zero_extend:DI (mod:SI (match_dup 2) (match_dup 3))))
8073 (div:SI (match_dup 2) (match_dup 3)))
8075 (clobber (reg:CC FLAGS_REG))])]
8077 operands[5] = GEN_INT (GET_MODE_BITSIZE (SImode)-1);
8078 operands[6] = gen_lowpart (SImode, operands[1]);
8080 if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
8081 operands[4] = operands[2];
8084 /* Avoid use of cltd in favor of a mov+shift. */
8085 emit_move_insn (operands[6], operands[2]);
8086 operands[4] = operands[6];
8089 [(set_attr "type" "multi")
8090 (set_attr "mode" "SI")])
8092 (define_insn_and_split "*divmod<mode>4"
8093 [(set (match_operand:SWIM248 0 "register_operand" "=a")
8094 (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
8095 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
8096 (set (match_operand:SWIM248 1 "register_operand" "=&d")
8097 (mod:SWIM248 (match_dup 2) (match_dup 3)))
8098 (clobber (reg:CC FLAGS_REG))]
8102 [(parallel [(set (match_dup 1)
8103 (ashiftrt:SWIM248 (match_dup 4) (match_dup 5)))
8104 (clobber (reg:CC FLAGS_REG))])
8105 (parallel [(set (match_dup 0)
8106 (div:SWIM248 (match_dup 2) (match_dup 3)))
8108 (mod:SWIM248 (match_dup 2) (match_dup 3)))
8110 (clobber (reg:CC FLAGS_REG))])]
8112 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
8114 if (<MODE>mode != HImode
8115 && (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD))
8116 operands[4] = operands[2];
8119 /* Avoid use of cltd in favor of a mov+shift. */
8120 emit_move_insn (operands[1], operands[2]);
8121 operands[4] = operands[1];
8124 [(set_attr "type" "multi")
8125 (set_attr "mode" "<MODE>")])
8127 (define_insn_and_split "*divmodsi4_zext_1"
8128 [(set (match_operand:DI 0 "register_operand" "=a")
8130 (div:SI (match_operand:SI 2 "register_operand" "0")
8131 (match_operand:SI 3 "nonimmediate_operand" "rm"))))
8132 (set (match_operand:SI 1 "register_operand" "=&d")
8133 (mod:SI (match_dup 2) (match_dup 3)))
8134 (clobber (reg:CC FLAGS_REG))]
8138 [(parallel [(set (match_dup 1)
8139 (ashiftrt:SI (match_dup 4) (match_dup 5)))
8140 (clobber (reg:CC FLAGS_REG))])
8141 (parallel [(set (match_dup 0)
8142 (zero_extend:DI (div:SI (match_dup 2) (match_dup 3))))
8144 (mod:SI (match_dup 2) (match_dup 3)))
8146 (clobber (reg:CC FLAGS_REG))])]
8148 operands[5] = GEN_INT (GET_MODE_BITSIZE (SImode)-1);
8150 if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
8151 operands[4] = operands[2];
8154 /* Avoid use of cltd in favor of a mov+shift. */
8155 emit_move_insn (operands[1], operands[2]);
8156 operands[4] = operands[1];
8159 [(set_attr "type" "multi")
8160 (set_attr "mode" "SI")])
8162 (define_insn_and_split "*divmodsi4_zext_2"
8163 [(set (match_operand:DI 1 "register_operand" "=&d")
8165 (mod:SI (match_operand:SI 2 "register_operand" "0")
8166 (match_operand:SI 3 "nonimmediate_operand" "rm"))))
8167 (set (match_operand:SI 0 "register_operand" "=a")
8168 (div:SI (match_dup 2) (match_dup 3)))
8169 (clobber (reg:CC FLAGS_REG))]
8173 [(parallel [(set (match_dup 6)
8174 (ashiftrt:SI (match_dup 4) (match_dup 5)))
8175 (clobber (reg:CC FLAGS_REG))])
8176 (parallel [(set (match_dup 1)
8177 (zero_extend:DI (mod:SI (match_dup 2) (match_dup 3))))
8179 (div:SI (match_dup 2) (match_dup 3)))
8181 (clobber (reg:CC FLAGS_REG))])]
8183 operands[5] = GEN_INT (GET_MODE_BITSIZE (SImode)-1);
8184 operands[6] = gen_lowpart (SImode, operands[1]);
8186 if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
8187 operands[4] = operands[2];
8190 /* Avoid use of cltd in favor of a mov+shift. */
8191 emit_move_insn (operands[6], operands[2]);
8192 operands[4] = operands[6];
8195 [(set_attr "type" "multi")
8196 (set_attr "mode" "SI")])
8198 (define_insn "*divmod<mode>4_noext"
8199 [(set (match_operand:SWIM248 0 "register_operand" "=a")
8200 (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
8201 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
8202 (set (match_operand:SWIM248 1 "register_operand" "=d")
8203 (mod:SWIM248 (match_dup 2) (match_dup 3)))
8204 (use (match_operand:SWIM248 4 "register_operand" "1"))
8205 (clobber (reg:CC FLAGS_REG))]
8207 "idiv{<imodesuffix>}\t%3"
8208 [(set_attr "type" "idiv")
8209 (set_attr "mode" "<MODE>")])
8211 (define_insn "*divmodsi4_noext_zext_1"
8212 [(set (match_operand:DI 0 "register_operand" "=a")
8214 (div:SI (match_operand:SI 2 "register_operand" "0")
8215 (match_operand:SI 3 "nonimmediate_operand" "rm"))))
8216 (set (match_operand:SI 1 "register_operand" "=d")
8217 (mod:SI (match_dup 2) (match_dup 3)))
8218 (use (match_operand:SI 4 "register_operand" "1"))
8219 (clobber (reg:CC FLAGS_REG))]
8222 [(set_attr "type" "idiv")
8223 (set_attr "mode" "SI")])
8225 (define_insn "*divmodsi4_noext_zext_2"
8226 [(set (match_operand:DI 1 "register_operand" "=d")
8228 (mod:SI (match_operand:SI 2 "register_operand" "0")
8229 (match_operand:SI 3 "nonimmediate_operand" "rm"))))
8230 (set (match_operand:SI 0 "register_operand" "=a")
8231 (div:SI (match_dup 2) (match_dup 3)))
8232 (use (match_operand:SI 4 "register_operand" "1"))
8233 (clobber (reg:CC FLAGS_REG))]
8236 [(set_attr "type" "idiv")
8237 (set_attr "mode" "SI")])
8239 (define_expand "divmodqi4"
8240 [(parallel [(set (match_operand:QI 0 "register_operand")
8242 (match_operand:QI 1 "register_operand")
8243 (match_operand:QI 2 "nonimmediate_operand")))
8244 (set (match_operand:QI 3 "register_operand")
8245 (mod:QI (match_dup 1) (match_dup 2)))
8246 (clobber (reg:CC FLAGS_REG))])]
8247 "TARGET_QIMODE_MATH"
8252 tmp0 = gen_reg_rtx (HImode);
8253 tmp1 = gen_reg_rtx (HImode);
8255 /* Extend operands[1] to HImode. Generate 8bit divide. Result is in AX. */
8256 emit_insn (gen_extendqihi2 (tmp1, operands[1]));
8257 emit_insn (gen_divmodhiqi3 (tmp0, tmp1, operands[2]));
8259 /* Extract remainder from AH. */
8260 tmp1 = gen_rtx_ZERO_EXTRACT (SImode, tmp0, GEN_INT (8), GEN_INT (8));
8261 tmp1 = lowpart_subreg (QImode, tmp1, SImode);
8262 rtx_insn *insn = emit_move_insn (operands[3], tmp1);
8264 mod = gen_rtx_MOD (QImode, operands[1], operands[2]);
8265 set_unique_reg_note (insn, REG_EQUAL, mod);
8267 /* Extract quotient from AL. */
8268 insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
8270 div = gen_rtx_DIV (QImode, operands[1], operands[2]);
8271 set_unique_reg_note (insn, REG_EQUAL, div);
8276 ;; Divide AX by r/m8, with result stored in
8279 ;; Change div/mod to HImode and extend the second argument to HImode
8280 ;; so that mode of div/mod matches with mode of arguments. Otherwise
8281 ;; combine may fail.
8282 (define_insn "divmodhiqi3"
8283 [(set (match_operand:HI 0 "register_operand" "=a")
8288 (mod:HI (match_operand:HI 1 "register_operand" "0")
8290 (match_operand:QI 2 "nonimmediate_operand" "qm")))))
8294 (div:HI (match_dup 1) (sign_extend:HI (match_dup 2)))))))
8295 (clobber (reg:CC FLAGS_REG))]
8296 "TARGET_QIMODE_MATH"
8298 [(set_attr "type" "idiv")
8299 (set_attr "mode" "QI")])
8301 (define_expand "udivmod<mode>4"
8302 [(parallel [(set (match_operand:SWIM248 0 "register_operand")
8304 (match_operand:SWIM248 1 "register_operand")
8305 (match_operand:SWIM248 2 "nonimmediate_operand")))
8306 (set (match_operand:SWIM248 3 "register_operand")
8307 (umod:SWIM248 (match_dup 1) (match_dup 2)))
8308 (clobber (reg:CC FLAGS_REG))])])
8310 ;; Split with 8bit unsigned divide:
8311 ;; if (dividend an divisor are in [0-255])
8312 ;; use 8bit unsigned integer divide
8314 ;; use original integer divide
8316 [(set (match_operand:SWI48 0 "register_operand")
8317 (udiv:SWI48 (match_operand:SWI48 2 "register_operand")
8318 (match_operand:SWI48 3 "nonimmediate_operand")))
8319 (set (match_operand:SWI48 1 "register_operand")
8320 (umod:SWI48 (match_dup 2) (match_dup 3)))
8321 (clobber (reg:CC FLAGS_REG))]
8322 "TARGET_USE_8BIT_IDIV
8323 && TARGET_QIMODE_MATH
8324 && can_create_pseudo_p ()
8325 && !optimize_insn_for_size_p ()"
8327 "ix86_split_idivmod (<MODE>mode, operands, false); DONE;")
8330 [(set (match_operand:DI 0 "register_operand")
8332 (udiv:SI (match_operand:SI 2 "register_operand")
8333 (match_operand:SI 3 "nonimmediate_operand"))))
8334 (set (match_operand:SI 1 "register_operand")
8335 (umod:SI (match_dup 2) (match_dup 3)))
8336 (clobber (reg:CC FLAGS_REG))]
8338 && TARGET_USE_8BIT_IDIV
8339 && TARGET_QIMODE_MATH
8340 && can_create_pseudo_p ()
8341 && !optimize_insn_for_size_p ()"
8343 "ix86_split_idivmod (SImode, operands, false); DONE;")
8346 [(set (match_operand:DI 1 "register_operand")
8348 (umod:SI (match_operand:SI 2 "register_operand")
8349 (match_operand:SI 3 "nonimmediate_operand"))))
8350 (set (match_operand:SI 0 "register_operand")
8351 (udiv:SI (match_dup 2) (match_dup 3)))
8352 (clobber (reg:CC FLAGS_REG))]
8354 && TARGET_USE_8BIT_IDIV
8355 && TARGET_QIMODE_MATH
8356 && can_create_pseudo_p ()
8357 && !optimize_insn_for_size_p ()"
8359 "ix86_split_idivmod (SImode, operands, false); DONE;")
8361 (define_insn_and_split "udivmod<mode>4_1"
8362 [(set (match_operand:SWI48 0 "register_operand" "=a")
8363 (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "0")
8364 (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
8365 (set (match_operand:SWI48 1 "register_operand" "=&d")
8366 (umod:SWI48 (match_dup 2) (match_dup 3)))
8367 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
8368 (clobber (reg:CC FLAGS_REG))]
8372 [(set (match_dup 1) (const_int 0))
8373 (parallel [(set (match_dup 0)
8374 (udiv:SWI48 (match_dup 2) (match_dup 3)))
8376 (umod:SWI48 (match_dup 2) (match_dup 3)))
8378 (clobber (reg:CC FLAGS_REG))])]
8380 [(set_attr "type" "multi")
8381 (set_attr "mode" "<MODE>")])
8383 (define_insn_and_split "udivmodsi4_zext_1"
8384 [(set (match_operand:DI 0 "register_operand" "=a")
8386 (udiv:SI (match_operand:SI 2 "register_operand" "0")
8387 (match_operand:SI 3 "nonimmediate_operand" "rm"))))
8388 (set (match_operand:SI 1 "register_operand" "=&d")
8389 (umod:SI (match_dup 2) (match_dup 3)))
8390 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
8391 (clobber (reg:CC FLAGS_REG))]
8395 [(set (match_dup 1) (const_int 0))
8396 (parallel [(set (match_dup 0)
8397 (zero_extend:DI (udiv:SI (match_dup 2) (match_dup 3))))
8399 (umod:SI (match_dup 2) (match_dup 3)))
8401 (clobber (reg:CC FLAGS_REG))])]
8403 [(set_attr "type" "multi")
8404 (set_attr "mode" "SI")])
8406 (define_insn_and_split "udivmodsi4_zext_2"
8407 [(set (match_operand:DI 1 "register_operand" "=&d")
8409 (umod:SI (match_operand:SI 2 "register_operand" "0")
8410 (match_operand:SI 3 "nonimmediate_operand" "rm"))))
8411 (set (match_operand:SI 0 "register_operand" "=a")
8412 (udiv:SI (match_dup 2) (match_dup 3)))
8413 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
8414 (clobber (reg:CC FLAGS_REG))]
8418 [(set (match_dup 4) (const_int 0))
8419 (parallel [(set (match_dup 1)
8420 (zero_extend:DI (umod:SI (match_dup 2) (match_dup 3))))
8422 (udiv:SI (match_dup 2) (match_dup 3)))
8424 (clobber (reg:CC FLAGS_REG))])]
8425 "operands[4] = gen_lowpart (SImode, operands[1]);"
8426 [(set_attr "type" "multi")
8427 (set_attr "mode" "SI")])
8429 (define_insn_and_split "*udivmod<mode>4"
8430 [(set (match_operand:SWIM248 0 "register_operand" "=a")
8431 (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
8432 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
8433 (set (match_operand:SWIM248 1 "register_operand" "=&d")
8434 (umod:SWIM248 (match_dup 2) (match_dup 3)))
8435 (clobber (reg:CC FLAGS_REG))]
8439 [(set (match_dup 1) (const_int 0))
8440 (parallel [(set (match_dup 0)
8441 (udiv:SWIM248 (match_dup 2) (match_dup 3)))
8443 (umod:SWIM248 (match_dup 2) (match_dup 3)))
8445 (clobber (reg:CC FLAGS_REG))])]
8447 [(set_attr "type" "multi")
8448 (set_attr "mode" "<MODE>")])
8450 (define_insn_and_split "*udivmodsi4_zext_1"
8451 [(set (match_operand:DI 0 "register_operand" "=a")
8453 (udiv:SI (match_operand:SI 2 "register_operand" "0")
8454 (match_operand:SI 3 "nonimmediate_operand" "rm"))))
8455 (set (match_operand:SI 1 "register_operand" "=&d")
8456 (umod:SI (match_dup 2) (match_dup 3)))
8457 (clobber (reg:CC FLAGS_REG))]
8461 [(set (match_dup 1) (const_int 0))
8462 (parallel [(set (match_dup 0)
8463 (zero_extend:DI (udiv:SI (match_dup 2) (match_dup 3))))
8465 (umod:SI (match_dup 2) (match_dup 3)))
8467 (clobber (reg:CC FLAGS_REG))])]
8469 [(set_attr "type" "multi")
8470 (set_attr "mode" "SI")])
8472 (define_insn_and_split "*udivmodsi4_zext_2"
8473 [(set (match_operand:DI 1 "register_operand" "=&d")
8475 (umod:SI (match_operand:SI 2 "register_operand" "0")
8476 (match_operand:SI 3 "nonimmediate_operand" "rm"))))
8477 (set (match_operand:SI 0 "register_operand" "=a")
8478 (udiv:SI (match_dup 2) (match_dup 3)))
8479 (clobber (reg:CC FLAGS_REG))]
8483 [(set (match_dup 4) (const_int 0))
8484 (parallel [(set (match_dup 1)
8485 (zero_extend:DI (umod:SI (match_dup 2) (match_dup 3))))
8487 (udiv:SI (match_dup 2) (match_dup 3)))
8489 (clobber (reg:CC FLAGS_REG))])]
8490 "operands[4] = gen_lowpart (SImode, operands[1]);"
8491 [(set_attr "type" "multi")
8492 (set_attr "mode" "SI")])
8494 ;; Optimize division or modulo by constant power of 2, if the constant
8495 ;; materializes only after expansion.
8496 (define_insn_and_split "*udivmod<mode>4_pow2"
8497 [(set (match_operand:SWI48 0 "register_operand" "=r")
8498 (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "0")
8499 (match_operand:SWI48 3 "const_int_operand" "n")))
8500 (set (match_operand:SWI48 1 "register_operand" "=r")
8501 (umod:SWI48 (match_dup 2) (match_dup 3)))
8502 (clobber (reg:CC FLAGS_REG))]
8503 "IN_RANGE (INTVAL (operands[3]), 2, HOST_WIDE_INT_UC (0x80000000))
8504 && (UINTVAL (operands[3]) & (UINTVAL (operands[3]) - 1)) == 0"
8507 [(set (match_dup 1) (match_dup 2))
8508 (parallel [(set (match_dup 0) (lshiftrt:<MODE> (match_dup 2) (match_dup 4)))
8509 (clobber (reg:CC FLAGS_REG))])
8510 (parallel [(set (match_dup 1) (and:<MODE> (match_dup 1) (match_dup 5)))
8511 (clobber (reg:CC FLAGS_REG))])]
8513 int v = exact_log2 (UINTVAL (operands[3]));
8514 operands[4] = GEN_INT (v);
8515 operands[5] = GEN_INT ((HOST_WIDE_INT_1U << v) - 1);
8517 [(set_attr "type" "multi")
8518 (set_attr "mode" "<MODE>")])
8520 (define_insn_and_split "*udivmodsi4_pow2_zext_1"
8521 [(set (match_operand:DI 0 "register_operand" "=r")
8523 (udiv:SI (match_operand:SI 2 "register_operand" "0")
8524 (match_operand:SI 3 "const_int_operand" "n"))))
8525 (set (match_operand:SI 1 "register_operand" "=r")
8526 (umod:SI (match_dup 2) (match_dup 3)))
8527 (clobber (reg:CC FLAGS_REG))]
8529 && IN_RANGE (INTVAL (operands[3]), 2, HOST_WIDE_INT_UC (0x80000000))
8530 && (UINTVAL (operands[3]) & (UINTVAL (operands[3]) - 1)) == 0"
8533 [(set (match_dup 1) (match_dup 2))
8534 (parallel [(set (match_dup 0)
8535 (zero_extend:DI (lshiftrt:SI (match_dup 2) (match_dup 4))))
8536 (clobber (reg:CC FLAGS_REG))])
8537 (parallel [(set (match_dup 1) (and:SI (match_dup 1) (match_dup 5)))
8538 (clobber (reg:CC FLAGS_REG))])]
8540 int v = exact_log2 (UINTVAL (operands[3]));
8541 operands[4] = GEN_INT (v);
8542 operands[5] = GEN_INT ((HOST_WIDE_INT_1U << v) - 1);
8544 [(set_attr "type" "multi")
8545 (set_attr "mode" "SI")])
8547 (define_insn_and_split "*udivmodsi4_pow2_zext_2"
8548 [(set (match_operand:DI 1 "register_operand" "=r")
8550 (umod:SI (match_operand:SI 2 "register_operand" "0")
8551 (match_operand:SI 3 "const_int_operand" "n"))))
8552 (set (match_operand:SI 0 "register_operand" "=r")
8553 (umod:SI (match_dup 2) (match_dup 3)))
8554 (clobber (reg:CC FLAGS_REG))]
8556 && IN_RANGE (INTVAL (operands[3]), 2, HOST_WIDE_INT_UC (0x80000000))
8557 && (UINTVAL (operands[3]) & (UINTVAL (operands[3]) - 1)) == 0"
8560 [(set (match_dup 1) (match_dup 2))
8561 (parallel [(set (match_dup 0) (lshiftrt:SI (match_dup 2) (match_dup 4)))
8562 (clobber (reg:CC FLAGS_REG))])
8563 (parallel [(set (match_dup 1)
8564 (zero_extend:DI (and:SI (match_dup 1) (match_dup 5))))
8565 (clobber (reg:CC FLAGS_REG))])]
8567 int v = exact_log2 (UINTVAL (operands[3]));
8568 operands[4] = GEN_INT (v);
8569 operands[5] = GEN_INT ((HOST_WIDE_INT_1U << v) - 1);
8571 [(set_attr "type" "multi")
8572 (set_attr "mode" "SI")])
8574 (define_insn "*udivmod<mode>4_noext"
8575 [(set (match_operand:SWIM248 0 "register_operand" "=a")
8576 (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
8577 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
8578 (set (match_operand:SWIM248 1 "register_operand" "=d")
8579 (umod:SWIM248 (match_dup 2) (match_dup 3)))
8580 (use (match_operand:SWIM248 4 "register_operand" "1"))
8581 (clobber (reg:CC FLAGS_REG))]
8583 "div{<imodesuffix>}\t%3"
8584 [(set_attr "type" "idiv")
8585 (set_attr "mode" "<MODE>")])
8587 (define_insn "*udivmodsi4_noext_zext_1"
8588 [(set (match_operand:DI 0 "register_operand" "=a")
8590 (udiv:SI (match_operand:SI 2 "register_operand" "0")
8591 (match_operand:SI 3 "nonimmediate_operand" "rm"))))
8592 (set (match_operand:SI 1 "register_operand" "=d")
8593 (umod:SI (match_dup 2) (match_dup 3)))
8594 (use (match_operand:SI 4 "register_operand" "1"))
8595 (clobber (reg:CC FLAGS_REG))]
8598 [(set_attr "type" "idiv")
8599 (set_attr "mode" "SI")])
8601 (define_insn "*udivmodsi4_noext_zext_2"
8602 [(set (match_operand:DI 1 "register_operand" "=d")
8604 (umod:SI (match_operand:SI 2 "register_operand" "0")
8605 (match_operand:SI 3 "nonimmediate_operand" "rm"))))
8606 (set (match_operand:SI 0 "register_operand" "=a")
8607 (udiv:SI (match_dup 2) (match_dup 3)))
8608 (use (match_operand:SI 4 "register_operand" "1"))
8609 (clobber (reg:CC FLAGS_REG))]
8612 [(set_attr "type" "idiv")
8613 (set_attr "mode" "SI")])
8615 (define_expand "udivmodqi4"
8616 [(parallel [(set (match_operand:QI 0 "register_operand")
8618 (match_operand:QI 1 "register_operand")
8619 (match_operand:QI 2 "nonimmediate_operand")))
8620 (set (match_operand:QI 3 "register_operand")
8621 (umod:QI (match_dup 1) (match_dup 2)))
8622 (clobber (reg:CC FLAGS_REG))])]
8623 "TARGET_QIMODE_MATH"
8628 tmp0 = gen_reg_rtx (HImode);
8629 tmp1 = gen_reg_rtx (HImode);
8631 /* Extend operands[1] to HImode. Generate 8bit divide. Result is in AX. */
8632 emit_insn (gen_zero_extendqihi2 (tmp1, operands[1]));
8633 emit_insn (gen_udivmodhiqi3 (tmp0, tmp1, operands[2]));
8635 /* Extract remainder from AH. */
8636 tmp1 = gen_rtx_ZERO_EXTRACT (SImode, tmp0, GEN_INT (8), GEN_INT (8));
8637 tmp1 = lowpart_subreg (QImode, tmp1, SImode);
8638 rtx_insn *insn = emit_move_insn (operands[3], tmp1);
8640 mod = gen_rtx_UMOD (QImode, operands[1], operands[2]);
8641 set_unique_reg_note (insn, REG_EQUAL, mod);
8643 /* Extract quotient from AL. */
8644 insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
8646 div = gen_rtx_UDIV (QImode, operands[1], operands[2]);
8647 set_unique_reg_note (insn, REG_EQUAL, div);
8652 (define_insn "udivmodhiqi3"
8653 [(set (match_operand:HI 0 "register_operand" "=a")
8658 (mod:HI (match_operand:HI 1 "register_operand" "0")
8660 (match_operand:QI 2 "nonimmediate_operand" "qm")))))
8664 (div:HI (match_dup 1) (zero_extend:HI (match_dup 2)))))))
8665 (clobber (reg:CC FLAGS_REG))]
8666 "TARGET_QIMODE_MATH"
8668 [(set_attr "type" "idiv")
8669 (set_attr "mode" "QI")])
8671 ;; We cannot use div/idiv for double division, because it causes
8672 ;; "division by zero" on the overflow and that's not what we expect
8673 ;; from truncate. Because true (non truncating) double division is
8674 ;; never generated, we can't create this insn anyway.
8677 ; [(set (match_operand:SI 0 "register_operand" "=a")
8679 ; (udiv:DI (match_operand:DI 1 "register_operand" "A")
8681 ; (match_operand:SI 2 "nonimmediate_operand" "rm")))))
8682 ; (set (match_operand:SI 3 "register_operand" "=d")
8684 ; (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
8685 ; (clobber (reg:CC FLAGS_REG))]
8687 ; "div{l}\t{%2, %0|%0, %2}"
8688 ; [(set_attr "type" "idiv")])
8690 ;;- Logical AND instructions
8692 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
8693 ;; Note that this excludes ah.
8695 (define_expand "testsi_ccno_1"
8696 [(set (reg:CCNO FLAGS_REG)
8698 (and:SI (match_operand:SI 0 "nonimmediate_operand")
8699 (match_operand:SI 1 "x86_64_nonmemory_operand"))
8702 (define_expand "testqi_ccz_1"
8703 [(set (reg:CCZ FLAGS_REG)
8704 (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand")
8705 (match_operand:QI 1 "nonmemory_operand"))
8708 (define_expand "testdi_ccno_1"
8709 [(set (reg:CCNO FLAGS_REG)
8711 (and:DI (match_operand:DI 0 "nonimmediate_operand")
8712 (match_operand:DI 1 "x86_64_szext_general_operand"))
8714 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))")
8716 (define_insn "*testdi_1"
8717 [(set (reg FLAGS_REG)
8720 (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
8721 (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
8723 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8724 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8726 test{l}\t{%k1, %k0|%k0, %k1}
8727 test{l}\t{%k1, %k0|%k0, %k1}
8728 test{q}\t{%1, %0|%0, %1}
8729 test{q}\t{%1, %0|%0, %1}
8730 test{q}\t{%1, %0|%0, %1}"
8731 [(set_attr "type" "test")
8732 (set_attr "modrm" "0,1,0,1,1")
8733 (set_attr "mode" "SI,SI,DI,DI,DI")])
8735 (define_insn "*testqi_1_maybe_si"
8736 [(set (reg FLAGS_REG)
8739 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
8740 (match_operand:QI 1 "general_operand" "n,n,qn,n"))
8742 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
8743 && ix86_match_ccmode (insn,
8744 CONST_INT_P (operands[1])
8745 && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
8747 if (which_alternative == 3)
8749 if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
8750 operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
8751 return "test{l}\t{%1, %k0|%k0, %1}";
8753 return "test{b}\t{%1, %0|%0, %1}";
8755 [(set_attr "type" "test")
8756 (set_attr "modrm" "0,1,1,1")
8757 (set_attr "mode" "QI,QI,QI,SI")
8758 (set_attr "pent_pair" "uv,np,uv,np")])
8760 (define_insn "*test<mode>_1"
8761 [(set (reg FLAGS_REG)
8764 (match_operand:SWI124 0 "nonimmediate_operand" "%!*a,<r>,<r>m")
8765 (match_operand:SWI124 1 "<general_operand>" "<i>,<i>,<r><i>"))
8767 "ix86_match_ccmode (insn, CCNOmode)
8768 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8769 "test{<imodesuffix>}\t{%1, %0|%0, %1}"
8770 [(set_attr "type" "test")
8771 (set_attr "modrm" "0,1,1")
8772 (set_attr "mode" "<MODE>")
8773 (set_attr "pent_pair" "uv,np,uv")])
8775 (define_expand "testqi_ext_1_ccno"
8776 [(set (reg:CCNO FLAGS_REG)
8780 (zero_extract:SI (match_operand 0 "ext_register_operand")
8783 (match_operand 1 "const_int_operand"))
8786 (define_insn "*testqi_ext_1"
8787 [(set (reg FLAGS_REG)
8791 (zero_extract:SI (match_operand 0 "ext_register_operand" "Q,Q")
8794 (match_operand:QI 1 "general_operand" "QnBc,m"))
8796 "ix86_match_ccmode (insn, CCNOmode)"
8797 "test{b}\t{%1, %h0|%h0, %1}"
8798 [(set_attr "isa" "*,nox64")
8799 (set_attr "type" "test")
8800 (set_attr "mode" "QI")])
8802 (define_insn "*testqi_ext_2"
8803 [(set (reg FLAGS_REG)
8807 (zero_extract:SI (match_operand 0 "ext_register_operand" "Q")
8811 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q")
8815 "ix86_match_ccmode (insn, CCNOmode)"
8816 "test{b}\t{%h1, %h0|%h0, %h1}"
8817 [(set_attr "type" "test")
8818 (set_attr "mode" "QI")])
8820 ;; Combine likes to form bit extractions for some tests. Humor it.
8821 (define_insn_and_split "*testqi_ext_3"
8822 [(set (match_operand 0 "flags_reg_operand")
8823 (match_operator 1 "compare_operator"
8824 [(zero_extract:SWI248
8825 (match_operand 2 "nonimmediate_operand" "rm")
8826 (match_operand 3 "const_int_operand" "n")
8827 (match_operand 4 "const_int_operand" "n"))
8829 "ix86_match_ccmode (insn, CCNOmode)
8830 && ((TARGET_64BIT && GET_MODE (operands[2]) == DImode)
8831 || GET_MODE (operands[2]) == SImode
8832 || GET_MODE (operands[2]) == HImode
8833 || GET_MODE (operands[2]) == QImode)
8834 /* Ensure that resulting mask is zero or sign extended operand. */
8835 && INTVAL (operands[4]) >= 0
8836 && ((INTVAL (operands[3]) > 0
8837 && INTVAL (operands[3]) + INTVAL (operands[4]) <= 32)
8838 || (<MODE>mode == DImode
8839 && INTVAL (operands[3]) > 32
8840 && INTVAL (operands[3]) + INTVAL (operands[4]) == 64))"
8843 [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
8845 rtx val = operands[2];
8846 HOST_WIDE_INT len = INTVAL (operands[3]);
8847 HOST_WIDE_INT pos = INTVAL (operands[4]);
8848 machine_mode mode = GET_MODE (val);
8852 machine_mode submode = GET_MODE (SUBREG_REG (val));
8854 /* Narrow paradoxical subregs to prevent partial register stalls. */
8855 if (GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode)
8856 && GET_MODE_CLASS (submode) == MODE_INT)
8858 val = SUBREG_REG (val);
8863 /* Small HImode tests can be converted to QImode. */
8864 if (register_operand (val, HImode) && pos + len <= 8)
8866 val = gen_lowpart (QImode, val);
8870 gcc_assert (pos + len <= GET_MODE_PRECISION (mode));
8873 = wi::shifted_mask (pos, len, false, GET_MODE_PRECISION (mode));
8875 operands[2] = gen_rtx_AND (mode, val, immed_wide_int_const (mask, mode));
8878 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
8879 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
8880 ;; this is relatively important trick.
8881 ;; Do the conversion only post-reload to avoid limiting of the register class
8884 [(set (match_operand 0 "flags_reg_operand")
8885 (match_operator 1 "compare_operator"
8886 [(and (match_operand 2 "QIreg_operand")
8887 (match_operand 3 "const_int_operand"))
8890 && GET_MODE (operands[2]) != QImode
8891 && ((ix86_match_ccmode (insn, CCZmode)
8892 && !(INTVAL (operands[3]) & ~(255 << 8)))
8893 || (ix86_match_ccmode (insn, CCNOmode)
8894 && !(INTVAL (operands[3]) & ~(127 << 8))))"
8899 (zero_extract:SI (match_dup 2)
8905 operands[2] = gen_lowpart (SImode, operands[2]);
8906 operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, QImode);
8910 [(set (match_operand 0 "flags_reg_operand")
8911 (match_operator 1 "compare_operator"
8912 [(and (match_operand 2 "nonimmediate_operand")
8913 (match_operand 3 "const_int_operand"))
8916 && GET_MODE (operands[2]) != QImode
8917 && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
8918 && ((ix86_match_ccmode (insn, CCZmode)
8919 && !(INTVAL (operands[3]) & ~255))
8920 || (ix86_match_ccmode (insn, CCNOmode)
8921 && !(INTVAL (operands[3]) & ~127)))"
8923 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
8926 operands[2] = gen_lowpart (QImode, operands[2]);
8927 operands[3] = gen_int_mode (INTVAL (operands[3]), QImode);
8930 ;; %%% This used to optimize known byte-wide and operations to memory,
8931 ;; and sometimes to QImode registers. If this is considered useful,
8932 ;; it should be done with splitters.
8934 (define_expand "and<mode>3"
8935 [(set (match_operand:SWIM1248x 0 "nonimmediate_operand")
8936 (and:SWIM1248x (match_operand:SWIM1248x 1 "nonimmediate_operand")
8937 (match_operand:SWIM1248x 2 "<general_szext_operand>")))]
8940 machine_mode mode = <MODE>mode;
8941 rtx (*insn) (rtx, rtx);
8943 if (CONST_INT_P (operands[2]) && REG_P (operands[0]))
8945 HOST_WIDE_INT ival = INTVAL (operands[2]);
8947 if (ival == (HOST_WIDE_INT) 0xffffffff)
8949 else if (ival == 0xffff)
8951 else if (ival == 0xff)
8955 if (mode == <MODE>mode)
8957 ix86_expand_binary_operator (AND, <MODE>mode, operands);
8961 if (<MODE>mode == DImode)
8962 insn = (mode == SImode)
8963 ? gen_zero_extendsidi2
8965 ? gen_zero_extendhidi2
8966 : gen_zero_extendqidi2;
8967 else if (<MODE>mode == SImode)
8968 insn = (mode == HImode)
8969 ? gen_zero_extendhisi2
8970 : gen_zero_extendqisi2;
8971 else if (<MODE>mode == HImode)
8972 insn = gen_zero_extendqihi2;
8976 emit_insn (insn (operands[0], gen_lowpart (mode, operands[1])));
8980 (define_insn_and_split "*anddi3_doubleword"
8981 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r")
8983 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8984 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm")))
8985 (clobber (reg:CC FLAGS_REG))]
8986 "!TARGET_64BIT && TARGET_STV && TARGET_SSE2
8987 && ix86_binary_operator_ok (AND, DImode, operands)"
8989 "&& reload_completed"
8992 split_double_mode (DImode, &operands[0], 3, &operands[0], &operands[3]);
8993 if (operands[2] == const0_rtx)
8995 operands[1] = const0_rtx;
8996 ix86_expand_move (SImode, &operands[0]);
8998 else if (operands[2] != constm1_rtx)
8999 ix86_expand_binary_operator (AND, SImode, &operands[0]);
9000 else if (operands[5] == constm1_rtx)
9001 emit_note (NOTE_INSN_DELETED);
9002 if (operands[5] == const0_rtx)
9004 operands[4] = const0_rtx;
9005 ix86_expand_move (SImode, &operands[3]);
9007 else if (operands[5] != constm1_rtx)
9008 ix86_expand_binary_operator (AND, SImode, &operands[3]);
9012 (define_insn "*anddi_1"
9013 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
9015 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
9016 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
9017 (clobber (reg:CC FLAGS_REG))]
9018 "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
9020 and{l}\t{%k2, %k0|%k0, %k2}
9021 and{q}\t{%2, %0|%0, %2}
9022 and{q}\t{%2, %0|%0, %2}
9024 [(set_attr "type" "alu,alu,alu,imovx")
9025 (set_attr "length_immediate" "*,*,*,0")
9026 (set (attr "prefix_rex")
9028 (and (eq_attr "type" "imovx")
9029 (and (match_test "INTVAL (operands[2]) == 0xff")
9030 (match_operand 1 "ext_QIreg_operand")))
9032 (const_string "*")))
9033 (set_attr "mode" "SI,DI,DI,SI")])
9035 (define_insn_and_split "*anddi_1_btr"
9036 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9038 (match_operand:DI 1 "nonimmediate_operand" "%0")
9039 (match_operand:DI 2 "const_int_operand" "n")))
9040 (clobber (reg:CC FLAGS_REG))]
9041 "TARGET_64BIT && TARGET_USE_BT
9042 && ix86_binary_operator_ok (AND, DImode, operands)
9043 && IN_RANGE (exact_log2 (~INTVAL (operands[2])), 31, 63)"
9045 "&& reload_completed"
9046 [(parallel [(set (zero_extract:DI (match_dup 0)
9050 (clobber (reg:CC FLAGS_REG))])]
9051 "operands[3] = GEN_INT (exact_log2 (~INTVAL (operands[2])));"
9052 [(set_attr "type" "alu1")
9053 (set_attr "prefix_0f" "1")
9054 (set_attr "znver1_decode" "double")
9055 (set_attr "mode" "DI")])
9057 ;; Turn *anddi_1 into *andsi_1_zext if possible.
9059 [(set (match_operand:DI 0 "register_operand")
9060 (and:DI (subreg:DI (match_operand:SI 1 "register_operand") 0)
9061 (match_operand:DI 2 "x86_64_zext_immediate_operand")))
9062 (clobber (reg:CC FLAGS_REG))]
9064 [(parallel [(set (match_dup 0)
9065 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))
9066 (clobber (reg:CC FLAGS_REG))])]
9067 "operands[2] = gen_lowpart (SImode, operands[2]);")
9069 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9070 (define_insn "*andsi_1_zext"
9071 [(set (match_operand:DI 0 "register_operand" "=r")
9073 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9074 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
9075 (clobber (reg:CC FLAGS_REG))]
9076 "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
9077 "and{l}\t{%2, %k0|%k0, %2}"
9078 [(set_attr "type" "alu")
9079 (set_attr "mode" "SI")])
9081 (define_insn "*and<mode>_1"
9082 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=rm,r,Ya")
9083 (and:SWI24 (match_operand:SWI24 1 "nonimmediate_operand" "%0,0,qm")
9084 (match_operand:SWI24 2 "<general_operand>" "r<i>,rm,L")))
9085 (clobber (reg:CC FLAGS_REG))]
9086 "ix86_binary_operator_ok (AND, <MODE>mode, operands)"
9088 and{<imodesuffix>}\t{%2, %0|%0, %2}
9089 and{<imodesuffix>}\t{%2, %0|%0, %2}
9091 [(set_attr "type" "alu,alu,imovx")
9092 (set_attr "length_immediate" "*,*,0")
9093 (set (attr "prefix_rex")
9095 (and (eq_attr "type" "imovx")
9096 (and (match_test "INTVAL (operands[2]) == 0xff")
9097 (match_operand 1 "ext_QIreg_operand")))
9099 (const_string "*")))
9100 (set_attr "mode" "<MODE>,<MODE>,SI")])
9102 (define_insn "*andqi_1"
9103 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
9104 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9105 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
9106 (clobber (reg:CC FLAGS_REG))]
9107 "ix86_binary_operator_ok (AND, QImode, operands)"
9109 and{b}\t{%2, %0|%0, %2}
9110 and{b}\t{%2, %0|%0, %2}
9111 and{l}\t{%k2, %k0|%k0, %k2}"
9112 [(set_attr "type" "alu")
9113 (set_attr "mode" "QI,QI,SI")
9114 ;; Potential partial reg stall on alternative 2.
9115 (set (attr "preferred_for_speed")
9116 (cond [(eq_attr "alternative" "2")
9117 (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
9118 (symbol_ref "true")))])
9120 (define_insn "*andqi_1_slp"
9121 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
9122 (and:QI (match_dup 0)
9123 (match_operand:QI 1 "general_operand" "qn,qmn")))
9124 (clobber (reg:CC FLAGS_REG))]
9125 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9126 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9127 "and{b}\t{%1, %0|%0, %1}"
9128 [(set_attr "type" "alu1")
9129 (set_attr "mode" "QI")])
9132 [(set (match_operand:SWI248 0 "register_operand")
9133 (and:SWI248 (match_operand:SWI248 1 "nonimmediate_operand")
9134 (match_operand:SWI248 2 "const_int_operand")))
9135 (clobber (reg:CC FLAGS_REG))]
9137 && (!REG_P (operands[1])
9138 || REGNO (operands[0]) != REGNO (operands[1]))"
9141 HOST_WIDE_INT ival = INTVAL (operands[2]);
9143 rtx (*insn) (rtx, rtx);
9145 if (ival == (HOST_WIDE_INT) 0xffffffff)
9147 else if (ival == 0xffff)
9151 gcc_assert (ival == 0xff);
9155 if (<MODE>mode == DImode)
9156 insn = (mode == SImode)
9157 ? gen_zero_extendsidi2
9159 ? gen_zero_extendhidi2
9160 : gen_zero_extendqidi2;
9163 if (<MODE>mode != SImode)
9164 /* Zero extend to SImode to avoid partial register stalls. */
9165 operands[0] = gen_lowpart (SImode, operands[0]);
9167 insn = (mode == HImode)
9168 ? gen_zero_extendhisi2
9169 : gen_zero_extendqisi2;
9171 emit_insn (insn (operands[0], gen_lowpart (mode, operands[1])));
9176 [(set (match_operand:SWI48 0 "register_operand")
9177 (and:SWI48 (match_dup 0)
9178 (const_int -65536)))
9179 (clobber (reg:CC FLAGS_REG))]
9180 "(TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)
9181 || optimize_function_for_size_p (cfun)"
9182 [(set (strict_low_part (match_dup 1)) (const_int 0))]
9183 "operands[1] = gen_lowpart (HImode, operands[0]);")
9186 [(set (match_operand:SWI248 0 "any_QIreg_operand")
9187 (and:SWI248 (match_dup 0)
9189 (clobber (reg:CC FLAGS_REG))]
9190 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9191 && reload_completed"
9192 [(set (strict_low_part (match_dup 1)) (const_int 0))]
9193 "operands[1] = gen_lowpart (QImode, operands[0]);")
9196 [(set (match_operand:SWI248 0 "QIreg_operand")
9197 (and:SWI248 (match_dup 0)
9198 (const_int -65281)))
9199 (clobber (reg:CC FLAGS_REG))]
9200 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9201 && reload_completed"
9203 [(set (zero_extract:SI (match_dup 0)
9209 (zero_extract:SI (match_dup 0)
9213 (zero_extract:SI (match_dup 0)
9215 (const_int 8)) 0)) 0))
9216 (clobber (reg:CC FLAGS_REG))])]
9217 "operands[0] = gen_lowpart (SImode, operands[0]);")
9219 (define_insn "*anddi_2"
9220 [(set (reg FLAGS_REG)
9223 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
9224 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
9226 (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
9227 (and:DI (match_dup 1) (match_dup 2)))]
9229 && ix86_match_ccmode
9231 /* If we are going to emit andl instead of andq, and the operands[2]
9232 constant might have the SImode sign bit set, make sure the sign
9233 flag isn't tested, because the instruction will set the sign flag
9234 based on bit 31 rather than bit 63. If it isn't CONST_INT,
9235 conservatively assume it might have bit 31 set. */
9236 (satisfies_constraint_Z (operands[2])
9237 && (!CONST_INT_P (operands[2])
9238 || val_signbit_known_set_p (SImode, INTVAL (operands[2]))))
9239 ? CCZmode : CCNOmode)
9240 && ix86_binary_operator_ok (AND, DImode, operands)"
9242 and{l}\t{%k2, %k0|%k0, %k2}
9243 and{q}\t{%2, %0|%0, %2}
9244 and{q}\t{%2, %0|%0, %2}"
9245 [(set_attr "type" "alu")
9246 (set_attr "mode" "SI,DI,DI")])
9248 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9249 (define_insn "*andsi_2_zext"
9250 [(set (reg FLAGS_REG)
9252 (match_operand:SI 1 "nonimmediate_operand" "%0")
9253 (match_operand:SI 2 "x86_64_general_operand" "rme"))
9255 (set (match_operand:DI 0 "register_operand" "=r")
9256 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
9257 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9258 && ix86_binary_operator_ok (AND, SImode, operands)"
9259 "and{l}\t{%2, %k0|%k0, %2}"
9260 [(set_attr "type" "alu")
9261 (set_attr "mode" "SI")])
9263 (define_insn "*andqi_2_maybe_si"
9264 [(set (reg FLAGS_REG)
9266 (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9267 (match_operand:QI 2 "general_operand" "qmn,qn,n"))
9269 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
9270 (and:QI (match_dup 1) (match_dup 2)))]
9271 "ix86_binary_operator_ok (AND, QImode, operands)
9272 && ix86_match_ccmode (insn,
9273 CONST_INT_P (operands[2])
9274 && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
9276 if (which_alternative == 2)
9278 if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
9279 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
9280 return "and{l}\t{%2, %k0|%k0, %2}";
9282 return "and{b}\t{%2, %0|%0, %2}";
9284 [(set_attr "type" "alu")
9285 (set_attr "mode" "QI,QI,SI")])
9287 (define_insn "*and<mode>_2"
9288 [(set (reg FLAGS_REG)
9289 (compare (and:SWI124
9290 (match_operand:SWI124 1 "nonimmediate_operand" "%0,0")
9291 (match_operand:SWI124 2 "<general_operand>" "<g>,<r><i>"))
9293 (set (match_operand:SWI124 0 "nonimmediate_operand" "=<r>,<r>m")
9294 (and:SWI124 (match_dup 1) (match_dup 2)))]
9295 "ix86_match_ccmode (insn, CCNOmode)
9296 && ix86_binary_operator_ok (AND, <MODE>mode, operands)"
9297 "and{<imodesuffix>}\t{%2, %0|%0, %2}"
9298 [(set_attr "type" "alu")
9299 (set_attr "mode" "<MODE>")])
9301 (define_insn "*andqi_2_slp"
9302 [(set (reg FLAGS_REG)
9304 (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9305 (match_operand:QI 1 "nonimmediate_operand" "qmn,qn"))
9307 (set (strict_low_part (match_dup 0))
9308 (and:QI (match_dup 0) (match_dup 1)))]
9309 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9310 && ix86_match_ccmode (insn, CCNOmode)
9311 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9312 "and{b}\t{%1, %0|%0, %1}"
9313 [(set_attr "type" "alu1")
9314 (set_attr "mode" "QI")])
9316 (define_insn "andqi_ext_1"
9317 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q,Q")
9323 (zero_extract:SI (match_operand 1 "ext_register_operand" "0,0")
9326 (match_operand:QI 2 "general_operand" "QnBc,m")) 0))
9327 (clobber (reg:CC FLAGS_REG))]
9328 "/* FIXME: without this LRA can't reload this pattern, see PR82524. */
9329 rtx_equal_p (operands[0], operands[1])"
9330 "and{b}\t{%2, %h0|%h0, %2}"
9331 [(set_attr "isa" "*,nox64")
9332 (set_attr "type" "alu")
9333 (set_attr "mode" "QI")])
9335 ;; Generated by peephole translating test to and. This shows up
9336 ;; often in fp comparisons.
9337 (define_insn "*andqi_ext_1_cc"
9338 [(set (reg FLAGS_REG)
9342 (zero_extract:SI (match_operand 1 "ext_register_operand" "0,0")
9345 (match_operand:QI 2 "general_operand" "QnBc,m"))
9347 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q,Q")
9353 (zero_extract:SI (match_dup 1)
9357 "ix86_match_ccmode (insn, CCNOmode)
9358 /* FIXME: without this LRA can't reload this pattern, see PR82524. */
9359 && rtx_equal_p (operands[0], operands[1])"
9360 "and{b}\t{%2, %h0|%h0, %2}"
9361 [(set_attr "isa" "*,nox64")
9362 (set_attr "type" "alu")
9363 (set_attr "mode" "QI")])
9365 (define_insn "*andqi_ext_2"
9366 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
9372 (zero_extract:SI (match_operand 1 "ext_register_operand" "%0")
9376 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9378 (const_int 8)) 0)) 0))
9379 (clobber (reg:CC FLAGS_REG))]
9380 "/* FIXME: without this LRA can't reload this pattern, see PR82524. */
9381 rtx_equal_p (operands[0], operands[1])
9382 || rtx_equal_p (operands[0], operands[2])"
9383 "and{b}\t{%h2, %h0|%h0, %h2}"
9384 [(set_attr "type" "alu")
9385 (set_attr "mode" "QI")])
9387 ;; Convert wide AND instructions with immediate operand to shorter QImode
9388 ;; equivalents when possible.
9389 ;; Don't do the splitting with memory operands, since it introduces risk
9390 ;; of memory mismatch stalls. We may want to do the splitting for optimizing
9391 ;; for size, but that can (should?) be handled by generic code instead.
9393 [(set (match_operand:SWI248 0 "QIreg_operand")
9394 (and:SWI248 (match_operand:SWI248 1 "register_operand")
9395 (match_operand:SWI248 2 "const_int_operand")))
9396 (clobber (reg:CC FLAGS_REG))]
9398 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9399 && !(~INTVAL (operands[2]) & ~(255 << 8))"
9401 [(set (zero_extract:SI (match_dup 0)
9407 (zero_extract:SI (match_dup 1)
9411 (clobber (reg:CC FLAGS_REG))])]
9413 operands[0] = gen_lowpart (SImode, operands[0]);
9414 operands[1] = gen_lowpart (SImode, operands[1]);
9415 operands[2] = gen_int_mode (INTVAL (operands[2]) >> 8, QImode);
9418 ;; Since AND can be encoded with sign extended immediate, this is only
9419 ;; profitable when 7th bit is not set.
9421 [(set (match_operand:SWI248 0 "any_QIreg_operand")
9422 (and:SWI248 (match_operand:SWI248 1 "general_operand")
9423 (match_operand:SWI248 2 "const_int_operand")))
9424 (clobber (reg:CC FLAGS_REG))]
9426 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9427 && !(~INTVAL (operands[2]) & ~255)
9428 && !(INTVAL (operands[2]) & 128)"
9429 [(parallel [(set (strict_low_part (match_dup 0))
9430 (and:QI (match_dup 1)
9432 (clobber (reg:CC FLAGS_REG))])]
9434 operands[0] = gen_lowpart (QImode, operands[0]);
9435 operands[1] = gen_lowpart (QImode, operands[1]);
9436 operands[2] = gen_int_mode (INTVAL (operands[2]), QImode);
9439 (define_insn "*andndi3_doubleword"
9440 [(set (match_operand:DI 0 "register_operand" "=&r,r,r,&r")
9442 (not:DI (match_operand:DI 1 "register_operand" "r,0,r,0"))
9443 (match_operand:DI 2 "nonimmediate_operand" "rm,rm,0,rm")))
9444 (clobber (reg:CC FLAGS_REG))]
9445 "!TARGET_64BIT && TARGET_STV && TARGET_SSE2"
9447 [(set_attr "isa" "bmi,bmi,bmi,*")])
9450 [(set (match_operand:DI 0 "register_operand")
9452 (not:DI (match_operand:DI 1 "register_operand"))
9453 (match_operand:DI 2 "nonimmediate_operand")))
9454 (clobber (reg:CC FLAGS_REG))]
9455 "!TARGET_64BIT && TARGET_BMI && TARGET_STV && TARGET_SSE2
9456 && reload_completed"
9457 [(parallel [(set (match_dup 0)
9458 (and:SI (not:SI (match_dup 1)) (match_dup 2)))
9459 (clobber (reg:CC FLAGS_REG))])
9460 (parallel [(set (match_dup 3)
9461 (and:SI (not:SI (match_dup 4)) (match_dup 5)))
9462 (clobber (reg:CC FLAGS_REG))])]
9463 "split_double_mode (DImode, &operands[0], 3, &operands[0], &operands[3]);")
9466 [(set (match_operand:DI 0 "register_operand")
9468 (not:DI (match_dup 0))
9469 (match_operand:DI 1 "nonimmediate_operand")))
9470 (clobber (reg:CC FLAGS_REG))]
9471 "!TARGET_64BIT && !TARGET_BMI && TARGET_STV && TARGET_SSE2
9472 && reload_completed"
9473 [(set (match_dup 0) (not:SI (match_dup 0)))
9474 (parallel [(set (match_dup 0)
9475 (and:SI (match_dup 0) (match_dup 1)))
9476 (clobber (reg:CC FLAGS_REG))])
9477 (set (match_dup 2) (not:SI (match_dup 2)))
9478 (parallel [(set (match_dup 2)
9479 (and:SI (match_dup 2) (match_dup 3)))
9480 (clobber (reg:CC FLAGS_REG))])]
9481 "split_double_mode (DImode, &operands[0], 2, &operands[0], &operands[2]);")
9483 (define_insn "*andn<mode>_1"
9484 [(set (match_operand:SWI48 0 "register_operand" "=r,r")
9486 (not:SWI48 (match_operand:SWI48 1 "register_operand" "r,r"))
9487 (match_operand:SWI48 2 "nonimmediate_operand" "r,m")))
9488 (clobber (reg:CC FLAGS_REG))]
9490 "andn\t{%2, %1, %0|%0, %1, %2}"
9491 [(set_attr "type" "bitmanip")
9492 (set_attr "btver2_decode" "direct, double")
9493 (set_attr "mode" "<MODE>")])
9495 (define_insn "*andn<mode>_1"
9496 [(set (match_operand:SWI12 0 "register_operand" "=r")
9498 (not:SWI12 (match_operand:SWI12 1 "register_operand" "r"))
9499 (match_operand:SWI12 2 "register_operand" "r")))
9500 (clobber (reg:CC FLAGS_REG))]
9502 "andn\t{%k2, %k1, %k0|%k0, %k1, %k2}"
9503 [(set_attr "type" "bitmanip")
9504 (set_attr "btver2_decode" "direct")
9505 (set_attr "mode" "SI")])
9507 (define_insn "*andn_<mode>_ccno"
9508 [(set (reg FLAGS_REG)
9511 (not:SWI48 (match_operand:SWI48 1 "register_operand" "r,r"))
9512 (match_operand:SWI48 2 "nonimmediate_operand" "r,m"))
9514 (clobber (match_scratch:SWI48 0 "=r,r"))]
9515 "TARGET_BMI && ix86_match_ccmode (insn, CCNOmode)"
9516 "andn\t{%2, %1, %0|%0, %1, %2}"
9517 [(set_attr "type" "bitmanip")
9518 (set_attr "btver2_decode" "direct, double")
9519 (set_attr "mode" "<MODE>")])
9521 ;; Logical inclusive and exclusive OR instructions
9523 ;; %%% This used to optimize known byte-wide and operations to memory.
9524 ;; If this is considered useful, it should be done with splitters.
9526 (define_expand "<code><mode>3"
9527 [(set (match_operand:SWIM1248x 0 "nonimmediate_operand")
9528 (any_or:SWIM1248x (match_operand:SWIM1248x 1 "nonimmediate_operand")
9529 (match_operand:SWIM1248x 2 "<general_operand>")))]
9531 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
9533 (define_insn_and_split "*<code>di3_doubleword"
9534 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r")
9536 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
9537 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm")))
9538 (clobber (reg:CC FLAGS_REG))]
9539 "!TARGET_64BIT && TARGET_STV && TARGET_SSE2
9540 && ix86_binary_operator_ok (<CODE>, DImode, operands)"
9542 "&& reload_completed"
9545 split_double_mode (DImode, &operands[0], 3, &operands[0], &operands[3]);
9546 if (operands[2] == constm1_rtx)
9550 operands[1] = constm1_rtx;
9551 ix86_expand_move (SImode, &operands[0]);
9554 ix86_expand_unary_operator (NOT, SImode, &operands[0]);
9556 else if (operands[2] != const0_rtx)
9557 ix86_expand_binary_operator (<CODE>, SImode, &operands[0]);
9558 else if (operands[5] == const0_rtx)
9559 emit_note (NOTE_INSN_DELETED);
9560 if (operands[5] == constm1_rtx)
9564 operands[4] = constm1_rtx;
9565 ix86_expand_move (SImode, &operands[3]);
9568 ix86_expand_unary_operator (NOT, SImode, &operands[3]);
9570 else if (operands[5] != const0_rtx)
9571 ix86_expand_binary_operator (<CODE>, SImode, &operands[3]);
9575 (define_insn "*<code><mode>_1"
9576 [(set (match_operand:SWI248 0 "nonimmediate_operand" "=r,rm")
9578 (match_operand:SWI248 1 "nonimmediate_operand" "%0,0")
9579 (match_operand:SWI248 2 "<general_operand>" "<g>,r<i>")))
9580 (clobber (reg:CC FLAGS_REG))]
9581 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9582 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
9583 [(set_attr "type" "alu")
9584 (set_attr "mode" "<MODE>")])
9586 (define_insn_and_split "*iordi_1_bts"
9587 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9589 (match_operand:DI 1 "nonimmediate_operand" "%0")
9590 (match_operand:DI 2 "const_int_operand" "n")))
9591 (clobber (reg:CC FLAGS_REG))]
9592 "TARGET_64BIT && TARGET_USE_BT
9593 && ix86_binary_operator_ok (IOR, DImode, operands)
9594 && IN_RANGE (exact_log2 (INTVAL (operands[2])), 31, 63)"
9596 "&& reload_completed"
9597 [(parallel [(set (zero_extract:DI (match_dup 0)
9601 (clobber (reg:CC FLAGS_REG))])]
9602 "operands[3] = GEN_INT (exact_log2 (INTVAL (operands[2])));"
9603 [(set_attr "type" "alu1")
9604 (set_attr "prefix_0f" "1")
9605 (set_attr "znver1_decode" "double")
9606 (set_attr "mode" "DI")])
9608 (define_insn_and_split "*xordi_1_btc"
9609 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9611 (match_operand:DI 1 "nonimmediate_operand" "%0")
9612 (match_operand:DI 2 "const_int_operand" "n")))
9613 (clobber (reg:CC FLAGS_REG))]
9614 "TARGET_64BIT && TARGET_USE_BT
9615 && ix86_binary_operator_ok (XOR, DImode, operands)
9616 && IN_RANGE (exact_log2 (INTVAL (operands[2])), 31, 63)"
9618 "&& reload_completed"
9619 [(parallel [(set (zero_extract:DI (match_dup 0)
9622 (not:DI (zero_extract:DI (match_dup 0)
9625 (clobber (reg:CC FLAGS_REG))])]
9626 "operands[3] = GEN_INT (exact_log2 (INTVAL (operands[2])));"
9627 [(set_attr "type" "alu1")
9628 (set_attr "prefix_0f" "1")
9629 (set_attr "znver1_decode" "double")
9630 (set_attr "mode" "DI")])
9632 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9633 (define_insn "*<code>si_1_zext"
9634 [(set (match_operand:DI 0 "register_operand" "=r")
9636 (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9637 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
9638 (clobber (reg:CC FLAGS_REG))]
9639 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
9640 "<logic>{l}\t{%2, %k0|%k0, %2}"
9641 [(set_attr "type" "alu")
9642 (set_attr "mode" "SI")])
9644 (define_insn "*<code>si_1_zext_imm"
9645 [(set (match_operand:DI 0 "register_operand" "=r")
9647 (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
9648 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
9649 (clobber (reg:CC FLAGS_REG))]
9650 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
9651 "<logic>{l}\t{%2, %k0|%k0, %2}"
9652 [(set_attr "type" "alu")
9653 (set_attr "mode" "SI")])
9655 (define_insn "*<code>qi_1"
9656 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
9657 (any_or:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9658 (match_operand:QI 2 "general_operand" "qmn,qn,rn")))
9659 (clobber (reg:CC FLAGS_REG))]
9660 "ix86_binary_operator_ok (<CODE>, QImode, operands)"
9662 <logic>{b}\t{%2, %0|%0, %2}
9663 <logic>{b}\t{%2, %0|%0, %2}
9664 <logic>{l}\t{%k2, %k0|%k0, %k2}"
9665 [(set_attr "type" "alu")
9666 (set_attr "mode" "QI,QI,SI")
9667 ;; Potential partial reg stall on alternative 2.
9668 (set (attr "preferred_for_speed")
9669 (cond [(eq_attr "alternative" "2")
9670 (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
9671 (symbol_ref "true")))])
9673 (define_insn "*<code>qi_1_slp"
9674 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
9675 (any_or:QI (match_dup 0)
9676 (match_operand:QI 1 "general_operand" "qmn,qn")))
9677 (clobber (reg:CC FLAGS_REG))]
9678 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9679 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9680 "<logic>{b}\t{%1, %0|%0, %1}"
9681 [(set_attr "type" "alu1")
9682 (set_attr "mode" "QI")])
9684 (define_insn "*<code><mode>_2"
9685 [(set (reg FLAGS_REG)
9686 (compare (any_or:SWI
9687 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
9688 (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>"))
9690 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
9691 (any_or:SWI (match_dup 1) (match_dup 2)))]
9692 "ix86_match_ccmode (insn, CCNOmode)
9693 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9694 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
9695 [(set_attr "type" "alu")
9696 (set_attr "mode" "<MODE>")])
9698 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9699 ;; ??? Special case for immediate operand is missing - it is tricky.
9700 (define_insn "*<code>si_2_zext"
9701 [(set (reg FLAGS_REG)
9702 (compare (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9703 (match_operand:SI 2 "x86_64_general_operand" "rme"))
9705 (set (match_operand:DI 0 "register_operand" "=r")
9706 (zero_extend:DI (any_or:SI (match_dup 1) (match_dup 2))))]
9707 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9708 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
9709 "<logic>{l}\t{%2, %k0|%k0, %2}"
9710 [(set_attr "type" "alu")
9711 (set_attr "mode" "SI")])
9713 (define_insn "*<code>si_2_zext_imm"
9714 [(set (reg FLAGS_REG)
9716 (match_operand:SI 1 "nonimmediate_operand" "%0")
9717 (match_operand:SI 2 "x86_64_zext_immediate_operand" "Z"))
9719 (set (match_operand:DI 0 "register_operand" "=r")
9720 (any_or:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
9721 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9722 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
9723 "<logic>{l}\t{%2, %k0|%k0, %2}"
9724 [(set_attr "type" "alu")
9725 (set_attr "mode" "SI")])
9727 (define_insn "*<code>qi_2_slp"
9728 [(set (reg FLAGS_REG)
9729 (compare (any_or:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9730 (match_operand:QI 1 "general_operand" "qmn,qn"))
9732 (set (strict_low_part (match_dup 0))
9733 (any_or:QI (match_dup 0) (match_dup 1)))]
9734 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9735 && ix86_match_ccmode (insn, CCNOmode)
9736 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9737 "<logic>{b}\t{%1, %0|%0, %1}"
9738 [(set_attr "type" "alu1")
9739 (set_attr "mode" "QI")])
9741 (define_insn "*<code><mode>_3"
9742 [(set (reg FLAGS_REG)
9743 (compare (any_or:SWI
9744 (match_operand:SWI 1 "nonimmediate_operand" "%0")
9745 (match_operand:SWI 2 "<general_operand>" "<g>"))
9747 (clobber (match_scratch:SWI 0 "=<r>"))]
9748 "ix86_match_ccmode (insn, CCNOmode)
9749 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9750 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
9751 [(set_attr "type" "alu")
9752 (set_attr "mode" "<MODE>")])
9754 (define_insn "*<code>qi_ext_1"
9755 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q,Q")
9761 (zero_extract:SI (match_operand 1 "ext_register_operand" "0,0")
9764 (match_operand:QI 2 "general_operand" "QnBc,m")) 0))
9765 (clobber (reg:CC FLAGS_REG))]
9766 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9767 /* FIXME: without this LRA can't reload this pattern, see PR82524. */
9768 && rtx_equal_p (operands[0], operands[1])"
9769 "<logic>{b}\t{%2, %h0|%h0, %2}"
9770 [(set_attr "isa" "*,nox64")
9771 (set_attr "type" "alu")
9772 (set_attr "mode" "QI")])
9774 (define_insn "*<code>qi_ext_2"
9775 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
9781 (zero_extract:SI (match_operand 1 "ext_register_operand" "%0")
9785 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9787 (const_int 8)) 0)) 0))
9788 (clobber (reg:CC FLAGS_REG))]
9789 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9790 /* FIXME: without this LRA can't reload this pattern, see PR82524. */
9791 && (rtx_equal_p (operands[0], operands[1])
9792 || rtx_equal_p (operands[0], operands[2]))"
9793 "<logic>{b}\t{%h2, %h0|%h0, %h2}"
9794 [(set_attr "type" "alu")
9795 (set_attr "mode" "QI")])
9797 ;; Convert wide OR instructions with immediate operand to shorter QImode
9798 ;; equivalents when possible.
9799 ;; Don't do the splitting with memory operands, since it introduces risk
9800 ;; of memory mismatch stalls. We may want to do the splitting for optimizing
9801 ;; for size, but that can (should?) be handled by generic code instead.
9803 [(set (match_operand:SWI248 0 "QIreg_operand")
9804 (any_or:SWI248 (match_operand:SWI248 1 "register_operand")
9805 (match_operand:SWI248 2 "const_int_operand")))
9806 (clobber (reg:CC FLAGS_REG))]
9808 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9809 && !(INTVAL (operands[2]) & ~(255 << 8))"
9811 [(set (zero_extract:SI (match_dup 0)
9817 (zero_extract:SI (match_dup 1)
9821 (clobber (reg:CC FLAGS_REG))])]
9823 operands[0] = gen_lowpart (SImode, operands[0]);
9824 operands[1] = gen_lowpart (SImode, operands[1]);
9825 operands[2] = gen_int_mode (INTVAL (operands[2]) >> 8, QImode);
9828 ;; Since OR can be encoded with sign extended immediate, this is only
9829 ;; profitable when 7th bit is set.
9831 [(set (match_operand:SWI248 0 "any_QIreg_operand")
9832 (any_or:SWI248 (match_operand:SWI248 1 "general_operand")
9833 (match_operand:SWI248 2 "const_int_operand")))
9834 (clobber (reg:CC FLAGS_REG))]
9836 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9837 && !(INTVAL (operands[2]) & ~255)
9838 && (INTVAL (operands[2]) & 128)"
9839 [(parallel [(set (strict_low_part (match_dup 0))
9840 (any_or:QI (match_dup 1)
9842 (clobber (reg:CC FLAGS_REG))])]
9844 operands[0] = gen_lowpart (QImode, operands[0]);
9845 operands[1] = gen_lowpart (QImode, operands[1]);
9846 operands[2] = gen_int_mode (INTVAL (operands[2]), QImode);
9849 (define_expand "xorqi_ext_1_cc"
9851 (set (reg:CCNO FLAGS_REG)
9855 (zero_extract:SI (match_operand 1 "ext_register_operand")
9858 (match_operand 2 "const_int_operand"))
9860 (set (zero_extract:SI (match_operand 0 "ext_register_operand")
9866 (zero_extract:SI (match_dup 1)
9869 (match_dup 2)) 0))])])
9871 (define_insn "*xorqi_ext_1_cc"
9872 [(set (reg FLAGS_REG)
9876 (zero_extract:SI (match_operand 1 "ext_register_operand" "0,0")
9879 (match_operand:QI 2 "general_operand" "QnBc,m"))
9881 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q,Q")
9887 (zero_extract:SI (match_dup 1)
9891 "ix86_match_ccmode (insn, CCNOmode)
9892 /* FIXME: without this LRA can't reload this pattern, see PR82524. */
9893 && rtx_equal_p (operands[0], operands[1])"
9894 "xor{b}\t{%2, %h0|%h0, %2}"
9895 [(set_attr "isa" "*,nox64")
9896 (set_attr "type" "alu")
9897 (set_attr "mode" "QI")])
9899 ;; Negation instructions
9901 (define_expand "neg<mode>2"
9902 [(set (match_operand:SDWIM 0 "nonimmediate_operand")
9903 (neg:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")))]
9905 "ix86_expand_unary_operator (NEG, <MODE>mode, operands); DONE;")
9907 (define_insn_and_split "*neg<dwi>2_doubleword"
9908 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro")
9909 (neg:<DWI> (match_operand:<DWI> 1 "nonimmediate_operand" "0")))
9910 (clobber (reg:CC FLAGS_REG))]
9911 "ix86_unary_operator_ok (NEG, <DWI>mode, operands)"
9915 [(set (reg:CCZ FLAGS_REG)
9916 (compare:CCZ (neg:DWIH (match_dup 1)) (const_int 0)))
9917 (set (match_dup 0) (neg:DWIH (match_dup 1)))])
9920 (plus:DWIH (plus:DWIH (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
9923 (clobber (reg:CC FLAGS_REG))])
9926 (neg:DWIH (match_dup 2)))
9927 (clobber (reg:CC FLAGS_REG))])]
9928 "split_double_mode (<DWI>mode, &operands[0], 2, &operands[0], &operands[2]);")
9930 (define_insn "*neg<mode>2_1"
9931 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9932 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")))
9933 (clobber (reg:CC FLAGS_REG))]
9934 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
9935 "neg{<imodesuffix>}\t%0"
9936 [(set_attr "type" "negnot")
9937 (set_attr "mode" "<MODE>")])
9939 ;; Combine is quite creative about this pattern.
9940 (define_insn "*negsi2_1_zext"
9941 [(set (match_operand:DI 0 "register_operand" "=r")
9943 (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
9946 (clobber (reg:CC FLAGS_REG))]
9947 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9949 [(set_attr "type" "negnot")
9950 (set_attr "mode" "SI")])
9952 ;; The problem with neg is that it does not perform (compare x 0),
9953 ;; it really performs (compare 0 x), which leaves us with the zero
9954 ;; flag being the only useful item.
9956 (define_insn "*neg<mode>2_cmpz"
9957 [(set (reg:CCZ FLAGS_REG)
9959 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
9961 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9962 (neg:SWI (match_dup 1)))]
9963 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
9964 "neg{<imodesuffix>}\t%0"
9965 [(set_attr "type" "negnot")
9966 (set_attr "mode" "<MODE>")])
9968 (define_insn "*negsi2_cmpz_zext"
9969 [(set (reg:CCZ FLAGS_REG)
9973 (match_operand:DI 1 "register_operand" "0")
9977 (set (match_operand:DI 0 "register_operand" "=r")
9978 (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
9981 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9983 [(set_attr "type" "negnot")
9984 (set_attr "mode" "SI")])
9986 ;; Negate with jump on overflow.
9987 (define_expand "negv<mode>3"
9988 [(parallel [(set (reg:CCO FLAGS_REG)
9989 (ne:CCO (match_operand:SWI 1 "register_operand")
9991 (set (match_operand:SWI 0 "register_operand")
9992 (neg:SWI (match_dup 1)))])
9993 (set (pc) (if_then_else
9994 (eq (reg:CCO FLAGS_REG) (const_int 0))
9995 (label_ref (match_operand 2))
10000 = gen_int_mode (HOST_WIDE_INT_1U << (GET_MODE_BITSIZE (<MODE>mode) - 1),
10004 (define_insn "*negv<mode>3"
10005 [(set (reg:CCO FLAGS_REG)
10006 (ne:CCO (match_operand:SWI 1 "nonimmediate_operand" "0")
10007 (match_operand:SWI 2 "const_int_operand")))
10008 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
10009 (neg:SWI (match_dup 1)))]
10010 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)
10011 && mode_signbit_p (<MODE>mode, operands[2])"
10012 "neg{<imodesuffix>}\t%0"
10013 [(set_attr "type" "negnot")
10014 (set_attr "mode" "<MODE>")])
10016 ;; Changing of sign for FP values is doable using integer unit too.
10018 (define_expand "<code><mode>2"
10019 [(set (match_operand:X87MODEF 0 "register_operand")
10020 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand")))]
10021 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
10022 "ix86_expand_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
10024 (define_insn "*absneg<mode>2"
10025 [(set (match_operand:MODEF 0 "register_operand" "=Yv,Yv,f,!r")
10026 (match_operator:MODEF 3 "absneg_operator"
10027 [(match_operand:MODEF 1 "register_operand" "0,Yv,0,0")]))
10028 (use (match_operand:<ssevecmode> 2 "nonimmediate_operand" "Yvm,0,X,X"))
10029 (clobber (reg:CC FLAGS_REG))]
10030 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
10032 [(set (attr "enabled")
10034 (match_test ("SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"))
10036 (eq_attr "alternative" "2")
10037 (symbol_ref "TARGET_MIX_SSE_I387")
10038 (symbol_ref "true"))
10040 (eq_attr "alternative" "2,3")
10041 (symbol_ref "true")
10042 (symbol_ref "false"))))])
10044 (define_insn "*absnegxf2_i387"
10045 [(set (match_operand:XF 0 "register_operand" "=f,!r")
10046 (match_operator:XF 3 "absneg_operator"
10047 [(match_operand:XF 1 "register_operand" "0,0")]))
10048 (use (match_operand 2))
10049 (clobber (reg:CC FLAGS_REG))]
10053 (define_expand "<code>tf2"
10054 [(set (match_operand:TF 0 "register_operand")
10055 (absneg:TF (match_operand:TF 1 "register_operand")))]
10057 "ix86_expand_fp_absneg_operator (<CODE>, TFmode, operands); DONE;")
10059 (define_insn "*absnegtf2_sse"
10060 [(set (match_operand:TF 0 "register_operand" "=Yv,Yv")
10061 (match_operator:TF 3 "absneg_operator"
10062 [(match_operand:TF 1 "register_operand" "0,Yv")]))
10063 (use (match_operand:TF 2 "nonimmediate_operand" "Yvm,0"))
10064 (clobber (reg:CC FLAGS_REG))]
10068 ;; Splitters for fp abs and neg.
10071 [(set (match_operand 0 "fp_register_operand")
10072 (match_operator 1 "absneg_operator" [(match_dup 0)]))
10073 (use (match_operand 2))
10074 (clobber (reg:CC FLAGS_REG))]
10076 [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
10079 [(set (match_operand 0 "sse_reg_operand")
10080 (match_operator 3 "absneg_operator"
10081 [(match_operand 1 "register_operand")]))
10082 (use (match_operand 2 "nonimmediate_operand"))
10083 (clobber (reg:CC FLAGS_REG))]
10085 [(set (match_dup 0) (match_dup 3))]
10087 machine_mode mode = GET_MODE (operands[0]);
10088 machine_mode vmode = GET_MODE (operands[2]);
10091 operands[0] = lowpart_subreg (vmode, operands[0], mode);
10092 operands[1] = lowpart_subreg (vmode, operands[1], mode);
10093 if (operands_match_p (operands[0], operands[2]))
10094 std::swap (operands[1], operands[2]);
10095 if (GET_CODE (operands[3]) == ABS)
10096 tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
10098 tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
10103 [(set (match_operand:SF 0 "general_reg_operand")
10104 (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
10105 (use (match_operand:V4SF 2))
10106 (clobber (reg:CC FLAGS_REG))]
10108 [(parallel [(set (match_dup 0) (match_dup 1))
10109 (clobber (reg:CC FLAGS_REG))])]
10112 operands[0] = gen_lowpart (SImode, operands[0]);
10113 if (GET_CODE (operands[1]) == ABS)
10115 tmp = gen_int_mode (0x7fffffff, SImode);
10116 tmp = gen_rtx_AND (SImode, operands[0], tmp);
10120 tmp = gen_int_mode (0x80000000, SImode);
10121 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
10127 [(set (match_operand:DF 0 "general_reg_operand")
10128 (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
10129 (use (match_operand 2))
10130 (clobber (reg:CC FLAGS_REG))]
10132 [(parallel [(set (match_dup 0) (match_dup 1))
10133 (clobber (reg:CC FLAGS_REG))])]
10138 tmp = gen_lowpart (DImode, operands[0]);
10139 tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
10142 if (GET_CODE (operands[1]) == ABS)
10145 tmp = gen_rtx_NOT (DImode, tmp);
10149 operands[0] = gen_highpart (SImode, operands[0]);
10150 if (GET_CODE (operands[1]) == ABS)
10152 tmp = gen_int_mode (0x7fffffff, SImode);
10153 tmp = gen_rtx_AND (SImode, operands[0], tmp);
10157 tmp = gen_int_mode (0x80000000, SImode);
10158 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
10165 [(set (match_operand:XF 0 "general_reg_operand")
10166 (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
10167 (use (match_operand 2))
10168 (clobber (reg:CC FLAGS_REG))]
10170 [(parallel [(set (match_dup 0) (match_dup 1))
10171 (clobber (reg:CC FLAGS_REG))])]
10174 operands[0] = gen_rtx_REG (SImode,
10175 REGNO (operands[0]) + (TARGET_64BIT ? 1 : 2));
10176 if (GET_CODE (operands[1]) == ABS)
10178 tmp = GEN_INT (0x7fff);
10179 tmp = gen_rtx_AND (SImode, operands[0], tmp);
10183 tmp = GEN_INT (0x8000);
10184 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
10189 ;; Conditionalize these after reload. If they match before reload, we
10190 ;; lose the clobber and ability to use integer instructions.
10192 (define_insn "*<code><mode>2_1"
10193 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
10194 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "0")))]
10196 && (reload_completed
10197 || !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
10198 "f<absneg_mnemonic>"
10199 [(set_attr "type" "fsgn")
10200 (set_attr "mode" "<MODE>")])
10202 (define_insn "*<code>extendsfdf2"
10203 [(set (match_operand:DF 0 "register_operand" "=f")
10204 (absneg:DF (float_extend:DF
10205 (match_operand:SF 1 "register_operand" "0"))))]
10206 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
10207 "f<absneg_mnemonic>"
10208 [(set_attr "type" "fsgn")
10209 (set_attr "mode" "DF")])
10211 (define_insn "*<code>extendsfxf2"
10212 [(set (match_operand:XF 0 "register_operand" "=f")
10213 (absneg:XF (float_extend:XF
10214 (match_operand:SF 1 "register_operand" "0"))))]
10216 "f<absneg_mnemonic>"
10217 [(set_attr "type" "fsgn")
10218 (set_attr "mode" "XF")])
10220 (define_insn "*<code>extenddfxf2"
10221 [(set (match_operand:XF 0 "register_operand" "=f")
10222 (absneg:XF (float_extend:XF
10223 (match_operand:DF 1 "register_operand" "0"))))]
10225 "f<absneg_mnemonic>"
10226 [(set_attr "type" "fsgn")
10227 (set_attr "mode" "XF")])
10229 ;; Copysign instructions
10231 (define_mode_iterator CSGNMODE [SF DF TF])
10232 (define_mode_attr CSGNVMODE [(SF "V4SF") (DF "V2DF") (TF "TF")])
10234 (define_expand "copysign<mode>3"
10235 [(match_operand:CSGNMODE 0 "register_operand")
10236 (match_operand:CSGNMODE 1 "nonmemory_operand")
10237 (match_operand:CSGNMODE 2 "register_operand")]
10238 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10239 || (TARGET_SSE && (<MODE>mode == TFmode))"
10240 "ix86_expand_copysign (operands); DONE;")
10242 (define_insn_and_split "copysign<mode>3_const"
10243 [(set (match_operand:CSGNMODE 0 "register_operand" "=Yv")
10245 [(match_operand:<CSGNVMODE> 1 "vector_move_operand" "YvmC")
10246 (match_operand:CSGNMODE 2 "register_operand" "0")
10247 (match_operand:<CSGNVMODE> 3 "nonimmediate_operand" "Yvm")]
10249 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10250 || (TARGET_SSE && (<MODE>mode == TFmode))"
10252 "&& reload_completed"
10254 "ix86_split_copysign_const (operands); DONE;")
10256 (define_insn "copysign<mode>3_var"
10257 [(set (match_operand:CSGNMODE 0 "register_operand" "=Yv,Yv,Yv,Yv,Yv")
10259 [(match_operand:CSGNMODE 2 "register_operand" "Yv,0,0,Yv,Yv")
10260 (match_operand:CSGNMODE 3 "register_operand" "1,1,Yv,1,Yv")
10261 (match_operand:<CSGNVMODE> 4
10262 "nonimmediate_operand" "X,Yvm,Yvm,0,0")
10263 (match_operand:<CSGNVMODE> 5
10264 "nonimmediate_operand" "0,Yvm,1,Yvm,1")]
10266 (clobber (match_scratch:<CSGNVMODE> 1 "=Yv,Yv,Yv,Yv,Yv"))]
10267 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10268 || (TARGET_SSE && (<MODE>mode == TFmode))"
10272 [(set (match_operand:CSGNMODE 0 "register_operand")
10274 [(match_operand:CSGNMODE 2 "register_operand")
10275 (match_operand:CSGNMODE 3 "register_operand")
10276 (match_operand:<CSGNVMODE> 4)
10277 (match_operand:<CSGNVMODE> 5)]
10279 (clobber (match_scratch:<CSGNVMODE> 1))]
10280 "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10281 || (TARGET_SSE && (<MODE>mode == TFmode)))
10282 && reload_completed"
10284 "ix86_split_copysign_var (operands); DONE;")
10286 ;; One complement instructions
10288 (define_expand "one_cmpl<mode>2"
10289 [(set (match_operand:SWIM1248x 0 "nonimmediate_operand")
10290 (not:SWIM1248x (match_operand:SWIM1248x 1 "nonimmediate_operand")))]
10292 "ix86_expand_unary_operator (NOT, <MODE>mode, operands); DONE;")
10294 (define_insn_and_split "*one_cmpldi2_doubleword"
10295 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10296 (not:DI (match_operand:DI 1 "nonimmediate_operand" "0")))]
10297 "!TARGET_64BIT && TARGET_STV && TARGET_SSE2
10298 && ix86_unary_operator_ok (NOT, DImode, operands)"
10300 "&& reload_completed"
10301 [(set (match_dup 0)
10302 (not:SI (match_dup 1)))
10304 (not:SI (match_dup 3)))]
10305 "split_double_mode (DImode, &operands[0], 2, &operands[0], &operands[2]);")
10307 (define_insn "*one_cmpl<mode>2_1"
10308 [(set (match_operand:SWI248 0 "nonimmediate_operand" "=rm")
10309 (not:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "0")))]
10310 "ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
10311 "not{<imodesuffix>}\t%0"
10312 [(set_attr "type" "negnot")
10313 (set_attr "mode" "<MODE>")])
10315 ;; ??? Currently never generated - xor is used instead.
10316 (define_insn "*one_cmplsi2_1_zext"
10317 [(set (match_operand:DI 0 "register_operand" "=r")
10319 (not:SI (match_operand:SI 1 "register_operand" "0"))))]
10320 "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
10322 [(set_attr "type" "negnot")
10323 (set_attr "mode" "SI")])
10325 (define_insn "*one_cmplqi2_1"
10326 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
10327 (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
10328 "ix86_unary_operator_ok (NOT, QImode, operands)"
10332 [(set_attr "type" "negnot")
10333 (set_attr "mode" "QI,SI")
10334 ;; Potential partial reg stall on alternative 1.
10335 (set (attr "preferred_for_speed")
10336 (cond [(eq_attr "alternative" "1")
10337 (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
10338 (symbol_ref "true")))])
10340 (define_insn "*one_cmpl<mode>2_2"
10341 [(set (reg FLAGS_REG)
10342 (compare (not:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
10344 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
10345 (not:SWI (match_dup 1)))]
10346 "ix86_match_ccmode (insn, CCNOmode)
10347 && ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
10349 [(set_attr "type" "alu1")
10350 (set_attr "mode" "<MODE>")])
10353 [(set (match_operand 0 "flags_reg_operand")
10354 (match_operator 2 "compare_operator"
10355 [(not:SWI (match_operand:SWI 3 "nonimmediate_operand"))
10357 (set (match_operand:SWI 1 "nonimmediate_operand")
10358 (not:SWI (match_dup 3)))]
10359 "ix86_match_ccmode (insn, CCNOmode)"
10360 [(parallel [(set (match_dup 0)
10361 (match_op_dup 2 [(xor:SWI (match_dup 3) (const_int -1))
10364 (xor:SWI (match_dup 3) (const_int -1)))])])
10366 ;; ??? Currently never generated - xor is used instead.
10367 (define_insn "*one_cmplsi2_2_zext"
10368 [(set (reg FLAGS_REG)
10369 (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
10371 (set (match_operand:DI 0 "register_operand" "=r")
10372 (zero_extend:DI (not:SI (match_dup 1))))]
10373 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10374 && ix86_unary_operator_ok (NOT, SImode, operands)"
10376 [(set_attr "type" "alu1")
10377 (set_attr "mode" "SI")])
10380 [(set (match_operand 0 "flags_reg_operand")
10381 (match_operator 2 "compare_operator"
10382 [(not:SI (match_operand:SI 3 "register_operand"))
10384 (set (match_operand:DI 1 "register_operand")
10385 (zero_extend:DI (not:SI (match_dup 3))))]
10386 "ix86_match_ccmode (insn, CCNOmode)"
10387 [(parallel [(set (match_dup 0)
10388 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10391 (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])])
10393 ;; Shift instructions
10395 ;; DImode shifts are implemented using the i386 "shift double" opcode,
10396 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem". If the shift count
10397 ;; is variable, then the count is in %cl and the "imm" operand is dropped
10398 ;; from the assembler input.
10400 ;; This instruction shifts the target reg/mem as usual, but instead of
10401 ;; shifting in zeros, bits are shifted in from reg operand. If the insn
10402 ;; is a left shift double, bits are taken from the high order bits of
10403 ;; reg, else if the insn is a shift right double, bits are taken from the
10404 ;; low order bits of reg. So if %eax is "1234" and %edx is "5678",
10405 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
10407 ;; Since sh[lr]d does not change the `reg' operand, that is done
10408 ;; separately, making all shifts emit pairs of shift double and normal
10409 ;; shift. Since sh[lr]d does not shift more than 31 bits, and we wish to
10410 ;; support a 63 bit shift, each shift where the count is in a reg expands
10411 ;; to a pair of shifts, a branch, a shift by 32 and a label.
10413 ;; If the shift count is a constant, we need never emit more than one
10414 ;; shift pair, instead using moves and sign extension for counts greater
10417 (define_expand "ashl<mode>3"
10418 [(set (match_operand:SDWIM 0 "<shift_operand>")
10419 (ashift:SDWIM (match_operand:SDWIM 1 "<ashl_input_operand>")
10420 (match_operand:QI 2 "nonmemory_operand")))]
10422 "ix86_expand_binary_operator (ASHIFT, <MODE>mode, operands); DONE;")
10424 (define_insn_and_split "*ashl<dwi>3_doubleword_mask"
10425 [(set (match_operand:<DWI> 0 "register_operand")
10427 (match_operand:<DWI> 1 "register_operand")
10430 (match_operand:SI 2 "register_operand" "c")
10431 (match_operand:SI 3 "const_int_operand")) 0)))
10432 (clobber (reg:CC FLAGS_REG))]
10433 "(INTVAL (operands[3]) & (<MODE_SIZE> * BITS_PER_UNIT)) == 0
10434 && can_create_pseudo_p ()"
10438 [(set (match_dup 6)
10439 (ior:DWIH (ashift:DWIH (match_dup 6) (match_dup 2))
10440 (lshiftrt:DWIH (match_dup 5)
10441 (minus:QI (match_dup 8) (match_dup 2)))))
10442 (clobber (reg:CC FLAGS_REG))])
10444 [(set (match_dup 4)
10445 (ashift:DWIH (match_dup 5) (match_dup 2)))
10446 (clobber (reg:CC FLAGS_REG))])]
10448 split_double_mode (<DWI>mode, &operands[0], 2, &operands[4], &operands[6]);
10450 operands[8] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT);
10452 if ((INTVAL (operands[3]) & ((<MODE_SIZE> * BITS_PER_UNIT) - 1))
10453 != ((<MODE_SIZE> * BITS_PER_UNIT) - 1))
10455 rtx tem = gen_reg_rtx (SImode);
10456 emit_insn (gen_andsi3 (tem, operands[2], operands[3]));
10460 operands[2] = gen_lowpart (QImode, operands[2]);
10462 if (!rtx_equal_p (operands[6], operands[7]))
10463 emit_move_insn (operands[6], operands[7]);
10466 (define_insn_and_split "*ashl<dwi>3_doubleword_mask_1"
10467 [(set (match_operand:<DWI> 0 "register_operand")
10469 (match_operand:<DWI> 1 "register_operand")
10471 (match_operand:QI 2 "register_operand" "c")
10472 (match_operand:QI 3 "const_int_operand"))))
10473 (clobber (reg:CC FLAGS_REG))]
10474 "(INTVAL (operands[3]) & (<MODE_SIZE> * BITS_PER_UNIT)) == 0
10475 && can_create_pseudo_p ()"
10479 [(set (match_dup 6)
10480 (ior:DWIH (ashift:DWIH (match_dup 6) (match_dup 2))
10481 (lshiftrt:DWIH (match_dup 5)
10482 (minus:QI (match_dup 8) (match_dup 2)))))
10483 (clobber (reg:CC FLAGS_REG))])
10485 [(set (match_dup 4)
10486 (ashift:DWIH (match_dup 5) (match_dup 2)))
10487 (clobber (reg:CC FLAGS_REG))])]
10489 split_double_mode (<DWI>mode, &operands[0], 2, &operands[4], &operands[6]);
10491 operands[8] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT);
10493 if ((INTVAL (operands[3]) & ((<MODE_SIZE> * BITS_PER_UNIT) - 1))
10494 != ((<MODE_SIZE> * BITS_PER_UNIT) - 1))
10496 rtx tem = gen_reg_rtx (QImode);
10497 emit_insn (gen_andqi3 (tem, operands[2], operands[3]));
10501 if (!rtx_equal_p (operands[6], operands[7]))
10502 emit_move_insn (operands[6], operands[7]);
10505 (define_insn "*ashl<mode>3_doubleword"
10506 [(set (match_operand:DWI 0 "register_operand" "=&r")
10507 (ashift:DWI (match_operand:DWI 1 "reg_or_pm1_operand" "0n")
10508 (match_operand:QI 2 "nonmemory_operand" "<S>c")))
10509 (clobber (reg:CC FLAGS_REG))]
10512 [(set_attr "type" "multi")])
10515 [(set (match_operand:DWI 0 "register_operand")
10516 (ashift:DWI (match_operand:DWI 1 "nonmemory_operand")
10517 (match_operand:QI 2 "nonmemory_operand")))
10518 (clobber (reg:CC FLAGS_REG))]
10519 "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
10521 "ix86_split_ashl (operands, NULL_RTX, <MODE>mode); DONE;")
10523 ;; By default we don't ask for a scratch register, because when DWImode
10524 ;; values are manipulated, registers are already at a premium. But if
10525 ;; we have one handy, we won't turn it away.
10528 [(match_scratch:DWIH 3 "r")
10529 (parallel [(set (match_operand:<DWI> 0 "register_operand")
10531 (match_operand:<DWI> 1 "nonmemory_operand")
10532 (match_operand:QI 2 "nonmemory_operand")))
10533 (clobber (reg:CC FLAGS_REG))])
10537 "ix86_split_ashl (operands, operands[3], <DWI>mode); DONE;")
10539 (define_insn "x86_64_shld"
10540 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
10541 (ior:DI (ashift:DI (match_dup 0)
10542 (match_operand:QI 2 "nonmemory_operand" "Jc"))
10543 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
10544 (minus:QI (const_int 64) (match_dup 2)))))
10545 (clobber (reg:CC FLAGS_REG))]
10547 "shld{q}\t{%s2%1, %0|%0, %1, %2}"
10548 [(set_attr "type" "ishift")
10549 (set_attr "prefix_0f" "1")
10550 (set_attr "mode" "DI")
10551 (set_attr "athlon_decode" "vector")
10552 (set_attr "amdfam10_decode" "vector")
10553 (set_attr "bdver1_decode" "vector")])
10555 (define_insn "x86_shld"
10556 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
10557 (ior:SI (ashift:SI (match_dup 0)
10558 (match_operand:QI 2 "nonmemory_operand" "Ic"))
10559 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
10560 (minus:QI (const_int 32) (match_dup 2)))))
10561 (clobber (reg:CC FLAGS_REG))]
10563 "shld{l}\t{%s2%1, %0|%0, %1, %2}"
10564 [(set_attr "type" "ishift")
10565 (set_attr "prefix_0f" "1")
10566 (set_attr "mode" "SI")
10567 (set_attr "pent_pair" "np")
10568 (set_attr "athlon_decode" "vector")
10569 (set_attr "amdfam10_decode" "vector")
10570 (set_attr "bdver1_decode" "vector")])
10572 (define_expand "x86_shift<mode>_adj_1"
10573 [(set (reg:CCZ FLAGS_REG)
10574 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand")
10577 (set (match_operand:SWI48 0 "register_operand")
10578 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
10579 (match_operand:SWI48 1 "register_operand")
10582 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
10583 (match_operand:SWI48 3 "register_operand")
10586 "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
10588 (define_expand "x86_shift<mode>_adj_2"
10589 [(use (match_operand:SWI48 0 "register_operand"))
10590 (use (match_operand:SWI48 1 "register_operand"))
10591 (use (match_operand:QI 2 "register_operand"))]
10594 rtx_code_label *label = gen_label_rtx ();
10597 emit_insn (gen_testqi_ccz_1 (operands[2],
10598 GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
10600 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
10601 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
10602 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
10603 gen_rtx_LABEL_REF (VOIDmode, label),
10605 tmp = emit_jump_insn (gen_rtx_SET (pc_rtx, tmp));
10606 JUMP_LABEL (tmp) = label;
10608 emit_move_insn (operands[0], operands[1]);
10609 ix86_expand_clear (operands[1]);
10611 emit_label (label);
10612 LABEL_NUSES (label) = 1;
10617 ;; Avoid useless masking of count operand.
10618 (define_insn_and_split "*ashl<mode>3_mask"
10619 [(set (match_operand:SWI48 0 "nonimmediate_operand")
10621 (match_operand:SWI48 1 "nonimmediate_operand")
10624 (match_operand:SI 2 "register_operand" "c,r")
10625 (match_operand:SI 3 "const_int_operand")) 0)))
10626 (clobber (reg:CC FLAGS_REG))]
10627 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)
10628 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10629 == GET_MODE_BITSIZE (<MODE>mode)-1
10630 && can_create_pseudo_p ()"
10634 [(set (match_dup 0)
10635 (ashift:SWI48 (match_dup 1)
10637 (clobber (reg:CC FLAGS_REG))])]
10638 "operands[2] = gen_lowpart (QImode, operands[2]);"
10639 [(set_attr "isa" "*,bmi2")])
10641 (define_insn_and_split "*ashl<mode>3_mask_1"
10642 [(set (match_operand:SWI48 0 "nonimmediate_operand")
10644 (match_operand:SWI48 1 "nonimmediate_operand")
10646 (match_operand:QI 2 "register_operand" "c,r")
10647 (match_operand:QI 3 "const_int_operand"))))
10648 (clobber (reg:CC FLAGS_REG))]
10649 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)
10650 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10651 == GET_MODE_BITSIZE (<MODE>mode)-1
10652 && can_create_pseudo_p ()"
10656 [(set (match_dup 0)
10657 (ashift:SWI48 (match_dup 1)
10659 (clobber (reg:CC FLAGS_REG))])]
10661 [(set_attr "isa" "*,bmi2")])
10663 (define_insn "*bmi2_ashl<mode>3_1"
10664 [(set (match_operand:SWI48 0 "register_operand" "=r")
10665 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
10666 (match_operand:SWI48 2 "register_operand" "r")))]
10668 "shlx\t{%2, %1, %0|%0, %1, %2}"
10669 [(set_attr "type" "ishiftx")
10670 (set_attr "mode" "<MODE>")])
10672 (define_insn "*ashl<mode>3_1"
10673 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r,r")
10674 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,l,rm")
10675 (match_operand:QI 2 "nonmemory_operand" "c<S>,M,r")))
10676 (clobber (reg:CC FLAGS_REG))]
10677 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
10679 switch (get_attr_type (insn))
10686 gcc_assert (operands[2] == const1_rtx);
10687 gcc_assert (rtx_equal_p (operands[0], operands[1]));
10688 return "add{<imodesuffix>}\t%0, %0";
10691 if (operands[2] == const1_rtx
10692 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10693 return "sal{<imodesuffix>}\t%0";
10695 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
10698 [(set_attr "isa" "*,*,bmi2")
10700 (cond [(eq_attr "alternative" "1")
10701 (const_string "lea")
10702 (eq_attr "alternative" "2")
10703 (const_string "ishiftx")
10704 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
10705 (match_operand 0 "register_operand"))
10706 (match_operand 2 "const1_operand"))
10707 (const_string "alu")
10709 (const_string "ishift")))
10710 (set (attr "length_immediate")
10712 (ior (eq_attr "type" "alu")
10713 (and (eq_attr "type" "ishift")
10714 (and (match_operand 2 "const1_operand")
10715 (ior (match_test "TARGET_SHIFT1")
10716 (match_test "optimize_function_for_size_p (cfun)")))))
10718 (const_string "*")))
10719 (set_attr "mode" "<MODE>")])
10721 ;; Convert shift to the shiftx pattern to avoid flags dependency.
10723 [(set (match_operand:SWI48 0 "register_operand")
10724 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
10725 (match_operand:QI 2 "register_operand")))
10726 (clobber (reg:CC FLAGS_REG))]
10727 "TARGET_BMI2 && reload_completed"
10728 [(set (match_dup 0)
10729 (ashift:SWI48 (match_dup 1) (match_dup 2)))]
10730 "operands[2] = gen_lowpart (<MODE>mode, operands[2]);")
10732 (define_insn "*bmi2_ashlsi3_1_zext"
10733 [(set (match_operand:DI 0 "register_operand" "=r")
10735 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
10736 (match_operand:SI 2 "register_operand" "r"))))]
10737 "TARGET_64BIT && TARGET_BMI2"
10738 "shlx\t{%2, %1, %k0|%k0, %1, %2}"
10739 [(set_attr "type" "ishiftx")
10740 (set_attr "mode" "SI")])
10742 (define_insn "*ashlsi3_1_zext"
10743 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
10745 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l,rm")
10746 (match_operand:QI 2 "nonmemory_operand" "cI,M,r"))))
10747 (clobber (reg:CC FLAGS_REG))]
10748 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10750 switch (get_attr_type (insn))
10757 gcc_assert (operands[2] == const1_rtx);
10758 return "add{l}\t%k0, %k0";
10761 if (operands[2] == const1_rtx
10762 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10763 return "sal{l}\t%k0";
10765 return "sal{l}\t{%2, %k0|%k0, %2}";
10768 [(set_attr "isa" "*,*,bmi2")
10770 (cond [(eq_attr "alternative" "1")
10771 (const_string "lea")
10772 (eq_attr "alternative" "2")
10773 (const_string "ishiftx")
10774 (and (match_test "TARGET_DOUBLE_WITH_ADD")
10775 (match_operand 2 "const1_operand"))
10776 (const_string "alu")
10778 (const_string "ishift")))
10779 (set (attr "length_immediate")
10781 (ior (eq_attr "type" "alu")
10782 (and (eq_attr "type" "ishift")
10783 (and (match_operand 2 "const1_operand")
10784 (ior (match_test "TARGET_SHIFT1")
10785 (match_test "optimize_function_for_size_p (cfun)")))))
10787 (const_string "*")))
10788 (set_attr "mode" "SI")])
10790 ;; Convert shift to the shiftx pattern to avoid flags dependency.
10792 [(set (match_operand:DI 0 "register_operand")
10794 (ashift:SI (match_operand:SI 1 "nonimmediate_operand")
10795 (match_operand:QI 2 "register_operand"))))
10796 (clobber (reg:CC FLAGS_REG))]
10797 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
10798 [(set (match_dup 0)
10799 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
10800 "operands[2] = gen_lowpart (SImode, operands[2]);")
10802 (define_insn "*ashlhi3_1"
10803 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,Yp")
10804 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
10805 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10806 (clobber (reg:CC FLAGS_REG))]
10807 "ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10809 switch (get_attr_type (insn))
10815 gcc_assert (operands[2] == const1_rtx);
10816 return "add{w}\t%0, %0";
10819 if (operands[2] == const1_rtx
10820 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10821 return "sal{w}\t%0";
10823 return "sal{w}\t{%2, %0|%0, %2}";
10826 [(set (attr "type")
10827 (cond [(eq_attr "alternative" "1")
10828 (const_string "lea")
10829 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
10830 (match_operand 0 "register_operand"))
10831 (match_operand 2 "const1_operand"))
10832 (const_string "alu")
10834 (const_string "ishift")))
10835 (set (attr "length_immediate")
10837 (ior (eq_attr "type" "alu")
10838 (and (eq_attr "type" "ishift")
10839 (and (match_operand 2 "const1_operand")
10840 (ior (match_test "TARGET_SHIFT1")
10841 (match_test "optimize_function_for_size_p (cfun)")))))
10843 (const_string "*")))
10844 (set_attr "mode" "HI,SI")])
10846 (define_insn "*ashlqi3_1"
10847 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,Yp")
10848 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
10849 (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
10850 (clobber (reg:CC FLAGS_REG))]
10851 "ix86_binary_operator_ok (ASHIFT, QImode, operands)"
10853 switch (get_attr_type (insn))
10859 gcc_assert (operands[2] == const1_rtx);
10860 if (REG_P (operands[1]) && !ANY_QI_REGNO_P (REGNO (operands[1])))
10861 return "add{l}\t%k0, %k0";
10863 return "add{b}\t%0, %0";
10866 if (operands[2] == const1_rtx
10867 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10869 if (get_attr_mode (insn) == MODE_SI)
10870 return "sal{l}\t%k0";
10872 return "sal{b}\t%0";
10876 if (get_attr_mode (insn) == MODE_SI)
10877 return "sal{l}\t{%2, %k0|%k0, %2}";
10879 return "sal{b}\t{%2, %0|%0, %2}";
10883 [(set (attr "type")
10884 (cond [(eq_attr "alternative" "2")
10885 (const_string "lea")
10886 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
10887 (match_operand 0 "register_operand"))
10888 (match_operand 2 "const1_operand"))
10889 (const_string "alu")
10891 (const_string "ishift")))
10892 (set (attr "length_immediate")
10894 (ior (eq_attr "type" "alu")
10895 (and (eq_attr "type" "ishift")
10896 (and (match_operand 2 "const1_operand")
10897 (ior (match_test "TARGET_SHIFT1")
10898 (match_test "optimize_function_for_size_p (cfun)")))))
10900 (const_string "*")))
10901 (set_attr "mode" "QI,SI,SI")
10902 ;; Potential partial reg stall on alternative 1.
10903 (set (attr "preferred_for_speed")
10904 (cond [(eq_attr "alternative" "1")
10905 (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
10906 (symbol_ref "true")))])
10908 (define_insn "*ashlqi3_1_slp"
10909 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10910 (ashift:QI (match_dup 0)
10911 (match_operand:QI 1 "nonmemory_operand" "cI")))
10912 (clobber (reg:CC FLAGS_REG))]
10913 "(optimize_function_for_size_p (cfun)
10914 || !TARGET_PARTIAL_FLAG_REG_STALL
10915 || (operands[1] == const1_rtx
10917 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
10919 switch (get_attr_type (insn))
10922 gcc_assert (operands[1] == const1_rtx);
10923 return "add{b}\t%0, %0";
10926 if (operands[1] == const1_rtx
10927 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10928 return "sal{b}\t%0";
10930 return "sal{b}\t{%1, %0|%0, %1}";
10933 [(set (attr "type")
10934 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
10935 (match_operand 0 "register_operand"))
10936 (match_operand 1 "const1_operand"))
10937 (const_string "alu1")
10939 (const_string "ishift1")))
10940 (set (attr "length_immediate")
10942 (ior (eq_attr "type" "alu1")
10943 (and (eq_attr "type" "ishift1")
10944 (and (match_operand 1 "const1_operand")
10945 (ior (match_test "TARGET_SHIFT1")
10946 (match_test "optimize_function_for_size_p (cfun)")))))
10948 (const_string "*")))
10949 (set_attr "mode" "QI")])
10951 ;; Convert ashift to the lea pattern to avoid flags dependency.
10953 [(set (match_operand:SWI 0 "register_operand")
10954 (ashift:SWI (match_operand:SWI 1 "index_register_operand")
10955 (match_operand 2 "const_0_to_3_operand")))
10956 (clobber (reg:CC FLAGS_REG))]
10958 && REGNO (operands[0]) != REGNO (operands[1])"
10959 [(set (match_dup 0)
10960 (mult:<LEAMODE> (match_dup 1) (match_dup 2)))]
10962 if (<MODE>mode != <LEAMODE>mode)
10964 operands[0] = gen_lowpart (<LEAMODE>mode, operands[0]);
10965 operands[1] = gen_lowpart (<LEAMODE>mode, operands[1]);
10967 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
10970 ;; Convert ashift to the lea pattern to avoid flags dependency.
10972 [(set (match_operand:DI 0 "register_operand")
10974 (ashift:SI (match_operand:SI 1 "index_register_operand")
10975 (match_operand 2 "const_0_to_3_operand"))))
10976 (clobber (reg:CC FLAGS_REG))]
10977 "TARGET_64BIT && reload_completed
10978 && REGNO (operands[0]) != REGNO (operands[1])"
10979 [(set (match_dup 0)
10980 (zero_extend:DI (mult:SI (match_dup 1) (match_dup 2))))]
10982 operands[1] = gen_lowpart (SImode, operands[1]);
10983 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
10986 ;; This pattern can't accept a variable shift count, since shifts by
10987 ;; zero don't affect the flags. We assume that shifts by constant
10988 ;; zero are optimized away.
10989 (define_insn "*ashl<mode>3_cmp"
10990 [(set (reg FLAGS_REG)
10992 (ashift:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
10993 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
10995 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
10996 (ashift:SWI (match_dup 1) (match_dup 2)))]
10997 "(optimize_function_for_size_p (cfun)
10998 || !TARGET_PARTIAL_FLAG_REG_STALL
10999 || (operands[2] == const1_rtx
11001 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
11002 && ix86_match_ccmode (insn, CCGOCmode)
11003 && ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
11005 switch (get_attr_type (insn))
11008 gcc_assert (operands[2] == const1_rtx);
11009 return "add{<imodesuffix>}\t%0, %0";
11012 if (operands[2] == const1_rtx
11013 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11014 return "sal{<imodesuffix>}\t%0";
11016 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
11019 [(set (attr "type")
11020 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
11021 (match_operand 0 "register_operand"))
11022 (match_operand 2 "const1_operand"))
11023 (const_string "alu")
11025 (const_string "ishift")))
11026 (set (attr "length_immediate")
11028 (ior (eq_attr "type" "alu")
11029 (and (eq_attr "type" "ishift")
11030 (and (match_operand 2 "const1_operand")
11031 (ior (match_test "TARGET_SHIFT1")
11032 (match_test "optimize_function_for_size_p (cfun)")))))
11034 (const_string "*")))
11035 (set_attr "mode" "<MODE>")])
11037 (define_insn "*ashlsi3_cmp_zext"
11038 [(set (reg FLAGS_REG)
11040 (ashift:SI (match_operand:SI 1 "register_operand" "0")
11041 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11043 (set (match_operand:DI 0 "register_operand" "=r")
11044 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
11046 && (optimize_function_for_size_p (cfun)
11047 || !TARGET_PARTIAL_FLAG_REG_STALL
11048 || (operands[2] == const1_rtx
11050 || TARGET_DOUBLE_WITH_ADD)))
11051 && ix86_match_ccmode (insn, CCGOCmode)
11052 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11054 switch (get_attr_type (insn))
11057 gcc_assert (operands[2] == const1_rtx);
11058 return "add{l}\t%k0, %k0";
11061 if (operands[2] == const1_rtx
11062 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11063 return "sal{l}\t%k0";
11065 return "sal{l}\t{%2, %k0|%k0, %2}";
11068 [(set (attr "type")
11069 (cond [(and (match_test "TARGET_DOUBLE_WITH_ADD")
11070 (match_operand 2 "const1_operand"))
11071 (const_string "alu")
11073 (const_string "ishift")))
11074 (set (attr "length_immediate")
11076 (ior (eq_attr "type" "alu")
11077 (and (eq_attr "type" "ishift")
11078 (and (match_operand 2 "const1_operand")
11079 (ior (match_test "TARGET_SHIFT1")
11080 (match_test "optimize_function_for_size_p (cfun)")))))
11082 (const_string "*")))
11083 (set_attr "mode" "SI")])
11085 (define_insn "*ashl<mode>3_cconly"
11086 [(set (reg FLAGS_REG)
11088 (ashift:SWI (match_operand:SWI 1 "register_operand" "0")
11089 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
11091 (clobber (match_scratch:SWI 0 "=<r>"))]
11092 "(optimize_function_for_size_p (cfun)
11093 || !TARGET_PARTIAL_FLAG_REG_STALL
11094 || (operands[2] == const1_rtx
11096 || TARGET_DOUBLE_WITH_ADD)))
11097 && ix86_match_ccmode (insn, CCGOCmode)"
11099 switch (get_attr_type (insn))
11102 gcc_assert (operands[2] == const1_rtx);
11103 return "add{<imodesuffix>}\t%0, %0";
11106 if (operands[2] == const1_rtx
11107 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11108 return "sal{<imodesuffix>}\t%0";
11110 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
11113 [(set (attr "type")
11114 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
11115 (match_operand 0 "register_operand"))
11116 (match_operand 2 "const1_operand"))
11117 (const_string "alu")
11119 (const_string "ishift")))
11120 (set (attr "length_immediate")
11122 (ior (eq_attr "type" "alu")
11123 (and (eq_attr "type" "ishift")
11124 (and (match_operand 2 "const1_operand")
11125 (ior (match_test "TARGET_SHIFT1")
11126 (match_test "optimize_function_for_size_p (cfun)")))))
11128 (const_string "*")))
11129 (set_attr "mode" "<MODE>")])
11131 ;; See comment above `ashl<mode>3' about how this works.
11133 (define_expand "<shift_insn><mode>3"
11134 [(set (match_operand:SDWIM 0 "<shift_operand>")
11135 (any_shiftrt:SDWIM (match_operand:SDWIM 1 "<shift_operand>")
11136 (match_operand:QI 2 "nonmemory_operand")))]
11138 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
11140 ;; Avoid useless masking of count operand.
11141 (define_insn_and_split "*<shift_insn><mode>3_mask"
11142 [(set (match_operand:SWI48 0 "nonimmediate_operand")
11144 (match_operand:SWI48 1 "nonimmediate_operand")
11147 (match_operand:SI 2 "register_operand" "c,r")
11148 (match_operand:SI 3 "const_int_operand")) 0)))
11149 (clobber (reg:CC FLAGS_REG))]
11150 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
11151 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
11152 == GET_MODE_BITSIZE (<MODE>mode)-1
11153 && can_create_pseudo_p ()"
11157 [(set (match_dup 0)
11158 (any_shiftrt:SWI48 (match_dup 1)
11160 (clobber (reg:CC FLAGS_REG))])]
11161 "operands[2] = gen_lowpart (QImode, operands[2]);"
11162 [(set_attr "isa" "*,bmi2")])
11164 (define_insn_and_split "*<shift_insn><mode>3_mask_1"
11165 [(set (match_operand:SWI48 0 "nonimmediate_operand")
11167 (match_operand:SWI48 1 "nonimmediate_operand")
11169 (match_operand:QI 2 "register_operand" "c,r")
11170 (match_operand:QI 3 "const_int_operand"))))
11171 (clobber (reg:CC FLAGS_REG))]
11172 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
11173 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
11174 == GET_MODE_BITSIZE (<MODE>mode)-1
11175 && can_create_pseudo_p ()"
11179 [(set (match_dup 0)
11180 (any_shiftrt:SWI48 (match_dup 1)
11182 (clobber (reg:CC FLAGS_REG))])]
11184 [(set_attr "isa" "*,bmi2")])
11186 (define_insn_and_split "*<shift_insn><dwi>3_doubleword_mask"
11187 [(set (match_operand:<DWI> 0 "register_operand")
11189 (match_operand:<DWI> 1 "register_operand")
11192 (match_operand:SI 2 "register_operand" "c")
11193 (match_operand:SI 3 "const_int_operand")) 0)))
11194 (clobber (reg:CC FLAGS_REG))]
11195 "(INTVAL (operands[3]) & (<MODE_SIZE> * BITS_PER_UNIT)) == 0
11196 && can_create_pseudo_p ()"
11200 [(set (match_dup 4)
11201 (ior:DWIH (lshiftrt:DWIH (match_dup 4) (match_dup 2))
11202 (ashift:DWIH (match_dup 7)
11203 (minus:QI (match_dup 8) (match_dup 2)))))
11204 (clobber (reg:CC FLAGS_REG))])
11206 [(set (match_dup 6)
11207 (any_shiftrt:DWIH (match_dup 7) (match_dup 2)))
11208 (clobber (reg:CC FLAGS_REG))])]
11210 split_double_mode (<DWI>mode, &operands[0], 2, &operands[4], &operands[6]);
11212 operands[8] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT);
11214 if ((INTVAL (operands[3]) & ((<MODE_SIZE> * BITS_PER_UNIT) - 1))
11215 != ((<MODE_SIZE> * BITS_PER_UNIT) - 1))
11217 rtx tem = gen_reg_rtx (SImode);
11218 emit_insn (gen_andsi3 (tem, operands[2], operands[3]));
11222 operands[2] = gen_lowpart (QImode, operands[2]);
11224 if (!rtx_equal_p (operands[4], operands[5]))
11225 emit_move_insn (operands[4], operands[5]);
11228 (define_insn_and_split "*<shift_insn><dwi>3_doubleword_mask_1"
11229 [(set (match_operand:<DWI> 0 "register_operand")
11231 (match_operand:<DWI> 1 "register_operand")
11233 (match_operand:QI 2 "register_operand" "c")
11234 (match_operand:QI 3 "const_int_operand"))))
11235 (clobber (reg:CC FLAGS_REG))]
11236 "(INTVAL (operands[3]) & (<MODE_SIZE> * BITS_PER_UNIT)) == 0
11237 && can_create_pseudo_p ()"
11241 [(set (match_dup 4)
11242 (ior:DWIH (lshiftrt:DWIH (match_dup 4) (match_dup 2))
11243 (ashift:DWIH (match_dup 7)
11244 (minus:QI (match_dup 8) (match_dup 2)))))
11245 (clobber (reg:CC FLAGS_REG))])
11247 [(set (match_dup 6)
11248 (any_shiftrt:DWIH (match_dup 7) (match_dup 2)))
11249 (clobber (reg:CC FLAGS_REG))])]
11251 split_double_mode (<DWI>mode, &operands[0], 2, &operands[4], &operands[6]);
11253 operands[8] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT);
11255 if ((INTVAL (operands[3]) & ((<MODE_SIZE> * BITS_PER_UNIT) - 1))
11256 != ((<MODE_SIZE> * BITS_PER_UNIT) - 1))
11258 rtx tem = gen_reg_rtx (QImode);
11259 emit_insn (gen_andqi3 (tem, operands[2], operands[3]));
11263 if (!rtx_equal_p (operands[4], operands[5]))
11264 emit_move_insn (operands[4], operands[5]);
11267 (define_insn_and_split "*<shift_insn><mode>3_doubleword"
11268 [(set (match_operand:DWI 0 "register_operand" "=&r")
11269 (any_shiftrt:DWI (match_operand:DWI 1 "register_operand" "0")
11270 (match_operand:QI 2 "nonmemory_operand" "<S>c")))
11271 (clobber (reg:CC FLAGS_REG))]
11274 "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
11276 "ix86_split_<shift_insn> (operands, NULL_RTX, <MODE>mode); DONE;"
11277 [(set_attr "type" "multi")])
11279 ;; By default we don't ask for a scratch register, because when DWImode
11280 ;; values are manipulated, registers are already at a premium. But if
11281 ;; we have one handy, we won't turn it away.
11284 [(match_scratch:DWIH 3 "r")
11285 (parallel [(set (match_operand:<DWI> 0 "register_operand")
11287 (match_operand:<DWI> 1 "register_operand")
11288 (match_operand:QI 2 "nonmemory_operand")))
11289 (clobber (reg:CC FLAGS_REG))])
11293 "ix86_split_<shift_insn> (operands, operands[3], <DWI>mode); DONE;")
11295 (define_insn "x86_64_shrd"
11296 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
11297 (ior:DI (lshiftrt:DI (match_dup 0)
11298 (match_operand:QI 2 "nonmemory_operand" "Jc"))
11299 (ashift:DI (match_operand:DI 1 "register_operand" "r")
11300 (minus:QI (const_int 64) (match_dup 2)))))
11301 (clobber (reg:CC FLAGS_REG))]
11303 "shrd{q}\t{%s2%1, %0|%0, %1, %2}"
11304 [(set_attr "type" "ishift")
11305 (set_attr "prefix_0f" "1")
11306 (set_attr "mode" "DI")
11307 (set_attr "athlon_decode" "vector")
11308 (set_attr "amdfam10_decode" "vector")
11309 (set_attr "bdver1_decode" "vector")])
11311 (define_insn "x86_shrd"
11312 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
11313 (ior:SI (lshiftrt:SI (match_dup 0)
11314 (match_operand:QI 2 "nonmemory_operand" "Ic"))
11315 (ashift:SI (match_operand:SI 1 "register_operand" "r")
11316 (minus:QI (const_int 32) (match_dup 2)))))
11317 (clobber (reg:CC FLAGS_REG))]
11319 "shrd{l}\t{%s2%1, %0|%0, %1, %2}"
11320 [(set_attr "type" "ishift")
11321 (set_attr "prefix_0f" "1")
11322 (set_attr "mode" "SI")
11323 (set_attr "pent_pair" "np")
11324 (set_attr "athlon_decode" "vector")
11325 (set_attr "amdfam10_decode" "vector")
11326 (set_attr "bdver1_decode" "vector")])
11328 (define_insn "ashrdi3_cvt"
11329 [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
11330 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
11331 (match_operand:QI 2 "const_int_operand")))
11332 (clobber (reg:CC FLAGS_REG))]
11333 "TARGET_64BIT && INTVAL (operands[2]) == 63
11334 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
11335 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11338 sar{q}\t{%2, %0|%0, %2}"
11339 [(set_attr "type" "imovx,ishift")
11340 (set_attr "prefix_0f" "0,*")
11341 (set_attr "length_immediate" "0,*")
11342 (set_attr "modrm" "0,1")
11343 (set_attr "mode" "DI")])
11345 (define_insn "*ashrsi3_cvt_zext"
11346 [(set (match_operand:DI 0 "register_operand" "=*d,r")
11348 (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
11349 (match_operand:QI 2 "const_int_operand"))))
11350 (clobber (reg:CC FLAGS_REG))]
11351 "TARGET_64BIT && INTVAL (operands[2]) == 31
11352 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
11353 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11356 sar{l}\t{%2, %k0|%k0, %2}"
11357 [(set_attr "type" "imovx,ishift")
11358 (set_attr "prefix_0f" "0,*")
11359 (set_attr "length_immediate" "0,*")
11360 (set_attr "modrm" "0,1")
11361 (set_attr "mode" "SI")])
11363 (define_insn "ashrsi3_cvt"
11364 [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
11365 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
11366 (match_operand:QI 2 "const_int_operand")))
11367 (clobber (reg:CC FLAGS_REG))]
11368 "INTVAL (operands[2]) == 31
11369 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
11370 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11373 sar{l}\t{%2, %0|%0, %2}"
11374 [(set_attr "type" "imovx,ishift")
11375 (set_attr "prefix_0f" "0,*")
11376 (set_attr "length_immediate" "0,*")
11377 (set_attr "modrm" "0,1")
11378 (set_attr "mode" "SI")])
11380 (define_expand "x86_shift<mode>_adj_3"
11381 [(use (match_operand:SWI48 0 "register_operand"))
11382 (use (match_operand:SWI48 1 "register_operand"))
11383 (use (match_operand:QI 2 "register_operand"))]
11386 rtx_code_label *label = gen_label_rtx ();
11389 emit_insn (gen_testqi_ccz_1 (operands[2],
11390 GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
11392 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
11393 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
11394 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
11395 gen_rtx_LABEL_REF (VOIDmode, label),
11397 tmp = emit_jump_insn (gen_rtx_SET (pc_rtx, tmp));
11398 JUMP_LABEL (tmp) = label;
11400 emit_move_insn (operands[0], operands[1]);
11401 emit_insn (gen_ashr<mode>3_cvt (operands[1], operands[1],
11402 GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1)));
11403 emit_label (label);
11404 LABEL_NUSES (label) = 1;
11409 (define_insn "*bmi2_<shift_insn><mode>3_1"
11410 [(set (match_operand:SWI48 0 "register_operand" "=r")
11411 (any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11412 (match_operand:SWI48 2 "register_operand" "r")))]
11414 "<shift>x\t{%2, %1, %0|%0, %1, %2}"
11415 [(set_attr "type" "ishiftx")
11416 (set_attr "mode" "<MODE>")])
11418 (define_insn "*<shift_insn><mode>3_1"
11419 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
11421 (match_operand:SWI48 1 "nonimmediate_operand" "0,rm")
11422 (match_operand:QI 2 "nonmemory_operand" "c<S>,r")))
11423 (clobber (reg:CC FLAGS_REG))]
11424 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
11426 switch (get_attr_type (insn))
11432 if (operands[2] == const1_rtx
11433 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11434 return "<shift>{<imodesuffix>}\t%0";
11436 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
11439 [(set_attr "isa" "*,bmi2")
11440 (set_attr "type" "ishift,ishiftx")
11441 (set (attr "length_immediate")
11443 (and (match_operand 2 "const1_operand")
11444 (ior (match_test "TARGET_SHIFT1")
11445 (match_test "optimize_function_for_size_p (cfun)")))
11447 (const_string "*")))
11448 (set_attr "mode" "<MODE>")])
11450 ;; Convert shift to the shiftx pattern to avoid flags dependency.
11452 [(set (match_operand:SWI48 0 "register_operand")
11453 (any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
11454 (match_operand:QI 2 "register_operand")))
11455 (clobber (reg:CC FLAGS_REG))]
11456 "TARGET_BMI2 && reload_completed"
11457 [(set (match_dup 0)
11458 (any_shiftrt:SWI48 (match_dup 1) (match_dup 2)))]
11459 "operands[2] = gen_lowpart (<MODE>mode, operands[2]);")
11461 (define_insn "*bmi2_<shift_insn>si3_1_zext"
11462 [(set (match_operand:DI 0 "register_operand" "=r")
11464 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
11465 (match_operand:SI 2 "register_operand" "r"))))]
11466 "TARGET_64BIT && TARGET_BMI2"
11467 "<shift>x\t{%2, %1, %k0|%k0, %1, %2}"
11468 [(set_attr "type" "ishiftx")
11469 (set_attr "mode" "SI")])
11471 (define_insn "*<shift_insn>si3_1_zext"
11472 [(set (match_operand:DI 0 "register_operand" "=r,r")
11474 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm")
11475 (match_operand:QI 2 "nonmemory_operand" "cI,r"))))
11476 (clobber (reg:CC FLAGS_REG))]
11477 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
11479 switch (get_attr_type (insn))
11485 if (operands[2] == const1_rtx
11486 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11487 return "<shift>{l}\t%k0";
11489 return "<shift>{l}\t{%2, %k0|%k0, %2}";
11492 [(set_attr "isa" "*,bmi2")
11493 (set_attr "type" "ishift,ishiftx")
11494 (set (attr "length_immediate")
11496 (and (match_operand 2 "const1_operand")
11497 (ior (match_test "TARGET_SHIFT1")
11498 (match_test "optimize_function_for_size_p (cfun)")))
11500 (const_string "*")))
11501 (set_attr "mode" "SI")])
11503 ;; Convert shift to the shiftx pattern to avoid flags dependency.
11505 [(set (match_operand:DI 0 "register_operand")
11507 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand")
11508 (match_operand:QI 2 "register_operand"))))
11509 (clobber (reg:CC FLAGS_REG))]
11510 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
11511 [(set (match_dup 0)
11512 (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
11513 "operands[2] = gen_lowpart (SImode, operands[2]);")
11515 (define_insn "*<shift_insn><mode>3_1"
11516 [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m")
11518 (match_operand:SWI12 1 "nonimmediate_operand" "0")
11519 (match_operand:QI 2 "nonmemory_operand" "c<S>")))
11520 (clobber (reg:CC FLAGS_REG))]
11521 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
11523 if (operands[2] == const1_rtx
11524 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11525 return "<shift>{<imodesuffix>}\t%0";
11527 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
11529 [(set_attr "type" "ishift")
11530 (set (attr "length_immediate")
11532 (and (match_operand 2 "const1_operand")
11533 (ior (match_test "TARGET_SHIFT1")
11534 (match_test "optimize_function_for_size_p (cfun)")))
11536 (const_string "*")))
11537 (set_attr "mode" "<MODE>")])
11539 (define_insn "*<shift_insn>qi3_1_slp"
11540 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
11541 (any_shiftrt:QI (match_dup 0)
11542 (match_operand:QI 1 "nonmemory_operand" "cI")))
11543 (clobber (reg:CC FLAGS_REG))]
11544 "(optimize_function_for_size_p (cfun)
11545 || !TARGET_PARTIAL_REG_STALL
11546 || (operands[1] == const1_rtx
11547 && TARGET_SHIFT1))"
11549 if (operands[1] == const1_rtx
11550 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11551 return "<shift>{b}\t%0";
11553 return "<shift>{b}\t{%1, %0|%0, %1}";
11555 [(set_attr "type" "ishift1")
11556 (set (attr "length_immediate")
11558 (and (match_operand 1 "const1_operand")
11559 (ior (match_test "TARGET_SHIFT1")
11560 (match_test "optimize_function_for_size_p (cfun)")))
11562 (const_string "*")))
11563 (set_attr "mode" "QI")])
11565 ;; This pattern can't accept a variable shift count, since shifts by
11566 ;; zero don't affect the flags. We assume that shifts by constant
11567 ;; zero are optimized away.
11568 (define_insn "*<shift_insn><mode>3_cmp"
11569 [(set (reg FLAGS_REG)
11572 (match_operand:SWI 1 "nonimmediate_operand" "0")
11573 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
11575 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
11576 (any_shiftrt:SWI (match_dup 1) (match_dup 2)))]
11577 "(optimize_function_for_size_p (cfun)
11578 || !TARGET_PARTIAL_FLAG_REG_STALL
11579 || (operands[2] == const1_rtx
11581 && ix86_match_ccmode (insn, CCGOCmode)
11582 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
11584 if (operands[2] == const1_rtx
11585 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11586 return "<shift>{<imodesuffix>}\t%0";
11588 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
11590 [(set_attr "type" "ishift")
11591 (set (attr "length_immediate")
11593 (and (match_operand 2 "const1_operand")
11594 (ior (match_test "TARGET_SHIFT1")
11595 (match_test "optimize_function_for_size_p (cfun)")))
11597 (const_string "*")))
11598 (set_attr "mode" "<MODE>")])
11600 (define_insn "*<shift_insn>si3_cmp_zext"
11601 [(set (reg FLAGS_REG)
11603 (any_shiftrt:SI (match_operand:SI 1 "register_operand" "0")
11604 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11606 (set (match_operand:DI 0 "register_operand" "=r")
11607 (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
11609 && (optimize_function_for_size_p (cfun)
11610 || !TARGET_PARTIAL_FLAG_REG_STALL
11611 || (operands[2] == const1_rtx
11613 && ix86_match_ccmode (insn, CCGOCmode)
11614 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
11616 if (operands[2] == const1_rtx
11617 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11618 return "<shift>{l}\t%k0";
11620 return "<shift>{l}\t{%2, %k0|%k0, %2}";
11622 [(set_attr "type" "ishift")
11623 (set (attr "length_immediate")
11625 (and (match_operand 2 "const1_operand")
11626 (ior (match_test "TARGET_SHIFT1")
11627 (match_test "optimize_function_for_size_p (cfun)")))
11629 (const_string "*")))
11630 (set_attr "mode" "SI")])
11632 (define_insn "*<shift_insn><mode>3_cconly"
11633 [(set (reg FLAGS_REG)
11636 (match_operand:SWI 1 "register_operand" "0")
11637 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
11639 (clobber (match_scratch:SWI 0 "=<r>"))]
11640 "(optimize_function_for_size_p (cfun)
11641 || !TARGET_PARTIAL_FLAG_REG_STALL
11642 || (operands[2] == const1_rtx
11644 && ix86_match_ccmode (insn, CCGOCmode)"
11646 if (operands[2] == const1_rtx
11647 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11648 return "<shift>{<imodesuffix>}\t%0";
11650 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
11652 [(set_attr "type" "ishift")
11653 (set (attr "length_immediate")
11655 (and (match_operand 2 "const1_operand")
11656 (ior (match_test "TARGET_SHIFT1")
11657 (match_test "optimize_function_for_size_p (cfun)")))
11659 (const_string "*")))
11660 (set_attr "mode" "<MODE>")])
11662 ;; Rotate instructions
11664 (define_expand "<rotate_insn>ti3"
11665 [(set (match_operand:TI 0 "register_operand")
11666 (any_rotate:TI (match_operand:TI 1 "register_operand")
11667 (match_operand:QI 2 "nonmemory_operand")))]
11670 if (const_1_to_63_operand (operands[2], VOIDmode))
11671 emit_insn (gen_ix86_<rotate_insn>ti3_doubleword
11672 (operands[0], operands[1], operands[2]));
11679 (define_expand "<rotate_insn>di3"
11680 [(set (match_operand:DI 0 "shiftdi_operand")
11681 (any_rotate:DI (match_operand:DI 1 "shiftdi_operand")
11682 (match_operand:QI 2 "nonmemory_operand")))]
11686 ix86_expand_binary_operator (<CODE>, DImode, operands);
11687 else if (const_1_to_31_operand (operands[2], VOIDmode))
11688 emit_insn (gen_ix86_<rotate_insn>di3_doubleword
11689 (operands[0], operands[1], operands[2]));
11696 (define_expand "<rotate_insn><mode>3"
11697 [(set (match_operand:SWIM124 0 "nonimmediate_operand")
11698 (any_rotate:SWIM124 (match_operand:SWIM124 1 "nonimmediate_operand")
11699 (match_operand:QI 2 "nonmemory_operand")))]
11701 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
11703 ;; Avoid useless masking of count operand.
11704 (define_insn_and_split "*<rotate_insn><mode>3_mask"
11705 [(set (match_operand:SWI48 0 "nonimmediate_operand")
11707 (match_operand:SWI48 1 "nonimmediate_operand")
11710 (match_operand:SI 2 "register_operand" "c")
11711 (match_operand:SI 3 "const_int_operand")) 0)))
11712 (clobber (reg:CC FLAGS_REG))]
11713 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
11714 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
11715 == GET_MODE_BITSIZE (<MODE>mode)-1
11716 && can_create_pseudo_p ()"
11720 [(set (match_dup 0)
11721 (any_rotate:SWI48 (match_dup 1)
11723 (clobber (reg:CC FLAGS_REG))])]
11724 "operands[2] = gen_lowpart (QImode, operands[2]);")
11726 (define_insn_and_split "*<rotate_insn><mode>3_mask_1"
11727 [(set (match_operand:SWI48 0 "nonimmediate_operand")
11729 (match_operand:SWI48 1 "nonimmediate_operand")
11731 (match_operand:QI 2 "register_operand" "c")
11732 (match_operand:QI 3 "const_int_operand"))))
11733 (clobber (reg:CC FLAGS_REG))]
11734 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
11735 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
11736 == GET_MODE_BITSIZE (<MODE>mode)-1
11737 && can_create_pseudo_p ()"
11741 [(set (match_dup 0)
11742 (any_rotate:SWI48 (match_dup 1)
11744 (clobber (reg:CC FLAGS_REG))])])
11746 ;; Implement rotation using two double-precision
11747 ;; shift instructions and a scratch register.
11749 (define_insn_and_split "ix86_rotl<dwi>3_doubleword"
11750 [(set (match_operand:<DWI> 0 "register_operand" "=r")
11751 (rotate:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
11752 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
11753 (clobber (reg:CC FLAGS_REG))
11754 (clobber (match_scratch:DWIH 3 "=&r"))]
11758 [(set (match_dup 3) (match_dup 4))
11760 [(set (match_dup 4)
11761 (ior:DWIH (ashift:DWIH (match_dup 4) (match_dup 2))
11762 (lshiftrt:DWIH (match_dup 5)
11763 (minus:QI (match_dup 6) (match_dup 2)))))
11764 (clobber (reg:CC FLAGS_REG))])
11766 [(set (match_dup 5)
11767 (ior:DWIH (ashift:DWIH (match_dup 5) (match_dup 2))
11768 (lshiftrt:DWIH (match_dup 3)
11769 (minus:QI (match_dup 6) (match_dup 2)))))
11770 (clobber (reg:CC FLAGS_REG))])]
11772 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
11774 split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
11777 (define_insn_and_split "ix86_rotr<dwi>3_doubleword"
11778 [(set (match_operand:<DWI> 0 "register_operand" "=r")
11779 (rotatert:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
11780 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
11781 (clobber (reg:CC FLAGS_REG))
11782 (clobber (match_scratch:DWIH 3 "=&r"))]
11786 [(set (match_dup 3) (match_dup 4))
11788 [(set (match_dup 4)
11789 (ior:DWIH (lshiftrt:DWIH (match_dup 4) (match_dup 2))
11790 (ashift:DWIH (match_dup 5)
11791 (minus:QI (match_dup 6) (match_dup 2)))))
11792 (clobber (reg:CC FLAGS_REG))])
11794 [(set (match_dup 5)
11795 (ior:DWIH (lshiftrt:DWIH (match_dup 5) (match_dup 2))
11796 (ashift:DWIH (match_dup 3)
11797 (minus:QI (match_dup 6) (match_dup 2)))))
11798 (clobber (reg:CC FLAGS_REG))])]
11800 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
11802 split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
11805 (define_mode_attr rorx_immediate_operand
11806 [(SI "const_0_to_31_operand")
11807 (DI "const_0_to_63_operand")])
11809 (define_insn "*bmi2_rorx<mode>3_1"
11810 [(set (match_operand:SWI48 0 "register_operand" "=r")
11812 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11813 (match_operand:QI 2 "<rorx_immediate_operand>" "<S>")))]
11815 "rorx\t{%2, %1, %0|%0, %1, %2}"
11816 [(set_attr "type" "rotatex")
11817 (set_attr "mode" "<MODE>")])
11819 (define_insn "*<rotate_insn><mode>3_1"
11820 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
11822 (match_operand:SWI48 1 "nonimmediate_operand" "0,rm")
11823 (match_operand:QI 2 "nonmemory_operand" "c<S>,<S>")))
11824 (clobber (reg:CC FLAGS_REG))]
11825 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
11827 switch (get_attr_type (insn))
11833 if (operands[2] == const1_rtx
11834 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11835 return "<rotate>{<imodesuffix>}\t%0";
11837 return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
11840 [(set_attr "isa" "*,bmi2")
11841 (set_attr "type" "rotate,rotatex")
11842 (set (attr "length_immediate")
11844 (and (eq_attr "type" "rotate")
11845 (and (match_operand 2 "const1_operand")
11846 (ior (match_test "TARGET_SHIFT1")
11847 (match_test "optimize_function_for_size_p (cfun)"))))
11849 (const_string "*")))
11850 (set_attr "mode" "<MODE>")])
11852 ;; Convert rotate to the rotatex pattern to avoid flags dependency.
11854 [(set (match_operand:SWI48 0 "register_operand")
11855 (rotate:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
11856 (match_operand:QI 2 "const_int_operand")))
11857 (clobber (reg:CC FLAGS_REG))]
11858 "TARGET_BMI2 && reload_completed"
11859 [(set (match_dup 0)
11860 (rotatert:SWI48 (match_dup 1) (match_dup 2)))]
11862 int bitsize = GET_MODE_BITSIZE (<MODE>mode);
11864 operands[2] = GEN_INT ((bitsize - INTVAL (operands[2])) % bitsize);
11868 [(set (match_operand:SWI48 0 "register_operand")
11869 (rotatert:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
11870 (match_operand:QI 2 "const_int_operand")))
11871 (clobber (reg:CC FLAGS_REG))]
11872 "TARGET_BMI2 && reload_completed"
11873 [(set (match_dup 0)
11874 (rotatert:SWI48 (match_dup 1) (match_dup 2)))])
11876 (define_insn "*bmi2_rorxsi3_1_zext"
11877 [(set (match_operand:DI 0 "register_operand" "=r")
11879 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
11880 (match_operand:QI 2 "const_0_to_31_operand" "I"))))]
11881 "TARGET_64BIT && TARGET_BMI2"
11882 "rorx\t{%2, %1, %k0|%k0, %1, %2}"
11883 [(set_attr "type" "rotatex")
11884 (set_attr "mode" "SI")])
11886 (define_insn "*<rotate_insn>si3_1_zext"
11887 [(set (match_operand:DI 0 "register_operand" "=r,r")
11889 (any_rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm")
11890 (match_operand:QI 2 "nonmemory_operand" "cI,I"))))
11891 (clobber (reg:CC FLAGS_REG))]
11892 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
11894 switch (get_attr_type (insn))
11900 if (operands[2] == const1_rtx
11901 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11902 return "<rotate>{l}\t%k0";
11904 return "<rotate>{l}\t{%2, %k0|%k0, %2}";
11907 [(set_attr "isa" "*,bmi2")
11908 (set_attr "type" "rotate,rotatex")
11909 (set (attr "length_immediate")
11911 (and (eq_attr "type" "rotate")
11912 (and (match_operand 2 "const1_operand")
11913 (ior (match_test "TARGET_SHIFT1")
11914 (match_test "optimize_function_for_size_p (cfun)"))))
11916 (const_string "*")))
11917 (set_attr "mode" "SI")])
11919 ;; Convert rotate to the rotatex pattern to avoid flags dependency.
11921 [(set (match_operand:DI 0 "register_operand")
11923 (rotate:SI (match_operand:SI 1 "nonimmediate_operand")
11924 (match_operand:QI 2 "const_int_operand"))))
11925 (clobber (reg:CC FLAGS_REG))]
11926 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
11927 [(set (match_dup 0)
11928 (zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))]
11930 int bitsize = GET_MODE_BITSIZE (SImode);
11932 operands[2] = GEN_INT ((bitsize - INTVAL (operands[2])) % bitsize);
11936 [(set (match_operand:DI 0 "register_operand")
11938 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand")
11939 (match_operand:QI 2 "const_int_operand"))))
11940 (clobber (reg:CC FLAGS_REG))]
11941 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
11942 [(set (match_dup 0)
11943 (zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))])
11945 (define_insn "*<rotate_insn><mode>3_1"
11946 [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m")
11947 (any_rotate:SWI12 (match_operand:SWI12 1 "nonimmediate_operand" "0")
11948 (match_operand:QI 2 "nonmemory_operand" "c<S>")))
11949 (clobber (reg:CC FLAGS_REG))]
11950 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
11952 if (operands[2] == const1_rtx
11953 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11954 return "<rotate>{<imodesuffix>}\t%0";
11956 return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
11958 [(set_attr "type" "rotate")
11959 (set (attr "length_immediate")
11961 (and (match_operand 2 "const1_operand")
11962 (ior (match_test "TARGET_SHIFT1")
11963 (match_test "optimize_function_for_size_p (cfun)")))
11965 (const_string "*")))
11966 (set_attr "mode" "<MODE>")])
11968 (define_insn "*<rotate_insn>qi3_1_slp"
11969 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
11970 (any_rotate:QI (match_dup 0)
11971 (match_operand:QI 1 "nonmemory_operand" "cI")))
11972 (clobber (reg:CC FLAGS_REG))]
11973 "(optimize_function_for_size_p (cfun)
11974 || !TARGET_PARTIAL_REG_STALL
11975 || (operands[1] == const1_rtx
11976 && TARGET_SHIFT1))"
11978 if (operands[1] == const1_rtx
11979 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11980 return "<rotate>{b}\t%0";
11982 return "<rotate>{b}\t{%1, %0|%0, %1}";
11984 [(set_attr "type" "rotate1")
11985 (set (attr "length_immediate")
11987 (and (match_operand 1 "const1_operand")
11988 (ior (match_test "TARGET_SHIFT1")
11989 (match_test "optimize_function_for_size_p (cfun)")))
11991 (const_string "*")))
11992 (set_attr "mode" "QI")])
11995 [(set (match_operand:HI 0 "QIreg_operand")
11996 (any_rotate:HI (match_dup 0) (const_int 8)))
11997 (clobber (reg:CC FLAGS_REG))]
11999 && (TARGET_USE_XCHGB || optimize_function_for_size_p (cfun))"
12000 [(parallel [(set (strict_low_part (match_dup 0))
12001 (bswap:HI (match_dup 0)))
12002 (clobber (reg:CC FLAGS_REG))])])
12004 ;; Bit set / bit test instructions
12006 ;; %%% bts, btr, btc
12008 ;; These instructions are *slow* when applied to memory.
12010 (define_code_attr btsc [(ior "bts") (xor "btc")])
12012 (define_insn "*<btsc><mode>"
12013 [(set (match_operand:SWI48 0 "register_operand" "=r")
12015 (ashift:SWI48 (const_int 1)
12016 (match_operand:QI 2 "register_operand" "r"))
12017 (match_operand:SWI48 1 "register_operand" "0")))
12018 (clobber (reg:CC FLAGS_REG))]
12020 "<btsc>{<imodesuffix>}\t{%<k>2, %0|%0, %<k>2}"
12021 [(set_attr "type" "alu1")
12022 (set_attr "prefix_0f" "1")
12023 (set_attr "znver1_decode" "double")
12024 (set_attr "mode" "<MODE>")])
12026 ;; Avoid useless masking of count operand.
12027 (define_insn_and_split "*<btsc><mode>_mask"
12028 [(set (match_operand:SWI48 0 "register_operand")
12034 (match_operand:SI 1 "register_operand")
12035 (match_operand:SI 2 "const_int_operand")) 0))
12036 (match_operand:SWI48 3 "register_operand")))
12037 (clobber (reg:CC FLAGS_REG))]
12039 && (INTVAL (operands[2]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
12040 == GET_MODE_BITSIZE (<MODE>mode)-1
12041 && can_create_pseudo_p ()"
12045 [(set (match_dup 0)
12047 (ashift:SWI48 (const_int 1)
12050 (clobber (reg:CC FLAGS_REG))])]
12051 "operands[1] = gen_lowpart (QImode, operands[1]);")
12053 (define_insn_and_split "*<btsc><mode>_mask_1"
12054 [(set (match_operand:SWI48 0 "register_operand")
12059 (match_operand:QI 1 "register_operand")
12060 (match_operand:QI 2 "const_int_operand")))
12061 (match_operand:SWI48 3 "register_operand")))
12062 (clobber (reg:CC FLAGS_REG))]
12064 && (INTVAL (operands[2]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
12065 == GET_MODE_BITSIZE (<MODE>mode)-1
12066 && can_create_pseudo_p ()"
12070 [(set (match_dup 0)
12072 (ashift:SWI48 (const_int 1)
12075 (clobber (reg:CC FLAGS_REG))])])
12077 (define_insn "*btr<mode>"
12078 [(set (match_operand:SWI48 0 "register_operand" "=r")
12080 (rotate:SWI48 (const_int -2)
12081 (match_operand:QI 2 "register_operand" "r"))
12082 (match_operand:SWI48 1 "register_operand" "0")))
12083 (clobber (reg:CC FLAGS_REG))]
12085 "btr{<imodesuffix>}\t{%<k>2, %0|%0, %<k>2}"
12086 [(set_attr "type" "alu1")
12087 (set_attr "prefix_0f" "1")
12088 (set_attr "znver1_decode" "double")
12089 (set_attr "mode" "<MODE>")])
12091 ;; Avoid useless masking of count operand.
12092 (define_insn_and_split "*btr<mode>_mask"
12093 [(set (match_operand:SWI48 0 "register_operand")
12099 (match_operand:SI 1 "register_operand")
12100 (match_operand:SI 2 "const_int_operand")) 0))
12101 (match_operand:SWI48 3 "register_operand")))
12102 (clobber (reg:CC FLAGS_REG))]
12104 && (INTVAL (operands[2]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
12105 == GET_MODE_BITSIZE (<MODE>mode)-1
12106 && can_create_pseudo_p ()"
12110 [(set (match_dup 0)
12112 (rotate:SWI48 (const_int -2)
12115 (clobber (reg:CC FLAGS_REG))])]
12116 "operands[1] = gen_lowpart (QImode, operands[1]);")
12118 (define_insn_and_split "*btr<mode>_mask_1"
12119 [(set (match_operand:SWI48 0 "register_operand")
12124 (match_operand:QI 1 "register_operand")
12125 (match_operand:QI 2 "const_int_operand")))
12126 (match_operand:SWI48 3 "register_operand")))
12127 (clobber (reg:CC FLAGS_REG))]
12129 && (INTVAL (operands[2]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
12130 == GET_MODE_BITSIZE (<MODE>mode)-1
12131 && can_create_pseudo_p ()"
12135 [(set (match_dup 0)
12137 (rotate:SWI48 (const_int -2)
12140 (clobber (reg:CC FLAGS_REG))])])
12142 ;; These instructions are never faster than the corresponding
12143 ;; and/ior/xor operations when using immediate operand, so with
12144 ;; 32-bit there's no point. But in 64-bit, we can't hold the
12145 ;; relevant immediates within the instruction itself, so operating
12146 ;; on bits in the high 32-bits of a register becomes easier.
12148 ;; These are slow on Nocona, but fast on Athlon64. We do require the use
12149 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
12150 ;; negdf respectively, so they can never be disabled entirely.
12152 (define_insn "*btsq_imm"
12153 [(set (zero_extract:DI (match_operand:DI 0 "nonimmediate_operand" "+rm")
12155 (match_operand 1 "const_0_to_63_operand" "J"))
12157 (clobber (reg:CC FLAGS_REG))]
12158 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
12159 "bts{q}\t{%1, %0|%0, %1}"
12160 [(set_attr "type" "alu1")
12161 (set_attr "prefix_0f" "1")
12162 (set_attr "znver1_decode" "double")
12163 (set_attr "mode" "DI")])
12165 (define_insn "*btrq_imm"
12166 [(set (zero_extract:DI (match_operand:DI 0 "nonimmediate_operand" "+rm")
12168 (match_operand 1 "const_0_to_63_operand" "J"))
12170 (clobber (reg:CC FLAGS_REG))]
12171 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
12172 "btr{q}\t{%1, %0|%0, %1}"
12173 [(set_attr "type" "alu1")
12174 (set_attr "prefix_0f" "1")
12175 (set_attr "znver1_decode" "double")
12176 (set_attr "mode" "DI")])
12178 (define_insn "*btcq_imm"
12179 [(set (zero_extract:DI (match_operand:DI 0 "nonimmediate_operand" "+rm")
12181 (match_operand 1 "const_0_to_63_operand" "J"))
12182 (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
12183 (clobber (reg:CC FLAGS_REG))]
12184 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
12185 "btc{q}\t{%1, %0|%0, %1}"
12186 [(set_attr "type" "alu1")
12187 (set_attr "prefix_0f" "1")
12188 (set_attr "znver1_decode" "double")
12189 (set_attr "mode" "DI")])
12191 ;; Allow Nocona to avoid these instructions if a register is available.
12194 [(match_scratch:DI 2 "r")
12195 (parallel [(set (zero_extract:DI
12196 (match_operand:DI 0 "nonimmediate_operand")
12198 (match_operand 1 "const_0_to_63_operand"))
12200 (clobber (reg:CC FLAGS_REG))])]
12201 "TARGET_64BIT && !TARGET_USE_BT"
12202 [(parallel [(set (match_dup 0)
12203 (ior:DI (match_dup 0) (match_dup 3)))
12204 (clobber (reg:CC FLAGS_REG))])]
12206 int i = INTVAL (operands[1]);
12208 operands[3] = gen_int_mode (HOST_WIDE_INT_1U << i, DImode);
12210 if (!x86_64_immediate_operand (operands[3], DImode))
12212 emit_move_insn (operands[2], operands[3]);
12213 operands[3] = operands[2];
12218 [(match_scratch:DI 2 "r")
12219 (parallel [(set (zero_extract:DI
12220 (match_operand:DI 0 "nonimmediate_operand")
12222 (match_operand 1 "const_0_to_63_operand"))
12224 (clobber (reg:CC FLAGS_REG))])]
12225 "TARGET_64BIT && !TARGET_USE_BT"
12226 [(parallel [(set (match_dup 0)
12227 (and:DI (match_dup 0) (match_dup 3)))
12228 (clobber (reg:CC FLAGS_REG))])]
12230 int i = INTVAL (operands[1]);
12232 operands[3] = gen_int_mode (~(HOST_WIDE_INT_1U << i), DImode);
12234 if (!x86_64_immediate_operand (operands[3], DImode))
12236 emit_move_insn (operands[2], operands[3]);
12237 operands[3] = operands[2];
12242 [(match_scratch:DI 2 "r")
12243 (parallel [(set (zero_extract:DI
12244 (match_operand:DI 0 "nonimmediate_operand")
12246 (match_operand 1 "const_0_to_63_operand"))
12247 (not:DI (zero_extract:DI
12248 (match_dup 0) (const_int 1) (match_dup 1))))
12249 (clobber (reg:CC FLAGS_REG))])]
12250 "TARGET_64BIT && !TARGET_USE_BT"
12251 [(parallel [(set (match_dup 0)
12252 (xor:DI (match_dup 0) (match_dup 3)))
12253 (clobber (reg:CC FLAGS_REG))])]
12255 int i = INTVAL (operands[1]);
12257 operands[3] = gen_int_mode (HOST_WIDE_INT_1U << i, DImode);
12259 if (!x86_64_immediate_operand (operands[3], DImode))
12261 emit_move_insn (operands[2], operands[3]);
12262 operands[3] = operands[2];
12268 (define_insn "*bt<mode>"
12269 [(set (reg:CCC FLAGS_REG)
12271 (zero_extract:SWI48
12272 (match_operand:SWI48 0 "nonimmediate_operand" "r,m")
12274 (match_operand:SI 1 "nonmemory_operand" "r<S>,<S>"))
12278 switch (get_attr_mode (insn))
12281 return "bt{l}\t{%1, %k0|%k0, %1}";
12284 return "bt{q}\t{%q1, %0|%0, %q1}";
12287 gcc_unreachable ();
12290 [(set_attr "type" "alu1")
12291 (set_attr "prefix_0f" "1")
12294 (and (match_test "CONST_INT_P (operands[1])")
12295 (match_test "INTVAL (operands[1]) < 32"))
12296 (const_string "SI")
12297 (const_string "<MODE>")))])
12299 (define_insn_and_split "*jcc_bt<mode>"
12301 (if_then_else (match_operator 0 "bt_comparison_operator"
12302 [(zero_extract:SWI48
12303 (match_operand:SWI48 1 "nonimmediate_operand")
12305 (match_operand:SI 2 "nonmemory_operand"))
12307 (label_ref (match_operand 3))
12309 (clobber (reg:CC FLAGS_REG))]
12310 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
12311 && (CONST_INT_P (operands[2])
12312 ? (INTVAL (operands[2]) < GET_MODE_BITSIZE (<MODE>mode)
12313 && INTVAL (operands[2])
12314 >= (optimize_function_for_size_p (cfun) ? 8 : 32))
12315 : !memory_operand (operands[1], <MODE>mode))
12316 && can_create_pseudo_p ()"
12319 [(set (reg:CCC FLAGS_REG)
12321 (zero_extract:SWI48
12327 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
12328 (label_ref (match_dup 3))
12331 operands[0] = shallow_copy_rtx (operands[0]);
12332 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
12335 (define_insn_and_split "*jcc_bt<mode>_1"
12337 (if_then_else (match_operator 0 "bt_comparison_operator"
12338 [(zero_extract:SWI48
12339 (match_operand:SWI48 1 "register_operand")
12342 (match_operand:QI 2 "register_operand")))
12344 (label_ref (match_operand 3))
12346 (clobber (reg:CC FLAGS_REG))]
12347 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
12348 && can_create_pseudo_p ()"
12351 [(set (reg:CCC FLAGS_REG)
12353 (zero_extract:SWI48
12359 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
12360 (label_ref (match_dup 3))
12363 operands[2] = lowpart_subreg (SImode, operands[2], QImode);
12364 operands[0] = shallow_copy_rtx (operands[0]);
12365 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
12368 ;; Avoid useless masking of bit offset operand.
12369 (define_insn_and_split "*jcc_bt<mode>_mask"
12371 (if_then_else (match_operator 0 "bt_comparison_operator"
12372 [(zero_extract:SWI48
12373 (match_operand:SWI48 1 "register_operand")
12376 (match_operand:SI 2 "register_operand")
12377 (match_operand 3 "const_int_operand")))])
12378 (label_ref (match_operand 4))
12380 (clobber (reg:CC FLAGS_REG))]
12381 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
12382 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
12383 == GET_MODE_BITSIZE (<MODE>mode)-1
12384 && can_create_pseudo_p ()"
12387 [(set (reg:CCC FLAGS_REG)
12389 (zero_extract:SWI48
12395 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
12396 (label_ref (match_dup 4))
12399 operands[0] = shallow_copy_rtx (operands[0]);
12400 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
12403 ;; Store-flag instructions.
12405 ;; For all sCOND expanders, also expand the compare or test insn that
12406 ;; generates cc0. Generate an equality comparison if `seq' or `sne'.
12408 (define_insn_and_split "*setcc_di_1"
12409 [(set (match_operand:DI 0 "register_operand" "=q")
12410 (match_operator:DI 1 "ix86_comparison_operator"
12411 [(reg FLAGS_REG) (const_int 0)]))]
12412 "TARGET_64BIT && !TARGET_PARTIAL_REG_STALL"
12414 "&& reload_completed"
12415 [(set (match_dup 2) (match_dup 1))
12416 (set (match_dup 0) (zero_extend:DI (match_dup 2)))]
12418 operands[1] = shallow_copy_rtx (operands[1]);
12419 PUT_MODE (operands[1], QImode);
12420 operands[2] = gen_lowpart (QImode, operands[0]);
12423 (define_insn_and_split "*setcc_si_1_and"
12424 [(set (match_operand:SI 0 "register_operand" "=q")
12425 (match_operator:SI 1 "ix86_comparison_operator"
12426 [(reg FLAGS_REG) (const_int 0)]))
12427 (clobber (reg:CC FLAGS_REG))]
12428 "!TARGET_PARTIAL_REG_STALL
12429 && TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
12431 "&& reload_completed"
12432 [(set (match_dup 2) (match_dup 1))
12433 (parallel [(set (match_dup 0) (zero_extend:SI (match_dup 2)))
12434 (clobber (reg:CC FLAGS_REG))])]
12436 operands[1] = shallow_copy_rtx (operands[1]);
12437 PUT_MODE (operands[1], QImode);
12438 operands[2] = gen_lowpart (QImode, operands[0]);
12441 (define_insn_and_split "*setcc_si_1_movzbl"
12442 [(set (match_operand:SI 0 "register_operand" "=q")
12443 (match_operator:SI 1 "ix86_comparison_operator"
12444 [(reg FLAGS_REG) (const_int 0)]))]
12445 "!TARGET_PARTIAL_REG_STALL
12446 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
12448 "&& reload_completed"
12449 [(set (match_dup 2) (match_dup 1))
12450 (set (match_dup 0) (zero_extend:SI (match_dup 2)))]
12452 operands[1] = shallow_copy_rtx (operands[1]);
12453 PUT_MODE (operands[1], QImode);
12454 operands[2] = gen_lowpart (QImode, operands[0]);
12457 (define_insn "*setcc_qi"
12458 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12459 (match_operator:QI 1 "ix86_comparison_operator"
12460 [(reg FLAGS_REG) (const_int 0)]))]
12463 [(set_attr "type" "setcc")
12464 (set_attr "mode" "QI")])
12466 (define_insn "*setcc_qi_slp"
12467 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12468 (match_operator:QI 1 "ix86_comparison_operator"
12469 [(reg FLAGS_REG) (const_int 0)]))]
12472 [(set_attr "type" "setcc")
12473 (set_attr "mode" "QI")])
12475 ;; In general it is not safe to assume too much about CCmode registers,
12476 ;; so simplify-rtx stops when it sees a second one. Under certain
12477 ;; conditions this is safe on x86, so help combine not create
12484 [(set (match_operand:QI 0 "nonimmediate_operand")
12485 (ne:QI (match_operator 1 "ix86_comparison_operator"
12486 [(reg FLAGS_REG) (const_int 0)])
12489 [(set (match_dup 0) (match_dup 1))]
12491 operands[1] = shallow_copy_rtx (operands[1]);
12492 PUT_MODE (operands[1], QImode);
12496 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand"))
12497 (ne:QI (match_operator 1 "ix86_comparison_operator"
12498 [(reg FLAGS_REG) (const_int 0)])
12501 [(set (match_dup 0) (match_dup 1))]
12503 operands[1] = shallow_copy_rtx (operands[1]);
12504 PUT_MODE (operands[1], QImode);
12508 [(set (match_operand:QI 0 "nonimmediate_operand")
12509 (eq:QI (match_operator 1 "ix86_comparison_operator"
12510 [(reg FLAGS_REG) (const_int 0)])
12513 [(set (match_dup 0) (match_dup 1))]
12515 operands[1] = shallow_copy_rtx (operands[1]);
12516 PUT_MODE (operands[1], QImode);
12517 PUT_CODE (operands[1],
12518 ix86_reverse_condition (GET_CODE (operands[1]),
12519 GET_MODE (XEXP (operands[1], 0))));
12521 /* Make sure that (a) the CCmode we have for the flags is strong
12522 enough for the reversed compare or (b) we have a valid FP compare. */
12523 if (! ix86_comparison_operator (operands[1], VOIDmode))
12528 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand"))
12529 (eq:QI (match_operator 1 "ix86_comparison_operator"
12530 [(reg FLAGS_REG) (const_int 0)])
12533 [(set (match_dup 0) (match_dup 1))]
12535 operands[1] = shallow_copy_rtx (operands[1]);
12536 PUT_MODE (operands[1], QImode);
12537 PUT_CODE (operands[1],
12538 ix86_reverse_condition (GET_CODE (operands[1]),
12539 GET_MODE (XEXP (operands[1], 0))));
12541 /* Make sure that (a) the CCmode we have for the flags is strong
12542 enough for the reversed compare or (b) we have a valid FP compare. */
12543 if (! ix86_comparison_operator (operands[1], VOIDmode))
12547 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
12548 ;; subsequent logical operations are used to imitate conditional moves.
12549 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
12552 (define_insn "setcc_<mode>_sse"
12553 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
12554 (match_operator:MODEF 3 "sse_comparison_operator"
12555 [(match_operand:MODEF 1 "register_operand" "0,x")
12556 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
12557 "SSE_FLOAT_MODE_P (<MODE>mode)"
12559 cmp%D3<ssemodesuffix>\t{%2, %0|%0, %2}
12560 vcmp%D3<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
12561 [(set_attr "isa" "noavx,avx")
12562 (set_attr "type" "ssecmp")
12563 (set_attr "length_immediate" "1")
12564 (set_attr "prefix" "orig,vex")
12565 (set_attr "mode" "<MODE>")])
12567 ;; Basic conditional jump instructions.
12568 ;; We ignore the overflow flag for signed branch instructions.
12570 (define_insn "*jcc"
12572 (if_then_else (match_operator 1 "ix86_comparison_operator"
12573 [(reg FLAGS_REG) (const_int 0)])
12574 (label_ref (match_operand 0))
12578 [(set_attr "type" "ibr")
12579 (set_attr "modrm" "0")
12580 (set (attr "length")
12582 (and (ge (minus (match_dup 0) (pc))
12584 (lt (minus (match_dup 0) (pc))
12589 ;; In general it is not safe to assume too much about CCmode registers,
12590 ;; so simplify-rtx stops when it sees a second one. Under certain
12591 ;; conditions this is safe on x86, so help combine not create
12599 (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
12600 [(reg FLAGS_REG) (const_int 0)])
12602 (label_ref (match_operand 1))
12606 (if_then_else (match_dup 0)
12607 (label_ref (match_dup 1))
12610 operands[0] = shallow_copy_rtx (operands[0]);
12611 PUT_MODE (operands[0], VOIDmode);
12616 (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
12617 [(reg FLAGS_REG) (const_int 0)])
12619 (label_ref (match_operand 1))
12623 (if_then_else (match_dup 0)
12624 (label_ref (match_dup 1))
12627 operands[0] = shallow_copy_rtx (operands[0]);
12628 PUT_MODE (operands[0], VOIDmode);
12629 PUT_CODE (operands[0],
12630 ix86_reverse_condition (GET_CODE (operands[0]),
12631 GET_MODE (XEXP (operands[0], 0))));
12633 /* Make sure that (a) the CCmode we have for the flags is strong
12634 enough for the reversed compare or (b) we have a valid FP compare. */
12635 if (! ix86_comparison_operator (operands[0], VOIDmode))
12639 ;; Unconditional and other jump instructions
12641 (define_insn "jump"
12643 (label_ref (match_operand 0)))]
12646 [(set_attr "type" "ibr")
12647 (set_attr "modrm" "0")
12648 (set (attr "length")
12650 (and (ge (minus (match_dup 0) (pc))
12652 (lt (minus (match_dup 0) (pc))
12657 (define_expand "indirect_jump"
12658 [(set (pc) (match_operand 0 "indirect_branch_operand"))]
12661 if (TARGET_X32 || TARGET_INDIRECT_BRANCH_REGISTER)
12662 operands[0] = convert_memory_address (word_mode, operands[0]);
12663 cfun->machine->has_local_indirect_jump = true;
12666 (define_insn "*indirect_jump"
12667 [(set (pc) (match_operand:W 0 "indirect_branch_operand" "rBw"))]
12669 "* return ix86_output_indirect_jmp (operands[0]);"
12670 [(set (attr "type")
12671 (if_then_else (match_test "(cfun->machine->indirect_branch_type
12672 != indirect_branch_keep)")
12673 (const_string "multi")
12674 (const_string "ibr")))
12675 (set_attr "length_immediate" "0")])
12677 (define_expand "tablejump"
12678 [(parallel [(set (pc) (match_operand 0 "indirect_branch_operand"))
12679 (use (label_ref (match_operand 1)))])]
12682 /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
12683 relative. Convert the relative address to an absolute address. */
12687 enum rtx_code code;
12689 /* We can't use @GOTOFF for text labels on VxWorks;
12690 see gotoff_operand. */
12691 if (TARGET_64BIT || TARGET_VXWORKS_RTP)
12695 op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
12697 else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
12701 op1 = pic_offset_table_rtx;
12706 op0 = pic_offset_table_rtx;
12710 operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
12714 if (TARGET_X32 || TARGET_INDIRECT_BRANCH_REGISTER)
12715 operands[0] = convert_memory_address (word_mode, operands[0]);
12716 cfun->machine->has_local_indirect_jump = true;
12719 (define_insn "*tablejump_1"
12720 [(set (pc) (match_operand:W 0 "indirect_branch_operand" "rBw"))
12721 (use (label_ref (match_operand 1)))]
12723 "* return ix86_output_indirect_jmp (operands[0]);"
12724 [(set (attr "type")
12725 (if_then_else (match_test "(cfun->machine->indirect_branch_type
12726 != indirect_branch_keep)")
12727 (const_string "multi")
12728 (const_string "ibr")))
12729 (set_attr "length_immediate" "0")])
12731 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
12734 [(set (reg FLAGS_REG) (match_operand 0))
12735 (set (match_operand:QI 1 "register_operand")
12736 (match_operator:QI 2 "ix86_comparison_operator"
12737 [(reg FLAGS_REG) (const_int 0)]))
12738 (set (match_operand 3 "any_QIreg_operand")
12739 (zero_extend (match_dup 1)))]
12740 "(peep2_reg_dead_p (3, operands[1])
12741 || operands_match_p (operands[1], operands[3]))
12742 && ! reg_overlap_mentioned_p (operands[3], operands[0])
12743 && peep2_regno_dead_p (0, FLAGS_REG)"
12744 [(set (match_dup 4) (match_dup 0))
12745 (set (strict_low_part (match_dup 5))
12748 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
12749 operands[5] = gen_lowpart (QImode, operands[3]);
12750 ix86_expand_clear (operands[3]);
12754 [(parallel [(set (reg FLAGS_REG) (match_operand 0))
12755 (match_operand 4)])
12756 (set (match_operand:QI 1 "register_operand")
12757 (match_operator:QI 2 "ix86_comparison_operator"
12758 [(reg FLAGS_REG) (const_int 0)]))
12759 (set (match_operand 3 "any_QIreg_operand")
12760 (zero_extend (match_dup 1)))]
12761 "(peep2_reg_dead_p (3, operands[1])
12762 || operands_match_p (operands[1], operands[3]))
12763 && ! reg_overlap_mentioned_p (operands[3], operands[0])
12764 && ! reg_overlap_mentioned_p (operands[3], operands[4])
12765 && ! reg_set_p (operands[3], operands[4])
12766 && peep2_regno_dead_p (0, FLAGS_REG)"
12767 [(parallel [(set (match_dup 5) (match_dup 0))
12769 (set (strict_low_part (match_dup 6))
12772 operands[5] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
12773 operands[6] = gen_lowpart (QImode, operands[3]);
12774 ix86_expand_clear (operands[3]);
12778 [(set (reg FLAGS_REG) (match_operand 0))
12779 (parallel [(set (reg FLAGS_REG) (match_operand 1))
12780 (match_operand 5)])
12781 (set (match_operand:QI 2 "register_operand")
12782 (match_operator:QI 3 "ix86_comparison_operator"
12783 [(reg FLAGS_REG) (const_int 0)]))
12784 (set (match_operand 4 "any_QIreg_operand")
12785 (zero_extend (match_dup 2)))]
12786 "(peep2_reg_dead_p (4, operands[2])
12787 || operands_match_p (operands[2], operands[4]))
12788 && ! reg_overlap_mentioned_p (operands[4], operands[0])
12789 && ! reg_overlap_mentioned_p (operands[4], operands[1])
12790 && ! reg_overlap_mentioned_p (operands[4], operands[5])
12791 && ! reg_set_p (operands[4], operands[5])
12792 && refers_to_regno_p (FLAGS_REG, operands[1], (rtx *)NULL)
12793 && peep2_regno_dead_p (0, FLAGS_REG)"
12794 [(set (match_dup 6) (match_dup 0))
12795 (parallel [(set (match_dup 7) (match_dup 1))
12797 (set (strict_low_part (match_dup 8))
12800 operands[6] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
12801 operands[7] = gen_rtx_REG (GET_MODE (operands[1]), FLAGS_REG);
12802 operands[8] = gen_lowpart (QImode, operands[4]);
12803 ix86_expand_clear (operands[4]);
12806 ;; Similar, but match zero extend with andsi3.
12809 [(set (reg FLAGS_REG) (match_operand 0))
12810 (set (match_operand:QI 1 "register_operand")
12811 (match_operator:QI 2 "ix86_comparison_operator"
12812 [(reg FLAGS_REG) (const_int 0)]))
12813 (parallel [(set (match_operand:SI 3 "any_QIreg_operand")
12814 (and:SI (match_dup 3) (const_int 255)))
12815 (clobber (reg:CC FLAGS_REG))])]
12816 "REGNO (operands[1]) == REGNO (operands[3])
12817 && ! reg_overlap_mentioned_p (operands[3], operands[0])
12818 && peep2_regno_dead_p (0, FLAGS_REG)"
12819 [(set (match_dup 4) (match_dup 0))
12820 (set (strict_low_part (match_dup 5))
12823 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
12824 operands[5] = gen_lowpart (QImode, operands[3]);
12825 ix86_expand_clear (operands[3]);
12829 [(parallel [(set (reg FLAGS_REG) (match_operand 0))
12830 (match_operand 4)])
12831 (set (match_operand:QI 1 "register_operand")
12832 (match_operator:QI 2 "ix86_comparison_operator"
12833 [(reg FLAGS_REG) (const_int 0)]))
12834 (parallel [(set (match_operand 3 "any_QIreg_operand")
12835 (zero_extend (match_dup 1)))
12836 (clobber (reg:CC FLAGS_REG))])]
12837 "(peep2_reg_dead_p (3, operands[1])
12838 || operands_match_p (operands[1], operands[3]))
12839 && ! reg_overlap_mentioned_p (operands[3], operands[0])
12840 && ! reg_overlap_mentioned_p (operands[3], operands[4])
12841 && ! reg_set_p (operands[3], operands[4])
12842 && peep2_regno_dead_p (0, FLAGS_REG)"
12843 [(parallel [(set (match_dup 5) (match_dup 0))
12845 (set (strict_low_part (match_dup 6))
12848 operands[5] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
12849 operands[6] = gen_lowpart (QImode, operands[3]);
12850 ix86_expand_clear (operands[3]);
12854 [(set (reg FLAGS_REG) (match_operand 0))
12855 (parallel [(set (reg FLAGS_REG) (match_operand 1))
12856 (match_operand 5)])
12857 (set (match_operand:QI 2 "register_operand")
12858 (match_operator:QI 3 "ix86_comparison_operator"
12859 [(reg FLAGS_REG) (const_int 0)]))
12860 (parallel [(set (match_operand 4 "any_QIreg_operand")
12861 (zero_extend (match_dup 2)))
12862 (clobber (reg:CC FLAGS_REG))])]
12863 "(peep2_reg_dead_p (4, operands[2])
12864 || operands_match_p (operands[2], operands[4]))
12865 && ! reg_overlap_mentioned_p (operands[4], operands[0])
12866 && ! reg_overlap_mentioned_p (operands[4], operands[1])
12867 && ! reg_overlap_mentioned_p (operands[4], operands[5])
12868 && ! reg_set_p (operands[4], operands[5])
12869 && refers_to_regno_p (FLAGS_REG, operands[1], (rtx *)NULL)
12870 && peep2_regno_dead_p (0, FLAGS_REG)"
12871 [(set (match_dup 6) (match_dup 0))
12872 (parallel [(set (match_dup 7) (match_dup 1))
12874 (set (strict_low_part (match_dup 8))
12877 operands[6] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
12878 operands[7] = gen_rtx_REG (GET_MODE (operands[1]), FLAGS_REG);
12879 operands[8] = gen_lowpart (QImode, operands[4]);
12880 ix86_expand_clear (operands[4]);
12883 ;; Call instructions.
12885 ;; The predicates normally associated with named expanders are not properly
12886 ;; checked for calls. This is a bug in the generic code, but it isn't that
12887 ;; easy to fix. Ignore it for now and be prepared to fix things up.
12889 ;; P6 processors will jump to the address after the decrement when %esp
12890 ;; is used as a call operand, so they will execute return address as a code.
12891 ;; See Pentium Pro errata 70, Pentium 2 errata A33 and Pentium 3 errata E17.
12893 ;; Register constraint for call instruction.
12894 (define_mode_attr c [(SI "l") (DI "r")])
12896 ;; Call subroutine returning no value.
12898 (define_expand "call"
12899 [(call (match_operand:QI 0)
12901 (use (match_operand 2))]
12904 ix86_expand_call (NULL, operands[0], operands[1],
12905 operands[2], NULL, false);
12909 (define_expand "sibcall"
12910 [(call (match_operand:QI 0)
12912 (use (match_operand 2))]
12915 ix86_expand_call (NULL, operands[0], operands[1],
12916 operands[2], NULL, true);
12920 (define_insn "*call"
12921 [(call (mem:QI (match_operand:W 0 "call_insn_operand" "<c>BwBz"))
12922 (match_operand 1))]
12923 "!SIBLING_CALL_P (insn)"
12924 "* return ix86_output_call_insn (insn, operands[0]);"
12925 [(set_attr "type" "call")])
12927 ;; This covers both call and sibcall since only GOT slot is allowed.
12928 (define_insn "*call_got_x32"
12929 [(call (mem:QI (zero_extend:DI
12930 (match_operand:SI 0 "GOT_memory_operand" "Bg")))
12931 (match_operand 1))]
12934 rtx fnaddr = gen_const_mem (DImode, XEXP (operands[0], 0));
12935 return ix86_output_call_insn (insn, fnaddr);
12937 [(set_attr "type" "call")])
12939 ;; Since sibcall never returns, we can only use call-clobbered register
12941 (define_insn "*sibcall_GOT_32"
12944 (match_operand:SI 0 "register_no_elim_operand" "U")
12945 (match_operand:SI 1 "GOT32_symbol_operand"))))
12946 (match_operand 2))]
12949 && !TARGET_INDIRECT_BRANCH_REGISTER
12950 && SIBLING_CALL_P (insn)"
12952 rtx fnaddr = gen_rtx_PLUS (SImode, operands[0], operands[1]);
12953 fnaddr = gen_const_mem (SImode, fnaddr);
12954 return ix86_output_call_insn (insn, fnaddr);
12956 [(set_attr "type" "call")])
12958 (define_insn "*sibcall"
12959 [(call (mem:QI (match_operand:W 0 "sibcall_insn_operand" "UBsBz"))
12960 (match_operand 1))]
12961 "SIBLING_CALL_P (insn)"
12962 "* return ix86_output_call_insn (insn, operands[0]);"
12963 [(set_attr "type" "call")])
12965 (define_insn "*sibcall_memory"
12966 [(call (mem:QI (match_operand:W 0 "memory_operand" "m"))
12968 (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
12969 "!TARGET_X32 && !TARGET_INDIRECT_BRANCH_REGISTER"
12970 "* return ix86_output_call_insn (insn, operands[0]);"
12971 [(set_attr "type" "call")])
12974 [(set (match_operand:W 0 "register_operand")
12975 (match_operand:W 1 "memory_operand"))
12976 (call (mem:QI (match_dup 0))
12977 (match_operand 3))]
12979 && !TARGET_INDIRECT_BRANCH_REGISTER
12980 && SIBLING_CALL_P (peep2_next_insn (1))
12981 && !reg_mentioned_p (operands[0],
12982 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (1)))"
12983 [(parallel [(call (mem:QI (match_dup 1))
12985 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
12988 [(set (match_operand:W 0 "register_operand")
12989 (match_operand:W 1 "memory_operand"))
12990 (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
12991 (call (mem:QI (match_dup 0))
12992 (match_operand 3))]
12994 && !TARGET_INDIRECT_BRANCH_REGISTER
12995 && SIBLING_CALL_P (peep2_next_insn (2))
12996 && !reg_mentioned_p (operands[0],
12997 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (2)))"
12998 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
12999 (parallel [(call (mem:QI (match_dup 1))
13001 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
13003 (define_expand "call_pop"
13004 [(parallel [(call (match_operand:QI 0)
13005 (match_operand:SI 1))
13006 (set (reg:SI SP_REG)
13007 (plus:SI (reg:SI SP_REG)
13008 (match_operand:SI 3)))])]
13011 ix86_expand_call (NULL, operands[0], operands[1],
13012 operands[2], operands[3], false);
13016 (define_insn "*call_pop"
13017 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lBwBz"))
13019 (set (reg:SI SP_REG)
13020 (plus:SI (reg:SI SP_REG)
13021 (match_operand:SI 2 "immediate_operand" "i")))]
13022 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
13023 "* return ix86_output_call_insn (insn, operands[0]);"
13024 [(set_attr "type" "call")])
13026 (define_insn "*sibcall_pop"
13027 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "UBsBz"))
13029 (set (reg:SI SP_REG)
13030 (plus:SI (reg:SI SP_REG)
13031 (match_operand:SI 2 "immediate_operand" "i")))]
13032 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
13033 "* return ix86_output_call_insn (insn, operands[0]);"
13034 [(set_attr "type" "call")])
13036 (define_insn "*sibcall_pop_memory"
13037 [(call (mem:QI (match_operand:SI 0 "memory_operand" "Bs"))
13039 (set (reg:SI SP_REG)
13040 (plus:SI (reg:SI SP_REG)
13041 (match_operand:SI 2 "immediate_operand" "i")))
13042 (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
13044 "* return ix86_output_call_insn (insn, operands[0]);"
13045 [(set_attr "type" "call")])
13048 [(set (match_operand:SI 0 "register_operand")
13049 (match_operand:SI 1 "memory_operand"))
13050 (parallel [(call (mem:QI (match_dup 0))
13052 (set (reg:SI SP_REG)
13053 (plus:SI (reg:SI SP_REG)
13054 (match_operand:SI 4 "immediate_operand")))])]
13055 "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (1))
13056 && !reg_mentioned_p (operands[0],
13057 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (1)))"
13058 [(parallel [(call (mem:QI (match_dup 1))
13060 (set (reg:SI SP_REG)
13061 (plus:SI (reg:SI SP_REG)
13063 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
13066 [(set (match_operand:SI 0 "register_operand")
13067 (match_operand:SI 1 "memory_operand"))
13068 (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
13069 (parallel [(call (mem:QI (match_dup 0))
13071 (set (reg:SI SP_REG)
13072 (plus:SI (reg:SI SP_REG)
13073 (match_operand:SI 4 "immediate_operand")))])]
13074 "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (2))
13075 && !reg_mentioned_p (operands[0],
13076 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (2)))"
13077 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
13078 (parallel [(call (mem:QI (match_dup 1))
13080 (set (reg:SI SP_REG)
13081 (plus:SI (reg:SI SP_REG)
13083 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
13085 ;; Combining simple memory jump instruction
13088 [(set (match_operand:W 0 "register_operand")
13089 (match_operand:W 1 "memory_operand"))
13090 (set (pc) (match_dup 0))]
13092 && !TARGET_INDIRECT_BRANCH_REGISTER
13093 && peep2_reg_dead_p (2, operands[0])"
13094 [(set (pc) (match_dup 1))])
13096 ;; Call subroutine, returning value in operand 0
13098 (define_expand "call_value"
13099 [(set (match_operand 0)
13100 (call (match_operand:QI 1)
13101 (match_operand 2)))
13102 (use (match_operand 3))]
13105 ix86_expand_call (operands[0], operands[1], operands[2],
13106 operands[3], NULL, false);
13110 (define_expand "sibcall_value"
13111 [(set (match_operand 0)
13112 (call (match_operand:QI 1)
13113 (match_operand 2)))
13114 (use (match_operand 3))]
13117 ix86_expand_call (operands[0], operands[1], operands[2],
13118 operands[3], NULL, true);
13122 (define_insn "*call_value"
13123 [(set (match_operand 0)
13124 (call (mem:QI (match_operand:W 1 "call_insn_operand" "<c>BwBz"))
13125 (match_operand 2)))]
13126 "!SIBLING_CALL_P (insn)"
13127 "* return ix86_output_call_insn (insn, operands[1]);"
13128 [(set_attr "type" "callv")])
13130 ;; This covers both call and sibcall since only GOT slot is allowed.
13131 (define_insn "*call_value_got_x32"
13132 [(set (match_operand 0)
13135 (match_operand:SI 1 "GOT_memory_operand" "Bg")))
13136 (match_operand 2)))]
13139 rtx fnaddr = gen_const_mem (DImode, XEXP (operands[1], 0));
13140 return ix86_output_call_insn (insn, fnaddr);
13142 [(set_attr "type" "callv")])
13144 ;; Since sibcall never returns, we can only use call-clobbered register
13146 (define_insn "*sibcall_value_GOT_32"
13147 [(set (match_operand 0)
13150 (match_operand:SI 1 "register_no_elim_operand" "U")
13151 (match_operand:SI 2 "GOT32_symbol_operand"))))
13152 (match_operand 3)))]
13155 && !TARGET_INDIRECT_BRANCH_REGISTER
13156 && SIBLING_CALL_P (insn)"
13158 rtx fnaddr = gen_rtx_PLUS (SImode, operands[1], operands[2]);
13159 fnaddr = gen_const_mem (SImode, fnaddr);
13160 return ix86_output_call_insn (insn, fnaddr);
13162 [(set_attr "type" "callv")])
13164 (define_insn "*sibcall_value"
13165 [(set (match_operand 0)
13166 (call (mem:QI (match_operand:W 1 "sibcall_insn_operand" "UBsBz"))
13167 (match_operand 2)))]
13168 "SIBLING_CALL_P (insn)"
13169 "* return ix86_output_call_insn (insn, operands[1]);"
13170 [(set_attr "type" "callv")])
13172 (define_insn "*sibcall_value_memory"
13173 [(set (match_operand 0)
13174 (call (mem:QI (match_operand:W 1 "memory_operand" "m"))
13175 (match_operand 2)))
13176 (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
13177 "!TARGET_X32 && !TARGET_INDIRECT_BRANCH_REGISTER"
13178 "* return ix86_output_call_insn (insn, operands[1]);"
13179 [(set_attr "type" "callv")])
13182 [(set (match_operand:W 0 "register_operand")
13183 (match_operand:W 1 "memory_operand"))
13184 (set (match_operand 2)
13185 (call (mem:QI (match_dup 0))
13186 (match_operand 3)))]
13188 && !TARGET_INDIRECT_BRANCH_REGISTER
13189 && SIBLING_CALL_P (peep2_next_insn (1))
13190 && !reg_mentioned_p (operands[0],
13191 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (1)))"
13192 [(parallel [(set (match_dup 2)
13193 (call (mem:QI (match_dup 1))
13195 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
13198 [(set (match_operand:W 0 "register_operand")
13199 (match_operand:W 1 "memory_operand"))
13200 (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
13201 (set (match_operand 2)
13202 (call (mem:QI (match_dup 0))
13203 (match_operand 3)))]
13205 && !TARGET_INDIRECT_BRANCH_REGISTER
13206 && SIBLING_CALL_P (peep2_next_insn (2))
13207 && !reg_mentioned_p (operands[0],
13208 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (2)))"
13209 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
13210 (parallel [(set (match_dup 2)
13211 (call (mem:QI (match_dup 1))
13213 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
13215 (define_expand "call_value_pop"
13216 [(parallel [(set (match_operand 0)
13217 (call (match_operand:QI 1)
13218 (match_operand:SI 2)))
13219 (set (reg:SI SP_REG)
13220 (plus:SI (reg:SI SP_REG)
13221 (match_operand:SI 4)))])]
13224 ix86_expand_call (operands[0], operands[1], operands[2],
13225 operands[3], operands[4], false);
13229 (define_insn "*call_value_pop"
13230 [(set (match_operand 0)
13231 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lBwBz"))
13232 (match_operand 2)))
13233 (set (reg:SI SP_REG)
13234 (plus:SI (reg:SI SP_REG)
13235 (match_operand:SI 3 "immediate_operand" "i")))]
13236 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
13237 "* return ix86_output_call_insn (insn, operands[1]);"
13238 [(set_attr "type" "callv")])
13240 (define_insn "*sibcall_value_pop"
13241 [(set (match_operand 0)
13242 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "UBsBz"))
13243 (match_operand 2)))
13244 (set (reg:SI SP_REG)
13245 (plus:SI (reg:SI SP_REG)
13246 (match_operand:SI 3 "immediate_operand" "i")))]
13247 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
13248 "* return ix86_output_call_insn (insn, operands[1]);"
13249 [(set_attr "type" "callv")])
13251 (define_insn "*sibcall_value_pop_memory"
13252 [(set (match_operand 0)
13253 (call (mem:QI (match_operand:SI 1 "memory_operand" "m"))
13254 (match_operand 2)))
13255 (set (reg:SI SP_REG)
13256 (plus:SI (reg:SI SP_REG)
13257 (match_operand:SI 3 "immediate_operand" "i")))
13258 (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
13260 "* return ix86_output_call_insn (insn, operands[1]);"
13261 [(set_attr "type" "callv")])
13264 [(set (match_operand:SI 0 "register_operand")
13265 (match_operand:SI 1 "memory_operand"))
13266 (parallel [(set (match_operand 2)
13267 (call (mem:QI (match_dup 0))
13268 (match_operand 3)))
13269 (set (reg:SI SP_REG)
13270 (plus:SI (reg:SI SP_REG)
13271 (match_operand:SI 4 "immediate_operand")))])]
13272 "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (1))
13273 && !reg_mentioned_p (operands[0],
13274 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (1)))"
13275 [(parallel [(set (match_dup 2)
13276 (call (mem:QI (match_dup 1))
13278 (set (reg:SI SP_REG)
13279 (plus:SI (reg:SI SP_REG)
13281 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
13284 [(set (match_operand:SI 0 "register_operand")
13285 (match_operand:SI 1 "memory_operand"))
13286 (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
13287 (parallel [(set (match_operand 2)
13288 (call (mem:QI (match_dup 0))
13289 (match_operand 3)))
13290 (set (reg:SI SP_REG)
13291 (plus:SI (reg:SI SP_REG)
13292 (match_operand:SI 4 "immediate_operand")))])]
13293 "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (2))
13294 && !reg_mentioned_p (operands[0],
13295 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (2)))"
13296 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
13297 (parallel [(set (match_dup 2)
13298 (call (mem:QI (match_dup 1))
13300 (set (reg:SI SP_REG)
13301 (plus:SI (reg:SI SP_REG)
13303 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
13305 ;; Call subroutine returning any type.
13307 (define_expand "untyped_call"
13308 [(parallel [(call (match_operand 0)
13311 (match_operand 2)])]
13316 /* In order to give reg-stack an easier job in validating two
13317 coprocessor registers as containing a possible return value,
13318 simply pretend the untyped call returns a complex long double
13321 We can't use SSE_REGPARM_MAX here since callee is unprototyped
13322 and should have the default ABI. */
13324 ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
13325 ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
13326 operands[0], const0_rtx,
13327 GEN_INT ((TARGET_64BIT
13328 ? (ix86_abi == SYSV_ABI
13329 ? X86_64_SSE_REGPARM_MAX
13330 : X86_64_MS_SSE_REGPARM_MAX)
13331 : X86_32_SSE_REGPARM_MAX)
13335 for (i = 0; i < XVECLEN (operands[2], 0); i++)
13337 rtx set = XVECEXP (operands[2], 0, i);
13338 emit_move_insn (SET_DEST (set), SET_SRC (set));
13341 /* The optimizer does not know that the call sets the function value
13342 registers we stored in the result block. We avoid problems by
13343 claiming that all hard registers are used and clobbered at this
13345 emit_insn (gen_blockage ());
13350 ;; Prologue and epilogue instructions
13352 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
13353 ;; all of memory. This blocks insns from being moved across this point.
13355 (define_insn "blockage"
13356 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
13359 [(set_attr "length" "0")])
13361 ;; Do not schedule instructions accessing memory across this point.
13363 (define_expand "memory_blockage"
13364 [(set (match_dup 0)
13365 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
13368 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
13369 MEM_VOLATILE_P (operands[0]) = 1;
13372 (define_insn "*memory_blockage"
13373 [(set (match_operand:BLK 0)
13374 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
13377 [(set_attr "length" "0")])
13379 ;; As USE insns aren't meaningful after reload, this is used instead
13380 ;; to prevent deleting instructions setting registers for PIC code
13381 (define_insn "prologue_use"
13382 [(unspec_volatile [(match_operand 0)] UNSPECV_PROLOGUE_USE)]
13385 [(set_attr "length" "0")])
13387 ;; Insn emitted into the body of a function to return from a function.
13388 ;; This is only done if the function's epilogue is known to be simple.
13389 ;; See comments for ix86_can_use_return_insn_p in i386.c.
13391 (define_expand "return"
13393 "ix86_can_use_return_insn_p ()"
13395 if (crtl->args.pops_args)
13397 rtx popc = GEN_INT (crtl->args.pops_args);
13398 emit_jump_insn (gen_simple_return_pop_internal (popc));
13403 ;; We need to disable this for TARGET_SEH, as otherwise
13404 ;; shrink-wrapped prologue gets enabled too. This might exceed
13405 ;; the maximum size of prologue in unwind information.
13406 ;; Also disallow shrink-wrapping if using stack slot to pass the
13407 ;; static chain pointer - the first instruction has to be pushl %esi
13408 ;; and it can't be moved around, as we use alternate entry points
13411 (define_expand "simple_return"
13413 "!TARGET_SEH && !ix86_static_chain_on_stack"
13415 if (crtl->args.pops_args)
13417 rtx popc = GEN_INT (crtl->args.pops_args);
13418 emit_jump_insn (gen_simple_return_pop_internal (popc));
13423 (define_insn "simple_return_internal"
13426 "* return ix86_output_function_return (false);"
13427 [(set_attr "length" "1")
13428 (set_attr "atom_unit" "jeu")
13429 (set_attr "length_immediate" "0")
13430 (set_attr "modrm" "0")])
13432 (define_insn "interrupt_return"
13434 (unspec [(const_int 0)] UNSPEC_INTERRUPT_RETURN)]
13437 return TARGET_64BIT ? "iretq" : "iret";
13440 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
13441 ;; instruction Athlon and K8 have.
13443 (define_insn "simple_return_internal_long"
13445 (unspec [(const_int 0)] UNSPEC_REP)]
13447 "* return ix86_output_function_return (true);"
13448 [(set_attr "length" "2")
13449 (set_attr "atom_unit" "jeu")
13450 (set_attr "length_immediate" "0")
13451 (set_attr "prefix_rep" "1")
13452 (set_attr "modrm" "0")])
13454 (define_insn_and_split "simple_return_pop_internal"
13456 (use (match_operand:SI 0 "const_int_operand"))]
13459 "&& cfun->machine->function_return_type != indirect_branch_keep"
13461 "ix86_split_simple_return_pop_internal (operands[0]); DONE;"
13462 [(set_attr "length" "3")
13463 (set_attr "atom_unit" "jeu")
13464 (set_attr "length_immediate" "2")
13465 (set_attr "modrm" "0")])
13467 (define_expand "simple_return_indirect_internal"
13470 (use (match_operand 0 "register_operand"))])])
13472 (define_insn "*simple_return_indirect_internal<mode>"
13474 (use (match_operand:W 0 "register_operand" "r"))]
13476 "* return ix86_output_indirect_function_return (operands[0]);"
13477 [(set (attr "type")
13478 (if_then_else (match_test "(cfun->machine->indirect_branch_type
13479 != indirect_branch_keep)")
13480 (const_string "multi")
13481 (const_string "ibr")))
13482 (set_attr "length_immediate" "0")])
13488 [(set_attr "length" "1")
13489 (set_attr "length_immediate" "0")
13490 (set_attr "modrm" "0")])
13492 ;; Generate nops. Operand 0 is the number of nops, up to 8.
13493 (define_insn "nops"
13494 [(unspec_volatile [(match_operand 0 "const_int_operand")]
13498 int num = INTVAL (operands[0]);
13500 gcc_assert (IN_RANGE (num, 1, 8));
13503 fputs ("\tnop\n", asm_out_file);
13507 [(set (attr "length") (symbol_ref "INTVAL (operands[0])"))
13508 (set_attr "length_immediate" "0")
13509 (set_attr "modrm" "0")])
13511 ;; Pad to 16-byte boundary, max skip in op0. Used to avoid
13512 ;; branch prediction penalty for the third jump in a 16-byte
13516 [(unspec_volatile [(match_operand 0)] UNSPECV_ALIGN)]
13519 #ifdef ASM_OUTPUT_MAX_SKIP_PAD
13520 ASM_OUTPUT_MAX_SKIP_PAD (asm_out_file, 4, (int)INTVAL (operands[0]));
13522 /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
13523 The align insn is used to avoid 3 jump instructions in the row to improve
13524 branch prediction and the benefits hardly outweigh the cost of extra 8
13525 nops on the average inserted by full alignment pseudo operation. */
13529 [(set_attr "length" "16")])
13531 (define_expand "prologue"
13534 "ix86_expand_prologue (); DONE;")
13536 (define_expand "set_got"
13538 [(set (match_operand:SI 0 "register_operand")
13539 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
13540 (clobber (reg:CC FLAGS_REG))])]
13543 if (flag_pic && !TARGET_VXWORKS_RTP)
13544 ix86_pc_thunk_call_expanded = true;
13547 (define_insn "*set_got"
13548 [(set (match_operand:SI 0 "register_operand" "=r")
13549 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
13550 (clobber (reg:CC FLAGS_REG))]
13552 "* return output_set_got (operands[0], NULL_RTX);"
13553 [(set_attr "type" "multi")
13554 (set_attr "length" "12")])
13556 (define_expand "set_got_labelled"
13558 [(set (match_operand:SI 0 "register_operand")
13559 (unspec:SI [(label_ref (match_operand 1))]
13561 (clobber (reg:CC FLAGS_REG))])]
13564 if (flag_pic && !TARGET_VXWORKS_RTP)
13565 ix86_pc_thunk_call_expanded = true;
13568 (define_insn "*set_got_labelled"
13569 [(set (match_operand:SI 0 "register_operand" "=r")
13570 (unspec:SI [(label_ref (match_operand 1))]
13572 (clobber (reg:CC FLAGS_REG))]
13574 "* return output_set_got (operands[0], operands[1]);"
13575 [(set_attr "type" "multi")
13576 (set_attr "length" "12")])
13578 (define_insn "set_got_rex64"
13579 [(set (match_operand:DI 0 "register_operand" "=r")
13580 (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
13582 "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}"
13583 [(set_attr "type" "lea")
13584 (set_attr "length_address" "4")
13585 (set_attr "modrm_class" "unknown")
13586 (set_attr "mode" "DI")])
13588 (define_insn "set_rip_rex64"
13589 [(set (match_operand:DI 0 "register_operand" "=r")
13590 (unspec:DI [(label_ref (match_operand 1))] UNSPEC_SET_RIP))]
13592 "lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}"
13593 [(set_attr "type" "lea")
13594 (set_attr "length_address" "4")
13595 (set_attr "mode" "DI")])
13597 (define_insn "set_got_offset_rex64"
13598 [(set (match_operand:DI 0 "register_operand" "=r")
13600 [(label_ref (match_operand 1))]
13601 UNSPEC_SET_GOT_OFFSET))]
13603 "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}"
13604 [(set_attr "type" "imov")
13605 (set_attr "length_immediate" "0")
13606 (set_attr "length_address" "8")
13607 (set_attr "mode" "DI")])
13609 (define_expand "epilogue"
13612 "ix86_expand_epilogue (1); DONE;")
13614 (define_expand "sibcall_epilogue"
13617 "ix86_expand_epilogue (0); DONE;")
13619 (define_expand "eh_return"
13620 [(use (match_operand 0 "register_operand"))]
13623 rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
13625 /* Tricky bit: we write the address of the handler to which we will
13626 be returning into someone else's stack frame, one word below the
13627 stack address we wish to restore. */
13628 tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
13629 tmp = plus_constant (Pmode, tmp, -UNITS_PER_WORD);
13630 tmp = gen_rtx_MEM (Pmode, tmp);
13631 emit_move_insn (tmp, ra);
13633 emit_jump_insn (gen_eh_return_internal ());
13638 (define_insn_and_split "eh_return_internal"
13642 "epilogue_completed"
13644 "ix86_expand_epilogue (2); DONE;")
13646 (define_insn "leave"
13647 [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
13648 (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
13649 (clobber (mem:BLK (scratch)))]
13652 [(set_attr "type" "leave")])
13654 (define_insn "leave_rex64"
13655 [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
13656 (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
13657 (clobber (mem:BLK (scratch)))]
13660 [(set_attr "type" "leave")])
13662 ;; Handle -fsplit-stack.
13664 (define_expand "split_stack_prologue"
13668 ix86_expand_split_stack_prologue ();
13672 ;; In order to support the call/return predictor, we use a return
13673 ;; instruction which the middle-end doesn't see.
13674 (define_insn "split_stack_return"
13675 [(unspec_volatile [(match_operand:SI 0 "const_int_operand")]
13676 UNSPECV_SPLIT_STACK_RETURN)]
13679 if (operands[0] == const0_rtx)
13684 [(set_attr "atom_unit" "jeu")
13685 (set_attr "modrm" "0")
13686 (set (attr "length")
13687 (if_then_else (match_operand:SI 0 "const0_operand")
13690 (set (attr "length_immediate")
13691 (if_then_else (match_operand:SI 0 "const0_operand")
13695 ;; If there are operand 0 bytes available on the stack, jump to
13698 (define_expand "split_stack_space_check"
13699 [(set (pc) (if_then_else
13700 (ltu (minus (reg SP_REG)
13701 (match_operand 0 "register_operand"))
13703 (label_ref (match_operand 1))
13707 rtx reg = gen_reg_rtx (Pmode);
13709 emit_insn (gen_sub3_insn (reg, stack_pointer_rtx, operands[0]));
13711 operands[2] = ix86_split_stack_guard ();
13712 ix86_expand_branch (GEU, reg, operands[2], operands[1]);
13717 ;; Bit manipulation instructions.
13719 (define_expand "ffs<mode>2"
13720 [(set (match_dup 2) (const_int -1))
13721 (parallel [(set (match_dup 3) (match_dup 4))
13722 (set (match_operand:SWI48 0 "register_operand")
13724 (match_operand:SWI48 1 "nonimmediate_operand")))])
13725 (set (match_dup 0) (if_then_else:SWI48
13726 (eq (match_dup 3) (const_int 0))
13729 (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (const_int 1)))
13730 (clobber (reg:CC FLAGS_REG))])]
13733 machine_mode flags_mode;
13735 if (<MODE>mode == SImode && !TARGET_CMOVE)
13737 emit_insn (gen_ffssi2_no_cmove (operands[0], operands [1]));
13741 flags_mode = TARGET_BMI ? CCCmode : CCZmode;
13743 operands[2] = gen_reg_rtx (<MODE>mode);
13744 operands[3] = gen_rtx_REG (flags_mode, FLAGS_REG);
13745 operands[4] = gen_rtx_COMPARE (flags_mode, operands[1], const0_rtx);
13748 (define_insn_and_split "ffssi2_no_cmove"
13749 [(set (match_operand:SI 0 "register_operand" "=r")
13750 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
13751 (clobber (match_scratch:SI 2 "=&q"))
13752 (clobber (reg:CC FLAGS_REG))]
13755 "&& reload_completed"
13756 [(parallel [(set (match_dup 4) (match_dup 5))
13757 (set (match_dup 0) (ctz:SI (match_dup 1)))])
13758 (set (strict_low_part (match_dup 3))
13759 (eq:QI (match_dup 4) (const_int 0)))
13760 (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
13761 (clobber (reg:CC FLAGS_REG))])
13762 (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
13763 (clobber (reg:CC FLAGS_REG))])
13764 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
13765 (clobber (reg:CC FLAGS_REG))])]
13767 machine_mode flags_mode = TARGET_BMI ? CCCmode : CCZmode;
13769 operands[3] = gen_lowpart (QImode, operands[2]);
13770 operands[4] = gen_rtx_REG (flags_mode, FLAGS_REG);
13771 operands[5] = gen_rtx_COMPARE (flags_mode, operands[1], const0_rtx);
13773 ix86_expand_clear (operands[2]);
13776 (define_insn_and_split "*tzcnt<mode>_1"
13777 [(set (reg:CCC FLAGS_REG)
13778 (compare:CCC (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13780 (set (match_operand:SWI48 0 "register_operand" "=r")
13781 (ctz:SWI48 (match_dup 1)))]
13783 "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
13784 "&& TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
13785 && optimize_function_for_speed_p (cfun)
13786 && !reg_mentioned_p (operands[0], operands[1])"
13788 [(set (reg:CCC FLAGS_REG)
13789 (compare:CCC (match_dup 1) (const_int 0)))
13791 (ctz:SWI48 (match_dup 1)))
13792 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)])]
13793 "ix86_expand_clear (operands[0]);"
13794 [(set_attr "type" "alu1")
13795 (set_attr "prefix_0f" "1")
13796 (set_attr "prefix_rep" "1")
13797 (set_attr "btver2_decode" "double")
13798 (set_attr "mode" "<MODE>")])
13800 ; False dependency happens when destination is only updated by tzcnt,
13801 ; lzcnt or popcnt. There is no false dependency when destination is
13802 ; also used in source.
13803 (define_insn "*tzcnt<mode>_1_falsedep"
13804 [(set (reg:CCC FLAGS_REG)
13805 (compare:CCC (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13807 (set (match_operand:SWI48 0 "register_operand" "=r")
13808 (ctz:SWI48 (match_dup 1)))
13809 (unspec [(match_operand:SWI48 2 "register_operand" "0")]
13810 UNSPEC_INSN_FALSE_DEP)]
13812 "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
13813 [(set_attr "type" "alu1")
13814 (set_attr "prefix_0f" "1")
13815 (set_attr "prefix_rep" "1")
13816 (set_attr "btver2_decode" "double")
13817 (set_attr "mode" "<MODE>")])
13819 (define_insn "*bsf<mode>_1"
13820 [(set (reg:CCZ FLAGS_REG)
13821 (compare:CCZ (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13823 (set (match_operand:SWI48 0 "register_operand" "=r")
13824 (ctz:SWI48 (match_dup 1)))]
13826 "bsf{<imodesuffix>}\t{%1, %0|%0, %1}"
13827 [(set_attr "type" "alu1")
13828 (set_attr "prefix_0f" "1")
13829 (set_attr "btver2_decode" "double")
13830 (set_attr "znver1_decode" "vector")
13831 (set_attr "mode" "<MODE>")])
13833 (define_insn_and_split "ctz<mode>2"
13834 [(set (match_operand:SWI48 0 "register_operand" "=r")
13836 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
13837 (clobber (reg:CC FLAGS_REG))]
13841 return "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
13842 else if (optimize_function_for_size_p (cfun))
13844 else if (TARGET_GENERIC)
13845 /* tzcnt expands to 'rep bsf' and we can use it even if !TARGET_BMI. */
13846 return "rep%; bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
13848 return "bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
13850 "(TARGET_BMI || TARGET_GENERIC)
13851 && TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
13852 && optimize_function_for_speed_p (cfun)
13853 && !reg_mentioned_p (operands[0], operands[1])"
13855 [(set (match_dup 0)
13856 (ctz:SWI48 (match_dup 1)))
13857 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
13858 (clobber (reg:CC FLAGS_REG))])]
13859 "ix86_expand_clear (operands[0]);"
13860 [(set_attr "type" "alu1")
13861 (set_attr "prefix_0f" "1")
13862 (set (attr "prefix_rep")
13864 (ior (match_test "TARGET_BMI")
13865 (and (not (match_test "optimize_function_for_size_p (cfun)"))
13866 (match_test "TARGET_GENERIC")))
13868 (const_string "0")))
13869 (set_attr "mode" "<MODE>")])
13871 ; False dependency happens when destination is only updated by tzcnt,
13872 ; lzcnt or popcnt. There is no false dependency when destination is
13873 ; also used in source.
13874 (define_insn "*ctz<mode>2_falsedep"
13875 [(set (match_operand:SWI48 0 "register_operand" "=r")
13877 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
13878 (unspec [(match_operand:SWI48 2 "register_operand" "0")]
13879 UNSPEC_INSN_FALSE_DEP)
13880 (clobber (reg:CC FLAGS_REG))]
13884 return "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
13885 else if (TARGET_GENERIC)
13886 /* tzcnt expands to 'rep bsf' and we can use it even if !TARGET_BMI. */
13887 return "rep%; bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
13889 gcc_unreachable ();
13891 [(set_attr "type" "alu1")
13892 (set_attr "prefix_0f" "1")
13893 (set_attr "prefix_rep" "1")
13894 (set_attr "mode" "<MODE>")])
13896 (define_insn "bsr_rex64"
13897 [(set (match_operand:DI 0 "register_operand" "=r")
13898 (minus:DI (const_int 63)
13899 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
13900 (clobber (reg:CC FLAGS_REG))]
13902 "bsr{q}\t{%1, %0|%0, %1}"
13903 [(set_attr "type" "alu1")
13904 (set_attr "prefix_0f" "1")
13905 (set_attr "znver1_decode" "vector")
13906 (set_attr "mode" "DI")])
13909 [(set (match_operand:SI 0 "register_operand" "=r")
13910 (minus:SI (const_int 31)
13911 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
13912 (clobber (reg:CC FLAGS_REG))]
13914 "bsr{l}\t{%1, %0|%0, %1}"
13915 [(set_attr "type" "alu1")
13916 (set_attr "prefix_0f" "1")
13917 (set_attr "znver1_decode" "vector")
13918 (set_attr "mode" "SI")])
13920 (define_insn "*bsrhi"
13921 [(set (match_operand:HI 0 "register_operand" "=r")
13922 (minus:HI (const_int 15)
13923 (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
13924 (clobber (reg:CC FLAGS_REG))]
13926 "bsr{w}\t{%1, %0|%0, %1}"
13927 [(set_attr "type" "alu1")
13928 (set_attr "prefix_0f" "1")
13929 (set_attr "znver1_decode" "vector")
13930 (set_attr "mode" "HI")])
13932 (define_expand "clz<mode>2"
13934 [(set (match_operand:SWI48 0 "register_operand")
13937 (clz:SWI48 (match_operand:SWI48 1 "nonimmediate_operand"))))
13938 (clobber (reg:CC FLAGS_REG))])
13940 [(set (match_dup 0) (xor:SWI48 (match_dup 0) (match_dup 2)))
13941 (clobber (reg:CC FLAGS_REG))])]
13946 emit_insn (gen_clz<mode>2_lzcnt (operands[0], operands[1]));
13949 operands[2] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
13952 (define_insn_and_split "clz<mode>2_lzcnt"
13953 [(set (match_operand:SWI48 0 "register_operand" "=r")
13955 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
13956 (clobber (reg:CC FLAGS_REG))]
13958 "lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
13959 "&& TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
13960 && optimize_function_for_speed_p (cfun)
13961 && !reg_mentioned_p (operands[0], operands[1])"
13963 [(set (match_dup 0)
13964 (clz:SWI48 (match_dup 1)))
13965 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
13966 (clobber (reg:CC FLAGS_REG))])]
13967 "ix86_expand_clear (operands[0]);"
13968 [(set_attr "prefix_rep" "1")
13969 (set_attr "type" "bitmanip")
13970 (set_attr "mode" "<MODE>")])
13972 ; False dependency happens when destination is only updated by tzcnt,
13973 ; lzcnt or popcnt. There is no false dependency when destination is
13974 ; also used in source.
13975 (define_insn "*clz<mode>2_lzcnt_falsedep"
13976 [(set (match_operand:SWI48 0 "register_operand" "=r")
13978 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
13979 (unspec [(match_operand:SWI48 2 "register_operand" "0")]
13980 UNSPEC_INSN_FALSE_DEP)
13981 (clobber (reg:CC FLAGS_REG))]
13983 "lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
13984 [(set_attr "prefix_rep" "1")
13985 (set_attr "type" "bitmanip")
13986 (set_attr "mode" "<MODE>")])
13988 (define_int_iterator LT_ZCNT
13989 [(UNSPEC_TZCNT "TARGET_BMI")
13990 (UNSPEC_LZCNT "TARGET_LZCNT")])
13992 (define_int_attr lt_zcnt
13993 [(UNSPEC_TZCNT "tzcnt")
13994 (UNSPEC_LZCNT "lzcnt")])
13996 (define_int_attr lt_zcnt_type
13997 [(UNSPEC_TZCNT "alu1")
13998 (UNSPEC_LZCNT "bitmanip")])
14000 ;; Version of lzcnt/tzcnt that is expanded from intrinsics. This version
14001 ;; provides operand size as output when source operand is zero.
14003 (define_insn_and_split "<lt_zcnt>_<mode>"
14004 [(set (match_operand:SWI48 0 "register_operand" "=r")
14006 [(match_operand:SWI48 1 "nonimmediate_operand" "rm")] LT_ZCNT))
14007 (clobber (reg:CC FLAGS_REG))]
14009 "<lt_zcnt>{<imodesuffix>}\t{%1, %0|%0, %1}"
14010 "&& TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
14011 && optimize_function_for_speed_p (cfun)
14012 && !reg_mentioned_p (operands[0], operands[1])"
14014 [(set (match_dup 0)
14015 (unspec:SWI48 [(match_dup 1)] LT_ZCNT))
14016 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
14017 (clobber (reg:CC FLAGS_REG))])]
14018 "ix86_expand_clear (operands[0]);"
14019 [(set_attr "type" "<lt_zcnt_type>")
14020 (set_attr "prefix_0f" "1")
14021 (set_attr "prefix_rep" "1")
14022 (set_attr "mode" "<MODE>")])
14024 ; False dependency happens when destination is only updated by tzcnt,
14025 ; lzcnt or popcnt. There is no false dependency when destination is
14026 ; also used in source.
14027 (define_insn "*<lt_zcnt>_<mode>_falsedep"
14028 [(set (match_operand:SWI48 0 "register_operand" "=r")
14030 [(match_operand:SWI48 1 "nonimmediate_operand" "rm")] LT_ZCNT))
14031 (unspec [(match_operand:SWI48 2 "register_operand" "0")]
14032 UNSPEC_INSN_FALSE_DEP)
14033 (clobber (reg:CC FLAGS_REG))]
14035 "<lt_zcnt>{<imodesuffix>}\t{%1, %0|%0, %1}"
14036 [(set_attr "type" "<lt_zcnt_type>")
14037 (set_attr "prefix_0f" "1")
14038 (set_attr "prefix_rep" "1")
14039 (set_attr "mode" "<MODE>")])
14041 (define_insn "<lt_zcnt>_hi"
14042 [(set (match_operand:HI 0 "register_operand" "=r")
14044 [(match_operand:HI 1 "nonimmediate_operand" "rm")] LT_ZCNT))
14045 (clobber (reg:CC FLAGS_REG))]
14047 "<lt_zcnt>{w}\t{%1, %0|%0, %1}"
14048 [(set_attr "type" "<lt_zcnt_type>")
14049 (set_attr "prefix_0f" "1")
14050 (set_attr "prefix_rep" "1")
14051 (set_attr "mode" "HI")])
14053 ;; BMI instructions.
14055 (define_insn "bmi_bextr_<mode>"
14056 [(set (match_operand:SWI48 0 "register_operand" "=r,r")
14057 (unspec:SWI48 [(match_operand:SWI48 1 "nonimmediate_operand" "r,m")
14058 (match_operand:SWI48 2 "register_operand" "r,r")]
14060 (clobber (reg:CC FLAGS_REG))]
14062 "bextr\t{%2, %1, %0|%0, %1, %2}"
14063 [(set_attr "type" "bitmanip")
14064 (set_attr "btver2_decode" "direct, double")
14065 (set_attr "mode" "<MODE>")])
14067 (define_insn "*bmi_bextr_<mode>_ccz"
14068 [(set (reg:CCZ FLAGS_REG)
14070 (unspec:SWI48 [(match_operand:SWI48 1 "nonimmediate_operand" "r,m")
14071 (match_operand:SWI48 2 "register_operand" "r,r")]
14074 (clobber (match_scratch:SWI48 0 "=r,r"))]
14076 "bextr\t{%2, %1, %0|%0, %1, %2}"
14077 [(set_attr "type" "bitmanip")
14078 (set_attr "btver2_decode" "direct, double")
14079 (set_attr "mode" "<MODE>")])
14081 (define_insn "*bmi_blsi_<mode>"
14082 [(set (match_operand:SWI48 0 "register_operand" "=r")
14085 (match_operand:SWI48 1 "nonimmediate_operand" "rm"))
14087 (clobber (reg:CC FLAGS_REG))]
14089 "blsi\t{%1, %0|%0, %1}"
14090 [(set_attr "type" "bitmanip")
14091 (set_attr "btver2_decode" "double")
14092 (set_attr "mode" "<MODE>")])
14094 (define_insn "*bmi_blsmsk_<mode>"
14095 [(set (match_operand:SWI48 0 "register_operand" "=r")
14098 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
14101 (clobber (reg:CC FLAGS_REG))]
14103 "blsmsk\t{%1, %0|%0, %1}"
14104 [(set_attr "type" "bitmanip")
14105 (set_attr "btver2_decode" "double")
14106 (set_attr "mode" "<MODE>")])
14108 (define_insn "*bmi_blsr_<mode>"
14109 [(set (match_operand:SWI48 0 "register_operand" "=r")
14112 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
14115 (clobber (reg:CC FLAGS_REG))]
14117 "blsr\t{%1, %0|%0, %1}"
14118 [(set_attr "type" "bitmanip")
14119 (set_attr "btver2_decode" "double")
14120 (set_attr "mode" "<MODE>")])
14122 (define_insn "*bmi_blsr_<mode>_cmp"
14123 [(set (reg:CCZ FLAGS_REG)
14127 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
14131 (set (match_operand:SWI48 0 "register_operand" "=r")
14138 "blsr\t{%1, %0|%0, %1}"
14139 [(set_attr "type" "bitmanip")
14140 (set_attr "btver2_decode" "double")
14141 (set_attr "mode" "<MODE>")])
14143 (define_insn "*bmi_blsr_<mode>_ccz"
14144 [(set (reg:CCZ FLAGS_REG)
14148 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
14152 (clobber (match_scratch:SWI48 0 "=r"))]
14154 "blsr\t{%1, %0|%0, %1}"
14155 [(set_attr "type" "bitmanip")
14156 (set_attr "btver2_decode" "double")
14157 (set_attr "mode" "<MODE>")])
14159 ;; BMI2 instructions.
14160 (define_expand "bmi2_bzhi_<mode>3"
14162 [(set (match_operand:SWI48 0 "register_operand")
14163 (zero_extract:SWI48
14164 (match_operand:SWI48 1 "nonimmediate_operand")
14166 (and:SWI48 (match_operand:SWI48 2 "register_operand")
14170 (clobber (reg:CC FLAGS_REG))])]
14172 "operands[3] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT);")
14174 (define_insn "*bmi2_bzhi_<mode>3"
14175 [(set (match_operand:SWI48 0 "register_operand" "=r")
14176 (zero_extract:SWI48
14177 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
14179 (and:SWI48 (match_operand:SWI48 2 "register_operand" "r")
14181 (match_operand:SWI48 3 "const_int_operand" "n"))
14183 (clobber (reg:CC FLAGS_REG))]
14184 "TARGET_BMI2 && INTVAL (operands[3]) == <MODE_SIZE> * BITS_PER_UNIT"
14185 "bzhi\t{%2, %1, %0|%0, %1, %2}"
14186 [(set_attr "type" "bitmanip")
14187 (set_attr "prefix" "vex")
14188 (set_attr "mode" "<MODE>")])
14190 (define_insn "*bmi2_bzhi_<mode>3_1"
14191 [(set (match_operand:SWI48 0 "register_operand" "=r")
14192 (zero_extract:SWI48
14193 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
14195 (zero_extend:SWI48 (match_operand:QI 2 "register_operand" "r"))
14196 (match_operand:SWI48 3 "const_int_operand" "n"))
14198 (clobber (reg:CC FLAGS_REG))]
14199 "TARGET_BMI2 && INTVAL (operands[3]) == <MODE_SIZE> * BITS_PER_UNIT"
14200 "bzhi\t{%<k>2, %1, %0|%0, %1, %<k>2}"
14201 [(set_attr "type" "bitmanip")
14202 (set_attr "prefix" "vex")
14203 (set_attr "mode" "<MODE>")])
14205 (define_insn "*bmi2_bzhi_<mode>3_1_ccz"
14206 [(set (reg:CCZ FLAGS_REG)
14208 (zero_extract:SWI48
14209 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
14211 (zero_extend:SWI48 (match_operand:QI 2 "register_operand" "r"))
14212 (match_operand:SWI48 3 "const_int_operand" "n"))
14215 (clobber (match_scratch:SWI48 0 "=r"))]
14216 "TARGET_BMI2 && INTVAL (operands[3]) == <MODE_SIZE> * BITS_PER_UNIT"
14217 "bzhi\t{%<k>2, %1, %0|%0, %1, %<k>2}"
14218 [(set_attr "type" "bitmanip")
14219 (set_attr "prefix" "vex")
14220 (set_attr "mode" "<MODE>")])
14222 (define_insn "bmi2_pdep_<mode>3"
14223 [(set (match_operand:SWI48 0 "register_operand" "=r")
14224 (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
14225 (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
14228 "pdep\t{%2, %1, %0|%0, %1, %2}"
14229 [(set_attr "type" "bitmanip")
14230 (set_attr "prefix" "vex")
14231 (set_attr "mode" "<MODE>")])
14233 (define_insn "bmi2_pext_<mode>3"
14234 [(set (match_operand:SWI48 0 "register_operand" "=r")
14235 (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
14236 (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
14239 "pext\t{%2, %1, %0|%0, %1, %2}"
14240 [(set_attr "type" "bitmanip")
14241 (set_attr "prefix" "vex")
14242 (set_attr "mode" "<MODE>")])
14244 ;; TBM instructions.
14245 (define_insn "tbm_bextri_<mode>"
14246 [(set (match_operand:SWI48 0 "register_operand" "=r")
14247 (zero_extract:SWI48
14248 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
14249 (match_operand 2 "const_0_to_255_operand" "N")
14250 (match_operand 3 "const_0_to_255_operand" "N")))
14251 (clobber (reg:CC FLAGS_REG))]
14254 operands[2] = GEN_INT (INTVAL (operands[2]) << 8 | INTVAL (operands[3]));
14255 return "bextr\t{%2, %1, %0|%0, %1, %2}";
14257 [(set_attr "type" "bitmanip")
14258 (set_attr "mode" "<MODE>")])
14260 (define_insn "*tbm_blcfill_<mode>"
14261 [(set (match_operand:SWI48 0 "register_operand" "=r")
14264 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
14267 (clobber (reg:CC FLAGS_REG))]
14269 "blcfill\t{%1, %0|%0, %1}"
14270 [(set_attr "type" "bitmanip")
14271 (set_attr "mode" "<MODE>")])
14273 (define_insn "*tbm_blci_<mode>"
14274 [(set (match_operand:SWI48 0 "register_operand" "=r")
14278 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
14281 (clobber (reg:CC FLAGS_REG))]
14283 "blci\t{%1, %0|%0, %1}"
14284 [(set_attr "type" "bitmanip")
14285 (set_attr "mode" "<MODE>")])
14287 (define_insn "*tbm_blcic_<mode>"
14288 [(set (match_operand:SWI48 0 "register_operand" "=r")
14291 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
14295 (clobber (reg:CC FLAGS_REG))]
14297 "blcic\t{%1, %0|%0, %1}"
14298 [(set_attr "type" "bitmanip")
14299 (set_attr "mode" "<MODE>")])
14301 (define_insn "*tbm_blcmsk_<mode>"
14302 [(set (match_operand:SWI48 0 "register_operand" "=r")
14305 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
14308 (clobber (reg:CC FLAGS_REG))]
14310 "blcmsk\t{%1, %0|%0, %1}"
14311 [(set_attr "type" "bitmanip")
14312 (set_attr "mode" "<MODE>")])
14314 (define_insn "*tbm_blcs_<mode>"
14315 [(set (match_operand:SWI48 0 "register_operand" "=r")
14318 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
14321 (clobber (reg:CC FLAGS_REG))]
14323 "blcs\t{%1, %0|%0, %1}"
14324 [(set_attr "type" "bitmanip")
14325 (set_attr "mode" "<MODE>")])
14327 (define_insn "*tbm_blsfill_<mode>"
14328 [(set (match_operand:SWI48 0 "register_operand" "=r")
14331 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
14334 (clobber (reg:CC FLAGS_REG))]
14336 "blsfill\t{%1, %0|%0, %1}"
14337 [(set_attr "type" "bitmanip")
14338 (set_attr "mode" "<MODE>")])
14340 (define_insn "*tbm_blsic_<mode>"
14341 [(set (match_operand:SWI48 0 "register_operand" "=r")
14344 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
14348 (clobber (reg:CC FLAGS_REG))]
14350 "blsic\t{%1, %0|%0, %1}"
14351 [(set_attr "type" "bitmanip")
14352 (set_attr "mode" "<MODE>")])
14354 (define_insn "*tbm_t1mskc_<mode>"
14355 [(set (match_operand:SWI48 0 "register_operand" "=r")
14358 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
14362 (clobber (reg:CC FLAGS_REG))]
14364 "t1mskc\t{%1, %0|%0, %1}"
14365 [(set_attr "type" "bitmanip")
14366 (set_attr "mode" "<MODE>")])
14368 (define_insn "*tbm_tzmsk_<mode>"
14369 [(set (match_operand:SWI48 0 "register_operand" "=r")
14372 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
14376 (clobber (reg:CC FLAGS_REG))]
14378 "tzmsk\t{%1, %0|%0, %1}"
14379 [(set_attr "type" "bitmanip")
14380 (set_attr "mode" "<MODE>")])
14382 (define_insn_and_split "popcount<mode>2"
14383 [(set (match_operand:SWI48 0 "register_operand" "=r")
14385 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
14386 (clobber (reg:CC FLAGS_REG))]
14390 return "popcnt\t{%1, %0|%0, %1}";
14392 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
14395 "&& TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
14396 && optimize_function_for_speed_p (cfun)
14397 && !reg_mentioned_p (operands[0], operands[1])"
14399 [(set (match_dup 0)
14400 (popcount:SWI48 (match_dup 1)))
14401 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
14402 (clobber (reg:CC FLAGS_REG))])]
14403 "ix86_expand_clear (operands[0]);"
14404 [(set_attr "prefix_rep" "1")
14405 (set_attr "type" "bitmanip")
14406 (set_attr "mode" "<MODE>")])
14408 ; False dependency happens when destination is only updated by tzcnt,
14409 ; lzcnt or popcnt. There is no false dependency when destination is
14410 ; also used in source.
14411 (define_insn "*popcount<mode>2_falsedep"
14412 [(set (match_operand:SWI48 0 "register_operand" "=r")
14414 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
14415 (unspec [(match_operand:SWI48 2 "register_operand" "0")]
14416 UNSPEC_INSN_FALSE_DEP)
14417 (clobber (reg:CC FLAGS_REG))]
14421 return "popcnt\t{%1, %0|%0, %1}";
14423 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
14426 [(set_attr "prefix_rep" "1")
14427 (set_attr "type" "bitmanip")
14428 (set_attr "mode" "<MODE>")])
14430 (define_insn_and_split "*popcounthi2_1"
14431 [(set (match_operand:SI 0 "register_operand")
14433 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand"))))
14434 (clobber (reg:CC FLAGS_REG))]
14436 && can_create_pseudo_p ()"
14441 rtx tmp = gen_reg_rtx (HImode);
14443 emit_insn (gen_popcounthi2 (tmp, operands[1]));
14444 emit_insn (gen_zero_extendhisi2 (operands[0], tmp));
14448 (define_insn "popcounthi2"
14449 [(set (match_operand:HI 0 "register_operand" "=r")
14451 (match_operand:HI 1 "nonimmediate_operand" "rm")))
14452 (clobber (reg:CC FLAGS_REG))]
14456 return "popcnt\t{%1, %0|%0, %1}";
14458 return "popcnt{w}\t{%1, %0|%0, %1}";
14461 [(set_attr "prefix_rep" "1")
14462 (set_attr "type" "bitmanip")
14463 (set_attr "mode" "HI")])
14465 (define_expand "bswapdi2"
14466 [(set (match_operand:DI 0 "register_operand")
14467 (bswap:DI (match_operand:DI 1 "nonimmediate_operand")))]
14471 operands[1] = force_reg (DImode, operands[1]);
14474 (define_expand "bswapsi2"
14475 [(set (match_operand:SI 0 "register_operand")
14476 (bswap:SI (match_operand:SI 1 "nonimmediate_operand")))]
14481 else if (TARGET_BSWAP)
14482 operands[1] = force_reg (SImode, operands[1]);
14485 rtx x = operands[0];
14487 emit_move_insn (x, operands[1]);
14488 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
14489 emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
14490 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
14495 (define_insn "*bswap<mode>2_movbe"
14496 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,r,m")
14497 (bswap:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,m,r")))]
14499 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
14502 movbe{<imodesuffix>}\t{%1, %0|%0, %1}
14503 movbe{<imodesuffix>}\t{%1, %0|%0, %1}"
14504 [(set_attr "type" "bitmanip,imov,imov")
14505 (set_attr "modrm" "0,1,1")
14506 (set_attr "prefix_0f" "*,1,1")
14507 (set_attr "prefix_extra" "*,1,1")
14508 (set_attr "mode" "<MODE>")])
14510 (define_insn "*bswap<mode>2"
14511 [(set (match_operand:SWI48 0 "register_operand" "=r")
14512 (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "0")))]
14515 [(set_attr "type" "bitmanip")
14516 (set_attr "modrm" "0")
14517 (set_attr "mode" "<MODE>")])
14519 (define_expand "bswaphi2"
14520 [(set (match_operand:HI 0 "register_operand")
14521 (bswap:HI (match_operand:HI 1 "nonimmediate_operand")))]
14524 (define_insn "*bswaphi2_movbe"
14525 [(set (match_operand:HI 0 "nonimmediate_operand" "=Q,r,m")
14526 (bswap:HI (match_operand:HI 1 "nonimmediate_operand" "0,m,r")))]
14528 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
14530 xchg{b}\t{%h0, %b0|%b0, %h0}
14531 movbe{w}\t{%1, %0|%0, %1}
14532 movbe{w}\t{%1, %0|%0, %1}"
14533 [(set_attr "type" "imov")
14534 (set_attr "modrm" "*,1,1")
14535 (set_attr "prefix_0f" "*,1,1")
14536 (set_attr "prefix_extra" "*,1,1")
14537 (set_attr "pent_pair" "np,*,*")
14538 (set_attr "athlon_decode" "vector,*,*")
14539 (set_attr "amdfam10_decode" "double,*,*")
14540 (set_attr "bdver1_decode" "double,*,*")
14541 (set_attr "mode" "QI,HI,HI")])
14544 [(set (match_operand:HI 0 "general_reg_operand")
14545 (bswap:HI (match_dup 0)))]
14547 && !(TARGET_USE_XCHGB || optimize_function_for_size_p (cfun))
14548 && peep2_regno_dead_p (0, FLAGS_REG)"
14549 [(parallel [(set (match_dup 0) (rotate:HI (match_dup 0) (const_int 8)))
14550 (clobber (reg:CC FLAGS_REG))])])
14552 (define_insn "bswaphi_lowpart"
14553 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
14554 (bswap:HI (match_dup 0)))
14555 (clobber (reg:CC FLAGS_REG))]
14558 xchg{b}\t{%h0, %b0|%b0, %h0}
14559 rol{w}\t{$8, %0|%0, 8}"
14560 [(set (attr "preferred_for_size")
14561 (cond [(eq_attr "alternative" "0")
14562 (symbol_ref "true")]
14563 (symbol_ref "false")))
14564 (set (attr "preferred_for_speed")
14565 (cond [(eq_attr "alternative" "0")
14566 (symbol_ref "TARGET_USE_XCHGB")]
14567 (symbol_ref "!TARGET_USE_XCHGB")))
14568 (set_attr "length" "2,4")
14569 (set_attr "mode" "QI,HI")])
14571 (define_expand "paritydi2"
14572 [(set (match_operand:DI 0 "register_operand")
14573 (parity:DI (match_operand:DI 1 "register_operand")))]
14576 rtx scratch = gen_reg_rtx (QImode);
14578 emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX,
14579 NULL_RTX, operands[1]));
14581 ix86_expand_setcc (scratch, ORDERED,
14582 gen_rtx_REG (CCmode, FLAGS_REG), const0_rtx);
14585 emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
14588 rtx tmp = gen_reg_rtx (SImode);
14590 emit_insn (gen_zero_extendqisi2 (tmp, scratch));
14591 emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
14596 (define_expand "paritysi2"
14597 [(set (match_operand:SI 0 "register_operand")
14598 (parity:SI (match_operand:SI 1 "register_operand")))]
14601 rtx scratch = gen_reg_rtx (QImode);
14603 emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1]));
14605 ix86_expand_setcc (scratch, ORDERED,
14606 gen_rtx_REG (CCmode, FLAGS_REG), const0_rtx);
14608 emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
14612 (define_insn_and_split "paritydi2_cmp"
14613 [(set (reg:CC FLAGS_REG)
14614 (unspec:CC [(match_operand:DI 3 "register_operand" "0")]
14616 (clobber (match_scratch:DI 0 "=r"))
14617 (clobber (match_scratch:SI 1 "=&r"))
14618 (clobber (match_scratch:HI 2 "=Q"))]
14621 "&& reload_completed"
14623 [(set (match_dup 1)
14624 (xor:SI (match_dup 1) (match_dup 4)))
14625 (clobber (reg:CC FLAGS_REG))])
14627 [(set (reg:CC FLAGS_REG)
14628 (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
14629 (clobber (match_dup 1))
14630 (clobber (match_dup 2))])]
14632 operands[4] = gen_lowpart (SImode, operands[3]);
14636 emit_move_insn (operands[1], gen_lowpart (SImode, operands[3]));
14637 emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32)));
14640 operands[1] = gen_highpart (SImode, operands[3]);
14643 (define_insn_and_split "paritysi2_cmp"
14644 [(set (reg:CC FLAGS_REG)
14645 (unspec:CC [(match_operand:SI 2 "register_operand" "0")]
14647 (clobber (match_scratch:SI 0 "=r"))
14648 (clobber (match_scratch:HI 1 "=&Q"))]
14651 "&& reload_completed"
14653 [(set (match_dup 1)
14654 (xor:HI (match_dup 1) (match_dup 3)))
14655 (clobber (reg:CC FLAGS_REG))])
14657 [(set (reg:CC FLAGS_REG)
14658 (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
14659 (clobber (match_dup 1))])]
14661 operands[3] = gen_lowpart (HImode, operands[2]);
14663 emit_move_insn (operands[1], gen_lowpart (HImode, operands[2]));
14664 emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16)));
14667 (define_insn "*parityhi2_cmp"
14668 [(set (reg:CC FLAGS_REG)
14669 (unspec:CC [(match_operand:HI 1 "register_operand" "0")]
14671 (clobber (match_scratch:HI 0 "=Q"))]
14673 "xor{b}\t{%h0, %b0|%b0, %h0}"
14674 [(set_attr "length" "2")
14675 (set_attr "mode" "HI")])
14678 ;; Thread-local storage patterns for ELF.
14680 ;; Note that these code sequences must appear exactly as shown
14681 ;; in order to allow linker relaxation.
14683 (define_insn "*tls_global_dynamic_32_gnu"
14684 [(set (match_operand:SI 0 "register_operand" "=a")
14686 [(match_operand:SI 1 "register_operand" "Yb")
14687 (match_operand 2 "tls_symbolic_operand")
14688 (match_operand 3 "constant_call_address_operand" "Bz")
14691 (clobber (match_scratch:SI 4 "=d"))
14692 (clobber (match_scratch:SI 5 "=c"))
14693 (clobber (reg:CC FLAGS_REG))]
14694 "!TARGET_64BIT && TARGET_GNU_TLS"
14696 if (TARGET_SUN_TLS || flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT)
14698 ("lea{l}\t{%E2@tlsgd(,%1,1), %0|%0, %E2@tlsgd[%1*1]}", operands);
14701 ("lea{l}\t{%E2@tlsgd(%1), %0|%0, %E2@tlsgd[%1]}", operands);
14702 if (TARGET_SUN_TLS)
14703 #ifdef HAVE_AS_IX86_TLSGDPLT
14704 return "call\t%a2@tlsgdplt";
14706 return "call\t%p3@plt";
14708 if (flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT)
14709 return "call\t%P3";
14710 return "call\t{*%p3@GOT(%1)|[DWORD PTR %p3@GOT[%1]]}";
14712 [(set_attr "type" "multi")
14713 (set_attr "length" "12")])
14715 (define_expand "tls_global_dynamic_32"
14717 [(set (match_operand:SI 0 "register_operand")
14718 (unspec:SI [(match_operand:SI 2 "register_operand")
14719 (match_operand 1 "tls_symbolic_operand")
14720 (match_operand 3 "constant_call_address_operand")
14723 (clobber (match_scratch:SI 4))
14724 (clobber (match_scratch:SI 5))
14725 (clobber (reg:CC FLAGS_REG))])]
14727 "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
14729 (define_insn "*tls_global_dynamic_64_<mode>"
14730 [(set (match_operand:P 0 "register_operand" "=a")
14732 (mem:QI (match_operand 2 "constant_call_address_operand" "Bz"))
14733 (match_operand 3)))
14734 (unspec:P [(match_operand 1 "tls_symbolic_operand")
14740 /* The .loc directive has effect for 'the immediately following assembly
14741 instruction'. So for a sequence:
14745 the 'immediately following assembly instruction' is insn1.
14746 We want to emit an insn prefix here, but if we use .byte (as shown in
14747 'ELF Handling For Thread-Local Storage'), a preceding .loc will point
14748 inside the insn sequence, rather than to the start. After relaxation
14749 of the sequence by the linker, the .loc might point inside an insn.
14750 Use data16 prefix instead, which doesn't have this problem. */
14751 fputs ("\tdata16", asm_out_file);
14753 ("lea{q}\t{%E1@tlsgd(%%rip), %%rdi|rdi, %E1@tlsgd[rip]}", operands);
14754 if (TARGET_SUN_TLS || flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT)
14755 fputs (ASM_SHORT "0x6666\n", asm_out_file);
14757 fputs (ASM_BYTE "0x66\n", asm_out_file);
14758 fputs ("\trex64\n", asm_out_file);
14759 if (TARGET_SUN_TLS)
14760 return "call\t%p2@plt";
14761 if (flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT)
14762 return "call\t%P2";
14763 return "call\t{*%p2@GOTPCREL(%%rip)|[QWORD PTR %p2@GOTPCREL[rip]]}";
14765 [(set_attr "type" "multi")
14766 (set (attr "length")
14767 (symbol_ref "TARGET_X32 ? 15 : 16"))])
14769 (define_insn "*tls_global_dynamic_64_largepic"
14770 [(set (match_operand:DI 0 "register_operand" "=a")
14772 (mem:QI (plus:DI (match_operand:DI 2 "register_operand" "b")
14773 (match_operand:DI 3 "immediate_operand" "i")))
14774 (match_operand 4)))
14775 (unspec:DI [(match_operand 1 "tls_symbolic_operand")
14778 "TARGET_64BIT && ix86_cmodel == CM_LARGE_PIC && !TARGET_PECOFF
14779 && GET_CODE (operands[3]) == CONST
14780 && GET_CODE (XEXP (operands[3], 0)) == UNSPEC
14781 && XINT (XEXP (operands[3], 0), 1) == UNSPEC_PLTOFF"
14784 ("lea{q}\t{%E1@tlsgd(%%rip), %%rdi|rdi, %E1@tlsgd[rip]}", operands);
14785 output_asm_insn ("movabs{q}\t{%3, %%rax|rax, %3}", operands);
14786 output_asm_insn ("add{q}\t{%2, %%rax|rax, %2}", operands);
14787 return "call\t{*%%rax|rax}";
14789 [(set_attr "type" "multi")
14790 (set_attr "length" "22")])
14792 (define_expand "tls_global_dynamic_64_<mode>"
14794 [(set (match_operand:P 0 "register_operand")
14796 (mem:QI (match_operand 2))
14798 (unspec:P [(match_operand 1 "tls_symbolic_operand")
14802 "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
14804 (define_insn "*tls_local_dynamic_base_32_gnu"
14805 [(set (match_operand:SI 0 "register_operand" "=a")
14807 [(match_operand:SI 1 "register_operand" "Yb")
14808 (match_operand 2 "constant_call_address_operand" "Bz")
14810 UNSPEC_TLS_LD_BASE))
14811 (clobber (match_scratch:SI 3 "=d"))
14812 (clobber (match_scratch:SI 4 "=c"))
14813 (clobber (reg:CC FLAGS_REG))]
14814 "!TARGET_64BIT && TARGET_GNU_TLS"
14817 ("lea{l}\t{%&@tlsldm(%1), %0|%0, %&@tlsldm[%1]}", operands);
14818 if (TARGET_SUN_TLS)
14820 if (HAVE_AS_IX86_TLSLDMPLT)
14821 return "call\t%&@tlsldmplt";
14823 return "call\t%p2@plt";
14825 if (flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT)
14826 return "call\t%P2";
14827 return "call\t{*%p2@GOT(%1)|[DWORD PTR %p2@GOT[%1]]}";
14829 [(set_attr "type" "multi")
14830 (set_attr "length" "11")])
14832 (define_expand "tls_local_dynamic_base_32"
14834 [(set (match_operand:SI 0 "register_operand")
14836 [(match_operand:SI 1 "register_operand")
14837 (match_operand 2 "constant_call_address_operand")
14839 UNSPEC_TLS_LD_BASE))
14840 (clobber (match_scratch:SI 3))
14841 (clobber (match_scratch:SI 4))
14842 (clobber (reg:CC FLAGS_REG))])]
14844 "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
14846 (define_insn "*tls_local_dynamic_base_64_<mode>"
14847 [(set (match_operand:P 0 "register_operand" "=a")
14849 (mem:QI (match_operand 1 "constant_call_address_operand" "Bz"))
14850 (match_operand 2)))
14851 (unspec:P [(reg:P SP_REG)] UNSPEC_TLS_LD_BASE)]
14855 ("lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}", operands);
14856 if (TARGET_SUN_TLS)
14857 return "call\t%p1@plt";
14858 if (flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT)
14859 return "call\t%P1";
14860 return "call\t{*%p1@GOTPCREL(%%rip)|[QWORD PTR %p1@GOTPCREL[rip]]}";
14862 [(set_attr "type" "multi")
14863 (set_attr "length" "12")])
14865 (define_insn "*tls_local_dynamic_base_64_largepic"
14866 [(set (match_operand:DI 0 "register_operand" "=a")
14868 (mem:QI (plus:DI (match_operand:DI 1 "register_operand" "b")
14869 (match_operand:DI 2 "immediate_operand" "i")))
14870 (match_operand 3)))
14871 (unspec:DI [(reg:DI SP_REG)] UNSPEC_TLS_LD_BASE)]
14872 "TARGET_64BIT && ix86_cmodel == CM_LARGE_PIC && !TARGET_PECOFF
14873 && GET_CODE (operands[2]) == CONST
14874 && GET_CODE (XEXP (operands[2], 0)) == UNSPEC
14875 && XINT (XEXP (operands[2], 0), 1) == UNSPEC_PLTOFF"
14878 ("lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}", operands);
14879 output_asm_insn ("movabs{q}\t{%2, %%rax|rax, %2}", operands);
14880 output_asm_insn ("add{q}\t{%1, %%rax|rax, %1}", operands);
14881 return "call\t{*%%rax|rax}";
14883 [(set_attr "type" "multi")
14884 (set_attr "length" "22")])
14886 (define_expand "tls_local_dynamic_base_64_<mode>"
14888 [(set (match_operand:P 0 "register_operand")
14890 (mem:QI (match_operand 1))
14892 (unspec:P [(reg:P SP_REG)] UNSPEC_TLS_LD_BASE)])]
14894 "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
14896 ;; Local dynamic of a single variable is a lose. Show combine how
14897 ;; to convert that back to global dynamic.
14899 (define_insn_and_split "*tls_local_dynamic_32_once"
14900 [(set (match_operand:SI 0 "register_operand" "=a")
14902 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14903 (match_operand 2 "constant_call_address_operand" "Bz")
14905 UNSPEC_TLS_LD_BASE)
14906 (const:SI (unspec:SI
14907 [(match_operand 3 "tls_symbolic_operand")]
14909 (clobber (match_scratch:SI 4 "=d"))
14910 (clobber (match_scratch:SI 5 "=c"))
14911 (clobber (reg:CC FLAGS_REG))]
14916 [(set (match_dup 0)
14917 (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)
14920 (clobber (match_dup 4))
14921 (clobber (match_dup 5))
14922 (clobber (reg:CC FLAGS_REG))])])
14924 ;; Load and add the thread base pointer from %<tp_seg>:0.
14925 (define_insn_and_split "*load_tp_<mode>"
14926 [(set (match_operand:PTR 0 "register_operand" "=r")
14927 (unspec:PTR [(const_int 0)] UNSPEC_TP))]
14931 [(set (match_dup 0)
14934 addr_space_t as = DEFAULT_TLS_SEG_REG;
14936 operands[1] = gen_const_mem (<MODE>mode, const0_rtx);
14937 set_mem_addr_space (operands[1], as);
14940 (define_insn_and_split "*load_tp_x32_zext"
14941 [(set (match_operand:DI 0 "register_operand" "=r")
14943 (unspec:SI [(const_int 0)] UNSPEC_TP)))]
14947 [(set (match_dup 0)
14948 (zero_extend:DI (match_dup 1)))]
14950 addr_space_t as = DEFAULT_TLS_SEG_REG;
14952 operands[1] = gen_const_mem (SImode, const0_rtx);
14953 set_mem_addr_space (operands[1], as);
14956 (define_insn_and_split "*add_tp_<mode>"
14957 [(set (match_operand:PTR 0 "register_operand" "=r")
14959 (unspec:PTR [(const_int 0)] UNSPEC_TP)
14960 (match_operand:PTR 1 "register_operand" "0")))
14961 (clobber (reg:CC FLAGS_REG))]
14966 [(set (match_dup 0)
14967 (plus:PTR (match_dup 1) (match_dup 2)))
14968 (clobber (reg:CC FLAGS_REG))])]
14970 addr_space_t as = DEFAULT_TLS_SEG_REG;
14972 operands[2] = gen_const_mem (<MODE>mode, const0_rtx);
14973 set_mem_addr_space (operands[2], as);
14976 (define_insn_and_split "*add_tp_x32_zext"
14977 [(set (match_operand:DI 0 "register_operand" "=r")
14979 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
14980 (match_operand:SI 1 "register_operand" "0"))))
14981 (clobber (reg:CC FLAGS_REG))]
14986 [(set (match_dup 0)
14988 (plus:SI (match_dup 1) (match_dup 2))))
14989 (clobber (reg:CC FLAGS_REG))])]
14991 addr_space_t as = DEFAULT_TLS_SEG_REG;
14993 operands[2] = gen_const_mem (SImode, const0_rtx);
14994 set_mem_addr_space (operands[2], as);
14997 ;; The Sun linker took the AMD64 TLS spec literally and can only handle
14998 ;; %rax as destination of the initial executable code sequence.
14999 (define_insn "tls_initial_exec_64_sun"
15000 [(set (match_operand:DI 0 "register_operand" "=a")
15002 [(match_operand 1 "tls_symbolic_operand")]
15003 UNSPEC_TLS_IE_SUN))
15004 (clobber (reg:CC FLAGS_REG))]
15005 "TARGET_64BIT && TARGET_SUN_TLS"
15008 ("mov{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}", operands);
15009 return "add{q}\t{%a1@gottpoff(%%rip), %0|%0, %a1@gottpoff[rip]}";
15011 [(set_attr "type" "multi")])
15013 ;; GNU2 TLS patterns can be split.
15015 (define_expand "tls_dynamic_gnu2_32"
15016 [(set (match_dup 3)
15017 (plus:SI (match_operand:SI 2 "register_operand")
15019 (unspec:SI [(match_operand 1 "tls_symbolic_operand")]
15022 [(set (match_operand:SI 0 "register_operand")
15023 (unspec:SI [(match_dup 1) (match_dup 3)
15024 (match_dup 2) (reg:SI SP_REG)]
15026 (clobber (reg:CC FLAGS_REG))])]
15027 "!TARGET_64BIT && TARGET_GNU2_TLS"
15029 operands[3] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
15030 ix86_tls_descriptor_calls_expanded_in_cfun = true;
15033 (define_insn "*tls_dynamic_gnu2_lea_32"
15034 [(set (match_operand:SI 0 "register_operand" "=r")
15035 (plus:SI (match_operand:SI 1 "register_operand" "b")
15037 (unspec:SI [(match_operand 2 "tls_symbolic_operand")]
15038 UNSPEC_TLSDESC))))]
15039 "!TARGET_64BIT && TARGET_GNU2_TLS"
15040 "lea{l}\t{%E2@TLSDESC(%1), %0|%0, %E2@TLSDESC[%1]}"
15041 [(set_attr "type" "lea")
15042 (set_attr "mode" "SI")
15043 (set_attr "length" "6")
15044 (set_attr "length_address" "4")])
15046 (define_insn "*tls_dynamic_gnu2_call_32"
15047 [(set (match_operand:SI 0 "register_operand" "=a")
15048 (unspec:SI [(match_operand 1 "tls_symbolic_operand")
15049 (match_operand:SI 2 "register_operand" "0")
15050 ;; we have to make sure %ebx still points to the GOT
15051 (match_operand:SI 3 "register_operand" "b")
15054 (clobber (reg:CC FLAGS_REG))]
15055 "!TARGET_64BIT && TARGET_GNU2_TLS"
15056 "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
15057 [(set_attr "type" "call")
15058 (set_attr "length" "2")
15059 (set_attr "length_address" "0")])
15061 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
15062 [(set (match_operand:SI 0 "register_operand" "=&a")
15064 (unspec:SI [(match_operand 3 "tls_modbase_operand")
15065 (match_operand:SI 4)
15066 (match_operand:SI 2 "register_operand" "b")
15069 (const:SI (unspec:SI
15070 [(match_operand 1 "tls_symbolic_operand")]
15072 (clobber (reg:CC FLAGS_REG))]
15073 "!TARGET_64BIT && TARGET_GNU2_TLS"
15076 [(set (match_dup 0) (match_dup 5))]
15078 operands[5] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
15079 emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
15082 (define_expand "tls_dynamic_gnu2_64"
15083 [(set (match_dup 2)
15084 (unspec:DI [(match_operand 1 "tls_symbolic_operand")]
15087 [(set (match_operand:DI 0 "register_operand")
15088 (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
15090 (clobber (reg:CC FLAGS_REG))])]
15091 "TARGET_64BIT && TARGET_GNU2_TLS"
15093 operands[2] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
15094 ix86_tls_descriptor_calls_expanded_in_cfun = true;
15097 (define_insn "*tls_dynamic_gnu2_lea_64"
15098 [(set (match_operand:DI 0 "register_operand" "=r")
15099 (unspec:DI [(match_operand 1 "tls_symbolic_operand")]
15101 "TARGET_64BIT && TARGET_GNU2_TLS"
15102 "lea{q}\t{%E1@TLSDESC(%%rip), %0|%0, %E1@TLSDESC[rip]}"
15103 [(set_attr "type" "lea")
15104 (set_attr "mode" "DI")
15105 (set_attr "length" "7")
15106 (set_attr "length_address" "4")])
15108 (define_insn "*tls_dynamic_gnu2_call_64"
15109 [(set (match_operand:DI 0 "register_operand" "=a")
15110 (unspec:DI [(match_operand 1 "tls_symbolic_operand")
15111 (match_operand:DI 2 "register_operand" "0")
15114 (clobber (reg:CC FLAGS_REG))]
15115 "TARGET_64BIT && TARGET_GNU2_TLS"
15116 "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
15117 [(set_attr "type" "call")
15118 (set_attr "length" "2")
15119 (set_attr "length_address" "0")])
15121 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
15122 [(set (match_operand:DI 0 "register_operand" "=&a")
15124 (unspec:DI [(match_operand 2 "tls_modbase_operand")
15125 (match_operand:DI 3)
15128 (const:DI (unspec:DI
15129 [(match_operand 1 "tls_symbolic_operand")]
15131 (clobber (reg:CC FLAGS_REG))]
15132 "TARGET_64BIT && TARGET_GNU2_TLS"
15135 [(set (match_dup 0) (match_dup 4))]
15137 operands[4] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
15138 emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
15142 [(match_operand 0 "tls_address_pattern")]
15143 "TARGET_TLS_DIRECT_SEG_REFS"
15145 "operands[0] = ix86_rewrite_tls_address (operands[0]);")
15148 ;; These patterns match the binary 387 instructions for addM3, subM3,
15149 ;; mulM3 and divM3. There are three patterns for each of DFmode and
15150 ;; SFmode. The first is the normal insn, the second the same insn but
15151 ;; with one operand a conversion, and the third the same insn but with
15152 ;; the other operand a conversion. The conversion may be SFmode or
15153 ;; SImode if the target mode DFmode, but only SImode if the target mode
15156 ;; Gcc is slightly more smart about handling normal two address instructions
15157 ;; so use special patterns for add and mull.
15159 (define_insn "*fop_<mode>_comm"
15160 [(set (match_operand:MODEF 0 "register_operand" "=f,x,v")
15161 (match_operator:MODEF 3 "binary_fp_operator"
15162 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,0,v")
15163 (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm,vm")]))]
15164 "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15165 || (TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)))
15166 && COMMUTATIVE_ARITH_P (operands[3])
15167 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15168 "* return output_387_binary_op (insn, operands);"
15169 [(set (attr "type")
15170 (if_then_else (eq_attr "alternative" "1,2")
15171 (if_then_else (match_operand:MODEF 3 "mult_operator")
15172 (const_string "ssemul")
15173 (const_string "sseadd"))
15174 (if_then_else (match_operand:MODEF 3 "mult_operator")
15175 (const_string "fmul")
15176 (const_string "fop"))))
15177 (set_attr "isa" "*,noavx,avx")
15178 (set_attr "prefix" "orig,orig,vex")
15179 (set_attr "mode" "<MODE>")
15180 (set (attr "enabled")
15182 (match_test ("SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"))
15184 (eq_attr "alternative" "0")
15185 (symbol_ref "TARGET_MIX_SSE_I387
15186 && X87_ENABLE_ARITH (<MODE>mode)")
15187 (const_string "*"))
15189 (eq_attr "alternative" "0")
15190 (symbol_ref "true")
15191 (symbol_ref "false"))))])
15193 (define_insn "*rcpsf2_sse"
15194 [(set (match_operand:SF 0 "register_operand" "=x,x")
15195 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "x,m")]
15197 "TARGET_SSE && TARGET_SSE_MATH"
15199 %vrcpss\t{%d1, %0|%0, %d1}
15200 %vrcpss\t{%1, %d0|%d0, %1}"
15201 [(set_attr "type" "sse")
15202 (set_attr "atom_sse_attr" "rcp")
15203 (set_attr "btver2_sse_attr" "rcp")
15204 (set_attr "prefix" "maybe_vex")
15205 (set_attr "mode" "SF")])
15207 (define_insn "*fop_<mode>_1"
15208 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,v")
15209 (match_operator:MODEF 3 "binary_fp_operator"
15210 [(match_operand:MODEF 1
15211 "x87nonimm_ssenomem_operand" "0,fm,0,v")
15212 (match_operand:MODEF 2
15213 "nonimmediate_operand" "fm,0,xm,vm")]))]
15214 "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15215 || (TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)))
15216 && !COMMUTATIVE_ARITH_P (operands[3])
15217 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15218 "* return output_387_binary_op (insn, operands);"
15219 [(set (attr "type")
15220 (if_then_else (eq_attr "alternative" "2,3")
15221 (if_then_else (match_operand:MODEF 3 "div_operator")
15222 (const_string "ssediv")
15223 (const_string "sseadd"))
15224 (if_then_else (match_operand:MODEF 3 "div_operator")
15225 (const_string "fdiv")
15226 (const_string "fop"))))
15227 (set_attr "isa" "*,*,noavx,avx")
15228 (set_attr "prefix" "orig,orig,orig,vex")
15229 (set_attr "mode" "<MODE>")
15230 (set (attr "enabled")
15232 (match_test ("SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"))
15234 (eq_attr "alternative" "0,1")
15235 (symbol_ref "TARGET_MIX_SSE_I387
15236 && X87_ENABLE_ARITH (<MODE>mode)")
15237 (const_string "*"))
15239 (eq_attr "alternative" "0,1")
15240 (symbol_ref "true")
15241 (symbol_ref "false"))))])
15243 ;; ??? Add SSE splitters for these!
15244 (define_insn "*fop_<MODEF:mode>_2_i387"
15245 [(set (match_operand:MODEF 0 "register_operand" "=f")
15246 (match_operator:MODEF 3 "binary_fp_operator"
15248 (match_operand:SWI24 1 "nonimmediate_operand" "m"))
15249 (match_operand:MODEF 2 "register_operand" "0")]))]
15250 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI24:MODE>mode)
15251 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
15252 && (TARGET_USE_<SWI24:MODE>MODE_FIOP
15253 || optimize_function_for_size_p (cfun))"
15254 "* return output_387_binary_op (insn, operands);"
15255 [(set (attr "type")
15256 (cond [(match_operand:MODEF 3 "mult_operator")
15257 (const_string "fmul")
15258 (match_operand:MODEF 3 "div_operator")
15259 (const_string "fdiv")
15261 (const_string "fop")))
15262 (set_attr "fp_int_src" "true")
15263 (set_attr "mode" "<SWI24:MODE>")])
15265 (define_insn "*fop_<MODEF:mode>_3_i387"
15266 [(set (match_operand:MODEF 0 "register_operand" "=f")
15267 (match_operator:MODEF 3 "binary_fp_operator"
15268 [(match_operand:MODEF 1 "register_operand" "0")
15270 (match_operand:SWI24 2 "nonimmediate_operand" "m"))]))]
15271 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI24:MODE>mode)
15272 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
15273 && (TARGET_USE_<SWI24:MODE>MODE_FIOP
15274 || optimize_function_for_size_p (cfun))"
15275 "* return output_387_binary_op (insn, operands);"
15276 [(set (attr "type")
15277 (cond [(match_operand:MODEF 3 "mult_operator")
15278 (const_string "fmul")
15279 (match_operand:MODEF 3 "div_operator")
15280 (const_string "fdiv")
15282 (const_string "fop")))
15283 (set_attr "fp_int_src" "true")
15284 (set_attr "mode" "<MODE>")])
15286 (define_insn "*fop_df_4_i387"
15287 [(set (match_operand:DF 0 "register_operand" "=f,f")
15288 (match_operator:DF 3 "binary_fp_operator"
15290 (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
15291 (match_operand:DF 2 "register_operand" "0,f")]))]
15292 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
15293 && !(SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
15294 "* return output_387_binary_op (insn, operands);"
15295 [(set (attr "type")
15296 (cond [(match_operand:DF 3 "mult_operator")
15297 (const_string "fmul")
15298 (match_operand:DF 3 "div_operator")
15299 (const_string "fdiv")
15301 (const_string "fop")))
15302 (set_attr "mode" "SF")])
15304 (define_insn "*fop_df_5_i387"
15305 [(set (match_operand:DF 0 "register_operand" "=f,f")
15306 (match_operator:DF 3 "binary_fp_operator"
15307 [(match_operand:DF 1 "register_operand" "0,f")
15309 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
15310 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
15311 && !(SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
15312 "* return output_387_binary_op (insn, operands);"
15313 [(set (attr "type")
15314 (cond [(match_operand:DF 3 "mult_operator")
15315 (const_string "fmul")
15316 (match_operand:DF 3 "div_operator")
15317 (const_string "fdiv")
15319 (const_string "fop")))
15320 (set_attr "mode" "SF")])
15322 (define_insn "*fop_df_6_i387"
15323 [(set (match_operand:DF 0 "register_operand" "=f,f")
15324 (match_operator:DF 3 "binary_fp_operator"
15326 (match_operand:SF 1 "register_operand" "0,f"))
15328 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
15329 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
15330 && !(SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
15331 "* return output_387_binary_op (insn, operands);"
15332 [(set (attr "type")
15333 (cond [(match_operand:DF 3 "mult_operator")
15334 (const_string "fmul")
15335 (match_operand:DF 3 "div_operator")
15336 (const_string "fdiv")
15338 (const_string "fop")))
15339 (set_attr "mode" "SF")])
15341 (define_insn "*fop_xf_comm_i387"
15342 [(set (match_operand:XF 0 "register_operand" "=f")
15343 (match_operator:XF 3 "binary_fp_operator"
15344 [(match_operand:XF 1 "register_operand" "%0")
15345 (match_operand:XF 2 "register_operand" "f")]))]
15347 && COMMUTATIVE_ARITH_P (operands[3])"
15348 "* return output_387_binary_op (insn, operands);"
15349 [(set (attr "type")
15350 (if_then_else (match_operand:XF 3 "mult_operator")
15351 (const_string "fmul")
15352 (const_string "fop")))
15353 (set_attr "mode" "XF")])
15355 (define_insn "*fop_xf_1_i387"
15356 [(set (match_operand:XF 0 "register_operand" "=f,f")
15357 (match_operator:XF 3 "binary_fp_operator"
15358 [(match_operand:XF 1 "register_operand" "0,f")
15359 (match_operand:XF 2 "register_operand" "f,0")]))]
15361 && !COMMUTATIVE_ARITH_P (operands[3])"
15362 "* return output_387_binary_op (insn, operands);"
15363 [(set (attr "type")
15364 (if_then_else (match_operand:XF 3 "div_operator")
15365 (const_string "fdiv")
15366 (const_string "fop")))
15367 (set_attr "mode" "XF")])
15369 (define_insn "*fop_xf_2_i387"
15370 [(set (match_operand:XF 0 "register_operand" "=f")
15371 (match_operator:XF 3 "binary_fp_operator"
15373 (match_operand:SWI24 1 "nonimmediate_operand" "m"))
15374 (match_operand:XF 2 "register_operand" "0")]))]
15376 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
15377 "* return output_387_binary_op (insn, operands);"
15378 [(set (attr "type")
15379 (cond [(match_operand:XF 3 "mult_operator")
15380 (const_string "fmul")
15381 (match_operand:XF 3 "div_operator")
15382 (const_string "fdiv")
15384 (const_string "fop")))
15385 (set_attr "fp_int_src" "true")
15386 (set_attr "mode" "<MODE>")])
15388 (define_insn "*fop_xf_3_i387"
15389 [(set (match_operand:XF 0 "register_operand" "=f")
15390 (match_operator:XF 3 "binary_fp_operator"
15391 [(match_operand:XF 1 "register_operand" "0")
15393 (match_operand:SWI24 2 "nonimmediate_operand" "m"))]))]
15395 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
15396 "* return output_387_binary_op (insn, operands);"
15397 [(set (attr "type")
15398 (cond [(match_operand:XF 3 "mult_operator")
15399 (const_string "fmul")
15400 (match_operand:XF 3 "div_operator")
15401 (const_string "fdiv")
15403 (const_string "fop")))
15404 (set_attr "fp_int_src" "true")
15405 (set_attr "mode" "<MODE>")])
15407 (define_insn "*fop_xf_4_i387"
15408 [(set (match_operand:XF 0 "register_operand" "=f,f")
15409 (match_operator:XF 3 "binary_fp_operator"
15411 (match_operand:MODEF 1 "nonimmediate_operand" "fm,0"))
15412 (match_operand:XF 2 "register_operand" "0,f")]))]
15414 "* return output_387_binary_op (insn, operands);"
15415 [(set (attr "type")
15416 (cond [(match_operand:XF 3 "mult_operator")
15417 (const_string "fmul")
15418 (match_operand:XF 3 "div_operator")
15419 (const_string "fdiv")
15421 (const_string "fop")))
15422 (set_attr "mode" "<MODE>")])
15424 (define_insn "*fop_xf_5_i387"
15425 [(set (match_operand:XF 0 "register_operand" "=f,f")
15426 (match_operator:XF 3 "binary_fp_operator"
15427 [(match_operand:XF 1 "register_operand" "0,f")
15429 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
15431 "* return output_387_binary_op (insn, operands);"
15432 [(set (attr "type")
15433 (cond [(match_operand:XF 3 "mult_operator")
15434 (const_string "fmul")
15435 (match_operand:XF 3 "div_operator")
15436 (const_string "fdiv")
15438 (const_string "fop")))
15439 (set_attr "mode" "<MODE>")])
15441 (define_insn "*fop_xf_6_i387"
15442 [(set (match_operand:XF 0 "register_operand" "=f,f")
15443 (match_operator:XF 3 "binary_fp_operator"
15445 (match_operand:MODEF 1 "register_operand" "0,f"))
15447 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
15449 "* return output_387_binary_op (insn, operands);"
15450 [(set (attr "type")
15451 (cond [(match_operand:XF 3 "mult_operator")
15452 (const_string "fmul")
15453 (match_operand:XF 3 "div_operator")
15454 (const_string "fdiv")
15456 (const_string "fop")))
15457 (set_attr "mode" "<MODE>")])
15459 ;; FPU special functions.
15461 ;; This pattern implements a no-op XFmode truncation for
15462 ;; all fancy i386 XFmode math functions.
15464 (define_insn "truncxf<mode>2_i387_noop_unspec"
15465 [(set (match_operand:MODEF 0 "register_operand" "=f")
15466 (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")]
15467 UNSPEC_TRUNC_NOOP))]
15468 "TARGET_USE_FANCY_MATH_387"
15469 "* return output_387_reg_move (insn, operands);"
15470 [(set_attr "type" "fmov")
15471 (set_attr "mode" "<MODE>")])
15473 (define_insn "sqrtxf2"
15474 [(set (match_operand:XF 0 "register_operand" "=f")
15475 (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
15476 "TARGET_USE_FANCY_MATH_387"
15478 [(set_attr "type" "fpspc")
15479 (set_attr "mode" "XF")
15480 (set_attr "athlon_decode" "direct")
15481 (set_attr "amdfam10_decode" "direct")
15482 (set_attr "bdver1_decode" "direct")])
15484 (define_insn "sqrt_extend<mode>xf2_i387"
15485 [(set (match_operand:XF 0 "register_operand" "=f")
15488 (match_operand:MODEF 1 "register_operand" "0"))))]
15489 "TARGET_USE_FANCY_MATH_387"
15491 [(set_attr "type" "fpspc")
15492 (set_attr "mode" "XF")
15493 (set_attr "athlon_decode" "direct")
15494 (set_attr "amdfam10_decode" "direct")
15495 (set_attr "bdver1_decode" "direct")])
15497 (define_insn "*rsqrtsf2_sse"
15498 [(set (match_operand:SF 0 "register_operand" "=x,x")
15499 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "x,m")]
15501 "TARGET_SSE && TARGET_SSE_MATH"
15503 %vrsqrtss\t{%d1, %0|%0, %d1}
15504 %vrsqrtss\t{%1, %d0|%d0, %1}"
15505 [(set_attr "type" "sse")
15506 (set_attr "atom_sse_attr" "rcp")
15507 (set_attr "btver2_sse_attr" "rcp")
15508 (set_attr "prefix" "maybe_vex")
15509 (set_attr "mode" "SF")])
15511 (define_expand "rsqrtsf2"
15512 [(set (match_operand:SF 0 "register_operand")
15513 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand")]
15515 "TARGET_SSE && TARGET_SSE_MATH"
15517 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
15521 (define_insn "*sqrt<mode>2_sse"
15522 [(set (match_operand:MODEF 0 "register_operand" "=v,v")
15524 (match_operand:MODEF 1 "nonimmediate_operand" "v,m")))]
15525 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
15527 %vsqrt<ssemodesuffix>\t{%d1, %0|%0, %d1}
15528 %vsqrt<ssemodesuffix>\t{%1, %d0|%d0, %1}"
15529 [(set_attr "type" "sse")
15530 (set_attr "atom_sse_attr" "sqrt")
15531 (set_attr "btver2_sse_attr" "sqrt")
15532 (set_attr "prefix" "maybe_vex")
15533 (set_attr "mode" "<MODE>")
15534 (set_attr "athlon_decode" "*")
15535 (set_attr "amdfam10_decode" "*")
15536 (set_attr "bdver1_decode" "*")])
15538 (define_expand "sqrt<mode>2"
15539 [(set (match_operand:MODEF 0 "register_operand")
15541 (match_operand:MODEF 1 "nonimmediate_operand")))]
15542 "(TARGET_USE_FANCY_MATH_387 && X87_ENABLE_ARITH (<MODE>mode))
15543 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
15545 if (<MODE>mode == SFmode
15546 && TARGET_SSE && TARGET_SSE_MATH
15547 && TARGET_RECIP_SQRT
15548 && !optimize_function_for_size_p (cfun)
15549 && flag_finite_math_only && !flag_trapping_math
15550 && flag_unsafe_math_optimizations)
15552 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
15556 if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
15558 rtx op0 = gen_reg_rtx (XFmode);
15559 rtx op1 = force_reg (<MODE>mode, operands[1]);
15561 emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
15562 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
15567 (define_insn "fpremxf4_i387"
15568 [(set (match_operand:XF 0 "register_operand" "=f")
15569 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15570 (match_operand:XF 3 "register_operand" "1")]
15572 (set (match_operand:XF 1 "register_operand" "=u")
15573 (unspec:XF [(match_dup 2) (match_dup 3)]
15575 (set (reg:CCFP FPSR_REG)
15576 (unspec:CCFP [(match_dup 2) (match_dup 3)]
15578 "TARGET_USE_FANCY_MATH_387
15579 && flag_finite_math_only"
15581 [(set_attr "type" "fpspc")
15582 (set_attr "znver1_decode" "vector")
15583 (set_attr "mode" "XF")])
15585 (define_expand "fmodxf3"
15586 [(use (match_operand:XF 0 "register_operand"))
15587 (use (match_operand:XF 1 "general_operand"))
15588 (use (match_operand:XF 2 "general_operand"))]
15589 "TARGET_USE_FANCY_MATH_387
15590 && flag_finite_math_only"
15592 rtx_code_label *label = gen_label_rtx ();
15594 rtx op1 = gen_reg_rtx (XFmode);
15595 rtx op2 = gen_reg_rtx (XFmode);
15597 emit_move_insn (op2, operands[2]);
15598 emit_move_insn (op1, operands[1]);
15600 emit_label (label);
15601 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
15602 ix86_emit_fp_unordered_jump (label);
15603 LABEL_NUSES (label) = 1;
15605 emit_move_insn (operands[0], op1);
15609 (define_expand "fmod<mode>3"
15610 [(use (match_operand:MODEF 0 "register_operand"))
15611 (use (match_operand:MODEF 1 "general_operand"))
15612 (use (match_operand:MODEF 2 "general_operand"))]
15613 "TARGET_USE_FANCY_MATH_387
15614 && flag_finite_math_only"
15616 rtx (*gen_truncxf) (rtx, rtx);
15618 rtx_code_label *label = gen_label_rtx ();
15620 rtx op1 = gen_reg_rtx (XFmode);
15621 rtx op2 = gen_reg_rtx (XFmode);
15623 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
15624 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15626 emit_label (label);
15627 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
15628 ix86_emit_fp_unordered_jump (label);
15629 LABEL_NUSES (label) = 1;
15631 /* Truncate the result properly for strict SSE math. */
15632 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15633 && !TARGET_MIX_SSE_I387)
15634 gen_truncxf = gen_truncxf<mode>2;
15636 gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
15638 emit_insn (gen_truncxf (operands[0], op1));
15642 (define_insn "fprem1xf4_i387"
15643 [(set (match_operand:XF 0 "register_operand" "=f")
15644 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15645 (match_operand:XF 3 "register_operand" "1")]
15647 (set (match_operand:XF 1 "register_operand" "=u")
15648 (unspec:XF [(match_dup 2) (match_dup 3)]
15650 (set (reg:CCFP FPSR_REG)
15651 (unspec:CCFP [(match_dup 2) (match_dup 3)]
15653 "TARGET_USE_FANCY_MATH_387
15654 && flag_finite_math_only"
15656 [(set_attr "type" "fpspc")
15657 (set_attr "znver1_decode" "vector")
15658 (set_attr "mode" "XF")])
15660 (define_expand "remainderxf3"
15661 [(use (match_operand:XF 0 "register_operand"))
15662 (use (match_operand:XF 1 "general_operand"))
15663 (use (match_operand:XF 2 "general_operand"))]
15664 "TARGET_USE_FANCY_MATH_387
15665 && flag_finite_math_only"
15667 rtx_code_label *label = gen_label_rtx ();
15669 rtx op1 = gen_reg_rtx (XFmode);
15670 rtx op2 = gen_reg_rtx (XFmode);
15672 emit_move_insn (op2, operands[2]);
15673 emit_move_insn (op1, operands[1]);
15675 emit_label (label);
15676 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
15677 ix86_emit_fp_unordered_jump (label);
15678 LABEL_NUSES (label) = 1;
15680 emit_move_insn (operands[0], op1);
15684 (define_expand "remainder<mode>3"
15685 [(use (match_operand:MODEF 0 "register_operand"))
15686 (use (match_operand:MODEF 1 "general_operand"))
15687 (use (match_operand:MODEF 2 "general_operand"))]
15688 "TARGET_USE_FANCY_MATH_387
15689 && flag_finite_math_only"
15691 rtx (*gen_truncxf) (rtx, rtx);
15693 rtx_code_label *label = gen_label_rtx ();
15695 rtx op1 = gen_reg_rtx (XFmode);
15696 rtx op2 = gen_reg_rtx (XFmode);
15698 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
15699 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15701 emit_label (label);
15703 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
15704 ix86_emit_fp_unordered_jump (label);
15705 LABEL_NUSES (label) = 1;
15707 /* Truncate the result properly for strict SSE math. */
15708 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15709 && !TARGET_MIX_SSE_I387)
15710 gen_truncxf = gen_truncxf<mode>2;
15712 gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
15714 emit_insn (gen_truncxf (operands[0], op1));
15718 (define_int_iterator SINCOS
15722 (define_int_attr sincos
15723 [(UNSPEC_SIN "sin")
15724 (UNSPEC_COS "cos")])
15726 (define_insn "*<sincos>xf2_i387"
15727 [(set (match_operand:XF 0 "register_operand" "=f")
15728 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15730 "TARGET_USE_FANCY_MATH_387
15731 && flag_unsafe_math_optimizations"
15733 [(set_attr "type" "fpspc")
15734 (set_attr "znver1_decode" "vector")
15735 (set_attr "mode" "XF")])
15737 (define_insn "*<sincos>_extend<mode>xf2_i387"
15738 [(set (match_operand:XF 0 "register_operand" "=f")
15739 (unspec:XF [(float_extend:XF
15740 (match_operand:MODEF 1 "register_operand" "0"))]
15742 "TARGET_USE_FANCY_MATH_387
15743 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15744 || TARGET_MIX_SSE_I387)
15745 && flag_unsafe_math_optimizations"
15747 [(set_attr "type" "fpspc")
15748 (set_attr "znver1_decode" "vector")
15749 (set_attr "mode" "XF")])
15751 ;; When sincos pattern is defined, sin and cos builtin functions will be
15752 ;; expanded to sincos pattern with one of its outputs left unused.
15753 ;; CSE pass will figure out if two sincos patterns can be combined,
15754 ;; otherwise sincos pattern will be split back to sin or cos pattern,
15755 ;; depending on the unused output.
15757 (define_insn "sincosxf3"
15758 [(set (match_operand:XF 0 "register_operand" "=f")
15759 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15760 UNSPEC_SINCOS_COS))
15761 (set (match_operand:XF 1 "register_operand" "=u")
15762 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15763 "TARGET_USE_FANCY_MATH_387
15764 && flag_unsafe_math_optimizations"
15766 [(set_attr "type" "fpspc")
15767 (set_attr "znver1_decode" "vector")
15768 (set_attr "mode" "XF")])
15771 [(set (match_operand:XF 0 "register_operand")
15772 (unspec:XF [(match_operand:XF 2 "register_operand")]
15773 UNSPEC_SINCOS_COS))
15774 (set (match_operand:XF 1 "register_operand")
15775 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15776 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15777 && can_create_pseudo_p ()"
15778 [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))])
15781 [(set (match_operand:XF 0 "register_operand")
15782 (unspec:XF [(match_operand:XF 2 "register_operand")]
15783 UNSPEC_SINCOS_COS))
15784 (set (match_operand:XF 1 "register_operand")
15785 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15786 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15787 && can_create_pseudo_p ()"
15788 [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))])
15790 (define_insn "sincos_extend<mode>xf3_i387"
15791 [(set (match_operand:XF 0 "register_operand" "=f")
15792 (unspec:XF [(float_extend:XF
15793 (match_operand:MODEF 2 "register_operand" "0"))]
15794 UNSPEC_SINCOS_COS))
15795 (set (match_operand:XF 1 "register_operand" "=u")
15796 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
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")])
15807 [(set (match_operand:XF 0 "register_operand")
15808 (unspec:XF [(float_extend:XF
15809 (match_operand:MODEF 2 "register_operand"))]
15810 UNSPEC_SINCOS_COS))
15811 (set (match_operand:XF 1 "register_operand")
15812 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
15813 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15814 && can_create_pseudo_p ()"
15815 [(set (match_dup 1)
15816 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))])
15819 [(set (match_operand:XF 0 "register_operand")
15820 (unspec:XF [(float_extend:XF
15821 (match_operand:MODEF 2 "register_operand"))]
15822 UNSPEC_SINCOS_COS))
15823 (set (match_operand:XF 1 "register_operand")
15824 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
15825 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15826 && can_create_pseudo_p ()"
15827 [(set (match_dup 0)
15828 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))])
15830 (define_expand "sincos<mode>3"
15831 [(use (match_operand:MODEF 0 "register_operand"))
15832 (use (match_operand:MODEF 1 "register_operand"))
15833 (use (match_operand:MODEF 2 "register_operand"))]
15834 "TARGET_USE_FANCY_MATH_387
15835 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15836 || TARGET_MIX_SSE_I387)
15837 && flag_unsafe_math_optimizations"
15839 rtx op0 = gen_reg_rtx (XFmode);
15840 rtx op1 = gen_reg_rtx (XFmode);
15842 emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
15843 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15844 emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
15848 (define_insn "fptanxf4_i387"
15849 [(set (match_operand:XF 0 "register_operand" "=f")
15850 (match_operand:XF 3 "const_double_operand" "F"))
15851 (set (match_operand:XF 1 "register_operand" "=u")
15852 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15854 "TARGET_USE_FANCY_MATH_387
15855 && flag_unsafe_math_optimizations
15856 && standard_80387_constant_p (operands[3]) == 2"
15858 [(set_attr "type" "fpspc")
15859 (set_attr "znver1_decode" "vector")
15860 (set_attr "mode" "XF")])
15862 (define_insn "fptan_extend<mode>xf4_i387"
15863 [(set (match_operand:MODEF 0 "register_operand" "=f")
15864 (match_operand:MODEF 3 "const_double_operand" "F"))
15865 (set (match_operand:XF 1 "register_operand" "=u")
15866 (unspec:XF [(float_extend:XF
15867 (match_operand:MODEF 2 "register_operand" "0"))]
15869 "TARGET_USE_FANCY_MATH_387
15870 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15871 || TARGET_MIX_SSE_I387)
15872 && flag_unsafe_math_optimizations
15873 && standard_80387_constant_p (operands[3]) == 2"
15875 [(set_attr "type" "fpspc")
15876 (set_attr "znver1_decode" "vector")
15877 (set_attr "mode" "XF")])
15879 (define_expand "tanxf2"
15880 [(use (match_operand:XF 0 "register_operand"))
15881 (use (match_operand:XF 1 "register_operand"))]
15882 "TARGET_USE_FANCY_MATH_387
15883 && flag_unsafe_math_optimizations"
15885 rtx one = gen_reg_rtx (XFmode);
15886 rtx op2 = CONST1_RTX (XFmode); /* fld1 */
15888 emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2));
15892 (define_expand "tan<mode>2"
15893 [(use (match_operand:MODEF 0 "register_operand"))
15894 (use (match_operand:MODEF 1 "register_operand"))]
15895 "TARGET_USE_FANCY_MATH_387
15896 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15897 || TARGET_MIX_SSE_I387)
15898 && flag_unsafe_math_optimizations"
15900 rtx op0 = gen_reg_rtx (XFmode);
15902 rtx one = gen_reg_rtx (<MODE>mode);
15903 rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */
15905 emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
15906 operands[1], op2));
15907 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15911 (define_insn "*fpatanxf3_i387"
15912 [(set (match_operand:XF 0 "register_operand" "=f")
15913 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
15914 (match_operand:XF 2 "register_operand" "u")]
15916 (clobber (match_scratch:XF 3 "=2"))]
15917 "TARGET_USE_FANCY_MATH_387
15918 && flag_unsafe_math_optimizations"
15920 [(set_attr "type" "fpspc")
15921 (set_attr "znver1_decode" "vector")
15922 (set_attr "mode" "XF")])
15924 (define_insn "fpatan_extend<mode>xf3_i387"
15925 [(set (match_operand:XF 0 "register_operand" "=f")
15926 (unspec:XF [(float_extend:XF
15927 (match_operand:MODEF 1 "register_operand" "0"))
15929 (match_operand:MODEF 2 "register_operand" "u"))]
15931 (clobber (match_scratch:XF 3 "=2"))]
15932 "TARGET_USE_FANCY_MATH_387
15933 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15934 || TARGET_MIX_SSE_I387)
15935 && flag_unsafe_math_optimizations"
15937 [(set_attr "type" "fpspc")
15938 (set_attr "znver1_decode" "vector")
15939 (set_attr "mode" "XF")])
15941 (define_expand "atan2xf3"
15942 [(parallel [(set (match_operand:XF 0 "register_operand")
15943 (unspec:XF [(match_operand:XF 2 "register_operand")
15944 (match_operand:XF 1 "register_operand")]
15946 (clobber (match_scratch:XF 3))])]
15947 "TARGET_USE_FANCY_MATH_387
15948 && flag_unsafe_math_optimizations")
15950 (define_expand "atan2<mode>3"
15951 [(use (match_operand:MODEF 0 "register_operand"))
15952 (use (match_operand:MODEF 1 "register_operand"))
15953 (use (match_operand:MODEF 2 "register_operand"))]
15954 "TARGET_USE_FANCY_MATH_387
15955 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15956 || TARGET_MIX_SSE_I387)
15957 && flag_unsafe_math_optimizations"
15959 rtx op0 = gen_reg_rtx (XFmode);
15961 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
15962 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15966 (define_expand "atanxf2"
15967 [(parallel [(set (match_operand:XF 0 "register_operand")
15968 (unspec:XF [(match_dup 2)
15969 (match_operand:XF 1 "register_operand")]
15971 (clobber (match_scratch:XF 3))])]
15972 "TARGET_USE_FANCY_MATH_387
15973 && flag_unsafe_math_optimizations"
15975 operands[2] = gen_reg_rtx (XFmode);
15976 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
15979 (define_expand "atan<mode>2"
15980 [(use (match_operand:MODEF 0 "register_operand"))
15981 (use (match_operand:MODEF 1 "register_operand"))]
15982 "TARGET_USE_FANCY_MATH_387
15983 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15984 || TARGET_MIX_SSE_I387)
15985 && flag_unsafe_math_optimizations"
15987 rtx op0 = gen_reg_rtx (XFmode);
15989 rtx op2 = gen_reg_rtx (<MODE>mode);
15990 emit_move_insn (op2, CONST1_RTX (<MODE>mode)); /* fld1 */
15992 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1]));
15993 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15997 (define_expand "asinxf2"
15998 [(set (match_dup 2)
15999 (mult:XF (match_operand:XF 1 "register_operand")
16001 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
16002 (set (match_dup 5) (sqrt:XF (match_dup 4)))
16003 (parallel [(set (match_operand:XF 0 "register_operand")
16004 (unspec:XF [(match_dup 5) (match_dup 1)]
16006 (clobber (match_scratch:XF 6))])]
16007 "TARGET_USE_FANCY_MATH_387
16008 && flag_unsafe_math_optimizations"
16012 for (i = 2; i < 6; i++)
16013 operands[i] = gen_reg_rtx (XFmode);
16015 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
16018 (define_expand "asin<mode>2"
16019 [(use (match_operand:MODEF 0 "register_operand"))
16020 (use (match_operand:MODEF 1 "general_operand"))]
16021 "TARGET_USE_FANCY_MATH_387
16022 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16023 || TARGET_MIX_SSE_I387)
16024 && flag_unsafe_math_optimizations"
16026 rtx op0 = gen_reg_rtx (XFmode);
16027 rtx op1 = gen_reg_rtx (XFmode);
16029 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16030 emit_insn (gen_asinxf2 (op0, op1));
16031 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16035 (define_expand "acosxf2"
16036 [(set (match_dup 2)
16037 (mult:XF (match_operand:XF 1 "register_operand")
16039 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
16040 (set (match_dup 5) (sqrt:XF (match_dup 4)))
16041 (parallel [(set (match_operand:XF 0 "register_operand")
16042 (unspec:XF [(match_dup 1) (match_dup 5)]
16044 (clobber (match_scratch:XF 6))])]
16045 "TARGET_USE_FANCY_MATH_387
16046 && flag_unsafe_math_optimizations"
16050 for (i = 2; i < 6; i++)
16051 operands[i] = gen_reg_rtx (XFmode);
16053 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
16056 (define_expand "acos<mode>2"
16057 [(use (match_operand:MODEF 0 "register_operand"))
16058 (use (match_operand:MODEF 1 "general_operand"))]
16059 "TARGET_USE_FANCY_MATH_387
16060 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16061 || TARGET_MIX_SSE_I387)
16062 && flag_unsafe_math_optimizations"
16064 rtx op0 = gen_reg_rtx (XFmode);
16065 rtx op1 = gen_reg_rtx (XFmode);
16067 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16068 emit_insn (gen_acosxf2 (op0, op1));
16069 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16073 (define_insn "fyl2xxf3_i387"
16074 [(set (match_operand:XF 0 "register_operand" "=f")
16075 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
16076 (match_operand:XF 2 "register_operand" "u")]
16078 (clobber (match_scratch:XF 3 "=2"))]
16079 "TARGET_USE_FANCY_MATH_387
16080 && flag_unsafe_math_optimizations"
16082 [(set_attr "type" "fpspc")
16083 (set_attr "znver1_decode" "vector")
16084 (set_attr "mode" "XF")])
16086 (define_insn "fyl2x_extend<mode>xf3_i387"
16087 [(set (match_operand:XF 0 "register_operand" "=f")
16088 (unspec:XF [(float_extend:XF
16089 (match_operand:MODEF 1 "register_operand" "0"))
16090 (match_operand:XF 2 "register_operand" "u")]
16092 (clobber (match_scratch:XF 3 "=2"))]
16093 "TARGET_USE_FANCY_MATH_387
16094 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16095 || TARGET_MIX_SSE_I387)
16096 && flag_unsafe_math_optimizations"
16098 [(set_attr "type" "fpspc")
16099 (set_attr "znver1_decode" "vector")
16100 (set_attr "mode" "XF")])
16102 (define_expand "logxf2"
16103 [(parallel [(set (match_operand:XF 0 "register_operand")
16104 (unspec:XF [(match_operand:XF 1 "register_operand")
16105 (match_dup 2)] UNSPEC_FYL2X))
16106 (clobber (match_scratch:XF 3))])]
16107 "TARGET_USE_FANCY_MATH_387
16108 && flag_unsafe_math_optimizations"
16110 operands[2] = gen_reg_rtx (XFmode);
16111 emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */
16114 (define_expand "log<mode>2"
16115 [(use (match_operand:MODEF 0 "register_operand"))
16116 (use (match_operand:MODEF 1 "register_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"
16122 rtx op0 = gen_reg_rtx (XFmode);
16124 rtx op2 = gen_reg_rtx (XFmode);
16125 emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */
16127 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
16128 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16132 (define_expand "log10xf2"
16133 [(parallel [(set (match_operand:XF 0 "register_operand")
16134 (unspec:XF [(match_operand:XF 1 "register_operand")
16135 (match_dup 2)] UNSPEC_FYL2X))
16136 (clobber (match_scratch:XF 3))])]
16137 "TARGET_USE_FANCY_MATH_387
16138 && flag_unsafe_math_optimizations"
16140 operands[2] = gen_reg_rtx (XFmode);
16141 emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
16144 (define_expand "log10<mode>2"
16145 [(use (match_operand:MODEF 0 "register_operand"))
16146 (use (match_operand:MODEF 1 "register_operand"))]
16147 "TARGET_USE_FANCY_MATH_387
16148 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16149 || TARGET_MIX_SSE_I387)
16150 && flag_unsafe_math_optimizations"
16152 rtx op0 = gen_reg_rtx (XFmode);
16154 rtx op2 = gen_reg_rtx (XFmode);
16155 emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */
16157 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
16158 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16162 (define_expand "log2xf2"
16163 [(parallel [(set (match_operand:XF 0 "register_operand")
16164 (unspec:XF [(match_operand:XF 1 "register_operand")
16165 (match_dup 2)] UNSPEC_FYL2X))
16166 (clobber (match_scratch:XF 3))])]
16167 "TARGET_USE_FANCY_MATH_387
16168 && flag_unsafe_math_optimizations"
16170 operands[2] = gen_reg_rtx (XFmode);
16171 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
16174 (define_expand "log2<mode>2"
16175 [(use (match_operand:MODEF 0 "register_operand"))
16176 (use (match_operand:MODEF 1 "register_operand"))]
16177 "TARGET_USE_FANCY_MATH_387
16178 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16179 || TARGET_MIX_SSE_I387)
16180 && flag_unsafe_math_optimizations"
16182 rtx op0 = gen_reg_rtx (XFmode);
16184 rtx op2 = gen_reg_rtx (XFmode);
16185 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
16187 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
16188 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16192 (define_insn "fyl2xp1xf3_i387"
16193 [(set (match_operand:XF 0 "register_operand" "=f")
16194 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
16195 (match_operand:XF 2 "register_operand" "u")]
16197 (clobber (match_scratch:XF 3 "=2"))]
16198 "TARGET_USE_FANCY_MATH_387
16199 && flag_unsafe_math_optimizations"
16201 [(set_attr "type" "fpspc")
16202 (set_attr "znver1_decode" "vector")
16203 (set_attr "mode" "XF")])
16205 (define_insn "fyl2xp1_extend<mode>xf3_i387"
16206 [(set (match_operand:XF 0 "register_operand" "=f")
16207 (unspec:XF [(float_extend:XF
16208 (match_operand:MODEF 1 "register_operand" "0"))
16209 (match_operand:XF 2 "register_operand" "u")]
16211 (clobber (match_scratch:XF 3 "=2"))]
16212 "TARGET_USE_FANCY_MATH_387
16213 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16214 || TARGET_MIX_SSE_I387)
16215 && flag_unsafe_math_optimizations"
16217 [(set_attr "type" "fpspc")
16218 (set_attr "znver1_decode" "vector")
16219 (set_attr "mode" "XF")])
16221 (define_expand "log1pxf2"
16222 [(use (match_operand:XF 0 "register_operand"))
16223 (use (match_operand:XF 1 "register_operand"))]
16224 "TARGET_USE_FANCY_MATH_387
16225 && flag_unsafe_math_optimizations"
16227 ix86_emit_i387_log1p (operands[0], operands[1]);
16231 (define_expand "log1p<mode>2"
16232 [(use (match_operand:MODEF 0 "register_operand"))
16233 (use (match_operand:MODEF 1 "register_operand"))]
16234 "TARGET_USE_FANCY_MATH_387
16235 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16236 || TARGET_MIX_SSE_I387)
16237 && flag_unsafe_math_optimizations"
16241 op0 = gen_reg_rtx (XFmode);
16243 operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
16245 ix86_emit_i387_log1p (op0, operands[1]);
16246 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16250 (define_insn "fxtractxf3_i387"
16251 [(set (match_operand:XF 0 "register_operand" "=f")
16252 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16253 UNSPEC_XTRACT_FRACT))
16254 (set (match_operand:XF 1 "register_operand" "=u")
16255 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
16256 "TARGET_USE_FANCY_MATH_387
16257 && flag_unsafe_math_optimizations"
16259 [(set_attr "type" "fpspc")
16260 (set_attr "znver1_decode" "vector")
16261 (set_attr "mode" "XF")])
16263 (define_insn "fxtract_extend<mode>xf3_i387"
16264 [(set (match_operand:XF 0 "register_operand" "=f")
16265 (unspec:XF [(float_extend:XF
16266 (match_operand:MODEF 2 "register_operand" "0"))]
16267 UNSPEC_XTRACT_FRACT))
16268 (set (match_operand:XF 1 "register_operand" "=u")
16269 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
16270 "TARGET_USE_FANCY_MATH_387
16271 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16272 || TARGET_MIX_SSE_I387)
16273 && flag_unsafe_math_optimizations"
16275 [(set_attr "type" "fpspc")
16276 (set_attr "znver1_decode" "vector")
16277 (set_attr "mode" "XF")])
16279 (define_expand "logbxf2"
16280 [(parallel [(set (match_dup 2)
16281 (unspec:XF [(match_operand:XF 1 "register_operand")]
16282 UNSPEC_XTRACT_FRACT))
16283 (set (match_operand:XF 0 "register_operand")
16284 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
16285 "TARGET_USE_FANCY_MATH_387
16286 && flag_unsafe_math_optimizations"
16287 "operands[2] = gen_reg_rtx (XFmode);")
16289 (define_expand "logb<mode>2"
16290 [(use (match_operand:MODEF 0 "register_operand"))
16291 (use (match_operand:MODEF 1 "register_operand"))]
16292 "TARGET_USE_FANCY_MATH_387
16293 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16294 || TARGET_MIX_SSE_I387)
16295 && flag_unsafe_math_optimizations"
16297 rtx op0 = gen_reg_rtx (XFmode);
16298 rtx op1 = gen_reg_rtx (XFmode);
16300 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
16301 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1));
16305 (define_expand "ilogbxf2"
16306 [(use (match_operand:SI 0 "register_operand"))
16307 (use (match_operand:XF 1 "register_operand"))]
16308 "TARGET_USE_FANCY_MATH_387
16309 && flag_unsafe_math_optimizations"
16313 if (optimize_insn_for_size_p ())
16316 op0 = gen_reg_rtx (XFmode);
16317 op1 = gen_reg_rtx (XFmode);
16319 emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
16320 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
16324 (define_expand "ilogb<mode>2"
16325 [(use (match_operand:SI 0 "register_operand"))
16326 (use (match_operand:MODEF 1 "register_operand"))]
16327 "TARGET_USE_FANCY_MATH_387
16328 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16329 || TARGET_MIX_SSE_I387)
16330 && flag_unsafe_math_optimizations"
16334 if (optimize_insn_for_size_p ())
16337 op0 = gen_reg_rtx (XFmode);
16338 op1 = gen_reg_rtx (XFmode);
16340 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
16341 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
16345 (define_insn "*f2xm1xf2_i387"
16346 [(set (match_operand:XF 0 "register_operand" "=f")
16347 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16349 "TARGET_USE_FANCY_MATH_387
16350 && flag_unsafe_math_optimizations"
16352 [(set_attr "type" "fpspc")
16353 (set_attr "znver1_decode" "vector")
16354 (set_attr "mode" "XF")])
16356 (define_insn "fscalexf4_i387"
16357 [(set (match_operand:XF 0 "register_operand" "=f")
16358 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16359 (match_operand:XF 3 "register_operand" "1")]
16360 UNSPEC_FSCALE_FRACT))
16361 (set (match_operand:XF 1 "register_operand" "=u")
16362 (unspec:XF [(match_dup 2) (match_dup 3)]
16363 UNSPEC_FSCALE_EXP))]
16364 "TARGET_USE_FANCY_MATH_387
16365 && flag_unsafe_math_optimizations"
16367 [(set_attr "type" "fpspc")
16368 (set_attr "znver1_decode" "vector")
16369 (set_attr "mode" "XF")])
16371 (define_expand "expNcorexf3"
16372 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand")
16373 (match_operand:XF 2 "register_operand")))
16374 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16375 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16376 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16377 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
16378 (parallel [(set (match_operand:XF 0 "register_operand")
16379 (unspec:XF [(match_dup 8) (match_dup 4)]
16380 UNSPEC_FSCALE_FRACT))
16382 (unspec:XF [(match_dup 8) (match_dup 4)]
16383 UNSPEC_FSCALE_EXP))])]
16384 "TARGET_USE_FANCY_MATH_387
16385 && flag_unsafe_math_optimizations"
16389 for (i = 3; i < 10; i++)
16390 operands[i] = gen_reg_rtx (XFmode);
16392 emit_move_insn (operands[7], CONST1_RTX (XFmode)); /* fld1 */
16395 (define_expand "expxf2"
16396 [(use (match_operand:XF 0 "register_operand"))
16397 (use (match_operand:XF 1 "register_operand"))]
16398 "TARGET_USE_FANCY_MATH_387
16399 && flag_unsafe_math_optimizations"
16403 op2 = gen_reg_rtx (XFmode);
16404 emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */
16406 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
16410 (define_expand "exp<mode>2"
16411 [(use (match_operand:MODEF 0 "register_operand"))
16412 (use (match_operand:MODEF 1 "general_operand"))]
16413 "TARGET_USE_FANCY_MATH_387
16414 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16415 || TARGET_MIX_SSE_I387)
16416 && flag_unsafe_math_optimizations"
16420 op0 = gen_reg_rtx (XFmode);
16421 op1 = gen_reg_rtx (XFmode);
16423 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16424 emit_insn (gen_expxf2 (op0, op1));
16425 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16429 (define_expand "exp10xf2"
16430 [(use (match_operand:XF 0 "register_operand"))
16431 (use (match_operand:XF 1 "register_operand"))]
16432 "TARGET_USE_FANCY_MATH_387
16433 && flag_unsafe_math_optimizations"
16437 op2 = gen_reg_rtx (XFmode);
16438 emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */
16440 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
16444 (define_expand "exp10<mode>2"
16445 [(use (match_operand:MODEF 0 "register_operand"))
16446 (use (match_operand:MODEF 1 "general_operand"))]
16447 "TARGET_USE_FANCY_MATH_387
16448 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16449 || TARGET_MIX_SSE_I387)
16450 && flag_unsafe_math_optimizations"
16454 op0 = gen_reg_rtx (XFmode);
16455 op1 = gen_reg_rtx (XFmode);
16457 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16458 emit_insn (gen_exp10xf2 (op0, op1));
16459 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16463 (define_expand "exp2xf2"
16464 [(use (match_operand:XF 0 "register_operand"))
16465 (use (match_operand:XF 1 "register_operand"))]
16466 "TARGET_USE_FANCY_MATH_387
16467 && flag_unsafe_math_optimizations"
16471 op2 = gen_reg_rtx (XFmode);
16472 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
16474 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
16478 (define_expand "exp2<mode>2"
16479 [(use (match_operand:MODEF 0 "register_operand"))
16480 (use (match_operand:MODEF 1 "general_operand"))]
16481 "TARGET_USE_FANCY_MATH_387
16482 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16483 || TARGET_MIX_SSE_I387)
16484 && flag_unsafe_math_optimizations"
16488 op0 = gen_reg_rtx (XFmode);
16489 op1 = gen_reg_rtx (XFmode);
16491 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16492 emit_insn (gen_exp2xf2 (op0, op1));
16493 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16497 (define_expand "expm1xf2"
16498 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand")
16500 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16501 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16502 (set (match_dup 9) (float_extend:XF (match_dup 13)))
16503 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16504 (parallel [(set (match_dup 7)
16505 (unspec:XF [(match_dup 6) (match_dup 4)]
16506 UNSPEC_FSCALE_FRACT))
16508 (unspec:XF [(match_dup 6) (match_dup 4)]
16509 UNSPEC_FSCALE_EXP))])
16510 (parallel [(set (match_dup 10)
16511 (unspec:XF [(match_dup 9) (match_dup 8)]
16512 UNSPEC_FSCALE_FRACT))
16513 (set (match_dup 11)
16514 (unspec:XF [(match_dup 9) (match_dup 8)]
16515 UNSPEC_FSCALE_EXP))])
16516 (set (match_dup 12) (minus:XF (match_dup 10)
16517 (float_extend:XF (match_dup 13))))
16518 (set (match_operand:XF 0 "register_operand")
16519 (plus:XF (match_dup 12) (match_dup 7)))]
16520 "TARGET_USE_FANCY_MATH_387
16521 && flag_unsafe_math_optimizations"
16525 for (i = 2; i < 13; i++)
16526 operands[i] = gen_reg_rtx (XFmode);
16529 = validize_mem (force_const_mem (SFmode, CONST1_RTX (SFmode))); /* fld1 */
16531 emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
16534 (define_expand "expm1<mode>2"
16535 [(use (match_operand:MODEF 0 "register_operand"))
16536 (use (match_operand:MODEF 1 "general_operand"))]
16537 "TARGET_USE_FANCY_MATH_387
16538 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16539 || TARGET_MIX_SSE_I387)
16540 && flag_unsafe_math_optimizations"
16544 op0 = gen_reg_rtx (XFmode);
16545 op1 = gen_reg_rtx (XFmode);
16547 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16548 emit_insn (gen_expm1xf2 (op0, op1));
16549 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16553 (define_expand "ldexpxf3"
16554 [(match_operand:XF 0 "register_operand")
16555 (match_operand:XF 1 "register_operand")
16556 (match_operand:SI 2 "register_operand")]
16557 "TARGET_USE_FANCY_MATH_387
16558 && flag_unsafe_math_optimizations"
16562 tmp1 = gen_reg_rtx (XFmode);
16563 tmp2 = gen_reg_rtx (XFmode);
16565 emit_insn (gen_floatsixf2 (tmp1, operands[2]));
16566 emit_insn (gen_fscalexf4_i387 (operands[0], tmp2,
16567 operands[1], tmp1));
16571 (define_expand "ldexp<mode>3"
16572 [(use (match_operand:MODEF 0 "register_operand"))
16573 (use (match_operand:MODEF 1 "general_operand"))
16574 (use (match_operand:SI 2 "register_operand"))]
16575 "TARGET_USE_FANCY_MATH_387
16576 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16577 || TARGET_MIX_SSE_I387)
16578 && flag_unsafe_math_optimizations"
16582 op0 = gen_reg_rtx (XFmode);
16583 op1 = gen_reg_rtx (XFmode);
16585 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16586 emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
16587 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16591 (define_expand "scalbxf3"
16592 [(parallel [(set (match_operand:XF 0 " register_operand")
16593 (unspec:XF [(match_operand:XF 1 "register_operand")
16594 (match_operand:XF 2 "register_operand")]
16595 UNSPEC_FSCALE_FRACT))
16597 (unspec:XF [(match_dup 1) (match_dup 2)]
16598 UNSPEC_FSCALE_EXP))])]
16599 "TARGET_USE_FANCY_MATH_387
16600 && flag_unsafe_math_optimizations"
16602 operands[3] = gen_reg_rtx (XFmode);
16605 (define_expand "scalb<mode>3"
16606 [(use (match_operand:MODEF 0 "register_operand"))
16607 (use (match_operand:MODEF 1 "general_operand"))
16608 (use (match_operand:MODEF 2 "general_operand"))]
16609 "TARGET_USE_FANCY_MATH_387
16610 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16611 || TARGET_MIX_SSE_I387)
16612 && flag_unsafe_math_optimizations"
16616 op0 = gen_reg_rtx (XFmode);
16617 op1 = gen_reg_rtx (XFmode);
16618 op2 = gen_reg_rtx (XFmode);
16620 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16621 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
16622 emit_insn (gen_scalbxf3 (op0, op1, op2));
16623 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16627 (define_expand "significandxf2"
16628 [(parallel [(set (match_operand:XF 0 "register_operand")
16629 (unspec:XF [(match_operand:XF 1 "register_operand")]
16630 UNSPEC_XTRACT_FRACT))
16632 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
16633 "TARGET_USE_FANCY_MATH_387
16634 && flag_unsafe_math_optimizations"
16635 "operands[2] = gen_reg_rtx (XFmode);")
16637 (define_expand "significand<mode>2"
16638 [(use (match_operand:MODEF 0 "register_operand"))
16639 (use (match_operand:MODEF 1 "register_operand"))]
16640 "TARGET_USE_FANCY_MATH_387
16641 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16642 || TARGET_MIX_SSE_I387)
16643 && flag_unsafe_math_optimizations"
16645 rtx op0 = gen_reg_rtx (XFmode);
16646 rtx op1 = gen_reg_rtx (XFmode);
16648 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
16649 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16654 (define_insn "sse4_1_round<mode>2"
16655 [(set (match_operand:MODEF 0 "register_operand" "=x,v")
16656 (unspec:MODEF [(match_operand:MODEF 1 "nonimmediate_operand" "xm,vm")
16657 (match_operand:SI 2 "const_0_to_15_operand" "n,n")]
16661 %vround<ssemodesuffix>\t{%2, %1, %d0|%d0, %1, %2}
16662 vrndscale<ssemodesuffix>\t{%2, %1, %d0|%d0, %1, %2}"
16663 [(set_attr "type" "ssecvt")
16664 (set_attr "prefix_extra" "1,*")
16665 (set_attr "length_immediate" "*,1")
16666 (set_attr "prefix" "maybe_vex,evex")
16667 (set_attr "isa" "noavx512f,avx512f")
16668 (set_attr "mode" "<MODE>")])
16670 (define_insn "rintxf2"
16671 [(set (match_operand:XF 0 "register_operand" "=f")
16672 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16674 "TARGET_USE_FANCY_MATH_387"
16676 [(set_attr "type" "fpspc")
16677 (set_attr "znver1_decode" "vector")
16678 (set_attr "mode" "XF")])
16680 (define_insn "rint<mode>2_frndint"
16681 [(set (match_operand:MODEF 0 "register_operand" "=f")
16682 (unspec:MODEF [(match_operand:MODEF 1 "register_operand" "0")]
16684 "TARGET_USE_FANCY_MATH_387"
16686 [(set_attr "type" "fpspc")
16687 (set_attr "znver1_decode" "vector")
16688 (set_attr "mode" "<MODE>")])
16690 (define_expand "rint<mode>2"
16691 [(use (match_operand:MODEF 0 "register_operand"))
16692 (use (match_operand:MODEF 1 "register_operand"))]
16693 "(TARGET_USE_FANCY_MATH_387
16694 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16695 || TARGET_MIX_SSE_I387))
16696 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
16698 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16701 emit_insn (gen_sse4_1_round<mode>2
16702 (operands[0], operands[1], GEN_INT (ROUND_MXCSR)));
16704 ix86_expand_rint (operands[0], operands[1]);
16707 emit_insn (gen_rint<mode>2_frndint (operands[0], operands[1]));
16711 (define_expand "round<mode>2"
16712 [(match_operand:X87MODEF 0 "register_operand")
16713 (match_operand:X87MODEF 1 "nonimmediate_operand")]
16714 "(TARGET_USE_FANCY_MATH_387
16715 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16716 || TARGET_MIX_SSE_I387)
16717 && flag_unsafe_math_optimizations
16718 && (flag_fp_int_builtin_inexact || !flag_trapping_math))
16719 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16720 && !flag_trapping_math && !flag_rounding_math)"
16722 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16723 && !flag_trapping_math && !flag_rounding_math)
16727 operands[1] = force_reg (<MODE>mode, operands[1]);
16728 ix86_expand_round_sse4 (operands[0], operands[1]);
16730 else if (TARGET_64BIT || (<MODE>mode != DFmode))
16731 ix86_expand_round (operands[0], operands[1]);
16733 ix86_expand_rounddf_32 (operands[0], operands[1]);
16737 operands[1] = force_reg (<MODE>mode, operands[1]);
16738 ix86_emit_i387_round (operands[0], operands[1]);
16743 (define_insn_and_split "*fistdi2_1"
16744 [(set (match_operand:DI 0 "nonimmediate_operand")
16745 (unspec:DI [(match_operand:XF 1 "register_operand")]
16747 "TARGET_USE_FANCY_MATH_387
16748 && can_create_pseudo_p ()"
16753 if (memory_operand (operands[0], VOIDmode))
16754 emit_insn (gen_fistdi2 (operands[0], operands[1]));
16757 operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
16758 emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
16763 [(set_attr "type" "fpspc")
16764 (set_attr "mode" "DI")])
16766 (define_insn "fistdi2"
16767 [(set (match_operand:DI 0 "memory_operand" "=m")
16768 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
16770 (clobber (match_scratch:XF 2 "=&1f"))]
16771 "TARGET_USE_FANCY_MATH_387"
16772 "* return output_fix_trunc (insn, operands, false);"
16773 [(set_attr "type" "fpspc")
16774 (set_attr "mode" "DI")])
16776 (define_insn "fistdi2_with_temp"
16777 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
16778 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
16780 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))
16781 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
16782 "TARGET_USE_FANCY_MATH_387"
16784 [(set_attr "type" "fpspc")
16785 (set_attr "mode" "DI")])
16788 [(set (match_operand:DI 0 "register_operand")
16789 (unspec:DI [(match_operand:XF 1 "register_operand")]
16791 (clobber (match_operand:DI 2 "memory_operand"))
16792 (clobber (match_scratch 3))]
16794 [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
16795 (clobber (match_dup 3))])
16796 (set (match_dup 0) (match_dup 2))])
16799 [(set (match_operand:DI 0 "memory_operand")
16800 (unspec:DI [(match_operand:XF 1 "register_operand")]
16802 (clobber (match_operand:DI 2 "memory_operand"))
16803 (clobber (match_scratch 3))]
16805 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
16806 (clobber (match_dup 3))])])
16808 (define_insn_and_split "*fist<mode>2_1"
16809 [(set (match_operand:SWI24 0 "register_operand")
16810 (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
16812 "TARGET_USE_FANCY_MATH_387
16813 && can_create_pseudo_p ()"
16818 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
16819 emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
16823 [(set_attr "type" "fpspc")
16824 (set_attr "mode" "<MODE>")])
16826 (define_insn "fist<mode>2"
16827 [(set (match_operand:SWI24 0 "memory_operand" "=m")
16828 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
16830 "TARGET_USE_FANCY_MATH_387"
16831 "* return output_fix_trunc (insn, operands, false);"
16832 [(set_attr "type" "fpspc")
16833 (set_attr "mode" "<MODE>")])
16835 (define_insn "fist<mode>2_with_temp"
16836 [(set (match_operand:SWI24 0 "register_operand" "=r")
16837 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
16839 (clobber (match_operand:SWI24 2 "memory_operand" "=m"))]
16840 "TARGET_USE_FANCY_MATH_387"
16842 [(set_attr "type" "fpspc")
16843 (set_attr "mode" "<MODE>")])
16846 [(set (match_operand:SWI24 0 "register_operand")
16847 (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
16849 (clobber (match_operand:SWI24 2 "memory_operand"))]
16851 [(set (match_dup 2) (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST))
16852 (set (match_dup 0) (match_dup 2))])
16855 [(set (match_operand:SWI24 0 "memory_operand")
16856 (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
16858 (clobber (match_operand:SWI24 2 "memory_operand"))]
16860 [(set (match_dup 0) (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST))])
16862 (define_expand "lrintxf<mode>2"
16863 [(set (match_operand:SWI248x 0 "nonimmediate_operand")
16864 (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
16866 "TARGET_USE_FANCY_MATH_387")
16868 (define_expand "lrint<MODEF:mode><SWI48:mode>2"
16869 [(set (match_operand:SWI48 0 "nonimmediate_operand")
16870 (unspec:SWI48 [(match_operand:MODEF 1 "register_operand")]
16871 UNSPEC_FIX_NOTRUNC))]
16872 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH")
16874 (define_expand "lround<X87MODEF:mode><SWI248x:mode>2"
16875 [(match_operand:SWI248x 0 "nonimmediate_operand")
16876 (match_operand:X87MODEF 1 "register_operand")]
16877 "(TARGET_USE_FANCY_MATH_387
16878 && (!(SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
16879 || TARGET_MIX_SSE_I387)
16880 && flag_unsafe_math_optimizations)
16881 || (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
16882 && <SWI248x:MODE>mode != HImode
16883 && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT)
16884 && !flag_trapping_math && !flag_rounding_math)"
16886 if (optimize_insn_for_size_p ())
16889 if (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
16890 && <SWI248x:MODE>mode != HImode
16891 && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT)
16892 && !flag_trapping_math && !flag_rounding_math)
16893 ix86_expand_lround (operands[0], operands[1]);
16895 ix86_emit_i387_round (operands[0], operands[1]);
16899 (define_int_iterator FRNDINT_ROUNDING
16900 [UNSPEC_FRNDINT_FLOOR
16901 UNSPEC_FRNDINT_CEIL
16902 UNSPEC_FRNDINT_TRUNC])
16904 (define_int_iterator FIST_ROUNDING
16908 ;; Base name for define_insn
16909 (define_int_attr rounding_insn
16910 [(UNSPEC_FRNDINT_FLOOR "floor")
16911 (UNSPEC_FRNDINT_CEIL "ceil")
16912 (UNSPEC_FRNDINT_TRUNC "btrunc")
16913 (UNSPEC_FIST_FLOOR "floor")
16914 (UNSPEC_FIST_CEIL "ceil")])
16916 (define_int_attr rounding
16917 [(UNSPEC_FRNDINT_FLOOR "floor")
16918 (UNSPEC_FRNDINT_CEIL "ceil")
16919 (UNSPEC_FRNDINT_TRUNC "trunc")
16920 (UNSPEC_FIST_FLOOR "floor")
16921 (UNSPEC_FIST_CEIL "ceil")])
16923 (define_int_attr ROUNDING
16924 [(UNSPEC_FRNDINT_FLOOR "FLOOR")
16925 (UNSPEC_FRNDINT_CEIL "CEIL")
16926 (UNSPEC_FRNDINT_TRUNC "TRUNC")
16927 (UNSPEC_FIST_FLOOR "FLOOR")
16928 (UNSPEC_FIST_CEIL "CEIL")])
16930 ;; Rounding mode control word calculation could clobber FLAGS_REG.
16931 (define_insn_and_split "frndint<mode>2_<rounding>"
16932 [(set (match_operand:X87MODEF 0 "register_operand")
16933 (unspec:X87MODEF [(match_operand:X87MODEF 1 "register_operand")]
16935 (clobber (reg:CC FLAGS_REG))]
16936 "TARGET_USE_FANCY_MATH_387
16937 && (flag_fp_int_builtin_inexact || !flag_trapping_math)
16938 && can_create_pseudo_p ()"
16943 ix86_optimize_mode_switching[I387_<ROUNDING>] = 1;
16945 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
16946 operands[3] = assign_386_stack_local (HImode, SLOT_CW_<ROUNDING>);
16948 emit_insn (gen_frndint<mode>2_<rounding>_i387 (operands[0], operands[1],
16949 operands[2], operands[3]));
16952 [(set_attr "type" "frndint")
16953 (set_attr "i387_cw" "<rounding>")
16954 (set_attr "mode" "<MODE>")])
16956 (define_insn "frndint<mode>2_<rounding>_i387"
16957 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
16958 (unspec:X87MODEF [(match_operand:X87MODEF 1 "register_operand" "0")]
16960 (use (match_operand:HI 2 "memory_operand" "m"))
16961 (use (match_operand:HI 3 "memory_operand" "m"))]
16962 "TARGET_USE_FANCY_MATH_387
16963 && (flag_fp_int_builtin_inexact || !flag_trapping_math)"
16964 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
16965 [(set_attr "type" "frndint")
16966 (set_attr "i387_cw" "<rounding>")
16967 (set_attr "mode" "<MODE>")])
16969 (define_expand "<rounding_insn>xf2"
16970 [(parallel [(set (match_operand:XF 0 "register_operand")
16971 (unspec:XF [(match_operand:XF 1 "register_operand")]
16973 (clobber (reg:CC FLAGS_REG))])]
16974 "TARGET_USE_FANCY_MATH_387
16975 && (flag_fp_int_builtin_inexact || !flag_trapping_math)")
16977 (define_expand "<rounding_insn><mode>2"
16978 [(parallel [(set (match_operand:MODEF 0 "register_operand")
16979 (unspec:MODEF [(match_operand:MODEF 1 "register_operand")]
16981 (clobber (reg:CC FLAGS_REG))])]
16982 "(TARGET_USE_FANCY_MATH_387
16983 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16984 || TARGET_MIX_SSE_I387)
16985 && (flag_fp_int_builtin_inexact || !flag_trapping_math))
16986 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16987 && (TARGET_SSE4_1 || !flag_trapping_math
16988 || flag_fp_int_builtin_inexact))"
16990 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16991 && (TARGET_SSE4_1 || !flag_trapping_math || flag_fp_int_builtin_inexact))
16994 emit_insn (gen_sse4_1_round<mode>2
16995 (operands[0], operands[1], GEN_INT (ROUND_<ROUNDING>
16997 else if (TARGET_64BIT || (<MODE>mode != DFmode))
16999 if (ROUND_<ROUNDING> == ROUND_FLOOR)
17000 ix86_expand_floorceil (operands[0], operands[1], true);
17001 else if (ROUND_<ROUNDING> == ROUND_CEIL)
17002 ix86_expand_floorceil (operands[0], operands[1], false);
17003 else if (ROUND_<ROUNDING> == ROUND_TRUNC)
17004 ix86_expand_trunc (operands[0], operands[1]);
17006 gcc_unreachable ();
17010 if (ROUND_<ROUNDING> == ROUND_FLOOR)
17011 ix86_expand_floorceildf_32 (operands[0], operands[1], true);
17012 else if (ROUND_<ROUNDING> == ROUND_CEIL)
17013 ix86_expand_floorceildf_32 (operands[0], operands[1], false);
17014 else if (ROUND_<ROUNDING> == ROUND_TRUNC)
17015 ix86_expand_truncdf_32 (operands[0], operands[1]);
17017 gcc_unreachable ();
17021 emit_insn (gen_frndint<mode>2_<rounding> (operands[0], operands[1]));
17025 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17026 (define_insn_and_split "frndintxf2_mask_pm"
17027 [(set (match_operand:XF 0 "register_operand")
17028 (unspec:XF [(match_operand:XF 1 "register_operand")]
17029 UNSPEC_FRNDINT_MASK_PM))
17030 (clobber (reg:CC FLAGS_REG))]
17031 "TARGET_USE_FANCY_MATH_387
17032 && flag_unsafe_math_optimizations
17033 && can_create_pseudo_p ()"
17038 ix86_optimize_mode_switching[I387_MASK_PM] = 1;
17040 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17041 operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
17043 emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
17044 operands[2], operands[3]));
17047 [(set_attr "type" "frndint")
17048 (set_attr "i387_cw" "mask_pm")
17049 (set_attr "mode" "XF")])
17051 (define_insn "frndintxf2_mask_pm_i387"
17052 [(set (match_operand:XF 0 "register_operand" "=f")
17053 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17054 UNSPEC_FRNDINT_MASK_PM))
17055 (use (match_operand:HI 2 "memory_operand" "m"))
17056 (use (match_operand:HI 3 "memory_operand" "m"))]
17057 "TARGET_USE_FANCY_MATH_387
17058 && flag_unsafe_math_optimizations"
17059 "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
17060 [(set_attr "type" "frndint")
17061 (set_attr "i387_cw" "mask_pm")
17062 (set_attr "mode" "XF")])
17064 (define_expand "nearbyintxf2"
17065 [(parallel [(set (match_operand:XF 0 "register_operand")
17066 (unspec:XF [(match_operand:XF 1 "register_operand")]
17067 UNSPEC_FRNDINT_MASK_PM))
17068 (clobber (reg:CC FLAGS_REG))])]
17069 "TARGET_USE_FANCY_MATH_387
17070 && flag_unsafe_math_optimizations")
17072 (define_expand "nearbyint<mode>2"
17073 [(use (match_operand:MODEF 0 "register_operand"))
17074 (use (match_operand:MODEF 1 "register_operand"))]
17075 "TARGET_USE_FANCY_MATH_387
17076 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17077 || TARGET_MIX_SSE_I387)
17078 && flag_unsafe_math_optimizations"
17080 rtx op0 = gen_reg_rtx (XFmode);
17081 rtx op1 = gen_reg_rtx (XFmode);
17083 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17084 emit_insn (gen_frndintxf2_mask_pm (op0, op1));
17086 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17090 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17091 (define_insn_and_split "*fist<mode>2_<rounding>_1"
17092 [(set (match_operand:SWI248x 0 "nonimmediate_operand")
17093 (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
17095 (clobber (reg:CC FLAGS_REG))]
17096 "TARGET_USE_FANCY_MATH_387
17097 && flag_unsafe_math_optimizations
17098 && can_create_pseudo_p ()"
17103 ix86_optimize_mode_switching[I387_<ROUNDING>] = 1;
17105 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17106 operands[3] = assign_386_stack_local (HImode, SLOT_CW_<ROUNDING>);
17107 if (memory_operand (operands[0], VOIDmode))
17108 emit_insn (gen_fist<mode>2_<rounding> (operands[0], operands[1],
17109 operands[2], operands[3]));
17112 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17113 emit_insn (gen_fist<mode>2_<rounding>_with_temp
17114 (operands[0], operands[1], operands[2],
17115 operands[3], operands[4]));
17119 [(set_attr "type" "fistp")
17120 (set_attr "i387_cw" "<rounding>")
17121 (set_attr "mode" "<MODE>")])
17123 (define_insn "fistdi2_<rounding>"
17124 [(set (match_operand:DI 0 "memory_operand" "=m")
17125 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17127 (use (match_operand:HI 2 "memory_operand" "m"))
17128 (use (match_operand:HI 3 "memory_operand" "m"))
17129 (clobber (match_scratch:XF 4 "=&1f"))]
17130 "TARGET_USE_FANCY_MATH_387
17131 && flag_unsafe_math_optimizations"
17132 "* return output_fix_trunc (insn, operands, false);"
17133 [(set_attr "type" "fistp")
17134 (set_attr "i387_cw" "<rounding>")
17135 (set_attr "mode" "DI")])
17137 (define_insn "fistdi2_<rounding>_with_temp"
17138 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17139 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17141 (use (match_operand:HI 2 "memory_operand" "m,m"))
17142 (use (match_operand:HI 3 "memory_operand" "m,m"))
17143 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
17144 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
17145 "TARGET_USE_FANCY_MATH_387
17146 && flag_unsafe_math_optimizations"
17148 [(set_attr "type" "fistp")
17149 (set_attr "i387_cw" "<rounding>")
17150 (set_attr "mode" "DI")])
17153 [(set (match_operand:DI 0 "register_operand")
17154 (unspec:DI [(match_operand:XF 1 "register_operand")]
17156 (use (match_operand:HI 2 "memory_operand"))
17157 (use (match_operand:HI 3 "memory_operand"))
17158 (clobber (match_operand:DI 4 "memory_operand"))
17159 (clobber (match_scratch 5))]
17161 [(parallel [(set (match_dup 4)
17162 (unspec:DI [(match_dup 1)] FIST_ROUNDING))
17163 (use (match_dup 2))
17164 (use (match_dup 3))
17165 (clobber (match_dup 5))])
17166 (set (match_dup 0) (match_dup 4))])
17169 [(set (match_operand:DI 0 "memory_operand")
17170 (unspec:DI [(match_operand:XF 1 "register_operand")]
17172 (use (match_operand:HI 2 "memory_operand"))
17173 (use (match_operand:HI 3 "memory_operand"))
17174 (clobber (match_operand:DI 4 "memory_operand"))
17175 (clobber (match_scratch 5))]
17177 [(parallel [(set (match_dup 0)
17178 (unspec:DI [(match_dup 1)] FIST_ROUNDING))
17179 (use (match_dup 2))
17180 (use (match_dup 3))
17181 (clobber (match_dup 5))])])
17183 (define_insn "fist<mode>2_<rounding>"
17184 [(set (match_operand:SWI24 0 "memory_operand" "=m")
17185 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
17187 (use (match_operand:HI 2 "memory_operand" "m"))
17188 (use (match_operand:HI 3 "memory_operand" "m"))]
17189 "TARGET_USE_FANCY_MATH_387
17190 && flag_unsafe_math_optimizations"
17191 "* return output_fix_trunc (insn, operands, false);"
17192 [(set_attr "type" "fistp")
17193 (set_attr "i387_cw" "<rounding>")
17194 (set_attr "mode" "<MODE>")])
17196 (define_insn "fist<mode>2_<rounding>_with_temp"
17197 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
17198 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f,f")]
17200 (use (match_operand:HI 2 "memory_operand" "m,m"))
17201 (use (match_operand:HI 3 "memory_operand" "m,m"))
17202 (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
17203 "TARGET_USE_FANCY_MATH_387
17204 && flag_unsafe_math_optimizations"
17206 [(set_attr "type" "fistp")
17207 (set_attr "i387_cw" "<rounding>")
17208 (set_attr "mode" "<MODE>")])
17211 [(set (match_operand:SWI24 0 "register_operand")
17212 (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
17214 (use (match_operand:HI 2 "memory_operand"))
17215 (use (match_operand:HI 3 "memory_operand"))
17216 (clobber (match_operand:SWI24 4 "memory_operand"))]
17218 [(parallel [(set (match_dup 4)
17219 (unspec:SWI24 [(match_dup 1)] FIST_ROUNDING))
17220 (use (match_dup 2))
17221 (use (match_dup 3))])
17222 (set (match_dup 0) (match_dup 4))])
17225 [(set (match_operand:SWI24 0 "memory_operand")
17226 (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
17228 (use (match_operand:HI 2 "memory_operand"))
17229 (use (match_operand:HI 3 "memory_operand"))
17230 (clobber (match_operand:SWI24 4 "memory_operand"))]
17232 [(parallel [(set (match_dup 0)
17233 (unspec:SWI24 [(match_dup 1)] FIST_ROUNDING))
17234 (use (match_dup 2))
17235 (use (match_dup 3))])])
17237 (define_expand "l<rounding_insn>xf<mode>2"
17238 [(parallel [(set (match_operand:SWI248x 0 "nonimmediate_operand")
17239 (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
17241 (clobber (reg:CC FLAGS_REG))])]
17242 "TARGET_USE_FANCY_MATH_387
17243 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17244 && flag_unsafe_math_optimizations")
17246 (define_expand "l<rounding_insn><MODEF:mode><SWI48:mode>2"
17247 [(parallel [(set (match_operand:SWI48 0 "nonimmediate_operand")
17248 (unspec:SWI48 [(match_operand:MODEF 1 "register_operand")]
17250 (clobber (reg:CC FLAGS_REG))])]
17251 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
17252 && (TARGET_SSE4_1 || !flag_trapping_math)"
17256 rtx tmp = gen_reg_rtx (<MODEF:MODE>mode);
17258 emit_insn (gen_sse4_1_round<mode>2
17259 (tmp, operands[1], GEN_INT (ROUND_<ROUNDING>
17261 emit_insn (gen_fix_trunc<MODEF:mode><SWI48:mode>2
17262 (operands[0], tmp));
17264 else if (ROUND_<ROUNDING> == ROUND_FLOOR)
17265 ix86_expand_lfloorceil (operands[0], operands[1], true);
17266 else if (ROUND_<ROUNDING> == ROUND_CEIL)
17267 ix86_expand_lfloorceil (operands[0], operands[1], false);
17269 gcc_unreachable ();
17274 (define_insn "fxam<mode>2_i387"
17275 [(set (match_operand:HI 0 "register_operand" "=a")
17277 [(match_operand:X87MODEF 1 "register_operand" "f")]
17279 "TARGET_USE_FANCY_MATH_387"
17280 "fxam\n\tfnstsw\t%0"
17281 [(set_attr "type" "multi")
17282 (set_attr "length" "4")
17283 (set_attr "unit" "i387")
17284 (set_attr "mode" "<MODE>")])
17286 (define_insn_and_split "fxam<mode>2_i387_with_temp"
17287 [(set (match_operand:HI 0 "register_operand")
17289 [(match_operand:MODEF 1 "memory_operand")]
17291 "TARGET_USE_FANCY_MATH_387
17292 && can_create_pseudo_p ()"
17295 [(set (match_dup 2)(match_dup 1))
17297 (unspec:HI [(match_dup 2)] UNSPEC_FXAM))]
17299 operands[2] = gen_reg_rtx (<MODE>mode);
17301 MEM_VOLATILE_P (operands[1]) = 1;
17303 [(set_attr "type" "multi")
17304 (set_attr "unit" "i387")
17305 (set_attr "mode" "<MODE>")])
17307 (define_expand "isinfxf2"
17308 [(use (match_operand:SI 0 "register_operand"))
17309 (use (match_operand:XF 1 "register_operand"))]
17310 "TARGET_USE_FANCY_MATH_387
17311 && ix86_libc_has_function (function_c99_misc)"
17313 rtx mask = GEN_INT (0x45);
17314 rtx val = GEN_INT (0x05);
17316 rtx scratch = gen_reg_rtx (HImode);
17317 rtx res = gen_reg_rtx (QImode);
17319 emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
17321 emit_insn (gen_andqi_ext_1 (scratch, scratch, mask));
17322 emit_insn (gen_cmpqi_ext_3 (scratch, val));
17323 ix86_expand_setcc (res, EQ,
17324 gen_rtx_REG (CCmode, FLAGS_REG), const0_rtx);
17325 emit_insn (gen_zero_extendqisi2 (operands[0], res));
17329 (define_expand "isinf<mode>2"
17330 [(use (match_operand:SI 0 "register_operand"))
17331 (use (match_operand:MODEF 1 "nonimmediate_operand"))]
17332 "TARGET_USE_FANCY_MATH_387
17333 && ix86_libc_has_function (function_c99_misc)
17334 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
17336 rtx mask = GEN_INT (0x45);
17337 rtx val = GEN_INT (0x05);
17339 rtx scratch = gen_reg_rtx (HImode);
17340 rtx res = gen_reg_rtx (QImode);
17342 /* Remove excess precision by forcing value through memory. */
17343 if (memory_operand (operands[1], VOIDmode))
17344 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, operands[1]));
17347 rtx temp = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17349 emit_move_insn (temp, operands[1]);
17350 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, temp));
17353 emit_insn (gen_andqi_ext_1 (scratch, scratch, mask));
17354 emit_insn (gen_cmpqi_ext_3 (scratch, val));
17355 ix86_expand_setcc (res, EQ,
17356 gen_rtx_REG (CCmode, FLAGS_REG), const0_rtx);
17357 emit_insn (gen_zero_extendqisi2 (operands[0], res));
17361 (define_expand "signbittf2"
17362 [(use (match_operand:SI 0 "register_operand"))
17363 (use (match_operand:TF 1 "register_operand"))]
17368 rtx mask = ix86_build_signbit_mask (TFmode, 0, 0);
17369 rtx scratch = gen_reg_rtx (QImode);
17371 emit_insn (gen_ptesttf2 (operands[1], mask));
17372 ix86_expand_setcc (scratch, NE,
17373 gen_rtx_REG (CCZmode, FLAGS_REG), const0_rtx);
17375 emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
17379 emit_insn (gen_sse_movmskps (operands[0],
17380 gen_lowpart (V4SFmode, operands[1])));
17381 emit_insn (gen_andsi3 (operands[0], operands[0], GEN_INT (0x8)));
17386 (define_expand "signbitxf2"
17387 [(use (match_operand:SI 0 "register_operand"))
17388 (use (match_operand:XF 1 "register_operand"))]
17389 "TARGET_USE_FANCY_MATH_387"
17391 rtx scratch = gen_reg_rtx (HImode);
17393 emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
17394 emit_insn (gen_andsi3 (operands[0],
17395 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
17399 (define_insn "movmsk_df"
17400 [(set (match_operand:SI 0 "register_operand" "=r")
17402 [(match_operand:DF 1 "register_operand" "x")]
17404 "SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH"
17405 "%vmovmskpd\t{%1, %0|%0, %1}"
17406 [(set_attr "type" "ssemov")
17407 (set_attr "prefix" "maybe_vex")
17408 (set_attr "mode" "DF")])
17410 ;; Use movmskpd in SSE mode to avoid store forwarding stall
17411 ;; for 32bit targets and movq+shrq sequence for 64bit targets.
17412 (define_expand "signbitdf2"
17413 [(use (match_operand:SI 0 "register_operand"))
17414 (use (match_operand:DF 1 "register_operand"))]
17415 "TARGET_USE_FANCY_MATH_387
17416 || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
17418 if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)
17420 emit_insn (gen_movmsk_df (operands[0], operands[1]));
17421 emit_insn (gen_andsi3 (operands[0], operands[0], const1_rtx));
17425 rtx scratch = gen_reg_rtx (HImode);
17427 emit_insn (gen_fxamdf2_i387 (scratch, operands[1]));
17428 emit_insn (gen_andsi3 (operands[0],
17429 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
17434 (define_expand "signbitsf2"
17435 [(use (match_operand:SI 0 "register_operand"))
17436 (use (match_operand:SF 1 "register_operand"))]
17437 "TARGET_USE_FANCY_MATH_387
17438 && !(SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH)"
17440 rtx scratch = gen_reg_rtx (HImode);
17442 emit_insn (gen_fxamsf2_i387 (scratch, operands[1]));
17443 emit_insn (gen_andsi3 (operands[0],
17444 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
17448 ;; Block operation instructions
17451 [(unspec_volatile [(const_int 0)] UNSPECV_CLD)]
17454 [(set_attr "length" "1")
17455 (set_attr "length_immediate" "0")
17456 (set_attr "modrm" "0")])
17458 (define_expand "movmem<mode>"
17459 [(use (match_operand:BLK 0 "memory_operand"))
17460 (use (match_operand:BLK 1 "memory_operand"))
17461 (use (match_operand:SWI48 2 "nonmemory_operand"))
17462 (use (match_operand:SWI48 3 "const_int_operand"))
17463 (use (match_operand:SI 4 "const_int_operand"))
17464 (use (match_operand:SI 5 "const_int_operand"))
17465 (use (match_operand:SI 6 ""))
17466 (use (match_operand:SI 7 ""))
17467 (use (match_operand:SI 8 ""))]
17470 if (ix86_expand_set_or_movmem (operands[0], operands[1],
17471 operands[2], NULL, operands[3],
17472 operands[4], operands[5],
17473 operands[6], operands[7],
17474 operands[8], false))
17480 ;; Most CPUs don't like single string operations
17481 ;; Handle this case here to simplify previous expander.
17483 (define_expand "strmov"
17484 [(set (match_dup 4) (match_operand 3 "memory_operand"))
17485 (set (match_operand 1 "memory_operand") (match_dup 4))
17486 (parallel [(set (match_operand 0 "register_operand") (match_dup 5))
17487 (clobber (reg:CC FLAGS_REG))])
17488 (parallel [(set (match_operand 2 "register_operand") (match_dup 6))
17489 (clobber (reg:CC FLAGS_REG))])]
17492 /* Can't use this for non-default address spaces. */
17493 if (!ADDR_SPACE_GENERIC_P (MEM_ADDR_SPACE (operands[3])))
17496 rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
17498 /* If .md ever supports :P for Pmode, these can be directly
17499 in the pattern above. */
17500 operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
17501 operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
17503 /* Can't use this if the user has appropriated esi or edi. */
17504 if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
17505 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG]))
17507 emit_insn (gen_strmov_singleop (operands[0], operands[1],
17508 operands[2], operands[3],
17509 operands[5], operands[6]));
17513 operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
17516 (define_expand "strmov_singleop"
17517 [(parallel [(set (match_operand 1 "memory_operand")
17518 (match_operand 3 "memory_operand"))
17519 (set (match_operand 0 "register_operand")
17521 (set (match_operand 2 "register_operand")
17522 (match_operand 5))])]
17526 ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
17529 (define_insn "*strmovdi_rex_1"
17530 [(set (mem:DI (match_operand:P 2 "register_operand" "0"))
17531 (mem:DI (match_operand:P 3 "register_operand" "1")))
17532 (set (match_operand:P 0 "register_operand" "=D")
17533 (plus:P (match_dup 2)
17535 (set (match_operand:P 1 "register_operand" "=S")
17536 (plus:P (match_dup 3)
17539 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG])
17540 && ix86_check_no_addr_space (insn)"
17542 [(set_attr "type" "str")
17543 (set_attr "memory" "both")
17544 (set_attr "mode" "DI")])
17546 (define_insn "*strmovsi_1"
17547 [(set (mem:SI (match_operand:P 2 "register_operand" "0"))
17548 (mem:SI (match_operand:P 3 "register_operand" "1")))
17549 (set (match_operand:P 0 "register_operand" "=D")
17550 (plus:P (match_dup 2)
17552 (set (match_operand:P 1 "register_operand" "=S")
17553 (plus:P (match_dup 3)
17555 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])
17556 && ix86_check_no_addr_space (insn)"
17558 [(set_attr "type" "str")
17559 (set_attr "memory" "both")
17560 (set_attr "mode" "SI")])
17562 (define_insn "*strmovhi_1"
17563 [(set (mem:HI (match_operand:P 2 "register_operand" "0"))
17564 (mem:HI (match_operand:P 3 "register_operand" "1")))
17565 (set (match_operand:P 0 "register_operand" "=D")
17566 (plus:P (match_dup 2)
17568 (set (match_operand:P 1 "register_operand" "=S")
17569 (plus:P (match_dup 3)
17571 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])
17572 && ix86_check_no_addr_space (insn)"
17574 [(set_attr "type" "str")
17575 (set_attr "memory" "both")
17576 (set_attr "mode" "HI")])
17578 (define_insn "*strmovqi_1"
17579 [(set (mem:QI (match_operand:P 2 "register_operand" "0"))
17580 (mem:QI (match_operand:P 3 "register_operand" "1")))
17581 (set (match_operand:P 0 "register_operand" "=D")
17582 (plus:P (match_dup 2)
17584 (set (match_operand:P 1 "register_operand" "=S")
17585 (plus:P (match_dup 3)
17587 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])
17588 && ix86_check_no_addr_space (insn)"
17590 [(set_attr "type" "str")
17591 (set_attr "memory" "both")
17592 (set (attr "prefix_rex")
17594 (match_test "<P:MODE>mode == DImode")
17596 (const_string "*")))
17597 (set_attr "mode" "QI")])
17599 (define_expand "rep_mov"
17600 [(parallel [(set (match_operand 4 "register_operand") (const_int 0))
17601 (set (match_operand 0 "register_operand")
17603 (set (match_operand 2 "register_operand")
17605 (set (match_operand 1 "memory_operand")
17606 (match_operand 3 "memory_operand"))
17607 (use (match_dup 4))])]
17611 ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
17614 (define_insn "*rep_movdi_rex64"
17615 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
17616 (set (match_operand:P 0 "register_operand" "=D")
17617 (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
17619 (match_operand:P 3 "register_operand" "0")))
17620 (set (match_operand:P 1 "register_operand" "=S")
17621 (plus:P (ashift:P (match_dup 5) (const_int 3))
17622 (match_operand:P 4 "register_operand" "1")))
17623 (set (mem:BLK (match_dup 3))
17624 (mem:BLK (match_dup 4)))
17625 (use (match_dup 5))]
17627 && !(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
17628 && ix86_check_no_addr_space (insn)"
17630 [(set_attr "type" "str")
17631 (set_attr "prefix_rep" "1")
17632 (set_attr "memory" "both")
17633 (set_attr "mode" "DI")])
17635 (define_insn "*rep_movsi"
17636 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
17637 (set (match_operand:P 0 "register_operand" "=D")
17638 (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
17640 (match_operand:P 3 "register_operand" "0")))
17641 (set (match_operand:P 1 "register_operand" "=S")
17642 (plus:P (ashift:P (match_dup 5) (const_int 2))
17643 (match_operand:P 4 "register_operand" "1")))
17644 (set (mem:BLK (match_dup 3))
17645 (mem:BLK (match_dup 4)))
17646 (use (match_dup 5))]
17647 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
17648 && ix86_check_no_addr_space (insn)"
17649 "%^rep{%;} movs{l|d}"
17650 [(set_attr "type" "str")
17651 (set_attr "prefix_rep" "1")
17652 (set_attr "memory" "both")
17653 (set_attr "mode" "SI")])
17655 (define_insn "*rep_movqi"
17656 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
17657 (set (match_operand:P 0 "register_operand" "=D")
17658 (plus:P (match_operand:P 3 "register_operand" "0")
17659 (match_operand:P 5 "register_operand" "2")))
17660 (set (match_operand:P 1 "register_operand" "=S")
17661 (plus:P (match_operand:P 4 "register_operand" "1") (match_dup 5)))
17662 (set (mem:BLK (match_dup 3))
17663 (mem:BLK (match_dup 4)))
17664 (use (match_dup 5))]
17665 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
17666 && ix86_check_no_addr_space (insn)"
17668 [(set_attr "type" "str")
17669 (set_attr "prefix_rep" "1")
17670 (set_attr "memory" "both")
17671 (set_attr "mode" "QI")])
17673 (define_expand "setmem<mode>"
17674 [(use (match_operand:BLK 0 "memory_operand"))
17675 (use (match_operand:SWI48 1 "nonmemory_operand"))
17676 (use (match_operand:QI 2 "nonmemory_operand"))
17677 (use (match_operand 3 "const_int_operand"))
17678 (use (match_operand:SI 4 "const_int_operand"))
17679 (use (match_operand:SI 5 "const_int_operand"))
17680 (use (match_operand:SI 6 ""))
17681 (use (match_operand:SI 7 ""))
17682 (use (match_operand:SI 8 ""))]
17685 if (ix86_expand_set_or_movmem (operands[0], NULL,
17686 operands[1], operands[2],
17687 operands[3], operands[4],
17688 operands[5], operands[6],
17689 operands[7], operands[8], true))
17695 ;; Most CPUs don't like single string operations
17696 ;; Handle this case here to simplify previous expander.
17698 (define_expand "strset"
17699 [(set (match_operand 1 "memory_operand")
17700 (match_operand 2 "register_operand"))
17701 (parallel [(set (match_operand 0 "register_operand")
17703 (clobber (reg:CC FLAGS_REG))])]
17706 /* Can't use this for non-default address spaces. */
17707 if (!ADDR_SPACE_GENERIC_P (MEM_ADDR_SPACE (operands[1])))
17710 if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
17711 operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
17713 /* If .md ever supports :P for Pmode, this can be directly
17714 in the pattern above. */
17715 operands[3] = gen_rtx_PLUS (Pmode, operands[0],
17716 GEN_INT (GET_MODE_SIZE (GET_MODE
17718 /* Can't use this if the user has appropriated eax or edi. */
17719 if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
17720 && !(fixed_regs[AX_REG] || fixed_regs[DI_REG]))
17722 emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
17728 (define_expand "strset_singleop"
17729 [(parallel [(set (match_operand 1 "memory_operand")
17730 (match_operand 2 "register_operand"))
17731 (set (match_operand 0 "register_operand")
17733 (unspec [(const_int 0)] UNSPEC_STOS)])]
17737 ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
17740 (define_insn "*strsetdi_rex_1"
17741 [(set (mem:DI (match_operand:P 1 "register_operand" "0"))
17742 (match_operand:DI 2 "register_operand" "a"))
17743 (set (match_operand:P 0 "register_operand" "=D")
17744 (plus:P (match_dup 1)
17746 (unspec [(const_int 0)] UNSPEC_STOS)]
17748 && !(fixed_regs[AX_REG] || fixed_regs[DI_REG])
17749 && ix86_check_no_addr_space (insn)"
17751 [(set_attr "type" "str")
17752 (set_attr "memory" "store")
17753 (set_attr "mode" "DI")])
17755 (define_insn "*strsetsi_1"
17756 [(set (mem:SI (match_operand:P 1 "register_operand" "0"))
17757 (match_operand:SI 2 "register_operand" "a"))
17758 (set (match_operand:P 0 "register_operand" "=D")
17759 (plus:P (match_dup 1)
17761 (unspec [(const_int 0)] UNSPEC_STOS)]
17762 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])
17763 && ix86_check_no_addr_space (insn)"
17765 [(set_attr "type" "str")
17766 (set_attr "memory" "store")
17767 (set_attr "mode" "SI")])
17769 (define_insn "*strsethi_1"
17770 [(set (mem:HI (match_operand:P 1 "register_operand" "0"))
17771 (match_operand:HI 2 "register_operand" "a"))
17772 (set (match_operand:P 0 "register_operand" "=D")
17773 (plus:P (match_dup 1)
17775 (unspec [(const_int 0)] UNSPEC_STOS)]
17776 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])
17777 && ix86_check_no_addr_space (insn)"
17779 [(set_attr "type" "str")
17780 (set_attr "memory" "store")
17781 (set_attr "mode" "HI")])
17783 (define_insn "*strsetqi_1"
17784 [(set (mem:QI (match_operand:P 1 "register_operand" "0"))
17785 (match_operand:QI 2 "register_operand" "a"))
17786 (set (match_operand:P 0 "register_operand" "=D")
17787 (plus:P (match_dup 1)
17789 (unspec [(const_int 0)] UNSPEC_STOS)]
17790 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])
17791 && ix86_check_no_addr_space (insn)"
17793 [(set_attr "type" "str")
17794 (set_attr "memory" "store")
17795 (set (attr "prefix_rex")
17797 (match_test "<P:MODE>mode == DImode")
17799 (const_string "*")))
17800 (set_attr "mode" "QI")])
17802 (define_expand "rep_stos"
17803 [(parallel [(set (match_operand 1 "register_operand") (const_int 0))
17804 (set (match_operand 0 "register_operand")
17806 (set (match_operand 2 "memory_operand") (const_int 0))
17807 (use (match_operand 3 "register_operand"))
17808 (use (match_dup 1))])]
17812 ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
17815 (define_insn "*rep_stosdi_rex64"
17816 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
17817 (set (match_operand:P 0 "register_operand" "=D")
17818 (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
17820 (match_operand:P 3 "register_operand" "0")))
17821 (set (mem:BLK (match_dup 3))
17823 (use (match_operand:DI 2 "register_operand" "a"))
17824 (use (match_dup 4))]
17826 && !(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])
17827 && ix86_check_no_addr_space (insn)"
17829 [(set_attr "type" "str")
17830 (set_attr "prefix_rep" "1")
17831 (set_attr "memory" "store")
17832 (set_attr "mode" "DI")])
17834 (define_insn "*rep_stossi"
17835 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
17836 (set (match_operand:P 0 "register_operand" "=D")
17837 (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
17839 (match_operand:P 3 "register_operand" "0")))
17840 (set (mem:BLK (match_dup 3))
17842 (use (match_operand:SI 2 "register_operand" "a"))
17843 (use (match_dup 4))]
17844 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])
17845 && ix86_check_no_addr_space (insn)"
17846 "%^rep{%;} stos{l|d}"
17847 [(set_attr "type" "str")
17848 (set_attr "prefix_rep" "1")
17849 (set_attr "memory" "store")
17850 (set_attr "mode" "SI")])
17852 (define_insn "*rep_stosqi"
17853 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
17854 (set (match_operand:P 0 "register_operand" "=D")
17855 (plus:P (match_operand:P 3 "register_operand" "0")
17856 (match_operand:P 4 "register_operand" "1")))
17857 (set (mem:BLK (match_dup 3))
17859 (use (match_operand:QI 2 "register_operand" "a"))
17860 (use (match_dup 4))]
17861 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])
17862 && ix86_check_no_addr_space (insn)"
17864 [(set_attr "type" "str")
17865 (set_attr "prefix_rep" "1")
17866 (set_attr "memory" "store")
17867 (set (attr "prefix_rex")
17869 (match_test "<P:MODE>mode == DImode")
17871 (const_string "*")))
17872 (set_attr "mode" "QI")])
17874 (define_expand "cmpstrnsi"
17875 [(set (match_operand:SI 0 "register_operand")
17876 (compare:SI (match_operand:BLK 1 "general_operand")
17877 (match_operand:BLK 2 "general_operand")))
17878 (use (match_operand 3 "general_operand"))
17879 (use (match_operand 4 "immediate_operand"))]
17882 rtx addr1, addr2, out, outlow, count, countreg, align;
17884 if (optimize_insn_for_size_p () && !TARGET_INLINE_ALL_STRINGOPS)
17887 /* Can't use this if the user has appropriated ecx, esi or edi. */
17888 if (fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
17891 /* One of the strings must be a constant. If so, expand_builtin_strncmp()
17892 will have rewritten the length arg to be the minimum of the const string
17893 length and the actual length arg. If both strings are the same and
17894 shorter than the length arg, repz cmpsb will not stop at the 0 byte and
17895 will incorrectly base the results on chars past the 0 byte. */
17896 tree t1 = MEM_EXPR (operands[1]);
17897 tree t2 = MEM_EXPR (operands[2]);
17898 if (!((t1 && TREE_CODE (t1) == MEM_REF
17899 && TREE_CODE (TREE_OPERAND (t1, 0)) == ADDR_EXPR
17900 && TREE_CODE (TREE_OPERAND (TREE_OPERAND (t1, 0), 0)) == STRING_CST)
17901 || (t2 && TREE_CODE (t2) == MEM_REF
17902 && TREE_CODE (TREE_OPERAND (t2, 0)) == ADDR_EXPR
17903 && TREE_CODE (TREE_OPERAND (TREE_OPERAND (t2, 0), 0)) == STRING_CST)))
17908 out = gen_reg_rtx (SImode);
17910 addr1 = copy_addr_to_reg (XEXP (operands[1], 0));
17911 addr2 = copy_addr_to_reg (XEXP (operands[2], 0));
17912 if (addr1 != XEXP (operands[1], 0))
17913 operands[1] = replace_equiv_address_nv (operands[1], addr1);
17914 if (addr2 != XEXP (operands[2], 0))
17915 operands[2] = replace_equiv_address_nv (operands[2], addr2);
17917 count = operands[3];
17918 countreg = ix86_zero_extend_to_Pmode (count);
17920 /* %%% Iff we are testing strict equality, we can use known alignment
17921 to good advantage. This may be possible with combine, particularly
17922 once cc0 is dead. */
17923 align = operands[4];
17925 if (CONST_INT_P (count))
17927 if (INTVAL (count) == 0)
17929 emit_move_insn (operands[0], const0_rtx);
17932 emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
17933 operands[1], operands[2]));
17937 rtx (*gen_cmp) (rtx, rtx);
17939 gen_cmp = (TARGET_64BIT
17940 ? gen_cmpdi_1 : gen_cmpsi_1);
17942 emit_insn (gen_cmp (countreg, countreg));
17943 emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
17944 operands[1], operands[2]));
17947 outlow = gen_lowpart (QImode, out);
17948 emit_insn (gen_cmpintqi (outlow));
17949 emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
17951 if (operands[0] != out)
17952 emit_move_insn (operands[0], out);
17957 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
17959 (define_expand "cmpintqi"
17960 [(set (match_dup 1)
17961 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
17963 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
17964 (parallel [(set (match_operand:QI 0 "register_operand")
17965 (minus:QI (match_dup 1)
17967 (clobber (reg:CC FLAGS_REG))])]
17970 operands[1] = gen_reg_rtx (QImode);
17971 operands[2] = gen_reg_rtx (QImode);
17974 ;; memcmp recognizers. The `cmpsb' opcode does nothing if the count is
17975 ;; zero. Emit extra code to make sure that a zero-length compare is EQ.
17977 (define_expand "cmpstrnqi_nz_1"
17978 [(parallel [(set (reg:CC FLAGS_REG)
17979 (compare:CC (match_operand 4 "memory_operand")
17980 (match_operand 5 "memory_operand")))
17981 (use (match_operand 2 "register_operand"))
17982 (use (match_operand:SI 3 "immediate_operand"))
17983 (clobber (match_operand 0 "register_operand"))
17984 (clobber (match_operand 1 "register_operand"))
17985 (clobber (match_dup 2))])]
17989 ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
17992 (define_insn "*cmpstrnqi_nz_1"
17993 [(set (reg:CC FLAGS_REG)
17994 (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
17995 (mem:BLK (match_operand:P 5 "register_operand" "1"))))
17996 (use (match_operand:P 6 "register_operand" "2"))
17997 (use (match_operand:SI 3 "immediate_operand" "i"))
17998 (clobber (match_operand:P 0 "register_operand" "=S"))
17999 (clobber (match_operand:P 1 "register_operand" "=D"))
18000 (clobber (match_operand:P 2 "register_operand" "=c"))]
18001 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
18002 && ix86_check_no_addr_space (insn)"
18004 [(set_attr "type" "str")
18005 (set_attr "mode" "QI")
18006 (set (attr "prefix_rex")
18008 (match_test "<P:MODE>mode == DImode")
18010 (const_string "*")))
18011 (set_attr "prefix_rep" "1")])
18013 ;; The same, but the count is not known to not be zero.
18015 (define_expand "cmpstrnqi_1"
18016 [(parallel [(set (reg:CC FLAGS_REG)
18017 (if_then_else:CC (ne (match_operand 2 "register_operand")
18019 (compare:CC (match_operand 4 "memory_operand")
18020 (match_operand 5 "memory_operand"))
18022 (use (match_operand:SI 3 "immediate_operand"))
18023 (use (reg:CC FLAGS_REG))
18024 (clobber (match_operand 0 "register_operand"))
18025 (clobber (match_operand 1 "register_operand"))
18026 (clobber (match_dup 2))])]
18030 ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
18033 (define_insn "*cmpstrnqi_1"
18034 [(set (reg:CC FLAGS_REG)
18035 (if_then_else:CC (ne (match_operand:P 6 "register_operand" "2")
18037 (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
18038 (mem:BLK (match_operand:P 5 "register_operand" "1")))
18040 (use (match_operand:SI 3 "immediate_operand" "i"))
18041 (use (reg:CC FLAGS_REG))
18042 (clobber (match_operand:P 0 "register_operand" "=S"))
18043 (clobber (match_operand:P 1 "register_operand" "=D"))
18044 (clobber (match_operand:P 2 "register_operand" "=c"))]
18045 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
18046 && ix86_check_no_addr_space (insn)"
18048 [(set_attr "type" "str")
18049 (set_attr "mode" "QI")
18050 (set (attr "prefix_rex")
18052 (match_test "<P:MODE>mode == DImode")
18054 (const_string "*")))
18055 (set_attr "prefix_rep" "1")])
18057 (define_expand "strlen<mode>"
18058 [(set (match_operand:P 0 "register_operand")
18059 (unspec:P [(match_operand:BLK 1 "general_operand")
18060 (match_operand:QI 2 "immediate_operand")
18061 (match_operand 3 "immediate_operand")]
18065 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
18071 (define_expand "strlenqi_1"
18072 [(parallel [(set (match_operand 0 "register_operand")
18074 (clobber (match_operand 1 "register_operand"))
18075 (clobber (reg:CC FLAGS_REG))])]
18079 ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
18082 (define_insn "*strlenqi_1"
18083 [(set (match_operand:P 0 "register_operand" "=&c")
18084 (unspec:P [(mem:BLK (match_operand:P 5 "register_operand" "1"))
18085 (match_operand:QI 2 "register_operand" "a")
18086 (match_operand:P 3 "immediate_operand" "i")
18087 (match_operand:P 4 "register_operand" "0")] UNSPEC_SCAS))
18088 (clobber (match_operand:P 1 "register_operand" "=D"))
18089 (clobber (reg:CC FLAGS_REG))]
18090 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])
18091 && ix86_check_no_addr_space (insn)"
18092 "%^repnz{%;} scasb"
18093 [(set_attr "type" "str")
18094 (set_attr "mode" "QI")
18095 (set (attr "prefix_rex")
18097 (match_test "<P:MODE>mode == DImode")
18099 (const_string "*")))
18100 (set_attr "prefix_rep" "1")])
18102 ;; Peephole optimizations to clean up after cmpstrn*. This should be
18103 ;; handled in combine, but it is not currently up to the task.
18104 ;; When used for their truth value, the cmpstrn* expanders generate
18113 ;; The intermediate three instructions are unnecessary.
18115 ;; This one handles cmpstrn*_nz_1...
18118 (set (reg:CC FLAGS_REG)
18119 (compare:CC (mem:BLK (match_operand 4 "register_operand"))
18120 (mem:BLK (match_operand 5 "register_operand"))))
18121 (use (match_operand 6 "register_operand"))
18122 (use (match_operand:SI 3 "immediate_operand"))
18123 (clobber (match_operand 0 "register_operand"))
18124 (clobber (match_operand 1 "register_operand"))
18125 (clobber (match_operand 2 "register_operand"))])
18126 (set (match_operand:QI 7 "register_operand")
18127 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
18128 (set (match_operand:QI 8 "register_operand")
18129 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
18130 (set (reg FLAGS_REG)
18131 (compare (match_dup 7) (match_dup 8)))
18133 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
18135 (set (reg:CC FLAGS_REG)
18136 (compare:CC (mem:BLK (match_dup 4))
18137 (mem:BLK (match_dup 5))))
18138 (use (match_dup 6))
18139 (use (match_dup 3))
18140 (clobber (match_dup 0))
18141 (clobber (match_dup 1))
18142 (clobber (match_dup 2))])])
18144 ;; ...and this one handles cmpstrn*_1.
18147 (set (reg:CC FLAGS_REG)
18148 (if_then_else:CC (ne (match_operand 6 "register_operand")
18150 (compare:CC (mem:BLK (match_operand 4 "register_operand"))
18151 (mem:BLK (match_operand 5 "register_operand")))
18153 (use (match_operand:SI 3 "immediate_operand"))
18154 (use (reg:CC FLAGS_REG))
18155 (clobber (match_operand 0 "register_operand"))
18156 (clobber (match_operand 1 "register_operand"))
18157 (clobber (match_operand 2 "register_operand"))])
18158 (set (match_operand:QI 7 "register_operand")
18159 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
18160 (set (match_operand:QI 8 "register_operand")
18161 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
18162 (set (reg FLAGS_REG)
18163 (compare (match_dup 7) (match_dup 8)))
18165 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
18167 (set (reg:CC FLAGS_REG)
18168 (if_then_else:CC (ne (match_dup 6)
18170 (compare:CC (mem:BLK (match_dup 4))
18171 (mem:BLK (match_dup 5)))
18173 (use (match_dup 3))
18174 (use (reg:CC FLAGS_REG))
18175 (clobber (match_dup 0))
18176 (clobber (match_dup 1))
18177 (clobber (match_dup 2))])])
18179 ;; Conditional move instructions.
18181 (define_expand "mov<mode>cc"
18182 [(set (match_operand:SWIM 0 "register_operand")
18183 (if_then_else:SWIM (match_operand 1 "comparison_operator")
18184 (match_operand:SWIM 2 "<general_operand>")
18185 (match_operand:SWIM 3 "<general_operand>")))]
18187 "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
18189 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
18190 ;; the register first winds up with `sbbl $0,reg', which is also weird.
18191 ;; So just document what we're doing explicitly.
18193 (define_expand "x86_mov<mode>cc_0_m1"
18195 [(set (match_operand:SWI48 0 "register_operand")
18196 (if_then_else:SWI48
18197 (match_operator:SWI48 2 "ix86_carry_flag_operator"
18198 [(match_operand 1 "flags_reg_operand")
18202 (clobber (reg:CC FLAGS_REG))])])
18204 (define_insn "*x86_mov<mode>cc_0_m1"
18205 [(set (match_operand:SWI48 0 "register_operand" "=r")
18206 (if_then_else:SWI48 (match_operator 1 "ix86_carry_flag_operator"
18207 [(reg FLAGS_REG) (const_int 0)])
18210 (clobber (reg:CC FLAGS_REG))]
18212 "sbb{<imodesuffix>}\t%0, %0"
18213 [(set_attr "type" "alu1")
18214 (set_attr "modrm_class" "op0")
18215 (set_attr "use_carry" "1")
18216 (set_attr "pent_pair" "pu")
18217 (set_attr "mode" "<MODE>")
18218 (set_attr "length_immediate" "0")])
18220 (define_insn "*x86_mov<mode>cc_0_m1_se"
18221 [(set (match_operand:SWI48 0 "register_operand" "=r")
18222 (sign_extract:SWI48 (match_operator 1 "ix86_carry_flag_operator"
18223 [(reg FLAGS_REG) (const_int 0)])
18226 (clobber (reg:CC FLAGS_REG))]
18228 "sbb{<imodesuffix>}\t%0, %0"
18229 [(set_attr "type" "alu1")
18230 (set_attr "modrm_class" "op0")
18231 (set_attr "use_carry" "1")
18232 (set_attr "pent_pair" "pu")
18233 (set_attr "mode" "<MODE>")
18234 (set_attr "length_immediate" "0")])
18236 (define_insn "*x86_mov<mode>cc_0_m1_neg"
18237 [(set (match_operand:SWI48 0 "register_operand" "=r")
18238 (neg:SWI48 (match_operator 1 "ix86_carry_flag_operator"
18239 [(reg FLAGS_REG) (const_int 0)])))
18240 (clobber (reg:CC FLAGS_REG))]
18242 "sbb{<imodesuffix>}\t%0, %0"
18243 [(set_attr "type" "alu1")
18244 (set_attr "modrm_class" "op0")
18245 (set_attr "use_carry" "1")
18246 (set_attr "pent_pair" "pu")
18247 (set_attr "mode" "<MODE>")
18248 (set_attr "length_immediate" "0")])
18250 (define_insn "*mov<mode>cc_noc"
18251 [(set (match_operand:SWI248 0 "register_operand" "=r,r")
18252 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
18253 [(reg FLAGS_REG) (const_int 0)])
18254 (match_operand:SWI248 2 "nonimmediate_operand" "rm,0")
18255 (match_operand:SWI248 3 "nonimmediate_operand" "0,rm")))]
18256 "TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
18258 cmov%O2%C1\t{%2, %0|%0, %2}
18259 cmov%O2%c1\t{%3, %0|%0, %3}"
18260 [(set_attr "type" "icmov")
18261 (set_attr "mode" "<MODE>")])
18263 (define_insn "*movsicc_noc_zext"
18264 [(set (match_operand:DI 0 "register_operand" "=r,r")
18265 (if_then_else:DI (match_operator 1 "ix86_comparison_operator"
18266 [(reg FLAGS_REG) (const_int 0)])
18268 (match_operand:SI 2 "nonimmediate_operand" "rm,0"))
18270 (match_operand:SI 3 "nonimmediate_operand" "0,rm"))))]
18272 && TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
18274 cmov%O2%C1\t{%2, %k0|%k0, %2}
18275 cmov%O2%c1\t{%3, %k0|%k0, %3}"
18276 [(set_attr "type" "icmov")
18277 (set_attr "mode" "SI")])
18279 ;; Don't do conditional moves with memory inputs. This splitter helps
18280 ;; register starved x86_32 by forcing inputs into registers before reload.
18282 [(set (match_operand:SWI248 0 "register_operand")
18283 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
18284 [(reg FLAGS_REG) (const_int 0)])
18285 (match_operand:SWI248 2 "nonimmediate_operand")
18286 (match_operand:SWI248 3 "nonimmediate_operand")))]
18287 "!TARGET_64BIT && TARGET_CMOVE
18288 && TARGET_AVOID_MEM_OPND_FOR_CMOVE
18289 && (MEM_P (operands[2]) || MEM_P (operands[3]))
18290 && can_create_pseudo_p ()
18291 && optimize_insn_for_speed_p ()"
18292 [(set (match_dup 0)
18293 (if_then_else:SWI248 (match_dup 1) (match_dup 2) (match_dup 3)))]
18295 if (MEM_P (operands[2]))
18296 operands[2] = force_reg (<MODE>mode, operands[2]);
18297 if (MEM_P (operands[3]))
18298 operands[3] = force_reg (<MODE>mode, operands[3]);
18301 (define_insn "*movqicc_noc"
18302 [(set (match_operand:QI 0 "register_operand" "=r,r")
18303 (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
18304 [(reg FLAGS_REG) (const_int 0)])
18305 (match_operand:QI 2 "register_operand" "r,0")
18306 (match_operand:QI 3 "register_operand" "0,r")))]
18307 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
18309 [(set_attr "type" "icmov")
18310 (set_attr "mode" "QI")])
18313 [(set (match_operand:SWI12 0 "register_operand")
18314 (if_then_else:SWI12 (match_operator 1 "ix86_comparison_operator"
18315 [(reg FLAGS_REG) (const_int 0)])
18316 (match_operand:SWI12 2 "register_operand")
18317 (match_operand:SWI12 3 "register_operand")))]
18318 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL
18319 && reload_completed"
18320 [(set (match_dup 0)
18321 (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
18323 operands[0] = gen_lowpart (SImode, operands[0]);
18324 operands[2] = gen_lowpart (SImode, operands[2]);
18325 operands[3] = gen_lowpart (SImode, operands[3]);
18328 ;; Don't do conditional moves with memory inputs
18330 [(match_scratch:SWI248 4 "r")
18331 (set (match_operand:SWI248 0 "register_operand")
18332 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
18333 [(reg FLAGS_REG) (const_int 0)])
18334 (match_operand:SWI248 2 "nonimmediate_operand")
18335 (match_operand:SWI248 3 "nonimmediate_operand")))]
18336 "TARGET_CMOVE && TARGET_AVOID_MEM_OPND_FOR_CMOVE
18337 && (MEM_P (operands[2]) || MEM_P (operands[3]))
18338 && optimize_insn_for_speed_p ()"
18339 [(set (match_dup 4) (match_dup 5))
18341 (if_then_else:SWI248 (match_dup 1) (match_dup 2) (match_dup 3)))]
18343 if (MEM_P (operands[2]))
18345 operands[5] = operands[2];
18346 operands[2] = operands[4];
18348 else if (MEM_P (operands[3]))
18350 operands[5] = operands[3];
18351 operands[3] = operands[4];
18354 gcc_unreachable ();
18358 [(match_scratch:SI 4 "r")
18359 (set (match_operand:DI 0 "register_operand")
18360 (if_then_else:DI (match_operator 1 "ix86_comparison_operator"
18361 [(reg FLAGS_REG) (const_int 0)])
18363 (match_operand:SI 2 "nonimmediate_operand"))
18365 (match_operand:SI 3 "nonimmediate_operand"))))]
18367 && TARGET_CMOVE && TARGET_AVOID_MEM_OPND_FOR_CMOVE
18368 && (MEM_P (operands[2]) || MEM_P (operands[3]))
18369 && optimize_insn_for_speed_p ()"
18370 [(set (match_dup 4) (match_dup 5))
18372 (if_then_else:DI (match_dup 1)
18373 (zero_extend:DI (match_dup 2))
18374 (zero_extend:DI (match_dup 3))))]
18376 if (MEM_P (operands[2]))
18378 operands[5] = operands[2];
18379 operands[2] = operands[4];
18381 else if (MEM_P (operands[3]))
18383 operands[5] = operands[3];
18384 operands[3] = operands[4];
18387 gcc_unreachable ();
18390 (define_expand "mov<mode>cc"
18391 [(set (match_operand:X87MODEF 0 "register_operand")
18392 (if_then_else:X87MODEF
18393 (match_operand 1 "comparison_operator")
18394 (match_operand:X87MODEF 2 "register_operand")
18395 (match_operand:X87MODEF 3 "register_operand")))]
18396 "(TARGET_80387 && TARGET_CMOVE)
18397 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
18398 "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
18400 (define_insn "*movxfcc_1"
18401 [(set (match_operand:XF 0 "register_operand" "=f,f")
18402 (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
18403 [(reg FLAGS_REG) (const_int 0)])
18404 (match_operand:XF 2 "register_operand" "f,0")
18405 (match_operand:XF 3 "register_operand" "0,f")))]
18406 "TARGET_80387 && TARGET_CMOVE"
18408 fcmov%F1\t{%2, %0|%0, %2}
18409 fcmov%f1\t{%3, %0|%0, %3}"
18410 [(set_attr "type" "fcmov")
18411 (set_attr "mode" "XF")])
18413 (define_insn "*movdfcc_1"
18414 [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r,r ,r")
18415 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
18416 [(reg FLAGS_REG) (const_int 0)])
18417 (match_operand:DF 2 "nonimmediate_operand"
18419 (match_operand:DF 3 "nonimmediate_operand"
18420 "0 ,f,0 ,rm,0, rm")))]
18421 "TARGET_80387 && TARGET_CMOVE
18422 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
18424 fcmov%F1\t{%2, %0|%0, %2}
18425 fcmov%f1\t{%3, %0|%0, %3}
18428 cmov%O2%C1\t{%2, %0|%0, %2}
18429 cmov%O2%c1\t{%3, %0|%0, %3}"
18430 [(set_attr "isa" "*,*,nox64,nox64,x64,x64")
18431 (set_attr "type" "fcmov,fcmov,multi,multi,icmov,icmov")
18432 (set_attr "mode" "DF,DF,DI,DI,DI,DI")])
18435 [(set (match_operand:DF 0 "general_reg_operand")
18436 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
18437 [(reg FLAGS_REG) (const_int 0)])
18438 (match_operand:DF 2 "nonimmediate_operand")
18439 (match_operand:DF 3 "nonimmediate_operand")))]
18440 "!TARGET_64BIT && reload_completed"
18441 [(set (match_dup 2)
18442 (if_then_else:SI (match_dup 1) (match_dup 4) (match_dup 5)))
18444 (if_then_else:SI (match_dup 1) (match_dup 6) (match_dup 7)))]
18446 split_double_mode (DImode, &operands[2], 2, &operands[4], &operands[6]);
18447 split_double_mode (DImode, &operands[0], 1, &operands[2], &operands[3]);
18450 (define_insn "*movsfcc_1_387"
18451 [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
18452 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
18453 [(reg FLAGS_REG) (const_int 0)])
18454 (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
18455 (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
18456 "TARGET_80387 && TARGET_CMOVE
18457 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
18459 fcmov%F1\t{%2, %0|%0, %2}
18460 fcmov%f1\t{%3, %0|%0, %3}
18461 cmov%O2%C1\t{%2, %0|%0, %2}
18462 cmov%O2%c1\t{%3, %0|%0, %3}"
18463 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
18464 (set_attr "mode" "SF,SF,SI,SI")])
18466 ;; Don't do conditional moves with memory inputs. This splitter helps
18467 ;; register starved x86_32 by forcing inputs into registers before reload.
18469 [(set (match_operand:MODEF 0 "register_operand")
18470 (if_then_else:MODEF (match_operator 1 "ix86_comparison_operator"
18471 [(reg FLAGS_REG) (const_int 0)])
18472 (match_operand:MODEF 2 "nonimmediate_operand")
18473 (match_operand:MODEF 3 "nonimmediate_operand")))]
18474 "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
18475 && TARGET_AVOID_MEM_OPND_FOR_CMOVE
18476 && (MEM_P (operands[2]) || MEM_P (operands[3]))
18477 && can_create_pseudo_p ()
18478 && optimize_insn_for_speed_p ()"
18479 [(set (match_dup 0)
18480 (if_then_else:MODEF (match_dup 1) (match_dup 2) (match_dup 3)))]
18482 if (MEM_P (operands[2]))
18483 operands[2] = force_reg (<MODE>mode, operands[2]);
18484 if (MEM_P (operands[3]))
18485 operands[3] = force_reg (<MODE>mode, operands[3]);
18488 ;; Don't do conditional moves with memory inputs
18490 [(match_scratch:MODEF 4 "r")
18491 (set (match_operand:MODEF 0 "general_reg_operand")
18492 (if_then_else:MODEF (match_operator 1 "fcmov_comparison_operator"
18493 [(reg FLAGS_REG) (const_int 0)])
18494 (match_operand:MODEF 2 "nonimmediate_operand")
18495 (match_operand:MODEF 3 "nonimmediate_operand")))]
18496 "(<MODE>mode != DFmode || TARGET_64BIT)
18497 && TARGET_80387 && TARGET_CMOVE
18498 && TARGET_AVOID_MEM_OPND_FOR_CMOVE
18499 && (MEM_P (operands[2]) || MEM_P (operands[3]))
18500 && optimize_insn_for_speed_p ()"
18501 [(set (match_dup 4) (match_dup 5))
18503 (if_then_else:MODEF (match_dup 1) (match_dup 2) (match_dup 3)))]
18505 if (MEM_P (operands[2]))
18507 operands[5] = operands[2];
18508 operands[2] = operands[4];
18510 else if (MEM_P (operands[3]))
18512 operands[5] = operands[3];
18513 operands[3] = operands[4];
18516 gcc_unreachable ();
18519 ;; All moves in XOP pcmov instructions are 128 bits and hence we restrict
18520 ;; the scalar versions to have only XMM registers as operands.
18522 ;; XOP conditional move
18523 (define_insn "*xop_pcmov_<mode>"
18524 [(set (match_operand:MODEF 0 "register_operand" "=x")
18525 (if_then_else:MODEF
18526 (match_operand:MODEF 1 "register_operand" "x")
18527 (match_operand:MODEF 2 "register_operand" "x")
18528 (match_operand:MODEF 3 "register_operand" "x")))]
18530 "vpcmov\t{%1, %3, %2, %0|%0, %2, %3, %1}"
18531 [(set_attr "type" "sse4arg")])
18533 ;; These versions of the min/max patterns are intentionally ignorant of
18534 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
18535 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
18536 ;; are undefined in this condition, we're certain this is correct.
18538 (define_insn "<code><mode>3"
18539 [(set (match_operand:MODEF 0 "register_operand" "=x,v")
18541 (match_operand:MODEF 1 "nonimmediate_operand" "%0,v")
18542 (match_operand:MODEF 2 "nonimmediate_operand" "xm,vm")))]
18543 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
18545 <maxmin_float><ssemodesuffix>\t{%2, %0|%0, %2}
18546 v<maxmin_float><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
18547 [(set_attr "isa" "noavx,avx")
18548 (set_attr "prefix" "orig,vex")
18549 (set_attr "type" "sseadd")
18550 (set_attr "mode" "<MODE>")])
18552 ;; These versions of the min/max patterns implement exactly the operations
18553 ;; min = (op1 < op2 ? op1 : op2)
18554 ;; max = (!(op1 < op2) ? op1 : op2)
18555 ;; Their operands are not commutative, and thus they may be used in the
18556 ;; presence of -0.0 and NaN.
18558 (define_insn "*ieee_s<ieee_maxmin><mode>3"
18559 [(set (match_operand:MODEF 0 "register_operand" "=x,v")
18561 [(match_operand:MODEF 1 "register_operand" "0,v")
18562 (match_operand:MODEF 2 "nonimmediate_operand" "xm,vm")]
18564 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
18566 <ieee_maxmin><ssemodesuffix>\t{%2, %0|%0, %2}
18567 v<ieee_maxmin><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
18568 [(set_attr "isa" "noavx,avx")
18569 (set_attr "prefix" "orig,maybe_evex")
18570 (set_attr "type" "sseadd")
18571 (set_attr "mode" "<MODE>")])
18573 ;; Make two stack loads independent:
18575 ;; fld %st(0) -> fld bb
18576 ;; fmul bb fmul %st(1), %st
18578 ;; Actually we only match the last two instructions for simplicity.
18581 [(set (match_operand 0 "fp_register_operand")
18582 (match_operand 1 "fp_register_operand"))
18584 (match_operator 2 "binary_fp_operator"
18586 (match_operand 3 "memory_operand")]))]
18587 "REGNO (operands[0]) != REGNO (operands[1])"
18588 [(set (match_dup 0) (match_dup 3))
18591 [(match_dup 5) (match_dup 4)]))]
18593 operands[4] = operands[0];
18594 operands[5] = operands[1];
18596 /* The % modifier is not operational anymore in peephole2's, so we have to
18597 swap the operands manually in the case of addition and multiplication. */
18598 if (COMMUTATIVE_ARITH_P (operands[2]))
18599 std::swap (operands[4], operands[5]);
18603 [(set (match_operand 0 "fp_register_operand")
18604 (match_operand 1 "fp_register_operand"))
18606 (match_operator 2 "binary_fp_operator"
18607 [(match_operand 3 "memory_operand")
18609 "REGNO (operands[0]) != REGNO (operands[1])"
18610 [(set (match_dup 0) (match_dup 3))
18613 [(match_dup 4) (match_dup 5)]))]
18615 operands[4] = operands[0];
18616 operands[5] = operands[1];
18618 /* The % modifier is not operational anymore in peephole2's, so we have to
18619 swap the operands manually in the case of addition and multiplication. */
18620 if (COMMUTATIVE_ARITH_P (operands[2]))
18621 std::swap (operands[4], operands[5]);
18624 ;; Conditional addition patterns
18625 (define_expand "add<mode>cc"
18626 [(match_operand:SWI 0 "register_operand")
18627 (match_operand 1 "ordered_comparison_operator")
18628 (match_operand:SWI 2 "register_operand")
18629 (match_operand:SWI 3 "const_int_operand")]
18631 "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
18633 ;; Misc patterns (?)
18635 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
18636 ;; Otherwise there will be nothing to keep
18638 ;; [(set (reg ebp) (reg esp))]
18639 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
18640 ;; (clobber (eflags)]
18641 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
18643 ;; in proper program order.
18645 (define_insn "pro_epilogue_adjust_stack_<mode>_add"
18646 [(set (match_operand:P 0 "register_operand" "=r,r")
18647 (plus:P (match_operand:P 1 "register_operand" "0,r")
18648 (match_operand:P 2 "<nonmemory_operand>" "r<i>,l<i>")))
18649 (clobber (reg:CC FLAGS_REG))
18650 (clobber (mem:BLK (scratch)))]
18653 switch (get_attr_type (insn))
18656 return "mov{<imodesuffix>}\t{%1, %0|%0, %1}";
18659 gcc_assert (rtx_equal_p (operands[0], operands[1]));
18660 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
18661 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
18663 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
18666 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
18667 return "lea{<imodesuffix>}\t{%E2, %0|%0, %E2}";
18670 [(set (attr "type")
18671 (cond [(and (eq_attr "alternative" "0")
18672 (not (match_test "TARGET_OPT_AGU")))
18673 (const_string "alu")
18674 (match_operand:<MODE> 2 "const0_operand")
18675 (const_string "imov")
18677 (const_string "lea")))
18678 (set (attr "length_immediate")
18679 (cond [(eq_attr "type" "imov")
18681 (and (eq_attr "type" "alu")
18682 (match_operand 2 "const128_operand"))
18685 (const_string "*")))
18686 (set_attr "mode" "<MODE>")])
18688 (define_insn "pro_epilogue_adjust_stack_<mode>_sub"
18689 [(set (match_operand:P 0 "register_operand" "=r")
18690 (minus:P (match_operand:P 1 "register_operand" "0")
18691 (match_operand:P 2 "register_operand" "r")))
18692 (clobber (reg:CC FLAGS_REG))
18693 (clobber (mem:BLK (scratch)))]
18695 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
18696 [(set_attr "type" "alu")
18697 (set_attr "mode" "<MODE>")])
18699 (define_insn "allocate_stack_worker_probe_<mode>"
18700 [(set (match_operand:P 0 "register_operand" "=a")
18701 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
18702 UNSPECV_STACK_PROBE))
18703 (clobber (reg:CC FLAGS_REG))]
18704 "ix86_target_stack_probe ()"
18705 "call\t___chkstk_ms"
18706 [(set_attr "type" "multi")
18707 (set_attr "length" "5")])
18709 (define_expand "allocate_stack"
18710 [(match_operand 0 "register_operand")
18711 (match_operand 1 "general_operand")]
18712 "ix86_target_stack_probe ()"
18716 #ifndef CHECK_STACK_LIMIT
18717 #define CHECK_STACK_LIMIT 0
18720 if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
18721 && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
18725 rtx (*insn) (rtx, rtx);
18727 x = copy_to_mode_reg (Pmode, operands[1]);
18729 insn = (TARGET_64BIT
18730 ? gen_allocate_stack_worker_probe_di
18731 : gen_allocate_stack_worker_probe_si);
18733 emit_insn (insn (x, x));
18736 x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, x,
18737 stack_pointer_rtx, 0, OPTAB_DIRECT);
18739 if (x != stack_pointer_rtx)
18740 emit_move_insn (stack_pointer_rtx, x);
18742 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
18746 (define_expand "probe_stack"
18747 [(match_operand 0 "memory_operand")]
18750 rtx (*insn) (rtx, rtx)
18751 = (GET_MODE (operands[0]) == DImode
18752 ? gen_probe_stack_di : gen_probe_stack_si);
18754 emit_insn (insn (operands[0], const0_rtx));
18758 ;; Use OR for stack probes, this is shorter.
18759 (define_insn "probe_stack_<mode>"
18760 [(set (match_operand:W 0 "memory_operand" "=m")
18761 (unspec:W [(match_operand:W 1 "const0_operand")]
18762 UNSPEC_PROBE_STACK))
18763 (clobber (reg:CC FLAGS_REG))]
18765 "or{<imodesuffix>}\t{%1, %0|%0, %1}"
18766 [(set_attr "type" "alu1")
18767 (set_attr "mode" "<MODE>")
18768 (set_attr "length_immediate" "1")])
18770 (define_insn "adjust_stack_and_probe<mode>"
18771 [(set (match_operand:P 0 "register_operand" "=r")
18772 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
18773 UNSPECV_PROBE_STACK_RANGE))
18774 (set (reg:P SP_REG)
18775 (minus:P (reg:P SP_REG) (match_operand:P 2 "const_int_operand" "n")))
18776 (clobber (reg:CC FLAGS_REG))
18777 (clobber (mem:BLK (scratch)))]
18779 "* return output_adjust_stack_and_probe (operands[0]);"
18780 [(set_attr "type" "multi")])
18782 (define_insn "probe_stack_range<mode>"
18783 [(set (match_operand:P 0 "register_operand" "=r")
18784 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
18785 (match_operand:P 2 "const_int_operand" "n")]
18786 UNSPECV_PROBE_STACK_RANGE))
18787 (clobber (reg:CC FLAGS_REG))]
18789 "* return output_probe_stack_range (operands[0], operands[2]);"
18790 [(set_attr "type" "multi")])
18792 (define_expand "builtin_setjmp_receiver"
18793 [(label_ref (match_operand 0))]
18794 "!TARGET_64BIT && flag_pic"
18800 rtx_code_label *label_rtx = gen_label_rtx ();
18801 emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
18802 xops[0] = xops[1] = pic_offset_table_rtx;
18803 xops[2] = machopic_gen_offset (gen_rtx_LABEL_REF (SImode, label_rtx));
18804 ix86_expand_binary_operator (MINUS, SImode, xops);
18808 emit_insn (gen_set_got (pic_offset_table_rtx));
18812 (define_expand "save_stack_nonlocal"
18813 [(set (match_operand 0 "memory_operand")
18814 (match_operand 1 "register_operand"))]
18818 if ((flag_cf_protection & CF_RETURN))
18820 /* Copy shadow stack pointer to the first slot and stack ppointer
18821 to the second slot. */
18822 rtx ssp_slot = adjust_address (operands[0], word_mode, 0);
18823 stack_slot = adjust_address (operands[0], Pmode, UNITS_PER_WORD);
18824 rtx ssp = gen_reg_rtx (word_mode);
18825 emit_insn ((word_mode == SImode)
18826 ? gen_rdsspsi (ssp)
18827 : gen_rdsspdi (ssp));
18828 emit_move_insn (ssp_slot, ssp);
18831 stack_slot = adjust_address (operands[0], Pmode, 0);
18832 emit_move_insn (stack_slot, operands[1]);
18836 (define_expand "restore_stack_nonlocal"
18837 [(set (match_operand 0 "register_operand" "")
18838 (match_operand 1 "memory_operand" ""))]
18842 if ((flag_cf_protection & CF_RETURN))
18844 /* Restore shadow stack pointer from the first slot and stack
18845 pointer from the second slot. */
18846 rtx ssp_slot = adjust_address (operands[1], word_mode, 0);
18847 stack_slot = adjust_address (operands[1], Pmode, UNITS_PER_WORD);
18849 rtx flags, jump, noadj_label, inc_label, loop_label;
18850 rtx reg_adj, reg_ssp, tmp, clob;
18852 /* Get the current shadow stack pointer. The code below will check if
18853 SHSTK feature is enabled. If it is not enabled the RDSSP instruction
18855 reg_ssp = gen_reg_rtx (word_mode);
18856 emit_insn (gen_rtx_SET (reg_ssp, const0_rtx));
18857 emit_insn ((word_mode == SImode)
18858 ? gen_rdsspsi (reg_ssp)
18859 : gen_rdsspdi (reg_ssp));
18861 /* Compare through substraction the saved and the current ssp to decide
18862 if ssp has to be adjusted. */
18863 tmp = gen_rtx_SET (reg_ssp, gen_rtx_MINUS (word_mode, reg_ssp,
18865 clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
18866 tmp = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, tmp, clob));
18869 /* Compare and jump over adjustment code. */
18870 noadj_label = gen_label_rtx ();
18871 flags = gen_rtx_REG (CCZmode, FLAGS_REG);
18872 tmp = gen_rtx_EQ (VOIDmode, flags, const0_rtx);
18873 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
18874 gen_rtx_LABEL_REF (VOIDmode, noadj_label),
18876 jump = emit_jump_insn (gen_rtx_SET (pc_rtx, tmp));
18877 JUMP_LABEL (jump) = noadj_label;
18879 /* Compute the numebr of frames to adjust. */
18880 reg_adj = gen_lowpart (ptr_mode, reg_ssp);
18881 tmp = gen_rtx_SET (reg_adj,
18882 gen_rtx_LSHIFTRT (ptr_mode,
18883 negate_rtx (ptr_mode, reg_adj),
18884 GEN_INT ((word_mode == SImode)
18887 clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
18888 tmp = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, tmp, clob));
18891 /* Check if number of frames <= 255 so no loop is needed. */
18892 tmp = gen_rtx_COMPARE (CCmode, reg_adj, GEN_INT (255));
18893 flags = gen_rtx_REG (CCmode, FLAGS_REG);
18894 emit_insn (gen_rtx_SET (flags, tmp));
18896 inc_label = gen_label_rtx ();
18897 tmp = gen_rtx_LEU (VOIDmode, flags, const0_rtx);
18898 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
18899 gen_rtx_LABEL_REF (VOIDmode, inc_label),
18901 jump = emit_jump_insn (gen_rtx_SET (pc_rtx, tmp));
18902 JUMP_LABEL (jump) = inc_label;
18904 rtx reg_255 = gen_reg_rtx (word_mode);
18905 emit_move_insn (reg_255, GEN_INT (255));
18907 /* Adjust the ssp in a loop. */
18908 loop_label = gen_label_rtx ();
18909 emit_label (loop_label);
18910 LABEL_NUSES (loop_label) = 1;
18912 emit_insn ((word_mode == SImode)
18913 ? gen_incsspsi (reg_255)
18914 : gen_incsspdi (reg_255));
18915 tmp = gen_rtx_SET (reg_adj, gen_rtx_MINUS (ptr_mode,
18918 clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
18919 tmp = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, tmp, clob));
18922 tmp = gen_rtx_COMPARE (CCmode, reg_adj, GEN_INT (255));
18923 flags = gen_rtx_REG (CCmode, FLAGS_REG);
18924 emit_insn (gen_rtx_SET (flags, tmp));
18926 /* Jump to the loop label. */
18927 tmp = gen_rtx_GTU (VOIDmode, flags, const0_rtx);
18928 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
18929 gen_rtx_LABEL_REF (VOIDmode, loop_label),
18931 jump = emit_jump_insn (gen_rtx_SET (pc_rtx, tmp));
18932 JUMP_LABEL (jump) = loop_label;
18934 emit_label (inc_label);
18935 LABEL_NUSES (inc_label) = 1;
18936 emit_insn ((word_mode == SImode)
18937 ? gen_incsspsi (reg_ssp)
18938 : gen_incsspdi (reg_ssp));
18940 emit_label (noadj_label);
18941 LABEL_NUSES (noadj_label) = 1;
18944 stack_slot = adjust_address (operands[1], Pmode, 0);
18945 emit_move_insn (operands[0], stack_slot);
18950 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
18951 ;; Do not split instructions with mask registers.
18953 [(set (match_operand 0 "general_reg_operand")
18954 (match_operator 3 "promotable_binary_operator"
18955 [(match_operand 1 "general_reg_operand")
18956 (match_operand 2 "aligned_operand")]))
18957 (clobber (reg:CC FLAGS_REG))]
18958 "! TARGET_PARTIAL_REG_STALL && reload_completed
18959 && ((GET_MODE (operands[0]) == HImode
18960 && ((optimize_function_for_speed_p (cfun) && !TARGET_FAST_PREFIX)
18961 /* ??? next two lines just !satisfies_constraint_K (...) */
18962 || !CONST_INT_P (operands[2])
18963 || satisfies_constraint_K (operands[2])))
18964 || (GET_MODE (operands[0]) == QImode
18965 && (TARGET_PROMOTE_QImode || optimize_function_for_size_p (cfun))))"
18966 [(parallel [(set (match_dup 0)
18967 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
18968 (clobber (reg:CC FLAGS_REG))])]
18970 operands[0] = gen_lowpart (SImode, operands[0]);
18971 operands[1] = gen_lowpart (SImode, operands[1]);
18972 if (GET_CODE (operands[3]) != ASHIFT)
18973 operands[2] = gen_lowpart (SImode, operands[2]);
18974 operands[3] = shallow_copy_rtx (operands[3]);
18975 PUT_MODE (operands[3], SImode);
18978 ; Promote the QImode tests, as i386 has encoding of the AND
18979 ; instruction with 32-bit sign-extended immediate and thus the
18980 ; instruction size is unchanged, except in the %eax case for
18981 ; which it is increased by one byte, hence the ! optimize_size.
18983 [(set (match_operand 0 "flags_reg_operand")
18984 (match_operator 2 "compare_operator"
18985 [(and (match_operand 3 "aligned_operand")
18986 (match_operand 4 "const_int_operand"))
18988 (set (match_operand 1 "register_operand")
18989 (and (match_dup 3) (match_dup 4)))]
18990 "! TARGET_PARTIAL_REG_STALL && reload_completed
18991 && optimize_insn_for_speed_p ()
18992 && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
18993 || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))
18994 /* Ensure that the operand will remain sign-extended immediate. */
18995 && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)"
18996 [(parallel [(set (match_dup 0)
18997 (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
19000 (and:SI (match_dup 3) (match_dup 4)))])]
19003 = gen_int_mode (INTVAL (operands[4])
19004 & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
19005 operands[1] = gen_lowpart (SImode, operands[1]);
19006 operands[3] = gen_lowpart (SImode, operands[3]);
19009 ; Don't promote the QImode tests, as i386 doesn't have encoding of
19010 ; the TEST instruction with 32-bit sign-extended immediate and thus
19011 ; the instruction size would at least double, which is not what we
19012 ; want even with ! optimize_size.
19014 [(set (match_operand 0 "flags_reg_operand")
19015 (match_operator 1 "compare_operator"
19016 [(and (match_operand:HI 2 "aligned_operand")
19017 (match_operand:HI 3 "const_int_operand"))
19019 "! TARGET_PARTIAL_REG_STALL && reload_completed
19020 && ! TARGET_FAST_PREFIX
19021 && optimize_insn_for_speed_p ()
19022 /* Ensure that the operand will remain sign-extended immediate. */
19023 && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)"
19024 [(set (match_dup 0)
19025 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
19029 = gen_int_mode (INTVAL (operands[3])
19030 & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
19031 operands[2] = gen_lowpart (SImode, operands[2]);
19035 [(set (match_operand 0 "register_operand")
19036 (neg (match_operand 1 "register_operand")))
19037 (clobber (reg:CC FLAGS_REG))]
19038 "! TARGET_PARTIAL_REG_STALL && reload_completed
19039 && (GET_MODE (operands[0]) == HImode
19040 || (GET_MODE (operands[0]) == QImode
19041 && (TARGET_PROMOTE_QImode
19042 || optimize_insn_for_size_p ())))"
19043 [(parallel [(set (match_dup 0)
19044 (neg:SI (match_dup 1)))
19045 (clobber (reg:CC FLAGS_REG))])]
19047 operands[0] = gen_lowpart (SImode, operands[0]);
19048 operands[1] = gen_lowpart (SImode, operands[1]);
19051 ;; Do not split instructions with mask regs.
19053 [(set (match_operand 0 "general_reg_operand")
19054 (not (match_operand 1 "general_reg_operand")))]
19055 "! TARGET_PARTIAL_REG_STALL && reload_completed
19056 && (GET_MODE (operands[0]) == HImode
19057 || (GET_MODE (operands[0]) == QImode
19058 && (TARGET_PROMOTE_QImode
19059 || optimize_insn_for_size_p ())))"
19060 [(set (match_dup 0)
19061 (not:SI (match_dup 1)))]
19063 operands[0] = gen_lowpart (SImode, operands[0]);
19064 operands[1] = gen_lowpart (SImode, operands[1]);
19067 ;; RTL Peephole optimizations, run before sched2. These primarily look to
19068 ;; transform a complex memory operation into two memory to register operations.
19070 ;; Don't push memory operands
19072 [(set (match_operand:SWI 0 "push_operand")
19073 (match_operand:SWI 1 "memory_operand"))
19074 (match_scratch:SWI 2 "<r>")]
19075 "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
19076 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19077 [(set (match_dup 2) (match_dup 1))
19078 (set (match_dup 0) (match_dup 2))])
19080 ;; We need to handle SFmode only, because DFmode and XFmode are split to
19083 [(set (match_operand:SF 0 "push_operand")
19084 (match_operand:SF 1 "memory_operand"))
19085 (match_scratch:SF 2 "r")]
19086 "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
19087 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19088 [(set (match_dup 2) (match_dup 1))
19089 (set (match_dup 0) (match_dup 2))])
19091 ;; Don't move an immediate directly to memory when the instruction
19092 ;; gets too big, or if LCP stalls are a problem for 16-bit moves.
19094 [(match_scratch:SWI124 1 "<r>")
19095 (set (match_operand:SWI124 0 "memory_operand")
19097 "optimize_insn_for_speed_p ()
19098 && ((<MODE>mode == HImode
19099 && TARGET_LCP_STALL)
19100 || (!TARGET_USE_MOV0
19101 && TARGET_SPLIT_LONG_MOVES
19102 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn))
19103 && peep2_regno_dead_p (0, FLAGS_REG)"
19104 [(parallel [(set (match_dup 2) (const_int 0))
19105 (clobber (reg:CC FLAGS_REG))])
19106 (set (match_dup 0) (match_dup 1))]
19107 "operands[2] = gen_lowpart (SImode, operands[1]);")
19110 [(match_scratch:SWI124 2 "<r>")
19111 (set (match_operand:SWI124 0 "memory_operand")
19112 (match_operand:SWI124 1 "immediate_operand"))]
19113 "optimize_insn_for_speed_p ()
19114 && ((<MODE>mode == HImode
19115 && TARGET_LCP_STALL)
19116 || (TARGET_SPLIT_LONG_MOVES
19117 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn))"
19118 [(set (match_dup 2) (match_dup 1))
19119 (set (match_dup 0) (match_dup 2))])
19121 ;; Don't compare memory with zero, load and use a test instead.
19123 [(set (match_operand 0 "flags_reg_operand")
19124 (match_operator 1 "compare_operator"
19125 [(match_operand:SI 2 "memory_operand")
19127 (match_scratch:SI 3 "r")]
19128 "optimize_insn_for_speed_p () && ix86_match_ccmode (insn, CCNOmode)"
19129 [(set (match_dup 3) (match_dup 2))
19130 (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))])
19132 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
19133 ;; Don't split NOTs with a displacement operand, because resulting XOR
19134 ;; will not be pairable anyway.
19136 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
19137 ;; represented using a modRM byte. The XOR replacement is long decoded,
19138 ;; so this split helps here as well.
19140 ;; Note: Can't do this as a regular split because we can't get proper
19141 ;; lifetime information then.
19144 [(set (match_operand:SWI124 0 "nonimmediate_gr_operand")
19145 (not:SWI124 (match_operand:SWI124 1 "nonimmediate_gr_operand")))]
19146 "optimize_insn_for_speed_p ()
19147 && ((TARGET_NOT_UNPAIRABLE
19148 && (!MEM_P (operands[0])
19149 || !memory_displacement_operand (operands[0], <MODE>mode)))
19150 || (TARGET_NOT_VECTORMODE
19151 && long_memory_operand (operands[0], <MODE>mode)))
19152 && peep2_regno_dead_p (0, FLAGS_REG)"
19153 [(parallel [(set (match_dup 0)
19154 (xor:SWI124 (match_dup 1) (const_int -1)))
19155 (clobber (reg:CC FLAGS_REG))])])
19157 ;; Non pairable "test imm, reg" instructions can be translated to
19158 ;; "and imm, reg" if reg dies. The "and" form is also shorter (one
19159 ;; byte opcode instead of two, have a short form for byte operands),
19160 ;; so do it for other CPUs as well. Given that the value was dead,
19161 ;; this should not create any new dependencies. Pass on the sub-word
19162 ;; versions if we're concerned about partial register stalls.
19165 [(set (match_operand 0 "flags_reg_operand")
19166 (match_operator 1 "compare_operator"
19167 [(and:SI (match_operand:SI 2 "register_operand")
19168 (match_operand:SI 3 "immediate_operand"))
19170 "ix86_match_ccmode (insn, CCNOmode)
19171 && (REGNO (operands[2]) != AX_REG
19172 || satisfies_constraint_K (operands[3]))
19173 && peep2_reg_dead_p (1, operands[2])"
19175 [(set (match_dup 0)
19176 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
19179 (and:SI (match_dup 2) (match_dup 3)))])])
19181 ;; We don't need to handle HImode case, because it will be promoted to SImode
19182 ;; on ! TARGET_PARTIAL_REG_STALL
19185 [(set (match_operand 0 "flags_reg_operand")
19186 (match_operator 1 "compare_operator"
19187 [(and:QI (match_operand:QI 2 "register_operand")
19188 (match_operand:QI 3 "immediate_operand"))
19190 "! TARGET_PARTIAL_REG_STALL
19191 && ix86_match_ccmode (insn, CCNOmode)
19192 && REGNO (operands[2]) != AX_REG
19193 && peep2_reg_dead_p (1, operands[2])"
19195 [(set (match_dup 0)
19196 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
19199 (and:QI (match_dup 2) (match_dup 3)))])])
19202 [(set (match_operand 0 "flags_reg_operand")
19203 (match_operator 1 "compare_operator"
19206 (zero_extract:SI (match_operand 2 "QIreg_operand")
19209 (match_operand 3 "const_int_operand"))
19211 "! TARGET_PARTIAL_REG_STALL
19212 && ix86_match_ccmode (insn, CCNOmode)
19213 && REGNO (operands[2]) != AX_REG
19214 && peep2_reg_dead_p (1, operands[2])"
19216 [(set (match_dup 0)
19220 (zero_extract:SI (match_dup 2)
19225 (set (zero_extract:SI (match_dup 2)
19231 (zero_extract:SI (match_dup 2)
19234 (match_dup 3)) 0))])])
19236 ;; Don't do logical operations with memory inputs.
19238 [(match_scratch:SWI 2 "<r>")
19239 (parallel [(set (match_operand:SWI 0 "register_operand")
19240 (match_operator:SWI 3 "arith_or_logical_operator"
19242 (match_operand:SWI 1 "memory_operand")]))
19243 (clobber (reg:CC FLAGS_REG))])]
19244 "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
19245 [(set (match_dup 2) (match_dup 1))
19246 (parallel [(set (match_dup 0)
19247 (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
19248 (clobber (reg:CC FLAGS_REG))])])
19251 [(match_scratch:SWI 2 "<r>")
19252 (parallel [(set (match_operand:SWI 0 "register_operand")
19253 (match_operator:SWI 3 "arith_or_logical_operator"
19254 [(match_operand:SWI 1 "memory_operand")
19256 (clobber (reg:CC FLAGS_REG))])]
19257 "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
19258 [(set (match_dup 2) (match_dup 1))
19259 (parallel [(set (match_dup 0)
19260 (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
19261 (clobber (reg:CC FLAGS_REG))])])
19263 ;; Prefer Load+RegOp to Mov+MemOp. Watch out for cases when
19264 ;; the memory address refers to the destination of the load!
19267 [(set (match_operand:SWI 0 "general_reg_operand")
19268 (match_operand:SWI 1 "general_reg_operand"))
19269 (parallel [(set (match_dup 0)
19270 (match_operator:SWI 3 "commutative_operator"
19272 (match_operand:SWI 2 "memory_operand")]))
19273 (clobber (reg:CC FLAGS_REG))])]
19274 "REGNO (operands[0]) != REGNO (operands[1])
19275 && (<MODE>mode != QImode
19276 || any_QIreg_operand (operands[1], QImode))"
19277 [(set (match_dup 0) (match_dup 4))
19278 (parallel [(set (match_dup 0)
19279 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))
19280 (clobber (reg:CC FLAGS_REG))])]
19281 "operands[4] = replace_rtx (operands[2], operands[0], operands[1], true);")
19284 [(set (match_operand 0 "mmx_reg_operand")
19285 (match_operand 1 "mmx_reg_operand"))
19287 (match_operator 3 "commutative_operator"
19289 (match_operand 2 "memory_operand")]))]
19290 "REGNO (operands[0]) != REGNO (operands[1])"
19291 [(set (match_dup 0) (match_dup 2))
19293 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))])
19296 [(set (match_operand 0 "sse_reg_operand")
19297 (match_operand 1 "sse_reg_operand"))
19299 (match_operator 3 "commutative_operator"
19301 (match_operand 2 "memory_operand")]))]
19302 "REGNO (operands[0]) != REGNO (operands[1])"
19303 [(set (match_dup 0) (match_dup 2))
19305 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))])
19307 ; Don't do logical operations with memory outputs
19309 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
19310 ; instruction into two 1-uop insns plus a 2-uop insn. That last has
19311 ; the same decoder scheduling characteristics as the original.
19314 [(match_scratch:SWI 2 "<r>")
19315 (parallel [(set (match_operand:SWI 0 "memory_operand")
19316 (match_operator:SWI 3 "arith_or_logical_operator"
19318 (match_operand:SWI 1 "<nonmemory_operand>")]))
19319 (clobber (reg:CC FLAGS_REG))])]
19320 "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())"
19321 [(set (match_dup 2) (match_dup 0))
19322 (parallel [(set (match_dup 2)
19323 (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
19324 (clobber (reg:CC FLAGS_REG))])
19325 (set (match_dup 0) (match_dup 2))])
19328 [(match_scratch:SWI 2 "<r>")
19329 (parallel [(set (match_operand:SWI 0 "memory_operand")
19330 (match_operator:SWI 3 "arith_or_logical_operator"
19331 [(match_operand:SWI 1 "<nonmemory_operand>")
19333 (clobber (reg:CC FLAGS_REG))])]
19334 "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())"
19335 [(set (match_dup 2) (match_dup 0))
19336 (parallel [(set (match_dup 2)
19337 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
19338 (clobber (reg:CC FLAGS_REG))])
19339 (set (match_dup 0) (match_dup 2))])
19341 ;; Attempt to use arith or logical operations with memory outputs with
19342 ;; setting of flags.
19344 [(set (match_operand:SWI 0 "register_operand")
19345 (match_operand:SWI 1 "memory_operand"))
19346 (parallel [(set (match_dup 0)
19347 (match_operator:SWI 3 "plusminuslogic_operator"
19349 (match_operand:SWI 2 "<nonmemory_operand>")]))
19350 (clobber (reg:CC FLAGS_REG))])
19351 (set (match_dup 1) (match_dup 0))
19352 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
19353 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
19354 && peep2_reg_dead_p (4, operands[0])
19355 && !reg_overlap_mentioned_p (operands[0], operands[1])
19356 && !reg_overlap_mentioned_p (operands[0], operands[2])
19357 && (<MODE>mode != QImode
19358 || immediate_operand (operands[2], QImode)
19359 || any_QIreg_operand (operands[2], QImode))
19360 && ix86_match_ccmode (peep2_next_insn (3),
19361 (GET_CODE (operands[3]) == PLUS
19362 || GET_CODE (operands[3]) == MINUS)
19363 ? CCGOCmode : CCNOmode)"
19364 [(parallel [(set (match_dup 4) (match_dup 6))
19365 (set (match_dup 1) (match_dup 5))])]
19367 operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
19369 = gen_rtx_fmt_ee (GET_CODE (operands[3]), GET_MODE (operands[3]),
19370 copy_rtx (operands[1]),
19373 = gen_rtx_COMPARE (GET_MODE (operands[4]),
19374 copy_rtx (operands[5]),
19378 ;; Likewise for cmpelim optimized pattern.
19380 [(set (match_operand:SWI 0 "register_operand")
19381 (match_operand:SWI 1 "memory_operand"))
19382 (parallel [(set (reg FLAGS_REG)
19383 (compare (match_operator:SWI 3 "plusminuslogic_operator"
19385 (match_operand:SWI 2 "<nonmemory_operand>")])
19387 (set (match_dup 0) (match_dup 3))])
19388 (set (match_dup 1) (match_dup 0))]
19389 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
19390 && peep2_reg_dead_p (3, operands[0])
19391 && !reg_overlap_mentioned_p (operands[0], operands[1])
19392 && !reg_overlap_mentioned_p (operands[0], operands[2])
19393 && ix86_match_ccmode (peep2_next_insn (1),
19394 (GET_CODE (operands[3]) == PLUS
19395 || GET_CODE (operands[3]) == MINUS)
19396 ? CCGOCmode : CCNOmode)"
19397 [(parallel [(set (match_dup 4) (match_dup 6))
19398 (set (match_dup 1) (match_dup 5))])]
19400 operands[4] = SET_DEST (XVECEXP (PATTERN (peep2_next_insn (1)), 0, 0));
19402 = gen_rtx_fmt_ee (GET_CODE (operands[3]), GET_MODE (operands[3]),
19403 copy_rtx (operands[1]), operands[2]);
19405 = gen_rtx_COMPARE (GET_MODE (operands[4]), copy_rtx (operands[5]),
19409 ;; Likewise for instances where we have a lea pattern.
19411 [(set (match_operand:SWI 0 "register_operand")
19412 (match_operand:SWI 1 "memory_operand"))
19413 (set (match_operand:SWI 3 "register_operand")
19414 (plus:SWI (match_dup 0)
19415 (match_operand:SWI 2 "<nonmemory_operand>")))
19416 (set (match_dup 1) (match_dup 3))
19417 (set (reg FLAGS_REG) (compare (match_dup 3) (const_int 0)))]
19418 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
19419 && peep2_reg_dead_p (4, operands[3])
19420 && (rtx_equal_p (operands[0], operands[3])
19421 || peep2_reg_dead_p (2, operands[0]))
19422 && !reg_overlap_mentioned_p (operands[0], operands[1])
19423 && !reg_overlap_mentioned_p (operands[3], operands[1])
19424 && !reg_overlap_mentioned_p (operands[0], operands[2])
19425 && (<MODE>mode != QImode
19426 || immediate_operand (operands[2], QImode)
19427 || any_QIreg_operand (operands[2], QImode))
19428 && ix86_match_ccmode (peep2_next_insn (3), CCGOCmode)"
19429 [(parallel [(set (match_dup 4) (match_dup 6))
19430 (set (match_dup 1) (match_dup 5))])]
19432 operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
19434 = gen_rtx_PLUS (<MODE>mode,
19435 copy_rtx (operands[1]),
19438 = gen_rtx_COMPARE (GET_MODE (operands[4]),
19439 copy_rtx (operands[5]),
19444 [(parallel [(set (match_operand:SWI 0 "register_operand")
19445 (match_operator:SWI 2 "plusminuslogic_operator"
19447 (match_operand:SWI 1 "memory_operand")]))
19448 (clobber (reg:CC FLAGS_REG))])
19449 (set (match_dup 1) (match_dup 0))
19450 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
19451 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
19452 && COMMUTATIVE_ARITH_P (operands[2])
19453 && peep2_reg_dead_p (3, operands[0])
19454 && !reg_overlap_mentioned_p (operands[0], operands[1])
19455 && ix86_match_ccmode (peep2_next_insn (2),
19456 GET_CODE (operands[2]) == PLUS
19457 ? CCGOCmode : CCNOmode)"
19458 [(parallel [(set (match_dup 3) (match_dup 5))
19459 (set (match_dup 1) (match_dup 4))])]
19461 operands[3] = SET_DEST (PATTERN (peep2_next_insn (2)));
19463 = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
19464 copy_rtx (operands[1]),
19467 = gen_rtx_COMPARE (GET_MODE (operands[3]),
19468 copy_rtx (operands[4]),
19472 ;; Likewise for cmpelim optimized pattern.
19474 [(parallel [(set (reg FLAGS_REG)
19475 (compare (match_operator:SWI 2 "plusminuslogic_operator"
19476 [(match_operand:SWI 0 "register_operand")
19477 (match_operand:SWI 1 "memory_operand")])
19479 (set (match_dup 0) (match_dup 2))])
19480 (set (match_dup 1) (match_dup 0))]
19481 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
19482 && COMMUTATIVE_ARITH_P (operands[2])
19483 && peep2_reg_dead_p (2, operands[0])
19484 && !reg_overlap_mentioned_p (operands[0], operands[1])
19485 && ix86_match_ccmode (peep2_next_insn (0),
19486 GET_CODE (operands[2]) == PLUS
19487 ? CCGOCmode : CCNOmode)"
19488 [(parallel [(set (match_dup 3) (match_dup 5))
19489 (set (match_dup 1) (match_dup 4))])]
19491 operands[3] = SET_DEST (XVECEXP (PATTERN (peep2_next_insn (0)), 0, 0));
19493 = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
19494 copy_rtx (operands[1]), operands[0]);
19496 = gen_rtx_COMPARE (GET_MODE (operands[3]), copy_rtx (operands[4]),
19501 [(set (match_operand:SWI12 0 "register_operand")
19502 (match_operand:SWI12 1 "memory_operand"))
19503 (parallel [(set (match_operand:SI 4 "register_operand")
19504 (match_operator:SI 3 "plusminuslogic_operator"
19506 (match_operand:SI 2 "nonmemory_operand")]))
19507 (clobber (reg:CC FLAGS_REG))])
19508 (set (match_dup 1) (match_dup 0))
19509 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
19510 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
19511 && REGNO (operands[0]) == REGNO (operands[4])
19512 && peep2_reg_dead_p (4, operands[0])
19513 && (<MODE>mode != QImode
19514 || immediate_operand (operands[2], SImode)
19515 || any_QIreg_operand (operands[2], SImode))
19516 && !reg_overlap_mentioned_p (operands[0], operands[1])
19517 && !reg_overlap_mentioned_p (operands[0], operands[2])
19518 && ix86_match_ccmode (peep2_next_insn (3),
19519 (GET_CODE (operands[3]) == PLUS
19520 || GET_CODE (operands[3]) == MINUS)
19521 ? CCGOCmode : CCNOmode)"
19522 [(parallel [(set (match_dup 4) (match_dup 6))
19523 (set (match_dup 1) (match_dup 5))])]
19525 operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
19527 = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
19528 copy_rtx (operands[1]),
19529 gen_lowpart (<MODE>mode, operands[2]));
19531 = gen_rtx_COMPARE (GET_MODE (operands[4]),
19532 copy_rtx (operands[5]),
19536 ;; Attempt to always use XOR for zeroing registers (including FP modes).
19538 [(set (match_operand 0 "general_reg_operand")
19539 (match_operand 1 "const0_operand"))]
19540 "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
19541 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
19542 && peep2_regno_dead_p (0, FLAGS_REG)"
19543 [(parallel [(set (match_dup 0) (const_int 0))
19544 (clobber (reg:CC FLAGS_REG))])]
19545 "operands[0] = gen_lowpart (word_mode, operands[0]);")
19548 [(set (strict_low_part (match_operand:SWI12 0 "general_reg_operand"))
19550 "(! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
19551 && peep2_regno_dead_p (0, FLAGS_REG)"
19552 [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
19553 (clobber (reg:CC FLAGS_REG))])])
19555 ;; For HI, SI and DI modes, or $-1,reg is smaller than mov $-1,reg.
19557 [(set (match_operand:SWI248 0 "general_reg_operand")
19559 "(TARGET_MOVE_M1_VIA_OR || optimize_insn_for_size_p ())
19560 && peep2_regno_dead_p (0, FLAGS_REG)"
19561 [(parallel [(set (match_dup 0) (const_int -1))
19562 (clobber (reg:CC FLAGS_REG))])]
19564 if (<MODE_SIZE> < GET_MODE_SIZE (SImode))
19565 operands[0] = gen_lowpart (SImode, operands[0]);
19568 ;; Attempt to convert simple lea to add/shift.
19569 ;; These can be created by move expanders.
19570 ;; Disable PLUS peepholes on TARGET_OPT_AGU, since all
19571 ;; relevant lea instructions were already split.
19574 [(set (match_operand:SWI48 0 "register_operand")
19575 (plus:SWI48 (match_dup 0)
19576 (match_operand:SWI48 1 "<nonmemory_operand>")))]
19578 && peep2_regno_dead_p (0, FLAGS_REG)"
19579 [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1)))
19580 (clobber (reg:CC FLAGS_REG))])])
19583 [(set (match_operand:SWI48 0 "register_operand")
19584 (plus:SWI48 (match_operand:SWI48 1 "<nonmemory_operand>")
19587 && peep2_regno_dead_p (0, FLAGS_REG)"
19588 [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1)))
19589 (clobber (reg:CC FLAGS_REG))])])
19592 [(set (match_operand:DI 0 "register_operand")
19594 (plus:SI (match_operand:SI 1 "register_operand")
19595 (match_operand:SI 2 "nonmemory_operand"))))]
19596 "TARGET_64BIT && !TARGET_OPT_AGU
19597 && REGNO (operands[0]) == REGNO (operands[1])
19598 && peep2_regno_dead_p (0, FLAGS_REG)"
19599 [(parallel [(set (match_dup 0)
19600 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))
19601 (clobber (reg:CC FLAGS_REG))])])
19604 [(set (match_operand:DI 0 "register_operand")
19606 (plus:SI (match_operand:SI 1 "nonmemory_operand")
19607 (match_operand:SI 2 "register_operand"))))]
19608 "TARGET_64BIT && !TARGET_OPT_AGU
19609 && REGNO (operands[0]) == REGNO (operands[2])
19610 && peep2_regno_dead_p (0, FLAGS_REG)"
19611 [(parallel [(set (match_dup 0)
19612 (zero_extend:DI (plus:SI (match_dup 2) (match_dup 1))))
19613 (clobber (reg:CC FLAGS_REG))])])
19616 [(set (match_operand:SWI48 0 "register_operand")
19617 (mult:SWI48 (match_dup 0)
19618 (match_operand:SWI48 1 "const_int_operand")))]
19619 "pow2p_hwi (INTVAL (operands[1]))
19620 && peep2_regno_dead_p (0, FLAGS_REG)"
19621 [(parallel [(set (match_dup 0) (ashift:SWI48 (match_dup 0) (match_dup 1)))
19622 (clobber (reg:CC FLAGS_REG))])]
19623 "operands[1] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
19626 [(set (match_operand:DI 0 "register_operand")
19628 (mult:SI (match_operand:SI 1 "register_operand")
19629 (match_operand:SI 2 "const_int_operand"))))]
19631 && pow2p_hwi (INTVAL (operands[2]))
19632 && REGNO (operands[0]) == REGNO (operands[1])
19633 && peep2_regno_dead_p (0, FLAGS_REG)"
19634 [(parallel [(set (match_dup 0)
19635 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))
19636 (clobber (reg:CC FLAGS_REG))])]
19637 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
19639 ;; The ESP adjustments can be done by the push and pop instructions. Resulting
19640 ;; code is shorter, since push is only 1 byte, while add imm, %esp is 3 bytes.
19641 ;; On many CPUs it is also faster, since special hardware to avoid esp
19642 ;; dependencies is present.
19644 ;; While some of these conversions may be done using splitters, we use
19645 ;; peepholes in order to allow combine_stack_adjustments pass to see
19646 ;; nonobfuscated RTL.
19648 ;; Convert prologue esp subtractions to push.
19649 ;; We need register to push. In order to keep verify_flow_info happy we have
19651 ;; - use scratch and clobber it in order to avoid dependencies
19652 ;; - use already live register
19653 ;; We can't use the second way right now, since there is no reliable way how to
19654 ;; verify that given register is live. First choice will also most likely in
19655 ;; fewer dependencies. On the place of esp adjustments it is very likely that
19656 ;; call clobbered registers are dead. We may want to use base pointer as an
19657 ;; alternative when no register is available later.
19660 [(match_scratch:W 1 "r")
19661 (parallel [(set (reg:P SP_REG)
19662 (plus:P (reg:P SP_REG)
19663 (match_operand:P 0 "const_int_operand")))
19664 (clobber (reg:CC FLAGS_REG))
19665 (clobber (mem:BLK (scratch)))])]
19666 "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
19667 && INTVAL (operands[0]) == -GET_MODE_SIZE (word_mode)
19668 && ix86_red_zone_size == 0"
19669 [(clobber (match_dup 1))
19670 (parallel [(set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
19671 (clobber (mem:BLK (scratch)))])])
19674 [(match_scratch:W 1 "r")
19675 (parallel [(set (reg:P SP_REG)
19676 (plus:P (reg:P SP_REG)
19677 (match_operand:P 0 "const_int_operand")))
19678 (clobber (reg:CC FLAGS_REG))
19679 (clobber (mem:BLK (scratch)))])]
19680 "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
19681 && INTVAL (operands[0]) == -2*GET_MODE_SIZE (word_mode)
19682 && ix86_red_zone_size == 0"
19683 [(clobber (match_dup 1))
19684 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
19685 (parallel [(set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
19686 (clobber (mem:BLK (scratch)))])])
19688 ;; Convert esp subtractions to push.
19690 [(match_scratch:W 1 "r")
19691 (parallel [(set (reg:P SP_REG)
19692 (plus:P (reg:P SP_REG)
19693 (match_operand:P 0 "const_int_operand")))
19694 (clobber (reg:CC FLAGS_REG))])]
19695 "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
19696 && INTVAL (operands[0]) == -GET_MODE_SIZE (word_mode)
19697 && ix86_red_zone_size == 0"
19698 [(clobber (match_dup 1))
19699 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
19702 [(match_scratch:W 1 "r")
19703 (parallel [(set (reg:P SP_REG)
19704 (plus:P (reg:P SP_REG)
19705 (match_operand:P 0 "const_int_operand")))
19706 (clobber (reg:CC FLAGS_REG))])]
19707 "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
19708 && INTVAL (operands[0]) == -2*GET_MODE_SIZE (word_mode)
19709 && ix86_red_zone_size == 0"
19710 [(clobber (match_dup 1))
19711 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
19712 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
19714 ;; Convert epilogue deallocator to pop.
19716 [(match_scratch:W 1 "r")
19717 (parallel [(set (reg:P SP_REG)
19718 (plus:P (reg:P SP_REG)
19719 (match_operand:P 0 "const_int_operand")))
19720 (clobber (reg:CC FLAGS_REG))
19721 (clobber (mem:BLK (scratch)))])]
19722 "(TARGET_SINGLE_POP || optimize_insn_for_size_p ())
19723 && INTVAL (operands[0]) == GET_MODE_SIZE (word_mode)"
19724 [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
19725 (clobber (mem:BLK (scratch)))])])
19727 ;; Two pops case is tricky, since pop causes dependency
19728 ;; on destination register. We use two registers if available.
19730 [(match_scratch:W 1 "r")
19731 (match_scratch:W 2 "r")
19732 (parallel [(set (reg:P SP_REG)
19733 (plus:P (reg:P SP_REG)
19734 (match_operand:P 0 "const_int_operand")))
19735 (clobber (reg:CC FLAGS_REG))
19736 (clobber (mem:BLK (scratch)))])]
19737 "(TARGET_DOUBLE_POP || optimize_insn_for_size_p ())
19738 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
19739 [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
19740 (clobber (mem:BLK (scratch)))])
19741 (set (match_dup 2) (mem:W (post_inc:P (reg:P SP_REG))))])
19744 [(match_scratch:W 1 "r")
19745 (parallel [(set (reg:P SP_REG)
19746 (plus:P (reg:P SP_REG)
19747 (match_operand:P 0 "const_int_operand")))
19748 (clobber (reg:CC FLAGS_REG))
19749 (clobber (mem:BLK (scratch)))])]
19750 "optimize_insn_for_size_p ()
19751 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
19752 [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
19753 (clobber (mem:BLK (scratch)))])
19754 (set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
19756 ;; Convert esp additions to pop.
19758 [(match_scratch:W 1 "r")
19759 (parallel [(set (reg:P SP_REG)
19760 (plus:P (reg:P SP_REG)
19761 (match_operand:P 0 "const_int_operand")))
19762 (clobber (reg:CC FLAGS_REG))])]
19763 "INTVAL (operands[0]) == GET_MODE_SIZE (word_mode)"
19764 [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
19766 ;; Two pops case is tricky, since pop causes dependency
19767 ;; on destination register. We use two registers if available.
19769 [(match_scratch:W 1 "r")
19770 (match_scratch:W 2 "r")
19771 (parallel [(set (reg:P SP_REG)
19772 (plus:P (reg:P SP_REG)
19773 (match_operand:P 0 "const_int_operand")))
19774 (clobber (reg:CC FLAGS_REG))])]
19775 "INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
19776 [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
19777 (set (match_dup 2) (mem:W (post_inc:P (reg:P SP_REG))))])
19780 [(match_scratch:W 1 "r")
19781 (parallel [(set (reg:P SP_REG)
19782 (plus:P (reg:P SP_REG)
19783 (match_operand:P 0 "const_int_operand")))
19784 (clobber (reg:CC FLAGS_REG))])]
19785 "optimize_insn_for_size_p ()
19786 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
19787 [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
19788 (set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
19790 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
19791 ;; required and register dies. Similarly for 128 to -128.
19793 [(set (match_operand 0 "flags_reg_operand")
19794 (match_operator 1 "compare_operator"
19795 [(match_operand 2 "register_operand")
19796 (match_operand 3 "const_int_operand")]))]
19797 "(((!TARGET_FUSE_CMP_AND_BRANCH || optimize_insn_for_size_p ())
19798 && incdec_operand (operands[3], GET_MODE (operands[3])))
19799 || (!TARGET_FUSE_CMP_AND_BRANCH
19800 && INTVAL (operands[3]) == 128))
19801 && ix86_match_ccmode (insn, CCGCmode)
19802 && peep2_reg_dead_p (1, operands[2])"
19803 [(parallel [(set (match_dup 0)
19804 (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
19805 (clobber (match_dup 2))])])
19807 ;; Convert imul by three, five and nine into lea
19810 [(set (match_operand:SWI48 0 "register_operand")
19811 (mult:SWI48 (match_operand:SWI48 1 "register_operand")
19812 (match_operand:SWI48 2 "const359_operand")))
19813 (clobber (reg:CC FLAGS_REG))])]
19814 "!TARGET_PARTIAL_REG_STALL
19815 || <MODE>mode == SImode
19816 || optimize_function_for_size_p (cfun)"
19817 [(set (match_dup 0)
19818 (plus:SWI48 (mult:SWI48 (match_dup 1) (match_dup 2))
19820 "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
19824 [(set (match_operand:SWI48 0 "register_operand")
19825 (mult:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
19826 (match_operand:SWI48 2 "const359_operand")))
19827 (clobber (reg:CC FLAGS_REG))])]
19828 "optimize_insn_for_speed_p ()
19829 && (!TARGET_PARTIAL_REG_STALL || <MODE>mode == SImode)"
19830 [(set (match_dup 0) (match_dup 1))
19832 (plus:SWI48 (mult:SWI48 (match_dup 0) (match_dup 2))
19834 "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
19836 ;; imul $32bit_imm, mem, reg is vector decoded, while
19837 ;; imul $32bit_imm, reg, reg is direct decoded.
19839 [(match_scratch:SWI48 3 "r")
19840 (parallel [(set (match_operand:SWI48 0 "register_operand")
19841 (mult:SWI48 (match_operand:SWI48 1 "memory_operand")
19842 (match_operand:SWI48 2 "immediate_operand")))
19843 (clobber (reg:CC FLAGS_REG))])]
19844 "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
19845 && !satisfies_constraint_K (operands[2])"
19846 [(set (match_dup 3) (match_dup 1))
19847 (parallel [(set (match_dup 0) (mult:SWI48 (match_dup 3) (match_dup 2)))
19848 (clobber (reg:CC FLAGS_REG))])])
19851 [(match_scratch:SI 3 "r")
19852 (parallel [(set (match_operand:DI 0 "register_operand")
19854 (mult:SI (match_operand:SI 1 "memory_operand")
19855 (match_operand:SI 2 "immediate_operand"))))
19856 (clobber (reg:CC FLAGS_REG))])]
19858 && TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
19859 && !satisfies_constraint_K (operands[2])"
19860 [(set (match_dup 3) (match_dup 1))
19861 (parallel [(set (match_dup 0)
19862 (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
19863 (clobber (reg:CC FLAGS_REG))])])
19865 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
19866 ;; Convert it into imul reg, reg
19867 ;; It would be better to force assembler to encode instruction using long
19868 ;; immediate, but there is apparently no way to do so.
19870 [(parallel [(set (match_operand:SWI248 0 "register_operand")
19872 (match_operand:SWI248 1 "nonimmediate_operand")
19873 (match_operand:SWI248 2 "const_int_operand")))
19874 (clobber (reg:CC FLAGS_REG))])
19875 (match_scratch:SWI248 3 "r")]
19876 "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
19877 && satisfies_constraint_K (operands[2])"
19878 [(set (match_dup 3) (match_dup 2))
19879 (parallel [(set (match_dup 0) (mult:SWI248 (match_dup 0) (match_dup 3)))
19880 (clobber (reg:CC FLAGS_REG))])]
19882 if (!rtx_equal_p (operands[0], operands[1]))
19883 emit_move_insn (operands[0], operands[1]);
19886 ;; After splitting up read-modify operations, array accesses with memory
19887 ;; operands might end up in form:
19889 ;; movl 4(%esp), %edx
19891 ;; instead of pre-splitting:
19893 ;; addl 4(%esp), %eax
19895 ;; movl 4(%esp), %edx
19896 ;; leal (%edx,%eax,4), %eax
19899 [(match_scratch:W 5 "r")
19900 (parallel [(set (match_operand 0 "register_operand")
19901 (ashift (match_operand 1 "register_operand")
19902 (match_operand 2 "const_int_operand")))
19903 (clobber (reg:CC FLAGS_REG))])
19904 (parallel [(set (match_operand 3 "register_operand")
19905 (plus (match_dup 0)
19906 (match_operand 4 "x86_64_general_operand")))
19907 (clobber (reg:CC FLAGS_REG))])]
19908 "IN_RANGE (INTVAL (operands[2]), 1, 3)
19909 /* Validate MODE for lea. */
19910 && ((!TARGET_PARTIAL_REG_STALL
19911 && (GET_MODE (operands[0]) == QImode
19912 || GET_MODE (operands[0]) == HImode))
19913 || GET_MODE (operands[0]) == SImode
19914 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
19915 && (rtx_equal_p (operands[0], operands[3])
19916 || peep2_reg_dead_p (2, operands[0]))
19917 /* We reorder load and the shift. */
19918 && !reg_overlap_mentioned_p (operands[0], operands[4])"
19919 [(set (match_dup 5) (match_dup 4))
19920 (set (match_dup 0) (match_dup 1))]
19922 machine_mode op1mode = GET_MODE (operands[1]);
19923 machine_mode mode = op1mode == DImode ? DImode : SImode;
19924 int scale = 1 << INTVAL (operands[2]);
19925 rtx index = gen_lowpart (word_mode, operands[1]);
19926 rtx base = gen_lowpart (word_mode, operands[5]);
19927 rtx dest = gen_lowpart (mode, operands[3]);
19929 operands[1] = gen_rtx_PLUS (word_mode, base,
19930 gen_rtx_MULT (word_mode, index, GEN_INT (scale)));
19931 if (mode != word_mode)
19932 operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
19934 operands[5] = base;
19935 if (op1mode != word_mode)
19936 operands[5] = gen_lowpart (op1mode, operands[5]);
19938 operands[0] = dest;
19941 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
19942 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
19943 ;; caught for use by garbage collectors and the like. Using an insn that
19944 ;; maps to SIGILL makes it more likely the program will rightfully die.
19945 ;; Keeping with tradition, "6" is in honor of #UD.
19946 (define_insn "trap"
19947 [(trap_if (const_int 1) (const_int 6))]
19950 #ifdef HAVE_AS_IX86_UD2
19953 return ASM_SHORT "0x0b0f";
19956 [(set_attr "length" "2")])
19959 [(unspec_volatile [(const_int 0)] UNSPECV_UD2)]
19962 #ifdef HAVE_AS_IX86_UD2
19965 return ASM_SHORT "0x0b0f";
19968 [(set_attr "length" "2")])
19970 (define_expand "prefetch"
19971 [(prefetch (match_operand 0 "address_operand")
19972 (match_operand:SI 1 "const_int_operand")
19973 (match_operand:SI 2 "const_int_operand"))]
19974 "TARGET_3DNOW || TARGET_PREFETCH_SSE || TARGET_PRFCHW || TARGET_PREFETCHWT1"
19976 bool write = INTVAL (operands[1]) != 0;
19977 int locality = INTVAL (operands[2]);
19979 gcc_assert (IN_RANGE (locality, 0, 3));
19981 /* Use 3dNOW prefetch in case we are asking for write prefetch not
19982 supported by SSE counterpart (non-SSE2 athlon machines) or the
19983 SSE prefetch is not available (K6 machines). Otherwise use SSE
19984 prefetch as it allows specifying of locality. */
19988 if (TARGET_PREFETCHWT1)
19989 operands[2] = GEN_INT (MAX (locality, 2));
19990 else if (TARGET_PRFCHW)
19991 operands[2] = GEN_INT (3);
19992 else if (TARGET_3DNOW && !TARGET_SSE2)
19993 operands[2] = GEN_INT (3);
19994 else if (TARGET_PREFETCH_SSE)
19995 operands[1] = const0_rtx;
19998 gcc_assert (TARGET_3DNOW);
19999 operands[2] = GEN_INT (3);
20004 if (TARGET_PREFETCH_SSE)
20008 gcc_assert (TARGET_3DNOW);
20009 operands[2] = GEN_INT (3);
20014 (define_insn "*prefetch_sse"
20015 [(prefetch (match_operand 0 "address_operand" "p")
20017 (match_operand:SI 1 "const_int_operand"))]
20018 "TARGET_PREFETCH_SSE"
20020 static const char * const patterns[4] = {
20021 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
20024 int locality = INTVAL (operands[1]);
20025 gcc_assert (IN_RANGE (locality, 0, 3));
20027 return patterns[locality];
20029 [(set_attr "type" "sse")
20030 (set_attr "atom_sse_attr" "prefetch")
20031 (set (attr "length_address")
20032 (symbol_ref "memory_address_length (operands[0], false)"))
20033 (set_attr "memory" "none")])
20035 (define_insn "*prefetch_3dnow"
20036 [(prefetch (match_operand 0 "address_operand" "p")
20037 (match_operand:SI 1 "const_int_operand" "n")
20039 "TARGET_3DNOW || TARGET_PRFCHW || TARGET_PREFETCHWT1"
20041 if (INTVAL (operands[1]) == 0)
20042 return "prefetch\t%a0";
20044 return "prefetchw\t%a0";
20046 [(set_attr "type" "mmx")
20047 (set (attr "length_address")
20048 (symbol_ref "memory_address_length (operands[0], false)"))
20049 (set_attr "memory" "none")])
20051 (define_insn "*prefetch_prefetchwt1"
20052 [(prefetch (match_operand 0 "address_operand" "p")
20055 "TARGET_PREFETCHWT1"
20056 "prefetchwt1\t%a0";
20057 [(set_attr "type" "sse")
20058 (set (attr "length_address")
20059 (symbol_ref "memory_address_length (operands[0], false)"))
20060 (set_attr "memory" "none")])
20062 (define_expand "stack_protect_set"
20063 [(match_operand 0 "memory_operand")
20064 (match_operand 1 "memory_operand")]
20065 "TARGET_SSP_TLS_GUARD"
20067 rtx (*insn)(rtx, rtx);
20069 insn = (TARGET_LP64
20070 ? gen_stack_protect_set_di
20071 : gen_stack_protect_set_si);
20073 emit_insn (insn (operands[0], operands[1]));
20077 (define_insn "stack_protect_set_<mode>"
20078 [(set (match_operand:PTR 0 "memory_operand" "=m")
20079 (unspec:PTR [(match_operand:PTR 1 "memory_operand" "m")]
20081 (set (match_scratch:PTR 2 "=&r") (const_int 0))
20082 (clobber (reg:CC FLAGS_REG))]
20083 "TARGET_SSP_TLS_GUARD"
20084 "mov{<imodesuffix>}\t{%1, %2|%2, %1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
20085 [(set_attr "type" "multi")])
20087 (define_expand "stack_protect_test"
20088 [(match_operand 0 "memory_operand")
20089 (match_operand 1 "memory_operand")
20091 "TARGET_SSP_TLS_GUARD"
20093 rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
20095 rtx (*insn)(rtx, rtx, rtx);
20097 insn = (TARGET_LP64
20098 ? gen_stack_protect_test_di
20099 : gen_stack_protect_test_si);
20101 emit_insn (insn (flags, operands[0], operands[1]));
20103 emit_jump_insn (gen_cbranchcc4 (gen_rtx_EQ (VOIDmode, flags, const0_rtx),
20104 flags, const0_rtx, operands[2]));
20108 (define_insn "stack_protect_test_<mode>"
20109 [(set (match_operand:CCZ 0 "flags_reg_operand")
20110 (unspec:CCZ [(match_operand:PTR 1 "memory_operand" "m")
20111 (match_operand:PTR 2 "memory_operand" "m")]
20113 (clobber (match_scratch:PTR 3 "=&r"))]
20114 "TARGET_SSP_TLS_GUARD"
20115 "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%2, %3|%3, %2}"
20116 [(set_attr "type" "multi")])
20118 (define_insn "sse4_2_crc32<mode>"
20119 [(set (match_operand:SI 0 "register_operand" "=r")
20121 [(match_operand:SI 1 "register_operand" "0")
20122 (match_operand:SWI124 2 "nonimmediate_operand" "<r>m")]
20124 "TARGET_SSE4_2 || TARGET_CRC32"
20125 "crc32{<imodesuffix>}\t{%2, %0|%0, %2}"
20126 [(set_attr "type" "sselog1")
20127 (set_attr "prefix_rep" "1")
20128 (set_attr "prefix_extra" "1")
20129 (set (attr "prefix_data16")
20130 (if_then_else (match_operand:HI 2)
20132 (const_string "*")))
20133 (set (attr "prefix_rex")
20134 (if_then_else (match_operand:QI 2 "ext_QIreg_operand")
20136 (const_string "*")))
20137 (set_attr "mode" "SI")])
20139 (define_insn "sse4_2_crc32di"
20140 [(set (match_operand:DI 0 "register_operand" "=r")
20142 [(match_operand:DI 1 "register_operand" "0")
20143 (match_operand:DI 2 "nonimmediate_operand" "rm")]
20145 "TARGET_64BIT && (TARGET_SSE4_2 || TARGET_CRC32)"
20146 "crc32{q}\t{%2, %0|%0, %2}"
20147 [(set_attr "type" "sselog1")
20148 (set_attr "prefix_rep" "1")
20149 (set_attr "prefix_extra" "1")
20150 (set_attr "mode" "DI")])
20152 (define_insn "rdpmc"
20153 [(set (match_operand:DI 0 "register_operand" "=A")
20154 (unspec_volatile:DI [(match_operand:SI 1 "register_operand" "c")]
20158 [(set_attr "type" "other")
20159 (set_attr "length" "2")])
20161 (define_insn "rdpmc_rex64"
20162 [(set (match_operand:DI 0 "register_operand" "=a")
20163 (unspec_volatile:DI [(match_operand:SI 2 "register_operand" "c")]
20165 (set (match_operand:DI 1 "register_operand" "=d")
20166 (unspec_volatile:DI [(match_dup 2)] UNSPECV_RDPMC))]
20169 [(set_attr "type" "other")
20170 (set_attr "length" "2")])
20172 (define_insn "rdtsc"
20173 [(set (match_operand:DI 0 "register_operand" "=A")
20174 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
20177 [(set_attr "type" "other")
20178 (set_attr "length" "2")])
20180 (define_insn "rdtsc_rex64"
20181 [(set (match_operand:DI 0 "register_operand" "=a")
20182 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))
20183 (set (match_operand:DI 1 "register_operand" "=d")
20184 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
20187 [(set_attr "type" "other")
20188 (set_attr "length" "2")])
20190 (define_insn "rdtscp"
20191 [(set (match_operand:DI 0 "register_operand" "=A")
20192 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
20193 (set (match_operand:SI 1 "register_operand" "=c")
20194 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
20197 [(set_attr "type" "other")
20198 (set_attr "length" "3")])
20200 (define_insn "rdtscp_rex64"
20201 [(set (match_operand:DI 0 "register_operand" "=a")
20202 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
20203 (set (match_operand:DI 1 "register_operand" "=d")
20204 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
20205 (set (match_operand:SI 2 "register_operand" "=c")
20206 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
20209 [(set_attr "type" "other")
20210 (set_attr "length" "3")])
20212 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
20214 ;; FXSR, XSAVE and XSAVEOPT instructions
20216 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
20218 (define_insn "fxsave"
20219 [(set (match_operand:BLK 0 "memory_operand" "=m")
20220 (unspec_volatile:BLK [(const_int 0)] UNSPECV_FXSAVE))]
20223 [(set_attr "type" "other")
20224 (set_attr "memory" "store")
20225 (set (attr "length")
20226 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
20228 (define_insn "fxsave64"
20229 [(set (match_operand:BLK 0 "memory_operand" "=m")
20230 (unspec_volatile:BLK [(const_int 0)] UNSPECV_FXSAVE64))]
20231 "TARGET_64BIT && TARGET_FXSR"
20233 [(set_attr "type" "other")
20234 (set_attr "memory" "store")
20235 (set (attr "length")
20236 (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
20238 (define_insn "fxrstor"
20239 [(unspec_volatile [(match_operand:BLK 0 "memory_operand" "m")]
20243 [(set_attr "type" "other")
20244 (set_attr "memory" "load")
20245 (set (attr "length")
20246 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
20248 (define_insn "fxrstor64"
20249 [(unspec_volatile [(match_operand:BLK 0 "memory_operand" "m")]
20250 UNSPECV_FXRSTOR64)]
20251 "TARGET_64BIT && TARGET_FXSR"
20253 [(set_attr "type" "other")
20254 (set_attr "memory" "load")
20255 (set (attr "length")
20256 (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
20258 (define_int_iterator ANY_XSAVE
20260 (UNSPECV_XSAVEOPT "TARGET_XSAVEOPT")
20261 (UNSPECV_XSAVEC "TARGET_XSAVEC")
20262 (UNSPECV_XSAVES "TARGET_XSAVES")])
20264 (define_int_iterator ANY_XSAVE64
20266 (UNSPECV_XSAVEOPT64 "TARGET_XSAVEOPT")
20267 (UNSPECV_XSAVEC64 "TARGET_XSAVEC")
20268 (UNSPECV_XSAVES64 "TARGET_XSAVES")])
20270 (define_int_attr xsave
20271 [(UNSPECV_XSAVE "xsave")
20272 (UNSPECV_XSAVE64 "xsave64")
20273 (UNSPECV_XSAVEOPT "xsaveopt")
20274 (UNSPECV_XSAVEOPT64 "xsaveopt64")
20275 (UNSPECV_XSAVEC "xsavec")
20276 (UNSPECV_XSAVEC64 "xsavec64")
20277 (UNSPECV_XSAVES "xsaves")
20278 (UNSPECV_XSAVES64 "xsaves64")])
20280 (define_int_iterator ANY_XRSTOR
20282 (UNSPECV_XRSTORS "TARGET_XSAVES")])
20284 (define_int_iterator ANY_XRSTOR64
20286 (UNSPECV_XRSTORS64 "TARGET_XSAVES")])
20288 (define_int_attr xrstor
20289 [(UNSPECV_XRSTOR "xrstor")
20290 (UNSPECV_XRSTOR64 "xrstor")
20291 (UNSPECV_XRSTORS "xrstors")
20292 (UNSPECV_XRSTORS64 "xrstors")])
20294 (define_insn "<xsave>"
20295 [(set (match_operand:BLK 0 "memory_operand" "=m")
20296 (unspec_volatile:BLK
20297 [(match_operand:DI 1 "register_operand" "A")]
20299 "!TARGET_64BIT && TARGET_XSAVE"
20301 [(set_attr "type" "other")
20302 (set_attr "memory" "store")
20303 (set (attr "length")
20304 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
20306 (define_insn "<xsave>_rex64"
20307 [(set (match_operand:BLK 0 "memory_operand" "=m")
20308 (unspec_volatile:BLK
20309 [(match_operand:SI 1 "register_operand" "a")
20310 (match_operand:SI 2 "register_operand" "d")]
20312 "TARGET_64BIT && TARGET_XSAVE"
20314 [(set_attr "type" "other")
20315 (set_attr "memory" "store")
20316 (set (attr "length")
20317 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
20319 (define_insn "<xsave>"
20320 [(set (match_operand:BLK 0 "memory_operand" "=m")
20321 (unspec_volatile:BLK
20322 [(match_operand:SI 1 "register_operand" "a")
20323 (match_operand:SI 2 "register_operand" "d")]
20325 "TARGET_64BIT && TARGET_XSAVE"
20327 [(set_attr "type" "other")
20328 (set_attr "memory" "store")
20329 (set (attr "length")
20330 (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
20332 (define_insn "<xrstor>"
20333 [(unspec_volatile:BLK
20334 [(match_operand:BLK 0 "memory_operand" "m")
20335 (match_operand:DI 1 "register_operand" "A")]
20337 "!TARGET_64BIT && TARGET_XSAVE"
20339 [(set_attr "type" "other")
20340 (set_attr "memory" "load")
20341 (set (attr "length")
20342 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
20344 (define_insn "<xrstor>_rex64"
20345 [(unspec_volatile:BLK
20346 [(match_operand:BLK 0 "memory_operand" "m")
20347 (match_operand:SI 1 "register_operand" "a")
20348 (match_operand:SI 2 "register_operand" "d")]
20350 "TARGET_64BIT && TARGET_XSAVE"
20352 [(set_attr "type" "other")
20353 (set_attr "memory" "load")
20354 (set (attr "length")
20355 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
20357 (define_insn "<xrstor>64"
20358 [(unspec_volatile:BLK
20359 [(match_operand:BLK 0 "memory_operand" "m")
20360 (match_operand:SI 1 "register_operand" "a")
20361 (match_operand:SI 2 "register_operand" "d")]
20363 "TARGET_64BIT && TARGET_XSAVE"
20365 [(set_attr "type" "other")
20366 (set_attr "memory" "load")
20367 (set (attr "length")
20368 (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
20370 (define_insn "xsetbv"
20371 [(unspec_volatile:SI
20372 [(match_operand:SI 0 "register_operand" "c")
20373 (match_operand:DI 1 "register_operand" "A")]
20375 "!TARGET_64BIT && TARGET_XSAVE"
20377 [(set_attr "type" "other")])
20379 (define_insn "xsetbv_rex64"
20380 [(unspec_volatile:SI
20381 [(match_operand:SI 0 "register_operand" "c")
20382 (match_operand:SI 1 "register_operand" "a")
20383 (match_operand:SI 2 "register_operand" "d")]
20385 "TARGET_64BIT && TARGET_XSAVE"
20387 [(set_attr "type" "other")])
20389 (define_insn "xgetbv"
20390 [(set (match_operand:DI 0 "register_operand" "=A")
20391 (unspec_volatile:DI [(match_operand:SI 1 "register_operand" "c")]
20393 "!TARGET_64BIT && TARGET_XSAVE"
20395 [(set_attr "type" "other")])
20397 (define_insn "xgetbv_rex64"
20398 [(set (match_operand:DI 0 "register_operand" "=a")
20399 (unspec_volatile:DI [(match_operand:SI 2 "register_operand" "c")]
20401 (set (match_operand:DI 1 "register_operand" "=d")
20402 (unspec_volatile:DI [(match_dup 2)] UNSPECV_XGETBV))]
20403 "TARGET_64BIT && TARGET_XSAVE"
20405 [(set_attr "type" "other")])
20407 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
20409 ;; Floating-point instructions for atomic compound assignments
20411 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
20413 ; Clobber all floating-point registers on environment save and restore
20414 ; to ensure that the TOS value saved at fnstenv is valid after fldenv.
20415 (define_insn "fnstenv"
20416 [(set (match_operand:BLK 0 "memory_operand" "=m")
20417 (unspec_volatile:BLK [(const_int 0)] UNSPECV_FNSTENV))
20418 (clobber (reg:HI FPCR_REG))
20419 (clobber (reg:XF ST0_REG))
20420 (clobber (reg:XF ST1_REG))
20421 (clobber (reg:XF ST2_REG))
20422 (clobber (reg:XF ST3_REG))
20423 (clobber (reg:XF ST4_REG))
20424 (clobber (reg:XF ST5_REG))
20425 (clobber (reg:XF ST6_REG))
20426 (clobber (reg:XF ST7_REG))]
20429 [(set_attr "type" "other")
20430 (set_attr "memory" "store")
20431 (set (attr "length")
20432 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))])
20434 (define_insn "fldenv"
20435 [(unspec_volatile [(match_operand:BLK 0 "memory_operand" "m")]
20437 (clobber (reg:CCFP FPSR_REG))
20438 (clobber (reg:HI FPCR_REG))
20439 (clobber (reg:XF ST0_REG))
20440 (clobber (reg:XF ST1_REG))
20441 (clobber (reg:XF ST2_REG))
20442 (clobber (reg:XF ST3_REG))
20443 (clobber (reg:XF ST4_REG))
20444 (clobber (reg:XF ST5_REG))
20445 (clobber (reg:XF ST6_REG))
20446 (clobber (reg:XF ST7_REG))]
20449 [(set_attr "type" "other")
20450 (set_attr "memory" "load")
20451 (set (attr "length")
20452 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))])
20454 (define_insn "fnstsw"
20455 [(set (match_operand:HI 0 "nonimmediate_operand" "=a,m")
20456 (unspec_volatile:HI [(const_int 0)] UNSPECV_FNSTSW))]
20459 [(set_attr "type" "other,other")
20460 (set_attr "memory" "none,store")
20461 (set (attr "length")
20462 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))])
20464 (define_insn "fnclex"
20465 [(unspec_volatile [(const_int 0)] UNSPECV_FNCLEX)]
20468 [(set_attr "type" "other")
20469 (set_attr "memory" "none")
20470 (set_attr "length" "2")])
20472 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
20474 ;; LWP instructions
20476 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
20478 (define_expand "lwp_llwpcb"
20479 [(unspec_volatile [(match_operand 0 "register_operand")]
20480 UNSPECV_LLWP_INTRINSIC)]
20483 (define_insn "*lwp_llwpcb<mode>1"
20484 [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
20485 UNSPECV_LLWP_INTRINSIC)]
20488 [(set_attr "type" "lwp")
20489 (set_attr "mode" "<MODE>")
20490 (set_attr "length" "5")])
20492 (define_expand "lwp_slwpcb"
20493 [(set (match_operand 0 "register_operand")
20494 (unspec_volatile [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
20499 insn = (Pmode == DImode
20501 : gen_lwp_slwpcbsi);
20503 emit_insn (insn (operands[0]));
20507 (define_insn "lwp_slwpcb<mode>"
20508 [(set (match_operand:P 0 "register_operand" "=r")
20509 (unspec_volatile:P [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
20512 [(set_attr "type" "lwp")
20513 (set_attr "mode" "<MODE>")
20514 (set_attr "length" "5")])
20516 (define_expand "lwp_lwpval<mode>3"
20517 [(unspec_volatile [(match_operand:SWI48 1 "register_operand")
20518 (match_operand:SI 2 "nonimmediate_operand")
20519 (match_operand:SI 3 "const_int_operand")]
20520 UNSPECV_LWPVAL_INTRINSIC)]
20522 ;; Avoid unused variable warning.
20523 "(void) operands[0];")
20525 (define_insn "*lwp_lwpval<mode>3_1"
20526 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")
20527 (match_operand:SI 1 "nonimmediate_operand" "rm")
20528 (match_operand:SI 2 "const_int_operand" "i")]
20529 UNSPECV_LWPVAL_INTRINSIC)]
20531 "lwpval\t{%2, %1, %0|%0, %1, %2}"
20532 [(set_attr "type" "lwp")
20533 (set_attr "mode" "<MODE>")
20534 (set (attr "length")
20535 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
20537 (define_expand "lwp_lwpins<mode>3"
20538 [(set (reg:CCC FLAGS_REG)
20539 (unspec_volatile:CCC [(match_operand:SWI48 1 "register_operand")
20540 (match_operand:SI 2 "nonimmediate_operand")
20541 (match_operand:SI 3 "const_int_operand")]
20542 UNSPECV_LWPINS_INTRINSIC))
20543 (set (match_operand:QI 0 "nonimmediate_operand")
20544 (eq:QI (reg:CCC FLAGS_REG) (const_int 0)))]
20547 (define_insn "*lwp_lwpins<mode>3_1"
20548 [(set (reg:CCC FLAGS_REG)
20549 (unspec_volatile:CCC [(match_operand:SWI48 0 "register_operand" "r")
20550 (match_operand:SI 1 "nonimmediate_operand" "rm")
20551 (match_operand:SI 2 "const_int_operand" "i")]
20552 UNSPECV_LWPINS_INTRINSIC))]
20554 "lwpins\t{%2, %1, %0|%0, %1, %2}"
20555 [(set_attr "type" "lwp")
20556 (set_attr "mode" "<MODE>")
20557 (set (attr "length")
20558 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
20560 (define_int_iterator RDFSGSBASE
20564 (define_int_iterator WRFSGSBASE
20568 (define_int_attr fsgs
20569 [(UNSPECV_RDFSBASE "fs")
20570 (UNSPECV_RDGSBASE "gs")
20571 (UNSPECV_WRFSBASE "fs")
20572 (UNSPECV_WRGSBASE "gs")])
20574 (define_insn "rd<fsgs>base<mode>"
20575 [(set (match_operand:SWI48 0 "register_operand" "=r")
20576 (unspec_volatile:SWI48 [(const_int 0)] RDFSGSBASE))]
20577 "TARGET_64BIT && TARGET_FSGSBASE"
20579 [(set_attr "type" "other")
20580 (set_attr "prefix_extra" "2")])
20582 (define_insn "wr<fsgs>base<mode>"
20583 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
20585 "TARGET_64BIT && TARGET_FSGSBASE"
20587 [(set_attr "type" "other")
20588 (set_attr "prefix_extra" "2")])
20590 (define_insn "rdrand<mode>_1"
20591 [(set (match_operand:SWI248 0 "register_operand" "=r")
20592 (unspec_volatile:SWI248 [(const_int 0)] UNSPECV_RDRAND))
20593 (set (reg:CCC FLAGS_REG)
20594 (unspec_volatile:CCC [(const_int 0)] UNSPECV_RDRAND))]
20597 [(set_attr "type" "other")
20598 (set_attr "prefix_extra" "1")])
20600 (define_insn "rdseed<mode>_1"
20601 [(set (match_operand:SWI248 0 "register_operand" "=r")
20602 (unspec_volatile:SWI248 [(const_int 0)] UNSPECV_RDSEED))
20603 (set (reg:CCC FLAGS_REG)
20604 (unspec_volatile:CCC [(const_int 0)] UNSPECV_RDSEED))]
20607 [(set_attr "type" "other")
20608 (set_attr "prefix_extra" "1")])
20610 (define_expand "pause"
20611 [(set (match_dup 0)
20612 (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
20615 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
20616 MEM_VOLATILE_P (operands[0]) = 1;
20619 ;; Use "rep; nop", instead of "pause", to support older assemblers.
20620 ;; They have the same encoding.
20621 (define_insn "*pause"
20622 [(set (match_operand:BLK 0)
20623 (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
20626 [(set_attr "length" "2")
20627 (set_attr "memory" "unknown")])
20629 ;; CET instructions
20630 (define_insn "rdssp<mode>"
20631 [(set (match_operand:SWI48x 0 "register_operand" "=r")
20632 (unspec_volatile:SWI48x [(const_int 0)] UNSPECV_NOP_RDSSP))]
20633 "TARGET_SHSTK || (flag_cf_protection & CF_RETURN)"
20634 "xor{l}\t%k0, %k0\n\trdssp<mskmodesuffix>\t%0"
20635 [(set_attr "length" "6")
20636 (set_attr "type" "other")])
20638 (define_insn "incssp<mode>"
20639 [(unspec_volatile [(match_operand:SWI48x 0 "register_operand" "r")]
20641 "TARGET_SHSTK || (flag_cf_protection & CF_RETURN)"
20642 "incssp<mskmodesuffix>\t%0"
20643 [(set_attr "length" "4")
20644 (set_attr "type" "other")])
20646 (define_insn "saveprevssp"
20647 [(unspec_volatile [(const_int 0)] UNSPECV_SAVEPREVSSP)]
20650 [(set_attr "length" "5")
20651 (set_attr "type" "other")])
20653 (define_expand "rstorssp"
20654 [(unspec_volatile [(match_operand 0 "memory_operand")]
20658 (define_insn "*rstorssp<mode>"
20659 [(unspec_volatile [(match_operand:P 0 "memory_operand" "m")]
20663 [(set_attr "length" "5")
20664 (set_attr "type" "other")])
20666 (define_insn "wrss<mode>"
20667 [(unspec_volatile [(match_operand:SWI48x 0 "register_operand" "r")
20668 (match_operand:SWI48x 1 "memory_operand" "m")]
20671 "wrss<mskmodesuffix>\t%0, %1"
20672 [(set_attr "length" "3")
20673 (set_attr "type" "other")])
20675 (define_insn "wruss<mode>"
20676 [(unspec_volatile [(match_operand:SWI48x 0 "register_operand" "r")
20677 (match_operand:SWI48x 1 "memory_operand" "m")]
20680 "wruss<mskmodesuffix>\t%0, %1"
20681 [(set_attr "length" "4")
20682 (set_attr "type" "other")])
20684 (define_insn "setssbsy"
20685 [(unspec_volatile [(const_int 0)] UNSPECV_SETSSBSY)]
20688 [(set_attr "length" "4")
20689 (set_attr "type" "other")])
20691 (define_expand "clrssbsy"
20692 [(unspec_volatile [(match_operand 0 "memory_operand")]
20696 (define_insn "*clrssbsy<mode>"
20697 [(unspec_volatile [(match_operand:P 0 "memory_operand" "m")]
20701 [(set_attr "length" "4")
20702 (set_attr "type" "other")])
20704 (define_insn "nop_endbr"
20705 [(unspec_volatile [(const_int 0)] UNSPECV_NOP_ENDBR)]
20706 "(flag_cf_protection & CF_BRANCH)"
20708 return TARGET_64BIT ? "endbr64" : "endbr32";
20710 [(set_attr "length" "4")
20711 (set_attr "length_immediate" "0")
20712 (set_attr "modrm" "0")])
20715 (define_expand "xbegin"
20716 [(set (match_operand:SI 0 "register_operand")
20717 (unspec_volatile:SI [(const_int 0)] UNSPECV_XBEGIN))]
20720 rtx_code_label *label = gen_label_rtx ();
20722 /* xbegin is emitted as jump_insn, so reload won't be able
20723 to reload its operand. Force the value into AX hard register. */
20724 rtx ax_reg = gen_rtx_REG (SImode, AX_REG);
20725 emit_move_insn (ax_reg, constm1_rtx);
20727 emit_jump_insn (gen_xbegin_1 (ax_reg, label));
20729 emit_label (label);
20730 LABEL_NUSES (label) = 1;
20732 emit_move_insn (operands[0], ax_reg);
20737 (define_insn "xbegin_1"
20739 (if_then_else (ne (unspec [(const_int 0)] UNSPEC_XBEGIN_ABORT)
20741 (label_ref (match_operand 1))
20743 (set (match_operand:SI 0 "register_operand" "+a")
20744 (unspec_volatile:SI [(match_dup 0)] UNSPECV_XBEGIN))]
20747 [(set_attr "type" "other")
20748 (set_attr "length" "6")])
20750 (define_insn "xend"
20751 [(unspec_volatile [(const_int 0)] UNSPECV_XEND)]
20754 [(set_attr "type" "other")
20755 (set_attr "length" "3")])
20757 (define_insn "xabort"
20758 [(unspec_volatile [(match_operand:SI 0 "const_0_to_255_operand" "n")]
20762 [(set_attr "type" "other")
20763 (set_attr "length" "3")])
20765 (define_expand "xtest"
20766 [(set (match_operand:QI 0 "register_operand")
20767 (unspec_volatile:QI [(const_int 0)] UNSPECV_XTEST))]
20770 emit_insn (gen_xtest_1 ());
20772 ix86_expand_setcc (operands[0], NE,
20773 gen_rtx_REG (CCZmode, FLAGS_REG), const0_rtx);
20777 (define_insn "xtest_1"
20778 [(set (reg:CCZ FLAGS_REG)
20779 (unspec_volatile:CCZ [(const_int 0)] UNSPECV_XTEST))]
20782 [(set_attr "type" "other")
20783 (set_attr "length" "3")])
20785 (define_insn "clwb"
20786 [(unspec_volatile [(match_operand 0 "address_operand" "p")]
20790 [(set_attr "type" "sse")
20791 (set_attr "atom_sse_attr" "fence")
20792 (set_attr "memory" "unknown")])
20794 (define_insn "clflushopt"
20795 [(unspec_volatile [(match_operand 0 "address_operand" "p")]
20796 UNSPECV_CLFLUSHOPT)]
20797 "TARGET_CLFLUSHOPT"
20799 [(set_attr "type" "sse")
20800 (set_attr "atom_sse_attr" "fence")
20801 (set_attr "memory" "unknown")])
20803 ;; MONITORX and MWAITX
20804 (define_insn "mwaitx"
20805 [(unspec_volatile [(match_operand:SI 0 "register_operand" "c")
20806 (match_operand:SI 1 "register_operand" "a")
20807 (match_operand:SI 2 "register_operand" "b")]
20810 ;; 64bit version is "mwaitx %rax,%rcx,%rbx". But only lower 32bits are used.
20811 ;; Since 32bit register operands are implicitly zero extended to 64bit,
20812 ;; we only need to set up 32bit registers.
20814 [(set_attr "length" "3")])
20816 (define_insn "monitorx_<mode>"
20817 [(unspec_volatile [(match_operand:P 0 "register_operand" "a")
20818 (match_operand:SI 1 "register_operand" "c")
20819 (match_operand:SI 2 "register_operand" "d")]
20822 ;; 64bit version is "monitorx %rax,%rcx,%rdx". But only lower 32bits in
20823 ;; RCX and RDX are used. Since 32bit register operands are implicitly
20824 ;; zero extended to 64bit, we only need to set up 32bit registers.
20826 [(set (attr "length")
20827 (symbol_ref ("(Pmode != word_mode) + 3")))])
20830 (define_insn "clzero_<mode>"
20831 [(unspec_volatile [(match_operand: P 0 "register_operand" "a")]
20835 [(set_attr "length" "3")
20836 (set_attr "memory" "unknown")])
20838 ;; RDPKRU and WRPKRU
20840 (define_expand "rdpkru"
20842 [(set (match_operand:SI 0 "register_operand")
20843 (unspec_volatile:SI [(match_dup 1)] UNSPECV_PKU))
20844 (set (match_dup 2) (const_int 0))])]
20847 operands[1] = force_reg (SImode, const0_rtx);
20848 operands[2] = gen_reg_rtx (SImode);
20851 (define_insn "*rdpkru"
20852 [(set (match_operand:SI 0 "register_operand" "=a")
20853 (unspec_volatile:SI [(match_operand:SI 2 "register_operand" "c")]
20855 (set (match_operand:SI 1 "register_operand" "=d")
20859 [(set_attr "type" "other")])
20861 (define_expand "wrpkru"
20862 [(unspec_volatile:SI
20863 [(match_operand:SI 0 "register_operand")
20864 (match_dup 1) (match_dup 2)] UNSPECV_PKU)]
20867 operands[1] = force_reg (SImode, const0_rtx);
20868 operands[2] = force_reg (SImode, const0_rtx);
20871 (define_insn "*wrpkru"
20872 [(unspec_volatile:SI
20873 [(match_operand:SI 0 "register_operand" "a")
20874 (match_operand:SI 1 "register_operand" "d")
20875 (match_operand:SI 2 "register_operand" "c")] UNSPECV_PKU)]
20878 [(set_attr "type" "other")])
20880 (define_insn "rdpid"
20881 [(set (match_operand:SI 0 "register_operand" "=r")
20882 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDPID))]
20883 "!TARGET_64BIT && TARGET_RDPID"
20885 [(set_attr "type" "other")])
20887 (define_insn "rdpid_rex64"
20888 [(set (match_operand:DI 0 "register_operand" "=r")
20889 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDPID))]
20890 "TARGET_64BIT && TARGET_RDPID"
20892 [(set_attr "type" "other")])
20894 ;; Intirinsics for > i486
20896 (define_insn "wbinvd"
20897 [(unspec_volatile [(const_int 0)] UNSPECV_WBINVD)]
20900 [(set_attr "type" "other")])
20902 (define_insn "wbnoinvd"
20903 [(unspec_volatile [(const_int 0)] UNSPECV_WBNOINVD)]
20906 [(set_attr "type" "other")])
20908 ;; MOVDIRI and MOVDIR64B
20910 (define_insn "movdiri<mode>"
20911 [(unspec_volatile:SWI48 [(match_operand:SWI48 0 "memory_operand" "m")
20912 (match_operand:SWI48 1 "register_operand" "r")]
20915 "movdiri\t{%1, %0|%0, %1}"
20916 [(set_attr "type" "other")])
20918 (define_insn "movdir64b_<mode>"
20919 [(unspec_volatile:XI [(match_operand:P 0 "register_operand" "r")
20920 (match_operand:XI 1 "memory_operand")]
20921 UNSPECV_MOVDIR64B)]
20923 "movdir64b\t{%1, %0|%0, %1}"
20924 [(set_attr "type" "other")])
20928 (define_insn "umwait"
20929 [(set (reg:CCC FLAGS_REG)
20930 (unspec_volatile:CCC [(match_operand:SI 0 "register_operand" "r")
20931 (match_operand:DI 1 "register_operand" "A")]
20933 "!TARGET_64BIT && TARGET_WAITPKG"
20935 [(set_attr "length" "3")])
20937 (define_insn "umwait_rex64"
20938 [(set (reg:CCC FLAGS_REG)
20939 (unspec_volatile:CCC [(match_operand:SI 0 "register_operand" "r")
20940 (match_operand:SI 1 "register_operand" "a")
20941 (match_operand:SI 2 "register_operand" "d")]
20943 "TARGET_64BIT && TARGET_WAITPKG"
20945 [(set_attr "length" "3")])
20947 (define_insn "umonitor_<mode>"
20948 [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
20952 [(set (attr "length")
20953 (symbol_ref ("(Pmode != word_mode) + 3")))])
20955 (define_insn "tpause"
20956 [(set (reg:CCC FLAGS_REG)
20957 (unspec_volatile:CCC [(match_operand:SI 0 "register_operand" "r")
20958 (match_operand:DI 1 "register_operand" "A")]
20960 "!TARGET_64BIT && TARGET_WAITPKG"
20962 [(set_attr "length" "3")])
20964 (define_insn "tpause_rex64"
20965 [(set (reg:CCC FLAGS_REG)
20966 (unspec_volatile:CCC [(match_operand:SI 0 "register_operand" "r")
20967 (match_operand:SI 1 "register_operand" "a")
20968 (match_operand:SI 2 "register_operand" "d")]
20970 "TARGET_64BIT && TARGET_WAITPKG"
20972 [(set_attr "length" "3")])
20974 (define_insn "cldemote"
20975 [(unspec_volatile[(match_operand 0 "address_operand" "p")]
20979 [(set_attr "type" "other")
20980 (set_attr "memory" "unknown")])
20984 (include "sync.md")