1 ;; GCC machine description for IA-32 and x86-64.
2 ;; Copyright (C) 1988-2018 Free Software Foundation, Inc.
3 ;; Mostly by William Schelter.
4 ;; x86_64 support added by Jan Hubicka
6 ;; This file is part of GCC.
8 ;; GCC is free software; you can redistribute it and/or modify
9 ;; it under the terms of the GNU General Public License as published by
10 ;; the Free Software Foundation; either version 3, or (at your option)
13 ;; GCC is distributed in the hope that it will be useful,
14 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
15 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 ;; GNU General Public License for more details.
18 ;; You should have received a copy of the GNU General Public License
19 ;; along with GCC; see the file COPYING3. If not see
20 ;; <http://www.gnu.org/licenses/>. */
22 ;; The original PO technology requires these to be ordered by speed,
23 ;; so that assigner will pick the fastest.
25 ;; See file "rtl.def" for documentation on define_insn, match_*, et. al.
27 ;; The special asm out single letter directives following a '%' are:
28 ;; L,W,B,Q,S,T -- print the opcode suffix for specified size of operand.
29 ;; C -- print opcode suffix for set/cmov insn.
30 ;; c -- like C, but print reversed condition
31 ;; F,f -- likewise, but for floating-point.
32 ;; O -- if HAVE_AS_IX86_CMOV_SUN_SYNTAX, expand to "w.", "l." or "q.",
34 ;; R -- print the prefix for register names.
35 ;; z -- print the opcode suffix for the size of the current operand.
36 ;; Z -- likewise, with special suffixes for x87 instructions.
37 ;; * -- print a star (in certain assembler syntax)
38 ;; A -- print an absolute memory reference.
39 ;; E -- print address with DImode register names if TARGET_64BIT.
40 ;; w -- print the operand as if it's a "word" (HImode) even if it isn't.
41 ;; s -- print a shift double count, followed by the assemblers argument
43 ;; b -- print the QImode name of the register for the indicated operand.
44 ;; %b0 would print %al if operands[0] is reg 0.
45 ;; w -- likewise, print the HImode name of the register.
46 ;; k -- likewise, print the SImode name of the register.
47 ;; q -- likewise, print the DImode name of the register.
48 ;; x -- likewise, print the V4SFmode name of the register.
49 ;; t -- likewise, print the V8SFmode name of the register.
50 ;; h -- print the QImode name for a "high" register, either ah, bh, ch or dh.
51 ;; y -- print "st(0)" instead of "st" as a register.
52 ;; d -- print duplicated register operand for AVX instruction.
53 ;; D -- print condition for SSE cmp instruction.
54 ;; P -- if PIC, print an @PLT suffix.
55 ;; p -- print raw symbol name.
56 ;; X -- don't print any sort of PIC '@' suffix for a symbol.
57 ;; & -- print some in-use local-dynamic symbol name.
58 ;; H -- print a memory address offset by 8; used for sse high-parts
59 ;; K -- print HLE lock prefix
60 ;; Y -- print condition for XOP pcom* instruction.
61 ;; + -- print a branch hint as 'cs' or 'ds' prefix
62 ;; ; -- print a semicolon (after prefixes due to bug in older gas).
63 ;; ~ -- print "i" if TARGET_AVX2, "f" otherwise.
64 ;; ^ -- print addr32 prefix if TARGET_64BIT and Pmode != word_mode
65 ;; ! -- print MPX or NOTRACK prefix for jxx/call/ret instructions if required.
67 (define_c_enum "unspec" [
68 ;; Relocation specifiers
79 UNSPEC_MACHOPIC_OFFSET
88 UNSPEC_MEMORY_BLOCKAGE
98 ;; Other random patterns
107 UNSPEC_LD_MPIC ; load_macho_picbase
109 UNSPEC_DIV_ALREADY_SPLIT
115 UNSPEC_INSN_FALSE_DEP
118 ;; For SSE/MMX support:
126 ;; Generic math support
128 UNSPEC_IEEE_MIN ; not commutative
129 UNSPEC_IEEE_MAX ; not commutative
131 ;; x87 Floating point
147 UNSPEC_FRNDINT_MASK_PM
151 ;; x87 Double output FP
176 ;; For LZCNT suppoprt
198 UNSPEC_INTERRUPT_RETURN
201 (define_c_enum "unspecv" [
205 UNSPECV_PROBE_STACK_RANGE
208 UNSPECV_SPLIT_STACK_RETURN
214 UNSPECV_LLWP_INTRINSIC
215 UNSPECV_SLWP_INTRINSIC
216 UNSPECV_LWPVAL_INTRINSIC
217 UNSPECV_LWPINS_INTRINSIC
243 ;; For atomic compound assignments.
249 ;; For RDRAND support
252 ;; For RDSEED support
266 ;; For CLFLUSHOPT support
269 ;; For MONITORX and MWAITX support
273 ;; For CLZERO support
276 ;; For RDPKRU and WRPKRU support
296 ;; Constants to represent rounding modes in the ROUND instruction
305 ;; Constants to represent AVX512F embeded rounding
307 [(ROUND_NEAREST_INT 0)
315 ;; Constants to represent pcomtrue/pcomfalse variants
325 ;; Constants used in the XOP pperm instruction
327 [(PPERM_SRC 0x00) /* copy source */
328 (PPERM_INVERT 0x20) /* invert source */
329 (PPERM_REVERSE 0x40) /* bit reverse source */
330 (PPERM_REV_INV 0x60) /* bit reverse & invert src */
331 (PPERM_ZERO 0x80) /* all 0's */
332 (PPERM_ONES 0xa0) /* all 1's */
333 (PPERM_SIGN 0xc0) /* propagate sign bit */
334 (PPERM_INV_SIGN 0xe0) /* invert & propagate sign */
335 (PPERM_SRC1 0x00) /* use first source byte */
336 (PPERM_SRC2 0x10) /* use second source byte */
339 ;; Registers by name.
422 (FIRST_PSEUDO_REG 81)
425 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
428 ;; In C guard expressions, put expressions which may be compile-time
429 ;; constants first. This allows for better optimization. For
430 ;; example, write "TARGET_64BIT && reload_completed", not
431 ;; "reload_completed && TARGET_64BIT".
435 (define_attr "cpu" "none,pentium,pentiumpro,geode,k6,athlon,k8,core2,nehalem,
436 atom,slm,glm,haswell,generic,amdfam10,bdver1,bdver2,bdver3,
437 bdver4,btver2,znver1"
438 (const (symbol_ref "ix86_schedule")))
440 ;; A basic instruction type. Refinements due to arguments to be
441 ;; provided in other attributes.
444 alu,alu1,negnot,imov,imovx,lea,
445 incdec,ishift,ishiftx,ishift1,rotate,rotatex,rotate1,
446 imul,imulx,idiv,icmp,test,ibr,setcc,icmov,
447 push,pop,call,callv,leave,
449 fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,
450 fxch,fistp,fisttp,frndint,
451 sse,ssemov,sseadd,sseadd1,sseiadd,sseiadd1,
452 ssemul,sseimul,ssediv,sselog,sselog1,
453 sseishft,sseishft1,ssecmp,ssecomi,
454 ssecvt,ssecvt1,sseicvt,sseins,
455 sseshuf,sseshuf1,ssemuladd,sse4arg,
457 mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft,
458 mpxmov,mpxmk,mpxchk,mpxld,mpxst"
459 (const_string "other"))
461 ;; Main data type used by the insn
463 "unknown,none,QI,HI,SI,DI,TI,OI,XI,SF,DF,XF,TF,V16SF,V8SF,V4DF,V4SF,
465 (const_string "unknown"))
467 ;; The CPU unit operations uses.
468 (define_attr "unit" "integer,i387,sse,mmx,unknown"
469 (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,
470 fxch,fistp,fisttp,frndint")
471 (const_string "i387")
472 (eq_attr "type" "sse,ssemov,sseadd,sseadd1,sseiadd,sseiadd1,
473 ssemul,sseimul,ssediv,sselog,sselog1,
474 sseishft,sseishft1,ssecmp,ssecomi,
475 ssecvt,ssecvt1,sseicvt,sseins,
476 sseshuf,sseshuf1,ssemuladd,sse4arg,mskmov")
478 (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
480 (eq_attr "type" "other")
481 (const_string "unknown")]
482 (const_string "integer")))
484 ;; The (bounding maximum) length of an instruction immediate.
485 (define_attr "length_immediate" ""
486 (cond [(eq_attr "type" "incdec,setcc,icmov,str,lea,other,multi,idiv,leave,
487 bitmanip,imulx,msklog,mskmov,mpxmk,mpxmov,mpxchk,
490 (eq_attr "unit" "i387,sse,mmx")
492 (eq_attr "type" "alu,alu1,negnot,imovx,ishift,ishiftx,ishift1,
493 rotate,rotatex,rotate1,imul,icmp,push,pop")
494 (symbol_ref "ix86_attr_length_immediate_default (insn, true)")
495 (eq_attr "type" "imov,test")
496 (symbol_ref "ix86_attr_length_immediate_default (insn, false)")
497 (eq_attr "type" "call")
498 (if_then_else (match_operand 0 "constant_call_address_operand")
501 (eq_attr "type" "callv")
502 (if_then_else (match_operand 1 "constant_call_address_operand")
505 ;; We don't know the size before shorten_branches. Expect
506 ;; the instruction to fit for better scheduling.
507 (eq_attr "type" "ibr")
510 (symbol_ref "/* Update immediate_length and other attributes! */
511 gcc_unreachable (),1")))
513 ;; The (bounding maximum) length of an instruction address.
514 (define_attr "length_address" ""
515 (cond [(eq_attr "type" "str,other,multi,fxch")
517 (and (eq_attr "type" "call")
518 (match_operand 0 "constant_call_address_operand"))
520 (and (eq_attr "type" "callv")
521 (match_operand 1 "constant_call_address_operand"))
524 (symbol_ref "ix86_attr_length_address_default (insn)")))
526 ;; Set when length prefix is used.
527 (define_attr "prefix_data16" ""
528 (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
530 (eq_attr "mode" "HI")
532 (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF,TI"))
537 ;; Set when string REP prefix is used.
538 (define_attr "prefix_rep" ""
539 (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
541 (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
543 (and (eq_attr "type" "ibr,call,callv")
544 (match_test "ix86_bnd_prefixed_insn_p (insn)"))
549 ;; Set when 0f opcode prefix is used.
550 (define_attr "prefix_0f" ""
552 (ior (eq_attr "type" "imovx,setcc,icmov,bitmanip,msklog,mskmov,
553 mpxmk,mpxmov,mpxchk,mpxld,mpxst")
554 (eq_attr "unit" "sse,mmx"))
558 ;; Set when REX opcode prefix is used.
559 (define_attr "prefix_rex" ""
560 (cond [(not (match_test "TARGET_64BIT"))
562 (and (eq_attr "mode" "DI")
563 (and (eq_attr "type" "!push,pop,call,callv,leave,ibr")
564 (eq_attr "unit" "!mmx")))
566 (and (eq_attr "mode" "QI")
567 (match_test "x86_extended_QIreg_mentioned_p (insn)"))
569 (match_test "x86_extended_reg_mentioned_p (insn)")
571 (and (eq_attr "type" "imovx")
572 (match_operand:QI 1 "ext_QIreg_operand"))
577 ;; There are also additional prefixes in 3DNOW, SSSE3.
578 ;; ssemuladd,sse4arg default to 0f24/0f25 and DREX byte,
579 ;; sseiadd1,ssecvt1 to 0f7a with no DREX byte.
580 ;; 3DNOW has 0f0f prefix, SSSE3 and SSE4_{1,2} 0f38/0f3a.
581 (define_attr "prefix_extra" ""
582 (cond [(eq_attr "type" "ssemuladd,sse4arg")
584 (eq_attr "type" "sseiadd1,ssecvt1")
589 ;; Set when BND opcode prefix may be used.
590 (define_attr "maybe_prefix_bnd" "" (const_int 0))
592 ;; Prefix used: original, VEX or maybe VEX.
593 (define_attr "prefix" "orig,vex,maybe_vex,evex,maybe_evex"
594 (cond [(eq_attr "mode" "OI,V8SF,V4DF")
596 (eq_attr "mode" "XI,V16SF,V8DF")
597 (const_string "evex")
599 (const_string "orig")))
601 ;; VEX W bit is used.
602 (define_attr "prefix_vex_w" "" (const_int 0))
604 ;; The length of VEX prefix
605 ;; Only instructions with 0f prefix can have 2 byte VEX prefix,
606 ;; 0f38/0f3a prefixes can't. In i386.md 0f3[8a] is
607 ;; still prefix_0f 1, with prefix_extra 1.
608 (define_attr "length_vex" ""
609 (if_then_else (and (eq_attr "prefix_0f" "1")
610 (eq_attr "prefix_extra" "0"))
611 (if_then_else (eq_attr "prefix_vex_w" "1")
612 (symbol_ref "ix86_attr_length_vex_default (insn, true, true)")
613 (symbol_ref "ix86_attr_length_vex_default (insn, true, false)"))
614 (if_then_else (eq_attr "prefix_vex_w" "1")
615 (symbol_ref "ix86_attr_length_vex_default (insn, false, true)")
616 (symbol_ref "ix86_attr_length_vex_default (insn, false, false)"))))
618 ;; 4-bytes evex prefix and 1 byte opcode.
619 (define_attr "length_evex" "" (const_int 5))
621 ;; Set when modrm byte is used.
622 (define_attr "modrm" ""
623 (cond [(eq_attr "type" "str,leave")
625 (eq_attr "unit" "i387")
627 (and (eq_attr "type" "incdec")
628 (and (not (match_test "TARGET_64BIT"))
629 (ior (match_operand:SI 1 "register_operand")
630 (match_operand:HI 1 "register_operand"))))
632 (and (eq_attr "type" "push")
633 (not (match_operand 1 "memory_operand")))
635 (and (eq_attr "type" "pop")
636 (not (match_operand 0 "memory_operand")))
638 (and (eq_attr "type" "imov")
639 (and (not (eq_attr "mode" "DI"))
640 (ior (and (match_operand 0 "register_operand")
641 (match_operand 1 "immediate_operand"))
642 (ior (and (match_operand 0 "ax_reg_operand")
643 (match_operand 1 "memory_displacement_only_operand"))
644 (and (match_operand 0 "memory_displacement_only_operand")
645 (match_operand 1 "ax_reg_operand"))))))
647 (and (eq_attr "type" "call")
648 (match_operand 0 "constant_call_address_operand"))
650 (and (eq_attr "type" "callv")
651 (match_operand 1 "constant_call_address_operand"))
653 (and (eq_attr "type" "alu,alu1,icmp,test")
654 (match_operand 0 "ax_reg_operand"))
655 (symbol_ref "(get_attr_length_immediate (insn) <= (get_attr_mode (insn) != MODE_QI))")
659 (define_attr "modrm_class" "none,incdec,op0,op01,op02,pushpop,unknown"
660 (cond [(eq_attr "modrm" "0")
661 (const_string "none")
662 (eq_attr "type" "alu,imul,ishift")
663 (const_string "op02")
664 (eq_attr "type" "imov,imovx,lea,alu1,icmp")
665 (const_string "op01")
666 (eq_attr "type" "incdec")
667 (const_string "incdec")
668 (eq_attr "type" "push,pop")
669 (const_string "pushpop")]
670 (const_string "unknown")))
672 ;; The (bounding maximum) length of an instruction in bytes.
673 ;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
674 ;; Later we may want to split them and compute proper length as for
676 (define_attr "length" ""
677 (cond [(eq_attr "type" "other,multi,fistp,frndint")
679 (eq_attr "type" "fcmp")
681 (eq_attr "unit" "i387")
683 (plus (attr "prefix_data16")
684 (attr "length_address")))
685 (ior (eq_attr "prefix" "evex")
686 (and (ior (eq_attr "prefix" "maybe_evex")
687 (eq_attr "prefix" "maybe_vex"))
688 (match_test "TARGET_AVX512F")))
689 (plus (attr "length_evex")
690 (plus (attr "length_immediate")
692 (attr "length_address"))))
693 (ior (eq_attr "prefix" "vex")
694 (and (ior (eq_attr "prefix" "maybe_vex")
695 (eq_attr "prefix" "maybe_evex"))
696 (match_test "TARGET_AVX")))
697 (plus (attr "length_vex")
698 (plus (attr "length_immediate")
700 (attr "length_address"))))]
701 (plus (plus (attr "modrm")
702 (plus (attr "prefix_0f")
703 (plus (attr "prefix_rex")
704 (plus (attr "prefix_extra")
706 (plus (attr "prefix_rep")
707 (plus (attr "prefix_data16")
708 (plus (attr "length_immediate")
709 (attr "length_address")))))))
711 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
712 ;; `store' if there is a simple memory reference therein, or `unknown'
713 ;; if the instruction is complex.
715 (define_attr "memory" "none,load,store,both,unknown"
716 (cond [(eq_attr "type" "other,multi,str,lwp")
717 (const_string "unknown")
718 (eq_attr "type" "lea,fcmov,fpspc,mpxmk,mpxchk")
719 (const_string "none")
720 (eq_attr "type" "fistp,leave")
721 (const_string "both")
722 (eq_attr "type" "frndint")
723 (const_string "load")
724 (eq_attr "type" "mpxld")
725 (const_string "load")
726 (eq_attr "type" "mpxst")
727 (const_string "store")
728 (eq_attr "type" "push")
729 (if_then_else (match_operand 1 "memory_operand")
730 (const_string "both")
731 (const_string "store"))
732 (eq_attr "type" "pop")
733 (if_then_else (match_operand 0 "memory_operand")
734 (const_string "both")
735 (const_string "load"))
736 (eq_attr "type" "setcc")
737 (if_then_else (match_operand 0 "memory_operand")
738 (const_string "store")
739 (const_string "none"))
740 (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
741 (if_then_else (ior (match_operand 0 "memory_operand")
742 (match_operand 1 "memory_operand"))
743 (const_string "load")
744 (const_string "none"))
745 (eq_attr "type" "ibr")
746 (if_then_else (match_operand 0 "memory_operand")
747 (const_string "load")
748 (const_string "none"))
749 (eq_attr "type" "call")
750 (if_then_else (match_operand 0 "constant_call_address_operand")
751 (const_string "none")
752 (const_string "load"))
753 (eq_attr "type" "callv")
754 (if_then_else (match_operand 1 "constant_call_address_operand")
755 (const_string "none")
756 (const_string "load"))
757 (and (eq_attr "type" "alu1,negnot,ishift1,rotate1,sselog1,sseshuf1")
758 (match_operand 1 "memory_operand"))
759 (const_string "both")
760 (and (match_operand 0 "memory_operand")
761 (match_operand 1 "memory_operand"))
762 (const_string "both")
763 (match_operand 0 "memory_operand")
764 (const_string "store")
765 (match_operand 1 "memory_operand")
766 (const_string "load")
768 "!alu1,negnot,ishift1,rotate1,
769 imov,imovx,icmp,test,bitmanip,
771 sse,ssemov,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,
772 sselog1,sseshuf1,sseadd1,sseiadd1,sseishft1,
773 mmx,mmxmov,mmxcmp,mmxcvt,mskmov,msklog,mpxmov")
774 (match_operand 2 "memory_operand"))
775 (const_string "load")
776 (and (eq_attr "type" "icmov,ssemuladd,sse4arg")
777 (match_operand 3 "memory_operand"))
778 (const_string "load")
780 (const_string "none")))
782 ;; Indicates if an instruction has both an immediate and a displacement.
784 (define_attr "imm_disp" "false,true,unknown"
785 (cond [(eq_attr "type" "other,multi")
786 (const_string "unknown")
787 (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
788 (and (match_operand 0 "memory_displacement_operand")
789 (match_operand 1 "immediate_operand")))
790 (const_string "true")
791 (and (eq_attr "type" "alu,ishift,ishiftx,rotate,rotatex,imul,idiv")
792 (and (match_operand 0 "memory_displacement_operand")
793 (match_operand 2 "immediate_operand")))
794 (const_string "true")
796 (const_string "false")))
798 ;; Indicates if an FP operation has an integer source.
800 (define_attr "fp_int_src" "false,true"
801 (const_string "false"))
803 ;; Defines rounding mode of an FP operation.
805 (define_attr "i387_cw" "trunc,floor,ceil,mask_pm,uninitialized,any"
806 (const_string "any"))
808 ;; Define attribute to classify add/sub insns that consumes carry flag (CF)
809 (define_attr "use_carry" "0,1" (const_string "0"))
811 ;; Define attribute to indicate unaligned ssemov insns
812 (define_attr "movu" "0,1" (const_string "0"))
814 ;; Used to control the "enabled" attribute on a per-instruction basis.
815 (define_attr "isa" "base,x64,x64_sse2,x64_sse4,x64_sse4_noavx,x64_avx,nox64,
816 sse2,sse2_noavx,sse3,sse4,sse4_noavx,avx,noavx,
817 avx2,noavx2,bmi,bmi2,fma4,fma,avx512f,noavx512f,
818 avx512bw,noavx512bw,avx512dq,noavx512dq,
819 avx512vl,noavx512vl,x64_avx512dq,x64_avx512bw"
820 (const_string "base"))
822 (define_attr "enabled" ""
823 (cond [(eq_attr "isa" "x64") (symbol_ref "TARGET_64BIT")
824 (eq_attr "isa" "x64_sse2")
825 (symbol_ref "TARGET_64BIT && TARGET_SSE2")
826 (eq_attr "isa" "x64_sse4")
827 (symbol_ref "TARGET_64BIT && TARGET_SSE4_1")
828 (eq_attr "isa" "x64_sse4_noavx")
829 (symbol_ref "TARGET_64BIT && TARGET_SSE4_1 && !TARGET_AVX")
830 (eq_attr "isa" "x64_avx")
831 (symbol_ref "TARGET_64BIT && TARGET_AVX")
832 (eq_attr "isa" "x64_avx512dq")
833 (symbol_ref "TARGET_64BIT && TARGET_AVX512DQ")
834 (eq_attr "isa" "x64_avx512bw")
835 (symbol_ref "TARGET_64BIT && TARGET_AVX512BW")
836 (eq_attr "isa" "nox64") (symbol_ref "!TARGET_64BIT")
837 (eq_attr "isa" "sse2") (symbol_ref "TARGET_SSE2")
838 (eq_attr "isa" "sse2_noavx")
839 (symbol_ref "TARGET_SSE2 && !TARGET_AVX")
840 (eq_attr "isa" "sse3") (symbol_ref "TARGET_SSE3")
841 (eq_attr "isa" "sse4") (symbol_ref "TARGET_SSE4_1")
842 (eq_attr "isa" "sse4_noavx")
843 (symbol_ref "TARGET_SSE4_1 && !TARGET_AVX")
844 (eq_attr "isa" "avx") (symbol_ref "TARGET_AVX")
845 (eq_attr "isa" "noavx") (symbol_ref "!TARGET_AVX")
846 (eq_attr "isa" "avx2") (symbol_ref "TARGET_AVX2")
847 (eq_attr "isa" "noavx2") (symbol_ref "!TARGET_AVX2")
848 (eq_attr "isa" "bmi") (symbol_ref "TARGET_BMI")
849 (eq_attr "isa" "bmi2") (symbol_ref "TARGET_BMI2")
850 (eq_attr "isa" "fma4") (symbol_ref "TARGET_FMA4")
851 (eq_attr "isa" "fma") (symbol_ref "TARGET_FMA")
852 (eq_attr "isa" "avx512f") (symbol_ref "TARGET_AVX512F")
853 (eq_attr "isa" "noavx512f") (symbol_ref "!TARGET_AVX512F")
854 (eq_attr "isa" "avx512bw") (symbol_ref "TARGET_AVX512BW")
855 (eq_attr "isa" "noavx512bw") (symbol_ref "!TARGET_AVX512BW")
856 (eq_attr "isa" "avx512dq") (symbol_ref "TARGET_AVX512DQ")
857 (eq_attr "isa" "noavx512dq") (symbol_ref "!TARGET_AVX512DQ")
858 (eq_attr "isa" "avx512vl") (symbol_ref "TARGET_AVX512VL")
859 (eq_attr "isa" "noavx512vl") (symbol_ref "!TARGET_AVX512VL")
863 (define_attr "preferred_for_size" "" (const_int 1))
864 (define_attr "preferred_for_speed" "" (const_int 1))
866 ;; Describe a user's asm statement.
867 (define_asm_attributes
868 [(set_attr "length" "128")
869 (set_attr "type" "multi")])
871 (define_code_iterator plusminus [plus minus])
873 (define_code_iterator sat_plusminus [ss_plus us_plus ss_minus us_minus])
875 (define_code_iterator multdiv [mult div])
877 ;; Base name for define_insn
878 (define_code_attr plusminus_insn
879 [(plus "add") (ss_plus "ssadd") (us_plus "usadd")
880 (minus "sub") (ss_minus "sssub") (us_minus "ussub")])
882 ;; Base name for insn mnemonic.
883 (define_code_attr plusminus_mnemonic
884 [(plus "add") (ss_plus "adds") (us_plus "addus")
885 (minus "sub") (ss_minus "subs") (us_minus "subus")])
886 (define_code_attr multdiv_mnemonic
887 [(mult "mul") (div "div")])
889 ;; Mark commutative operators as such in constraints.
890 (define_code_attr comm [(plus "%") (ss_plus "%") (us_plus "%")
891 (minus "") (ss_minus "") (us_minus "")])
893 ;; Mapping of max and min
894 (define_code_iterator maxmin [smax smin umax umin])
896 ;; Mapping of signed max and min
897 (define_code_iterator smaxmin [smax smin])
899 ;; Mapping of unsigned max and min
900 (define_code_iterator umaxmin [umax umin])
902 ;; Base name for integer and FP insn mnemonic
903 (define_code_attr maxmin_int [(smax "maxs") (smin "mins")
904 (umax "maxu") (umin "minu")])
905 (define_code_attr maxmin_float [(smax "max") (smin "min")])
907 (define_int_iterator IEEE_MAXMIN
911 (define_int_attr ieee_maxmin
912 [(UNSPEC_IEEE_MAX "max")
913 (UNSPEC_IEEE_MIN "min")])
915 ;; Mapping of logic operators
916 (define_code_iterator any_logic [and ior xor])
917 (define_code_iterator any_or [ior xor])
918 (define_code_iterator fpint_logic [and xor])
920 ;; Base name for insn mnemonic.
921 (define_code_attr logic [(and "and") (ior "or") (xor "xor")])
923 ;; Mapping of logic-shift operators
924 (define_code_iterator any_lshift [ashift lshiftrt])
926 ;; Mapping of shift-right operators
927 (define_code_iterator any_shiftrt [lshiftrt ashiftrt])
929 ;; Mapping of all shift operators
930 (define_code_iterator any_shift [ashift lshiftrt ashiftrt])
932 ;; Base name for define_insn
933 (define_code_attr shift_insn
934 [(ashift "ashl") (lshiftrt "lshr") (ashiftrt "ashr")])
936 ;; Base name for insn mnemonic.
937 (define_code_attr shift [(ashift "sll") (lshiftrt "shr") (ashiftrt "sar")])
938 (define_code_attr vshift [(ashift "sll") (lshiftrt "srl") (ashiftrt "sra")])
940 ;; Mapping of rotate operators
941 (define_code_iterator any_rotate [rotate rotatert])
943 ;; Base name for define_insn
944 (define_code_attr rotate_insn [(rotate "rotl") (rotatert "rotr")])
946 ;; Base name for insn mnemonic.
947 (define_code_attr rotate [(rotate "rol") (rotatert "ror")])
949 ;; Mapping of abs neg operators
950 (define_code_iterator absneg [abs neg])
952 ;; Base name for x87 insn mnemonic.
953 (define_code_attr absneg_mnemonic [(abs "abs") (neg "chs")])
955 ;; Used in signed and unsigned widening multiplications.
956 (define_code_iterator any_extend [sign_extend zero_extend])
958 ;; Prefix for insn menmonic.
959 (define_code_attr sgnprefix [(sign_extend "i") (zero_extend "")])
961 ;; Prefix for define_insn
962 (define_code_attr u [(sign_extend "") (zero_extend "u")])
963 (define_code_attr s [(sign_extend "s") (zero_extend "u")])
964 (define_code_attr u_bool [(sign_extend "false") (zero_extend "true")])
966 ;; Used in signed and unsigned truncations.
967 (define_code_iterator any_truncate [ss_truncate truncate us_truncate])
968 ;; Instruction suffix for truncations.
969 (define_code_attr trunsuffix [(ss_truncate "s") (truncate "") (us_truncate "us")])
971 ;; Used in signed and unsigned fix.
972 (define_code_iterator any_fix [fix unsigned_fix])
973 (define_code_attr fixsuffix [(fix "") (unsigned_fix "u")])
975 ;; Used in signed and unsigned float.
976 (define_code_iterator any_float [float unsigned_float])
977 (define_code_attr floatsuffix [(float "") (unsigned_float "u")])
979 ;; All integer modes.
980 (define_mode_iterator SWI1248x [QI HI SI DI])
982 ;; All integer modes without QImode.
983 (define_mode_iterator SWI248x [HI SI DI])
985 ;; All integer modes without QImode and HImode.
986 (define_mode_iterator SWI48x [SI DI])
988 ;; All integer modes without SImode and DImode.
989 (define_mode_iterator SWI12 [QI HI])
991 ;; All integer modes without DImode.
992 (define_mode_iterator SWI124 [QI HI SI])
994 ;; All integer modes without QImode and DImode.
995 (define_mode_iterator SWI24 [HI SI])
997 ;; Single word integer modes.
998 (define_mode_iterator SWI [QI HI SI (DI "TARGET_64BIT")])
1000 ;; Single word integer modes without QImode.
1001 (define_mode_iterator SWI248 [HI SI (DI "TARGET_64BIT")])
1003 ;; Single word integer modes without QImode and HImode.
1004 (define_mode_iterator SWI48 [SI (DI "TARGET_64BIT")])
1006 ;; All math-dependant single and double word integer modes.
1007 (define_mode_iterator SDWIM [(QI "TARGET_QIMODE_MATH")
1008 (HI "TARGET_HIMODE_MATH")
1009 SI DI (TI "TARGET_64BIT")])
1011 ;; Math-dependant single word integer modes.
1012 (define_mode_iterator SWIM [(QI "TARGET_QIMODE_MATH")
1013 (HI "TARGET_HIMODE_MATH")
1014 SI (DI "TARGET_64BIT")])
1016 ;; Math-dependant integer modes without DImode.
1017 (define_mode_iterator SWIM124 [(QI "TARGET_QIMODE_MATH")
1018 (HI "TARGET_HIMODE_MATH")
1021 ;; Math-dependant integer modes with DImode.
1022 (define_mode_iterator SWIM1248x [(QI "TARGET_QIMODE_MATH")
1023 (HI "TARGET_HIMODE_MATH")
1024 SI (DI "(TARGET_STV && TARGET_SSE2) || TARGET_64BIT")])
1026 ;; Math-dependant single word integer modes without QImode.
1027 (define_mode_iterator SWIM248 [(HI "TARGET_HIMODE_MATH")
1028 SI (DI "TARGET_64BIT")])
1030 ;; Double word integer modes.
1031 (define_mode_iterator DWI [(DI "!TARGET_64BIT")
1032 (TI "TARGET_64BIT")])
1034 ;; GET_MODE_SIZE for selected modes. As GET_MODE_SIZE is not
1035 ;; compile time constant, it is faster to use <MODE_SIZE> than
1036 ;; GET_MODE_SIZE (<MODE>mode). For XFmode which depends on
1037 ;; command line options just use GET_MODE_SIZE macro.
1038 (define_mode_attr MODE_SIZE [(QI "1") (HI "2") (SI "4") (DI "8") (TI "16")
1039 (SF "4") (DF "8") (XF "GET_MODE_SIZE (XFmode)")
1040 (V16QI "16") (V32QI "32") (V64QI "64")
1041 (V8HI "16") (V16HI "32") (V32HI "64")
1042 (V4SI "16") (V8SI "32") (V16SI "64")
1043 (V2DI "16") (V4DI "32") (V8DI "64")
1044 (V1TI "16") (V2TI "32") (V4TI "64")
1045 (V2DF "16") (V4DF "32") (V8DF "64")
1046 (V4SF "16") (V8SF "32") (V16SF "64")])
1048 ;; Double word integer modes as mode attribute.
1049 (define_mode_attr DWI [(QI "HI") (HI "SI") (SI "DI") (DI "TI")])
1050 (define_mode_attr dwi [(QI "hi") (HI "si") (SI "di") (DI "ti")])
1052 ;; LEA mode corresponding to an integer mode
1053 (define_mode_attr LEAMODE [(QI "SI") (HI "SI") (SI "SI") (DI "DI")])
1055 ;; Half mode for double word integer modes.
1056 (define_mode_iterator DWIH [(SI "!TARGET_64BIT")
1057 (DI "TARGET_64BIT")])
1060 (define_mode_iterator BND [(BND32 "!TARGET_LP64")
1061 (BND64 "TARGET_LP64")])
1063 ;; Pointer mode corresponding to bound mode.
1064 (define_mode_attr bnd_ptr [(BND32 "SI") (BND64 "DI")])
1067 (define_int_iterator BNDCHECK [UNSPEC_BNDCL UNSPEC_BNDCU UNSPEC_BNDCN])
1070 (define_int_attr bndcheck [(UNSPEC_BNDCL "cl")
1072 (UNSPEC_BNDCN "cn")])
1074 ;; Instruction suffix for integer modes.
1075 (define_mode_attr imodesuffix [(QI "b") (HI "w") (SI "l") (DI "q")])
1077 ;; Instruction suffix for masks.
1078 (define_mode_attr mskmodesuffix [(QI "b") (HI "w") (SI "d") (DI "q")])
1080 ;; Pointer size prefix for integer modes (Intel asm dialect)
1081 (define_mode_attr iptrsize [(QI "BYTE")
1086 ;; Register class for integer modes.
1087 (define_mode_attr r [(QI "q") (HI "r") (SI "r") (DI "r")])
1089 ;; Immediate operand constraint for integer modes.
1090 (define_mode_attr i [(QI "n") (HI "n") (SI "e") (DI "e")])
1092 ;; General operand constraint for word modes.
1093 (define_mode_attr g [(QI "qmn") (HI "rmn") (SI "rme") (DI "rme")])
1095 ;; Immediate operand constraint for double integer modes.
1096 (define_mode_attr di [(SI "nF") (DI "Wd")])
1098 ;; Immediate operand constraint for shifts.
1099 (define_mode_attr S [(QI "I") (HI "I") (SI "I") (DI "J") (TI "O")])
1101 ;; Print register name in the specified mode.
1102 (define_mode_attr k [(QI "b") (HI "w") (SI "k") (DI "q")])
1104 ;; General operand predicate for integer modes.
1105 (define_mode_attr general_operand
1106 [(QI "general_operand")
1107 (HI "general_operand")
1108 (SI "x86_64_general_operand")
1109 (DI "x86_64_general_operand")
1110 (TI "x86_64_general_operand")])
1112 ;; General operand predicate for integer modes, where for TImode
1113 ;; we need both words of the operand to be general operands.
1114 (define_mode_attr general_hilo_operand
1115 [(QI "general_operand")
1116 (HI "general_operand")
1117 (SI "x86_64_general_operand")
1118 (DI "x86_64_general_operand")
1119 (TI "x86_64_hilo_general_operand")])
1121 ;; General sign extend operand predicate for integer modes,
1122 ;; which disallows VOIDmode operands and thus it is suitable
1123 ;; for use inside sign_extend.
1124 (define_mode_attr general_sext_operand
1125 [(QI "sext_operand")
1127 (SI "x86_64_sext_operand")
1128 (DI "x86_64_sext_operand")])
1130 ;; General sign/zero extend operand predicate for integer modes.
1131 (define_mode_attr general_szext_operand
1132 [(QI "general_operand")
1133 (HI "general_operand")
1134 (SI "x86_64_szext_general_operand")
1135 (DI "x86_64_szext_general_operand")])
1137 ;; Immediate operand predicate for integer modes.
1138 (define_mode_attr immediate_operand
1139 [(QI "immediate_operand")
1140 (HI "immediate_operand")
1141 (SI "x86_64_immediate_operand")
1142 (DI "x86_64_immediate_operand")])
1144 ;; Nonmemory operand predicate for integer modes.
1145 (define_mode_attr nonmemory_operand
1146 [(QI "nonmemory_operand")
1147 (HI "nonmemory_operand")
1148 (SI "x86_64_nonmemory_operand")
1149 (DI "x86_64_nonmemory_operand")])
1151 ;; Operand predicate for shifts.
1152 (define_mode_attr shift_operand
1153 [(QI "nonimmediate_operand")
1154 (HI "nonimmediate_operand")
1155 (SI "nonimmediate_operand")
1156 (DI "shiftdi_operand")
1157 (TI "register_operand")])
1159 ;; Operand predicate for shift argument.
1160 (define_mode_attr shift_immediate_operand
1161 [(QI "const_1_to_31_operand")
1162 (HI "const_1_to_31_operand")
1163 (SI "const_1_to_31_operand")
1164 (DI "const_1_to_63_operand")])
1166 ;; Input operand predicate for arithmetic left shifts.
1167 (define_mode_attr ashl_input_operand
1168 [(QI "nonimmediate_operand")
1169 (HI "nonimmediate_operand")
1170 (SI "nonimmediate_operand")
1171 (DI "ashldi_input_operand")
1172 (TI "reg_or_pm1_operand")])
1174 ;; SSE and x87 SFmode and DFmode floating point modes
1175 (define_mode_iterator MODEF [SF DF])
1177 ;; All x87 floating point modes
1178 (define_mode_iterator X87MODEF [SF DF XF])
1180 ;; SSE instruction suffix for various modes
1181 (define_mode_attr ssemodesuffix
1182 [(SF "ss") (DF "sd")
1183 (V16SF "ps") (V8DF "pd")
1184 (V8SF "ps") (V4DF "pd")
1185 (V4SF "ps") (V2DF "pd")
1186 (V16QI "b") (V8HI "w") (V4SI "d") (V2DI "q")
1187 (V32QI "b") (V16HI "w") (V8SI "d") (V4DI "q")
1188 (V64QI "b") (V32HI "w") (V16SI "d") (V8DI "q")])
1190 ;; SSE vector suffix for floating point modes
1191 (define_mode_attr ssevecmodesuffix [(SF "ps") (DF "pd")])
1193 ;; SSE vector mode corresponding to a scalar mode
1194 (define_mode_attr ssevecmode
1195 [(QI "V16QI") (HI "V8HI") (SI "V4SI") (DI "V2DI") (SF "V4SF") (DF "V2DF")])
1196 (define_mode_attr ssevecmodelower
1197 [(QI "v16qi") (HI "v8hi") (SI "v4si") (DI "v2di") (SF "v4sf") (DF "v2df")])
1199 ;; AVX512F vector mode corresponding to a scalar mode
1200 (define_mode_attr avx512fvecmode
1201 [(QI "V64QI") (HI "V32HI") (SI "V16SI") (DI "V8DI") (SF "V16SF") (DF "V8DF")])
1203 ;; Instruction suffix for REX 64bit operators.
1204 (define_mode_attr rex64suffix [(SI "") (DI "{q}")])
1206 ;; This mode iterator allows :P to be used for patterns that operate on
1207 ;; pointer-sized quantities. Exactly one of the two alternatives will match.
1208 (define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
1210 ;; This mode iterator allows :W to be used for patterns that operate on
1211 ;; word_mode sized quantities.
1212 (define_mode_iterator W
1213 [(SI "word_mode == SImode") (DI "word_mode == DImode")])
1215 ;; This mode iterator allows :PTR to be used for patterns that operate on
1216 ;; ptr_mode sized quantities.
1217 (define_mode_iterator PTR
1218 [(SI "ptr_mode == SImode") (DI "ptr_mode == DImode")])
1220 ;; Scheduling descriptions
1222 (include "pentium.md")
1225 (include "athlon.md")
1226 (include "bdver1.md")
1227 (include "bdver3.md")
1228 (include "btver2.md")
1229 (include "znver1.md")
1230 (include "geode.md")
1234 (include "core2.md")
1235 (include "haswell.md")
1238 ;; Operand and operator predicates and constraints
1240 (include "predicates.md")
1241 (include "constraints.md")
1244 ;; Compare and branch/compare and store instructions.
1246 (define_expand "cbranch<mode>4"
1247 [(set (reg:CC FLAGS_REG)
1248 (compare:CC (match_operand:SDWIM 1 "nonimmediate_operand")
1249 (match_operand:SDWIM 2 "<general_operand>")))
1250 (set (pc) (if_then_else
1251 (match_operator 0 "ordered_comparison_operator"
1252 [(reg:CC FLAGS_REG) (const_int 0)])
1253 (label_ref (match_operand 3))
1257 if (MEM_P (operands[1]) && MEM_P (operands[2]))
1258 operands[1] = force_reg (<MODE>mode, operands[1]);
1259 ix86_expand_branch (GET_CODE (operands[0]),
1260 operands[1], operands[2], operands[3]);
1264 (define_expand "cstore<mode>4"
1265 [(set (reg:CC FLAGS_REG)
1266 (compare:CC (match_operand:SWIM 2 "nonimmediate_operand")
1267 (match_operand:SWIM 3 "<general_operand>")))
1268 (set (match_operand:QI 0 "register_operand")
1269 (match_operator 1 "ordered_comparison_operator"
1270 [(reg:CC FLAGS_REG) (const_int 0)]))]
1273 if (MEM_P (operands[2]) && MEM_P (operands[3]))
1274 operands[2] = force_reg (<MODE>mode, operands[2]);
1275 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1276 operands[2], operands[3]);
1280 (define_expand "cmp<mode>_1"
1281 [(set (reg:CC FLAGS_REG)
1282 (compare:CC (match_operand:SWI48 0 "nonimmediate_operand")
1283 (match_operand:SWI48 1 "<general_operand>")))])
1285 (define_mode_iterator SWI1248_AVX512BWDQ2_64
1286 [(QI "TARGET_AVX512DQ") (HI "TARGET_AVX512DQ")
1287 (SI "TARGET_AVX512BW") (DI "TARGET_AVX512BW && TARGET_64BIT")])
1289 (define_insn "*cmp<mode>_ccz_1"
1290 [(set (reg FLAGS_REG)
1291 (compare (match_operand:SWI1248_AVX512BWDQ2_64 0
1292 "nonimmediate_operand" "<r>,?m<r>,$k")
1293 (match_operand:SWI1248_AVX512BWDQ2_64 1 "const0_operand")))]
1294 "ix86_match_ccmode (insn, CCZmode)"
1296 test{<imodesuffix>}\t%0, %0
1297 cmp{<imodesuffix>}\t{%1, %0|%0, %1}
1298 ktest<mskmodesuffix>\t%0, %0"
1299 [(set_attr "type" "test,icmp,msklog")
1300 (set_attr "length_immediate" "0,1,*")
1301 (set_attr "modrm_class" "op0,unknown,*")
1302 (set_attr "prefix" "*,*,vex")
1303 (set_attr "mode" "<MODE>")])
1305 (define_insn "*cmp<mode>_ccno_1"
1306 [(set (reg FLAGS_REG)
1307 (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>,?m<r>")
1308 (match_operand:SWI 1 "const0_operand")))]
1309 "ix86_match_ccmode (insn, CCNOmode)"
1311 test{<imodesuffix>}\t%0, %0
1312 cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1313 [(set_attr "type" "test,icmp")
1314 (set_attr "length_immediate" "0,1")
1315 (set_attr "modrm_class" "op0,unknown")
1316 (set_attr "mode" "<MODE>")])
1318 (define_insn "*cmp<mode>_1"
1319 [(set (reg FLAGS_REG)
1320 (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
1321 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m")))]
1322 "ix86_match_ccmode (insn, CCmode)"
1323 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1324 [(set_attr "type" "icmp")
1325 (set_attr "mode" "<MODE>")])
1327 (define_insn "*cmp<mode>_minus_1"
1328 [(set (reg FLAGS_REG)
1330 (minus:SWI (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
1331 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
1333 "ix86_match_ccmode (insn, CCGOCmode)"
1334 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1335 [(set_attr "type" "icmp")
1336 (set_attr "mode" "<MODE>")])
1338 (define_insn "*cmpqi_ext_1"
1339 [(set (reg FLAGS_REG)
1341 (match_operand:QI 0 "nonimmediate_operand" "QBc,m")
1344 (match_operand 1 "ext_register_operand" "Q,Q")
1346 (const_int 8)) 0)))]
1347 "ix86_match_ccmode (insn, CCmode)"
1348 "cmp{b}\t{%h1, %0|%0, %h1}"
1349 [(set_attr "isa" "*,nox64")
1350 (set_attr "type" "icmp")
1351 (set_attr "mode" "QI")])
1353 (define_insn "*cmpqi_ext_2"
1354 [(set (reg FLAGS_REG)
1358 (match_operand 0 "ext_register_operand" "Q")
1361 (match_operand:QI 1 "const0_operand")))]
1362 "ix86_match_ccmode (insn, CCNOmode)"
1364 [(set_attr "type" "test")
1365 (set_attr "length_immediate" "0")
1366 (set_attr "mode" "QI")])
1368 (define_expand "cmpqi_ext_3"
1369 [(set (reg:CC FLAGS_REG)
1373 (match_operand 0 "ext_register_operand")
1376 (match_operand:QI 1 "const_int_operand")))])
1378 (define_insn "*cmpqi_ext_3"
1379 [(set (reg FLAGS_REG)
1383 (match_operand 0 "ext_register_operand" "Q,Q")
1386 (match_operand:QI 1 "general_operand" "QnBc,m")))]
1387 "ix86_match_ccmode (insn, CCmode)"
1388 "cmp{b}\t{%1, %h0|%h0, %1}"
1389 [(set_attr "isa" "*,nox64")
1390 (set_attr "type" "icmp")
1391 (set_attr "mode" "QI")])
1393 (define_insn "*cmpqi_ext_4"
1394 [(set (reg FLAGS_REG)
1398 (match_operand 0 "ext_register_operand" "Q")
1403 (match_operand 1 "ext_register_operand" "Q")
1405 (const_int 8)) 0)))]
1406 "ix86_match_ccmode (insn, CCmode)"
1407 "cmp{b}\t{%h1, %h0|%h0, %h1}"
1408 [(set_attr "type" "icmp")
1409 (set_attr "mode" "QI")])
1411 ;; These implement float point compares.
1412 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
1413 ;; which would allow mix and match FP modes on the compares. Which is what
1414 ;; the old patterns did, but with many more of them.
1416 (define_expand "cbranchxf4"
1417 [(set (reg:CC FLAGS_REG)
1418 (compare:CC (match_operand:XF 1 "nonmemory_operand")
1419 (match_operand:XF 2 "nonmemory_operand")))
1420 (set (pc) (if_then_else
1421 (match_operator 0 "ix86_fp_comparison_operator"
1424 (label_ref (match_operand 3))
1428 ix86_expand_branch (GET_CODE (operands[0]),
1429 operands[1], operands[2], operands[3]);
1433 (define_expand "cstorexf4"
1434 [(set (reg:CC FLAGS_REG)
1435 (compare:CC (match_operand:XF 2 "nonmemory_operand")
1436 (match_operand:XF 3 "nonmemory_operand")))
1437 (set (match_operand:QI 0 "register_operand")
1438 (match_operator 1 "ix86_fp_comparison_operator"
1443 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1444 operands[2], operands[3]);
1448 (define_expand "cbranch<mode>4"
1449 [(set (reg:CC FLAGS_REG)
1450 (compare:CC (match_operand:MODEF 1 "cmp_fp_expander_operand")
1451 (match_operand:MODEF 2 "cmp_fp_expander_operand")))
1452 (set (pc) (if_then_else
1453 (match_operator 0 "ix86_fp_comparison_operator"
1456 (label_ref (match_operand 3))
1458 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1460 ix86_expand_branch (GET_CODE (operands[0]),
1461 operands[1], operands[2], operands[3]);
1465 (define_expand "cstore<mode>4"
1466 [(set (reg:CC FLAGS_REG)
1467 (compare:CC (match_operand:MODEF 2 "cmp_fp_expander_operand")
1468 (match_operand:MODEF 3 "cmp_fp_expander_operand")))
1469 (set (match_operand:QI 0 "register_operand")
1470 (match_operator 1 "ix86_fp_comparison_operator"
1473 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1475 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1476 operands[2], operands[3]);
1480 (define_expand "cbranchcc4"
1481 [(set (pc) (if_then_else
1482 (match_operator 0 "comparison_operator"
1483 [(match_operand 1 "flags_reg_operand")
1484 (match_operand 2 "const0_operand")])
1485 (label_ref (match_operand 3))
1489 ix86_expand_branch (GET_CODE (operands[0]),
1490 operands[1], operands[2], operands[3]);
1494 (define_expand "cstorecc4"
1495 [(set (match_operand:QI 0 "register_operand")
1496 (match_operator 1 "comparison_operator"
1497 [(match_operand 2 "flags_reg_operand")
1498 (match_operand 3 "const0_operand")]))]
1501 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1502 operands[2], operands[3]);
1507 ;; FP compares, step 1:
1508 ;; Set the FP condition codes.
1510 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
1511 ;; used to manage the reg stack popping would not be preserved.
1513 (define_insn "*cmp<mode>_0_i387"
1514 [(set (match_operand:HI 0 "register_operand" "=a")
1517 (match_operand:X87MODEF 1 "register_operand" "f")
1518 (match_operand:X87MODEF 2 "const0_operand"))]
1521 "* return output_fp_compare (insn, operands, false, false);"
1522 [(set_attr "type" "multi")
1523 (set_attr "unit" "i387")
1524 (set_attr "mode" "<MODE>")])
1526 (define_insn_and_split "*cmp<mode>_0_cc_i387"
1527 [(set (reg:CCFP FLAGS_REG)
1529 (match_operand:X87MODEF 1 "register_operand" "f")
1530 (match_operand:X87MODEF 2 "const0_operand")))
1531 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1532 "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE"
1534 "&& reload_completed"
1537 [(compare:CCFP (match_dup 1)(match_dup 2))]
1539 (set (reg:CC FLAGS_REG)
1540 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1542 [(set_attr "type" "multi")
1543 (set_attr "unit" "i387")
1544 (set_attr "mode" "<MODE>")])
1546 (define_insn "*cmpxf_i387"
1547 [(set (match_operand:HI 0 "register_operand" "=a")
1550 (match_operand:XF 1 "register_operand" "f")
1551 (match_operand:XF 2 "register_operand" "f"))]
1554 "* return output_fp_compare (insn, operands, false, false);"
1555 [(set_attr "type" "multi")
1556 (set_attr "unit" "i387")
1557 (set_attr "mode" "XF")])
1559 (define_insn_and_split "*cmpxf_cc_i387"
1560 [(set (reg:CCFP FLAGS_REG)
1562 (match_operand:XF 1 "register_operand" "f")
1563 (match_operand:XF 2 "register_operand" "f")))
1564 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1565 "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE"
1567 "&& reload_completed"
1570 [(compare:CCFP (match_dup 1)(match_dup 2))]
1572 (set (reg:CC FLAGS_REG)
1573 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1575 [(set_attr "type" "multi")
1576 (set_attr "unit" "i387")
1577 (set_attr "mode" "XF")])
1579 (define_insn "*cmp<mode>_i387"
1580 [(set (match_operand:HI 0 "register_operand" "=a")
1583 (match_operand:MODEF 1 "register_operand" "f")
1584 (match_operand:MODEF 2 "nonimmediate_operand" "fm"))]
1587 "* return output_fp_compare (insn, operands, false, false);"
1588 [(set_attr "type" "multi")
1589 (set_attr "unit" "i387")
1590 (set_attr "mode" "<MODE>")])
1592 (define_insn_and_split "*cmp<mode>_cc_i387"
1593 [(set (reg:CCFP FLAGS_REG)
1595 (match_operand:MODEF 1 "register_operand" "f")
1596 (match_operand:MODEF 2 "nonimmediate_operand" "fm")))
1597 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1598 "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE"
1600 "&& reload_completed"
1603 [(compare:CCFP (match_dup 1)(match_dup 2))]
1605 (set (reg:CC FLAGS_REG)
1606 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1608 [(set_attr "type" "multi")
1609 (set_attr "unit" "i387")
1610 (set_attr "mode" "<MODE>")])
1612 (define_insn "*cmpu<mode>_i387"
1613 [(set (match_operand:HI 0 "register_operand" "=a")
1617 (match_operand:X87MODEF 1 "register_operand" "f")
1618 (match_operand:X87MODEF 2 "register_operand" "f"))]
1622 "* return output_fp_compare (insn, operands, false, true);"
1623 [(set_attr "type" "multi")
1624 (set_attr "unit" "i387")
1625 (set_attr "mode" "<MODE>")])
1627 (define_insn_and_split "*cmpu<mode>_cc_i387"
1628 [(set (reg:CCFP FLAGS_REG)
1631 (match_operand:X87MODEF 1 "register_operand" "f")
1632 (match_operand:X87MODEF 2 "register_operand" "f"))]
1634 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1635 "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE"
1637 "&& reload_completed"
1641 [(compare:CCFP (match_dup 1)(match_dup 2))]
1644 (set (reg:CC FLAGS_REG)
1645 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1647 [(set_attr "type" "multi")
1648 (set_attr "unit" "i387")
1649 (set_attr "mode" "<MODE>")])
1651 (define_insn "*cmp<X87MODEF:mode>_<SWI24:mode>_i387"
1652 [(set (match_operand:HI 0 "register_operand" "=a")
1655 (match_operand:X87MODEF 1 "register_operand" "f")
1657 (match_operand:SWI24 2 "memory_operand" "m")))]
1660 && (TARGET_USE_<SWI24:MODE>MODE_FIOP
1661 || optimize_function_for_size_p (cfun))"
1662 "* return output_fp_compare (insn, operands, false, false);"
1663 [(set_attr "type" "multi")
1664 (set_attr "unit" "i387")
1665 (set_attr "fp_int_src" "true")
1666 (set_attr "mode" "<SWI24:MODE>")])
1668 (define_insn_and_split "*cmp<X87MODEF:mode>_<SWI24:mode>_cc_i387"
1669 [(set (reg:CCFP FLAGS_REG)
1671 (match_operand:X87MODEF 1 "register_operand" "f")
1673 (match_operand:SWI24 2 "memory_operand" "m"))))
1674 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1675 "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE
1676 && (TARGET_USE_<SWI24:MODE>MODE_FIOP
1677 || optimize_function_for_size_p (cfun))"
1679 "&& reload_completed"
1684 (float:X87MODEF (match_dup 2)))]
1686 (set (reg:CC FLAGS_REG)
1687 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1689 [(set_attr "type" "multi")
1690 (set_attr "unit" "i387")
1691 (set_attr "fp_int_src" "true")
1692 (set_attr "mode" "<SWI24:MODE>")])
1694 ;; FP compares, step 2
1695 ;; Move the fpsw to ax.
1697 (define_insn "x86_fnstsw_1"
1698 [(set (match_operand:HI 0 "register_operand" "=a")
1699 (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
1702 [(set_attr "length" "2")
1703 (set_attr "mode" "SI")
1704 (set_attr "unit" "i387")])
1706 ;; FP compares, step 3
1707 ;; Get ax into flags, general case.
1709 (define_insn "x86_sahf_1"
1710 [(set (reg:CC FLAGS_REG)
1711 (unspec:CC [(match_operand:HI 0 "register_operand" "a")]
1715 #ifndef HAVE_AS_IX86_SAHF
1717 return ASM_BYTE "0x9e";
1722 [(set_attr "length" "1")
1723 (set_attr "athlon_decode" "vector")
1724 (set_attr "amdfam10_decode" "direct")
1725 (set_attr "bdver1_decode" "direct")
1726 (set_attr "mode" "SI")])
1728 ;; Pentium Pro can do steps 1 through 3 in one go.
1729 ;; (these instructions set flags directly)
1731 (define_subst_attr "unord" "unord_subst" "" "u")
1732 (define_subst_attr "unordered" "unord_subst" "false" "true")
1734 (define_subst "unord_subst"
1735 [(set (match_operand:CCFP 0)
1736 (match_operand:CCFP 1))]
1743 (define_insn "*cmpi<unord><MODEF:mode>"
1744 [(set (reg:CCFP FLAGS_REG)
1746 (match_operand:MODEF 0 "register_operand" "f,v")
1747 (match_operand:MODEF 1 "register_ssemem_operand" "f,vm")))]
1748 "(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
1749 || (TARGET_80387 && TARGET_CMOVE)"
1751 * return output_fp_compare (insn, operands, true, <unordered>);
1752 %v<unord>comi<MODEF:ssemodesuffix>\t{%1, %0|%0, %1}"
1753 [(set_attr "type" "fcmp,ssecomi")
1754 (set_attr "prefix" "orig,maybe_vex")
1755 (set_attr "mode" "<MODEF:MODE>")
1756 (set_attr "prefix_rep" "*,0")
1757 (set (attr "prefix_data16")
1758 (cond [(eq_attr "alternative" "0")
1760 (eq_attr "mode" "DF")
1763 (const_string "0")))
1764 (set_attr "athlon_decode" "vector")
1765 (set_attr "amdfam10_decode" "direct")
1766 (set_attr "bdver1_decode" "double")
1767 (set_attr "znver1_decode" "double")
1768 (set (attr "enabled")
1770 (match_test ("SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"))
1772 (eq_attr "alternative" "0")
1773 (symbol_ref "TARGET_MIX_SSE_I387")
1774 (symbol_ref "true"))
1776 (eq_attr "alternative" "0")
1778 (symbol_ref "false"))))])
1780 (define_insn "*cmpi<unord>xf_i387"
1781 [(set (reg:CCFP FLAGS_REG)
1783 (match_operand:XF 0 "register_operand" "f")
1784 (match_operand:XF 1 "register_operand" "f")))]
1785 "TARGET_80387 && TARGET_CMOVE"
1786 "* return output_fp_compare (insn, operands, true, <unordered>);"
1787 [(set_attr "type" "fcmp")
1788 (set_attr "mode" "XF")
1789 (set_attr "athlon_decode" "vector")
1790 (set_attr "amdfam10_decode" "direct")
1791 (set_attr "bdver1_decode" "double")
1792 (set_attr "znver1_decode" "double")])
1794 ;; Push/pop instructions.
1796 (define_insn "*push<mode>2"
1797 [(set (match_operand:DWI 0 "push_operand" "=<")
1798 (match_operand:DWI 1 "general_no_elim_operand" "riF*o"))]
1801 [(set_attr "type" "multi")
1802 (set_attr "mode" "<MODE>")])
1805 [(set (match_operand:DWI 0 "push_operand")
1806 (match_operand:DWI 1 "general_gr_operand"))]
1809 "ix86_split_long_move (operands); DONE;")
1811 (define_insn "*pushdi2_rex64"
1812 [(set (match_operand:DI 0 "push_operand" "=<,!<")
1813 (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1818 [(set_attr "type" "push,multi")
1819 (set_attr "mode" "DI")])
1821 ;; Convert impossible pushes of immediate to existing instructions.
1822 ;; First try to get scratch register and go through it. In case this
1823 ;; fails, push sign extended lower part first and then overwrite
1824 ;; upper part by 32bit move.
1826 [(match_scratch:DI 2 "r")
1827 (set (match_operand:DI 0 "push_operand")
1828 (match_operand:DI 1 "immediate_operand"))]
1829 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1830 && !x86_64_immediate_operand (operands[1], DImode)"
1831 [(set (match_dup 2) (match_dup 1))
1832 (set (match_dup 0) (match_dup 2))])
1834 ;; We need to define this as both peepholer and splitter for case
1835 ;; peephole2 pass is not run.
1836 ;; "&& 1" is needed to keep it from matching the previous pattern.
1838 [(set (match_operand:DI 0 "push_operand")
1839 (match_operand:DI 1 "immediate_operand"))]
1840 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1841 && !x86_64_immediate_operand (operands[1], DImode) && 1"
1842 [(set (match_dup 0) (match_dup 1))
1843 (set (match_dup 2) (match_dup 3))]
1845 split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1847 operands[1] = gen_lowpart (DImode, operands[2]);
1848 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (Pmode, stack_pointer_rtx,
1853 [(set (match_operand:DI 0 "push_operand")
1854 (match_operand:DI 1 "immediate_operand"))]
1855 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
1856 ? epilogue_completed : reload_completed)
1857 && !symbolic_operand (operands[1], DImode)
1858 && !x86_64_immediate_operand (operands[1], DImode)"
1859 [(set (match_dup 0) (match_dup 1))
1860 (set (match_dup 2) (match_dup 3))]
1862 split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1864 operands[1] = gen_lowpart (DImode, operands[2]);
1865 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (Pmode, stack_pointer_rtx,
1869 (define_insn "*pushsi2"
1870 [(set (match_operand:SI 0 "push_operand" "=<")
1871 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1874 [(set_attr "type" "push")
1875 (set_attr "mode" "SI")])
1877 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1878 ;; "push a byte/word". But actually we use pushl, which has the effect
1879 ;; of rounding the amount pushed up to a word.
1881 ;; For TARGET_64BIT we always round up to 8 bytes.
1882 (define_insn "*push<mode>2_rex64"
1883 [(set (match_operand:SWI124 0 "push_operand" "=X")
1884 (match_operand:SWI124 1 "nonmemory_no_elim_operand" "r<i>"))]
1887 [(set_attr "type" "push")
1888 (set_attr "mode" "DI")])
1890 (define_insn "*push<mode>2"
1891 [(set (match_operand:SWI12 0 "push_operand" "=X")
1892 (match_operand:SWI12 1 "nonmemory_no_elim_operand" "rn"))]
1895 [(set_attr "type" "push")
1896 (set_attr "mode" "SI")])
1898 (define_insn "*push<mode>2_prologue"
1899 [(set (match_operand:W 0 "push_operand" "=<")
1900 (match_operand:W 1 "general_no_elim_operand" "r<i>*m"))
1901 (clobber (mem:BLK (scratch)))]
1903 "push{<imodesuffix>}\t%1"
1904 [(set_attr "type" "push")
1905 (set_attr "mode" "<MODE>")])
1907 (define_insn "*pop<mode>1"
1908 [(set (match_operand:W 0 "nonimmediate_operand" "=r*m")
1909 (match_operand:W 1 "pop_operand" ">"))]
1911 "pop{<imodesuffix>}\t%0"
1912 [(set_attr "type" "pop")
1913 (set_attr "mode" "<MODE>")])
1915 (define_insn "*pop<mode>1_epilogue"
1916 [(set (match_operand:W 0 "nonimmediate_operand" "=r*m")
1917 (match_operand:W 1 "pop_operand" ">"))
1918 (clobber (mem:BLK (scratch)))]
1920 "pop{<imodesuffix>}\t%0"
1921 [(set_attr "type" "pop")
1922 (set_attr "mode" "<MODE>")])
1924 (define_insn "*pushfl<mode>2"
1925 [(set (match_operand:W 0 "push_operand" "=<")
1926 (match_operand:W 1 "flags_reg_operand"))]
1928 "pushf{<imodesuffix>}"
1929 [(set_attr "type" "push")
1930 (set_attr "mode" "<MODE>")])
1932 (define_insn "*popfl<mode>1"
1933 [(set (match_operand:W 0 "flags_reg_operand")
1934 (match_operand:W 1 "pop_operand" ">"))]
1936 "popf{<imodesuffix>}"
1937 [(set_attr "type" "pop")
1938 (set_attr "mode" "<MODE>")])
1941 ;; Reload patterns to support multi-word load/store
1942 ;; with non-offsetable address.
1943 (define_expand "reload_noff_store"
1944 [(parallel [(match_operand 0 "memory_operand" "=m")
1945 (match_operand 1 "register_operand" "r")
1946 (match_operand:DI 2 "register_operand" "=&r")])]
1949 rtx mem = operands[0];
1950 rtx addr = XEXP (mem, 0);
1952 emit_move_insn (operands[2], addr);
1953 mem = replace_equiv_address_nv (mem, operands[2]);
1955 emit_insn (gen_rtx_SET (mem, operands[1]));
1959 (define_expand "reload_noff_load"
1960 [(parallel [(match_operand 0 "register_operand" "=r")
1961 (match_operand 1 "memory_operand" "m")
1962 (match_operand:DI 2 "register_operand" "=r")])]
1965 rtx mem = operands[1];
1966 rtx addr = XEXP (mem, 0);
1968 emit_move_insn (operands[2], addr);
1969 mem = replace_equiv_address_nv (mem, operands[2]);
1971 emit_insn (gen_rtx_SET (operands[0], mem));
1975 ;; Move instructions.
1977 (define_expand "movxi"
1978 [(set (match_operand:XI 0 "nonimmediate_operand")
1979 (match_operand:XI 1 "general_operand"))]
1981 "ix86_expand_vector_move (XImode, operands); DONE;")
1983 (define_expand "movoi"
1984 [(set (match_operand:OI 0 "nonimmediate_operand")
1985 (match_operand:OI 1 "general_operand"))]
1987 "ix86_expand_vector_move (OImode, operands); DONE;")
1989 (define_expand "movti"
1990 [(set (match_operand:TI 0 "nonimmediate_operand")
1991 (match_operand:TI 1 "general_operand"))]
1992 "TARGET_64BIT || TARGET_SSE"
1995 ix86_expand_move (TImode, operands);
1997 ix86_expand_vector_move (TImode, operands);
2001 ;; This expands to what emit_move_complex would generate if we didn't
2002 ;; have a movti pattern. Having this avoids problems with reload on
2003 ;; 32-bit targets when SSE is present, but doesn't seem to be harmful
2004 ;; to have around all the time.
2005 (define_expand "movcdi"
2006 [(set (match_operand:CDI 0 "nonimmediate_operand")
2007 (match_operand:CDI 1 "general_operand"))]
2010 if (push_operand (operands[0], CDImode))
2011 emit_move_complex_push (CDImode, operands[0], operands[1]);
2013 emit_move_complex_parts (operands[0], operands[1]);
2017 (define_expand "mov<mode>"
2018 [(set (match_operand:SWI1248x 0 "nonimmediate_operand")
2019 (match_operand:SWI1248x 1 "general_operand"))]
2021 "ix86_expand_move (<MODE>mode, operands); DONE;")
2023 (define_insn "*mov<mode>_xor"
2024 [(set (match_operand:SWI48 0 "register_operand" "=r")
2025 (match_operand:SWI48 1 "const0_operand"))
2026 (clobber (reg:CC FLAGS_REG))]
2029 [(set_attr "type" "alu1")
2030 (set_attr "modrm_class" "op0")
2031 (set_attr "mode" "SI")
2032 (set_attr "length_immediate" "0")])
2034 (define_insn "*mov<mode>_or"
2035 [(set (match_operand:SWI48 0 "register_operand" "=r")
2036 (match_operand:SWI48 1 "constm1_operand"))
2037 (clobber (reg:CC FLAGS_REG))]
2039 "or{<imodesuffix>}\t{%1, %0|%0, %1}"
2040 [(set_attr "type" "alu1")
2041 (set_attr "mode" "<MODE>")
2042 (set_attr "length_immediate" "1")])
2044 (define_insn "*movxi_internal_avx512f"
2045 [(set (match_operand:XI 0 "nonimmediate_operand" "=v,v ,v ,m")
2046 (match_operand:XI 1 "nonimmediate_or_sse_const_operand" " C,BC,vm,v"))]
2048 && (register_operand (operands[0], XImode)
2049 || register_operand (operands[1], XImode))"
2051 switch (get_attr_type (insn))
2054 return standard_sse_constant_opcode (insn, operands);
2057 if (misaligned_operand (operands[0], XImode)
2058 || misaligned_operand (operands[1], XImode))
2059 return "vmovdqu32\t{%1, %0|%0, %1}";
2061 return "vmovdqa32\t{%1, %0|%0, %1}";
2067 [(set_attr "type" "sselog1,sselog1,ssemov,ssemov")
2068 (set_attr "prefix" "evex")
2069 (set_attr "mode" "XI")])
2071 (define_insn "*movoi_internal_avx"
2072 [(set (match_operand:OI 0 "nonimmediate_operand" "=v,v ,v ,m")
2073 (match_operand:OI 1 "nonimmediate_or_sse_const_operand" " C,BC,vm,v"))]
2075 && (register_operand (operands[0], OImode)
2076 || register_operand (operands[1], OImode))"
2078 switch (get_attr_type (insn))
2081 return standard_sse_constant_opcode (insn, operands);
2084 if (misaligned_operand (operands[0], OImode)
2085 || misaligned_operand (operands[1], OImode))
2087 if (get_attr_mode (insn) == MODE_V8SF)
2088 return "vmovups\t{%1, %0|%0, %1}";
2089 else if (get_attr_mode (insn) == MODE_XI)
2090 return "vmovdqu32\t{%1, %0|%0, %1}";
2092 return "vmovdqu\t{%1, %0|%0, %1}";
2096 if (get_attr_mode (insn) == MODE_V8SF)
2097 return "vmovaps\t{%1, %0|%0, %1}";
2098 else if (get_attr_mode (insn) == MODE_XI)
2099 return "vmovdqa32\t{%1, %0|%0, %1}";
2101 return "vmovdqa\t{%1, %0|%0, %1}";
2108 [(set_attr "isa" "*,avx2,*,*")
2109 (set_attr "type" "sselog1,sselog1,ssemov,ssemov")
2110 (set_attr "prefix" "vex")
2112 (cond [(ior (match_operand 0 "ext_sse_reg_operand")
2113 (match_operand 1 "ext_sse_reg_operand"))
2115 (and (eq_attr "alternative" "1")
2116 (match_test "TARGET_AVX512VL"))
2118 (ior (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
2119 (and (eq_attr "alternative" "3")
2120 (match_test "TARGET_SSE_TYPELESS_STORES")))
2121 (const_string "V8SF")
2123 (const_string "OI")))])
2125 (define_insn "*movti_internal"
2126 [(set (match_operand:TI 0 "nonimmediate_operand" "=!r ,o ,v,v ,v ,m,?r,?Yd")
2127 (match_operand:TI 1 "general_operand" "riFo,re,C,BC,vm,v,Yd,r"))]
2129 && !(MEM_P (operands[0]) && MEM_P (operands[1])))
2131 && nonimmediate_or_sse_const_operand (operands[1], TImode)
2132 && (register_operand (operands[0], TImode)
2133 || register_operand (operands[1], TImode)))"
2135 switch (get_attr_type (insn))
2141 return standard_sse_constant_opcode (insn, operands);
2144 /* TDmode values are passed as TImode on the stack. Moving them
2145 to stack may result in unaligned memory access. */
2146 if (misaligned_operand (operands[0], TImode)
2147 || misaligned_operand (operands[1], TImode))
2149 if (get_attr_mode (insn) == MODE_V4SF)
2150 return "%vmovups\t{%1, %0|%0, %1}";
2151 else if (get_attr_mode (insn) == MODE_XI)
2152 return "vmovdqu32\t{%1, %0|%0, %1}";
2154 return "%vmovdqu\t{%1, %0|%0, %1}";
2158 if (get_attr_mode (insn) == MODE_V4SF)
2159 return "%vmovaps\t{%1, %0|%0, %1}";
2160 else if (get_attr_mode (insn) == MODE_XI)
2161 return "vmovdqa32\t{%1, %0|%0, %1}";
2163 return "%vmovdqa\t{%1, %0|%0, %1}";
2171 (cond [(eq_attr "alternative" "0,1,6,7")
2172 (const_string "x64")
2173 (eq_attr "alternative" "3")
2174 (const_string "sse2")
2176 (const_string "*")))
2178 (cond [(eq_attr "alternative" "0,1,6,7")
2179 (const_string "multi")
2180 (eq_attr "alternative" "2,3")
2181 (const_string "sselog1")
2183 (const_string "ssemov")))
2184 (set (attr "prefix")
2185 (if_then_else (eq_attr "type" "sselog1,ssemov")
2186 (const_string "maybe_vex")
2187 (const_string "orig")))
2189 (cond [(eq_attr "alternative" "0,1")
2191 (ior (match_operand 0 "ext_sse_reg_operand")
2192 (match_operand 1 "ext_sse_reg_operand"))
2194 (and (eq_attr "alternative" "3")
2195 (match_test "TARGET_AVX512VL"))
2197 (ior (not (match_test "TARGET_SSE2"))
2198 (ior (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
2199 (and (eq_attr "alternative" "5")
2200 (match_test "TARGET_SSE_TYPELESS_STORES"))))
2201 (const_string "V4SF")
2202 (match_test "TARGET_AVX")
2204 (match_test "optimize_function_for_size_p (cfun)")
2205 (const_string "V4SF")
2207 (const_string "TI")))
2208 (set (attr "preferred_for_speed")
2209 (cond [(eq_attr "alternative" "6")
2210 (symbol_ref "TARGET_INTER_UNIT_MOVES_FROM_VEC")
2211 (eq_attr "alternative" "7")
2212 (symbol_ref "TARGET_INTER_UNIT_MOVES_TO_VEC")
2214 (symbol_ref "true")))])
2217 [(set (match_operand:TI 0 "sse_reg_operand")
2218 (match_operand:TI 1 "general_reg_operand"))]
2219 "TARGET_64BIT && TARGET_SSE4_1
2220 && reload_completed"
2223 (vec_duplicate:V2DI (match_dup 3))
2227 operands[2] = lowpart_subreg (V2DImode, operands[0], TImode);
2228 operands[3] = gen_highpart (DImode, operands[1]);
2230 emit_move_insn (gen_lowpart (DImode, operands[0]),
2231 gen_lowpart (DImode, operands[1]));
2234 (define_insn "*movdi_internal"
2235 [(set (match_operand:DI 0 "nonimmediate_operand"
2236 "=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")
2237 (match_operand:DI 1 "general_operand"
2238 "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"))]
2239 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2241 switch (get_attr_type (insn))
2244 return "kmovq\t{%1, %0|%0, %1}";
2250 return "pxor\t%0, %0";
2253 /* Handle broken assemblers that require movd instead of movq. */
2254 if (!HAVE_AS_IX86_INTERUNIT_MOVQ
2255 && (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1])))
2256 return "movd\t{%1, %0|%0, %1}";
2257 return "movq\t{%1, %0|%0, %1}";
2260 return standard_sse_constant_opcode (insn, operands);
2263 switch (get_attr_mode (insn))
2266 /* Handle broken assemblers that require movd instead of movq. */
2267 if (!HAVE_AS_IX86_INTERUNIT_MOVQ
2268 && (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1])))
2269 return "%vmovd\t{%1, %0|%0, %1}";
2270 return "%vmovq\t{%1, %0|%0, %1}";
2273 /* Handle AVX512 registers set. */
2274 if (EXT_REX_SSE_REG_P (operands[0])
2275 || EXT_REX_SSE_REG_P (operands[1]))
2276 return "vmovdqa64\t{%1, %0|%0, %1}";
2277 return "%vmovdqa\t{%1, %0|%0, %1}";
2280 gcc_assert (!TARGET_AVX);
2281 return "movlps\t{%1, %0|%0, %1}";
2283 return "%vmovaps\t{%1, %0|%0, %1}";
2290 if (SSE_REG_P (operands[0]))
2291 return "movq2dq\t{%1, %0|%0, %1}";
2293 return "movdq2q\t{%1, %0|%0, %1}";
2296 return "lea{q}\t{%E1, %0|%0, %E1}";
2299 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2300 if (get_attr_mode (insn) == MODE_SI)
2301 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2302 else if (which_alternative == 4)
2303 return "movabs{q}\t{%1, %0|%0, %1}";
2304 else if (ix86_use_lea_for_mov (insn, operands))
2305 return "lea{q}\t{%E1, %0|%0, %E1}";
2307 return "mov{q}\t{%1, %0|%0, %1}";
2314 (cond [(eq_attr "alternative" "0,1,17,18")
2315 (const_string "nox64")
2316 (eq_attr "alternative" "2,3,4,5,10,11,23,25")
2317 (const_string "x64")
2318 (eq_attr "alternative" "19,20")
2319 (const_string "x64_sse2")
2320 (eq_attr "alternative" "21,22")
2321 (const_string "sse2")
2323 (const_string "*")))
2325 (cond [(eq_attr "alternative" "0,1,17,18")
2326 (const_string "multi")
2327 (eq_attr "alternative" "6")
2328 (const_string "mmx")
2329 (eq_attr "alternative" "7,8,9,10,11")
2330 (const_string "mmxmov")
2331 (eq_attr "alternative" "12")
2332 (const_string "sselog1")
2333 (eq_attr "alternative" "13,14,15,16,19,20")
2334 (const_string "ssemov")
2335 (eq_attr "alternative" "21,22")
2336 (const_string "ssecvt")
2337 (eq_attr "alternative" "23,24,25,26")
2338 (const_string "mskmov")
2339 (and (match_operand 0 "register_operand")
2340 (match_operand 1 "pic_32bit_operand"))
2341 (const_string "lea")
2343 (const_string "imov")))
2346 (and (eq_attr "alternative" "4") (eq_attr "type" "imov"))
2348 (const_string "*")))
2349 (set (attr "length_immediate")
2351 (and (eq_attr "alternative" "4") (eq_attr "type" "imov"))
2353 (const_string "*")))
2354 (set (attr "prefix_rex")
2356 (eq_attr "alternative" "10,11,19,20")
2358 (const_string "*")))
2359 (set (attr "prefix")
2360 (if_then_else (eq_attr "type" "sselog1,ssemov")
2361 (const_string "maybe_vex")
2362 (const_string "orig")))
2363 (set (attr "prefix_data16")
2364 (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "DI"))
2366 (const_string "*")))
2368 (cond [(eq_attr "alternative" "2")
2370 (eq_attr "alternative" "12,13")
2371 (cond [(ior (match_operand 0 "ext_sse_reg_operand")
2372 (match_operand 1 "ext_sse_reg_operand"))
2374 (ior (not (match_test "TARGET_SSE2"))
2375 (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL"))
2376 (const_string "V4SF")
2377 (match_test "TARGET_AVX")
2379 (match_test "optimize_function_for_size_p (cfun)")
2380 (const_string "V4SF")
2382 (const_string "TI"))
2384 (and (eq_attr "alternative" "14,15,16")
2385 (not (match_test "TARGET_SSE2")))
2386 (const_string "V2SF")
2388 (const_string "DI")))
2389 (set (attr "preferred_for_speed")
2390 (cond [(eq_attr "alternative" "10,17,19")
2391 (symbol_ref "TARGET_INTER_UNIT_MOVES_FROM_VEC")
2392 (eq_attr "alternative" "11,18,20")
2393 (symbol_ref "TARGET_INTER_UNIT_MOVES_TO_VEC")
2395 (symbol_ref "true")))
2396 (set (attr "enabled")
2397 (cond [(eq_attr "alternative" "15")
2399 (match_test "TARGET_STV && TARGET_SSE2")
2400 (symbol_ref "false")
2402 (eq_attr "alternative" "16")
2404 (match_test "TARGET_STV && TARGET_SSE2")
2406 (symbol_ref "false"))
2408 (const_string "*")))])
2411 [(set (match_operand:<DWI> 0 "general_reg_operand")
2412 (match_operand:<DWI> 1 "sse_reg_operand"))]
2414 && reload_completed"
2418 (parallel [(const_int 1)])))]
2420 operands[2] = gen_highpart (<MODE>mode, operands[0]);
2421 operands[3] = lowpart_subreg (<ssevecmode>mode, operands[1], <DWI>mode);
2423 emit_move_insn (gen_lowpart (<MODE>mode, operands[0]),
2424 gen_lowpart (<MODE>mode, operands[1]));
2428 [(set (match_operand:DWI 0 "nonimmediate_gr_operand")
2429 (match_operand:DWI 1 "general_gr_operand"))]
2432 "ix86_split_long_move (operands); DONE;")
2435 [(set (match_operand:DI 0 "sse_reg_operand")
2436 (match_operand:DI 1 "general_reg_operand"))]
2437 "!TARGET_64BIT && TARGET_SSE4_1
2438 && reload_completed"
2441 (vec_duplicate:V4SI (match_dup 3))
2445 operands[2] = lowpart_subreg (V4SImode, operands[0], DImode);
2446 operands[3] = gen_highpart (SImode, operands[1]);
2448 emit_move_insn (gen_lowpart (SImode, operands[0]),
2449 gen_lowpart (SImode, operands[1]));
2452 ;; movabsq $0x0012345678000000, %rax is longer
2453 ;; than movl $0x12345678, %eax; shlq $24, %rax.
2455 [(set (match_operand:DI 0 "register_operand")
2456 (match_operand:DI 1 "const_int_operand"))]
2458 && optimize_insn_for_size_p ()
2459 && LEGACY_INT_REG_P (operands[0])
2460 && !x86_64_immediate_operand (operands[1], DImode)
2461 && !x86_64_zext_immediate_operand (operands[1], DImode)
2462 && !((UINTVAL (operands[1]) >> ctz_hwi (UINTVAL (operands[1])))
2463 & ~(HOST_WIDE_INT) 0xffffffff)
2464 && peep2_regno_dead_p (0, FLAGS_REG)"
2465 [(set (match_dup 0) (match_dup 1))
2466 (parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
2467 (clobber (reg:CC FLAGS_REG))])]
2469 int shift = ctz_hwi (UINTVAL (operands[1]));
2470 operands[1] = gen_int_mode (UINTVAL (operands[1]) >> shift, DImode);
2471 operands[2] = gen_int_mode (shift, QImode);
2474 (define_insn "*movsi_internal"
2475 [(set (match_operand:SI 0 "nonimmediate_operand"
2476 "=r,m ,*y,*y,?*y,?m,?r,?*y,*v,*v,*v,m ,?r,?*v,*k,*k ,*rm")
2477 (match_operand:SI 1 "general_operand"
2478 "g ,re,C ,*y,m ,*y,*y,r ,C ,*v,m ,*v,*v,r ,*r,*km,*k"))]
2479 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2481 switch (get_attr_type (insn))
2484 return standard_sse_constant_opcode (insn, operands);
2487 return "kmovd\t{%1, %0|%0, %1}";
2490 switch (get_attr_mode (insn))
2493 return "%vmovd\t{%1, %0|%0, %1}";
2495 return "%vmovdqa\t{%1, %0|%0, %1}";
2497 return "vmovdqa32\t{%g1, %g0|%g0, %g1}";
2500 return "%vmovaps\t{%1, %0|%0, %1}";
2503 gcc_assert (!TARGET_AVX);
2504 return "movss\t{%1, %0|%0, %1}";
2511 return "pxor\t%0, %0";
2514 switch (get_attr_mode (insn))
2517 return "movq\t{%1, %0|%0, %1}";
2519 return "movd\t{%1, %0|%0, %1}";
2526 return "lea{l}\t{%E1, %0|%0, %E1}";
2529 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2530 if (ix86_use_lea_for_mov (insn, operands))
2531 return "lea{l}\t{%E1, %0|%0, %E1}";
2533 return "mov{l}\t{%1, %0|%0, %1}";
2540 (cond [(eq_attr "alternative" "12,13")
2541 (const_string "sse2")
2543 (const_string "*")))
2545 (cond [(eq_attr "alternative" "2")
2546 (const_string "mmx")
2547 (eq_attr "alternative" "3,4,5,6,7")
2548 (const_string "mmxmov")
2549 (eq_attr "alternative" "8")
2550 (const_string "sselog1")
2551 (eq_attr "alternative" "9,10,11,12,13")
2552 (const_string "ssemov")
2553 (eq_attr "alternative" "14,15,16")
2554 (const_string "mskmov")
2555 (and (match_operand 0 "register_operand")
2556 (match_operand 1 "pic_32bit_operand"))
2557 (const_string "lea")
2559 (const_string "imov")))
2560 (set (attr "prefix")
2561 (if_then_else (eq_attr "type" "sselog1,ssemov")
2562 (const_string "maybe_vex")
2563 (const_string "orig")))
2564 (set (attr "prefix_data16")
2565 (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
2567 (const_string "*")))
2569 (cond [(eq_attr "alternative" "2,3")
2571 (eq_attr "alternative" "8,9")
2572 (cond [(ior (match_operand 0 "ext_sse_reg_operand")
2573 (match_operand 1 "ext_sse_reg_operand"))
2575 (ior (not (match_test "TARGET_SSE2"))
2576 (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL"))
2577 (const_string "V4SF")
2578 (match_test "TARGET_AVX")
2580 (match_test "optimize_function_for_size_p (cfun)")
2581 (const_string "V4SF")
2583 (const_string "TI"))
2585 (and (eq_attr "alternative" "10,11")
2586 (not (match_test "TARGET_SSE2")))
2589 (const_string "SI")))
2590 (set (attr "preferred_for_speed")
2591 (cond [(eq_attr "alternative" "6,12")
2592 (symbol_ref "TARGET_INTER_UNIT_MOVES_FROM_VEC")
2593 (eq_attr "alternative" "7,13")
2594 (symbol_ref "TARGET_INTER_UNIT_MOVES_TO_VEC")
2596 (symbol_ref "true")))])
2598 (define_insn "*movhi_internal"
2599 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r ,r ,m ,k,k ,r,m")
2600 (match_operand:HI 1 "general_operand" "r ,rn,rm,rn,r,km,k,k"))]
2601 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2603 switch (get_attr_type (insn))
2606 /* movzwl is faster than movw on p2 due to partial word stalls,
2607 though not as fast as an aligned movl. */
2608 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
2611 switch (which_alternative)
2614 return "kmovw\t{%k1, %0|%0, %k1}";
2616 return "kmovw\t{%1, %k0|%k0, %1}";
2619 return "kmovw\t{%1, %0|%0, %1}";
2625 if (get_attr_mode (insn) == MODE_SI)
2626 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2628 return "mov{w}\t{%1, %0|%0, %1}";
2632 (cond [(eq_attr "alternative" "4,5,6,7")
2633 (const_string "mskmov")
2634 (match_test "optimize_function_for_size_p (cfun)")
2635 (const_string "imov")
2636 (and (eq_attr "alternative" "0")
2637 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2638 (not (match_test "TARGET_HIMODE_MATH"))))
2639 (const_string "imov")
2640 (and (eq_attr "alternative" "1,2")
2641 (match_operand:HI 1 "aligned_operand"))
2642 (const_string "imov")
2643 (and (match_test "TARGET_MOVX")
2644 (eq_attr "alternative" "0,2"))
2645 (const_string "imovx")
2647 (const_string "imov")))
2648 (set (attr "prefix")
2649 (if_then_else (eq_attr "alternative" "4,5,6,7")
2650 (const_string "vex")
2651 (const_string "orig")))
2653 (cond [(eq_attr "type" "imovx")
2655 (and (eq_attr "alternative" "1,2")
2656 (match_operand:HI 1 "aligned_operand"))
2658 (and (eq_attr "alternative" "0")
2659 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2660 (not (match_test "TARGET_HIMODE_MATH"))))
2663 (const_string "HI")))])
2665 ;; Situation is quite tricky about when to choose full sized (SImode) move
2666 ;; over QImode moves. For Q_REG -> Q_REG move we use full size only for
2667 ;; partial register dependency machines (such as AMD Athlon), where QImode
2668 ;; moves issue extra dependency and for partial register stalls machines
2669 ;; that don't use QImode patterns (and QImode move cause stall on the next
2672 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
2673 ;; register stall machines with, where we use QImode instructions, since
2674 ;; partial register stall can be caused there. Then we use movzx.
2676 (define_insn "*movqi_internal"
2677 [(set (match_operand:QI 0 "nonimmediate_operand"
2678 "=Q,R,r,q,q,r,r ,?r,m ,k,k,r,m,k")
2679 (match_operand:QI 1 "general_operand"
2680 "Q ,R,r,n,m,q,rn, m,qn,r,k,k,k,m"))]
2681 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2683 static char buf[128];
2687 switch (get_attr_type (insn))
2690 gcc_assert (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]));
2691 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
2694 switch (which_alternative)
2697 ops = "kmov%s\t{%%k1, %%0|%%0, %%k1}";
2700 ops = "kmov%s\t{%%1, %%k0|%%k0, %%1}";
2704 gcc_assert (TARGET_AVX512DQ);
2707 ops = "kmov%s\t{%%1, %%0|%%0, %%1}";
2713 suffix = (get_attr_mode (insn) == MODE_HI) ? "w" : "b";
2715 snprintf (buf, sizeof (buf), ops, suffix);
2719 if (get_attr_mode (insn) == MODE_SI)
2720 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2722 return "mov{b}\t{%1, %0|%0, %1}";
2726 (cond [(eq_attr "alternative" "1,2")
2727 (const_string "x64")
2728 (eq_attr "alternative" "12,13")
2729 (const_string "avx512dq")
2731 (const_string "*")))
2733 (cond [(eq_attr "alternative" "9,10,11,12,13")
2734 (const_string "mskmov")
2735 (and (eq_attr "alternative" "7")
2736 (not (match_operand:QI 1 "aligned_operand")))
2737 (const_string "imovx")
2738 (match_test "optimize_function_for_size_p (cfun)")
2739 (const_string "imov")
2740 (and (eq_attr "alternative" "5")
2741 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2742 (not (match_test "TARGET_QIMODE_MATH"))))
2743 (const_string "imov")
2744 (eq_attr "alternative" "5,7")
2745 (const_string "imovx")
2746 (and (match_test "TARGET_MOVX")
2747 (eq_attr "alternative" "4"))
2748 (const_string "imovx")
2750 (const_string "imov")))
2751 (set (attr "prefix")
2752 (if_then_else (eq_attr "alternative" "9,10,11")
2753 (const_string "vex")
2754 (const_string "orig")))
2756 (cond [(eq_attr "alternative" "5,6,7")
2758 (eq_attr "alternative" "8")
2760 (and (eq_attr "alternative" "9,10,11")
2761 (not (match_test "TARGET_AVX512DQ")))
2763 (eq_attr "type" "imovx")
2765 ;; For -Os, 8-bit immediates are always shorter than 32-bit
2767 (and (eq_attr "type" "imov")
2768 (and (eq_attr "alternative" "3")
2769 (match_test "optimize_function_for_size_p (cfun)")))
2771 ;; For -Os, movl where one or both operands are NON_Q_REGS
2772 ;; and both are LEGACY_REGS is shorter than movb.
2773 ;; Otherwise movb and movl sizes are the same, so decide purely
2774 ;; based on speed factors.
2775 (and (eq_attr "type" "imov")
2776 (and (eq_attr "alternative" "1")
2777 (match_test "optimize_function_for_size_p (cfun)")))
2779 (and (eq_attr "type" "imov")
2780 (and (eq_attr "alternative" "0,1,2,3")
2781 (and (match_test "TARGET_PARTIAL_REG_DEPENDENCY")
2782 (not (match_test "TARGET_PARTIAL_REG_STALL")))))
2784 ;; Avoid partial register stalls when not using QImode arithmetic
2785 (and (eq_attr "type" "imov")
2786 (and (eq_attr "alternative" "0,1,2,3")
2787 (and (match_test "TARGET_PARTIAL_REG_STALL")
2788 (not (match_test "TARGET_QIMODE_MATH")))))
2791 (const_string "QI")))])
2793 ;; Stores and loads of ax to arbitrary constant address.
2794 ;; We fake an second form of instruction to force reload to load address
2795 ;; into register when rax is not available
2796 (define_insn "*movabs<mode>_1"
2797 [(set (mem:SWI1248x (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2798 (match_operand:SWI1248x 1 "nonmemory_operand" "a,r<i>"))]
2799 "TARGET_LP64 && ix86_check_movabs (insn, 0)"
2801 /* Recover the full memory rtx. */
2802 operands[0] = SET_DEST (PATTERN (insn));
2803 switch (which_alternative)
2806 return "movabs{<imodesuffix>}\t{%1, %P0|<iptrsize> PTR [%P0], %1}";
2808 return "mov{<imodesuffix>}\t{%1, %0|%0, %1}";
2813 [(set_attr "type" "imov")
2814 (set_attr "modrm" "0,*")
2815 (set_attr "length_address" "8,0")
2816 (set_attr "length_immediate" "0,*")
2817 (set_attr "memory" "store")
2818 (set_attr "mode" "<MODE>")])
2820 (define_insn "*movabs<mode>_2"
2821 [(set (match_operand:SWI1248x 0 "register_operand" "=a,r")
2822 (mem:SWI1248x (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2823 "TARGET_LP64 && ix86_check_movabs (insn, 1)"
2825 /* Recover the full memory rtx. */
2826 operands[1] = SET_SRC (PATTERN (insn));
2827 switch (which_alternative)
2830 return "movabs{<imodesuffix>}\t{%P1, %0|%0, <iptrsize> PTR [%P1]}";
2832 return "mov{<imodesuffix>}\t{%1, %0|%0, %1}";
2837 [(set_attr "type" "imov")
2838 (set_attr "modrm" "0,*")
2839 (set_attr "length_address" "8,0")
2840 (set_attr "length_immediate" "0")
2841 (set_attr "memory" "load")
2842 (set_attr "mode" "<MODE>")])
2844 (define_insn "*swap<mode>"
2845 [(set (match_operand:SWI48 0 "register_operand" "+r")
2846 (match_operand:SWI48 1 "register_operand" "+r"))
2850 "xchg{<imodesuffix>}\t%1, %0"
2851 [(set_attr "type" "imov")
2852 (set_attr "mode" "<MODE>")
2853 (set_attr "pent_pair" "np")
2854 (set_attr "athlon_decode" "vector")
2855 (set_attr "amdfam10_decode" "double")
2856 (set_attr "bdver1_decode" "double")])
2858 (define_insn "*swap<mode>"
2859 [(set (match_operand:SWI12 0 "register_operand" "+<r>,r")
2860 (match_operand:SWI12 1 "register_operand" "+<r>,r"))
2865 xchg{<imodesuffix>}\t%1, %0
2867 [(set_attr "type" "imov")
2868 (set_attr "mode" "<MODE>,SI")
2869 (set (attr "preferred_for_size")
2870 (cond [(eq_attr "alternative" "0")
2871 (symbol_ref "false")]
2872 (symbol_ref "true")))
2873 ;; Potential partial reg stall on alternative 1.
2874 (set (attr "preferred_for_speed")
2875 (cond [(eq_attr "alternative" "1")
2876 (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
2877 (symbol_ref "true")))
2878 (set_attr "pent_pair" "np")
2879 (set_attr "athlon_decode" "vector")
2880 (set_attr "amdfam10_decode" "double")
2881 (set_attr "bdver1_decode" "double")])
2883 (define_expand "movstrict<mode>"
2884 [(set (strict_low_part (match_operand:SWI12 0 "nonimmediate_operand"))
2885 (match_operand:SWI12 1 "general_operand"))]
2888 if (TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun))
2890 if (SUBREG_P (operands[0])
2891 && GET_MODE_CLASS (GET_MODE (SUBREG_REG (operands[0]))) != MODE_INT)
2893 /* Don't generate memory->memory moves, go through a register */
2894 if (MEM_P (operands[0]) && MEM_P (operands[1]))
2895 operands[1] = force_reg (<MODE>mode, operands[1]);
2898 (define_insn "*movstrict<mode>_1"
2899 [(set (strict_low_part
2900 (match_operand:SWI12 0 "nonimmediate_operand" "+<r>m,<r>"))
2901 (match_operand:SWI12 1 "general_operand" "<r>n,m"))]
2902 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
2903 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2904 "mov{<imodesuffix>}\t{%1, %0|%0, %1}"
2905 [(set_attr "type" "imov")
2906 (set_attr "mode" "<MODE>")])
2908 (define_insn "*movstrict<mode>_xor"
2909 [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>"))
2910 (match_operand:SWI12 1 "const0_operand"))
2911 (clobber (reg:CC FLAGS_REG))]
2913 "xor{<imodesuffix>}\t%0, %0"
2914 [(set_attr "type" "alu1")
2915 (set_attr "modrm_class" "op0")
2916 (set_attr "mode" "<MODE>")
2917 (set_attr "length_immediate" "0")])
2919 (define_expand "extv<mode>"
2920 [(set (match_operand:SWI24 0 "register_operand")
2921 (sign_extract:SWI24 (match_operand:SWI24 1 "register_operand")
2922 (match_operand:SI 2 "const_int_operand")
2923 (match_operand:SI 3 "const_int_operand")))]
2926 /* Handle extractions from %ah et al. */
2927 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
2930 unsigned int regno = reg_or_subregno (operands[1]);
2932 /* Be careful to expand only with registers having upper parts. */
2933 if (regno <= LAST_VIRTUAL_REGISTER && !QI_REGNO_P (regno))
2934 operands[1] = copy_to_reg (operands[1]);
2937 (define_insn "*extv<mode>"
2938 [(set (match_operand:SWI24 0 "register_operand" "=R")
2939 (sign_extract:SWI24 (match_operand 1 "ext_register_operand" "Q")
2943 "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
2944 [(set_attr "type" "imovx")
2945 (set_attr "mode" "SI")])
2947 (define_expand "extzv<mode>"
2948 [(set (match_operand:SWI248 0 "register_operand")
2949 (zero_extract:SWI248 (match_operand:SWI248 1 "register_operand")
2950 (match_operand:SI 2 "const_int_operand")
2951 (match_operand:SI 3 "const_int_operand")))]
2954 if (ix86_expand_pextr (operands))
2957 /* Handle extractions from %ah et al. */
2958 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
2961 unsigned int regno = reg_or_subregno (operands[1]);
2963 /* Be careful to expand only with registers having upper parts. */
2964 if (regno <= LAST_VIRTUAL_REGISTER && !QI_REGNO_P (regno))
2965 operands[1] = copy_to_reg (operands[1]);
2968 (define_insn "*extzvqi_mem_rex64"
2969 [(set (match_operand:QI 0 "norex_memory_operand" "=Bn")
2971 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q")
2974 "TARGET_64BIT && reload_completed"
2975 "mov{b}\t{%h1, %0|%0, %h1}"
2976 [(set_attr "type" "imov")
2977 (set_attr "mode" "QI")])
2979 (define_insn "*extzv<mode>"
2980 [(set (match_operand:SWI248 0 "register_operand" "=R")
2981 (zero_extract:SWI248 (match_operand 1 "ext_register_operand" "Q")
2985 "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
2986 [(set_attr "type" "imovx")
2987 (set_attr "mode" "SI")])
2989 (define_insn "*extzvqi"
2990 [(set (match_operand:QI 0 "nonimmediate_operand" "=QBc,?R,m")
2992 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q,Q")
2997 switch (get_attr_type (insn))
3000 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
3002 return "mov{b}\t{%h1, %0|%0, %h1}";
3005 [(set_attr "isa" "*,*,nox64")
3007 (if_then_else (and (match_operand:QI 0 "register_operand")
3008 (ior (not (match_operand:QI 0 "QIreg_operand"))
3009 (match_test "TARGET_MOVX")))
3010 (const_string "imovx")
3011 (const_string "imov")))
3013 (if_then_else (eq_attr "type" "imovx")
3015 (const_string "QI")))])
3018 [(set (match_operand:QI 0 "register_operand")
3020 (zero_extract:SI (match_operand 1 "ext_register_operand")
3023 (set (match_operand:QI 2 "norex_memory_operand") (match_dup 0))]
3025 && peep2_reg_dead_p (2, operands[0])"
3028 (zero_extract:SI (match_dup 1)
3030 (const_int 8)) 0))])
3032 (define_expand "insv<mode>"
3033 [(set (zero_extract:SWI248 (match_operand:SWI248 0 "register_operand")
3034 (match_operand:SI 1 "const_int_operand")
3035 (match_operand:SI 2 "const_int_operand"))
3036 (match_operand:SWI248 3 "register_operand"))]
3041 if (ix86_expand_pinsr (operands))
3044 /* Handle insertions to %ah et al. */
3045 if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
3048 unsigned int regno = reg_or_subregno (operands[0]);
3050 /* Be careful to expand only with registers having upper parts. */
3051 if (regno <= LAST_VIRTUAL_REGISTER && !QI_REGNO_P (regno))
3052 dst = copy_to_reg (operands[0]);
3056 emit_insn (gen_insv<mode>_1 (dst, operands[3]));
3058 /* Fix up the destination if needed. */
3059 if (dst != operands[0])
3060 emit_move_insn (operands[0], dst);
3065 (define_insn "*insvqi_1_mem_rex64"
3066 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
3070 (match_operand:QI 1 "norex_memory_operand" "Bn") 0))]
3071 "TARGET_64BIT && reload_completed"
3072 "mov{b}\t{%1, %h0|%h0, %1}"
3073 [(set_attr "type" "imov")
3074 (set_attr "mode" "QI")])
3076 (define_insn "insv<mode>_1"
3077 [(set (zero_extract:SWI248 (match_operand 0 "ext_register_operand" "+Q,Q")
3080 (match_operand:SWI248 1 "general_operand" "QnBc,m"))]
3083 if (CONST_INT_P (operands[1]))
3084 operands[1] = gen_int_mode (INTVAL (operands[1]), QImode);
3085 return "mov{b}\t{%b1, %h0|%h0, %b1}";
3087 [(set_attr "isa" "*,nox64")
3088 (set_attr "type" "imov")
3089 (set_attr "mode" "QI")])
3091 (define_insn "*insvqi_1"
3092 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q,Q")
3096 (match_operand:QI 1 "general_operand" "QnBc,m") 0))]
3098 "mov{b}\t{%1, %h0|%h0, %1}"
3099 [(set_attr "isa" "*,nox64")
3100 (set_attr "type" "imov")
3101 (set_attr "mode" "QI")])
3104 [(set (match_operand:QI 0 "register_operand")
3105 (match_operand:QI 1 "norex_memory_operand"))
3106 (set (zero_extract:SI (match_operand 2 "ext_register_operand")
3109 (subreg:SI (match_dup 0) 0))]
3111 && peep2_reg_dead_p (2, operands[0])"
3112 [(set (zero_extract:SI (match_dup 2)
3115 (subreg:SI (match_dup 1) 0))])
3117 (define_code_iterator any_extract [sign_extract zero_extract])
3119 (define_insn "*insvqi_2"
3120 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
3123 (any_extract:SI (match_operand 1 "ext_register_operand" "Q")
3127 "mov{b}\t{%h1, %h0|%h0, %h1}"
3128 [(set_attr "type" "imov")
3129 (set_attr "mode" "QI")])
3131 (define_insn "*insvqi_3"
3132 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
3135 (any_shiftrt:SI (match_operand:SI 1 "register_operand" "Q")
3138 "mov{b}\t{%h1, %h0|%h0, %h1}"
3139 [(set_attr "type" "imov")
3140 (set_attr "mode" "QI")])
3142 ;; Floating point push instructions.
3144 (define_insn "*pushtf"
3145 [(set (match_operand:TF 0 "push_operand" "=<,<")
3146 (match_operand:TF 1 "general_no_elim_operand" "v,*roC"))]
3147 "TARGET_64BIT || TARGET_SSE"
3149 /* This insn should be already split before reg-stack. */
3152 [(set_attr "isa" "*,x64")
3153 (set_attr "type" "multi")
3154 (set_attr "unit" "sse,*")
3155 (set_attr "mode" "TF,DI")])
3157 ;; %%% Kill this when call knows how to work this out.
3159 [(set (match_operand:TF 0 "push_operand")
3160 (match_operand:TF 1 "sse_reg_operand"))]
3161 "TARGET_SSE && reload_completed"
3162 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -16)))
3163 (set (match_dup 0) (match_dup 1))]
3165 /* Preserve memory attributes. */
3166 operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
3169 (define_insn_and_split "*pushxf_rounded"
3173 (plus:P (reg:P SP_REG) (const_int -16))))
3174 (match_operand:XF 0 "nonmemory_no_elim_operand" "f,r,*r,C"))]
3178 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -16)))
3179 (set (match_dup 1) (match_dup 0))]
3181 rtx pat = PATTERN (curr_insn);
3182 operands[1] = SET_DEST (pat);
3184 /* Preserve memory attributes. */
3185 operands[1] = replace_equiv_address (operands[1], stack_pointer_rtx);
3187 [(set_attr "type" "multi")
3188 (set_attr "unit" "i387,*,*,*")
3190 (cond [(eq_attr "alternative" "1,2,3")
3193 (const_string "XF")))
3194 (set (attr "preferred_for_size")
3195 (cond [(eq_attr "alternative" "1")
3196 (symbol_ref "false")]
3197 (symbol_ref "true")))])
3199 (define_insn "*pushxf"
3200 [(set (match_operand:XF 0 "push_operand" "=<,<,<,<,<")
3201 (match_operand:XF 1 "general_no_elim_operand" "f,r,*r,oF,oC"))]
3204 /* This insn should be already split before reg-stack. */
3207 [(set_attr "isa" "*,*,*,nox64,x64")
3208 (set_attr "type" "multi")
3209 (set_attr "unit" "i387,*,*,*,*")
3211 (cond [(eq_attr "alternative" "1,2,3,4")
3212 (if_then_else (match_test "TARGET_64BIT")
3214 (const_string "SI"))
3216 (const_string "XF")))
3217 (set (attr "preferred_for_size")
3218 (cond [(eq_attr "alternative" "1")
3219 (symbol_ref "false")]
3220 (symbol_ref "true")))])
3222 ;; %%% Kill this when call knows how to work this out.
3224 [(set (match_operand:XF 0 "push_operand")
3225 (match_operand:XF 1 "fp_register_operand"))]
3227 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
3228 (set (match_dup 0) (match_dup 1))]
3230 operands[2] = GEN_INT (-PUSH_ROUNDING (GET_MODE_SIZE (XFmode)));
3231 /* Preserve memory attributes. */
3232 operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
3235 (define_insn "*pushdf"
3236 [(set (match_operand:DF 0 "push_operand" "=<,<,<,<,<,<")
3237 (match_operand:DF 1 "general_no_elim_operand" "f,r,*r,oF,rmC,x"))]
3240 /* This insn should be already split before reg-stack. */
3243 [(set_attr "isa" "*,nox64,nox64,nox64,x64,sse2")
3244 (set_attr "type" "multi")
3245 (set_attr "unit" "i387,*,*,*,*,sse")
3246 (set_attr "mode" "DF,SI,SI,SI,DI,DF")
3247 (set (attr "preferred_for_size")
3248 (cond [(eq_attr "alternative" "1")
3249 (symbol_ref "false")]
3250 (symbol_ref "true")))
3251 (set (attr "preferred_for_speed")
3252 (cond [(eq_attr "alternative" "1")
3253 (symbol_ref "TARGET_INTEGER_DFMODE_MOVES")]
3254 (symbol_ref "true")))])
3256 ;; %%% Kill this when call knows how to work this out.
3258 [(set (match_operand:DF 0 "push_operand")
3259 (match_operand:DF 1 "any_fp_register_operand"))]
3261 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
3262 (set (match_dup 0) (match_dup 1))]
3264 /* Preserve memory attributes. */
3265 operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
3268 (define_insn "*pushsf_rex64"
3269 [(set (match_operand:SF 0 "push_operand" "=X,X,X")
3270 (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
3273 /* Anything else should be already split before reg-stack. */
3274 gcc_assert (which_alternative == 1);
3275 return "push{q}\t%q1";
3277 [(set_attr "type" "multi,push,multi")
3278 (set_attr "unit" "i387,*,*")
3279 (set_attr "mode" "SF,DI,SF")])
3281 (define_insn "*pushsf"
3282 [(set (match_operand:SF 0 "push_operand" "=<,<,<")
3283 (match_operand:SF 1 "general_no_elim_operand" "f,rmF,x"))]
3286 /* Anything else should be already split before reg-stack. */
3287 gcc_assert (which_alternative == 1);
3288 return "push{l}\t%1";
3290 [(set_attr "type" "multi,push,multi")
3291 (set_attr "unit" "i387,*,*")
3292 (set_attr "mode" "SF,SI,SF")])
3294 ;; %%% Kill this when call knows how to work this out.
3296 [(set (match_operand:SF 0 "push_operand")
3297 (match_operand:SF 1 "any_fp_register_operand"))]
3299 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
3300 (set (match_dup 0) (match_dup 1))]
3302 rtx op = XEXP (operands[0], 0);
3303 if (GET_CODE (op) == PRE_DEC)
3305 gcc_assert (!TARGET_64BIT);
3310 op = XEXP (XEXP (op, 1), 1);
3311 gcc_assert (CONST_INT_P (op));
3314 /* Preserve memory attributes. */
3315 operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
3319 [(set (match_operand:SF 0 "push_operand")
3320 (match_operand:SF 1 "memory_operand"))]
3322 && find_constant_src (insn)"
3323 [(set (match_dup 0) (match_dup 2))]
3324 "operands[2] = find_constant_src (curr_insn);")
3327 [(set (match_operand 0 "push_operand")
3328 (match_operand 1 "general_gr_operand"))]
3330 && (GET_MODE (operands[0]) == TFmode
3331 || GET_MODE (operands[0]) == XFmode
3332 || GET_MODE (operands[0]) == DFmode)"
3334 "ix86_split_long_move (operands); DONE;")
3336 ;; Floating point move instructions.
3338 (define_expand "movtf"
3339 [(set (match_operand:TF 0 "nonimmediate_operand")
3340 (match_operand:TF 1 "nonimmediate_operand"))]
3341 "TARGET_64BIT || TARGET_SSE"
3342 "ix86_expand_move (TFmode, operands); DONE;")
3344 (define_expand "mov<mode>"
3345 [(set (match_operand:X87MODEF 0 "nonimmediate_operand")
3346 (match_operand:X87MODEF 1 "general_operand"))]
3348 "ix86_expand_move (<MODE>mode, operands); DONE;")
3350 (define_insn "*movtf_internal"
3351 [(set (match_operand:TF 0 "nonimmediate_operand" "=v,v ,m,?*r ,!o")
3352 (match_operand:TF 1 "general_operand" "C ,vm,v,*roF,*rC"))]
3353 "(TARGET_64BIT || TARGET_SSE)
3354 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3355 && (lra_in_progress || reload_completed
3356 || !CONST_DOUBLE_P (operands[1])
3357 || ((optimize_function_for_size_p (cfun)
3358 || (ix86_cmodel == CM_LARGE || ix86_cmodel == CM_LARGE_PIC))
3359 && standard_sse_constant_p (operands[1], TFmode) == 1
3360 && !memory_operand (operands[0], TFmode))
3361 || (!TARGET_MEMORY_MISMATCH_STALL
3362 && memory_operand (operands[0], TFmode)))"
3364 switch (get_attr_type (insn))
3367 return standard_sse_constant_opcode (insn, operands);
3370 /* Handle misaligned load/store since we
3371 don't have movmisaligntf pattern. */
3372 if (misaligned_operand (operands[0], TFmode)
3373 || misaligned_operand (operands[1], TFmode))
3375 if (get_attr_mode (insn) == MODE_V4SF)
3376 return "%vmovups\t{%1, %0|%0, %1}";
3377 else if (TARGET_AVX512VL
3378 && (EXT_REX_SSE_REG_P (operands[0])
3379 || EXT_REX_SSE_REG_P (operands[1])))
3380 return "vmovdqu64\t{%1, %0|%0, %1}";
3382 return "%vmovdqu\t{%1, %0|%0, %1}";
3386 if (get_attr_mode (insn) == MODE_V4SF)
3387 return "%vmovaps\t{%1, %0|%0, %1}";
3388 else if (TARGET_AVX512VL
3389 && (EXT_REX_SSE_REG_P (operands[0])
3390 || EXT_REX_SSE_REG_P (operands[1])))
3391 return "vmovdqa64\t{%1, %0|%0, %1}";
3393 return "%vmovdqa\t{%1, %0|%0, %1}";
3403 [(set_attr "isa" "*,*,*,x64,x64")
3404 (set_attr "type" "sselog1,ssemov,ssemov,multi,multi")
3405 (set (attr "prefix")
3406 (if_then_else (eq_attr "type" "sselog1,ssemov")
3407 (const_string "maybe_vex")
3408 (const_string "orig")))
3410 (cond [(eq_attr "alternative" "3,4")
3412 (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
3413 (const_string "V4SF")
3414 (and (eq_attr "alternative" "2")
3415 (match_test "TARGET_SSE_TYPELESS_STORES"))
3416 (const_string "V4SF")
3417 (match_test "TARGET_AVX")
3419 (ior (not (match_test "TARGET_SSE2"))
3420 (match_test "optimize_function_for_size_p (cfun)"))
3421 (const_string "V4SF")
3423 (const_string "TI")))])
3426 [(set (match_operand:TF 0 "nonimmediate_gr_operand")
3427 (match_operand:TF 1 "general_gr_operand"))]
3430 "ix86_split_long_move (operands); DONE;")
3432 ;; Possible store forwarding (partial memory) stall
3433 ;; in alternatives 4, 6, 7 and 8.
3434 (define_insn "*movxf_internal"
3435 [(set (match_operand:XF 0 "nonimmediate_operand"
3436 "=f,m,f,?r ,!o,?*r ,!o,!o,!o,r ,o ,o")
3437 (match_operand:XF 1 "general_operand"
3438 "fm,f,G,roF,r ,*roF,*r,F ,C ,roF,rF,rC"))]
3439 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3440 && (lra_in_progress || reload_completed
3441 || !CONST_DOUBLE_P (operands[1])
3442 || ((optimize_function_for_size_p (cfun)
3443 || (ix86_cmodel == CM_LARGE || ix86_cmodel == CM_LARGE_PIC))
3444 && standard_80387_constant_p (operands[1]) > 0
3445 && !memory_operand (operands[0], XFmode))
3446 || (!TARGET_MEMORY_MISMATCH_STALL
3447 && memory_operand (operands[0], XFmode))
3448 || !TARGET_HARD_XF_REGS)"
3450 switch (get_attr_type (insn))
3453 if (which_alternative == 2)
3454 return standard_80387_constant_opcode (operands[1]);
3455 return output_387_reg_move (insn, operands);
3465 (cond [(eq_attr "alternative" "7,10")
3466 (const_string "nox64")
3467 (eq_attr "alternative" "8,11")
3468 (const_string "x64")
3470 (const_string "*")))
3472 (cond [(eq_attr "alternative" "3,4,5,6,7,8,9,10,11")
3473 (const_string "multi")
3475 (const_string "fmov")))
3477 (cond [(eq_attr "alternative" "3,4,5,6,7,8,9,10,11")
3478 (if_then_else (match_test "TARGET_64BIT")
3480 (const_string "SI"))
3482 (const_string "XF")))
3483 (set (attr "preferred_for_size")
3484 (cond [(eq_attr "alternative" "3,4")
3485 (symbol_ref "false")]
3486 (symbol_ref "true")))
3487 (set (attr "enabled")
3488 (cond [(eq_attr "alternative" "9,10,11")
3490 (match_test "TARGET_HARD_XF_REGS")
3491 (symbol_ref "false")
3493 (not (match_test "TARGET_HARD_XF_REGS"))
3494 (symbol_ref "false")
3496 (const_string "*")))])
3499 [(set (match_operand:XF 0 "nonimmediate_gr_operand")
3500 (match_operand:XF 1 "general_gr_operand"))]
3503 "ix86_split_long_move (operands); DONE;")
3505 ;; Possible store forwarding (partial memory) stall in alternatives 4, 6 and 7.
3506 (define_insn "*movdf_internal"
3507 [(set (match_operand:DF 0 "nonimmediate_operand"
3508 "=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")
3509 (match_operand:DF 1 "general_operand"
3510 "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"))]
3511 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3512 && (lra_in_progress || reload_completed
3513 || !CONST_DOUBLE_P (operands[1])
3514 || ((optimize_function_for_size_p (cfun)
3515 || (ix86_cmodel == CM_LARGE || ix86_cmodel == CM_LARGE_PIC))
3516 && ((IS_STACK_MODE (DFmode)
3517 && standard_80387_constant_p (operands[1]) > 0)
3518 || (TARGET_SSE2 && TARGET_SSE_MATH
3519 && standard_sse_constant_p (operands[1], DFmode) == 1))
3520 && !memory_operand (operands[0], DFmode))
3521 || ((TARGET_64BIT || !TARGET_MEMORY_MISMATCH_STALL)
3522 && memory_operand (operands[0], DFmode))
3523 || !TARGET_HARD_DF_REGS)"
3525 switch (get_attr_type (insn))
3528 if (which_alternative == 2)
3529 return standard_80387_constant_opcode (operands[1]);
3530 return output_387_reg_move (insn, operands);
3536 if (get_attr_mode (insn) == MODE_SI)
3537 return "mov{l}\t{%1, %k0|%k0, %1}";
3538 else if (which_alternative == 11)
3539 return "movabs{q}\t{%1, %0|%0, %1}";
3541 return "mov{q}\t{%1, %0|%0, %1}";
3544 return standard_sse_constant_opcode (insn, operands);
3547 switch (get_attr_mode (insn))
3550 if (TARGET_AVX && REG_P (operands[0]) && REG_P (operands[1]))
3551 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
3552 return "%vmovsd\t{%1, %0|%0, %1}";
3555 return "%vmovaps\t{%1, %0|%0, %1}";
3557 return "vmovapd\t{%g1, %g0|%g0, %g1}";
3559 return "%vmovapd\t{%1, %0|%0, %1}";
3562 gcc_assert (!TARGET_AVX);
3563 return "movlps\t{%1, %0|%0, %1}";
3565 gcc_assert (!TARGET_AVX);
3566 return "movlpd\t{%1, %0|%0, %1}";
3569 /* Handle broken assemblers that require movd instead of movq. */
3570 if (!HAVE_AS_IX86_INTERUNIT_MOVQ
3571 && (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1])))
3572 return "%vmovd\t{%1, %0|%0, %1}";
3573 return "%vmovq\t{%1, %0|%0, %1}";
3584 (cond [(eq_attr "alternative" "3,4,5,6,7,22,23")
3585 (const_string "nox64")
3586 (eq_attr "alternative" "8,9,10,11,24,25")
3587 (const_string "x64")
3588 (eq_attr "alternative" "12,13,14,15")
3589 (const_string "sse2")
3590 (eq_attr "alternative" "20,21")
3591 (const_string "x64_sse2")
3593 (const_string "*")))
3595 (cond [(eq_attr "alternative" "0,1,2")
3596 (const_string "fmov")
3597 (eq_attr "alternative" "3,4,5,6,7,22,23")
3598 (const_string "multi")
3599 (eq_attr "alternative" "8,9,10,11,24,25")
3600 (const_string "imov")
3601 (eq_attr "alternative" "12,16")
3602 (const_string "sselog1")
3604 (const_string "ssemov")))
3606 (if_then_else (eq_attr "alternative" "11")
3608 (const_string "*")))
3609 (set (attr "length_immediate")
3610 (if_then_else (eq_attr "alternative" "11")
3612 (const_string "*")))
3613 (set (attr "prefix")
3614 (if_then_else (eq_attr "type" "sselog1,ssemov")
3615 (const_string "maybe_vex")
3616 (const_string "orig")))
3617 (set (attr "prefix_data16")
3619 (ior (and (eq_attr "type" "ssemov") (eq_attr "mode" "DI"))
3620 (eq_attr "mode" "V1DF"))
3622 (const_string "*")))
3624 (cond [(eq_attr "alternative" "3,4,5,6,7,10,22,23")
3626 (eq_attr "alternative" "8,9,11,20,21,24,25")
3629 /* xorps is one byte shorter for non-AVX targets. */
3630 (eq_attr "alternative" "12,16")
3631 (cond [(not (match_test "TARGET_SSE2"))
3632 (const_string "V4SF")
3633 (and (match_test "TARGET_AVX512F")
3634 (not (match_test "TARGET_PREFER_AVX256")))
3636 (match_test "TARGET_AVX")
3637 (const_string "V2DF")
3638 (match_test "optimize_function_for_size_p (cfun)")
3639 (const_string "V4SF")
3640 (match_test "TARGET_SSE_LOAD0_BY_PXOR")
3643 (const_string "V2DF"))
3645 /* For architectures resolving dependencies on
3646 whole SSE registers use movapd to break dependency
3647 chains, otherwise use short move to avoid extra work. */
3649 /* movaps is one byte shorter for non-AVX targets. */
3650 (eq_attr "alternative" "13,17")
3651 (cond [(and (ior (not (match_test "TARGET_PREFER_AVX256"))
3652 (not (match_test "TARGET_AVX512VL")))
3653 (ior (match_operand 0 "ext_sse_reg_operand")
3654 (match_operand 1 "ext_sse_reg_operand")))
3655 (const_string "V8DF")
3656 (ior (not (match_test "TARGET_SSE2"))
3657 (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL"))
3658 (const_string "V4SF")
3659 (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3660 (const_string "V2DF")
3661 (match_test "TARGET_AVX")
3663 (match_test "optimize_function_for_size_p (cfun)")
3664 (const_string "V4SF")
3666 (const_string "DF"))
3668 /* For architectures resolving dependencies on register
3669 parts we may avoid extra work to zero out upper part
3671 (eq_attr "alternative" "14,18")
3672 (cond [(not (match_test "TARGET_SSE2"))
3673 (const_string "V2SF")
3674 (match_test "TARGET_AVX")
3676 (match_test "TARGET_SSE_SPLIT_REGS")
3677 (const_string "V1DF")
3679 (const_string "DF"))
3681 (and (eq_attr "alternative" "15,19")
3682 (not (match_test "TARGET_SSE2")))
3683 (const_string "V2SF")
3685 (const_string "DF")))
3686 (set (attr "preferred_for_size")
3687 (cond [(eq_attr "alternative" "3,4")
3688 (symbol_ref "false")]
3689 (symbol_ref "true")))
3690 (set (attr "preferred_for_speed")
3691 (cond [(eq_attr "alternative" "3,4")
3692 (symbol_ref "TARGET_INTEGER_DFMODE_MOVES")
3693 (eq_attr "alternative" "20")
3694 (symbol_ref "TARGET_INTER_UNIT_MOVES_FROM_VEC")
3695 (eq_attr "alternative" "21")
3696 (symbol_ref "TARGET_INTER_UNIT_MOVES_TO_VEC")
3698 (symbol_ref "true")))
3699 (set (attr "enabled")
3700 (cond [(eq_attr "alternative" "22,23,24,25")
3702 (match_test "TARGET_HARD_DF_REGS")
3703 (symbol_ref "false")
3705 (not (match_test "TARGET_HARD_DF_REGS"))
3706 (symbol_ref "false")
3708 (const_string "*")))])
3711 [(set (match_operand:DF 0 "nonimmediate_gr_operand")
3712 (match_operand:DF 1 "general_gr_operand"))]
3713 "!TARGET_64BIT && reload_completed"
3715 "ix86_split_long_move (operands); DONE;")
3717 (define_insn "*movsf_internal"
3718 [(set (match_operand:SF 0 "nonimmediate_operand"
3719 "=Yf*f,m ,Yf*f,?r ,?m,v,v,v,m,?r,?v,!*y,!*y,!m,!r,!*y,r ,m")
3720 (match_operand:SF 1 "general_operand"
3721 "Yf*fm,Yf*f,G ,rmF,rF,C,v,m,v,v ,r ,*y ,m ,*y,*y,r ,rmF,rF"))]
3722 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3723 && (lra_in_progress || reload_completed
3724 || !CONST_DOUBLE_P (operands[1])
3725 || ((optimize_function_for_size_p (cfun)
3726 || (ix86_cmodel == CM_LARGE || ix86_cmodel == CM_LARGE_PIC))
3727 && ((IS_STACK_MODE (SFmode)
3728 && standard_80387_constant_p (operands[1]) > 0)
3729 || (TARGET_SSE && TARGET_SSE_MATH
3730 && standard_sse_constant_p (operands[1], SFmode) == 1)))
3731 || memory_operand (operands[0], SFmode)
3732 || !TARGET_HARD_SF_REGS)"
3734 switch (get_attr_type (insn))
3737 if (which_alternative == 2)
3738 return standard_80387_constant_opcode (operands[1]);
3739 return output_387_reg_move (insn, operands);
3742 return "mov{l}\t{%1, %0|%0, %1}";
3745 return standard_sse_constant_opcode (insn, operands);
3748 switch (get_attr_mode (insn))
3751 if (TARGET_AVX && REG_P (operands[0]) && REG_P (operands[1]))
3752 return "vmovss\t{%1, %0, %0|%0, %0, %1}";
3753 return "%vmovss\t{%1, %0|%0, %1}";
3756 return "vmovaps\t{%g1, %g0|%g0, %g1}";
3758 return "%vmovaps\t{%1, %0|%0, %1}";
3761 return "%vmovd\t{%1, %0|%0, %1}";
3768 switch (get_attr_mode (insn))
3771 return "movq\t{%1, %0|%0, %1}";
3773 return "movd\t{%1, %0|%0, %1}";
3784 (cond [(eq_attr "alternative" "14,15")
3785 (const_string "sse2")
3787 (const_string "*")))
3789 (cond [(eq_attr "alternative" "0,1,2")
3790 (const_string "fmov")
3791 (eq_attr "alternative" "3,4,16,17")
3792 (const_string "imov")
3793 (eq_attr "alternative" "5")
3794 (const_string "sselog1")
3795 (eq_attr "alternative" "11,12,13,14,15")
3796 (const_string "mmxmov")
3798 (const_string "ssemov")))
3799 (set (attr "prefix")
3800 (if_then_else (eq_attr "type" "sselog1,ssemov")
3801 (const_string "maybe_vex")
3802 (const_string "orig")))
3803 (set (attr "prefix_data16")
3804 (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
3806 (const_string "*")))
3808 (cond [(eq_attr "alternative" "3,4,9,10,12,13,14,15,16,17")
3810 (eq_attr "alternative" "11")
3812 (eq_attr "alternative" "5")
3813 (cond [(not (match_test "TARGET_SSE2"))
3814 (const_string "V4SF")
3815 (and (match_test "TARGET_AVX512F")
3816 (not (match_test "TARGET_PREFER_AVX256")))
3817 (const_string "V16SF")
3818 (match_test "TARGET_AVX")
3819 (const_string "V4SF")
3820 (match_test "optimize_function_for_size_p (cfun)")
3821 (const_string "V4SF")
3822 (match_test "TARGET_SSE_LOAD0_BY_PXOR")
3825 (const_string "V4SF"))
3827 /* For architectures resolving dependencies on
3828 whole SSE registers use APS move to break dependency
3829 chains, otherwise use short move to avoid extra work.
3831 Do the same for architectures resolving dependencies on
3832 the parts. While in DF mode it is better to always handle
3833 just register parts, the SF mode is different due to lack
3834 of instructions to load just part of the register. It is
3835 better to maintain the whole registers in single format
3836 to avoid problems on using packed logical operations. */
3837 (eq_attr "alternative" "6")
3838 (cond [(and (ior (not (match_test "TARGET_PREFER_AVX256"))
3839 (not (match_test "TARGET_AVX512VL")))
3840 (ior (match_operand 0 "ext_sse_reg_operand")
3841 (match_operand 1 "ext_sse_reg_operand")))
3842 (const_string "V16SF")
3843 (ior (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3844 (match_test "TARGET_SSE_SPLIT_REGS"))
3845 (const_string "V4SF")
3847 (const_string "SF"))
3849 (const_string "SF")))
3850 (set (attr "preferred_for_speed")
3851 (cond [(eq_attr "alternative" "9,14")
3852 (symbol_ref "TARGET_INTER_UNIT_MOVES_FROM_VEC")
3853 (eq_attr "alternative" "10,15")
3854 (symbol_ref "TARGET_INTER_UNIT_MOVES_TO_VEC")
3856 (symbol_ref "true")))
3857 (set (attr "enabled")
3858 (cond [(eq_attr "alternative" "16,17")
3860 (match_test "TARGET_HARD_SF_REGS")
3861 (symbol_ref "false")
3863 (not (match_test "TARGET_HARD_SF_REGS"))
3864 (symbol_ref "false")
3866 (const_string "*")))])
3869 [(set (match_operand 0 "any_fp_register_operand")
3870 (match_operand 1 "nonimmediate_operand"))]
3872 && (GET_MODE (operands[0]) == TFmode
3873 || GET_MODE (operands[0]) == XFmode
3874 || GET_MODE (operands[0]) == DFmode
3875 || GET_MODE (operands[0]) == SFmode)
3876 && ix86_standard_x87sse_constant_load_p (insn, operands[0])"
3877 [(set (match_dup 0) (match_dup 2))]
3878 "operands[2] = find_constant_src (curr_insn);")
3881 [(set (match_operand 0 "any_fp_register_operand")
3882 (float_extend (match_operand 1 "nonimmediate_operand")))]
3884 && (GET_MODE (operands[0]) == TFmode
3885 || GET_MODE (operands[0]) == XFmode
3886 || GET_MODE (operands[0]) == DFmode)
3887 && ix86_standard_x87sse_constant_load_p (insn, operands[0])"
3888 [(set (match_dup 0) (match_dup 2))]
3889 "operands[2] = find_constant_src (curr_insn);")
3891 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
3893 [(set (match_operand:X87MODEF 0 "fp_register_operand")
3894 (match_operand:X87MODEF 1 "immediate_operand"))]
3896 && (standard_80387_constant_p (operands[1]) == 8
3897 || standard_80387_constant_p (operands[1]) == 9)"
3898 [(set (match_dup 0)(match_dup 1))
3900 (neg:X87MODEF (match_dup 0)))]
3902 if (real_isnegzero (CONST_DOUBLE_REAL_VALUE (operands[1])))
3903 operands[1] = CONST0_RTX (<MODE>mode);
3905 operands[1] = CONST1_RTX (<MODE>mode);
3908 (define_insn "swapxf"
3909 [(set (match_operand:XF 0 "register_operand" "+f")
3910 (match_operand:XF 1 "register_operand" "+f"))
3915 if (STACK_TOP_P (operands[0]))
3920 [(set_attr "type" "fxch")
3921 (set_attr "mode" "XF")])
3923 (define_insn "*swap<mode>"
3924 [(set (match_operand:MODEF 0 "fp_register_operand" "+f")
3925 (match_operand:MODEF 1 "fp_register_operand" "+f"))
3928 "TARGET_80387 || reload_completed"
3930 if (STACK_TOP_P (operands[0]))
3935 [(set_attr "type" "fxch")
3936 (set_attr "mode" "<MODE>")])
3938 ;; Zero extension instructions
3940 (define_expand "zero_extendsidi2"
3941 [(set (match_operand:DI 0 "nonimmediate_operand")
3942 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand")))])
3944 (define_insn "*zero_extendsidi2"
3945 [(set (match_operand:DI 0 "nonimmediate_operand"
3946 "=r,?r,?o,r ,o,?*y,?!*y,$r,$v,$x,*x,*v,*r")
3948 (match_operand:SI 1 "x86_64_zext_operand"
3949 "0 ,rm,r ,rmWz,0,r ,m ,v ,r ,m ,*x,*v,*k")))]
3952 switch (get_attr_type (insn))
3955 if (ix86_use_lea_for_mov (insn, operands))
3956 return "lea{l}\t{%E1, %k0|%k0, %E1}";
3958 return "mov{l}\t{%1, %k0|%k0, %1}";
3964 return "movd\t{%1, %0|%0, %1}";
3967 if (SSE_REG_P (operands[0]) && SSE_REG_P (operands[1]))
3969 if (EXT_REX_SSE_REG_P (operands[0])
3970 || EXT_REX_SSE_REG_P (operands[1]))
3971 return "vpmovzxdq\t{%t1, %g0|%g0, %t1}";
3973 return "%vpmovzxdq\t{%1, %0|%0, %1}";
3976 if (GENERAL_REG_P (operands[0]))
3977 return "%vmovd\t{%1, %k0|%k0, %1}";
3979 return "%vmovd\t{%1, %0|%0, %1}";
3982 return "kmovd\t{%1, %k0|%k0, %1}";
3989 (cond [(eq_attr "alternative" "0,1,2")
3990 (const_string "nox64")
3991 (eq_attr "alternative" "3")
3992 (const_string "x64")
3993 (eq_attr "alternative" "7,8,9")
3994 (const_string "sse2")
3995 (eq_attr "alternative" "10")
3996 (const_string "sse4")
3997 (eq_attr "alternative" "11")
3998 (const_string "avx512f")
3999 (eq_attr "alternative" "12")
4000 (const_string "x64_avx512bw")
4002 (const_string "*")))
4004 (cond [(eq_attr "alternative" "0,1,2,4")
4005 (const_string "multi")
4006 (eq_attr "alternative" "5,6")
4007 (const_string "mmxmov")
4008 (eq_attr "alternative" "7")
4009 (if_then_else (match_test "TARGET_64BIT")
4010 (const_string "ssemov")
4011 (const_string "multi"))
4012 (eq_attr "alternative" "8,9,10,11")
4013 (const_string "ssemov")
4014 (eq_attr "alternative" "12")
4015 (const_string "mskmov")
4017 (const_string "imovx")))
4018 (set (attr "prefix_extra")
4019 (if_then_else (eq_attr "alternative" "10,11")
4021 (const_string "*")))
4022 (set (attr "prefix")
4023 (if_then_else (eq_attr "type" "ssemov")
4024 (const_string "maybe_vex")
4025 (const_string "orig")))
4026 (set (attr "prefix_0f")
4027 (if_then_else (eq_attr "type" "imovx")
4029 (const_string "*")))
4031 (cond [(eq_attr "alternative" "5,6")
4033 (and (eq_attr "alternative" "7")
4034 (match_test "TARGET_64BIT"))
4036 (eq_attr "alternative" "8,10,11")
4039 (const_string "SI")))
4040 (set (attr "preferred_for_speed")
4041 (cond [(eq_attr "alternative" "7")
4042 (symbol_ref "TARGET_INTER_UNIT_MOVES_FROM_VEC")
4043 (eq_attr "alternative" "5,8")
4044 (symbol_ref "TARGET_INTER_UNIT_MOVES_TO_VEC")
4046 (symbol_ref "true")))])
4049 [(set (match_operand:DI 0 "memory_operand")
4050 (zero_extend:DI (match_operand:SI 1 "memory_operand")))]
4052 [(set (match_dup 4) (const_int 0))]
4053 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
4056 [(set (match_operand:DI 0 "general_reg_operand")
4057 (zero_extend:DI (match_operand:SI 1 "general_reg_operand")))]
4058 "!TARGET_64BIT && reload_completed
4059 && REGNO (operands[0]) == REGNO (operands[1])"
4060 [(set (match_dup 4) (const_int 0))]
4061 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
4064 [(set (match_operand:DI 0 "nonimmediate_gr_operand")
4065 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand")))]
4066 "!TARGET_64BIT && reload_completed
4067 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
4068 [(set (match_dup 3) (match_dup 1))
4069 (set (match_dup 4) (const_int 0))]
4070 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
4072 (define_mode_attr kmov_isa
4073 [(QI "avx512dq") (HI "avx512f") (SI "avx512bw") (DI "avx512bw")])
4075 (define_insn "zero_extend<mode>di2"
4076 [(set (match_operand:DI 0 "register_operand" "=r,*r")
4078 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m,*k")))]
4081 movz{<imodesuffix>l|x}\t{%1, %k0|%k0, %1}
4082 kmov<mskmodesuffix>\t{%1, %k0|%k0, %1}"
4083 [(set_attr "isa" "*,<kmov_isa>")
4084 (set_attr "type" "imovx,mskmov")
4085 (set_attr "mode" "SI,<MODE>")])
4087 (define_expand "zero_extend<mode>si2"
4088 [(set (match_operand:SI 0 "register_operand")
4089 (zero_extend:SI (match_operand:SWI12 1 "nonimmediate_operand")))]
4092 if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
4094 operands[1] = force_reg (<MODE>mode, operands[1]);
4095 emit_insn (gen_zero_extend<mode>si2_and (operands[0], operands[1]));
4100 (define_insn_and_split "zero_extend<mode>si2_and"
4101 [(set (match_operand:SI 0 "register_operand" "=r,?&<r>")
4103 (match_operand:SWI12 1 "nonimmediate_operand" "0,<r>m")))
4104 (clobber (reg:CC FLAGS_REG))]
4105 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
4107 "&& reload_completed"
4108 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (match_dup 2)))
4109 (clobber (reg:CC FLAGS_REG))])]
4111 if (!REG_P (operands[1])
4112 || REGNO (operands[0]) != REGNO (operands[1]))
4114 ix86_expand_clear (operands[0]);
4116 gcc_assert (!TARGET_PARTIAL_REG_STALL);
4117 emit_insn (gen_movstrict<mode>
4118 (gen_lowpart (<MODE>mode, operands[0]), operands[1]));
4122 operands[2] = GEN_INT (GET_MODE_MASK (<MODE>mode));
4124 [(set_attr "type" "alu1")
4125 (set_attr "mode" "SI")])
4127 (define_insn "*zero_extend<mode>si2"
4128 [(set (match_operand:SI 0 "register_operand" "=r,*r")
4130 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m,*k")))]
4131 "!(TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))"
4133 movz{<imodesuffix>l|x}\t{%1, %0|%0, %1}
4134 kmov<mskmodesuffix>\t{%1, %0|%0, %1}"
4135 [(set_attr "isa" "*,<kmov_isa>")
4136 (set_attr "type" "imovx,mskmov")
4137 (set_attr "mode" "SI,<MODE>")])
4139 (define_expand "zero_extendqihi2"
4140 [(set (match_operand:HI 0 "register_operand")
4141 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand")))]
4144 if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
4146 operands[1] = force_reg (QImode, operands[1]);
4147 emit_insn (gen_zero_extendqihi2_and (operands[0], operands[1]));
4152 (define_insn_and_split "zero_extendqihi2_and"
4153 [(set (match_operand:HI 0 "register_operand" "=r,?&q")
4154 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
4155 (clobber (reg:CC FLAGS_REG))]
4156 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
4158 "&& reload_completed"
4159 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
4160 (clobber (reg:CC FLAGS_REG))])]
4162 if (!REG_P (operands[1])
4163 || REGNO (operands[0]) != REGNO (operands[1]))
4165 ix86_expand_clear (operands[0]);
4167 gcc_assert (!TARGET_PARTIAL_REG_STALL);
4168 emit_insn (gen_movstrictqi
4169 (gen_lowpart (QImode, operands[0]), operands[1]));
4173 operands[0] = gen_lowpart (SImode, operands[0]);
4175 [(set_attr "type" "alu1")
4176 (set_attr "mode" "SI")])
4178 ; zero extend to SImode to avoid partial register stalls
4179 (define_insn "*zero_extendqihi2"
4180 [(set (match_operand:HI 0 "register_operand" "=r,*r")
4181 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,*k")))]
4182 "!(TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))"
4184 movz{bl|x}\t{%1, %k0|%k0, %1}
4185 kmovb\t{%1, %k0|%k0, %1}"
4186 [(set_attr "isa" "*,avx512dq")
4187 (set_attr "type" "imovx,mskmov")
4188 (set_attr "mode" "SI,QI")])
4190 (define_insn_and_split "*zext<mode>_doubleword_and"
4191 [(set (match_operand:DI 0 "register_operand" "=&<r>")
4192 (zero_extend:DI (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
4193 "!TARGET_64BIT && TARGET_STV && TARGET_SSE2
4194 && TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
4196 "&& reload_completed && GENERAL_REG_P (operands[0])"
4197 [(set (match_dup 2) (const_int 0))]
4199 split_double_mode (DImode, &operands[0], 1, &operands[0], &operands[2]);
4201 emit_move_insn (operands[0], const0_rtx);
4203 gcc_assert (!TARGET_PARTIAL_REG_STALL);
4204 emit_insn (gen_movstrict<mode>
4205 (gen_lowpart (<MODE>mode, operands[0]), operands[1]));
4208 (define_insn_and_split "*zext<mode>_doubleword"
4209 [(set (match_operand:DI 0 "register_operand" "=r")
4210 (zero_extend:DI (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
4211 "!TARGET_64BIT && TARGET_STV && TARGET_SSE2
4212 && !(TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))"
4214 "&& reload_completed && GENERAL_REG_P (operands[0])"
4215 [(set (match_dup 0) (zero_extend:SI (match_dup 1)))
4216 (set (match_dup 2) (const_int 0))]
4217 "split_double_mode (DImode, &operands[0], 1, &operands[0], &operands[2]);")
4219 (define_insn_and_split "*zextsi_doubleword"
4220 [(set (match_operand:DI 0 "register_operand" "=r")
4221 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm")))]
4222 "!TARGET_64BIT && TARGET_STV && TARGET_SSE2"
4224 "&& reload_completed && GENERAL_REG_P (operands[0])"
4225 [(set (match_dup 0) (match_dup 1))
4226 (set (match_dup 2) (const_int 0))]
4227 "split_double_mode (DImode, &operands[0], 1, &operands[0], &operands[2]);")
4229 ;; Sign extension instructions
4231 (define_expand "extendsidi2"
4232 [(set (match_operand:DI 0 "register_operand")
4233 (sign_extend:DI (match_operand:SI 1 "register_operand")))]
4238 emit_insn (gen_extendsidi2_1 (operands[0], operands[1]));
4243 (define_insn "*extendsidi2_rex64"
4244 [(set (match_operand:DI 0 "register_operand" "=*a,r")
4245 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
4249 movs{lq|x}\t{%1, %0|%0, %1}"
4250 [(set_attr "type" "imovx")
4251 (set_attr "mode" "DI")
4252 (set_attr "prefix_0f" "0")
4253 (set_attr "modrm" "0,1")])
4255 (define_insn "extendsidi2_1"
4256 [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
4257 (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
4258 (clobber (reg:CC FLAGS_REG))
4259 (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
4263 ;; Split the memory case. If the source register doesn't die, it will stay
4264 ;; this way, if it does die, following peephole2s take care of it.
4266 [(set (match_operand:DI 0 "memory_operand")
4267 (sign_extend:DI (match_operand:SI 1 "register_operand")))
4268 (clobber (reg:CC FLAGS_REG))
4269 (clobber (match_operand:SI 2 "register_operand"))]
4273 split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
4275 emit_move_insn (operands[3], operands[1]);
4277 /* Generate a cltd if possible and doing so it profitable. */
4278 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
4279 && REGNO (operands[1]) == AX_REG
4280 && REGNO (operands[2]) == DX_REG)
4282 emit_insn (gen_ashrsi3_cvt (operands[2], operands[1], GEN_INT (31)));
4286 emit_move_insn (operands[2], operands[1]);
4287 emit_insn (gen_ashrsi3_cvt (operands[2], operands[2], GEN_INT (31)));
4289 emit_move_insn (operands[4], operands[2]);
4293 ;; Peepholes for the case where the source register does die, after
4294 ;; being split with the above splitter.
4296 [(set (match_operand:SI 0 "memory_operand")
4297 (match_operand:SI 1 "general_reg_operand"))
4298 (set (match_operand:SI 2 "general_reg_operand") (match_dup 1))
4299 (parallel [(set (match_dup 2)
4300 (ashiftrt:SI (match_dup 2) (const_int 31)))
4301 (clobber (reg:CC FLAGS_REG))])
4302 (set (match_operand:SI 3 "memory_operand") (match_dup 2))]
4303 "REGNO (operands[1]) != REGNO (operands[2])
4304 && peep2_reg_dead_p (2, operands[1])
4305 && peep2_reg_dead_p (4, operands[2])
4306 && !reg_mentioned_p (operands[2], operands[3])"
4307 [(set (match_dup 0) (match_dup 1))
4308 (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
4309 (clobber (reg:CC FLAGS_REG))])
4310 (set (match_dup 3) (match_dup 1))])
4313 [(set (match_operand:SI 0 "memory_operand")
4314 (match_operand:SI 1 "general_reg_operand"))
4315 (parallel [(set (match_operand:SI 2 "general_reg_operand")
4316 (ashiftrt:SI (match_dup 1) (const_int 31)))
4317 (clobber (reg:CC FLAGS_REG))])
4318 (set (match_operand:SI 3 "memory_operand") (match_dup 2))]
4319 "/* cltd is shorter than sarl $31, %eax */
4320 !optimize_function_for_size_p (cfun)
4321 && REGNO (operands[1]) == AX_REG
4322 && REGNO (operands[2]) == DX_REG
4323 && peep2_reg_dead_p (2, operands[1])
4324 && peep2_reg_dead_p (3, operands[2])
4325 && !reg_mentioned_p (operands[2], operands[3])"
4326 [(set (match_dup 0) (match_dup 1))
4327 (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
4328 (clobber (reg:CC FLAGS_REG))])
4329 (set (match_dup 3) (match_dup 1))])
4331 ;; Extend to register case. Optimize case where source and destination
4332 ;; registers match and cases where we can use cltd.
4334 [(set (match_operand:DI 0 "register_operand")
4335 (sign_extend:DI (match_operand:SI 1 "register_operand")))
4336 (clobber (reg:CC FLAGS_REG))
4337 (clobber (match_scratch:SI 2))]
4341 split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
4343 if (REGNO (operands[3]) != REGNO (operands[1]))
4344 emit_move_insn (operands[3], operands[1]);
4346 /* Generate a cltd if possible and doing so it profitable. */
4347 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
4348 && REGNO (operands[3]) == AX_REG
4349 && REGNO (operands[4]) == DX_REG)
4351 emit_insn (gen_ashrsi3_cvt (operands[4], operands[3], GEN_INT (31)));
4355 if (REGNO (operands[4]) != REGNO (operands[1]))
4356 emit_move_insn (operands[4], operands[1]);
4358 emit_insn (gen_ashrsi3_cvt (operands[4], operands[4], GEN_INT (31)));
4362 (define_insn "extend<mode>di2"
4363 [(set (match_operand:DI 0 "register_operand" "=r")
4365 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
4367 "movs{<imodesuffix>q|x}\t{%1, %0|%0, %1}"
4368 [(set_attr "type" "imovx")
4369 (set_attr "mode" "DI")])
4371 (define_insn "extendhisi2"
4372 [(set (match_operand:SI 0 "register_operand" "=*a,r")
4373 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
4376 switch (get_attr_prefix_0f (insn))
4379 return "{cwtl|cwde}";
4381 return "movs{wl|x}\t{%1, %0|%0, %1}";
4384 [(set_attr "type" "imovx")
4385 (set_attr "mode" "SI")
4386 (set (attr "prefix_0f")
4387 ;; movsx is short decodable while cwtl is vector decoded.
4388 (if_then_else (and (eq_attr "cpu" "!k6")
4389 (eq_attr "alternative" "0"))
4391 (const_string "1")))
4392 (set (attr "znver1_decode")
4393 (if_then_else (eq_attr "prefix_0f" "0")
4394 (const_string "double")
4395 (const_string "direct")))
4397 (if_then_else (eq_attr "prefix_0f" "0")
4399 (const_string "1")))])
4401 (define_insn "*extendhisi2_zext"
4402 [(set (match_operand:DI 0 "register_operand" "=*a,r")
4405 (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
4408 switch (get_attr_prefix_0f (insn))
4411 return "{cwtl|cwde}";
4413 return "movs{wl|x}\t{%1, %k0|%k0, %1}";
4416 [(set_attr "type" "imovx")
4417 (set_attr "mode" "SI")
4418 (set (attr "prefix_0f")
4419 ;; movsx is short decodable while cwtl is vector decoded.
4420 (if_then_else (and (eq_attr "cpu" "!k6")
4421 (eq_attr "alternative" "0"))
4423 (const_string "1")))
4425 (if_then_else (eq_attr "prefix_0f" "0")
4427 (const_string "1")))])
4429 (define_insn "extendqisi2"
4430 [(set (match_operand:SI 0 "register_operand" "=r")
4431 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
4433 "movs{bl|x}\t{%1, %0|%0, %1}"
4434 [(set_attr "type" "imovx")
4435 (set_attr "mode" "SI")])
4437 (define_insn "*extendqisi2_zext"
4438 [(set (match_operand:DI 0 "register_operand" "=r")
4440 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
4442 "movs{bl|x}\t{%1, %k0|%k0, %1}"
4443 [(set_attr "type" "imovx")
4444 (set_attr "mode" "SI")])
4446 (define_insn "extendqihi2"
4447 [(set (match_operand:HI 0 "register_operand" "=*a,r")
4448 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
4451 switch (get_attr_prefix_0f (insn))
4454 return "{cbtw|cbw}";
4456 return "movs{bw|x}\t{%1, %0|%0, %1}";
4459 [(set_attr "type" "imovx")
4460 (set_attr "mode" "HI")
4461 (set (attr "prefix_0f")
4462 ;; movsx is short decodable while cwtl is vector decoded.
4463 (if_then_else (and (eq_attr "cpu" "!k6")
4464 (eq_attr "alternative" "0"))
4466 (const_string "1")))
4468 (if_then_else (eq_attr "prefix_0f" "0")
4470 (const_string "1")))])
4472 ;; Conversions between float and double.
4474 ;; These are all no-ops in the model used for the 80387.
4475 ;; So just emit moves.
4477 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
4479 [(set (match_operand:DF 0 "push_operand")
4480 (float_extend:DF (match_operand:SF 1 "fp_register_operand")))]
4482 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
4483 (set (mem:DF (reg:P SP_REG)) (float_extend:DF (match_dup 1)))])
4486 [(set (match_operand:XF 0 "push_operand")
4487 (float_extend:XF (match_operand:MODEF 1 "fp_register_operand")))]
4489 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
4490 (set (mem:XF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
4491 "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
4493 (define_expand "extendsfdf2"
4494 [(set (match_operand:DF 0 "nonimm_ssenomem_operand")
4495 (float_extend:DF (match_operand:SF 1 "general_operand")))]
4496 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4498 /* ??? Needed for compress_float_constant since all fp constants
4499 are TARGET_LEGITIMATE_CONSTANT_P. */
4500 if (CONST_DOUBLE_P (operands[1]))
4502 if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
4503 && standard_80387_constant_p (operands[1]) > 0)
4505 operands[1] = simplify_const_unary_operation
4506 (FLOAT_EXTEND, DFmode, operands[1], SFmode);
4507 emit_move_insn_1 (operands[0], operands[1]);
4510 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
4514 /* For converting SF(xmm2) to DF(xmm1), use the following code instead of
4516 unpcklps xmm2,xmm2 ; packed conversion might crash on signaling NaNs
4518 We do the conversion post reload to avoid producing of 128bit spills
4519 that might lead to ICE on 32bit target. The sequence unlikely combine
4522 [(set (match_operand:DF 0 "sse_reg_operand")
4524 (match_operand:SF 1 "nonimmediate_operand")))]
4525 "TARGET_USE_VECTOR_FP_CONVERTS
4526 && optimize_insn_for_speed_p ()
4528 && (!EXT_REX_SSE_REG_P (operands[0])
4529 || TARGET_AVX512VL)"
4534 (parallel [(const_int 0) (const_int 1)]))))]
4536 operands[2] = lowpart_subreg (V2DFmode, operands[0], DFmode);
4537 operands[3] = lowpart_subreg (V4SFmode, operands[0], DFmode);
4538 /* Use movss for loading from memory, unpcklps reg, reg for registers.
4539 Try to avoid move when unpacking can be done in source. */
4540 if (REG_P (operands[1]))
4542 /* If it is unsafe to overwrite upper half of source, we need
4543 to move to destination and unpack there. */
4544 if (REGNO (operands[0]) != REGNO (operands[1])
4545 || (EXT_REX_SSE_REG_P (operands[1])
4546 && !TARGET_AVX512VL))
4548 rtx tmp = lowpart_subreg (SFmode, operands[0], DFmode);
4549 emit_move_insn (tmp, operands[1]);
4552 operands[3] = lowpart_subreg (V4SFmode, operands[1], SFmode);
4553 /* FIXME: vec_interleave_lowv4sf for AVX512VL should allow
4554 =v, v, then vbroadcastss will be only needed for AVX512F without
4556 if (!EXT_REX_SSE_REGNO_P (REGNO (operands[3])))
4557 emit_insn (gen_vec_interleave_lowv4sf (operands[3], operands[3],
4561 rtx tmp = lowpart_subreg (V16SFmode, operands[3], V4SFmode);
4562 emit_insn (gen_avx512f_vec_dupv16sf_1 (tmp, tmp));
4566 emit_insn (gen_vec_setv4sf_0 (operands[3],
4567 CONST0_RTX (V4SFmode), operands[1]));
4570 ;; It's more profitable to split and then extend in the same register.
4572 [(set (match_operand:DF 0 "sse_reg_operand")
4574 (match_operand:SF 1 "memory_operand")))]
4575 "TARGET_SPLIT_MEM_OPND_FOR_FP_CONVERTS
4576 && optimize_insn_for_speed_p ()"
4577 [(set (match_dup 2) (match_dup 1))
4578 (set (match_dup 0) (float_extend:DF (match_dup 2)))]
4579 "operands[2] = lowpart_subreg (SFmode, operands[0], DFmode);")
4581 (define_insn "*extendsfdf2"
4582 [(set (match_operand:DF 0 "nonimm_ssenomem_operand" "=f,m,v")
4584 (match_operand:SF 1 "nonimmediate_operand" "fm,f,vm")))]
4585 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4587 switch (which_alternative)
4591 return output_387_reg_move (insn, operands);
4594 return "%vcvtss2sd\t{%1, %d0|%d0, %1}";
4600 [(set_attr "type" "fmov,fmov,ssecvt")
4601 (set_attr "prefix" "orig,orig,maybe_vex")
4602 (set_attr "mode" "SF,XF,DF")
4603 (set (attr "enabled")
4605 (match_test ("TARGET_SSE2 && TARGET_SSE_MATH"))
4607 (eq_attr "alternative" "0,1")
4608 (symbol_ref "TARGET_MIX_SSE_I387")
4609 (symbol_ref "true"))
4611 (eq_attr "alternative" "0,1")
4613 (symbol_ref "false"))))])
4615 (define_expand "extend<mode>xf2"
4616 [(set (match_operand:XF 0 "nonimmediate_operand")
4617 (float_extend:XF (match_operand:MODEF 1 "general_operand")))]
4620 /* ??? Needed for compress_float_constant since all fp constants
4621 are TARGET_LEGITIMATE_CONSTANT_P. */
4622 if (CONST_DOUBLE_P (operands[1]))
4624 if (standard_80387_constant_p (operands[1]) > 0)
4626 operands[1] = simplify_const_unary_operation
4627 (FLOAT_EXTEND, XFmode, operands[1], <MODE>mode);
4628 emit_move_insn_1 (operands[0], operands[1]);
4631 operands[1] = validize_mem (force_const_mem (<MODE>mode, operands[1]));
4635 (define_insn "*extend<mode>xf2_i387"
4636 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
4638 (match_operand:MODEF 1 "nonimmediate_operand" "fm,f")))]
4640 "* return output_387_reg_move (insn, operands);"
4641 [(set_attr "type" "fmov")
4642 (set_attr "mode" "<MODE>,XF")])
4644 ;; %%% This seems like bad news.
4645 ;; This cannot output into an f-reg because there is no way to be sure
4646 ;; of truncating in that case. Otherwise this is just like a simple move
4647 ;; insn. So we pretend we can output to a reg in order to get better
4648 ;; register preferencing, but we really use a stack slot.
4650 ;; Conversion from DFmode to SFmode.
4652 (define_expand "truncdfsf2"
4653 [(set (match_operand:SF 0 "nonimmediate_operand")
4655 (match_operand:DF 1 "nonimmediate_operand")))]
4656 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4658 if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
4660 else if (flag_unsafe_math_optimizations)
4664 rtx temp = assign_386_stack_local (SFmode, SLOT_TEMP);
4665 emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
4670 /* For converting DF(xmm2) to SF(xmm1), use the following code instead of
4672 unpcklpd xmm2,xmm2 ; packed conversion might crash on signaling NaNs
4674 We do the conversion post reload to avoid producing of 128bit spills
4675 that might lead to ICE on 32bit target. The sequence unlikely combine
4678 [(set (match_operand:SF 0 "sse_reg_operand")
4680 (match_operand:DF 1 "nonimmediate_operand")))]
4681 "TARGET_USE_VECTOR_FP_CONVERTS
4682 && optimize_insn_for_speed_p ()
4684 && (!EXT_REX_SSE_REG_P (operands[0])
4685 || TARGET_AVX512VL)"
4688 (float_truncate:V2SF
4692 operands[2] = lowpart_subreg (V4SFmode, operands[0], SFmode);
4693 operands[3] = CONST0_RTX (V2SFmode);
4694 operands[4] = lowpart_subreg (V2DFmode, operands[0], SFmode);
4695 /* Use movsd for loading from memory, unpcklpd for registers.
4696 Try to avoid move when unpacking can be done in source, or SSE3
4697 movddup is available. */
4698 if (REG_P (operands[1]))
4701 && REGNO (operands[0]) != REGNO (operands[1]))
4703 rtx tmp = lowpart_subreg (DFmode, operands[0], SFmode);
4704 emit_move_insn (tmp, operands[1]);
4707 else if (!TARGET_SSE3)
4708 operands[4] = lowpart_subreg (V2DFmode, operands[1], DFmode);
4709 emit_insn (gen_vec_dupv2df (operands[4], operands[1]));
4712 emit_insn (gen_vec_concatv2df (operands[4], operands[1],
4713 CONST0_RTX (DFmode)));
4716 ;; It's more profitable to split and then extend in the same register.
4718 [(set (match_operand:SF 0 "sse_reg_operand")
4720 (match_operand:DF 1 "memory_operand")))]
4721 "TARGET_SPLIT_MEM_OPND_FOR_FP_CONVERTS
4722 && optimize_insn_for_speed_p ()"
4723 [(set (match_dup 2) (match_dup 1))
4724 (set (match_dup 0) (float_truncate:SF (match_dup 2)))]
4725 "operands[2] = lowpart_subreg (DFmode, operands[0], SFmode);")
4727 (define_expand "truncdfsf2_with_temp"
4728 [(parallel [(set (match_operand:SF 0)
4729 (float_truncate:SF (match_operand:DF 1)))
4730 (clobber (match_operand:SF 2))])])
4732 ;; SSE alternative doesn't depend on flag_unsafe_math_optimizations,
4733 ;; because nothing we do there is unsafe.
4734 (define_insn "*truncdfsf_fast_mixed"
4735 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm,v")
4737 (match_operand:DF 1 "nonimmediate_operand" "f ,vm")))]
4738 "TARGET_SSE2 && TARGET_SSE_MATH"
4740 switch (which_alternative)
4743 return output_387_reg_move (insn, operands);
4745 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4750 [(set_attr "type" "fmov,ssecvt")
4751 (set_attr "prefix" "orig,maybe_vex")
4752 (set_attr "mode" "SF")
4753 (set (attr "enabled")
4754 (cond [(eq_attr "alternative" "0")
4755 (symbol_ref "TARGET_MIX_SSE_I387
4756 && flag_unsafe_math_optimizations")
4758 (symbol_ref "true")))])
4760 (define_insn "*truncdfsf_fast_i387"
4761 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm")
4763 (match_operand:DF 1 "nonimmediate_operand" "f")))]
4764 "TARGET_80387 && flag_unsafe_math_optimizations"
4765 "* return output_387_reg_move (insn, operands);"
4766 [(set_attr "type" "fmov")
4767 (set_attr "mode" "SF")])
4769 (define_insn "*truncdfsf_mixed"
4770 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,v ,?f,?v,?*r")
4772 (match_operand:DF 1 "nonimmediate_operand" "f ,vm,f ,f ,f")))
4773 (clobber (match_operand:SF 2 "memory_operand" "=X,X ,m ,m ,m"))]
4774 "TARGET_MIX_SSE_I387"
4776 switch (which_alternative)
4779 return output_387_reg_move (insn, operands);
4781 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4787 [(set_attr "isa" "*,sse2,*,*,*")
4788 (set_attr "type" "fmov,ssecvt,multi,multi,multi")
4789 (set_attr "unit" "*,*,i387,i387,i387")
4790 (set_attr "prefix" "orig,maybe_vex,orig,orig,orig")
4791 (set_attr "mode" "SF")])
4793 (define_insn "*truncdfsf_i387"
4794 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?v,?*r")
4796 (match_operand:DF 1 "nonimmediate_operand" "f ,f ,f ,f")))
4797 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,m ,m"))]
4800 switch (which_alternative)
4803 return output_387_reg_move (insn, operands);
4809 [(set_attr "type" "fmov,multi,multi,multi")
4810 (set_attr "unit" "*,i387,i387,i387")
4811 (set_attr "mode" "SF")])
4813 (define_insn "*truncdfsf2_i387_1"
4814 [(set (match_operand:SF 0 "memory_operand" "=m")
4816 (match_operand:DF 1 "register_operand" "f")))]
4818 && !(TARGET_SSE2 && TARGET_SSE_MATH)
4819 && !TARGET_MIX_SSE_I387"
4820 "* return output_387_reg_move (insn, operands);"
4821 [(set_attr "type" "fmov")
4822 (set_attr "mode" "SF")])
4825 [(set (match_operand:SF 0 "register_operand")
4827 (match_operand:DF 1 "fp_register_operand")))
4828 (clobber (match_operand 2))]
4830 [(set (match_dup 2) (match_dup 1))
4831 (set (match_dup 0) (match_dup 2))]
4832 "operands[1] = gen_rtx_REG (SFmode, REGNO (operands[1]));")
4834 ;; Conversion from XFmode to {SF,DF}mode
4836 (define_expand "truncxf<mode>2"
4837 [(parallel [(set (match_operand:MODEF 0 "nonimmediate_operand")
4838 (float_truncate:MODEF
4839 (match_operand:XF 1 "register_operand")))
4840 (clobber (match_dup 2))])]
4843 if (flag_unsafe_math_optimizations)
4845 rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (<MODE>mode);
4846 emit_insn (gen_truncxf<mode>2_i387_noop (reg, operands[1]));
4847 if (reg != operands[0])
4848 emit_move_insn (operands[0], reg);
4852 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4855 (define_insn "*truncxfsf2_mixed"
4856 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?v,?*r")
4858 (match_operand:XF 1 "register_operand" "f ,f ,f ,f")))
4859 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,m ,m"))]
4862 gcc_assert (!which_alternative);
4863 return output_387_reg_move (insn, operands);
4865 [(set_attr "type" "fmov,multi,multi,multi")
4866 (set_attr "unit" "*,i387,i387,i387")
4867 (set_attr "mode" "SF")])
4869 (define_insn "*truncxfdf2_mixed"
4870 [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?v,?*r")
4872 (match_operand:XF 1 "register_operand" "f ,f ,f ,f")))
4873 (clobber (match_operand:DF 2 "memory_operand" "=X,m ,m ,m"))]
4876 gcc_assert (!which_alternative);
4877 return output_387_reg_move (insn, operands);
4879 [(set_attr "isa" "*,*,sse2,*")
4880 (set_attr "type" "fmov,multi,multi,multi")
4881 (set_attr "unit" "*,i387,i387,i387")
4882 (set_attr "mode" "DF")])
4884 (define_insn "truncxf<mode>2_i387_noop"
4885 [(set (match_operand:MODEF 0 "register_operand" "=f")
4886 (float_truncate:MODEF
4887 (match_operand:XF 1 "register_operand" "f")))]
4888 "TARGET_80387 && flag_unsafe_math_optimizations"
4889 "* return output_387_reg_move (insn, operands);"
4890 [(set_attr "type" "fmov")
4891 (set_attr "mode" "<MODE>")])
4893 (define_insn "*truncxf<mode>2_i387"
4894 [(set (match_operand:MODEF 0 "memory_operand" "=m")
4895 (float_truncate:MODEF
4896 (match_operand:XF 1 "register_operand" "f")))]
4898 "* return output_387_reg_move (insn, operands);"
4899 [(set_attr "type" "fmov")
4900 (set_attr "mode" "<MODE>")])
4903 [(set (match_operand:MODEF 0 "register_operand")
4904 (float_truncate:MODEF
4905 (match_operand:XF 1 "register_operand")))
4906 (clobber (match_operand:MODEF 2 "memory_operand"))]
4907 "TARGET_80387 && reload_completed"
4908 [(set (match_dup 2) (float_truncate:MODEF (match_dup 1)))
4909 (set (match_dup 0) (match_dup 2))])
4912 [(set (match_operand:MODEF 0 "memory_operand")
4913 (float_truncate:MODEF
4914 (match_operand:XF 1 "register_operand")))
4915 (clobber (match_operand:MODEF 2 "memory_operand"))]
4917 [(set (match_dup 0) (float_truncate:MODEF (match_dup 1)))])
4919 ;; Signed conversion to DImode.
4921 (define_expand "fix_truncxfdi2"
4922 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand")
4923 (fix:DI (match_operand:XF 1 "register_operand")))
4924 (clobber (reg:CC FLAGS_REG))])]
4929 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4934 (define_expand "fix_trunc<mode>di2"
4935 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand")
4936 (fix:DI (match_operand:MODEF 1 "register_operand")))
4937 (clobber (reg:CC FLAGS_REG))])]
4938 "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4941 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4943 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4946 if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4948 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4949 emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4950 if (out != operands[0])
4951 emit_move_insn (operands[0], out);
4956 ;; Signed conversion to SImode.
4958 (define_expand "fix_truncxfsi2"
4959 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand")
4960 (fix:SI (match_operand:XF 1 "register_operand")))
4961 (clobber (reg:CC FLAGS_REG))])]
4966 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4971 (define_expand "fix_trunc<mode>si2"
4972 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand")
4973 (fix:SI (match_operand:MODEF 1 "register_operand")))
4974 (clobber (reg:CC FLAGS_REG))])]
4975 "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4978 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4980 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4983 if (SSE_FLOAT_MODE_P (<MODE>mode))
4985 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4986 emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4987 if (out != operands[0])
4988 emit_move_insn (operands[0], out);
4993 ;; Signed conversion to HImode.
4995 (define_expand "fix_trunc<mode>hi2"
4996 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand")
4997 (fix:HI (match_operand:X87MODEF 1 "register_operand")))
4998 (clobber (reg:CC FLAGS_REG))])]
5000 && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
5004 emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
5009 ;; Unsigned conversion to SImode.
5011 (define_expand "fixuns_trunc<mode>si2"
5013 [(set (match_operand:SI 0 "register_operand")
5015 (match_operand:MODEF 1 "nonimmediate_operand")))
5017 (clobber (match_scratch:<ssevecmode> 3))
5018 (clobber (match_scratch:<ssevecmode> 4))])]
5019 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
5021 machine_mode mode = <MODE>mode;
5022 machine_mode vecmode = <ssevecmode>mode;
5023 REAL_VALUE_TYPE TWO31r;
5026 if (optimize_insn_for_size_p ())
5029 real_ldexp (&TWO31r, &dconst1, 31);
5030 two31 = const_double_from_real_value (TWO31r, mode);
5031 two31 = ix86_build_const_vector (vecmode, true, two31);
5032 operands[2] = force_reg (vecmode, two31);
5035 (define_insn_and_split "*fixuns_trunc<mode>_1"
5036 [(set (match_operand:SI 0 "register_operand" "=&x,&x")
5038 (match_operand:MODEF 3 "nonimmediate_operand" "xm,xm")))
5039 (use (match_operand:<ssevecmode> 4 "nonimmediate_operand" "m,x"))
5040 (clobber (match_scratch:<ssevecmode> 1 "=x,&x"))
5041 (clobber (match_scratch:<ssevecmode> 2 "=x,x"))]
5042 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH
5043 && optimize_function_for_speed_p (cfun)"
5045 "&& reload_completed"
5048 ix86_split_convert_uns_si_sse (operands);
5052 ;; Unsigned conversion to HImode.
5053 ;; Without these patterns, we'll try the unsigned SI conversion which
5054 ;; is complex for SSE, rather than the signed SI conversion, which isn't.
5056 (define_expand "fixuns_trunc<mode>hi2"
5058 (fix:SI (match_operand:MODEF 1 "nonimmediate_operand")))
5059 (set (match_operand:HI 0 "nonimmediate_operand")
5060 (subreg:HI (match_dup 2) 0))]
5061 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
5062 "operands[2] = gen_reg_rtx (SImode);")
5064 ;; When SSE is available, it is always faster to use it!
5065 (define_insn "fix_trunc<MODEF:mode><SWI48:mode>_sse"
5066 [(set (match_operand:SWI48 0 "register_operand" "=r,r")
5067 (fix:SWI48 (match_operand:MODEF 1 "nonimmediate_operand" "v,m")))]
5068 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode)
5069 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
5070 "%vcvtt<MODEF:ssemodesuffix>2si<SWI48:rex64suffix>\t{%1, %0|%0, %1}"
5071 [(set_attr "type" "sseicvt")
5072 (set_attr "prefix" "maybe_vex")
5073 (set (attr "prefix_rex")
5075 (match_test "<SWI48:MODE>mode == DImode")
5077 (const_string "*")))
5078 (set_attr "mode" "<MODEF:MODE>")
5079 (set_attr "athlon_decode" "double,vector")
5080 (set_attr "amdfam10_decode" "double,double")
5081 (set_attr "bdver1_decode" "double,double")])
5083 ;; Avoid vector decoded forms of the instruction.
5085 [(match_scratch:MODEF 2 "x")
5086 (set (match_operand:SWI48 0 "register_operand")
5087 (fix:SWI48 (match_operand:MODEF 1 "memory_operand")))]
5088 "TARGET_AVOID_VECTOR_DECODE
5089 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode)
5090 && optimize_insn_for_speed_p ()"
5091 [(set (match_dup 2) (match_dup 1))
5092 (set (match_dup 0) (fix:SWI48 (match_dup 2)))])
5094 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
5095 [(set (match_operand:SWI248x 0 "nonimmediate_operand")
5096 (fix:SWI248x (match_operand 1 "register_operand")))]
5097 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5099 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
5100 && (TARGET_64BIT || <MODE>mode != DImode))
5102 && can_create_pseudo_p ()"
5107 if (memory_operand (operands[0], VOIDmode))
5108 emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
5111 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
5112 emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
5118 [(set_attr "type" "fisttp")
5119 (set_attr "mode" "<MODE>")])
5121 (define_insn "fix_trunc<mode>_i387_fisttp"
5122 [(set (match_operand:SWI248x 0 "memory_operand" "=m")
5123 (fix:SWI248x (match_operand 1 "register_operand" "f")))
5124 (clobber (match_scratch:XF 2 "=&1f"))]
5125 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5127 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
5128 && (TARGET_64BIT || <MODE>mode != DImode))
5129 && TARGET_SSE_MATH)"
5130 "* return output_fix_trunc (insn, operands, true);"
5131 [(set_attr "type" "fisttp")
5132 (set_attr "mode" "<MODE>")])
5134 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
5135 [(set (match_operand:SWI248x 0 "nonimmediate_operand" "=m,?r")
5136 (fix:SWI248x (match_operand 1 "register_operand" "f,f")))
5137 (clobber (match_operand:SWI248x 2 "memory_operand" "=X,m"))
5138 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
5139 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5141 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
5142 && (TARGET_64BIT || <MODE>mode != DImode))
5143 && TARGET_SSE_MATH)"
5145 [(set_attr "type" "fisttp")
5146 (set_attr "mode" "<MODE>")])
5149 [(set (match_operand:SWI248x 0 "register_operand")
5150 (fix:SWI248x (match_operand 1 "register_operand")))
5151 (clobber (match_operand:SWI248x 2 "memory_operand"))
5152 (clobber (match_scratch 3))]
5154 [(parallel [(set (match_dup 2) (fix:SWI248x (match_dup 1)))
5155 (clobber (match_dup 3))])
5156 (set (match_dup 0) (match_dup 2))])
5159 [(set (match_operand:SWI248x 0 "memory_operand")
5160 (fix:SWI248x (match_operand 1 "register_operand")))
5161 (clobber (match_operand:SWI248x 2 "memory_operand"))
5162 (clobber (match_scratch 3))]
5164 [(parallel [(set (match_dup 0) (fix:SWI248x (match_dup 1)))
5165 (clobber (match_dup 3))])])
5167 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
5168 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
5169 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
5170 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
5171 ;; function in i386.c.
5172 (define_insn_and_split "*fix_trunc<mode>_i387_1"
5173 [(set (match_operand:SWI248x 0 "nonimmediate_operand")
5174 (fix:SWI248x (match_operand 1 "register_operand")))
5175 (clobber (reg:CC FLAGS_REG))]
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 && can_create_pseudo_p ()"
5185 ix86_optimize_mode_switching[I387_TRUNC] = 1;
5187 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
5188 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
5189 if (memory_operand (operands[0], VOIDmode))
5190 emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
5191 operands[2], operands[3]));
5194 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
5195 emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
5196 operands[2], operands[3],
5201 [(set_attr "type" "fistp")
5202 (set_attr "i387_cw" "trunc")
5203 (set_attr "mode" "<MODE>")])
5205 (define_insn "fix_truncdi_i387"
5206 [(set (match_operand:DI 0 "memory_operand" "=m")
5207 (fix:DI (match_operand 1 "register_operand" "f")))
5208 (use (match_operand:HI 2 "memory_operand" "m"))
5209 (use (match_operand:HI 3 "memory_operand" "m"))
5210 (clobber (match_scratch:XF 4 "=&1f"))]
5211 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5213 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
5214 "* return output_fix_trunc (insn, operands, false);"
5215 [(set_attr "type" "fistp")
5216 (set_attr "i387_cw" "trunc")
5217 (set_attr "mode" "DI")])
5219 (define_insn "fix_truncdi_i387_with_temp"
5220 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
5221 (fix:DI (match_operand 1 "register_operand" "f,f")))
5222 (use (match_operand:HI 2 "memory_operand" "m,m"))
5223 (use (match_operand:HI 3 "memory_operand" "m,m"))
5224 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
5225 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
5226 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5228 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
5230 [(set_attr "type" "fistp")
5231 (set_attr "i387_cw" "trunc")
5232 (set_attr "mode" "DI")])
5235 [(set (match_operand:DI 0 "register_operand")
5236 (fix:DI (match_operand 1 "register_operand")))
5237 (use (match_operand:HI 2 "memory_operand"))
5238 (use (match_operand:HI 3 "memory_operand"))
5239 (clobber (match_operand:DI 4 "memory_operand"))
5240 (clobber (match_scratch 5))]
5242 [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
5245 (clobber (match_dup 5))])
5246 (set (match_dup 0) (match_dup 4))])
5249 [(set (match_operand:DI 0 "memory_operand")
5250 (fix:DI (match_operand 1 "register_operand")))
5251 (use (match_operand:HI 2 "memory_operand"))
5252 (use (match_operand:HI 3 "memory_operand"))
5253 (clobber (match_operand:DI 4 "memory_operand"))
5254 (clobber (match_scratch 5))]
5256 [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
5259 (clobber (match_dup 5))])])
5261 (define_insn "fix_trunc<mode>_i387"
5262 [(set (match_operand:SWI24 0 "memory_operand" "=m")
5263 (fix:SWI24 (match_operand 1 "register_operand" "f")))
5264 (use (match_operand:HI 2 "memory_operand" "m"))
5265 (use (match_operand:HI 3 "memory_operand" "m"))]
5266 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5268 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
5269 "* return output_fix_trunc (insn, operands, false);"
5270 [(set_attr "type" "fistp")
5271 (set_attr "i387_cw" "trunc")
5272 (set_attr "mode" "<MODE>")])
5274 (define_insn "fix_trunc<mode>_i387_with_temp"
5275 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
5276 (fix:SWI24 (match_operand 1 "register_operand" "f,f")))
5277 (use (match_operand:HI 2 "memory_operand" "m,m"))
5278 (use (match_operand:HI 3 "memory_operand" "m,m"))
5279 (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
5280 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5282 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
5284 [(set_attr "type" "fistp")
5285 (set_attr "i387_cw" "trunc")
5286 (set_attr "mode" "<MODE>")])
5289 [(set (match_operand:SWI24 0 "register_operand")
5290 (fix:SWI24 (match_operand 1 "register_operand")))
5291 (use (match_operand:HI 2 "memory_operand"))
5292 (use (match_operand:HI 3 "memory_operand"))
5293 (clobber (match_operand:SWI24 4 "memory_operand"))]
5295 [(parallel [(set (match_dup 4) (fix:SWI24 (match_dup 1)))
5297 (use (match_dup 3))])
5298 (set (match_dup 0) (match_dup 4))])
5301 [(set (match_operand:SWI24 0 "memory_operand")
5302 (fix:SWI24 (match_operand 1 "register_operand")))
5303 (use (match_operand:HI 2 "memory_operand"))
5304 (use (match_operand:HI 3 "memory_operand"))
5305 (clobber (match_operand:SWI24 4 "memory_operand"))]
5307 [(parallel [(set (match_dup 0) (fix:SWI24 (match_dup 1)))
5309 (use (match_dup 3))])])
5311 (define_insn "x86_fnstcw_1"
5312 [(set (match_operand:HI 0 "memory_operand" "=m")
5313 (unspec:HI [(reg:HI FPCR_REG)] UNSPEC_FSTCW))]
5316 [(set (attr "length")
5317 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
5318 (set_attr "mode" "HI")
5319 (set_attr "unit" "i387")
5320 (set_attr "bdver1_decode" "vector")])
5322 (define_insn "x86_fldcw_1"
5323 [(set (reg:HI FPCR_REG)
5324 (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
5327 [(set (attr "length")
5328 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
5329 (set_attr "mode" "HI")
5330 (set_attr "unit" "i387")
5331 (set_attr "athlon_decode" "vector")
5332 (set_attr "amdfam10_decode" "vector")
5333 (set_attr "bdver1_decode" "vector")])
5335 ;; Conversion between fixed point and floating point.
5337 ;; Even though we only accept memory inputs, the backend _really_
5338 ;; wants to be able to do this between registers. Thankfully, LRA
5339 ;; will fix this up for us during register allocation.
5341 (define_insn "floathi<mode>2"
5342 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5343 (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "m")))]
5345 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5346 || TARGET_MIX_SSE_I387)"
5348 [(set_attr "type" "fmov")
5349 (set_attr "mode" "<MODE>")
5350 (set_attr "znver1_decode" "double")
5351 (set_attr "fp_int_src" "true")])
5353 (define_insn "float<SWI48x:mode>xf2"
5354 [(set (match_operand:XF 0 "register_operand" "=f")
5355 (float:XF (match_operand:SWI48x 1 "nonimmediate_operand" "m")))]
5358 [(set_attr "type" "fmov")
5359 (set_attr "mode" "XF")
5360 (set_attr "znver1_decode" "double")
5361 (set_attr "fp_int_src" "true")])
5363 (define_expand "float<SWI48:mode><MODEF:mode>2"
5364 [(set (match_operand:MODEF 0 "register_operand")
5365 (float:MODEF (match_operand:SWI48 1 "nonimmediate_operand")))]
5366 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)"
5368 if (!(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
5369 && !X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI48:MODE>mode))
5371 rtx reg = gen_reg_rtx (XFmode);
5372 rtx (*insn)(rtx, rtx);
5374 emit_insn (gen_float<SWI48:mode>xf2 (reg, operands[1]));
5376 if (<MODEF:MODE>mode == SFmode)
5377 insn = gen_truncxfsf2;
5378 else if (<MODEF:MODE>mode == DFmode)
5379 insn = gen_truncxfdf2;
5383 emit_insn (insn (operands[0], reg));
5388 (define_insn "*float<SWI48:mode><MODEF:mode>2_mixed"
5389 [(set (match_operand:MODEF 0 "register_operand" "=f,v,v")
5391 (match_operand:SWI48 1 "nonimmediate_operand" "m,r,m")))]
5392 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
5395 %vcvtsi2<MODEF:ssemodesuffix><SWI48:rex64suffix>\t{%1, %d0|%d0, %1}
5396 %vcvtsi2<MODEF:ssemodesuffix><SWI48:rex64suffix>\t{%1, %d0|%d0, %1}"
5397 [(set_attr "type" "fmov,sseicvt,sseicvt")
5398 (set_attr "prefix" "orig,maybe_vex,maybe_vex")
5399 (set_attr "mode" "<MODEF:MODE>")
5400 (set (attr "prefix_rex")
5402 (and (eq_attr "prefix" "maybe_vex")
5403 (match_test "<SWI48:MODE>mode == DImode"))
5405 (const_string "*")))
5406 (set_attr "unit" "i387,*,*")
5407 (set_attr "athlon_decode" "*,double,direct")
5408 (set_attr "amdfam10_decode" "*,vector,double")
5409 (set_attr "bdver1_decode" "*,double,direct")
5410 (set_attr "znver1_decode" "double,*,*")
5411 (set_attr "fp_int_src" "true")
5412 (set (attr "enabled")
5413 (cond [(eq_attr "alternative" "0")
5414 (symbol_ref "TARGET_MIX_SSE_I387
5415 && X87_ENABLE_FLOAT (<MODEF:MODE>mode,
5418 (symbol_ref "true")))
5419 (set (attr "preferred_for_speed")
5420 (cond [(eq_attr "alternative" "1")
5421 (symbol_ref "TARGET_INTER_UNIT_CONVERSIONS")]
5422 (symbol_ref "true")))])
5424 (define_insn "*float<SWI48x:mode><MODEF:mode>2_i387"
5425 [(set (match_operand:MODEF 0 "register_operand" "=f")
5426 (float:MODEF (match_operand:SWI48x 1 "nonimmediate_operand" "m")))]
5427 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI48x:MODE>mode)"
5429 [(set_attr "type" "fmov")
5430 (set_attr "mode" "<MODEF:MODE>")
5431 (set_attr "znver1_decode" "double")
5432 (set_attr "fp_int_src" "true")])
5434 ;; Try TARGET_USE_VECTOR_CONVERTS, but not so hard as to require extra memory
5435 ;; slots when !TARGET_INTER_UNIT_MOVES_TO_VEC disables the general_regs
5436 ;; alternative in sse2_loadld.
5438 [(set (match_operand:MODEF 0 "sse_reg_operand")
5439 (float:MODEF (match_operand:SI 1 "nonimmediate_operand")))]
5441 && TARGET_USE_VECTOR_CONVERTS
5442 && optimize_function_for_speed_p (cfun)
5444 && (MEM_P (operands[1]) || TARGET_INTER_UNIT_MOVES_TO_VEC)
5445 && (!EXT_REX_SSE_REG_P (operands[0])
5446 || TARGET_AVX512VL)"
5449 operands[3] = lowpart_subreg (<ssevecmode>mode, operands[0], <MODE>mode);
5450 operands[4] = lowpart_subreg (V4SImode, operands[0], <MODE>mode);
5452 emit_insn (gen_sse2_loadld (operands[4],
5453 CONST0_RTX (V4SImode), operands[1]));
5455 if (<ssevecmode>mode == V4SFmode)
5456 emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
5458 emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
5462 ;; Avoid partial SSE register dependency stalls. This splitter should split
5463 ;; late in the pass sequence (after register rename pass), so allocated
5464 ;; registers won't change anymore
5467 [(set (match_operand:MODEF 0 "sse_reg_operand")
5468 (float:MODEF (match_operand:SWI48 1 "nonimmediate_operand")))]
5469 "TARGET_SSE_PARTIAL_REG_DEPENDENCY && epilogue_completed
5470 && optimize_function_for_speed_p (cfun)
5471 && (!EXT_REX_SSE_REG_P (operands[0])
5472 || TARGET_AVX512VL)"
5474 (vec_merge:<MODEF:ssevecmode>
5475 (vec_duplicate:<MODEF:ssevecmode>
5481 const machine_mode vmode = <MODEF:ssevecmode>mode;
5483 operands[0] = lowpart_subreg (vmode, operands[0], <MODEF:MODE>mode);
5484 emit_move_insn (operands[0], CONST0_RTX (vmode));
5487 ;; Break partial reg stall for cvtsd2ss. This splitter should split
5488 ;; late in the pass sequence (after register rename pass),
5489 ;; so allocated registers won't change anymore.
5492 [(set (match_operand:SF 0 "sse_reg_operand")
5494 (match_operand:DF 1 "nonimmediate_operand")))]
5495 "TARGET_SSE_PARTIAL_REG_DEPENDENCY && epilogue_completed
5496 && optimize_function_for_speed_p (cfun)
5497 && (!REG_P (operands[1])
5498 || REGNO (operands[0]) != REGNO (operands[1]))
5499 && (!EXT_REX_SSE_REG_P (operands[0])
5500 || TARGET_AVX512VL)"
5509 operands[0] = lowpart_subreg (V4SFmode, operands[0], SFmode);
5510 emit_move_insn (operands[0], CONST0_RTX (V4SFmode));
5513 ;; Break partial reg stall for cvtss2sd. This splitter should split
5514 ;; late in the pass sequence (after register rename pass),
5515 ;; so allocated registers won't change anymore.
5518 [(set (match_operand:DF 0 "sse_reg_operand")
5520 (match_operand:SF 1 "nonimmediate_operand")))]
5521 "TARGET_SSE_PARTIAL_REG_DEPENDENCY && epilogue_completed
5522 && optimize_function_for_speed_p (cfun)
5523 && (!REG_P (operands[1])
5524 || REGNO (operands[0]) != REGNO (operands[1]))
5525 && (!EXT_REX_SSE_REG_P (operands[0])
5526 || TARGET_AVX512VL)"
5535 operands[0] = lowpart_subreg (V2DFmode, operands[0], DFmode);
5536 emit_move_insn (operands[0], CONST0_RTX (V2DFmode));
5539 ;; Avoid store forwarding (partial memory) stall penalty
5540 ;; by passing DImode value through XMM registers. */
5542 (define_insn "floatdi<X87MODEF:mode>2_i387_with_xmm"
5543 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5545 (match_operand:DI 1 "nonimmediate_operand" "m,?r")))
5546 (clobber (match_scratch:V4SI 3 "=X,x"))
5547 (clobber (match_scratch:V4SI 4 "=X,x"))
5548 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))]
5549 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5550 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC
5551 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)"
5553 [(set_attr "type" "multi")
5554 (set_attr "mode" "<X87MODEF:MODE>")
5555 (set_attr "unit" "i387")
5556 (set_attr "fp_int_src" "true")])
5559 [(set (match_operand:X87MODEF 0 "fp_register_operand")
5560 (float:X87MODEF (match_operand:DI 1 "register_operand")))
5561 (clobber (match_scratch:V4SI 3))
5562 (clobber (match_scratch:V4SI 4))
5563 (clobber (match_operand:DI 2 "memory_operand"))]
5564 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5565 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC
5566 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5567 && reload_completed"
5568 [(set (match_dup 2) (match_dup 3))
5569 (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5571 /* The DImode arrived in a pair of integral registers (e.g. %edx:%eax).
5572 Assemble the 64-bit DImode value in an xmm register. */
5573 emit_insn (gen_sse2_loadld (operands[3], CONST0_RTX (V4SImode),
5574 gen_lowpart (SImode, operands[1])));
5575 emit_insn (gen_sse2_loadld (operands[4], CONST0_RTX (V4SImode),
5576 gen_highpart (SImode, operands[1])));
5577 emit_insn (gen_vec_interleave_lowv4si (operands[3], operands[3],
5580 operands[3] = gen_lowpart (DImode, operands[3]);
5584 [(set (match_operand:X87MODEF 0 "fp_register_operand")
5585 (float:X87MODEF (match_operand:DI 1 "memory_operand")))
5586 (clobber (match_scratch:V4SI 3))
5587 (clobber (match_scratch:V4SI 4))
5588 (clobber (match_operand:DI 2 "memory_operand"))]
5589 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5590 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC
5591 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5592 && reload_completed"
5593 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
5595 (define_expand "floatuns<SWI12:mode><MODEF:mode>2"
5596 [(set (match_operand:MODEF 0 "register_operand")
5597 (unsigned_float:MODEF
5598 (match_operand:SWI12 1 "nonimmediate_operand")))]
5600 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
5602 operands[1] = convert_to_mode (SImode, operands[1], 1);
5603 emit_insn (gen_floatsi<MODEF:mode>2 (operands[0], operands[1]));
5607 ;; Avoid store forwarding (partial memory) stall penalty by extending
5608 ;; SImode value to DImode through XMM register instead of pushing two
5609 ;; SImode values to stack. Also note that fild loads from memory only.
5611 (define_insn_and_split "*floatunssi<mode>2_i387_with_xmm"
5612 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5613 (unsigned_float:X87MODEF
5614 (match_operand:SI 1 "nonimmediate_operand" "rm")))
5615 (clobber (match_scratch:DI 3 "=x"))
5616 (clobber (match_operand:DI 2 "memory_operand" "=m"))]
5618 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5619 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC"
5621 "&& reload_completed"
5622 [(set (match_dup 3) (zero_extend:DI (match_dup 1)))
5623 (set (match_dup 2) (match_dup 3))
5625 (float:X87MODEF (match_dup 2)))]
5627 [(set_attr "type" "multi")
5628 (set_attr "mode" "<MODE>")])
5630 (define_expand "floatunssi<mode>2"
5632 [(set (match_operand:X87MODEF 0 "register_operand")
5633 (unsigned_float:X87MODEF
5634 (match_operand:SI 1 "nonimmediate_operand")))
5635 (clobber (match_scratch:DI 3))
5636 (clobber (match_dup 2))])]
5638 && ((TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5639 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC)
5640 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
5642 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5644 ix86_expand_convert_uns_si<mode>_sse (operands[0], operands[1]);
5648 operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
5651 (define_expand "floatunsdisf2"
5652 [(use (match_operand:SF 0 "register_operand"))
5653 (use (match_operand:DI 1 "nonimmediate_operand"))]
5654 "TARGET_64BIT && TARGET_SSE && TARGET_SSE_MATH"
5655 "x86_emit_floatuns (operands); DONE;")
5657 (define_expand "floatunsdidf2"
5658 [(use (match_operand:DF 0 "register_operand"))
5659 (use (match_operand:DI 1 "nonimmediate_operand"))]
5660 "(TARGET_64BIT || TARGET_KEEPS_VECTOR_ALIGNED_STACK)
5661 && TARGET_SSE2 && TARGET_SSE_MATH"
5664 x86_emit_floatuns (operands);
5666 ix86_expand_convert_uns_didf_sse (operands[0], operands[1]);
5670 ;; Load effective address instructions
5672 (define_insn_and_split "*lea<mode>"
5673 [(set (match_operand:SWI48 0 "register_operand" "=r")
5674 (match_operand:SWI48 1 "address_no_seg_operand" "Ts"))]
5677 if (SImode_address_operand (operands[1], VOIDmode))
5679 gcc_assert (TARGET_64BIT);
5680 return "lea{l}\t{%E1, %k0|%k0, %E1}";
5683 return "lea{<imodesuffix>}\t{%E1, %0|%0, %E1}";
5685 "reload_completed && ix86_avoid_lea_for_addr (insn, operands)"
5688 machine_mode mode = <MODE>mode;
5691 /* ix86_avoid_lea_for_addr re-recognizes insn and may
5692 change operands[] array behind our back. */
5693 pat = PATTERN (curr_insn);
5695 operands[0] = SET_DEST (pat);
5696 operands[1] = SET_SRC (pat);
5698 /* Emit all operations in SImode for zero-extended addresses. */
5699 if (SImode_address_operand (operands[1], VOIDmode))
5702 ix86_split_lea_for_addr (curr_insn, operands, mode);
5704 /* Zero-extend return register to DImode for zero-extended addresses. */
5705 if (mode != <MODE>mode)
5706 emit_insn (gen_zero_extendsidi2
5707 (operands[0], gen_lowpart (mode, operands[0])));
5711 [(set_attr "type" "lea")
5714 (match_operand 1 "SImode_address_operand")
5716 (const_string "<MODE>")))])
5720 (define_expand "add<mode>3"
5721 [(set (match_operand:SDWIM 0 "nonimmediate_operand")
5722 (plus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")
5723 (match_operand:SDWIM 2 "<general_hilo_operand>")))]
5725 "ix86_expand_binary_operator (PLUS, <MODE>mode, operands); DONE;")
5727 (define_insn_and_split "*add<dwi>3_doubleword"
5728 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
5730 (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0")
5731 (match_operand:<DWI> 2 "x86_64_hilo_general_operand"
5733 (clobber (reg:CC FLAGS_REG))]
5734 "ix86_binary_operator_ok (PLUS, <DWI>mode, operands)"
5737 [(parallel [(set (reg:CCC FLAGS_REG)
5739 (plus:DWIH (match_dup 1) (match_dup 2))
5742 (plus:DWIH (match_dup 1) (match_dup 2)))])
5743 (parallel [(set (match_dup 3)
5746 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
5749 (clobber (reg:CC FLAGS_REG))])]
5751 split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
5752 if (operands[2] == const0_rtx)
5754 ix86_expand_binary_operator (PLUS, <MODE>mode, &operands[3]);
5759 (define_insn "*add<mode>_1"
5760 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,rm,r,r")
5762 (match_operand:SWI48 1 "nonimmediate_operand" "%0,0,r,r")
5763 (match_operand:SWI48 2 "x86_64_general_operand" "rme,re,0,le")))
5764 (clobber (reg:CC FLAGS_REG))]
5765 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5767 switch (get_attr_type (insn))
5773 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5774 if (operands[2] == const1_rtx)
5775 return "inc{<imodesuffix>}\t%0";
5778 gcc_assert (operands[2] == constm1_rtx);
5779 return "dec{<imodesuffix>}\t%0";
5783 /* For most processors, ADD is faster than LEA. This alternative
5784 was added to use ADD as much as possible. */
5785 if (which_alternative == 2)
5786 std::swap (operands[1], operands[2]);
5788 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5789 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5790 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5792 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5796 (cond [(eq_attr "alternative" "3")
5797 (const_string "lea")
5798 (match_operand:SWI48 2 "incdec_operand")
5799 (const_string "incdec")
5801 (const_string "alu")))
5802 (set (attr "length_immediate")
5804 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5806 (const_string "*")))
5807 (set_attr "mode" "<MODE>")])
5809 ;; It may seem that nonimmediate operand is proper one for operand 1.
5810 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5811 ;; we take care in ix86_binary_operator_ok to not allow two memory
5812 ;; operands so proper swapping will be done in reload. This allow
5813 ;; patterns constructed from addsi_1 to match.
5815 (define_insn "addsi_1_zext"
5816 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
5818 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r,r")
5819 (match_operand:SI 2 "x86_64_general_operand" "rme,0,le"))))
5820 (clobber (reg:CC FLAGS_REG))]
5821 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5823 switch (get_attr_type (insn))
5829 if (operands[2] == const1_rtx)
5830 return "inc{l}\t%k0";
5833 gcc_assert (operands[2] == constm1_rtx);
5834 return "dec{l}\t%k0";
5838 /* For most processors, ADD is faster than LEA. This alternative
5839 was added to use ADD as much as possible. */
5840 if (which_alternative == 1)
5841 std::swap (operands[1], operands[2]);
5843 if (x86_maybe_negate_const_int (&operands[2], SImode))
5844 return "sub{l}\t{%2, %k0|%k0, %2}";
5846 return "add{l}\t{%2, %k0|%k0, %2}";
5850 (cond [(eq_attr "alternative" "2")
5851 (const_string "lea")
5852 (match_operand:SI 2 "incdec_operand")
5853 (const_string "incdec")
5855 (const_string "alu")))
5856 (set (attr "length_immediate")
5858 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5860 (const_string "*")))
5861 (set_attr "mode" "SI")])
5863 (define_insn "*addhi_1"
5864 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r,Yp")
5865 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r,Yp")
5866 (match_operand:HI 2 "general_operand" "rn,rm,0,ln")))
5867 (clobber (reg:CC FLAGS_REG))]
5868 "ix86_binary_operator_ok (PLUS, HImode, operands)"
5870 switch (get_attr_type (insn))
5876 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5877 if (operands[2] == const1_rtx)
5878 return "inc{w}\t%0";
5881 gcc_assert (operands[2] == constm1_rtx);
5882 return "dec{w}\t%0";
5886 /* For most processors, ADD is faster than LEA. This alternative
5887 was added to use ADD as much as possible. */
5888 if (which_alternative == 2)
5889 std::swap (operands[1], operands[2]);
5891 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5892 if (x86_maybe_negate_const_int (&operands[2], HImode))
5893 return "sub{w}\t{%2, %0|%0, %2}";
5895 return "add{w}\t{%2, %0|%0, %2}";
5899 (cond [(eq_attr "alternative" "3")
5900 (const_string "lea")
5901 (match_operand:HI 2 "incdec_operand")
5902 (const_string "incdec")
5904 (const_string "alu")))
5905 (set (attr "length_immediate")
5907 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5909 (const_string "*")))
5910 (set_attr "mode" "HI,HI,HI,SI")])
5912 (define_insn "*addqi_1"
5913 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,q,r,r,Yp")
5914 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,q,0,r,Yp")
5915 (match_operand:QI 2 "general_operand" "qn,qm,0,rn,0,ln")))
5916 (clobber (reg:CC FLAGS_REG))]
5917 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5919 bool widen = (get_attr_mode (insn) != MODE_QI);
5921 switch (get_attr_type (insn))
5927 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5928 if (operands[2] == const1_rtx)
5929 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
5932 gcc_assert (operands[2] == constm1_rtx);
5933 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
5937 /* For most processors, ADD is faster than LEA. These alternatives
5938 were added to use ADD as much as possible. */
5939 if (which_alternative == 2 || which_alternative == 4)
5940 std::swap (operands[1], operands[2]);
5942 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5943 if (x86_maybe_negate_const_int (&operands[2], QImode))
5946 return "sub{l}\t{%2, %k0|%k0, %2}";
5948 return "sub{b}\t{%2, %0|%0, %2}";
5951 return "add{l}\t{%k2, %k0|%k0, %k2}";
5953 return "add{b}\t{%2, %0|%0, %2}";
5957 (cond [(eq_attr "alternative" "5")
5958 (const_string "lea")
5959 (match_operand:QI 2 "incdec_operand")
5960 (const_string "incdec")
5962 (const_string "alu")))
5963 (set (attr "length_immediate")
5965 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5967 (const_string "*")))
5968 (set_attr "mode" "QI,QI,QI,SI,SI,SI")
5969 ;; Potential partial reg stall on alternatives 3 and 4.
5970 (set (attr "preferred_for_speed")
5971 (cond [(eq_attr "alternative" "3,4")
5972 (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
5973 (symbol_ref "true")))])
5975 (define_insn "*addqi_1_slp"
5976 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
5977 (plus:QI (match_dup 0)
5978 (match_operand:QI 1 "general_operand" "qn,qm")))
5979 (clobber (reg:CC FLAGS_REG))]
5980 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
5981 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
5983 switch (get_attr_type (insn))
5986 if (operands[1] == const1_rtx)
5987 return "inc{b}\t%0";
5990 gcc_assert (operands[1] == constm1_rtx);
5991 return "dec{b}\t%0";
5995 if (x86_maybe_negate_const_int (&operands[1], QImode))
5996 return "sub{b}\t{%1, %0|%0, %1}";
5998 return "add{b}\t{%1, %0|%0, %1}";
6002 (if_then_else (match_operand:QI 1 "incdec_operand")
6003 (const_string "incdec")
6004 (const_string "alu1")))
6005 (set (attr "memory")
6006 (if_then_else (match_operand 1 "memory_operand")
6007 (const_string "load")
6008 (const_string "none")))
6009 (set_attr "mode" "QI")])
6011 ;; Split non destructive adds if we cannot use lea.
6013 [(set (match_operand:SWI48 0 "register_operand")
6014 (plus:SWI48 (match_operand:SWI48 1 "register_operand")
6015 (match_operand:SWI48 2 "x86_64_nonmemory_operand")))
6016 (clobber (reg:CC FLAGS_REG))]
6017 "reload_completed && ix86_avoid_lea_for_add (insn, operands)"
6018 [(set (match_dup 0) (match_dup 1))
6019 (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 2)))
6020 (clobber (reg:CC FLAGS_REG))])])
6022 ;; Split non destructive adds if we cannot use lea.
6024 [(set (match_operand:DI 0 "register_operand")
6026 (plus:SI (match_operand:SI 1 "register_operand")
6027 (match_operand:SI 2 "x86_64_nonmemory_operand"))))
6028 (clobber (reg:CC FLAGS_REG))]
6030 && reload_completed && ix86_avoid_lea_for_add (insn, operands)"
6031 [(set (match_dup 3) (match_dup 1))
6032 (parallel [(set (match_dup 0)
6033 (zero_extend:DI (plus:SI (match_dup 3) (match_dup 2))))
6034 (clobber (reg:CC FLAGS_REG))])]
6035 "operands[3] = gen_lowpart (SImode, operands[0]);")
6037 ;; Convert add to the lea pattern to avoid flags dependency.
6039 [(set (match_operand:SWI 0 "register_operand")
6040 (plus:SWI (match_operand:SWI 1 "register_operand")
6041 (match_operand:SWI 2 "<nonmemory_operand>")))
6042 (clobber (reg:CC FLAGS_REG))]
6043 "reload_completed && ix86_lea_for_add_ok (insn, operands)"
6045 (plus:<LEAMODE> (match_dup 1) (match_dup 2)))]
6047 if (<MODE>mode != <LEAMODE>mode)
6049 operands[0] = gen_lowpart (<LEAMODE>mode, operands[0]);
6050 operands[1] = gen_lowpart (<LEAMODE>mode, operands[1]);
6051 operands[2] = gen_lowpart (<LEAMODE>mode, operands[2]);
6055 ;; Convert add to the lea pattern to avoid flags dependency.
6057 [(set (match_operand:DI 0 "register_operand")
6059 (plus:SI (match_operand:SI 1 "register_operand")
6060 (match_operand:SI 2 "x86_64_nonmemory_operand"))))
6061 (clobber (reg:CC FLAGS_REG))]
6062 "TARGET_64BIT && reload_completed && ix86_lea_for_add_ok (insn, operands)"
6064 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))])
6066 (define_insn "*add<mode>_2"
6067 [(set (reg FLAGS_REG)
6070 (match_operand:SWI 1 "nonimmediate_operand" "%0,0,<r>")
6071 (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>,0"))
6073 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m,<r>")
6074 (plus:SWI (match_dup 1) (match_dup 2)))]
6075 "ix86_match_ccmode (insn, CCGOCmode)
6076 && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6078 switch (get_attr_type (insn))
6081 if (operands[2] == const1_rtx)
6082 return "inc{<imodesuffix>}\t%0";
6085 gcc_assert (operands[2] == constm1_rtx);
6086 return "dec{<imodesuffix>}\t%0";
6090 if (which_alternative == 2)
6091 std::swap (operands[1], operands[2]);
6093 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6094 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6095 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6097 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6101 (if_then_else (match_operand:SWI 2 "incdec_operand")
6102 (const_string "incdec")
6103 (const_string "alu")))
6104 (set (attr "length_immediate")
6106 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6108 (const_string "*")))
6109 (set_attr "mode" "<MODE>")])
6111 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6112 (define_insn "*addsi_2_zext"
6113 [(set (reg FLAGS_REG)
6115 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
6116 (match_operand:SI 2 "x86_64_general_operand" "rme,0"))
6118 (set (match_operand:DI 0 "register_operand" "=r,r")
6119 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6120 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6121 && ix86_binary_operator_ok (PLUS, SImode, operands)"
6123 switch (get_attr_type (insn))
6126 if (operands[2] == const1_rtx)
6127 return "inc{l}\t%k0";
6130 gcc_assert (operands[2] == constm1_rtx);
6131 return "dec{l}\t%k0";
6135 if (which_alternative == 1)
6136 std::swap (operands[1], operands[2]);
6138 if (x86_maybe_negate_const_int (&operands[2], SImode))
6139 return "sub{l}\t{%2, %k0|%k0, %2}";
6141 return "add{l}\t{%2, %k0|%k0, %2}";
6145 (if_then_else (match_operand:SI 2 "incdec_operand")
6146 (const_string "incdec")
6147 (const_string "alu")))
6148 (set (attr "length_immediate")
6150 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6152 (const_string "*")))
6153 (set_attr "mode" "SI")])
6155 (define_insn "*add<mode>_3"
6156 [(set (reg FLAGS_REG)
6158 (neg:SWI (match_operand:SWI 2 "<general_operand>" "<g>,0"))
6159 (match_operand:SWI 1 "nonimmediate_operand" "%0,<r>")))
6160 (clobber (match_scratch:SWI 0 "=<r>,<r>"))]
6161 "ix86_match_ccmode (insn, CCZmode)
6162 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6164 switch (get_attr_type (insn))
6167 if (operands[2] == const1_rtx)
6168 return "inc{<imodesuffix>}\t%0";
6171 gcc_assert (operands[2] == constm1_rtx);
6172 return "dec{<imodesuffix>}\t%0";
6176 if (which_alternative == 1)
6177 std::swap (operands[1], operands[2]);
6179 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6180 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6181 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6183 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6187 (if_then_else (match_operand:SWI 2 "incdec_operand")
6188 (const_string "incdec")
6189 (const_string "alu")))
6190 (set (attr "length_immediate")
6192 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6194 (const_string "*")))
6195 (set_attr "mode" "<MODE>")])
6197 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6198 (define_insn "*addsi_3_zext"
6199 [(set (reg FLAGS_REG)
6201 (neg:SI (match_operand:SI 2 "x86_64_general_operand" "rme,0"))
6202 (match_operand:SI 1 "nonimmediate_operand" "%0,r")))
6203 (set (match_operand:DI 0 "register_operand" "=r,r")
6204 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6205 "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
6206 && ix86_binary_operator_ok (PLUS, SImode, operands)"
6208 switch (get_attr_type (insn))
6211 if (operands[2] == const1_rtx)
6212 return "inc{l}\t%k0";
6215 gcc_assert (operands[2] == constm1_rtx);
6216 return "dec{l}\t%k0";
6220 if (which_alternative == 1)
6221 std::swap (operands[1], operands[2]);
6223 if (x86_maybe_negate_const_int (&operands[2], SImode))
6224 return "sub{l}\t{%2, %k0|%k0, %2}";
6226 return "add{l}\t{%2, %k0|%k0, %2}";
6230 (if_then_else (match_operand:SI 2 "incdec_operand")
6231 (const_string "incdec")
6232 (const_string "alu")))
6233 (set (attr "length_immediate")
6235 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6237 (const_string "*")))
6238 (set_attr "mode" "SI")])
6240 ; For comparisons against 1, -1 and 128, we may generate better code
6241 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
6242 ; is matched then. We can't accept general immediate, because for
6243 ; case of overflows, the result is messed up.
6244 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6245 ; only for comparisons not depending on it.
6247 (define_insn "*adddi_4"
6248 [(set (reg FLAGS_REG)
6250 (match_operand:DI 1 "nonimmediate_operand" "0")
6251 (match_operand:DI 2 "x86_64_immediate_operand" "e")))
6252 (clobber (match_scratch:DI 0 "=rm"))]
6254 && ix86_match_ccmode (insn, CCGCmode)"
6256 switch (get_attr_type (insn))
6259 if (operands[2] == constm1_rtx)
6260 return "inc{q}\t%0";
6263 gcc_assert (operands[2] == const1_rtx);
6264 return "dec{q}\t%0";
6268 if (x86_maybe_negate_const_int (&operands[2], DImode))
6269 return "add{q}\t{%2, %0|%0, %2}";
6271 return "sub{q}\t{%2, %0|%0, %2}";
6275 (if_then_else (match_operand:DI 2 "incdec_operand")
6276 (const_string "incdec")
6277 (const_string "alu")))
6278 (set (attr "length_immediate")
6280 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6282 (const_string "*")))
6283 (set_attr "mode" "DI")])
6285 ; For comparisons against 1, -1 and 128, we may generate better code
6286 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
6287 ; is matched then. We can't accept general immediate, because for
6288 ; case of overflows, the result is messed up.
6289 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6290 ; only for comparisons not depending on it.
6292 (define_insn "*add<mode>_4"
6293 [(set (reg FLAGS_REG)
6295 (match_operand:SWI124 1 "nonimmediate_operand" "0")
6296 (match_operand:SWI124 2 "const_int_operand" "n")))
6297 (clobber (match_scratch:SWI124 0 "=<r>m"))]
6298 "ix86_match_ccmode (insn, CCGCmode)"
6300 switch (get_attr_type (insn))
6303 if (operands[2] == constm1_rtx)
6304 return "inc{<imodesuffix>}\t%0";
6307 gcc_assert (operands[2] == const1_rtx);
6308 return "dec{<imodesuffix>}\t%0";
6312 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6313 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6315 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6319 (if_then_else (match_operand:<MODE> 2 "incdec_operand")
6320 (const_string "incdec")
6321 (const_string "alu")))
6322 (set (attr "length_immediate")
6324 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6326 (const_string "*")))
6327 (set_attr "mode" "<MODE>")])
6329 (define_insn "*add<mode>_5"
6330 [(set (reg FLAGS_REG)
6333 (match_operand:SWI 1 "nonimmediate_operand" "%0,<r>")
6334 (match_operand:SWI 2 "<general_operand>" "<g>,0"))
6336 (clobber (match_scratch:SWI 0 "=<r>,<r>"))]
6337 "ix86_match_ccmode (insn, CCGOCmode)
6338 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6340 switch (get_attr_type (insn))
6343 if (operands[2] == const1_rtx)
6344 return "inc{<imodesuffix>}\t%0";
6347 gcc_assert (operands[2] == constm1_rtx);
6348 return "dec{<imodesuffix>}\t%0";
6352 if (which_alternative == 1)
6353 std::swap (operands[1], operands[2]);
6355 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6356 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6357 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6359 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6363 (if_then_else (match_operand:SWI 2 "incdec_operand")
6364 (const_string "incdec")
6365 (const_string "alu")))
6366 (set (attr "length_immediate")
6368 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6370 (const_string "*")))
6371 (set_attr "mode" "<MODE>")])
6373 (define_insn "addqi_ext_1"
6374 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q,Q")
6380 (zero_extract:SI (match_operand 1 "ext_register_operand" "0,0")
6383 (match_operand:QI 2 "general_operand" "QnBc,m")) 0))
6384 (clobber (reg:CC FLAGS_REG))]
6385 "/* FIXME: without this LRA can't reload this pattern, see PR82524. */
6386 rtx_equal_p (operands[0], operands[1])"
6388 switch (get_attr_type (insn))
6391 if (operands[2] == const1_rtx)
6392 return "inc{b}\t%h0";
6395 gcc_assert (operands[2] == constm1_rtx);
6396 return "dec{b}\t%h0";
6400 return "add{b}\t{%2, %h0|%h0, %2}";
6403 [(set_attr "isa" "*,nox64")
6405 (if_then_else (match_operand:QI 2 "incdec_operand")
6406 (const_string "incdec")
6407 (const_string "alu")))
6408 (set_attr "mode" "QI")])
6410 (define_insn "*addqi_ext_2"
6411 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
6417 (zero_extract:SI (match_operand 1 "ext_register_operand" "%0")
6421 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
6423 (const_int 8)) 0)) 0))
6424 (clobber (reg:CC FLAGS_REG))]
6425 "/* FIXME: without this LRA can't reload this pattern, see PR82524. */
6426 rtx_equal_p (operands[0], operands[1])
6427 || rtx_equal_p (operands[0], operands[2])"
6428 "add{b}\t{%h2, %h0|%h0, %h2}"
6429 [(set_attr "type" "alu")
6430 (set_attr "mode" "QI")])
6432 ;; Add with jump on overflow.
6433 (define_expand "addv<mode>4"
6434 [(parallel [(set (reg:CCO FLAGS_REG)
6437 (match_operand:SWI 1 "nonimmediate_operand"))
6440 (plus:SWI (match_dup 1)
6441 (match_operand:SWI 2
6442 "<general_operand>")))))
6443 (set (match_operand:SWI 0 "register_operand")
6444 (plus:SWI (match_dup 1) (match_dup 2)))])
6445 (set (pc) (if_then_else
6446 (eq (reg:CCO FLAGS_REG) (const_int 0))
6447 (label_ref (match_operand 3))
6451 ix86_fixup_binary_operands_no_copy (PLUS, <MODE>mode, operands);
6452 if (CONST_INT_P (operands[2]))
6453 operands[4] = operands[2];
6455 operands[4] = gen_rtx_SIGN_EXTEND (<DWI>mode, operands[2]);
6458 (define_insn "*addv<mode>4"
6459 [(set (reg:CCO FLAGS_REG)
6462 (match_operand:SWI 1 "nonimmediate_operand" "%0,0"))
6464 (match_operand:SWI 2 "<general_sext_operand>"
6467 (plus:SWI (match_dup 1) (match_dup 2)))))
6468 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
6469 (plus:SWI (match_dup 1) (match_dup 2)))]
6470 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6471 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6472 [(set_attr "type" "alu")
6473 (set_attr "mode" "<MODE>")])
6475 (define_insn "*addv<mode>4_1"
6476 [(set (reg:CCO FLAGS_REG)
6479 (match_operand:SWI 1 "nonimmediate_operand" "0"))
6480 (match_operand:<DWI> 3 "const_int_operand" "i"))
6482 (plus:SWI (match_dup 1)
6483 (match_operand:SWI 2 "x86_64_immediate_operand"
6485 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
6486 (plus:SWI (match_dup 1) (match_dup 2)))]
6487 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)
6488 && CONST_INT_P (operands[2])
6489 && INTVAL (operands[2]) == INTVAL (operands[3])"
6490 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6491 [(set_attr "type" "alu")
6492 (set_attr "mode" "<MODE>")
6493 (set (attr "length_immediate")
6494 (cond [(match_test "IN_RANGE (INTVAL (operands[2]), -128, 127)")
6496 (match_test "<MODE_SIZE> == 8")
6498 (const_string "<MODE_SIZE>")))])
6500 (define_expand "uaddv<mode>4"
6501 [(parallel [(set (reg:CCC FLAGS_REG)
6504 (match_operand:SWI 1 "nonimmediate_operand")
6505 (match_operand:SWI 2 "<general_operand>"))
6507 (set (match_operand:SWI 0 "register_operand")
6508 (plus:SWI (match_dup 1) (match_dup 2)))])
6509 (set (pc) (if_then_else
6510 (ltu (reg:CCC FLAGS_REG) (const_int 0))
6511 (label_ref (match_operand 3))
6514 "ix86_fixup_binary_operands_no_copy (PLUS, <MODE>mode, operands);")
6516 ;; The lea patterns for modes less than 32 bits need to be matched by
6517 ;; several insns converted to real lea by splitters.
6519 (define_insn_and_split "*lea<mode>_general_1"
6520 [(set (match_operand:SWI12 0 "register_operand" "=r")
6522 (plus:SWI12 (match_operand:SWI12 1 "index_register_operand" "l")
6523 (match_operand:SWI12 2 "register_operand" "r"))
6524 (match_operand:SWI12 3 "immediate_operand" "i")))]
6525 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
6527 "&& reload_completed"
6530 (plus:SI (match_dup 1) (match_dup 2))
6533 operands[0] = gen_lowpart (SImode, operands[0]);
6534 operands[1] = gen_lowpart (SImode, operands[1]);
6535 operands[2] = gen_lowpart (SImode, operands[2]);
6536 operands[3] = gen_lowpart (SImode, operands[3]);
6538 [(set_attr "type" "lea")
6539 (set_attr "mode" "SI")])
6541 (define_insn_and_split "*lea<mode>_general_2"
6542 [(set (match_operand:SWI12 0 "register_operand" "=r")
6544 (mult:SWI12 (match_operand:SWI12 1 "index_register_operand" "l")
6545 (match_operand 2 "const248_operand" "n"))
6546 (match_operand:SWI12 3 "nonmemory_operand" "ri")))]
6547 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
6549 "&& reload_completed"
6552 (mult:SI (match_dup 1) (match_dup 2))
6555 operands[0] = gen_lowpart (SImode, operands[0]);
6556 operands[1] = gen_lowpart (SImode, operands[1]);
6557 operands[3] = gen_lowpart (SImode, operands[3]);
6559 [(set_attr "type" "lea")
6560 (set_attr "mode" "SI")])
6562 (define_insn_and_split "*lea<mode>_general_2b"
6563 [(set (match_operand:SWI12 0 "register_operand" "=r")
6565 (ashift:SWI12 (match_operand:SWI12 1 "index_register_operand" "l")
6566 (match_operand 2 "const123_operand" "n"))
6567 (match_operand:SWI12 3 "nonmemory_operand" "ri")))]
6568 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
6570 "&& reload_completed"
6573 (ashift:SI (match_dup 1) (match_dup 2))
6576 operands[0] = gen_lowpart (SImode, operands[0]);
6577 operands[1] = gen_lowpart (SImode, operands[1]);
6578 operands[3] = gen_lowpart (SImode, operands[3]);
6580 [(set_attr "type" "lea")
6581 (set_attr "mode" "SI")])
6583 (define_insn_and_split "*lea<mode>_general_3"
6584 [(set (match_operand:SWI12 0 "register_operand" "=r")
6587 (mult:SWI12 (match_operand:SWI12 1 "index_register_operand" "l")
6588 (match_operand 2 "const248_operand" "n"))
6589 (match_operand:SWI12 3 "register_operand" "r"))
6590 (match_operand:SWI12 4 "immediate_operand" "i")))]
6591 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
6593 "&& reload_completed"
6597 (mult:SI (match_dup 1) (match_dup 2))
6601 operands[0] = gen_lowpart (SImode, operands[0]);
6602 operands[1] = gen_lowpart (SImode, operands[1]);
6603 operands[3] = gen_lowpart (SImode, operands[3]);
6604 operands[4] = gen_lowpart (SImode, operands[4]);
6606 [(set_attr "type" "lea")
6607 (set_attr "mode" "SI")])
6609 (define_insn_and_split "*lea<mode>_general_3b"
6610 [(set (match_operand:SWI12 0 "register_operand" "=r")
6613 (ashift:SWI12 (match_operand:SWI12 1 "index_register_operand" "l")
6614 (match_operand 2 "const123_operand" "n"))
6615 (match_operand:SWI12 3 "register_operand" "r"))
6616 (match_operand:SWI12 4 "immediate_operand" "i")))]
6617 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
6619 "&& reload_completed"
6623 (ashift:SI (match_dup 1) (match_dup 2))
6627 operands[0] = gen_lowpart (SImode, operands[0]);
6628 operands[1] = gen_lowpart (SImode, operands[1]);
6629 operands[3] = gen_lowpart (SImode, operands[3]);
6630 operands[4] = gen_lowpart (SImode, operands[4]);
6632 [(set_attr "type" "lea")
6633 (set_attr "mode" "SI")])
6635 (define_insn_and_split "*lea<mode>_general_4"
6636 [(set (match_operand:SWI12 0 "register_operand" "=r")
6639 (match_operand:SWI12 1 "index_register_operand" "l")
6640 (match_operand 2 "const_0_to_3_operand" "n"))
6641 (match_operand 3 "const_int_operand" "n")))]
6642 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6643 && ((unsigned HOST_WIDE_INT) INTVAL (operands[3])
6644 < (HOST_WIDE_INT_1U << INTVAL (operands[2])))"
6646 "&& reload_completed"
6649 (mult:SI (match_dup 1) (match_dup 2))
6652 operands[0] = gen_lowpart (SImode, operands[0]);
6653 operands[1] = gen_lowpart (SImode, operands[1]);
6654 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
6656 [(set_attr "type" "lea")
6657 (set_attr "mode" "SI")])
6659 (define_insn_and_split "*lea<mode>_general_4"
6660 [(set (match_operand:SWI48 0 "register_operand" "=r")
6663 (match_operand:SWI48 1 "index_register_operand" "l")
6664 (match_operand 2 "const_0_to_3_operand" "n"))
6665 (match_operand 3 "const_int_operand" "n")))]
6666 "(unsigned HOST_WIDE_INT) INTVAL (operands[3])
6667 < (HOST_WIDE_INT_1U << INTVAL (operands[2]))"
6669 "&& reload_completed"
6672 (mult:SWI48 (match_dup 1) (match_dup 2))
6674 "operands[2] = GEN_INT (1 << INTVAL (operands[2]));"
6675 [(set_attr "type" "lea")
6676 (set_attr "mode" "<MODE>")])
6678 ;; Subtract instructions
6680 (define_expand "sub<mode>3"
6681 [(set (match_operand:SDWIM 0 "nonimmediate_operand")
6682 (minus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")
6683 (match_operand:SDWIM 2 "<general_hilo_operand>")))]
6685 "ix86_expand_binary_operator (MINUS, <MODE>mode, operands); DONE;")
6687 (define_insn_and_split "*sub<dwi>3_doubleword"
6688 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
6690 (match_operand:<DWI> 1 "nonimmediate_operand" "0,0")
6691 (match_operand:<DWI> 2 "x86_64_hilo_general_operand"
6693 (clobber (reg:CC FLAGS_REG))]
6694 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6697 [(parallel [(set (reg:CC FLAGS_REG)
6698 (compare:CC (match_dup 1) (match_dup 2)))
6700 (minus:DWIH (match_dup 1) (match_dup 2)))])
6701 (parallel [(set (match_dup 3)
6705 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0)))
6707 (clobber (reg:CC FLAGS_REG))])]
6709 split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
6710 if (operands[2] == const0_rtx)
6712 ix86_expand_binary_operator (MINUS, <MODE>mode, &operands[3]);
6717 (define_insn "*sub<mode>_1"
6718 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6720 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6721 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6722 (clobber (reg:CC FLAGS_REG))]
6723 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6724 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6725 [(set_attr "type" "alu")
6726 (set_attr "mode" "<MODE>")])
6728 (define_insn "*subsi_1_zext"
6729 [(set (match_operand:DI 0 "register_operand" "=r")
6731 (minus:SI (match_operand:SI 1 "register_operand" "0")
6732 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
6733 (clobber (reg:CC FLAGS_REG))]
6734 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6735 "sub{l}\t{%2, %k0|%k0, %2}"
6736 [(set_attr "type" "alu")
6737 (set_attr "mode" "SI")])
6739 (define_insn "*subqi_1_slp"
6740 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6741 (minus:QI (match_dup 0)
6742 (match_operand:QI 1 "general_operand" "qn,qm")))
6743 (clobber (reg:CC FLAGS_REG))]
6744 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6745 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
6746 "sub{b}\t{%1, %0|%0, %1}"
6747 [(set_attr "type" "alu1")
6748 (set_attr "mode" "QI")])
6750 (define_insn "*sub<mode>_2"
6751 [(set (reg FLAGS_REG)
6754 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6755 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6757 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6758 (minus:SWI (match_dup 1) (match_dup 2)))]
6759 "ix86_match_ccmode (insn, CCGOCmode)
6760 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6761 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6762 [(set_attr "type" "alu")
6763 (set_attr "mode" "<MODE>")])
6765 (define_insn "*subsi_2_zext"
6766 [(set (reg FLAGS_REG)
6768 (minus:SI (match_operand:SI 1 "register_operand" "0")
6769 (match_operand:SI 2 "x86_64_general_operand" "rme"))
6771 (set (match_operand:DI 0 "register_operand" "=r")
6773 (minus:SI (match_dup 1)
6775 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6776 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6777 "sub{l}\t{%2, %k0|%k0, %2}"
6778 [(set_attr "type" "alu")
6779 (set_attr "mode" "SI")])
6781 ;; Subtract with jump on overflow.
6782 (define_expand "subv<mode>4"
6783 [(parallel [(set (reg:CCO FLAGS_REG)
6784 (eq:CCO (minus:<DWI>
6786 (match_operand:SWI 1 "nonimmediate_operand"))
6789 (minus:SWI (match_dup 1)
6790 (match_operand:SWI 2
6791 "<general_operand>")))))
6792 (set (match_operand:SWI 0 "register_operand")
6793 (minus:SWI (match_dup 1) (match_dup 2)))])
6794 (set (pc) (if_then_else
6795 (eq (reg:CCO FLAGS_REG) (const_int 0))
6796 (label_ref (match_operand 3))
6800 ix86_fixup_binary_operands_no_copy (MINUS, <MODE>mode, operands);
6801 if (CONST_INT_P (operands[2]))
6802 operands[4] = operands[2];
6804 operands[4] = gen_rtx_SIGN_EXTEND (<DWI>mode, operands[2]);
6807 (define_insn "*subv<mode>4"
6808 [(set (reg:CCO FLAGS_REG)
6809 (eq:CCO (minus:<DWI>
6811 (match_operand:SWI 1 "nonimmediate_operand" "0,0"))
6813 (match_operand:SWI 2 "<general_sext_operand>"
6816 (minus:SWI (match_dup 1) (match_dup 2)))))
6817 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6818 (minus:SWI (match_dup 1) (match_dup 2)))]
6819 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6820 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6821 [(set_attr "type" "alu")
6822 (set_attr "mode" "<MODE>")])
6824 (define_insn "*subv<mode>4_1"
6825 [(set (reg:CCO FLAGS_REG)
6826 (eq:CCO (minus:<DWI>
6828 (match_operand:SWI 1 "nonimmediate_operand" "0"))
6829 (match_operand:<DWI> 3 "const_int_operand" "i"))
6831 (minus:SWI (match_dup 1)
6832 (match_operand:SWI 2 "x86_64_immediate_operand"
6834 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
6835 (minus:SWI (match_dup 1) (match_dup 2)))]
6836 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)
6837 && CONST_INT_P (operands[2])
6838 && INTVAL (operands[2]) == INTVAL (operands[3])"
6839 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6840 [(set_attr "type" "alu")
6841 (set_attr "mode" "<MODE>")
6842 (set (attr "length_immediate")
6843 (cond [(match_test "IN_RANGE (INTVAL (operands[2]), -128, 127)")
6845 (match_test "<MODE_SIZE> == 8")
6847 (const_string "<MODE_SIZE>")))])
6849 (define_expand "usubv<mode>4"
6850 [(parallel [(set (reg:CC FLAGS_REG)
6852 (match_operand:SWI 1 "nonimmediate_operand")
6853 (match_operand:SWI 2 "<general_operand>")))
6854 (set (match_operand:SWI 0 "register_operand")
6855 (minus:SWI (match_dup 1) (match_dup 2)))])
6856 (set (pc) (if_then_else
6857 (ltu (reg:CC FLAGS_REG) (const_int 0))
6858 (label_ref (match_operand 3))
6861 "ix86_fixup_binary_operands_no_copy (MINUS, <MODE>mode, operands);")
6863 (define_insn "*sub<mode>_3"
6864 [(set (reg FLAGS_REG)
6865 (compare (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6866 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6867 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6868 (minus:SWI (match_dup 1) (match_dup 2)))]
6869 "ix86_match_ccmode (insn, CCmode)
6870 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6871 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6872 [(set_attr "type" "alu")
6873 (set_attr "mode" "<MODE>")])
6877 [(set (reg:CC FLAGS_REG)
6878 (compare:CC (match_operand:SWI 0 "general_reg_operand")
6879 (match_operand:SWI 1 "general_gr_operand")))
6881 (minus:SWI (match_dup 0) (match_dup 1)))])]
6882 "find_regno_note (peep2_next_insn (0), REG_UNUSED, REGNO (operands[0])) != 0"
6883 [(set (reg:CC FLAGS_REG)
6884 (compare:CC (match_dup 0) (match_dup 1)))])
6886 (define_insn "*subsi_3_zext"
6887 [(set (reg FLAGS_REG)
6888 (compare (match_operand:SI 1 "register_operand" "0")
6889 (match_operand:SI 2 "x86_64_general_operand" "rme")))
6890 (set (match_operand:DI 0 "register_operand" "=r")
6892 (minus:SI (match_dup 1)
6894 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6895 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6896 "sub{l}\t{%2, %1|%1, %2}"
6897 [(set_attr "type" "alu")
6898 (set_attr "mode" "SI")])
6900 ;; Add with carry and subtract with borrow
6902 (define_insn "add<mode>3_carry"
6903 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6906 (match_operator:SWI 4 "ix86_carry_flag_operator"
6907 [(match_operand 3 "flags_reg_operand") (const_int 0)])
6908 (match_operand:SWI 1 "nonimmediate_operand" "%0,0"))
6909 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6910 (clobber (reg:CC FLAGS_REG))]
6911 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6912 "adc{<imodesuffix>}\t{%2, %0|%0, %2}"
6913 [(set_attr "type" "alu")
6914 (set_attr "use_carry" "1")
6915 (set_attr "pent_pair" "pu")
6916 (set_attr "mode" "<MODE>")])
6918 (define_insn "*add<mode>3_carry_0"
6919 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
6921 (match_operator:SWI 3 "ix86_carry_flag_operator"
6922 [(match_operand 2 "flags_reg_operand") (const_int 0)])
6923 (match_operand:SWI 1 "nonimmediate_operand" "0")))
6924 (clobber (reg:CC FLAGS_REG))]
6925 "ix86_unary_operator_ok (PLUS, <MODE>mode, operands)"
6926 "adc{<imodesuffix>}\t{$0, %0|%0, 0}"
6927 [(set_attr "type" "alu")
6928 (set_attr "use_carry" "1")
6929 (set_attr "pent_pair" "pu")
6930 (set_attr "mode" "<MODE>")])
6932 (define_insn "*addsi3_carry_zext"
6933 [(set (match_operand:DI 0 "register_operand" "=r")
6936 (plus:SI (match_operator:SI 3 "ix86_carry_flag_operator"
6937 [(reg FLAGS_REG) (const_int 0)])
6938 (match_operand:SI 1 "register_operand" "%0"))
6939 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
6940 (clobber (reg:CC FLAGS_REG))]
6941 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6942 "adc{l}\t{%2, %k0|%k0, %2}"
6943 [(set_attr "type" "alu")
6944 (set_attr "use_carry" "1")
6945 (set_attr "pent_pair" "pu")
6946 (set_attr "mode" "SI")])
6948 (define_insn "*addsi3_carry_zext_0"
6949 [(set (match_operand:DI 0 "register_operand" "=r")
6951 (plus:SI (match_operator:SI 2 "ix86_carry_flag_operator"
6952 [(reg FLAGS_REG) (const_int 0)])
6953 (match_operand:SI 1 "register_operand" "0"))))
6954 (clobber (reg:CC FLAGS_REG))]
6956 "adc{l}\t{$0, %k0|%k0, 0}"
6957 [(set_attr "type" "alu")
6958 (set_attr "use_carry" "1")
6959 (set_attr "pent_pair" "pu")
6960 (set_attr "mode" "SI")])
6962 ;; There is no point to generate ADCX instruction. ADC is shorter and faster.
6964 (define_insn "addcarry<mode>"
6965 [(set (reg:CCC FLAGS_REG)
6970 (match_operator:SWI48 5 "ix86_carry_flag_operator"
6971 [(match_operand 3 "flags_reg_operand") (const_int 0)])
6972 (match_operand:SWI48 1 "nonimmediate_operand" "%0"))
6973 (match_operand:SWI48 2 "nonimmediate_operand" "rm")))
6975 (zero_extend:<DWI> (match_dup 2))
6976 (match_operator:<DWI> 4 "ix86_carry_flag_operator"
6977 [(match_dup 3) (const_int 0)]))))
6978 (set (match_operand:SWI48 0 "register_operand" "=r")
6979 (plus:SWI48 (plus:SWI48 (match_op_dup 5
6980 [(match_dup 3) (const_int 0)])
6983 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6984 "adc{<imodesuffix>}\t{%2, %0|%0, %2}"
6985 [(set_attr "type" "alu")
6986 (set_attr "use_carry" "1")
6987 (set_attr "pent_pair" "pu")
6988 (set_attr "mode" "<MODE>")])
6990 (define_expand "addcarry<mode>_0"
6992 [(set (reg:CCC FLAGS_REG)
6995 (match_operand:SWI48 1 "nonimmediate_operand")
6996 (match_operand:SWI48 2 "x86_64_general_operand"))
6998 (set (match_operand:SWI48 0 "register_operand")
6999 (plus:SWI48 (match_dup 1) (match_dup 2)))])]
7000 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)")
7002 (define_insn "sub<mode>3_carry"
7003 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
7006 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
7007 (match_operator:SWI 4 "ix86_carry_flag_operator"
7008 [(match_operand 3 "flags_reg_operand") (const_int 0)]))
7009 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
7010 (clobber (reg:CC FLAGS_REG))]
7011 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
7012 "sbb{<imodesuffix>}\t{%2, %0|%0, %2}"
7013 [(set_attr "type" "alu")
7014 (set_attr "use_carry" "1")
7015 (set_attr "pent_pair" "pu")
7016 (set_attr "mode" "<MODE>")])
7018 (define_insn "*sub<mode>3_carry_0"
7019 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
7021 (match_operand:SWI 1 "nonimmediate_operand" "0")
7022 (match_operator:SWI 3 "ix86_carry_flag_operator"
7023 [(match_operand 2 "flags_reg_operand") (const_int 0)])))
7024 (clobber (reg:CC FLAGS_REG))]
7025 "ix86_unary_operator_ok (MINUS, <MODE>mode, operands)"
7026 "sbb{<imodesuffix>}\t{$0, %0|%0, 0}"
7027 [(set_attr "type" "alu")
7028 (set_attr "use_carry" "1")
7029 (set_attr "pent_pair" "pu")
7030 (set_attr "mode" "<MODE>")])
7032 (define_insn "*subsi3_carry_zext"
7033 [(set (match_operand:DI 0 "register_operand" "=r")
7037 (match_operand:SI 1 "register_operand" "0")
7038 (match_operator:SI 3 "ix86_carry_flag_operator"
7039 [(reg FLAGS_REG) (const_int 0)]))
7040 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
7041 (clobber (reg:CC FLAGS_REG))]
7042 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
7043 "sbb{l}\t{%2, %k0|%k0, %2}"
7044 [(set_attr "type" "alu")
7045 (set_attr "use_carry" "1")
7046 (set_attr "pent_pair" "pu")
7047 (set_attr "mode" "SI")])
7049 (define_insn "*subsi3_carry_zext_0"
7050 [(set (match_operand:DI 0 "register_operand" "=r")
7053 (match_operand:SI 1 "register_operand" "0")
7054 (match_operator:SI 2 "ix86_carry_flag_operator"
7055 [(reg FLAGS_REG) (const_int 0)]))))
7056 (clobber (reg:CC FLAGS_REG))]
7058 "sbb{l}\t{$0, %k0|%k0, 0}"
7059 [(set_attr "type" "alu")
7060 (set_attr "use_carry" "1")
7061 (set_attr "pent_pair" "pu")
7062 (set_attr "mode" "SI")])
7064 (define_insn "sub<mode>3_carry_ccc"
7065 [(set (reg:CCC FLAGS_REG)
7067 (zero_extend:<DWI> (match_operand:DWIH 1 "register_operand" "0"))
7069 (ltu:<DWI> (reg:CC FLAGS_REG) (const_int 0))
7071 (match_operand:DWIH 2 "x86_64_sext_operand" "rmWe")))))
7072 (clobber (match_scratch:DWIH 0 "=r"))]
7074 "sbb{<imodesuffix>}\t{%2, %0|%0, %2}"
7075 [(set_attr "type" "alu")
7076 (set_attr "mode" "<MODE>")])
7078 (define_insn "*sub<mode>3_carry_ccc_1"
7079 [(set (reg:CCC FLAGS_REG)
7081 (zero_extend:<DWI> (match_operand:DWIH 1 "register_operand" "0"))
7083 (ltu:<DWI> (reg:CC FLAGS_REG) (const_int 0))
7084 (match_operand:<DWI> 2 "x86_64_dwzext_immediate_operand" "Wf"))))
7085 (clobber (match_scratch:DWIH 0 "=r"))]
7088 operands[3] = simplify_subreg (<MODE>mode, operands[2], <DWI>mode, 0);
7089 return "sbb{<imodesuffix>}\t{%3, %0|%0, %3}";
7091 [(set_attr "type" "alu")
7092 (set_attr "mode" "<MODE>")])
7094 ;; The sign flag is set from the
7095 ;; (compare (match_dup 1) (plus:DWIH (ltu:DWIH ...) (match_dup 2)))
7096 ;; result, the overflow flag likewise, but the overflow flag is also
7097 ;; set if the (plus:DWIH (ltu:DWIH ...) (match_dup 2)) overflows.
7098 (define_insn "sub<mode>3_carry_ccgz"
7099 [(set (reg:CCGZ FLAGS_REG)
7100 (unspec:CCGZ [(match_operand:DWIH 1 "register_operand" "0")
7101 (match_operand:DWIH 2 "x86_64_general_operand" "rme")
7102 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))]
7104 (clobber (match_scratch:DWIH 0 "=r"))]
7106 "sbb{<imodesuffix>}\t{%2, %0|%0, %2}"
7107 [(set_attr "type" "alu")
7108 (set_attr "mode" "<MODE>")])
7110 (define_insn "subborrow<mode>"
7111 [(set (reg:CCC FLAGS_REG)
7114 (match_operand:SWI48 1 "nonimmediate_operand" "0"))
7116 (match_operator:<DWI> 4 "ix86_carry_flag_operator"
7117 [(match_operand 3 "flags_reg_operand") (const_int 0)])
7119 (match_operand:SWI48 2 "nonimmediate_operand" "rm")))))
7120 (set (match_operand:SWI48 0 "register_operand" "=r")
7121 (minus:SWI48 (minus:SWI48
7123 (match_operator:SWI48 5 "ix86_carry_flag_operator"
7124 [(match_dup 3) (const_int 0)]))
7126 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
7127 "sbb{<imodesuffix>}\t{%2, %0|%0, %2}"
7128 [(set_attr "type" "alu")
7129 (set_attr "use_carry" "1")
7130 (set_attr "pent_pair" "pu")
7131 (set_attr "mode" "<MODE>")])
7133 (define_expand "subborrow<mode>_0"
7135 [(set (reg:CC FLAGS_REG)
7137 (match_operand:SWI48 1 "nonimmediate_operand")
7138 (match_operand:SWI48 2 "<general_operand>")))
7139 (set (match_operand:SWI48 0 "register_operand")
7140 (minus:SWI48 (match_dup 1) (match_dup 2)))])]
7141 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)")
7143 ;; Overflow setting add instructions
7145 (define_expand "addqi3_cconly_overflow"
7147 [(set (reg:CCC FLAGS_REG)
7150 (match_operand:QI 0 "nonimmediate_operand")
7151 (match_operand:QI 1 "general_operand"))
7153 (clobber (match_scratch:QI 2))])]
7154 "!(MEM_P (operands[0]) && MEM_P (operands[1]))")
7156 (define_insn "*add<mode>3_cconly_overflow_1"
7157 [(set (reg:CCC FLAGS_REG)
7160 (match_operand:SWI 1 "nonimmediate_operand" "%0")
7161 (match_operand:SWI 2 "<general_operand>" "<g>"))
7163 (clobber (match_scratch:SWI 0 "=<r>"))]
7164 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7165 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
7166 [(set_attr "type" "alu")
7167 (set_attr "mode" "<MODE>")])
7169 (define_insn "*add<mode>3_cc_overflow_1"
7170 [(set (reg:CCC FLAGS_REG)
7173 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
7174 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
7176 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
7177 (plus:SWI (match_dup 1) (match_dup 2)))]
7178 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
7179 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
7180 [(set_attr "type" "alu")
7181 (set_attr "mode" "<MODE>")])
7183 (define_insn "*addsi3_zext_cc_overflow_1"
7184 [(set (reg:CCC FLAGS_REG)
7187 (match_operand:SI 1 "nonimmediate_operand" "%0")
7188 (match_operand:SI 2 "x86_64_general_operand" "rme"))
7190 (set (match_operand:DI 0 "register_operand" "=r")
7191 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
7192 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
7193 "add{l}\t{%2, %k0|%k0, %2}"
7194 [(set_attr "type" "alu")
7195 (set_attr "mode" "SI")])
7197 (define_insn "*add<mode>3_cconly_overflow_2"
7198 [(set (reg:CCC FLAGS_REG)
7201 (match_operand:SWI 1 "nonimmediate_operand" "%0")
7202 (match_operand:SWI 2 "<general_operand>" "<g>"))
7204 (clobber (match_scratch:SWI 0 "=<r>"))]
7205 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7206 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
7207 [(set_attr "type" "alu")
7208 (set_attr "mode" "<MODE>")])
7210 (define_insn "*add<mode>3_cc_overflow_2"
7211 [(set (reg:CCC FLAGS_REG)
7214 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
7215 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
7217 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
7218 (plus:SWI (match_dup 1) (match_dup 2)))]
7219 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
7220 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
7221 [(set_attr "type" "alu")
7222 (set_attr "mode" "<MODE>")])
7224 (define_insn "*addsi3_zext_cc_overflow_2"
7225 [(set (reg:CCC FLAGS_REG)
7228 (match_operand:SI 1 "nonimmediate_operand" "%0")
7229 (match_operand:SI 2 "x86_64_general_operand" "rme"))
7231 (set (match_operand:DI 0 "register_operand" "=r")
7232 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
7233 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
7234 "add{l}\t{%2, %k0|%k0, %2}"
7235 [(set_attr "type" "alu")
7236 (set_attr "mode" "SI")])
7238 ;; The patterns that match these are at the end of this file.
7240 (define_expand "<plusminus_insn>xf3"
7241 [(set (match_operand:XF 0 "register_operand")
7243 (match_operand:XF 1 "register_operand")
7244 (match_operand:XF 2 "register_operand")))]
7247 (define_expand "<plusminus_insn><mode>3"
7248 [(set (match_operand:MODEF 0 "register_operand")
7250 (match_operand:MODEF 1 "register_operand")
7251 (match_operand:MODEF 2 "nonimmediate_operand")))]
7252 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
7253 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
7255 ;; Multiply instructions
7257 (define_expand "mul<mode>3"
7258 [(parallel [(set (match_operand:SWIM248 0 "register_operand")
7260 (match_operand:SWIM248 1 "register_operand")
7261 (match_operand:SWIM248 2 "<general_operand>")))
7262 (clobber (reg:CC FLAGS_REG))])])
7264 (define_expand "mulqi3"
7265 [(parallel [(set (match_operand:QI 0 "register_operand")
7267 (match_operand:QI 1 "register_operand")
7268 (match_operand:QI 2 "nonimmediate_operand")))
7269 (clobber (reg:CC FLAGS_REG))])]
7270 "TARGET_QIMODE_MATH")
7273 ;; IMUL reg32/64, reg32/64, imm8 Direct
7274 ;; IMUL reg32/64, mem32/64, imm8 VectorPath
7275 ;; IMUL reg32/64, reg32/64, imm32 Direct
7276 ;; IMUL reg32/64, mem32/64, imm32 VectorPath
7277 ;; IMUL reg32/64, reg32/64 Direct
7278 ;; IMUL reg32/64, mem32/64 Direct
7280 ;; On BDVER1, all above IMULs use DirectPath
7283 ;; IMUL reg16, reg16, imm8 VectorPath
7284 ;; IMUL reg16, mem16, imm8 VectorPath
7285 ;; IMUL reg16, reg16, imm16 VectorPath
7286 ;; IMUL reg16, mem16, imm16 VectorPath
7287 ;; IMUL reg16, reg16 Direct
7288 ;; IMUL reg16, mem16 Direct
7290 ;; On BDVER1, all HI MULs use DoublePath
7292 (define_insn "*mul<mode>3_1"
7293 [(set (match_operand:SWIM248 0 "register_operand" "=r,r,r")
7295 (match_operand:SWIM248 1 "nonimmediate_operand" "%rm,rm,0")
7296 (match_operand:SWIM248 2 "<general_operand>" "K,<i>,mr")))
7297 (clobber (reg:CC FLAGS_REG))]
7298 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7300 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
7301 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
7302 imul{<imodesuffix>}\t{%2, %0|%0, %2}"
7303 [(set_attr "type" "imul")
7304 (set_attr "prefix_0f" "0,0,1")
7305 (set (attr "athlon_decode")
7306 (cond [(eq_attr "cpu" "athlon")
7307 (const_string "vector")
7308 (eq_attr "alternative" "1")
7309 (const_string "vector")
7310 (and (eq_attr "alternative" "2")
7311 (ior (match_test "<MODE>mode == HImode")
7312 (match_operand 1 "memory_operand")))
7313 (const_string "vector")]
7314 (const_string "direct")))
7315 (set (attr "amdfam10_decode")
7316 (cond [(and (eq_attr "alternative" "0,1")
7317 (ior (match_test "<MODE>mode == HImode")
7318 (match_operand 1 "memory_operand")))
7319 (const_string "vector")]
7320 (const_string "direct")))
7321 (set (attr "bdver1_decode")
7323 (match_test "<MODE>mode == HImode")
7324 (const_string "double")
7325 (const_string "direct")))
7326 (set_attr "mode" "<MODE>")])
7328 (define_insn "*mulsi3_1_zext"
7329 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
7331 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
7332 (match_operand:SI 2 "x86_64_general_operand" "K,e,mr"))))
7333 (clobber (reg:CC FLAGS_REG))]
7335 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7337 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7338 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7339 imul{l}\t{%2, %k0|%k0, %2}"
7340 [(set_attr "type" "imul")
7341 (set_attr "prefix_0f" "0,0,1")
7342 (set (attr "athlon_decode")
7343 (cond [(eq_attr "cpu" "athlon")
7344 (const_string "vector")
7345 (eq_attr "alternative" "1")
7346 (const_string "vector")
7347 (and (eq_attr "alternative" "2")
7348 (match_operand 1 "memory_operand"))
7349 (const_string "vector")]
7350 (const_string "direct")))
7351 (set (attr "amdfam10_decode")
7352 (cond [(and (eq_attr "alternative" "0,1")
7353 (match_operand 1 "memory_operand"))
7354 (const_string "vector")]
7355 (const_string "direct")))
7356 (set_attr "bdver1_decode" "direct")
7357 (set_attr "mode" "SI")])
7359 ;;On AMDFAM10 and BDVER1
7363 (define_insn "*mulqi3_1"
7364 [(set (match_operand:QI 0 "register_operand" "=a")
7365 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
7366 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7367 (clobber (reg:CC FLAGS_REG))]
7369 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7371 [(set_attr "type" "imul")
7372 (set_attr "length_immediate" "0")
7373 (set (attr "athlon_decode")
7374 (if_then_else (eq_attr "cpu" "athlon")
7375 (const_string "vector")
7376 (const_string "direct")))
7377 (set_attr "amdfam10_decode" "direct")
7378 (set_attr "bdver1_decode" "direct")
7379 (set_attr "mode" "QI")])
7381 ;; Multiply with jump on overflow.
7382 (define_expand "mulv<mode>4"
7383 [(parallel [(set (reg:CCO FLAGS_REG)
7386 (match_operand:SWI248 1 "register_operand"))
7389 (mult:SWI248 (match_dup 1)
7390 (match_operand:SWI248 2
7391 "<general_operand>")))))
7392 (set (match_operand:SWI248 0 "register_operand")
7393 (mult:SWI248 (match_dup 1) (match_dup 2)))])
7394 (set (pc) (if_then_else
7395 (eq (reg:CCO FLAGS_REG) (const_int 0))
7396 (label_ref (match_operand 3))
7400 if (CONST_INT_P (operands[2]))
7401 operands[4] = operands[2];
7403 operands[4] = gen_rtx_SIGN_EXTEND (<DWI>mode, operands[2]);
7406 (define_insn "*mulv<mode>4"
7407 [(set (reg:CCO FLAGS_REG)
7410 (match_operand:SWI48 1 "nonimmediate_operand" "%rm,0"))
7412 (match_operand:SWI48 2 "x86_64_sext_operand" "We,mr")))
7414 (mult:SWI48 (match_dup 1) (match_dup 2)))))
7415 (set (match_operand:SWI48 0 "register_operand" "=r,r")
7416 (mult:SWI48 (match_dup 1) (match_dup 2)))]
7417 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7419 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
7420 imul{<imodesuffix>}\t{%2, %0|%0, %2}"
7421 [(set_attr "type" "imul")
7422 (set_attr "prefix_0f" "0,1")
7423 (set (attr "athlon_decode")
7424 (cond [(eq_attr "cpu" "athlon")
7425 (const_string "vector")
7426 (eq_attr "alternative" "0")
7427 (const_string "vector")
7428 (and (eq_attr "alternative" "1")
7429 (match_operand 1 "memory_operand"))
7430 (const_string "vector")]
7431 (const_string "direct")))
7432 (set (attr "amdfam10_decode")
7433 (cond [(and (eq_attr "alternative" "1")
7434 (match_operand 1 "memory_operand"))
7435 (const_string "vector")]
7436 (const_string "direct")))
7437 (set_attr "bdver1_decode" "direct")
7438 (set_attr "mode" "<MODE>")])
7440 (define_insn "*mulvhi4"
7441 [(set (reg:CCO FLAGS_REG)
7444 (match_operand:HI 1 "nonimmediate_operand" "%0"))
7446 (match_operand:HI 2 "nonimmediate_operand" "mr")))
7448 (mult:HI (match_dup 1) (match_dup 2)))))
7449 (set (match_operand:HI 0 "register_operand" "=r")
7450 (mult:HI (match_dup 1) (match_dup 2)))]
7451 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7452 "imul{w}\t{%2, %0|%0, %2}"
7453 [(set_attr "type" "imul")
7454 (set_attr "prefix_0f" "1")
7455 (set_attr "athlon_decode" "vector")
7456 (set_attr "amdfam10_decode" "direct")
7457 (set_attr "bdver1_decode" "double")
7458 (set_attr "mode" "HI")])
7460 (define_insn "*mulv<mode>4_1"
7461 [(set (reg:CCO FLAGS_REG)
7464 (match_operand:SWI248 1 "nonimmediate_operand" "rm,rm"))
7465 (match_operand:<DWI> 3 "const_int_operand" "K,i"))
7467 (mult:SWI248 (match_dup 1)
7468 (match_operand:SWI248 2
7469 "<immediate_operand>" "K,<i>")))))
7470 (set (match_operand:SWI248 0 "register_operand" "=r,r")
7471 (mult:SWI248 (match_dup 1) (match_dup 2)))]
7472 "!(MEM_P (operands[1]) && MEM_P (operands[2]))
7473 && CONST_INT_P (operands[2])
7474 && INTVAL (operands[2]) == INTVAL (operands[3])"
7475 "imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}"
7476 [(set_attr "type" "imul")
7477 (set (attr "prefix_0f")
7479 (match_test "<MODE>mode == HImode")
7481 (const_string "*")))
7482 (set (attr "athlon_decode")
7483 (cond [(eq_attr "cpu" "athlon")
7484 (const_string "vector")
7485 (eq_attr "alternative" "1")
7486 (const_string "vector")]
7487 (const_string "direct")))
7488 (set (attr "amdfam10_decode")
7489 (cond [(ior (match_test "<MODE>mode == HImode")
7490 (match_operand 1 "memory_operand"))
7491 (const_string "vector")]
7492 (const_string "direct")))
7493 (set (attr "bdver1_decode")
7495 (match_test "<MODE>mode == HImode")
7496 (const_string "double")
7497 (const_string "direct")))
7498 (set_attr "mode" "<MODE>")
7499 (set (attr "length_immediate")
7500 (cond [(eq_attr "alternative" "0")
7502 (match_test "<MODE_SIZE> == 8")
7504 (const_string "<MODE_SIZE>")))])
7506 (define_expand "umulv<mode>4"
7507 [(parallel [(set (reg:CCO FLAGS_REG)
7510 (match_operand:SWI248 1
7511 "nonimmediate_operand"))
7513 (match_operand:SWI248 2
7514 "nonimmediate_operand")))
7516 (mult:SWI248 (match_dup 1) (match_dup 2)))))
7517 (set (match_operand:SWI248 0 "register_operand")
7518 (mult:SWI248 (match_dup 1) (match_dup 2)))
7519 (clobber (match_scratch:SWI248 4))])
7520 (set (pc) (if_then_else
7521 (eq (reg:CCO FLAGS_REG) (const_int 0))
7522 (label_ref (match_operand 3))
7526 if (MEM_P (operands[1]) && MEM_P (operands[2]))
7527 operands[1] = force_reg (<MODE>mode, operands[1]);
7530 (define_insn "*umulv<mode>4"
7531 [(set (reg:CCO FLAGS_REG)
7534 (match_operand:SWI248 1 "nonimmediate_operand" "%0"))
7536 (match_operand:SWI248 2 "nonimmediate_operand" "rm")))
7538 (mult:SWI248 (match_dup 1) (match_dup 2)))))
7539 (set (match_operand:SWI248 0 "register_operand" "=a")
7540 (mult:SWI248 (match_dup 1) (match_dup 2)))
7541 (clobber (match_scratch:SWI248 3 "=d"))]
7542 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7543 "mul{<imodesuffix>}\t%2"
7544 [(set_attr "type" "imul")
7545 (set_attr "length_immediate" "0")
7546 (set (attr "athlon_decode")
7547 (if_then_else (eq_attr "cpu" "athlon")
7548 (const_string "vector")
7549 (const_string "double")))
7550 (set_attr "amdfam10_decode" "double")
7551 (set_attr "bdver1_decode" "direct")
7552 (set_attr "mode" "<MODE>")])
7554 (define_expand "<u>mulvqi4"
7555 [(parallel [(set (reg:CCO FLAGS_REG)
7558 (match_operand:QI 1 "nonimmediate_operand"))
7560 (match_operand:QI 2 "nonimmediate_operand")))
7562 (mult:QI (match_dup 1) (match_dup 2)))))
7563 (set (match_operand:QI 0 "register_operand")
7564 (mult:QI (match_dup 1) (match_dup 2)))])
7565 (set (pc) (if_then_else
7566 (eq (reg:CCO FLAGS_REG) (const_int 0))
7567 (label_ref (match_operand 3))
7569 "TARGET_QIMODE_MATH"
7571 if (MEM_P (operands[1]) && MEM_P (operands[2]))
7572 operands[1] = force_reg (QImode, operands[1]);
7575 (define_insn "*<u>mulvqi4"
7576 [(set (reg:CCO FLAGS_REG)
7579 (match_operand:QI 1 "nonimmediate_operand" "%0"))
7581 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7583 (mult:QI (match_dup 1) (match_dup 2)))))
7584 (set (match_operand:QI 0 "register_operand" "=a")
7585 (mult:QI (match_dup 1) (match_dup 2)))]
7587 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7588 "<sgnprefix>mul{b}\t%2"
7589 [(set_attr "type" "imul")
7590 (set_attr "length_immediate" "0")
7591 (set (attr "athlon_decode")
7592 (if_then_else (eq_attr "cpu" "athlon")
7593 (const_string "vector")
7594 (const_string "direct")))
7595 (set_attr "amdfam10_decode" "direct")
7596 (set_attr "bdver1_decode" "direct")
7597 (set_attr "mode" "QI")])
7599 (define_expand "<u>mul<mode><dwi>3"
7600 [(parallel [(set (match_operand:<DWI> 0 "register_operand")
7603 (match_operand:DWIH 1 "nonimmediate_operand"))
7605 (match_operand:DWIH 2 "register_operand"))))
7606 (clobber (reg:CC FLAGS_REG))])])
7608 (define_expand "<u>mulqihi3"
7609 [(parallel [(set (match_operand:HI 0 "register_operand")
7612 (match_operand:QI 1 "nonimmediate_operand"))
7614 (match_operand:QI 2 "register_operand"))))
7615 (clobber (reg:CC FLAGS_REG))])]
7616 "TARGET_QIMODE_MATH")
7618 (define_insn "*bmi2_umul<mode><dwi>3_1"
7619 [(set (match_operand:DWIH 0 "register_operand" "=r")
7621 (match_operand:DWIH 2 "nonimmediate_operand" "%d")
7622 (match_operand:DWIH 3 "nonimmediate_operand" "rm")))
7623 (set (match_operand:DWIH 1 "register_operand" "=r")
7626 (mult:<DWI> (zero_extend:<DWI> (match_dup 2))
7627 (zero_extend:<DWI> (match_dup 3)))
7628 (match_operand:QI 4 "const_int_operand" "n"))))]
7629 "TARGET_BMI2 && INTVAL (operands[4]) == <MODE_SIZE> * BITS_PER_UNIT
7630 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7631 "mulx\t{%3, %0, %1|%1, %0, %3}"
7632 [(set_attr "type" "imulx")
7633 (set_attr "prefix" "vex")
7634 (set_attr "mode" "<MODE>")])
7636 (define_insn "*umul<mode><dwi>3_1"
7637 [(set (match_operand:<DWI> 0 "register_operand" "=r,A")
7640 (match_operand:DWIH 1 "nonimmediate_operand" "%d,0"))
7642 (match_operand:DWIH 2 "nonimmediate_operand" "rm,rm"))))
7643 (clobber (reg:CC FLAGS_REG))]
7644 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7647 mul{<imodesuffix>}\t%2"
7648 [(set_attr "isa" "bmi2,*")
7649 (set_attr "type" "imulx,imul")
7650 (set_attr "length_immediate" "*,0")
7651 (set (attr "athlon_decode")
7652 (cond [(eq_attr "alternative" "1")
7653 (if_then_else (eq_attr "cpu" "athlon")
7654 (const_string "vector")
7655 (const_string "double"))]
7656 (const_string "*")))
7657 (set_attr "amdfam10_decode" "*,double")
7658 (set_attr "bdver1_decode" "*,direct")
7659 (set_attr "prefix" "vex,orig")
7660 (set_attr "mode" "<MODE>")])
7662 ;; Convert mul to the mulx pattern to avoid flags dependency.
7664 [(set (match_operand:<DWI> 0 "register_operand")
7667 (match_operand:DWIH 1 "register_operand"))
7669 (match_operand:DWIH 2 "nonimmediate_operand"))))
7670 (clobber (reg:CC FLAGS_REG))]
7671 "TARGET_BMI2 && reload_completed
7672 && REGNO (operands[1]) == DX_REG"
7673 [(parallel [(set (match_dup 3)
7674 (mult:DWIH (match_dup 1) (match_dup 2)))
7678 (mult:<DWI> (zero_extend:<DWI> (match_dup 1))
7679 (zero_extend:<DWI> (match_dup 2)))
7682 split_double_mode (<DWI>mode, &operands[0], 1, &operands[3], &operands[4]);
7684 operands[5] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT);
7687 (define_insn "*mul<mode><dwi>3_1"
7688 [(set (match_operand:<DWI> 0 "register_operand" "=A")
7691 (match_operand:DWIH 1 "nonimmediate_operand" "%0"))
7693 (match_operand:DWIH 2 "nonimmediate_operand" "rm"))))
7694 (clobber (reg:CC FLAGS_REG))]
7695 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7696 "imul{<imodesuffix>}\t%2"
7697 [(set_attr "type" "imul")
7698 (set_attr "length_immediate" "0")
7699 (set (attr "athlon_decode")
7700 (if_then_else (eq_attr "cpu" "athlon")
7701 (const_string "vector")
7702 (const_string "double")))
7703 (set_attr "amdfam10_decode" "double")
7704 (set_attr "bdver1_decode" "direct")
7705 (set_attr "mode" "<MODE>")])
7707 (define_insn "*<u>mulqihi3_1"
7708 [(set (match_operand:HI 0 "register_operand" "=a")
7711 (match_operand:QI 1 "nonimmediate_operand" "%0"))
7713 (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7714 (clobber (reg:CC FLAGS_REG))]
7716 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7717 "<sgnprefix>mul{b}\t%2"
7718 [(set_attr "type" "imul")
7719 (set_attr "length_immediate" "0")
7720 (set (attr "athlon_decode")
7721 (if_then_else (eq_attr "cpu" "athlon")
7722 (const_string "vector")
7723 (const_string "direct")))
7724 (set_attr "amdfam10_decode" "direct")
7725 (set_attr "bdver1_decode" "direct")
7726 (set_attr "mode" "QI")])
7728 (define_expand "<s>mul<mode>3_highpart"
7729 [(parallel [(set (match_operand:SWI48 0 "register_operand")
7734 (match_operand:SWI48 1 "nonimmediate_operand"))
7736 (match_operand:SWI48 2 "register_operand")))
7738 (clobber (match_scratch:SWI48 4))
7739 (clobber (reg:CC FLAGS_REG))])]
7741 "operands[3] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
7743 (define_insn "*<s>muldi3_highpart_1"
7744 [(set (match_operand:DI 0 "register_operand" "=d")
7749 (match_operand:DI 1 "nonimmediate_operand" "%a"))
7751 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7753 (clobber (match_scratch:DI 3 "=1"))
7754 (clobber (reg:CC FLAGS_REG))]
7756 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7757 "<sgnprefix>mul{q}\t%2"
7758 [(set_attr "type" "imul")
7759 (set_attr "length_immediate" "0")
7760 (set (attr "athlon_decode")
7761 (if_then_else (eq_attr "cpu" "athlon")
7762 (const_string "vector")
7763 (const_string "double")))
7764 (set_attr "amdfam10_decode" "double")
7765 (set_attr "bdver1_decode" "direct")
7766 (set_attr "mode" "DI")])
7768 (define_insn "*<s>mulsi3_highpart_zext"
7769 [(set (match_operand:DI 0 "register_operand" "=d")
7770 (zero_extend:DI (truncate:SI
7772 (mult:DI (any_extend:DI
7773 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7775 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7777 (clobber (match_scratch:SI 3 "=1"))
7778 (clobber (reg:CC FLAGS_REG))]
7780 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7781 "<sgnprefix>mul{l}\t%2"
7782 [(set_attr "type" "imul")
7783 (set_attr "length_immediate" "0")
7784 (set (attr "athlon_decode")
7785 (if_then_else (eq_attr "cpu" "athlon")
7786 (const_string "vector")
7787 (const_string "double")))
7788 (set_attr "amdfam10_decode" "double")
7789 (set_attr "bdver1_decode" "direct")
7790 (set_attr "mode" "SI")])
7792 (define_insn "*<s>mulsi3_highpart_1"
7793 [(set (match_operand:SI 0 "register_operand" "=d")
7798 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7800 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7802 (clobber (match_scratch:SI 3 "=1"))
7803 (clobber (reg:CC FLAGS_REG))]
7804 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7805 "<sgnprefix>mul{l}\t%2"
7806 [(set_attr "type" "imul")
7807 (set_attr "length_immediate" "0")
7808 (set (attr "athlon_decode")
7809 (if_then_else (eq_attr "cpu" "athlon")
7810 (const_string "vector")
7811 (const_string "double")))
7812 (set_attr "amdfam10_decode" "double")
7813 (set_attr "bdver1_decode" "direct")
7814 (set_attr "mode" "SI")])
7816 ;; The patterns that match these are at the end of this file.
7818 (define_expand "mulxf3"
7819 [(set (match_operand:XF 0 "register_operand")
7820 (mult:XF (match_operand:XF 1 "register_operand")
7821 (match_operand:XF 2 "register_operand")))]
7824 (define_expand "mul<mode>3"
7825 [(set (match_operand:MODEF 0 "register_operand")
7826 (mult:MODEF (match_operand:MODEF 1 "register_operand")
7827 (match_operand:MODEF 2 "nonimmediate_operand")))]
7828 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
7829 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
7831 ;; Divide instructions
7833 ;; The patterns that match these are at the end of this file.
7835 (define_expand "divxf3"
7836 [(set (match_operand:XF 0 "register_operand")
7837 (div:XF (match_operand:XF 1 "register_operand")
7838 (match_operand:XF 2 "register_operand")))]
7841 (define_expand "div<mode>3"
7842 [(set (match_operand:MODEF 0 "register_operand")
7843 (div:MODEF (match_operand:MODEF 1 "register_operand")
7844 (match_operand:MODEF 2 "nonimmediate_operand")))]
7845 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
7846 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
7848 if (<MODE>mode == SFmode
7849 && TARGET_SSE && TARGET_SSE_MATH
7851 && optimize_insn_for_speed_p ()
7852 && flag_finite_math_only && !flag_trapping_math
7853 && flag_unsafe_math_optimizations)
7855 ix86_emit_swdivsf (operands[0], operands[1],
7856 operands[2], SFmode);
7861 ;; Divmod instructions.
7863 (define_expand "divmod<mode>4"
7864 [(parallel [(set (match_operand:SWIM248 0 "register_operand")
7866 (match_operand:SWIM248 1 "register_operand")
7867 (match_operand:SWIM248 2 "nonimmediate_operand")))
7868 (set (match_operand:SWIM248 3 "register_operand")
7869 (mod:SWIM248 (match_dup 1) (match_dup 2)))
7870 (clobber (reg:CC FLAGS_REG))])])
7872 ;; Split with 8bit unsigned divide:
7873 ;; if (dividend an divisor are in [0-255])
7874 ;; use 8bit unsigned integer divide
7876 ;; use original integer divide
7878 [(set (match_operand:SWI48 0 "register_operand")
7879 (div:SWI48 (match_operand:SWI48 2 "register_operand")
7880 (match_operand:SWI48 3 "nonimmediate_operand")))
7881 (set (match_operand:SWI48 1 "register_operand")
7882 (mod:SWI48 (match_dup 2) (match_dup 3)))
7883 (clobber (reg:CC FLAGS_REG))]
7884 "TARGET_USE_8BIT_IDIV
7885 && TARGET_QIMODE_MATH
7886 && can_create_pseudo_p ()
7887 && !optimize_insn_for_size_p ()"
7889 "ix86_split_idivmod (<MODE>mode, operands, true); DONE;")
7892 [(set (match_operand:DI 0 "register_operand")
7894 (div:SI (match_operand:SI 2 "register_operand")
7895 (match_operand:SI 3 "nonimmediate_operand"))))
7896 (set (match_operand:SI 1 "register_operand")
7897 (mod:SI (match_dup 2) (match_dup 3)))
7898 (clobber (reg:CC FLAGS_REG))]
7899 "TARGET_USE_8BIT_IDIV
7900 && TARGET_QIMODE_MATH
7901 && can_create_pseudo_p ()
7902 && !optimize_insn_for_size_p ()"
7904 "ix86_split_idivmod (SImode, operands, true); DONE;")
7907 [(set (match_operand:DI 1 "register_operand")
7909 (mod:SI (match_operand:SI 2 "register_operand")
7910 (match_operand:SI 3 "nonimmediate_operand"))))
7911 (set (match_operand:SI 0 "register_operand")
7912 (div:SI (match_dup 2) (match_dup 3)))
7913 (clobber (reg:CC FLAGS_REG))]
7914 "TARGET_USE_8BIT_IDIV
7915 && TARGET_QIMODE_MATH
7916 && can_create_pseudo_p ()
7917 && !optimize_insn_for_size_p ()"
7919 "ix86_split_idivmod (SImode, operands, true); DONE;")
7921 (define_insn_and_split "divmod<mode>4_1"
7922 [(set (match_operand:SWI48 0 "register_operand" "=a")
7923 (div:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7924 (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
7925 (set (match_operand:SWI48 1 "register_operand" "=&d")
7926 (mod:SWI48 (match_dup 2) (match_dup 3)))
7927 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7928 (clobber (reg:CC FLAGS_REG))]
7932 [(parallel [(set (match_dup 1)
7933 (ashiftrt:SWI48 (match_dup 4) (match_dup 5)))
7934 (clobber (reg:CC FLAGS_REG))])
7935 (parallel [(set (match_dup 0)
7936 (div:SWI48 (match_dup 2) (match_dup 3)))
7938 (mod:SWI48 (match_dup 2) (match_dup 3)))
7940 (clobber (reg:CC FLAGS_REG))])]
7942 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7944 if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
7945 operands[4] = operands[2];
7948 /* Avoid use of cltd in favor of a mov+shift. */
7949 emit_move_insn (operands[1], operands[2]);
7950 operands[4] = operands[1];
7953 [(set_attr "type" "multi")
7954 (set_attr "mode" "<MODE>")])
7956 (define_insn_and_split "divmodsi4_zext_1"
7957 [(set (match_operand:DI 0 "register_operand" "=a")
7959 (div:SI (match_operand:SI 2 "register_operand" "0")
7960 (match_operand:SI 3 "nonimmediate_operand" "rm"))))
7961 (set (match_operand:SI 1 "register_operand" "=&d")
7962 (mod:SI (match_dup 2) (match_dup 3)))
7963 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7964 (clobber (reg:CC FLAGS_REG))]
7968 [(parallel [(set (match_dup 1)
7969 (ashiftrt:SI (match_dup 4) (match_dup 5)))
7970 (clobber (reg:CC FLAGS_REG))])
7971 (parallel [(set (match_dup 0)
7972 (zero_extend:DI (div:SI (match_dup 2) (match_dup 3))))
7974 (mod:SI (match_dup 2) (match_dup 3)))
7976 (clobber (reg:CC FLAGS_REG))])]
7978 operands[5] = GEN_INT (GET_MODE_BITSIZE (SImode)-1);
7980 if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
7981 operands[4] = operands[2];
7984 /* Avoid use of cltd in favor of a mov+shift. */
7985 emit_move_insn (operands[1], operands[2]);
7986 operands[4] = operands[1];
7989 [(set_attr "type" "multi")
7990 (set_attr "mode" "SI")])
7992 (define_insn_and_split "divmodsi4_zext_2"
7993 [(set (match_operand:DI 1 "register_operand" "=&d")
7995 (mod:SI (match_operand:SI 2 "register_operand" "0")
7996 (match_operand:SI 3 "nonimmediate_operand" "rm"))))
7997 (set (match_operand:SI 0 "register_operand" "=a")
7998 (div:SI (match_dup 2) (match_dup 3)))
7999 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
8000 (clobber (reg:CC FLAGS_REG))]
8004 [(parallel [(set (match_dup 6)
8005 (ashiftrt:SI (match_dup 4) (match_dup 5)))
8006 (clobber (reg:CC FLAGS_REG))])
8007 (parallel [(set (match_dup 1)
8008 (zero_extend:DI (mod:SI (match_dup 2) (match_dup 3))))
8010 (div:SI (match_dup 2) (match_dup 3)))
8012 (clobber (reg:CC FLAGS_REG))])]
8014 operands[5] = GEN_INT (GET_MODE_BITSIZE (SImode)-1);
8015 operands[6] = gen_lowpart (SImode, operands[1]);
8017 if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
8018 operands[4] = operands[2];
8021 /* Avoid use of cltd in favor of a mov+shift. */
8022 emit_move_insn (operands[6], operands[2]);
8023 operands[4] = operands[6];
8026 [(set_attr "type" "multi")
8027 (set_attr "mode" "SI")])
8029 (define_insn_and_split "*divmod<mode>4"
8030 [(set (match_operand:SWIM248 0 "register_operand" "=a")
8031 (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
8032 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
8033 (set (match_operand:SWIM248 1 "register_operand" "=&d")
8034 (mod:SWIM248 (match_dup 2) (match_dup 3)))
8035 (clobber (reg:CC FLAGS_REG))]
8039 [(parallel [(set (match_dup 1)
8040 (ashiftrt:SWIM248 (match_dup 4) (match_dup 5)))
8041 (clobber (reg:CC FLAGS_REG))])
8042 (parallel [(set (match_dup 0)
8043 (div:SWIM248 (match_dup 2) (match_dup 3)))
8045 (mod:SWIM248 (match_dup 2) (match_dup 3)))
8047 (clobber (reg:CC FLAGS_REG))])]
8049 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
8051 if (<MODE>mode != HImode
8052 && (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD))
8053 operands[4] = operands[2];
8056 /* Avoid use of cltd in favor of a mov+shift. */
8057 emit_move_insn (operands[1], operands[2]);
8058 operands[4] = operands[1];
8061 [(set_attr "type" "multi")
8062 (set_attr "mode" "<MODE>")])
8064 (define_insn_and_split "*divmodsi4_zext_1"
8065 [(set (match_operand:DI 0 "register_operand" "=a")
8067 (div:SI (match_operand:SI 2 "register_operand" "0")
8068 (match_operand:SI 3 "nonimmediate_operand" "rm"))))
8069 (set (match_operand:SI 1 "register_operand" "=&d")
8070 (mod:SI (match_dup 2) (match_dup 3)))
8071 (clobber (reg:CC FLAGS_REG))]
8075 [(parallel [(set (match_dup 1)
8076 (ashiftrt:SI (match_dup 4) (match_dup 5)))
8077 (clobber (reg:CC FLAGS_REG))])
8078 (parallel [(set (match_dup 0)
8079 (zero_extend:DI (div:SI (match_dup 2) (match_dup 3))))
8081 (mod:SI (match_dup 2) (match_dup 3)))
8083 (clobber (reg:CC FLAGS_REG))])]
8085 operands[5] = GEN_INT (GET_MODE_BITSIZE (SImode)-1);
8087 if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
8088 operands[4] = operands[2];
8091 /* Avoid use of cltd in favor of a mov+shift. */
8092 emit_move_insn (operands[1], operands[2]);
8093 operands[4] = operands[1];
8096 [(set_attr "type" "multi")
8097 (set_attr "mode" "SI")])
8099 (define_insn_and_split "*divmodsi4_zext_2"
8100 [(set (match_operand:DI 1 "register_operand" "=&d")
8102 (mod:SI (match_operand:SI 2 "register_operand" "0")
8103 (match_operand:SI 3 "nonimmediate_operand" "rm"))))
8104 (set (match_operand:SI 0 "register_operand" "=a")
8105 (div:SI (match_dup 2) (match_dup 3)))
8106 (clobber (reg:CC FLAGS_REG))]
8110 [(parallel [(set (match_dup 6)
8111 (ashiftrt:SI (match_dup 4) (match_dup 5)))
8112 (clobber (reg:CC FLAGS_REG))])
8113 (parallel [(set (match_dup 1)
8114 (zero_extend:DI (mod:SI (match_dup 2) (match_dup 3))))
8116 (div:SI (match_dup 2) (match_dup 3)))
8118 (clobber (reg:CC FLAGS_REG))])]
8120 operands[5] = GEN_INT (GET_MODE_BITSIZE (SImode)-1);
8121 operands[6] = gen_lowpart (SImode, operands[1]);
8123 if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
8124 operands[4] = operands[2];
8127 /* Avoid use of cltd in favor of a mov+shift. */
8128 emit_move_insn (operands[6], operands[2]);
8129 operands[4] = operands[6];
8132 [(set_attr "type" "multi")
8133 (set_attr "mode" "SI")])
8135 (define_insn "*divmod<mode>4_noext"
8136 [(set (match_operand:SWIM248 0 "register_operand" "=a")
8137 (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
8138 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
8139 (set (match_operand:SWIM248 1 "register_operand" "=d")
8140 (mod:SWIM248 (match_dup 2) (match_dup 3)))
8141 (use (match_operand:SWIM248 4 "register_operand" "1"))
8142 (clobber (reg:CC FLAGS_REG))]
8144 "idiv{<imodesuffix>}\t%3"
8145 [(set_attr "type" "idiv")
8146 (set_attr "mode" "<MODE>")])
8148 (define_insn "*divmodsi4_noext_zext_1"
8149 [(set (match_operand:DI 0 "register_operand" "=a")
8151 (div:SI (match_operand:SI 2 "register_operand" "0")
8152 (match_operand:SI 3 "nonimmediate_operand" "rm"))))
8153 (set (match_operand:SI 1 "register_operand" "=d")
8154 (mod:SI (match_dup 2) (match_dup 3)))
8155 (use (match_operand:SI 4 "register_operand" "1"))
8156 (clobber (reg:CC FLAGS_REG))]
8159 [(set_attr "type" "idiv")
8160 (set_attr "mode" "SI")])
8162 (define_insn "*divmodsi4_noext_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 (use (match_operand:SI 4 "register_operand" "1"))
8170 (clobber (reg:CC FLAGS_REG))]
8173 [(set_attr "type" "idiv")
8174 (set_attr "mode" "SI")])
8176 (define_expand "divmodqi4"
8177 [(parallel [(set (match_operand:QI 0 "register_operand")
8179 (match_operand:QI 1 "register_operand")
8180 (match_operand:QI 2 "nonimmediate_operand")))
8181 (set (match_operand:QI 3 "register_operand")
8182 (mod:QI (match_dup 1) (match_dup 2)))
8183 (clobber (reg:CC FLAGS_REG))])]
8184 "TARGET_QIMODE_MATH"
8189 tmp0 = gen_reg_rtx (HImode);
8190 tmp1 = gen_reg_rtx (HImode);
8192 /* Extend operands[1] to HImode. Generate 8bit divide. Result is in AX. */
8193 emit_insn (gen_extendqihi2 (tmp1, operands[1]));
8194 emit_insn (gen_divmodhiqi3 (tmp0, tmp1, operands[2]));
8196 /* Extract remainder from AH. */
8197 tmp1 = gen_rtx_ZERO_EXTRACT (SImode, tmp0, GEN_INT (8), GEN_INT (8));
8198 tmp1 = lowpart_subreg (QImode, tmp1, SImode);
8199 rtx_insn *insn = emit_move_insn (operands[3], tmp1);
8201 mod = gen_rtx_MOD (QImode, operands[1], operands[2]);
8202 set_unique_reg_note (insn, REG_EQUAL, mod);
8204 /* Extract quotient from AL. */
8205 insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
8207 div = gen_rtx_DIV (QImode, operands[1], operands[2]);
8208 set_unique_reg_note (insn, REG_EQUAL, div);
8213 ;; Divide AX by r/m8, with result stored in
8216 ;; Change div/mod to HImode and extend the second argument to HImode
8217 ;; so that mode of div/mod matches with mode of arguments. Otherwise
8218 ;; combine may fail.
8219 (define_insn "divmodhiqi3"
8220 [(set (match_operand:HI 0 "register_operand" "=a")
8225 (mod:HI (match_operand:HI 1 "register_operand" "0")
8227 (match_operand:QI 2 "nonimmediate_operand" "qm")))))
8231 (div:HI (match_dup 1) (sign_extend:HI (match_dup 2)))))))
8232 (clobber (reg:CC FLAGS_REG))]
8233 "TARGET_QIMODE_MATH"
8235 [(set_attr "type" "idiv")
8236 (set_attr "mode" "QI")])
8238 (define_expand "udivmod<mode>4"
8239 [(parallel [(set (match_operand:SWIM248 0 "register_operand")
8241 (match_operand:SWIM248 1 "register_operand")
8242 (match_operand:SWIM248 2 "nonimmediate_operand")))
8243 (set (match_operand:SWIM248 3 "register_operand")
8244 (umod:SWIM248 (match_dup 1) (match_dup 2)))
8245 (clobber (reg:CC FLAGS_REG))])])
8247 ;; Split with 8bit unsigned divide:
8248 ;; if (dividend an divisor are in [0-255])
8249 ;; use 8bit unsigned integer divide
8251 ;; use original integer divide
8253 [(set (match_operand:SWI48 0 "register_operand")
8254 (udiv:SWI48 (match_operand:SWI48 2 "register_operand")
8255 (match_operand:SWI48 3 "nonimmediate_operand")))
8256 (set (match_operand:SWI48 1 "register_operand")
8257 (umod:SWI48 (match_dup 2) (match_dup 3)))
8258 (clobber (reg:CC FLAGS_REG))]
8259 "TARGET_USE_8BIT_IDIV
8260 && TARGET_QIMODE_MATH
8261 && can_create_pseudo_p ()
8262 && !optimize_insn_for_size_p ()"
8264 "ix86_split_idivmod (<MODE>mode, operands, false); DONE;")
8267 [(set (match_operand:DI 0 "register_operand")
8269 (udiv:SI (match_operand:SI 2 "register_operand")
8270 (match_operand:SI 3 "nonimmediate_operand"))))
8271 (set (match_operand:SI 1 "register_operand")
8272 (umod:SI (match_dup 2) (match_dup 3)))
8273 (clobber (reg:CC FLAGS_REG))]
8275 && TARGET_USE_8BIT_IDIV
8276 && TARGET_QIMODE_MATH
8277 && can_create_pseudo_p ()
8278 && !optimize_insn_for_size_p ()"
8280 "ix86_split_idivmod (SImode, operands, false); DONE;")
8283 [(set (match_operand:DI 1 "register_operand")
8285 (umod:SI (match_operand:SI 2 "register_operand")
8286 (match_operand:SI 3 "nonimmediate_operand"))))
8287 (set (match_operand:SI 0 "register_operand")
8288 (udiv:SI (match_dup 2) (match_dup 3)))
8289 (clobber (reg:CC FLAGS_REG))]
8291 && TARGET_USE_8BIT_IDIV
8292 && TARGET_QIMODE_MATH
8293 && can_create_pseudo_p ()
8294 && !optimize_insn_for_size_p ()"
8296 "ix86_split_idivmod (SImode, operands, false); DONE;")
8298 (define_insn_and_split "udivmod<mode>4_1"
8299 [(set (match_operand:SWI48 0 "register_operand" "=a")
8300 (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "0")
8301 (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
8302 (set (match_operand:SWI48 1 "register_operand" "=&d")
8303 (umod:SWI48 (match_dup 2) (match_dup 3)))
8304 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
8305 (clobber (reg:CC FLAGS_REG))]
8309 [(set (match_dup 1) (const_int 0))
8310 (parallel [(set (match_dup 0)
8311 (udiv:SWI48 (match_dup 2) (match_dup 3)))
8313 (umod:SWI48 (match_dup 2) (match_dup 3)))
8315 (clobber (reg:CC FLAGS_REG))])]
8317 [(set_attr "type" "multi")
8318 (set_attr "mode" "<MODE>")])
8320 (define_insn_and_split "udivmodsi4_zext_1"
8321 [(set (match_operand:DI 0 "register_operand" "=a")
8323 (udiv:SI (match_operand:SI 2 "register_operand" "0")
8324 (match_operand:SI 3 "nonimmediate_operand" "rm"))))
8325 (set (match_operand:SI 1 "register_operand" "=&d")
8326 (umod:SI (match_dup 2) (match_dup 3)))
8327 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
8328 (clobber (reg:CC FLAGS_REG))]
8332 [(set (match_dup 1) (const_int 0))
8333 (parallel [(set (match_dup 0)
8334 (zero_extend:DI (udiv:SI (match_dup 2) (match_dup 3))))
8336 (umod:SI (match_dup 2) (match_dup 3)))
8338 (clobber (reg:CC FLAGS_REG))])]
8340 [(set_attr "type" "multi")
8341 (set_attr "mode" "SI")])
8343 (define_insn_and_split "udivmodsi4_zext_2"
8344 [(set (match_operand:DI 1 "register_operand" "=&d")
8346 (umod:SI (match_operand:SI 2 "register_operand" "0")
8347 (match_operand:SI 3 "nonimmediate_operand" "rm"))))
8348 (set (match_operand:SI 0 "register_operand" "=a")
8349 (udiv:SI (match_dup 2) (match_dup 3)))
8350 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
8351 (clobber (reg:CC FLAGS_REG))]
8355 [(set (match_dup 4) (const_int 0))
8356 (parallel [(set (match_dup 1)
8357 (zero_extend:DI (umod:SI (match_dup 2) (match_dup 3))))
8359 (udiv:SI (match_dup 2) (match_dup 3)))
8361 (clobber (reg:CC FLAGS_REG))])]
8362 "operands[4] = gen_lowpart (SImode, operands[1]);"
8363 [(set_attr "type" "multi")
8364 (set_attr "mode" "SI")])
8366 (define_insn_and_split "*udivmod<mode>4"
8367 [(set (match_operand:SWIM248 0 "register_operand" "=a")
8368 (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
8369 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
8370 (set (match_operand:SWIM248 1 "register_operand" "=&d")
8371 (umod:SWIM248 (match_dup 2) (match_dup 3)))
8372 (clobber (reg:CC FLAGS_REG))]
8376 [(set (match_dup 1) (const_int 0))
8377 (parallel [(set (match_dup 0)
8378 (udiv:SWIM248 (match_dup 2) (match_dup 3)))
8380 (umod:SWIM248 (match_dup 2) (match_dup 3)))
8382 (clobber (reg:CC FLAGS_REG))])]
8384 [(set_attr "type" "multi")
8385 (set_attr "mode" "<MODE>")])
8387 (define_insn_and_split "*udivmodsi4_zext_1"
8388 [(set (match_operand:DI 0 "register_operand" "=a")
8390 (udiv:SI (match_operand:SI 2 "register_operand" "0")
8391 (match_operand:SI 3 "nonimmediate_operand" "rm"))))
8392 (set (match_operand:SI 1 "register_operand" "=&d")
8393 (umod:SI (match_dup 2) (match_dup 3)))
8394 (clobber (reg:CC FLAGS_REG))]
8398 [(set (match_dup 1) (const_int 0))
8399 (parallel [(set (match_dup 0)
8400 (zero_extend:DI (udiv:SI (match_dup 2) (match_dup 3))))
8402 (umod:SI (match_dup 2) (match_dup 3)))
8404 (clobber (reg:CC FLAGS_REG))])]
8406 [(set_attr "type" "multi")
8407 (set_attr "mode" "SI")])
8409 (define_insn_and_split "*udivmodsi4_zext_2"
8410 [(set (match_operand:DI 1 "register_operand" "=&d")
8412 (umod:SI (match_operand:SI 2 "register_operand" "0")
8413 (match_operand:SI 3 "nonimmediate_operand" "rm"))))
8414 (set (match_operand:SI 0 "register_operand" "=a")
8415 (udiv:SI (match_dup 2) (match_dup 3)))
8416 (clobber (reg:CC FLAGS_REG))]
8420 [(set (match_dup 4) (const_int 0))
8421 (parallel [(set (match_dup 1)
8422 (zero_extend:DI (umod:SI (match_dup 2) (match_dup 3))))
8424 (udiv:SI (match_dup 2) (match_dup 3)))
8426 (clobber (reg:CC FLAGS_REG))])]
8427 "operands[4] = gen_lowpart (SImode, operands[1]);"
8428 [(set_attr "type" "multi")
8429 (set_attr "mode" "SI")])
8431 ;; Optimize division or modulo by constant power of 2, if the constant
8432 ;; materializes only after expansion.
8433 (define_insn_and_split "*udivmod<mode>4_pow2"
8434 [(set (match_operand:SWI48 0 "register_operand" "=r")
8435 (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "0")
8436 (match_operand:SWI48 3 "const_int_operand" "n")))
8437 (set (match_operand:SWI48 1 "register_operand" "=r")
8438 (umod:SWI48 (match_dup 2) (match_dup 3)))
8439 (clobber (reg:CC FLAGS_REG))]
8440 "IN_RANGE (INTVAL (operands[3]), 2, HOST_WIDE_INT_UC (0x80000000))
8441 && (UINTVAL (operands[3]) & (UINTVAL (operands[3]) - 1)) == 0"
8444 [(set (match_dup 1) (match_dup 2))
8445 (parallel [(set (match_dup 0) (lshiftrt:<MODE> (match_dup 2) (match_dup 4)))
8446 (clobber (reg:CC FLAGS_REG))])
8447 (parallel [(set (match_dup 1) (and:<MODE> (match_dup 1) (match_dup 5)))
8448 (clobber (reg:CC FLAGS_REG))])]
8450 int v = exact_log2 (UINTVAL (operands[3]));
8451 operands[4] = GEN_INT (v);
8452 operands[5] = GEN_INT ((HOST_WIDE_INT_1U << v) - 1);
8454 [(set_attr "type" "multi")
8455 (set_attr "mode" "<MODE>")])
8457 (define_insn_and_split "*udivmodsi4_pow2_zext_1"
8458 [(set (match_operand:DI 0 "register_operand" "=r")
8460 (udiv:SI (match_operand:SI 2 "register_operand" "0")
8461 (match_operand:SI 3 "const_int_operand" "n"))))
8462 (set (match_operand:SI 1 "register_operand" "=r")
8463 (umod:SI (match_dup 2) (match_dup 3)))
8464 (clobber (reg:CC FLAGS_REG))]
8466 && IN_RANGE (INTVAL (operands[3]), 2, HOST_WIDE_INT_UC (0x80000000))
8467 && (UINTVAL (operands[3]) & (UINTVAL (operands[3]) - 1)) == 0"
8470 [(set (match_dup 1) (match_dup 2))
8471 (parallel [(set (match_dup 0)
8472 (zero_extend:DI (lshiftrt:SI (match_dup 2) (match_dup 4))))
8473 (clobber (reg:CC FLAGS_REG))])
8474 (parallel [(set (match_dup 1) (and:SI (match_dup 1) (match_dup 5)))
8475 (clobber (reg:CC FLAGS_REG))])]
8477 int v = exact_log2 (UINTVAL (operands[3]));
8478 operands[4] = GEN_INT (v);
8479 operands[5] = GEN_INT ((HOST_WIDE_INT_1U << v) - 1);
8481 [(set_attr "type" "multi")
8482 (set_attr "mode" "SI")])
8484 (define_insn_and_split "*udivmodsi4_pow2_zext_2"
8485 [(set (match_operand:DI 1 "register_operand" "=r")
8487 (umod:SI (match_operand:SI 2 "register_operand" "0")
8488 (match_operand:SI 3 "const_int_operand" "n"))))
8489 (set (match_operand:SI 0 "register_operand" "=r")
8490 (umod:SI (match_dup 2) (match_dup 3)))
8491 (clobber (reg:CC FLAGS_REG))]
8493 && IN_RANGE (INTVAL (operands[3]), 2, HOST_WIDE_INT_UC (0x80000000))
8494 && (UINTVAL (operands[3]) & (UINTVAL (operands[3]) - 1)) == 0"
8497 [(set (match_dup 1) (match_dup 2))
8498 (parallel [(set (match_dup 0) (lshiftrt:SI (match_dup 2) (match_dup 4)))
8499 (clobber (reg:CC FLAGS_REG))])
8500 (parallel [(set (match_dup 1)
8501 (zero_extend:DI (and:SI (match_dup 1) (match_dup 5))))
8502 (clobber (reg:CC FLAGS_REG))])]
8504 int v = exact_log2 (UINTVAL (operands[3]));
8505 operands[4] = GEN_INT (v);
8506 operands[5] = GEN_INT ((HOST_WIDE_INT_1U << v) - 1);
8508 [(set_attr "type" "multi")
8509 (set_attr "mode" "SI")])
8511 (define_insn "*udivmod<mode>4_noext"
8512 [(set (match_operand:SWIM248 0 "register_operand" "=a")
8513 (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
8514 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
8515 (set (match_operand:SWIM248 1 "register_operand" "=d")
8516 (umod:SWIM248 (match_dup 2) (match_dup 3)))
8517 (use (match_operand:SWIM248 4 "register_operand" "1"))
8518 (clobber (reg:CC FLAGS_REG))]
8520 "div{<imodesuffix>}\t%3"
8521 [(set_attr "type" "idiv")
8522 (set_attr "mode" "<MODE>")])
8524 (define_insn "*udivmodsi4_noext_zext_1"
8525 [(set (match_operand:DI 0 "register_operand" "=a")
8527 (udiv:SI (match_operand:SI 2 "register_operand" "0")
8528 (match_operand:SI 3 "nonimmediate_operand" "rm"))))
8529 (set (match_operand:SI 1 "register_operand" "=d")
8530 (umod:SI (match_dup 2) (match_dup 3)))
8531 (use (match_operand:SI 4 "register_operand" "1"))
8532 (clobber (reg:CC FLAGS_REG))]
8535 [(set_attr "type" "idiv")
8536 (set_attr "mode" "SI")])
8538 (define_insn "*udivmodsi4_noext_zext_2"
8539 [(set (match_operand:DI 1 "register_operand" "=d")
8541 (umod:SI (match_operand:SI 2 "register_operand" "0")
8542 (match_operand:SI 3 "nonimmediate_operand" "rm"))))
8543 (set (match_operand:SI 0 "register_operand" "=a")
8544 (udiv:SI (match_dup 2) (match_dup 3)))
8545 (use (match_operand:SI 4 "register_operand" "1"))
8546 (clobber (reg:CC FLAGS_REG))]
8549 [(set_attr "type" "idiv")
8550 (set_attr "mode" "SI")])
8552 (define_expand "udivmodqi4"
8553 [(parallel [(set (match_operand:QI 0 "register_operand")
8555 (match_operand:QI 1 "register_operand")
8556 (match_operand:QI 2 "nonimmediate_operand")))
8557 (set (match_operand:QI 3 "register_operand")
8558 (umod:QI (match_dup 1) (match_dup 2)))
8559 (clobber (reg:CC FLAGS_REG))])]
8560 "TARGET_QIMODE_MATH"
8565 tmp0 = gen_reg_rtx (HImode);
8566 tmp1 = gen_reg_rtx (HImode);
8568 /* Extend operands[1] to HImode. Generate 8bit divide. Result is in AX. */
8569 emit_insn (gen_zero_extendqihi2 (tmp1, operands[1]));
8570 emit_insn (gen_udivmodhiqi3 (tmp0, tmp1, operands[2]));
8572 /* Extract remainder from AH. */
8573 tmp1 = gen_rtx_ZERO_EXTRACT (SImode, tmp0, GEN_INT (8), GEN_INT (8));
8574 tmp1 = lowpart_subreg (QImode, tmp1, SImode);
8575 rtx_insn *insn = emit_move_insn (operands[3], tmp1);
8577 mod = gen_rtx_UMOD (QImode, operands[1], operands[2]);
8578 set_unique_reg_note (insn, REG_EQUAL, mod);
8580 /* Extract quotient from AL. */
8581 insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
8583 div = gen_rtx_UDIV (QImode, operands[1], operands[2]);
8584 set_unique_reg_note (insn, REG_EQUAL, div);
8589 (define_insn "udivmodhiqi3"
8590 [(set (match_operand:HI 0 "register_operand" "=a")
8595 (mod:HI (match_operand:HI 1 "register_operand" "0")
8597 (match_operand:QI 2 "nonimmediate_operand" "qm")))))
8601 (div:HI (match_dup 1) (zero_extend:HI (match_dup 2)))))))
8602 (clobber (reg:CC FLAGS_REG))]
8603 "TARGET_QIMODE_MATH"
8605 [(set_attr "type" "idiv")
8606 (set_attr "mode" "QI")])
8608 ;; We cannot use div/idiv for double division, because it causes
8609 ;; "division by zero" on the overflow and that's not what we expect
8610 ;; from truncate. Because true (non truncating) double division is
8611 ;; never generated, we can't create this insn anyway.
8614 ; [(set (match_operand:SI 0 "register_operand" "=a")
8616 ; (udiv:DI (match_operand:DI 1 "register_operand" "A")
8618 ; (match_operand:SI 2 "nonimmediate_operand" "rm")))))
8619 ; (set (match_operand:SI 3 "register_operand" "=d")
8621 ; (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
8622 ; (clobber (reg:CC FLAGS_REG))]
8624 ; "div{l}\t{%2, %0|%0, %2}"
8625 ; [(set_attr "type" "idiv")])
8627 ;;- Logical AND instructions
8629 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
8630 ;; Note that this excludes ah.
8632 (define_expand "testsi_ccno_1"
8633 [(set (reg:CCNO FLAGS_REG)
8635 (and:SI (match_operand:SI 0 "nonimmediate_operand")
8636 (match_operand:SI 1 "x86_64_nonmemory_operand"))
8639 (define_expand "testqi_ccz_1"
8640 [(set (reg:CCZ FLAGS_REG)
8641 (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand")
8642 (match_operand:QI 1 "nonmemory_operand"))
8645 (define_expand "testdi_ccno_1"
8646 [(set (reg:CCNO FLAGS_REG)
8648 (and:DI (match_operand:DI 0 "nonimmediate_operand")
8649 (match_operand:DI 1 "x86_64_szext_general_operand"))
8651 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))")
8653 (define_insn "*testdi_1"
8654 [(set (reg FLAGS_REG)
8657 (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
8658 (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
8660 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8661 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8663 test{l}\t{%k1, %k0|%k0, %k1}
8664 test{l}\t{%k1, %k0|%k0, %k1}
8665 test{q}\t{%1, %0|%0, %1}
8666 test{q}\t{%1, %0|%0, %1}
8667 test{q}\t{%1, %0|%0, %1}"
8668 [(set_attr "type" "test")
8669 (set_attr "modrm" "0,1,0,1,1")
8670 (set_attr "mode" "SI,SI,DI,DI,DI")])
8672 (define_insn "*testqi_1_maybe_si"
8673 [(set (reg FLAGS_REG)
8676 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
8677 (match_operand:QI 1 "general_operand" "n,n,qn,n"))
8679 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
8680 && ix86_match_ccmode (insn,
8681 CONST_INT_P (operands[1])
8682 && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
8684 if (which_alternative == 3)
8686 if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
8687 operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
8688 return "test{l}\t{%1, %k0|%k0, %1}";
8690 return "test{b}\t{%1, %0|%0, %1}";
8692 [(set_attr "type" "test")
8693 (set_attr "modrm" "0,1,1,1")
8694 (set_attr "mode" "QI,QI,QI,SI")
8695 (set_attr "pent_pair" "uv,np,uv,np")])
8697 (define_insn "*test<mode>_1"
8698 [(set (reg FLAGS_REG)
8701 (match_operand:SWI124 0 "nonimmediate_operand" "%!*a,<r>,<r>m")
8702 (match_operand:SWI124 1 "<general_operand>" "<i>,<i>,<r><i>"))
8704 "ix86_match_ccmode (insn, CCNOmode)
8705 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8706 "test{<imodesuffix>}\t{%1, %0|%0, %1}"
8707 [(set_attr "type" "test")
8708 (set_attr "modrm" "0,1,1")
8709 (set_attr "mode" "<MODE>")
8710 (set_attr "pent_pair" "uv,np,uv")])
8712 (define_expand "testqi_ext_1_ccno"
8713 [(set (reg:CCNO FLAGS_REG)
8717 (zero_extract:SI (match_operand 0 "ext_register_operand")
8720 (match_operand 1 "const_int_operand"))
8723 (define_insn "*testqi_ext_1"
8724 [(set (reg FLAGS_REG)
8728 (zero_extract:SI (match_operand 0 "ext_register_operand" "Q,Q")
8731 (match_operand:QI 1 "general_operand" "QnBc,m"))
8733 "ix86_match_ccmode (insn, CCNOmode)"
8734 "test{b}\t{%1, %h0|%h0, %1}"
8735 [(set_attr "isa" "*,nox64")
8736 (set_attr "type" "test")
8737 (set_attr "mode" "QI")])
8739 (define_insn "*testqi_ext_2"
8740 [(set (reg FLAGS_REG)
8744 (zero_extract:SI (match_operand 0 "ext_register_operand" "Q")
8748 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q")
8752 "ix86_match_ccmode (insn, CCNOmode)"
8753 "test{b}\t{%h1, %h0|%h0, %h1}"
8754 [(set_attr "type" "test")
8755 (set_attr "mode" "QI")])
8757 ;; Combine likes to form bit extractions for some tests. Humor it.
8758 (define_insn_and_split "*testqi_ext_3"
8759 [(set (match_operand 0 "flags_reg_operand")
8760 (match_operator 1 "compare_operator"
8761 [(zero_extract:SWI248
8762 (match_operand 2 "nonimmediate_operand" "rm")
8763 (match_operand 3 "const_int_operand" "n")
8764 (match_operand 4 "const_int_operand" "n"))
8766 "ix86_match_ccmode (insn, CCNOmode)
8767 && ((TARGET_64BIT && GET_MODE (operands[2]) == DImode)
8768 || GET_MODE (operands[2]) == SImode
8769 || GET_MODE (operands[2]) == HImode
8770 || GET_MODE (operands[2]) == QImode)
8771 /* Ensure that resulting mask is zero or sign extended operand. */
8772 && INTVAL (operands[4]) >= 0
8773 && ((INTVAL (operands[3]) > 0
8774 && INTVAL (operands[3]) + INTVAL (operands[4]) <= 32)
8775 || (<MODE>mode == DImode
8776 && INTVAL (operands[3]) > 32
8777 && INTVAL (operands[3]) + INTVAL (operands[4]) == 64))"
8780 [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
8782 rtx val = operands[2];
8783 HOST_WIDE_INT len = INTVAL (operands[3]);
8784 HOST_WIDE_INT pos = INTVAL (operands[4]);
8785 machine_mode mode = GET_MODE (val);
8789 machine_mode submode = GET_MODE (SUBREG_REG (val));
8791 /* Narrow paradoxical subregs to prevent partial register stalls. */
8792 if (GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode)
8793 && GET_MODE_CLASS (submode) == MODE_INT)
8795 val = SUBREG_REG (val);
8800 /* Small HImode tests can be converted to QImode. */
8801 if (register_operand (val, HImode) && pos + len <= 8)
8803 val = gen_lowpart (QImode, val);
8807 gcc_assert (pos + len <= GET_MODE_PRECISION (mode));
8810 = wi::shifted_mask (pos, len, false, GET_MODE_PRECISION (mode));
8812 operands[2] = gen_rtx_AND (mode, val, immed_wide_int_const (mask, mode));
8815 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
8816 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
8817 ;; this is relatively important trick.
8818 ;; Do the conversion only post-reload to avoid limiting of the register class
8821 [(set (match_operand 0 "flags_reg_operand")
8822 (match_operator 1 "compare_operator"
8823 [(and (match_operand 2 "QIreg_operand")
8824 (match_operand 3 "const_int_operand"))
8827 && GET_MODE (operands[2]) != QImode
8828 && ((ix86_match_ccmode (insn, CCZmode)
8829 && !(INTVAL (operands[3]) & ~(255 << 8)))
8830 || (ix86_match_ccmode (insn, CCNOmode)
8831 && !(INTVAL (operands[3]) & ~(127 << 8))))"
8836 (zero_extract:SI (match_dup 2)
8842 operands[2] = gen_lowpart (SImode, operands[2]);
8843 operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, QImode);
8847 [(set (match_operand 0 "flags_reg_operand")
8848 (match_operator 1 "compare_operator"
8849 [(and (match_operand 2 "nonimmediate_operand")
8850 (match_operand 3 "const_int_operand"))
8853 && GET_MODE (operands[2]) != QImode
8854 && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
8855 && ((ix86_match_ccmode (insn, CCZmode)
8856 && !(INTVAL (operands[3]) & ~255))
8857 || (ix86_match_ccmode (insn, CCNOmode)
8858 && !(INTVAL (operands[3]) & ~127)))"
8860 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
8863 operands[2] = gen_lowpart (QImode, operands[2]);
8864 operands[3] = gen_int_mode (INTVAL (operands[3]), QImode);
8867 ;; %%% This used to optimize known byte-wide and operations to memory,
8868 ;; and sometimes to QImode registers. If this is considered useful,
8869 ;; it should be done with splitters.
8871 (define_expand "and<mode>3"
8872 [(set (match_operand:SWIM1248x 0 "nonimmediate_operand")
8873 (and:SWIM1248x (match_operand:SWIM1248x 1 "nonimmediate_operand")
8874 (match_operand:SWIM1248x 2 "<general_szext_operand>")))]
8877 machine_mode mode = <MODE>mode;
8878 rtx (*insn) (rtx, rtx);
8880 if (CONST_INT_P (operands[2]) && REG_P (operands[0]))
8882 HOST_WIDE_INT ival = INTVAL (operands[2]);
8884 if (ival == (HOST_WIDE_INT) 0xffffffff)
8886 else if (ival == 0xffff)
8888 else if (ival == 0xff)
8892 if (mode == <MODE>mode)
8894 ix86_expand_binary_operator (AND, <MODE>mode, operands);
8898 if (<MODE>mode == DImode)
8899 insn = (mode == SImode)
8900 ? gen_zero_extendsidi2
8902 ? gen_zero_extendhidi2
8903 : gen_zero_extendqidi2;
8904 else if (<MODE>mode == SImode)
8905 insn = (mode == HImode)
8906 ? gen_zero_extendhisi2
8907 : gen_zero_extendqisi2;
8908 else if (<MODE>mode == HImode)
8909 insn = gen_zero_extendqihi2;
8913 emit_insn (insn (operands[0], gen_lowpart (mode, operands[1])));
8917 (define_insn_and_split "*anddi3_doubleword"
8918 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r")
8920 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8921 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm")))
8922 (clobber (reg:CC FLAGS_REG))]
8923 "!TARGET_64BIT && TARGET_STV && TARGET_SSE2
8924 && ix86_binary_operator_ok (AND, DImode, operands)"
8926 "&& reload_completed"
8929 split_double_mode (DImode, &operands[0], 3, &operands[0], &operands[3]);
8930 if (operands[2] == const0_rtx)
8932 operands[1] = const0_rtx;
8933 ix86_expand_move (SImode, &operands[0]);
8935 else if (operands[2] != constm1_rtx)
8936 ix86_expand_binary_operator (AND, SImode, &operands[0]);
8937 else if (operands[5] == constm1_rtx)
8938 emit_note (NOTE_INSN_DELETED);
8939 if (operands[5] == const0_rtx)
8941 operands[4] = const0_rtx;
8942 ix86_expand_move (SImode, &operands[3]);
8944 else if (operands[5] != constm1_rtx)
8945 ix86_expand_binary_operator (AND, SImode, &operands[3]);
8949 (define_insn "*anddi_1"
8950 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
8952 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
8953 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
8954 (clobber (reg:CC FLAGS_REG))]
8955 "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
8957 and{l}\t{%k2, %k0|%k0, %k2}
8958 and{q}\t{%2, %0|%0, %2}
8959 and{q}\t{%2, %0|%0, %2}
8961 [(set_attr "type" "alu,alu,alu,imovx")
8962 (set_attr "length_immediate" "*,*,*,0")
8963 (set (attr "prefix_rex")
8965 (and (eq_attr "type" "imovx")
8966 (and (match_test "INTVAL (operands[2]) == 0xff")
8967 (match_operand 1 "ext_QIreg_operand")))
8969 (const_string "*")))
8970 (set_attr "mode" "SI,DI,DI,SI")])
8972 (define_insn_and_split "*anddi_1_btr"
8973 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
8975 (match_operand:DI 1 "nonimmediate_operand" "%0")
8976 (match_operand:DI 2 "const_int_operand" "n")))
8977 (clobber (reg:CC FLAGS_REG))]
8978 "TARGET_64BIT && TARGET_USE_BT
8979 && ix86_binary_operator_ok (AND, DImode, operands)
8980 && IN_RANGE (exact_log2 (~INTVAL (operands[2])), 31, 63)"
8982 "&& reload_completed"
8983 [(parallel [(set (zero_extract:DI (match_dup 0)
8987 (clobber (reg:CC FLAGS_REG))])]
8988 "operands[3] = GEN_INT (exact_log2 (~INTVAL (operands[2])));"
8989 [(set_attr "type" "alu1")
8990 (set_attr "prefix_0f" "1")
8991 (set_attr "znver1_decode" "double")
8992 (set_attr "mode" "DI")])
8994 ;; Turn *anddi_1 into *andsi_1_zext if possible.
8996 [(set (match_operand:DI 0 "register_operand")
8997 (and:DI (subreg:DI (match_operand:SI 1 "register_operand") 0)
8998 (match_operand:DI 2 "x86_64_zext_immediate_operand")))
8999 (clobber (reg:CC FLAGS_REG))]
9001 [(parallel [(set (match_dup 0)
9002 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))
9003 (clobber (reg:CC FLAGS_REG))])]
9004 "operands[2] = gen_lowpart (SImode, operands[2]);")
9006 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9007 (define_insn "*andsi_1_zext"
9008 [(set (match_operand:DI 0 "register_operand" "=r")
9010 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9011 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
9012 (clobber (reg:CC FLAGS_REG))]
9013 "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
9014 "and{l}\t{%2, %k0|%k0, %2}"
9015 [(set_attr "type" "alu")
9016 (set_attr "mode" "SI")])
9018 (define_insn "*and<mode>_1"
9019 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=rm,r,Ya")
9020 (and:SWI24 (match_operand:SWI24 1 "nonimmediate_operand" "%0,0,qm")
9021 (match_operand:SWI24 2 "<general_operand>" "r<i>,rm,L")))
9022 (clobber (reg:CC FLAGS_REG))]
9023 "ix86_binary_operator_ok (AND, <MODE>mode, operands)"
9025 and{<imodesuffix>}\t{%2, %0|%0, %2}
9026 and{<imodesuffix>}\t{%2, %0|%0, %2}
9028 [(set_attr "type" "alu,alu,imovx")
9029 (set_attr "length_immediate" "*,*,0")
9030 (set (attr "prefix_rex")
9032 (and (eq_attr "type" "imovx")
9033 (and (match_test "INTVAL (operands[2]) == 0xff")
9034 (match_operand 1 "ext_QIreg_operand")))
9036 (const_string "*")))
9037 (set_attr "mode" "<MODE>,<MODE>,SI")])
9039 (define_insn "*andqi_1"
9040 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
9041 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9042 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
9043 (clobber (reg:CC FLAGS_REG))]
9044 "ix86_binary_operator_ok (AND, QImode, operands)"
9046 and{b}\t{%2, %0|%0, %2}
9047 and{b}\t{%2, %0|%0, %2}
9048 and{l}\t{%k2, %k0|%k0, %k2}"
9049 [(set_attr "type" "alu")
9050 (set_attr "mode" "QI,QI,SI")
9051 ;; Potential partial reg stall on alternative 2.
9052 (set (attr "preferred_for_speed")
9053 (cond [(eq_attr "alternative" "2")
9054 (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
9055 (symbol_ref "true")))])
9057 (define_insn "*andqi_1_slp"
9058 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
9059 (and:QI (match_dup 0)
9060 (match_operand:QI 1 "general_operand" "qn,qmn")))
9061 (clobber (reg:CC FLAGS_REG))]
9062 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9063 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9064 "and{b}\t{%1, %0|%0, %1}"
9065 [(set_attr "type" "alu1")
9066 (set_attr "mode" "QI")])
9069 [(set (match_operand:SWI248 0 "register_operand")
9070 (and:SWI248 (match_operand:SWI248 1 "nonimmediate_operand")
9071 (match_operand:SWI248 2 "const_int_operand")))
9072 (clobber (reg:CC FLAGS_REG))]
9074 && (!REG_P (operands[1])
9075 || REGNO (operands[0]) != REGNO (operands[1]))"
9078 HOST_WIDE_INT ival = INTVAL (operands[2]);
9080 rtx (*insn) (rtx, rtx);
9082 if (ival == (HOST_WIDE_INT) 0xffffffff)
9084 else if (ival == 0xffff)
9088 gcc_assert (ival == 0xff);
9092 if (<MODE>mode == DImode)
9093 insn = (mode == SImode)
9094 ? gen_zero_extendsidi2
9096 ? gen_zero_extendhidi2
9097 : gen_zero_extendqidi2;
9100 if (<MODE>mode != SImode)
9101 /* Zero extend to SImode to avoid partial register stalls. */
9102 operands[0] = gen_lowpart (SImode, operands[0]);
9104 insn = (mode == HImode)
9105 ? gen_zero_extendhisi2
9106 : gen_zero_extendqisi2;
9108 emit_insn (insn (operands[0], gen_lowpart (mode, operands[1])));
9113 [(set (match_operand:SWI48 0 "register_operand")
9114 (and:SWI48 (match_dup 0)
9115 (const_int -65536)))
9116 (clobber (reg:CC FLAGS_REG))]
9117 "(TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)
9118 || optimize_function_for_size_p (cfun)"
9119 [(set (strict_low_part (match_dup 1)) (const_int 0))]
9120 "operands[1] = gen_lowpart (HImode, operands[0]);")
9123 [(set (match_operand:SWI248 0 "any_QIreg_operand")
9124 (and:SWI248 (match_dup 0)
9126 (clobber (reg:CC FLAGS_REG))]
9127 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9128 && reload_completed"
9129 [(set (strict_low_part (match_dup 1)) (const_int 0))]
9130 "operands[1] = gen_lowpart (QImode, operands[0]);")
9133 [(set (match_operand:SWI248 0 "QIreg_operand")
9134 (and:SWI248 (match_dup 0)
9135 (const_int -65281)))
9136 (clobber (reg:CC FLAGS_REG))]
9137 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9138 && reload_completed"
9140 [(set (zero_extract:SI (match_dup 0)
9146 (zero_extract:SI (match_dup 0)
9150 (zero_extract:SI (match_dup 0)
9152 (const_int 8)) 0)) 0))
9153 (clobber (reg:CC FLAGS_REG))])]
9154 "operands[0] = gen_lowpart (SImode, operands[0]);")
9156 (define_insn "*anddi_2"
9157 [(set (reg FLAGS_REG)
9160 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
9161 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
9163 (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
9164 (and:DI (match_dup 1) (match_dup 2)))]
9166 && ix86_match_ccmode
9168 /* If we are going to emit andl instead of andq, and the operands[2]
9169 constant might have the SImode sign bit set, make sure the sign
9170 flag isn't tested, because the instruction will set the sign flag
9171 based on bit 31 rather than bit 63. If it isn't CONST_INT,
9172 conservatively assume it might have bit 31 set. */
9173 (satisfies_constraint_Z (operands[2])
9174 && (!CONST_INT_P (operands[2])
9175 || val_signbit_known_set_p (SImode, INTVAL (operands[2]))))
9176 ? CCZmode : CCNOmode)
9177 && ix86_binary_operator_ok (AND, DImode, operands)"
9179 and{l}\t{%k2, %k0|%k0, %k2}
9180 and{q}\t{%2, %0|%0, %2}
9181 and{q}\t{%2, %0|%0, %2}"
9182 [(set_attr "type" "alu")
9183 (set_attr "mode" "SI,DI,DI")])
9185 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9186 (define_insn "*andsi_2_zext"
9187 [(set (reg FLAGS_REG)
9189 (match_operand:SI 1 "nonimmediate_operand" "%0")
9190 (match_operand:SI 2 "x86_64_general_operand" "rme"))
9192 (set (match_operand:DI 0 "register_operand" "=r")
9193 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
9194 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9195 && ix86_binary_operator_ok (AND, SImode, operands)"
9196 "and{l}\t{%2, %k0|%k0, %2}"
9197 [(set_attr "type" "alu")
9198 (set_attr "mode" "SI")])
9200 (define_insn "*andqi_2_maybe_si"
9201 [(set (reg FLAGS_REG)
9203 (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9204 (match_operand:QI 2 "general_operand" "qmn,qn,n"))
9206 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
9207 (and:QI (match_dup 1) (match_dup 2)))]
9208 "ix86_binary_operator_ok (AND, QImode, operands)
9209 && ix86_match_ccmode (insn,
9210 CONST_INT_P (operands[2])
9211 && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
9213 if (which_alternative == 2)
9215 if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
9216 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
9217 return "and{l}\t{%2, %k0|%k0, %2}";
9219 return "and{b}\t{%2, %0|%0, %2}";
9221 [(set_attr "type" "alu")
9222 (set_attr "mode" "QI,QI,SI")])
9224 (define_insn "*and<mode>_2"
9225 [(set (reg FLAGS_REG)
9226 (compare (and:SWI124
9227 (match_operand:SWI124 1 "nonimmediate_operand" "%0,0")
9228 (match_operand:SWI124 2 "<general_operand>" "<g>,<r><i>"))
9230 (set (match_operand:SWI124 0 "nonimmediate_operand" "=<r>,<r>m")
9231 (and:SWI124 (match_dup 1) (match_dup 2)))]
9232 "ix86_match_ccmode (insn, CCNOmode)
9233 && ix86_binary_operator_ok (AND, <MODE>mode, operands)"
9234 "and{<imodesuffix>}\t{%2, %0|%0, %2}"
9235 [(set_attr "type" "alu")
9236 (set_attr "mode" "<MODE>")])
9238 (define_insn "*andqi_2_slp"
9239 [(set (reg FLAGS_REG)
9241 (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9242 (match_operand:QI 1 "nonimmediate_operand" "qmn,qn"))
9244 (set (strict_low_part (match_dup 0))
9245 (and:QI (match_dup 0) (match_dup 1)))]
9246 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9247 && ix86_match_ccmode (insn, CCNOmode)
9248 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9249 "and{b}\t{%1, %0|%0, %1}"
9250 [(set_attr "type" "alu1")
9251 (set_attr "mode" "QI")])
9253 (define_insn "andqi_ext_1"
9254 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q,Q")
9260 (zero_extract:SI (match_operand 1 "ext_register_operand" "0,0")
9263 (match_operand:QI 2 "general_operand" "QnBc,m")) 0))
9264 (clobber (reg:CC FLAGS_REG))]
9265 "/* FIXME: without this LRA can't reload this pattern, see PR82524. */
9266 rtx_equal_p (operands[0], operands[1])"
9267 "and{b}\t{%2, %h0|%h0, %2}"
9268 [(set_attr "isa" "*,nox64")
9269 (set_attr "type" "alu")
9270 (set_attr "mode" "QI")])
9272 ;; Generated by peephole translating test to and. This shows up
9273 ;; often in fp comparisons.
9274 (define_insn "*andqi_ext_1_cc"
9275 [(set (reg FLAGS_REG)
9279 (zero_extract:SI (match_operand 1 "ext_register_operand" "0,0")
9282 (match_operand:QI 2 "general_operand" "QnBc,m"))
9284 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q,Q")
9290 (zero_extract:SI (match_dup 1)
9294 "ix86_match_ccmode (insn, CCNOmode)
9295 /* FIXME: without this LRA can't reload this pattern, see PR82524. */
9296 && rtx_equal_p (operands[0], operands[1])"
9297 "and{b}\t{%2, %h0|%h0, %2}"
9298 [(set_attr "isa" "*,nox64")
9299 (set_attr "type" "alu")
9300 (set_attr "mode" "QI")])
9302 (define_insn "*andqi_ext_2"
9303 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
9309 (zero_extract:SI (match_operand 1 "ext_register_operand" "%0")
9313 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9315 (const_int 8)) 0)) 0))
9316 (clobber (reg:CC FLAGS_REG))]
9317 "/* FIXME: without this LRA can't reload this pattern, see PR82524. */
9318 rtx_equal_p (operands[0], operands[1])
9319 || rtx_equal_p (operands[0], operands[2])"
9320 "and{b}\t{%h2, %h0|%h0, %h2}"
9321 [(set_attr "type" "alu")
9322 (set_attr "mode" "QI")])
9324 ;; Convert wide AND instructions with immediate operand to shorter QImode
9325 ;; equivalents when possible.
9326 ;; Don't do the splitting with memory operands, since it introduces risk
9327 ;; of memory mismatch stalls. We may want to do the splitting for optimizing
9328 ;; for size, but that can (should?) be handled by generic code instead.
9330 [(set (match_operand:SWI248 0 "QIreg_operand")
9331 (and:SWI248 (match_operand:SWI248 1 "register_operand")
9332 (match_operand:SWI248 2 "const_int_operand")))
9333 (clobber (reg:CC FLAGS_REG))]
9335 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9336 && !(~INTVAL (operands[2]) & ~(255 << 8))"
9338 [(set (zero_extract:SI (match_dup 0)
9344 (zero_extract:SI (match_dup 1)
9348 (clobber (reg:CC FLAGS_REG))])]
9350 operands[0] = gen_lowpart (SImode, operands[0]);
9351 operands[1] = gen_lowpart (SImode, operands[1]);
9352 operands[2] = gen_int_mode (INTVAL (operands[2]) >> 8, QImode);
9355 ;; Since AND can be encoded with sign extended immediate, this is only
9356 ;; profitable when 7th bit is not set.
9358 [(set (match_operand:SWI248 0 "any_QIreg_operand")
9359 (and:SWI248 (match_operand:SWI248 1 "general_operand")
9360 (match_operand:SWI248 2 "const_int_operand")))
9361 (clobber (reg:CC FLAGS_REG))]
9363 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9364 && !(~INTVAL (operands[2]) & ~255)
9365 && !(INTVAL (operands[2]) & 128)"
9366 [(parallel [(set (strict_low_part (match_dup 0))
9367 (and:QI (match_dup 1)
9369 (clobber (reg:CC FLAGS_REG))])]
9371 operands[0] = gen_lowpart (QImode, operands[0]);
9372 operands[1] = gen_lowpart (QImode, operands[1]);
9373 operands[2] = gen_int_mode (INTVAL (operands[2]), QImode);
9376 (define_insn "*andndi3_doubleword"
9377 [(set (match_operand:DI 0 "register_operand" "=&r,r,r,&r")
9379 (not:DI (match_operand:DI 1 "register_operand" "r,0,r,0"))
9380 (match_operand:DI 2 "nonimmediate_operand" "rm,rm,0,rm")))
9381 (clobber (reg:CC FLAGS_REG))]
9382 "!TARGET_64BIT && TARGET_STV && TARGET_SSE2"
9384 [(set_attr "isa" "bmi,bmi,bmi,*")])
9387 [(set (match_operand:DI 0 "register_operand")
9389 (not:DI (match_operand:DI 1 "register_operand"))
9390 (match_operand:DI 2 "nonimmediate_operand")))
9391 (clobber (reg:CC FLAGS_REG))]
9392 "!TARGET_64BIT && TARGET_BMI && TARGET_STV && TARGET_SSE2
9393 && reload_completed"
9394 [(parallel [(set (match_dup 0)
9395 (and:SI (not:SI (match_dup 1)) (match_dup 2)))
9396 (clobber (reg:CC FLAGS_REG))])
9397 (parallel [(set (match_dup 3)
9398 (and:SI (not:SI (match_dup 4)) (match_dup 5)))
9399 (clobber (reg:CC FLAGS_REG))])]
9400 "split_double_mode (DImode, &operands[0], 3, &operands[0], &operands[3]);")
9403 [(set (match_operand:DI 0 "register_operand")
9405 (not:DI (match_dup 0))
9406 (match_operand:DI 1 "nonimmediate_operand")))
9407 (clobber (reg:CC FLAGS_REG))]
9408 "!TARGET_64BIT && !TARGET_BMI && TARGET_STV && TARGET_SSE2
9409 && reload_completed"
9410 [(set (match_dup 0) (not:SI (match_dup 0)))
9411 (parallel [(set (match_dup 0)
9412 (and:SI (match_dup 0) (match_dup 1)))
9413 (clobber (reg:CC FLAGS_REG))])
9414 (set (match_dup 2) (not:SI (match_dup 2)))
9415 (parallel [(set (match_dup 2)
9416 (and:SI (match_dup 2) (match_dup 3)))
9417 (clobber (reg:CC FLAGS_REG))])]
9418 "split_double_mode (DImode, &operands[0], 2, &operands[0], &operands[2]);")
9420 (define_insn "*andn<mode>_1"
9421 [(set (match_operand:SWI48 0 "register_operand" "=r,r")
9423 (not:SWI48 (match_operand:SWI48 1 "register_operand" "r,r"))
9424 (match_operand:SWI48 2 "nonimmediate_operand" "r,m")))
9425 (clobber (reg:CC FLAGS_REG))]
9427 "andn\t{%2, %1, %0|%0, %1, %2}"
9428 [(set_attr "type" "bitmanip")
9429 (set_attr "btver2_decode" "direct, double")
9430 (set_attr "mode" "<MODE>")])
9432 (define_insn "*andn<mode>_1"
9433 [(set (match_operand:SWI12 0 "register_operand" "=r")
9435 (not:SWI12 (match_operand:SWI12 1 "register_operand" "r"))
9436 (match_operand:SWI12 2 "register_operand" "r")))
9437 (clobber (reg:CC FLAGS_REG))]
9439 "andn\t{%k2, %k1, %k0|%k0, %k1, %k2}"
9440 [(set_attr "type" "bitmanip")
9441 (set_attr "btver2_decode" "direct")
9442 (set_attr "mode" "SI")])
9444 (define_insn "*andn_<mode>_ccno"
9445 [(set (reg FLAGS_REG)
9448 (not:SWI48 (match_operand:SWI48 1 "register_operand" "r,r"))
9449 (match_operand:SWI48 2 "nonimmediate_operand" "r,m"))
9451 (clobber (match_scratch:SWI48 0 "=r,r"))]
9452 "TARGET_BMI && ix86_match_ccmode (insn, CCNOmode)"
9453 "andn\t{%2, %1, %0|%0, %1, %2}"
9454 [(set_attr "type" "bitmanip")
9455 (set_attr "btver2_decode" "direct, double")
9456 (set_attr "mode" "<MODE>")])
9458 ;; Logical inclusive and exclusive OR instructions
9460 ;; %%% This used to optimize known byte-wide and operations to memory.
9461 ;; If this is considered useful, it should be done with splitters.
9463 (define_expand "<code><mode>3"
9464 [(set (match_operand:SWIM1248x 0 "nonimmediate_operand")
9465 (any_or:SWIM1248x (match_operand:SWIM1248x 1 "nonimmediate_operand")
9466 (match_operand:SWIM1248x 2 "<general_operand>")))]
9468 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
9470 (define_insn_and_split "*<code>di3_doubleword"
9471 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r")
9473 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
9474 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm")))
9475 (clobber (reg:CC FLAGS_REG))]
9476 "!TARGET_64BIT && TARGET_STV && TARGET_SSE2
9477 && ix86_binary_operator_ok (<CODE>, DImode, operands)"
9479 "&& reload_completed"
9482 split_double_mode (DImode, &operands[0], 3, &operands[0], &operands[3]);
9483 if (operands[2] == constm1_rtx)
9487 operands[1] = constm1_rtx;
9488 ix86_expand_move (SImode, &operands[0]);
9491 ix86_expand_unary_operator (NOT, SImode, &operands[0]);
9493 else if (operands[2] != const0_rtx)
9494 ix86_expand_binary_operator (<CODE>, SImode, &operands[0]);
9495 else if (operands[5] == const0_rtx)
9496 emit_note (NOTE_INSN_DELETED);
9497 if (operands[5] == constm1_rtx)
9501 operands[4] = constm1_rtx;
9502 ix86_expand_move (SImode, &operands[3]);
9505 ix86_expand_unary_operator (NOT, SImode, &operands[3]);
9507 else if (operands[5] != const0_rtx)
9508 ix86_expand_binary_operator (<CODE>, SImode, &operands[3]);
9512 (define_insn "*<code><mode>_1"
9513 [(set (match_operand:SWI248 0 "nonimmediate_operand" "=r,rm")
9515 (match_operand:SWI248 1 "nonimmediate_operand" "%0,0")
9516 (match_operand:SWI248 2 "<general_operand>" "<g>,r<i>")))
9517 (clobber (reg:CC FLAGS_REG))]
9518 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9519 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
9520 [(set_attr "type" "alu")
9521 (set_attr "mode" "<MODE>")])
9523 (define_insn_and_split "*iordi_1_bts"
9524 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9526 (match_operand:DI 1 "nonimmediate_operand" "%0")
9527 (match_operand:DI 2 "const_int_operand" "n")))
9528 (clobber (reg:CC FLAGS_REG))]
9529 "TARGET_64BIT && TARGET_USE_BT
9530 && ix86_binary_operator_ok (IOR, DImode, operands)
9531 && IN_RANGE (exact_log2 (INTVAL (operands[2])), 31, 63)"
9533 "&& reload_completed"
9534 [(parallel [(set (zero_extract:DI (match_dup 0)
9538 (clobber (reg:CC FLAGS_REG))])]
9539 "operands[3] = GEN_INT (exact_log2 (INTVAL (operands[2])));"
9540 [(set_attr "type" "alu1")
9541 (set_attr "prefix_0f" "1")
9542 (set_attr "znver1_decode" "double")
9543 (set_attr "mode" "DI")])
9545 (define_insn_and_split "*xordi_1_btc"
9546 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9548 (match_operand:DI 1 "nonimmediate_operand" "%0")
9549 (match_operand:DI 2 "const_int_operand" "n")))
9550 (clobber (reg:CC FLAGS_REG))]
9551 "TARGET_64BIT && TARGET_USE_BT
9552 && ix86_binary_operator_ok (XOR, DImode, operands)
9553 && IN_RANGE (exact_log2 (INTVAL (operands[2])), 31, 63)"
9555 "&& reload_completed"
9556 [(parallel [(set (zero_extract:DI (match_dup 0)
9559 (not:DI (zero_extract:DI (match_dup 0)
9562 (clobber (reg:CC FLAGS_REG))])]
9563 "operands[3] = GEN_INT (exact_log2 (INTVAL (operands[2])));"
9564 [(set_attr "type" "alu1")
9565 (set_attr "prefix_0f" "1")
9566 (set_attr "znver1_decode" "double")
9567 (set_attr "mode" "DI")])
9569 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9570 (define_insn "*<code>si_1_zext"
9571 [(set (match_operand:DI 0 "register_operand" "=r")
9573 (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9574 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
9575 (clobber (reg:CC FLAGS_REG))]
9576 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
9577 "<logic>{l}\t{%2, %k0|%k0, %2}"
9578 [(set_attr "type" "alu")
9579 (set_attr "mode" "SI")])
9581 (define_insn "*<code>si_1_zext_imm"
9582 [(set (match_operand:DI 0 "register_operand" "=r")
9584 (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
9585 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
9586 (clobber (reg:CC FLAGS_REG))]
9587 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
9588 "<logic>{l}\t{%2, %k0|%k0, %2}"
9589 [(set_attr "type" "alu")
9590 (set_attr "mode" "SI")])
9592 (define_insn "*<code>qi_1"
9593 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
9594 (any_or:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9595 (match_operand:QI 2 "general_operand" "qmn,qn,rn")))
9596 (clobber (reg:CC FLAGS_REG))]
9597 "ix86_binary_operator_ok (<CODE>, QImode, operands)"
9599 <logic>{b}\t{%2, %0|%0, %2}
9600 <logic>{b}\t{%2, %0|%0, %2}
9601 <logic>{l}\t{%k2, %k0|%k0, %k2}"
9602 [(set_attr "type" "alu")
9603 (set_attr "mode" "QI,QI,SI")
9604 ;; Potential partial reg stall on alternative 2.
9605 (set (attr "preferred_for_speed")
9606 (cond [(eq_attr "alternative" "2")
9607 (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
9608 (symbol_ref "true")))])
9610 (define_insn "*<code>qi_1_slp"
9611 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
9612 (any_or:QI (match_dup 0)
9613 (match_operand:QI 1 "general_operand" "qmn,qn")))
9614 (clobber (reg:CC FLAGS_REG))]
9615 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9616 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9617 "<logic>{b}\t{%1, %0|%0, %1}"
9618 [(set_attr "type" "alu1")
9619 (set_attr "mode" "QI")])
9621 (define_insn "*<code><mode>_2"
9622 [(set (reg FLAGS_REG)
9623 (compare (any_or:SWI
9624 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
9625 (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>"))
9627 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
9628 (any_or:SWI (match_dup 1) (match_dup 2)))]
9629 "ix86_match_ccmode (insn, CCNOmode)
9630 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9631 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
9632 [(set_attr "type" "alu")
9633 (set_attr "mode" "<MODE>")])
9635 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9636 ;; ??? Special case for immediate operand is missing - it is tricky.
9637 (define_insn "*<code>si_2_zext"
9638 [(set (reg FLAGS_REG)
9639 (compare (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9640 (match_operand:SI 2 "x86_64_general_operand" "rme"))
9642 (set (match_operand:DI 0 "register_operand" "=r")
9643 (zero_extend:DI (any_or:SI (match_dup 1) (match_dup 2))))]
9644 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9645 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
9646 "<logic>{l}\t{%2, %k0|%k0, %2}"
9647 [(set_attr "type" "alu")
9648 (set_attr "mode" "SI")])
9650 (define_insn "*<code>si_2_zext_imm"
9651 [(set (reg FLAGS_REG)
9653 (match_operand:SI 1 "nonimmediate_operand" "%0")
9654 (match_operand:SI 2 "x86_64_zext_immediate_operand" "Z"))
9656 (set (match_operand:DI 0 "register_operand" "=r")
9657 (any_or:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
9658 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9659 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
9660 "<logic>{l}\t{%2, %k0|%k0, %2}"
9661 [(set_attr "type" "alu")
9662 (set_attr "mode" "SI")])
9664 (define_insn "*<code>qi_2_slp"
9665 [(set (reg FLAGS_REG)
9666 (compare (any_or:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9667 (match_operand:QI 1 "general_operand" "qmn,qn"))
9669 (set (strict_low_part (match_dup 0))
9670 (any_or:QI (match_dup 0) (match_dup 1)))]
9671 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9672 && ix86_match_ccmode (insn, CCNOmode)
9673 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9674 "<logic>{b}\t{%1, %0|%0, %1}"
9675 [(set_attr "type" "alu1")
9676 (set_attr "mode" "QI")])
9678 (define_insn "*<code><mode>_3"
9679 [(set (reg FLAGS_REG)
9680 (compare (any_or:SWI
9681 (match_operand:SWI 1 "nonimmediate_operand" "%0")
9682 (match_operand:SWI 2 "<general_operand>" "<g>"))
9684 (clobber (match_scratch:SWI 0 "=<r>"))]
9685 "ix86_match_ccmode (insn, CCNOmode)
9686 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9687 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
9688 [(set_attr "type" "alu")
9689 (set_attr "mode" "<MODE>")])
9691 (define_insn "*<code>qi_ext_1"
9692 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q,Q")
9698 (zero_extract:SI (match_operand 1 "ext_register_operand" "0,0")
9701 (match_operand:QI 2 "general_operand" "QnBc,m")) 0))
9702 (clobber (reg:CC FLAGS_REG))]
9703 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9704 /* FIXME: without this LRA can't reload this pattern, see PR82524. */
9705 && rtx_equal_p (operands[0], operands[1])"
9706 "<logic>{b}\t{%2, %h0|%h0, %2}"
9707 [(set_attr "isa" "*,nox64")
9708 (set_attr "type" "alu")
9709 (set_attr "mode" "QI")])
9711 (define_insn "*<code>qi_ext_2"
9712 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
9718 (zero_extract:SI (match_operand 1 "ext_register_operand" "%0")
9722 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9724 (const_int 8)) 0)) 0))
9725 (clobber (reg:CC FLAGS_REG))]
9726 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9727 /* FIXME: without this LRA can't reload this pattern, see PR82524. */
9728 && (rtx_equal_p (operands[0], operands[1])
9729 || rtx_equal_p (operands[0], operands[2]))"
9730 "<logic>{b}\t{%h2, %h0|%h0, %h2}"
9731 [(set_attr "type" "alu")
9732 (set_attr "mode" "QI")])
9734 ;; Convert wide OR instructions with immediate operand to shorter QImode
9735 ;; equivalents when possible.
9736 ;; Don't do the splitting with memory operands, since it introduces risk
9737 ;; of memory mismatch stalls. We may want to do the splitting for optimizing
9738 ;; for size, but that can (should?) be handled by generic code instead.
9740 [(set (match_operand:SWI248 0 "QIreg_operand")
9741 (any_or:SWI248 (match_operand:SWI248 1 "register_operand")
9742 (match_operand:SWI248 2 "const_int_operand")))
9743 (clobber (reg:CC FLAGS_REG))]
9745 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9746 && !(INTVAL (operands[2]) & ~(255 << 8))"
9748 [(set (zero_extract:SI (match_dup 0)
9754 (zero_extract:SI (match_dup 1)
9758 (clobber (reg:CC FLAGS_REG))])]
9760 operands[0] = gen_lowpart (SImode, operands[0]);
9761 operands[1] = gen_lowpart (SImode, operands[1]);
9762 operands[2] = gen_int_mode (INTVAL (operands[2]) >> 8, QImode);
9765 ;; Since OR can be encoded with sign extended immediate, this is only
9766 ;; profitable when 7th bit is set.
9768 [(set (match_operand:SWI248 0 "any_QIreg_operand")
9769 (any_or:SWI248 (match_operand:SWI248 1 "general_operand")
9770 (match_operand:SWI248 2 "const_int_operand")))
9771 (clobber (reg:CC FLAGS_REG))]
9773 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9774 && !(INTVAL (operands[2]) & ~255)
9775 && (INTVAL (operands[2]) & 128)"
9776 [(parallel [(set (strict_low_part (match_dup 0))
9777 (any_or:QI (match_dup 1)
9779 (clobber (reg:CC FLAGS_REG))])]
9781 operands[0] = gen_lowpart (QImode, operands[0]);
9782 operands[1] = gen_lowpart (QImode, operands[1]);
9783 operands[2] = gen_int_mode (INTVAL (operands[2]), QImode);
9786 (define_expand "xorqi_ext_1_cc"
9788 (set (reg:CCNO FLAGS_REG)
9792 (zero_extract:SI (match_operand 1 "ext_register_operand")
9795 (match_operand 2 "const_int_operand"))
9797 (set (zero_extract:SI (match_operand 0 "ext_register_operand")
9803 (zero_extract:SI (match_dup 1)
9806 (match_dup 2)) 0))])])
9808 (define_insn "*xorqi_ext_1_cc"
9809 [(set (reg FLAGS_REG)
9813 (zero_extract:SI (match_operand 1 "ext_register_operand" "0,0")
9816 (match_operand:QI 2 "general_operand" "QnBc,m"))
9818 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q,Q")
9824 (zero_extract:SI (match_dup 1)
9828 "ix86_match_ccmode (insn, CCNOmode)
9829 /* FIXME: without this LRA can't reload this pattern, see PR82524. */
9830 && rtx_equal_p (operands[0], operands[1])"
9831 "xor{b}\t{%2, %h0|%h0, %2}"
9832 [(set_attr "isa" "*,nox64")
9833 (set_attr "type" "alu")
9834 (set_attr "mode" "QI")])
9836 ;; Negation instructions
9838 (define_expand "neg<mode>2"
9839 [(set (match_operand:SDWIM 0 "nonimmediate_operand")
9840 (neg:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")))]
9842 "ix86_expand_unary_operator (NEG, <MODE>mode, operands); DONE;")
9844 (define_insn_and_split "*neg<dwi>2_doubleword"
9845 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro")
9846 (neg:<DWI> (match_operand:<DWI> 1 "nonimmediate_operand" "0")))
9847 (clobber (reg:CC FLAGS_REG))]
9848 "ix86_unary_operator_ok (NEG, <DWI>mode, operands)"
9852 [(set (reg:CCZ FLAGS_REG)
9853 (compare:CCZ (neg:DWIH (match_dup 1)) (const_int 0)))
9854 (set (match_dup 0) (neg:DWIH (match_dup 1)))])
9857 (plus:DWIH (plus:DWIH (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
9860 (clobber (reg:CC FLAGS_REG))])
9863 (neg:DWIH (match_dup 2)))
9864 (clobber (reg:CC FLAGS_REG))])]
9865 "split_double_mode (<DWI>mode, &operands[0], 2, &operands[0], &operands[2]);")
9867 (define_insn "*neg<mode>2_1"
9868 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9869 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")))
9870 (clobber (reg:CC FLAGS_REG))]
9871 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
9872 "neg{<imodesuffix>}\t%0"
9873 [(set_attr "type" "negnot")
9874 (set_attr "mode" "<MODE>")])
9876 ;; Combine is quite creative about this pattern.
9877 (define_insn "*negsi2_1_zext"
9878 [(set (match_operand:DI 0 "register_operand" "=r")
9880 (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
9883 (clobber (reg:CC FLAGS_REG))]
9884 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9886 [(set_attr "type" "negnot")
9887 (set_attr "mode" "SI")])
9889 ;; The problem with neg is that it does not perform (compare x 0),
9890 ;; it really performs (compare 0 x), which leaves us with the zero
9891 ;; flag being the only useful item.
9893 (define_insn "*neg<mode>2_cmpz"
9894 [(set (reg:CCZ FLAGS_REG)
9896 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
9898 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9899 (neg:SWI (match_dup 1)))]
9900 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
9901 "neg{<imodesuffix>}\t%0"
9902 [(set_attr "type" "negnot")
9903 (set_attr "mode" "<MODE>")])
9905 (define_insn "*negsi2_cmpz_zext"
9906 [(set (reg:CCZ FLAGS_REG)
9910 (match_operand:DI 1 "register_operand" "0")
9914 (set (match_operand:DI 0 "register_operand" "=r")
9915 (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
9918 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9920 [(set_attr "type" "negnot")
9921 (set_attr "mode" "SI")])
9923 ;; Negate with jump on overflow.
9924 (define_expand "negv<mode>3"
9925 [(parallel [(set (reg:CCO FLAGS_REG)
9926 (ne:CCO (match_operand:SWI 1 "register_operand")
9928 (set (match_operand:SWI 0 "register_operand")
9929 (neg:SWI (match_dup 1)))])
9930 (set (pc) (if_then_else
9931 (eq (reg:CCO FLAGS_REG) (const_int 0))
9932 (label_ref (match_operand 2))
9937 = gen_int_mode (HOST_WIDE_INT_1U << (GET_MODE_BITSIZE (<MODE>mode) - 1),
9941 (define_insn "*negv<mode>3"
9942 [(set (reg:CCO FLAGS_REG)
9943 (ne:CCO (match_operand:SWI 1 "nonimmediate_operand" "0")
9944 (match_operand:SWI 2 "const_int_operand")))
9945 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9946 (neg:SWI (match_dup 1)))]
9947 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)
9948 && mode_signbit_p (<MODE>mode, operands[2])"
9949 "neg{<imodesuffix>}\t%0"
9950 [(set_attr "type" "negnot")
9951 (set_attr "mode" "<MODE>")])
9953 ;; Changing of sign for FP values is doable using integer unit too.
9955 (define_expand "<code><mode>2"
9956 [(set (match_operand:X87MODEF 0 "register_operand")
9957 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand")))]
9958 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
9959 "ix86_expand_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
9961 (define_insn "*absneg<mode>2"
9962 [(set (match_operand:MODEF 0 "register_operand" "=Yv,Yv,f,!r")
9963 (match_operator:MODEF 3 "absneg_operator"
9964 [(match_operand:MODEF 1 "register_operand" "0,Yv,0,0")]))
9965 (use (match_operand:<ssevecmode> 2 "nonimmediate_operand" "Yvm,0,X,X"))
9966 (clobber (reg:CC FLAGS_REG))]
9967 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
9969 [(set (attr "enabled")
9971 (match_test ("SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"))
9973 (eq_attr "alternative" "2")
9974 (symbol_ref "TARGET_MIX_SSE_I387")
9975 (symbol_ref "true"))
9977 (eq_attr "alternative" "2,3")
9979 (symbol_ref "false"))))])
9981 (define_insn "*absnegxf2_i387"
9982 [(set (match_operand:XF 0 "register_operand" "=f,!r")
9983 (match_operator:XF 3 "absneg_operator"
9984 [(match_operand:XF 1 "register_operand" "0,0")]))
9985 (use (match_operand 2))
9986 (clobber (reg:CC FLAGS_REG))]
9990 (define_expand "<code>tf2"
9991 [(set (match_operand:TF 0 "register_operand")
9992 (absneg:TF (match_operand:TF 1 "register_operand")))]
9994 "ix86_expand_fp_absneg_operator (<CODE>, TFmode, operands); DONE;")
9996 (define_insn "*absnegtf2_sse"
9997 [(set (match_operand:TF 0 "register_operand" "=Yv,Yv")
9998 (match_operator:TF 3 "absneg_operator"
9999 [(match_operand:TF 1 "register_operand" "0,Yv")]))
10000 (use (match_operand:TF 2 "nonimmediate_operand" "Yvm,0"))
10001 (clobber (reg:CC FLAGS_REG))]
10005 ;; Splitters for fp abs and neg.
10008 [(set (match_operand 0 "fp_register_operand")
10009 (match_operator 1 "absneg_operator" [(match_dup 0)]))
10010 (use (match_operand 2))
10011 (clobber (reg:CC FLAGS_REG))]
10013 [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
10016 [(set (match_operand 0 "sse_reg_operand")
10017 (match_operator 3 "absneg_operator"
10018 [(match_operand 1 "register_operand")]))
10019 (use (match_operand 2 "nonimmediate_operand"))
10020 (clobber (reg:CC FLAGS_REG))]
10022 [(set (match_dup 0) (match_dup 3))]
10024 machine_mode mode = GET_MODE (operands[0]);
10025 machine_mode vmode = GET_MODE (operands[2]);
10028 operands[0] = lowpart_subreg (vmode, operands[0], mode);
10029 operands[1] = lowpart_subreg (vmode, operands[1], mode);
10030 if (operands_match_p (operands[0], operands[2]))
10031 std::swap (operands[1], operands[2]);
10032 if (GET_CODE (operands[3]) == ABS)
10033 tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
10035 tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
10040 [(set (match_operand:SF 0 "general_reg_operand")
10041 (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
10042 (use (match_operand:V4SF 2))
10043 (clobber (reg:CC FLAGS_REG))]
10045 [(parallel [(set (match_dup 0) (match_dup 1))
10046 (clobber (reg:CC FLAGS_REG))])]
10049 operands[0] = gen_lowpart (SImode, operands[0]);
10050 if (GET_CODE (operands[1]) == ABS)
10052 tmp = gen_int_mode (0x7fffffff, SImode);
10053 tmp = gen_rtx_AND (SImode, operands[0], tmp);
10057 tmp = gen_int_mode (0x80000000, SImode);
10058 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
10064 [(set (match_operand:DF 0 "general_reg_operand")
10065 (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
10066 (use (match_operand 2))
10067 (clobber (reg:CC FLAGS_REG))]
10069 [(parallel [(set (match_dup 0) (match_dup 1))
10070 (clobber (reg:CC FLAGS_REG))])]
10075 tmp = gen_lowpart (DImode, operands[0]);
10076 tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
10079 if (GET_CODE (operands[1]) == ABS)
10082 tmp = gen_rtx_NOT (DImode, tmp);
10086 operands[0] = gen_highpart (SImode, operands[0]);
10087 if (GET_CODE (operands[1]) == ABS)
10089 tmp = gen_int_mode (0x7fffffff, SImode);
10090 tmp = gen_rtx_AND (SImode, operands[0], tmp);
10094 tmp = gen_int_mode (0x80000000, SImode);
10095 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
10102 [(set (match_operand:XF 0 "general_reg_operand")
10103 (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
10104 (use (match_operand 2))
10105 (clobber (reg:CC FLAGS_REG))]
10107 [(parallel [(set (match_dup 0) (match_dup 1))
10108 (clobber (reg:CC FLAGS_REG))])]
10111 operands[0] = gen_rtx_REG (SImode,
10112 REGNO (operands[0]) + (TARGET_64BIT ? 1 : 2));
10113 if (GET_CODE (operands[1]) == ABS)
10115 tmp = GEN_INT (0x7fff);
10116 tmp = gen_rtx_AND (SImode, operands[0], tmp);
10120 tmp = GEN_INT (0x8000);
10121 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
10126 ;; Conditionalize these after reload. If they match before reload, we
10127 ;; lose the clobber and ability to use integer instructions.
10129 (define_insn "*<code><mode>2_1"
10130 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
10131 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "0")))]
10133 && (reload_completed
10134 || !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
10135 "f<absneg_mnemonic>"
10136 [(set_attr "type" "fsgn")
10137 (set_attr "mode" "<MODE>")])
10139 (define_insn "*<code>extendsfdf2"
10140 [(set (match_operand:DF 0 "register_operand" "=f")
10141 (absneg:DF (float_extend:DF
10142 (match_operand:SF 1 "register_operand" "0"))))]
10143 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
10144 "f<absneg_mnemonic>"
10145 [(set_attr "type" "fsgn")
10146 (set_attr "mode" "DF")])
10148 (define_insn "*<code>extendsfxf2"
10149 [(set (match_operand:XF 0 "register_operand" "=f")
10150 (absneg:XF (float_extend:XF
10151 (match_operand:SF 1 "register_operand" "0"))))]
10153 "f<absneg_mnemonic>"
10154 [(set_attr "type" "fsgn")
10155 (set_attr "mode" "XF")])
10157 (define_insn "*<code>extenddfxf2"
10158 [(set (match_operand:XF 0 "register_operand" "=f")
10159 (absneg:XF (float_extend:XF
10160 (match_operand:DF 1 "register_operand" "0"))))]
10162 "f<absneg_mnemonic>"
10163 [(set_attr "type" "fsgn")
10164 (set_attr "mode" "XF")])
10166 ;; Copysign instructions
10168 (define_mode_iterator CSGNMODE [SF DF TF])
10169 (define_mode_attr CSGNVMODE [(SF "V4SF") (DF "V2DF") (TF "TF")])
10171 (define_expand "copysign<mode>3"
10172 [(match_operand:CSGNMODE 0 "register_operand")
10173 (match_operand:CSGNMODE 1 "nonmemory_operand")
10174 (match_operand:CSGNMODE 2 "register_operand")]
10175 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10176 || (TARGET_SSE && (<MODE>mode == TFmode))"
10177 "ix86_expand_copysign (operands); DONE;")
10179 (define_insn_and_split "copysign<mode>3_const"
10180 [(set (match_operand:CSGNMODE 0 "register_operand" "=Yv")
10182 [(match_operand:<CSGNVMODE> 1 "vector_move_operand" "YvmC")
10183 (match_operand:CSGNMODE 2 "register_operand" "0")
10184 (match_operand:<CSGNVMODE> 3 "nonimmediate_operand" "Yvm")]
10186 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10187 || (TARGET_SSE && (<MODE>mode == TFmode))"
10189 "&& reload_completed"
10191 "ix86_split_copysign_const (operands); DONE;")
10193 (define_insn "copysign<mode>3_var"
10194 [(set (match_operand:CSGNMODE 0 "register_operand" "=Yv,Yv,Yv,Yv,Yv")
10196 [(match_operand:CSGNMODE 2 "register_operand" "Yv,0,0,Yv,Yv")
10197 (match_operand:CSGNMODE 3 "register_operand" "1,1,Yv,1,Yv")
10198 (match_operand:<CSGNVMODE> 4
10199 "nonimmediate_operand" "X,Yvm,Yvm,0,0")
10200 (match_operand:<CSGNVMODE> 5
10201 "nonimmediate_operand" "0,Yvm,1,Yvm,1")]
10203 (clobber (match_scratch:<CSGNVMODE> 1 "=Yv,Yv,Yv,Yv,Yv"))]
10204 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10205 || (TARGET_SSE && (<MODE>mode == TFmode))"
10209 [(set (match_operand:CSGNMODE 0 "register_operand")
10211 [(match_operand:CSGNMODE 2 "register_operand")
10212 (match_operand:CSGNMODE 3 "register_operand")
10213 (match_operand:<CSGNVMODE> 4)
10214 (match_operand:<CSGNVMODE> 5)]
10216 (clobber (match_scratch:<CSGNVMODE> 1))]
10217 "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10218 || (TARGET_SSE && (<MODE>mode == TFmode)))
10219 && reload_completed"
10221 "ix86_split_copysign_var (operands); DONE;")
10223 ;; One complement instructions
10225 (define_expand "one_cmpl<mode>2"
10226 [(set (match_operand:SWIM1248x 0 "nonimmediate_operand")
10227 (not:SWIM1248x (match_operand:SWIM1248x 1 "nonimmediate_operand")))]
10229 "ix86_expand_unary_operator (NOT, <MODE>mode, operands); DONE;")
10231 (define_insn_and_split "*one_cmpldi2_doubleword"
10232 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10233 (not:DI (match_operand:DI 1 "nonimmediate_operand" "0")))]
10234 "!TARGET_64BIT && TARGET_STV && TARGET_SSE2
10235 && ix86_unary_operator_ok (NOT, DImode, operands)"
10237 "&& reload_completed"
10238 [(set (match_dup 0)
10239 (not:SI (match_dup 1)))
10241 (not:SI (match_dup 3)))]
10242 "split_double_mode (DImode, &operands[0], 2, &operands[0], &operands[2]);")
10244 (define_insn "*one_cmpl<mode>2_1"
10245 [(set (match_operand:SWI248 0 "nonimmediate_operand" "=rm")
10246 (not:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "0")))]
10247 "ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
10248 "not{<imodesuffix>}\t%0"
10249 [(set_attr "type" "negnot")
10250 (set_attr "mode" "<MODE>")])
10252 ;; ??? Currently never generated - xor is used instead.
10253 (define_insn "*one_cmplsi2_1_zext"
10254 [(set (match_operand:DI 0 "register_operand" "=r")
10256 (not:SI (match_operand:SI 1 "register_operand" "0"))))]
10257 "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
10259 [(set_attr "type" "negnot")
10260 (set_attr "mode" "SI")])
10262 (define_insn "*one_cmplqi2_1"
10263 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
10264 (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
10265 "ix86_unary_operator_ok (NOT, QImode, operands)"
10269 [(set_attr "type" "negnot")
10270 (set_attr "mode" "QI,SI")
10271 ;; Potential partial reg stall on alternative 1.
10272 (set (attr "preferred_for_speed")
10273 (cond [(eq_attr "alternative" "1")
10274 (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
10275 (symbol_ref "true")))])
10277 (define_insn "*one_cmpl<mode>2_2"
10278 [(set (reg FLAGS_REG)
10279 (compare (not:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
10281 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
10282 (not:SWI (match_dup 1)))]
10283 "ix86_match_ccmode (insn, CCNOmode)
10284 && ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
10286 [(set_attr "type" "alu1")
10287 (set_attr "mode" "<MODE>")])
10290 [(set (match_operand 0 "flags_reg_operand")
10291 (match_operator 2 "compare_operator"
10292 [(not:SWI (match_operand:SWI 3 "nonimmediate_operand"))
10294 (set (match_operand:SWI 1 "nonimmediate_operand")
10295 (not:SWI (match_dup 3)))]
10296 "ix86_match_ccmode (insn, CCNOmode)"
10297 [(parallel [(set (match_dup 0)
10298 (match_op_dup 2 [(xor:SWI (match_dup 3) (const_int -1))
10301 (xor:SWI (match_dup 3) (const_int -1)))])])
10303 ;; ??? Currently never generated - xor is used instead.
10304 (define_insn "*one_cmplsi2_2_zext"
10305 [(set (reg FLAGS_REG)
10306 (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
10308 (set (match_operand:DI 0 "register_operand" "=r")
10309 (zero_extend:DI (not:SI (match_dup 1))))]
10310 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10311 && ix86_unary_operator_ok (NOT, SImode, operands)"
10313 [(set_attr "type" "alu1")
10314 (set_attr "mode" "SI")])
10317 [(set (match_operand 0 "flags_reg_operand")
10318 (match_operator 2 "compare_operator"
10319 [(not:SI (match_operand:SI 3 "register_operand"))
10321 (set (match_operand:DI 1 "register_operand")
10322 (zero_extend:DI (not:SI (match_dup 3))))]
10323 "ix86_match_ccmode (insn, CCNOmode)"
10324 [(parallel [(set (match_dup 0)
10325 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10328 (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])])
10330 ;; Shift instructions
10332 ;; DImode shifts are implemented using the i386 "shift double" opcode,
10333 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem". If the shift count
10334 ;; is variable, then the count is in %cl and the "imm" operand is dropped
10335 ;; from the assembler input.
10337 ;; This instruction shifts the target reg/mem as usual, but instead of
10338 ;; shifting in zeros, bits are shifted in from reg operand. If the insn
10339 ;; is a left shift double, bits are taken from the high order bits of
10340 ;; reg, else if the insn is a shift right double, bits are taken from the
10341 ;; low order bits of reg. So if %eax is "1234" and %edx is "5678",
10342 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
10344 ;; Since sh[lr]d does not change the `reg' operand, that is done
10345 ;; separately, making all shifts emit pairs of shift double and normal
10346 ;; shift. Since sh[lr]d does not shift more than 31 bits, and we wish to
10347 ;; support a 63 bit shift, each shift where the count is in a reg expands
10348 ;; to a pair of shifts, a branch, a shift by 32 and a label.
10350 ;; If the shift count is a constant, we need never emit more than one
10351 ;; shift pair, instead using moves and sign extension for counts greater
10354 (define_expand "ashl<mode>3"
10355 [(set (match_operand:SDWIM 0 "<shift_operand>")
10356 (ashift:SDWIM (match_operand:SDWIM 1 "<ashl_input_operand>")
10357 (match_operand:QI 2 "nonmemory_operand")))]
10359 "ix86_expand_binary_operator (ASHIFT, <MODE>mode, operands); DONE;")
10361 (define_insn_and_split "*ashl<dwi>3_doubleword_mask"
10362 [(set (match_operand:<DWI> 0 "register_operand")
10364 (match_operand:<DWI> 1 "register_operand")
10367 (match_operand:SI 2 "register_operand" "c")
10368 (match_operand:SI 3 "const_int_operand")) 0)))
10369 (clobber (reg:CC FLAGS_REG))]
10370 "(INTVAL (operands[3]) & (<MODE_SIZE> * BITS_PER_UNIT)) == 0
10371 && can_create_pseudo_p ()"
10375 [(set (match_dup 6)
10376 (ior:DWIH (ashift:DWIH (match_dup 6) (match_dup 2))
10377 (lshiftrt:DWIH (match_dup 5)
10378 (minus:QI (match_dup 8) (match_dup 2)))))
10379 (clobber (reg:CC FLAGS_REG))])
10381 [(set (match_dup 4)
10382 (ashift:DWIH (match_dup 5) (match_dup 2)))
10383 (clobber (reg:CC FLAGS_REG))])]
10385 split_double_mode (<DWI>mode, &operands[0], 2, &operands[4], &operands[6]);
10387 operands[8] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT);
10389 if ((INTVAL (operands[3]) & ((<MODE_SIZE> * BITS_PER_UNIT) - 1))
10390 != ((<MODE_SIZE> * BITS_PER_UNIT) - 1))
10392 rtx tem = gen_reg_rtx (SImode);
10393 emit_insn (gen_andsi3 (tem, operands[2], operands[3]));
10397 operands[2] = gen_lowpart (QImode, operands[2]);
10399 if (!rtx_equal_p (operands[6], operands[7]))
10400 emit_move_insn (operands[6], operands[7]);
10403 (define_insn_and_split "*ashl<dwi>3_doubleword_mask_1"
10404 [(set (match_operand:<DWI> 0 "register_operand")
10406 (match_operand:<DWI> 1 "register_operand")
10408 (match_operand:QI 2 "register_operand" "c")
10409 (match_operand:QI 3 "const_int_operand"))))
10410 (clobber (reg:CC FLAGS_REG))]
10411 "(INTVAL (operands[3]) & (<MODE_SIZE> * BITS_PER_UNIT)) == 0
10412 && can_create_pseudo_p ()"
10416 [(set (match_dup 6)
10417 (ior:DWIH (ashift:DWIH (match_dup 6) (match_dup 2))
10418 (lshiftrt:DWIH (match_dup 5)
10419 (minus:QI (match_dup 8) (match_dup 2)))))
10420 (clobber (reg:CC FLAGS_REG))])
10422 [(set (match_dup 4)
10423 (ashift:DWIH (match_dup 5) (match_dup 2)))
10424 (clobber (reg:CC FLAGS_REG))])]
10426 split_double_mode (<DWI>mode, &operands[0], 2, &operands[4], &operands[6]);
10428 operands[8] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT);
10430 if ((INTVAL (operands[3]) & ((<MODE_SIZE> * BITS_PER_UNIT) - 1))
10431 != ((<MODE_SIZE> * BITS_PER_UNIT) - 1))
10433 rtx tem = gen_reg_rtx (QImode);
10434 emit_insn (gen_andqi3 (tem, operands[2], operands[3]));
10438 if (!rtx_equal_p (operands[6], operands[7]))
10439 emit_move_insn (operands[6], operands[7]);
10442 (define_insn "*ashl<mode>3_doubleword"
10443 [(set (match_operand:DWI 0 "register_operand" "=&r")
10444 (ashift:DWI (match_operand:DWI 1 "reg_or_pm1_operand" "0n")
10445 (match_operand:QI 2 "nonmemory_operand" "<S>c")))
10446 (clobber (reg:CC FLAGS_REG))]
10449 [(set_attr "type" "multi")])
10452 [(set (match_operand:DWI 0 "register_operand")
10453 (ashift:DWI (match_operand:DWI 1 "nonmemory_operand")
10454 (match_operand:QI 2 "nonmemory_operand")))
10455 (clobber (reg:CC FLAGS_REG))]
10456 "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
10458 "ix86_split_ashl (operands, NULL_RTX, <MODE>mode); DONE;")
10460 ;; By default we don't ask for a scratch register, because when DWImode
10461 ;; values are manipulated, registers are already at a premium. But if
10462 ;; we have one handy, we won't turn it away.
10465 [(match_scratch:DWIH 3 "r")
10466 (parallel [(set (match_operand:<DWI> 0 "register_operand")
10468 (match_operand:<DWI> 1 "nonmemory_operand")
10469 (match_operand:QI 2 "nonmemory_operand")))
10470 (clobber (reg:CC FLAGS_REG))])
10474 "ix86_split_ashl (operands, operands[3], <DWI>mode); DONE;")
10476 (define_insn "x86_64_shld"
10477 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
10478 (ior:DI (ashift:DI (match_dup 0)
10479 (match_operand:QI 2 "nonmemory_operand" "Jc"))
10480 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
10481 (minus:QI (const_int 64) (match_dup 2)))))
10482 (clobber (reg:CC FLAGS_REG))]
10484 "shld{q}\t{%s2%1, %0|%0, %1, %2}"
10485 [(set_attr "type" "ishift")
10486 (set_attr "prefix_0f" "1")
10487 (set_attr "mode" "DI")
10488 (set_attr "athlon_decode" "vector")
10489 (set_attr "amdfam10_decode" "vector")
10490 (set_attr "bdver1_decode" "vector")])
10492 (define_insn "x86_shld"
10493 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
10494 (ior:SI (ashift:SI (match_dup 0)
10495 (match_operand:QI 2 "nonmemory_operand" "Ic"))
10496 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
10497 (minus:QI (const_int 32) (match_dup 2)))))
10498 (clobber (reg:CC FLAGS_REG))]
10500 "shld{l}\t{%s2%1, %0|%0, %1, %2}"
10501 [(set_attr "type" "ishift")
10502 (set_attr "prefix_0f" "1")
10503 (set_attr "mode" "SI")
10504 (set_attr "pent_pair" "np")
10505 (set_attr "athlon_decode" "vector")
10506 (set_attr "amdfam10_decode" "vector")
10507 (set_attr "bdver1_decode" "vector")])
10509 (define_expand "x86_shift<mode>_adj_1"
10510 [(set (reg:CCZ FLAGS_REG)
10511 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand")
10514 (set (match_operand:SWI48 0 "register_operand")
10515 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
10516 (match_operand:SWI48 1 "register_operand")
10519 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
10520 (match_operand:SWI48 3 "register_operand")
10523 "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
10525 (define_expand "x86_shift<mode>_adj_2"
10526 [(use (match_operand:SWI48 0 "register_operand"))
10527 (use (match_operand:SWI48 1 "register_operand"))
10528 (use (match_operand:QI 2 "register_operand"))]
10531 rtx_code_label *label = gen_label_rtx ();
10534 emit_insn (gen_testqi_ccz_1 (operands[2],
10535 GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
10537 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
10538 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
10539 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
10540 gen_rtx_LABEL_REF (VOIDmode, label),
10542 tmp = emit_jump_insn (gen_rtx_SET (pc_rtx, tmp));
10543 JUMP_LABEL (tmp) = label;
10545 emit_move_insn (operands[0], operands[1]);
10546 ix86_expand_clear (operands[1]);
10548 emit_label (label);
10549 LABEL_NUSES (label) = 1;
10554 ;; Avoid useless masking of count operand.
10555 (define_insn_and_split "*ashl<mode>3_mask"
10556 [(set (match_operand:SWI48 0 "nonimmediate_operand")
10558 (match_operand:SWI48 1 "nonimmediate_operand")
10561 (match_operand:SI 2 "register_operand" "c,r")
10562 (match_operand:SI 3 "const_int_operand")) 0)))
10563 (clobber (reg:CC FLAGS_REG))]
10564 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)
10565 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10566 == GET_MODE_BITSIZE (<MODE>mode)-1
10567 && can_create_pseudo_p ()"
10571 [(set (match_dup 0)
10572 (ashift:SWI48 (match_dup 1)
10574 (clobber (reg:CC FLAGS_REG))])]
10575 "operands[2] = gen_lowpart (QImode, operands[2]);"
10576 [(set_attr "isa" "*,bmi2")])
10578 (define_insn_and_split "*ashl<mode>3_mask_1"
10579 [(set (match_operand:SWI48 0 "nonimmediate_operand")
10581 (match_operand:SWI48 1 "nonimmediate_operand")
10583 (match_operand:QI 2 "register_operand" "c,r")
10584 (match_operand:QI 3 "const_int_operand"))))
10585 (clobber (reg:CC FLAGS_REG))]
10586 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)
10587 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10588 == GET_MODE_BITSIZE (<MODE>mode)-1
10589 && can_create_pseudo_p ()"
10593 [(set (match_dup 0)
10594 (ashift:SWI48 (match_dup 1)
10596 (clobber (reg:CC FLAGS_REG))])]
10598 [(set_attr "isa" "*,bmi2")])
10600 (define_insn "*bmi2_ashl<mode>3_1"
10601 [(set (match_operand:SWI48 0 "register_operand" "=r")
10602 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
10603 (match_operand:SWI48 2 "register_operand" "r")))]
10605 "shlx\t{%2, %1, %0|%0, %1, %2}"
10606 [(set_attr "type" "ishiftx")
10607 (set_attr "mode" "<MODE>")])
10609 (define_insn "*ashl<mode>3_1"
10610 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r,r")
10611 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,l,rm")
10612 (match_operand:QI 2 "nonmemory_operand" "c<S>,M,r")))
10613 (clobber (reg:CC FLAGS_REG))]
10614 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
10616 switch (get_attr_type (insn))
10623 gcc_assert (operands[2] == const1_rtx);
10624 gcc_assert (rtx_equal_p (operands[0], operands[1]));
10625 return "add{<imodesuffix>}\t%0, %0";
10628 if (operands[2] == const1_rtx
10629 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10630 return "sal{<imodesuffix>}\t%0";
10632 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
10635 [(set_attr "isa" "*,*,bmi2")
10637 (cond [(eq_attr "alternative" "1")
10638 (const_string "lea")
10639 (eq_attr "alternative" "2")
10640 (const_string "ishiftx")
10641 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
10642 (match_operand 0 "register_operand"))
10643 (match_operand 2 "const1_operand"))
10644 (const_string "alu")
10646 (const_string "ishift")))
10647 (set (attr "length_immediate")
10649 (ior (eq_attr "type" "alu")
10650 (and (eq_attr "type" "ishift")
10651 (and (match_operand 2 "const1_operand")
10652 (ior (match_test "TARGET_SHIFT1")
10653 (match_test "optimize_function_for_size_p (cfun)")))))
10655 (const_string "*")))
10656 (set_attr "mode" "<MODE>")])
10658 ;; Convert shift to the shiftx pattern to avoid flags dependency.
10660 [(set (match_operand:SWI48 0 "register_operand")
10661 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
10662 (match_operand:QI 2 "register_operand")))
10663 (clobber (reg:CC FLAGS_REG))]
10664 "TARGET_BMI2 && reload_completed"
10665 [(set (match_dup 0)
10666 (ashift:SWI48 (match_dup 1) (match_dup 2)))]
10667 "operands[2] = gen_lowpart (<MODE>mode, operands[2]);")
10669 (define_insn "*bmi2_ashlsi3_1_zext"
10670 [(set (match_operand:DI 0 "register_operand" "=r")
10672 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
10673 (match_operand:SI 2 "register_operand" "r"))))]
10674 "TARGET_64BIT && TARGET_BMI2"
10675 "shlx\t{%2, %1, %k0|%k0, %1, %2}"
10676 [(set_attr "type" "ishiftx")
10677 (set_attr "mode" "SI")])
10679 (define_insn "*ashlsi3_1_zext"
10680 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
10682 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l,rm")
10683 (match_operand:QI 2 "nonmemory_operand" "cI,M,r"))))
10684 (clobber (reg:CC FLAGS_REG))]
10685 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10687 switch (get_attr_type (insn))
10694 gcc_assert (operands[2] == const1_rtx);
10695 return "add{l}\t%k0, %k0";
10698 if (operands[2] == const1_rtx
10699 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10700 return "sal{l}\t%k0";
10702 return "sal{l}\t{%2, %k0|%k0, %2}";
10705 [(set_attr "isa" "*,*,bmi2")
10707 (cond [(eq_attr "alternative" "1")
10708 (const_string "lea")
10709 (eq_attr "alternative" "2")
10710 (const_string "ishiftx")
10711 (and (match_test "TARGET_DOUBLE_WITH_ADD")
10712 (match_operand 2 "const1_operand"))
10713 (const_string "alu")
10715 (const_string "ishift")))
10716 (set (attr "length_immediate")
10718 (ior (eq_attr "type" "alu")
10719 (and (eq_attr "type" "ishift")
10720 (and (match_operand 2 "const1_operand")
10721 (ior (match_test "TARGET_SHIFT1")
10722 (match_test "optimize_function_for_size_p (cfun)")))))
10724 (const_string "*")))
10725 (set_attr "mode" "SI")])
10727 ;; Convert shift to the shiftx pattern to avoid flags dependency.
10729 [(set (match_operand:DI 0 "register_operand")
10731 (ashift:SI (match_operand:SI 1 "nonimmediate_operand")
10732 (match_operand:QI 2 "register_operand"))))
10733 (clobber (reg:CC FLAGS_REG))]
10734 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
10735 [(set (match_dup 0)
10736 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
10737 "operands[2] = gen_lowpart (SImode, operands[2]);")
10739 (define_insn "*ashlhi3_1"
10740 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,Yp")
10741 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
10742 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10743 (clobber (reg:CC FLAGS_REG))]
10744 "ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10746 switch (get_attr_type (insn))
10752 gcc_assert (operands[2] == const1_rtx);
10753 return "add{w}\t%0, %0";
10756 if (operands[2] == const1_rtx
10757 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10758 return "sal{w}\t%0";
10760 return "sal{w}\t{%2, %0|%0, %2}";
10763 [(set (attr "type")
10764 (cond [(eq_attr "alternative" "1")
10765 (const_string "lea")
10766 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
10767 (match_operand 0 "register_operand"))
10768 (match_operand 2 "const1_operand"))
10769 (const_string "alu")
10771 (const_string "ishift")))
10772 (set (attr "length_immediate")
10774 (ior (eq_attr "type" "alu")
10775 (and (eq_attr "type" "ishift")
10776 (and (match_operand 2 "const1_operand")
10777 (ior (match_test "TARGET_SHIFT1")
10778 (match_test "optimize_function_for_size_p (cfun)")))))
10780 (const_string "*")))
10781 (set_attr "mode" "HI,SI")])
10783 (define_insn "*ashlqi3_1"
10784 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,Yp")
10785 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
10786 (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
10787 (clobber (reg:CC FLAGS_REG))]
10788 "ix86_binary_operator_ok (ASHIFT, QImode, operands)"
10790 switch (get_attr_type (insn))
10796 gcc_assert (operands[2] == const1_rtx);
10797 if (REG_P (operands[1]) && !ANY_QI_REGNO_P (REGNO (operands[1])))
10798 return "add{l}\t%k0, %k0";
10800 return "add{b}\t%0, %0";
10803 if (operands[2] == const1_rtx
10804 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10806 if (get_attr_mode (insn) == MODE_SI)
10807 return "sal{l}\t%k0";
10809 return "sal{b}\t%0";
10813 if (get_attr_mode (insn) == MODE_SI)
10814 return "sal{l}\t{%2, %k0|%k0, %2}";
10816 return "sal{b}\t{%2, %0|%0, %2}";
10820 [(set (attr "type")
10821 (cond [(eq_attr "alternative" "2")
10822 (const_string "lea")
10823 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
10824 (match_operand 0 "register_operand"))
10825 (match_operand 2 "const1_operand"))
10826 (const_string "alu")
10828 (const_string "ishift")))
10829 (set (attr "length_immediate")
10831 (ior (eq_attr "type" "alu")
10832 (and (eq_attr "type" "ishift")
10833 (and (match_operand 2 "const1_operand")
10834 (ior (match_test "TARGET_SHIFT1")
10835 (match_test "optimize_function_for_size_p (cfun)")))))
10837 (const_string "*")))
10838 (set_attr "mode" "QI,SI,SI")
10839 ;; Potential partial reg stall on alternative 1.
10840 (set (attr "preferred_for_speed")
10841 (cond [(eq_attr "alternative" "1")
10842 (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
10843 (symbol_ref "true")))])
10845 (define_insn "*ashlqi3_1_slp"
10846 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10847 (ashift:QI (match_dup 0)
10848 (match_operand:QI 1 "nonmemory_operand" "cI")))
10849 (clobber (reg:CC FLAGS_REG))]
10850 "(optimize_function_for_size_p (cfun)
10851 || !TARGET_PARTIAL_FLAG_REG_STALL
10852 || (operands[1] == const1_rtx
10854 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
10856 switch (get_attr_type (insn))
10859 gcc_assert (operands[1] == const1_rtx);
10860 return "add{b}\t%0, %0";
10863 if (operands[1] == const1_rtx
10864 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10865 return "sal{b}\t%0";
10867 return "sal{b}\t{%1, %0|%0, %1}";
10870 [(set (attr "type")
10871 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
10872 (match_operand 0 "register_operand"))
10873 (match_operand 1 "const1_operand"))
10874 (const_string "alu1")
10876 (const_string "ishift1")))
10877 (set (attr "length_immediate")
10879 (ior (eq_attr "type" "alu1")
10880 (and (eq_attr "type" "ishift1")
10881 (and (match_operand 1 "const1_operand")
10882 (ior (match_test "TARGET_SHIFT1")
10883 (match_test "optimize_function_for_size_p (cfun)")))))
10885 (const_string "*")))
10886 (set_attr "mode" "QI")])
10888 ;; Convert ashift to the lea pattern to avoid flags dependency.
10890 [(set (match_operand:SWI 0 "register_operand")
10891 (ashift:SWI (match_operand:SWI 1 "index_register_operand")
10892 (match_operand 2 "const_0_to_3_operand")))
10893 (clobber (reg:CC FLAGS_REG))]
10895 && REGNO (operands[0]) != REGNO (operands[1])"
10896 [(set (match_dup 0)
10897 (mult:<LEAMODE> (match_dup 1) (match_dup 2)))]
10899 if (<MODE>mode != <LEAMODE>mode)
10901 operands[0] = gen_lowpart (<LEAMODE>mode, operands[0]);
10902 operands[1] = gen_lowpart (<LEAMODE>mode, operands[1]);
10904 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
10907 ;; Convert ashift to the lea pattern to avoid flags dependency.
10909 [(set (match_operand:DI 0 "register_operand")
10911 (ashift:SI (match_operand:SI 1 "index_register_operand")
10912 (match_operand 2 "const_0_to_3_operand"))))
10913 (clobber (reg:CC FLAGS_REG))]
10914 "TARGET_64BIT && reload_completed
10915 && REGNO (operands[0]) != REGNO (operands[1])"
10916 [(set (match_dup 0)
10917 (zero_extend:DI (mult:SI (match_dup 1) (match_dup 2))))]
10919 operands[1] = gen_lowpart (SImode, operands[1]);
10920 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
10923 ;; This pattern can't accept a variable shift count, since shifts by
10924 ;; zero don't affect the flags. We assume that shifts by constant
10925 ;; zero are optimized away.
10926 (define_insn "*ashl<mode>3_cmp"
10927 [(set (reg FLAGS_REG)
10929 (ashift:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
10930 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
10932 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
10933 (ashift:SWI (match_dup 1) (match_dup 2)))]
10934 "(optimize_function_for_size_p (cfun)
10935 || !TARGET_PARTIAL_FLAG_REG_STALL
10936 || (operands[2] == const1_rtx
10938 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
10939 && ix86_match_ccmode (insn, CCGOCmode)
10940 && ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
10942 switch (get_attr_type (insn))
10945 gcc_assert (operands[2] == const1_rtx);
10946 return "add{<imodesuffix>}\t%0, %0";
10949 if (operands[2] == const1_rtx
10950 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10951 return "sal{<imodesuffix>}\t%0";
10953 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
10956 [(set (attr "type")
10957 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
10958 (match_operand 0 "register_operand"))
10959 (match_operand 2 "const1_operand"))
10960 (const_string "alu")
10962 (const_string "ishift")))
10963 (set (attr "length_immediate")
10965 (ior (eq_attr "type" "alu")
10966 (and (eq_attr "type" "ishift")
10967 (and (match_operand 2 "const1_operand")
10968 (ior (match_test "TARGET_SHIFT1")
10969 (match_test "optimize_function_for_size_p (cfun)")))))
10971 (const_string "*")))
10972 (set_attr "mode" "<MODE>")])
10974 (define_insn "*ashlsi3_cmp_zext"
10975 [(set (reg FLAGS_REG)
10977 (ashift:SI (match_operand:SI 1 "register_operand" "0")
10978 (match_operand:QI 2 "const_1_to_31_operand" "I"))
10980 (set (match_operand:DI 0 "register_operand" "=r")
10981 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
10983 && (optimize_function_for_size_p (cfun)
10984 || !TARGET_PARTIAL_FLAG_REG_STALL
10985 || (operands[2] == const1_rtx
10987 || TARGET_DOUBLE_WITH_ADD)))
10988 && ix86_match_ccmode (insn, CCGOCmode)
10989 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10991 switch (get_attr_type (insn))
10994 gcc_assert (operands[2] == const1_rtx);
10995 return "add{l}\t%k0, %k0";
10998 if (operands[2] == const1_rtx
10999 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11000 return "sal{l}\t%k0";
11002 return "sal{l}\t{%2, %k0|%k0, %2}";
11005 [(set (attr "type")
11006 (cond [(and (match_test "TARGET_DOUBLE_WITH_ADD")
11007 (match_operand 2 "const1_operand"))
11008 (const_string "alu")
11010 (const_string "ishift")))
11011 (set (attr "length_immediate")
11013 (ior (eq_attr "type" "alu")
11014 (and (eq_attr "type" "ishift")
11015 (and (match_operand 2 "const1_operand")
11016 (ior (match_test "TARGET_SHIFT1")
11017 (match_test "optimize_function_for_size_p (cfun)")))))
11019 (const_string "*")))
11020 (set_attr "mode" "SI")])
11022 (define_insn "*ashl<mode>3_cconly"
11023 [(set (reg FLAGS_REG)
11025 (ashift:SWI (match_operand:SWI 1 "register_operand" "0")
11026 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
11028 (clobber (match_scratch:SWI 0 "=<r>"))]
11029 "(optimize_function_for_size_p (cfun)
11030 || !TARGET_PARTIAL_FLAG_REG_STALL
11031 || (operands[2] == const1_rtx
11033 || TARGET_DOUBLE_WITH_ADD)))
11034 && ix86_match_ccmode (insn, CCGOCmode)"
11036 switch (get_attr_type (insn))
11039 gcc_assert (operands[2] == const1_rtx);
11040 return "add{<imodesuffix>}\t%0, %0";
11043 if (operands[2] == const1_rtx
11044 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11045 return "sal{<imodesuffix>}\t%0";
11047 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
11050 [(set (attr "type")
11051 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
11052 (match_operand 0 "register_operand"))
11053 (match_operand 2 "const1_operand"))
11054 (const_string "alu")
11056 (const_string "ishift")))
11057 (set (attr "length_immediate")
11059 (ior (eq_attr "type" "alu")
11060 (and (eq_attr "type" "ishift")
11061 (and (match_operand 2 "const1_operand")
11062 (ior (match_test "TARGET_SHIFT1")
11063 (match_test "optimize_function_for_size_p (cfun)")))))
11065 (const_string "*")))
11066 (set_attr "mode" "<MODE>")])
11068 ;; See comment above `ashl<mode>3' about how this works.
11070 (define_expand "<shift_insn><mode>3"
11071 [(set (match_operand:SDWIM 0 "<shift_operand>")
11072 (any_shiftrt:SDWIM (match_operand:SDWIM 1 "<shift_operand>")
11073 (match_operand:QI 2 "nonmemory_operand")))]
11075 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
11077 ;; Avoid useless masking of count operand.
11078 (define_insn_and_split "*<shift_insn><mode>3_mask"
11079 [(set (match_operand:SWI48 0 "nonimmediate_operand")
11081 (match_operand:SWI48 1 "nonimmediate_operand")
11084 (match_operand:SI 2 "register_operand" "c,r")
11085 (match_operand:SI 3 "const_int_operand")) 0)))
11086 (clobber (reg:CC FLAGS_REG))]
11087 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
11088 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
11089 == GET_MODE_BITSIZE (<MODE>mode)-1
11090 && can_create_pseudo_p ()"
11094 [(set (match_dup 0)
11095 (any_shiftrt:SWI48 (match_dup 1)
11097 (clobber (reg:CC FLAGS_REG))])]
11098 "operands[2] = gen_lowpart (QImode, operands[2]);"
11099 [(set_attr "isa" "*,bmi2")])
11101 (define_insn_and_split "*<shift_insn><mode>3_mask_1"
11102 [(set (match_operand:SWI48 0 "nonimmediate_operand")
11104 (match_operand:SWI48 1 "nonimmediate_operand")
11106 (match_operand:QI 2 "register_operand" "c,r")
11107 (match_operand:QI 3 "const_int_operand"))))
11108 (clobber (reg:CC FLAGS_REG))]
11109 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
11110 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
11111 == GET_MODE_BITSIZE (<MODE>mode)-1
11112 && can_create_pseudo_p ()"
11116 [(set (match_dup 0)
11117 (any_shiftrt:SWI48 (match_dup 1)
11119 (clobber (reg:CC FLAGS_REG))])]
11121 [(set_attr "isa" "*,bmi2")])
11123 (define_insn_and_split "*<shift_insn><dwi>3_doubleword_mask"
11124 [(set (match_operand:<DWI> 0 "register_operand")
11126 (match_operand:<DWI> 1 "register_operand")
11129 (match_operand:SI 2 "register_operand" "c")
11130 (match_operand:SI 3 "const_int_operand")) 0)))
11131 (clobber (reg:CC FLAGS_REG))]
11132 "(INTVAL (operands[3]) & (<MODE_SIZE> * BITS_PER_UNIT)) == 0
11133 && can_create_pseudo_p ()"
11137 [(set (match_dup 4)
11138 (ior:DWIH (lshiftrt:DWIH (match_dup 4) (match_dup 2))
11139 (ashift:DWIH (match_dup 7)
11140 (minus:QI (match_dup 8) (match_dup 2)))))
11141 (clobber (reg:CC FLAGS_REG))])
11143 [(set (match_dup 6)
11144 (any_shiftrt:DWIH (match_dup 7) (match_dup 2)))
11145 (clobber (reg:CC FLAGS_REG))])]
11147 split_double_mode (<DWI>mode, &operands[0], 2, &operands[4], &operands[6]);
11149 operands[8] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT);
11151 if ((INTVAL (operands[3]) & ((<MODE_SIZE> * BITS_PER_UNIT) - 1))
11152 != ((<MODE_SIZE> * BITS_PER_UNIT) - 1))
11154 rtx tem = gen_reg_rtx (SImode);
11155 emit_insn (gen_andsi3 (tem, operands[2], operands[3]));
11159 operands[2] = gen_lowpart (QImode, operands[2]);
11161 if (!rtx_equal_p (operands[4], operands[5]))
11162 emit_move_insn (operands[4], operands[5]);
11165 (define_insn_and_split "*<shift_insn><dwi>3_doubleword_mask_1"
11166 [(set (match_operand:<DWI> 0 "register_operand")
11168 (match_operand:<DWI> 1 "register_operand")
11170 (match_operand:QI 2 "register_operand" "c")
11171 (match_operand:QI 3 "const_int_operand"))))
11172 (clobber (reg:CC FLAGS_REG))]
11173 "(INTVAL (operands[3]) & (<MODE_SIZE> * BITS_PER_UNIT)) == 0
11174 && can_create_pseudo_p ()"
11178 [(set (match_dup 4)
11179 (ior:DWIH (lshiftrt:DWIH (match_dup 4) (match_dup 2))
11180 (ashift:DWIH (match_dup 7)
11181 (minus:QI (match_dup 8) (match_dup 2)))))
11182 (clobber (reg:CC FLAGS_REG))])
11184 [(set (match_dup 6)
11185 (any_shiftrt:DWIH (match_dup 7) (match_dup 2)))
11186 (clobber (reg:CC FLAGS_REG))])]
11188 split_double_mode (<DWI>mode, &operands[0], 2, &operands[4], &operands[6]);
11190 operands[8] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT);
11192 if ((INTVAL (operands[3]) & ((<MODE_SIZE> * BITS_PER_UNIT) - 1))
11193 != ((<MODE_SIZE> * BITS_PER_UNIT) - 1))
11195 rtx tem = gen_reg_rtx (QImode);
11196 emit_insn (gen_andqi3 (tem, operands[2], operands[3]));
11200 if (!rtx_equal_p (operands[4], operands[5]))
11201 emit_move_insn (operands[4], operands[5]);
11204 (define_insn_and_split "*<shift_insn><mode>3_doubleword"
11205 [(set (match_operand:DWI 0 "register_operand" "=&r")
11206 (any_shiftrt:DWI (match_operand:DWI 1 "register_operand" "0")
11207 (match_operand:QI 2 "nonmemory_operand" "<S>c")))
11208 (clobber (reg:CC FLAGS_REG))]
11211 "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
11213 "ix86_split_<shift_insn> (operands, NULL_RTX, <MODE>mode); DONE;"
11214 [(set_attr "type" "multi")])
11216 ;; By default we don't ask for a scratch register, because when DWImode
11217 ;; values are manipulated, registers are already at a premium. But if
11218 ;; we have one handy, we won't turn it away.
11221 [(match_scratch:DWIH 3 "r")
11222 (parallel [(set (match_operand:<DWI> 0 "register_operand")
11224 (match_operand:<DWI> 1 "register_operand")
11225 (match_operand:QI 2 "nonmemory_operand")))
11226 (clobber (reg:CC FLAGS_REG))])
11230 "ix86_split_<shift_insn> (operands, operands[3], <DWI>mode); DONE;")
11232 (define_insn "x86_64_shrd"
11233 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
11234 (ior:DI (lshiftrt:DI (match_dup 0)
11235 (match_operand:QI 2 "nonmemory_operand" "Jc"))
11236 (ashift:DI (match_operand:DI 1 "register_operand" "r")
11237 (minus:QI (const_int 64) (match_dup 2)))))
11238 (clobber (reg:CC FLAGS_REG))]
11240 "shrd{q}\t{%s2%1, %0|%0, %1, %2}"
11241 [(set_attr "type" "ishift")
11242 (set_attr "prefix_0f" "1")
11243 (set_attr "mode" "DI")
11244 (set_attr "athlon_decode" "vector")
11245 (set_attr "amdfam10_decode" "vector")
11246 (set_attr "bdver1_decode" "vector")])
11248 (define_insn "x86_shrd"
11249 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
11250 (ior:SI (lshiftrt:SI (match_dup 0)
11251 (match_operand:QI 2 "nonmemory_operand" "Ic"))
11252 (ashift:SI (match_operand:SI 1 "register_operand" "r")
11253 (minus:QI (const_int 32) (match_dup 2)))))
11254 (clobber (reg:CC FLAGS_REG))]
11256 "shrd{l}\t{%s2%1, %0|%0, %1, %2}"
11257 [(set_attr "type" "ishift")
11258 (set_attr "prefix_0f" "1")
11259 (set_attr "mode" "SI")
11260 (set_attr "pent_pair" "np")
11261 (set_attr "athlon_decode" "vector")
11262 (set_attr "amdfam10_decode" "vector")
11263 (set_attr "bdver1_decode" "vector")])
11265 (define_insn "ashrdi3_cvt"
11266 [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
11267 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
11268 (match_operand:QI 2 "const_int_operand")))
11269 (clobber (reg:CC FLAGS_REG))]
11270 "TARGET_64BIT && INTVAL (operands[2]) == 63
11271 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
11272 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11275 sar{q}\t{%2, %0|%0, %2}"
11276 [(set_attr "type" "imovx,ishift")
11277 (set_attr "prefix_0f" "0,*")
11278 (set_attr "length_immediate" "0,*")
11279 (set_attr "modrm" "0,1")
11280 (set_attr "mode" "DI")])
11282 (define_insn "*ashrsi3_cvt_zext"
11283 [(set (match_operand:DI 0 "register_operand" "=*d,r")
11285 (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
11286 (match_operand:QI 2 "const_int_operand"))))
11287 (clobber (reg:CC FLAGS_REG))]
11288 "TARGET_64BIT && INTVAL (operands[2]) == 31
11289 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
11290 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11293 sar{l}\t{%2, %k0|%k0, %2}"
11294 [(set_attr "type" "imovx,ishift")
11295 (set_attr "prefix_0f" "0,*")
11296 (set_attr "length_immediate" "0,*")
11297 (set_attr "modrm" "0,1")
11298 (set_attr "mode" "SI")])
11300 (define_insn "ashrsi3_cvt"
11301 [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
11302 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
11303 (match_operand:QI 2 "const_int_operand")))
11304 (clobber (reg:CC FLAGS_REG))]
11305 "INTVAL (operands[2]) == 31
11306 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
11307 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11310 sar{l}\t{%2, %0|%0, %2}"
11311 [(set_attr "type" "imovx,ishift")
11312 (set_attr "prefix_0f" "0,*")
11313 (set_attr "length_immediate" "0,*")
11314 (set_attr "modrm" "0,1")
11315 (set_attr "mode" "SI")])
11317 (define_expand "x86_shift<mode>_adj_3"
11318 [(use (match_operand:SWI48 0 "register_operand"))
11319 (use (match_operand:SWI48 1 "register_operand"))
11320 (use (match_operand:QI 2 "register_operand"))]
11323 rtx_code_label *label = gen_label_rtx ();
11326 emit_insn (gen_testqi_ccz_1 (operands[2],
11327 GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
11329 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
11330 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
11331 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
11332 gen_rtx_LABEL_REF (VOIDmode, label),
11334 tmp = emit_jump_insn (gen_rtx_SET (pc_rtx, tmp));
11335 JUMP_LABEL (tmp) = label;
11337 emit_move_insn (operands[0], operands[1]);
11338 emit_insn (gen_ashr<mode>3_cvt (operands[1], operands[1],
11339 GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1)));
11340 emit_label (label);
11341 LABEL_NUSES (label) = 1;
11346 (define_insn "*bmi2_<shift_insn><mode>3_1"
11347 [(set (match_operand:SWI48 0 "register_operand" "=r")
11348 (any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11349 (match_operand:SWI48 2 "register_operand" "r")))]
11351 "<shift>x\t{%2, %1, %0|%0, %1, %2}"
11352 [(set_attr "type" "ishiftx")
11353 (set_attr "mode" "<MODE>")])
11355 (define_insn "*<shift_insn><mode>3_1"
11356 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
11358 (match_operand:SWI48 1 "nonimmediate_operand" "0,rm")
11359 (match_operand:QI 2 "nonmemory_operand" "c<S>,r")))
11360 (clobber (reg:CC FLAGS_REG))]
11361 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
11363 switch (get_attr_type (insn))
11369 if (operands[2] == const1_rtx
11370 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11371 return "<shift>{<imodesuffix>}\t%0";
11373 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
11376 [(set_attr "isa" "*,bmi2")
11377 (set_attr "type" "ishift,ishiftx")
11378 (set (attr "length_immediate")
11380 (and (match_operand 2 "const1_operand")
11381 (ior (match_test "TARGET_SHIFT1")
11382 (match_test "optimize_function_for_size_p (cfun)")))
11384 (const_string "*")))
11385 (set_attr "mode" "<MODE>")])
11387 ;; Convert shift to the shiftx pattern to avoid flags dependency.
11389 [(set (match_operand:SWI48 0 "register_operand")
11390 (any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
11391 (match_operand:QI 2 "register_operand")))
11392 (clobber (reg:CC FLAGS_REG))]
11393 "TARGET_BMI2 && reload_completed"
11394 [(set (match_dup 0)
11395 (any_shiftrt:SWI48 (match_dup 1) (match_dup 2)))]
11396 "operands[2] = gen_lowpart (<MODE>mode, operands[2]);")
11398 (define_insn "*bmi2_<shift_insn>si3_1_zext"
11399 [(set (match_operand:DI 0 "register_operand" "=r")
11401 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
11402 (match_operand:SI 2 "register_operand" "r"))))]
11403 "TARGET_64BIT && TARGET_BMI2"
11404 "<shift>x\t{%2, %1, %k0|%k0, %1, %2}"
11405 [(set_attr "type" "ishiftx")
11406 (set_attr "mode" "SI")])
11408 (define_insn "*<shift_insn>si3_1_zext"
11409 [(set (match_operand:DI 0 "register_operand" "=r,r")
11411 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm")
11412 (match_operand:QI 2 "nonmemory_operand" "cI,r"))))
11413 (clobber (reg:CC FLAGS_REG))]
11414 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
11416 switch (get_attr_type (insn))
11422 if (operands[2] == const1_rtx
11423 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11424 return "<shift>{l}\t%k0";
11426 return "<shift>{l}\t{%2, %k0|%k0, %2}";
11429 [(set_attr "isa" "*,bmi2")
11430 (set_attr "type" "ishift,ishiftx")
11431 (set (attr "length_immediate")
11433 (and (match_operand 2 "const1_operand")
11434 (ior (match_test "TARGET_SHIFT1")
11435 (match_test "optimize_function_for_size_p (cfun)")))
11437 (const_string "*")))
11438 (set_attr "mode" "SI")])
11440 ;; Convert shift to the shiftx pattern to avoid flags dependency.
11442 [(set (match_operand:DI 0 "register_operand")
11444 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand")
11445 (match_operand:QI 2 "register_operand"))))
11446 (clobber (reg:CC FLAGS_REG))]
11447 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
11448 [(set (match_dup 0)
11449 (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
11450 "operands[2] = gen_lowpart (SImode, operands[2]);")
11452 (define_insn "*<shift_insn><mode>3_1"
11453 [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m")
11455 (match_operand:SWI12 1 "nonimmediate_operand" "0")
11456 (match_operand:QI 2 "nonmemory_operand" "c<S>")))
11457 (clobber (reg:CC FLAGS_REG))]
11458 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
11460 if (operands[2] == const1_rtx
11461 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11462 return "<shift>{<imodesuffix>}\t%0";
11464 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
11466 [(set_attr "type" "ishift")
11467 (set (attr "length_immediate")
11469 (and (match_operand 2 "const1_operand")
11470 (ior (match_test "TARGET_SHIFT1")
11471 (match_test "optimize_function_for_size_p (cfun)")))
11473 (const_string "*")))
11474 (set_attr "mode" "<MODE>")])
11476 (define_insn "*<shift_insn>qi3_1_slp"
11477 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
11478 (any_shiftrt:QI (match_dup 0)
11479 (match_operand:QI 1 "nonmemory_operand" "cI")))
11480 (clobber (reg:CC FLAGS_REG))]
11481 "(optimize_function_for_size_p (cfun)
11482 || !TARGET_PARTIAL_REG_STALL
11483 || (operands[1] == const1_rtx
11484 && TARGET_SHIFT1))"
11486 if (operands[1] == const1_rtx
11487 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11488 return "<shift>{b}\t%0";
11490 return "<shift>{b}\t{%1, %0|%0, %1}";
11492 [(set_attr "type" "ishift1")
11493 (set (attr "length_immediate")
11495 (and (match_operand 1 "const1_operand")
11496 (ior (match_test "TARGET_SHIFT1")
11497 (match_test "optimize_function_for_size_p (cfun)")))
11499 (const_string "*")))
11500 (set_attr "mode" "QI")])
11502 ;; This pattern can't accept a variable shift count, since shifts by
11503 ;; zero don't affect the flags. We assume that shifts by constant
11504 ;; zero are optimized away.
11505 (define_insn "*<shift_insn><mode>3_cmp"
11506 [(set (reg FLAGS_REG)
11509 (match_operand:SWI 1 "nonimmediate_operand" "0")
11510 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
11512 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
11513 (any_shiftrt:SWI (match_dup 1) (match_dup 2)))]
11514 "(optimize_function_for_size_p (cfun)
11515 || !TARGET_PARTIAL_FLAG_REG_STALL
11516 || (operands[2] == const1_rtx
11518 && ix86_match_ccmode (insn, CCGOCmode)
11519 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
11521 if (operands[2] == const1_rtx
11522 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11523 return "<shift>{<imodesuffix>}\t%0";
11525 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
11527 [(set_attr "type" "ishift")
11528 (set (attr "length_immediate")
11530 (and (match_operand 2 "const1_operand")
11531 (ior (match_test "TARGET_SHIFT1")
11532 (match_test "optimize_function_for_size_p (cfun)")))
11534 (const_string "*")))
11535 (set_attr "mode" "<MODE>")])
11537 (define_insn "*<shift_insn>si3_cmp_zext"
11538 [(set (reg FLAGS_REG)
11540 (any_shiftrt:SI (match_operand:SI 1 "register_operand" "0")
11541 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11543 (set (match_operand:DI 0 "register_operand" "=r")
11544 (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
11546 && (optimize_function_for_size_p (cfun)
11547 || !TARGET_PARTIAL_FLAG_REG_STALL
11548 || (operands[2] == const1_rtx
11550 && ix86_match_ccmode (insn, CCGOCmode)
11551 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
11553 if (operands[2] == const1_rtx
11554 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11555 return "<shift>{l}\t%k0";
11557 return "<shift>{l}\t{%2, %k0|%k0, %2}";
11559 [(set_attr "type" "ishift")
11560 (set (attr "length_immediate")
11562 (and (match_operand 2 "const1_operand")
11563 (ior (match_test "TARGET_SHIFT1")
11564 (match_test "optimize_function_for_size_p (cfun)")))
11566 (const_string "*")))
11567 (set_attr "mode" "SI")])
11569 (define_insn "*<shift_insn><mode>3_cconly"
11570 [(set (reg FLAGS_REG)
11573 (match_operand:SWI 1 "register_operand" "0")
11574 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
11576 (clobber (match_scratch:SWI 0 "=<r>"))]
11577 "(optimize_function_for_size_p (cfun)
11578 || !TARGET_PARTIAL_FLAG_REG_STALL
11579 || (operands[2] == const1_rtx
11581 && ix86_match_ccmode (insn, CCGOCmode)"
11583 if (operands[2] == const1_rtx
11584 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11585 return "<shift>{<imodesuffix>}\t%0";
11587 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
11589 [(set_attr "type" "ishift")
11590 (set (attr "length_immediate")
11592 (and (match_operand 2 "const1_operand")
11593 (ior (match_test "TARGET_SHIFT1")
11594 (match_test "optimize_function_for_size_p (cfun)")))
11596 (const_string "*")))
11597 (set_attr "mode" "<MODE>")])
11599 ;; Rotate instructions
11601 (define_expand "<rotate_insn>ti3"
11602 [(set (match_operand:TI 0 "register_operand")
11603 (any_rotate:TI (match_operand:TI 1 "register_operand")
11604 (match_operand:QI 2 "nonmemory_operand")))]
11607 if (const_1_to_63_operand (operands[2], VOIDmode))
11608 emit_insn (gen_ix86_<rotate_insn>ti3_doubleword
11609 (operands[0], operands[1], operands[2]));
11616 (define_expand "<rotate_insn>di3"
11617 [(set (match_operand:DI 0 "shiftdi_operand")
11618 (any_rotate:DI (match_operand:DI 1 "shiftdi_operand")
11619 (match_operand:QI 2 "nonmemory_operand")))]
11623 ix86_expand_binary_operator (<CODE>, DImode, operands);
11624 else if (const_1_to_31_operand (operands[2], VOIDmode))
11625 emit_insn (gen_ix86_<rotate_insn>di3_doubleword
11626 (operands[0], operands[1], operands[2]));
11633 (define_expand "<rotate_insn><mode>3"
11634 [(set (match_operand:SWIM124 0 "nonimmediate_operand")
11635 (any_rotate:SWIM124 (match_operand:SWIM124 1 "nonimmediate_operand")
11636 (match_operand:QI 2 "nonmemory_operand")))]
11638 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
11640 ;; Avoid useless masking of count operand.
11641 (define_insn_and_split "*<rotate_insn><mode>3_mask"
11642 [(set (match_operand:SWI48 0 "nonimmediate_operand")
11644 (match_operand:SWI48 1 "nonimmediate_operand")
11647 (match_operand:SI 2 "register_operand" "c")
11648 (match_operand:SI 3 "const_int_operand")) 0)))
11649 (clobber (reg:CC FLAGS_REG))]
11650 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
11651 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
11652 == GET_MODE_BITSIZE (<MODE>mode)-1
11653 && can_create_pseudo_p ()"
11657 [(set (match_dup 0)
11658 (any_rotate:SWI48 (match_dup 1)
11660 (clobber (reg:CC FLAGS_REG))])]
11661 "operands[2] = gen_lowpart (QImode, operands[2]);")
11663 (define_insn_and_split "*<rotate_insn><mode>3_mask_1"
11664 [(set (match_operand:SWI48 0 "nonimmediate_operand")
11666 (match_operand:SWI48 1 "nonimmediate_operand")
11668 (match_operand:QI 2 "register_operand" "c")
11669 (match_operand:QI 3 "const_int_operand"))))
11670 (clobber (reg:CC FLAGS_REG))]
11671 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
11672 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
11673 == GET_MODE_BITSIZE (<MODE>mode)-1
11674 && can_create_pseudo_p ()"
11678 [(set (match_dup 0)
11679 (any_rotate:SWI48 (match_dup 1)
11681 (clobber (reg:CC FLAGS_REG))])])
11683 ;; Implement rotation using two double-precision
11684 ;; shift instructions and a scratch register.
11686 (define_insn_and_split "ix86_rotl<dwi>3_doubleword"
11687 [(set (match_operand:<DWI> 0 "register_operand" "=r")
11688 (rotate:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
11689 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
11690 (clobber (reg:CC FLAGS_REG))
11691 (clobber (match_scratch:DWIH 3 "=&r"))]
11695 [(set (match_dup 3) (match_dup 4))
11697 [(set (match_dup 4)
11698 (ior:DWIH (ashift:DWIH (match_dup 4) (match_dup 2))
11699 (lshiftrt:DWIH (match_dup 5)
11700 (minus:QI (match_dup 6) (match_dup 2)))))
11701 (clobber (reg:CC FLAGS_REG))])
11703 [(set (match_dup 5)
11704 (ior:DWIH (ashift:DWIH (match_dup 5) (match_dup 2))
11705 (lshiftrt:DWIH (match_dup 3)
11706 (minus:QI (match_dup 6) (match_dup 2)))))
11707 (clobber (reg:CC FLAGS_REG))])]
11709 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
11711 split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
11714 (define_insn_and_split "ix86_rotr<dwi>3_doubleword"
11715 [(set (match_operand:<DWI> 0 "register_operand" "=r")
11716 (rotatert:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
11717 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
11718 (clobber (reg:CC FLAGS_REG))
11719 (clobber (match_scratch:DWIH 3 "=&r"))]
11723 [(set (match_dup 3) (match_dup 4))
11725 [(set (match_dup 4)
11726 (ior:DWIH (lshiftrt:DWIH (match_dup 4) (match_dup 2))
11727 (ashift:DWIH (match_dup 5)
11728 (minus:QI (match_dup 6) (match_dup 2)))))
11729 (clobber (reg:CC FLAGS_REG))])
11731 [(set (match_dup 5)
11732 (ior:DWIH (lshiftrt:DWIH (match_dup 5) (match_dup 2))
11733 (ashift:DWIH (match_dup 3)
11734 (minus:QI (match_dup 6) (match_dup 2)))))
11735 (clobber (reg:CC FLAGS_REG))])]
11737 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
11739 split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
11742 (define_mode_attr rorx_immediate_operand
11743 [(SI "const_0_to_31_operand")
11744 (DI "const_0_to_63_operand")])
11746 (define_insn "*bmi2_rorx<mode>3_1"
11747 [(set (match_operand:SWI48 0 "register_operand" "=r")
11749 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11750 (match_operand:QI 2 "<rorx_immediate_operand>" "<S>")))]
11752 "rorx\t{%2, %1, %0|%0, %1, %2}"
11753 [(set_attr "type" "rotatex")
11754 (set_attr "mode" "<MODE>")])
11756 (define_insn "*<rotate_insn><mode>3_1"
11757 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
11759 (match_operand:SWI48 1 "nonimmediate_operand" "0,rm")
11760 (match_operand:QI 2 "nonmemory_operand" "c<S>,<S>")))
11761 (clobber (reg:CC FLAGS_REG))]
11762 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
11764 switch (get_attr_type (insn))
11770 if (operands[2] == const1_rtx
11771 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11772 return "<rotate>{<imodesuffix>}\t%0";
11774 return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
11777 [(set_attr "isa" "*,bmi2")
11778 (set_attr "type" "rotate,rotatex")
11779 (set (attr "length_immediate")
11781 (and (eq_attr "type" "rotate")
11782 (and (match_operand 2 "const1_operand")
11783 (ior (match_test "TARGET_SHIFT1")
11784 (match_test "optimize_function_for_size_p (cfun)"))))
11786 (const_string "*")))
11787 (set_attr "mode" "<MODE>")])
11789 ;; Convert rotate to the rotatex pattern to avoid flags dependency.
11791 [(set (match_operand:SWI48 0 "register_operand")
11792 (rotate:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
11793 (match_operand:QI 2 "const_int_operand")))
11794 (clobber (reg:CC FLAGS_REG))]
11795 "TARGET_BMI2 && reload_completed"
11796 [(set (match_dup 0)
11797 (rotatert:SWI48 (match_dup 1) (match_dup 2)))]
11799 int bitsize = GET_MODE_BITSIZE (<MODE>mode);
11801 operands[2] = GEN_INT ((bitsize - INTVAL (operands[2])) % bitsize);
11805 [(set (match_operand:SWI48 0 "register_operand")
11806 (rotatert:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
11807 (match_operand:QI 2 "const_int_operand")))
11808 (clobber (reg:CC FLAGS_REG))]
11809 "TARGET_BMI2 && reload_completed"
11810 [(set (match_dup 0)
11811 (rotatert:SWI48 (match_dup 1) (match_dup 2)))])
11813 (define_insn "*bmi2_rorxsi3_1_zext"
11814 [(set (match_operand:DI 0 "register_operand" "=r")
11816 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
11817 (match_operand:QI 2 "const_0_to_31_operand" "I"))))]
11818 "TARGET_64BIT && TARGET_BMI2"
11819 "rorx\t{%2, %1, %k0|%k0, %1, %2}"
11820 [(set_attr "type" "rotatex")
11821 (set_attr "mode" "SI")])
11823 (define_insn "*<rotate_insn>si3_1_zext"
11824 [(set (match_operand:DI 0 "register_operand" "=r,r")
11826 (any_rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm")
11827 (match_operand:QI 2 "nonmemory_operand" "cI,I"))))
11828 (clobber (reg:CC FLAGS_REG))]
11829 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
11831 switch (get_attr_type (insn))
11837 if (operands[2] == const1_rtx
11838 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11839 return "<rotate>{l}\t%k0";
11841 return "<rotate>{l}\t{%2, %k0|%k0, %2}";
11844 [(set_attr "isa" "*,bmi2")
11845 (set_attr "type" "rotate,rotatex")
11846 (set (attr "length_immediate")
11848 (and (eq_attr "type" "rotate")
11849 (and (match_operand 2 "const1_operand")
11850 (ior (match_test "TARGET_SHIFT1")
11851 (match_test "optimize_function_for_size_p (cfun)"))))
11853 (const_string "*")))
11854 (set_attr "mode" "SI")])
11856 ;; Convert rotate to the rotatex pattern to avoid flags dependency.
11858 [(set (match_operand:DI 0 "register_operand")
11860 (rotate:SI (match_operand:SI 1 "nonimmediate_operand")
11861 (match_operand:QI 2 "const_int_operand"))))
11862 (clobber (reg:CC FLAGS_REG))]
11863 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
11864 [(set (match_dup 0)
11865 (zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))]
11867 int bitsize = GET_MODE_BITSIZE (SImode);
11869 operands[2] = GEN_INT ((bitsize - INTVAL (operands[2])) % bitsize);
11873 [(set (match_operand:DI 0 "register_operand")
11875 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand")
11876 (match_operand:QI 2 "const_int_operand"))))
11877 (clobber (reg:CC FLAGS_REG))]
11878 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
11879 [(set (match_dup 0)
11880 (zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))])
11882 (define_insn "*<rotate_insn><mode>3_1"
11883 [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m")
11884 (any_rotate:SWI12 (match_operand:SWI12 1 "nonimmediate_operand" "0")
11885 (match_operand:QI 2 "nonmemory_operand" "c<S>")))
11886 (clobber (reg:CC FLAGS_REG))]
11887 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
11889 if (operands[2] == const1_rtx
11890 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11891 return "<rotate>{<imodesuffix>}\t%0";
11893 return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
11895 [(set_attr "type" "rotate")
11896 (set (attr "length_immediate")
11898 (and (match_operand 2 "const1_operand")
11899 (ior (match_test "TARGET_SHIFT1")
11900 (match_test "optimize_function_for_size_p (cfun)")))
11902 (const_string "*")))
11903 (set_attr "mode" "<MODE>")])
11905 (define_insn "*<rotate_insn>qi3_1_slp"
11906 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
11907 (any_rotate:QI (match_dup 0)
11908 (match_operand:QI 1 "nonmemory_operand" "cI")))
11909 (clobber (reg:CC FLAGS_REG))]
11910 "(optimize_function_for_size_p (cfun)
11911 || !TARGET_PARTIAL_REG_STALL
11912 || (operands[1] == const1_rtx
11913 && TARGET_SHIFT1))"
11915 if (operands[1] == const1_rtx
11916 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11917 return "<rotate>{b}\t%0";
11919 return "<rotate>{b}\t{%1, %0|%0, %1}";
11921 [(set_attr "type" "rotate1")
11922 (set (attr "length_immediate")
11924 (and (match_operand 1 "const1_operand")
11925 (ior (match_test "TARGET_SHIFT1")
11926 (match_test "optimize_function_for_size_p (cfun)")))
11928 (const_string "*")))
11929 (set_attr "mode" "QI")])
11932 [(set (match_operand:HI 0 "QIreg_operand")
11933 (any_rotate:HI (match_dup 0) (const_int 8)))
11934 (clobber (reg:CC FLAGS_REG))]
11936 && (TARGET_USE_XCHGB || optimize_function_for_size_p (cfun))"
11937 [(parallel [(set (strict_low_part (match_dup 0))
11938 (bswap:HI (match_dup 0)))
11939 (clobber (reg:CC FLAGS_REG))])])
11941 ;; Bit set / bit test instructions
11943 ;; %%% bts, btr, btc
11945 ;; These instructions are *slow* when applied to memory.
11947 (define_code_attr btsc [(ior "bts") (xor "btc")])
11949 (define_insn "*<btsc><mode>"
11950 [(set (match_operand:SWI48 0 "register_operand" "=r")
11952 (ashift:SWI48 (const_int 1)
11953 (match_operand:QI 2 "register_operand" "r"))
11954 (match_operand:SWI48 1 "register_operand" "0")))
11955 (clobber (reg:CC FLAGS_REG))]
11957 "<btsc>{<imodesuffix>}\t{%<k>2, %0|%0, %<k>2}"
11958 [(set_attr "type" "alu1")
11959 (set_attr "prefix_0f" "1")
11960 (set_attr "znver1_decode" "double")
11961 (set_attr "mode" "<MODE>")])
11963 ;; Avoid useless masking of count operand.
11964 (define_insn_and_split "*<btsc><mode>_mask"
11965 [(set (match_operand:SWI48 0 "register_operand")
11971 (match_operand:SI 1 "register_operand")
11972 (match_operand:SI 2 "const_int_operand")) 0))
11973 (match_operand:SWI48 3 "register_operand")))
11974 (clobber (reg:CC FLAGS_REG))]
11976 && (INTVAL (operands[2]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
11977 == GET_MODE_BITSIZE (<MODE>mode)-1
11978 && can_create_pseudo_p ()"
11982 [(set (match_dup 0)
11984 (ashift:SWI48 (const_int 1)
11987 (clobber (reg:CC FLAGS_REG))])]
11988 "operands[1] = gen_lowpart (QImode, operands[1]);")
11990 (define_insn_and_split "*<btsc><mode>_mask_1"
11991 [(set (match_operand:SWI48 0 "register_operand")
11996 (match_operand:QI 1 "register_operand")
11997 (match_operand:QI 2 "const_int_operand")))
11998 (match_operand:SWI48 3 "register_operand")))
11999 (clobber (reg:CC FLAGS_REG))]
12001 && (INTVAL (operands[2]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
12002 == GET_MODE_BITSIZE (<MODE>mode)-1
12003 && can_create_pseudo_p ()"
12007 [(set (match_dup 0)
12009 (ashift:SWI48 (const_int 1)
12012 (clobber (reg:CC FLAGS_REG))])])
12014 (define_insn "*btr<mode>"
12015 [(set (match_operand:SWI48 0 "register_operand" "=r")
12017 (rotate:SWI48 (const_int -2)
12018 (match_operand:QI 2 "register_operand" "r"))
12019 (match_operand:SWI48 1 "register_operand" "0")))
12020 (clobber (reg:CC FLAGS_REG))]
12022 "btr{<imodesuffix>}\t{%<k>2, %0|%0, %<k>2}"
12023 [(set_attr "type" "alu1")
12024 (set_attr "prefix_0f" "1")
12025 (set_attr "znver1_decode" "double")
12026 (set_attr "mode" "<MODE>")])
12028 ;; Avoid useless masking of count operand.
12029 (define_insn_and_split "*btr<mode>_mask"
12030 [(set (match_operand:SWI48 0 "register_operand")
12036 (match_operand:SI 1 "register_operand")
12037 (match_operand:SI 2 "const_int_operand")) 0))
12038 (match_operand:SWI48 3 "register_operand")))
12039 (clobber (reg:CC FLAGS_REG))]
12041 && (INTVAL (operands[2]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
12042 == GET_MODE_BITSIZE (<MODE>mode)-1
12043 && can_create_pseudo_p ()"
12047 [(set (match_dup 0)
12049 (rotate:SWI48 (const_int -2)
12052 (clobber (reg:CC FLAGS_REG))])]
12053 "operands[1] = gen_lowpart (QImode, operands[1]);")
12055 (define_insn_and_split "*btr<mode>_mask_1"
12056 [(set (match_operand:SWI48 0 "register_operand")
12061 (match_operand:QI 1 "register_operand")
12062 (match_operand:QI 2 "const_int_operand")))
12063 (match_operand:SWI48 3 "register_operand")))
12064 (clobber (reg:CC FLAGS_REG))]
12066 && (INTVAL (operands[2]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
12067 == GET_MODE_BITSIZE (<MODE>mode)-1
12068 && can_create_pseudo_p ()"
12072 [(set (match_dup 0)
12074 (rotate:SWI48 (const_int -2)
12077 (clobber (reg:CC FLAGS_REG))])])
12079 ;; These instructions are never faster than the corresponding
12080 ;; and/ior/xor operations when using immediate operand, so with
12081 ;; 32-bit there's no point. But in 64-bit, we can't hold the
12082 ;; relevant immediates within the instruction itself, so operating
12083 ;; on bits in the high 32-bits of a register becomes easier.
12085 ;; These are slow on Nocona, but fast on Athlon64. We do require the use
12086 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
12087 ;; negdf respectively, so they can never be disabled entirely.
12089 (define_insn "*btsq_imm"
12090 [(set (zero_extract:DI (match_operand:DI 0 "nonimmediate_operand" "+rm")
12092 (match_operand 1 "const_0_to_63_operand" "J"))
12094 (clobber (reg:CC FLAGS_REG))]
12095 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
12096 "bts{q}\t{%1, %0|%0, %1}"
12097 [(set_attr "type" "alu1")
12098 (set_attr "prefix_0f" "1")
12099 (set_attr "znver1_decode" "double")
12100 (set_attr "mode" "DI")])
12102 (define_insn "*btrq_imm"
12103 [(set (zero_extract:DI (match_operand:DI 0 "nonimmediate_operand" "+rm")
12105 (match_operand 1 "const_0_to_63_operand" "J"))
12107 (clobber (reg:CC FLAGS_REG))]
12108 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
12109 "btr{q}\t{%1, %0|%0, %1}"
12110 [(set_attr "type" "alu1")
12111 (set_attr "prefix_0f" "1")
12112 (set_attr "znver1_decode" "double")
12113 (set_attr "mode" "DI")])
12115 (define_insn "*btcq_imm"
12116 [(set (zero_extract:DI (match_operand:DI 0 "nonimmediate_operand" "+rm")
12118 (match_operand 1 "const_0_to_63_operand" "J"))
12119 (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
12120 (clobber (reg:CC FLAGS_REG))]
12121 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
12122 "btc{q}\t{%1, %0|%0, %1}"
12123 [(set_attr "type" "alu1")
12124 (set_attr "prefix_0f" "1")
12125 (set_attr "znver1_decode" "double")
12126 (set_attr "mode" "DI")])
12128 ;; Allow Nocona to avoid these instructions if a register is available.
12131 [(match_scratch:DI 2 "r")
12132 (parallel [(set (zero_extract:DI
12133 (match_operand:DI 0 "nonimmediate_operand")
12135 (match_operand 1 "const_0_to_63_operand"))
12137 (clobber (reg:CC FLAGS_REG))])]
12138 "TARGET_64BIT && !TARGET_USE_BT"
12139 [(parallel [(set (match_dup 0)
12140 (ior:DI (match_dup 0) (match_dup 3)))
12141 (clobber (reg:CC FLAGS_REG))])]
12143 int i = INTVAL (operands[1]);
12145 operands[3] = gen_int_mode (HOST_WIDE_INT_1U << i, DImode);
12147 if (!x86_64_immediate_operand (operands[3], DImode))
12149 emit_move_insn (operands[2], operands[3]);
12150 operands[3] = operands[2];
12155 [(match_scratch:DI 2 "r")
12156 (parallel [(set (zero_extract:DI
12157 (match_operand:DI 0 "nonimmediate_operand")
12159 (match_operand 1 "const_0_to_63_operand"))
12161 (clobber (reg:CC FLAGS_REG))])]
12162 "TARGET_64BIT && !TARGET_USE_BT"
12163 [(parallel [(set (match_dup 0)
12164 (and:DI (match_dup 0) (match_dup 3)))
12165 (clobber (reg:CC FLAGS_REG))])]
12167 int i = INTVAL (operands[1]);
12169 operands[3] = gen_int_mode (~(HOST_WIDE_INT_1U << i), DImode);
12171 if (!x86_64_immediate_operand (operands[3], DImode))
12173 emit_move_insn (operands[2], operands[3]);
12174 operands[3] = operands[2];
12179 [(match_scratch:DI 2 "r")
12180 (parallel [(set (zero_extract:DI
12181 (match_operand:DI 0 "nonimmediate_operand")
12183 (match_operand 1 "const_0_to_63_operand"))
12184 (not:DI (zero_extract:DI
12185 (match_dup 0) (const_int 1) (match_dup 1))))
12186 (clobber (reg:CC FLAGS_REG))])]
12187 "TARGET_64BIT && !TARGET_USE_BT"
12188 [(parallel [(set (match_dup 0)
12189 (xor:DI (match_dup 0) (match_dup 3)))
12190 (clobber (reg:CC FLAGS_REG))])]
12192 int i = INTVAL (operands[1]);
12194 operands[3] = gen_int_mode (HOST_WIDE_INT_1U << i, DImode);
12196 if (!x86_64_immediate_operand (operands[3], DImode))
12198 emit_move_insn (operands[2], operands[3]);
12199 operands[3] = operands[2];
12205 (define_insn "*bt<mode>"
12206 [(set (reg:CCC FLAGS_REG)
12208 (zero_extract:SWI48
12209 (match_operand:SWI48 0 "nonimmediate_operand" "r,m")
12211 (match_operand:SI 1 "nonmemory_operand" "r<S>,<S>"))
12215 switch (get_attr_mode (insn))
12218 return "bt{l}\t{%1, %k0|%k0, %1}";
12221 return "bt{q}\t{%q1, %0|%0, %q1}";
12224 gcc_unreachable ();
12227 [(set_attr "type" "alu1")
12228 (set_attr "prefix_0f" "1")
12231 (and (match_test "CONST_INT_P (operands[1])")
12232 (match_test "INTVAL (operands[1]) < 32"))
12233 (const_string "SI")
12234 (const_string "<MODE>")))])
12236 (define_insn_and_split "*jcc_bt<mode>"
12238 (if_then_else (match_operator 0 "bt_comparison_operator"
12239 [(zero_extract:SWI48
12240 (match_operand:SWI48 1 "nonimmediate_operand")
12242 (match_operand:SI 2 "nonmemory_operand"))
12244 (label_ref (match_operand 3))
12246 (clobber (reg:CC FLAGS_REG))]
12247 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
12248 && (CONST_INT_P (operands[2])
12249 ? (INTVAL (operands[2]) < GET_MODE_BITSIZE (<MODE>mode)
12250 && INTVAL (operands[2])
12251 >= (optimize_function_for_size_p (cfun) ? 8 : 32))
12252 : !memory_operand (operands[1], <MODE>mode))
12253 && can_create_pseudo_p ()"
12256 [(set (reg:CCC FLAGS_REG)
12258 (zero_extract:SWI48
12264 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
12265 (label_ref (match_dup 3))
12268 operands[0] = shallow_copy_rtx (operands[0]);
12269 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
12272 (define_insn_and_split "*jcc_bt<mode>_1"
12274 (if_then_else (match_operator 0 "bt_comparison_operator"
12275 [(zero_extract:SWI48
12276 (match_operand:SWI48 1 "register_operand")
12279 (match_operand:QI 2 "register_operand")))
12281 (label_ref (match_operand 3))
12283 (clobber (reg:CC FLAGS_REG))]
12284 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
12285 && can_create_pseudo_p ()"
12288 [(set (reg:CCC FLAGS_REG)
12290 (zero_extract:SWI48
12296 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
12297 (label_ref (match_dup 3))
12300 operands[2] = lowpart_subreg (SImode, operands[2], QImode);
12301 operands[0] = shallow_copy_rtx (operands[0]);
12302 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
12305 ;; Avoid useless masking of bit offset operand.
12306 (define_insn_and_split "*jcc_bt<mode>_mask"
12308 (if_then_else (match_operator 0 "bt_comparison_operator"
12309 [(zero_extract:SWI48
12310 (match_operand:SWI48 1 "register_operand")
12313 (match_operand:SI 2 "register_operand")
12314 (match_operand 3 "const_int_operand")))])
12315 (label_ref (match_operand 4))
12317 (clobber (reg:CC FLAGS_REG))]
12318 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
12319 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
12320 == GET_MODE_BITSIZE (<MODE>mode)-1
12321 && can_create_pseudo_p ()"
12324 [(set (reg:CCC FLAGS_REG)
12326 (zero_extract:SWI48
12332 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
12333 (label_ref (match_dup 4))
12336 operands[0] = shallow_copy_rtx (operands[0]);
12337 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
12340 ;; Store-flag instructions.
12342 ;; For all sCOND expanders, also expand the compare or test insn that
12343 ;; generates cc0. Generate an equality comparison if `seq' or `sne'.
12345 (define_insn_and_split "*setcc_di_1"
12346 [(set (match_operand:DI 0 "register_operand" "=q")
12347 (match_operator:DI 1 "ix86_comparison_operator"
12348 [(reg FLAGS_REG) (const_int 0)]))]
12349 "TARGET_64BIT && !TARGET_PARTIAL_REG_STALL"
12351 "&& reload_completed"
12352 [(set (match_dup 2) (match_dup 1))
12353 (set (match_dup 0) (zero_extend:DI (match_dup 2)))]
12355 operands[1] = shallow_copy_rtx (operands[1]);
12356 PUT_MODE (operands[1], QImode);
12357 operands[2] = gen_lowpart (QImode, operands[0]);
12360 (define_insn_and_split "*setcc_si_1_and"
12361 [(set (match_operand:SI 0 "register_operand" "=q")
12362 (match_operator:SI 1 "ix86_comparison_operator"
12363 [(reg FLAGS_REG) (const_int 0)]))
12364 (clobber (reg:CC FLAGS_REG))]
12365 "!TARGET_PARTIAL_REG_STALL
12366 && TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
12368 "&& reload_completed"
12369 [(set (match_dup 2) (match_dup 1))
12370 (parallel [(set (match_dup 0) (zero_extend:SI (match_dup 2)))
12371 (clobber (reg:CC FLAGS_REG))])]
12373 operands[1] = shallow_copy_rtx (operands[1]);
12374 PUT_MODE (operands[1], QImode);
12375 operands[2] = gen_lowpart (QImode, operands[0]);
12378 (define_insn_and_split "*setcc_si_1_movzbl"
12379 [(set (match_operand:SI 0 "register_operand" "=q")
12380 (match_operator:SI 1 "ix86_comparison_operator"
12381 [(reg FLAGS_REG) (const_int 0)]))]
12382 "!TARGET_PARTIAL_REG_STALL
12383 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
12385 "&& reload_completed"
12386 [(set (match_dup 2) (match_dup 1))
12387 (set (match_dup 0) (zero_extend:SI (match_dup 2)))]
12389 operands[1] = shallow_copy_rtx (operands[1]);
12390 PUT_MODE (operands[1], QImode);
12391 operands[2] = gen_lowpart (QImode, operands[0]);
12394 (define_insn "*setcc_qi"
12395 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12396 (match_operator:QI 1 "ix86_comparison_operator"
12397 [(reg FLAGS_REG) (const_int 0)]))]
12400 [(set_attr "type" "setcc")
12401 (set_attr "mode" "QI")])
12403 (define_insn "*setcc_qi_slp"
12404 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12405 (match_operator:QI 1 "ix86_comparison_operator"
12406 [(reg FLAGS_REG) (const_int 0)]))]
12409 [(set_attr "type" "setcc")
12410 (set_attr "mode" "QI")])
12412 ;; In general it is not safe to assume too much about CCmode registers,
12413 ;; so simplify-rtx stops when it sees a second one. Under certain
12414 ;; conditions this is safe on x86, so help combine not create
12421 [(set (match_operand:QI 0 "nonimmediate_operand")
12422 (ne:QI (match_operator 1 "ix86_comparison_operator"
12423 [(reg FLAGS_REG) (const_int 0)])
12426 [(set (match_dup 0) (match_dup 1))]
12428 operands[1] = shallow_copy_rtx (operands[1]);
12429 PUT_MODE (operands[1], QImode);
12433 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand"))
12434 (ne:QI (match_operator 1 "ix86_comparison_operator"
12435 [(reg FLAGS_REG) (const_int 0)])
12438 [(set (match_dup 0) (match_dup 1))]
12440 operands[1] = shallow_copy_rtx (operands[1]);
12441 PUT_MODE (operands[1], QImode);
12445 [(set (match_operand:QI 0 "nonimmediate_operand")
12446 (eq:QI (match_operator 1 "ix86_comparison_operator"
12447 [(reg FLAGS_REG) (const_int 0)])
12450 [(set (match_dup 0) (match_dup 1))]
12452 operands[1] = shallow_copy_rtx (operands[1]);
12453 PUT_MODE (operands[1], QImode);
12454 PUT_CODE (operands[1],
12455 ix86_reverse_condition (GET_CODE (operands[1]),
12456 GET_MODE (XEXP (operands[1], 0))));
12458 /* Make sure that (a) the CCmode we have for the flags is strong
12459 enough for the reversed compare or (b) we have a valid FP compare. */
12460 if (! ix86_comparison_operator (operands[1], VOIDmode))
12465 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand"))
12466 (eq:QI (match_operator 1 "ix86_comparison_operator"
12467 [(reg FLAGS_REG) (const_int 0)])
12470 [(set (match_dup 0) (match_dup 1))]
12472 operands[1] = shallow_copy_rtx (operands[1]);
12473 PUT_MODE (operands[1], QImode);
12474 PUT_CODE (operands[1],
12475 ix86_reverse_condition (GET_CODE (operands[1]),
12476 GET_MODE (XEXP (operands[1], 0))));
12478 /* Make sure that (a) the CCmode we have for the flags is strong
12479 enough for the reversed compare or (b) we have a valid FP compare. */
12480 if (! ix86_comparison_operator (operands[1], VOIDmode))
12484 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
12485 ;; subsequent logical operations are used to imitate conditional moves.
12486 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
12489 (define_insn "setcc_<mode>_sse"
12490 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
12491 (match_operator:MODEF 3 "sse_comparison_operator"
12492 [(match_operand:MODEF 1 "register_operand" "0,x")
12493 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
12494 "SSE_FLOAT_MODE_P (<MODE>mode)"
12496 cmp%D3<ssemodesuffix>\t{%2, %0|%0, %2}
12497 vcmp%D3<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
12498 [(set_attr "isa" "noavx,avx")
12499 (set_attr "type" "ssecmp")
12500 (set_attr "length_immediate" "1")
12501 (set_attr "prefix" "orig,vex")
12502 (set_attr "mode" "<MODE>")])
12504 ;; Basic conditional jump instructions.
12505 ;; We ignore the overflow flag for signed branch instructions.
12507 (define_insn "*jcc"
12509 (if_then_else (match_operator 1 "ix86_comparison_operator"
12510 [(reg FLAGS_REG) (const_int 0)])
12511 (label_ref (match_operand 0))
12515 [(set_attr "type" "ibr")
12516 (set_attr "modrm" "0")
12517 (set (attr "length")
12519 (and (ge (minus (match_dup 0) (pc))
12521 (lt (minus (match_dup 0) (pc))
12525 (set_attr "maybe_prefix_bnd" "1")])
12527 ;; In general it is not safe to assume too much about CCmode registers,
12528 ;; so simplify-rtx stops when it sees a second one. Under certain
12529 ;; conditions this is safe on x86, so help combine not create
12537 (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
12538 [(reg FLAGS_REG) (const_int 0)])
12540 (label_ref (match_operand 1))
12544 (if_then_else (match_dup 0)
12545 (label_ref (match_dup 1))
12548 operands[0] = shallow_copy_rtx (operands[0]);
12549 PUT_MODE (operands[0], VOIDmode);
12554 (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
12555 [(reg FLAGS_REG) (const_int 0)])
12557 (label_ref (match_operand 1))
12561 (if_then_else (match_dup 0)
12562 (label_ref (match_dup 1))
12565 operands[0] = shallow_copy_rtx (operands[0]);
12566 PUT_MODE (operands[0], VOIDmode);
12567 PUT_CODE (operands[0],
12568 ix86_reverse_condition (GET_CODE (operands[0]),
12569 GET_MODE (XEXP (operands[0], 0))));
12571 /* Make sure that (a) the CCmode we have for the flags is strong
12572 enough for the reversed compare or (b) we have a valid FP compare. */
12573 if (! ix86_comparison_operator (operands[0], VOIDmode))
12577 ;; Unconditional and other jump instructions
12579 (define_insn "jump"
12581 (label_ref (match_operand 0)))]
12584 [(set_attr "type" "ibr")
12585 (set_attr "modrm" "0")
12586 (set (attr "length")
12588 (and (ge (minus (match_dup 0) (pc))
12590 (lt (minus (match_dup 0) (pc))
12594 (set_attr "maybe_prefix_bnd" "1")])
12596 (define_expand "indirect_jump"
12597 [(set (pc) (match_operand 0 "indirect_branch_operand"))]
12600 if (TARGET_X32 || TARGET_INDIRECT_BRANCH_REGISTER)
12601 operands[0] = convert_memory_address (word_mode, operands[0]);
12602 cfun->machine->has_local_indirect_jump = true;
12605 (define_insn "*indirect_jump"
12606 [(set (pc) (match_operand:W 0 "indirect_branch_operand" "rBw"))]
12608 "* return ix86_output_indirect_jmp (operands[0]);"
12609 [(set (attr "type")
12610 (if_then_else (match_test "(cfun->machine->indirect_branch_type
12611 != indirect_branch_keep)")
12612 (const_string "multi")
12613 (const_string "ibr")))
12614 (set_attr "length_immediate" "0")
12615 (set_attr "maybe_prefix_bnd" "1")])
12617 (define_expand "tablejump"
12618 [(parallel [(set (pc) (match_operand 0 "indirect_branch_operand"))
12619 (use (label_ref (match_operand 1)))])]
12622 /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
12623 relative. Convert the relative address to an absolute address. */
12627 enum rtx_code code;
12629 /* We can't use @GOTOFF for text labels on VxWorks;
12630 see gotoff_operand. */
12631 if (TARGET_64BIT || TARGET_VXWORKS_RTP)
12635 op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
12637 else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
12641 op1 = pic_offset_table_rtx;
12646 op0 = pic_offset_table_rtx;
12650 operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
12654 if (TARGET_X32 || TARGET_INDIRECT_BRANCH_REGISTER)
12655 operands[0] = convert_memory_address (word_mode, operands[0]);
12656 cfun->machine->has_local_indirect_jump = true;
12659 (define_insn "*tablejump_1"
12660 [(set (pc) (match_operand:W 0 "indirect_branch_operand" "rBw"))
12661 (use (label_ref (match_operand 1)))]
12663 "* return ix86_output_indirect_jmp (operands[0]);"
12664 [(set (attr "type")
12665 (if_then_else (match_test "(cfun->machine->indirect_branch_type
12666 != indirect_branch_keep)")
12667 (const_string "multi")
12668 (const_string "ibr")))
12669 (set_attr "length_immediate" "0")
12670 (set_attr "maybe_prefix_bnd" "1")])
12672 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
12675 [(set (reg FLAGS_REG) (match_operand 0))
12676 (set (match_operand:QI 1 "register_operand")
12677 (match_operator:QI 2 "ix86_comparison_operator"
12678 [(reg FLAGS_REG) (const_int 0)]))
12679 (set (match_operand 3 "any_QIreg_operand")
12680 (zero_extend (match_dup 1)))]
12681 "(peep2_reg_dead_p (3, operands[1])
12682 || operands_match_p (operands[1], operands[3]))
12683 && ! reg_overlap_mentioned_p (operands[3], operands[0])
12684 && peep2_regno_dead_p (0, FLAGS_REG)"
12685 [(set (match_dup 4) (match_dup 0))
12686 (set (strict_low_part (match_dup 5))
12689 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
12690 operands[5] = gen_lowpart (QImode, operands[3]);
12691 ix86_expand_clear (operands[3]);
12695 [(parallel [(set (reg FLAGS_REG) (match_operand 0))
12696 (match_operand 4)])
12697 (set (match_operand:QI 1 "register_operand")
12698 (match_operator:QI 2 "ix86_comparison_operator"
12699 [(reg FLAGS_REG) (const_int 0)]))
12700 (set (match_operand 3 "any_QIreg_operand")
12701 (zero_extend (match_dup 1)))]
12702 "(peep2_reg_dead_p (3, operands[1])
12703 || operands_match_p (operands[1], operands[3]))
12704 && ! reg_overlap_mentioned_p (operands[3], operands[0])
12705 && ! reg_set_p (operands[3], operands[4])
12706 && peep2_regno_dead_p (0, FLAGS_REG)"
12707 [(parallel [(set (match_dup 5) (match_dup 0))
12709 (set (strict_low_part (match_dup 6))
12712 operands[5] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
12713 operands[6] = gen_lowpart (QImode, operands[3]);
12714 ix86_expand_clear (operands[3]);
12718 [(set (reg FLAGS_REG) (match_operand 0))
12719 (parallel [(set (reg FLAGS_REG) (match_operand 1))
12720 (match_operand 5)])
12721 (set (match_operand:QI 2 "register_operand")
12722 (match_operator:QI 3 "ix86_comparison_operator"
12723 [(reg FLAGS_REG) (const_int 0)]))
12724 (set (match_operand 4 "any_QIreg_operand")
12725 (zero_extend (match_dup 2)))]
12726 "(peep2_reg_dead_p (4, operands[2])
12727 || operands_match_p (operands[2], operands[4]))
12728 && ! reg_overlap_mentioned_p (operands[4], operands[0])
12729 && ! reg_overlap_mentioned_p (operands[4], operands[1])
12730 && ! reg_set_p (operands[4], operands[5])
12731 && refers_to_regno_p (FLAGS_REG, operands[1], (rtx *)NULL)
12732 && peep2_regno_dead_p (0, FLAGS_REG)"
12733 [(set (match_dup 6) (match_dup 0))
12734 (parallel [(set (match_dup 7) (match_dup 1))
12736 (set (strict_low_part (match_dup 8))
12739 operands[6] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
12740 operands[7] = gen_rtx_REG (GET_MODE (operands[1]), FLAGS_REG);
12741 operands[8] = gen_lowpart (QImode, operands[4]);
12742 ix86_expand_clear (operands[4]);
12745 ;; Similar, but match zero extend with andsi3.
12748 [(set (reg FLAGS_REG) (match_operand 0))
12749 (set (match_operand:QI 1 "register_operand")
12750 (match_operator:QI 2 "ix86_comparison_operator"
12751 [(reg FLAGS_REG) (const_int 0)]))
12752 (parallel [(set (match_operand:SI 3 "any_QIreg_operand")
12753 (and:SI (match_dup 3) (const_int 255)))
12754 (clobber (reg:CC FLAGS_REG))])]
12755 "REGNO (operands[1]) == REGNO (operands[3])
12756 && ! reg_overlap_mentioned_p (operands[3], operands[0])
12757 && peep2_regno_dead_p (0, FLAGS_REG)"
12758 [(set (match_dup 4) (match_dup 0))
12759 (set (strict_low_part (match_dup 5))
12762 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
12763 operands[5] = gen_lowpart (QImode, operands[3]);
12764 ix86_expand_clear (operands[3]);
12768 [(parallel [(set (reg FLAGS_REG) (match_operand 0))
12769 (match_operand 4)])
12770 (set (match_operand:QI 1 "register_operand")
12771 (match_operator:QI 2 "ix86_comparison_operator"
12772 [(reg FLAGS_REG) (const_int 0)]))
12773 (parallel [(set (match_operand 3 "any_QIreg_operand")
12774 (zero_extend (match_dup 1)))
12775 (clobber (reg:CC FLAGS_REG))])]
12776 "(peep2_reg_dead_p (3, operands[1])
12777 || operands_match_p (operands[1], operands[3]))
12778 && ! reg_overlap_mentioned_p (operands[3], operands[0])
12779 && ! reg_set_p (operands[3], operands[4])
12780 && peep2_regno_dead_p (0, FLAGS_REG)"
12781 [(parallel [(set (match_dup 5) (match_dup 0))
12783 (set (strict_low_part (match_dup 6))
12786 operands[5] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
12787 operands[6] = gen_lowpart (QImode, operands[3]);
12788 ix86_expand_clear (operands[3]);
12792 [(set (reg FLAGS_REG) (match_operand 0))
12793 (parallel [(set (reg FLAGS_REG) (match_operand 1))
12794 (match_operand 5)])
12795 (set (match_operand:QI 2 "register_operand")
12796 (match_operator:QI 3 "ix86_comparison_operator"
12797 [(reg FLAGS_REG) (const_int 0)]))
12798 (parallel [(set (match_operand 4 "any_QIreg_operand")
12799 (zero_extend (match_dup 2)))
12800 (clobber (reg:CC FLAGS_REG))])]
12801 "(peep2_reg_dead_p (4, operands[2])
12802 || operands_match_p (operands[2], operands[4]))
12803 && ! reg_overlap_mentioned_p (operands[4], operands[0])
12804 && ! reg_overlap_mentioned_p (operands[4], operands[1])
12805 && ! reg_set_p (operands[4], operands[5])
12806 && refers_to_regno_p (FLAGS_REG, operands[1], (rtx *)NULL)
12807 && peep2_regno_dead_p (0, FLAGS_REG)"
12808 [(set (match_dup 6) (match_dup 0))
12809 (parallel [(set (match_dup 7) (match_dup 1))
12811 (set (strict_low_part (match_dup 8))
12814 operands[6] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
12815 operands[7] = gen_rtx_REG (GET_MODE (operands[1]), FLAGS_REG);
12816 operands[8] = gen_lowpart (QImode, operands[4]);
12817 ix86_expand_clear (operands[4]);
12820 ;; Call instructions.
12822 ;; The predicates normally associated with named expanders are not properly
12823 ;; checked for calls. This is a bug in the generic code, but it isn't that
12824 ;; easy to fix. Ignore it for now and be prepared to fix things up.
12826 ;; P6 processors will jump to the address after the decrement when %esp
12827 ;; is used as a call operand, so they will execute return address as a code.
12828 ;; See Pentium Pro errata 70, Pentium 2 errata A33 and Pentium 3 errata E17.
12830 ;; Register constraint for call instruction.
12831 (define_mode_attr c [(SI "l") (DI "r")])
12833 ;; Call subroutine returning no value.
12835 (define_expand "call"
12836 [(call (match_operand:QI 0)
12838 (use (match_operand 2))]
12841 ix86_expand_call (NULL, operands[0], operands[1],
12842 operands[2], NULL, false);
12846 (define_expand "sibcall"
12847 [(call (match_operand:QI 0)
12849 (use (match_operand 2))]
12852 ix86_expand_call (NULL, operands[0], operands[1],
12853 operands[2], NULL, true);
12857 (define_insn "*call"
12858 [(call (mem:QI (match_operand:W 0 "call_insn_operand" "<c>BwBz"))
12859 (match_operand 1))]
12860 "!SIBLING_CALL_P (insn)"
12861 "* return ix86_output_call_insn (insn, operands[0]);"
12862 [(set_attr "type" "call")])
12864 ;; This covers both call and sibcall since only GOT slot is allowed.
12865 (define_insn "*call_got_x32"
12866 [(call (mem:QI (zero_extend:DI
12867 (match_operand:SI 0 "GOT_memory_operand" "Bg")))
12868 (match_operand 1))]
12871 rtx fnaddr = gen_const_mem (DImode, XEXP (operands[0], 0));
12872 return ix86_output_call_insn (insn, fnaddr);
12874 [(set_attr "type" "call")])
12876 ;; Since sibcall never returns, we can only use call-clobbered register
12878 (define_insn "*sibcall_GOT_32"
12881 (match_operand:SI 0 "register_no_elim_operand" "U")
12882 (match_operand:SI 1 "GOT32_symbol_operand"))))
12883 (match_operand 2))]
12886 && !TARGET_INDIRECT_BRANCH_REGISTER
12887 && SIBLING_CALL_P (insn)"
12889 rtx fnaddr = gen_rtx_PLUS (SImode, operands[0], operands[1]);
12890 fnaddr = gen_const_mem (SImode, fnaddr);
12891 return ix86_output_call_insn (insn, fnaddr);
12893 [(set_attr "type" "call")])
12895 (define_insn "*sibcall"
12896 [(call (mem:QI (match_operand:W 0 "sibcall_insn_operand" "UBsBz"))
12897 (match_operand 1))]
12898 "SIBLING_CALL_P (insn)"
12899 "* return ix86_output_call_insn (insn, operands[0]);"
12900 [(set_attr "type" "call")])
12902 (define_insn "*sibcall_memory"
12903 [(call (mem:QI (match_operand:W 0 "memory_operand" "m"))
12905 (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
12906 "!TARGET_X32 && !TARGET_INDIRECT_BRANCH_REGISTER"
12907 "* return ix86_output_call_insn (insn, operands[0]);"
12908 [(set_attr "type" "call")])
12911 [(set (match_operand:W 0 "register_operand")
12912 (match_operand:W 1 "memory_operand"))
12913 (call (mem:QI (match_dup 0))
12914 (match_operand 3))]
12916 && !TARGET_INDIRECT_BRANCH_REGISTER
12917 && SIBLING_CALL_P (peep2_next_insn (1))
12918 && !reg_mentioned_p (operands[0],
12919 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (1)))"
12920 [(parallel [(call (mem:QI (match_dup 1))
12922 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
12925 [(set (match_operand:W 0 "register_operand")
12926 (match_operand:W 1 "memory_operand"))
12927 (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
12928 (call (mem:QI (match_dup 0))
12929 (match_operand 3))]
12931 && !TARGET_INDIRECT_BRANCH_REGISTER
12932 && SIBLING_CALL_P (peep2_next_insn (2))
12933 && !reg_mentioned_p (operands[0],
12934 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (2)))"
12935 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
12936 (parallel [(call (mem:QI (match_dup 1))
12938 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
12940 (define_expand "call_pop"
12941 [(parallel [(call (match_operand:QI 0)
12942 (match_operand:SI 1))
12943 (set (reg:SI SP_REG)
12944 (plus:SI (reg:SI SP_REG)
12945 (match_operand:SI 3)))])]
12948 ix86_expand_call (NULL, operands[0], operands[1],
12949 operands[2], operands[3], false);
12953 (define_insn "*call_pop"
12954 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lBwBz"))
12956 (set (reg:SI SP_REG)
12957 (plus:SI (reg:SI SP_REG)
12958 (match_operand:SI 2 "immediate_operand" "i")))]
12959 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
12960 "* return ix86_output_call_insn (insn, operands[0]);"
12961 [(set_attr "type" "call")])
12963 (define_insn "*sibcall_pop"
12964 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "UBsBz"))
12966 (set (reg:SI SP_REG)
12967 (plus:SI (reg:SI SP_REG)
12968 (match_operand:SI 2 "immediate_operand" "i")))]
12969 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
12970 "* return ix86_output_call_insn (insn, operands[0]);"
12971 [(set_attr "type" "call")])
12973 (define_insn "*sibcall_pop_memory"
12974 [(call (mem:QI (match_operand:SI 0 "memory_operand" "Bs"))
12976 (set (reg:SI SP_REG)
12977 (plus:SI (reg:SI SP_REG)
12978 (match_operand:SI 2 "immediate_operand" "i")))
12979 (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
12981 "* return ix86_output_call_insn (insn, operands[0]);"
12982 [(set_attr "type" "call")])
12985 [(set (match_operand:SI 0 "register_operand")
12986 (match_operand:SI 1 "memory_operand"))
12987 (parallel [(call (mem:QI (match_dup 0))
12989 (set (reg:SI SP_REG)
12990 (plus:SI (reg:SI SP_REG)
12991 (match_operand:SI 4 "immediate_operand")))])]
12992 "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (1))
12993 && !reg_mentioned_p (operands[0],
12994 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (1)))"
12995 [(parallel [(call (mem:QI (match_dup 1))
12997 (set (reg:SI SP_REG)
12998 (plus:SI (reg:SI SP_REG)
13000 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
13003 [(set (match_operand:SI 0 "register_operand")
13004 (match_operand:SI 1 "memory_operand"))
13005 (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
13006 (parallel [(call (mem:QI (match_dup 0))
13008 (set (reg:SI SP_REG)
13009 (plus:SI (reg:SI SP_REG)
13010 (match_operand:SI 4 "immediate_operand")))])]
13011 "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (2))
13012 && !reg_mentioned_p (operands[0],
13013 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (2)))"
13014 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
13015 (parallel [(call (mem:QI (match_dup 1))
13017 (set (reg:SI SP_REG)
13018 (plus:SI (reg:SI SP_REG)
13020 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
13022 ;; Combining simple memory jump instruction
13025 [(set (match_operand:W 0 "register_operand")
13026 (match_operand:W 1 "memory_operand"))
13027 (set (pc) (match_dup 0))]
13029 && !TARGET_INDIRECT_BRANCH_REGISTER
13030 && peep2_reg_dead_p (2, operands[0])"
13031 [(set (pc) (match_dup 1))])
13033 ;; Call subroutine, returning value in operand 0
13035 (define_expand "call_value"
13036 [(set (match_operand 0)
13037 (call (match_operand:QI 1)
13038 (match_operand 2)))
13039 (use (match_operand 3))]
13042 ix86_expand_call (operands[0], operands[1], operands[2],
13043 operands[3], NULL, false);
13047 (define_expand "sibcall_value"
13048 [(set (match_operand 0)
13049 (call (match_operand:QI 1)
13050 (match_operand 2)))
13051 (use (match_operand 3))]
13054 ix86_expand_call (operands[0], operands[1], operands[2],
13055 operands[3], NULL, true);
13059 (define_insn "*call_value"
13060 [(set (match_operand 0)
13061 (call (mem:QI (match_operand:W 1 "call_insn_operand" "<c>BwBz"))
13062 (match_operand 2)))]
13063 "!SIBLING_CALL_P (insn)"
13064 "* return ix86_output_call_insn (insn, operands[1]);"
13065 [(set_attr "type" "callv")])
13067 ;; This covers both call and sibcall since only GOT slot is allowed.
13068 (define_insn "*call_value_got_x32"
13069 [(set (match_operand 0)
13072 (match_operand:SI 1 "GOT_memory_operand" "Bg")))
13073 (match_operand 2)))]
13076 rtx fnaddr = gen_const_mem (DImode, XEXP (operands[1], 0));
13077 return ix86_output_call_insn (insn, fnaddr);
13079 [(set_attr "type" "callv")])
13081 ;; Since sibcall never returns, we can only use call-clobbered register
13083 (define_insn "*sibcall_value_GOT_32"
13084 [(set (match_operand 0)
13087 (match_operand:SI 1 "register_no_elim_operand" "U")
13088 (match_operand:SI 2 "GOT32_symbol_operand"))))
13089 (match_operand 3)))]
13092 && !TARGET_INDIRECT_BRANCH_REGISTER
13093 && SIBLING_CALL_P (insn)"
13095 rtx fnaddr = gen_rtx_PLUS (SImode, operands[1], operands[2]);
13096 fnaddr = gen_const_mem (SImode, fnaddr);
13097 return ix86_output_call_insn (insn, fnaddr);
13099 [(set_attr "type" "callv")])
13101 (define_insn "*sibcall_value"
13102 [(set (match_operand 0)
13103 (call (mem:QI (match_operand:W 1 "sibcall_insn_operand" "UBsBz"))
13104 (match_operand 2)))]
13105 "SIBLING_CALL_P (insn)"
13106 "* return ix86_output_call_insn (insn, operands[1]);"
13107 [(set_attr "type" "callv")])
13109 (define_insn "*sibcall_value_memory"
13110 [(set (match_operand 0)
13111 (call (mem:QI (match_operand:W 1 "memory_operand" "m"))
13112 (match_operand 2)))
13113 (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
13114 "!TARGET_X32 && !TARGET_INDIRECT_BRANCH_REGISTER"
13115 "* return ix86_output_call_insn (insn, operands[1]);"
13116 [(set_attr "type" "callv")])
13119 [(set (match_operand:W 0 "register_operand")
13120 (match_operand:W 1 "memory_operand"))
13121 (set (match_operand 2)
13122 (call (mem:QI (match_dup 0))
13123 (match_operand 3)))]
13125 && !TARGET_INDIRECT_BRANCH_REGISTER
13126 && SIBLING_CALL_P (peep2_next_insn (1))
13127 && !reg_mentioned_p (operands[0],
13128 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (1)))"
13129 [(parallel [(set (match_dup 2)
13130 (call (mem:QI (match_dup 1))
13132 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
13135 [(set (match_operand:W 0 "register_operand")
13136 (match_operand:W 1 "memory_operand"))
13137 (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
13138 (set (match_operand 2)
13139 (call (mem:QI (match_dup 0))
13140 (match_operand 3)))]
13142 && !TARGET_INDIRECT_BRANCH_REGISTER
13143 && SIBLING_CALL_P (peep2_next_insn (2))
13144 && !reg_mentioned_p (operands[0],
13145 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (2)))"
13146 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
13147 (parallel [(set (match_dup 2)
13148 (call (mem:QI (match_dup 1))
13150 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
13152 (define_expand "call_value_pop"
13153 [(parallel [(set (match_operand 0)
13154 (call (match_operand:QI 1)
13155 (match_operand:SI 2)))
13156 (set (reg:SI SP_REG)
13157 (plus:SI (reg:SI SP_REG)
13158 (match_operand:SI 4)))])]
13161 ix86_expand_call (operands[0], operands[1], operands[2],
13162 operands[3], operands[4], false);
13166 (define_insn "*call_value_pop"
13167 [(set (match_operand 0)
13168 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lBwBz"))
13169 (match_operand 2)))
13170 (set (reg:SI SP_REG)
13171 (plus:SI (reg:SI SP_REG)
13172 (match_operand:SI 3 "immediate_operand" "i")))]
13173 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
13174 "* return ix86_output_call_insn (insn, operands[1]);"
13175 [(set_attr "type" "callv")])
13177 (define_insn "*sibcall_value_pop"
13178 [(set (match_operand 0)
13179 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "UBsBz"))
13180 (match_operand 2)))
13181 (set (reg:SI SP_REG)
13182 (plus:SI (reg:SI SP_REG)
13183 (match_operand:SI 3 "immediate_operand" "i")))]
13184 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
13185 "* return ix86_output_call_insn (insn, operands[1]);"
13186 [(set_attr "type" "callv")])
13188 (define_insn "*sibcall_value_pop_memory"
13189 [(set (match_operand 0)
13190 (call (mem:QI (match_operand:SI 1 "memory_operand" "m"))
13191 (match_operand 2)))
13192 (set (reg:SI SP_REG)
13193 (plus:SI (reg:SI SP_REG)
13194 (match_operand:SI 3 "immediate_operand" "i")))
13195 (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
13197 "* return ix86_output_call_insn (insn, operands[1]);"
13198 [(set_attr "type" "callv")])
13201 [(set (match_operand:SI 0 "register_operand")
13202 (match_operand:SI 1 "memory_operand"))
13203 (parallel [(set (match_operand 2)
13204 (call (mem:QI (match_dup 0))
13205 (match_operand 3)))
13206 (set (reg:SI SP_REG)
13207 (plus:SI (reg:SI SP_REG)
13208 (match_operand:SI 4 "immediate_operand")))])]
13209 "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (1))
13210 && !reg_mentioned_p (operands[0],
13211 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (1)))"
13212 [(parallel [(set (match_dup 2)
13213 (call (mem:QI (match_dup 1))
13215 (set (reg:SI SP_REG)
13216 (plus:SI (reg:SI SP_REG)
13218 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
13221 [(set (match_operand:SI 0 "register_operand")
13222 (match_operand:SI 1 "memory_operand"))
13223 (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
13224 (parallel [(set (match_operand 2)
13225 (call (mem:QI (match_dup 0))
13226 (match_operand 3)))
13227 (set (reg:SI SP_REG)
13228 (plus:SI (reg:SI SP_REG)
13229 (match_operand:SI 4 "immediate_operand")))])]
13230 "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (2))
13231 && !reg_mentioned_p (operands[0],
13232 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (2)))"
13233 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
13234 (parallel [(set (match_dup 2)
13235 (call (mem:QI (match_dup 1))
13237 (set (reg:SI SP_REG)
13238 (plus:SI (reg:SI SP_REG)
13240 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
13242 ;; Call subroutine returning any type.
13244 (define_expand "untyped_call"
13245 [(parallel [(call (match_operand 0)
13248 (match_operand 2)])]
13253 /* In order to give reg-stack an easier job in validating two
13254 coprocessor registers as containing a possible return value,
13255 simply pretend the untyped call returns a complex long double
13258 We can't use SSE_REGPARM_MAX here since callee is unprototyped
13259 and should have the default ABI. */
13261 ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
13262 ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
13263 operands[0], const0_rtx,
13264 GEN_INT ((TARGET_64BIT
13265 ? (ix86_abi == SYSV_ABI
13266 ? X86_64_SSE_REGPARM_MAX
13267 : X86_64_MS_SSE_REGPARM_MAX)
13268 : X86_32_SSE_REGPARM_MAX)
13272 for (i = 0; i < XVECLEN (operands[2], 0); i++)
13274 rtx set = XVECEXP (operands[2], 0, i);
13275 emit_move_insn (SET_DEST (set), SET_SRC (set));
13278 /* The optimizer does not know that the call sets the function value
13279 registers we stored in the result block. We avoid problems by
13280 claiming that all hard registers are used and clobbered at this
13282 emit_insn (gen_blockage ());
13287 ;; Prologue and epilogue instructions
13289 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
13290 ;; all of memory. This blocks insns from being moved across this point.
13292 (define_insn "blockage"
13293 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
13296 [(set_attr "length" "0")])
13298 ;; Do not schedule instructions accessing memory across this point.
13300 (define_expand "memory_blockage"
13301 [(set (match_dup 0)
13302 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
13305 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
13306 MEM_VOLATILE_P (operands[0]) = 1;
13309 (define_insn "*memory_blockage"
13310 [(set (match_operand:BLK 0)
13311 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
13314 [(set_attr "length" "0")])
13316 ;; As USE insns aren't meaningful after reload, this is used instead
13317 ;; to prevent deleting instructions setting registers for PIC code
13318 (define_insn "prologue_use"
13319 [(unspec_volatile [(match_operand 0)] UNSPECV_PROLOGUE_USE)]
13322 [(set_attr "length" "0")])
13324 ;; Insn emitted into the body of a function to return from a function.
13325 ;; This is only done if the function's epilogue is known to be simple.
13326 ;; See comments for ix86_can_use_return_insn_p in i386.c.
13328 (define_expand "return"
13330 "ix86_can_use_return_insn_p ()"
13332 if (crtl->args.pops_args)
13334 rtx popc = GEN_INT (crtl->args.pops_args);
13335 emit_jump_insn (gen_simple_return_pop_internal (popc));
13340 ;; We need to disable this for TARGET_SEH, as otherwise
13341 ;; shrink-wrapped prologue gets enabled too. This might exceed
13342 ;; the maximum size of prologue in unwind information.
13343 ;; Also disallow shrink-wrapping if using stack slot to pass the
13344 ;; static chain pointer - the first instruction has to be pushl %esi
13345 ;; and it can't be moved around, as we use alternate entry points
13348 (define_expand "simple_return"
13350 "!TARGET_SEH && !ix86_static_chain_on_stack"
13352 if (crtl->args.pops_args)
13354 rtx popc = GEN_INT (crtl->args.pops_args);
13355 emit_jump_insn (gen_simple_return_pop_internal (popc));
13360 (define_insn "simple_return_internal"
13363 "* return ix86_output_function_return (false);"
13364 [(set_attr "length" "1")
13365 (set_attr "atom_unit" "jeu")
13366 (set_attr "length_immediate" "0")
13367 (set_attr "modrm" "0")
13368 (set_attr "maybe_prefix_bnd" "1")])
13370 (define_insn "interrupt_return"
13372 (unspec [(const_int 0)] UNSPEC_INTERRUPT_RETURN)]
13375 return TARGET_64BIT ? "iretq" : "iret";
13378 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
13379 ;; instruction Athlon and K8 have.
13381 (define_insn "simple_return_internal_long"
13383 (unspec [(const_int 0)] UNSPEC_REP)]
13385 "* return ix86_output_function_return (true);"
13386 [(set_attr "length" "2")
13387 (set_attr "atom_unit" "jeu")
13388 (set_attr "length_immediate" "0")
13389 (set_attr "prefix_rep" "1")
13390 (set_attr "modrm" "0")])
13392 (define_insn_and_split "simple_return_pop_internal"
13394 (use (match_operand:SI 0 "const_int_operand"))]
13397 "&& cfun->machine->function_return_type != indirect_branch_keep"
13399 "ix86_split_simple_return_pop_internal (operands[0]); DONE;"
13400 [(set_attr "length" "3")
13401 (set_attr "atom_unit" "jeu")
13402 (set_attr "length_immediate" "2")
13403 (set_attr "modrm" "0")
13404 (set_attr "maybe_prefix_bnd" "1")])
13406 (define_insn "simple_return_indirect_internal"
13408 (use (match_operand 0 "register_operand" "r"))]
13410 "* return ix86_output_indirect_function_return (operands[0]);"
13411 [(set (attr "type")
13412 (if_then_else (match_test "(cfun->machine->indirect_branch_type
13413 != indirect_branch_keep)")
13414 (const_string "multi")
13415 (const_string "ibr")))
13416 (set_attr "length_immediate" "0")
13417 (set_attr "maybe_prefix_bnd" "1")])
13423 [(set_attr "length" "1")
13424 (set_attr "length_immediate" "0")
13425 (set_attr "modrm" "0")])
13427 ;; Generate nops. Operand 0 is the number of nops, up to 8.
13428 (define_insn "nops"
13429 [(unspec_volatile [(match_operand 0 "const_int_operand")]
13433 int num = INTVAL (operands[0]);
13435 gcc_assert (IN_RANGE (num, 1, 8));
13438 fputs ("\tnop\n", asm_out_file);
13442 [(set (attr "length") (symbol_ref "INTVAL (operands[0])"))
13443 (set_attr "length_immediate" "0")
13444 (set_attr "modrm" "0")])
13446 ;; Pad to 16-byte boundary, max skip in op0. Used to avoid
13447 ;; branch prediction penalty for the third jump in a 16-byte
13451 [(unspec_volatile [(match_operand 0)] UNSPECV_ALIGN)]
13454 #ifdef ASM_OUTPUT_MAX_SKIP_PAD
13455 ASM_OUTPUT_MAX_SKIP_PAD (asm_out_file, 4, (int)INTVAL (operands[0]));
13457 /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
13458 The align insn is used to avoid 3 jump instructions in the row to improve
13459 branch prediction and the benefits hardly outweigh the cost of extra 8
13460 nops on the average inserted by full alignment pseudo operation. */
13464 [(set_attr "length" "16")])
13466 (define_expand "prologue"
13469 "ix86_expand_prologue (); DONE;")
13471 (define_expand "set_got"
13473 [(set (match_operand:SI 0 "register_operand")
13474 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
13475 (clobber (reg:CC FLAGS_REG))])]
13478 if (flag_pic && !TARGET_VXWORKS_RTP)
13479 ix86_pc_thunk_call_expanded = true;
13482 (define_insn "*set_got"
13483 [(set (match_operand:SI 0 "register_operand" "=r")
13484 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
13485 (clobber (reg:CC FLAGS_REG))]
13487 "* return output_set_got (operands[0], NULL_RTX);"
13488 [(set_attr "type" "multi")
13489 (set_attr "length" "12")])
13491 (define_expand "set_got_labelled"
13493 [(set (match_operand:SI 0 "register_operand")
13494 (unspec:SI [(label_ref (match_operand 1))]
13496 (clobber (reg:CC FLAGS_REG))])]
13499 if (flag_pic && !TARGET_VXWORKS_RTP)
13500 ix86_pc_thunk_call_expanded = true;
13503 (define_insn "*set_got_labelled"
13504 [(set (match_operand:SI 0 "register_operand" "=r")
13505 (unspec:SI [(label_ref (match_operand 1))]
13507 (clobber (reg:CC FLAGS_REG))]
13509 "* return output_set_got (operands[0], operands[1]);"
13510 [(set_attr "type" "multi")
13511 (set_attr "length" "12")])
13513 (define_insn "set_got_rex64"
13514 [(set (match_operand:DI 0 "register_operand" "=r")
13515 (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
13517 "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}"
13518 [(set_attr "type" "lea")
13519 (set_attr "length_address" "4")
13520 (set_attr "modrm_class" "unknown")
13521 (set_attr "mode" "DI")])
13523 (define_insn "set_rip_rex64"
13524 [(set (match_operand:DI 0 "register_operand" "=r")
13525 (unspec:DI [(label_ref (match_operand 1))] UNSPEC_SET_RIP))]
13527 "lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}"
13528 [(set_attr "type" "lea")
13529 (set_attr "length_address" "4")
13530 (set_attr "mode" "DI")])
13532 (define_insn "set_got_offset_rex64"
13533 [(set (match_operand:DI 0 "register_operand" "=r")
13535 [(label_ref (match_operand 1))]
13536 UNSPEC_SET_GOT_OFFSET))]
13538 "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}"
13539 [(set_attr "type" "imov")
13540 (set_attr "length_immediate" "0")
13541 (set_attr "length_address" "8")
13542 (set_attr "mode" "DI")])
13544 (define_expand "epilogue"
13547 "ix86_expand_epilogue (1); DONE;")
13549 (define_expand "sibcall_epilogue"
13552 "ix86_expand_epilogue (0); DONE;")
13554 (define_expand "eh_return"
13555 [(use (match_operand 0 "register_operand"))]
13558 rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
13560 /* Tricky bit: we write the address of the handler to which we will
13561 be returning into someone else's stack frame, one word below the
13562 stack address we wish to restore. */
13563 tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
13564 tmp = plus_constant (Pmode, tmp, -UNITS_PER_WORD);
13565 tmp = gen_rtx_MEM (Pmode, tmp);
13566 emit_move_insn (tmp, ra);
13568 emit_jump_insn (gen_eh_return_internal ());
13573 (define_insn_and_split "eh_return_internal"
13577 "epilogue_completed"
13579 "ix86_expand_epilogue (2); DONE;")
13581 (define_insn "leave"
13582 [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
13583 (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
13584 (clobber (mem:BLK (scratch)))]
13587 [(set_attr "type" "leave")])
13589 (define_insn "leave_rex64"
13590 [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
13591 (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
13592 (clobber (mem:BLK (scratch)))]
13595 [(set_attr "type" "leave")])
13597 ;; Handle -fsplit-stack.
13599 (define_expand "split_stack_prologue"
13603 ix86_expand_split_stack_prologue ();
13607 ;; In order to support the call/return predictor, we use a return
13608 ;; instruction which the middle-end doesn't see.
13609 (define_insn "split_stack_return"
13610 [(unspec_volatile [(match_operand:SI 0 "const_int_operand")]
13611 UNSPECV_SPLIT_STACK_RETURN)]
13614 if (operands[0] == const0_rtx)
13619 [(set_attr "atom_unit" "jeu")
13620 (set_attr "modrm" "0")
13621 (set (attr "length")
13622 (if_then_else (match_operand:SI 0 "const0_operand")
13625 (set (attr "length_immediate")
13626 (if_then_else (match_operand:SI 0 "const0_operand")
13630 ;; If there are operand 0 bytes available on the stack, jump to
13633 (define_expand "split_stack_space_check"
13634 [(set (pc) (if_then_else
13635 (ltu (minus (reg SP_REG)
13636 (match_operand 0 "register_operand"))
13638 (label_ref (match_operand 1))
13642 rtx reg = gen_reg_rtx (Pmode);
13644 emit_insn (gen_sub3_insn (reg, stack_pointer_rtx, operands[0]));
13646 operands[2] = ix86_split_stack_guard ();
13647 ix86_expand_branch (GEU, reg, operands[2], operands[1]);
13652 ;; Bit manipulation instructions.
13654 (define_expand "ffs<mode>2"
13655 [(set (match_dup 2) (const_int -1))
13656 (parallel [(set (match_dup 3) (match_dup 4))
13657 (set (match_operand:SWI48 0 "register_operand")
13659 (match_operand:SWI48 1 "nonimmediate_operand")))])
13660 (set (match_dup 0) (if_then_else:SWI48
13661 (eq (match_dup 3) (const_int 0))
13664 (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (const_int 1)))
13665 (clobber (reg:CC FLAGS_REG))])]
13668 machine_mode flags_mode;
13670 if (<MODE>mode == SImode && !TARGET_CMOVE)
13672 emit_insn (gen_ffssi2_no_cmove (operands[0], operands [1]));
13676 flags_mode = TARGET_BMI ? CCCmode : CCZmode;
13678 operands[2] = gen_reg_rtx (<MODE>mode);
13679 operands[3] = gen_rtx_REG (flags_mode, FLAGS_REG);
13680 operands[4] = gen_rtx_COMPARE (flags_mode, operands[1], const0_rtx);
13683 (define_insn_and_split "ffssi2_no_cmove"
13684 [(set (match_operand:SI 0 "register_operand" "=r")
13685 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
13686 (clobber (match_scratch:SI 2 "=&q"))
13687 (clobber (reg:CC FLAGS_REG))]
13690 "&& reload_completed"
13691 [(parallel [(set (match_dup 4) (match_dup 5))
13692 (set (match_dup 0) (ctz:SI (match_dup 1)))])
13693 (set (strict_low_part (match_dup 3))
13694 (eq:QI (match_dup 4) (const_int 0)))
13695 (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
13696 (clobber (reg:CC FLAGS_REG))])
13697 (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
13698 (clobber (reg:CC FLAGS_REG))])
13699 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
13700 (clobber (reg:CC FLAGS_REG))])]
13702 machine_mode flags_mode = TARGET_BMI ? CCCmode : CCZmode;
13704 operands[3] = gen_lowpart (QImode, operands[2]);
13705 operands[4] = gen_rtx_REG (flags_mode, FLAGS_REG);
13706 operands[5] = gen_rtx_COMPARE (flags_mode, operands[1], const0_rtx);
13708 ix86_expand_clear (operands[2]);
13711 (define_insn_and_split "*tzcnt<mode>_1"
13712 [(set (reg:CCC FLAGS_REG)
13713 (compare:CCC (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13715 (set (match_operand:SWI48 0 "register_operand" "=r")
13716 (ctz:SWI48 (match_dup 1)))]
13718 "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
13719 "&& TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
13720 && optimize_function_for_speed_p (cfun)
13721 && !reg_mentioned_p (operands[0], operands[1])"
13723 [(set (reg:CCC FLAGS_REG)
13724 (compare:CCC (match_dup 1) (const_int 0)))
13726 (ctz:SWI48 (match_dup 1)))
13727 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)])]
13728 "ix86_expand_clear (operands[0]);"
13729 [(set_attr "type" "alu1")
13730 (set_attr "prefix_0f" "1")
13731 (set_attr "prefix_rep" "1")
13732 (set_attr "btver2_decode" "double")
13733 (set_attr "mode" "<MODE>")])
13735 ; False dependency happens when destination is only updated by tzcnt,
13736 ; lzcnt or popcnt. There is no false dependency when destination is
13737 ; also used in source.
13738 (define_insn "*tzcnt<mode>_1_falsedep"
13739 [(set (reg:CCC FLAGS_REG)
13740 (compare:CCC (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13742 (set (match_operand:SWI48 0 "register_operand" "=r")
13743 (ctz:SWI48 (match_dup 1)))
13744 (unspec [(match_operand:SWI48 2 "register_operand" "0")]
13745 UNSPEC_INSN_FALSE_DEP)]
13747 "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
13748 [(set_attr "type" "alu1")
13749 (set_attr "prefix_0f" "1")
13750 (set_attr "prefix_rep" "1")
13751 (set_attr "btver2_decode" "double")
13752 (set_attr "mode" "<MODE>")])
13754 (define_insn "*bsf<mode>_1"
13755 [(set (reg:CCZ FLAGS_REG)
13756 (compare:CCZ (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13758 (set (match_operand:SWI48 0 "register_operand" "=r")
13759 (ctz:SWI48 (match_dup 1)))]
13761 "bsf{<imodesuffix>}\t{%1, %0|%0, %1}"
13762 [(set_attr "type" "alu1")
13763 (set_attr "prefix_0f" "1")
13764 (set_attr "btver2_decode" "double")
13765 (set_attr "znver1_decode" "vector")
13766 (set_attr "mode" "<MODE>")])
13768 (define_insn_and_split "ctz<mode>2"
13769 [(set (match_operand:SWI48 0 "register_operand" "=r")
13771 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
13772 (clobber (reg:CC FLAGS_REG))]
13776 return "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
13777 else if (optimize_function_for_size_p (cfun))
13779 else if (TARGET_GENERIC)
13780 /* tzcnt expands to 'rep bsf' and we can use it even if !TARGET_BMI. */
13781 return "rep%; bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
13783 return "bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
13785 "(TARGET_BMI || TARGET_GENERIC)
13786 && TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
13787 && optimize_function_for_speed_p (cfun)
13788 && !reg_mentioned_p (operands[0], operands[1])"
13790 [(set (match_dup 0)
13791 (ctz:SWI48 (match_dup 1)))
13792 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
13793 (clobber (reg:CC FLAGS_REG))])]
13794 "ix86_expand_clear (operands[0]);"
13795 [(set_attr "type" "alu1")
13796 (set_attr "prefix_0f" "1")
13797 (set (attr "prefix_rep")
13799 (ior (match_test "TARGET_BMI")
13800 (and (not (match_test "optimize_function_for_size_p (cfun)"))
13801 (match_test "TARGET_GENERIC")))
13803 (const_string "0")))
13804 (set_attr "mode" "<MODE>")])
13806 ; False dependency happens when destination is only updated by tzcnt,
13807 ; lzcnt or popcnt. There is no false dependency when destination is
13808 ; also used in source.
13809 (define_insn "*ctz<mode>2_falsedep"
13810 [(set (match_operand:SWI48 0 "register_operand" "=r")
13812 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
13813 (unspec [(match_operand:SWI48 2 "register_operand" "0")]
13814 UNSPEC_INSN_FALSE_DEP)
13815 (clobber (reg:CC FLAGS_REG))]
13819 return "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
13820 else if (TARGET_GENERIC)
13821 /* tzcnt expands to 'rep bsf' and we can use it even if !TARGET_BMI. */
13822 return "rep%; bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
13824 gcc_unreachable ();
13826 [(set_attr "type" "alu1")
13827 (set_attr "prefix_0f" "1")
13828 (set_attr "prefix_rep" "1")
13829 (set_attr "mode" "<MODE>")])
13831 (define_insn "bsr_rex64"
13832 [(set (match_operand:DI 0 "register_operand" "=r")
13833 (minus:DI (const_int 63)
13834 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
13835 (clobber (reg:CC FLAGS_REG))]
13837 "bsr{q}\t{%1, %0|%0, %1}"
13838 [(set_attr "type" "alu1")
13839 (set_attr "prefix_0f" "1")
13840 (set_attr "znver1_decode" "vector")
13841 (set_attr "mode" "DI")])
13844 [(set (match_operand:SI 0 "register_operand" "=r")
13845 (minus:SI (const_int 31)
13846 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
13847 (clobber (reg:CC FLAGS_REG))]
13849 "bsr{l}\t{%1, %0|%0, %1}"
13850 [(set_attr "type" "alu1")
13851 (set_attr "prefix_0f" "1")
13852 (set_attr "znver1_decode" "vector")
13853 (set_attr "mode" "SI")])
13855 (define_insn "*bsrhi"
13856 [(set (match_operand:HI 0 "register_operand" "=r")
13857 (minus:HI (const_int 15)
13858 (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
13859 (clobber (reg:CC FLAGS_REG))]
13861 "bsr{w}\t{%1, %0|%0, %1}"
13862 [(set_attr "type" "alu1")
13863 (set_attr "prefix_0f" "1")
13864 (set_attr "znver1_decode" "vector")
13865 (set_attr "mode" "HI")])
13867 (define_expand "clz<mode>2"
13869 [(set (match_operand:SWI48 0 "register_operand")
13872 (clz:SWI48 (match_operand:SWI48 1 "nonimmediate_operand"))))
13873 (clobber (reg:CC FLAGS_REG))])
13875 [(set (match_dup 0) (xor:SWI48 (match_dup 0) (match_dup 2)))
13876 (clobber (reg:CC FLAGS_REG))])]
13881 emit_insn (gen_clz<mode>2_lzcnt (operands[0], operands[1]));
13884 operands[2] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
13887 (define_insn_and_split "clz<mode>2_lzcnt"
13888 [(set (match_operand:SWI48 0 "register_operand" "=r")
13890 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
13891 (clobber (reg:CC FLAGS_REG))]
13893 "lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
13894 "&& TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
13895 && optimize_function_for_speed_p (cfun)
13896 && !reg_mentioned_p (operands[0], operands[1])"
13898 [(set (match_dup 0)
13899 (clz:SWI48 (match_dup 1)))
13900 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
13901 (clobber (reg:CC FLAGS_REG))])]
13902 "ix86_expand_clear (operands[0]);"
13903 [(set_attr "prefix_rep" "1")
13904 (set_attr "type" "bitmanip")
13905 (set_attr "mode" "<MODE>")])
13907 ; False dependency happens when destination is only updated by tzcnt,
13908 ; lzcnt or popcnt. There is no false dependency when destination is
13909 ; also used in source.
13910 (define_insn "*clz<mode>2_lzcnt_falsedep"
13911 [(set (match_operand:SWI48 0 "register_operand" "=r")
13913 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
13914 (unspec [(match_operand:SWI48 2 "register_operand" "0")]
13915 UNSPEC_INSN_FALSE_DEP)
13916 (clobber (reg:CC FLAGS_REG))]
13918 "lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
13919 [(set_attr "prefix_rep" "1")
13920 (set_attr "type" "bitmanip")
13921 (set_attr "mode" "<MODE>")])
13923 (define_int_iterator LT_ZCNT
13924 [(UNSPEC_TZCNT "TARGET_BMI")
13925 (UNSPEC_LZCNT "TARGET_LZCNT")])
13927 (define_int_attr lt_zcnt
13928 [(UNSPEC_TZCNT "tzcnt")
13929 (UNSPEC_LZCNT "lzcnt")])
13931 (define_int_attr lt_zcnt_type
13932 [(UNSPEC_TZCNT "alu1")
13933 (UNSPEC_LZCNT "bitmanip")])
13935 ;; Version of lzcnt/tzcnt that is expanded from intrinsics. This version
13936 ;; provides operand size as output when source operand is zero.
13938 (define_insn_and_split "<lt_zcnt>_<mode>"
13939 [(set (match_operand:SWI48 0 "register_operand" "=r")
13941 [(match_operand:SWI48 1 "nonimmediate_operand" "rm")] LT_ZCNT))
13942 (clobber (reg:CC FLAGS_REG))]
13944 "<lt_zcnt>{<imodesuffix>}\t{%1, %0|%0, %1}"
13945 "&& TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
13946 && optimize_function_for_speed_p (cfun)
13947 && !reg_mentioned_p (operands[0], operands[1])"
13949 [(set (match_dup 0)
13950 (unspec:SWI48 [(match_dup 1)] LT_ZCNT))
13951 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
13952 (clobber (reg:CC FLAGS_REG))])]
13953 "ix86_expand_clear (operands[0]);"
13954 [(set_attr "type" "<lt_zcnt_type>")
13955 (set_attr "prefix_0f" "1")
13956 (set_attr "prefix_rep" "1")
13957 (set_attr "mode" "<MODE>")])
13959 ; False dependency happens when destination is only updated by tzcnt,
13960 ; lzcnt or popcnt. There is no false dependency when destination is
13961 ; also used in source.
13962 (define_insn "*<lt_zcnt>_<mode>_falsedep"
13963 [(set (match_operand:SWI48 0 "register_operand" "=r")
13965 [(match_operand:SWI48 1 "nonimmediate_operand" "rm")] LT_ZCNT))
13966 (unspec [(match_operand:SWI48 2 "register_operand" "0")]
13967 UNSPEC_INSN_FALSE_DEP)
13968 (clobber (reg:CC FLAGS_REG))]
13970 "<lt_zcnt>{<imodesuffix>}\t{%1, %0|%0, %1}"
13971 [(set_attr "type" "<lt_zcnt_type>")
13972 (set_attr "prefix_0f" "1")
13973 (set_attr "prefix_rep" "1")
13974 (set_attr "mode" "<MODE>")])
13976 (define_insn "<lt_zcnt>_hi"
13977 [(set (match_operand:HI 0 "register_operand" "=r")
13979 [(match_operand:HI 1 "nonimmediate_operand" "rm")] LT_ZCNT))
13980 (clobber (reg:CC FLAGS_REG))]
13982 "<lt_zcnt>{w}\t{%1, %0|%0, %1}"
13983 [(set_attr "type" "<lt_zcnt_type>")
13984 (set_attr "prefix_0f" "1")
13985 (set_attr "prefix_rep" "1")
13986 (set_attr "mode" "HI")])
13988 ;; BMI instructions.
13990 (define_insn "bmi_bextr_<mode>"
13991 [(set (match_operand:SWI48 0 "register_operand" "=r,r")
13992 (unspec:SWI48 [(match_operand:SWI48 1 "nonimmediate_operand" "r,m")
13993 (match_operand:SWI48 2 "register_operand" "r,r")]
13995 (clobber (reg:CC FLAGS_REG))]
13997 "bextr\t{%2, %1, %0|%0, %1, %2}"
13998 [(set_attr "type" "bitmanip")
13999 (set_attr "btver2_decode" "direct, double")
14000 (set_attr "mode" "<MODE>")])
14002 (define_insn "*bmi_bextr_<mode>_ccz"
14003 [(set (reg:CCZ FLAGS_REG)
14005 (unspec:SWI48 [(match_operand:SWI48 1 "nonimmediate_operand" "r,m")
14006 (match_operand:SWI48 2 "register_operand" "r,r")]
14009 (clobber (match_scratch:SWI48 0 "=r,r"))]
14011 "bextr\t{%2, %1, %0|%0, %1, %2}"
14012 [(set_attr "type" "bitmanip")
14013 (set_attr "btver2_decode" "direct, double")
14014 (set_attr "mode" "<MODE>")])
14016 (define_insn "*bmi_blsi_<mode>"
14017 [(set (match_operand:SWI48 0 "register_operand" "=r")
14020 (match_operand:SWI48 1 "nonimmediate_operand" "rm"))
14022 (clobber (reg:CC FLAGS_REG))]
14024 "blsi\t{%1, %0|%0, %1}"
14025 [(set_attr "type" "bitmanip")
14026 (set_attr "btver2_decode" "double")
14027 (set_attr "mode" "<MODE>")])
14029 (define_insn "*bmi_blsmsk_<mode>"
14030 [(set (match_operand:SWI48 0 "register_operand" "=r")
14033 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
14036 (clobber (reg:CC FLAGS_REG))]
14038 "blsmsk\t{%1, %0|%0, %1}"
14039 [(set_attr "type" "bitmanip")
14040 (set_attr "btver2_decode" "double")
14041 (set_attr "mode" "<MODE>")])
14043 (define_insn "*bmi_blsr_<mode>"
14044 [(set (match_operand:SWI48 0 "register_operand" "=r")
14047 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
14050 (clobber (reg:CC FLAGS_REG))]
14052 "blsr\t{%1, %0|%0, %1}"
14053 [(set_attr "type" "bitmanip")
14054 (set_attr "btver2_decode" "double")
14055 (set_attr "mode" "<MODE>")])
14057 (define_insn "*bmi_blsr_<mode>_cmp"
14058 [(set (reg:CCZ FLAGS_REG)
14062 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
14066 (set (match_operand:SWI48 0 "register_operand" "=r")
14073 "blsr\t{%1, %0|%0, %1}"
14074 [(set_attr "type" "bitmanip")
14075 (set_attr "btver2_decode" "double")
14076 (set_attr "mode" "<MODE>")])
14078 (define_insn "*bmi_blsr_<mode>_ccz"
14079 [(set (reg:CCZ FLAGS_REG)
14083 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
14087 (clobber (match_scratch:SWI48 0 "=r"))]
14089 "blsr\t{%1, %0|%0, %1}"
14090 [(set_attr "type" "bitmanip")
14091 (set_attr "btver2_decode" "double")
14092 (set_attr "mode" "<MODE>")])
14094 ;; BMI2 instructions.
14095 (define_expand "bmi2_bzhi_<mode>3"
14097 [(set (match_operand:SWI48 0 "register_operand")
14098 (zero_extract:SWI48
14099 (match_operand:SWI48 1 "nonimmediate_operand")
14101 (and:SWI48 (match_operand:SWI48 2 "register_operand")
14105 (clobber (reg:CC FLAGS_REG))])]
14107 "operands[3] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT);")
14109 (define_insn "*bmi2_bzhi_<mode>3"
14110 [(set (match_operand:SWI48 0 "register_operand" "=r")
14111 (zero_extract:SWI48
14112 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
14114 (and:SWI48 (match_operand:SWI48 2 "register_operand" "r")
14116 (match_operand:SWI48 3 "const_int_operand" "n"))
14118 (clobber (reg:CC FLAGS_REG))]
14119 "TARGET_BMI2 && INTVAL (operands[3]) == <MODE_SIZE> * BITS_PER_UNIT"
14120 "bzhi\t{%2, %1, %0|%0, %1, %2}"
14121 [(set_attr "type" "bitmanip")
14122 (set_attr "prefix" "vex")
14123 (set_attr "mode" "<MODE>")])
14125 (define_insn "*bmi2_bzhi_<mode>3_1"
14126 [(set (match_operand:SWI48 0 "register_operand" "=r")
14127 (zero_extract:SWI48
14128 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
14130 (zero_extend:SWI48 (match_operand:QI 2 "register_operand" "r"))
14131 (match_operand:SWI48 3 "const_int_operand" "n"))
14133 (clobber (reg:CC FLAGS_REG))]
14134 "TARGET_BMI2 && INTVAL (operands[3]) == <MODE_SIZE> * BITS_PER_UNIT"
14135 "bzhi\t{%<k>2, %1, %0|%0, %1, %<k>2}"
14136 [(set_attr "type" "bitmanip")
14137 (set_attr "prefix" "vex")
14138 (set_attr "mode" "<MODE>")])
14140 (define_insn "*bmi2_bzhi_<mode>3_1_ccz"
14141 [(set (reg:CCZ FLAGS_REG)
14143 (zero_extract:SWI48
14144 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
14146 (zero_extend:SWI48 (match_operand:QI 2 "register_operand" "r"))
14147 (match_operand:SWI48 3 "const_int_operand" "n"))
14150 (clobber (match_scratch:SWI48 0 "=r"))]
14151 "TARGET_BMI2 && INTVAL (operands[3]) == <MODE_SIZE> * BITS_PER_UNIT"
14152 "bzhi\t{%<k>2, %1, %0|%0, %1, %<k>2}"
14153 [(set_attr "type" "bitmanip")
14154 (set_attr "prefix" "vex")
14155 (set_attr "mode" "<MODE>")])
14157 (define_insn "bmi2_pdep_<mode>3"
14158 [(set (match_operand:SWI48 0 "register_operand" "=r")
14159 (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
14160 (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
14163 "pdep\t{%2, %1, %0|%0, %1, %2}"
14164 [(set_attr "type" "bitmanip")
14165 (set_attr "prefix" "vex")
14166 (set_attr "mode" "<MODE>")])
14168 (define_insn "bmi2_pext_<mode>3"
14169 [(set (match_operand:SWI48 0 "register_operand" "=r")
14170 (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
14171 (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
14174 "pext\t{%2, %1, %0|%0, %1, %2}"
14175 [(set_attr "type" "bitmanip")
14176 (set_attr "prefix" "vex")
14177 (set_attr "mode" "<MODE>")])
14179 ;; TBM instructions.
14180 (define_insn "tbm_bextri_<mode>"
14181 [(set (match_operand:SWI48 0 "register_operand" "=r")
14182 (zero_extract:SWI48
14183 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
14184 (match_operand 2 "const_0_to_255_operand" "N")
14185 (match_operand 3 "const_0_to_255_operand" "N")))
14186 (clobber (reg:CC FLAGS_REG))]
14189 operands[2] = GEN_INT (INTVAL (operands[2]) << 8 | INTVAL (operands[3]));
14190 return "bextr\t{%2, %1, %0|%0, %1, %2}";
14192 [(set_attr "type" "bitmanip")
14193 (set_attr "mode" "<MODE>")])
14195 (define_insn "*tbm_blcfill_<mode>"
14196 [(set (match_operand:SWI48 0 "register_operand" "=r")
14199 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
14202 (clobber (reg:CC FLAGS_REG))]
14204 "blcfill\t{%1, %0|%0, %1}"
14205 [(set_attr "type" "bitmanip")
14206 (set_attr "mode" "<MODE>")])
14208 (define_insn "*tbm_blci_<mode>"
14209 [(set (match_operand:SWI48 0 "register_operand" "=r")
14213 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
14216 (clobber (reg:CC FLAGS_REG))]
14218 "blci\t{%1, %0|%0, %1}"
14219 [(set_attr "type" "bitmanip")
14220 (set_attr "mode" "<MODE>")])
14222 (define_insn "*tbm_blcic_<mode>"
14223 [(set (match_operand:SWI48 0 "register_operand" "=r")
14226 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
14230 (clobber (reg:CC FLAGS_REG))]
14232 "blcic\t{%1, %0|%0, %1}"
14233 [(set_attr "type" "bitmanip")
14234 (set_attr "mode" "<MODE>")])
14236 (define_insn "*tbm_blcmsk_<mode>"
14237 [(set (match_operand:SWI48 0 "register_operand" "=r")
14240 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
14243 (clobber (reg:CC FLAGS_REG))]
14245 "blcmsk\t{%1, %0|%0, %1}"
14246 [(set_attr "type" "bitmanip")
14247 (set_attr "mode" "<MODE>")])
14249 (define_insn "*tbm_blcs_<mode>"
14250 [(set (match_operand:SWI48 0 "register_operand" "=r")
14253 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
14256 (clobber (reg:CC FLAGS_REG))]
14258 "blcs\t{%1, %0|%0, %1}"
14259 [(set_attr "type" "bitmanip")
14260 (set_attr "mode" "<MODE>")])
14262 (define_insn "*tbm_blsfill_<mode>"
14263 [(set (match_operand:SWI48 0 "register_operand" "=r")
14266 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
14269 (clobber (reg:CC FLAGS_REG))]
14271 "blsfill\t{%1, %0|%0, %1}"
14272 [(set_attr "type" "bitmanip")
14273 (set_attr "mode" "<MODE>")])
14275 (define_insn "*tbm_blsic_<mode>"
14276 [(set (match_operand:SWI48 0 "register_operand" "=r")
14279 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
14283 (clobber (reg:CC FLAGS_REG))]
14285 "blsic\t{%1, %0|%0, %1}"
14286 [(set_attr "type" "bitmanip")
14287 (set_attr "mode" "<MODE>")])
14289 (define_insn "*tbm_t1mskc_<mode>"
14290 [(set (match_operand:SWI48 0 "register_operand" "=r")
14293 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
14297 (clobber (reg:CC FLAGS_REG))]
14299 "t1mskc\t{%1, %0|%0, %1}"
14300 [(set_attr "type" "bitmanip")
14301 (set_attr "mode" "<MODE>")])
14303 (define_insn "*tbm_tzmsk_<mode>"
14304 [(set (match_operand:SWI48 0 "register_operand" "=r")
14307 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
14311 (clobber (reg:CC FLAGS_REG))]
14313 "tzmsk\t{%1, %0|%0, %1}"
14314 [(set_attr "type" "bitmanip")
14315 (set_attr "mode" "<MODE>")])
14317 (define_insn_and_split "popcount<mode>2"
14318 [(set (match_operand:SWI48 0 "register_operand" "=r")
14320 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
14321 (clobber (reg:CC FLAGS_REG))]
14325 return "popcnt\t{%1, %0|%0, %1}";
14327 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
14330 "&& TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
14331 && optimize_function_for_speed_p (cfun)
14332 && !reg_mentioned_p (operands[0], operands[1])"
14334 [(set (match_dup 0)
14335 (popcount:SWI48 (match_dup 1)))
14336 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
14337 (clobber (reg:CC FLAGS_REG))])]
14338 "ix86_expand_clear (operands[0]);"
14339 [(set_attr "prefix_rep" "1")
14340 (set_attr "type" "bitmanip")
14341 (set_attr "mode" "<MODE>")])
14343 ; False dependency happens when destination is only updated by tzcnt,
14344 ; lzcnt or popcnt. There is no false dependency when destination is
14345 ; also used in source.
14346 (define_insn "*popcount<mode>2_falsedep"
14347 [(set (match_operand:SWI48 0 "register_operand" "=r")
14349 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
14350 (unspec [(match_operand:SWI48 2 "register_operand" "0")]
14351 UNSPEC_INSN_FALSE_DEP)
14352 (clobber (reg:CC FLAGS_REG))]
14356 return "popcnt\t{%1, %0|%0, %1}";
14358 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
14361 [(set_attr "prefix_rep" "1")
14362 (set_attr "type" "bitmanip")
14363 (set_attr "mode" "<MODE>")])
14365 (define_insn_and_split "*popcounthi2_1"
14366 [(set (match_operand:SI 0 "register_operand")
14368 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand"))))
14369 (clobber (reg:CC FLAGS_REG))]
14371 && can_create_pseudo_p ()"
14376 rtx tmp = gen_reg_rtx (HImode);
14378 emit_insn (gen_popcounthi2 (tmp, operands[1]));
14379 emit_insn (gen_zero_extendhisi2 (operands[0], tmp));
14383 (define_insn "popcounthi2"
14384 [(set (match_operand:HI 0 "register_operand" "=r")
14386 (match_operand:HI 1 "nonimmediate_operand" "rm")))
14387 (clobber (reg:CC FLAGS_REG))]
14391 return "popcnt\t{%1, %0|%0, %1}";
14393 return "popcnt{w}\t{%1, %0|%0, %1}";
14396 [(set_attr "prefix_rep" "1")
14397 (set_attr "type" "bitmanip")
14398 (set_attr "mode" "HI")])
14400 (define_expand "bswapdi2"
14401 [(set (match_operand:DI 0 "register_operand")
14402 (bswap:DI (match_operand:DI 1 "nonimmediate_operand")))]
14406 operands[1] = force_reg (DImode, operands[1]);
14409 (define_expand "bswapsi2"
14410 [(set (match_operand:SI 0 "register_operand")
14411 (bswap:SI (match_operand:SI 1 "nonimmediate_operand")))]
14416 else if (TARGET_BSWAP)
14417 operands[1] = force_reg (SImode, operands[1]);
14420 rtx x = operands[0];
14422 emit_move_insn (x, operands[1]);
14423 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
14424 emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
14425 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
14430 (define_insn "*bswap<mode>2_movbe"
14431 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,r,m")
14432 (bswap:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,m,r")))]
14434 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
14437 movbe{<imodesuffix>}\t{%1, %0|%0, %1}
14438 movbe{<imodesuffix>}\t{%1, %0|%0, %1}"
14439 [(set_attr "type" "bitmanip,imov,imov")
14440 (set_attr "modrm" "0,1,1")
14441 (set_attr "prefix_0f" "*,1,1")
14442 (set_attr "prefix_extra" "*,1,1")
14443 (set_attr "mode" "<MODE>")])
14445 (define_insn "*bswap<mode>2"
14446 [(set (match_operand:SWI48 0 "register_operand" "=r")
14447 (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "0")))]
14450 [(set_attr "type" "bitmanip")
14451 (set_attr "modrm" "0")
14452 (set_attr "mode" "<MODE>")])
14454 (define_expand "bswaphi2"
14455 [(set (match_operand:HI 0 "register_operand")
14456 (bswap:HI (match_operand:HI 1 "nonimmediate_operand")))]
14459 (define_insn "*bswaphi2_movbe"
14460 [(set (match_operand:HI 0 "nonimmediate_operand" "=Q,r,m")
14461 (bswap:HI (match_operand:HI 1 "nonimmediate_operand" "0,m,r")))]
14463 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
14465 xchg{b}\t{%h0, %b0|%b0, %h0}
14466 movbe{w}\t{%1, %0|%0, %1}
14467 movbe{w}\t{%1, %0|%0, %1}"
14468 [(set_attr "type" "imov")
14469 (set_attr "modrm" "*,1,1")
14470 (set_attr "prefix_0f" "*,1,1")
14471 (set_attr "prefix_extra" "*,1,1")
14472 (set_attr "pent_pair" "np,*,*")
14473 (set_attr "athlon_decode" "vector,*,*")
14474 (set_attr "amdfam10_decode" "double,*,*")
14475 (set_attr "bdver1_decode" "double,*,*")
14476 (set_attr "mode" "QI,HI,HI")])
14479 [(set (match_operand:HI 0 "general_reg_operand")
14480 (bswap:HI (match_dup 0)))]
14482 && !(TARGET_USE_XCHGB || optimize_function_for_size_p (cfun))
14483 && peep2_regno_dead_p (0, FLAGS_REG)"
14484 [(parallel [(set (match_dup 0) (rotate:HI (match_dup 0) (const_int 8)))
14485 (clobber (reg:CC FLAGS_REG))])])
14487 (define_insn "bswaphi_lowpart"
14488 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
14489 (bswap:HI (match_dup 0)))
14490 (clobber (reg:CC FLAGS_REG))]
14493 xchg{b}\t{%h0, %b0|%b0, %h0}
14494 rol{w}\t{$8, %0|%0, 8}"
14495 [(set (attr "preferred_for_size")
14496 (cond [(eq_attr "alternative" "0")
14497 (symbol_ref "true")]
14498 (symbol_ref "false")))
14499 (set (attr "preferred_for_speed")
14500 (cond [(eq_attr "alternative" "0")
14501 (symbol_ref "TARGET_USE_XCHGB")]
14502 (symbol_ref "!TARGET_USE_XCHGB")))
14503 (set_attr "length" "2,4")
14504 (set_attr "mode" "QI,HI")])
14506 (define_expand "paritydi2"
14507 [(set (match_operand:DI 0 "register_operand")
14508 (parity:DI (match_operand:DI 1 "register_operand")))]
14511 rtx scratch = gen_reg_rtx (QImode);
14513 emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX,
14514 NULL_RTX, operands[1]));
14516 ix86_expand_setcc (scratch, ORDERED,
14517 gen_rtx_REG (CCmode, FLAGS_REG), const0_rtx);
14520 emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
14523 rtx tmp = gen_reg_rtx (SImode);
14525 emit_insn (gen_zero_extendqisi2 (tmp, scratch));
14526 emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
14531 (define_expand "paritysi2"
14532 [(set (match_operand:SI 0 "register_operand")
14533 (parity:SI (match_operand:SI 1 "register_operand")))]
14536 rtx scratch = gen_reg_rtx (QImode);
14538 emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1]));
14540 ix86_expand_setcc (scratch, ORDERED,
14541 gen_rtx_REG (CCmode, FLAGS_REG), const0_rtx);
14543 emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
14547 (define_insn_and_split "paritydi2_cmp"
14548 [(set (reg:CC FLAGS_REG)
14549 (unspec:CC [(match_operand:DI 3 "register_operand" "0")]
14551 (clobber (match_scratch:DI 0 "=r"))
14552 (clobber (match_scratch:SI 1 "=&r"))
14553 (clobber (match_scratch:HI 2 "=Q"))]
14556 "&& reload_completed"
14558 [(set (match_dup 1)
14559 (xor:SI (match_dup 1) (match_dup 4)))
14560 (clobber (reg:CC FLAGS_REG))])
14562 [(set (reg:CC FLAGS_REG)
14563 (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
14564 (clobber (match_dup 1))
14565 (clobber (match_dup 2))])]
14567 operands[4] = gen_lowpart (SImode, operands[3]);
14571 emit_move_insn (operands[1], gen_lowpart (SImode, operands[3]));
14572 emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32)));
14575 operands[1] = gen_highpart (SImode, operands[3]);
14578 (define_insn_and_split "paritysi2_cmp"
14579 [(set (reg:CC FLAGS_REG)
14580 (unspec:CC [(match_operand:SI 2 "register_operand" "0")]
14582 (clobber (match_scratch:SI 0 "=r"))
14583 (clobber (match_scratch:HI 1 "=&Q"))]
14586 "&& reload_completed"
14588 [(set (match_dup 1)
14589 (xor:HI (match_dup 1) (match_dup 3)))
14590 (clobber (reg:CC FLAGS_REG))])
14592 [(set (reg:CC FLAGS_REG)
14593 (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
14594 (clobber (match_dup 1))])]
14596 operands[3] = gen_lowpart (HImode, operands[2]);
14598 emit_move_insn (operands[1], gen_lowpart (HImode, operands[2]));
14599 emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16)));
14602 (define_insn "*parityhi2_cmp"
14603 [(set (reg:CC FLAGS_REG)
14604 (unspec:CC [(match_operand:HI 1 "register_operand" "0")]
14606 (clobber (match_scratch:HI 0 "=Q"))]
14608 "xor{b}\t{%h0, %b0|%b0, %h0}"
14609 [(set_attr "length" "2")
14610 (set_attr "mode" "HI")])
14613 ;; Thread-local storage patterns for ELF.
14615 ;; Note that these code sequences must appear exactly as shown
14616 ;; in order to allow linker relaxation.
14618 (define_insn "*tls_global_dynamic_32_gnu"
14619 [(set (match_operand:SI 0 "register_operand" "=a")
14621 [(match_operand:SI 1 "register_operand" "Yb")
14622 (match_operand 2 "tls_symbolic_operand")
14623 (match_operand 3 "constant_call_address_operand" "Bz")
14626 (clobber (match_scratch:SI 4 "=d"))
14627 (clobber (match_scratch:SI 5 "=c"))
14628 (clobber (reg:CC FLAGS_REG))]
14629 "!TARGET_64BIT && TARGET_GNU_TLS"
14631 if (TARGET_SUN_TLS || flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT)
14633 ("lea{l}\t{%E2@tlsgd(,%1,1), %0|%0, %E2@tlsgd[%1*1]}", operands);
14636 ("lea{l}\t{%E2@tlsgd(%1), %0|%0, %E2@tlsgd[%1]}", operands);
14637 if (TARGET_SUN_TLS)
14638 #ifdef HAVE_AS_IX86_TLSGDPLT
14639 return "call\t%a2@tlsgdplt";
14641 return "call\t%p3@plt";
14643 if (flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT)
14644 return "call\t%P3";
14645 return "call\t{*%p3@GOT(%1)|[DWORD PTR %p3@GOT[%1]]}";
14647 [(set_attr "type" "multi")
14648 (set_attr "length" "12")])
14650 (define_expand "tls_global_dynamic_32"
14652 [(set (match_operand:SI 0 "register_operand")
14653 (unspec:SI [(match_operand:SI 2 "register_operand")
14654 (match_operand 1 "tls_symbolic_operand")
14655 (match_operand 3 "constant_call_address_operand")
14658 (clobber (match_scratch:SI 4))
14659 (clobber (match_scratch:SI 5))
14660 (clobber (reg:CC FLAGS_REG))])]
14662 "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
14664 (define_insn "*tls_global_dynamic_64_<mode>"
14665 [(set (match_operand:P 0 "register_operand" "=a")
14667 (mem:QI (match_operand 2 "constant_call_address_operand" "Bz"))
14668 (match_operand 3)))
14669 (unspec:P [(match_operand 1 "tls_symbolic_operand")
14675 fputs (ASM_BYTE "0x66\n", asm_out_file);
14677 ("lea{q}\t{%E1@tlsgd(%%rip), %%rdi|rdi, %E1@tlsgd[rip]}", operands);
14678 if (TARGET_SUN_TLS || flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT)
14679 fputs (ASM_SHORT "0x6666\n", asm_out_file);
14681 fputs (ASM_BYTE "0x66\n", asm_out_file);
14682 fputs ("\trex64\n", asm_out_file);
14683 if (TARGET_SUN_TLS)
14684 return "call\t%p2@plt";
14685 if (flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT)
14686 return "call\t%P2";
14687 return "call\t{*%p2@GOTPCREL(%%rip)|[QWORD PTR %p2@GOTPCREL[rip]]}";
14689 [(set_attr "type" "multi")
14690 (set (attr "length")
14691 (symbol_ref "TARGET_X32 ? 15 : 16"))])
14693 (define_insn "*tls_global_dynamic_64_largepic"
14694 [(set (match_operand:DI 0 "register_operand" "=a")
14696 (mem:QI (plus:DI (match_operand:DI 2 "register_operand" "b")
14697 (match_operand:DI 3 "immediate_operand" "i")))
14698 (match_operand 4)))
14699 (unspec:DI [(match_operand 1 "tls_symbolic_operand")
14702 "TARGET_64BIT && ix86_cmodel == CM_LARGE_PIC && !TARGET_PECOFF
14703 && GET_CODE (operands[3]) == CONST
14704 && GET_CODE (XEXP (operands[3], 0)) == UNSPEC
14705 && XINT (XEXP (operands[3], 0), 1) == UNSPEC_PLTOFF"
14708 ("lea{q}\t{%E1@tlsgd(%%rip), %%rdi|rdi, %E1@tlsgd[rip]}", operands);
14709 output_asm_insn ("movabs{q}\t{%3, %%rax|rax, %3}", operands);
14710 output_asm_insn ("add{q}\t{%2, %%rax|rax, %2}", operands);
14711 return "call\t{*%%rax|rax}";
14713 [(set_attr "type" "multi")
14714 (set_attr "length" "22")])
14716 (define_expand "tls_global_dynamic_64_<mode>"
14718 [(set (match_operand:P 0 "register_operand")
14720 (mem:QI (match_operand 2))
14722 (unspec:P [(match_operand 1 "tls_symbolic_operand")
14726 "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
14728 (define_insn "*tls_local_dynamic_base_32_gnu"
14729 [(set (match_operand:SI 0 "register_operand" "=a")
14731 [(match_operand:SI 1 "register_operand" "Yb")
14732 (match_operand 2 "constant_call_address_operand" "Bz")
14734 UNSPEC_TLS_LD_BASE))
14735 (clobber (match_scratch:SI 3 "=d"))
14736 (clobber (match_scratch:SI 4 "=c"))
14737 (clobber (reg:CC FLAGS_REG))]
14738 "!TARGET_64BIT && TARGET_GNU_TLS"
14741 ("lea{l}\t{%&@tlsldm(%1), %0|%0, %&@tlsldm[%1]}", operands);
14742 if (TARGET_SUN_TLS)
14744 if (HAVE_AS_IX86_TLSLDMPLT)
14745 return "call\t%&@tlsldmplt";
14747 return "call\t%p2@plt";
14749 if (flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT)
14750 return "call\t%P2";
14751 return "call\t{*%p2@GOT(%1)|[DWORD PTR %p2@GOT[%1]]}";
14753 [(set_attr "type" "multi")
14754 (set_attr "length" "11")])
14756 (define_expand "tls_local_dynamic_base_32"
14758 [(set (match_operand:SI 0 "register_operand")
14760 [(match_operand:SI 1 "register_operand")
14761 (match_operand 2 "constant_call_address_operand")
14763 UNSPEC_TLS_LD_BASE))
14764 (clobber (match_scratch:SI 3))
14765 (clobber (match_scratch:SI 4))
14766 (clobber (reg:CC FLAGS_REG))])]
14768 "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
14770 (define_insn "*tls_local_dynamic_base_64_<mode>"
14771 [(set (match_operand:P 0 "register_operand" "=a")
14773 (mem:QI (match_operand 1 "constant_call_address_operand" "Bz"))
14774 (match_operand 2)))
14775 (unspec:P [(reg:P SP_REG)] UNSPEC_TLS_LD_BASE)]
14779 ("lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}", operands);
14780 if (TARGET_SUN_TLS)
14781 return "call\t%p1@plt";
14782 if (flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT)
14783 return "call\t%P1";
14784 return "call\t{*%p1@GOTPCREL(%%rip)|[QWORD PTR %p1@GOTPCREL[rip]]}";
14786 [(set_attr "type" "multi")
14787 (set_attr "length" "12")])
14789 (define_insn "*tls_local_dynamic_base_64_largepic"
14790 [(set (match_operand:DI 0 "register_operand" "=a")
14792 (mem:QI (plus:DI (match_operand:DI 1 "register_operand" "b")
14793 (match_operand:DI 2 "immediate_operand" "i")))
14794 (match_operand 3)))
14795 (unspec:DI [(reg:DI SP_REG)] UNSPEC_TLS_LD_BASE)]
14796 "TARGET_64BIT && ix86_cmodel == CM_LARGE_PIC && !TARGET_PECOFF
14797 && GET_CODE (operands[2]) == CONST
14798 && GET_CODE (XEXP (operands[2], 0)) == UNSPEC
14799 && XINT (XEXP (operands[2], 0), 1) == UNSPEC_PLTOFF"
14802 ("lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}", operands);
14803 output_asm_insn ("movabs{q}\t{%2, %%rax|rax, %2}", operands);
14804 output_asm_insn ("add{q}\t{%1, %%rax|rax, %1}", operands);
14805 return "call\t{*%%rax|rax}";
14807 [(set_attr "type" "multi")
14808 (set_attr "length" "22")])
14810 (define_expand "tls_local_dynamic_base_64_<mode>"
14812 [(set (match_operand:P 0 "register_operand")
14814 (mem:QI (match_operand 1))
14816 (unspec:P [(reg:P SP_REG)] UNSPEC_TLS_LD_BASE)])]
14818 "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
14820 ;; Local dynamic of a single variable is a lose. Show combine how
14821 ;; to convert that back to global dynamic.
14823 (define_insn_and_split "*tls_local_dynamic_32_once"
14824 [(set (match_operand:SI 0 "register_operand" "=a")
14826 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14827 (match_operand 2 "constant_call_address_operand" "Bz")
14829 UNSPEC_TLS_LD_BASE)
14830 (const:SI (unspec:SI
14831 [(match_operand 3 "tls_symbolic_operand")]
14833 (clobber (match_scratch:SI 4 "=d"))
14834 (clobber (match_scratch:SI 5 "=c"))
14835 (clobber (reg:CC FLAGS_REG))]
14840 [(set (match_dup 0)
14841 (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)
14844 (clobber (match_dup 4))
14845 (clobber (match_dup 5))
14846 (clobber (reg:CC FLAGS_REG))])])
14848 ;; Load and add the thread base pointer from %<tp_seg>:0.
14849 (define_insn_and_split "*load_tp_<mode>"
14850 [(set (match_operand:PTR 0 "register_operand" "=r")
14851 (unspec:PTR [(const_int 0)] UNSPEC_TP))]
14855 [(set (match_dup 0)
14858 addr_space_t as = DEFAULT_TLS_SEG_REG;
14860 operands[1] = gen_const_mem (<MODE>mode, const0_rtx);
14861 set_mem_addr_space (operands[1], as);
14864 (define_insn_and_split "*load_tp_x32_zext"
14865 [(set (match_operand:DI 0 "register_operand" "=r")
14867 (unspec:SI [(const_int 0)] UNSPEC_TP)))]
14871 [(set (match_dup 0)
14872 (zero_extend:DI (match_dup 1)))]
14874 addr_space_t as = DEFAULT_TLS_SEG_REG;
14876 operands[1] = gen_const_mem (SImode, const0_rtx);
14877 set_mem_addr_space (operands[1], as);
14880 (define_insn_and_split "*add_tp_<mode>"
14881 [(set (match_operand:PTR 0 "register_operand" "=r")
14883 (unspec:PTR [(const_int 0)] UNSPEC_TP)
14884 (match_operand:PTR 1 "register_operand" "0")))
14885 (clobber (reg:CC FLAGS_REG))]
14890 [(set (match_dup 0)
14891 (plus:PTR (match_dup 1) (match_dup 2)))
14892 (clobber (reg:CC FLAGS_REG))])]
14894 addr_space_t as = DEFAULT_TLS_SEG_REG;
14896 operands[2] = gen_const_mem (<MODE>mode, const0_rtx);
14897 set_mem_addr_space (operands[2], as);
14900 (define_insn_and_split "*add_tp_x32_zext"
14901 [(set (match_operand:DI 0 "register_operand" "=r")
14903 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
14904 (match_operand:SI 1 "register_operand" "0"))))
14905 (clobber (reg:CC FLAGS_REG))]
14910 [(set (match_dup 0)
14912 (plus:SI (match_dup 1) (match_dup 2))))
14913 (clobber (reg:CC FLAGS_REG))])]
14915 addr_space_t as = DEFAULT_TLS_SEG_REG;
14917 operands[2] = gen_const_mem (SImode, const0_rtx);
14918 set_mem_addr_space (operands[2], as);
14921 ;; The Sun linker took the AMD64 TLS spec literally and can only handle
14922 ;; %rax as destination of the initial executable code sequence.
14923 (define_insn "tls_initial_exec_64_sun"
14924 [(set (match_operand:DI 0 "register_operand" "=a")
14926 [(match_operand 1 "tls_symbolic_operand")]
14927 UNSPEC_TLS_IE_SUN))
14928 (clobber (reg:CC FLAGS_REG))]
14929 "TARGET_64BIT && TARGET_SUN_TLS"
14932 ("mov{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}", operands);
14933 return "add{q}\t{%a1@gottpoff(%%rip), %0|%0, %a1@gottpoff[rip]}";
14935 [(set_attr "type" "multi")])
14937 ;; GNU2 TLS patterns can be split.
14939 (define_expand "tls_dynamic_gnu2_32"
14940 [(set (match_dup 3)
14941 (plus:SI (match_operand:SI 2 "register_operand")
14943 (unspec:SI [(match_operand 1 "tls_symbolic_operand")]
14946 [(set (match_operand:SI 0 "register_operand")
14947 (unspec:SI [(match_dup 1) (match_dup 3)
14948 (match_dup 2) (reg:SI SP_REG)]
14950 (clobber (reg:CC FLAGS_REG))])]
14951 "!TARGET_64BIT && TARGET_GNU2_TLS"
14953 operands[3] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
14954 ix86_tls_descriptor_calls_expanded_in_cfun = true;
14957 (define_insn "*tls_dynamic_gnu2_lea_32"
14958 [(set (match_operand:SI 0 "register_operand" "=r")
14959 (plus:SI (match_operand:SI 1 "register_operand" "b")
14961 (unspec:SI [(match_operand 2 "tls_symbolic_operand")]
14962 UNSPEC_TLSDESC))))]
14963 "!TARGET_64BIT && TARGET_GNU2_TLS"
14964 "lea{l}\t{%E2@TLSDESC(%1), %0|%0, %E2@TLSDESC[%1]}"
14965 [(set_attr "type" "lea")
14966 (set_attr "mode" "SI")
14967 (set_attr "length" "6")
14968 (set_attr "length_address" "4")])
14970 (define_insn "*tls_dynamic_gnu2_call_32"
14971 [(set (match_operand:SI 0 "register_operand" "=a")
14972 (unspec:SI [(match_operand 1 "tls_symbolic_operand")
14973 (match_operand:SI 2 "register_operand" "0")
14974 ;; we have to make sure %ebx still points to the GOT
14975 (match_operand:SI 3 "register_operand" "b")
14978 (clobber (reg:CC FLAGS_REG))]
14979 "!TARGET_64BIT && TARGET_GNU2_TLS"
14980 "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
14981 [(set_attr "type" "call")
14982 (set_attr "length" "2")
14983 (set_attr "length_address" "0")])
14985 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
14986 [(set (match_operand:SI 0 "register_operand" "=&a")
14988 (unspec:SI [(match_operand 3 "tls_modbase_operand")
14989 (match_operand:SI 4)
14990 (match_operand:SI 2 "register_operand" "b")
14993 (const:SI (unspec:SI
14994 [(match_operand 1 "tls_symbolic_operand")]
14996 (clobber (reg:CC FLAGS_REG))]
14997 "!TARGET_64BIT && TARGET_GNU2_TLS"
15000 [(set (match_dup 0) (match_dup 5))]
15002 operands[5] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
15003 emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
15006 (define_expand "tls_dynamic_gnu2_64"
15007 [(set (match_dup 2)
15008 (unspec:DI [(match_operand 1 "tls_symbolic_operand")]
15011 [(set (match_operand:DI 0 "register_operand")
15012 (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
15014 (clobber (reg:CC FLAGS_REG))])]
15015 "TARGET_64BIT && TARGET_GNU2_TLS"
15017 operands[2] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
15018 ix86_tls_descriptor_calls_expanded_in_cfun = true;
15021 (define_insn "*tls_dynamic_gnu2_lea_64"
15022 [(set (match_operand:DI 0 "register_operand" "=r")
15023 (unspec:DI [(match_operand 1 "tls_symbolic_operand")]
15025 "TARGET_64BIT && TARGET_GNU2_TLS"
15026 "lea{q}\t{%E1@TLSDESC(%%rip), %0|%0, %E1@TLSDESC[rip]}"
15027 [(set_attr "type" "lea")
15028 (set_attr "mode" "DI")
15029 (set_attr "length" "7")
15030 (set_attr "length_address" "4")])
15032 (define_insn "*tls_dynamic_gnu2_call_64"
15033 [(set (match_operand:DI 0 "register_operand" "=a")
15034 (unspec:DI [(match_operand 1 "tls_symbolic_operand")
15035 (match_operand:DI 2 "register_operand" "0")
15038 (clobber (reg:CC FLAGS_REG))]
15039 "TARGET_64BIT && TARGET_GNU2_TLS"
15040 "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
15041 [(set_attr "type" "call")
15042 (set_attr "length" "2")
15043 (set_attr "length_address" "0")])
15045 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
15046 [(set (match_operand:DI 0 "register_operand" "=&a")
15048 (unspec:DI [(match_operand 2 "tls_modbase_operand")
15049 (match_operand:DI 3)
15052 (const:DI (unspec:DI
15053 [(match_operand 1 "tls_symbolic_operand")]
15055 (clobber (reg:CC FLAGS_REG))]
15056 "TARGET_64BIT && TARGET_GNU2_TLS"
15059 [(set (match_dup 0) (match_dup 4))]
15061 operands[4] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
15062 emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
15066 [(match_operand 0 "tls_address_pattern")]
15067 "TARGET_TLS_DIRECT_SEG_REFS"
15069 "operands[0] = ix86_rewrite_tls_address (operands[0]);")
15072 ;; These patterns match the binary 387 instructions for addM3, subM3,
15073 ;; mulM3 and divM3. There are three patterns for each of DFmode and
15074 ;; SFmode. The first is the normal insn, the second the same insn but
15075 ;; with one operand a conversion, and the third the same insn but with
15076 ;; the other operand a conversion. The conversion may be SFmode or
15077 ;; SImode if the target mode DFmode, but only SImode if the target mode
15080 ;; Gcc is slightly more smart about handling normal two address instructions
15081 ;; so use special patterns for add and mull.
15083 (define_insn "*fop_<mode>_comm"
15084 [(set (match_operand:MODEF 0 "register_operand" "=f,x,v")
15085 (match_operator:MODEF 3 "binary_fp_operator"
15086 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,0,v")
15087 (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm,vm")]))]
15088 "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15089 || (TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)))
15090 && COMMUTATIVE_ARITH_P (operands[3])
15091 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15092 "* return output_387_binary_op (insn, operands);"
15093 [(set (attr "type")
15094 (if_then_else (eq_attr "alternative" "1,2")
15095 (if_then_else (match_operand:MODEF 3 "mult_operator")
15096 (const_string "ssemul")
15097 (const_string "sseadd"))
15098 (if_then_else (match_operand:MODEF 3 "mult_operator")
15099 (const_string "fmul")
15100 (const_string "fop"))))
15101 (set_attr "isa" "*,noavx,avx")
15102 (set_attr "prefix" "orig,orig,vex")
15103 (set_attr "mode" "<MODE>")
15104 (set (attr "enabled")
15106 (match_test ("SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"))
15108 (eq_attr "alternative" "0")
15109 (symbol_ref "TARGET_MIX_SSE_I387
15110 && X87_ENABLE_ARITH (<MODE>mode)")
15111 (const_string "*"))
15113 (eq_attr "alternative" "0")
15114 (symbol_ref "true")
15115 (symbol_ref "false"))))])
15117 (define_insn "*rcpsf2_sse"
15118 [(set (match_operand:SF 0 "register_operand" "=x")
15119 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
15121 "TARGET_SSE && TARGET_SSE_MATH"
15122 "%vrcpss\t{%1, %d0|%d0, %1}"
15123 [(set_attr "type" "sse")
15124 (set_attr "atom_sse_attr" "rcp")
15125 (set_attr "btver2_sse_attr" "rcp")
15126 (set_attr "prefix" "maybe_vex")
15127 (set_attr "mode" "SF")])
15129 (define_insn "*fop_<mode>_1"
15130 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,v")
15131 (match_operator:MODEF 3 "binary_fp_operator"
15132 [(match_operand:MODEF 1
15133 "x87nonimm_ssenomem_operand" "0,fm,0,v")
15134 (match_operand:MODEF 2
15135 "nonimmediate_operand" "fm,0,xm,vm")]))]
15136 "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15137 || (TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)))
15138 && !COMMUTATIVE_ARITH_P (operands[3])
15139 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15140 "* return output_387_binary_op (insn, operands);"
15141 [(set (attr "type")
15142 (if_then_else (eq_attr "alternative" "2,3")
15143 (if_then_else (match_operand:MODEF 3 "div_operator")
15144 (const_string "ssediv")
15145 (const_string "sseadd"))
15146 (if_then_else (match_operand:MODEF 3 "div_operator")
15147 (const_string "fdiv")
15148 (const_string "fop"))))
15149 (set_attr "isa" "*,*,noavx,avx")
15150 (set_attr "prefix" "orig,orig,orig,vex")
15151 (set_attr "mode" "<MODE>")
15152 (set (attr "enabled")
15154 (match_test ("SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"))
15156 (eq_attr "alternative" "0,1")
15157 (symbol_ref "TARGET_MIX_SSE_I387
15158 && X87_ENABLE_ARITH (<MODE>mode)")
15159 (const_string "*"))
15161 (eq_attr "alternative" "0,1")
15162 (symbol_ref "true")
15163 (symbol_ref "false"))))])
15165 ;; ??? Add SSE splitters for these!
15166 (define_insn "*fop_<MODEF:mode>_2_i387"
15167 [(set (match_operand:MODEF 0 "register_operand" "=f")
15168 (match_operator:MODEF 3 "binary_fp_operator"
15170 (match_operand:SWI24 1 "nonimmediate_operand" "m"))
15171 (match_operand:MODEF 2 "register_operand" "0")]))]
15172 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI24:MODE>mode)
15173 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
15174 && (TARGET_USE_<SWI24:MODE>MODE_FIOP
15175 || optimize_function_for_size_p (cfun))"
15176 "* return output_387_binary_op (insn, operands);"
15177 [(set (attr "type")
15178 (cond [(match_operand:MODEF 3 "mult_operator")
15179 (const_string "fmul")
15180 (match_operand:MODEF 3 "div_operator")
15181 (const_string "fdiv")
15183 (const_string "fop")))
15184 (set_attr "fp_int_src" "true")
15185 (set_attr "mode" "<SWI24:MODE>")])
15187 (define_insn "*fop_<MODEF:mode>_3_i387"
15188 [(set (match_operand:MODEF 0 "register_operand" "=f")
15189 (match_operator:MODEF 3 "binary_fp_operator"
15190 [(match_operand:MODEF 1 "register_operand" "0")
15192 (match_operand:SWI24 2 "nonimmediate_operand" "m"))]))]
15193 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI24:MODE>mode)
15194 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
15195 && (TARGET_USE_<SWI24:MODE>MODE_FIOP
15196 || optimize_function_for_size_p (cfun))"
15197 "* return output_387_binary_op (insn, operands);"
15198 [(set (attr "type")
15199 (cond [(match_operand:MODEF 3 "mult_operator")
15200 (const_string "fmul")
15201 (match_operand:MODEF 3 "div_operator")
15202 (const_string "fdiv")
15204 (const_string "fop")))
15205 (set_attr "fp_int_src" "true")
15206 (set_attr "mode" "<MODE>")])
15208 (define_insn "*fop_df_4_i387"
15209 [(set (match_operand:DF 0 "register_operand" "=f,f")
15210 (match_operator:DF 3 "binary_fp_operator"
15212 (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
15213 (match_operand:DF 2 "register_operand" "0,f")]))]
15214 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
15215 && !(SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
15216 "* return output_387_binary_op (insn, operands);"
15217 [(set (attr "type")
15218 (cond [(match_operand:DF 3 "mult_operator")
15219 (const_string "fmul")
15220 (match_operand:DF 3 "div_operator")
15221 (const_string "fdiv")
15223 (const_string "fop")))
15224 (set_attr "mode" "SF")])
15226 (define_insn "*fop_df_5_i387"
15227 [(set (match_operand:DF 0 "register_operand" "=f,f")
15228 (match_operator:DF 3 "binary_fp_operator"
15229 [(match_operand:DF 1 "register_operand" "0,f")
15231 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
15232 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
15233 && !(SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
15234 "* return output_387_binary_op (insn, operands);"
15235 [(set (attr "type")
15236 (cond [(match_operand:DF 3 "mult_operator")
15237 (const_string "fmul")
15238 (match_operand:DF 3 "div_operator")
15239 (const_string "fdiv")
15241 (const_string "fop")))
15242 (set_attr "mode" "SF")])
15244 (define_insn "*fop_df_6_i387"
15245 [(set (match_operand:DF 0 "register_operand" "=f,f")
15246 (match_operator:DF 3 "binary_fp_operator"
15248 (match_operand:SF 1 "register_operand" "0,f"))
15250 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
15251 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
15252 && !(SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
15253 "* return output_387_binary_op (insn, operands);"
15254 [(set (attr "type")
15255 (cond [(match_operand:DF 3 "mult_operator")
15256 (const_string "fmul")
15257 (match_operand:DF 3 "div_operator")
15258 (const_string "fdiv")
15260 (const_string "fop")))
15261 (set_attr "mode" "SF")])
15263 (define_insn "*fop_xf_comm_i387"
15264 [(set (match_operand:XF 0 "register_operand" "=f")
15265 (match_operator:XF 3 "binary_fp_operator"
15266 [(match_operand:XF 1 "register_operand" "%0")
15267 (match_operand:XF 2 "register_operand" "f")]))]
15269 && COMMUTATIVE_ARITH_P (operands[3])"
15270 "* return output_387_binary_op (insn, operands);"
15271 [(set (attr "type")
15272 (if_then_else (match_operand:XF 3 "mult_operator")
15273 (const_string "fmul")
15274 (const_string "fop")))
15275 (set_attr "mode" "XF")])
15277 (define_insn "*fop_xf_1_i387"
15278 [(set (match_operand:XF 0 "register_operand" "=f,f")
15279 (match_operator:XF 3 "binary_fp_operator"
15280 [(match_operand:XF 1 "register_operand" "0,f")
15281 (match_operand:XF 2 "register_operand" "f,0")]))]
15283 && !COMMUTATIVE_ARITH_P (operands[3])"
15284 "* return output_387_binary_op (insn, operands);"
15285 [(set (attr "type")
15286 (if_then_else (match_operand:XF 3 "div_operator")
15287 (const_string "fdiv")
15288 (const_string "fop")))
15289 (set_attr "mode" "XF")])
15291 (define_insn "*fop_xf_2_i387"
15292 [(set (match_operand:XF 0 "register_operand" "=f")
15293 (match_operator:XF 3 "binary_fp_operator"
15295 (match_operand:SWI24 1 "nonimmediate_operand" "m"))
15296 (match_operand:XF 2 "register_operand" "0")]))]
15298 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
15299 "* return output_387_binary_op (insn, operands);"
15300 [(set (attr "type")
15301 (cond [(match_operand:XF 3 "mult_operator")
15302 (const_string "fmul")
15303 (match_operand:XF 3 "div_operator")
15304 (const_string "fdiv")
15306 (const_string "fop")))
15307 (set_attr "fp_int_src" "true")
15308 (set_attr "mode" "<MODE>")])
15310 (define_insn "*fop_xf_3_i387"
15311 [(set (match_operand:XF 0 "register_operand" "=f")
15312 (match_operator:XF 3 "binary_fp_operator"
15313 [(match_operand:XF 1 "register_operand" "0")
15315 (match_operand:SWI24 2 "nonimmediate_operand" "m"))]))]
15317 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
15318 "* return output_387_binary_op (insn, operands);"
15319 [(set (attr "type")
15320 (cond [(match_operand:XF 3 "mult_operator")
15321 (const_string "fmul")
15322 (match_operand:XF 3 "div_operator")
15323 (const_string "fdiv")
15325 (const_string "fop")))
15326 (set_attr "fp_int_src" "true")
15327 (set_attr "mode" "<MODE>")])
15329 (define_insn "*fop_xf_4_i387"
15330 [(set (match_operand:XF 0 "register_operand" "=f,f")
15331 (match_operator:XF 3 "binary_fp_operator"
15333 (match_operand:MODEF 1 "nonimmediate_operand" "fm,0"))
15334 (match_operand:XF 2 "register_operand" "0,f")]))]
15336 "* return output_387_binary_op (insn, operands);"
15337 [(set (attr "type")
15338 (cond [(match_operand:XF 3 "mult_operator")
15339 (const_string "fmul")
15340 (match_operand:XF 3 "div_operator")
15341 (const_string "fdiv")
15343 (const_string "fop")))
15344 (set_attr "mode" "<MODE>")])
15346 (define_insn "*fop_xf_5_i387"
15347 [(set (match_operand:XF 0 "register_operand" "=f,f")
15348 (match_operator:XF 3 "binary_fp_operator"
15349 [(match_operand:XF 1 "register_operand" "0,f")
15351 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
15353 "* return output_387_binary_op (insn, operands);"
15354 [(set (attr "type")
15355 (cond [(match_operand:XF 3 "mult_operator")
15356 (const_string "fmul")
15357 (match_operand:XF 3 "div_operator")
15358 (const_string "fdiv")
15360 (const_string "fop")))
15361 (set_attr "mode" "<MODE>")])
15363 (define_insn "*fop_xf_6_i387"
15364 [(set (match_operand:XF 0 "register_operand" "=f,f")
15365 (match_operator:XF 3 "binary_fp_operator"
15367 (match_operand:MODEF 1 "register_operand" "0,f"))
15369 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
15371 "* return output_387_binary_op (insn, operands);"
15372 [(set (attr "type")
15373 (cond [(match_operand:XF 3 "mult_operator")
15374 (const_string "fmul")
15375 (match_operand:XF 3 "div_operator")
15376 (const_string "fdiv")
15378 (const_string "fop")))
15379 (set_attr "mode" "<MODE>")])
15381 ;; FPU special functions.
15383 ;; This pattern implements a no-op XFmode truncation for
15384 ;; all fancy i386 XFmode math functions.
15386 (define_insn "truncxf<mode>2_i387_noop_unspec"
15387 [(set (match_operand:MODEF 0 "register_operand" "=f")
15388 (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")]
15389 UNSPEC_TRUNC_NOOP))]
15390 "TARGET_USE_FANCY_MATH_387"
15391 "* return output_387_reg_move (insn, operands);"
15392 [(set_attr "type" "fmov")
15393 (set_attr "mode" "<MODE>")])
15395 (define_insn "sqrtxf2"
15396 [(set (match_operand:XF 0 "register_operand" "=f")
15397 (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
15398 "TARGET_USE_FANCY_MATH_387"
15400 [(set_attr "type" "fpspc")
15401 (set_attr "mode" "XF")
15402 (set_attr "athlon_decode" "direct")
15403 (set_attr "amdfam10_decode" "direct")
15404 (set_attr "bdver1_decode" "direct")])
15406 (define_insn "sqrt_extend<mode>xf2_i387"
15407 [(set (match_operand:XF 0 "register_operand" "=f")
15410 (match_operand:MODEF 1 "register_operand" "0"))))]
15411 "TARGET_USE_FANCY_MATH_387"
15413 [(set_attr "type" "fpspc")
15414 (set_attr "mode" "XF")
15415 (set_attr "athlon_decode" "direct")
15416 (set_attr "amdfam10_decode" "direct")
15417 (set_attr "bdver1_decode" "direct")])
15419 (define_insn "*rsqrtsf2_sse"
15420 [(set (match_operand:SF 0 "register_operand" "=x")
15421 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
15423 "TARGET_SSE && TARGET_SSE_MATH"
15424 "%vrsqrtss\t{%1, %d0|%d0, %1}"
15425 [(set_attr "type" "sse")
15426 (set_attr "atom_sse_attr" "rcp")
15427 (set_attr "btver2_sse_attr" "rcp")
15428 (set_attr "prefix" "maybe_vex")
15429 (set_attr "mode" "SF")])
15431 (define_expand "rsqrtsf2"
15432 [(set (match_operand:SF 0 "register_operand")
15433 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand")]
15435 "TARGET_SSE && TARGET_SSE_MATH"
15437 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
15441 (define_insn "*sqrt<mode>2_sse"
15442 [(set (match_operand:MODEF 0 "register_operand" "=v")
15444 (match_operand:MODEF 1 "nonimmediate_operand" "vm")))]
15445 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
15446 "%vsqrt<ssemodesuffix>\t{%1, %d0|%d0, %1}"
15447 [(set_attr "type" "sse")
15448 (set_attr "atom_sse_attr" "sqrt")
15449 (set_attr "btver2_sse_attr" "sqrt")
15450 (set_attr "prefix" "maybe_vex")
15451 (set_attr "mode" "<MODE>")
15452 (set_attr "athlon_decode" "*")
15453 (set_attr "amdfam10_decode" "*")
15454 (set_attr "bdver1_decode" "*")])
15456 (define_expand "sqrt<mode>2"
15457 [(set (match_operand:MODEF 0 "register_operand")
15459 (match_operand:MODEF 1 "nonimmediate_operand")))]
15460 "(TARGET_USE_FANCY_MATH_387 && X87_ENABLE_ARITH (<MODE>mode))
15461 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
15463 if (<MODE>mode == SFmode
15464 && TARGET_SSE && TARGET_SSE_MATH
15465 && TARGET_RECIP_SQRT
15466 && !optimize_function_for_size_p (cfun)
15467 && flag_finite_math_only && !flag_trapping_math
15468 && flag_unsafe_math_optimizations)
15470 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
15474 if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
15476 rtx op0 = gen_reg_rtx (XFmode);
15477 rtx op1 = force_reg (<MODE>mode, operands[1]);
15479 emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
15480 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
15485 (define_insn "fpremxf4_i387"
15486 [(set (match_operand:XF 0 "register_operand" "=f")
15487 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15488 (match_operand:XF 3 "register_operand" "1")]
15490 (set (match_operand:XF 1 "register_operand" "=u")
15491 (unspec:XF [(match_dup 2) (match_dup 3)]
15493 (set (reg:CCFP FPSR_REG)
15494 (unspec:CCFP [(match_dup 2) (match_dup 3)]
15496 "TARGET_USE_FANCY_MATH_387
15497 && flag_finite_math_only"
15499 [(set_attr "type" "fpspc")
15500 (set_attr "znver1_decode" "vector")
15501 (set_attr "mode" "XF")])
15503 (define_expand "fmodxf3"
15504 [(use (match_operand:XF 0 "register_operand"))
15505 (use (match_operand:XF 1 "general_operand"))
15506 (use (match_operand:XF 2 "general_operand"))]
15507 "TARGET_USE_FANCY_MATH_387
15508 && flag_finite_math_only"
15510 rtx_code_label *label = gen_label_rtx ();
15512 rtx op1 = gen_reg_rtx (XFmode);
15513 rtx op2 = gen_reg_rtx (XFmode);
15515 emit_move_insn (op2, operands[2]);
15516 emit_move_insn (op1, operands[1]);
15518 emit_label (label);
15519 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
15520 ix86_emit_fp_unordered_jump (label);
15521 LABEL_NUSES (label) = 1;
15523 emit_move_insn (operands[0], op1);
15527 (define_expand "fmod<mode>3"
15528 [(use (match_operand:MODEF 0 "register_operand"))
15529 (use (match_operand:MODEF 1 "general_operand"))
15530 (use (match_operand:MODEF 2 "general_operand"))]
15531 "TARGET_USE_FANCY_MATH_387
15532 && flag_finite_math_only"
15534 rtx (*gen_truncxf) (rtx, rtx);
15536 rtx_code_label *label = gen_label_rtx ();
15538 rtx op1 = gen_reg_rtx (XFmode);
15539 rtx op2 = gen_reg_rtx (XFmode);
15541 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
15542 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15544 emit_label (label);
15545 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
15546 ix86_emit_fp_unordered_jump (label);
15547 LABEL_NUSES (label) = 1;
15549 /* Truncate the result properly for strict SSE math. */
15550 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15551 && !TARGET_MIX_SSE_I387)
15552 gen_truncxf = gen_truncxf<mode>2;
15554 gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
15556 emit_insn (gen_truncxf (operands[0], op1));
15560 (define_insn "fprem1xf4_i387"
15561 [(set (match_operand:XF 0 "register_operand" "=f")
15562 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15563 (match_operand:XF 3 "register_operand" "1")]
15565 (set (match_operand:XF 1 "register_operand" "=u")
15566 (unspec:XF [(match_dup 2) (match_dup 3)]
15568 (set (reg:CCFP FPSR_REG)
15569 (unspec:CCFP [(match_dup 2) (match_dup 3)]
15571 "TARGET_USE_FANCY_MATH_387
15572 && flag_finite_math_only"
15574 [(set_attr "type" "fpspc")
15575 (set_attr "znver1_decode" "vector")
15576 (set_attr "mode" "XF")])
15578 (define_expand "remainderxf3"
15579 [(use (match_operand:XF 0 "register_operand"))
15580 (use (match_operand:XF 1 "general_operand"))
15581 (use (match_operand:XF 2 "general_operand"))]
15582 "TARGET_USE_FANCY_MATH_387
15583 && flag_finite_math_only"
15585 rtx_code_label *label = gen_label_rtx ();
15587 rtx op1 = gen_reg_rtx (XFmode);
15588 rtx op2 = gen_reg_rtx (XFmode);
15590 emit_move_insn (op2, operands[2]);
15591 emit_move_insn (op1, operands[1]);
15593 emit_label (label);
15594 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
15595 ix86_emit_fp_unordered_jump (label);
15596 LABEL_NUSES (label) = 1;
15598 emit_move_insn (operands[0], op1);
15602 (define_expand "remainder<mode>3"
15603 [(use (match_operand:MODEF 0 "register_operand"))
15604 (use (match_operand:MODEF 1 "general_operand"))
15605 (use (match_operand:MODEF 2 "general_operand"))]
15606 "TARGET_USE_FANCY_MATH_387
15607 && flag_finite_math_only"
15609 rtx (*gen_truncxf) (rtx, rtx);
15611 rtx_code_label *label = gen_label_rtx ();
15613 rtx op1 = gen_reg_rtx (XFmode);
15614 rtx op2 = gen_reg_rtx (XFmode);
15616 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
15617 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15619 emit_label (label);
15621 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
15622 ix86_emit_fp_unordered_jump (label);
15623 LABEL_NUSES (label) = 1;
15625 /* Truncate the result properly for strict SSE math. */
15626 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15627 && !TARGET_MIX_SSE_I387)
15628 gen_truncxf = gen_truncxf<mode>2;
15630 gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
15632 emit_insn (gen_truncxf (operands[0], op1));
15636 (define_int_iterator SINCOS
15640 (define_int_attr sincos
15641 [(UNSPEC_SIN "sin")
15642 (UNSPEC_COS "cos")])
15644 (define_insn "*<sincos>xf2_i387"
15645 [(set (match_operand:XF 0 "register_operand" "=f")
15646 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15648 "TARGET_USE_FANCY_MATH_387
15649 && flag_unsafe_math_optimizations"
15651 [(set_attr "type" "fpspc")
15652 (set_attr "znver1_decode" "vector")
15653 (set_attr "mode" "XF")])
15655 (define_insn "*<sincos>_extend<mode>xf2_i387"
15656 [(set (match_operand:XF 0 "register_operand" "=f")
15657 (unspec:XF [(float_extend:XF
15658 (match_operand:MODEF 1 "register_operand" "0"))]
15660 "TARGET_USE_FANCY_MATH_387
15661 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15662 || TARGET_MIX_SSE_I387)
15663 && flag_unsafe_math_optimizations"
15665 [(set_attr "type" "fpspc")
15666 (set_attr "znver1_decode" "vector")
15667 (set_attr "mode" "XF")])
15669 ;; When sincos pattern is defined, sin and cos builtin functions will be
15670 ;; expanded to sincos pattern with one of its outputs left unused.
15671 ;; CSE pass will figure out if two sincos patterns can be combined,
15672 ;; otherwise sincos pattern will be split back to sin or cos pattern,
15673 ;; depending on the unused output.
15675 (define_insn "sincosxf3"
15676 [(set (match_operand:XF 0 "register_operand" "=f")
15677 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15678 UNSPEC_SINCOS_COS))
15679 (set (match_operand:XF 1 "register_operand" "=u")
15680 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15681 "TARGET_USE_FANCY_MATH_387
15682 && flag_unsafe_math_optimizations"
15684 [(set_attr "type" "fpspc")
15685 (set_attr "znver1_decode" "vector")
15686 (set_attr "mode" "XF")])
15689 [(set (match_operand:XF 0 "register_operand")
15690 (unspec:XF [(match_operand:XF 2 "register_operand")]
15691 UNSPEC_SINCOS_COS))
15692 (set (match_operand:XF 1 "register_operand")
15693 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15694 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15695 && can_create_pseudo_p ()"
15696 [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))])
15699 [(set (match_operand:XF 0 "register_operand")
15700 (unspec:XF [(match_operand:XF 2 "register_operand")]
15701 UNSPEC_SINCOS_COS))
15702 (set (match_operand:XF 1 "register_operand")
15703 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15704 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15705 && can_create_pseudo_p ()"
15706 [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))])
15708 (define_insn "sincos_extend<mode>xf3_i387"
15709 [(set (match_operand:XF 0 "register_operand" "=f")
15710 (unspec:XF [(float_extend:XF
15711 (match_operand:MODEF 2 "register_operand" "0"))]
15712 UNSPEC_SINCOS_COS))
15713 (set (match_operand:XF 1 "register_operand" "=u")
15714 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
15715 "TARGET_USE_FANCY_MATH_387
15716 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15717 || TARGET_MIX_SSE_I387)
15718 && flag_unsafe_math_optimizations"
15720 [(set_attr "type" "fpspc")
15721 (set_attr "znver1_decode" "vector")
15722 (set_attr "mode" "XF")])
15725 [(set (match_operand:XF 0 "register_operand")
15726 (unspec:XF [(float_extend:XF
15727 (match_operand:MODEF 2 "register_operand"))]
15728 UNSPEC_SINCOS_COS))
15729 (set (match_operand:XF 1 "register_operand")
15730 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
15731 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15732 && can_create_pseudo_p ()"
15733 [(set (match_dup 1)
15734 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))])
15737 [(set (match_operand:XF 0 "register_operand")
15738 (unspec:XF [(float_extend:XF
15739 (match_operand:MODEF 2 "register_operand"))]
15740 UNSPEC_SINCOS_COS))
15741 (set (match_operand:XF 1 "register_operand")
15742 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
15743 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15744 && can_create_pseudo_p ()"
15745 [(set (match_dup 0)
15746 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))])
15748 (define_expand "sincos<mode>3"
15749 [(use (match_operand:MODEF 0 "register_operand"))
15750 (use (match_operand:MODEF 1 "register_operand"))
15751 (use (match_operand:MODEF 2 "register_operand"))]
15752 "TARGET_USE_FANCY_MATH_387
15753 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15754 || TARGET_MIX_SSE_I387)
15755 && flag_unsafe_math_optimizations"
15757 rtx op0 = gen_reg_rtx (XFmode);
15758 rtx op1 = gen_reg_rtx (XFmode);
15760 emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
15761 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15762 emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
15766 (define_insn "fptanxf4_i387"
15767 [(set (match_operand:XF 0 "register_operand" "=f")
15768 (match_operand:XF 3 "const_double_operand" "F"))
15769 (set (match_operand:XF 1 "register_operand" "=u")
15770 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15772 "TARGET_USE_FANCY_MATH_387
15773 && flag_unsafe_math_optimizations
15774 && standard_80387_constant_p (operands[3]) == 2"
15776 [(set_attr "type" "fpspc")
15777 (set_attr "znver1_decode" "vector")
15778 (set_attr "mode" "XF")])
15780 (define_insn "fptan_extend<mode>xf4_i387"
15781 [(set (match_operand:MODEF 0 "register_operand" "=f")
15782 (match_operand:MODEF 3 "const_double_operand" "F"))
15783 (set (match_operand:XF 1 "register_operand" "=u")
15784 (unspec:XF [(float_extend:XF
15785 (match_operand:MODEF 2 "register_operand" "0"))]
15787 "TARGET_USE_FANCY_MATH_387
15788 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15789 || TARGET_MIX_SSE_I387)
15790 && flag_unsafe_math_optimizations
15791 && standard_80387_constant_p (operands[3]) == 2"
15793 [(set_attr "type" "fpspc")
15794 (set_attr "znver1_decode" "vector")
15795 (set_attr "mode" "XF")])
15797 (define_expand "tanxf2"
15798 [(use (match_operand:XF 0 "register_operand"))
15799 (use (match_operand:XF 1 "register_operand"))]
15800 "TARGET_USE_FANCY_MATH_387
15801 && flag_unsafe_math_optimizations"
15803 rtx one = gen_reg_rtx (XFmode);
15804 rtx op2 = CONST1_RTX (XFmode); /* fld1 */
15806 emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2));
15810 (define_expand "tan<mode>2"
15811 [(use (match_operand:MODEF 0 "register_operand"))
15812 (use (match_operand:MODEF 1 "register_operand"))]
15813 "TARGET_USE_FANCY_MATH_387
15814 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15815 || TARGET_MIX_SSE_I387)
15816 && flag_unsafe_math_optimizations"
15818 rtx op0 = gen_reg_rtx (XFmode);
15820 rtx one = gen_reg_rtx (<MODE>mode);
15821 rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */
15823 emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
15824 operands[1], op2));
15825 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15829 (define_insn "*fpatanxf3_i387"
15830 [(set (match_operand:XF 0 "register_operand" "=f")
15831 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
15832 (match_operand:XF 2 "register_operand" "u")]
15834 (clobber (match_scratch:XF 3 "=2"))]
15835 "TARGET_USE_FANCY_MATH_387
15836 && flag_unsafe_math_optimizations"
15838 [(set_attr "type" "fpspc")
15839 (set_attr "znver1_decode" "vector")
15840 (set_attr "mode" "XF")])
15842 (define_insn "fpatan_extend<mode>xf3_i387"
15843 [(set (match_operand:XF 0 "register_operand" "=f")
15844 (unspec:XF [(float_extend:XF
15845 (match_operand:MODEF 1 "register_operand" "0"))
15847 (match_operand:MODEF 2 "register_operand" "u"))]
15849 (clobber (match_scratch:XF 3 "=2"))]
15850 "TARGET_USE_FANCY_MATH_387
15851 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15852 || TARGET_MIX_SSE_I387)
15853 && flag_unsafe_math_optimizations"
15855 [(set_attr "type" "fpspc")
15856 (set_attr "znver1_decode" "vector")
15857 (set_attr "mode" "XF")])
15859 (define_expand "atan2xf3"
15860 [(parallel [(set (match_operand:XF 0 "register_operand")
15861 (unspec:XF [(match_operand:XF 2 "register_operand")
15862 (match_operand:XF 1 "register_operand")]
15864 (clobber (match_scratch:XF 3))])]
15865 "TARGET_USE_FANCY_MATH_387
15866 && flag_unsafe_math_optimizations")
15868 (define_expand "atan2<mode>3"
15869 [(use (match_operand:MODEF 0 "register_operand"))
15870 (use (match_operand:MODEF 1 "register_operand"))
15871 (use (match_operand:MODEF 2 "register_operand"))]
15872 "TARGET_USE_FANCY_MATH_387
15873 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15874 || TARGET_MIX_SSE_I387)
15875 && flag_unsafe_math_optimizations"
15877 rtx op0 = gen_reg_rtx (XFmode);
15879 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
15880 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15884 (define_expand "atanxf2"
15885 [(parallel [(set (match_operand:XF 0 "register_operand")
15886 (unspec:XF [(match_dup 2)
15887 (match_operand:XF 1 "register_operand")]
15889 (clobber (match_scratch:XF 3))])]
15890 "TARGET_USE_FANCY_MATH_387
15891 && flag_unsafe_math_optimizations"
15893 operands[2] = gen_reg_rtx (XFmode);
15894 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
15897 (define_expand "atan<mode>2"
15898 [(use (match_operand:MODEF 0 "register_operand"))
15899 (use (match_operand:MODEF 1 "register_operand"))]
15900 "TARGET_USE_FANCY_MATH_387
15901 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15902 || TARGET_MIX_SSE_I387)
15903 && flag_unsafe_math_optimizations"
15905 rtx op0 = gen_reg_rtx (XFmode);
15907 rtx op2 = gen_reg_rtx (<MODE>mode);
15908 emit_move_insn (op2, CONST1_RTX (<MODE>mode)); /* fld1 */
15910 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1]));
15911 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15915 (define_expand "asinxf2"
15916 [(set (match_dup 2)
15917 (mult:XF (match_operand:XF 1 "register_operand")
15919 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
15920 (set (match_dup 5) (sqrt:XF (match_dup 4)))
15921 (parallel [(set (match_operand:XF 0 "register_operand")
15922 (unspec:XF [(match_dup 5) (match_dup 1)]
15924 (clobber (match_scratch:XF 6))])]
15925 "TARGET_USE_FANCY_MATH_387
15926 && flag_unsafe_math_optimizations"
15930 for (i = 2; i < 6; i++)
15931 operands[i] = gen_reg_rtx (XFmode);
15933 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
15936 (define_expand "asin<mode>2"
15937 [(use (match_operand:MODEF 0 "register_operand"))
15938 (use (match_operand:MODEF 1 "general_operand"))]
15939 "TARGET_USE_FANCY_MATH_387
15940 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15941 || TARGET_MIX_SSE_I387)
15942 && flag_unsafe_math_optimizations"
15944 rtx op0 = gen_reg_rtx (XFmode);
15945 rtx op1 = gen_reg_rtx (XFmode);
15947 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15948 emit_insn (gen_asinxf2 (op0, op1));
15949 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15953 (define_expand "acosxf2"
15954 [(set (match_dup 2)
15955 (mult:XF (match_operand:XF 1 "register_operand")
15957 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
15958 (set (match_dup 5) (sqrt:XF (match_dup 4)))
15959 (parallel [(set (match_operand:XF 0 "register_operand")
15960 (unspec:XF [(match_dup 1) (match_dup 5)]
15962 (clobber (match_scratch:XF 6))])]
15963 "TARGET_USE_FANCY_MATH_387
15964 && flag_unsafe_math_optimizations"
15968 for (i = 2; i < 6; i++)
15969 operands[i] = gen_reg_rtx (XFmode);
15971 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
15974 (define_expand "acos<mode>2"
15975 [(use (match_operand:MODEF 0 "register_operand"))
15976 (use (match_operand:MODEF 1 "general_operand"))]
15977 "TARGET_USE_FANCY_MATH_387
15978 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15979 || TARGET_MIX_SSE_I387)
15980 && flag_unsafe_math_optimizations"
15982 rtx op0 = gen_reg_rtx (XFmode);
15983 rtx op1 = gen_reg_rtx (XFmode);
15985 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15986 emit_insn (gen_acosxf2 (op0, op1));
15987 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15991 (define_insn "fyl2xxf3_i387"
15992 [(set (match_operand:XF 0 "register_operand" "=f")
15993 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
15994 (match_operand:XF 2 "register_operand" "u")]
15996 (clobber (match_scratch:XF 3 "=2"))]
15997 "TARGET_USE_FANCY_MATH_387
15998 && flag_unsafe_math_optimizations"
16000 [(set_attr "type" "fpspc")
16001 (set_attr "znver1_decode" "vector")
16002 (set_attr "mode" "XF")])
16004 (define_insn "fyl2x_extend<mode>xf3_i387"
16005 [(set (match_operand:XF 0 "register_operand" "=f")
16006 (unspec:XF [(float_extend:XF
16007 (match_operand:MODEF 1 "register_operand" "0"))
16008 (match_operand:XF 2 "register_operand" "u")]
16010 (clobber (match_scratch:XF 3 "=2"))]
16011 "TARGET_USE_FANCY_MATH_387
16012 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16013 || TARGET_MIX_SSE_I387)
16014 && flag_unsafe_math_optimizations"
16016 [(set_attr "type" "fpspc")
16017 (set_attr "znver1_decode" "vector")
16018 (set_attr "mode" "XF")])
16020 (define_expand "logxf2"
16021 [(parallel [(set (match_operand:XF 0 "register_operand")
16022 (unspec:XF [(match_operand:XF 1 "register_operand")
16023 (match_dup 2)] UNSPEC_FYL2X))
16024 (clobber (match_scratch:XF 3))])]
16025 "TARGET_USE_FANCY_MATH_387
16026 && flag_unsafe_math_optimizations"
16028 operands[2] = gen_reg_rtx (XFmode);
16029 emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */
16032 (define_expand "log<mode>2"
16033 [(use (match_operand:MODEF 0 "register_operand"))
16034 (use (match_operand:MODEF 1 "register_operand"))]
16035 "TARGET_USE_FANCY_MATH_387
16036 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16037 || TARGET_MIX_SSE_I387)
16038 && flag_unsafe_math_optimizations"
16040 rtx op0 = gen_reg_rtx (XFmode);
16042 rtx op2 = gen_reg_rtx (XFmode);
16043 emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */
16045 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
16046 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16050 (define_expand "log10xf2"
16051 [(parallel [(set (match_operand:XF 0 "register_operand")
16052 (unspec:XF [(match_operand:XF 1 "register_operand")
16053 (match_dup 2)] UNSPEC_FYL2X))
16054 (clobber (match_scratch:XF 3))])]
16055 "TARGET_USE_FANCY_MATH_387
16056 && flag_unsafe_math_optimizations"
16058 operands[2] = gen_reg_rtx (XFmode);
16059 emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
16062 (define_expand "log10<mode>2"
16063 [(use (match_operand:MODEF 0 "register_operand"))
16064 (use (match_operand:MODEF 1 "register_operand"))]
16065 "TARGET_USE_FANCY_MATH_387
16066 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16067 || TARGET_MIX_SSE_I387)
16068 && flag_unsafe_math_optimizations"
16070 rtx op0 = gen_reg_rtx (XFmode);
16072 rtx op2 = gen_reg_rtx (XFmode);
16073 emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */
16075 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
16076 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16080 (define_expand "log2xf2"
16081 [(parallel [(set (match_operand:XF 0 "register_operand")
16082 (unspec:XF [(match_operand:XF 1 "register_operand")
16083 (match_dup 2)] UNSPEC_FYL2X))
16084 (clobber (match_scratch:XF 3))])]
16085 "TARGET_USE_FANCY_MATH_387
16086 && flag_unsafe_math_optimizations"
16088 operands[2] = gen_reg_rtx (XFmode);
16089 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
16092 (define_expand "log2<mode>2"
16093 [(use (match_operand:MODEF 0 "register_operand"))
16094 (use (match_operand:MODEF 1 "register_operand"))]
16095 "TARGET_USE_FANCY_MATH_387
16096 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16097 || TARGET_MIX_SSE_I387)
16098 && flag_unsafe_math_optimizations"
16100 rtx op0 = gen_reg_rtx (XFmode);
16102 rtx op2 = gen_reg_rtx (XFmode);
16103 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
16105 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
16106 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16110 (define_insn "fyl2xp1xf3_i387"
16111 [(set (match_operand:XF 0 "register_operand" "=f")
16112 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
16113 (match_operand:XF 2 "register_operand" "u")]
16115 (clobber (match_scratch:XF 3 "=2"))]
16116 "TARGET_USE_FANCY_MATH_387
16117 && flag_unsafe_math_optimizations"
16119 [(set_attr "type" "fpspc")
16120 (set_attr "znver1_decode" "vector")
16121 (set_attr "mode" "XF")])
16123 (define_insn "fyl2xp1_extend<mode>xf3_i387"
16124 [(set (match_operand:XF 0 "register_operand" "=f")
16125 (unspec:XF [(float_extend:XF
16126 (match_operand:MODEF 1 "register_operand" "0"))
16127 (match_operand:XF 2 "register_operand" "u")]
16129 (clobber (match_scratch:XF 3 "=2"))]
16130 "TARGET_USE_FANCY_MATH_387
16131 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16132 || TARGET_MIX_SSE_I387)
16133 && flag_unsafe_math_optimizations"
16135 [(set_attr "type" "fpspc")
16136 (set_attr "znver1_decode" "vector")
16137 (set_attr "mode" "XF")])
16139 (define_expand "log1pxf2"
16140 [(use (match_operand:XF 0 "register_operand"))
16141 (use (match_operand:XF 1 "register_operand"))]
16142 "TARGET_USE_FANCY_MATH_387
16143 && flag_unsafe_math_optimizations"
16145 ix86_emit_i387_log1p (operands[0], operands[1]);
16149 (define_expand "log1p<mode>2"
16150 [(use (match_operand:MODEF 0 "register_operand"))
16151 (use (match_operand:MODEF 1 "register_operand"))]
16152 "TARGET_USE_FANCY_MATH_387
16153 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16154 || TARGET_MIX_SSE_I387)
16155 && flag_unsafe_math_optimizations"
16159 op0 = gen_reg_rtx (XFmode);
16161 operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
16163 ix86_emit_i387_log1p (op0, operands[1]);
16164 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16168 (define_insn "fxtractxf3_i387"
16169 [(set (match_operand:XF 0 "register_operand" "=f")
16170 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16171 UNSPEC_XTRACT_FRACT))
16172 (set (match_operand:XF 1 "register_operand" "=u")
16173 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
16174 "TARGET_USE_FANCY_MATH_387
16175 && flag_unsafe_math_optimizations"
16177 [(set_attr "type" "fpspc")
16178 (set_attr "znver1_decode" "vector")
16179 (set_attr "mode" "XF")])
16181 (define_insn "fxtract_extend<mode>xf3_i387"
16182 [(set (match_operand:XF 0 "register_operand" "=f")
16183 (unspec:XF [(float_extend:XF
16184 (match_operand:MODEF 2 "register_operand" "0"))]
16185 UNSPEC_XTRACT_FRACT))
16186 (set (match_operand:XF 1 "register_operand" "=u")
16187 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
16188 "TARGET_USE_FANCY_MATH_387
16189 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16190 || TARGET_MIX_SSE_I387)
16191 && flag_unsafe_math_optimizations"
16193 [(set_attr "type" "fpspc")
16194 (set_attr "znver1_decode" "vector")
16195 (set_attr "mode" "XF")])
16197 (define_expand "logbxf2"
16198 [(parallel [(set (match_dup 2)
16199 (unspec:XF [(match_operand:XF 1 "register_operand")]
16200 UNSPEC_XTRACT_FRACT))
16201 (set (match_operand:XF 0 "register_operand")
16202 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
16203 "TARGET_USE_FANCY_MATH_387
16204 && flag_unsafe_math_optimizations"
16205 "operands[2] = gen_reg_rtx (XFmode);")
16207 (define_expand "logb<mode>2"
16208 [(use (match_operand:MODEF 0 "register_operand"))
16209 (use (match_operand:MODEF 1 "register_operand"))]
16210 "TARGET_USE_FANCY_MATH_387
16211 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16212 || TARGET_MIX_SSE_I387)
16213 && flag_unsafe_math_optimizations"
16215 rtx op0 = gen_reg_rtx (XFmode);
16216 rtx op1 = gen_reg_rtx (XFmode);
16218 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
16219 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1));
16223 (define_expand "ilogbxf2"
16224 [(use (match_operand:SI 0 "register_operand"))
16225 (use (match_operand:XF 1 "register_operand"))]
16226 "TARGET_USE_FANCY_MATH_387
16227 && flag_unsafe_math_optimizations"
16231 if (optimize_insn_for_size_p ())
16234 op0 = gen_reg_rtx (XFmode);
16235 op1 = gen_reg_rtx (XFmode);
16237 emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
16238 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
16242 (define_expand "ilogb<mode>2"
16243 [(use (match_operand:SI 0 "register_operand"))
16244 (use (match_operand:MODEF 1 "register_operand"))]
16245 "TARGET_USE_FANCY_MATH_387
16246 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16247 || TARGET_MIX_SSE_I387)
16248 && flag_unsafe_math_optimizations"
16252 if (optimize_insn_for_size_p ())
16255 op0 = gen_reg_rtx (XFmode);
16256 op1 = gen_reg_rtx (XFmode);
16258 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
16259 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
16263 (define_insn "*f2xm1xf2_i387"
16264 [(set (match_operand:XF 0 "register_operand" "=f")
16265 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16267 "TARGET_USE_FANCY_MATH_387
16268 && flag_unsafe_math_optimizations"
16270 [(set_attr "type" "fpspc")
16271 (set_attr "znver1_decode" "vector")
16272 (set_attr "mode" "XF")])
16274 (define_insn "fscalexf4_i387"
16275 [(set (match_operand:XF 0 "register_operand" "=f")
16276 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16277 (match_operand:XF 3 "register_operand" "1")]
16278 UNSPEC_FSCALE_FRACT))
16279 (set (match_operand:XF 1 "register_operand" "=u")
16280 (unspec:XF [(match_dup 2) (match_dup 3)]
16281 UNSPEC_FSCALE_EXP))]
16282 "TARGET_USE_FANCY_MATH_387
16283 && flag_unsafe_math_optimizations"
16285 [(set_attr "type" "fpspc")
16286 (set_attr "znver1_decode" "vector")
16287 (set_attr "mode" "XF")])
16289 (define_expand "expNcorexf3"
16290 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand")
16291 (match_operand:XF 2 "register_operand")))
16292 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16293 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16294 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16295 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
16296 (parallel [(set (match_operand:XF 0 "register_operand")
16297 (unspec:XF [(match_dup 8) (match_dup 4)]
16298 UNSPEC_FSCALE_FRACT))
16300 (unspec:XF [(match_dup 8) (match_dup 4)]
16301 UNSPEC_FSCALE_EXP))])]
16302 "TARGET_USE_FANCY_MATH_387
16303 && flag_unsafe_math_optimizations"
16307 for (i = 3; i < 10; i++)
16308 operands[i] = gen_reg_rtx (XFmode);
16310 emit_move_insn (operands[7], CONST1_RTX (XFmode)); /* fld1 */
16313 (define_expand "expxf2"
16314 [(use (match_operand:XF 0 "register_operand"))
16315 (use (match_operand:XF 1 "register_operand"))]
16316 "TARGET_USE_FANCY_MATH_387
16317 && flag_unsafe_math_optimizations"
16321 op2 = gen_reg_rtx (XFmode);
16322 emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */
16324 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
16328 (define_expand "exp<mode>2"
16329 [(use (match_operand:MODEF 0 "register_operand"))
16330 (use (match_operand:MODEF 1 "general_operand"))]
16331 "TARGET_USE_FANCY_MATH_387
16332 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16333 || TARGET_MIX_SSE_I387)
16334 && flag_unsafe_math_optimizations"
16338 op0 = gen_reg_rtx (XFmode);
16339 op1 = gen_reg_rtx (XFmode);
16341 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16342 emit_insn (gen_expxf2 (op0, op1));
16343 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16347 (define_expand "exp10xf2"
16348 [(use (match_operand:XF 0 "register_operand"))
16349 (use (match_operand:XF 1 "register_operand"))]
16350 "TARGET_USE_FANCY_MATH_387
16351 && flag_unsafe_math_optimizations"
16355 op2 = gen_reg_rtx (XFmode);
16356 emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */
16358 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
16362 (define_expand "exp10<mode>2"
16363 [(use (match_operand:MODEF 0 "register_operand"))
16364 (use (match_operand:MODEF 1 "general_operand"))]
16365 "TARGET_USE_FANCY_MATH_387
16366 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16367 || TARGET_MIX_SSE_I387)
16368 && flag_unsafe_math_optimizations"
16372 op0 = gen_reg_rtx (XFmode);
16373 op1 = gen_reg_rtx (XFmode);
16375 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16376 emit_insn (gen_exp10xf2 (op0, op1));
16377 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16381 (define_expand "exp2xf2"
16382 [(use (match_operand:XF 0 "register_operand"))
16383 (use (match_operand:XF 1 "register_operand"))]
16384 "TARGET_USE_FANCY_MATH_387
16385 && flag_unsafe_math_optimizations"
16389 op2 = gen_reg_rtx (XFmode);
16390 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
16392 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
16396 (define_expand "exp2<mode>2"
16397 [(use (match_operand:MODEF 0 "register_operand"))
16398 (use (match_operand:MODEF 1 "general_operand"))]
16399 "TARGET_USE_FANCY_MATH_387
16400 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16401 || TARGET_MIX_SSE_I387)
16402 && flag_unsafe_math_optimizations"
16406 op0 = gen_reg_rtx (XFmode);
16407 op1 = gen_reg_rtx (XFmode);
16409 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16410 emit_insn (gen_exp2xf2 (op0, op1));
16411 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16415 (define_expand "expm1xf2"
16416 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand")
16418 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16419 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16420 (set (match_dup 9) (float_extend:XF (match_dup 13)))
16421 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16422 (parallel [(set (match_dup 7)
16423 (unspec:XF [(match_dup 6) (match_dup 4)]
16424 UNSPEC_FSCALE_FRACT))
16426 (unspec:XF [(match_dup 6) (match_dup 4)]
16427 UNSPEC_FSCALE_EXP))])
16428 (parallel [(set (match_dup 10)
16429 (unspec:XF [(match_dup 9) (match_dup 8)]
16430 UNSPEC_FSCALE_FRACT))
16431 (set (match_dup 11)
16432 (unspec:XF [(match_dup 9) (match_dup 8)]
16433 UNSPEC_FSCALE_EXP))])
16434 (set (match_dup 12) (minus:XF (match_dup 10)
16435 (float_extend:XF (match_dup 13))))
16436 (set (match_operand:XF 0 "register_operand")
16437 (plus:XF (match_dup 12) (match_dup 7)))]
16438 "TARGET_USE_FANCY_MATH_387
16439 && flag_unsafe_math_optimizations"
16443 for (i = 2; i < 13; i++)
16444 operands[i] = gen_reg_rtx (XFmode);
16447 = validize_mem (force_const_mem (SFmode, CONST1_RTX (SFmode))); /* fld1 */
16449 emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
16452 (define_expand "expm1<mode>2"
16453 [(use (match_operand:MODEF 0 "register_operand"))
16454 (use (match_operand:MODEF 1 "general_operand"))]
16455 "TARGET_USE_FANCY_MATH_387
16456 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16457 || TARGET_MIX_SSE_I387)
16458 && flag_unsafe_math_optimizations"
16462 op0 = gen_reg_rtx (XFmode);
16463 op1 = gen_reg_rtx (XFmode);
16465 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16466 emit_insn (gen_expm1xf2 (op0, op1));
16467 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16471 (define_expand "ldexpxf3"
16472 [(match_operand:XF 0 "register_operand")
16473 (match_operand:XF 1 "register_operand")
16474 (match_operand:SI 2 "register_operand")]
16475 "TARGET_USE_FANCY_MATH_387
16476 && flag_unsafe_math_optimizations"
16480 tmp1 = gen_reg_rtx (XFmode);
16481 tmp2 = gen_reg_rtx (XFmode);
16483 emit_insn (gen_floatsixf2 (tmp1, operands[2]));
16484 emit_insn (gen_fscalexf4_i387 (operands[0], tmp2,
16485 operands[1], tmp1));
16489 (define_expand "ldexp<mode>3"
16490 [(use (match_operand:MODEF 0 "register_operand"))
16491 (use (match_operand:MODEF 1 "general_operand"))
16492 (use (match_operand:SI 2 "register_operand"))]
16493 "TARGET_USE_FANCY_MATH_387
16494 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16495 || TARGET_MIX_SSE_I387)
16496 && flag_unsafe_math_optimizations"
16500 op0 = gen_reg_rtx (XFmode);
16501 op1 = gen_reg_rtx (XFmode);
16503 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16504 emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
16505 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16509 (define_expand "scalbxf3"
16510 [(parallel [(set (match_operand:XF 0 " register_operand")
16511 (unspec:XF [(match_operand:XF 1 "register_operand")
16512 (match_operand:XF 2 "register_operand")]
16513 UNSPEC_FSCALE_FRACT))
16515 (unspec:XF [(match_dup 1) (match_dup 2)]
16516 UNSPEC_FSCALE_EXP))])]
16517 "TARGET_USE_FANCY_MATH_387
16518 && flag_unsafe_math_optimizations"
16520 operands[3] = gen_reg_rtx (XFmode);
16523 (define_expand "scalb<mode>3"
16524 [(use (match_operand:MODEF 0 "register_operand"))
16525 (use (match_operand:MODEF 1 "general_operand"))
16526 (use (match_operand:MODEF 2 "general_operand"))]
16527 "TARGET_USE_FANCY_MATH_387
16528 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16529 || TARGET_MIX_SSE_I387)
16530 && flag_unsafe_math_optimizations"
16534 op0 = gen_reg_rtx (XFmode);
16535 op1 = gen_reg_rtx (XFmode);
16536 op2 = gen_reg_rtx (XFmode);
16538 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16539 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
16540 emit_insn (gen_scalbxf3 (op0, op1, op2));
16541 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16545 (define_expand "significandxf2"
16546 [(parallel [(set (match_operand:XF 0 "register_operand")
16547 (unspec:XF [(match_operand:XF 1 "register_operand")]
16548 UNSPEC_XTRACT_FRACT))
16550 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
16551 "TARGET_USE_FANCY_MATH_387
16552 && flag_unsafe_math_optimizations"
16553 "operands[2] = gen_reg_rtx (XFmode);")
16555 (define_expand "significand<mode>2"
16556 [(use (match_operand:MODEF 0 "register_operand"))
16557 (use (match_operand:MODEF 1 "register_operand"))]
16558 "TARGET_USE_FANCY_MATH_387
16559 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16560 || TARGET_MIX_SSE_I387)
16561 && flag_unsafe_math_optimizations"
16563 rtx op0 = gen_reg_rtx (XFmode);
16564 rtx op1 = gen_reg_rtx (XFmode);
16566 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
16567 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16572 (define_insn "sse4_1_round<mode>2"
16573 [(set (match_operand:MODEF 0 "register_operand" "=x,v")
16574 (unspec:MODEF [(match_operand:MODEF 1 "register_operand" "x,v")
16575 (match_operand:SI 2 "const_0_to_15_operand" "n,n")]
16579 %vround<ssemodesuffix>\t{%2, %1, %d0|%d0, %1, %2}
16580 vrndscale<ssemodesuffix>\t{%2, %1, %d0|%d0, %1, %2}"
16581 [(set_attr "type" "ssecvt")
16582 (set_attr "prefix_extra" "1,*")
16583 (set_attr "length_immediate" "*,1")
16584 (set_attr "prefix" "maybe_vex,evex")
16585 (set_attr "isa" "noavx512f,avx512f")
16586 (set_attr "mode" "<MODE>")])
16588 (define_insn "rintxf2"
16589 [(set (match_operand:XF 0 "register_operand" "=f")
16590 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16592 "TARGET_USE_FANCY_MATH_387"
16594 [(set_attr "type" "fpspc")
16595 (set_attr "znver1_decode" "vector")
16596 (set_attr "mode" "XF")])
16598 (define_insn "rint<mode>2_frndint"
16599 [(set (match_operand:MODEF 0 "register_operand" "=f")
16600 (unspec:MODEF [(match_operand:MODEF 1 "register_operand" "0")]
16602 "TARGET_USE_FANCY_MATH_387"
16604 [(set_attr "type" "fpspc")
16605 (set_attr "znver1_decode" "vector")
16606 (set_attr "mode" "<MODE>")])
16608 (define_expand "rint<mode>2"
16609 [(use (match_operand:MODEF 0 "register_operand"))
16610 (use (match_operand:MODEF 1 "register_operand"))]
16611 "(TARGET_USE_FANCY_MATH_387
16612 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16613 || TARGET_MIX_SSE_I387))
16614 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
16616 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16619 emit_insn (gen_sse4_1_round<mode>2
16620 (operands[0], operands[1], GEN_INT (ROUND_MXCSR)));
16622 ix86_expand_rint (operands[0], operands[1]);
16625 emit_insn (gen_rint<mode>2_frndint (operands[0], operands[1]));
16629 (define_expand "round<mode>2"
16630 [(match_operand:X87MODEF 0 "register_operand")
16631 (match_operand:X87MODEF 1 "nonimmediate_operand")]
16632 "(TARGET_USE_FANCY_MATH_387
16633 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16634 || TARGET_MIX_SSE_I387)
16635 && flag_unsafe_math_optimizations
16636 && (flag_fp_int_builtin_inexact || !flag_trapping_math))
16637 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16638 && !flag_trapping_math && !flag_rounding_math)"
16640 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16641 && !flag_trapping_math && !flag_rounding_math)
16645 operands[1] = force_reg (<MODE>mode, operands[1]);
16646 ix86_expand_round_sse4 (operands[0], operands[1]);
16648 else if (TARGET_64BIT || (<MODE>mode != DFmode))
16649 ix86_expand_round (operands[0], operands[1]);
16651 ix86_expand_rounddf_32 (operands[0], operands[1]);
16655 operands[1] = force_reg (<MODE>mode, operands[1]);
16656 ix86_emit_i387_round (operands[0], operands[1]);
16661 (define_insn_and_split "*fistdi2_1"
16662 [(set (match_operand:DI 0 "nonimmediate_operand")
16663 (unspec:DI [(match_operand:XF 1 "register_operand")]
16665 "TARGET_USE_FANCY_MATH_387
16666 && can_create_pseudo_p ()"
16671 if (memory_operand (operands[0], VOIDmode))
16672 emit_insn (gen_fistdi2 (operands[0], operands[1]));
16675 operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
16676 emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
16681 [(set_attr "type" "fpspc")
16682 (set_attr "mode" "DI")])
16684 (define_insn "fistdi2"
16685 [(set (match_operand:DI 0 "memory_operand" "=m")
16686 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
16688 (clobber (match_scratch:XF 2 "=&1f"))]
16689 "TARGET_USE_FANCY_MATH_387"
16690 "* return output_fix_trunc (insn, operands, false);"
16691 [(set_attr "type" "fpspc")
16692 (set_attr "mode" "DI")])
16694 (define_insn "fistdi2_with_temp"
16695 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
16696 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
16698 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))
16699 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
16700 "TARGET_USE_FANCY_MATH_387"
16702 [(set_attr "type" "fpspc")
16703 (set_attr "mode" "DI")])
16706 [(set (match_operand:DI 0 "register_operand")
16707 (unspec:DI [(match_operand:XF 1 "register_operand")]
16709 (clobber (match_operand:DI 2 "memory_operand"))
16710 (clobber (match_scratch 3))]
16712 [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
16713 (clobber (match_dup 3))])
16714 (set (match_dup 0) (match_dup 2))])
16717 [(set (match_operand:DI 0 "memory_operand")
16718 (unspec:DI [(match_operand:XF 1 "register_operand")]
16720 (clobber (match_operand:DI 2 "memory_operand"))
16721 (clobber (match_scratch 3))]
16723 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
16724 (clobber (match_dup 3))])])
16726 (define_insn_and_split "*fist<mode>2_1"
16727 [(set (match_operand:SWI24 0 "register_operand")
16728 (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
16730 "TARGET_USE_FANCY_MATH_387
16731 && can_create_pseudo_p ()"
16736 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
16737 emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
16741 [(set_attr "type" "fpspc")
16742 (set_attr "mode" "<MODE>")])
16744 (define_insn "fist<mode>2"
16745 [(set (match_operand:SWI24 0 "memory_operand" "=m")
16746 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
16748 "TARGET_USE_FANCY_MATH_387"
16749 "* return output_fix_trunc (insn, operands, false);"
16750 [(set_attr "type" "fpspc")
16751 (set_attr "mode" "<MODE>")])
16753 (define_insn "fist<mode>2_with_temp"
16754 [(set (match_operand:SWI24 0 "register_operand" "=r")
16755 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
16757 (clobber (match_operand:SWI24 2 "memory_operand" "=m"))]
16758 "TARGET_USE_FANCY_MATH_387"
16760 [(set_attr "type" "fpspc")
16761 (set_attr "mode" "<MODE>")])
16764 [(set (match_operand:SWI24 0 "register_operand")
16765 (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
16767 (clobber (match_operand:SWI24 2 "memory_operand"))]
16769 [(set (match_dup 2) (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST))
16770 (set (match_dup 0) (match_dup 2))])
16773 [(set (match_operand:SWI24 0 "memory_operand")
16774 (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
16776 (clobber (match_operand:SWI24 2 "memory_operand"))]
16778 [(set (match_dup 0) (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST))])
16780 (define_expand "lrintxf<mode>2"
16781 [(set (match_operand:SWI248x 0 "nonimmediate_operand")
16782 (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
16784 "TARGET_USE_FANCY_MATH_387")
16786 (define_expand "lrint<MODEF:mode><SWI48:mode>2"
16787 [(set (match_operand:SWI48 0 "nonimmediate_operand")
16788 (unspec:SWI48 [(match_operand:MODEF 1 "register_operand")]
16789 UNSPEC_FIX_NOTRUNC))]
16790 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH")
16792 (define_expand "lround<X87MODEF:mode><SWI248x:mode>2"
16793 [(match_operand:SWI248x 0 "nonimmediate_operand")
16794 (match_operand:X87MODEF 1 "register_operand")]
16795 "(TARGET_USE_FANCY_MATH_387
16796 && (!(SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
16797 || TARGET_MIX_SSE_I387)
16798 && flag_unsafe_math_optimizations)
16799 || (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
16800 && <SWI248x:MODE>mode != HImode
16801 && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT)
16802 && !flag_trapping_math && !flag_rounding_math)"
16804 if (optimize_insn_for_size_p ())
16807 if (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
16808 && <SWI248x:MODE>mode != HImode
16809 && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT)
16810 && !flag_trapping_math && !flag_rounding_math)
16811 ix86_expand_lround (operands[0], operands[1]);
16813 ix86_emit_i387_round (operands[0], operands[1]);
16817 (define_int_iterator FRNDINT_ROUNDING
16818 [UNSPEC_FRNDINT_FLOOR
16819 UNSPEC_FRNDINT_CEIL
16820 UNSPEC_FRNDINT_TRUNC])
16822 (define_int_iterator FIST_ROUNDING
16826 ;; Base name for define_insn
16827 (define_int_attr rounding_insn
16828 [(UNSPEC_FRNDINT_FLOOR "floor")
16829 (UNSPEC_FRNDINT_CEIL "ceil")
16830 (UNSPEC_FRNDINT_TRUNC "btrunc")
16831 (UNSPEC_FIST_FLOOR "floor")
16832 (UNSPEC_FIST_CEIL "ceil")])
16834 (define_int_attr rounding
16835 [(UNSPEC_FRNDINT_FLOOR "floor")
16836 (UNSPEC_FRNDINT_CEIL "ceil")
16837 (UNSPEC_FRNDINT_TRUNC "trunc")
16838 (UNSPEC_FIST_FLOOR "floor")
16839 (UNSPEC_FIST_CEIL "ceil")])
16841 (define_int_attr ROUNDING
16842 [(UNSPEC_FRNDINT_FLOOR "FLOOR")
16843 (UNSPEC_FRNDINT_CEIL "CEIL")
16844 (UNSPEC_FRNDINT_TRUNC "TRUNC")
16845 (UNSPEC_FIST_FLOOR "FLOOR")
16846 (UNSPEC_FIST_CEIL "CEIL")])
16848 ;; Rounding mode control word calculation could clobber FLAGS_REG.
16849 (define_insn_and_split "frndint<mode>2_<rounding>"
16850 [(set (match_operand:X87MODEF 0 "register_operand")
16851 (unspec:X87MODEF [(match_operand:X87MODEF 1 "register_operand")]
16853 (clobber (reg:CC FLAGS_REG))]
16854 "TARGET_USE_FANCY_MATH_387
16855 && (flag_fp_int_builtin_inexact || !flag_trapping_math)
16856 && can_create_pseudo_p ()"
16861 ix86_optimize_mode_switching[I387_<ROUNDING>] = 1;
16863 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
16864 operands[3] = assign_386_stack_local (HImode, SLOT_CW_<ROUNDING>);
16866 emit_insn (gen_frndint<mode>2_<rounding>_i387 (operands[0], operands[1],
16867 operands[2], operands[3]));
16870 [(set_attr "type" "frndint")
16871 (set_attr "i387_cw" "<rounding>")
16872 (set_attr "mode" "<MODE>")])
16874 (define_insn "frndint<mode>2_<rounding>_i387"
16875 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
16876 (unspec:X87MODEF [(match_operand:X87MODEF 1 "register_operand" "0")]
16878 (use (match_operand:HI 2 "memory_operand" "m"))
16879 (use (match_operand:HI 3 "memory_operand" "m"))]
16880 "TARGET_USE_FANCY_MATH_387
16881 && (flag_fp_int_builtin_inexact || !flag_trapping_math)"
16882 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
16883 [(set_attr "type" "frndint")
16884 (set_attr "i387_cw" "<rounding>")
16885 (set_attr "mode" "<MODE>")])
16887 (define_expand "<rounding_insn>xf2"
16888 [(parallel [(set (match_operand:XF 0 "register_operand")
16889 (unspec:XF [(match_operand:XF 1 "register_operand")]
16891 (clobber (reg:CC FLAGS_REG))])]
16892 "TARGET_USE_FANCY_MATH_387
16893 && (flag_fp_int_builtin_inexact || !flag_trapping_math)")
16895 (define_expand "<rounding_insn><mode>2"
16896 [(parallel [(set (match_operand:MODEF 0 "register_operand")
16897 (unspec:MODEF [(match_operand:MODEF 1 "register_operand")]
16899 (clobber (reg:CC FLAGS_REG))])]
16900 "(TARGET_USE_FANCY_MATH_387
16901 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16902 || TARGET_MIX_SSE_I387)
16903 && (flag_fp_int_builtin_inexact || !flag_trapping_math))
16904 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16905 && (TARGET_SSE4_1 || !flag_trapping_math
16906 || flag_fp_int_builtin_inexact))"
16908 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16909 && (TARGET_SSE4_1 || !flag_trapping_math || flag_fp_int_builtin_inexact))
16912 emit_insn (gen_sse4_1_round<mode>2
16913 (operands[0], operands[1], GEN_INT (ROUND_<ROUNDING>
16915 else if (TARGET_64BIT || (<MODE>mode != DFmode))
16917 if (ROUND_<ROUNDING> == ROUND_FLOOR)
16918 ix86_expand_floorceil (operands[0], operands[1], true);
16919 else if (ROUND_<ROUNDING> == ROUND_CEIL)
16920 ix86_expand_floorceil (operands[0], operands[1], false);
16921 else if (ROUND_<ROUNDING> == ROUND_TRUNC)
16922 ix86_expand_trunc (operands[0], operands[1]);
16924 gcc_unreachable ();
16928 if (ROUND_<ROUNDING> == ROUND_FLOOR)
16929 ix86_expand_floorceildf_32 (operands[0], operands[1], true);
16930 else if (ROUND_<ROUNDING> == ROUND_CEIL)
16931 ix86_expand_floorceildf_32 (operands[0], operands[1], false);
16932 else if (ROUND_<ROUNDING> == ROUND_TRUNC)
16933 ix86_expand_truncdf_32 (operands[0], operands[1]);
16935 gcc_unreachable ();
16939 emit_insn (gen_frndint<mode>2_<rounding> (operands[0], operands[1]));
16943 ;; Rounding mode control word calculation could clobber FLAGS_REG.
16944 (define_insn_and_split "frndintxf2_mask_pm"
16945 [(set (match_operand:XF 0 "register_operand")
16946 (unspec:XF [(match_operand:XF 1 "register_operand")]
16947 UNSPEC_FRNDINT_MASK_PM))
16948 (clobber (reg:CC FLAGS_REG))]
16949 "TARGET_USE_FANCY_MATH_387
16950 && flag_unsafe_math_optimizations
16951 && can_create_pseudo_p ()"
16956 ix86_optimize_mode_switching[I387_MASK_PM] = 1;
16958 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
16959 operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
16961 emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
16962 operands[2], operands[3]));
16965 [(set_attr "type" "frndint")
16966 (set_attr "i387_cw" "mask_pm")
16967 (set_attr "mode" "XF")])
16969 (define_insn "frndintxf2_mask_pm_i387"
16970 [(set (match_operand:XF 0 "register_operand" "=f")
16971 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16972 UNSPEC_FRNDINT_MASK_PM))
16973 (use (match_operand:HI 2 "memory_operand" "m"))
16974 (use (match_operand:HI 3 "memory_operand" "m"))]
16975 "TARGET_USE_FANCY_MATH_387
16976 && flag_unsafe_math_optimizations"
16977 "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
16978 [(set_attr "type" "frndint")
16979 (set_attr "i387_cw" "mask_pm")
16980 (set_attr "mode" "XF")])
16982 (define_expand "nearbyintxf2"
16983 [(parallel [(set (match_operand:XF 0 "register_operand")
16984 (unspec:XF [(match_operand:XF 1 "register_operand")]
16985 UNSPEC_FRNDINT_MASK_PM))
16986 (clobber (reg:CC FLAGS_REG))])]
16987 "TARGET_USE_FANCY_MATH_387
16988 && flag_unsafe_math_optimizations")
16990 (define_expand "nearbyint<mode>2"
16991 [(use (match_operand:MODEF 0 "register_operand"))
16992 (use (match_operand:MODEF 1 "register_operand"))]
16993 "TARGET_USE_FANCY_MATH_387
16994 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16995 || TARGET_MIX_SSE_I387)
16996 && flag_unsafe_math_optimizations"
16998 rtx op0 = gen_reg_rtx (XFmode);
16999 rtx op1 = gen_reg_rtx (XFmode);
17001 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17002 emit_insn (gen_frndintxf2_mask_pm (op0, op1));
17004 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17008 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17009 (define_insn_and_split "*fist<mode>2_<rounding>_1"
17010 [(set (match_operand:SWI248x 0 "nonimmediate_operand")
17011 (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
17013 (clobber (reg:CC FLAGS_REG))]
17014 "TARGET_USE_FANCY_MATH_387
17015 && flag_unsafe_math_optimizations
17016 && can_create_pseudo_p ()"
17021 ix86_optimize_mode_switching[I387_<ROUNDING>] = 1;
17023 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17024 operands[3] = assign_386_stack_local (HImode, SLOT_CW_<ROUNDING>);
17025 if (memory_operand (operands[0], VOIDmode))
17026 emit_insn (gen_fist<mode>2_<rounding> (operands[0], operands[1],
17027 operands[2], operands[3]));
17030 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17031 emit_insn (gen_fist<mode>2_<rounding>_with_temp
17032 (operands[0], operands[1], operands[2],
17033 operands[3], operands[4]));
17037 [(set_attr "type" "fistp")
17038 (set_attr "i387_cw" "<rounding>")
17039 (set_attr "mode" "<MODE>")])
17041 (define_insn "fistdi2_<rounding>"
17042 [(set (match_operand:DI 0 "memory_operand" "=m")
17043 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17045 (use (match_operand:HI 2 "memory_operand" "m"))
17046 (use (match_operand:HI 3 "memory_operand" "m"))
17047 (clobber (match_scratch:XF 4 "=&1f"))]
17048 "TARGET_USE_FANCY_MATH_387
17049 && flag_unsafe_math_optimizations"
17050 "* return output_fix_trunc (insn, operands, false);"
17051 [(set_attr "type" "fistp")
17052 (set_attr "i387_cw" "<rounding>")
17053 (set_attr "mode" "DI")])
17055 (define_insn "fistdi2_<rounding>_with_temp"
17056 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17057 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17059 (use (match_operand:HI 2 "memory_operand" "m,m"))
17060 (use (match_operand:HI 3 "memory_operand" "m,m"))
17061 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
17062 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
17063 "TARGET_USE_FANCY_MATH_387
17064 && flag_unsafe_math_optimizations"
17066 [(set_attr "type" "fistp")
17067 (set_attr "i387_cw" "<rounding>")
17068 (set_attr "mode" "DI")])
17071 [(set (match_operand:DI 0 "register_operand")
17072 (unspec:DI [(match_operand:XF 1 "register_operand")]
17074 (use (match_operand:HI 2 "memory_operand"))
17075 (use (match_operand:HI 3 "memory_operand"))
17076 (clobber (match_operand:DI 4 "memory_operand"))
17077 (clobber (match_scratch 5))]
17079 [(parallel [(set (match_dup 4)
17080 (unspec:DI [(match_dup 1)] FIST_ROUNDING))
17081 (use (match_dup 2))
17082 (use (match_dup 3))
17083 (clobber (match_dup 5))])
17084 (set (match_dup 0) (match_dup 4))])
17087 [(set (match_operand:DI 0 "memory_operand")
17088 (unspec:DI [(match_operand:XF 1 "register_operand")]
17090 (use (match_operand:HI 2 "memory_operand"))
17091 (use (match_operand:HI 3 "memory_operand"))
17092 (clobber (match_operand:DI 4 "memory_operand"))
17093 (clobber (match_scratch 5))]
17095 [(parallel [(set (match_dup 0)
17096 (unspec:DI [(match_dup 1)] FIST_ROUNDING))
17097 (use (match_dup 2))
17098 (use (match_dup 3))
17099 (clobber (match_dup 5))])])
17101 (define_insn "fist<mode>2_<rounding>"
17102 [(set (match_operand:SWI24 0 "memory_operand" "=m")
17103 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
17105 (use (match_operand:HI 2 "memory_operand" "m"))
17106 (use (match_operand:HI 3 "memory_operand" "m"))]
17107 "TARGET_USE_FANCY_MATH_387
17108 && flag_unsafe_math_optimizations"
17109 "* return output_fix_trunc (insn, operands, false);"
17110 [(set_attr "type" "fistp")
17111 (set_attr "i387_cw" "<rounding>")
17112 (set_attr "mode" "<MODE>")])
17114 (define_insn "fist<mode>2_<rounding>_with_temp"
17115 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
17116 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f,f")]
17118 (use (match_operand:HI 2 "memory_operand" "m,m"))
17119 (use (match_operand:HI 3 "memory_operand" "m,m"))
17120 (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
17121 "TARGET_USE_FANCY_MATH_387
17122 && flag_unsafe_math_optimizations"
17124 [(set_attr "type" "fistp")
17125 (set_attr "i387_cw" "<rounding>")
17126 (set_attr "mode" "<MODE>")])
17129 [(set (match_operand:SWI24 0 "register_operand")
17130 (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
17132 (use (match_operand:HI 2 "memory_operand"))
17133 (use (match_operand:HI 3 "memory_operand"))
17134 (clobber (match_operand:SWI24 4 "memory_operand"))]
17136 [(parallel [(set (match_dup 4)
17137 (unspec:SWI24 [(match_dup 1)] FIST_ROUNDING))
17138 (use (match_dup 2))
17139 (use (match_dup 3))])
17140 (set (match_dup 0) (match_dup 4))])
17143 [(set (match_operand:SWI24 0 "memory_operand")
17144 (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
17146 (use (match_operand:HI 2 "memory_operand"))
17147 (use (match_operand:HI 3 "memory_operand"))
17148 (clobber (match_operand:SWI24 4 "memory_operand"))]
17150 [(parallel [(set (match_dup 0)
17151 (unspec:SWI24 [(match_dup 1)] FIST_ROUNDING))
17152 (use (match_dup 2))
17153 (use (match_dup 3))])])
17155 (define_expand "l<rounding_insn>xf<mode>2"
17156 [(parallel [(set (match_operand:SWI248x 0 "nonimmediate_operand")
17157 (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
17159 (clobber (reg:CC FLAGS_REG))])]
17160 "TARGET_USE_FANCY_MATH_387
17161 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17162 && flag_unsafe_math_optimizations")
17164 (define_expand "l<rounding_insn><MODEF:mode><SWI48:mode>2"
17165 [(parallel [(set (match_operand:SWI48 0 "nonimmediate_operand")
17166 (unspec:SWI48 [(match_operand:MODEF 1 "register_operand")]
17168 (clobber (reg:CC FLAGS_REG))])]
17169 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
17170 && !flag_trapping_math"
17172 if (TARGET_64BIT && optimize_insn_for_size_p ())
17175 if (ROUND_<ROUNDING> == ROUND_FLOOR)
17176 ix86_expand_lfloorceil (operands[0], operands[1], true);
17177 else if (ROUND_<ROUNDING> == ROUND_CEIL)
17178 ix86_expand_lfloorceil (operands[0], operands[1], false);
17180 gcc_unreachable ();
17185 (define_insn "fxam<mode>2_i387"
17186 [(set (match_operand:HI 0 "register_operand" "=a")
17188 [(match_operand:X87MODEF 1 "register_operand" "f")]
17190 "TARGET_USE_FANCY_MATH_387"
17191 "fxam\n\tfnstsw\t%0"
17192 [(set_attr "type" "multi")
17193 (set_attr "length" "4")
17194 (set_attr "unit" "i387")
17195 (set_attr "mode" "<MODE>")])
17197 (define_insn_and_split "fxam<mode>2_i387_with_temp"
17198 [(set (match_operand:HI 0 "register_operand")
17200 [(match_operand:MODEF 1 "memory_operand")]
17202 "TARGET_USE_FANCY_MATH_387
17203 && can_create_pseudo_p ()"
17206 [(set (match_dup 2)(match_dup 1))
17208 (unspec:HI [(match_dup 2)] UNSPEC_FXAM))]
17210 operands[2] = gen_reg_rtx (<MODE>mode);
17212 MEM_VOLATILE_P (operands[1]) = 1;
17214 [(set_attr "type" "multi")
17215 (set_attr "unit" "i387")
17216 (set_attr "mode" "<MODE>")])
17218 (define_expand "isinfxf2"
17219 [(use (match_operand:SI 0 "register_operand"))
17220 (use (match_operand:XF 1 "register_operand"))]
17221 "TARGET_USE_FANCY_MATH_387
17222 && ix86_libc_has_function (function_c99_misc)"
17224 rtx mask = GEN_INT (0x45);
17225 rtx val = GEN_INT (0x05);
17227 rtx scratch = gen_reg_rtx (HImode);
17228 rtx res = gen_reg_rtx (QImode);
17230 emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
17232 emit_insn (gen_andqi_ext_1 (scratch, scratch, mask));
17233 emit_insn (gen_cmpqi_ext_3 (scratch, val));
17234 ix86_expand_setcc (res, EQ,
17235 gen_rtx_REG (CCmode, FLAGS_REG), const0_rtx);
17236 emit_insn (gen_zero_extendqisi2 (operands[0], res));
17240 (define_expand "isinf<mode>2"
17241 [(use (match_operand:SI 0 "register_operand"))
17242 (use (match_operand:MODEF 1 "nonimmediate_operand"))]
17243 "TARGET_USE_FANCY_MATH_387
17244 && ix86_libc_has_function (function_c99_misc)
17245 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
17247 rtx mask = GEN_INT (0x45);
17248 rtx val = GEN_INT (0x05);
17250 rtx scratch = gen_reg_rtx (HImode);
17251 rtx res = gen_reg_rtx (QImode);
17253 /* Remove excess precision by forcing value through memory. */
17254 if (memory_operand (operands[1], VOIDmode))
17255 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, operands[1]));
17258 rtx temp = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17260 emit_move_insn (temp, operands[1]);
17261 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, temp));
17264 emit_insn (gen_andqi_ext_1 (scratch, scratch, mask));
17265 emit_insn (gen_cmpqi_ext_3 (scratch, val));
17266 ix86_expand_setcc (res, EQ,
17267 gen_rtx_REG (CCmode, FLAGS_REG), const0_rtx);
17268 emit_insn (gen_zero_extendqisi2 (operands[0], res));
17272 (define_expand "signbittf2"
17273 [(use (match_operand:SI 0 "register_operand"))
17274 (use (match_operand:TF 1 "register_operand"))]
17279 rtx mask = ix86_build_signbit_mask (TFmode, 0, 0);
17280 rtx scratch = gen_reg_rtx (QImode);
17282 emit_insn (gen_ptesttf2 (operands[1], mask));
17283 ix86_expand_setcc (scratch, NE,
17284 gen_rtx_REG (CCZmode, FLAGS_REG), const0_rtx);
17286 emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
17290 emit_insn (gen_sse_movmskps (operands[0],
17291 gen_lowpart (V4SFmode, operands[1])));
17292 emit_insn (gen_andsi3 (operands[0], operands[0], GEN_INT (0x8)));
17297 (define_expand "signbitxf2"
17298 [(use (match_operand:SI 0 "register_operand"))
17299 (use (match_operand:XF 1 "register_operand"))]
17300 "TARGET_USE_FANCY_MATH_387"
17302 rtx scratch = gen_reg_rtx (HImode);
17304 emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
17305 emit_insn (gen_andsi3 (operands[0],
17306 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
17310 (define_insn "movmsk_df"
17311 [(set (match_operand:SI 0 "register_operand" "=r")
17313 [(match_operand:DF 1 "register_operand" "x")]
17315 "SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH"
17316 "%vmovmskpd\t{%1, %0|%0, %1}"
17317 [(set_attr "type" "ssemov")
17318 (set_attr "prefix" "maybe_vex")
17319 (set_attr "mode" "DF")])
17321 ;; Use movmskpd in SSE mode to avoid store forwarding stall
17322 ;; for 32bit targets and movq+shrq sequence for 64bit targets.
17323 (define_expand "signbitdf2"
17324 [(use (match_operand:SI 0 "register_operand"))
17325 (use (match_operand:DF 1 "register_operand"))]
17326 "TARGET_USE_FANCY_MATH_387
17327 || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
17329 if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)
17331 emit_insn (gen_movmsk_df (operands[0], operands[1]));
17332 emit_insn (gen_andsi3 (operands[0], operands[0], const1_rtx));
17336 rtx scratch = gen_reg_rtx (HImode);
17338 emit_insn (gen_fxamdf2_i387 (scratch, operands[1]));
17339 emit_insn (gen_andsi3 (operands[0],
17340 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
17345 (define_expand "signbitsf2"
17346 [(use (match_operand:SI 0 "register_operand"))
17347 (use (match_operand:SF 1 "register_operand"))]
17348 "TARGET_USE_FANCY_MATH_387
17349 && !(SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH)"
17351 rtx scratch = gen_reg_rtx (HImode);
17353 emit_insn (gen_fxamsf2_i387 (scratch, operands[1]));
17354 emit_insn (gen_andsi3 (operands[0],
17355 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
17359 ;; Block operation instructions
17362 [(unspec_volatile [(const_int 0)] UNSPECV_CLD)]
17365 [(set_attr "length" "1")
17366 (set_attr "length_immediate" "0")
17367 (set_attr "modrm" "0")])
17369 (define_expand "movmem<mode>"
17370 [(use (match_operand:BLK 0 "memory_operand"))
17371 (use (match_operand:BLK 1 "memory_operand"))
17372 (use (match_operand:SWI48 2 "nonmemory_operand"))
17373 (use (match_operand:SWI48 3 "const_int_operand"))
17374 (use (match_operand:SI 4 "const_int_operand"))
17375 (use (match_operand:SI 5 "const_int_operand"))
17376 (use (match_operand:SI 6 ""))
17377 (use (match_operand:SI 7 ""))
17378 (use (match_operand:SI 8 ""))]
17381 if (ix86_expand_set_or_movmem (operands[0], operands[1],
17382 operands[2], NULL, operands[3],
17383 operands[4], operands[5],
17384 operands[6], operands[7],
17385 operands[8], false))
17391 ;; Most CPUs don't like single string operations
17392 ;; Handle this case here to simplify previous expander.
17394 (define_expand "strmov"
17395 [(set (match_dup 4) (match_operand 3 "memory_operand"))
17396 (set (match_operand 1 "memory_operand") (match_dup 4))
17397 (parallel [(set (match_operand 0 "register_operand") (match_dup 5))
17398 (clobber (reg:CC FLAGS_REG))])
17399 (parallel [(set (match_operand 2 "register_operand") (match_dup 6))
17400 (clobber (reg:CC FLAGS_REG))])]
17403 /* Can't use this for non-default address spaces. */
17404 if (!ADDR_SPACE_GENERIC_P (MEM_ADDR_SPACE (operands[3])))
17407 rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
17409 /* If .md ever supports :P for Pmode, these can be directly
17410 in the pattern above. */
17411 operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
17412 operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
17414 /* Can't use this if the user has appropriated esi or edi. */
17415 if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
17416 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG]))
17418 emit_insn (gen_strmov_singleop (operands[0], operands[1],
17419 operands[2], operands[3],
17420 operands[5], operands[6]));
17424 operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
17427 (define_expand "strmov_singleop"
17428 [(parallel [(set (match_operand 1 "memory_operand")
17429 (match_operand 3 "memory_operand"))
17430 (set (match_operand 0 "register_operand")
17432 (set (match_operand 2 "register_operand")
17433 (match_operand 5))])]
17437 ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
17440 (define_insn "*strmovdi_rex_1"
17441 [(set (mem:DI (match_operand:P 2 "register_operand" "0"))
17442 (mem:DI (match_operand:P 3 "register_operand" "1")))
17443 (set (match_operand:P 0 "register_operand" "=D")
17444 (plus:P (match_dup 2)
17446 (set (match_operand:P 1 "register_operand" "=S")
17447 (plus:P (match_dup 3)
17450 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG])
17451 && ix86_check_no_addr_space (insn)"
17453 [(set_attr "type" "str")
17454 (set_attr "memory" "both")
17455 (set_attr "mode" "DI")])
17457 (define_insn "*strmovsi_1"
17458 [(set (mem:SI (match_operand:P 2 "register_operand" "0"))
17459 (mem:SI (match_operand:P 3 "register_operand" "1")))
17460 (set (match_operand:P 0 "register_operand" "=D")
17461 (plus:P (match_dup 2)
17463 (set (match_operand:P 1 "register_operand" "=S")
17464 (plus:P (match_dup 3)
17466 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])
17467 && ix86_check_no_addr_space (insn)"
17469 [(set_attr "type" "str")
17470 (set_attr "memory" "both")
17471 (set_attr "mode" "SI")])
17473 (define_insn "*strmovhi_1"
17474 [(set (mem:HI (match_operand:P 2 "register_operand" "0"))
17475 (mem:HI (match_operand:P 3 "register_operand" "1")))
17476 (set (match_operand:P 0 "register_operand" "=D")
17477 (plus:P (match_dup 2)
17479 (set (match_operand:P 1 "register_operand" "=S")
17480 (plus:P (match_dup 3)
17482 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])
17483 && ix86_check_no_addr_space (insn)"
17485 [(set_attr "type" "str")
17486 (set_attr "memory" "both")
17487 (set_attr "mode" "HI")])
17489 (define_insn "*strmovqi_1"
17490 [(set (mem:QI (match_operand:P 2 "register_operand" "0"))
17491 (mem:QI (match_operand:P 3 "register_operand" "1")))
17492 (set (match_operand:P 0 "register_operand" "=D")
17493 (plus:P (match_dup 2)
17495 (set (match_operand:P 1 "register_operand" "=S")
17496 (plus:P (match_dup 3)
17498 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])
17499 && ix86_check_no_addr_space (insn)"
17501 [(set_attr "type" "str")
17502 (set_attr "memory" "both")
17503 (set (attr "prefix_rex")
17505 (match_test "<P:MODE>mode == DImode")
17507 (const_string "*")))
17508 (set_attr "mode" "QI")])
17510 (define_expand "rep_mov"
17511 [(parallel [(set (match_operand 4 "register_operand") (const_int 0))
17512 (set (match_operand 0 "register_operand")
17514 (set (match_operand 2 "register_operand")
17516 (set (match_operand 1 "memory_operand")
17517 (match_operand 3 "memory_operand"))
17518 (use (match_dup 4))])]
17522 ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
17525 (define_insn "*rep_movdi_rex64"
17526 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
17527 (set (match_operand:P 0 "register_operand" "=D")
17528 (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
17530 (match_operand:P 3 "register_operand" "0")))
17531 (set (match_operand:P 1 "register_operand" "=S")
17532 (plus:P (ashift:P (match_dup 5) (const_int 3))
17533 (match_operand:P 4 "register_operand" "1")))
17534 (set (mem:BLK (match_dup 3))
17535 (mem:BLK (match_dup 4)))
17536 (use (match_dup 5))]
17538 && !(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
17539 && ix86_check_no_addr_space (insn)"
17541 [(set_attr "type" "str")
17542 (set_attr "prefix_rep" "1")
17543 (set_attr "memory" "both")
17544 (set_attr "mode" "DI")])
17546 (define_insn "*rep_movsi"
17547 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
17548 (set (match_operand:P 0 "register_operand" "=D")
17549 (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
17551 (match_operand:P 3 "register_operand" "0")))
17552 (set (match_operand:P 1 "register_operand" "=S")
17553 (plus:P (ashift:P (match_dup 5) (const_int 2))
17554 (match_operand:P 4 "register_operand" "1")))
17555 (set (mem:BLK (match_dup 3))
17556 (mem:BLK (match_dup 4)))
17557 (use (match_dup 5))]
17558 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
17559 && ix86_check_no_addr_space (insn)"
17560 "%^rep{%;} movs{l|d}"
17561 [(set_attr "type" "str")
17562 (set_attr "prefix_rep" "1")
17563 (set_attr "memory" "both")
17564 (set_attr "mode" "SI")])
17566 (define_insn "*rep_movqi"
17567 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
17568 (set (match_operand:P 0 "register_operand" "=D")
17569 (plus:P (match_operand:P 3 "register_operand" "0")
17570 (match_operand:P 5 "register_operand" "2")))
17571 (set (match_operand:P 1 "register_operand" "=S")
17572 (plus:P (match_operand:P 4 "register_operand" "1") (match_dup 5)))
17573 (set (mem:BLK (match_dup 3))
17574 (mem:BLK (match_dup 4)))
17575 (use (match_dup 5))]
17576 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
17577 && ix86_check_no_addr_space (insn)"
17579 [(set_attr "type" "str")
17580 (set_attr "prefix_rep" "1")
17581 (set_attr "memory" "both")
17582 (set_attr "mode" "QI")])
17584 (define_expand "setmem<mode>"
17585 [(use (match_operand:BLK 0 "memory_operand"))
17586 (use (match_operand:SWI48 1 "nonmemory_operand"))
17587 (use (match_operand:QI 2 "nonmemory_operand"))
17588 (use (match_operand 3 "const_int_operand"))
17589 (use (match_operand:SI 4 "const_int_operand"))
17590 (use (match_operand:SI 5 "const_int_operand"))
17591 (use (match_operand:SI 6 ""))
17592 (use (match_operand:SI 7 ""))
17593 (use (match_operand:SI 8 ""))]
17596 if (ix86_expand_set_or_movmem (operands[0], NULL,
17597 operands[1], operands[2],
17598 operands[3], operands[4],
17599 operands[5], operands[6],
17600 operands[7], operands[8], true))
17606 ;; Most CPUs don't like single string operations
17607 ;; Handle this case here to simplify previous expander.
17609 (define_expand "strset"
17610 [(set (match_operand 1 "memory_operand")
17611 (match_operand 2 "register_operand"))
17612 (parallel [(set (match_operand 0 "register_operand")
17614 (clobber (reg:CC FLAGS_REG))])]
17617 /* Can't use this for non-default address spaces. */
17618 if (!ADDR_SPACE_GENERIC_P (MEM_ADDR_SPACE (operands[1])))
17621 if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
17622 operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
17624 /* If .md ever supports :P for Pmode, this can be directly
17625 in the pattern above. */
17626 operands[3] = gen_rtx_PLUS (Pmode, operands[0],
17627 GEN_INT (GET_MODE_SIZE (GET_MODE
17629 /* Can't use this if the user has appropriated eax or edi. */
17630 if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
17631 && !(fixed_regs[AX_REG] || fixed_regs[DI_REG]))
17633 emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
17639 (define_expand "strset_singleop"
17640 [(parallel [(set (match_operand 1 "memory_operand")
17641 (match_operand 2 "register_operand"))
17642 (set (match_operand 0 "register_operand")
17644 (unspec [(const_int 0)] UNSPEC_STOS)])]
17648 ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
17651 (define_insn "*strsetdi_rex_1"
17652 [(set (mem:DI (match_operand:P 1 "register_operand" "0"))
17653 (match_operand:DI 2 "register_operand" "a"))
17654 (set (match_operand:P 0 "register_operand" "=D")
17655 (plus:P (match_dup 1)
17657 (unspec [(const_int 0)] UNSPEC_STOS)]
17659 && !(fixed_regs[AX_REG] || fixed_regs[DI_REG])
17660 && ix86_check_no_addr_space (insn)"
17662 [(set_attr "type" "str")
17663 (set_attr "memory" "store")
17664 (set_attr "mode" "DI")])
17666 (define_insn "*strsetsi_1"
17667 [(set (mem:SI (match_operand:P 1 "register_operand" "0"))
17668 (match_operand:SI 2 "register_operand" "a"))
17669 (set (match_operand:P 0 "register_operand" "=D")
17670 (plus:P (match_dup 1)
17672 (unspec [(const_int 0)] UNSPEC_STOS)]
17673 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])
17674 && ix86_check_no_addr_space (insn)"
17676 [(set_attr "type" "str")
17677 (set_attr "memory" "store")
17678 (set_attr "mode" "SI")])
17680 (define_insn "*strsethi_1"
17681 [(set (mem:HI (match_operand:P 1 "register_operand" "0"))
17682 (match_operand:HI 2 "register_operand" "a"))
17683 (set (match_operand:P 0 "register_operand" "=D")
17684 (plus:P (match_dup 1)
17686 (unspec [(const_int 0)] UNSPEC_STOS)]
17687 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])
17688 && ix86_check_no_addr_space (insn)"
17690 [(set_attr "type" "str")
17691 (set_attr "memory" "store")
17692 (set_attr "mode" "HI")])
17694 (define_insn "*strsetqi_1"
17695 [(set (mem:QI (match_operand:P 1 "register_operand" "0"))
17696 (match_operand:QI 2 "register_operand" "a"))
17697 (set (match_operand:P 0 "register_operand" "=D")
17698 (plus:P (match_dup 1)
17700 (unspec [(const_int 0)] UNSPEC_STOS)]
17701 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])
17702 && ix86_check_no_addr_space (insn)"
17704 [(set_attr "type" "str")
17705 (set_attr "memory" "store")
17706 (set (attr "prefix_rex")
17708 (match_test "<P:MODE>mode == DImode")
17710 (const_string "*")))
17711 (set_attr "mode" "QI")])
17713 (define_expand "rep_stos"
17714 [(parallel [(set (match_operand 1 "register_operand") (const_int 0))
17715 (set (match_operand 0 "register_operand")
17717 (set (match_operand 2 "memory_operand") (const_int 0))
17718 (use (match_operand 3 "register_operand"))
17719 (use (match_dup 1))])]
17723 ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
17726 (define_insn "*rep_stosdi_rex64"
17727 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
17728 (set (match_operand:P 0 "register_operand" "=D")
17729 (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
17731 (match_operand:P 3 "register_operand" "0")))
17732 (set (mem:BLK (match_dup 3))
17734 (use (match_operand:DI 2 "register_operand" "a"))
17735 (use (match_dup 4))]
17737 && !(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])
17738 && ix86_check_no_addr_space (insn)"
17740 [(set_attr "type" "str")
17741 (set_attr "prefix_rep" "1")
17742 (set_attr "memory" "store")
17743 (set_attr "mode" "DI")])
17745 (define_insn "*rep_stossi"
17746 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
17747 (set (match_operand:P 0 "register_operand" "=D")
17748 (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
17750 (match_operand:P 3 "register_operand" "0")))
17751 (set (mem:BLK (match_dup 3))
17753 (use (match_operand:SI 2 "register_operand" "a"))
17754 (use (match_dup 4))]
17755 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])
17756 && ix86_check_no_addr_space (insn)"
17757 "%^rep{%;} stos{l|d}"
17758 [(set_attr "type" "str")
17759 (set_attr "prefix_rep" "1")
17760 (set_attr "memory" "store")
17761 (set_attr "mode" "SI")])
17763 (define_insn "*rep_stosqi"
17764 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
17765 (set (match_operand:P 0 "register_operand" "=D")
17766 (plus:P (match_operand:P 3 "register_operand" "0")
17767 (match_operand:P 4 "register_operand" "1")))
17768 (set (mem:BLK (match_dup 3))
17770 (use (match_operand:QI 2 "register_operand" "a"))
17771 (use (match_dup 4))]
17772 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])
17773 && ix86_check_no_addr_space (insn)"
17775 [(set_attr "type" "str")
17776 (set_attr "prefix_rep" "1")
17777 (set_attr "memory" "store")
17778 (set (attr "prefix_rex")
17780 (match_test "<P:MODE>mode == DImode")
17782 (const_string "*")))
17783 (set_attr "mode" "QI")])
17785 (define_expand "cmpstrnsi"
17786 [(set (match_operand:SI 0 "register_operand")
17787 (compare:SI (match_operand:BLK 1 "general_operand")
17788 (match_operand:BLK 2 "general_operand")))
17789 (use (match_operand 3 "general_operand"))
17790 (use (match_operand 4 "immediate_operand"))]
17793 rtx addr1, addr2, out, outlow, count, countreg, align;
17795 if (optimize_insn_for_size_p () && !TARGET_INLINE_ALL_STRINGOPS)
17798 /* Can't use this if the user has appropriated ecx, esi or edi. */
17799 if (fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
17802 /* One of the strings must be a constant. If so, expand_builtin_strncmp()
17803 will have rewritten the length arg to be the minimum of the const string
17804 length and the actual length arg. If both strings are the same and
17805 shorter than the length arg, repz cmpsb will not stop at the 0 byte and
17806 will incorrectly base the results on chars past the 0 byte. */
17807 tree t1 = MEM_EXPR (operands[1]);
17808 tree t2 = MEM_EXPR (operands[2]);
17809 if (!((t1 && TREE_CODE (t1) == MEM_REF
17810 && TREE_CODE (TREE_OPERAND (t1, 0)) == ADDR_EXPR
17811 && TREE_CODE (TREE_OPERAND (TREE_OPERAND (t1, 0), 0)) == STRING_CST)
17812 || (t2 && TREE_CODE (t2) == MEM_REF
17813 && TREE_CODE (TREE_OPERAND (t2, 0)) == ADDR_EXPR
17814 && TREE_CODE (TREE_OPERAND (TREE_OPERAND (t2, 0), 0)) == STRING_CST)))
17819 out = gen_reg_rtx (SImode);
17821 addr1 = copy_addr_to_reg (XEXP (operands[1], 0));
17822 addr2 = copy_addr_to_reg (XEXP (operands[2], 0));
17823 if (addr1 != XEXP (operands[1], 0))
17824 operands[1] = replace_equiv_address_nv (operands[1], addr1);
17825 if (addr2 != XEXP (operands[2], 0))
17826 operands[2] = replace_equiv_address_nv (operands[2], addr2);
17828 count = operands[3];
17829 countreg = ix86_zero_extend_to_Pmode (count);
17831 /* %%% Iff we are testing strict equality, we can use known alignment
17832 to good advantage. This may be possible with combine, particularly
17833 once cc0 is dead. */
17834 align = operands[4];
17836 if (CONST_INT_P (count))
17838 if (INTVAL (count) == 0)
17840 emit_move_insn (operands[0], const0_rtx);
17843 emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
17844 operands[1], operands[2]));
17848 rtx (*gen_cmp) (rtx, rtx);
17850 gen_cmp = (TARGET_64BIT
17851 ? gen_cmpdi_1 : gen_cmpsi_1);
17853 emit_insn (gen_cmp (countreg, countreg));
17854 emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
17855 operands[1], operands[2]));
17858 outlow = gen_lowpart (QImode, out);
17859 emit_insn (gen_cmpintqi (outlow));
17860 emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
17862 if (operands[0] != out)
17863 emit_move_insn (operands[0], out);
17868 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
17870 (define_expand "cmpintqi"
17871 [(set (match_dup 1)
17872 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
17874 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
17875 (parallel [(set (match_operand:QI 0 "register_operand")
17876 (minus:QI (match_dup 1)
17878 (clobber (reg:CC FLAGS_REG))])]
17881 operands[1] = gen_reg_rtx (QImode);
17882 operands[2] = gen_reg_rtx (QImode);
17885 ;; memcmp recognizers. The `cmpsb' opcode does nothing if the count is
17886 ;; zero. Emit extra code to make sure that a zero-length compare is EQ.
17888 (define_expand "cmpstrnqi_nz_1"
17889 [(parallel [(set (reg:CC FLAGS_REG)
17890 (compare:CC (match_operand 4 "memory_operand")
17891 (match_operand 5 "memory_operand")))
17892 (use (match_operand 2 "register_operand"))
17893 (use (match_operand:SI 3 "immediate_operand"))
17894 (clobber (match_operand 0 "register_operand"))
17895 (clobber (match_operand 1 "register_operand"))
17896 (clobber (match_dup 2))])]
17900 ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
17903 (define_insn "*cmpstrnqi_nz_1"
17904 [(set (reg:CC FLAGS_REG)
17905 (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
17906 (mem:BLK (match_operand:P 5 "register_operand" "1"))))
17907 (use (match_operand:P 6 "register_operand" "2"))
17908 (use (match_operand:SI 3 "immediate_operand" "i"))
17909 (clobber (match_operand:P 0 "register_operand" "=S"))
17910 (clobber (match_operand:P 1 "register_operand" "=D"))
17911 (clobber (match_operand:P 2 "register_operand" "=c"))]
17912 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
17913 && ix86_check_no_addr_space (insn)"
17915 [(set_attr "type" "str")
17916 (set_attr "mode" "QI")
17917 (set (attr "prefix_rex")
17919 (match_test "<P:MODE>mode == DImode")
17921 (const_string "*")))
17922 (set_attr "prefix_rep" "1")])
17924 ;; The same, but the count is not known to not be zero.
17926 (define_expand "cmpstrnqi_1"
17927 [(parallel [(set (reg:CC FLAGS_REG)
17928 (if_then_else:CC (ne (match_operand 2 "register_operand")
17930 (compare:CC (match_operand 4 "memory_operand")
17931 (match_operand 5 "memory_operand"))
17933 (use (match_operand:SI 3 "immediate_operand"))
17934 (use (reg:CC FLAGS_REG))
17935 (clobber (match_operand 0 "register_operand"))
17936 (clobber (match_operand 1 "register_operand"))
17937 (clobber (match_dup 2))])]
17941 ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
17944 (define_insn "*cmpstrnqi_1"
17945 [(set (reg:CC FLAGS_REG)
17946 (if_then_else:CC (ne (match_operand:P 6 "register_operand" "2")
17948 (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
17949 (mem:BLK (match_operand:P 5 "register_operand" "1")))
17951 (use (match_operand:SI 3 "immediate_operand" "i"))
17952 (use (reg:CC FLAGS_REG))
17953 (clobber (match_operand:P 0 "register_operand" "=S"))
17954 (clobber (match_operand:P 1 "register_operand" "=D"))
17955 (clobber (match_operand:P 2 "register_operand" "=c"))]
17956 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
17957 && ix86_check_no_addr_space (insn)"
17959 [(set_attr "type" "str")
17960 (set_attr "mode" "QI")
17961 (set (attr "prefix_rex")
17963 (match_test "<P:MODE>mode == DImode")
17965 (const_string "*")))
17966 (set_attr "prefix_rep" "1")])
17968 (define_expand "strlen<mode>"
17969 [(set (match_operand:P 0 "register_operand")
17970 (unspec:P [(match_operand:BLK 1 "general_operand")
17971 (match_operand:QI 2 "immediate_operand")
17972 (match_operand 3 "immediate_operand")]
17976 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
17982 (define_expand "strlenqi_1"
17983 [(parallel [(set (match_operand 0 "register_operand")
17985 (clobber (match_operand 1 "register_operand"))
17986 (clobber (reg:CC FLAGS_REG))])]
17990 ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
17993 (define_insn "*strlenqi_1"
17994 [(set (match_operand:P 0 "register_operand" "=&c")
17995 (unspec:P [(mem:BLK (match_operand:P 5 "register_operand" "1"))
17996 (match_operand:QI 2 "register_operand" "a")
17997 (match_operand:P 3 "immediate_operand" "i")
17998 (match_operand:P 4 "register_operand" "0")] UNSPEC_SCAS))
17999 (clobber (match_operand:P 1 "register_operand" "=D"))
18000 (clobber (reg:CC FLAGS_REG))]
18001 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])
18002 && ix86_check_no_addr_space (insn)"
18003 "%^repnz{%;} scasb"
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 ;; Peephole optimizations to clean up after cmpstrn*. This should be
18014 ;; handled in combine, but it is not currently up to the task.
18015 ;; When used for their truth value, the cmpstrn* expanders generate
18024 ;; The intermediate three instructions are unnecessary.
18026 ;; This one handles cmpstrn*_nz_1...
18029 (set (reg:CC FLAGS_REG)
18030 (compare:CC (mem:BLK (match_operand 4 "register_operand"))
18031 (mem:BLK (match_operand 5 "register_operand"))))
18032 (use (match_operand 6 "register_operand"))
18033 (use (match_operand:SI 3 "immediate_operand"))
18034 (clobber (match_operand 0 "register_operand"))
18035 (clobber (match_operand 1 "register_operand"))
18036 (clobber (match_operand 2 "register_operand"))])
18037 (set (match_operand:QI 7 "register_operand")
18038 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
18039 (set (match_operand:QI 8 "register_operand")
18040 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
18041 (set (reg FLAGS_REG)
18042 (compare (match_dup 7) (match_dup 8)))
18044 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
18046 (set (reg:CC FLAGS_REG)
18047 (compare:CC (mem:BLK (match_dup 4))
18048 (mem:BLK (match_dup 5))))
18049 (use (match_dup 6))
18050 (use (match_dup 3))
18051 (clobber (match_dup 0))
18052 (clobber (match_dup 1))
18053 (clobber (match_dup 2))])])
18055 ;; ...and this one handles cmpstrn*_1.
18058 (set (reg:CC FLAGS_REG)
18059 (if_then_else:CC (ne (match_operand 6 "register_operand")
18061 (compare:CC (mem:BLK (match_operand 4 "register_operand"))
18062 (mem:BLK (match_operand 5 "register_operand")))
18064 (use (match_operand:SI 3 "immediate_operand"))
18065 (use (reg:CC FLAGS_REG))
18066 (clobber (match_operand 0 "register_operand"))
18067 (clobber (match_operand 1 "register_operand"))
18068 (clobber (match_operand 2 "register_operand"))])
18069 (set (match_operand:QI 7 "register_operand")
18070 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
18071 (set (match_operand:QI 8 "register_operand")
18072 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
18073 (set (reg FLAGS_REG)
18074 (compare (match_dup 7) (match_dup 8)))
18076 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
18078 (set (reg:CC FLAGS_REG)
18079 (if_then_else:CC (ne (match_dup 6)
18081 (compare:CC (mem:BLK (match_dup 4))
18082 (mem:BLK (match_dup 5)))
18084 (use (match_dup 3))
18085 (use (reg:CC FLAGS_REG))
18086 (clobber (match_dup 0))
18087 (clobber (match_dup 1))
18088 (clobber (match_dup 2))])])
18090 ;; Conditional move instructions.
18092 (define_expand "mov<mode>cc"
18093 [(set (match_operand:SWIM 0 "register_operand")
18094 (if_then_else:SWIM (match_operand 1 "comparison_operator")
18095 (match_operand:SWIM 2 "<general_operand>")
18096 (match_operand:SWIM 3 "<general_operand>")))]
18098 "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
18100 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
18101 ;; the register first winds up with `sbbl $0,reg', which is also weird.
18102 ;; So just document what we're doing explicitly.
18104 (define_expand "x86_mov<mode>cc_0_m1"
18106 [(set (match_operand:SWI48 0 "register_operand")
18107 (if_then_else:SWI48
18108 (match_operator:SWI48 2 "ix86_carry_flag_operator"
18109 [(match_operand 1 "flags_reg_operand")
18113 (clobber (reg:CC FLAGS_REG))])])
18115 (define_insn "*x86_mov<mode>cc_0_m1"
18116 [(set (match_operand:SWI48 0 "register_operand" "=r")
18117 (if_then_else:SWI48 (match_operator 1 "ix86_carry_flag_operator"
18118 [(reg FLAGS_REG) (const_int 0)])
18121 (clobber (reg:CC FLAGS_REG))]
18123 "sbb{<imodesuffix>}\t%0, %0"
18124 [(set_attr "type" "alu1")
18125 (set_attr "modrm_class" "op0")
18126 (set_attr "use_carry" "1")
18127 (set_attr "pent_pair" "pu")
18128 (set_attr "mode" "<MODE>")
18129 (set_attr "length_immediate" "0")])
18131 (define_insn "*x86_mov<mode>cc_0_m1_se"
18132 [(set (match_operand:SWI48 0 "register_operand" "=r")
18133 (sign_extract:SWI48 (match_operator 1 "ix86_carry_flag_operator"
18134 [(reg FLAGS_REG) (const_int 0)])
18137 (clobber (reg:CC FLAGS_REG))]
18139 "sbb{<imodesuffix>}\t%0, %0"
18140 [(set_attr "type" "alu1")
18141 (set_attr "modrm_class" "op0")
18142 (set_attr "use_carry" "1")
18143 (set_attr "pent_pair" "pu")
18144 (set_attr "mode" "<MODE>")
18145 (set_attr "length_immediate" "0")])
18147 (define_insn "*x86_mov<mode>cc_0_m1_neg"
18148 [(set (match_operand:SWI48 0 "register_operand" "=r")
18149 (neg:SWI48 (match_operator 1 "ix86_carry_flag_operator"
18150 [(reg FLAGS_REG) (const_int 0)])))
18151 (clobber (reg:CC FLAGS_REG))]
18153 "sbb{<imodesuffix>}\t%0, %0"
18154 [(set_attr "type" "alu1")
18155 (set_attr "modrm_class" "op0")
18156 (set_attr "use_carry" "1")
18157 (set_attr "pent_pair" "pu")
18158 (set_attr "mode" "<MODE>")
18159 (set_attr "length_immediate" "0")])
18161 (define_insn "*mov<mode>cc_noc"
18162 [(set (match_operand:SWI248 0 "register_operand" "=r,r")
18163 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
18164 [(reg FLAGS_REG) (const_int 0)])
18165 (match_operand:SWI248 2 "nonimmediate_operand" "rm,0")
18166 (match_operand:SWI248 3 "nonimmediate_operand" "0,rm")))]
18167 "TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
18169 cmov%O2%C1\t{%2, %0|%0, %2}
18170 cmov%O2%c1\t{%3, %0|%0, %3}"
18171 [(set_attr "type" "icmov")
18172 (set_attr "mode" "<MODE>")])
18174 (define_insn "*movsicc_noc_zext"
18175 [(set (match_operand:DI 0 "register_operand" "=r,r")
18176 (if_then_else:DI (match_operator 1 "ix86_comparison_operator"
18177 [(reg FLAGS_REG) (const_int 0)])
18179 (match_operand:SI 2 "nonimmediate_operand" "rm,0"))
18181 (match_operand:SI 3 "nonimmediate_operand" "0,rm"))))]
18183 && TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
18185 cmov%O2%C1\t{%2, %k0|%k0, %2}
18186 cmov%O2%c1\t{%3, %k0|%k0, %3}"
18187 [(set_attr "type" "icmov")
18188 (set_attr "mode" "SI")])
18190 ;; Don't do conditional moves with memory inputs. This splitter helps
18191 ;; register starved x86_32 by forcing inputs into registers before reload.
18193 [(set (match_operand:SWI248 0 "register_operand")
18194 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
18195 [(reg FLAGS_REG) (const_int 0)])
18196 (match_operand:SWI248 2 "nonimmediate_operand")
18197 (match_operand:SWI248 3 "nonimmediate_operand")))]
18198 "!TARGET_64BIT && TARGET_CMOVE
18199 && TARGET_AVOID_MEM_OPND_FOR_CMOVE
18200 && (MEM_P (operands[2]) || MEM_P (operands[3]))
18201 && can_create_pseudo_p ()
18202 && optimize_insn_for_speed_p ()"
18203 [(set (match_dup 0)
18204 (if_then_else:SWI248 (match_dup 1) (match_dup 2) (match_dup 3)))]
18206 if (MEM_P (operands[2]))
18207 operands[2] = force_reg (<MODE>mode, operands[2]);
18208 if (MEM_P (operands[3]))
18209 operands[3] = force_reg (<MODE>mode, operands[3]);
18212 (define_insn "*movqicc_noc"
18213 [(set (match_operand:QI 0 "register_operand" "=r,r")
18214 (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
18215 [(reg FLAGS_REG) (const_int 0)])
18216 (match_operand:QI 2 "register_operand" "r,0")
18217 (match_operand:QI 3 "register_operand" "0,r")))]
18218 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
18220 [(set_attr "type" "icmov")
18221 (set_attr "mode" "QI")])
18224 [(set (match_operand:SWI12 0 "register_operand")
18225 (if_then_else:SWI12 (match_operator 1 "ix86_comparison_operator"
18226 [(reg FLAGS_REG) (const_int 0)])
18227 (match_operand:SWI12 2 "register_operand")
18228 (match_operand:SWI12 3 "register_operand")))]
18229 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL
18230 && reload_completed"
18231 [(set (match_dup 0)
18232 (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
18234 operands[0] = gen_lowpart (SImode, operands[0]);
18235 operands[2] = gen_lowpart (SImode, operands[2]);
18236 operands[3] = gen_lowpart (SImode, operands[3]);
18239 ;; Don't do conditional moves with memory inputs
18241 [(match_scratch:SWI248 4 "r")
18242 (set (match_operand:SWI248 0 "register_operand")
18243 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
18244 [(reg FLAGS_REG) (const_int 0)])
18245 (match_operand:SWI248 2 "nonimmediate_operand")
18246 (match_operand:SWI248 3 "nonimmediate_operand")))]
18247 "TARGET_CMOVE && TARGET_AVOID_MEM_OPND_FOR_CMOVE
18248 && (MEM_P (operands[2]) || MEM_P (operands[3]))
18249 && optimize_insn_for_speed_p ()"
18250 [(set (match_dup 4) (match_dup 5))
18252 (if_then_else:SWI248 (match_dup 1) (match_dup 2) (match_dup 3)))]
18254 if (MEM_P (operands[2]))
18256 operands[5] = operands[2];
18257 operands[2] = operands[4];
18259 else if (MEM_P (operands[3]))
18261 operands[5] = operands[3];
18262 operands[3] = operands[4];
18265 gcc_unreachable ();
18269 [(match_scratch:SI 4 "r")
18270 (set (match_operand:DI 0 "register_operand")
18271 (if_then_else:DI (match_operator 1 "ix86_comparison_operator"
18272 [(reg FLAGS_REG) (const_int 0)])
18274 (match_operand:SI 2 "nonimmediate_operand"))
18276 (match_operand:SI 3 "nonimmediate_operand"))))]
18278 && TARGET_CMOVE && TARGET_AVOID_MEM_OPND_FOR_CMOVE
18279 && (MEM_P (operands[2]) || MEM_P (operands[3]))
18280 && optimize_insn_for_speed_p ()"
18281 [(set (match_dup 4) (match_dup 5))
18283 (if_then_else:DI (match_dup 1)
18284 (zero_extend:DI (match_dup 2))
18285 (zero_extend:DI (match_dup 3))))]
18287 if (MEM_P (operands[2]))
18289 operands[5] = operands[2];
18290 operands[2] = operands[4];
18292 else if (MEM_P (operands[3]))
18294 operands[5] = operands[3];
18295 operands[3] = operands[4];
18298 gcc_unreachable ();
18301 (define_expand "mov<mode>cc"
18302 [(set (match_operand:X87MODEF 0 "register_operand")
18303 (if_then_else:X87MODEF
18304 (match_operand 1 "comparison_operator")
18305 (match_operand:X87MODEF 2 "register_operand")
18306 (match_operand:X87MODEF 3 "register_operand")))]
18307 "(TARGET_80387 && TARGET_CMOVE)
18308 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
18309 "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
18311 (define_insn "*movxfcc_1"
18312 [(set (match_operand:XF 0 "register_operand" "=f,f")
18313 (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
18314 [(reg FLAGS_REG) (const_int 0)])
18315 (match_operand:XF 2 "register_operand" "f,0")
18316 (match_operand:XF 3 "register_operand" "0,f")))]
18317 "TARGET_80387 && TARGET_CMOVE"
18319 fcmov%F1\t{%2, %0|%0, %2}
18320 fcmov%f1\t{%3, %0|%0, %3}"
18321 [(set_attr "type" "fcmov")
18322 (set_attr "mode" "XF")])
18324 (define_insn "*movdfcc_1"
18325 [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r,r ,r")
18326 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
18327 [(reg FLAGS_REG) (const_int 0)])
18328 (match_operand:DF 2 "nonimmediate_operand"
18330 (match_operand:DF 3 "nonimmediate_operand"
18331 "0 ,f,0 ,rm,0, rm")))]
18332 "TARGET_80387 && TARGET_CMOVE
18333 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
18335 fcmov%F1\t{%2, %0|%0, %2}
18336 fcmov%f1\t{%3, %0|%0, %3}
18339 cmov%O2%C1\t{%2, %0|%0, %2}
18340 cmov%O2%c1\t{%3, %0|%0, %3}"
18341 [(set_attr "isa" "*,*,nox64,nox64,x64,x64")
18342 (set_attr "type" "fcmov,fcmov,multi,multi,icmov,icmov")
18343 (set_attr "mode" "DF,DF,DI,DI,DI,DI")])
18346 [(set (match_operand:DF 0 "general_reg_operand")
18347 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
18348 [(reg FLAGS_REG) (const_int 0)])
18349 (match_operand:DF 2 "nonimmediate_operand")
18350 (match_operand:DF 3 "nonimmediate_operand")))]
18351 "!TARGET_64BIT && reload_completed"
18352 [(set (match_dup 2)
18353 (if_then_else:SI (match_dup 1) (match_dup 4) (match_dup 5)))
18355 (if_then_else:SI (match_dup 1) (match_dup 6) (match_dup 7)))]
18357 split_double_mode (DImode, &operands[2], 2, &operands[4], &operands[6]);
18358 split_double_mode (DImode, &operands[0], 1, &operands[2], &operands[3]);
18361 (define_insn "*movsfcc_1_387"
18362 [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
18363 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
18364 [(reg FLAGS_REG) (const_int 0)])
18365 (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
18366 (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
18367 "TARGET_80387 && TARGET_CMOVE
18368 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
18370 fcmov%F1\t{%2, %0|%0, %2}
18371 fcmov%f1\t{%3, %0|%0, %3}
18372 cmov%O2%C1\t{%2, %0|%0, %2}
18373 cmov%O2%c1\t{%3, %0|%0, %3}"
18374 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
18375 (set_attr "mode" "SF,SF,SI,SI")])
18377 ;; Don't do conditional moves with memory inputs. This splitter helps
18378 ;; register starved x86_32 by forcing inputs into registers before reload.
18380 [(set (match_operand:MODEF 0 "register_operand")
18381 (if_then_else:MODEF (match_operator 1 "ix86_comparison_operator"
18382 [(reg FLAGS_REG) (const_int 0)])
18383 (match_operand:MODEF 2 "nonimmediate_operand")
18384 (match_operand:MODEF 3 "nonimmediate_operand")))]
18385 "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
18386 && TARGET_AVOID_MEM_OPND_FOR_CMOVE
18387 && (MEM_P (operands[2]) || MEM_P (operands[3]))
18388 && can_create_pseudo_p ()
18389 && optimize_insn_for_speed_p ()"
18390 [(set (match_dup 0)
18391 (if_then_else:MODEF (match_dup 1) (match_dup 2) (match_dup 3)))]
18393 if (MEM_P (operands[2]))
18394 operands[2] = force_reg (<MODE>mode, operands[2]);
18395 if (MEM_P (operands[3]))
18396 operands[3] = force_reg (<MODE>mode, operands[3]);
18399 ;; Don't do conditional moves with memory inputs
18401 [(match_scratch:MODEF 4 "r")
18402 (set (match_operand:MODEF 0 "general_reg_operand")
18403 (if_then_else:MODEF (match_operator 1 "fcmov_comparison_operator"
18404 [(reg FLAGS_REG) (const_int 0)])
18405 (match_operand:MODEF 2 "nonimmediate_operand")
18406 (match_operand:MODEF 3 "nonimmediate_operand")))]
18407 "(<MODE>mode != DFmode || TARGET_64BIT)
18408 && TARGET_80387 && TARGET_CMOVE
18409 && TARGET_AVOID_MEM_OPND_FOR_CMOVE
18410 && (MEM_P (operands[2]) || MEM_P (operands[3]))
18411 && optimize_insn_for_speed_p ()"
18412 [(set (match_dup 4) (match_dup 5))
18414 (if_then_else:MODEF (match_dup 1) (match_dup 2) (match_dup 3)))]
18416 if (MEM_P (operands[2]))
18418 operands[5] = operands[2];
18419 operands[2] = operands[4];
18421 else if (MEM_P (operands[3]))
18423 operands[5] = operands[3];
18424 operands[3] = operands[4];
18427 gcc_unreachable ();
18430 ;; All moves in XOP pcmov instructions are 128 bits and hence we restrict
18431 ;; the scalar versions to have only XMM registers as operands.
18433 ;; XOP conditional move
18434 (define_insn "*xop_pcmov_<mode>"
18435 [(set (match_operand:MODEF 0 "register_operand" "=x")
18436 (if_then_else:MODEF
18437 (match_operand:MODEF 1 "register_operand" "x")
18438 (match_operand:MODEF 2 "register_operand" "x")
18439 (match_operand:MODEF 3 "register_operand" "x")))]
18441 "vpcmov\t{%1, %3, %2, %0|%0, %2, %3, %1}"
18442 [(set_attr "type" "sse4arg")])
18444 ;; These versions of the min/max patterns are intentionally ignorant of
18445 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
18446 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
18447 ;; are undefined in this condition, we're certain this is correct.
18449 (define_insn "<code><mode>3"
18450 [(set (match_operand:MODEF 0 "register_operand" "=x,v")
18452 (match_operand:MODEF 1 "nonimmediate_operand" "%0,v")
18453 (match_operand:MODEF 2 "nonimmediate_operand" "xm,vm")))]
18454 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
18456 <maxmin_float><ssemodesuffix>\t{%2, %0|%0, %2}
18457 v<maxmin_float><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
18458 [(set_attr "isa" "noavx,avx")
18459 (set_attr "prefix" "orig,vex")
18460 (set_attr "type" "sseadd")
18461 (set_attr "mode" "<MODE>")])
18463 ;; These versions of the min/max patterns implement exactly the operations
18464 ;; min = (op1 < op2 ? op1 : op2)
18465 ;; max = (!(op1 < op2) ? op1 : op2)
18466 ;; Their operands are not commutative, and thus they may be used in the
18467 ;; presence of -0.0 and NaN.
18469 (define_insn "*ieee_s<ieee_maxmin><mode>3"
18470 [(set (match_operand:MODEF 0 "register_operand" "=x,v")
18472 [(match_operand:MODEF 1 "register_operand" "0,v")
18473 (match_operand:MODEF 2 "nonimmediate_operand" "xm,vm")]
18475 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
18477 <ieee_maxmin><ssemodesuffix>\t{%2, %0|%0, %2}
18478 v<ieee_maxmin><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
18479 [(set_attr "isa" "noavx,avx")
18480 (set_attr "prefix" "orig,maybe_evex")
18481 (set_attr "type" "sseadd")
18482 (set_attr "mode" "<MODE>")])
18484 ;; Make two stack loads independent:
18486 ;; fld %st(0) -> fld bb
18487 ;; fmul bb fmul %st(1), %st
18489 ;; Actually we only match the last two instructions for simplicity.
18492 [(set (match_operand 0 "fp_register_operand")
18493 (match_operand 1 "fp_register_operand"))
18495 (match_operator 2 "binary_fp_operator"
18497 (match_operand 3 "memory_operand")]))]
18498 "REGNO (operands[0]) != REGNO (operands[1])"
18499 [(set (match_dup 0) (match_dup 3))
18502 [(match_dup 5) (match_dup 4)]))]
18504 operands[4] = operands[0];
18505 operands[5] = operands[1];
18507 /* The % modifier is not operational anymore in peephole2's, so we have to
18508 swap the operands manually in the case of addition and multiplication. */
18509 if (COMMUTATIVE_ARITH_P (operands[2]))
18510 std::swap (operands[4], operands[5]);
18514 [(set (match_operand 0 "fp_register_operand")
18515 (match_operand 1 "fp_register_operand"))
18517 (match_operator 2 "binary_fp_operator"
18518 [(match_operand 3 "memory_operand")
18520 "REGNO (operands[0]) != REGNO (operands[1])"
18521 [(set (match_dup 0) (match_dup 3))
18524 [(match_dup 4) (match_dup 5)]))]
18526 operands[4] = operands[0];
18527 operands[5] = operands[1];
18529 /* The % modifier is not operational anymore in peephole2's, so we have to
18530 swap the operands manually in the case of addition and multiplication. */
18531 if (COMMUTATIVE_ARITH_P (operands[2]))
18532 std::swap (operands[4], operands[5]);
18535 ;; Conditional addition patterns
18536 (define_expand "add<mode>cc"
18537 [(match_operand:SWI 0 "register_operand")
18538 (match_operand 1 "ordered_comparison_operator")
18539 (match_operand:SWI 2 "register_operand")
18540 (match_operand:SWI 3 "const_int_operand")]
18542 "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
18544 ;; Misc patterns (?)
18546 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
18547 ;; Otherwise there will be nothing to keep
18549 ;; [(set (reg ebp) (reg esp))]
18550 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
18551 ;; (clobber (eflags)]
18552 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
18554 ;; in proper program order.
18556 (define_insn "pro_epilogue_adjust_stack_<mode>_add"
18557 [(set (match_operand:P 0 "register_operand" "=r,r")
18558 (plus:P (match_operand:P 1 "register_operand" "0,r")
18559 (match_operand:P 2 "<nonmemory_operand>" "r<i>,l<i>")))
18560 (clobber (reg:CC FLAGS_REG))
18561 (clobber (mem:BLK (scratch)))]
18564 switch (get_attr_type (insn))
18567 return "mov{<imodesuffix>}\t{%1, %0|%0, %1}";
18570 gcc_assert (rtx_equal_p (operands[0], operands[1]));
18571 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
18572 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
18574 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
18577 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
18578 return "lea{<imodesuffix>}\t{%E2, %0|%0, %E2}";
18581 [(set (attr "type")
18582 (cond [(and (eq_attr "alternative" "0")
18583 (not (match_test "TARGET_OPT_AGU")))
18584 (const_string "alu")
18585 (match_operand:<MODE> 2 "const0_operand")
18586 (const_string "imov")
18588 (const_string "lea")))
18589 (set (attr "length_immediate")
18590 (cond [(eq_attr "type" "imov")
18592 (and (eq_attr "type" "alu")
18593 (match_operand 2 "const128_operand"))
18596 (const_string "*")))
18597 (set_attr "mode" "<MODE>")])
18599 (define_insn "pro_epilogue_adjust_stack_<mode>_sub"
18600 [(set (match_operand:P 0 "register_operand" "=r")
18601 (minus:P (match_operand:P 1 "register_operand" "0")
18602 (match_operand:P 2 "register_operand" "r")))
18603 (clobber (reg:CC FLAGS_REG))
18604 (clobber (mem:BLK (scratch)))]
18606 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
18607 [(set_attr "type" "alu")
18608 (set_attr "mode" "<MODE>")])
18610 (define_insn "allocate_stack_worker_probe_<mode>"
18611 [(set (match_operand:P 0 "register_operand" "=a")
18612 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
18613 UNSPECV_STACK_PROBE))
18614 (clobber (reg:CC FLAGS_REG))]
18615 "ix86_target_stack_probe ()"
18616 "call\t___chkstk_ms"
18617 [(set_attr "type" "multi")
18618 (set_attr "length" "5")])
18620 (define_expand "allocate_stack"
18621 [(match_operand 0 "register_operand")
18622 (match_operand 1 "general_operand")]
18623 "ix86_target_stack_probe ()"
18627 #ifndef CHECK_STACK_LIMIT
18628 #define CHECK_STACK_LIMIT 0
18631 if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
18632 && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
18636 rtx (*insn) (rtx, rtx);
18638 x = copy_to_mode_reg (Pmode, operands[1]);
18640 insn = (TARGET_64BIT
18641 ? gen_allocate_stack_worker_probe_di
18642 : gen_allocate_stack_worker_probe_si);
18644 emit_insn (insn (x, x));
18647 x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, x,
18648 stack_pointer_rtx, 0, OPTAB_DIRECT);
18650 if (x != stack_pointer_rtx)
18651 emit_move_insn (stack_pointer_rtx, x);
18653 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
18657 (define_expand "probe_stack"
18658 [(match_operand 0 "memory_operand")]
18661 rtx (*insn) (rtx, rtx)
18662 = (GET_MODE (operands[0]) == DImode
18663 ? gen_probe_stack_di : gen_probe_stack_si);
18665 emit_insn (insn (operands[0], const0_rtx));
18669 ;; Use OR for stack probes, this is shorter.
18670 (define_insn "probe_stack_<mode>"
18671 [(set (match_operand:W 0 "memory_operand" "=m")
18672 (unspec:W [(match_operand:W 1 "const0_operand")]
18673 UNSPEC_PROBE_STACK))
18674 (clobber (reg:CC FLAGS_REG))]
18676 "or{<imodesuffix>}\t{%1, %0|%0, %1}"
18677 [(set_attr "type" "alu1")
18678 (set_attr "mode" "<MODE>")
18679 (set_attr "length_immediate" "1")])
18681 (define_insn "adjust_stack_and_probe<mode>"
18682 [(set (match_operand:P 0 "register_operand" "=r")
18683 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
18684 UNSPECV_PROBE_STACK_RANGE))
18685 (set (reg:P SP_REG)
18686 (minus:P (reg:P SP_REG) (match_operand:P 2 "const_int_operand" "n")))
18687 (clobber (reg:CC FLAGS_REG))
18688 (clobber (mem:BLK (scratch)))]
18690 "* return output_adjust_stack_and_probe (operands[0]);"
18691 [(set_attr "type" "multi")])
18693 (define_insn "probe_stack_range<mode>"
18694 [(set (match_operand:P 0 "register_operand" "=r")
18695 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
18696 (match_operand:P 2 "const_int_operand" "n")]
18697 UNSPECV_PROBE_STACK_RANGE))
18698 (clobber (reg:CC FLAGS_REG))]
18700 "* return output_probe_stack_range (operands[0], operands[2]);"
18701 [(set_attr "type" "multi")])
18703 (define_expand "builtin_setjmp_receiver"
18704 [(label_ref (match_operand 0))]
18705 "!TARGET_64BIT && flag_pic"
18711 rtx_code_label *label_rtx = gen_label_rtx ();
18712 emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
18713 xops[0] = xops[1] = pic_offset_table_rtx;
18714 xops[2] = machopic_gen_offset (gen_rtx_LABEL_REF (SImode, label_rtx));
18715 ix86_expand_binary_operator (MINUS, SImode, xops);
18719 emit_insn (gen_set_got (pic_offset_table_rtx));
18723 (define_expand "save_stack_nonlocal"
18724 [(set (match_operand 0 "memory_operand")
18725 (match_operand 1 "register_operand"))]
18729 if ((flag_cf_protection & CF_RETURN))
18731 /* Copy shadow stack pointer to the first slot and stack ppointer
18732 to the second slot. */
18733 rtx ssp_slot = adjust_address (operands[0], word_mode, 0);
18734 stack_slot = adjust_address (operands[0], Pmode, UNITS_PER_WORD);
18735 rtx ssp = gen_reg_rtx (word_mode);
18736 emit_insn ((word_mode == SImode)
18737 ? gen_rdsspsi (ssp)
18738 : gen_rdsspdi (ssp));
18739 emit_move_insn (ssp_slot, ssp);
18742 stack_slot = adjust_address (operands[0], Pmode, 0);
18743 emit_move_insn (stack_slot, operands[1]);
18747 (define_expand "restore_stack_nonlocal"
18748 [(set (match_operand 0 "register_operand" "")
18749 (match_operand 1 "memory_operand" ""))]
18753 if ((flag_cf_protection & CF_RETURN))
18755 /* Restore shadow stack pointer from the first slot and stack
18756 pointer from the second slot. */
18757 rtx ssp_slot = adjust_address (operands[1], word_mode, 0);
18758 stack_slot = adjust_address (operands[1], Pmode, UNITS_PER_WORD);
18760 rtx flags, jump, noadj_label, inc_label, loop_label;
18761 rtx reg_adj, reg_ssp, tmp, clob;
18763 /* Get the current shadow stack pointer. The code below will check if
18764 SHSTK feature is enabled. If it is not enabled the RDSSP instruction
18766 reg_ssp = gen_reg_rtx (word_mode);
18767 emit_insn (gen_rtx_SET (reg_ssp, const0_rtx));
18768 emit_insn ((word_mode == SImode)
18769 ? gen_rdsspsi (reg_ssp)
18770 : gen_rdsspdi (reg_ssp));
18772 /* Compare through substraction the saved and the current ssp to decide
18773 if ssp has to be adjusted. */
18774 tmp = gen_rtx_SET (reg_ssp, gen_rtx_MINUS (word_mode, reg_ssp,
18776 clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
18777 tmp = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, tmp, clob));
18780 /* Compare and jump over adjustment code. */
18781 noadj_label = gen_label_rtx ();
18782 flags = gen_rtx_REG (CCZmode, FLAGS_REG);
18783 tmp = gen_rtx_EQ (VOIDmode, flags, const0_rtx);
18784 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
18785 gen_rtx_LABEL_REF (VOIDmode, noadj_label),
18787 jump = emit_jump_insn (gen_rtx_SET (pc_rtx, tmp));
18788 JUMP_LABEL (jump) = noadj_label;
18790 /* Compute the numebr of frames to adjust. */
18791 reg_adj = gen_lowpart (ptr_mode, reg_ssp);
18792 tmp = gen_rtx_SET (reg_adj,
18793 gen_rtx_LSHIFTRT (ptr_mode,
18794 negate_rtx (ptr_mode, reg_adj),
18795 GEN_INT ((word_mode == SImode)
18798 clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
18799 tmp = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, tmp, clob));
18802 /* Check if number of frames <= 255 so no loop is needed. */
18803 tmp = gen_rtx_COMPARE (CCmode, reg_adj, GEN_INT (255));
18804 flags = gen_rtx_REG (CCmode, FLAGS_REG);
18805 emit_insn (gen_rtx_SET (flags, tmp));
18807 inc_label = gen_label_rtx ();
18808 tmp = gen_rtx_LEU (VOIDmode, flags, const0_rtx);
18809 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
18810 gen_rtx_LABEL_REF (VOIDmode, inc_label),
18812 jump = emit_jump_insn (gen_rtx_SET (pc_rtx, tmp));
18813 JUMP_LABEL (jump) = inc_label;
18815 rtx reg_255 = gen_reg_rtx (word_mode);
18816 emit_move_insn (reg_255, GEN_INT (255));
18818 /* Adjust the ssp in a loop. */
18819 loop_label = gen_label_rtx ();
18820 emit_label (loop_label);
18821 LABEL_NUSES (loop_label) = 1;
18823 emit_insn ((word_mode == SImode)
18824 ? gen_incsspsi (reg_255)
18825 : gen_incsspdi (reg_255));
18826 tmp = gen_rtx_SET (reg_adj, gen_rtx_MINUS (ptr_mode,
18829 clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
18830 tmp = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, tmp, clob));
18833 tmp = gen_rtx_COMPARE (CCmode, reg_adj, GEN_INT (255));
18834 flags = gen_rtx_REG (CCmode, FLAGS_REG);
18835 emit_insn (gen_rtx_SET (flags, tmp));
18837 /* Jump to the loop label. */
18838 tmp = gen_rtx_GTU (VOIDmode, flags, const0_rtx);
18839 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
18840 gen_rtx_LABEL_REF (VOIDmode, loop_label),
18842 jump = emit_jump_insn (gen_rtx_SET (pc_rtx, tmp));
18843 JUMP_LABEL (jump) = loop_label;
18845 emit_label (inc_label);
18846 LABEL_NUSES (inc_label) = 1;
18847 emit_insn ((word_mode == SImode)
18848 ? gen_incsspsi (reg_ssp)
18849 : gen_incsspdi (reg_ssp));
18851 emit_label (noadj_label);
18852 LABEL_NUSES (noadj_label) = 1;
18855 stack_slot = adjust_address (operands[1], Pmode, 0);
18856 emit_move_insn (operands[0], stack_slot);
18861 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
18862 ;; Do not split instructions with mask registers.
18864 [(set (match_operand 0 "general_reg_operand")
18865 (match_operator 3 "promotable_binary_operator"
18866 [(match_operand 1 "general_reg_operand")
18867 (match_operand 2 "aligned_operand")]))
18868 (clobber (reg:CC FLAGS_REG))]
18869 "! TARGET_PARTIAL_REG_STALL && reload_completed
18870 && ((GET_MODE (operands[0]) == HImode
18871 && ((optimize_function_for_speed_p (cfun) && !TARGET_FAST_PREFIX)
18872 /* ??? next two lines just !satisfies_constraint_K (...) */
18873 || !CONST_INT_P (operands[2])
18874 || satisfies_constraint_K (operands[2])))
18875 || (GET_MODE (operands[0]) == QImode
18876 && (TARGET_PROMOTE_QImode || optimize_function_for_size_p (cfun))))"
18877 [(parallel [(set (match_dup 0)
18878 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
18879 (clobber (reg:CC FLAGS_REG))])]
18881 operands[0] = gen_lowpart (SImode, operands[0]);
18882 operands[1] = gen_lowpart (SImode, operands[1]);
18883 if (GET_CODE (operands[3]) != ASHIFT)
18884 operands[2] = gen_lowpart (SImode, operands[2]);
18885 operands[3] = shallow_copy_rtx (operands[3]);
18886 PUT_MODE (operands[3], SImode);
18889 ; Promote the QImode tests, as i386 has encoding of the AND
18890 ; instruction with 32-bit sign-extended immediate and thus the
18891 ; instruction size is unchanged, except in the %eax case for
18892 ; which it is increased by one byte, hence the ! optimize_size.
18894 [(set (match_operand 0 "flags_reg_operand")
18895 (match_operator 2 "compare_operator"
18896 [(and (match_operand 3 "aligned_operand")
18897 (match_operand 4 "const_int_operand"))
18899 (set (match_operand 1 "register_operand")
18900 (and (match_dup 3) (match_dup 4)))]
18901 "! TARGET_PARTIAL_REG_STALL && reload_completed
18902 && optimize_insn_for_speed_p ()
18903 && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
18904 || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))
18905 /* Ensure that the operand will remain sign-extended immediate. */
18906 && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)"
18907 [(parallel [(set (match_dup 0)
18908 (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
18911 (and:SI (match_dup 3) (match_dup 4)))])]
18914 = gen_int_mode (INTVAL (operands[4])
18915 & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
18916 operands[1] = gen_lowpart (SImode, operands[1]);
18917 operands[3] = gen_lowpart (SImode, operands[3]);
18920 ; Don't promote the QImode tests, as i386 doesn't have encoding of
18921 ; the TEST instruction with 32-bit sign-extended immediate and thus
18922 ; the instruction size would at least double, which is not what we
18923 ; want even with ! optimize_size.
18925 [(set (match_operand 0 "flags_reg_operand")
18926 (match_operator 1 "compare_operator"
18927 [(and (match_operand:HI 2 "aligned_operand")
18928 (match_operand:HI 3 "const_int_operand"))
18930 "! TARGET_PARTIAL_REG_STALL && reload_completed
18931 && ! TARGET_FAST_PREFIX
18932 && optimize_insn_for_speed_p ()
18933 /* Ensure that the operand will remain sign-extended immediate. */
18934 && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)"
18935 [(set (match_dup 0)
18936 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
18940 = gen_int_mode (INTVAL (operands[3])
18941 & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
18942 operands[2] = gen_lowpart (SImode, operands[2]);
18946 [(set (match_operand 0 "register_operand")
18947 (neg (match_operand 1 "register_operand")))
18948 (clobber (reg:CC FLAGS_REG))]
18949 "! TARGET_PARTIAL_REG_STALL && reload_completed
18950 && (GET_MODE (operands[0]) == HImode
18951 || (GET_MODE (operands[0]) == QImode
18952 && (TARGET_PROMOTE_QImode
18953 || optimize_insn_for_size_p ())))"
18954 [(parallel [(set (match_dup 0)
18955 (neg:SI (match_dup 1)))
18956 (clobber (reg:CC FLAGS_REG))])]
18958 operands[0] = gen_lowpart (SImode, operands[0]);
18959 operands[1] = gen_lowpart (SImode, operands[1]);
18962 ;; Do not split instructions with mask regs.
18964 [(set (match_operand 0 "general_reg_operand")
18965 (not (match_operand 1 "general_reg_operand")))]
18966 "! TARGET_PARTIAL_REG_STALL && reload_completed
18967 && (GET_MODE (operands[0]) == HImode
18968 || (GET_MODE (operands[0]) == QImode
18969 && (TARGET_PROMOTE_QImode
18970 || optimize_insn_for_size_p ())))"
18971 [(set (match_dup 0)
18972 (not:SI (match_dup 1)))]
18974 operands[0] = gen_lowpart (SImode, operands[0]);
18975 operands[1] = gen_lowpart (SImode, operands[1]);
18978 ;; RTL Peephole optimizations, run before sched2. These primarily look to
18979 ;; transform a complex memory operation into two memory to register operations.
18981 ;; Don't push memory operands
18983 [(set (match_operand:SWI 0 "push_operand")
18984 (match_operand:SWI 1 "memory_operand"))
18985 (match_scratch:SWI 2 "<r>")]
18986 "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
18987 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
18988 [(set (match_dup 2) (match_dup 1))
18989 (set (match_dup 0) (match_dup 2))])
18991 ;; We need to handle SFmode only, because DFmode and XFmode are split to
18994 [(set (match_operand:SF 0 "push_operand")
18995 (match_operand:SF 1 "memory_operand"))
18996 (match_scratch:SF 2 "r")]
18997 "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
18998 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
18999 [(set (match_dup 2) (match_dup 1))
19000 (set (match_dup 0) (match_dup 2))])
19002 ;; Don't move an immediate directly to memory when the instruction
19003 ;; gets too big, or if LCP stalls are a problem for 16-bit moves.
19005 [(match_scratch:SWI124 1 "<r>")
19006 (set (match_operand:SWI124 0 "memory_operand")
19008 "optimize_insn_for_speed_p ()
19009 && ((<MODE>mode == HImode
19010 && TARGET_LCP_STALL)
19011 || (!TARGET_USE_MOV0
19012 && TARGET_SPLIT_LONG_MOVES
19013 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn))
19014 && peep2_regno_dead_p (0, FLAGS_REG)"
19015 [(parallel [(set (match_dup 2) (const_int 0))
19016 (clobber (reg:CC FLAGS_REG))])
19017 (set (match_dup 0) (match_dup 1))]
19018 "operands[2] = gen_lowpart (SImode, operands[1]);")
19021 [(match_scratch:SWI124 2 "<r>")
19022 (set (match_operand:SWI124 0 "memory_operand")
19023 (match_operand:SWI124 1 "immediate_operand"))]
19024 "optimize_insn_for_speed_p ()
19025 && ((<MODE>mode == HImode
19026 && TARGET_LCP_STALL)
19027 || (TARGET_SPLIT_LONG_MOVES
19028 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn))"
19029 [(set (match_dup 2) (match_dup 1))
19030 (set (match_dup 0) (match_dup 2))])
19032 ;; Don't compare memory with zero, load and use a test instead.
19034 [(set (match_operand 0 "flags_reg_operand")
19035 (match_operator 1 "compare_operator"
19036 [(match_operand:SI 2 "memory_operand")
19038 (match_scratch:SI 3 "r")]
19039 "optimize_insn_for_speed_p () && ix86_match_ccmode (insn, CCNOmode)"
19040 [(set (match_dup 3) (match_dup 2))
19041 (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))])
19043 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
19044 ;; Don't split NOTs with a displacement operand, because resulting XOR
19045 ;; will not be pairable anyway.
19047 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
19048 ;; represented using a modRM byte. The XOR replacement is long decoded,
19049 ;; so this split helps here as well.
19051 ;; Note: Can't do this as a regular split because we can't get proper
19052 ;; lifetime information then.
19055 [(set (match_operand:SWI124 0 "nonimmediate_gr_operand")
19056 (not:SWI124 (match_operand:SWI124 1 "nonimmediate_gr_operand")))]
19057 "optimize_insn_for_speed_p ()
19058 && ((TARGET_NOT_UNPAIRABLE
19059 && (!MEM_P (operands[0])
19060 || !memory_displacement_operand (operands[0], <MODE>mode)))
19061 || (TARGET_NOT_VECTORMODE
19062 && long_memory_operand (operands[0], <MODE>mode)))
19063 && peep2_regno_dead_p (0, FLAGS_REG)"
19064 [(parallel [(set (match_dup 0)
19065 (xor:SWI124 (match_dup 1) (const_int -1)))
19066 (clobber (reg:CC FLAGS_REG))])])
19068 ;; Non pairable "test imm, reg" instructions can be translated to
19069 ;; "and imm, reg" if reg dies. The "and" form is also shorter (one
19070 ;; byte opcode instead of two, have a short form for byte operands),
19071 ;; so do it for other CPUs as well. Given that the value was dead,
19072 ;; this should not create any new dependencies. Pass on the sub-word
19073 ;; versions if we're concerned about partial register stalls.
19076 [(set (match_operand 0 "flags_reg_operand")
19077 (match_operator 1 "compare_operator"
19078 [(and:SI (match_operand:SI 2 "register_operand")
19079 (match_operand:SI 3 "immediate_operand"))
19081 "ix86_match_ccmode (insn, CCNOmode)
19082 && (REGNO (operands[2]) != AX_REG
19083 || satisfies_constraint_K (operands[3]))
19084 && peep2_reg_dead_p (1, operands[2])"
19086 [(set (match_dup 0)
19087 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
19090 (and:SI (match_dup 2) (match_dup 3)))])])
19092 ;; We don't need to handle HImode case, because it will be promoted to SImode
19093 ;; on ! TARGET_PARTIAL_REG_STALL
19096 [(set (match_operand 0 "flags_reg_operand")
19097 (match_operator 1 "compare_operator"
19098 [(and:QI (match_operand:QI 2 "register_operand")
19099 (match_operand:QI 3 "immediate_operand"))
19101 "! TARGET_PARTIAL_REG_STALL
19102 && ix86_match_ccmode (insn, CCNOmode)
19103 && REGNO (operands[2]) != AX_REG
19104 && peep2_reg_dead_p (1, operands[2])"
19106 [(set (match_dup 0)
19107 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
19110 (and:QI (match_dup 2) (match_dup 3)))])])
19113 [(set (match_operand 0 "flags_reg_operand")
19114 (match_operator 1 "compare_operator"
19117 (zero_extract:SI (match_operand 2 "QIreg_operand")
19120 (match_operand 3 "const_int_operand"))
19122 "! TARGET_PARTIAL_REG_STALL
19123 && ix86_match_ccmode (insn, CCNOmode)
19124 && REGNO (operands[2]) != AX_REG
19125 && peep2_reg_dead_p (1, operands[2])"
19127 [(set (match_dup 0)
19131 (zero_extract:SI (match_dup 2)
19136 (set (zero_extract:SI (match_dup 2)
19142 (zero_extract:SI (match_dup 2)
19145 (match_dup 3)) 0))])])
19147 ;; Don't do logical operations with memory inputs.
19149 [(match_scratch:SWI 2 "<r>")
19150 (parallel [(set (match_operand:SWI 0 "register_operand")
19151 (match_operator:SWI 3 "arith_or_logical_operator"
19153 (match_operand:SWI 1 "memory_operand")]))
19154 (clobber (reg:CC FLAGS_REG))])]
19155 "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
19156 [(set (match_dup 2) (match_dup 1))
19157 (parallel [(set (match_dup 0)
19158 (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
19159 (clobber (reg:CC FLAGS_REG))])])
19162 [(match_scratch:SWI 2 "<r>")
19163 (parallel [(set (match_operand:SWI 0 "register_operand")
19164 (match_operator:SWI 3 "arith_or_logical_operator"
19165 [(match_operand:SWI 1 "memory_operand")
19167 (clobber (reg:CC FLAGS_REG))])]
19168 "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
19169 [(set (match_dup 2) (match_dup 1))
19170 (parallel [(set (match_dup 0)
19171 (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
19172 (clobber (reg:CC FLAGS_REG))])])
19174 ;; Prefer Load+RegOp to Mov+MemOp. Watch out for cases when
19175 ;; the memory address refers to the destination of the load!
19178 [(set (match_operand:SWI 0 "general_reg_operand")
19179 (match_operand:SWI 1 "general_reg_operand"))
19180 (parallel [(set (match_dup 0)
19181 (match_operator:SWI 3 "commutative_operator"
19183 (match_operand:SWI 2 "memory_operand")]))
19184 (clobber (reg:CC FLAGS_REG))])]
19185 "REGNO (operands[0]) != REGNO (operands[1])
19186 && (<MODE>mode != QImode
19187 || any_QIreg_operand (operands[1], QImode))"
19188 [(set (match_dup 0) (match_dup 4))
19189 (parallel [(set (match_dup 0)
19190 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))
19191 (clobber (reg:CC FLAGS_REG))])]
19192 "operands[4] = replace_rtx (operands[2], operands[0], operands[1], true);")
19195 [(set (match_operand 0 "mmx_reg_operand")
19196 (match_operand 1 "mmx_reg_operand"))
19198 (match_operator 3 "commutative_operator"
19200 (match_operand 2 "memory_operand")]))]
19201 "REGNO (operands[0]) != REGNO (operands[1])"
19202 [(set (match_dup 0) (match_dup 2))
19204 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))])
19207 [(set (match_operand 0 "sse_reg_operand")
19208 (match_operand 1 "sse_reg_operand"))
19210 (match_operator 3 "commutative_operator"
19212 (match_operand 2 "memory_operand")]))]
19213 "REGNO (operands[0]) != REGNO (operands[1])"
19214 [(set (match_dup 0) (match_dup 2))
19216 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))])
19218 ; Don't do logical operations with memory outputs
19220 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
19221 ; instruction into two 1-uop insns plus a 2-uop insn. That last has
19222 ; the same decoder scheduling characteristics as the original.
19225 [(match_scratch:SWI 2 "<r>")
19226 (parallel [(set (match_operand:SWI 0 "memory_operand")
19227 (match_operator:SWI 3 "arith_or_logical_operator"
19229 (match_operand:SWI 1 "<nonmemory_operand>")]))
19230 (clobber (reg:CC FLAGS_REG))])]
19231 "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())"
19232 [(set (match_dup 2) (match_dup 0))
19233 (parallel [(set (match_dup 2)
19234 (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
19235 (clobber (reg:CC FLAGS_REG))])
19236 (set (match_dup 0) (match_dup 2))])
19239 [(match_scratch:SWI 2 "<r>")
19240 (parallel [(set (match_operand:SWI 0 "memory_operand")
19241 (match_operator:SWI 3 "arith_or_logical_operator"
19242 [(match_operand:SWI 1 "<nonmemory_operand>")
19244 (clobber (reg:CC FLAGS_REG))])]
19245 "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())"
19246 [(set (match_dup 2) (match_dup 0))
19247 (parallel [(set (match_dup 2)
19248 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
19249 (clobber (reg:CC FLAGS_REG))])
19250 (set (match_dup 0) (match_dup 2))])
19252 ;; Attempt to use arith or logical operations with memory outputs with
19253 ;; setting of flags.
19255 [(set (match_operand:SWI 0 "register_operand")
19256 (match_operand:SWI 1 "memory_operand"))
19257 (parallel [(set (match_dup 0)
19258 (match_operator:SWI 3 "plusminuslogic_operator"
19260 (match_operand:SWI 2 "<nonmemory_operand>")]))
19261 (clobber (reg:CC FLAGS_REG))])
19262 (set (match_dup 1) (match_dup 0))
19263 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
19264 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
19265 && peep2_reg_dead_p (4, operands[0])
19266 && !reg_overlap_mentioned_p (operands[0], operands[1])
19267 && !reg_overlap_mentioned_p (operands[0], operands[2])
19268 && (<MODE>mode != QImode
19269 || immediate_operand (operands[2], QImode)
19270 || any_QIreg_operand (operands[2], QImode))
19271 && ix86_match_ccmode (peep2_next_insn (3),
19272 (GET_CODE (operands[3]) == PLUS
19273 || GET_CODE (operands[3]) == MINUS)
19274 ? CCGOCmode : CCNOmode)"
19275 [(parallel [(set (match_dup 4) (match_dup 6))
19276 (set (match_dup 1) (match_dup 5))])]
19278 operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
19280 = gen_rtx_fmt_ee (GET_CODE (operands[3]), GET_MODE (operands[3]),
19281 copy_rtx (operands[1]),
19284 = gen_rtx_COMPARE (GET_MODE (operands[4]),
19285 copy_rtx (operands[5]),
19289 ;; Likewise for cmpelim optimized pattern.
19291 [(set (match_operand:SWI 0 "register_operand")
19292 (match_operand:SWI 1 "memory_operand"))
19293 (parallel [(set (reg FLAGS_REG)
19294 (compare (match_operator:SWI 3 "plusminuslogic_operator"
19296 (match_operand:SWI 2 "<nonmemory_operand>")])
19298 (set (match_dup 0) (match_dup 3))])
19299 (set (match_dup 1) (match_dup 0))]
19300 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
19301 && peep2_reg_dead_p (3, operands[0])
19302 && !reg_overlap_mentioned_p (operands[0], operands[1])
19303 && !reg_overlap_mentioned_p (operands[0], operands[2])
19304 && ix86_match_ccmode (peep2_next_insn (1),
19305 (GET_CODE (operands[3]) == PLUS
19306 || GET_CODE (operands[3]) == MINUS)
19307 ? CCGOCmode : CCNOmode)"
19308 [(parallel [(set (match_dup 4) (match_dup 6))
19309 (set (match_dup 1) (match_dup 5))])]
19311 operands[4] = SET_DEST (XVECEXP (PATTERN (peep2_next_insn (1)), 0, 0));
19313 = gen_rtx_fmt_ee (GET_CODE (operands[3]), GET_MODE (operands[3]),
19314 copy_rtx (operands[1]), operands[2]);
19316 = gen_rtx_COMPARE (GET_MODE (operands[4]), copy_rtx (operands[5]),
19320 ;; Likewise for instances where we have a lea pattern.
19322 [(set (match_operand:SWI 0 "register_operand")
19323 (match_operand:SWI 1 "memory_operand"))
19324 (set (match_operand:SWI 3 "register_operand")
19325 (plus:SWI (match_dup 0)
19326 (match_operand:SWI 2 "<nonmemory_operand>")))
19327 (set (match_dup 1) (match_dup 3))
19328 (set (reg FLAGS_REG) (compare (match_dup 3) (const_int 0)))]
19329 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
19330 && peep2_reg_dead_p (4, operands[3])
19331 && (rtx_equal_p (operands[0], operands[3])
19332 || peep2_reg_dead_p (2, operands[0]))
19333 && !reg_overlap_mentioned_p (operands[0], operands[1])
19334 && !reg_overlap_mentioned_p (operands[3], operands[1])
19335 && !reg_overlap_mentioned_p (operands[0], operands[2])
19336 && (<MODE>mode != QImode
19337 || immediate_operand (operands[2], QImode)
19338 || any_QIreg_operand (operands[2], QImode))
19339 && ix86_match_ccmode (peep2_next_insn (3), CCGOCmode)"
19340 [(parallel [(set (match_dup 4) (match_dup 6))
19341 (set (match_dup 1) (match_dup 5))])]
19343 operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
19345 = gen_rtx_PLUS (<MODE>mode,
19346 copy_rtx (operands[1]),
19349 = gen_rtx_COMPARE (GET_MODE (operands[4]),
19350 copy_rtx (operands[5]),
19355 [(parallel [(set (match_operand:SWI 0 "register_operand")
19356 (match_operator:SWI 2 "plusminuslogic_operator"
19358 (match_operand:SWI 1 "memory_operand")]))
19359 (clobber (reg:CC FLAGS_REG))])
19360 (set (match_dup 1) (match_dup 0))
19361 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
19362 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
19363 && GET_CODE (operands[2]) != MINUS
19364 && peep2_reg_dead_p (3, operands[0])
19365 && !reg_overlap_mentioned_p (operands[0], operands[1])
19366 && ix86_match_ccmode (peep2_next_insn (2),
19367 GET_CODE (operands[2]) == PLUS
19368 ? CCGOCmode : CCNOmode)"
19369 [(parallel [(set (match_dup 3) (match_dup 5))
19370 (set (match_dup 1) (match_dup 4))])]
19372 operands[3] = SET_DEST (PATTERN (peep2_next_insn (2)));
19374 = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
19375 copy_rtx (operands[1]),
19378 = gen_rtx_COMPARE (GET_MODE (operands[3]),
19379 copy_rtx (operands[4]),
19383 ;; Likewise for cmpelim optimized pattern.
19385 [(parallel [(set (reg FLAGS_REG)
19386 (compare (match_operator:SWI 2 "plusminuslogic_operator"
19387 [(match_operand:SWI 0 "register_operand")
19388 (match_operand:SWI 1 "memory_operand")])
19390 (set (match_dup 0) (match_dup 2))])
19391 (set (match_dup 1) (match_dup 0))]
19392 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
19393 && peep2_reg_dead_p (2, operands[0])
19394 && !reg_overlap_mentioned_p (operands[0], operands[1])
19395 && ix86_match_ccmode (peep2_next_insn (0),
19396 (GET_CODE (operands[2]) == PLUS
19397 || GET_CODE (operands[2]) == MINUS)
19398 ? CCGOCmode : CCNOmode)"
19399 [(parallel [(set (match_dup 3) (match_dup 5))
19400 (set (match_dup 1) (match_dup 4))])]
19402 operands[3] = SET_DEST (XVECEXP (PATTERN (peep2_next_insn (0)), 0, 0));
19404 = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
19405 copy_rtx (operands[1]), operands[0]);
19407 = gen_rtx_COMPARE (GET_MODE (operands[3]), copy_rtx (operands[4]),
19412 [(set (match_operand:SWI12 0 "register_operand")
19413 (match_operand:SWI12 1 "memory_operand"))
19414 (parallel [(set (match_operand:SI 4 "register_operand")
19415 (match_operator:SI 3 "plusminuslogic_operator"
19417 (match_operand:SI 2 "nonmemory_operand")]))
19418 (clobber (reg:CC FLAGS_REG))])
19419 (set (match_dup 1) (match_dup 0))
19420 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
19421 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
19422 && REGNO (operands[0]) == REGNO (operands[4])
19423 && peep2_reg_dead_p (4, operands[0])
19424 && (<MODE>mode != QImode
19425 || immediate_operand (operands[2], SImode)
19426 || any_QIreg_operand (operands[2], SImode))
19427 && !reg_overlap_mentioned_p (operands[0], operands[1])
19428 && !reg_overlap_mentioned_p (operands[0], operands[2])
19429 && ix86_match_ccmode (peep2_next_insn (3),
19430 (GET_CODE (operands[3]) == PLUS
19431 || GET_CODE (operands[3]) == MINUS)
19432 ? CCGOCmode : CCNOmode)"
19433 [(parallel [(set (match_dup 4) (match_dup 6))
19434 (set (match_dup 1) (match_dup 5))])]
19436 operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
19438 = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
19439 copy_rtx (operands[1]),
19440 gen_lowpart (<MODE>mode, operands[2]));
19442 = gen_rtx_COMPARE (GET_MODE (operands[4]),
19443 copy_rtx (operands[5]),
19447 ;; Attempt to always use XOR for zeroing registers (including FP modes).
19449 [(set (match_operand 0 "general_reg_operand")
19450 (match_operand 1 "const0_operand"))]
19451 "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
19452 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
19453 && peep2_regno_dead_p (0, FLAGS_REG)"
19454 [(parallel [(set (match_dup 0) (const_int 0))
19455 (clobber (reg:CC FLAGS_REG))])]
19456 "operands[0] = gen_lowpart (word_mode, operands[0]);")
19459 [(set (strict_low_part (match_operand:SWI12 0 "general_reg_operand"))
19461 "(! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
19462 && peep2_regno_dead_p (0, FLAGS_REG)"
19463 [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
19464 (clobber (reg:CC FLAGS_REG))])])
19466 ;; For HI, SI and DI modes, or $-1,reg is smaller than mov $-1,reg.
19468 [(set (match_operand:SWI248 0 "general_reg_operand")
19470 "(TARGET_MOVE_M1_VIA_OR || optimize_insn_for_size_p ())
19471 && peep2_regno_dead_p (0, FLAGS_REG)"
19472 [(parallel [(set (match_dup 0) (const_int -1))
19473 (clobber (reg:CC FLAGS_REG))])]
19475 if (<MODE_SIZE> < GET_MODE_SIZE (SImode))
19476 operands[0] = gen_lowpart (SImode, operands[0]);
19479 ;; Attempt to convert simple lea to add/shift.
19480 ;; These can be created by move expanders.
19481 ;; Disable PLUS peepholes on TARGET_OPT_AGU, since all
19482 ;; relevant lea instructions were already split.
19485 [(set (match_operand:SWI48 0 "register_operand")
19486 (plus:SWI48 (match_dup 0)
19487 (match_operand:SWI48 1 "<nonmemory_operand>")))]
19489 && peep2_regno_dead_p (0, FLAGS_REG)"
19490 [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1)))
19491 (clobber (reg:CC FLAGS_REG))])])
19494 [(set (match_operand:SWI48 0 "register_operand")
19495 (plus:SWI48 (match_operand:SWI48 1 "<nonmemory_operand>")
19498 && peep2_regno_dead_p (0, FLAGS_REG)"
19499 [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1)))
19500 (clobber (reg:CC FLAGS_REG))])])
19503 [(set (match_operand:DI 0 "register_operand")
19505 (plus:SI (match_operand:SI 1 "register_operand")
19506 (match_operand:SI 2 "nonmemory_operand"))))]
19507 "TARGET_64BIT && !TARGET_OPT_AGU
19508 && REGNO (operands[0]) == REGNO (operands[1])
19509 && peep2_regno_dead_p (0, FLAGS_REG)"
19510 [(parallel [(set (match_dup 0)
19511 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))
19512 (clobber (reg:CC FLAGS_REG))])])
19515 [(set (match_operand:DI 0 "register_operand")
19517 (plus:SI (match_operand:SI 1 "nonmemory_operand")
19518 (match_operand:SI 2 "register_operand"))))]
19519 "TARGET_64BIT && !TARGET_OPT_AGU
19520 && REGNO (operands[0]) == REGNO (operands[2])
19521 && peep2_regno_dead_p (0, FLAGS_REG)"
19522 [(parallel [(set (match_dup 0)
19523 (zero_extend:DI (plus:SI (match_dup 2) (match_dup 1))))
19524 (clobber (reg:CC FLAGS_REG))])])
19527 [(set (match_operand:SWI48 0 "register_operand")
19528 (mult:SWI48 (match_dup 0)
19529 (match_operand:SWI48 1 "const_int_operand")))]
19530 "pow2p_hwi (INTVAL (operands[1]))
19531 && peep2_regno_dead_p (0, FLAGS_REG)"
19532 [(parallel [(set (match_dup 0) (ashift:SWI48 (match_dup 0) (match_dup 1)))
19533 (clobber (reg:CC FLAGS_REG))])]
19534 "operands[1] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
19537 [(set (match_operand:DI 0 "register_operand")
19539 (mult:SI (match_operand:SI 1 "register_operand")
19540 (match_operand:SI 2 "const_int_operand"))))]
19542 && pow2p_hwi (INTVAL (operands[2]))
19543 && REGNO (operands[0]) == REGNO (operands[1])
19544 && peep2_regno_dead_p (0, FLAGS_REG)"
19545 [(parallel [(set (match_dup 0)
19546 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))
19547 (clobber (reg:CC FLAGS_REG))])]
19548 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
19550 ;; The ESP adjustments can be done by the push and pop instructions. Resulting
19551 ;; code is shorter, since push is only 1 byte, while add imm, %esp is 3 bytes.
19552 ;; On many CPUs it is also faster, since special hardware to avoid esp
19553 ;; dependencies is present.
19555 ;; While some of these conversions may be done using splitters, we use
19556 ;; peepholes in order to allow combine_stack_adjustments pass to see
19557 ;; nonobfuscated RTL.
19559 ;; Convert prologue esp subtractions to push.
19560 ;; We need register to push. In order to keep verify_flow_info happy we have
19562 ;; - use scratch and clobber it in order to avoid dependencies
19563 ;; - use already live register
19564 ;; We can't use the second way right now, since there is no reliable way how to
19565 ;; verify that given register is live. First choice will also most likely in
19566 ;; fewer dependencies. On the place of esp adjustments it is very likely that
19567 ;; call clobbered registers are dead. We may want to use base pointer as an
19568 ;; alternative when no register is available later.
19571 [(match_scratch:W 1 "r")
19572 (parallel [(set (reg:P SP_REG)
19573 (plus:P (reg:P SP_REG)
19574 (match_operand:P 0 "const_int_operand")))
19575 (clobber (reg:CC FLAGS_REG))
19576 (clobber (mem:BLK (scratch)))])]
19577 "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
19578 && INTVAL (operands[0]) == -GET_MODE_SIZE (word_mode)
19579 && ix86_red_zone_size == 0"
19580 [(clobber (match_dup 1))
19581 (parallel [(set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
19582 (clobber (mem:BLK (scratch)))])])
19585 [(match_scratch:W 1 "r")
19586 (parallel [(set (reg:P SP_REG)
19587 (plus:P (reg:P SP_REG)
19588 (match_operand:P 0 "const_int_operand")))
19589 (clobber (reg:CC FLAGS_REG))
19590 (clobber (mem:BLK (scratch)))])]
19591 "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
19592 && INTVAL (operands[0]) == -2*GET_MODE_SIZE (word_mode)
19593 && ix86_red_zone_size == 0"
19594 [(clobber (match_dup 1))
19595 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
19596 (parallel [(set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
19597 (clobber (mem:BLK (scratch)))])])
19599 ;; Convert esp subtractions to push.
19601 [(match_scratch:W 1 "r")
19602 (parallel [(set (reg:P SP_REG)
19603 (plus:P (reg:P SP_REG)
19604 (match_operand:P 0 "const_int_operand")))
19605 (clobber (reg:CC FLAGS_REG))])]
19606 "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
19607 && INTVAL (operands[0]) == -GET_MODE_SIZE (word_mode)
19608 && ix86_red_zone_size == 0"
19609 [(clobber (match_dup 1))
19610 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
19613 [(match_scratch:W 1 "r")
19614 (parallel [(set (reg:P SP_REG)
19615 (plus:P (reg:P SP_REG)
19616 (match_operand:P 0 "const_int_operand")))
19617 (clobber (reg:CC FLAGS_REG))])]
19618 "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
19619 && INTVAL (operands[0]) == -2*GET_MODE_SIZE (word_mode)
19620 && ix86_red_zone_size == 0"
19621 [(clobber (match_dup 1))
19622 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
19623 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
19625 ;; Convert epilogue deallocator to pop.
19627 [(match_scratch:W 1 "r")
19628 (parallel [(set (reg:P SP_REG)
19629 (plus:P (reg:P SP_REG)
19630 (match_operand:P 0 "const_int_operand")))
19631 (clobber (reg:CC FLAGS_REG))
19632 (clobber (mem:BLK (scratch)))])]
19633 "(TARGET_SINGLE_POP || optimize_insn_for_size_p ())
19634 && INTVAL (operands[0]) == GET_MODE_SIZE (word_mode)"
19635 [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
19636 (clobber (mem:BLK (scratch)))])])
19638 ;; Two pops case is tricky, since pop causes dependency
19639 ;; on destination register. We use two registers if available.
19641 [(match_scratch:W 1 "r")
19642 (match_scratch:W 2 "r")
19643 (parallel [(set (reg:P SP_REG)
19644 (plus:P (reg:P SP_REG)
19645 (match_operand:P 0 "const_int_operand")))
19646 (clobber (reg:CC FLAGS_REG))
19647 (clobber (mem:BLK (scratch)))])]
19648 "(TARGET_DOUBLE_POP || optimize_insn_for_size_p ())
19649 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
19650 [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
19651 (clobber (mem:BLK (scratch)))])
19652 (set (match_dup 2) (mem:W (post_inc:P (reg:P SP_REG))))])
19655 [(match_scratch:W 1 "r")
19656 (parallel [(set (reg:P SP_REG)
19657 (plus:P (reg:P SP_REG)
19658 (match_operand:P 0 "const_int_operand")))
19659 (clobber (reg:CC FLAGS_REG))
19660 (clobber (mem:BLK (scratch)))])]
19661 "optimize_insn_for_size_p ()
19662 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
19663 [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
19664 (clobber (mem:BLK (scratch)))])
19665 (set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
19667 ;; Convert esp additions to pop.
19669 [(match_scratch:W 1 "r")
19670 (parallel [(set (reg:P SP_REG)
19671 (plus:P (reg:P SP_REG)
19672 (match_operand:P 0 "const_int_operand")))
19673 (clobber (reg:CC FLAGS_REG))])]
19674 "INTVAL (operands[0]) == GET_MODE_SIZE (word_mode)"
19675 [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
19677 ;; Two pops case is tricky, since pop causes dependency
19678 ;; on destination register. We use two registers if available.
19680 [(match_scratch:W 1 "r")
19681 (match_scratch:W 2 "r")
19682 (parallel [(set (reg:P SP_REG)
19683 (plus:P (reg:P SP_REG)
19684 (match_operand:P 0 "const_int_operand")))
19685 (clobber (reg:CC FLAGS_REG))])]
19686 "INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
19687 [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
19688 (set (match_dup 2) (mem:W (post_inc:P (reg:P SP_REG))))])
19691 [(match_scratch:W 1 "r")
19692 (parallel [(set (reg:P SP_REG)
19693 (plus:P (reg:P SP_REG)
19694 (match_operand:P 0 "const_int_operand")))
19695 (clobber (reg:CC FLAGS_REG))])]
19696 "optimize_insn_for_size_p ()
19697 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
19698 [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
19699 (set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
19701 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
19702 ;; required and register dies. Similarly for 128 to -128.
19704 [(set (match_operand 0 "flags_reg_operand")
19705 (match_operator 1 "compare_operator"
19706 [(match_operand 2 "register_operand")
19707 (match_operand 3 "const_int_operand")]))]
19708 "(((!TARGET_FUSE_CMP_AND_BRANCH || optimize_insn_for_size_p ())
19709 && incdec_operand (operands[3], GET_MODE (operands[3])))
19710 || (!TARGET_FUSE_CMP_AND_BRANCH
19711 && INTVAL (operands[3]) == 128))
19712 && ix86_match_ccmode (insn, CCGCmode)
19713 && peep2_reg_dead_p (1, operands[2])"
19714 [(parallel [(set (match_dup 0)
19715 (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
19716 (clobber (match_dup 2))])])
19718 ;; Convert imul by three, five and nine into lea
19721 [(set (match_operand:SWI48 0 "register_operand")
19722 (mult:SWI48 (match_operand:SWI48 1 "register_operand")
19723 (match_operand:SWI48 2 "const359_operand")))
19724 (clobber (reg:CC FLAGS_REG))])]
19725 "!TARGET_PARTIAL_REG_STALL
19726 || <MODE>mode == SImode
19727 || optimize_function_for_size_p (cfun)"
19728 [(set (match_dup 0)
19729 (plus:SWI48 (mult:SWI48 (match_dup 1) (match_dup 2))
19731 "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
19735 [(set (match_operand:SWI48 0 "register_operand")
19736 (mult:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
19737 (match_operand:SWI48 2 "const359_operand")))
19738 (clobber (reg:CC FLAGS_REG))])]
19739 "optimize_insn_for_speed_p ()
19740 && (!TARGET_PARTIAL_REG_STALL || <MODE>mode == SImode)"
19741 [(set (match_dup 0) (match_dup 1))
19743 (plus:SWI48 (mult:SWI48 (match_dup 0) (match_dup 2))
19745 "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
19747 ;; imul $32bit_imm, mem, reg is vector decoded, while
19748 ;; imul $32bit_imm, reg, reg is direct decoded.
19750 [(match_scratch:SWI48 3 "r")
19751 (parallel [(set (match_operand:SWI48 0 "register_operand")
19752 (mult:SWI48 (match_operand:SWI48 1 "memory_operand")
19753 (match_operand:SWI48 2 "immediate_operand")))
19754 (clobber (reg:CC FLAGS_REG))])]
19755 "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
19756 && !satisfies_constraint_K (operands[2])"
19757 [(set (match_dup 3) (match_dup 1))
19758 (parallel [(set (match_dup 0) (mult:SWI48 (match_dup 3) (match_dup 2)))
19759 (clobber (reg:CC FLAGS_REG))])])
19762 [(match_scratch:SI 3 "r")
19763 (parallel [(set (match_operand:DI 0 "register_operand")
19765 (mult:SI (match_operand:SI 1 "memory_operand")
19766 (match_operand:SI 2 "immediate_operand"))))
19767 (clobber (reg:CC FLAGS_REG))])]
19769 && TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
19770 && !satisfies_constraint_K (operands[2])"
19771 [(set (match_dup 3) (match_dup 1))
19772 (parallel [(set (match_dup 0)
19773 (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
19774 (clobber (reg:CC FLAGS_REG))])])
19776 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
19777 ;; Convert it into imul reg, reg
19778 ;; It would be better to force assembler to encode instruction using long
19779 ;; immediate, but there is apparently no way to do so.
19781 [(parallel [(set (match_operand:SWI248 0 "register_operand")
19783 (match_operand:SWI248 1 "nonimmediate_operand")
19784 (match_operand:SWI248 2 "const_int_operand")))
19785 (clobber (reg:CC FLAGS_REG))])
19786 (match_scratch:SWI248 3 "r")]
19787 "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
19788 && satisfies_constraint_K (operands[2])"
19789 [(set (match_dup 3) (match_dup 2))
19790 (parallel [(set (match_dup 0) (mult:SWI248 (match_dup 0) (match_dup 3)))
19791 (clobber (reg:CC FLAGS_REG))])]
19793 if (!rtx_equal_p (operands[0], operands[1]))
19794 emit_move_insn (operands[0], operands[1]);
19797 ;; After splitting up read-modify operations, array accesses with memory
19798 ;; operands might end up in form:
19800 ;; movl 4(%esp), %edx
19802 ;; instead of pre-splitting:
19804 ;; addl 4(%esp), %eax
19806 ;; movl 4(%esp), %edx
19807 ;; leal (%edx,%eax,4), %eax
19810 [(match_scratch:W 5 "r")
19811 (parallel [(set (match_operand 0 "register_operand")
19812 (ashift (match_operand 1 "register_operand")
19813 (match_operand 2 "const_int_operand")))
19814 (clobber (reg:CC FLAGS_REG))])
19815 (parallel [(set (match_operand 3 "register_operand")
19816 (plus (match_dup 0)
19817 (match_operand 4 "x86_64_general_operand")))
19818 (clobber (reg:CC FLAGS_REG))])]
19819 "IN_RANGE (INTVAL (operands[2]), 1, 3)
19820 /* Validate MODE for lea. */
19821 && ((!TARGET_PARTIAL_REG_STALL
19822 && (GET_MODE (operands[0]) == QImode
19823 || GET_MODE (operands[0]) == HImode))
19824 || GET_MODE (operands[0]) == SImode
19825 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
19826 && (rtx_equal_p (operands[0], operands[3])
19827 || peep2_reg_dead_p (2, operands[0]))
19828 /* We reorder load and the shift. */
19829 && !reg_overlap_mentioned_p (operands[0], operands[4])"
19830 [(set (match_dup 5) (match_dup 4))
19831 (set (match_dup 0) (match_dup 1))]
19833 machine_mode op1mode = GET_MODE (operands[1]);
19834 machine_mode mode = op1mode == DImode ? DImode : SImode;
19835 int scale = 1 << INTVAL (operands[2]);
19836 rtx index = gen_lowpart (word_mode, operands[1]);
19837 rtx base = gen_lowpart (word_mode, operands[5]);
19838 rtx dest = gen_lowpart (mode, operands[3]);
19840 operands[1] = gen_rtx_PLUS (word_mode, base,
19841 gen_rtx_MULT (word_mode, index, GEN_INT (scale)));
19842 if (mode != word_mode)
19843 operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
19845 operands[5] = base;
19846 if (op1mode != word_mode)
19847 operands[5] = gen_lowpart (op1mode, operands[5]);
19849 operands[0] = dest;
19852 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
19853 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
19854 ;; caught for use by garbage collectors and the like. Using an insn that
19855 ;; maps to SIGILL makes it more likely the program will rightfully die.
19856 ;; Keeping with tradition, "6" is in honor of #UD.
19857 (define_insn "trap"
19858 [(trap_if (const_int 1) (const_int 6))]
19861 #ifdef HAVE_AS_IX86_UD2
19864 return ASM_SHORT "0x0b0f";
19867 [(set_attr "length" "2")])
19870 [(unspec_volatile [(const_int 0)] UNSPECV_UD2)]
19873 #ifdef HAVE_AS_IX86_UD2
19876 return ASM_SHORT "0x0b0f";
19879 [(set_attr "length" "2")])
19881 (define_expand "prefetch"
19882 [(prefetch (match_operand 0 "address_operand")
19883 (match_operand:SI 1 "const_int_operand")
19884 (match_operand:SI 2 "const_int_operand"))]
19885 "TARGET_3DNOW || TARGET_PREFETCH_SSE || TARGET_PRFCHW || TARGET_PREFETCHWT1"
19887 bool write = INTVAL (operands[1]) != 0;
19888 int locality = INTVAL (operands[2]);
19890 gcc_assert (IN_RANGE (locality, 0, 3));
19892 /* Use 3dNOW prefetch in case we are asking for write prefetch not
19893 supported by SSE counterpart (non-SSE2 athlon machines) or the
19894 SSE prefetch is not available (K6 machines). Otherwise use SSE
19895 prefetch as it allows specifying of locality. */
19899 if (TARGET_PREFETCHWT1)
19900 operands[2] = GEN_INT (MAX (locality, 2));
19901 else if (TARGET_PRFCHW)
19902 operands[2] = GEN_INT (3);
19903 else if (TARGET_3DNOW && !TARGET_SSE2)
19904 operands[2] = GEN_INT (3);
19905 else if (TARGET_PREFETCH_SSE)
19906 operands[1] = const0_rtx;
19909 gcc_assert (TARGET_3DNOW);
19910 operands[2] = GEN_INT (3);
19915 if (TARGET_PREFETCH_SSE)
19919 gcc_assert (TARGET_3DNOW);
19920 operands[2] = GEN_INT (3);
19925 (define_insn "*prefetch_sse"
19926 [(prefetch (match_operand 0 "address_operand" "p")
19928 (match_operand:SI 1 "const_int_operand"))]
19929 "TARGET_PREFETCH_SSE"
19931 static const char * const patterns[4] = {
19932 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
19935 int locality = INTVAL (operands[1]);
19936 gcc_assert (IN_RANGE (locality, 0, 3));
19938 return patterns[locality];
19940 [(set_attr "type" "sse")
19941 (set_attr "atom_sse_attr" "prefetch")
19942 (set (attr "length_address")
19943 (symbol_ref "memory_address_length (operands[0], false)"))
19944 (set_attr "memory" "none")])
19946 (define_insn "*prefetch_3dnow"
19947 [(prefetch (match_operand 0 "address_operand" "p")
19948 (match_operand:SI 1 "const_int_operand" "n")
19950 "TARGET_3DNOW || TARGET_PRFCHW || TARGET_PREFETCHWT1"
19952 if (INTVAL (operands[1]) == 0)
19953 return "prefetch\t%a0";
19955 return "prefetchw\t%a0";
19957 [(set_attr "type" "mmx")
19958 (set (attr "length_address")
19959 (symbol_ref "memory_address_length (operands[0], false)"))
19960 (set_attr "memory" "none")])
19962 (define_insn "*prefetch_prefetchwt1"
19963 [(prefetch (match_operand 0 "address_operand" "p")
19966 "TARGET_PREFETCHWT1"
19967 "prefetchwt1\t%a0";
19968 [(set_attr "type" "sse")
19969 (set (attr "length_address")
19970 (symbol_ref "memory_address_length (operands[0], false)"))
19971 (set_attr "memory" "none")])
19973 (define_expand "stack_protect_set"
19974 [(match_operand 0 "memory_operand")
19975 (match_operand 1 "memory_operand")]
19976 "TARGET_SSP_TLS_GUARD"
19978 rtx (*insn)(rtx, rtx);
19980 insn = (TARGET_LP64
19981 ? gen_stack_protect_set_di
19982 : gen_stack_protect_set_si);
19984 emit_insn (insn (operands[0], operands[1]));
19988 (define_insn "stack_protect_set_<mode>"
19989 [(set (match_operand:PTR 0 "memory_operand" "=m")
19990 (unspec:PTR [(match_operand:PTR 1 "memory_operand" "m")]
19992 (set (match_scratch:PTR 2 "=&r") (const_int 0))
19993 (clobber (reg:CC FLAGS_REG))]
19994 "TARGET_SSP_TLS_GUARD"
19995 "mov{<imodesuffix>}\t{%1, %2|%2, %1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
19996 [(set_attr "type" "multi")])
19998 (define_expand "stack_protect_test"
19999 [(match_operand 0 "memory_operand")
20000 (match_operand 1 "memory_operand")
20002 "TARGET_SSP_TLS_GUARD"
20004 rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
20006 rtx (*insn)(rtx, rtx, rtx);
20008 insn = (TARGET_LP64
20009 ? gen_stack_protect_test_di
20010 : gen_stack_protect_test_si);
20012 emit_insn (insn (flags, operands[0], operands[1]));
20014 emit_jump_insn (gen_cbranchcc4 (gen_rtx_EQ (VOIDmode, flags, const0_rtx),
20015 flags, const0_rtx, operands[2]));
20019 (define_insn "stack_protect_test_<mode>"
20020 [(set (match_operand:CCZ 0 "flags_reg_operand")
20021 (unspec:CCZ [(match_operand:PTR 1 "memory_operand" "m")
20022 (match_operand:PTR 2 "memory_operand" "m")]
20024 (clobber (match_scratch:PTR 3 "=&r"))]
20025 "TARGET_SSP_TLS_GUARD"
20026 "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%2, %3|%3, %2}"
20027 [(set_attr "type" "multi")])
20029 (define_insn "sse4_2_crc32<mode>"
20030 [(set (match_operand:SI 0 "register_operand" "=r")
20032 [(match_operand:SI 1 "register_operand" "0")
20033 (match_operand:SWI124 2 "nonimmediate_operand" "<r>m")]
20035 "TARGET_SSE4_2 || TARGET_CRC32"
20036 "crc32{<imodesuffix>}\t{%2, %0|%0, %2}"
20037 [(set_attr "type" "sselog1")
20038 (set_attr "prefix_rep" "1")
20039 (set_attr "prefix_extra" "1")
20040 (set (attr "prefix_data16")
20041 (if_then_else (match_operand:HI 2)
20043 (const_string "*")))
20044 (set (attr "prefix_rex")
20045 (if_then_else (match_operand:QI 2 "ext_QIreg_operand")
20047 (const_string "*")))
20048 (set_attr "mode" "SI")])
20050 (define_insn "sse4_2_crc32di"
20051 [(set (match_operand:DI 0 "register_operand" "=r")
20053 [(match_operand:DI 1 "register_operand" "0")
20054 (match_operand:DI 2 "nonimmediate_operand" "rm")]
20056 "TARGET_64BIT && (TARGET_SSE4_2 || TARGET_CRC32)"
20057 "crc32{q}\t{%2, %0|%0, %2}"
20058 [(set_attr "type" "sselog1")
20059 (set_attr "prefix_rep" "1")
20060 (set_attr "prefix_extra" "1")
20061 (set_attr "mode" "DI")])
20063 (define_insn "rdpmc"
20064 [(set (match_operand:DI 0 "register_operand" "=A")
20065 (unspec_volatile:DI [(match_operand:SI 1 "register_operand" "c")]
20069 [(set_attr "type" "other")
20070 (set_attr "length" "2")])
20072 (define_insn "rdpmc_rex64"
20073 [(set (match_operand:DI 0 "register_operand" "=a")
20074 (unspec_volatile:DI [(match_operand:SI 2 "register_operand" "c")]
20076 (set (match_operand:DI 1 "register_operand" "=d")
20077 (unspec_volatile:DI [(match_dup 2)] UNSPECV_RDPMC))]
20080 [(set_attr "type" "other")
20081 (set_attr "length" "2")])
20083 (define_insn "rdtsc"
20084 [(set (match_operand:DI 0 "register_operand" "=A")
20085 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
20088 [(set_attr "type" "other")
20089 (set_attr "length" "2")])
20091 (define_insn "rdtsc_rex64"
20092 [(set (match_operand:DI 0 "register_operand" "=a")
20093 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))
20094 (set (match_operand:DI 1 "register_operand" "=d")
20095 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
20098 [(set_attr "type" "other")
20099 (set_attr "length" "2")])
20101 (define_insn "rdtscp"
20102 [(set (match_operand:DI 0 "register_operand" "=A")
20103 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
20104 (set (match_operand:SI 1 "register_operand" "=c")
20105 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
20108 [(set_attr "type" "other")
20109 (set_attr "length" "3")])
20111 (define_insn "rdtscp_rex64"
20112 [(set (match_operand:DI 0 "register_operand" "=a")
20113 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
20114 (set (match_operand:DI 1 "register_operand" "=d")
20115 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
20116 (set (match_operand:SI 2 "register_operand" "=c")
20117 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
20120 [(set_attr "type" "other")
20121 (set_attr "length" "3")])
20123 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
20125 ;; FXSR, XSAVE and XSAVEOPT instructions
20127 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
20129 (define_insn "fxsave"
20130 [(set (match_operand:BLK 0 "memory_operand" "=m")
20131 (unspec_volatile:BLK [(const_int 0)] UNSPECV_FXSAVE))]
20134 [(set_attr "type" "other")
20135 (set_attr "memory" "store")
20136 (set (attr "length")
20137 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
20139 (define_insn "fxsave64"
20140 [(set (match_operand:BLK 0 "memory_operand" "=m")
20141 (unspec_volatile:BLK [(const_int 0)] UNSPECV_FXSAVE64))]
20142 "TARGET_64BIT && TARGET_FXSR"
20144 [(set_attr "type" "other")
20145 (set_attr "memory" "store")
20146 (set (attr "length")
20147 (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
20149 (define_insn "fxrstor"
20150 [(unspec_volatile [(match_operand:BLK 0 "memory_operand" "m")]
20154 [(set_attr "type" "other")
20155 (set_attr "memory" "load")
20156 (set (attr "length")
20157 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
20159 (define_insn "fxrstor64"
20160 [(unspec_volatile [(match_operand:BLK 0 "memory_operand" "m")]
20161 UNSPECV_FXRSTOR64)]
20162 "TARGET_64BIT && TARGET_FXSR"
20164 [(set_attr "type" "other")
20165 (set_attr "memory" "load")
20166 (set (attr "length")
20167 (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
20169 (define_int_iterator ANY_XSAVE
20171 (UNSPECV_XSAVEOPT "TARGET_XSAVEOPT")
20172 (UNSPECV_XSAVEC "TARGET_XSAVEC")
20173 (UNSPECV_XSAVES "TARGET_XSAVES")])
20175 (define_int_iterator ANY_XSAVE64
20177 (UNSPECV_XSAVEOPT64 "TARGET_XSAVEOPT")
20178 (UNSPECV_XSAVEC64 "TARGET_XSAVEC")
20179 (UNSPECV_XSAVES64 "TARGET_XSAVES")])
20181 (define_int_attr xsave
20182 [(UNSPECV_XSAVE "xsave")
20183 (UNSPECV_XSAVE64 "xsave64")
20184 (UNSPECV_XSAVEOPT "xsaveopt")
20185 (UNSPECV_XSAVEOPT64 "xsaveopt64")
20186 (UNSPECV_XSAVEC "xsavec")
20187 (UNSPECV_XSAVEC64 "xsavec64")
20188 (UNSPECV_XSAVES "xsaves")
20189 (UNSPECV_XSAVES64 "xsaves64")])
20191 (define_int_iterator ANY_XRSTOR
20193 (UNSPECV_XRSTORS "TARGET_XSAVES")])
20195 (define_int_iterator ANY_XRSTOR64
20197 (UNSPECV_XRSTORS64 "TARGET_XSAVES")])
20199 (define_int_attr xrstor
20200 [(UNSPECV_XRSTOR "xrstor")
20201 (UNSPECV_XRSTOR64 "xrstor")
20202 (UNSPECV_XRSTORS "xrstors")
20203 (UNSPECV_XRSTORS64 "xrstors")])
20205 (define_insn "<xsave>"
20206 [(set (match_operand:BLK 0 "memory_operand" "=m")
20207 (unspec_volatile:BLK
20208 [(match_operand:DI 1 "register_operand" "A")]
20210 "!TARGET_64BIT && TARGET_XSAVE"
20212 [(set_attr "type" "other")
20213 (set_attr "memory" "store")
20214 (set (attr "length")
20215 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
20217 (define_insn "<xsave>_rex64"
20218 [(set (match_operand:BLK 0 "memory_operand" "=m")
20219 (unspec_volatile:BLK
20220 [(match_operand:SI 1 "register_operand" "a")
20221 (match_operand:SI 2 "register_operand" "d")]
20223 "TARGET_64BIT && TARGET_XSAVE"
20225 [(set_attr "type" "other")
20226 (set_attr "memory" "store")
20227 (set (attr "length")
20228 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
20230 (define_insn "<xsave>"
20231 [(set (match_operand:BLK 0 "memory_operand" "=m")
20232 (unspec_volatile:BLK
20233 [(match_operand:SI 1 "register_operand" "a")
20234 (match_operand:SI 2 "register_operand" "d")]
20236 "TARGET_64BIT && TARGET_XSAVE"
20238 [(set_attr "type" "other")
20239 (set_attr "memory" "store")
20240 (set (attr "length")
20241 (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
20243 (define_insn "<xrstor>"
20244 [(unspec_volatile:BLK
20245 [(match_operand:BLK 0 "memory_operand" "m")
20246 (match_operand:DI 1 "register_operand" "A")]
20248 "!TARGET_64BIT && TARGET_XSAVE"
20250 [(set_attr "type" "other")
20251 (set_attr "memory" "load")
20252 (set (attr "length")
20253 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
20255 (define_insn "<xrstor>_rex64"
20256 [(unspec_volatile:BLK
20257 [(match_operand:BLK 0 "memory_operand" "m")
20258 (match_operand:SI 1 "register_operand" "a")
20259 (match_operand:SI 2 "register_operand" "d")]
20261 "TARGET_64BIT && TARGET_XSAVE"
20263 [(set_attr "type" "other")
20264 (set_attr "memory" "load")
20265 (set (attr "length")
20266 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
20268 (define_insn "<xrstor>64"
20269 [(unspec_volatile:BLK
20270 [(match_operand:BLK 0 "memory_operand" "m")
20271 (match_operand:SI 1 "register_operand" "a")
20272 (match_operand:SI 2 "register_operand" "d")]
20274 "TARGET_64BIT && TARGET_XSAVE"
20276 [(set_attr "type" "other")
20277 (set_attr "memory" "load")
20278 (set (attr "length")
20279 (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
20281 (define_insn "xsetbv"
20282 [(unspec_volatile:SI
20283 [(match_operand:SI 0 "register_operand" "c")
20284 (match_operand:DI 1 "register_operand" "A")]
20286 "!TARGET_64BIT && TARGET_XSAVE"
20288 [(set_attr "type" "other")])
20290 (define_insn "xsetbv_rex64"
20291 [(unspec_volatile:SI
20292 [(match_operand:SI 0 "register_operand" "c")
20293 (match_operand:SI 1 "register_operand" "a")
20294 (match_operand:SI 2 "register_operand" "d")]
20296 "TARGET_64BIT && TARGET_XSAVE"
20298 [(set_attr "type" "other")])
20300 (define_insn "xgetbv"
20301 [(set (match_operand:DI 0 "register_operand" "=A")
20302 (unspec_volatile:DI [(match_operand:SI 1 "register_operand" "c")]
20304 "!TARGET_64BIT && TARGET_XSAVE"
20306 [(set_attr "type" "other")])
20308 (define_insn "xgetbv_rex64"
20309 [(set (match_operand:DI 0 "register_operand" "=a")
20310 (unspec_volatile:DI [(match_operand:SI 2 "register_operand" "c")]
20312 (set (match_operand:DI 1 "register_operand" "=d")
20313 (unspec_volatile:DI [(match_dup 2)] UNSPECV_XGETBV))]
20314 "TARGET_64BIT && TARGET_XSAVE"
20316 [(set_attr "type" "other")])
20318 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
20320 ;; Floating-point instructions for atomic compound assignments
20322 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
20324 ; Clobber all floating-point registers on environment save and restore
20325 ; to ensure that the TOS value saved at fnstenv is valid after fldenv.
20326 (define_insn "fnstenv"
20327 [(set (match_operand:BLK 0 "memory_operand" "=m")
20328 (unspec_volatile:BLK [(const_int 0)] UNSPECV_FNSTENV))
20329 (clobber (reg:HI FPCR_REG))
20330 (clobber (reg:XF ST0_REG))
20331 (clobber (reg:XF ST1_REG))
20332 (clobber (reg:XF ST2_REG))
20333 (clobber (reg:XF ST3_REG))
20334 (clobber (reg:XF ST4_REG))
20335 (clobber (reg:XF ST5_REG))
20336 (clobber (reg:XF ST6_REG))
20337 (clobber (reg:XF ST7_REG))]
20340 [(set_attr "type" "other")
20341 (set_attr "memory" "store")
20342 (set (attr "length")
20343 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))])
20345 (define_insn "fldenv"
20346 [(unspec_volatile [(match_operand:BLK 0 "memory_operand" "m")]
20348 (clobber (reg:CCFP FPSR_REG))
20349 (clobber (reg:HI FPCR_REG))
20350 (clobber (reg:XF ST0_REG))
20351 (clobber (reg:XF ST1_REG))
20352 (clobber (reg:XF ST2_REG))
20353 (clobber (reg:XF ST3_REG))
20354 (clobber (reg:XF ST4_REG))
20355 (clobber (reg:XF ST5_REG))
20356 (clobber (reg:XF ST6_REG))
20357 (clobber (reg:XF ST7_REG))]
20360 [(set_attr "type" "other")
20361 (set_attr "memory" "load")
20362 (set (attr "length")
20363 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))])
20365 (define_insn "fnstsw"
20366 [(set (match_operand:HI 0 "nonimmediate_operand" "=a,m")
20367 (unspec_volatile:HI [(const_int 0)] UNSPECV_FNSTSW))]
20370 [(set_attr "type" "other,other")
20371 (set_attr "memory" "none,store")
20372 (set (attr "length")
20373 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))])
20375 (define_insn "fnclex"
20376 [(unspec_volatile [(const_int 0)] UNSPECV_FNCLEX)]
20379 [(set_attr "type" "other")
20380 (set_attr "memory" "none")
20381 (set_attr "length" "2")])
20383 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
20385 ;; LWP instructions
20387 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
20389 (define_expand "lwp_llwpcb"
20390 [(unspec_volatile [(match_operand 0 "register_operand")]
20391 UNSPECV_LLWP_INTRINSIC)]
20394 (define_insn "*lwp_llwpcb<mode>1"
20395 [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
20396 UNSPECV_LLWP_INTRINSIC)]
20399 [(set_attr "type" "lwp")
20400 (set_attr "mode" "<MODE>")
20401 (set_attr "length" "5")])
20403 (define_expand "lwp_slwpcb"
20404 [(set (match_operand 0 "register_operand")
20405 (unspec_volatile [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
20410 insn = (Pmode == DImode
20412 : gen_lwp_slwpcbsi);
20414 emit_insn (insn (operands[0]));
20418 (define_insn "lwp_slwpcb<mode>"
20419 [(set (match_operand:P 0 "register_operand" "=r")
20420 (unspec_volatile:P [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
20423 [(set_attr "type" "lwp")
20424 (set_attr "mode" "<MODE>")
20425 (set_attr "length" "5")])
20427 (define_expand "lwp_lwpval<mode>3"
20428 [(unspec_volatile [(match_operand:SWI48 1 "register_operand")
20429 (match_operand:SI 2 "nonimmediate_operand")
20430 (match_operand:SI 3 "const_int_operand")]
20431 UNSPECV_LWPVAL_INTRINSIC)]
20433 ;; Avoid unused variable warning.
20434 "(void) operands[0];")
20436 (define_insn "*lwp_lwpval<mode>3_1"
20437 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")
20438 (match_operand:SI 1 "nonimmediate_operand" "rm")
20439 (match_operand:SI 2 "const_int_operand" "i")]
20440 UNSPECV_LWPVAL_INTRINSIC)]
20442 "lwpval\t{%2, %1, %0|%0, %1, %2}"
20443 [(set_attr "type" "lwp")
20444 (set_attr "mode" "<MODE>")
20445 (set (attr "length")
20446 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
20448 (define_expand "lwp_lwpins<mode>3"
20449 [(set (reg:CCC FLAGS_REG)
20450 (unspec_volatile:CCC [(match_operand:SWI48 1 "register_operand")
20451 (match_operand:SI 2 "nonimmediate_operand")
20452 (match_operand:SI 3 "const_int_operand")]
20453 UNSPECV_LWPINS_INTRINSIC))
20454 (set (match_operand:QI 0 "nonimmediate_operand")
20455 (eq:QI (reg:CCC FLAGS_REG) (const_int 0)))]
20458 (define_insn "*lwp_lwpins<mode>3_1"
20459 [(set (reg:CCC FLAGS_REG)
20460 (unspec_volatile:CCC [(match_operand:SWI48 0 "register_operand" "r")
20461 (match_operand:SI 1 "nonimmediate_operand" "rm")
20462 (match_operand:SI 2 "const_int_operand" "i")]
20463 UNSPECV_LWPINS_INTRINSIC))]
20465 "lwpins\t{%2, %1, %0|%0, %1, %2}"
20466 [(set_attr "type" "lwp")
20467 (set_attr "mode" "<MODE>")
20468 (set (attr "length")
20469 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
20471 (define_int_iterator RDFSGSBASE
20475 (define_int_iterator WRFSGSBASE
20479 (define_int_attr fsgs
20480 [(UNSPECV_RDFSBASE "fs")
20481 (UNSPECV_RDGSBASE "gs")
20482 (UNSPECV_WRFSBASE "fs")
20483 (UNSPECV_WRGSBASE "gs")])
20485 (define_insn "rd<fsgs>base<mode>"
20486 [(set (match_operand:SWI48 0 "register_operand" "=r")
20487 (unspec_volatile:SWI48 [(const_int 0)] RDFSGSBASE))]
20488 "TARGET_64BIT && TARGET_FSGSBASE"
20490 [(set_attr "type" "other")
20491 (set_attr "prefix_extra" "2")])
20493 (define_insn "wr<fsgs>base<mode>"
20494 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
20496 "TARGET_64BIT && TARGET_FSGSBASE"
20498 [(set_attr "type" "other")
20499 (set_attr "prefix_extra" "2")])
20501 (define_insn "rdrand<mode>_1"
20502 [(set (match_operand:SWI248 0 "register_operand" "=r")
20503 (unspec_volatile:SWI248 [(const_int 0)] UNSPECV_RDRAND))
20504 (set (reg:CCC FLAGS_REG)
20505 (unspec_volatile:CCC [(const_int 0)] UNSPECV_RDRAND))]
20508 [(set_attr "type" "other")
20509 (set_attr "prefix_extra" "1")])
20511 (define_insn "rdseed<mode>_1"
20512 [(set (match_operand:SWI248 0 "register_operand" "=r")
20513 (unspec_volatile:SWI248 [(const_int 0)] UNSPECV_RDSEED))
20514 (set (reg:CCC FLAGS_REG)
20515 (unspec_volatile:CCC [(const_int 0)] UNSPECV_RDSEED))]
20518 [(set_attr "type" "other")
20519 (set_attr "prefix_extra" "1")])
20521 (define_expand "pause"
20522 [(set (match_dup 0)
20523 (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
20526 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
20527 MEM_VOLATILE_P (operands[0]) = 1;
20530 ;; Use "rep; nop", instead of "pause", to support older assemblers.
20531 ;; They have the same encoding.
20532 (define_insn "*pause"
20533 [(set (match_operand:BLK 0)
20534 (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
20537 [(set_attr "length" "2")
20538 (set_attr "memory" "unknown")])
20540 ;; CET instructions
20541 (define_insn "rdssp<mode>"
20542 [(set (match_operand:SWI48x 0 "register_operand" "=r")
20543 (unspec_volatile:SWI48x [(const_int 0)] UNSPECV_NOP_RDSSP))]
20544 "TARGET_SHSTK || (flag_cf_protection & CF_RETURN)"
20545 "xor{l}\t%k0, %k0\n\trdssp<mskmodesuffix>\t%0"
20546 [(set_attr "length" "6")
20547 (set_attr "type" "other")])
20549 (define_insn "incssp<mode>"
20550 [(unspec_volatile [(match_operand:SWI48x 0 "register_operand" "r")]
20552 "TARGET_SHSTK || (flag_cf_protection & CF_RETURN)"
20553 "incssp<mskmodesuffix>\t%0"
20554 [(set_attr "length" "4")
20555 (set_attr "type" "other")])
20557 (define_insn "saveprevssp"
20558 [(unspec_volatile [(const_int 0)] UNSPECV_SAVEPREVSSP)]
20561 [(set_attr "length" "5")
20562 (set_attr "type" "other")])
20564 (define_insn "rstorssp"
20565 [(unspec_volatile [(match_operand 0 "memory_operand" "m")]
20569 [(set_attr "length" "5")
20570 (set_attr "type" "other")])
20572 (define_insn "wrss<mode>"
20573 [(unspec_volatile [(match_operand:SWI48x 0 "register_operand" "r")
20574 (match_operand:SWI48x 1 "memory_operand" "m")]
20577 "wrss<mskmodesuffix>\t%0, %1"
20578 [(set_attr "length" "3")
20579 (set_attr "type" "other")])
20581 (define_insn "wruss<mode>"
20582 [(unspec_volatile [(match_operand:SWI48x 0 "register_operand" "r")
20583 (match_operand:SWI48x 1 "memory_operand" "m")]
20586 "wruss<mskmodesuffix>\t%0, %1"
20587 [(set_attr "length" "4")
20588 (set_attr "type" "other")])
20590 (define_insn "setssbsy"
20591 [(unspec_volatile [(const_int 0)] UNSPECV_SETSSBSY)]
20594 [(set_attr "length" "4")
20595 (set_attr "type" "other")])
20597 (define_insn "clrssbsy"
20598 [(unspec_volatile [(match_operand 0 "memory_operand" "m")]
20602 [(set_attr "length" "4")
20603 (set_attr "type" "other")])
20605 (define_insn "nop_endbr"
20606 [(unspec_volatile [(const_int 0)] UNSPECV_NOP_ENDBR)]
20607 "(flag_cf_protection & CF_BRANCH)"
20609 { return (TARGET_64BIT)? \"endbr64\" : \"endbr32\"; }"
20610 [(set_attr "length" "4")
20611 (set_attr "length_immediate" "0")
20612 (set_attr "modrm" "0")])
20615 (define_expand "xbegin"
20616 [(set (match_operand:SI 0 "register_operand")
20617 (unspec_volatile:SI [(const_int 0)] UNSPECV_XBEGIN))]
20620 rtx_code_label *label = gen_label_rtx ();
20622 /* xbegin is emitted as jump_insn, so reload won't be able
20623 to reload its operand. Force the value into AX hard register. */
20624 rtx ax_reg = gen_rtx_REG (SImode, AX_REG);
20625 emit_move_insn (ax_reg, constm1_rtx);
20627 emit_jump_insn (gen_xbegin_1 (ax_reg, label));
20629 emit_label (label);
20630 LABEL_NUSES (label) = 1;
20632 emit_move_insn (operands[0], ax_reg);
20637 (define_insn "xbegin_1"
20639 (if_then_else (ne (unspec [(const_int 0)] UNSPEC_XBEGIN_ABORT)
20641 (label_ref (match_operand 1))
20643 (set (match_operand:SI 0 "register_operand" "+a")
20644 (unspec_volatile:SI [(match_dup 0)] UNSPECV_XBEGIN))]
20647 [(set_attr "type" "other")
20648 (set_attr "length" "6")])
20650 (define_insn "xend"
20651 [(unspec_volatile [(const_int 0)] UNSPECV_XEND)]
20654 [(set_attr "type" "other")
20655 (set_attr "length" "3")])
20657 (define_insn "xabort"
20658 [(unspec_volatile [(match_operand:SI 0 "const_0_to_255_operand" "n")]
20662 [(set_attr "type" "other")
20663 (set_attr "length" "3")])
20665 (define_expand "xtest"
20666 [(set (match_operand:QI 0 "register_operand")
20667 (unspec_volatile:QI [(const_int 0)] UNSPECV_XTEST))]
20670 emit_insn (gen_xtest_1 ());
20672 ix86_expand_setcc (operands[0], NE,
20673 gen_rtx_REG (CCZmode, FLAGS_REG), const0_rtx);
20677 (define_insn "xtest_1"
20678 [(set (reg:CCZ FLAGS_REG)
20679 (unspec_volatile:CCZ [(const_int 0)] UNSPECV_XTEST))]
20682 [(set_attr "type" "other")
20683 (set_attr "length" "3")])
20685 (define_insn "clwb"
20686 [(unspec_volatile [(match_operand 0 "address_operand" "p")]
20690 [(set_attr "type" "sse")
20691 (set_attr "atom_sse_attr" "fence")
20692 (set_attr "memory" "unknown")])
20694 (define_insn "clflushopt"
20695 [(unspec_volatile [(match_operand 0 "address_operand" "p")]
20696 UNSPECV_CLFLUSHOPT)]
20697 "TARGET_CLFLUSHOPT"
20699 [(set_attr "type" "sse")
20700 (set_attr "atom_sse_attr" "fence")
20701 (set_attr "memory" "unknown")])
20703 ;; MONITORX and MWAITX
20704 (define_insn "mwaitx"
20705 [(unspec_volatile [(match_operand:SI 0 "register_operand" "c")
20706 (match_operand:SI 1 "register_operand" "a")
20707 (match_operand:SI 2 "register_operand" "b")]
20710 ;; 64bit version is "mwaitx %rax,%rcx,%rbx". But only lower 32bits are used.
20711 ;; Since 32bit register operands are implicitly zero extended to 64bit,
20712 ;; we only need to set up 32bit registers.
20714 [(set_attr "length" "3")])
20716 (define_insn "monitorx_<mode>"
20717 [(unspec_volatile [(match_operand:P 0 "register_operand" "a")
20718 (match_operand:SI 1 "register_operand" "c")
20719 (match_operand:SI 2 "register_operand" "d")]
20722 ;; 64bit version is "monitorx %rax,%rcx,%rdx". But only lower 32bits in
20723 ;; RCX and RDX are used. Since 32bit register operands are implicitly
20724 ;; zero extended to 64bit, we only need to set up 32bit registers.
20726 [(set (attr "length")
20727 (symbol_ref ("(Pmode != word_mode) + 3")))])
20730 (define_insn "clzero_<mode>"
20731 [(unspec_volatile [(match_operand: P 0 "register_operand" "a")]
20735 [(set_attr "length" "3")
20736 (set_attr "memory" "unknown")])
20738 ;; MPX instructions
20740 (define_expand "<mode>_mk"
20741 [(set (match_operand:BND 0 "register_operand")
20745 [(match_operand:<bnd_ptr> 1 "register_operand")
20746 (match_operand:<bnd_ptr> 2 "address_mpx_no_base_operand")]))]
20750 operands[3] = gen_rtx_UNSPEC (Pmode, gen_rtvec (2, operands[1],
20752 UNSPEC_BNDMK_ADDR);
20755 (define_insn "*<mode>_mk"
20756 [(set (match_operand:BND 0 "register_operand" "=w")
20758 [(match_operator:<bnd_ptr> 3 "bnd_mem_operator"
20760 [(match_operand:<bnd_ptr> 1 "register_operand" "r")
20761 (match_operand:<bnd_ptr> 2 "address_mpx_no_base_operand" "Tb")]
20762 UNSPEC_BNDMK_ADDR)])]
20765 "bndmk\t{%3, %0|%0, %3}"
20766 [(set_attr "type" "mpxmk")])
20768 (define_expand "mov<mode>"
20769 [(set (match_operand:BND 0 "general_operand")
20770 (match_operand:BND 1 "general_operand"))]
20772 "ix86_expand_move (<MODE>mode, operands); DONE;")
20774 (define_insn "*mov<mode>_internal_mpx"
20775 [(set (match_operand:BND 0 "nonimmediate_operand" "=w,m")
20776 (match_operand:BND 1 "general_operand" "wm,w"))]
20778 "bndmov\t{%1, %0|%0, %1}"
20779 [(set_attr "type" "mpxmov")])
20781 (define_expand "<mode>_<bndcheck>"
20784 [(match_operand:BND 0 "register_operand")
20785 (match_operand:<bnd_ptr> 1 "address_no_seg_operand")] BNDCHECK)
20787 (unspec:BLK [(match_dup 2)] UNSPEC_MPX_FENCE))])]
20790 operands[2] = gen_rtx_MEM (BLKmode, operands[1]);
20791 MEM_VOLATILE_P (operands[2]) = 1;
20794 (define_insn "*<mode>_<bndcheck>"
20796 [(match_operand:BND 0 "register_operand" "w")
20797 (match_operand:<bnd_ptr> 1 "address_no_seg_operand" "Ts")] BNDCHECK)
20798 (set (match_operand:BLK 2 "bnd_mem_operator")
20799 (unspec:BLK [(match_dup 2)] UNSPEC_MPX_FENCE))]
20801 "bnd<bndcheck>\t{%a1, %0|%0, %a1}"
20802 [(set_attr "type" "mpxchk")])
20804 (define_expand "<mode>_ldx"
20806 [(set (match_operand:BND 0 "register_operand")
20810 [(match_operand:<bnd_ptr> 1 "address_mpx_no_index_operand")
20811 (match_operand:<bnd_ptr> 2 "register_operand")]))]
20813 (use (mem:BLK (match_dup 1)))])]
20816 /* Avoid registers which cannot be used as index. */
20817 if (!index_register_operand (operands[2], Pmode))
20818 operands[2] = copy_addr_to_reg (operands[2]);
20820 operands[3] = gen_rtx_UNSPEC (Pmode, gen_rtvec (2, operands[1],
20822 UNSPEC_BNDLDX_ADDR);
20825 (define_insn "*<mode>_ldx"
20826 [(set (match_operand:BND 0 "register_operand" "=w")
20828 [(match_operator:<bnd_ptr> 3 "bnd_mem_operator"
20830 [(match_operand:<bnd_ptr> 1 "address_mpx_no_index_operand" "Ti")
20831 (match_operand:<bnd_ptr> 2 "register_operand" "l")]
20832 UNSPEC_BNDLDX_ADDR)])]
20834 (use (mem:BLK (match_dup 1)))]
20836 "bndldx\t{%3, %0|%0, %3}"
20837 [(set_attr "type" "mpxld")])
20839 (define_expand "<mode>_stx"
20844 [(match_operand:<bnd_ptr> 0 "address_mpx_no_index_operand")
20845 (match_operand:<bnd_ptr> 1 "register_operand")]))
20846 (match_operand:BND 2 "register_operand")]
20849 (unspec:BLK [(match_dup 4)] UNSPEC_MPX_FENCE))])]
20852 /* Avoid registers which cannot be used as index. */
20853 if (!index_register_operand (operands[1], Pmode))
20854 operands[1] = copy_addr_to_reg (operands[1]);
20856 operands[3] = gen_rtx_UNSPEC (Pmode, gen_rtvec (2, operands[0],
20858 UNSPEC_BNDLDX_ADDR);
20859 operands[4] = gen_rtx_MEM (BLKmode, operands[0]);
20860 MEM_VOLATILE_P (operands[4]) = 1;
20863 (define_insn "*<mode>_stx"
20865 [(match_operator:<bnd_ptr> 3 "bnd_mem_operator"
20867 [(match_operand:<bnd_ptr> 0 "address_mpx_no_index_operand" "Ti")
20868 (match_operand:<bnd_ptr> 1 "register_operand" "l")]
20869 UNSPEC_BNDLDX_ADDR)])
20870 (match_operand:BND 2 "register_operand" "w")]
20872 (set (match_operand:BLK 4 "bnd_mem_operator")
20873 (unspec:BLK [(match_dup 4)] UNSPEC_MPX_FENCE))]
20875 "bndstx\t{%2, %3|%3, %2}"
20876 [(set_attr "type" "mpxst")])
20878 (define_insn "move_size_reloc_<mode>"
20879 [(set (match_operand:SWI48 0 "register_operand" "=r")
20881 [(match_operand:SWI48 1 "symbol_operand")]
20885 if (x86_64_immediate_size_operand (operands[1], VOIDmode))
20886 return "mov{l}\t{%1@SIZE, %k0|%k0, %1@SIZE}";
20888 return "movabs{q}\t{%1@SIZE, %0|%0, %1@SIZE}";
20890 [(set_attr "type" "imov")
20891 (set_attr "mode" "<MODE>")])
20893 ;; RDPKRU and WRPKRU
20895 (define_expand "rdpkru"
20897 [(set (match_operand:SI 0 "register_operand")
20898 (unspec_volatile:SI [(match_dup 1)] UNSPECV_PKU))
20899 (set (match_dup 2) (const_int 0))])]
20902 operands[1] = force_reg (SImode, const0_rtx);
20903 operands[2] = gen_reg_rtx (SImode);
20906 (define_insn "*rdpkru"
20907 [(set (match_operand:SI 0 "register_operand" "=a")
20908 (unspec_volatile:SI [(match_operand:SI 2 "register_operand" "c")]
20910 (set (match_operand:SI 1 "register_operand" "=d")
20914 [(set_attr "type" "other")])
20916 (define_expand "wrpkru"
20917 [(unspec_volatile:SI
20918 [(match_operand:SI 0 "register_operand")
20919 (match_dup 1) (match_dup 2)] UNSPECV_PKU)]
20922 operands[1] = force_reg (SImode, const0_rtx);
20923 operands[2] = force_reg (SImode, const0_rtx);
20926 (define_insn "*wrpkru"
20927 [(unspec_volatile:SI
20928 [(match_operand:SI 0 "register_operand" "a")
20929 (match_operand:SI 1 "register_operand" "d")
20930 (match_operand:SI 2 "register_operand" "c")] UNSPECV_PKU)]
20933 [(set_attr "type" "other")])
20935 (define_insn "rdpid"
20936 [(set (match_operand:SI 0 "register_operand" "=r")
20937 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDPID))]
20938 "!TARGET_64BIT && TARGET_RDPID"
20940 [(set_attr "type" "other")])
20942 (define_insn "rdpid_rex64"
20943 [(set (match_operand:DI 0 "register_operand" "=r")
20944 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDPID))]
20945 "TARGET_64BIT && TARGET_RDPID"
20947 [(set_attr "type" "other")])
20949 ;; Intirinsics for > i486
20951 (define_insn "wbinvd"
20952 [(unspec_volatile [(const_int 0)] UNSPECV_WBINVD)]
20955 [(set_attr "type" "other")])
20957 (define_insn "wbnoinvd"
20958 [(unspec_volatile [(const_int 0)] UNSPECV_WBNOINVD)]
20961 [(set_attr "type" "other")])
20963 (define_insn "movdiri<mode>"
20964 [(unspec_volatile:SWI48[(match_operand:SWI48 0 "memory_operand" "m")
20965 (match_operand:SWI48 1 "register_operand" "r")]
20968 "movdiri\t{%1, %0|%0, %1}"
20969 [(set_attr "type" "other")])
20971 (define_insn "movdir64b_<mode>"
20972 [(unspec_volatile:XI[(match_operand:P 0 "register_operand" "r")
20973 (match_operand:XI 1 "memory_operand")]
20974 UNSPECV_MOVDIR64B)]
20976 "movdir64b\t{%1, %0|%0, %1}"
20977 [(set_attr "type" "other")])
20981 (include "sync.md")