1 ;; GCC machine description for IA-32 and x86-64.
2 ;; Copyright (C) 1988-2019 Free Software Foundation, Inc.
3 ;; Mostly by William Schelter.
4 ;; x86_64 support added by Jan Hubicka
6 ;; This file is part of GCC.
8 ;; GCC is free software; you can redistribute it and/or modify
9 ;; it under the terms of the GNU General Public License as published by
10 ;; the Free Software Foundation; either version 3, or (at your option)
13 ;; GCC is distributed in the hope that it will be useful,
14 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
15 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 ;; GNU General Public License for more details.
18 ;; You should have received a copy of the GNU General Public License
19 ;; along with GCC; see the file COPYING3. If not see
20 ;; <http://www.gnu.org/licenses/>. */
22 ;; The original PO technology requires these to be ordered by speed,
23 ;; so that assigner will pick the fastest.
25 ;; See file "rtl.def" for documentation on define_insn, match_*, et. al.
27 ;; The special asm out single letter directives following a '%' are:
28 ;; L,W,B,Q,S,T -- print the opcode suffix for specified size of operand.
29 ;; C -- print opcode suffix for set/cmov insn.
30 ;; c -- like C, but print reversed condition
31 ;; F,f -- likewise, but for floating-point.
32 ;; O -- if HAVE_AS_IX86_CMOV_SUN_SYNTAX, expand to "w.", "l." or "q.",
34 ;; R -- print the prefix for register names.
35 ;; z -- print the opcode suffix for the size of the current operand.
36 ;; Z -- likewise, with special suffixes for x87 instructions.
37 ;; * -- print a star (in certain assembler syntax)
38 ;; A -- print an absolute memory reference.
39 ;; E -- print address with DImode register names if TARGET_64BIT.
40 ;; w -- print the operand as if it's a "word" (HImode) even if it isn't.
41 ;; s -- print a shift double count, followed by the assemblers argument
43 ;; b -- print the QImode name of the register for the indicated operand.
44 ;; %b0 would print %al if operands[0] is reg 0.
45 ;; w -- likewise, print the HImode name of the register.
46 ;; k -- likewise, print the SImode name of the register.
47 ;; q -- likewise, print the DImode name of the register.
48 ;; x -- likewise, print the V4SFmode name of the register.
49 ;; t -- likewise, print the V8SFmode name of the register.
50 ;; h -- print the QImode name for a "high" register, either ah, bh, ch or dh.
51 ;; y -- print "st(0)" instead of "st" as a register.
52 ;; d -- print duplicated register operand for AVX instruction.
53 ;; D -- print condition for SSE cmp instruction.
54 ;; P -- if PIC, print an @PLT suffix.
55 ;; p -- print raw symbol name.
56 ;; X -- don't print any sort of PIC '@' suffix for a symbol.
57 ;; & -- print some in-use local-dynamic symbol name.
58 ;; H -- print a memory address offset by 8; used for sse high-parts
59 ;; K -- print HLE lock prefix
60 ;; Y -- print condition for XOP pcom* instruction.
61 ;; + -- print a branch hint as 'cs' or 'ds' prefix
62 ;; ; -- print a semicolon (after prefixes due to bug in older gas).
63 ;; ~ -- print "i" if TARGET_AVX2, "f" otherwise.
64 ;; ^ -- print addr32 prefix if TARGET_64BIT and Pmode != word_mode
65 ;; ! -- print NOTRACK prefix for jxx/call/ret instructions if required.
67 (define_c_enum "unspec" [
68 ;; Relocation specifiers
79 UNSPEC_MACHOPIC_OFFSET
88 UNSPEC_MEMORY_BLOCKAGE
98 ;; Other random patterns
106 UNSPEC_LD_MPIC ; load_macho_picbase
108 UNSPEC_DIV_ALREADY_SPLIT
114 UNSPEC_INSN_FALSE_DEP
117 ;; For SSE/MMX support:
125 ;; Generic math support
128 UNSPEC_IEEE_MIN ; not commutative
129 UNSPEC_IEEE_MAX ; not commutative
131 ;; x87 Floating point
150 ;; x87 Double output FP
175 ;; For LZCNT suppoprt
187 UNSPEC_INTERRUPT_RETURN
190 (define_c_enum "unspecv" [
194 UNSPECV_PROBE_STACK_RANGE
197 UNSPECV_SPLIT_STACK_RETURN
203 UNSPECV_LLWP_INTRINSIC
204 UNSPECV_SLWP_INTRINSIC
205 UNSPECV_LWPVAL_INTRINSIC
206 UNSPECV_LWPINS_INTRINSIC
232 ;; For atomic compound assignments.
238 ;; For RDRAND support
241 ;; For RDSEED support
255 ;; For CLFLUSHOPT support
258 ;; For MONITORX and MWAITX support
262 ;; For CLZERO support
265 ;; For RDPKRU and WRPKRU support
282 ;; For MOVDIRI and MOVDIR64B support
286 ;; For WAITPKG support
291 ;; For CLDEMOTE support
294 ;; For Speculation Barrier support
295 UNSPECV_SPECULATION_BARRIER
299 ;; For ENQCMD and ENQCMDS support
304 ;; Constants to represent rounding modes in the ROUND instruction
313 ;; Constants to represent AVX512F embeded rounding
315 [(ROUND_NEAREST_INT 0)
323 ;; Constants to represent pcomtrue/pcomfalse variants
333 ;; Constants used in the XOP pperm instruction
335 [(PPERM_SRC 0x00) /* copy source */
336 (PPERM_INVERT 0x20) /* invert source */
337 (PPERM_REVERSE 0x40) /* bit reverse source */
338 (PPERM_REV_INV 0x60) /* bit reverse & invert src */
339 (PPERM_ZERO 0x80) /* all 0's */
340 (PPERM_ONES 0xa0) /* all 1's */
341 (PPERM_SIGN 0xc0) /* propagate sign bit */
342 (PPERM_INV_SIGN 0xe0) /* invert & propagate sign */
343 (PPERM_SRC1 0x00) /* use first source byte */
344 (PPERM_SRC2 0x10) /* use second source byte */
347 ;; Registers by name.
425 (FIRST_PSEUDO_REG 76)
428 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
431 ;; In C guard expressions, put expressions which may be compile-time
432 ;; constants first. This allows for better optimization. For
433 ;; example, write "TARGET_64BIT && reload_completed", not
434 ;; "reload_completed && TARGET_64BIT".
438 (define_attr "cpu" "none,pentium,pentiumpro,geode,k6,athlon,k8,core2,nehalem,
439 atom,slm,glm,haswell,generic,amdfam10,bdver1,bdver2,bdver3,
440 bdver4,btver2,znver1,znver2"
441 (const (symbol_ref "ix86_schedule")))
443 ;; A basic instruction type. Refinements due to arguments to be
444 ;; provided in other attributes.
447 alu,alu1,negnot,imov,imovx,lea,
448 incdec,ishift,ishiftx,ishift1,rotate,rotatex,rotate1,
449 imul,imulx,idiv,icmp,test,ibr,setcc,icmov,
450 push,pop,call,callv,leave,
452 fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,
453 fxch,fistp,fisttp,frndint,
454 sse,ssemov,sseadd,sseadd1,sseiadd,sseiadd1,
455 ssemul,sseimul,ssediv,sselog,sselog1,
456 sseishft,sseishft1,ssecmp,ssecomi,
457 ssecvt,ssecvt1,sseicvt,sseins,
458 sseshuf,sseshuf1,ssemuladd,sse4arg,
460 mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
461 (const_string "other"))
463 ;; Main data type used by the insn
465 "unknown,none,QI,HI,SI,DI,TI,OI,XI,SF,DF,XF,TF,V16SF,V8SF,V4DF,V4SF,
467 (const_string "unknown"))
469 ;; The CPU unit operations uses.
470 (define_attr "unit" "integer,i387,sse,mmx,unknown"
471 (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,
472 fxch,fistp,fisttp,frndint")
473 (const_string "i387")
474 (eq_attr "type" "sse,ssemov,sseadd,sseadd1,sseiadd,sseiadd1,
475 ssemul,sseimul,ssediv,sselog,sselog1,
476 sseishft,sseishft1,ssecmp,ssecomi,
477 ssecvt,ssecvt1,sseicvt,sseins,
478 sseshuf,sseshuf1,ssemuladd,sse4arg,mskmov")
480 (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
482 (eq_attr "type" "other")
483 (const_string "unknown")]
484 (const_string "integer")))
486 ;; The (bounding maximum) length of an instruction immediate.
487 (define_attr "length_immediate" ""
488 (cond [(eq_attr "type" "incdec,setcc,icmov,str,lea,other,multi,idiv,leave,
489 bitmanip,imulx,msklog,mskmov")
491 (eq_attr "unit" "i387,sse,mmx")
493 (eq_attr "type" "alu,alu1,negnot,imovx,ishift,ishiftx,ishift1,
494 rotate,rotatex,rotate1,imul,icmp,push,pop")
495 (symbol_ref "ix86_attr_length_immediate_default (insn, true)")
496 (eq_attr "type" "imov,test")
497 (symbol_ref "ix86_attr_length_immediate_default (insn, false)")
498 (eq_attr "type" "call")
499 (if_then_else (match_operand 0 "constant_call_address_operand")
502 (eq_attr "type" "callv")
503 (if_then_else (match_operand 1 "constant_call_address_operand")
506 ;; We don't know the size before shorten_branches. Expect
507 ;; the instruction to fit for better scheduling.
508 (eq_attr "type" "ibr")
511 (symbol_ref "/* Update immediate_length and other attributes! */
512 gcc_unreachable (),1")))
514 ;; The (bounding maximum) length of an instruction address.
515 (define_attr "length_address" ""
516 (cond [(eq_attr "type" "str,other,multi,fxch")
518 (and (eq_attr "type" "call")
519 (match_operand 0 "constant_call_address_operand"))
521 (and (eq_attr "type" "callv")
522 (match_operand 1 "constant_call_address_operand"))
525 (symbol_ref "ix86_attr_length_address_default (insn)")))
527 ;; Set when length prefix is used.
528 (define_attr "prefix_data16" ""
529 (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
531 (eq_attr "mode" "HI")
533 (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF,TI"))
538 ;; Set when string REP prefix is used.
539 (define_attr "prefix_rep" ""
540 (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
542 (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
547 ;; Set when 0f opcode prefix is used.
548 (define_attr "prefix_0f" ""
550 (ior (eq_attr "type" "imovx,setcc,icmov,bitmanip,msklog,mskmov")
551 (eq_attr "unit" "sse,mmx"))
555 ;; Set when REX opcode prefix is used.
556 (define_attr "prefix_rex" ""
557 (cond [(not (match_test "TARGET_64BIT"))
559 (and (eq_attr "mode" "DI")
560 (and (eq_attr "type" "!push,pop,call,callv,leave,ibr")
561 (eq_attr "unit" "!mmx")))
563 (and (eq_attr "mode" "QI")
564 (match_test "x86_extended_QIreg_mentioned_p (insn)"))
566 (match_test "x86_extended_reg_mentioned_p (insn)")
568 (and (eq_attr "type" "imovx")
569 (match_operand:QI 1 "ext_QIreg_operand"))
574 ;; There are also additional prefixes in 3DNOW, SSSE3.
575 ;; ssemuladd,sse4arg default to 0f24/0f25 and DREX byte,
576 ;; sseiadd1,ssecvt1 to 0f7a with no DREX byte.
577 ;; 3DNOW has 0f0f prefix, SSSE3 and SSE4_{1,2} 0f38/0f3a.
578 (define_attr "prefix_extra" ""
579 (cond [(eq_attr "type" "ssemuladd,sse4arg")
581 (eq_attr "type" "sseiadd1,ssecvt1")
586 ;; Prefix used: original, VEX or maybe VEX.
587 (define_attr "prefix" "orig,vex,maybe_vex,evex,maybe_evex"
588 (cond [(eq_attr "mode" "OI,V8SF,V4DF")
590 (eq_attr "mode" "XI,V16SF,V8DF")
591 (const_string "evex")
593 (const_string "orig")))
595 ;; VEX W bit is used.
596 (define_attr "prefix_vex_w" "" (const_int 0))
598 ;; The length of VEX prefix
599 ;; Only instructions with 0f prefix can have 2 byte VEX prefix,
600 ;; 0f38/0f3a prefixes can't. In i386.md 0f3[8a] is
601 ;; still prefix_0f 1, with prefix_extra 1.
602 (define_attr "length_vex" ""
603 (if_then_else (and (eq_attr "prefix_0f" "1")
604 (eq_attr "prefix_extra" "0"))
605 (if_then_else (eq_attr "prefix_vex_w" "1")
606 (symbol_ref "ix86_attr_length_vex_default (insn, true, true)")
607 (symbol_ref "ix86_attr_length_vex_default (insn, true, false)"))
608 (if_then_else (eq_attr "prefix_vex_w" "1")
609 (symbol_ref "ix86_attr_length_vex_default (insn, false, true)")
610 (symbol_ref "ix86_attr_length_vex_default (insn, false, false)"))))
612 ;; 4-bytes evex prefix and 1 byte opcode.
613 (define_attr "length_evex" "" (const_int 5))
615 ;; Set when modrm byte is used.
616 (define_attr "modrm" ""
617 (cond [(eq_attr "type" "str,leave")
619 (eq_attr "unit" "i387")
621 (and (eq_attr "type" "incdec")
622 (and (not (match_test "TARGET_64BIT"))
623 (ior (match_operand:SI 1 "register_operand")
624 (match_operand:HI 1 "register_operand"))))
626 (and (eq_attr "type" "push")
627 (not (match_operand 1 "memory_operand")))
629 (and (eq_attr "type" "pop")
630 (not (match_operand 0 "memory_operand")))
632 (and (eq_attr "type" "imov")
633 (and (not (eq_attr "mode" "DI"))
634 (ior (and (match_operand 0 "register_operand")
635 (match_operand 1 "immediate_operand"))
636 (ior (and (match_operand 0 "ax_reg_operand")
637 (match_operand 1 "memory_displacement_only_operand"))
638 (and (match_operand 0 "memory_displacement_only_operand")
639 (match_operand 1 "ax_reg_operand"))))))
641 (and (eq_attr "type" "call")
642 (match_operand 0 "constant_call_address_operand"))
644 (and (eq_attr "type" "callv")
645 (match_operand 1 "constant_call_address_operand"))
647 (and (eq_attr "type" "alu,alu1,icmp,test")
648 (match_operand 0 "ax_reg_operand"))
649 (symbol_ref "(get_attr_length_immediate (insn) <= (get_attr_mode (insn) != MODE_QI))")
653 ;; The (bounding maximum) length of an instruction in bytes.
654 ;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
655 ;; Later we may want to split them and compute proper length as for
657 (define_attr "length" ""
658 (cond [(eq_attr "type" "other,multi,fistp,frndint")
660 (eq_attr "type" "fcmp")
662 (eq_attr "unit" "i387")
664 (plus (attr "prefix_data16")
665 (attr "length_address")))
666 (ior (eq_attr "prefix" "evex")
667 (and (ior (eq_attr "prefix" "maybe_evex")
668 (eq_attr "prefix" "maybe_vex"))
669 (match_test "TARGET_AVX512F")))
670 (plus (attr "length_evex")
671 (plus (attr "length_immediate")
673 (attr "length_address"))))
674 (ior (eq_attr "prefix" "vex")
675 (and (ior (eq_attr "prefix" "maybe_vex")
676 (eq_attr "prefix" "maybe_evex"))
677 (match_test "TARGET_AVX")))
678 (plus (attr "length_vex")
679 (plus (attr "length_immediate")
681 (attr "length_address"))))]
682 (plus (plus (attr "modrm")
683 (plus (attr "prefix_0f")
684 (plus (attr "prefix_rex")
685 (plus (attr "prefix_extra")
687 (plus (attr "prefix_rep")
688 (plus (attr "prefix_data16")
689 (plus (attr "length_immediate")
690 (attr "length_address")))))))
692 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
693 ;; `store' if there is a simple memory reference therein, or `unknown'
694 ;; if the instruction is complex.
696 (define_attr "memory" "none,load,store,both,unknown"
697 (cond [(eq_attr "type" "other,multi,str,lwp")
698 (const_string "unknown")
699 (eq_attr "type" "lea,fcmov,fpspc")
700 (const_string "none")
701 (eq_attr "type" "fistp,leave")
702 (const_string "both")
703 (eq_attr "type" "frndint")
704 (const_string "load")
705 (eq_attr "type" "push")
706 (if_then_else (match_operand 1 "memory_operand")
707 (const_string "both")
708 (const_string "store"))
709 (eq_attr "type" "pop")
710 (if_then_else (match_operand 0 "memory_operand")
711 (const_string "both")
712 (const_string "load"))
713 (eq_attr "type" "setcc")
714 (if_then_else (match_operand 0 "memory_operand")
715 (const_string "store")
716 (const_string "none"))
717 (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
718 (if_then_else (ior (match_operand 0 "memory_operand")
719 (match_operand 1 "memory_operand"))
720 (const_string "load")
721 (const_string "none"))
722 (eq_attr "type" "ibr")
723 (if_then_else (match_operand 0 "memory_operand")
724 (const_string "load")
725 (const_string "none"))
726 (eq_attr "type" "call")
727 (if_then_else (match_operand 0 "constant_call_address_operand")
728 (const_string "none")
729 (const_string "load"))
730 (eq_attr "type" "callv")
731 (if_then_else (match_operand 1 "constant_call_address_operand")
732 (const_string "none")
733 (const_string "load"))
734 (and (eq_attr "type" "alu1,negnot,ishift1,rotate1,sselog1,sseshuf1")
735 (match_operand 1 "memory_operand"))
736 (const_string "both")
737 (and (match_operand 0 "memory_operand")
738 (match_operand 1 "memory_operand"))
739 (const_string "both")
740 (match_operand 0 "memory_operand")
741 (const_string "store")
742 (match_operand 1 "memory_operand")
743 (const_string "load")
745 "!alu1,negnot,ishift1,rotate1,
746 imov,imovx,icmp,test,bitmanip,
748 sse,ssemov,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,
749 sselog1,sseshuf1,sseadd1,sseiadd1,sseishft1,
750 mmx,mmxmov,mmxcmp,mmxcvt,mskmov,msklog")
751 (match_operand 2 "memory_operand"))
752 (const_string "load")
753 (and (eq_attr "type" "icmov,ssemuladd,sse4arg")
754 (match_operand 3 "memory_operand"))
755 (const_string "load")
757 (const_string "none")))
759 ;; Indicates if an instruction has both an immediate and a displacement.
761 (define_attr "imm_disp" "false,true,unknown"
762 (cond [(eq_attr "type" "other,multi")
763 (const_string "unknown")
764 (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
765 (and (match_operand 0 "memory_displacement_operand")
766 (match_operand 1 "immediate_operand")))
767 (const_string "true")
768 (and (eq_attr "type" "alu,ishift,ishiftx,rotate,rotatex,imul,idiv")
769 (and (match_operand 0 "memory_displacement_operand")
770 (match_operand 2 "immediate_operand")))
771 (const_string "true")
773 (const_string "false")))
775 ;; Indicates if an FP operation has an integer source.
777 (define_attr "fp_int_src" "false,true"
778 (const_string "false"))
780 ;; Defines rounding mode of an FP operation.
782 (define_attr "i387_cw" "trunc,floor,ceil,uninitialized,any"
783 (const_string "any"))
785 ;; Define attribute to indicate AVX insns with partial XMM register update.
786 (define_attr "avx_partial_xmm_update" "false,true"
787 (const_string "false"))
789 ;; Define attribute to classify add/sub insns that consumes carry flag (CF)
790 (define_attr "use_carry" "0,1" (const_string "0"))
792 ;; Define attribute to indicate unaligned ssemov insns
793 (define_attr "movu" "0,1" (const_string "0"))
795 ;; Used to control the "enabled" attribute on a per-instruction basis.
796 (define_attr "isa" "base,x64,x64_sse2,x64_sse4,x64_sse4_noavx,x64_avx,nox64,
797 sse2,sse2_noavx,sse3,sse4,sse4_noavx,avx,noavx,
798 avx2,noavx2,bmi,bmi2,fma4,fma,avx512f,noavx512f,
799 avx512bw,noavx512bw,avx512dq,noavx512dq,
800 avx512vl,noavx512vl,x64_avx512dq,x64_avx512bw"
801 (const_string "base"))
803 ;; Define instruction set of MMX instructions
804 (define_attr "mmx_isa" "base,native,x64,x64_noavx,x64_avx"
805 (const_string "base"))
807 (define_attr "enabled" ""
808 (cond [(eq_attr "isa" "x64") (symbol_ref "TARGET_64BIT")
809 (eq_attr "isa" "x64_sse2")
810 (symbol_ref "TARGET_64BIT && TARGET_SSE2")
811 (eq_attr "isa" "x64_sse4")
812 (symbol_ref "TARGET_64BIT && TARGET_SSE4_1")
813 (eq_attr "isa" "x64_sse4_noavx")
814 (symbol_ref "TARGET_64BIT && TARGET_SSE4_1 && !TARGET_AVX")
815 (eq_attr "isa" "x64_avx")
816 (symbol_ref "TARGET_64BIT && TARGET_AVX")
817 (eq_attr "isa" "x64_avx512dq")
818 (symbol_ref "TARGET_64BIT && TARGET_AVX512DQ")
819 (eq_attr "isa" "x64_avx512bw")
820 (symbol_ref "TARGET_64BIT && TARGET_AVX512BW")
821 (eq_attr "isa" "nox64") (symbol_ref "!TARGET_64BIT")
822 (eq_attr "isa" "sse2") (symbol_ref "TARGET_SSE2")
823 (eq_attr "isa" "sse2_noavx")
824 (symbol_ref "TARGET_SSE2 && !TARGET_AVX")
825 (eq_attr "isa" "sse3") (symbol_ref "TARGET_SSE3")
826 (eq_attr "isa" "sse4") (symbol_ref "TARGET_SSE4_1")
827 (eq_attr "isa" "sse4_noavx")
828 (symbol_ref "TARGET_SSE4_1 && !TARGET_AVX")
829 (eq_attr "isa" "avx") (symbol_ref "TARGET_AVX")
830 (eq_attr "isa" "noavx") (symbol_ref "!TARGET_AVX")
831 (eq_attr "isa" "avx2") (symbol_ref "TARGET_AVX2")
832 (eq_attr "isa" "noavx2") (symbol_ref "!TARGET_AVX2")
833 (eq_attr "isa" "bmi") (symbol_ref "TARGET_BMI")
834 (eq_attr "isa" "bmi2") (symbol_ref "TARGET_BMI2")
835 (eq_attr "isa" "fma4") (symbol_ref "TARGET_FMA4")
836 (eq_attr "isa" "fma") (symbol_ref "TARGET_FMA")
837 (eq_attr "isa" "avx512f") (symbol_ref "TARGET_AVX512F")
838 (eq_attr "isa" "noavx512f") (symbol_ref "!TARGET_AVX512F")
839 (eq_attr "isa" "avx512bw") (symbol_ref "TARGET_AVX512BW")
840 (eq_attr "isa" "noavx512bw") (symbol_ref "!TARGET_AVX512BW")
841 (eq_attr "isa" "avx512dq") (symbol_ref "TARGET_AVX512DQ")
842 (eq_attr "isa" "noavx512dq") (symbol_ref "!TARGET_AVX512DQ")
843 (eq_attr "isa" "avx512vl") (symbol_ref "TARGET_AVX512VL")
844 (eq_attr "isa" "noavx512vl") (symbol_ref "!TARGET_AVX512VL")
846 (eq_attr "mmx_isa" "native")
847 (symbol_ref "!TARGET_MMX_WITH_SSE")
848 (eq_attr "mmx_isa" "x64")
849 (symbol_ref "TARGET_MMX_WITH_SSE")
850 (eq_attr "mmx_isa" "x64_avx")
851 (symbol_ref "TARGET_MMX_WITH_SSE && TARGET_AVX")
852 (eq_attr "mmx_isa" "x64_noavx")
853 (symbol_ref "TARGET_MMX_WITH_SSE && !TARGET_AVX")
857 (define_attr "preferred_for_size" "" (const_int 1))
858 (define_attr "preferred_for_speed" "" (const_int 1))
860 ;; Describe a user's asm statement.
861 (define_asm_attributes
862 [(set_attr "length" "128")
863 (set_attr "type" "multi")])
865 (define_code_iterator plusminus [plus minus])
867 (define_code_iterator sat_plusminus [ss_plus us_plus ss_minus us_minus])
869 (define_code_iterator multdiv [mult div])
871 ;; Base name for define_insn
872 (define_code_attr plusminus_insn
873 [(plus "add") (ss_plus "ssadd") (us_plus "usadd")
874 (minus "sub") (ss_minus "sssub") (us_minus "ussub")])
876 ;; Base name for insn mnemonic.
877 (define_code_attr plusminus_mnemonic
878 [(plus "add") (ss_plus "adds") (us_plus "addus")
879 (minus "sub") (ss_minus "subs") (us_minus "subus")])
880 (define_code_attr multdiv_mnemonic
881 [(mult "mul") (div "div")])
883 ;; Mark commutative operators as such in constraints.
884 (define_code_attr comm [(plus "%") (ss_plus "%") (us_plus "%")
885 (minus "") (ss_minus "") (us_minus "")])
887 ;; Mapping of max and min
888 (define_code_iterator maxmin [smax smin umax umin])
890 ;; Mapping of signed max and min
891 (define_code_iterator smaxmin [smax smin])
893 ;; Mapping of unsigned max and min
894 (define_code_iterator umaxmin [umax umin])
896 ;; Base name for integer and FP insn mnemonic
897 (define_code_attr maxmin_int [(smax "maxs") (smin "mins")
898 (umax "maxu") (umin "minu")])
899 (define_code_attr maxmin_float [(smax "max") (smin "min")])
901 (define_int_iterator IEEE_MAXMIN
905 (define_int_attr ieee_maxmin
906 [(UNSPEC_IEEE_MAX "max")
907 (UNSPEC_IEEE_MIN "min")])
909 ;; Mapping of logic operators
910 (define_code_iterator any_logic [and ior xor])
911 (define_code_iterator any_or [ior xor])
912 (define_code_iterator fpint_logic [and xor])
914 ;; Base name for insn mnemonic.
915 (define_code_attr logic [(and "and") (ior "or") (xor "xor")])
917 ;; Mapping of logic-shift operators
918 (define_code_iterator any_lshift [ashift lshiftrt])
920 ;; Mapping of shift-right operators
921 (define_code_iterator any_shiftrt [lshiftrt ashiftrt])
923 ;; Mapping of all shift operators
924 (define_code_iterator any_shift [ashift lshiftrt ashiftrt])
926 ;; Base name for define_insn
927 (define_code_attr shift_insn
928 [(ashift "ashl") (lshiftrt "lshr") (ashiftrt "ashr")])
930 ;; Base name for insn mnemonic.
931 (define_code_attr shift [(ashift "sll") (lshiftrt "shr") (ashiftrt "sar")])
932 (define_code_attr vshift [(ashift "sll") (lshiftrt "srl") (ashiftrt "sra")])
934 ;; Mapping of rotate operators
935 (define_code_iterator any_rotate [rotate rotatert])
937 ;; Base name for define_insn
938 (define_code_attr rotate_insn [(rotate "rotl") (rotatert "rotr")])
940 ;; Base name for insn mnemonic.
941 (define_code_attr rotate [(rotate "rol") (rotatert "ror")])
943 ;; Mapping of abs neg operators
944 (define_code_iterator absneg [abs neg])
946 ;; Base name for x87 insn mnemonic.
947 (define_code_attr absneg_mnemonic [(abs "fabs") (neg "fchs")])
949 ;; Used in signed and unsigned widening multiplications.
950 (define_code_iterator any_extend [sign_extend zero_extend])
952 ;; Prefix for insn menmonic.
953 (define_code_attr sgnprefix [(sign_extend "i") (zero_extend "")
954 (div "i") (udiv "")])
955 ;; Prefix for define_insn
956 (define_code_attr s [(sign_extend "s") (zero_extend "u")])
957 (define_code_attr u [(sign_extend "") (zero_extend "u")
958 (div "") (udiv "u")])
959 (define_code_attr u_bool [(sign_extend "false") (zero_extend "true")
960 (div "false") (udiv "true")])
962 ;; Used in signed and unsigned truncations.
963 (define_code_iterator any_truncate [ss_truncate truncate us_truncate])
964 ;; Instruction suffix for truncations.
965 (define_code_attr trunsuffix [(ss_truncate "s") (truncate "") (us_truncate "us")])
967 ;; Used in signed and unsigned fix.
968 (define_code_iterator any_fix [fix unsigned_fix])
969 (define_code_attr fixsuffix [(fix "") (unsigned_fix "u")])
970 (define_code_attr fixunssuffix [(fix "") (unsigned_fix "uns")])
971 (define_code_attr fixprefix [(fix "s") (unsigned_fix "u")])
973 ;; Used in signed and unsigned float.
974 (define_code_iterator any_float [float unsigned_float])
975 (define_code_attr floatsuffix [(float "") (unsigned_float "u")])
976 (define_code_attr floatunssuffix [(float "") (unsigned_float "uns")])
977 (define_code_attr floatprefix [(float "s") (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")])
1059 ;; Instruction suffix for integer modes.
1060 (define_mode_attr imodesuffix [(QI "b") (HI "w") (SI "l") (DI "q")])
1062 ;; Instruction suffix for masks.
1063 (define_mode_attr mskmodesuffix [(QI "b") (HI "w") (SI "d") (DI "q")])
1065 ;; Pointer size prefix for integer modes (Intel asm dialect)
1066 (define_mode_attr iptrsize [(QI "BYTE")
1071 ;; Register class for integer modes.
1072 (define_mode_attr r [(QI "q") (HI "r") (SI "r") (DI "r")])
1074 ;; Immediate operand constraint for integer modes.
1075 (define_mode_attr i [(QI "n") (HI "n") (SI "e") (DI "e")])
1077 ;; General operand constraint for word modes.
1078 (define_mode_attr g [(QI "qmn") (HI "rmn") (SI "rme") (DI "rme")])
1080 ;; Immediate operand constraint for double integer modes.
1081 (define_mode_attr di [(SI "nF") (DI "Wd")])
1083 ;; Immediate operand constraint for shifts.
1084 (define_mode_attr S [(QI "I") (HI "I") (SI "I") (DI "J") (TI "O")])
1086 ;; Print register name in the specified mode.
1087 (define_mode_attr k [(QI "b") (HI "w") (SI "k") (DI "q")])
1089 ;; General operand predicate for integer modes.
1090 (define_mode_attr general_operand
1091 [(QI "general_operand")
1092 (HI "general_operand")
1093 (SI "x86_64_general_operand")
1094 (DI "x86_64_general_operand")
1095 (TI "x86_64_general_operand")])
1097 ;; General operand predicate for integer modes, where for TImode
1098 ;; we need both words of the operand to be general operands.
1099 (define_mode_attr general_hilo_operand
1100 [(QI "general_operand")
1101 (HI "general_operand")
1102 (SI "x86_64_general_operand")
1103 (DI "x86_64_general_operand")
1104 (TI "x86_64_hilo_general_operand")])
1106 ;; General sign extend operand predicate for integer modes,
1107 ;; which disallows VOIDmode operands and thus it is suitable
1108 ;; for use inside sign_extend.
1109 (define_mode_attr general_sext_operand
1110 [(QI "sext_operand")
1112 (SI "x86_64_sext_operand")
1113 (DI "x86_64_sext_operand")])
1115 ;; General sign/zero extend operand predicate for integer modes.
1116 (define_mode_attr general_szext_operand
1117 [(QI "general_operand")
1118 (HI "general_operand")
1119 (SI "x86_64_szext_general_operand")
1120 (DI "x86_64_szext_general_operand")])
1122 ;; Immediate operand predicate for integer modes.
1123 (define_mode_attr immediate_operand
1124 [(QI "immediate_operand")
1125 (HI "immediate_operand")
1126 (SI "x86_64_immediate_operand")
1127 (DI "x86_64_immediate_operand")])
1129 ;; Nonmemory operand predicate for integer modes.
1130 (define_mode_attr nonmemory_operand
1131 [(QI "nonmemory_operand")
1132 (HI "nonmemory_operand")
1133 (SI "x86_64_nonmemory_operand")
1134 (DI "x86_64_nonmemory_operand")])
1136 ;; Operand predicate for shifts.
1137 (define_mode_attr shift_operand
1138 [(QI "nonimmediate_operand")
1139 (HI "nonimmediate_operand")
1140 (SI "nonimmediate_operand")
1141 (DI "shiftdi_operand")
1142 (TI "register_operand")])
1144 ;; Operand predicate for shift argument.
1145 (define_mode_attr shift_immediate_operand
1146 [(QI "const_1_to_31_operand")
1147 (HI "const_1_to_31_operand")
1148 (SI "const_1_to_31_operand")
1149 (DI "const_1_to_63_operand")])
1151 ;; Input operand predicate for arithmetic left shifts.
1152 (define_mode_attr ashl_input_operand
1153 [(QI "nonimmediate_operand")
1154 (HI "nonimmediate_operand")
1155 (SI "nonimmediate_operand")
1156 (DI "ashldi_input_operand")
1157 (TI "reg_or_pm1_operand")])
1159 ;; SSE and x87 SFmode and DFmode floating point modes
1160 (define_mode_iterator MODEF [SF DF])
1162 ;; All x87 floating point modes
1163 (define_mode_iterator X87MODEF [SF DF XF])
1165 ;; SSE instruction suffix for various modes
1166 (define_mode_attr ssemodesuffix
1167 [(SF "ss") (DF "sd")
1168 (V16SF "ps") (V8DF "pd")
1169 (V8SF "ps") (V4DF "pd")
1170 (V4SF "ps") (V2DF "pd")
1171 (V16QI "b") (V8HI "w") (V4SI "d") (V2DI "q")
1172 (V32QI "b") (V16HI "w") (V8SI "d") (V4DI "q")
1173 (V64QI "b") (V32HI "w") (V16SI "d") (V8DI "q")])
1175 ;; SSE vector suffix for floating point modes
1176 (define_mode_attr ssevecmodesuffix [(SF "ps") (DF "pd")])
1178 ;; SSE vector mode corresponding to a scalar mode
1179 (define_mode_attr ssevecmode
1180 [(QI "V16QI") (HI "V8HI") (SI "V4SI") (DI "V2DI") (SF "V4SF") (DF "V2DF")])
1181 (define_mode_attr ssevecmodelower
1182 [(QI "v16qi") (HI "v8hi") (SI "v4si") (DI "v2di") (SF "v4sf") (DF "v2df")])
1184 ;; AVX512F vector mode corresponding to a scalar mode
1185 (define_mode_attr avx512fvecmode
1186 [(QI "V64QI") (HI "V32HI") (SI "V16SI") (DI "V8DI") (SF "V16SF") (DF "V8DF")])
1188 ;; Instruction suffix for REX 64bit operators.
1189 (define_mode_attr rex64suffix [(SI "{l}") (DI "{q}")])
1190 (define_mode_attr rex64namesuffix [(SI "") (DI "q")])
1192 ;; This mode iterator allows :P to be used for patterns that operate on
1193 ;; pointer-sized quantities. Exactly one of the two alternatives will match.
1194 (define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
1196 ;; This mode iterator allows :W to be used for patterns that operate on
1197 ;; word_mode sized quantities.
1198 (define_mode_iterator W
1199 [(SI "word_mode == SImode") (DI "word_mode == DImode")])
1201 ;; This mode iterator allows :PTR to be used for patterns that operate on
1202 ;; ptr_mode sized quantities.
1203 (define_mode_iterator PTR
1204 [(SI "ptr_mode == SImode") (DI "ptr_mode == DImode")])
1206 ;; Scheduling descriptions
1208 (include "pentium.md")
1211 (include "athlon.md")
1212 (include "bdver1.md")
1213 (include "bdver3.md")
1214 (include "btver2.md")
1215 (include "znver1.md")
1216 (include "geode.md")
1220 (include "core2.md")
1221 (include "haswell.md")
1224 ;; Operand and operator predicates and constraints
1226 (include "predicates.md")
1227 (include "constraints.md")
1230 ;; Compare and branch/compare and store instructions.
1232 (define_expand "cbranch<mode>4"
1233 [(set (reg:CC FLAGS_REG)
1234 (compare:CC (match_operand:SDWIM 1 "nonimmediate_operand")
1235 (match_operand:SDWIM 2 "<general_operand>")))
1236 (set (pc) (if_then_else
1237 (match_operator 0 "ordered_comparison_operator"
1238 [(reg:CC FLAGS_REG) (const_int 0)])
1239 (label_ref (match_operand 3))
1243 if (MEM_P (operands[1]) && MEM_P (operands[2]))
1244 operands[1] = force_reg (<MODE>mode, operands[1]);
1245 ix86_expand_branch (GET_CODE (operands[0]),
1246 operands[1], operands[2], operands[3]);
1250 (define_expand "cstore<mode>4"
1251 [(set (reg:CC FLAGS_REG)
1252 (compare:CC (match_operand:SWIM 2 "nonimmediate_operand")
1253 (match_operand:SWIM 3 "<general_operand>")))
1254 (set (match_operand:QI 0 "register_operand")
1255 (match_operator 1 "ordered_comparison_operator"
1256 [(reg:CC FLAGS_REG) (const_int 0)]))]
1259 if (MEM_P (operands[2]) && MEM_P (operands[3]))
1260 operands[2] = force_reg (<MODE>mode, operands[2]);
1261 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1262 operands[2], operands[3]);
1266 (define_expand "cmp<mode>_1"
1267 [(set (reg:CC FLAGS_REG)
1268 (compare:CC (match_operand:SWI48 0 "nonimmediate_operand")
1269 (match_operand:SWI48 1 "<general_operand>")))])
1271 (define_mode_iterator SWI1248_AVX512BWDQ_64
1272 [(QI "TARGET_AVX512DQ") HI
1273 (SI "TARGET_AVX512BW") (DI "TARGET_AVX512BW && TARGET_64BIT")])
1275 (define_insn "*cmp<mode>_ccz_1"
1276 [(set (reg FLAGS_REG)
1277 (compare (match_operand:SWI1248_AVX512BWDQ_64 0
1278 "nonimmediate_operand" "<r>,?m<r>,$k")
1279 (match_operand:SWI1248_AVX512BWDQ_64 1 "const0_operand")))]
1280 "TARGET_AVX512F && ix86_match_ccmode (insn, CCZmode)"
1282 test{<imodesuffix>}\t%0, %0
1283 cmp{<imodesuffix>}\t{%1, %0|%0, %1}
1284 kortest<mskmodesuffix>\t%0, %0"
1285 [(set_attr "type" "test,icmp,msklog")
1286 (set_attr "length_immediate" "0,1,*")
1287 (set_attr "prefix" "*,*,vex")
1288 (set_attr "mode" "<MODE>")])
1290 (define_insn "*cmp<mode>_ccno_1"
1291 [(set (reg FLAGS_REG)
1292 (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>,?m<r>")
1293 (match_operand:SWI 1 "const0_operand")))]
1294 "ix86_match_ccmode (insn, CCNOmode)"
1296 test{<imodesuffix>}\t%0, %0
1297 cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1298 [(set_attr "type" "test,icmp")
1299 (set_attr "length_immediate" "0,1")
1300 (set_attr "mode" "<MODE>")])
1302 (define_insn "*cmp<mode>_1"
1303 [(set (reg FLAGS_REG)
1304 (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
1305 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m")))]
1306 "ix86_match_ccmode (insn, CCmode)"
1307 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1308 [(set_attr "type" "icmp")
1309 (set_attr "mode" "<MODE>")])
1311 (define_insn "*cmp<mode>_minus_1"
1312 [(set (reg FLAGS_REG)
1314 (minus:SWI (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
1315 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
1317 "ix86_match_ccmode (insn, CCGOCmode)"
1318 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1319 [(set_attr "type" "icmp")
1320 (set_attr "mode" "<MODE>")])
1322 (define_insn "*cmpqi_ext_1"
1323 [(set (reg FLAGS_REG)
1325 (match_operand:QI 0 "nonimmediate_operand" "QBc,m")
1328 (match_operand 1 "ext_register_operand" "Q,Q")
1330 (const_int 8)) 0)))]
1331 "ix86_match_ccmode (insn, CCmode)"
1332 "cmp{b}\t{%h1, %0|%0, %h1}"
1333 [(set_attr "isa" "*,nox64")
1334 (set_attr "type" "icmp")
1335 (set_attr "mode" "QI")])
1337 (define_insn "*cmpqi_ext_2"
1338 [(set (reg FLAGS_REG)
1342 (match_operand 0 "ext_register_operand" "Q")
1345 (match_operand:QI 1 "const0_operand")))]
1346 "ix86_match_ccmode (insn, CCNOmode)"
1348 [(set_attr "type" "test")
1349 (set_attr "length_immediate" "0")
1350 (set_attr "mode" "QI")])
1352 (define_expand "cmpqi_ext_3"
1353 [(set (reg:CC FLAGS_REG)
1357 (match_operand 0 "ext_register_operand")
1360 (match_operand:QI 1 "const_int_operand")))])
1362 (define_insn "*cmpqi_ext_3"
1363 [(set (reg FLAGS_REG)
1367 (match_operand 0 "ext_register_operand" "Q,Q")
1370 (match_operand:QI 1 "general_operand" "QnBc,m")))]
1371 "ix86_match_ccmode (insn, CCmode)"
1372 "cmp{b}\t{%1, %h0|%h0, %1}"
1373 [(set_attr "isa" "*,nox64")
1374 (set_attr "type" "icmp")
1375 (set_attr "mode" "QI")])
1377 (define_insn "*cmpqi_ext_4"
1378 [(set (reg FLAGS_REG)
1382 (match_operand 0 "ext_register_operand" "Q")
1387 (match_operand 1 "ext_register_operand" "Q")
1389 (const_int 8)) 0)))]
1390 "ix86_match_ccmode (insn, CCmode)"
1391 "cmp{b}\t{%h1, %h0|%h0, %h1}"
1392 [(set_attr "type" "icmp")
1393 (set_attr "mode" "QI")])
1395 ;; These implement float point compares.
1396 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
1397 ;; which would allow mix and match FP modes on the compares. Which is what
1398 ;; the old patterns did, but with many more of them.
1400 (define_expand "cbranchxf4"
1401 [(set (reg:CC FLAGS_REG)
1402 (compare:CC (match_operand:XF 1 "nonmemory_operand")
1403 (match_operand:XF 2 "nonmemory_operand")))
1404 (set (pc) (if_then_else
1405 (match_operator 0 "ix86_fp_comparison_operator"
1408 (label_ref (match_operand 3))
1412 ix86_expand_branch (GET_CODE (operands[0]),
1413 operands[1], operands[2], operands[3]);
1417 (define_expand "cstorexf4"
1418 [(set (reg:CC FLAGS_REG)
1419 (compare:CC (match_operand:XF 2 "nonmemory_operand")
1420 (match_operand:XF 3 "nonmemory_operand")))
1421 (set (match_operand:QI 0 "register_operand")
1422 (match_operator 1 "ix86_fp_comparison_operator"
1427 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1428 operands[2], operands[3]);
1432 (define_expand "cbranch<mode>4"
1433 [(set (reg:CC FLAGS_REG)
1434 (compare:CC (match_operand:MODEF 1 "cmp_fp_expander_operand")
1435 (match_operand:MODEF 2 "cmp_fp_expander_operand")))
1436 (set (pc) (if_then_else
1437 (match_operator 0 "ix86_fp_comparison_operator"
1440 (label_ref (match_operand 3))
1442 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1444 ix86_expand_branch (GET_CODE (operands[0]),
1445 operands[1], operands[2], operands[3]);
1449 (define_expand "cstore<mode>4"
1450 [(set (reg:CC FLAGS_REG)
1451 (compare:CC (match_operand:MODEF 2 "cmp_fp_expander_operand")
1452 (match_operand:MODEF 3 "cmp_fp_expander_operand")))
1453 (set (match_operand:QI 0 "register_operand")
1454 (match_operator 1 "ix86_fp_comparison_operator"
1457 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1459 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1460 operands[2], operands[3]);
1464 (define_expand "cbranchcc4"
1465 [(set (pc) (if_then_else
1466 (match_operator 0 "comparison_operator"
1467 [(match_operand 1 "flags_reg_operand")
1468 (match_operand 2 "const0_operand")])
1469 (label_ref (match_operand 3))
1473 ix86_expand_branch (GET_CODE (operands[0]),
1474 operands[1], operands[2], operands[3]);
1478 (define_expand "cstorecc4"
1479 [(set (match_operand:QI 0 "register_operand")
1480 (match_operator 1 "comparison_operator"
1481 [(match_operand 2 "flags_reg_operand")
1482 (match_operand 3 "const0_operand")]))]
1485 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1486 operands[2], operands[3]);
1490 ;; FP compares, step 1:
1491 ;; Set the FP condition codes and move fpsr to ax.
1493 ;; We may not use "#" to split and emit these
1494 ;; due to reg-stack pops killing fpsr.
1496 (define_insn "*cmpxf_i387"
1497 [(set (match_operand:HI 0 "register_operand" "=a")
1500 (match_operand:XF 1 "register_operand" "f")
1501 (match_operand:XF 2 "reg_or_0_operand" "fC"))]
1504 "* return output_fp_compare (insn, operands, false, false);"
1505 [(set_attr "type" "multi")
1506 (set_attr "unit" "i387")
1507 (set_attr "mode" "XF")])
1509 (define_insn "*cmp<mode>_i387"
1510 [(set (match_operand:HI 0 "register_operand" "=a")
1513 (match_operand:MODEF 1 "register_operand" "f")
1514 (match_operand:MODEF 2 "nonimm_or_0_operand" "fmC"))]
1517 "* return output_fp_compare (insn, operands, false, false);"
1518 [(set_attr "type" "multi")
1519 (set_attr "unit" "i387")
1520 (set_attr "mode" "<MODE>")])
1522 (define_insn "*cmp<X87MODEF:mode>_<SWI24:mode>_i387"
1523 [(set (match_operand:HI 0 "register_operand" "=a")
1526 (match_operand:X87MODEF 1 "register_operand" "f")
1528 (match_operand:SWI24 2 "nonimmediate_operand" "m")))]
1531 && (TARGET_USE_<SWI24:MODE>MODE_FIOP
1532 || optimize_function_for_size_p (cfun))"
1533 "* return output_fp_compare (insn, operands, false, false);"
1534 [(set_attr "type" "multi")
1535 (set_attr "unit" "i387")
1536 (set_attr "fp_int_src" "true")
1537 (set_attr "mode" "<SWI24:MODE>")])
1539 (define_insn "*cmpu<mode>_i387"
1540 [(set (match_operand:HI 0 "register_operand" "=a")
1544 (match_operand:X87MODEF 1 "register_operand" "f")
1545 (match_operand:X87MODEF 2 "register_operand" "f"))]
1549 "* return output_fp_compare (insn, operands, false, true);"
1550 [(set_attr "type" "multi")
1551 (set_attr "unit" "i387")
1552 (set_attr "mode" "<MODE>")])
1554 ;; FP compares, step 2:
1555 ;; Get ax into flags, general case.
1557 (define_insn "x86_sahf_1"
1558 [(set (reg:CC FLAGS_REG)
1559 (unspec:CC [(match_operand:HI 0 "register_operand" "a")]
1563 #ifndef HAVE_AS_IX86_SAHF
1565 return ASM_BYTE "0x9e";
1570 [(set_attr "length" "1")
1571 (set_attr "athlon_decode" "vector")
1572 (set_attr "amdfam10_decode" "direct")
1573 (set_attr "bdver1_decode" "direct")
1574 (set_attr "mode" "SI")])
1576 ;; Pentium Pro can do both steps in one go.
1577 ;; (these instructions set flags directly)
1579 (define_subst_attr "unord" "unord_subst" "" "u")
1580 (define_subst_attr "unordered" "unord_subst" "false" "true")
1582 (define_subst "unord_subst"
1583 [(set (match_operand:CCFP 0)
1584 (match_operand:CCFP 1))]
1591 (define_insn "*cmpi<unord>xf_i387"
1592 [(set (reg:CCFP FLAGS_REG)
1594 (match_operand:XF 0 "register_operand" "f")
1595 (match_operand:XF 1 "register_operand" "f")))]
1596 "TARGET_80387 && TARGET_CMOVE"
1597 "* return output_fp_compare (insn, operands, true, <unordered>);"
1598 [(set_attr "type" "fcmp")
1599 (set_attr "mode" "XF")
1600 (set_attr "athlon_decode" "vector")
1601 (set_attr "amdfam10_decode" "direct")
1602 (set_attr "bdver1_decode" "double")
1603 (set_attr "znver1_decode" "double")])
1605 (define_insn "*cmpi<unord><MODEF:mode>"
1606 [(set (reg:CCFP FLAGS_REG)
1608 (match_operand:MODEF 0 "register_operand" "f,v")
1609 (match_operand:MODEF 1 "register_ssemem_operand" "f,vm")))]
1610 "(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
1611 || (TARGET_80387 && TARGET_CMOVE)"
1613 * return output_fp_compare (insn, operands, true, <unordered>);
1614 %v<unord>comi<MODEF:ssemodesuffix>\t{%1, %0|%0, %1}"
1615 [(set_attr "type" "fcmp,ssecomi")
1616 (set_attr "prefix" "orig,maybe_vex")
1617 (set_attr "mode" "<MODEF:MODE>")
1618 (set_attr "prefix_rep" "*,0")
1619 (set (attr "prefix_data16")
1620 (cond [(eq_attr "alternative" "0")
1622 (eq_attr "mode" "DF")
1625 (const_string "0")))
1626 (set_attr "athlon_decode" "vector")
1627 (set_attr "amdfam10_decode" "direct")
1628 (set_attr "bdver1_decode" "double")
1629 (set_attr "znver1_decode" "double")
1630 (set (attr "enabled")
1632 (match_test ("SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"))
1634 (eq_attr "alternative" "0")
1635 (symbol_ref "TARGET_MIX_SSE_I387")
1636 (symbol_ref "true"))
1638 (eq_attr "alternative" "0")
1640 (symbol_ref "false"))))])
1642 ;; Push/pop instructions.
1644 (define_insn "*push<mode>2"
1645 [(set (match_operand:DWI 0 "push_operand" "=<")
1646 (match_operand:DWI 1 "general_no_elim_operand" "riF*o"))]
1649 [(set_attr "type" "multi")
1650 (set_attr "mode" "<MODE>")])
1653 [(set (match_operand:DWI 0 "push_operand")
1654 (match_operand:DWI 1 "general_gr_operand"))]
1657 "ix86_split_long_move (operands); DONE;")
1659 (define_insn "*pushdi2_rex64"
1660 [(set (match_operand:DI 0 "push_operand" "=<,!<")
1661 (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1666 [(set_attr "type" "push,multi")
1667 (set_attr "mode" "DI")])
1669 ;; Convert impossible pushes of immediate to existing instructions.
1670 ;; First try to get scratch register and go through it. In case this
1671 ;; fails, push sign extended lower part first and then overwrite
1672 ;; upper part by 32bit move.
1674 [(match_scratch:DI 2 "r")
1675 (set (match_operand:DI 0 "push_operand")
1676 (match_operand:DI 1 "immediate_operand"))]
1677 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1678 && !x86_64_immediate_operand (operands[1], DImode)"
1679 [(set (match_dup 2) (match_dup 1))
1680 (set (match_dup 0) (match_dup 2))])
1682 ;; We need to define this as both peepholer and splitter for case
1683 ;; peephole2 pass is not run.
1684 ;; "&& 1" is needed to keep it from matching the previous pattern.
1686 [(set (match_operand:DI 0 "push_operand")
1687 (match_operand:DI 1 "immediate_operand"))]
1688 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1689 && !x86_64_immediate_operand (operands[1], DImode) && 1"
1690 [(set (match_dup 0) (match_dup 1))
1691 (set (match_dup 2) (match_dup 3))]
1693 split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1695 operands[1] = gen_lowpart (DImode, operands[2]);
1696 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (Pmode, stack_pointer_rtx,
1701 [(set (match_operand:DI 0 "push_operand")
1702 (match_operand:DI 1 "immediate_operand"))]
1703 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
1704 ? epilogue_completed : reload_completed)
1705 && !symbolic_operand (operands[1], DImode)
1706 && !x86_64_immediate_operand (operands[1], DImode)"
1707 [(set (match_dup 0) (match_dup 1))
1708 (set (match_dup 2) (match_dup 3))]
1710 split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1712 operands[1] = gen_lowpart (DImode, operands[2]);
1713 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (Pmode, stack_pointer_rtx,
1717 (define_insn "*pushsi2"
1718 [(set (match_operand:SI 0 "push_operand" "=<")
1719 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1722 [(set_attr "type" "push")
1723 (set_attr "mode" "SI")])
1725 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1726 ;; "push a byte/word". But actually we use pushl, which has the effect
1727 ;; of rounding the amount pushed up to a word.
1729 ;; For TARGET_64BIT we always round up to 8 bytes.
1730 (define_insn "*push<mode>2_rex64"
1731 [(set (match_operand:SWI124 0 "push_operand" "=X")
1732 (match_operand:SWI124 1 "nonmemory_no_elim_operand" "r<i>"))]
1735 [(set_attr "type" "push")
1736 (set_attr "mode" "DI")])
1738 (define_insn "*push<mode>2"
1739 [(set (match_operand:SWI12 0 "push_operand" "=X")
1740 (match_operand:SWI12 1 "nonmemory_no_elim_operand" "rn"))]
1743 [(set_attr "type" "push")
1744 (set_attr "mode" "SI")])
1746 (define_insn "*push<mode>2_prologue"
1747 [(set (match_operand:W 0 "push_operand" "=<")
1748 (match_operand:W 1 "general_no_elim_operand" "r<i>*m"))
1749 (clobber (mem:BLK (scratch)))]
1751 "push{<imodesuffix>}\t%1"
1752 [(set_attr "type" "push")
1753 (set_attr "mode" "<MODE>")])
1755 (define_insn "*pop<mode>1"
1756 [(set (match_operand:W 0 "nonimmediate_operand" "=r*m")
1757 (match_operand:W 1 "pop_operand" ">"))]
1759 "pop{<imodesuffix>}\t%0"
1760 [(set_attr "type" "pop")
1761 (set_attr "mode" "<MODE>")])
1763 (define_insn "*pop<mode>1_epilogue"
1764 [(set (match_operand:W 0 "nonimmediate_operand" "=r*m")
1765 (match_operand:W 1 "pop_operand" ">"))
1766 (clobber (mem:BLK (scratch)))]
1768 "pop{<imodesuffix>}\t%0"
1769 [(set_attr "type" "pop")
1770 (set_attr "mode" "<MODE>")])
1772 (define_insn "*pushfl<mode>2"
1773 [(set (match_operand:W 0 "push_operand" "=<")
1774 (match_operand:W 1 "flags_reg_operand"))]
1776 "pushf{<imodesuffix>}"
1777 [(set_attr "type" "push")
1778 (set_attr "mode" "<MODE>")])
1780 (define_insn "*popfl<mode>1"
1781 [(set (match_operand:W 0 "flags_reg_operand")
1782 (match_operand:W 1 "pop_operand" ">"))]
1784 "popf{<imodesuffix>}"
1785 [(set_attr "type" "pop")
1786 (set_attr "mode" "<MODE>")])
1789 ;; Reload patterns to support multi-word load/store
1790 ;; with non-offsetable address.
1791 (define_expand "reload_noff_store"
1792 [(parallel [(match_operand 0 "memory_operand" "=m")
1793 (match_operand 1 "register_operand" "r")
1794 (match_operand:DI 2 "register_operand" "=&r")])]
1797 rtx mem = operands[0];
1798 rtx addr = XEXP (mem, 0);
1800 emit_move_insn (operands[2], addr);
1801 mem = replace_equiv_address_nv (mem, operands[2]);
1803 emit_insn (gen_rtx_SET (mem, operands[1]));
1807 (define_expand "reload_noff_load"
1808 [(parallel [(match_operand 0 "register_operand" "=r")
1809 (match_operand 1 "memory_operand" "m")
1810 (match_operand:DI 2 "register_operand" "=r")])]
1813 rtx mem = operands[1];
1814 rtx addr = XEXP (mem, 0);
1816 emit_move_insn (operands[2], addr);
1817 mem = replace_equiv_address_nv (mem, operands[2]);
1819 emit_insn (gen_rtx_SET (operands[0], mem));
1823 ;; Move instructions.
1825 (define_expand "movxi"
1826 [(set (match_operand:XI 0 "nonimmediate_operand")
1827 (match_operand:XI 1 "general_operand"))]
1829 "ix86_expand_vector_move (XImode, operands); DONE;")
1831 (define_expand "movoi"
1832 [(set (match_operand:OI 0 "nonimmediate_operand")
1833 (match_operand:OI 1 "general_operand"))]
1835 "ix86_expand_vector_move (OImode, operands); DONE;")
1837 (define_expand "movti"
1838 [(set (match_operand:TI 0 "nonimmediate_operand")
1839 (match_operand:TI 1 "general_operand"))]
1840 "TARGET_64BIT || TARGET_SSE"
1843 ix86_expand_move (TImode, operands);
1845 ix86_expand_vector_move (TImode, operands);
1849 ;; This expands to what emit_move_complex would generate if we didn't
1850 ;; have a movti pattern. Having this avoids problems with reload on
1851 ;; 32-bit targets when SSE is present, but doesn't seem to be harmful
1852 ;; to have around all the time.
1853 (define_expand "movcdi"
1854 [(set (match_operand:CDI 0 "nonimmediate_operand")
1855 (match_operand:CDI 1 "general_operand"))]
1858 if (push_operand (operands[0], CDImode))
1859 emit_move_complex_push (CDImode, operands[0], operands[1]);
1861 emit_move_complex_parts (operands[0], operands[1]);
1865 (define_expand "mov<mode>"
1866 [(set (match_operand:SWI1248x 0 "nonimmediate_operand")
1867 (match_operand:SWI1248x 1 "general_operand"))]
1869 "ix86_expand_move (<MODE>mode, operands); DONE;")
1871 (define_insn "*mov<mode>_xor"
1872 [(set (match_operand:SWI48 0 "register_operand" "=r")
1873 (match_operand:SWI48 1 "const0_operand"))
1874 (clobber (reg:CC FLAGS_REG))]
1877 [(set_attr "type" "alu1")
1878 (set_attr "mode" "SI")
1879 (set_attr "length_immediate" "0")])
1881 (define_insn "*mov<mode>_or"
1882 [(set (match_operand:SWI48 0 "register_operand" "=r")
1883 (match_operand:SWI48 1 "constm1_operand"))
1884 (clobber (reg:CC FLAGS_REG))]
1886 "or{<imodesuffix>}\t{%1, %0|%0, %1}"
1887 [(set_attr "type" "alu1")
1888 (set_attr "mode" "<MODE>")
1889 (set_attr "length_immediate" "1")])
1891 (define_insn "*movxi_internal_avx512f"
1892 [(set (match_operand:XI 0 "nonimmediate_operand" "=v,v ,v ,m")
1893 (match_operand:XI 1 "nonimmediate_or_sse_const_operand" " C,BC,vm,v"))]
1895 && (register_operand (operands[0], XImode)
1896 || register_operand (operands[1], XImode))"
1898 switch (get_attr_type (insn))
1901 return standard_sse_constant_opcode (insn, operands);
1904 if (misaligned_operand (operands[0], XImode)
1905 || misaligned_operand (operands[1], XImode))
1906 return "vmovdqu32\t{%1, %0|%0, %1}";
1908 return "vmovdqa32\t{%1, %0|%0, %1}";
1914 [(set_attr "type" "sselog1,sselog1,ssemov,ssemov")
1915 (set_attr "prefix" "evex")
1916 (set_attr "mode" "XI")])
1918 (define_insn "*movoi_internal_avx"
1919 [(set (match_operand:OI 0 "nonimmediate_operand" "=v,v ,v ,m")
1920 (match_operand:OI 1 "nonimmediate_or_sse_const_operand" " C,BC,vm,v"))]
1922 && (register_operand (operands[0], OImode)
1923 || register_operand (operands[1], OImode))"
1925 switch (get_attr_type (insn))
1928 return standard_sse_constant_opcode (insn, operands);
1931 if (misaligned_operand (operands[0], OImode)
1932 || misaligned_operand (operands[1], OImode))
1934 if (get_attr_mode (insn) == MODE_V8SF)
1935 return "vmovups\t{%1, %0|%0, %1}";
1936 else if (get_attr_mode (insn) == MODE_XI)
1937 return "vmovdqu32\t{%1, %0|%0, %1}";
1939 return "vmovdqu\t{%1, %0|%0, %1}";
1943 if (get_attr_mode (insn) == MODE_V8SF)
1944 return "vmovaps\t{%1, %0|%0, %1}";
1945 else if (get_attr_mode (insn) == MODE_XI)
1946 return "vmovdqa32\t{%1, %0|%0, %1}";
1948 return "vmovdqa\t{%1, %0|%0, %1}";
1955 [(set_attr "isa" "*,avx2,*,*")
1956 (set_attr "type" "sselog1,sselog1,ssemov,ssemov")
1957 (set_attr "prefix" "vex")
1959 (cond [(ior (match_operand 0 "ext_sse_reg_operand")
1960 (match_operand 1 "ext_sse_reg_operand"))
1962 (and (eq_attr "alternative" "1")
1963 (match_test "TARGET_AVX512VL"))
1965 (ior (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
1966 (and (eq_attr "alternative" "3")
1967 (match_test "TARGET_SSE_TYPELESS_STORES")))
1968 (const_string "V8SF")
1970 (const_string "OI")))])
1972 (define_insn "*movti_internal"
1973 [(set (match_operand:TI 0 "nonimmediate_operand" "=!r ,o ,v,v ,v ,m,?r,?Yd")
1974 (match_operand:TI 1 "general_operand" "riFo,re,C,BC,vm,v,Yd,r"))]
1976 && !(MEM_P (operands[0]) && MEM_P (operands[1])))
1978 && nonimmediate_or_sse_const_operand (operands[1], TImode)
1979 && (register_operand (operands[0], TImode)
1980 || register_operand (operands[1], TImode)))"
1982 switch (get_attr_type (insn))
1988 return standard_sse_constant_opcode (insn, operands);
1991 /* TDmode values are passed as TImode on the stack. Moving them
1992 to stack may result in unaligned memory access. */
1993 if (misaligned_operand (operands[0], TImode)
1994 || misaligned_operand (operands[1], TImode))
1996 if (get_attr_mode (insn) == MODE_V4SF)
1997 return "%vmovups\t{%1, %0|%0, %1}";
1998 else if (get_attr_mode (insn) == MODE_XI)
1999 return "vmovdqu32\t{%1, %0|%0, %1}";
2001 return "%vmovdqu\t{%1, %0|%0, %1}";
2005 if (get_attr_mode (insn) == MODE_V4SF)
2006 return "%vmovaps\t{%1, %0|%0, %1}";
2007 else if (get_attr_mode (insn) == MODE_XI)
2008 return "vmovdqa32\t{%1, %0|%0, %1}";
2010 return "%vmovdqa\t{%1, %0|%0, %1}";
2018 (cond [(eq_attr "alternative" "0,1,6,7")
2019 (const_string "x64")
2020 (eq_attr "alternative" "3")
2021 (const_string "sse2")
2023 (const_string "*")))
2025 (cond [(eq_attr "alternative" "0,1,6,7")
2026 (const_string "multi")
2027 (eq_attr "alternative" "2,3")
2028 (const_string "sselog1")
2030 (const_string "ssemov")))
2031 (set (attr "prefix")
2032 (if_then_else (eq_attr "type" "sselog1,ssemov")
2033 (const_string "maybe_vex")
2034 (const_string "orig")))
2036 (cond [(eq_attr "alternative" "0,1")
2038 (ior (match_operand 0 "ext_sse_reg_operand")
2039 (match_operand 1 "ext_sse_reg_operand"))
2041 (and (eq_attr "alternative" "3")
2042 (match_test "TARGET_AVX512VL"))
2044 (ior (not (match_test "TARGET_SSE2"))
2045 (ior (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
2046 (and (eq_attr "alternative" "5")
2047 (match_test "TARGET_SSE_TYPELESS_STORES"))))
2048 (const_string "V4SF")
2049 (match_test "TARGET_AVX")
2051 (match_test "optimize_function_for_size_p (cfun)")
2052 (const_string "V4SF")
2054 (const_string "TI")))
2055 (set (attr "preferred_for_speed")
2056 (cond [(eq_attr "alternative" "6")
2057 (symbol_ref "TARGET_INTER_UNIT_MOVES_FROM_VEC")
2058 (eq_attr "alternative" "7")
2059 (symbol_ref "TARGET_INTER_UNIT_MOVES_TO_VEC")
2061 (symbol_ref "true")))])
2064 [(set (match_operand:TI 0 "sse_reg_operand")
2065 (match_operand:TI 1 "general_reg_operand"))]
2066 "TARGET_64BIT && TARGET_SSE4_1
2067 && reload_completed"
2070 (vec_duplicate:V2DI (match_dup 3))
2074 operands[2] = lowpart_subreg (V2DImode, operands[0], TImode);
2075 operands[3] = gen_highpart (DImode, operands[1]);
2077 emit_move_insn (gen_lowpart (DImode, operands[0]),
2078 gen_lowpart (DImode, operands[1]));
2081 (define_insn "*movdi_internal"
2082 [(set (match_operand:DI 0 "nonimmediate_operand"
2083 "=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,*k")
2084 (match_operand:DI 1 "general_operand"
2085 "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,CBC"))]
2086 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2088 switch (get_attr_type (insn))
2091 return "kmovq\t{%1, %0|%0, %1}";
2094 if (operands[1] == const0_rtx)
2095 return "kxorq\t%0, %0, %0";
2096 else if (operands[1] == constm1_rtx)
2097 return "kxnorq\t%0, %0, %0";
2104 return "pxor\t%0, %0";
2107 /* Handle broken assemblers that require movd instead of movq. */
2108 if (!HAVE_AS_IX86_INTERUNIT_MOVQ
2109 && (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1])))
2110 return "movd\t{%1, %0|%0, %1}";
2111 return "movq\t{%1, %0|%0, %1}";
2114 return standard_sse_constant_opcode (insn, operands);
2117 switch (get_attr_mode (insn))
2120 /* Handle broken assemblers that require movd instead of movq. */
2121 if (!HAVE_AS_IX86_INTERUNIT_MOVQ
2122 && (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1])))
2123 return "%vmovd\t{%1, %0|%0, %1}";
2124 return "%vmovq\t{%1, %0|%0, %1}";
2127 /* Handle AVX512 registers set. */
2128 if (EXT_REX_SSE_REG_P (operands[0])
2129 || EXT_REX_SSE_REG_P (operands[1]))
2130 return "vmovdqa64\t{%1, %0|%0, %1}";
2131 return "%vmovdqa\t{%1, %0|%0, %1}";
2134 gcc_assert (!TARGET_AVX);
2135 return "movlps\t{%1, %0|%0, %1}";
2137 return "%vmovaps\t{%1, %0|%0, %1}";
2144 if (SSE_REG_P (operands[0]))
2145 return "movq2dq\t{%1, %0|%0, %1}";
2147 return "movdq2q\t{%1, %0|%0, %1}";
2150 return "lea{q}\t{%E1, %0|%0, %E1}";
2153 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2154 if (get_attr_mode (insn) == MODE_SI)
2155 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2156 else if (which_alternative == 4)
2157 return "movabs{q}\t{%1, %0|%0, %1}";
2158 else if (ix86_use_lea_for_mov (insn, operands))
2159 return "lea{q}\t{%E1, %0|%0, %E1}";
2161 return "mov{q}\t{%1, %0|%0, %1}";
2168 (cond [(eq_attr "alternative" "0,1,17,18")
2169 (const_string "nox64")
2170 (eq_attr "alternative" "2,3,4,5,10,11,23,25")
2171 (const_string "x64")
2172 (eq_attr "alternative" "19,20")
2173 (const_string "x64_sse2")
2174 (eq_attr "alternative" "21,22")
2175 (const_string "sse2")
2177 (const_string "*")))
2179 (cond [(eq_attr "alternative" "0,1,17,18")
2180 (const_string "multi")
2181 (eq_attr "alternative" "6")
2182 (const_string "mmx")
2183 (eq_attr "alternative" "7,8,9,10,11")
2184 (const_string "mmxmov")
2185 (eq_attr "alternative" "12")
2186 (const_string "sselog1")
2187 (eq_attr "alternative" "13,14,15,16,19,20")
2188 (const_string "ssemov")
2189 (eq_attr "alternative" "21,22")
2190 (const_string "ssecvt")
2191 (eq_attr "alternative" "23,24,25,26")
2192 (const_string "mskmov")
2193 (eq_attr "alternative" "27")
2194 (const_string "msklog")
2195 (and (match_operand 0 "register_operand")
2196 (match_operand 1 "pic_32bit_operand"))
2197 (const_string "lea")
2199 (const_string "imov")))
2202 (and (eq_attr "alternative" "4") (eq_attr "type" "imov"))
2204 (const_string "*")))
2205 (set (attr "length_immediate")
2207 (and (eq_attr "alternative" "4") (eq_attr "type" "imov"))
2209 (const_string "*")))
2210 (set (attr "prefix_rex")
2212 (eq_attr "alternative" "10,11,19,20")
2214 (const_string "*")))
2215 (set (attr "prefix")
2216 (if_then_else (eq_attr "type" "sselog1,ssemov")
2217 (const_string "maybe_vex")
2218 (const_string "orig")))
2219 (set (attr "prefix_data16")
2220 (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "DI"))
2222 (const_string "*")))
2224 (cond [(eq_attr "alternative" "2")
2226 (eq_attr "alternative" "12,13")
2227 (cond [(ior (match_operand 0 "ext_sse_reg_operand")
2228 (match_operand 1 "ext_sse_reg_operand"))
2230 (ior (not (match_test "TARGET_SSE2"))
2231 (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL"))
2232 (const_string "V4SF")
2233 (match_test "TARGET_AVX")
2235 (match_test "optimize_function_for_size_p (cfun)")
2236 (const_string "V4SF")
2238 (const_string "TI"))
2240 (and (eq_attr "alternative" "14,15,16")
2241 (not (match_test "TARGET_SSE2")))
2242 (const_string "V2SF")
2244 (const_string "DI")))
2245 (set (attr "preferred_for_speed")
2246 (cond [(eq_attr "alternative" "10,17,19")
2247 (symbol_ref "TARGET_INTER_UNIT_MOVES_FROM_VEC")
2248 (eq_attr "alternative" "11,18,20")
2249 (symbol_ref "TARGET_INTER_UNIT_MOVES_TO_VEC")
2251 (symbol_ref "true")))
2252 (set (attr "enabled")
2253 (cond [(eq_attr "alternative" "15")
2255 (match_test "TARGET_STV && TARGET_SSE2")
2256 (symbol_ref "false")
2258 (eq_attr "alternative" "16")
2260 (match_test "TARGET_STV && TARGET_SSE2")
2262 (symbol_ref "false"))
2264 (const_string "*")))])
2267 [(set (match_operand:<DWI> 0 "general_reg_operand")
2268 (match_operand:<DWI> 1 "sse_reg_operand"))]
2270 && reload_completed"
2274 (parallel [(const_int 1)])))]
2276 operands[2] = gen_highpart (<MODE>mode, operands[0]);
2277 operands[3] = lowpart_subreg (<ssevecmode>mode, operands[1], <DWI>mode);
2279 emit_move_insn (gen_lowpart (<MODE>mode, operands[0]),
2280 gen_lowpart (<MODE>mode, operands[1]));
2284 [(set (match_operand:DWI 0 "nonimmediate_gr_operand")
2285 (match_operand:DWI 1 "general_gr_operand"))]
2288 "ix86_split_long_move (operands); DONE;")
2291 [(set (match_operand:DI 0 "sse_reg_operand")
2292 (match_operand:DI 1 "general_reg_operand"))]
2293 "!TARGET_64BIT && TARGET_SSE4_1
2294 && reload_completed"
2297 (vec_duplicate:V4SI (match_dup 3))
2301 operands[2] = lowpart_subreg (V4SImode, operands[0], DImode);
2302 operands[3] = gen_highpart (SImode, operands[1]);
2304 emit_move_insn (gen_lowpart (SImode, operands[0]),
2305 gen_lowpart (SImode, operands[1]));
2308 ;; movabsq $0x0012345678000000, %rax is longer
2309 ;; than movl $0x12345678, %eax; shlq $24, %rax.
2311 [(set (match_operand:DI 0 "register_operand")
2312 (match_operand:DI 1 "const_int_operand"))]
2314 && optimize_insn_for_size_p ()
2315 && LEGACY_INT_REG_P (operands[0])
2316 && !x86_64_immediate_operand (operands[1], DImode)
2317 && !x86_64_zext_immediate_operand (operands[1], DImode)
2318 && !((UINTVAL (operands[1]) >> ctz_hwi (UINTVAL (operands[1])))
2319 & ~(HOST_WIDE_INT) 0xffffffff)
2320 && peep2_regno_dead_p (0, FLAGS_REG)"
2321 [(set (match_dup 0) (match_dup 1))
2322 (parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
2323 (clobber (reg:CC FLAGS_REG))])]
2325 int shift = ctz_hwi (UINTVAL (operands[1]));
2326 operands[1] = gen_int_mode (UINTVAL (operands[1]) >> shift, DImode);
2327 operands[2] = gen_int_mode (shift, QImode);
2330 (define_insn "*movsi_internal"
2331 [(set (match_operand:SI 0 "nonimmediate_operand"
2332 "=r,m ,*y,*y,?*y,?m,?r,?*y,*v,*v,*v,m ,?r,?*v,*k,*k ,*rm,*k")
2333 (match_operand:SI 1 "general_operand"
2334 "g ,re,C ,*y,m ,*y,*y,r ,C ,*v,m ,*v,*v,r ,*r,*km,*k ,CBC"))]
2335 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2337 switch (get_attr_type (insn))
2340 return standard_sse_constant_opcode (insn, operands);
2343 return "kmovd\t{%1, %0|%0, %1}";
2346 if (operands[1] == const0_rtx)
2347 return "kxord\t%0, %0, %0";
2348 else if (operands[1] == constm1_rtx)
2349 return "kxnord\t%0, %0, %0";
2353 switch (get_attr_mode (insn))
2356 return "%vmovd\t{%1, %0|%0, %1}";
2358 return "%vmovdqa\t{%1, %0|%0, %1}";
2360 return "vmovdqa32\t{%g1, %g0|%g0, %g1}";
2363 return "%vmovaps\t{%1, %0|%0, %1}";
2366 gcc_assert (!TARGET_AVX);
2367 return "movss\t{%1, %0|%0, %1}";
2374 return "pxor\t%0, %0";
2377 switch (get_attr_mode (insn))
2380 return "movq\t{%1, %0|%0, %1}";
2382 return "movd\t{%1, %0|%0, %1}";
2389 return "lea{l}\t{%E1, %0|%0, %E1}";
2392 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2393 if (ix86_use_lea_for_mov (insn, operands))
2394 return "lea{l}\t{%E1, %0|%0, %E1}";
2396 return "mov{l}\t{%1, %0|%0, %1}";
2403 (cond [(eq_attr "alternative" "12,13")
2404 (const_string "sse2")
2406 (const_string "*")))
2408 (cond [(eq_attr "alternative" "2")
2409 (const_string "mmx")
2410 (eq_attr "alternative" "3,4,5,6,7")
2411 (const_string "mmxmov")
2412 (eq_attr "alternative" "8")
2413 (const_string "sselog1")
2414 (eq_attr "alternative" "9,10,11,12,13")
2415 (const_string "ssemov")
2416 (eq_attr "alternative" "14,15,16")
2417 (const_string "mskmov")
2418 (eq_attr "alternative" "17")
2419 (const_string "msklog")
2420 (and (match_operand 0 "register_operand")
2421 (match_operand 1 "pic_32bit_operand"))
2422 (const_string "lea")
2424 (const_string "imov")))
2425 (set (attr "prefix")
2426 (if_then_else (eq_attr "type" "sselog1,ssemov")
2427 (const_string "maybe_vex")
2428 (const_string "orig")))
2429 (set (attr "prefix_data16")
2430 (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
2432 (const_string "*")))
2434 (cond [(eq_attr "alternative" "2,3")
2436 (eq_attr "alternative" "8,9")
2437 (cond [(ior (match_operand 0 "ext_sse_reg_operand")
2438 (match_operand 1 "ext_sse_reg_operand"))
2440 (ior (not (match_test "TARGET_SSE2"))
2441 (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL"))
2442 (const_string "V4SF")
2443 (match_test "TARGET_AVX")
2445 (match_test "optimize_function_for_size_p (cfun)")
2446 (const_string "V4SF")
2448 (const_string "TI"))
2450 (and (eq_attr "alternative" "10,11")
2451 (not (match_test "TARGET_SSE2")))
2454 (const_string "SI")))
2455 (set (attr "preferred_for_speed")
2456 (cond [(eq_attr "alternative" "6,12")
2457 (symbol_ref "TARGET_INTER_UNIT_MOVES_FROM_VEC")
2458 (eq_attr "alternative" "7,13")
2459 (symbol_ref "TARGET_INTER_UNIT_MOVES_TO_VEC")
2461 (symbol_ref "true")))])
2463 (define_insn "*movhi_internal"
2464 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r ,r ,m ,k,k ,r,m,k")
2465 (match_operand:HI 1 "general_operand" "r ,rn,rm,rn,r,km,k,k,CBC"))]
2466 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2468 switch (get_attr_type (insn))
2471 /* movzwl is faster than movw on p2 due to partial word stalls,
2472 though not as fast as an aligned movl. */
2473 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
2476 switch (which_alternative)
2479 return "kmovw\t{%k1, %0|%0, %k1}";
2481 return "kmovw\t{%1, %k0|%k0, %1}";
2484 return "kmovw\t{%1, %0|%0, %1}";
2490 if (operands[1] == const0_rtx)
2491 return "kxorw\t%0, %0, %0";
2492 else if (operands[1] == constm1_rtx)
2493 return "kxnorw\t%0, %0, %0";
2497 if (get_attr_mode (insn) == MODE_SI)
2498 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2500 return "mov{w}\t{%1, %0|%0, %1}";
2504 (cond [(eq_attr "alternative" "4,5,6,7")
2505 (const_string "mskmov")
2506 (eq_attr "alternative" "8")
2507 (const_string "msklog")
2508 (match_test "optimize_function_for_size_p (cfun)")
2509 (const_string "imov")
2510 (and (eq_attr "alternative" "0")
2511 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2512 (not (match_test "TARGET_HIMODE_MATH"))))
2513 (const_string "imov")
2514 (and (eq_attr "alternative" "1,2")
2515 (match_operand:HI 1 "aligned_operand"))
2516 (const_string "imov")
2517 (and (match_test "TARGET_MOVX")
2518 (eq_attr "alternative" "0,2"))
2519 (const_string "imovx")
2521 (const_string "imov")))
2522 (set (attr "prefix")
2523 (if_then_else (eq_attr "alternative" "4,5,6,7,8")
2524 (const_string "vex")
2525 (const_string "orig")))
2527 (cond [(eq_attr "type" "imovx")
2529 (and (eq_attr "alternative" "1,2")
2530 (match_operand:HI 1 "aligned_operand"))
2532 (and (eq_attr "alternative" "0")
2533 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2534 (not (match_test "TARGET_HIMODE_MATH"))))
2537 (const_string "HI")))])
2539 ;; Situation is quite tricky about when to choose full sized (SImode) move
2540 ;; over QImode moves. For Q_REG -> Q_REG move we use full size only for
2541 ;; partial register dependency machines (such as AMD Athlon), where QImode
2542 ;; moves issue extra dependency and for partial register stalls machines
2543 ;; that don't use QImode patterns (and QImode move cause stall on the next
2546 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
2547 ;; register stall machines with, where we use QImode instructions, since
2548 ;; partial register stall can be caused there. Then we use movzx.
2550 (define_insn "*movqi_internal"
2551 [(set (match_operand:QI 0 "nonimmediate_operand"
2552 "=Q,R,r,q,q,r,r ,?r,m ,k,k,r,m,k,k,k")
2553 (match_operand:QI 1 "general_operand"
2554 "Q ,R,r,n,m,q,rn, m,qn,r,k,k,k,m,C,BC"))]
2555 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2561 switch (get_attr_type (insn))
2564 gcc_assert (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]));
2565 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
2568 switch (which_alternative)
2571 ops = "kmov%s\t{%%k1, %%0|%%0, %%k1}";
2574 ops = "kmov%s\t{%%1, %%k0|%%k0, %%1}";
2578 gcc_assert (TARGET_AVX512DQ);
2581 ops = "kmov%s\t{%%1, %%0|%%0, %%1}";
2587 suffix = (get_attr_mode (insn) == MODE_HI) ? "w" : "b";
2589 snprintf (buf, sizeof (buf), ops, suffix);
2590 output_asm_insn (buf, operands);
2594 if (operands[1] == const0_rtx)
2596 if (get_attr_mode (insn) == MODE_HI)
2597 return "kxorw\t%0, %0, %0";
2599 return "kxorb\t%0, %0, %0";
2601 else if (operands[1] == constm1_rtx)
2603 gcc_assert (TARGET_AVX512DQ);
2604 return "kxnorb\t%0, %0, %0";
2609 if (get_attr_mode (insn) == MODE_SI)
2610 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2612 return "mov{b}\t{%1, %0|%0, %1}";
2616 (cond [(eq_attr "alternative" "1,2")
2617 (const_string "x64")
2618 (eq_attr "alternative" "12,13,15")
2619 (const_string "avx512dq")
2621 (const_string "*")))
2623 (cond [(eq_attr "alternative" "9,10,11,12,13")
2624 (const_string "mskmov")
2625 (eq_attr "alternative" "14,15")
2626 (const_string "msklog")
2627 (and (eq_attr "alternative" "7")
2628 (not (match_operand:QI 1 "aligned_operand")))
2629 (const_string "imovx")
2630 (match_test "optimize_function_for_size_p (cfun)")
2631 (const_string "imov")
2632 (and (eq_attr "alternative" "5")
2633 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2634 (not (match_test "TARGET_QIMODE_MATH"))))
2635 (const_string "imov")
2636 (eq_attr "alternative" "5,7")
2637 (const_string "imovx")
2638 (and (match_test "TARGET_MOVX")
2639 (eq_attr "alternative" "4"))
2640 (const_string "imovx")
2642 (const_string "imov")))
2643 (set (attr "prefix")
2644 (if_then_else (eq_attr "alternative" "9,10,11,12,13,14,15")
2645 (const_string "vex")
2646 (const_string "orig")))
2648 (cond [(eq_attr "alternative" "5,6,7")
2650 (eq_attr "alternative" "8")
2652 (and (eq_attr "alternative" "9,10,11,14")
2653 (not (match_test "TARGET_AVX512DQ")))
2655 (eq_attr "type" "imovx")
2657 ;; For -Os, 8-bit immediates are always shorter than 32-bit
2659 (and (eq_attr "type" "imov")
2660 (and (eq_attr "alternative" "3")
2661 (match_test "optimize_function_for_size_p (cfun)")))
2663 ;; For -Os, movl where one or both operands are NON_Q_REGS
2664 ;; and both are LEGACY_REGS is shorter than movb.
2665 ;; Otherwise movb and movl sizes are the same, so decide purely
2666 ;; based on speed factors.
2667 (and (eq_attr "type" "imov")
2668 (and (eq_attr "alternative" "1")
2669 (match_test "optimize_function_for_size_p (cfun)")))
2671 (and (eq_attr "type" "imov")
2672 (and (eq_attr "alternative" "0,1,2,3")
2673 (and (match_test "TARGET_PARTIAL_REG_DEPENDENCY")
2674 (not (match_test "TARGET_PARTIAL_REG_STALL")))))
2676 ;; Avoid partial register stalls when not using QImode arithmetic
2677 (and (eq_attr "type" "imov")
2678 (and (eq_attr "alternative" "0,1,2,3")
2679 (and (match_test "TARGET_PARTIAL_REG_STALL")
2680 (not (match_test "TARGET_QIMODE_MATH")))))
2683 (const_string "QI")))])
2685 ;; Stores and loads of ax to arbitrary constant address.
2686 ;; We fake an second form of instruction to force reload to load address
2687 ;; into register when rax is not available
2688 (define_insn "*movabs<mode>_1"
2689 [(set (mem:SWI1248x (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2690 (match_operand:SWI1248x 1 "nonmemory_operand" "a,r<i>"))]
2691 "TARGET_LP64 && ix86_check_movabs (insn, 0)"
2693 /* Recover the full memory rtx. */
2694 operands[0] = SET_DEST (PATTERN (insn));
2695 switch (which_alternative)
2698 return "movabs{<imodesuffix>}\t{%1, %P0|<iptrsize> PTR [%P0], %1}";
2700 return "mov{<imodesuffix>}\t{%1, %0|%0, %1}";
2705 [(set_attr "type" "imov")
2706 (set_attr "modrm" "0,*")
2707 (set_attr "length_address" "8,0")
2708 (set_attr "length_immediate" "0,*")
2709 (set_attr "memory" "store")
2710 (set_attr "mode" "<MODE>")])
2712 (define_insn "*movabs<mode>_2"
2713 [(set (match_operand:SWI1248x 0 "register_operand" "=a,r")
2714 (mem:SWI1248x (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2715 "TARGET_LP64 && ix86_check_movabs (insn, 1)"
2717 /* Recover the full memory rtx. */
2718 operands[1] = SET_SRC (PATTERN (insn));
2719 switch (which_alternative)
2722 return "movabs{<imodesuffix>}\t{%P1, %0|%0, <iptrsize> PTR [%P1]}";
2724 return "mov{<imodesuffix>}\t{%1, %0|%0, %1}";
2729 [(set_attr "type" "imov")
2730 (set_attr "modrm" "0,*")
2731 (set_attr "length_address" "8,0")
2732 (set_attr "length_immediate" "0")
2733 (set_attr "memory" "load")
2734 (set_attr "mode" "<MODE>")])
2736 (define_insn "*swap<mode>"
2737 [(set (match_operand:SWI48 0 "register_operand" "+r")
2738 (match_operand:SWI48 1 "register_operand" "+r"))
2742 "xchg{<imodesuffix>}\t%1, %0"
2743 [(set_attr "type" "imov")
2744 (set_attr "mode" "<MODE>")
2745 (set_attr "pent_pair" "np")
2746 (set_attr "athlon_decode" "vector")
2747 (set_attr "amdfam10_decode" "double")
2748 (set_attr "bdver1_decode" "double")])
2750 (define_insn "*swap<mode>"
2751 [(set (match_operand:SWI12 0 "register_operand" "+<r>,r")
2752 (match_operand:SWI12 1 "register_operand" "+<r>,r"))
2757 xchg{<imodesuffix>}\t%1, %0
2759 [(set_attr "type" "imov")
2760 (set_attr "mode" "<MODE>,SI")
2761 (set (attr "preferred_for_size")
2762 (cond [(eq_attr "alternative" "0")
2763 (symbol_ref "false")]
2764 (symbol_ref "true")))
2765 ;; Potential partial reg stall on alternative 1.
2766 (set (attr "preferred_for_speed")
2767 (cond [(eq_attr "alternative" "1")
2768 (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
2769 (symbol_ref "true")))
2770 (set_attr "pent_pair" "np")
2771 (set_attr "athlon_decode" "vector")
2772 (set_attr "amdfam10_decode" "double")
2773 (set_attr "bdver1_decode" "double")])
2775 (define_expand "movstrict<mode>"
2776 [(set (strict_low_part (match_operand:SWI12 0 "nonimmediate_operand"))
2777 (match_operand:SWI12 1 "general_operand"))]
2780 if (TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun))
2782 if (SUBREG_P (operands[0])
2783 && GET_MODE_CLASS (GET_MODE (SUBREG_REG (operands[0]))) != MODE_INT)
2785 /* Don't generate memory->memory moves, go through a register */
2786 if (MEM_P (operands[0]) && MEM_P (operands[1]))
2787 operands[1] = force_reg (<MODE>mode, operands[1]);
2790 (define_insn "*movstrict<mode>_1"
2791 [(set (strict_low_part
2792 (match_operand:SWI12 0 "nonimmediate_operand" "+<r>m,<r>"))
2793 (match_operand:SWI12 1 "general_operand" "<r>n,m"))]
2794 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
2795 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2796 "mov{<imodesuffix>}\t{%1, %0|%0, %1}"
2797 [(set_attr "type" "imov")
2798 (set_attr "mode" "<MODE>")])
2800 (define_insn "*movstrict<mode>_xor"
2801 [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>"))
2802 (match_operand:SWI12 1 "const0_operand"))
2803 (clobber (reg:CC FLAGS_REG))]
2805 "xor{<imodesuffix>}\t%0, %0"
2806 [(set_attr "type" "alu1")
2807 (set_attr "mode" "<MODE>")
2808 (set_attr "length_immediate" "0")])
2810 (define_expand "extv<mode>"
2811 [(set (match_operand:SWI24 0 "register_operand")
2812 (sign_extract:SWI24 (match_operand:SWI24 1 "register_operand")
2813 (match_operand:SI 2 "const_int_operand")
2814 (match_operand:SI 3 "const_int_operand")))]
2817 /* Handle extractions from %ah et al. */
2818 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
2821 unsigned int regno = reg_or_subregno (operands[1]);
2823 /* Be careful to expand only with registers having upper parts. */
2824 if (regno <= LAST_VIRTUAL_REGISTER && !QI_REGNO_P (regno))
2825 operands[1] = copy_to_reg (operands[1]);
2828 (define_insn "*extv<mode>"
2829 [(set (match_operand:SWI24 0 "register_operand" "=R")
2830 (sign_extract:SWI24 (match_operand 1 "ext_register_operand" "Q")
2834 "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
2835 [(set_attr "type" "imovx")
2836 (set_attr "mode" "SI")])
2838 (define_expand "extzv<mode>"
2839 [(set (match_operand:SWI248 0 "register_operand")
2840 (zero_extract:SWI248 (match_operand:SWI248 1 "register_operand")
2841 (match_operand:SI 2 "const_int_operand")
2842 (match_operand:SI 3 "const_int_operand")))]
2845 if (ix86_expand_pextr (operands))
2848 /* Handle extractions from %ah et al. */
2849 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
2852 unsigned int regno = reg_or_subregno (operands[1]);
2854 /* Be careful to expand only with registers having upper parts. */
2855 if (regno <= LAST_VIRTUAL_REGISTER && !QI_REGNO_P (regno))
2856 operands[1] = copy_to_reg (operands[1]);
2859 (define_insn "*extzvqi_mem_rex64"
2860 [(set (match_operand:QI 0 "norex_memory_operand" "=Bn")
2862 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q")
2865 "TARGET_64BIT && reload_completed"
2866 "mov{b}\t{%h1, %0|%0, %h1}"
2867 [(set_attr "type" "imov")
2868 (set_attr "mode" "QI")])
2870 (define_insn "*extzv<mode>"
2871 [(set (match_operand:SWI248 0 "register_operand" "=R")
2872 (zero_extract:SWI248 (match_operand 1 "ext_register_operand" "Q")
2876 "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
2877 [(set_attr "type" "imovx")
2878 (set_attr "mode" "SI")])
2880 (define_insn "*extzvqi"
2881 [(set (match_operand:QI 0 "nonimmediate_operand" "=QBc,?R,m")
2883 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q,Q")
2888 switch (get_attr_type (insn))
2891 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2893 return "mov{b}\t{%h1, %0|%0, %h1}";
2896 [(set_attr "isa" "*,*,nox64")
2898 (if_then_else (and (match_operand:QI 0 "register_operand")
2899 (ior (not (match_operand:QI 0 "QIreg_operand"))
2900 (match_test "TARGET_MOVX")))
2901 (const_string "imovx")
2902 (const_string "imov")))
2904 (if_then_else (eq_attr "type" "imovx")
2906 (const_string "QI")))])
2909 [(set (match_operand:QI 0 "register_operand")
2911 (zero_extract:SI (match_operand 1 "ext_register_operand")
2914 (set (match_operand:QI 2 "norex_memory_operand") (match_dup 0))]
2916 && peep2_reg_dead_p (2, operands[0])"
2919 (zero_extract:SI (match_dup 1)
2921 (const_int 8)) 0))])
2923 (define_expand "insv<mode>"
2924 [(set (zero_extract:SWI248 (match_operand:SWI248 0 "register_operand")
2925 (match_operand:SI 1 "const_int_operand")
2926 (match_operand:SI 2 "const_int_operand"))
2927 (match_operand:SWI248 3 "register_operand"))]
2932 if (ix86_expand_pinsr (operands))
2935 /* Handle insertions to %ah et al. */
2936 if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
2939 unsigned int regno = reg_or_subregno (operands[0]);
2941 /* Be careful to expand only with registers having upper parts. */
2942 if (regno <= LAST_VIRTUAL_REGISTER && !QI_REGNO_P (regno))
2943 dst = copy_to_reg (operands[0]);
2947 emit_insn (gen_insv<mode>_1 (dst, operands[3]));
2949 /* Fix up the destination if needed. */
2950 if (dst != operands[0])
2951 emit_move_insn (operands[0], dst);
2956 (define_insn "*insvqi_1_mem_rex64"
2957 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2961 (match_operand:QI 1 "norex_memory_operand" "Bn") 0))]
2962 "TARGET_64BIT && reload_completed"
2963 "mov{b}\t{%1, %h0|%h0, %1}"
2964 [(set_attr "type" "imov")
2965 (set_attr "mode" "QI")])
2967 (define_insn "insv<mode>_1"
2968 [(set (zero_extract:SWI248 (match_operand 0 "ext_register_operand" "+Q,Q")
2971 (match_operand:SWI248 1 "general_operand" "QnBc,m"))]
2974 if (CONST_INT_P (operands[1]))
2975 operands[1] = gen_int_mode (INTVAL (operands[1]), QImode);
2976 return "mov{b}\t{%b1, %h0|%h0, %b1}";
2978 [(set_attr "isa" "*,nox64")
2979 (set_attr "type" "imov")
2980 (set_attr "mode" "QI")])
2982 (define_insn "*insvqi_1"
2983 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q,Q")
2987 (match_operand:QI 1 "general_operand" "QnBc,m") 0))]
2989 "mov{b}\t{%1, %h0|%h0, %1}"
2990 [(set_attr "isa" "*,nox64")
2991 (set_attr "type" "imov")
2992 (set_attr "mode" "QI")])
2995 [(set (match_operand:QI 0 "register_operand")
2996 (match_operand:QI 1 "norex_memory_operand"))
2997 (set (zero_extract:SI (match_operand 2 "ext_register_operand")
3000 (subreg:SI (match_dup 0) 0))]
3002 && peep2_reg_dead_p (2, operands[0])"
3003 [(set (zero_extract:SI (match_dup 2)
3006 (subreg:SI (match_dup 1) 0))])
3008 (define_code_iterator any_extract [sign_extract zero_extract])
3010 (define_insn "*insvqi_2"
3011 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
3014 (any_extract:SI (match_operand 1 "ext_register_operand" "Q")
3018 "mov{b}\t{%h1, %h0|%h0, %h1}"
3019 [(set_attr "type" "imov")
3020 (set_attr "mode" "QI")])
3022 (define_insn "*insvqi_3"
3023 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
3026 (any_shiftrt:SI (match_operand:SI 1 "register_operand" "Q")
3029 "mov{b}\t{%h1, %h0|%h0, %h1}"
3030 [(set_attr "type" "imov")
3031 (set_attr "mode" "QI")])
3033 ;; Floating point push instructions.
3035 (define_insn "*pushtf"
3036 [(set (match_operand:TF 0 "push_operand" "=<,<")
3037 (match_operand:TF 1 "general_no_elim_operand" "v,*roC"))]
3038 "TARGET_64BIT || TARGET_SSE"
3040 /* This insn should be already split before reg-stack. */
3043 [(set_attr "isa" "*,x64")
3044 (set_attr "type" "multi")
3045 (set_attr "unit" "sse,*")
3046 (set_attr "mode" "TF,DI")])
3048 ;; %%% Kill this when call knows how to work this out.
3050 [(set (match_operand:TF 0 "push_operand")
3051 (match_operand:TF 1 "sse_reg_operand"))]
3052 "TARGET_SSE && reload_completed"
3053 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -16)))
3054 (set (match_dup 0) (match_dup 1))]
3056 /* Preserve memory attributes. */
3057 operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
3060 (define_insn_and_split "*pushxf_rounded"
3064 (plus:P (reg:P SP_REG) (const_int -16))))
3065 (match_operand:XF 0 "nonmemory_no_elim_operand" "f,r,*r,C"))]
3069 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -16)))
3070 (set (match_dup 1) (match_dup 0))]
3072 rtx pat = PATTERN (curr_insn);
3073 operands[1] = SET_DEST (pat);
3075 /* Preserve memory attributes. */
3076 operands[1] = replace_equiv_address (operands[1], stack_pointer_rtx);
3078 [(set_attr "type" "multi")
3079 (set_attr "unit" "i387,*,*,*")
3081 (cond [(eq_attr "alternative" "1,2,3")
3084 (const_string "XF")))
3085 (set (attr "preferred_for_size")
3086 (cond [(eq_attr "alternative" "1")
3087 (symbol_ref "false")]
3088 (symbol_ref "true")))])
3090 (define_insn "*pushxf"
3091 [(set (match_operand:XF 0 "push_operand" "=<,<,<,<,<")
3092 (match_operand:XF 1 "general_no_elim_operand" "f,r,*r,oF,oC"))]
3095 /* This insn should be already split before reg-stack. */
3098 [(set_attr "isa" "*,*,*,nox64,x64")
3099 (set_attr "type" "multi")
3100 (set_attr "unit" "i387,*,*,*,*")
3102 (cond [(eq_attr "alternative" "1,2,3,4")
3103 (if_then_else (match_test "TARGET_64BIT")
3105 (const_string "SI"))
3107 (const_string "XF")))
3108 (set (attr "preferred_for_size")
3109 (cond [(eq_attr "alternative" "1")
3110 (symbol_ref "false")]
3111 (symbol_ref "true")))])
3113 ;; %%% Kill this when call knows how to work this out.
3115 [(set (match_operand:XF 0 "push_operand")
3116 (match_operand:XF 1 "fp_register_operand"))]
3118 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
3119 (set (match_dup 0) (match_dup 1))]
3121 operands[2] = GEN_INT (-PUSH_ROUNDING (GET_MODE_SIZE (XFmode)));
3122 /* Preserve memory attributes. */
3123 operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
3126 (define_insn "*pushdf"
3127 [(set (match_operand:DF 0 "push_operand" "=<,<,<,<,<,<")
3128 (match_operand:DF 1 "general_no_elim_operand" "f,r,*r,oF,rmC,x"))]
3131 /* This insn should be already split before reg-stack. */
3134 [(set_attr "isa" "*,nox64,nox64,nox64,x64,sse2")
3135 (set_attr "type" "multi")
3136 (set_attr "unit" "i387,*,*,*,*,sse")
3137 (set_attr "mode" "DF,SI,SI,SI,DI,DF")
3138 (set (attr "preferred_for_size")
3139 (cond [(eq_attr "alternative" "1")
3140 (symbol_ref "false")]
3141 (symbol_ref "true")))
3142 (set (attr "preferred_for_speed")
3143 (cond [(eq_attr "alternative" "1")
3144 (symbol_ref "TARGET_INTEGER_DFMODE_MOVES")]
3145 (symbol_ref "true")))])
3147 ;; %%% Kill this when call knows how to work this out.
3149 [(set (match_operand:DF 0 "push_operand")
3150 (match_operand:DF 1 "any_fp_register_operand"))]
3152 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
3153 (set (match_dup 0) (match_dup 1))]
3155 /* Preserve memory attributes. */
3156 operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
3159 (define_insn "*pushsf_rex64"
3160 [(set (match_operand:SF 0 "push_operand" "=X,X,X")
3161 (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
3164 /* Anything else should be already split before reg-stack. */
3165 gcc_assert (which_alternative == 1);
3166 return "push{q}\t%q1";
3168 [(set_attr "type" "multi,push,multi")
3169 (set_attr "unit" "i387,*,*")
3170 (set_attr "mode" "SF,DI,SF")])
3172 (define_insn "*pushsf"
3173 [(set (match_operand:SF 0 "push_operand" "=<,<,<")
3174 (match_operand:SF 1 "general_no_elim_operand" "f,rmF,x"))]
3177 /* Anything else should be already split before reg-stack. */
3178 gcc_assert (which_alternative == 1);
3179 return "push{l}\t%1";
3181 [(set_attr "type" "multi,push,multi")
3182 (set_attr "unit" "i387,*,*")
3183 (set_attr "mode" "SF,SI,SF")])
3185 ;; %%% Kill this when call knows how to work this out.
3187 [(set (match_operand:SF 0 "push_operand")
3188 (match_operand:SF 1 "any_fp_register_operand"))]
3190 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
3191 (set (match_dup 0) (match_dup 1))]
3193 rtx op = XEXP (operands[0], 0);
3194 if (GET_CODE (op) == PRE_DEC)
3196 gcc_assert (!TARGET_64BIT);
3201 op = XEXP (XEXP (op, 1), 1);
3202 gcc_assert (CONST_INT_P (op));
3205 /* Preserve memory attributes. */
3206 operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
3210 [(set (match_operand:SF 0 "push_operand")
3211 (match_operand:SF 1 "memory_operand"))]
3213 && find_constant_src (insn)"
3214 [(set (match_dup 0) (match_dup 2))]
3215 "operands[2] = find_constant_src (curr_insn);")
3218 [(set (match_operand 0 "push_operand")
3219 (match_operand 1 "general_gr_operand"))]
3221 && (GET_MODE (operands[0]) == TFmode
3222 || GET_MODE (operands[0]) == XFmode
3223 || GET_MODE (operands[0]) == DFmode)"
3225 "ix86_split_long_move (operands); DONE;")
3227 ;; Floating point move instructions.
3229 (define_expand "movtf"
3230 [(set (match_operand:TF 0 "nonimmediate_operand")
3231 (match_operand:TF 1 "nonimmediate_operand"))]
3232 "TARGET_64BIT || TARGET_SSE"
3233 "ix86_expand_move (TFmode, operands); DONE;")
3235 (define_expand "mov<mode>"
3236 [(set (match_operand:X87MODEF 0 "nonimmediate_operand")
3237 (match_operand:X87MODEF 1 "general_operand"))]
3239 "ix86_expand_move (<MODE>mode, operands); DONE;")
3241 (define_insn "*movtf_internal"
3242 [(set (match_operand:TF 0 "nonimmediate_operand" "=v,v ,m,?*r ,!o")
3243 (match_operand:TF 1 "general_operand" "C ,vm,v,*roF,*rC"))]
3244 "(TARGET_64BIT || TARGET_SSE)
3245 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3246 && (lra_in_progress || reload_completed
3247 || !CONST_DOUBLE_P (operands[1])
3248 || ((optimize_function_for_size_p (cfun)
3249 || (ix86_cmodel == CM_LARGE || ix86_cmodel == CM_LARGE_PIC))
3250 && standard_sse_constant_p (operands[1], TFmode) == 1
3251 && !memory_operand (operands[0], TFmode))
3252 || (!TARGET_MEMORY_MISMATCH_STALL
3253 && memory_operand (operands[0], TFmode)))"
3255 switch (get_attr_type (insn))
3258 return standard_sse_constant_opcode (insn, operands);
3261 /* Handle misaligned load/store since we
3262 don't have movmisaligntf pattern. */
3263 if (misaligned_operand (operands[0], TFmode)
3264 || misaligned_operand (operands[1], TFmode))
3266 if (get_attr_mode (insn) == MODE_V4SF)
3267 return "%vmovups\t{%1, %0|%0, %1}";
3268 else if (TARGET_AVX512VL
3269 && (EXT_REX_SSE_REG_P (operands[0])
3270 || EXT_REX_SSE_REG_P (operands[1])))
3271 return "vmovdqu64\t{%1, %0|%0, %1}";
3273 return "%vmovdqu\t{%1, %0|%0, %1}";
3277 if (get_attr_mode (insn) == MODE_V4SF)
3278 return "%vmovaps\t{%1, %0|%0, %1}";
3279 else if (TARGET_AVX512VL
3280 && (EXT_REX_SSE_REG_P (operands[0])
3281 || EXT_REX_SSE_REG_P (operands[1])))
3282 return "vmovdqa64\t{%1, %0|%0, %1}";
3284 return "%vmovdqa\t{%1, %0|%0, %1}";
3294 [(set_attr "isa" "*,*,*,x64,x64")
3295 (set_attr "type" "sselog1,ssemov,ssemov,multi,multi")
3296 (set (attr "prefix")
3297 (if_then_else (eq_attr "type" "sselog1,ssemov")
3298 (const_string "maybe_vex")
3299 (const_string "orig")))
3301 (cond [(eq_attr "alternative" "3,4")
3303 (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
3304 (const_string "V4SF")
3305 (and (eq_attr "alternative" "2")
3306 (match_test "TARGET_SSE_TYPELESS_STORES"))
3307 (const_string "V4SF")
3308 (match_test "TARGET_AVX")
3310 (ior (not (match_test "TARGET_SSE2"))
3311 (match_test "optimize_function_for_size_p (cfun)"))
3312 (const_string "V4SF")
3314 (const_string "TI")))])
3317 [(set (match_operand:TF 0 "nonimmediate_gr_operand")
3318 (match_operand:TF 1 "general_gr_operand"))]
3321 "ix86_split_long_move (operands); DONE;")
3323 ;; Possible store forwarding (partial memory) stall
3324 ;; in alternatives 4, 6, 7 and 8.
3325 (define_insn "*movxf_internal"
3326 [(set (match_operand:XF 0 "nonimmediate_operand"
3327 "=f,m,f,?r ,!o,?*r ,!o,!o,!o,r ,o ,o")
3328 (match_operand:XF 1 "general_operand"
3329 "fm,f,G,roF,r ,*roF,*r,F ,C ,roF,rF,rC"))]
3330 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3331 && (lra_in_progress || reload_completed
3332 || !CONST_DOUBLE_P (operands[1])
3333 || ((optimize_function_for_size_p (cfun)
3334 || (ix86_cmodel == CM_LARGE || ix86_cmodel == CM_LARGE_PIC))
3335 && standard_80387_constant_p (operands[1]) > 0
3336 && !memory_operand (operands[0], XFmode))
3337 || (!TARGET_MEMORY_MISMATCH_STALL
3338 && memory_operand (operands[0], XFmode))
3339 || !TARGET_HARD_XF_REGS)"
3341 switch (get_attr_type (insn))
3344 if (which_alternative == 2)
3345 return standard_80387_constant_opcode (operands[1]);
3346 return output_387_reg_move (insn, operands);
3356 (cond [(eq_attr "alternative" "7,10")
3357 (const_string "nox64")
3358 (eq_attr "alternative" "8,11")
3359 (const_string "x64")
3361 (const_string "*")))
3363 (cond [(eq_attr "alternative" "3,4,5,6,7,8,9,10,11")
3364 (const_string "multi")
3366 (const_string "fmov")))
3368 (cond [(eq_attr "alternative" "3,4,5,6,7,8,9,10,11")
3369 (if_then_else (match_test "TARGET_64BIT")
3371 (const_string "SI"))
3373 (const_string "XF")))
3374 (set (attr "preferred_for_size")
3375 (cond [(eq_attr "alternative" "3,4")
3376 (symbol_ref "false")]
3377 (symbol_ref "true")))
3378 (set (attr "enabled")
3379 (cond [(eq_attr "alternative" "9,10,11")
3381 (match_test "TARGET_HARD_XF_REGS")
3382 (symbol_ref "false")
3384 (not (match_test "TARGET_HARD_XF_REGS"))
3385 (symbol_ref "false")
3387 (const_string "*")))])
3390 [(set (match_operand:XF 0 "nonimmediate_gr_operand")
3391 (match_operand:XF 1 "general_gr_operand"))]
3394 "ix86_split_long_move (operands); DONE;")
3396 ;; Possible store forwarding (partial memory) stall in alternatives 4, 6 and 7.
3397 (define_insn "*movdf_internal"
3398 [(set (match_operand:DF 0 "nonimmediate_operand"
3399 "=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")
3400 (match_operand:DF 1 "general_operand"
3401 "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"))]
3402 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3403 && (lra_in_progress || reload_completed
3404 || !CONST_DOUBLE_P (operands[1])
3405 || ((optimize_function_for_size_p (cfun)
3406 || (ix86_cmodel == CM_LARGE || ix86_cmodel == CM_LARGE_PIC))
3407 && ((IS_STACK_MODE (DFmode)
3408 && standard_80387_constant_p (operands[1]) > 0)
3409 || (TARGET_SSE2 && TARGET_SSE_MATH
3410 && standard_sse_constant_p (operands[1], DFmode) == 1))
3411 && !memory_operand (operands[0], DFmode))
3412 || ((TARGET_64BIT || !TARGET_MEMORY_MISMATCH_STALL)
3413 && memory_operand (operands[0], DFmode))
3414 || !TARGET_HARD_DF_REGS)"
3416 switch (get_attr_type (insn))
3419 if (which_alternative == 2)
3420 return standard_80387_constant_opcode (operands[1]);
3421 return output_387_reg_move (insn, operands);
3427 if (get_attr_mode (insn) == MODE_SI)
3428 return "mov{l}\t{%1, %k0|%k0, %1}";
3429 else if (which_alternative == 11)
3430 return "movabs{q}\t{%1, %0|%0, %1}";
3432 return "mov{q}\t{%1, %0|%0, %1}";
3435 return standard_sse_constant_opcode (insn, operands);
3438 switch (get_attr_mode (insn))
3441 if (TARGET_AVX && REG_P (operands[0]) && REG_P (operands[1]))
3442 return "vmovsd\t{%d1, %0|%0, %d1}";
3443 return "%vmovsd\t{%1, %0|%0, %1}";
3446 return "%vmovaps\t{%1, %0|%0, %1}";
3448 return "vmovapd\t{%g1, %g0|%g0, %g1}";
3450 return "%vmovapd\t{%1, %0|%0, %1}";
3453 gcc_assert (!TARGET_AVX);
3454 return "movlps\t{%1, %0|%0, %1}";
3456 gcc_assert (!TARGET_AVX);
3457 return "movlpd\t{%1, %0|%0, %1}";
3460 /* Handle broken assemblers that require movd instead of movq. */
3461 if (!HAVE_AS_IX86_INTERUNIT_MOVQ
3462 && (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1])))
3463 return "%vmovd\t{%1, %0|%0, %1}";
3464 return "%vmovq\t{%1, %0|%0, %1}";
3475 (cond [(eq_attr "alternative" "3,4,5,6,7,22,23")
3476 (const_string "nox64")
3477 (eq_attr "alternative" "8,9,10,11,24,25")
3478 (const_string "x64")
3479 (eq_attr "alternative" "12,13,14,15")
3480 (const_string "sse2")
3481 (eq_attr "alternative" "20,21")
3482 (const_string "x64_sse2")
3484 (const_string "*")))
3486 (cond [(eq_attr "alternative" "0,1,2")
3487 (const_string "fmov")
3488 (eq_attr "alternative" "3,4,5,6,7,22,23")
3489 (const_string "multi")
3490 (eq_attr "alternative" "8,9,10,11,24,25")
3491 (const_string "imov")
3492 (eq_attr "alternative" "12,16")
3493 (const_string "sselog1")
3495 (const_string "ssemov")))
3497 (if_then_else (eq_attr "alternative" "11")
3499 (const_string "*")))
3500 (set (attr "length_immediate")
3501 (if_then_else (eq_attr "alternative" "11")
3503 (const_string "*")))
3504 (set (attr "prefix")
3505 (if_then_else (eq_attr "type" "sselog1,ssemov")
3506 (const_string "maybe_vex")
3507 (const_string "orig")))
3508 (set (attr "prefix_data16")
3510 (ior (and (eq_attr "type" "ssemov") (eq_attr "mode" "DI"))
3511 (eq_attr "mode" "V1DF"))
3513 (const_string "*")))
3515 (cond [(eq_attr "alternative" "3,4,5,6,7,10,22,23")
3517 (eq_attr "alternative" "8,9,11,20,21,24,25")
3520 /* xorps is one byte shorter for non-AVX targets. */
3521 (eq_attr "alternative" "12,16")
3522 (cond [(not (match_test "TARGET_SSE2"))
3523 (const_string "V4SF")
3524 (and (match_test "TARGET_AVX512F")
3525 (not (match_test "TARGET_PREFER_AVX256")))
3527 (match_test "TARGET_AVX")
3528 (const_string "V2DF")
3529 (match_test "optimize_function_for_size_p (cfun)")
3530 (const_string "V4SF")
3531 (match_test "TARGET_SSE_LOAD0_BY_PXOR")
3534 (const_string "V2DF"))
3536 /* For architectures resolving dependencies on
3537 whole SSE registers use movapd to break dependency
3538 chains, otherwise use short move to avoid extra work. */
3540 /* movaps is one byte shorter for non-AVX targets. */
3541 (eq_attr "alternative" "13,17")
3542 (cond [(and (ior (not (match_test "TARGET_PREFER_AVX256"))
3543 (not (match_test "TARGET_AVX512VL")))
3544 (ior (match_operand 0 "ext_sse_reg_operand")
3545 (match_operand 1 "ext_sse_reg_operand")))
3546 (const_string "V8DF")
3547 (ior (not (match_test "TARGET_SSE2"))
3548 (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL"))
3549 (const_string "V4SF")
3550 (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3551 (const_string "V2DF")
3552 (match_test "TARGET_AVX")
3554 (match_test "optimize_function_for_size_p (cfun)")
3555 (const_string "V4SF")
3557 (const_string "DF"))
3559 /* For architectures resolving dependencies on register
3560 parts we may avoid extra work to zero out upper part
3562 (eq_attr "alternative" "14,18")
3563 (cond [(not (match_test "TARGET_SSE2"))
3564 (const_string "V2SF")
3565 (match_test "TARGET_AVX")
3567 (match_test "TARGET_SSE_SPLIT_REGS")
3568 (const_string "V1DF")
3570 (const_string "DF"))
3572 (and (eq_attr "alternative" "15,19")
3573 (not (match_test "TARGET_SSE2")))
3574 (const_string "V2SF")
3576 (const_string "DF")))
3577 (set (attr "preferred_for_size")
3578 (cond [(eq_attr "alternative" "3,4")
3579 (symbol_ref "false")]
3580 (symbol_ref "true")))
3581 (set (attr "preferred_for_speed")
3582 (cond [(eq_attr "alternative" "3,4")
3583 (symbol_ref "TARGET_INTEGER_DFMODE_MOVES")
3584 (eq_attr "alternative" "20")
3585 (symbol_ref "TARGET_INTER_UNIT_MOVES_FROM_VEC")
3586 (eq_attr "alternative" "21")
3587 (symbol_ref "TARGET_INTER_UNIT_MOVES_TO_VEC")
3589 (symbol_ref "true")))
3590 (set (attr "enabled")
3591 (cond [(eq_attr "alternative" "22,23,24,25")
3593 (match_test "TARGET_HARD_DF_REGS")
3594 (symbol_ref "false")
3596 (not (match_test "TARGET_HARD_DF_REGS"))
3597 (symbol_ref "false")
3599 (const_string "*")))])
3602 [(set (match_operand:DF 0 "nonimmediate_gr_operand")
3603 (match_operand:DF 1 "general_gr_operand"))]
3604 "!TARGET_64BIT && reload_completed"
3606 "ix86_split_long_move (operands); DONE;")
3608 (define_insn "*movsf_internal"
3609 [(set (match_operand:SF 0 "nonimmediate_operand"
3610 "=Yf*f,m ,Yf*f,?r ,?m,v,v,v,m,?r,?v,!*y,!*y,!m,!r,!*y,r ,m")
3611 (match_operand:SF 1 "general_operand"
3612 "Yf*fm,Yf*f,G ,rmF,rF,C,v,m,v,v ,r ,*y ,m ,*y,*y,r ,rmF,rF"))]
3613 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3614 && (lra_in_progress || reload_completed
3615 || !CONST_DOUBLE_P (operands[1])
3616 || ((optimize_function_for_size_p (cfun)
3617 || (ix86_cmodel == CM_LARGE || ix86_cmodel == CM_LARGE_PIC))
3618 && ((IS_STACK_MODE (SFmode)
3619 && standard_80387_constant_p (operands[1]) > 0)
3620 || (TARGET_SSE && TARGET_SSE_MATH
3621 && standard_sse_constant_p (operands[1], SFmode) == 1)))
3622 || memory_operand (operands[0], SFmode)
3623 || !TARGET_HARD_SF_REGS)"
3625 switch (get_attr_type (insn))
3628 if (which_alternative == 2)
3629 return standard_80387_constant_opcode (operands[1]);
3630 return output_387_reg_move (insn, operands);
3633 return "mov{l}\t{%1, %0|%0, %1}";
3636 return standard_sse_constant_opcode (insn, operands);
3639 switch (get_attr_mode (insn))
3642 if (TARGET_AVX && REG_P (operands[0]) && REG_P (operands[1]))
3643 return "vmovss\t{%d1, %0|%0, %d1}";
3644 return "%vmovss\t{%1, %0|%0, %1}";
3647 return "vmovaps\t{%g1, %g0|%g0, %g1}";
3649 return "%vmovaps\t{%1, %0|%0, %1}";
3652 return "%vmovd\t{%1, %0|%0, %1}";
3659 switch (get_attr_mode (insn))
3662 return "movq\t{%1, %0|%0, %1}";
3664 return "movd\t{%1, %0|%0, %1}";
3675 (cond [(eq_attr "alternative" "14,15")
3676 (const_string "sse2")
3678 (const_string "*")))
3680 (cond [(eq_attr "alternative" "0,1,2")
3681 (const_string "fmov")
3682 (eq_attr "alternative" "3,4,16,17")
3683 (const_string "imov")
3684 (eq_attr "alternative" "5")
3685 (const_string "sselog1")
3686 (eq_attr "alternative" "11,12,13,14,15")
3687 (const_string "mmxmov")
3689 (const_string "ssemov")))
3690 (set (attr "prefix")
3691 (if_then_else (eq_attr "type" "sselog1,ssemov")
3692 (const_string "maybe_vex")
3693 (const_string "orig")))
3694 (set (attr "prefix_data16")
3695 (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
3697 (const_string "*")))
3699 (cond [(eq_attr "alternative" "3,4,9,10,12,13,14,15,16,17")
3701 (eq_attr "alternative" "11")
3703 (eq_attr "alternative" "5")
3704 (cond [(not (match_test "TARGET_SSE2"))
3705 (const_string "V4SF")
3706 (and (match_test "TARGET_AVX512F")
3707 (not (match_test "TARGET_PREFER_AVX256")))
3708 (const_string "V16SF")
3709 (match_test "TARGET_AVX")
3710 (const_string "V4SF")
3711 (match_test "optimize_function_for_size_p (cfun)")
3712 (const_string "V4SF")
3713 (match_test "TARGET_SSE_LOAD0_BY_PXOR")
3716 (const_string "V4SF"))
3718 /* For architectures resolving dependencies on
3719 whole SSE registers use APS move to break dependency
3720 chains, otherwise use short move to avoid extra work.
3722 Do the same for architectures resolving dependencies on
3723 the parts. While in DF mode it is better to always handle
3724 just register parts, the SF mode is different due to lack
3725 of instructions to load just part of the register. It is
3726 better to maintain the whole registers in single format
3727 to avoid problems on using packed logical operations. */
3728 (eq_attr "alternative" "6")
3729 (cond [(and (ior (not (match_test "TARGET_PREFER_AVX256"))
3730 (not (match_test "TARGET_AVX512VL")))
3731 (ior (match_operand 0 "ext_sse_reg_operand")
3732 (match_operand 1 "ext_sse_reg_operand")))
3733 (const_string "V16SF")
3734 (ior (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3735 (match_test "TARGET_SSE_SPLIT_REGS"))
3736 (const_string "V4SF")
3738 (const_string "SF"))
3740 (const_string "SF")))
3741 (set (attr "preferred_for_speed")
3742 (cond [(eq_attr "alternative" "9,14")
3743 (symbol_ref "TARGET_INTER_UNIT_MOVES_FROM_VEC")
3744 (eq_attr "alternative" "10,15")
3745 (symbol_ref "TARGET_INTER_UNIT_MOVES_TO_VEC")
3747 (symbol_ref "true")))
3748 (set (attr "enabled")
3749 (cond [(eq_attr "alternative" "16,17")
3751 (match_test "TARGET_HARD_SF_REGS")
3752 (symbol_ref "false")
3754 (not (match_test "TARGET_HARD_SF_REGS"))
3755 (symbol_ref "false")
3757 (const_string "*")))])
3760 [(set (match_operand 0 "any_fp_register_operand")
3761 (match_operand 1 "memory_operand"))]
3763 && (GET_MODE (operands[0]) == TFmode
3764 || GET_MODE (operands[0]) == XFmode
3765 || GET_MODE (operands[0]) == DFmode
3766 || GET_MODE (operands[0]) == SFmode)
3767 && ix86_standard_x87sse_constant_load_p (insn, operands[0])"
3768 [(set (match_dup 0) (match_dup 2))]
3769 "operands[2] = find_constant_src (curr_insn);")
3772 [(set (match_operand 0 "any_fp_register_operand")
3773 (float_extend (match_operand 1 "memory_operand")))]
3775 && (GET_MODE (operands[0]) == TFmode
3776 || GET_MODE (operands[0]) == XFmode
3777 || GET_MODE (operands[0]) == DFmode)
3778 && ix86_standard_x87sse_constant_load_p (insn, operands[0])"
3779 [(set (match_dup 0) (match_dup 2))]
3780 "operands[2] = find_constant_src (curr_insn);")
3782 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
3784 [(set (match_operand:X87MODEF 0 "fp_register_operand")
3785 (match_operand:X87MODEF 1 "immediate_operand"))]
3787 && (standard_80387_constant_p (operands[1]) == 8
3788 || standard_80387_constant_p (operands[1]) == 9)"
3789 [(set (match_dup 0)(match_dup 1))
3791 (neg:X87MODEF (match_dup 0)))]
3793 if (real_isnegzero (CONST_DOUBLE_REAL_VALUE (operands[1])))
3794 operands[1] = CONST0_RTX (<MODE>mode);
3796 operands[1] = CONST1_RTX (<MODE>mode);
3799 (define_insn "*swapxf"
3800 [(set (match_operand:XF 0 "register_operand" "+f")
3801 (match_operand:XF 1 "register_operand" "+f"))
3806 if (STACK_TOP_P (operands[0]))
3811 [(set_attr "type" "fxch")
3812 (set_attr "mode" "XF")])
3815 ;; Zero extension instructions
3817 (define_expand "zero_extendsidi2"
3818 [(set (match_operand:DI 0 "nonimmediate_operand")
3819 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand")))])
3821 (define_insn "*zero_extendsidi2"
3822 [(set (match_operand:DI 0 "nonimmediate_operand"
3823 "=r,?r,?o,r ,o,?*y,?!*y,$r,$v,$x,*x,*v,*r,*k")
3825 (match_operand:SI 1 "x86_64_zext_operand"
3826 "0 ,rm,r ,rmWz,0,r ,m ,v ,r ,m ,*x,*v,*k,*km")))]
3829 switch (get_attr_type (insn))
3832 if (ix86_use_lea_for_mov (insn, operands))
3833 return "lea{l}\t{%E1, %k0|%k0, %E1}";
3835 return "mov{l}\t{%1, %k0|%k0, %1}";
3841 return "movd\t{%1, %0|%0, %1}";
3844 if (SSE_REG_P (operands[0]) && SSE_REG_P (operands[1]))
3846 if (EXT_REX_SSE_REG_P (operands[0])
3847 || EXT_REX_SSE_REG_P (operands[1]))
3848 return "vpmovzxdq\t{%t1, %g0|%g0, %t1}";
3850 return "%vpmovzxdq\t{%1, %0|%0, %1}";
3853 if (GENERAL_REG_P (operands[0]))
3854 return "%vmovd\t{%1, %k0|%k0, %1}";
3856 return "%vmovd\t{%1, %0|%0, %1}";
3859 return "kmovd\t{%1, %k0|%k0, %1}";
3866 (cond [(eq_attr "alternative" "0,1,2")
3867 (const_string "nox64")
3868 (eq_attr "alternative" "3")
3869 (const_string "x64")
3870 (eq_attr "alternative" "7,8,9")
3871 (const_string "sse2")
3872 (eq_attr "alternative" "10")
3873 (const_string "sse4")
3874 (eq_attr "alternative" "11")
3875 (const_string "avx512f")
3876 (eq_attr "alternative" "12")
3877 (const_string "x64_avx512bw")
3878 (eq_attr "alternative" "13")
3879 (const_string "avx512bw")
3881 (const_string "*")))
3882 (set (attr "mmx_isa")
3883 (if_then_else (eq_attr "alternative" "5,6")
3884 (const_string "native")
3885 (const_string "*")))
3887 (cond [(eq_attr "alternative" "0,1,2,4")
3888 (const_string "multi")
3889 (eq_attr "alternative" "5,6")
3890 (const_string "mmxmov")
3891 (eq_attr "alternative" "7")
3892 (if_then_else (match_test "TARGET_64BIT")
3893 (const_string "ssemov")
3894 (const_string "multi"))
3895 (eq_attr "alternative" "8,9,10,11")
3896 (const_string "ssemov")
3897 (eq_attr "alternative" "12,13")
3898 (const_string "mskmov")
3900 (const_string "imovx")))
3901 (set (attr "prefix_extra")
3902 (if_then_else (eq_attr "alternative" "10,11")
3904 (const_string "*")))
3905 (set (attr "prefix")
3906 (if_then_else (eq_attr "type" "ssemov")
3907 (const_string "maybe_vex")
3908 (const_string "orig")))
3909 (set (attr "prefix_0f")
3910 (if_then_else (eq_attr "type" "imovx")
3912 (const_string "*")))
3914 (cond [(eq_attr "alternative" "5,6")
3916 (and (eq_attr "alternative" "7")
3917 (match_test "TARGET_64BIT"))
3919 (eq_attr "alternative" "8,10,11")
3922 (const_string "SI")))
3923 (set (attr "preferred_for_speed")
3924 (cond [(eq_attr "alternative" "7")
3925 (symbol_ref "TARGET_INTER_UNIT_MOVES_FROM_VEC")
3926 (eq_attr "alternative" "5,8")
3927 (symbol_ref "TARGET_INTER_UNIT_MOVES_TO_VEC")
3929 (symbol_ref "true")))])
3932 [(set (match_operand:DI 0 "memory_operand")
3933 (zero_extend:DI (match_operand:SI 1 "memory_operand")))]
3935 [(set (match_dup 4) (const_int 0))]
3936 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3939 [(set (match_operand:DI 0 "general_reg_operand")
3940 (zero_extend:DI (match_operand:SI 1 "general_reg_operand")))]
3941 "!TARGET_64BIT && reload_completed
3942 && REGNO (operands[0]) == REGNO (operands[1])"
3943 [(set (match_dup 4) (const_int 0))]
3944 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3947 [(set (match_operand:DI 0 "nonimmediate_gr_operand")
3948 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand")))]
3949 "!TARGET_64BIT && reload_completed
3950 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
3951 [(set (match_dup 3) (match_dup 1))
3952 (set (match_dup 4) (const_int 0))]
3953 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3955 (define_mode_attr kmov_isa
3956 [(QI "avx512dq") (HI "avx512f") (SI "avx512bw") (DI "avx512bw")])
3958 (define_insn "zero_extend<mode>di2"
3959 [(set (match_operand:DI 0 "register_operand" "=r,*r,*k")
3961 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m,*k,*km")))]
3964 movz{<imodesuffix>l|x}\t{%1, %k0|%k0, %1}
3965 kmov<mskmodesuffix>\t{%1, %k0|%k0, %1}
3966 kmov<mskmodesuffix>\t{%1, %k0|%k0, %1}"
3967 [(set_attr "isa" "*,<kmov_isa>,<kmov_isa>")
3968 (set_attr "type" "imovx,mskmov,mskmov")
3969 (set_attr "mode" "SI,<MODE>,<MODE>")])
3971 (define_expand "zero_extend<mode>si2"
3972 [(set (match_operand:SI 0 "register_operand")
3973 (zero_extend:SI (match_operand:SWI12 1 "nonimmediate_operand")))]
3976 if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3978 operands[1] = force_reg (<MODE>mode, operands[1]);
3979 emit_insn (gen_zero_extend<mode>si2_and (operands[0], operands[1]));
3984 (define_insn_and_split "zero_extend<mode>si2_and"
3985 [(set (match_operand:SI 0 "register_operand" "=r,?&<r>")
3987 (match_operand:SWI12 1 "nonimmediate_operand" "0,<r>m")))
3988 (clobber (reg:CC FLAGS_REG))]
3989 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3991 "&& reload_completed"
3992 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (match_dup 2)))
3993 (clobber (reg:CC FLAGS_REG))])]
3995 if (!REG_P (operands[1])
3996 || REGNO (operands[0]) != REGNO (operands[1]))
3998 ix86_expand_clear (operands[0]);
4000 gcc_assert (!TARGET_PARTIAL_REG_STALL);
4001 emit_insn (gen_movstrict<mode>
4002 (gen_lowpart (<MODE>mode, operands[0]), operands[1]));
4006 operands[2] = GEN_INT (GET_MODE_MASK (<MODE>mode));
4008 [(set_attr "type" "alu1")
4009 (set_attr "mode" "SI")])
4011 (define_insn "*zero_extend<mode>si2"
4012 [(set (match_operand:SI 0 "register_operand" "=r,*r,*k")
4014 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m,*k,*km")))]
4015 "!(TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))"
4017 movz{<imodesuffix>l|x}\t{%1, %0|%0, %1}
4018 kmov<mskmodesuffix>\t{%1, %0|%0, %1}
4019 kmov<mskmodesuffix>\t{%1, %0|%0, %1}"
4020 [(set_attr "isa" "*,<kmov_isa>,<kmov_isa>")
4021 (set_attr "type" "imovx,mskmov,mskmov")
4022 (set_attr "mode" "SI,<MODE>,<MODE>")])
4024 (define_expand "zero_extendqihi2"
4025 [(set (match_operand:HI 0 "register_operand")
4026 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand")))]
4029 if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
4031 operands[1] = force_reg (QImode, operands[1]);
4032 emit_insn (gen_zero_extendqihi2_and (operands[0], operands[1]));
4037 (define_insn_and_split "zero_extendqihi2_and"
4038 [(set (match_operand:HI 0 "register_operand" "=r,?&q")
4039 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
4040 (clobber (reg:CC FLAGS_REG))]
4041 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
4043 "&& reload_completed"
4044 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
4045 (clobber (reg:CC FLAGS_REG))])]
4047 if (!REG_P (operands[1])
4048 || REGNO (operands[0]) != REGNO (operands[1]))
4050 ix86_expand_clear (operands[0]);
4052 gcc_assert (!TARGET_PARTIAL_REG_STALL);
4053 emit_insn (gen_movstrictqi
4054 (gen_lowpart (QImode, operands[0]), operands[1]));
4058 operands[0] = gen_lowpart (SImode, operands[0]);
4060 [(set_attr "type" "alu1")
4061 (set_attr "mode" "SI")])
4063 ; zero extend to SImode to avoid partial register stalls
4064 (define_insn "*zero_extendqihi2"
4065 [(set (match_operand:HI 0 "register_operand" "=r,*r,*k")
4066 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,*k,*km")))]
4067 "!(TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))"
4069 movz{bl|x}\t{%1, %k0|%k0, %1}
4070 kmovb\t{%1, %k0|%k0, %1}
4071 kmovb\t{%1, %0|%0, %1}"
4072 [(set_attr "isa" "*,avx512dq,avx512dq")
4073 (set_attr "type" "imovx,mskmov,mskmov")
4074 (set_attr "mode" "SI,QI,QI")])
4076 (define_insn_and_split "*zext<mode>_doubleword_and"
4077 [(set (match_operand:DI 0 "register_operand" "=&<r>")
4078 (zero_extend:DI (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
4079 "!TARGET_64BIT && TARGET_STV && TARGET_SSE2
4080 && TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
4082 "&& reload_completed && GENERAL_REG_P (operands[0])"
4083 [(set (match_dup 2) (const_int 0))]
4085 split_double_mode (DImode, &operands[0], 1, &operands[0], &operands[2]);
4087 emit_move_insn (operands[0], const0_rtx);
4089 gcc_assert (!TARGET_PARTIAL_REG_STALL);
4090 emit_insn (gen_movstrict<mode>
4091 (gen_lowpart (<MODE>mode, operands[0]), operands[1]));
4094 (define_insn_and_split "*zext<mode>_doubleword"
4095 [(set (match_operand:DI 0 "register_operand" "=r")
4096 (zero_extend:DI (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
4097 "!TARGET_64BIT && TARGET_STV && TARGET_SSE2
4098 && !(TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))"
4100 "&& reload_completed && GENERAL_REG_P (operands[0])"
4101 [(set (match_dup 0) (zero_extend:SI (match_dup 1)))
4102 (set (match_dup 2) (const_int 0))]
4103 "split_double_mode (DImode, &operands[0], 1, &operands[0], &operands[2]);")
4105 (define_insn_and_split "*zextsi_doubleword"
4106 [(set (match_operand:DI 0 "register_operand" "=r")
4107 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm")))]
4108 "!TARGET_64BIT && TARGET_STV && TARGET_SSE2"
4110 "&& reload_completed && GENERAL_REG_P (operands[0])"
4111 [(set (match_dup 0) (match_dup 1))
4112 (set (match_dup 2) (const_int 0))]
4113 "split_double_mode (DImode, &operands[0], 1, &operands[0], &operands[2]);")
4115 ;; Sign extension instructions
4117 (define_expand "extendsidi2"
4118 [(set (match_operand:DI 0 "register_operand")
4119 (sign_extend:DI (match_operand:SI 1 "register_operand")))]
4124 emit_insn (gen_extendsidi2_1 (operands[0], operands[1]));
4129 (define_insn "*extendsidi2_rex64"
4130 [(set (match_operand:DI 0 "register_operand" "=*a,r")
4131 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
4135 movs{lq|x}\t{%1, %0|%0, %1}"
4136 [(set_attr "type" "imovx")
4137 (set_attr "mode" "DI")
4138 (set_attr "prefix_0f" "0")
4139 (set_attr "modrm" "0,1")])
4141 (define_insn "extendsidi2_1"
4142 [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
4143 (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
4144 (clobber (reg:CC FLAGS_REG))
4145 (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
4149 ;; Split the memory case. If the source register doesn't die, it will stay
4150 ;; this way, if it does die, following peephole2s take care of it.
4152 [(set (match_operand:DI 0 "memory_operand")
4153 (sign_extend:DI (match_operand:SI 1 "register_operand")))
4154 (clobber (reg:CC FLAGS_REG))
4155 (clobber (match_operand:SI 2 "register_operand"))]
4159 split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
4161 emit_move_insn (operands[3], operands[1]);
4163 /* Generate a cltd if possible and doing so it profitable. */
4164 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
4165 && REGNO (operands[1]) == AX_REG
4166 && REGNO (operands[2]) == DX_REG)
4168 emit_insn (gen_ashrsi3_cvt (operands[2], operands[1], GEN_INT (31)));
4172 emit_move_insn (operands[2], operands[1]);
4173 emit_insn (gen_ashrsi3_cvt (operands[2], operands[2], GEN_INT (31)));
4175 emit_move_insn (operands[4], operands[2]);
4179 ;; Peepholes for the case where the source register does die, after
4180 ;; being split with the above splitter.
4182 [(set (match_operand:SI 0 "memory_operand")
4183 (match_operand:SI 1 "general_reg_operand"))
4184 (set (match_operand:SI 2 "general_reg_operand") (match_dup 1))
4185 (parallel [(set (match_dup 2)
4186 (ashiftrt:SI (match_dup 2) (const_int 31)))
4187 (clobber (reg:CC FLAGS_REG))])
4188 (set (match_operand:SI 3 "memory_operand") (match_dup 2))]
4189 "REGNO (operands[1]) != REGNO (operands[2])
4190 && peep2_reg_dead_p (2, operands[1])
4191 && peep2_reg_dead_p (4, operands[2])
4192 && !reg_mentioned_p (operands[2], operands[3])"
4193 [(set (match_dup 0) (match_dup 1))
4194 (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
4195 (clobber (reg:CC FLAGS_REG))])
4196 (set (match_dup 3) (match_dup 1))])
4199 [(set (match_operand:SI 0 "memory_operand")
4200 (match_operand:SI 1 "general_reg_operand"))
4201 (parallel [(set (match_operand:SI 2 "general_reg_operand")
4202 (ashiftrt:SI (match_dup 1) (const_int 31)))
4203 (clobber (reg:CC FLAGS_REG))])
4204 (set (match_operand:SI 3 "memory_operand") (match_dup 2))]
4205 "/* cltd is shorter than sarl $31, %eax */
4206 !optimize_function_for_size_p (cfun)
4207 && REGNO (operands[1]) == AX_REG
4208 && REGNO (operands[2]) == DX_REG
4209 && peep2_reg_dead_p (2, operands[1])
4210 && peep2_reg_dead_p (3, operands[2])
4211 && !reg_mentioned_p (operands[2], operands[3])"
4212 [(set (match_dup 0) (match_dup 1))
4213 (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
4214 (clobber (reg:CC FLAGS_REG))])
4215 (set (match_dup 3) (match_dup 1))])
4217 ;; Extend to register case. Optimize case where source and destination
4218 ;; registers match and cases where we can use cltd.
4220 [(set (match_operand:DI 0 "register_operand")
4221 (sign_extend:DI (match_operand:SI 1 "register_operand")))
4222 (clobber (reg:CC FLAGS_REG))
4223 (clobber (match_scratch:SI 2))]
4227 split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
4229 if (REGNO (operands[3]) != REGNO (operands[1]))
4230 emit_move_insn (operands[3], operands[1]);
4232 /* Generate a cltd if possible and doing so it profitable. */
4233 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
4234 && REGNO (operands[3]) == AX_REG
4235 && REGNO (operands[4]) == DX_REG)
4237 emit_insn (gen_ashrsi3_cvt (operands[4], operands[3], GEN_INT (31)));
4241 if (REGNO (operands[4]) != REGNO (operands[1]))
4242 emit_move_insn (operands[4], operands[1]);
4244 emit_insn (gen_ashrsi3_cvt (operands[4], operands[4], GEN_INT (31)));
4248 (define_insn "extend<mode>di2"
4249 [(set (match_operand:DI 0 "register_operand" "=r")
4251 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
4253 "movs{<imodesuffix>q|x}\t{%1, %0|%0, %1}"
4254 [(set_attr "type" "imovx")
4255 (set_attr "mode" "DI")])
4257 (define_insn "extendhisi2"
4258 [(set (match_operand:SI 0 "register_operand" "=*a,r")
4259 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
4262 switch (get_attr_prefix_0f (insn))
4265 return "{cwtl|cwde}";
4267 return "movs{wl|x}\t{%1, %0|%0, %1}";
4270 [(set_attr "type" "imovx")
4271 (set_attr "mode" "SI")
4272 (set (attr "prefix_0f")
4273 ;; movsx is short decodable while cwtl is vector decoded.
4274 (if_then_else (and (eq_attr "cpu" "!k6")
4275 (eq_attr "alternative" "0"))
4277 (const_string "1")))
4278 (set (attr "znver1_decode")
4279 (if_then_else (eq_attr "prefix_0f" "0")
4280 (const_string "double")
4281 (const_string "direct")))
4283 (if_then_else (eq_attr "prefix_0f" "0")
4285 (const_string "1")))])
4287 (define_insn "*extendhisi2_zext"
4288 [(set (match_operand:DI 0 "register_operand" "=*a,r")
4291 (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
4294 switch (get_attr_prefix_0f (insn))
4297 return "{cwtl|cwde}";
4299 return "movs{wl|x}\t{%1, %k0|%k0, %1}";
4302 [(set_attr "type" "imovx")
4303 (set_attr "mode" "SI")
4304 (set (attr "prefix_0f")
4305 ;; movsx is short decodable while cwtl is vector decoded.
4306 (if_then_else (and (eq_attr "cpu" "!k6")
4307 (eq_attr "alternative" "0"))
4309 (const_string "1")))
4311 (if_then_else (eq_attr "prefix_0f" "0")
4313 (const_string "1")))])
4315 (define_insn "extendqisi2"
4316 [(set (match_operand:SI 0 "register_operand" "=r")
4317 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
4319 "movs{bl|x}\t{%1, %0|%0, %1}"
4320 [(set_attr "type" "imovx")
4321 (set_attr "mode" "SI")])
4323 (define_insn "*extendqisi2_zext"
4324 [(set (match_operand:DI 0 "register_operand" "=r")
4326 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
4328 "movs{bl|x}\t{%1, %k0|%k0, %1}"
4329 [(set_attr "type" "imovx")
4330 (set_attr "mode" "SI")])
4332 (define_insn "extendqihi2"
4333 [(set (match_operand:HI 0 "register_operand" "=*a,r")
4334 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
4337 switch (get_attr_prefix_0f (insn))
4340 return "{cbtw|cbw}";
4342 return "movs{bw|x}\t{%1, %0|%0, %1}";
4345 [(set_attr "type" "imovx")
4346 (set_attr "mode" "HI")
4347 (set (attr "prefix_0f")
4348 ;; movsx is short decodable while cwtl is vector decoded.
4349 (if_then_else (and (eq_attr "cpu" "!k6")
4350 (eq_attr "alternative" "0"))
4352 (const_string "1")))
4354 (if_then_else (eq_attr "prefix_0f" "0")
4356 (const_string "1")))])
4358 ;; Conversions between float and double.
4360 ;; These are all no-ops in the model used for the 80387.
4361 ;; So just emit moves.
4363 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
4365 [(set (match_operand:DF 0 "push_operand")
4366 (float_extend:DF (match_operand:SF 1 "fp_register_operand")))]
4368 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
4369 (set (mem:DF (reg:P SP_REG)) (float_extend:DF (match_dup 1)))])
4372 [(set (match_operand:XF 0 "push_operand")
4373 (float_extend:XF (match_operand:MODEF 1 "fp_register_operand")))]
4375 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
4376 (set (mem:XF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
4377 "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
4379 (define_expand "extendsfdf2"
4380 [(set (match_operand:DF 0 "nonimm_ssenomem_operand")
4381 (float_extend:DF (match_operand:SF 1 "general_operand")))]
4382 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4384 /* ??? Needed for compress_float_constant since all fp constants
4385 are TARGET_LEGITIMATE_CONSTANT_P. */
4386 if (CONST_DOUBLE_P (operands[1]))
4388 if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
4389 && standard_80387_constant_p (operands[1]) > 0)
4391 operands[1] = simplify_const_unary_operation
4392 (FLOAT_EXTEND, DFmode, operands[1], SFmode);
4393 emit_move_insn_1 (operands[0], operands[1]);
4396 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
4400 (define_insn "*extendsfdf2"
4401 [(set (match_operand:DF 0 "nonimm_ssenomem_operand" "=f,m,v,v")
4403 (match_operand:SF 1 "nonimmediate_operand" "fm,f,v,m")))]
4404 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4406 switch (which_alternative)
4410 return output_387_reg_move (insn, operands);
4413 return "%vcvtss2sd\t{%d1, %0|%0, %d1}";
4415 return "%vcvtss2sd\t{%1, %d0|%d0, %1}";
4421 [(set_attr "type" "fmov,fmov,ssecvt,ssecvt")
4422 (set_attr "avx_partial_xmm_update" "false,false,false,true")
4423 (set_attr "prefix" "orig,orig,maybe_vex,maybe_vex")
4424 (set_attr "mode" "SF,XF,DF,DF")
4425 (set (attr "enabled")
4427 (match_test ("TARGET_SSE2 && TARGET_SSE_MATH"))
4429 (eq_attr "alternative" "0,1")
4430 (symbol_ref "TARGET_MIX_SSE_I387")
4431 (symbol_ref "true"))
4433 (eq_attr "alternative" "0,1")
4435 (symbol_ref "false"))))])
4437 /* For converting SF(xmm2) to DF(xmm1), use the following code instead of
4439 unpcklps xmm2,xmm2 ; packed conversion might crash on signaling NaNs
4441 We do the conversion post reload to avoid producing of 128bit spills
4442 that might lead to ICE on 32bit target. The sequence unlikely combine
4445 [(set (match_operand:DF 0 "sse_reg_operand")
4447 (match_operand:SF 1 "nonimmediate_operand")))]
4448 "TARGET_USE_VECTOR_FP_CONVERTS
4449 && optimize_insn_for_speed_p ()
4451 && (!EXT_REX_SSE_REG_P (operands[0])
4452 || TARGET_AVX512VL)"
4457 (parallel [(const_int 0) (const_int 1)]))))]
4459 operands[2] = lowpart_subreg (V2DFmode, operands[0], DFmode);
4460 operands[3] = lowpart_subreg (V4SFmode, operands[0], DFmode);
4461 /* Use movss for loading from memory, unpcklps reg, reg for registers.
4462 Try to avoid move when unpacking can be done in source. */
4463 if (REG_P (operands[1]))
4465 /* If it is unsafe to overwrite upper half of source, we need
4466 to move to destination and unpack there. */
4467 if (REGNO (operands[0]) != REGNO (operands[1])
4468 || (EXT_REX_SSE_REG_P (operands[1])
4469 && !TARGET_AVX512VL))
4471 rtx tmp = lowpart_subreg (SFmode, operands[0], DFmode);
4472 emit_move_insn (tmp, operands[1]);
4475 operands[3] = lowpart_subreg (V4SFmode, operands[1], SFmode);
4476 /* FIXME: vec_interleave_lowv4sf for AVX512VL should allow
4477 =v, v, then vbroadcastss will be only needed for AVX512F without
4479 if (!EXT_REX_SSE_REGNO_P (REGNO (operands[3])))
4480 emit_insn (gen_vec_interleave_lowv4sf (operands[3], operands[3],
4484 rtx tmp = lowpart_subreg (V16SFmode, operands[3], V4SFmode);
4485 emit_insn (gen_avx512f_vec_dupv16sf_1 (tmp, tmp));
4489 emit_insn (gen_vec_setv4sf_0 (operands[3],
4490 CONST0_RTX (V4SFmode), operands[1]));
4493 ;; It's more profitable to split and then extend in the same register.
4495 [(set (match_operand:DF 0 "sse_reg_operand")
4497 (match_operand:SF 1 "memory_operand")))]
4498 "TARGET_SPLIT_MEM_OPND_FOR_FP_CONVERTS
4499 && optimize_insn_for_speed_p ()"
4500 [(set (match_dup 2) (match_dup 1))
4501 (set (match_dup 0) (float_extend:DF (match_dup 2)))]
4502 "operands[2] = lowpart_subreg (SFmode, operands[0], DFmode);")
4504 ;; Break partial SSE register dependency stall. This splitter should split
4505 ;; late in the pass sequence (after register rename pass), so allocated
4506 ;; registers won't change anymore
4509 [(set (match_operand:DF 0 "sse_reg_operand")
4511 (match_operand:SF 1 "nonimmediate_operand")))]
4513 && TARGET_SSE_PARTIAL_REG_DEPENDENCY && epilogue_completed
4514 && optimize_function_for_speed_p (cfun)
4515 && (!REG_P (operands[1])
4516 || (!TARGET_AVX && REGNO (operands[0]) != REGNO (operands[1])))
4517 && (!EXT_REX_SSE_REG_P (operands[0])
4518 || TARGET_AVX512VL)"
4527 operands[0] = lowpart_subreg (V2DFmode, operands[0], DFmode);
4528 emit_move_insn (operands[0], CONST0_RTX (V2DFmode));
4531 (define_expand "extend<mode>xf2"
4532 [(set (match_operand:XF 0 "nonimmediate_operand")
4533 (float_extend:XF (match_operand:MODEF 1 "general_operand")))]
4536 /* ??? Needed for compress_float_constant since all fp constants
4537 are TARGET_LEGITIMATE_CONSTANT_P. */
4538 if (CONST_DOUBLE_P (operands[1]))
4540 if (standard_80387_constant_p (operands[1]) > 0)
4542 operands[1] = simplify_const_unary_operation
4543 (FLOAT_EXTEND, XFmode, operands[1], <MODE>mode);
4544 emit_move_insn_1 (operands[0], operands[1]);
4547 operands[1] = validize_mem (force_const_mem (<MODE>mode, operands[1]));
4551 (define_insn "*extend<mode>xf2_i387"
4552 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
4554 (match_operand:MODEF 1 "nonimmediate_operand" "fm,f")))]
4556 "* return output_387_reg_move (insn, operands);"
4557 [(set_attr "type" "fmov")
4558 (set_attr "mode" "<MODE>,XF")])
4560 ;; %%% This seems like bad news.
4561 ;; This cannot output into an f-reg because there is no way to be sure
4562 ;; of truncating in that case. Otherwise this is just like a simple move
4563 ;; insn. So we pretend we can output to a reg in order to get better
4564 ;; register preferencing, but we really use a stack slot.
4566 ;; Conversion from DFmode to SFmode.
4568 (define_insn "truncdfsf2"
4569 [(set (match_operand:SF 0 "nonimm_ssenomem_operand" "=m,f,v,v")
4571 (match_operand:DF 1 "register_ssemem_operand" "f,f,v,m")))]
4572 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4574 switch (which_alternative)
4578 return output_387_reg_move (insn, operands);
4581 return "%vcvtsd2ss\t{%d1, %0|%0, %d1}";
4583 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4589 [(set_attr "type" "fmov,fmov,ssecvt,ssecvt")
4590 (set_attr "avx_partial_xmm_update" "false,false,false,true")
4591 (set_attr "mode" "SF")
4592 (set (attr "enabled")
4594 (match_test ("TARGET_SSE2 && TARGET_SSE_MATH"))
4595 (cond [(eq_attr "alternative" "0")
4596 (symbol_ref "TARGET_MIX_SSE_I387")
4597 (eq_attr "alternative" "1")
4598 (symbol_ref "TARGET_MIX_SSE_I387
4599 && flag_unsafe_math_optimizations")
4601 (symbol_ref "true"))
4602 (cond [(eq_attr "alternative" "0")
4604 (eq_attr "alternative" "1")
4605 (symbol_ref "flag_unsafe_math_optimizations")
4607 (symbol_ref "false"))))])
4609 /* For converting DF(xmm2) to SF(xmm1), use the following code instead of
4611 unpcklpd xmm2,xmm2 ; packed conversion might crash on signaling NaNs
4613 We do the conversion post reload to avoid producing of 128bit spills
4614 that might lead to ICE on 32bit target. The sequence unlikely combine
4617 [(set (match_operand:SF 0 "sse_reg_operand")
4619 (match_operand:DF 1 "nonimmediate_operand")))]
4620 "TARGET_USE_VECTOR_FP_CONVERTS
4621 && optimize_insn_for_speed_p ()
4623 && (!EXT_REX_SSE_REG_P (operands[0])
4624 || TARGET_AVX512VL)"
4627 (float_truncate:V2SF
4631 operands[2] = lowpart_subreg (V4SFmode, operands[0], SFmode);
4632 operands[3] = CONST0_RTX (V2SFmode);
4633 operands[4] = lowpart_subreg (V2DFmode, operands[0], SFmode);
4634 /* Use movsd for loading from memory, unpcklpd for registers.
4635 Try to avoid move when unpacking can be done in source, or SSE3
4636 movddup is available. */
4637 if (REG_P (operands[1]))
4640 && REGNO (operands[0]) != REGNO (operands[1]))
4642 rtx tmp = lowpart_subreg (DFmode, operands[0], SFmode);
4643 emit_move_insn (tmp, operands[1]);
4646 else if (!TARGET_SSE3)
4647 operands[4] = lowpart_subreg (V2DFmode, operands[1], DFmode);
4648 emit_insn (gen_vec_dupv2df (operands[4], operands[1]));
4651 emit_insn (gen_vec_concatv2df (operands[4], operands[1],
4652 CONST0_RTX (DFmode)));
4655 ;; It's more profitable to split and then truncate in the same register.
4657 [(set (match_operand:SF 0 "sse_reg_operand")
4659 (match_operand:DF 1 "memory_operand")))]
4660 "TARGET_SPLIT_MEM_OPND_FOR_FP_CONVERTS
4661 && optimize_insn_for_speed_p ()"
4662 [(set (match_dup 2) (match_dup 1))
4663 (set (match_dup 0) (float_truncate:SF (match_dup 2)))]
4664 "operands[2] = lowpart_subreg (DFmode, operands[0], SFmode);")
4666 ;; Break partial SSE register dependency stall. This splitter should split
4667 ;; late in the pass sequence (after register rename pass), so allocated
4668 ;; registers won't change anymore
4671 [(set (match_operand:SF 0 "sse_reg_operand")
4673 (match_operand:DF 1 "nonimmediate_operand")))]
4675 && TARGET_SSE_PARTIAL_REG_DEPENDENCY && epilogue_completed
4676 && optimize_function_for_speed_p (cfun)
4677 && (!REG_P (operands[1])
4678 || (!TARGET_AVX && REGNO (operands[0]) != REGNO (operands[1])))
4679 && (!EXT_REX_SSE_REG_P (operands[0])
4680 || TARGET_AVX512VL)"
4689 operands[0] = lowpart_subreg (V4SFmode, operands[0], SFmode);
4690 emit_move_insn (operands[0], CONST0_RTX (V4SFmode));
4693 ;; Conversion from XFmode to {SF,DF}mode
4695 (define_insn "truncxf<mode>2"
4696 [(set (match_operand:MODEF 0 "nonimmediate_operand" "=m,f")
4697 (float_truncate:MODEF
4698 (match_operand:XF 1 "register_operand" "f,f")))]
4700 "* return output_387_reg_move (insn, operands);"
4701 [(set_attr "type" "fmov")
4702 (set_attr "mode" "<MODE>")
4703 (set (attr "enabled")
4704 (cond [(eq_attr "alternative" "1")
4705 (symbol_ref "flag_unsafe_math_optimizations")
4707 (symbol_ref "true")))])
4709 ;; Signed conversion to DImode.
4711 (define_expand "fix_truncxfdi2"
4712 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand")
4713 (fix:DI (match_operand:XF 1 "register_operand")))
4714 (clobber (reg:CC FLAGS_REG))])]
4719 emit_insn (gen_fix_truncdi_i387_fisttp (operands[0], operands[1]));
4724 (define_expand "fix_trunc<mode>di2"
4725 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand")
4726 (fix:DI (match_operand:MODEF 1 "register_operand")))
4727 (clobber (reg:CC FLAGS_REG))])]
4728 "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4731 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4733 emit_insn (gen_fix_truncdi_i387_fisttp (operands[0], operands[1]));
4736 if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4738 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4739 emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4740 if (out != operands[0])
4741 emit_move_insn (operands[0], out);
4746 ;; Signed conversion to SImode.
4748 (define_expand "fix_truncxfsi2"
4749 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand")
4750 (fix:SI (match_operand:XF 1 "register_operand")))
4751 (clobber (reg:CC FLAGS_REG))])]
4756 emit_insn (gen_fix_truncsi_i387_fisttp (operands[0], operands[1]));
4761 (define_expand "fix_trunc<mode>si2"
4762 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand")
4763 (fix:SI (match_operand:MODEF 1 "register_operand")))
4764 (clobber (reg:CC FLAGS_REG))])]
4765 "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4768 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4770 emit_insn (gen_fix_truncsi_i387_fisttp (operands[0], operands[1]));
4773 if (SSE_FLOAT_MODE_P (<MODE>mode))
4775 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4776 emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4777 if (out != operands[0])
4778 emit_move_insn (operands[0], out);
4783 ;; Signed conversion to HImode.
4785 (define_expand "fix_trunc<mode>hi2"
4786 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand")
4787 (fix:HI (match_operand:X87MODEF 1 "register_operand")))
4788 (clobber (reg:CC FLAGS_REG))])]
4790 && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4794 emit_insn (gen_fix_trunchi_i387_fisttp (operands[0], operands[1]));
4799 ;; Unsigned conversion to DImode
4801 (define_insn "fixuns_trunc<mode>di2"
4802 [(set (match_operand:DI 0 "register_operand" "=r")
4804 (match_operand:MODEF 1 "nonimmediate_operand" "vm")))]
4805 "TARGET_64BIT && TARGET_AVX512F && TARGET_SSE_MATH"
4806 "vcvtt<ssemodesuffix>2usi\t{%1, %0|%0, %1}"
4807 [(set_attr "type" "sseicvt")
4808 (set_attr "prefix" "evex")
4809 (set_attr "mode" "DI")])
4811 ;; Unsigned conversion to SImode.
4813 (define_expand "fixuns_trunc<mode>si2"
4815 [(set (match_operand:SI 0 "register_operand")
4817 (match_operand:MODEF 1 "nonimmediate_operand")))
4819 (clobber (match_scratch:<ssevecmode> 3))
4820 (clobber (match_scratch:<ssevecmode> 4))])]
4821 "(!TARGET_64BIT || TARGET_AVX512F) && TARGET_SSE2 && TARGET_SSE_MATH"
4823 machine_mode mode = <MODE>mode;
4824 machine_mode vecmode = <ssevecmode>mode;
4825 REAL_VALUE_TYPE TWO31r;
4830 emit_insn (gen_fixuns_trunc<mode>si2_avx512f (operands[0], operands[1]));
4834 if (optimize_insn_for_size_p ())
4837 real_ldexp (&TWO31r, &dconst1, 31);
4838 two31 = const_double_from_real_value (TWO31r, mode);
4839 two31 = ix86_build_const_vector (vecmode, true, two31);
4840 operands[2] = force_reg (vecmode, two31);
4843 (define_insn "fixuns_trunc<mode>si2_avx512f"
4844 [(set (match_operand:SI 0 "register_operand" "=r")
4846 (match_operand:MODEF 1 "nonimmediate_operand" "vm")))]
4847 "TARGET_AVX512F && TARGET_SSE_MATH"
4848 "vcvtt<ssemodesuffix>2usi\t{%1, %0|%0, %1}"
4849 [(set_attr "type" "sseicvt")
4850 (set_attr "prefix" "evex")
4851 (set_attr "mode" "SI")])
4853 (define_insn "*fixuns_trunc<mode>si2_avx512f_zext"
4854 [(set (match_operand:DI 0 "register_operand" "=r")
4857 (match_operand:MODEF 1 "nonimmediate_operand" "vm"))))]
4858 "TARGET_64BIT && TARGET_AVX512F && TARGET_SSE_MATH"
4859 "vcvtt<ssemodesuffix>2usi\t{%1, %k0|%k0, %1}"
4860 [(set_attr "type" "sseicvt")
4861 (set_attr "prefix" "evex")
4862 (set_attr "mode" "SI")])
4864 (define_insn_and_split "*fixuns_trunc<mode>_1"
4865 [(set (match_operand:SI 0 "register_operand" "=&x,&x")
4867 (match_operand:MODEF 3 "nonimmediate_operand" "xm,xm")))
4868 (use (match_operand:<ssevecmode> 4 "nonimmediate_operand" "m,x"))
4869 (clobber (match_scratch:<ssevecmode> 1 "=x,&x"))
4870 (clobber (match_scratch:<ssevecmode> 2 "=x,x"))]
4871 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH
4872 && optimize_function_for_speed_p (cfun)"
4874 "&& reload_completed"
4877 ix86_split_convert_uns_si_sse (operands);
4881 ;; Unsigned conversion to HImode.
4882 ;; Without these patterns, we'll try the unsigned SI conversion which
4883 ;; is complex for SSE, rather than the signed SI conversion, which isn't.
4885 (define_expand "fixuns_trunc<mode>hi2"
4887 (fix:SI (match_operand:MODEF 1 "nonimmediate_operand")))
4888 (set (match_operand:HI 0 "nonimmediate_operand")
4889 (subreg:HI (match_dup 2) 0))]
4890 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
4891 "operands[2] = gen_reg_rtx (SImode);")
4893 ;; When SSE is available, it is always faster to use it!
4894 (define_insn "fix_trunc<MODEF:mode><SWI48:mode>_sse"
4895 [(set (match_operand:SWI48 0 "register_operand" "=r,r")
4896 (fix:SWI48 (match_operand:MODEF 1 "nonimmediate_operand" "v,m")))]
4897 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode)
4898 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4899 "%vcvtt<MODEF:ssemodesuffix>2si<SWI48:rex64suffix>\t{%1, %0|%0, %1}"
4900 [(set_attr "type" "sseicvt")
4901 (set_attr "prefix" "maybe_vex")
4902 (set (attr "prefix_rex")
4904 (match_test "<SWI48:MODE>mode == DImode")
4906 (const_string "*")))
4907 (set_attr "mode" "<MODEF:MODE>")
4908 (set_attr "athlon_decode" "double,vector")
4909 (set_attr "amdfam10_decode" "double,double")
4910 (set_attr "bdver1_decode" "double,double")])
4912 ;; Avoid vector decoded forms of the instruction.
4914 [(match_scratch:MODEF 2 "x")
4915 (set (match_operand:SWI48 0 "register_operand")
4916 (fix:SWI48 (match_operand:MODEF 1 "memory_operand")))]
4917 "TARGET_AVOID_VECTOR_DECODE
4918 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode)
4919 && optimize_insn_for_speed_p ()"
4920 [(set (match_dup 2) (match_dup 1))
4921 (set (match_dup 0) (fix:SWI48 (match_dup 2)))])
4923 (define_insn "fix_trunc<mode>_i387_fisttp"
4924 [(set (match_operand:SWI248x 0 "nonimmediate_operand" "=m")
4925 (fix:SWI248x (match_operand 1 "register_operand" "f")))
4926 (clobber (match_scratch:XF 2 "=&f"))]
4927 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4929 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4930 && (TARGET_64BIT || <MODE>mode != DImode))
4931 && TARGET_SSE_MATH)"
4932 "* return output_fix_trunc (insn, operands, true);"
4933 [(set_attr "type" "fisttp")
4934 (set_attr "mode" "<MODE>")])
4936 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4937 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4938 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4939 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4940 ;; function in i386.c.
4941 (define_insn_and_split "*fix_trunc<mode>_i387_1"
4942 [(set (match_operand:SWI248x 0 "nonimmediate_operand")
4943 (fix:SWI248x (match_operand 1 "register_operand")))
4944 (clobber (reg:CC FLAGS_REG))]
4945 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4947 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4948 && (TARGET_64BIT || <MODE>mode != DImode))
4949 && can_create_pseudo_p ()"
4954 ix86_optimize_mode_switching[I387_TRUNC] = 1;
4956 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
4957 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
4959 emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4960 operands[2], operands[3]));
4963 [(set_attr "type" "fistp")
4964 (set_attr "i387_cw" "trunc")
4965 (set_attr "mode" "<MODE>")])
4967 (define_insn "fix_truncdi_i387"
4968 [(set (match_operand:DI 0 "nonimmediate_operand" "=m")
4969 (fix:DI (match_operand 1 "register_operand" "f")))
4970 (use (match_operand:HI 2 "memory_operand" "m"))
4971 (use (match_operand:HI 3 "memory_operand" "m"))
4972 (clobber (match_scratch:XF 4 "=&f"))]
4973 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4975 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4976 "* return output_fix_trunc (insn, operands, false);"
4977 [(set_attr "type" "fistp")
4978 (set_attr "i387_cw" "trunc")
4979 (set_attr "mode" "DI")])
4981 (define_insn "fix_trunc<mode>_i387"
4982 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m")
4983 (fix:SWI24 (match_operand 1 "register_operand" "f")))
4984 (use (match_operand:HI 2 "memory_operand" "m"))
4985 (use (match_operand:HI 3 "memory_operand" "m"))]
4986 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4988 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4989 "* return output_fix_trunc (insn, operands, false);"
4990 [(set_attr "type" "fistp")
4991 (set_attr "i387_cw" "trunc")
4992 (set_attr "mode" "<MODE>")])
4994 (define_insn "x86_fnstcw_1"
4995 [(set (match_operand:HI 0 "memory_operand" "=m")
4996 (unspec:HI [(const_int 0)] UNSPEC_FSTCW))]
4999 [(set (attr "length")
5000 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
5001 (set_attr "mode" "HI")
5002 (set_attr "unit" "i387")
5003 (set_attr "bdver1_decode" "vector")])
5005 ;; Conversion between fixed point and floating point.
5007 ;; Even though we only accept memory inputs, the backend _really_
5008 ;; wants to be able to do this between registers. Thankfully, LRA
5009 ;; will fix this up for us during register allocation.
5011 (define_insn "floathi<mode>2"
5012 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5013 (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "m")))]
5015 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5016 || TARGET_MIX_SSE_I387)"
5018 [(set_attr "type" "fmov")
5019 (set_attr "mode" "<MODE>")
5020 (set_attr "znver1_decode" "double")
5021 (set_attr "fp_int_src" "true")])
5023 (define_insn "float<SWI48x:mode>xf2"
5024 [(set (match_operand:XF 0 "register_operand" "=f")
5025 (float:XF (match_operand:SWI48x 1 "nonimmediate_operand" "m")))]
5028 [(set_attr "type" "fmov")
5029 (set_attr "mode" "XF")
5030 (set_attr "znver1_decode" "double")
5031 (set_attr "fp_int_src" "true")])
5033 (define_expand "float<SWI48x:mode><MODEF:mode>2"
5034 [(set (match_operand:MODEF 0 "register_operand")
5035 (float:MODEF (match_operand:SWI48x 1 "nonimmediate_operand")))]
5036 "(TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI48x:MODE>mode))
5037 || (SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5038 && ((<SWI48x:MODE>mode != DImode) || TARGET_64BIT))")
5040 (define_insn "*float<SWI48:mode><MODEF:mode>2"
5041 [(set (match_operand:MODEF 0 "register_operand" "=f,v,v")
5043 (match_operand:SWI48 1 "nonimmediate_operand" "m,r,m")))]
5044 "(TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI48:MODE>mode))
5045 || (SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)"
5048 %vcvtsi2<MODEF:ssemodesuffix><SWI48:rex64suffix>\t{%1, %d0|%d0, %1}
5049 %vcvtsi2<MODEF:ssemodesuffix><SWI48:rex64suffix>\t{%1, %d0|%d0, %1}"
5050 [(set_attr "type" "fmov,sseicvt,sseicvt")
5051 (set_attr "avx_partial_xmm_update" "false,true,true")
5052 (set_attr "prefix" "orig,maybe_vex,maybe_vex")
5053 (set_attr "mode" "<MODEF:MODE>")
5054 (set (attr "prefix_rex")
5056 (and (eq_attr "prefix" "maybe_vex")
5057 (match_test "<SWI48:MODE>mode == DImode"))
5059 (const_string "*")))
5060 (set_attr "unit" "i387,*,*")
5061 (set_attr "athlon_decode" "*,double,direct")
5062 (set_attr "amdfam10_decode" "*,vector,double")
5063 (set_attr "bdver1_decode" "*,double,direct")
5064 (set_attr "znver1_decode" "double,*,*")
5065 (set_attr "fp_int_src" "true")
5066 (set (attr "enabled")
5068 (match_test ("SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"))
5070 (eq_attr "alternative" "0")
5071 (symbol_ref "TARGET_MIX_SSE_I387
5072 && X87_ENABLE_FLOAT (<MODEF:MODE>mode,
5074 (symbol_ref "true"))
5076 (eq_attr "alternative" "0")
5078 (symbol_ref "false"))))
5079 (set (attr "preferred_for_speed")
5080 (cond [(eq_attr "alternative" "1")
5081 (symbol_ref "TARGET_INTER_UNIT_CONVERSIONS")]
5082 (symbol_ref "true")))])
5084 (define_insn "*floatdi<MODEF:mode>2_i387"
5085 [(set (match_operand:MODEF 0 "register_operand" "=f")
5086 (float:MODEF (match_operand:DI 1 "nonimmediate_operand" "m")))]
5088 && TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, DImode)"
5090 [(set_attr "type" "fmov")
5091 (set_attr "mode" "<MODEF:MODE>")
5092 (set_attr "znver1_decode" "double")
5093 (set_attr "fp_int_src" "true")])
5095 ;; Try TARGET_USE_VECTOR_CONVERTS, but not so hard as to require extra memory
5096 ;; slots when !TARGET_INTER_UNIT_MOVES_TO_VEC disables the general_regs
5097 ;; alternative in sse2_loadld.
5099 [(set (match_operand:MODEF 0 "sse_reg_operand")
5100 (float:MODEF (match_operand:SI 1 "nonimmediate_operand")))]
5102 && TARGET_USE_VECTOR_CONVERTS
5103 && optimize_function_for_speed_p (cfun)
5105 && (MEM_P (operands[1]) || TARGET_INTER_UNIT_MOVES_TO_VEC)
5106 && (!EXT_REX_SSE_REG_P (operands[0])
5107 || TARGET_AVX512VL)"
5110 operands[3] = lowpart_subreg (<ssevecmode>mode, operands[0], <MODE>mode);
5111 operands[4] = lowpart_subreg (V4SImode, operands[0], <MODE>mode);
5113 emit_insn (gen_sse2_loadld (operands[4],
5114 CONST0_RTX (V4SImode), operands[1]));
5116 if (<ssevecmode>mode == V4SFmode)
5117 emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
5119 emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
5123 ;; Avoid store forwarding (partial memory) stall penalty
5124 ;; by passing DImode value through XMM registers. */
5127 [(set (match_operand:X87MODEF 0 "register_operand")
5129 (match_operand:DI 1 "register_operand")))]
5130 "!TARGET_64BIT && TARGET_INTER_UNIT_MOVES_TO_VEC
5131 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5132 && TARGET_SSE2 && optimize_function_for_speed_p (cfun)
5133 && can_create_pseudo_p ()"
5136 emit_insn (gen_floatdi<mode>2_i387_with_xmm
5137 (operands[0], operands[1],
5138 assign_386_stack_local (DImode, SLOT_TEMP)));
5142 (define_insn_and_split "floatdi<X87MODEF:mode>2_i387_with_xmm"
5143 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5145 (match_operand:DI 1 "register_operand" "r,r")))
5146 (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
5147 (clobber (match_scratch:V4SI 3 "=x,x"))
5148 (clobber (match_scratch:V4SI 4 "=X,x"))]
5149 "!TARGET_64BIT && TARGET_INTER_UNIT_MOVES_TO_VEC
5150 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5151 && TARGET_SSE2 && optimize_function_for_speed_p (cfun)"
5153 "&& reload_completed"
5154 [(set (match_dup 2) (match_dup 3))
5155 (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5157 /* The DImode arrived in a pair of integral registers (e.g. %edx:%eax).
5158 Assemble the 64-bit DImode value in an xmm register. */
5159 emit_insn (gen_sse2_loadld (operands[3], CONST0_RTX (V4SImode),
5160 gen_lowpart (SImode, operands[1])));
5162 emit_insn (gen_sse4_1_pinsrd (operands[3], operands[3],
5163 gen_highpart (SImode, operands[1]),
5167 emit_insn (gen_sse2_loadld (operands[4], CONST0_RTX (V4SImode),
5168 gen_highpart (SImode, operands[1])));
5169 emit_insn (gen_vec_interleave_lowv4si (operands[3], operands[3],
5172 operands[3] = gen_lowpart (DImode, operands[3]);
5174 [(set_attr "isa" "sse4,*")
5175 (set_attr "type" "multi")
5176 (set_attr "mode" "<X87MODEF:MODE>")
5177 (set_attr "unit" "i387")
5178 (set_attr "fp_int_src" "true")])
5180 ;; Break partial SSE register dependency stall. This splitter should split
5181 ;; late in the pass sequence (after register rename pass), so allocated
5182 ;; registers won't change anymore
5185 [(set (match_operand:MODEF 0 "sse_reg_operand")
5186 (float:MODEF (match_operand:SWI48 1 "nonimmediate_operand")))]
5188 && TARGET_SSE_PARTIAL_REG_DEPENDENCY && epilogue_completed
5189 && optimize_function_for_speed_p (cfun)
5190 && (!EXT_REX_SSE_REG_P (operands[0])
5191 || TARGET_AVX512VL)"
5193 (vec_merge:<MODEF:ssevecmode>
5194 (vec_duplicate:<MODEF:ssevecmode>
5200 const machine_mode vmode = <MODEF:ssevecmode>mode;
5202 operands[0] = lowpart_subreg (vmode, operands[0], <MODEF:MODE>mode);
5203 emit_move_insn (operands[0], CONST0_RTX (vmode));
5206 (define_expand "floatuns<SWI12:mode><MODEF:mode>2"
5207 [(set (match_operand:MODEF 0 "register_operand")
5208 (unsigned_float:MODEF
5209 (match_operand:SWI12 1 "nonimmediate_operand")))]
5211 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
5213 operands[1] = convert_to_mode (SImode, operands[1], 1);
5214 emit_insn (gen_floatsi<MODEF:mode>2 (operands[0], operands[1]));
5218 (define_insn "*floatuns<SWI48:mode><MODEF:mode>2_avx512"
5219 [(set (match_operand:MODEF 0 "register_operand" "=v")
5220 (unsigned_float:MODEF
5221 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))]
5222 "TARGET_AVX512F && TARGET_SSE_MATH"
5223 "vcvtusi2<MODEF:ssemodesuffix><SWI48:rex64suffix>\t{%1, %0, %0|%0, %0, %1}"
5224 [(set_attr "type" "sseicvt")
5225 (set_attr "prefix" "evex")
5226 (set_attr "mode" "<MODEF:MODE>")])
5228 ;; Avoid store forwarding (partial memory) stall penalty by extending
5229 ;; SImode value to DImode through XMM register instead of pushing two
5230 ;; SImode values to stack. Also note that fild loads from memory only.
5232 (define_insn_and_split "floatunssi<mode>2_i387_with_xmm"
5233 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5234 (unsigned_float:X87MODEF
5235 (match_operand:SI 1 "nonimmediate_operand" "rm")))
5236 (clobber (match_operand:DI 2 "memory_operand" "=m"))
5237 (clobber (match_scratch:DI 3 "=x"))]
5239 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5240 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC"
5242 "&& reload_completed"
5243 [(set (match_dup 3) (zero_extend:DI (match_dup 1)))
5244 (set (match_dup 2) (match_dup 3))
5246 (float:X87MODEF (match_dup 2)))]
5248 [(set_attr "type" "multi")
5249 (set_attr "mode" "<MODE>")])
5251 (define_expand "floatunssi<mode>2"
5252 [(set (match_operand:X87MODEF 0 "register_operand")
5253 (unsigned_float:X87MODEF
5254 (match_operand:SI 1 "nonimmediate_operand")))]
5256 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5257 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC)
5258 || ((!TARGET_64BIT || TARGET_AVX512F)
5259 && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
5261 if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
5263 emit_insn (gen_floatunssi<mode>2_i387_with_xmm
5264 (operands[0], operands[1],
5265 assign_386_stack_local (DImode, SLOT_TEMP)));
5268 if (!TARGET_AVX512F)
5270 ix86_expand_convert_uns_si<mode>_sse (operands[0], operands[1]);
5275 (define_expand "floatunsdisf2"
5276 [(set (match_operand:SF 0 "register_operand")
5278 (match_operand:DI 1 "nonimmediate_operand")))]
5279 "TARGET_64BIT && TARGET_SSE && TARGET_SSE_MATH"
5281 if (!TARGET_AVX512F)
5283 x86_emit_floatuns (operands);
5288 (define_expand "floatunsdidf2"
5289 [(set (match_operand:DF 0 "register_operand")
5291 (match_operand:DI 1 "nonimmediate_operand")))]
5292 "((TARGET_64BIT && TARGET_AVX512F)
5293 || TARGET_KEEPS_VECTOR_ALIGNED_STACK)
5294 && TARGET_SSE2 && TARGET_SSE_MATH"
5298 ix86_expand_convert_uns_didf_sse (operands[0], operands[1]);
5301 if (!TARGET_AVX512F)
5303 x86_emit_floatuns (operands);
5308 ;; Load effective address instructions
5310 (define_insn_and_split "*lea<mode>"
5311 [(set (match_operand:SWI48 0 "register_operand" "=r")
5312 (match_operand:SWI48 1 "address_no_seg_operand" "Ts"))]
5315 if (SImode_address_operand (operands[1], VOIDmode))
5317 gcc_assert (TARGET_64BIT);
5318 return "lea{l}\t{%E1, %k0|%k0, %E1}";
5321 return "lea{<imodesuffix>}\t{%E1, %0|%0, %E1}";
5323 "reload_completed && ix86_avoid_lea_for_addr (insn, operands)"
5326 machine_mode mode = <MODE>mode;
5329 /* ix86_avoid_lea_for_addr re-recognizes insn and may
5330 change operands[] array behind our back. */
5331 pat = PATTERN (curr_insn);
5333 operands[0] = SET_DEST (pat);
5334 operands[1] = SET_SRC (pat);
5336 /* Emit all operations in SImode for zero-extended addresses. */
5337 if (SImode_address_operand (operands[1], VOIDmode))
5340 ix86_split_lea_for_addr (curr_insn, operands, mode);
5342 /* Zero-extend return register to DImode for zero-extended addresses. */
5343 if (mode != <MODE>mode)
5344 emit_insn (gen_zero_extendsidi2
5345 (operands[0], gen_lowpart (mode, operands[0])));
5349 [(set_attr "type" "lea")
5352 (match_operand 1 "SImode_address_operand")
5354 (const_string "<MODE>")))])
5358 (define_expand "add<mode>3"
5359 [(set (match_operand:SDWIM 0 "nonimmediate_operand")
5360 (plus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")
5361 (match_operand:SDWIM 2 "<general_hilo_operand>")))]
5363 "ix86_expand_binary_operator (PLUS, <MODE>mode, operands); DONE;")
5365 (define_insn_and_split "*add<dwi>3_doubleword"
5366 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
5368 (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0")
5369 (match_operand:<DWI> 2 "x86_64_hilo_general_operand"
5371 (clobber (reg:CC FLAGS_REG))]
5372 "ix86_binary_operator_ok (PLUS, <DWI>mode, operands)"
5375 [(parallel [(set (reg:CCC FLAGS_REG)
5377 (plus:DWIH (match_dup 1) (match_dup 2))
5380 (plus:DWIH (match_dup 1) (match_dup 2)))])
5381 (parallel [(set (match_dup 3)
5384 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
5387 (clobber (reg:CC FLAGS_REG))])]
5389 split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
5390 if (operands[2] == const0_rtx)
5392 ix86_expand_binary_operator (PLUS, <MODE>mode, &operands[3]);
5397 (define_insn "*add<mode>_1"
5398 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,rm,r,r")
5400 (match_operand:SWI48 1 "nonimmediate_operand" "%0,0,r,r")
5401 (match_operand:SWI48 2 "x86_64_general_operand" "rme,re,0,le")))
5402 (clobber (reg:CC FLAGS_REG))]
5403 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5405 switch (get_attr_type (insn))
5411 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5412 if (operands[2] == const1_rtx)
5413 return "inc{<imodesuffix>}\t%0";
5416 gcc_assert (operands[2] == constm1_rtx);
5417 return "dec{<imodesuffix>}\t%0";
5421 /* For most processors, ADD is faster than LEA. This alternative
5422 was added to use ADD as much as possible. */
5423 if (which_alternative == 2)
5424 std::swap (operands[1], operands[2]);
5426 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5427 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5428 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5430 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5434 (cond [(eq_attr "alternative" "3")
5435 (const_string "lea")
5436 (match_operand:SWI48 2 "incdec_operand")
5437 (const_string "incdec")
5439 (const_string "alu")))
5440 (set (attr "length_immediate")
5442 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5444 (const_string "*")))
5445 (set_attr "mode" "<MODE>")])
5447 ;; It may seem that nonimmediate operand is proper one for operand 1.
5448 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5449 ;; we take care in ix86_binary_operator_ok to not allow two memory
5450 ;; operands so proper swapping will be done in reload. This allow
5451 ;; patterns constructed from addsi_1 to match.
5453 (define_insn "addsi_1_zext"
5454 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
5456 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r,r")
5457 (match_operand:SI 2 "x86_64_general_operand" "rme,0,le"))))
5458 (clobber (reg:CC FLAGS_REG))]
5459 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5461 switch (get_attr_type (insn))
5467 if (operands[2] == const1_rtx)
5468 return "inc{l}\t%k0";
5471 gcc_assert (operands[2] == constm1_rtx);
5472 return "dec{l}\t%k0";
5476 /* For most processors, ADD is faster than LEA. This alternative
5477 was added to use ADD as much as possible. */
5478 if (which_alternative == 1)
5479 std::swap (operands[1], operands[2]);
5481 if (x86_maybe_negate_const_int (&operands[2], SImode))
5482 return "sub{l}\t{%2, %k0|%k0, %2}";
5484 return "add{l}\t{%2, %k0|%k0, %2}";
5488 (cond [(eq_attr "alternative" "2")
5489 (const_string "lea")
5490 (match_operand:SI 2 "incdec_operand")
5491 (const_string "incdec")
5493 (const_string "alu")))
5494 (set (attr "length_immediate")
5496 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5498 (const_string "*")))
5499 (set_attr "mode" "SI")])
5501 (define_insn "*addhi_1"
5502 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r,Yp")
5503 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r,Yp")
5504 (match_operand:HI 2 "general_operand" "rn,rm,0,ln")))
5505 (clobber (reg:CC FLAGS_REG))]
5506 "ix86_binary_operator_ok (PLUS, HImode, operands)"
5508 switch (get_attr_type (insn))
5514 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5515 if (operands[2] == const1_rtx)
5516 return "inc{w}\t%0";
5519 gcc_assert (operands[2] == constm1_rtx);
5520 return "dec{w}\t%0";
5524 /* For most processors, ADD is faster than LEA. This alternative
5525 was added to use ADD as much as possible. */
5526 if (which_alternative == 2)
5527 std::swap (operands[1], operands[2]);
5529 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5530 if (x86_maybe_negate_const_int (&operands[2], HImode))
5531 return "sub{w}\t{%2, %0|%0, %2}";
5533 return "add{w}\t{%2, %0|%0, %2}";
5537 (cond [(eq_attr "alternative" "3")
5538 (const_string "lea")
5539 (match_operand:HI 2 "incdec_operand")
5540 (const_string "incdec")
5542 (const_string "alu")))
5543 (set (attr "length_immediate")
5545 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5547 (const_string "*")))
5548 (set_attr "mode" "HI,HI,HI,SI")])
5550 (define_insn "*addqi_1"
5551 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,q,r,r,Yp")
5552 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,q,0,r,Yp")
5553 (match_operand:QI 2 "general_operand" "qn,qm,0,rn,0,ln")))
5554 (clobber (reg:CC FLAGS_REG))]
5555 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5557 bool widen = (get_attr_mode (insn) != MODE_QI);
5559 switch (get_attr_type (insn))
5565 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5566 if (operands[2] == const1_rtx)
5567 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
5570 gcc_assert (operands[2] == constm1_rtx);
5571 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
5575 /* For most processors, ADD is faster than LEA. These alternatives
5576 were added to use ADD as much as possible. */
5577 if (which_alternative == 2 || which_alternative == 4)
5578 std::swap (operands[1], operands[2]);
5580 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5581 if (x86_maybe_negate_const_int (&operands[2], QImode))
5584 return "sub{l}\t{%2, %k0|%k0, %2}";
5586 return "sub{b}\t{%2, %0|%0, %2}";
5589 return "add{l}\t{%k2, %k0|%k0, %k2}";
5591 return "add{b}\t{%2, %0|%0, %2}";
5595 (cond [(eq_attr "alternative" "5")
5596 (const_string "lea")
5597 (match_operand:QI 2 "incdec_operand")
5598 (const_string "incdec")
5600 (const_string "alu")))
5601 (set (attr "length_immediate")
5603 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5605 (const_string "*")))
5606 (set_attr "mode" "QI,QI,QI,SI,SI,SI")
5607 ;; Potential partial reg stall on alternatives 3 and 4.
5608 (set (attr "preferred_for_speed")
5609 (cond [(eq_attr "alternative" "3,4")
5610 (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
5611 (symbol_ref "true")))])
5613 (define_insn "*addqi_1_slp"
5614 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
5615 (plus:QI (match_dup 0)
5616 (match_operand:QI 1 "general_operand" "qn,qm")))
5617 (clobber (reg:CC FLAGS_REG))]
5618 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
5619 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
5621 switch (get_attr_type (insn))
5624 if (operands[1] == const1_rtx)
5625 return "inc{b}\t%0";
5628 gcc_assert (operands[1] == constm1_rtx);
5629 return "dec{b}\t%0";
5633 if (x86_maybe_negate_const_int (&operands[1], QImode))
5634 return "sub{b}\t{%1, %0|%0, %1}";
5636 return "add{b}\t{%1, %0|%0, %1}";
5640 (if_then_else (match_operand:QI 1 "incdec_operand")
5641 (const_string "incdec")
5642 (const_string "alu1")))
5643 (set (attr "memory")
5644 (if_then_else (match_operand 1 "memory_operand")
5645 (const_string "load")
5646 (const_string "none")))
5647 (set_attr "mode" "QI")])
5649 ;; Split non destructive adds if we cannot use lea.
5651 [(set (match_operand:SWI48 0 "register_operand")
5652 (plus:SWI48 (match_operand:SWI48 1 "register_operand")
5653 (match_operand:SWI48 2 "x86_64_nonmemory_operand")))
5654 (clobber (reg:CC FLAGS_REG))]
5655 "reload_completed && ix86_avoid_lea_for_add (insn, operands)"
5656 [(set (match_dup 0) (match_dup 1))
5657 (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 2)))
5658 (clobber (reg:CC FLAGS_REG))])])
5660 ;; Split non destructive adds if we cannot use lea.
5662 [(set (match_operand:DI 0 "register_operand")
5664 (plus:SI (match_operand:SI 1 "register_operand")
5665 (match_operand:SI 2 "x86_64_nonmemory_operand"))))
5666 (clobber (reg:CC FLAGS_REG))]
5668 && reload_completed && ix86_avoid_lea_for_add (insn, operands)"
5669 [(set (match_dup 3) (match_dup 1))
5670 (parallel [(set (match_dup 0)
5671 (zero_extend:DI (plus:SI (match_dup 3) (match_dup 2))))
5672 (clobber (reg:CC FLAGS_REG))])]
5673 "operands[3] = gen_lowpart (SImode, operands[0]);")
5675 ;; Convert add to the lea pattern to avoid flags dependency.
5677 [(set (match_operand:SWI 0 "register_operand")
5678 (plus:SWI (match_operand:SWI 1 "register_operand")
5679 (match_operand:SWI 2 "<nonmemory_operand>")))
5680 (clobber (reg:CC FLAGS_REG))]
5681 "reload_completed && ix86_lea_for_add_ok (insn, operands)"
5683 (plus:<LEAMODE> (match_dup 1) (match_dup 2)))]
5685 if (<MODE>mode != <LEAMODE>mode)
5687 operands[0] = gen_lowpart (<LEAMODE>mode, operands[0]);
5688 operands[1] = gen_lowpart (<LEAMODE>mode, operands[1]);
5689 operands[2] = gen_lowpart (<LEAMODE>mode, operands[2]);
5693 ;; Convert add to the lea pattern to avoid flags dependency.
5695 [(set (match_operand:DI 0 "register_operand")
5697 (plus:SI (match_operand:SI 1 "register_operand")
5698 (match_operand:SI 2 "x86_64_nonmemory_operand"))))
5699 (clobber (reg:CC FLAGS_REG))]
5700 "TARGET_64BIT && reload_completed && ix86_lea_for_add_ok (insn, operands)"
5702 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))])
5704 (define_insn "*add<mode>_2"
5705 [(set (reg FLAGS_REG)
5708 (match_operand:SWI 1 "nonimmediate_operand" "%0,0,<r>")
5709 (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>,0"))
5711 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m,<r>")
5712 (plus:SWI (match_dup 1) (match_dup 2)))]
5713 "ix86_match_ccmode (insn, CCGOCmode)
5714 && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5716 switch (get_attr_type (insn))
5719 if (operands[2] == const1_rtx)
5720 return "inc{<imodesuffix>}\t%0";
5723 gcc_assert (operands[2] == constm1_rtx);
5724 return "dec{<imodesuffix>}\t%0";
5728 if (which_alternative == 2)
5729 std::swap (operands[1], operands[2]);
5731 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5732 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5733 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5735 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5739 (if_then_else (match_operand:SWI 2 "incdec_operand")
5740 (const_string "incdec")
5741 (const_string "alu")))
5742 (set (attr "length_immediate")
5744 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5746 (const_string "*")))
5747 (set_attr "mode" "<MODE>")])
5749 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5750 (define_insn "*addsi_2_zext"
5751 [(set (reg FLAGS_REG)
5753 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
5754 (match_operand:SI 2 "x86_64_general_operand" "rme,0"))
5756 (set (match_operand:DI 0 "register_operand" "=r,r")
5757 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5758 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5759 && ix86_binary_operator_ok (PLUS, SImode, operands)"
5761 switch (get_attr_type (insn))
5764 if (operands[2] == const1_rtx)
5765 return "inc{l}\t%k0";
5768 gcc_assert (operands[2] == constm1_rtx);
5769 return "dec{l}\t%k0";
5773 if (which_alternative == 1)
5774 std::swap (operands[1], operands[2]);
5776 if (x86_maybe_negate_const_int (&operands[2], SImode))
5777 return "sub{l}\t{%2, %k0|%k0, %2}";
5779 return "add{l}\t{%2, %k0|%k0, %2}";
5783 (if_then_else (match_operand:SI 2 "incdec_operand")
5784 (const_string "incdec")
5785 (const_string "alu")))
5786 (set (attr "length_immediate")
5788 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5790 (const_string "*")))
5791 (set_attr "mode" "SI")])
5793 (define_insn "*add<mode>_3"
5794 [(set (reg FLAGS_REG)
5796 (neg:SWI (match_operand:SWI 2 "<general_operand>" "<g>,0"))
5797 (match_operand:SWI 1 "nonimmediate_operand" "%0,<r>")))
5798 (clobber (match_scratch:SWI 0 "=<r>,<r>"))]
5799 "ix86_match_ccmode (insn, CCZmode)
5800 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
5802 switch (get_attr_type (insn))
5805 if (operands[2] == const1_rtx)
5806 return "inc{<imodesuffix>}\t%0";
5809 gcc_assert (operands[2] == constm1_rtx);
5810 return "dec{<imodesuffix>}\t%0";
5814 if (which_alternative == 1)
5815 std::swap (operands[1], operands[2]);
5817 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5818 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5819 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5821 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5825 (if_then_else (match_operand:SWI 2 "incdec_operand")
5826 (const_string "incdec")
5827 (const_string "alu")))
5828 (set (attr "length_immediate")
5830 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5832 (const_string "*")))
5833 (set_attr "mode" "<MODE>")])
5835 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5836 (define_insn "*addsi_3_zext"
5837 [(set (reg FLAGS_REG)
5839 (neg:SI (match_operand:SI 2 "x86_64_general_operand" "rme,0"))
5840 (match_operand:SI 1 "nonimmediate_operand" "%0,r")))
5841 (set (match_operand:DI 0 "register_operand" "=r,r")
5842 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5843 "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
5844 && ix86_binary_operator_ok (PLUS, SImode, operands)"
5846 switch (get_attr_type (insn))
5849 if (operands[2] == const1_rtx)
5850 return "inc{l}\t%k0";
5853 gcc_assert (operands[2] == constm1_rtx);
5854 return "dec{l}\t%k0";
5858 if (which_alternative == 1)
5859 std::swap (operands[1], operands[2]);
5861 if (x86_maybe_negate_const_int (&operands[2], SImode))
5862 return "sub{l}\t{%2, %k0|%k0, %2}";
5864 return "add{l}\t{%2, %k0|%k0, %2}";
5868 (if_then_else (match_operand:SI 2 "incdec_operand")
5869 (const_string "incdec")
5870 (const_string "alu")))
5871 (set (attr "length_immediate")
5873 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5875 (const_string "*")))
5876 (set_attr "mode" "SI")])
5878 ; For comparisons against 1, -1 and 128, we may generate better code
5879 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
5880 ; is matched then. We can't accept general immediate, because for
5881 ; case of overflows, the result is messed up.
5882 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5883 ; only for comparisons not depending on it.
5885 (define_insn "*adddi_4"
5886 [(set (reg FLAGS_REG)
5888 (match_operand:DI 1 "nonimmediate_operand" "0")
5889 (match_operand:DI 2 "x86_64_immediate_operand" "e")))
5890 (clobber (match_scratch:DI 0 "=rm"))]
5892 && ix86_match_ccmode (insn, CCGCmode)"
5894 switch (get_attr_type (insn))
5897 if (operands[2] == constm1_rtx)
5898 return "inc{q}\t%0";
5901 gcc_assert (operands[2] == const1_rtx);
5902 return "dec{q}\t%0";
5906 if (x86_maybe_negate_const_int (&operands[2], DImode))
5907 return "add{q}\t{%2, %0|%0, %2}";
5909 return "sub{q}\t{%2, %0|%0, %2}";
5913 (if_then_else (match_operand:DI 2 "incdec_operand")
5914 (const_string "incdec")
5915 (const_string "alu")))
5916 (set (attr "length_immediate")
5918 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5920 (const_string "*")))
5921 (set_attr "mode" "DI")])
5923 ; For comparisons against 1, -1 and 128, we may generate better code
5924 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
5925 ; is matched then. We can't accept general immediate, because for
5926 ; case of overflows, the result is messed up.
5927 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5928 ; only for comparisons not depending on it.
5930 (define_insn "*add<mode>_4"
5931 [(set (reg FLAGS_REG)
5933 (match_operand:SWI124 1 "nonimmediate_operand" "0")
5934 (match_operand:SWI124 2 "const_int_operand" "n")))
5935 (clobber (match_scratch:SWI124 0 "=<r>m"))]
5936 "ix86_match_ccmode (insn, CCGCmode)"
5938 switch (get_attr_type (insn))
5941 if (operands[2] == constm1_rtx)
5942 return "inc{<imodesuffix>}\t%0";
5945 gcc_assert (operands[2] == const1_rtx);
5946 return "dec{<imodesuffix>}\t%0";
5950 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5951 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5953 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5957 (if_then_else (match_operand:<MODE> 2 "incdec_operand")
5958 (const_string "incdec")
5959 (const_string "alu")))
5960 (set (attr "length_immediate")
5962 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5964 (const_string "*")))
5965 (set_attr "mode" "<MODE>")])
5967 (define_insn "*add<mode>_5"
5968 [(set (reg FLAGS_REG)
5971 (match_operand:SWI 1 "nonimmediate_operand" "%0,<r>")
5972 (match_operand:SWI 2 "<general_operand>" "<g>,0"))
5974 (clobber (match_scratch:SWI 0 "=<r>,<r>"))]
5975 "ix86_match_ccmode (insn, CCGOCmode)
5976 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
5978 switch (get_attr_type (insn))
5981 if (operands[2] == const1_rtx)
5982 return "inc{<imodesuffix>}\t%0";
5985 gcc_assert (operands[2] == constm1_rtx);
5986 return "dec{<imodesuffix>}\t%0";
5990 if (which_alternative == 1)
5991 std::swap (operands[1], operands[2]);
5993 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5994 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5995 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5997 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6001 (if_then_else (match_operand:SWI 2 "incdec_operand")
6002 (const_string "incdec")
6003 (const_string "alu")))
6004 (set (attr "length_immediate")
6006 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6008 (const_string "*")))
6009 (set_attr "mode" "<MODE>")])
6011 (define_insn "addqi_ext_1"
6012 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q,Q")
6018 (zero_extract:SI (match_operand 1 "ext_register_operand" "0,0")
6021 (match_operand:QI 2 "general_operand" "QnBc,m")) 0))
6022 (clobber (reg:CC FLAGS_REG))]
6023 "/* FIXME: without this LRA can't reload this pattern, see PR82524. */
6024 rtx_equal_p (operands[0], operands[1])"
6026 switch (get_attr_type (insn))
6029 if (operands[2] == const1_rtx)
6030 return "inc{b}\t%h0";
6033 gcc_assert (operands[2] == constm1_rtx);
6034 return "dec{b}\t%h0";
6038 return "add{b}\t{%2, %h0|%h0, %2}";
6041 [(set_attr "isa" "*,nox64")
6043 (if_then_else (match_operand:QI 2 "incdec_operand")
6044 (const_string "incdec")
6045 (const_string "alu")))
6046 (set_attr "mode" "QI")])
6048 (define_insn "*addqi_ext_2"
6049 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
6055 (zero_extract:SI (match_operand 1 "ext_register_operand" "%0")
6059 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
6061 (const_int 8)) 0)) 0))
6062 (clobber (reg:CC FLAGS_REG))]
6063 "/* FIXME: without this LRA can't reload this pattern, see PR82524. */
6064 rtx_equal_p (operands[0], operands[1])
6065 || rtx_equal_p (operands[0], operands[2])"
6066 "add{b}\t{%h2, %h0|%h0, %h2}"
6067 [(set_attr "type" "alu")
6068 (set_attr "mode" "QI")])
6070 ;; Add with jump on overflow.
6071 (define_expand "addv<mode>4"
6072 [(parallel [(set (reg:CCO FLAGS_REG)
6075 (match_operand:SWI 1 "nonimmediate_operand"))
6078 (plus:SWI (match_dup 1)
6079 (match_operand:SWI 2
6080 "<general_operand>")))))
6081 (set (match_operand:SWI 0 "register_operand")
6082 (plus:SWI (match_dup 1) (match_dup 2)))])
6083 (set (pc) (if_then_else
6084 (eq (reg:CCO FLAGS_REG) (const_int 0))
6085 (label_ref (match_operand 3))
6089 ix86_fixup_binary_operands_no_copy (PLUS, <MODE>mode, operands);
6090 if (CONST_INT_P (operands[2]))
6091 operands[4] = operands[2];
6093 operands[4] = gen_rtx_SIGN_EXTEND (<DWI>mode, operands[2]);
6096 (define_insn "*addv<mode>4"
6097 [(set (reg:CCO FLAGS_REG)
6100 (match_operand:SWI 1 "nonimmediate_operand" "%0,0"))
6102 (match_operand:SWI 2 "<general_sext_operand>"
6105 (plus:SWI (match_dup 1) (match_dup 2)))))
6106 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
6107 (plus:SWI (match_dup 1) (match_dup 2)))]
6108 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6109 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6110 [(set_attr "type" "alu")
6111 (set_attr "mode" "<MODE>")])
6113 (define_insn "*addv<mode>4_1"
6114 [(set (reg:CCO FLAGS_REG)
6117 (match_operand:SWI 1 "nonimmediate_operand" "0"))
6118 (match_operand:<DWI> 3 "const_int_operand" "i"))
6120 (plus:SWI (match_dup 1)
6121 (match_operand:SWI 2 "x86_64_immediate_operand"
6123 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
6124 (plus:SWI (match_dup 1) (match_dup 2)))]
6125 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)
6126 && CONST_INT_P (operands[2])
6127 && INTVAL (operands[2]) == INTVAL (operands[3])"
6128 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6129 [(set_attr "type" "alu")
6130 (set_attr "mode" "<MODE>")
6131 (set (attr "length_immediate")
6132 (cond [(match_test "IN_RANGE (INTVAL (operands[2]), -128, 127)")
6134 (match_test "<MODE_SIZE> == 8")
6136 (const_string "<MODE_SIZE>")))])
6138 (define_expand "uaddv<mode>4"
6139 [(parallel [(set (reg:CCC FLAGS_REG)
6142 (match_operand:SWI 1 "nonimmediate_operand")
6143 (match_operand:SWI 2 "<general_operand>"))
6145 (set (match_operand:SWI 0 "register_operand")
6146 (plus:SWI (match_dup 1) (match_dup 2)))])
6147 (set (pc) (if_then_else
6148 (ltu (reg:CCC FLAGS_REG) (const_int 0))
6149 (label_ref (match_operand 3))
6152 "ix86_fixup_binary_operands_no_copy (PLUS, <MODE>mode, operands);")
6154 ;; The lea patterns for modes less than 32 bits need to be matched by
6155 ;; several insns converted to real lea by splitters.
6157 (define_insn_and_split "*lea<mode>_general_1"
6158 [(set (match_operand:SWI12 0 "register_operand" "=r")
6160 (plus:SWI12 (match_operand:SWI12 1 "index_register_operand" "l")
6161 (match_operand:SWI12 2 "register_operand" "r"))
6162 (match_operand:SWI12 3 "immediate_operand" "i")))]
6163 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
6165 "&& reload_completed"
6168 (plus:SI (match_dup 1) (match_dup 2))
6171 operands[0] = gen_lowpart (SImode, operands[0]);
6172 operands[1] = gen_lowpart (SImode, operands[1]);
6173 operands[2] = gen_lowpart (SImode, operands[2]);
6174 operands[3] = gen_lowpart (SImode, operands[3]);
6176 [(set_attr "type" "lea")
6177 (set_attr "mode" "SI")])
6179 (define_insn_and_split "*lea<mode>_general_2"
6180 [(set (match_operand:SWI12 0 "register_operand" "=r")
6182 (mult:SWI12 (match_operand:SWI12 1 "index_register_operand" "l")
6183 (match_operand 2 "const248_operand" "n"))
6184 (match_operand:SWI12 3 "nonmemory_operand" "ri")))]
6185 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
6187 "&& reload_completed"
6190 (mult:SI (match_dup 1) (match_dup 2))
6193 operands[0] = gen_lowpart (SImode, operands[0]);
6194 operands[1] = gen_lowpart (SImode, operands[1]);
6195 operands[3] = gen_lowpart (SImode, operands[3]);
6197 [(set_attr "type" "lea")
6198 (set_attr "mode" "SI")])
6200 (define_insn_and_split "*lea<mode>_general_2b"
6201 [(set (match_operand:SWI12 0 "register_operand" "=r")
6203 (ashift:SWI12 (match_operand:SWI12 1 "index_register_operand" "l")
6204 (match_operand 2 "const123_operand" "n"))
6205 (match_operand:SWI12 3 "nonmemory_operand" "ri")))]
6206 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
6208 "&& reload_completed"
6211 (ashift:SI (match_dup 1) (match_dup 2))
6214 operands[0] = gen_lowpart (SImode, operands[0]);
6215 operands[1] = gen_lowpart (SImode, operands[1]);
6216 operands[3] = gen_lowpart (SImode, operands[3]);
6218 [(set_attr "type" "lea")
6219 (set_attr "mode" "SI")])
6221 (define_insn_and_split "*lea<mode>_general_3"
6222 [(set (match_operand:SWI12 0 "register_operand" "=r")
6225 (mult:SWI12 (match_operand:SWI12 1 "index_register_operand" "l")
6226 (match_operand 2 "const248_operand" "n"))
6227 (match_operand:SWI12 3 "register_operand" "r"))
6228 (match_operand:SWI12 4 "immediate_operand" "i")))]
6229 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
6231 "&& reload_completed"
6235 (mult:SI (match_dup 1) (match_dup 2))
6239 operands[0] = gen_lowpart (SImode, operands[0]);
6240 operands[1] = gen_lowpart (SImode, operands[1]);
6241 operands[3] = gen_lowpart (SImode, operands[3]);
6242 operands[4] = gen_lowpart (SImode, operands[4]);
6244 [(set_attr "type" "lea")
6245 (set_attr "mode" "SI")])
6247 (define_insn_and_split "*lea<mode>_general_3b"
6248 [(set (match_operand:SWI12 0 "register_operand" "=r")
6251 (ashift:SWI12 (match_operand:SWI12 1 "index_register_operand" "l")
6252 (match_operand 2 "const123_operand" "n"))
6253 (match_operand:SWI12 3 "register_operand" "r"))
6254 (match_operand:SWI12 4 "immediate_operand" "i")))]
6255 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
6257 "&& reload_completed"
6261 (ashift:SI (match_dup 1) (match_dup 2))
6265 operands[0] = gen_lowpart (SImode, operands[0]);
6266 operands[1] = gen_lowpart (SImode, operands[1]);
6267 operands[3] = gen_lowpart (SImode, operands[3]);
6268 operands[4] = gen_lowpart (SImode, operands[4]);
6270 [(set_attr "type" "lea")
6271 (set_attr "mode" "SI")])
6273 (define_insn_and_split "*lea<mode>_general_4"
6274 [(set (match_operand:SWI12 0 "register_operand" "=r")
6277 (match_operand:SWI12 1 "index_register_operand" "l")
6278 (match_operand 2 "const_0_to_3_operand" "n"))
6279 (match_operand 3 "const_int_operand" "n")))]
6280 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6281 && ((unsigned HOST_WIDE_INT) INTVAL (operands[3])
6282 < (HOST_WIDE_INT_1U << INTVAL (operands[2])))"
6284 "&& reload_completed"
6287 (mult:SI (match_dup 1) (match_dup 2))
6290 operands[0] = gen_lowpart (SImode, operands[0]);
6291 operands[1] = gen_lowpart (SImode, operands[1]);
6292 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
6294 [(set_attr "type" "lea")
6295 (set_attr "mode" "SI")])
6297 (define_insn_and_split "*lea<mode>_general_4"
6298 [(set (match_operand:SWI48 0 "register_operand" "=r")
6301 (match_operand:SWI48 1 "index_register_operand" "l")
6302 (match_operand 2 "const_0_to_3_operand" "n"))
6303 (match_operand 3 "const_int_operand" "n")))]
6304 "(unsigned HOST_WIDE_INT) INTVAL (operands[3])
6305 < (HOST_WIDE_INT_1U << INTVAL (operands[2]))"
6307 "&& reload_completed"
6310 (mult:SWI48 (match_dup 1) (match_dup 2))
6312 "operands[2] = GEN_INT (1 << INTVAL (operands[2]));"
6313 [(set_attr "type" "lea")
6314 (set_attr "mode" "<MODE>")])
6316 ;; Subtract instructions
6318 (define_expand "sub<mode>3"
6319 [(set (match_operand:SDWIM 0 "nonimmediate_operand")
6320 (minus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")
6321 (match_operand:SDWIM 2 "<general_hilo_operand>")))]
6323 "ix86_expand_binary_operator (MINUS, <MODE>mode, operands); DONE;")
6325 (define_insn_and_split "*sub<dwi>3_doubleword"
6326 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
6328 (match_operand:<DWI> 1 "nonimmediate_operand" "0,0")
6329 (match_operand:<DWI> 2 "x86_64_hilo_general_operand"
6331 (clobber (reg:CC FLAGS_REG))]
6332 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6335 [(parallel [(set (reg:CC FLAGS_REG)
6336 (compare:CC (match_dup 1) (match_dup 2)))
6338 (minus:DWIH (match_dup 1) (match_dup 2)))])
6339 (parallel [(set (match_dup 3)
6343 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0)))
6345 (clobber (reg:CC FLAGS_REG))])]
6347 split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
6348 if (operands[2] == const0_rtx)
6350 ix86_expand_binary_operator (MINUS, <MODE>mode, &operands[3]);
6355 (define_insn "*sub<mode>_1"
6356 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6358 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6359 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6360 (clobber (reg:CC FLAGS_REG))]
6361 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6362 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6363 [(set_attr "type" "alu")
6364 (set_attr "mode" "<MODE>")])
6366 (define_insn "*subsi_1_zext"
6367 [(set (match_operand:DI 0 "register_operand" "=r")
6369 (minus:SI (match_operand:SI 1 "register_operand" "0")
6370 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
6371 (clobber (reg:CC FLAGS_REG))]
6372 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6373 "sub{l}\t{%2, %k0|%k0, %2}"
6374 [(set_attr "type" "alu")
6375 (set_attr "mode" "SI")])
6377 (define_insn "*subqi_1_slp"
6378 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6379 (minus:QI (match_dup 0)
6380 (match_operand:QI 1 "general_operand" "qn,qm")))
6381 (clobber (reg:CC FLAGS_REG))]
6382 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6383 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
6384 "sub{b}\t{%1, %0|%0, %1}"
6385 [(set_attr "type" "alu1")
6386 (set_attr "mode" "QI")])
6388 (define_insn "*sub<mode>_2"
6389 [(set (reg FLAGS_REG)
6392 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6393 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6395 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6396 (minus:SWI (match_dup 1) (match_dup 2)))]
6397 "ix86_match_ccmode (insn, CCGOCmode)
6398 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6399 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6400 [(set_attr "type" "alu")
6401 (set_attr "mode" "<MODE>")])
6403 (define_insn "*subsi_2_zext"
6404 [(set (reg FLAGS_REG)
6406 (minus:SI (match_operand:SI 1 "register_operand" "0")
6407 (match_operand:SI 2 "x86_64_general_operand" "rme"))
6409 (set (match_operand:DI 0 "register_operand" "=r")
6411 (minus:SI (match_dup 1)
6413 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6414 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6415 "sub{l}\t{%2, %k0|%k0, %2}"
6416 [(set_attr "type" "alu")
6417 (set_attr "mode" "SI")])
6419 ;; Subtract with jump on overflow.
6420 (define_expand "subv<mode>4"
6421 [(parallel [(set (reg:CCO FLAGS_REG)
6422 (eq:CCO (minus:<DWI>
6424 (match_operand:SWI 1 "nonimmediate_operand"))
6427 (minus:SWI (match_dup 1)
6428 (match_operand:SWI 2
6429 "<general_operand>")))))
6430 (set (match_operand:SWI 0 "register_operand")
6431 (minus:SWI (match_dup 1) (match_dup 2)))])
6432 (set (pc) (if_then_else
6433 (eq (reg:CCO FLAGS_REG) (const_int 0))
6434 (label_ref (match_operand 3))
6438 ix86_fixup_binary_operands_no_copy (MINUS, <MODE>mode, operands);
6439 if (CONST_INT_P (operands[2]))
6440 operands[4] = operands[2];
6442 operands[4] = gen_rtx_SIGN_EXTEND (<DWI>mode, operands[2]);
6445 (define_insn "*subv<mode>4"
6446 [(set (reg:CCO FLAGS_REG)
6447 (eq:CCO (minus:<DWI>
6449 (match_operand:SWI 1 "nonimmediate_operand" "0,0"))
6451 (match_operand:SWI 2 "<general_sext_operand>"
6454 (minus:SWI (match_dup 1) (match_dup 2)))))
6455 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6456 (minus:SWI (match_dup 1) (match_dup 2)))]
6457 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6458 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6459 [(set_attr "type" "alu")
6460 (set_attr "mode" "<MODE>")])
6462 (define_insn "*subv<mode>4_1"
6463 [(set (reg:CCO FLAGS_REG)
6464 (eq:CCO (minus:<DWI>
6466 (match_operand:SWI 1 "nonimmediate_operand" "0"))
6467 (match_operand:<DWI> 3 "const_int_operand" "i"))
6469 (minus:SWI (match_dup 1)
6470 (match_operand:SWI 2 "x86_64_immediate_operand"
6472 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
6473 (minus:SWI (match_dup 1) (match_dup 2)))]
6474 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)
6475 && CONST_INT_P (operands[2])
6476 && INTVAL (operands[2]) == INTVAL (operands[3])"
6477 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6478 [(set_attr "type" "alu")
6479 (set_attr "mode" "<MODE>")
6480 (set (attr "length_immediate")
6481 (cond [(match_test "IN_RANGE (INTVAL (operands[2]), -128, 127)")
6483 (match_test "<MODE_SIZE> == 8")
6485 (const_string "<MODE_SIZE>")))])
6487 (define_expand "usubv<mode>4"
6488 [(parallel [(set (reg:CC FLAGS_REG)
6490 (match_operand:SWI 1 "nonimmediate_operand")
6491 (match_operand:SWI 2 "<general_operand>")))
6492 (set (match_operand:SWI 0 "register_operand")
6493 (minus:SWI (match_dup 1) (match_dup 2)))])
6494 (set (pc) (if_then_else
6495 (ltu (reg:CC FLAGS_REG) (const_int 0))
6496 (label_ref (match_operand 3))
6499 "ix86_fixup_binary_operands_no_copy (MINUS, <MODE>mode, operands);")
6501 (define_insn "*sub<mode>_3"
6502 [(set (reg FLAGS_REG)
6503 (compare (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6504 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6505 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6506 (minus:SWI (match_dup 1) (match_dup 2)))]
6507 "ix86_match_ccmode (insn, CCmode)
6508 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6509 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6510 [(set_attr "type" "alu")
6511 (set_attr "mode" "<MODE>")])
6515 [(set (reg:CC FLAGS_REG)
6516 (compare:CC (match_operand:SWI 0 "general_reg_operand")
6517 (match_operand:SWI 1 "general_gr_operand")))
6519 (minus:SWI (match_dup 0) (match_dup 1)))])]
6520 "find_regno_note (peep2_next_insn (0), REG_UNUSED, REGNO (operands[0])) != 0"
6521 [(set (reg:CC FLAGS_REG)
6522 (compare:CC (match_dup 0) (match_dup 1)))])
6524 (define_insn "*subsi_3_zext"
6525 [(set (reg FLAGS_REG)
6526 (compare (match_operand:SI 1 "register_operand" "0")
6527 (match_operand:SI 2 "x86_64_general_operand" "rme")))
6528 (set (match_operand:DI 0 "register_operand" "=r")
6530 (minus:SI (match_dup 1)
6532 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6533 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6534 "sub{l}\t{%2, %1|%1, %2}"
6535 [(set_attr "type" "alu")
6536 (set_attr "mode" "SI")])
6538 ;; Add with carry and subtract with borrow
6540 (define_insn "add<mode>3_carry"
6541 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6544 (match_operator:SWI 4 "ix86_carry_flag_operator"
6545 [(match_operand 3 "flags_reg_operand") (const_int 0)])
6546 (match_operand:SWI 1 "nonimmediate_operand" "%0,0"))
6547 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6548 (clobber (reg:CC FLAGS_REG))]
6549 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6550 "adc{<imodesuffix>}\t{%2, %0|%0, %2}"
6551 [(set_attr "type" "alu")
6552 (set_attr "use_carry" "1")
6553 (set_attr "pent_pair" "pu")
6554 (set_attr "mode" "<MODE>")])
6556 (define_insn "*add<mode>3_carry_0"
6557 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
6559 (match_operator:SWI 3 "ix86_carry_flag_operator"
6560 [(match_operand 2 "flags_reg_operand") (const_int 0)])
6561 (match_operand:SWI 1 "nonimmediate_operand" "0")))
6562 (clobber (reg:CC FLAGS_REG))]
6563 "ix86_unary_operator_ok (PLUS, <MODE>mode, operands)"
6564 "adc{<imodesuffix>}\t{$0, %0|%0, 0}"
6565 [(set_attr "type" "alu")
6566 (set_attr "use_carry" "1")
6567 (set_attr "pent_pair" "pu")
6568 (set_attr "mode" "<MODE>")])
6570 (define_insn "*addsi3_carry_zext"
6571 [(set (match_operand:DI 0 "register_operand" "=r")
6574 (plus:SI (match_operator:SI 3 "ix86_carry_flag_operator"
6575 [(reg FLAGS_REG) (const_int 0)])
6576 (match_operand:SI 1 "register_operand" "%0"))
6577 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
6578 (clobber (reg:CC FLAGS_REG))]
6579 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6580 "adc{l}\t{%2, %k0|%k0, %2}"
6581 [(set_attr "type" "alu")
6582 (set_attr "use_carry" "1")
6583 (set_attr "pent_pair" "pu")
6584 (set_attr "mode" "SI")])
6586 (define_insn "*addsi3_carry_zext_0"
6587 [(set (match_operand:DI 0 "register_operand" "=r")
6589 (plus:SI (match_operator:SI 2 "ix86_carry_flag_operator"
6590 [(reg FLAGS_REG) (const_int 0)])
6591 (match_operand:SI 1 "register_operand" "0"))))
6592 (clobber (reg:CC FLAGS_REG))]
6594 "adc{l}\t{$0, %k0|%k0, 0}"
6595 [(set_attr "type" "alu")
6596 (set_attr "use_carry" "1")
6597 (set_attr "pent_pair" "pu")
6598 (set_attr "mode" "SI")])
6600 ;; There is no point to generate ADCX instruction. ADC is shorter and faster.
6602 (define_insn "addcarry<mode>"
6603 [(set (reg:CCC FLAGS_REG)
6608 (match_operator:SWI48 5 "ix86_carry_flag_operator"
6609 [(match_operand 3 "flags_reg_operand") (const_int 0)])
6610 (match_operand:SWI48 1 "nonimmediate_operand" "%0"))
6611 (match_operand:SWI48 2 "nonimmediate_operand" "rm")))
6613 (zero_extend:<DWI> (match_dup 2))
6614 (match_operator:<DWI> 4 "ix86_carry_flag_operator"
6615 [(match_dup 3) (const_int 0)]))))
6616 (set (match_operand:SWI48 0 "register_operand" "=r")
6617 (plus:SWI48 (plus:SWI48 (match_op_dup 5
6618 [(match_dup 3) (const_int 0)])
6621 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6622 "adc{<imodesuffix>}\t{%2, %0|%0, %2}"
6623 [(set_attr "type" "alu")
6624 (set_attr "use_carry" "1")
6625 (set_attr "pent_pair" "pu")
6626 (set_attr "mode" "<MODE>")])
6628 (define_expand "addcarry<mode>_0"
6630 [(set (reg:CCC FLAGS_REG)
6633 (match_operand:SWI48 1 "nonimmediate_operand")
6634 (match_operand:SWI48 2 "x86_64_general_operand"))
6636 (set (match_operand:SWI48 0 "register_operand")
6637 (plus:SWI48 (match_dup 1) (match_dup 2)))])]
6638 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)")
6640 (define_insn "@sub<mode>3_carry"
6641 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6644 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6645 (match_operator:SWI 4 "ix86_carry_flag_operator"
6646 [(match_operand 3 "flags_reg_operand") (const_int 0)]))
6647 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6648 (clobber (reg:CC FLAGS_REG))]
6649 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6650 "sbb{<imodesuffix>}\t{%2, %0|%0, %2}"
6651 [(set_attr "type" "alu")
6652 (set_attr "use_carry" "1")
6653 (set_attr "pent_pair" "pu")
6654 (set_attr "mode" "<MODE>")])
6656 (define_insn "*sub<mode>3_carry_0"
6657 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
6659 (match_operand:SWI 1 "nonimmediate_operand" "0")
6660 (match_operator:SWI 3 "ix86_carry_flag_operator"
6661 [(match_operand 2 "flags_reg_operand") (const_int 0)])))
6662 (clobber (reg:CC FLAGS_REG))]
6663 "ix86_unary_operator_ok (MINUS, <MODE>mode, operands)"
6664 "sbb{<imodesuffix>}\t{$0, %0|%0, 0}"
6665 [(set_attr "type" "alu")
6666 (set_attr "use_carry" "1")
6667 (set_attr "pent_pair" "pu")
6668 (set_attr "mode" "<MODE>")])
6670 (define_insn "*subsi3_carry_zext"
6671 [(set (match_operand:DI 0 "register_operand" "=r")
6675 (match_operand:SI 1 "register_operand" "0")
6676 (match_operator:SI 3 "ix86_carry_flag_operator"
6677 [(reg FLAGS_REG) (const_int 0)]))
6678 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
6679 (clobber (reg:CC FLAGS_REG))]
6680 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6681 "sbb{l}\t{%2, %k0|%k0, %2}"
6682 [(set_attr "type" "alu")
6683 (set_attr "use_carry" "1")
6684 (set_attr "pent_pair" "pu")
6685 (set_attr "mode" "SI")])
6687 (define_insn "*subsi3_carry_zext_0"
6688 [(set (match_operand:DI 0 "register_operand" "=r")
6691 (match_operand:SI 1 "register_operand" "0")
6692 (match_operator:SI 2 "ix86_carry_flag_operator"
6693 [(reg FLAGS_REG) (const_int 0)]))))
6694 (clobber (reg:CC FLAGS_REG))]
6696 "sbb{l}\t{$0, %k0|%k0, 0}"
6697 [(set_attr "type" "alu")
6698 (set_attr "use_carry" "1")
6699 (set_attr "pent_pair" "pu")
6700 (set_attr "mode" "SI")])
6702 (define_insn "sub<mode>3_carry_ccc"
6703 [(set (reg:CCC FLAGS_REG)
6705 (zero_extend:<DWI> (match_operand:DWIH 1 "register_operand" "0"))
6707 (ltu:<DWI> (reg:CC FLAGS_REG) (const_int 0))
6709 (match_operand:DWIH 2 "x86_64_sext_operand" "rmWe")))))
6710 (clobber (match_scratch:DWIH 0 "=r"))]
6712 "sbb{<imodesuffix>}\t{%2, %0|%0, %2}"
6713 [(set_attr "type" "alu")
6714 (set_attr "mode" "<MODE>")])
6716 (define_insn "*sub<mode>3_carry_ccc_1"
6717 [(set (reg:CCC FLAGS_REG)
6719 (zero_extend:<DWI> (match_operand:DWIH 1 "register_operand" "0"))
6721 (ltu:<DWI> (reg:CC FLAGS_REG) (const_int 0))
6722 (match_operand:<DWI> 2 "x86_64_dwzext_immediate_operand" "Wf"))))
6723 (clobber (match_scratch:DWIH 0 "=r"))]
6726 operands[3] = simplify_subreg (<MODE>mode, operands[2], <DWI>mode, 0);
6727 return "sbb{<imodesuffix>}\t{%3, %0|%0, %3}";
6729 [(set_attr "type" "alu")
6730 (set_attr "mode" "<MODE>")])
6732 ;; The sign flag is set from the
6733 ;; (compare (match_dup 1) (plus:DWIH (ltu:DWIH ...) (match_dup 2)))
6734 ;; result, the overflow flag likewise, but the overflow flag is also
6735 ;; set if the (plus:DWIH (ltu:DWIH ...) (match_dup 2)) overflows.
6736 (define_insn "sub<mode>3_carry_ccgz"
6737 [(set (reg:CCGZ FLAGS_REG)
6738 (unspec:CCGZ [(match_operand:DWIH 1 "register_operand" "0")
6739 (match_operand:DWIH 2 "x86_64_general_operand" "rme")
6740 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))]
6742 (clobber (match_scratch:DWIH 0 "=r"))]
6744 "sbb{<imodesuffix>}\t{%2, %0|%0, %2}"
6745 [(set_attr "type" "alu")
6746 (set_attr "mode" "<MODE>")])
6748 (define_insn "subborrow<mode>"
6749 [(set (reg:CCC FLAGS_REG)
6752 (match_operand:SWI48 1 "nonimmediate_operand" "0"))
6754 (match_operator:<DWI> 4 "ix86_carry_flag_operator"
6755 [(match_operand 3 "flags_reg_operand") (const_int 0)])
6757 (match_operand:SWI48 2 "nonimmediate_operand" "rm")))))
6758 (set (match_operand:SWI48 0 "register_operand" "=r")
6759 (minus:SWI48 (minus:SWI48
6761 (match_operator:SWI48 5 "ix86_carry_flag_operator"
6762 [(match_dup 3) (const_int 0)]))
6764 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6765 "sbb{<imodesuffix>}\t{%2, %0|%0, %2}"
6766 [(set_attr "type" "alu")
6767 (set_attr "use_carry" "1")
6768 (set_attr "pent_pair" "pu")
6769 (set_attr "mode" "<MODE>")])
6771 (define_expand "subborrow<mode>_0"
6773 [(set (reg:CC FLAGS_REG)
6775 (match_operand:SWI48 1 "nonimmediate_operand")
6776 (match_operand:SWI48 2 "<general_operand>")))
6777 (set (match_operand:SWI48 0 "register_operand")
6778 (minus:SWI48 (match_dup 1) (match_dup 2)))])]
6779 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)")
6781 ;; Overflow setting add instructions
6783 (define_expand "addqi3_cconly_overflow"
6785 [(set (reg:CCC FLAGS_REG)
6788 (match_operand:QI 0 "nonimmediate_operand")
6789 (match_operand:QI 1 "general_operand"))
6791 (clobber (match_scratch:QI 2))])]
6792 "!(MEM_P (operands[0]) && MEM_P (operands[1]))")
6794 (define_insn "*add<mode>3_cconly_overflow_1"
6795 [(set (reg:CCC FLAGS_REG)
6798 (match_operand:SWI 1 "nonimmediate_operand" "%0")
6799 (match_operand:SWI 2 "<general_operand>" "<g>"))
6801 (clobber (match_scratch:SWI 0 "=<r>"))]
6802 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6803 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6804 [(set_attr "type" "alu")
6805 (set_attr "mode" "<MODE>")])
6807 (define_insn "*add<mode>3_cc_overflow_1"
6808 [(set (reg:CCC FLAGS_REG)
6811 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
6812 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6814 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6815 (plus:SWI (match_dup 1) (match_dup 2)))]
6816 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6817 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6818 [(set_attr "type" "alu")
6819 (set_attr "mode" "<MODE>")])
6821 (define_insn "*addsi3_zext_cc_overflow_1"
6822 [(set (reg:CCC FLAGS_REG)
6825 (match_operand:SI 1 "nonimmediate_operand" "%0")
6826 (match_operand:SI 2 "x86_64_general_operand" "rme"))
6828 (set (match_operand:DI 0 "register_operand" "=r")
6829 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6830 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6831 "add{l}\t{%2, %k0|%k0, %2}"
6832 [(set_attr "type" "alu")
6833 (set_attr "mode" "SI")])
6835 (define_insn "*add<mode>3_cconly_overflow_2"
6836 [(set (reg:CCC FLAGS_REG)
6839 (match_operand:SWI 1 "nonimmediate_operand" "%0")
6840 (match_operand:SWI 2 "<general_operand>" "<g>"))
6842 (clobber (match_scratch:SWI 0 "=<r>"))]
6843 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6844 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6845 [(set_attr "type" "alu")
6846 (set_attr "mode" "<MODE>")])
6848 (define_insn "*add<mode>3_cc_overflow_2"
6849 [(set (reg:CCC FLAGS_REG)
6852 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
6853 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6855 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6856 (plus:SWI (match_dup 1) (match_dup 2)))]
6857 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6858 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6859 [(set_attr "type" "alu")
6860 (set_attr "mode" "<MODE>")])
6862 (define_insn "*addsi3_zext_cc_overflow_2"
6863 [(set (reg:CCC FLAGS_REG)
6866 (match_operand:SI 1 "nonimmediate_operand" "%0")
6867 (match_operand:SI 2 "x86_64_general_operand" "rme"))
6869 (set (match_operand:DI 0 "register_operand" "=r")
6870 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6871 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6872 "add{l}\t{%2, %k0|%k0, %2}"
6873 [(set_attr "type" "alu")
6874 (set_attr "mode" "SI")])
6876 ;; The patterns that match these are at the end of this file.
6878 (define_expand "<plusminus_insn>xf3"
6879 [(set (match_operand:XF 0 "register_operand")
6881 (match_operand:XF 1 "register_operand")
6882 (match_operand:XF 2 "register_operand")))]
6885 (define_expand "<plusminus_insn><mode>3"
6886 [(set (match_operand:MODEF 0 "register_operand")
6888 (match_operand:MODEF 1 "register_operand")
6889 (match_operand:MODEF 2 "nonimmediate_operand")))]
6890 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
6891 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
6893 ;; Multiply instructions
6895 (define_expand "mul<mode>3"
6896 [(parallel [(set (match_operand:SWIM248 0 "register_operand")
6898 (match_operand:SWIM248 1 "register_operand")
6899 (match_operand:SWIM248 2 "<general_operand>")))
6900 (clobber (reg:CC FLAGS_REG))])])
6902 (define_expand "mulqi3"
6903 [(parallel [(set (match_operand:QI 0 "register_operand")
6905 (match_operand:QI 1 "register_operand")
6906 (match_operand:QI 2 "nonimmediate_operand")))
6907 (clobber (reg:CC FLAGS_REG))])]
6908 "TARGET_QIMODE_MATH")
6911 ;; IMUL reg32/64, reg32/64, imm8 Direct
6912 ;; IMUL reg32/64, mem32/64, imm8 VectorPath
6913 ;; IMUL reg32/64, reg32/64, imm32 Direct
6914 ;; IMUL reg32/64, mem32/64, imm32 VectorPath
6915 ;; IMUL reg32/64, reg32/64 Direct
6916 ;; IMUL reg32/64, mem32/64 Direct
6918 ;; On BDVER1, all above IMULs use DirectPath
6921 ;; IMUL reg16, reg16, imm8 VectorPath
6922 ;; IMUL reg16, mem16, imm8 VectorPath
6923 ;; IMUL reg16, reg16, imm16 VectorPath
6924 ;; IMUL reg16, mem16, imm16 VectorPath
6925 ;; IMUL reg16, reg16 Direct
6926 ;; IMUL reg16, mem16 Direct
6928 ;; On BDVER1, all HI MULs use DoublePath
6930 (define_insn "*mul<mode>3_1"
6931 [(set (match_operand:SWIM248 0 "register_operand" "=r,r,r")
6933 (match_operand:SWIM248 1 "nonimmediate_operand" "%rm,rm,0")
6934 (match_operand:SWIM248 2 "<general_operand>" "K,<i>,mr")))
6935 (clobber (reg:CC FLAGS_REG))]
6936 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6938 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6939 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6940 imul{<imodesuffix>}\t{%2, %0|%0, %2}"
6941 [(set_attr "type" "imul")
6942 (set_attr "prefix_0f" "0,0,1")
6943 (set (attr "athlon_decode")
6944 (cond [(eq_attr "cpu" "athlon")
6945 (const_string "vector")
6946 (eq_attr "alternative" "1")
6947 (const_string "vector")
6948 (and (eq_attr "alternative" "2")
6949 (ior (match_test "<MODE>mode == HImode")
6950 (match_operand 1 "memory_operand")))
6951 (const_string "vector")]
6952 (const_string "direct")))
6953 (set (attr "amdfam10_decode")
6954 (cond [(and (eq_attr "alternative" "0,1")
6955 (ior (match_test "<MODE>mode == HImode")
6956 (match_operand 1 "memory_operand")))
6957 (const_string "vector")]
6958 (const_string "direct")))
6959 (set (attr "bdver1_decode")
6961 (match_test "<MODE>mode == HImode")
6962 (const_string "double")
6963 (const_string "direct")))
6964 (set_attr "mode" "<MODE>")])
6966 (define_insn "*mulsi3_1_zext"
6967 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6969 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6970 (match_operand:SI 2 "x86_64_general_operand" "K,e,mr"))))
6971 (clobber (reg:CC FLAGS_REG))]
6973 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6975 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6976 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6977 imul{l}\t{%2, %k0|%k0, %2}"
6978 [(set_attr "type" "imul")
6979 (set_attr "prefix_0f" "0,0,1")
6980 (set (attr "athlon_decode")
6981 (cond [(eq_attr "cpu" "athlon")
6982 (const_string "vector")
6983 (eq_attr "alternative" "1")
6984 (const_string "vector")
6985 (and (eq_attr "alternative" "2")
6986 (match_operand 1 "memory_operand"))
6987 (const_string "vector")]
6988 (const_string "direct")))
6989 (set (attr "amdfam10_decode")
6990 (cond [(and (eq_attr "alternative" "0,1")
6991 (match_operand 1 "memory_operand"))
6992 (const_string "vector")]
6993 (const_string "direct")))
6994 (set_attr "bdver1_decode" "direct")
6995 (set_attr "mode" "SI")])
6997 ;;On AMDFAM10 and BDVER1
7001 (define_insn "*mulqi3_1"
7002 [(set (match_operand:QI 0 "register_operand" "=a")
7003 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
7004 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7005 (clobber (reg:CC FLAGS_REG))]
7007 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7009 [(set_attr "type" "imul")
7010 (set_attr "length_immediate" "0")
7011 (set (attr "athlon_decode")
7012 (if_then_else (eq_attr "cpu" "athlon")
7013 (const_string "vector")
7014 (const_string "direct")))
7015 (set_attr "amdfam10_decode" "direct")
7016 (set_attr "bdver1_decode" "direct")
7017 (set_attr "mode" "QI")])
7019 ;; Multiply with jump on overflow.
7020 (define_expand "mulv<mode>4"
7021 [(parallel [(set (reg:CCO FLAGS_REG)
7024 (match_operand:SWI248 1 "register_operand"))
7027 (mult:SWI248 (match_dup 1)
7028 (match_operand:SWI248 2
7029 "<general_operand>")))))
7030 (set (match_operand:SWI248 0 "register_operand")
7031 (mult:SWI248 (match_dup 1) (match_dup 2)))])
7032 (set (pc) (if_then_else
7033 (eq (reg:CCO FLAGS_REG) (const_int 0))
7034 (label_ref (match_operand 3))
7038 if (CONST_INT_P (operands[2]))
7039 operands[4] = operands[2];
7041 operands[4] = gen_rtx_SIGN_EXTEND (<DWI>mode, operands[2]);
7044 (define_insn "*mulv<mode>4"
7045 [(set (reg:CCO FLAGS_REG)
7048 (match_operand:SWI48 1 "nonimmediate_operand" "%rm,0"))
7050 (match_operand:SWI48 2 "x86_64_sext_operand" "We,mr")))
7052 (mult:SWI48 (match_dup 1) (match_dup 2)))))
7053 (set (match_operand:SWI48 0 "register_operand" "=r,r")
7054 (mult:SWI48 (match_dup 1) (match_dup 2)))]
7055 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7057 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
7058 imul{<imodesuffix>}\t{%2, %0|%0, %2}"
7059 [(set_attr "type" "imul")
7060 (set_attr "prefix_0f" "0,1")
7061 (set (attr "athlon_decode")
7062 (cond [(eq_attr "cpu" "athlon")
7063 (const_string "vector")
7064 (eq_attr "alternative" "0")
7065 (const_string "vector")
7066 (and (eq_attr "alternative" "1")
7067 (match_operand 1 "memory_operand"))
7068 (const_string "vector")]
7069 (const_string "direct")))
7070 (set (attr "amdfam10_decode")
7071 (cond [(and (eq_attr "alternative" "1")
7072 (match_operand 1 "memory_operand"))
7073 (const_string "vector")]
7074 (const_string "direct")))
7075 (set_attr "bdver1_decode" "direct")
7076 (set_attr "mode" "<MODE>")])
7078 (define_insn "*mulvhi4"
7079 [(set (reg:CCO FLAGS_REG)
7082 (match_operand:HI 1 "nonimmediate_operand" "%0"))
7084 (match_operand:HI 2 "nonimmediate_operand" "mr")))
7086 (mult:HI (match_dup 1) (match_dup 2)))))
7087 (set (match_operand:HI 0 "register_operand" "=r")
7088 (mult:HI (match_dup 1) (match_dup 2)))]
7089 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7090 "imul{w}\t{%2, %0|%0, %2}"
7091 [(set_attr "type" "imul")
7092 (set_attr "prefix_0f" "1")
7093 (set_attr "athlon_decode" "vector")
7094 (set_attr "amdfam10_decode" "direct")
7095 (set_attr "bdver1_decode" "double")
7096 (set_attr "mode" "HI")])
7098 (define_insn "*mulv<mode>4_1"
7099 [(set (reg:CCO FLAGS_REG)
7102 (match_operand:SWI248 1 "nonimmediate_operand" "rm,rm"))
7103 (match_operand:<DWI> 3 "const_int_operand" "K,i"))
7105 (mult:SWI248 (match_dup 1)
7106 (match_operand:SWI248 2
7107 "<immediate_operand>" "K,<i>")))))
7108 (set (match_operand:SWI248 0 "register_operand" "=r,r")
7109 (mult:SWI248 (match_dup 1) (match_dup 2)))]
7110 "!(MEM_P (operands[1]) && MEM_P (operands[2]))
7111 && CONST_INT_P (operands[2])
7112 && INTVAL (operands[2]) == INTVAL (operands[3])"
7113 "imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}"
7114 [(set_attr "type" "imul")
7115 (set (attr "prefix_0f")
7117 (match_test "<MODE>mode == HImode")
7119 (const_string "*")))
7120 (set (attr "athlon_decode")
7121 (cond [(eq_attr "cpu" "athlon")
7122 (const_string "vector")
7123 (eq_attr "alternative" "1")
7124 (const_string "vector")]
7125 (const_string "direct")))
7126 (set (attr "amdfam10_decode")
7127 (cond [(ior (match_test "<MODE>mode == HImode")
7128 (match_operand 1 "memory_operand"))
7129 (const_string "vector")]
7130 (const_string "direct")))
7131 (set (attr "bdver1_decode")
7133 (match_test "<MODE>mode == HImode")
7134 (const_string "double")
7135 (const_string "direct")))
7136 (set_attr "mode" "<MODE>")
7137 (set (attr "length_immediate")
7138 (cond [(eq_attr "alternative" "0")
7140 (match_test "<MODE_SIZE> == 8")
7142 (const_string "<MODE_SIZE>")))])
7144 (define_expand "umulv<mode>4"
7145 [(parallel [(set (reg:CCO FLAGS_REG)
7148 (match_operand:SWI248 1
7149 "nonimmediate_operand"))
7151 (match_operand:SWI248 2
7152 "nonimmediate_operand")))
7154 (mult:SWI248 (match_dup 1) (match_dup 2)))))
7155 (set (match_operand:SWI248 0 "register_operand")
7156 (mult:SWI248 (match_dup 1) (match_dup 2)))
7157 (clobber (match_scratch:SWI248 4))])
7158 (set (pc) (if_then_else
7159 (eq (reg:CCO FLAGS_REG) (const_int 0))
7160 (label_ref (match_operand 3))
7164 if (MEM_P (operands[1]) && MEM_P (operands[2]))
7165 operands[1] = force_reg (<MODE>mode, operands[1]);
7168 (define_insn "*umulv<mode>4"
7169 [(set (reg:CCO FLAGS_REG)
7172 (match_operand:SWI248 1 "nonimmediate_operand" "%0"))
7174 (match_operand:SWI248 2 "nonimmediate_operand" "rm")))
7176 (mult:SWI248 (match_dup 1) (match_dup 2)))))
7177 (set (match_operand:SWI248 0 "register_operand" "=a")
7178 (mult:SWI248 (match_dup 1) (match_dup 2)))
7179 (clobber (match_scratch:SWI248 3 "=d"))]
7180 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7181 "mul{<imodesuffix>}\t%2"
7182 [(set_attr "type" "imul")
7183 (set_attr "length_immediate" "0")
7184 (set (attr "athlon_decode")
7185 (if_then_else (eq_attr "cpu" "athlon")
7186 (const_string "vector")
7187 (const_string "double")))
7188 (set_attr "amdfam10_decode" "double")
7189 (set_attr "bdver1_decode" "direct")
7190 (set_attr "mode" "<MODE>")])
7192 (define_expand "<u>mulvqi4"
7193 [(parallel [(set (reg:CCO FLAGS_REG)
7196 (match_operand:QI 1 "nonimmediate_operand"))
7198 (match_operand:QI 2 "nonimmediate_operand")))
7200 (mult:QI (match_dup 1) (match_dup 2)))))
7201 (set (match_operand:QI 0 "register_operand")
7202 (mult:QI (match_dup 1) (match_dup 2)))])
7203 (set (pc) (if_then_else
7204 (eq (reg:CCO FLAGS_REG) (const_int 0))
7205 (label_ref (match_operand 3))
7207 "TARGET_QIMODE_MATH"
7209 if (MEM_P (operands[1]) && MEM_P (operands[2]))
7210 operands[1] = force_reg (QImode, operands[1]);
7213 (define_insn "*<u>mulvqi4"
7214 [(set (reg:CCO FLAGS_REG)
7217 (match_operand:QI 1 "nonimmediate_operand" "%0"))
7219 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7221 (mult:QI (match_dup 1) (match_dup 2)))))
7222 (set (match_operand:QI 0 "register_operand" "=a")
7223 (mult:QI (match_dup 1) (match_dup 2)))]
7225 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7226 "<sgnprefix>mul{b}\t%2"
7227 [(set_attr "type" "imul")
7228 (set_attr "length_immediate" "0")
7229 (set (attr "athlon_decode")
7230 (if_then_else (eq_attr "cpu" "athlon")
7231 (const_string "vector")
7232 (const_string "direct")))
7233 (set_attr "amdfam10_decode" "direct")
7234 (set_attr "bdver1_decode" "direct")
7235 (set_attr "mode" "QI")])
7237 (define_expand "<u>mul<mode><dwi>3"
7238 [(parallel [(set (match_operand:<DWI> 0 "register_operand")
7241 (match_operand:DWIH 1 "nonimmediate_operand"))
7243 (match_operand:DWIH 2 "register_operand"))))
7244 (clobber (reg:CC FLAGS_REG))])])
7246 (define_expand "<u>mulqihi3"
7247 [(parallel [(set (match_operand:HI 0 "register_operand")
7250 (match_operand:QI 1 "nonimmediate_operand"))
7252 (match_operand:QI 2 "register_operand"))))
7253 (clobber (reg:CC FLAGS_REG))])]
7254 "TARGET_QIMODE_MATH")
7256 (define_insn "*bmi2_umul<mode><dwi>3_1"
7257 [(set (match_operand:DWIH 0 "register_operand" "=r")
7259 (match_operand:DWIH 2 "nonimmediate_operand" "%d")
7260 (match_operand:DWIH 3 "nonimmediate_operand" "rm")))
7261 (set (match_operand:DWIH 1 "register_operand" "=r")
7264 (mult:<DWI> (zero_extend:<DWI> (match_dup 2))
7265 (zero_extend:<DWI> (match_dup 3)))
7266 (match_operand:QI 4 "const_int_operand" "n"))))]
7267 "TARGET_BMI2 && INTVAL (operands[4]) == <MODE_SIZE> * BITS_PER_UNIT
7268 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7269 "mulx\t{%3, %0, %1|%1, %0, %3}"
7270 [(set_attr "type" "imulx")
7271 (set_attr "prefix" "vex")
7272 (set_attr "mode" "<MODE>")])
7274 (define_insn "*umul<mode><dwi>3_1"
7275 [(set (match_operand:<DWI> 0 "register_operand" "=r,A")
7278 (match_operand:DWIH 1 "nonimmediate_operand" "%d,0"))
7280 (match_operand:DWIH 2 "nonimmediate_operand" "rm,rm"))))
7281 (clobber (reg:CC FLAGS_REG))]
7282 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7285 mul{<imodesuffix>}\t%2"
7286 [(set_attr "isa" "bmi2,*")
7287 (set_attr "type" "imulx,imul")
7288 (set_attr "length_immediate" "*,0")
7289 (set (attr "athlon_decode")
7290 (cond [(eq_attr "alternative" "1")
7291 (if_then_else (eq_attr "cpu" "athlon")
7292 (const_string "vector")
7293 (const_string "double"))]
7294 (const_string "*")))
7295 (set_attr "amdfam10_decode" "*,double")
7296 (set_attr "bdver1_decode" "*,direct")
7297 (set_attr "prefix" "vex,orig")
7298 (set_attr "mode" "<MODE>")])
7300 ;; Convert mul to the mulx pattern to avoid flags dependency.
7302 [(set (match_operand:<DWI> 0 "register_operand")
7305 (match_operand:DWIH 1 "register_operand"))
7307 (match_operand:DWIH 2 "nonimmediate_operand"))))
7308 (clobber (reg:CC FLAGS_REG))]
7309 "TARGET_BMI2 && reload_completed
7310 && REGNO (operands[1]) == DX_REG"
7311 [(parallel [(set (match_dup 3)
7312 (mult:DWIH (match_dup 1) (match_dup 2)))
7316 (mult:<DWI> (zero_extend:<DWI> (match_dup 1))
7317 (zero_extend:<DWI> (match_dup 2)))
7320 split_double_mode (<DWI>mode, &operands[0], 1, &operands[3], &operands[4]);
7322 operands[5] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT);
7325 (define_insn "*mul<mode><dwi>3_1"
7326 [(set (match_operand:<DWI> 0 "register_operand" "=A")
7329 (match_operand:DWIH 1 "nonimmediate_operand" "%0"))
7331 (match_operand:DWIH 2 "nonimmediate_operand" "rm"))))
7332 (clobber (reg:CC FLAGS_REG))]
7333 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7334 "imul{<imodesuffix>}\t%2"
7335 [(set_attr "type" "imul")
7336 (set_attr "length_immediate" "0")
7337 (set (attr "athlon_decode")
7338 (if_then_else (eq_attr "cpu" "athlon")
7339 (const_string "vector")
7340 (const_string "double")))
7341 (set_attr "amdfam10_decode" "double")
7342 (set_attr "bdver1_decode" "direct")
7343 (set_attr "mode" "<MODE>")])
7345 (define_insn "*<u>mulqihi3_1"
7346 [(set (match_operand:HI 0 "register_operand" "=a")
7349 (match_operand:QI 1 "nonimmediate_operand" "%0"))
7351 (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7352 (clobber (reg:CC FLAGS_REG))]
7354 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7355 "<sgnprefix>mul{b}\t%2"
7356 [(set_attr "type" "imul")
7357 (set_attr "length_immediate" "0")
7358 (set (attr "athlon_decode")
7359 (if_then_else (eq_attr "cpu" "athlon")
7360 (const_string "vector")
7361 (const_string "direct")))
7362 (set_attr "amdfam10_decode" "direct")
7363 (set_attr "bdver1_decode" "direct")
7364 (set_attr "mode" "QI")])
7366 (define_expand "<s>mul<mode>3_highpart"
7367 [(parallel [(set (match_operand:DWIH 0 "register_operand")
7372 (match_operand:DWIH 1 "nonimmediate_operand"))
7374 (match_operand:DWIH 2 "register_operand")))
7376 (clobber (match_scratch:DWIH 4))
7377 (clobber (reg:CC FLAGS_REG))])]
7379 "operands[3] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
7381 (define_insn "*<s>muldi3_highpart_1"
7382 [(set (match_operand:DI 0 "register_operand" "=d")
7387 (match_operand:DI 1 "nonimmediate_operand" "%a"))
7389 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7391 (clobber (match_scratch:DI 3 "=1"))
7392 (clobber (reg:CC FLAGS_REG))]
7394 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7395 "<sgnprefix>mul{q}\t%2"
7396 [(set_attr "type" "imul")
7397 (set_attr "length_immediate" "0")
7398 (set (attr "athlon_decode")
7399 (if_then_else (eq_attr "cpu" "athlon")
7400 (const_string "vector")
7401 (const_string "double")))
7402 (set_attr "amdfam10_decode" "double")
7403 (set_attr "bdver1_decode" "direct")
7404 (set_attr "mode" "DI")])
7406 (define_insn "*<s>mulsi3_highpart_zext"
7407 [(set (match_operand:DI 0 "register_operand" "=d")
7408 (zero_extend:DI (truncate:SI
7410 (mult:DI (any_extend:DI
7411 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7413 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7415 (clobber (match_scratch:SI 3 "=1"))
7416 (clobber (reg:CC FLAGS_REG))]
7418 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7419 "<sgnprefix>mul{l}\t%2"
7420 [(set_attr "type" "imul")
7421 (set_attr "length_immediate" "0")
7422 (set (attr "athlon_decode")
7423 (if_then_else (eq_attr "cpu" "athlon")
7424 (const_string "vector")
7425 (const_string "double")))
7426 (set_attr "amdfam10_decode" "double")
7427 (set_attr "bdver1_decode" "direct")
7428 (set_attr "mode" "SI")])
7430 (define_insn "*<s>mulsi3_highpart_1"
7431 [(set (match_operand:SI 0 "register_operand" "=d")
7436 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7438 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7440 (clobber (match_scratch:SI 3 "=1"))
7441 (clobber (reg:CC FLAGS_REG))]
7442 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7443 "<sgnprefix>mul{l}\t%2"
7444 [(set_attr "type" "imul")
7445 (set_attr "length_immediate" "0")
7446 (set (attr "athlon_decode")
7447 (if_then_else (eq_attr "cpu" "athlon")
7448 (const_string "vector")
7449 (const_string "double")))
7450 (set_attr "amdfam10_decode" "double")
7451 (set_attr "bdver1_decode" "direct")
7452 (set_attr "mode" "SI")])
7454 ;; The patterns that match these are at the end of this file.
7456 (define_expand "mulxf3"
7457 [(set (match_operand:XF 0 "register_operand")
7458 (mult:XF (match_operand:XF 1 "register_operand")
7459 (match_operand:XF 2 "register_operand")))]
7462 (define_expand "mul<mode>3"
7463 [(set (match_operand:MODEF 0 "register_operand")
7464 (mult:MODEF (match_operand:MODEF 1 "register_operand")
7465 (match_operand:MODEF 2 "nonimmediate_operand")))]
7466 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
7467 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
7469 ;; Divide instructions
7471 ;; The patterns that match these are at the end of this file.
7473 (define_expand "divxf3"
7474 [(set (match_operand:XF 0 "register_operand")
7475 (div:XF (match_operand:XF 1 "register_operand")
7476 (match_operand:XF 2 "register_operand")))]
7479 (define_expand "div<mode>3"
7480 [(set (match_operand:MODEF 0 "register_operand")
7481 (div:MODEF (match_operand:MODEF 1 "register_operand")
7482 (match_operand:MODEF 2 "nonimmediate_operand")))]
7483 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
7484 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
7486 if (<MODE>mode == SFmode
7487 && TARGET_SSE && TARGET_SSE_MATH
7489 && optimize_insn_for_speed_p ()
7490 && flag_finite_math_only && !flag_trapping_math
7491 && flag_unsafe_math_optimizations)
7493 ix86_emit_swdivsf (operands[0], operands[1],
7494 operands[2], SFmode);
7499 ;; Divmod instructions.
7501 (define_code_iterator any_div [div udiv])
7502 (define_code_attr paired_mod [(div "mod") (udiv "umod")])
7504 (define_expand "<u>divmod<mode>4"
7505 [(parallel [(set (match_operand:SWIM248 0 "register_operand")
7507 (match_operand:SWIM248 1 "register_operand")
7508 (match_operand:SWIM248 2 "nonimmediate_operand")))
7509 (set (match_operand:SWIM248 3 "register_operand")
7510 (<paired_mod>:SWIM248 (match_dup 1) (match_dup 2)))
7511 (clobber (reg:CC FLAGS_REG))])])
7513 ;; Split with 8bit unsigned divide:
7514 ;; if (dividend an divisor are in [0-255])
7515 ;; use 8bit unsigned integer divide
7517 ;; use original integer divide
7519 [(set (match_operand:SWI48 0 "register_operand")
7520 (any_div:SWI48 (match_operand:SWI48 2 "register_operand")
7521 (match_operand:SWI48 3 "nonimmediate_operand")))
7522 (set (match_operand:SWI48 1 "register_operand")
7523 (<paired_mod>:SWI48 (match_dup 2) (match_dup 3)))
7524 (clobber (reg:CC FLAGS_REG))]
7525 "TARGET_USE_8BIT_IDIV
7526 && TARGET_QIMODE_MATH
7527 && can_create_pseudo_p ()
7528 && !optimize_insn_for_size_p ()"
7530 "ix86_split_idivmod (<MODE>mode, operands, <u_bool>); DONE;")
7533 [(set (match_operand:DI 0 "register_operand")
7535 (any_div:SI (match_operand:SI 2 "register_operand")
7536 (match_operand:SI 3 "nonimmediate_operand"))))
7537 (set (match_operand:SI 1 "register_operand")
7538 (<paired_mod>:SI (match_dup 2) (match_dup 3)))
7539 (clobber (reg:CC FLAGS_REG))]
7541 && TARGET_USE_8BIT_IDIV
7542 && TARGET_QIMODE_MATH
7543 && can_create_pseudo_p ()
7544 && !optimize_insn_for_size_p ()"
7546 "ix86_split_idivmod (SImode, operands, <u_bool>); DONE;")
7549 [(set (match_operand:DI 1 "register_operand")
7551 (<paired_mod>:SI (match_operand:SI 2 "register_operand")
7552 (match_operand:SI 3 "nonimmediate_operand"))))
7553 (set (match_operand:SI 0 "register_operand")
7554 (any_div:SI (match_dup 2) (match_dup 3)))
7555 (clobber (reg:CC FLAGS_REG))]
7557 && TARGET_USE_8BIT_IDIV
7558 && TARGET_QIMODE_MATH
7559 && can_create_pseudo_p ()
7560 && !optimize_insn_for_size_p ()"
7562 "ix86_split_idivmod (SImode, operands, <u_bool>); DONE;")
7564 (define_insn_and_split "divmod<mode>4_1"
7565 [(set (match_operand:SWI48 0 "register_operand" "=a")
7566 (div:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7567 (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
7568 (set (match_operand:SWI48 1 "register_operand" "=&d")
7569 (mod:SWI48 (match_dup 2) (match_dup 3)))
7570 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7571 (clobber (reg:CC FLAGS_REG))]
7575 [(parallel [(set (match_dup 1)
7576 (ashiftrt:SWI48 (match_dup 4) (match_dup 5)))
7577 (clobber (reg:CC FLAGS_REG))])
7578 (parallel [(set (match_dup 0)
7579 (div:SWI48 (match_dup 2) (match_dup 3)))
7581 (mod:SWI48 (match_dup 2) (match_dup 3)))
7583 (clobber (reg:CC FLAGS_REG))])]
7585 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7587 if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
7588 operands[4] = operands[2];
7591 /* Avoid use of cltd in favor of a mov+shift. */
7592 emit_move_insn (operands[1], operands[2]);
7593 operands[4] = operands[1];
7596 [(set_attr "type" "multi")
7597 (set_attr "mode" "<MODE>")])
7599 (define_insn_and_split "udivmod<mode>4_1"
7600 [(set (match_operand:SWI48 0 "register_operand" "=a")
7601 (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7602 (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
7603 (set (match_operand:SWI48 1 "register_operand" "=&d")
7604 (umod:SWI48 (match_dup 2) (match_dup 3)))
7605 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7606 (clobber (reg:CC FLAGS_REG))]
7610 [(set (match_dup 1) (const_int 0))
7611 (parallel [(set (match_dup 0)
7612 (udiv:SWI48 (match_dup 2) (match_dup 3)))
7614 (umod:SWI48 (match_dup 2) (match_dup 3)))
7616 (clobber (reg:CC FLAGS_REG))])]
7618 [(set_attr "type" "multi")
7619 (set_attr "mode" "<MODE>")])
7621 (define_insn_and_split "divmodsi4_zext_1"
7622 [(set (match_operand:DI 0 "register_operand" "=a")
7624 (div:SI (match_operand:SI 2 "register_operand" "0")
7625 (match_operand:SI 3 "nonimmediate_operand" "rm"))))
7626 (set (match_operand:SI 1 "register_operand" "=&d")
7627 (mod:SI (match_dup 2) (match_dup 3)))
7628 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7629 (clobber (reg:CC FLAGS_REG))]
7632 "&& reload_completed"
7633 [(parallel [(set (match_dup 1)
7634 (ashiftrt:SI (match_dup 4) (match_dup 5)))
7635 (clobber (reg:CC FLAGS_REG))])
7636 (parallel [(set (match_dup 0)
7637 (zero_extend:DI (div:SI (match_dup 2) (match_dup 3))))
7639 (mod:SI (match_dup 2) (match_dup 3)))
7641 (clobber (reg:CC FLAGS_REG))])]
7643 operands[5] = GEN_INT (GET_MODE_BITSIZE (SImode)-1);
7645 if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
7646 operands[4] = operands[2];
7649 /* Avoid use of cltd in favor of a mov+shift. */
7650 emit_move_insn (operands[1], operands[2]);
7651 operands[4] = operands[1];
7654 [(set_attr "type" "multi")
7655 (set_attr "mode" "SI")])
7657 (define_insn_and_split "udivmodsi4_zext_1"
7658 [(set (match_operand:DI 0 "register_operand" "=a")
7660 (udiv:SI (match_operand:SI 2 "register_operand" "0")
7661 (match_operand:SI 3 "nonimmediate_operand" "rm"))))
7662 (set (match_operand:SI 1 "register_operand" "=&d")
7663 (umod:SI (match_dup 2) (match_dup 3)))
7664 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7665 (clobber (reg:CC FLAGS_REG))]
7668 "&& reload_completed"
7669 [(set (match_dup 1) (const_int 0))
7670 (parallel [(set (match_dup 0)
7671 (zero_extend:DI (udiv:SI (match_dup 2) (match_dup 3))))
7673 (umod:SI (match_dup 2) (match_dup 3)))
7675 (clobber (reg:CC FLAGS_REG))])]
7677 [(set_attr "type" "multi")
7678 (set_attr "mode" "SI")])
7680 (define_insn_and_split "divmodsi4_zext_2"
7681 [(set (match_operand:DI 1 "register_operand" "=&d")
7683 (mod:SI (match_operand:SI 2 "register_operand" "0")
7684 (match_operand:SI 3 "nonimmediate_operand" "rm"))))
7685 (set (match_operand:SI 0 "register_operand" "=a")
7686 (div:SI (match_dup 2) (match_dup 3)))
7687 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7688 (clobber (reg:CC FLAGS_REG))]
7691 "&& reload_completed"
7692 [(parallel [(set (match_dup 6)
7693 (ashiftrt:SI (match_dup 4) (match_dup 5)))
7694 (clobber (reg:CC FLAGS_REG))])
7695 (parallel [(set (match_dup 1)
7696 (zero_extend:DI (mod:SI (match_dup 2) (match_dup 3))))
7698 (div:SI (match_dup 2) (match_dup 3)))
7700 (clobber (reg:CC FLAGS_REG))])]
7702 operands[5] = GEN_INT (GET_MODE_BITSIZE (SImode)-1);
7703 operands[6] = gen_lowpart (SImode, operands[1]);
7705 if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
7706 operands[4] = operands[2];
7709 /* Avoid use of cltd in favor of a mov+shift. */
7710 emit_move_insn (operands[6], operands[2]);
7711 operands[4] = operands[6];
7714 [(set_attr "type" "multi")
7715 (set_attr "mode" "SI")])
7717 (define_insn_and_split "udivmodsi4_zext_2"
7718 [(set (match_operand:DI 1 "register_operand" "=&d")
7720 (umod:SI (match_operand:SI 2 "register_operand" "0")
7721 (match_operand:SI 3 "nonimmediate_operand" "rm"))))
7722 (set (match_operand:SI 0 "register_operand" "=a")
7723 (udiv:SI (match_dup 2) (match_dup 3)))
7724 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7725 (clobber (reg:CC FLAGS_REG))]
7728 "&& reload_completed"
7729 [(set (match_dup 4) (const_int 0))
7730 (parallel [(set (match_dup 1)
7731 (zero_extend:DI (umod:SI (match_dup 2) (match_dup 3))))
7733 (udiv:SI (match_dup 2) (match_dup 3)))
7735 (clobber (reg:CC FLAGS_REG))])]
7736 "operands[4] = gen_lowpart (SImode, operands[1]);"
7737 [(set_attr "type" "multi")
7738 (set_attr "mode" "SI")])
7740 (define_insn_and_split "*divmod<mode>4"
7741 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7742 (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7743 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7744 (set (match_operand:SWIM248 1 "register_operand" "=&d")
7745 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7746 (clobber (reg:CC FLAGS_REG))]
7750 [(parallel [(set (match_dup 1)
7751 (ashiftrt:SWIM248 (match_dup 4) (match_dup 5)))
7752 (clobber (reg:CC FLAGS_REG))])
7753 (parallel [(set (match_dup 0)
7754 (div:SWIM248 (match_dup 2) (match_dup 3)))
7756 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7758 (clobber (reg:CC FLAGS_REG))])]
7760 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7762 if (<MODE>mode != HImode
7763 && (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD))
7764 operands[4] = operands[2];
7767 /* Avoid use of cltd in favor of a mov+shift. */
7768 emit_move_insn (operands[1], operands[2]);
7769 operands[4] = operands[1];
7772 [(set_attr "type" "multi")
7773 (set_attr "mode" "<MODE>")])
7775 (define_insn_and_split "*udivmod<mode>4"
7776 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7777 (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7778 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7779 (set (match_operand:SWIM248 1 "register_operand" "=&d")
7780 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7781 (clobber (reg:CC FLAGS_REG))]
7785 [(set (match_dup 1) (const_int 0))
7786 (parallel [(set (match_dup 0)
7787 (udiv:SWIM248 (match_dup 2) (match_dup 3)))
7789 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7791 (clobber (reg:CC FLAGS_REG))])]
7793 [(set_attr "type" "multi")
7794 (set_attr "mode" "<MODE>")])
7796 ;; Optimize division or modulo by constant power of 2, if the constant
7797 ;; materializes only after expansion.
7798 (define_insn_and_split "*udivmod<mode>4_pow2"
7799 [(set (match_operand:SWI48 0 "register_operand" "=r")
7800 (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7801 (match_operand:SWI48 3 "const_int_operand" "n")))
7802 (set (match_operand:SWI48 1 "register_operand" "=r")
7803 (umod:SWI48 (match_dup 2) (match_dup 3)))
7804 (clobber (reg:CC FLAGS_REG))]
7805 "IN_RANGE (exact_log2 (UINTVAL (operands[3])), 1, 31)"
7807 "&& reload_completed"
7808 [(set (match_dup 1) (match_dup 2))
7809 (parallel [(set (match_dup 0) (lshiftrt:<MODE> (match_dup 2) (match_dup 4)))
7810 (clobber (reg:CC FLAGS_REG))])
7811 (parallel [(set (match_dup 1) (and:<MODE> (match_dup 1) (match_dup 5)))
7812 (clobber (reg:CC FLAGS_REG))])]
7814 int v = exact_log2 (UINTVAL (operands[3]));
7815 operands[4] = GEN_INT (v);
7816 operands[5] = GEN_INT ((HOST_WIDE_INT_1U << v) - 1);
7818 [(set_attr "type" "multi")
7819 (set_attr "mode" "<MODE>")])
7821 (define_insn_and_split "*divmodsi4_zext_1"
7822 [(set (match_operand:DI 0 "register_operand" "=a")
7824 (div:SI (match_operand:SI 2 "register_operand" "0")
7825 (match_operand:SI 3 "nonimmediate_operand" "rm"))))
7826 (set (match_operand:SI 1 "register_operand" "=&d")
7827 (mod:SI (match_dup 2) (match_dup 3)))
7828 (clobber (reg:CC FLAGS_REG))]
7831 "&& reload_completed"
7832 [(parallel [(set (match_dup 1)
7833 (ashiftrt:SI (match_dup 4) (match_dup 5)))
7834 (clobber (reg:CC FLAGS_REG))])
7835 (parallel [(set (match_dup 0)
7836 (zero_extend:DI (div:SI (match_dup 2) (match_dup 3))))
7838 (mod:SI (match_dup 2) (match_dup 3)))
7840 (clobber (reg:CC FLAGS_REG))])]
7842 operands[5] = GEN_INT (GET_MODE_BITSIZE (SImode)-1);
7844 if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
7845 operands[4] = operands[2];
7848 /* Avoid use of cltd in favor of a mov+shift. */
7849 emit_move_insn (operands[1], operands[2]);
7850 operands[4] = operands[1];
7853 [(set_attr "type" "multi")
7854 (set_attr "mode" "SI")])
7856 (define_insn_and_split "*udivmodsi4_zext_1"
7857 [(set (match_operand:DI 0 "register_operand" "=a")
7859 (udiv:SI (match_operand:SI 2 "register_operand" "0")
7860 (match_operand:SI 3 "nonimmediate_operand" "rm"))))
7861 (set (match_operand:SI 1 "register_operand" "=&d")
7862 (umod:SI (match_dup 2) (match_dup 3)))
7863 (clobber (reg:CC FLAGS_REG))]
7866 "&& reload_completed"
7867 [(set (match_dup 1) (const_int 0))
7868 (parallel [(set (match_dup 0)
7869 (zero_extend:DI (udiv:SI (match_dup 2) (match_dup 3))))
7871 (umod:SI (match_dup 2) (match_dup 3)))
7873 (clobber (reg:CC FLAGS_REG))])]
7875 [(set_attr "type" "multi")
7876 (set_attr "mode" "SI")])
7878 (define_insn_and_split "*udivmodsi4_pow2_zext_1"
7879 [(set (match_operand:DI 0 "register_operand" "=r")
7881 (udiv:SI (match_operand:SI 2 "register_operand" "0")
7882 (match_operand:SI 3 "const_int_operand" "n"))))
7883 (set (match_operand:SI 1 "register_operand" "=r")
7884 (umod:SI (match_dup 2) (match_dup 3)))
7885 (clobber (reg:CC FLAGS_REG))]
7887 && exact_log2 (UINTVAL (operands[3])) > 0"
7889 "&& reload_completed"
7890 [(set (match_dup 1) (match_dup 2))
7891 (parallel [(set (match_dup 0)
7892 (zero_extend:DI (lshiftrt:SI (match_dup 2) (match_dup 4))))
7893 (clobber (reg:CC FLAGS_REG))])
7894 (parallel [(set (match_dup 1) (and:SI (match_dup 1) (match_dup 5)))
7895 (clobber (reg:CC FLAGS_REG))])]
7897 int v = exact_log2 (UINTVAL (operands[3]));
7898 operands[4] = GEN_INT (v);
7899 operands[5] = GEN_INT ((HOST_WIDE_INT_1U << v) - 1);
7901 [(set_attr "type" "multi")
7902 (set_attr "mode" "SI")])
7904 (define_insn_and_split "*divmodsi4_zext_2"
7905 [(set (match_operand:DI 1 "register_operand" "=&d")
7907 (mod:SI (match_operand:SI 2 "register_operand" "0")
7908 (match_operand:SI 3 "nonimmediate_operand" "rm"))))
7909 (set (match_operand:SI 0 "register_operand" "=a")
7910 (div:SI (match_dup 2) (match_dup 3)))
7911 (clobber (reg:CC FLAGS_REG))]
7914 "&& reload_completed"
7915 [(parallel [(set (match_dup 6)
7916 (ashiftrt:SI (match_dup 4) (match_dup 5)))
7917 (clobber (reg:CC FLAGS_REG))])
7918 (parallel [(set (match_dup 1)
7919 (zero_extend:DI (mod:SI (match_dup 2) (match_dup 3))))
7921 (div:SI (match_dup 2) (match_dup 3)))
7923 (clobber (reg:CC FLAGS_REG))])]
7925 operands[5] = GEN_INT (GET_MODE_BITSIZE (SImode)-1);
7926 operands[6] = gen_lowpart (SImode, operands[1]);
7928 if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
7929 operands[4] = operands[2];
7932 /* Avoid use of cltd in favor of a mov+shift. */
7933 emit_move_insn (operands[6], operands[2]);
7934 operands[4] = operands[6];
7937 [(set_attr "type" "multi")
7938 (set_attr "mode" "SI")])
7940 (define_insn_and_split "*udivmodsi4_zext_2"
7941 [(set (match_operand:DI 1 "register_operand" "=&d")
7943 (umod:SI (match_operand:SI 2 "register_operand" "0")
7944 (match_operand:SI 3 "nonimmediate_operand" "rm"))))
7945 (set (match_operand:SI 0 "register_operand" "=a")
7946 (udiv:SI (match_dup 2) (match_dup 3)))
7947 (clobber (reg:CC FLAGS_REG))]
7950 "&& reload_completed"
7951 [(set (match_dup 4) (const_int 0))
7952 (parallel [(set (match_dup 1)
7953 (zero_extend:DI (umod:SI (match_dup 2) (match_dup 3))))
7955 (udiv:SI (match_dup 2) (match_dup 3)))
7957 (clobber (reg:CC FLAGS_REG))])]
7958 "operands[4] = gen_lowpart (SImode, operands[1]);"
7959 [(set_attr "type" "multi")
7960 (set_attr "mode" "SI")])
7962 (define_insn_and_split "*udivmodsi4_pow2_zext_2"
7963 [(set (match_operand:DI 1 "register_operand" "=r")
7965 (umod:SI (match_operand:SI 2 "register_operand" "0")
7966 (match_operand:SI 3 "const_int_operand" "n"))))
7967 (set (match_operand:SI 0 "register_operand" "=r")
7968 (umod:SI (match_dup 2) (match_dup 3)))
7969 (clobber (reg:CC FLAGS_REG))]
7971 && exact_log2 (UINTVAL (operands[3])) > 0"
7973 "&& reload_completed"
7974 [(set (match_dup 1) (match_dup 2))
7975 (parallel [(set (match_dup 0) (lshiftrt:SI (match_dup 2) (match_dup 4)))
7976 (clobber (reg:CC FLAGS_REG))])
7977 (parallel [(set (match_dup 1)
7978 (zero_extend:DI (and:SI (match_dup 1) (match_dup 5))))
7979 (clobber (reg:CC FLAGS_REG))])]
7981 int v = exact_log2 (UINTVAL (operands[3]));
7982 operands[4] = GEN_INT (v);
7983 operands[5] = GEN_INT ((HOST_WIDE_INT_1U << v) - 1);
7985 [(set_attr "type" "multi")
7986 (set_attr "mode" "SI")])
7988 (define_insn "*<u>divmod<mode>4_noext"
7989 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7991 (match_operand:SWIM248 2 "register_operand" "0")
7992 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7993 (set (match_operand:SWIM248 1 "register_operand" "=d")
7994 (<paired_mod>:SWIM248 (match_dup 2) (match_dup 3)))
7995 (use (match_operand:SWIM248 4 "register_operand" "1"))
7996 (clobber (reg:CC FLAGS_REG))]
7998 "<sgnprefix>div{<imodesuffix>}\t%3"
7999 [(set_attr "type" "idiv")
8000 (set_attr "mode" "<MODE>")])
8002 (define_insn "*<u>divmodsi4_noext_zext_1"
8003 [(set (match_operand:DI 0 "register_operand" "=a")
8005 (any_div:SI (match_operand:SI 2 "register_operand" "0")
8006 (match_operand:SI 3 "nonimmediate_operand" "rm"))))
8007 (set (match_operand:SI 1 "register_operand" "=d")
8008 (<paired_mod>:SI (match_dup 2) (match_dup 3)))
8009 (use (match_operand:SI 4 "register_operand" "1"))
8010 (clobber (reg:CC FLAGS_REG))]
8012 "<sgnprefix>div{l}\t%3"
8013 [(set_attr "type" "idiv")
8014 (set_attr "mode" "SI")])
8016 (define_insn "*<u>divmodsi4_noext_zext_2"
8017 [(set (match_operand:DI 1 "register_operand" "=d")
8019 (<paired_mod>:SI (match_operand:SI 2 "register_operand" "0")
8020 (match_operand:SI 3 "nonimmediate_operand" "rm"))))
8021 (set (match_operand:SI 0 "register_operand" "=a")
8022 (any_div:SI (match_dup 2) (match_dup 3)))
8023 (use (match_operand:SI 4 "register_operand" "1"))
8024 (clobber (reg:CC FLAGS_REG))]
8026 "<sgnprefix>div{l}\t%3"
8027 [(set_attr "type" "idiv")
8028 (set_attr "mode" "SI")])
8030 (define_expand "divmodqi4"
8031 [(parallel [(set (match_operand:QI 0 "register_operand")
8033 (match_operand:QI 1 "register_operand")
8034 (match_operand:QI 2 "nonimmediate_operand")))
8035 (set (match_operand:QI 3 "register_operand")
8036 (mod:QI (match_dup 1) (match_dup 2)))
8037 (clobber (reg:CC FLAGS_REG))])]
8038 "TARGET_QIMODE_MATH"
8043 tmp0 = gen_reg_rtx (HImode);
8044 tmp1 = gen_reg_rtx (HImode);
8046 /* Extend operands[1] to HImode. Generate 8bit divide. Result is in AX. */
8047 emit_insn (gen_extendqihi2 (tmp1, operands[1]));
8048 emit_insn (gen_divmodhiqi3 (tmp0, tmp1, operands[2]));
8050 /* Extract remainder from AH. */
8051 tmp1 = gen_rtx_ZERO_EXTRACT (SImode, tmp0, GEN_INT (8), GEN_INT (8));
8052 tmp1 = lowpart_subreg (QImode, tmp1, SImode);
8053 rtx_insn *insn = emit_move_insn (operands[3], tmp1);
8055 mod = gen_rtx_MOD (QImode, operands[1], operands[2]);
8056 set_unique_reg_note (insn, REG_EQUAL, mod);
8058 /* Extract quotient from AL. */
8059 insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
8061 div = gen_rtx_DIV (QImode, operands[1], operands[2]);
8062 set_unique_reg_note (insn, REG_EQUAL, div);
8067 (define_expand "udivmodqi4"
8068 [(parallel [(set (match_operand:QI 0 "register_operand")
8070 (match_operand:QI 1 "register_operand")
8071 (match_operand:QI 2 "nonimmediate_operand")))
8072 (set (match_operand:QI 3 "register_operand")
8073 (umod:QI (match_dup 1) (match_dup 2)))
8074 (clobber (reg:CC FLAGS_REG))])]
8075 "TARGET_QIMODE_MATH"
8080 tmp0 = gen_reg_rtx (HImode);
8081 tmp1 = gen_reg_rtx (HImode);
8083 /* Extend operands[1] to HImode. Generate 8bit divide. Result is in AX. */
8084 emit_insn (gen_zero_extendqihi2 (tmp1, operands[1]));
8085 emit_insn (gen_udivmodhiqi3 (tmp0, tmp1, operands[2]));
8087 /* Extract remainder from AH. */
8088 tmp1 = gen_rtx_ZERO_EXTRACT (SImode, tmp0, GEN_INT (8), GEN_INT (8));
8089 tmp1 = lowpart_subreg (QImode, tmp1, SImode);
8090 rtx_insn *insn = emit_move_insn (operands[3], tmp1);
8092 mod = gen_rtx_UMOD (QImode, operands[1], operands[2]);
8093 set_unique_reg_note (insn, REG_EQUAL, mod);
8095 /* Extract quotient from AL. */
8096 insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
8098 div = gen_rtx_UDIV (QImode, operands[1], operands[2]);
8099 set_unique_reg_note (insn, REG_EQUAL, div);
8104 ;; Divide AX by r/m8, with result stored in
8107 ;; Change div/mod to HImode and extend the second argument to HImode
8108 ;; so that mode of div/mod matches with mode of arguments. Otherwise
8109 ;; combine may fail.
8110 (define_insn "<u>divmodhiqi3"
8111 [(set (match_operand:HI 0 "register_operand" "=a")
8116 (mod:HI (match_operand:HI 1 "register_operand" "0")
8118 (match_operand:QI 2 "nonimmediate_operand" "qm")))))
8122 (div:HI (match_dup 1) (any_extend:HI (match_dup 2)))))))
8123 (clobber (reg:CC FLAGS_REG))]
8124 "TARGET_QIMODE_MATH"
8125 "<sgnprefix>div{b}\t%2"
8126 [(set_attr "type" "idiv")
8127 (set_attr "mode" "QI")])
8129 ;; We cannot use div/idiv for double division, because it causes
8130 ;; "division by zero" on the overflow and that's not what we expect
8131 ;; from truncate. Because true (non truncating) double division is
8132 ;; never generated, we can't create this insn anyway.
8135 ; [(set (match_operand:SI 0 "register_operand" "=a")
8137 ; (udiv:DI (match_operand:DI 1 "register_operand" "A")
8139 ; (match_operand:SI 2 "nonimmediate_operand" "rm")))))
8140 ; (set (match_operand:SI 3 "register_operand" "=d")
8142 ; (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
8143 ; (clobber (reg:CC FLAGS_REG))]
8145 ; "div{l}\t{%2, %0|%0, %2}"
8146 ; [(set_attr "type" "idiv")])
8148 ;;- Logical AND instructions
8150 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
8151 ;; Note that this excludes ah.
8153 (define_expand "testsi_ccno_1"
8154 [(set (reg:CCNO FLAGS_REG)
8156 (and:SI (match_operand:SI 0 "nonimmediate_operand")
8157 (match_operand:SI 1 "x86_64_nonmemory_operand"))
8160 (define_expand "testqi_ccz_1"
8161 [(set (reg:CCZ FLAGS_REG)
8162 (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand")
8163 (match_operand:QI 1 "nonmemory_operand"))
8166 (define_expand "testdi_ccno_1"
8167 [(set (reg:CCNO FLAGS_REG)
8169 (and:DI (match_operand:DI 0 "nonimmediate_operand")
8170 (match_operand:DI 1 "x86_64_szext_general_operand"))
8172 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))")
8174 (define_insn "*testdi_1"
8175 [(set (reg FLAGS_REG)
8178 (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
8179 (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
8181 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8182 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8184 test{l}\t{%k1, %k0|%k0, %k1}
8185 test{l}\t{%k1, %k0|%k0, %k1}
8186 test{q}\t{%1, %0|%0, %1}
8187 test{q}\t{%1, %0|%0, %1}
8188 test{q}\t{%1, %0|%0, %1}"
8189 [(set_attr "type" "test")
8190 (set_attr "modrm" "0,1,0,1,1")
8191 (set_attr "mode" "SI,SI,DI,DI,DI")])
8193 (define_insn "*testqi_1_maybe_si"
8194 [(set (reg FLAGS_REG)
8197 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
8198 (match_operand:QI 1 "general_operand" "n,n,qn,n"))
8200 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
8201 && ix86_match_ccmode (insn,
8202 CONST_INT_P (operands[1])
8203 && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
8205 if (which_alternative == 3)
8207 if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
8208 operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
8209 return "test{l}\t{%1, %k0|%k0, %1}";
8211 return "test{b}\t{%1, %0|%0, %1}";
8213 [(set_attr "type" "test")
8214 (set_attr "modrm" "0,1,1,1")
8215 (set_attr "mode" "QI,QI,QI,SI")
8216 (set_attr "pent_pair" "uv,np,uv,np")])
8218 (define_insn "*test<mode>_1"
8219 [(set (reg FLAGS_REG)
8222 (match_operand:SWI124 0 "nonimmediate_operand" "%!*a,<r>,<r>m")
8223 (match_operand:SWI124 1 "<general_operand>" "<i>,<i>,<r><i>"))
8225 "ix86_match_ccmode (insn, CCNOmode)
8226 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8227 "test{<imodesuffix>}\t{%1, %0|%0, %1}"
8228 [(set_attr "type" "test")
8229 (set_attr "modrm" "0,1,1")
8230 (set_attr "mode" "<MODE>")
8231 (set_attr "pent_pair" "uv,np,uv")])
8233 (define_expand "testqi_ext_1_ccno"
8234 [(set (reg:CCNO FLAGS_REG)
8238 (zero_extract:SI (match_operand 0 "ext_register_operand")
8241 (match_operand 1 "const_int_operand"))
8244 (define_insn "*testqi_ext_1"
8245 [(set (reg FLAGS_REG)
8249 (zero_extract:SI (match_operand 0 "ext_register_operand" "Q,Q")
8252 (match_operand:QI 1 "general_operand" "QnBc,m"))
8254 "ix86_match_ccmode (insn, CCNOmode)"
8255 "test{b}\t{%1, %h0|%h0, %1}"
8256 [(set_attr "isa" "*,nox64")
8257 (set_attr "type" "test")
8258 (set_attr "mode" "QI")])
8260 (define_insn "*testqi_ext_2"
8261 [(set (reg FLAGS_REG)
8265 (zero_extract:SI (match_operand 0 "ext_register_operand" "Q")
8269 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q")
8273 "ix86_match_ccmode (insn, CCNOmode)"
8274 "test{b}\t{%h1, %h0|%h0, %h1}"
8275 [(set_attr "type" "test")
8276 (set_attr "mode" "QI")])
8278 ;; Combine likes to form bit extractions for some tests. Humor it.
8279 (define_insn_and_split "*testqi_ext_3"
8280 [(set (match_operand 0 "flags_reg_operand")
8281 (match_operator 1 "compare_operator"
8282 [(zero_extract:SWI248
8283 (match_operand 2 "nonimmediate_operand" "rm")
8284 (match_operand 3 "const_int_operand" "n")
8285 (match_operand 4 "const_int_operand" "n"))
8287 "ix86_match_ccmode (insn, CCNOmode)
8288 && ((TARGET_64BIT && GET_MODE (operands[2]) == DImode)
8289 || GET_MODE (operands[2]) == SImode
8290 || GET_MODE (operands[2]) == HImode
8291 || GET_MODE (operands[2]) == QImode)
8292 /* Ensure that resulting mask is zero or sign extended operand. */
8293 && INTVAL (operands[4]) >= 0
8294 && ((INTVAL (operands[3]) > 0
8295 && INTVAL (operands[3]) + INTVAL (operands[4]) <= 32)
8296 || (<MODE>mode == DImode
8297 && INTVAL (operands[3]) > 32
8298 && INTVAL (operands[3]) + INTVAL (operands[4]) == 64))"
8301 [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
8303 rtx val = operands[2];
8304 HOST_WIDE_INT len = INTVAL (operands[3]);
8305 HOST_WIDE_INT pos = INTVAL (operands[4]);
8306 machine_mode mode = GET_MODE (val);
8310 machine_mode submode = GET_MODE (SUBREG_REG (val));
8312 /* Narrow paradoxical subregs to prevent partial register stalls. */
8313 if (GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode)
8314 && GET_MODE_CLASS (submode) == MODE_INT)
8316 val = SUBREG_REG (val);
8321 /* Small HImode tests can be converted to QImode. */
8322 if (register_operand (val, HImode) && pos + len <= 8)
8324 val = gen_lowpart (QImode, val);
8328 gcc_assert (pos + len <= GET_MODE_PRECISION (mode));
8331 = wi::shifted_mask (pos, len, false, GET_MODE_PRECISION (mode));
8333 operands[2] = gen_rtx_AND (mode, val, immed_wide_int_const (mask, mode));
8336 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
8337 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
8338 ;; this is relatively important trick.
8339 ;; Do the conversion only post-reload to avoid limiting of the register class
8342 [(set (match_operand 0 "flags_reg_operand")
8343 (match_operator 1 "compare_operator"
8344 [(and (match_operand 2 "QIreg_operand")
8345 (match_operand 3 "const_int_operand"))
8348 && GET_MODE (operands[2]) != QImode
8349 && ((ix86_match_ccmode (insn, CCZmode)
8350 && !(INTVAL (operands[3]) & ~(255 << 8)))
8351 || (ix86_match_ccmode (insn, CCNOmode)
8352 && !(INTVAL (operands[3]) & ~(127 << 8))))"
8357 (zero_extract:SI (match_dup 2)
8363 operands[2] = gen_lowpart (SImode, operands[2]);
8364 operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, QImode);
8368 [(set (match_operand 0 "flags_reg_operand")
8369 (match_operator 1 "compare_operator"
8370 [(and (match_operand 2 "nonimmediate_operand")
8371 (match_operand 3 "const_int_operand"))
8374 && GET_MODE (operands[2]) != QImode
8375 && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
8376 && ((ix86_match_ccmode (insn, CCZmode)
8377 && !(INTVAL (operands[3]) & ~255))
8378 || (ix86_match_ccmode (insn, CCNOmode)
8379 && !(INTVAL (operands[3]) & ~127)))"
8381 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
8384 operands[2] = gen_lowpart (QImode, operands[2]);
8385 operands[3] = gen_int_mode (INTVAL (operands[3]), QImode);
8388 ;; %%% This used to optimize known byte-wide and operations to memory,
8389 ;; and sometimes to QImode registers. If this is considered useful,
8390 ;; it should be done with splitters.
8392 (define_expand "and<mode>3"
8393 [(set (match_operand:SWIM1248x 0 "nonimmediate_operand")
8394 (and:SWIM1248x (match_operand:SWIM1248x 1 "nonimmediate_operand")
8395 (match_operand:SWIM1248x 2 "<general_szext_operand>")))]
8398 machine_mode mode = <MODE>mode;
8399 rtx (*insn) (rtx, rtx);
8401 if (CONST_INT_P (operands[2]) && REG_P (operands[0]))
8403 HOST_WIDE_INT ival = INTVAL (operands[2]);
8405 if (ival == (HOST_WIDE_INT) 0xffffffff)
8407 else if (ival == 0xffff)
8409 else if (ival == 0xff)
8413 if (mode == <MODE>mode)
8415 ix86_expand_binary_operator (AND, <MODE>mode, operands);
8419 if (<MODE>mode == DImode)
8420 insn = (mode == SImode)
8421 ? gen_zero_extendsidi2
8423 ? gen_zero_extendhidi2
8424 : gen_zero_extendqidi2;
8425 else if (<MODE>mode == SImode)
8426 insn = (mode == HImode)
8427 ? gen_zero_extendhisi2
8428 : gen_zero_extendqisi2;
8429 else if (<MODE>mode == HImode)
8430 insn = gen_zero_extendqihi2;
8434 emit_insn (insn (operands[0], gen_lowpart (mode, operands[1])));
8438 (define_insn_and_split "*anddi3_doubleword"
8439 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r")
8441 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8442 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm")))
8443 (clobber (reg:CC FLAGS_REG))]
8444 "!TARGET_64BIT && TARGET_STV && TARGET_SSE2
8445 && ix86_binary_operator_ok (AND, DImode, operands)"
8447 "&& reload_completed"
8450 split_double_mode (DImode, &operands[0], 3, &operands[0], &operands[3]);
8451 if (operands[2] == const0_rtx)
8453 operands[1] = const0_rtx;
8454 ix86_expand_move (SImode, &operands[0]);
8456 else if (operands[2] != constm1_rtx)
8457 ix86_expand_binary_operator (AND, SImode, &operands[0]);
8458 else if (operands[5] == constm1_rtx)
8459 emit_note (NOTE_INSN_DELETED);
8460 if (operands[5] == const0_rtx)
8462 operands[4] = const0_rtx;
8463 ix86_expand_move (SImode, &operands[3]);
8465 else if (operands[5] != constm1_rtx)
8466 ix86_expand_binary_operator (AND, SImode, &operands[3]);
8470 (define_insn "*anddi_1"
8471 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
8473 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
8474 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
8475 (clobber (reg:CC FLAGS_REG))]
8476 "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
8478 and{l}\t{%k2, %k0|%k0, %k2}
8479 and{q}\t{%2, %0|%0, %2}
8480 and{q}\t{%2, %0|%0, %2}
8482 [(set_attr "type" "alu,alu,alu,imovx")
8483 (set_attr "length_immediate" "*,*,*,0")
8484 (set (attr "prefix_rex")
8486 (and (eq_attr "type" "imovx")
8487 (and (match_test "INTVAL (operands[2]) == 0xff")
8488 (match_operand 1 "ext_QIreg_operand")))
8490 (const_string "*")))
8491 (set_attr "mode" "SI,DI,DI,SI")])
8493 (define_insn_and_split "*anddi_1_btr"
8494 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
8496 (match_operand:DI 1 "nonimmediate_operand" "%0")
8497 (match_operand:DI 2 "const_int_operand" "n")))
8498 (clobber (reg:CC FLAGS_REG))]
8499 "TARGET_64BIT && TARGET_USE_BT
8500 && ix86_binary_operator_ok (AND, DImode, operands)
8501 && IN_RANGE (exact_log2 (~INTVAL (operands[2])), 31, 63)"
8503 "&& reload_completed"
8504 [(parallel [(set (zero_extract:DI (match_dup 0)
8508 (clobber (reg:CC FLAGS_REG))])]
8509 "operands[3] = GEN_INT (exact_log2 (~INTVAL (operands[2])));"
8510 [(set_attr "type" "alu1")
8511 (set_attr "prefix_0f" "1")
8512 (set_attr "znver1_decode" "double")
8513 (set_attr "mode" "DI")])
8515 ;; Turn *anddi_1 into *andsi_1_zext if possible.
8517 [(set (match_operand:DI 0 "register_operand")
8518 (and:DI (subreg:DI (match_operand:SI 1 "register_operand") 0)
8519 (match_operand:DI 2 "x86_64_zext_immediate_operand")))
8520 (clobber (reg:CC FLAGS_REG))]
8522 [(parallel [(set (match_dup 0)
8523 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))
8524 (clobber (reg:CC FLAGS_REG))])]
8526 if (GET_CODE (operands[2]) == SYMBOL_REF
8527 || GET_CODE (operands[2]) == LABEL_REF)
8529 operands[2] = shallow_copy_rtx (operands[2]);
8530 PUT_MODE (operands[2], SImode);
8532 else if (GET_CODE (operands[2]) == CONST)
8534 /* (const:DI (plus:DI (symbol_ref:DI ("...")) (const_int N))) */
8535 operands[2] = copy_rtx (operands[2]);
8536 PUT_MODE (operands[2], SImode);
8537 PUT_MODE (XEXP (operands[2], 0), SImode);
8538 PUT_MODE (XEXP (XEXP (operands[2], 0), 0), SImode);
8541 operands[2] = gen_lowpart (SImode, operands[2]);
8544 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8545 (define_insn "*andsi_1_zext"
8546 [(set (match_operand:DI 0 "register_operand" "=r")
8548 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8549 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
8550 (clobber (reg:CC FLAGS_REG))]
8551 "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
8552 "and{l}\t{%2, %k0|%k0, %2}"
8553 [(set_attr "type" "alu")
8554 (set_attr "mode" "SI")])
8556 (define_insn "*and<mode>_1"
8557 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=rm,r,Ya")
8558 (and:SWI24 (match_operand:SWI24 1 "nonimmediate_operand" "%0,0,qm")
8559 (match_operand:SWI24 2 "<general_operand>" "r<i>,rm,L")))
8560 (clobber (reg:CC FLAGS_REG))]
8561 "ix86_binary_operator_ok (AND, <MODE>mode, operands)"
8563 and{<imodesuffix>}\t{%2, %0|%0, %2}
8564 and{<imodesuffix>}\t{%2, %0|%0, %2}
8566 [(set_attr "type" "alu,alu,imovx")
8567 (set_attr "length_immediate" "*,*,0")
8568 (set (attr "prefix_rex")
8570 (and (eq_attr "type" "imovx")
8571 (and (match_test "INTVAL (operands[2]) == 0xff")
8572 (match_operand 1 "ext_QIreg_operand")))
8574 (const_string "*")))
8575 (set_attr "mode" "<MODE>,<MODE>,SI")])
8577 (define_insn "*andqi_1"
8578 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
8579 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8580 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
8581 (clobber (reg:CC FLAGS_REG))]
8582 "ix86_binary_operator_ok (AND, QImode, operands)"
8584 and{b}\t{%2, %0|%0, %2}
8585 and{b}\t{%2, %0|%0, %2}
8586 and{l}\t{%k2, %k0|%k0, %k2}"
8587 [(set_attr "type" "alu")
8588 (set_attr "mode" "QI,QI,SI")
8589 ;; Potential partial reg stall on alternative 2.
8590 (set (attr "preferred_for_speed")
8591 (cond [(eq_attr "alternative" "2")
8592 (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
8593 (symbol_ref "true")))])
8595 (define_insn "*andqi_1_slp"
8596 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
8597 (and:QI (match_dup 0)
8598 (match_operand:QI 1 "general_operand" "qn,qmn")))
8599 (clobber (reg:CC FLAGS_REG))]
8600 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8601 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8602 "and{b}\t{%1, %0|%0, %1}"
8603 [(set_attr "type" "alu1")
8604 (set_attr "mode" "QI")])
8607 [(set (match_operand:SWI248 0 "register_operand")
8608 (and:SWI248 (match_operand:SWI248 1 "nonimmediate_operand")
8609 (match_operand:SWI248 2 "const_int_operand")))
8610 (clobber (reg:CC FLAGS_REG))]
8612 && (!REG_P (operands[1])
8613 || REGNO (operands[0]) != REGNO (operands[1]))"
8616 HOST_WIDE_INT ival = INTVAL (operands[2]);
8618 rtx (*insn) (rtx, rtx);
8620 if (ival == (HOST_WIDE_INT) 0xffffffff)
8622 else if (ival == 0xffff)
8626 gcc_assert (ival == 0xff);
8630 if (<MODE>mode == DImode)
8631 insn = (mode == SImode)
8632 ? gen_zero_extendsidi2
8634 ? gen_zero_extendhidi2
8635 : gen_zero_extendqidi2;
8638 if (<MODE>mode != SImode)
8639 /* Zero extend to SImode to avoid partial register stalls. */
8640 operands[0] = gen_lowpart (SImode, operands[0]);
8642 insn = (mode == HImode)
8643 ? gen_zero_extendhisi2
8644 : gen_zero_extendqisi2;
8646 emit_insn (insn (operands[0], gen_lowpart (mode, operands[1])));
8651 [(set (match_operand:SWI48 0 "register_operand")
8652 (and:SWI48 (match_dup 0)
8653 (const_int -65536)))
8654 (clobber (reg:CC FLAGS_REG))]
8655 "(TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)
8656 || optimize_function_for_size_p (cfun)"
8657 [(set (strict_low_part (match_dup 1)) (const_int 0))]
8658 "operands[1] = gen_lowpart (HImode, operands[0]);")
8661 [(set (match_operand:SWI248 0 "any_QIreg_operand")
8662 (and:SWI248 (match_dup 0)
8664 (clobber (reg:CC FLAGS_REG))]
8665 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8666 && reload_completed"
8667 [(set (strict_low_part (match_dup 1)) (const_int 0))]
8668 "operands[1] = gen_lowpart (QImode, operands[0]);")
8671 [(set (match_operand:SWI248 0 "QIreg_operand")
8672 (and:SWI248 (match_dup 0)
8673 (const_int -65281)))
8674 (clobber (reg:CC FLAGS_REG))]
8675 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8676 && reload_completed"
8678 [(set (zero_extract:SI (match_dup 0)
8684 (zero_extract:SI (match_dup 0)
8688 (zero_extract:SI (match_dup 0)
8690 (const_int 8)) 0)) 0))
8691 (clobber (reg:CC FLAGS_REG))])]
8692 "operands[0] = gen_lowpart (SImode, operands[0]);")
8694 (define_insn "*anddi_2"
8695 [(set (reg FLAGS_REG)
8698 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8699 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
8701 (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
8702 (and:DI (match_dup 1) (match_dup 2)))]
8704 && ix86_match_ccmode
8706 /* If we are going to emit andl instead of andq, and the operands[2]
8707 constant might have the SImode sign bit set, make sure the sign
8708 flag isn't tested, because the instruction will set the sign flag
8709 based on bit 31 rather than bit 63. If it isn't CONST_INT,
8710 conservatively assume it might have bit 31 set. */
8711 (satisfies_constraint_Z (operands[2])
8712 && (!CONST_INT_P (operands[2])
8713 || val_signbit_known_set_p (SImode, INTVAL (operands[2]))))
8714 ? CCZmode : CCNOmode)
8715 && ix86_binary_operator_ok (AND, DImode, operands)"
8717 and{l}\t{%k2, %k0|%k0, %k2}
8718 and{q}\t{%2, %0|%0, %2}
8719 and{q}\t{%2, %0|%0, %2}"
8720 [(set_attr "type" "alu")
8721 (set_attr "mode" "SI,DI,DI")])
8723 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8724 (define_insn "*andsi_2_zext"
8725 [(set (reg FLAGS_REG)
8727 (match_operand:SI 1 "nonimmediate_operand" "%0")
8728 (match_operand:SI 2 "x86_64_general_operand" "rme"))
8730 (set (match_operand:DI 0 "register_operand" "=r")
8731 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
8732 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8733 && ix86_binary_operator_ok (AND, SImode, operands)"
8734 "and{l}\t{%2, %k0|%k0, %2}"
8735 [(set_attr "type" "alu")
8736 (set_attr "mode" "SI")])
8738 (define_insn "*andqi_2_maybe_si"
8739 [(set (reg FLAGS_REG)
8741 (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8742 (match_operand:QI 2 "general_operand" "qmn,qn,n"))
8744 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
8745 (and:QI (match_dup 1) (match_dup 2)))]
8746 "ix86_binary_operator_ok (AND, QImode, operands)
8747 && ix86_match_ccmode (insn,
8748 CONST_INT_P (operands[2])
8749 && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
8751 if (which_alternative == 2)
8753 if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
8754 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
8755 return "and{l}\t{%2, %k0|%k0, %2}";
8757 return "and{b}\t{%2, %0|%0, %2}";
8759 [(set_attr "type" "alu")
8760 (set_attr "mode" "QI,QI,SI")])
8762 (define_insn "*and<mode>_2"
8763 [(set (reg FLAGS_REG)
8764 (compare (and:SWI124
8765 (match_operand:SWI124 1 "nonimmediate_operand" "%0,0")
8766 (match_operand:SWI124 2 "<general_operand>" "<g>,<r><i>"))
8768 (set (match_operand:SWI124 0 "nonimmediate_operand" "=<r>,<r>m")
8769 (and:SWI124 (match_dup 1) (match_dup 2)))]
8770 "ix86_match_ccmode (insn, CCNOmode)
8771 && ix86_binary_operator_ok (AND, <MODE>mode, operands)"
8772 "and{<imodesuffix>}\t{%2, %0|%0, %2}"
8773 [(set_attr "type" "alu")
8774 (set_attr "mode" "<MODE>")])
8776 (define_insn "*andqi_2_slp"
8777 [(set (reg FLAGS_REG)
8779 (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8780 (match_operand:QI 1 "nonimmediate_operand" "qmn,qn"))
8782 (set (strict_low_part (match_dup 0))
8783 (and:QI (match_dup 0) (match_dup 1)))]
8784 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8785 && ix86_match_ccmode (insn, CCNOmode)
8786 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8787 "and{b}\t{%1, %0|%0, %1}"
8788 [(set_attr "type" "alu1")
8789 (set_attr "mode" "QI")])
8791 (define_insn "andqi_ext_1"
8792 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q,Q")
8798 (zero_extract:SI (match_operand 1 "ext_register_operand" "0,0")
8801 (match_operand:QI 2 "general_operand" "QnBc,m")) 0))
8802 (clobber (reg:CC FLAGS_REG))]
8803 "/* FIXME: without this LRA can't reload this pattern, see PR82524. */
8804 rtx_equal_p (operands[0], operands[1])"
8805 "and{b}\t{%2, %h0|%h0, %2}"
8806 [(set_attr "isa" "*,nox64")
8807 (set_attr "type" "alu")
8808 (set_attr "mode" "QI")])
8810 ;; Generated by peephole translating test to and. This shows up
8811 ;; often in fp comparisons.
8812 (define_insn "*andqi_ext_1_cc"
8813 [(set (reg FLAGS_REG)
8817 (zero_extract:SI (match_operand 1 "ext_register_operand" "0,0")
8820 (match_operand:QI 2 "general_operand" "QnBc,m"))
8822 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q,Q")
8828 (zero_extract:SI (match_dup 1)
8832 "ix86_match_ccmode (insn, CCNOmode)
8833 /* FIXME: without this LRA can't reload this pattern, see PR82524. */
8834 && rtx_equal_p (operands[0], operands[1])"
8835 "and{b}\t{%2, %h0|%h0, %2}"
8836 [(set_attr "isa" "*,nox64")
8837 (set_attr "type" "alu")
8838 (set_attr "mode" "QI")])
8840 (define_insn "*andqi_ext_2"
8841 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
8847 (zero_extract:SI (match_operand 1 "ext_register_operand" "%0")
8851 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
8853 (const_int 8)) 0)) 0))
8854 (clobber (reg:CC FLAGS_REG))]
8855 "/* FIXME: without this LRA can't reload this pattern, see PR82524. */
8856 rtx_equal_p (operands[0], operands[1])
8857 || rtx_equal_p (operands[0], operands[2])"
8858 "and{b}\t{%h2, %h0|%h0, %h2}"
8859 [(set_attr "type" "alu")
8860 (set_attr "mode" "QI")])
8862 ;; Convert wide AND instructions with immediate operand to shorter QImode
8863 ;; equivalents when possible.
8864 ;; Don't do the splitting with memory operands, since it introduces risk
8865 ;; of memory mismatch stalls. We may want to do the splitting for optimizing
8866 ;; for size, but that can (should?) be handled by generic code instead.
8868 [(set (match_operand:SWI248 0 "QIreg_operand")
8869 (and:SWI248 (match_operand:SWI248 1 "register_operand")
8870 (match_operand:SWI248 2 "const_int_operand")))
8871 (clobber (reg:CC FLAGS_REG))]
8873 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8874 && !(~INTVAL (operands[2]) & ~(255 << 8))"
8876 [(set (zero_extract:SI (match_dup 0)
8882 (zero_extract:SI (match_dup 1)
8886 (clobber (reg:CC FLAGS_REG))])]
8888 operands[0] = gen_lowpart (SImode, operands[0]);
8889 operands[1] = gen_lowpart (SImode, operands[1]);
8890 operands[2] = gen_int_mode (INTVAL (operands[2]) >> 8, QImode);
8893 ;; Since AND can be encoded with sign extended immediate, this is only
8894 ;; profitable when 7th bit is not set.
8896 [(set (match_operand:SWI248 0 "any_QIreg_operand")
8897 (and:SWI248 (match_operand:SWI248 1 "general_operand")
8898 (match_operand:SWI248 2 "const_int_operand")))
8899 (clobber (reg:CC FLAGS_REG))]
8901 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8902 && !(~INTVAL (operands[2]) & ~255)
8903 && !(INTVAL (operands[2]) & 128)"
8904 [(parallel [(set (strict_low_part (match_dup 0))
8905 (and:QI (match_dup 1)
8907 (clobber (reg:CC FLAGS_REG))])]
8909 operands[0] = gen_lowpart (QImode, operands[0]);
8910 operands[1] = gen_lowpart (QImode, operands[1]);
8911 operands[2] = gen_int_mode (INTVAL (operands[2]), QImode);
8914 (define_insn "*andndi3_doubleword"
8915 [(set (match_operand:DI 0 "register_operand" "=&r,r,r,&r")
8917 (not:DI (match_operand:DI 1 "register_operand" "r,0,r,0"))
8918 (match_operand:DI 2 "nonimmediate_operand" "rm,rm,0,rm")))
8919 (clobber (reg:CC FLAGS_REG))]
8920 "!TARGET_64BIT && TARGET_STV && TARGET_SSE2"
8922 [(set_attr "isa" "bmi,bmi,bmi,*")])
8925 [(set (match_operand:DI 0 "register_operand")
8927 (not:DI (match_operand:DI 1 "register_operand"))
8928 (match_operand:DI 2 "nonimmediate_operand")))
8929 (clobber (reg:CC FLAGS_REG))]
8930 "!TARGET_64BIT && TARGET_BMI && TARGET_STV && TARGET_SSE2
8931 && reload_completed"
8932 [(parallel [(set (match_dup 0)
8933 (and:SI (not:SI (match_dup 1)) (match_dup 2)))
8934 (clobber (reg:CC FLAGS_REG))])
8935 (parallel [(set (match_dup 3)
8936 (and:SI (not:SI (match_dup 4)) (match_dup 5)))
8937 (clobber (reg:CC FLAGS_REG))])]
8938 "split_double_mode (DImode, &operands[0], 3, &operands[0], &operands[3]);")
8941 [(set (match_operand:DI 0 "register_operand")
8943 (not:DI (match_dup 0))
8944 (match_operand:DI 1 "nonimmediate_operand")))
8945 (clobber (reg:CC FLAGS_REG))]
8946 "!TARGET_64BIT && !TARGET_BMI && TARGET_STV && TARGET_SSE2
8947 && reload_completed"
8948 [(set (match_dup 0) (not:SI (match_dup 0)))
8949 (parallel [(set (match_dup 0)
8950 (and:SI (match_dup 0) (match_dup 1)))
8951 (clobber (reg:CC FLAGS_REG))])
8952 (set (match_dup 2) (not:SI (match_dup 2)))
8953 (parallel [(set (match_dup 2)
8954 (and:SI (match_dup 2) (match_dup 3)))
8955 (clobber (reg:CC FLAGS_REG))])]
8956 "split_double_mode (DImode, &operands[0], 2, &operands[0], &operands[2]);")
8958 (define_insn "*andn<mode>_1"
8959 [(set (match_operand:SWI48 0 "register_operand" "=r,r")
8961 (not:SWI48 (match_operand:SWI48 1 "register_operand" "r,r"))
8962 (match_operand:SWI48 2 "nonimmediate_operand" "r,m")))
8963 (clobber (reg:CC FLAGS_REG))]
8965 "andn\t{%2, %1, %0|%0, %1, %2}"
8966 [(set_attr "type" "bitmanip")
8967 (set_attr "btver2_decode" "direct, double")
8968 (set_attr "mode" "<MODE>")])
8970 (define_insn "*andn<mode>_1"
8971 [(set (match_operand:SWI12 0 "register_operand" "=r")
8973 (not:SWI12 (match_operand:SWI12 1 "register_operand" "r"))
8974 (match_operand:SWI12 2 "register_operand" "r")))
8975 (clobber (reg:CC FLAGS_REG))]
8977 "andn\t{%k2, %k1, %k0|%k0, %k1, %k2}"
8978 [(set_attr "type" "bitmanip")
8979 (set_attr "btver2_decode" "direct")
8980 (set_attr "mode" "SI")])
8982 (define_insn "*andn_<mode>_ccno"
8983 [(set (reg FLAGS_REG)
8986 (not:SWI48 (match_operand:SWI48 1 "register_operand" "r,r"))
8987 (match_operand:SWI48 2 "nonimmediate_operand" "r,m"))
8989 (clobber (match_scratch:SWI48 0 "=r,r"))]
8990 "TARGET_BMI && ix86_match_ccmode (insn, CCNOmode)"
8991 "andn\t{%2, %1, %0|%0, %1, %2}"
8992 [(set_attr "type" "bitmanip")
8993 (set_attr "btver2_decode" "direct, double")
8994 (set_attr "mode" "<MODE>")])
8996 ;; Logical inclusive and exclusive OR instructions
8998 ;; %%% This used to optimize known byte-wide and operations to memory.
8999 ;; If this is considered useful, it should be done with splitters.
9001 (define_expand "<code><mode>3"
9002 [(set (match_operand:SWIM1248x 0 "nonimmediate_operand")
9003 (any_or:SWIM1248x (match_operand:SWIM1248x 1 "nonimmediate_operand")
9004 (match_operand:SWIM1248x 2 "<general_operand>")))]
9006 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
9008 (define_insn_and_split "*<code>di3_doubleword"
9009 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r")
9011 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
9012 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm")))
9013 (clobber (reg:CC FLAGS_REG))]
9014 "!TARGET_64BIT && TARGET_STV && TARGET_SSE2
9015 && ix86_binary_operator_ok (<CODE>, DImode, operands)"
9017 "&& reload_completed"
9020 split_double_mode (DImode, &operands[0], 3, &operands[0], &operands[3]);
9021 if (operands[2] == constm1_rtx)
9025 operands[1] = constm1_rtx;
9026 ix86_expand_move (SImode, &operands[0]);
9029 ix86_expand_unary_operator (NOT, SImode, &operands[0]);
9031 else if (operands[2] != const0_rtx)
9032 ix86_expand_binary_operator (<CODE>, SImode, &operands[0]);
9033 else if (operands[5] == const0_rtx)
9034 emit_note (NOTE_INSN_DELETED);
9035 if (operands[5] == constm1_rtx)
9039 operands[4] = constm1_rtx;
9040 ix86_expand_move (SImode, &operands[3]);
9043 ix86_expand_unary_operator (NOT, SImode, &operands[3]);
9045 else if (operands[5] != const0_rtx)
9046 ix86_expand_binary_operator (<CODE>, SImode, &operands[3]);
9050 (define_insn "*<code><mode>_1"
9051 [(set (match_operand:SWI248 0 "nonimmediate_operand" "=r,rm")
9053 (match_operand:SWI248 1 "nonimmediate_operand" "%0,0")
9054 (match_operand:SWI248 2 "<general_operand>" "<g>,r<i>")))
9055 (clobber (reg:CC FLAGS_REG))]
9056 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9057 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
9058 [(set_attr "type" "alu")
9059 (set_attr "mode" "<MODE>")])
9061 (define_insn_and_split "*iordi_1_bts"
9062 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9064 (match_operand:DI 1 "nonimmediate_operand" "%0")
9065 (match_operand:DI 2 "const_int_operand" "n")))
9066 (clobber (reg:CC FLAGS_REG))]
9067 "TARGET_64BIT && TARGET_USE_BT
9068 && ix86_binary_operator_ok (IOR, DImode, operands)
9069 && IN_RANGE (exact_log2 (INTVAL (operands[2])), 31, 63)"
9071 "&& reload_completed"
9072 [(parallel [(set (zero_extract:DI (match_dup 0)
9076 (clobber (reg:CC FLAGS_REG))])]
9077 "operands[3] = GEN_INT (exact_log2 (INTVAL (operands[2])));"
9078 [(set_attr "type" "alu1")
9079 (set_attr "prefix_0f" "1")
9080 (set_attr "znver1_decode" "double")
9081 (set_attr "mode" "DI")])
9083 (define_insn_and_split "*xordi_1_btc"
9084 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9086 (match_operand:DI 1 "nonimmediate_operand" "%0")
9087 (match_operand:DI 2 "const_int_operand" "n")))
9088 (clobber (reg:CC FLAGS_REG))]
9089 "TARGET_64BIT && TARGET_USE_BT
9090 && ix86_binary_operator_ok (XOR, DImode, operands)
9091 && IN_RANGE (exact_log2 (INTVAL (operands[2])), 31, 63)"
9093 "&& reload_completed"
9094 [(parallel [(set (zero_extract:DI (match_dup 0)
9097 (not:DI (zero_extract:DI (match_dup 0)
9100 (clobber (reg:CC FLAGS_REG))])]
9101 "operands[3] = GEN_INT (exact_log2 (INTVAL (operands[2])));"
9102 [(set_attr "type" "alu1")
9103 (set_attr "prefix_0f" "1")
9104 (set_attr "znver1_decode" "double")
9105 (set_attr "mode" "DI")])
9107 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9108 (define_insn "*<code>si_1_zext"
9109 [(set (match_operand:DI 0 "register_operand" "=r")
9111 (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9112 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
9113 (clobber (reg:CC FLAGS_REG))]
9114 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
9115 "<logic>{l}\t{%2, %k0|%k0, %2}"
9116 [(set_attr "type" "alu")
9117 (set_attr "mode" "SI")])
9119 (define_insn "*<code>si_1_zext_imm"
9120 [(set (match_operand:DI 0 "register_operand" "=r")
9122 (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
9123 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
9124 (clobber (reg:CC FLAGS_REG))]
9125 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
9126 "<logic>{l}\t{%2, %k0|%k0, %2}"
9127 [(set_attr "type" "alu")
9128 (set_attr "mode" "SI")])
9130 (define_insn "*<code>qi_1"
9131 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
9132 (any_or:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9133 (match_operand:QI 2 "general_operand" "qmn,qn,rn")))
9134 (clobber (reg:CC FLAGS_REG))]
9135 "ix86_binary_operator_ok (<CODE>, QImode, operands)"
9137 <logic>{b}\t{%2, %0|%0, %2}
9138 <logic>{b}\t{%2, %0|%0, %2}
9139 <logic>{l}\t{%k2, %k0|%k0, %k2}"
9140 [(set_attr "type" "alu")
9141 (set_attr "mode" "QI,QI,SI")
9142 ;; Potential partial reg stall on alternative 2.
9143 (set (attr "preferred_for_speed")
9144 (cond [(eq_attr "alternative" "2")
9145 (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
9146 (symbol_ref "true")))])
9148 (define_insn "*<code>qi_1_slp"
9149 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
9150 (any_or:QI (match_dup 0)
9151 (match_operand:QI 1 "general_operand" "qmn,qn")))
9152 (clobber (reg:CC FLAGS_REG))]
9153 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9154 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9155 "<logic>{b}\t{%1, %0|%0, %1}"
9156 [(set_attr "type" "alu1")
9157 (set_attr "mode" "QI")])
9159 (define_insn "*<code><mode>_2"
9160 [(set (reg FLAGS_REG)
9161 (compare (any_or:SWI
9162 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
9163 (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>"))
9165 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
9166 (any_or:SWI (match_dup 1) (match_dup 2)))]
9167 "ix86_match_ccmode (insn, CCNOmode)
9168 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9169 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
9170 [(set_attr "type" "alu")
9171 (set_attr "mode" "<MODE>")])
9173 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9174 ;; ??? Special case for immediate operand is missing - it is tricky.
9175 (define_insn "*<code>si_2_zext"
9176 [(set (reg FLAGS_REG)
9177 (compare (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9178 (match_operand:SI 2 "x86_64_general_operand" "rme"))
9180 (set (match_operand:DI 0 "register_operand" "=r")
9181 (zero_extend:DI (any_or:SI (match_dup 1) (match_dup 2))))]
9182 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9183 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
9184 "<logic>{l}\t{%2, %k0|%k0, %2}"
9185 [(set_attr "type" "alu")
9186 (set_attr "mode" "SI")])
9188 (define_insn "*<code>si_2_zext_imm"
9189 [(set (reg FLAGS_REG)
9191 (match_operand:SI 1 "nonimmediate_operand" "%0")
9192 (match_operand:SI 2 "x86_64_zext_immediate_operand" "Z"))
9194 (set (match_operand:DI 0 "register_operand" "=r")
9195 (any_or:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
9196 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9197 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
9198 "<logic>{l}\t{%2, %k0|%k0, %2}"
9199 [(set_attr "type" "alu")
9200 (set_attr "mode" "SI")])
9202 (define_insn "*<code>qi_2_slp"
9203 [(set (reg FLAGS_REG)
9204 (compare (any_or:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9205 (match_operand:QI 1 "general_operand" "qmn,qn"))
9207 (set (strict_low_part (match_dup 0))
9208 (any_or:QI (match_dup 0) (match_dup 1)))]
9209 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9210 && ix86_match_ccmode (insn, CCNOmode)
9211 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9212 "<logic>{b}\t{%1, %0|%0, %1}"
9213 [(set_attr "type" "alu1")
9214 (set_attr "mode" "QI")])
9216 (define_insn "*<code><mode>_3"
9217 [(set (reg FLAGS_REG)
9218 (compare (any_or:SWI
9219 (match_operand:SWI 1 "nonimmediate_operand" "%0")
9220 (match_operand:SWI 2 "<general_operand>" "<g>"))
9222 (clobber (match_scratch:SWI 0 "=<r>"))]
9223 "ix86_match_ccmode (insn, CCNOmode)
9224 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9225 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
9226 [(set_attr "type" "alu")
9227 (set_attr "mode" "<MODE>")])
9229 (define_insn "*<code>qi_ext_1"
9230 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q,Q")
9236 (zero_extract:SI (match_operand 1 "ext_register_operand" "0,0")
9239 (match_operand:QI 2 "general_operand" "QnBc,m")) 0))
9240 (clobber (reg:CC FLAGS_REG))]
9241 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9242 /* FIXME: without this LRA can't reload this pattern, see PR82524. */
9243 && rtx_equal_p (operands[0], operands[1])"
9244 "<logic>{b}\t{%2, %h0|%h0, %2}"
9245 [(set_attr "isa" "*,nox64")
9246 (set_attr "type" "alu")
9247 (set_attr "mode" "QI")])
9249 (define_insn "*<code>qi_ext_2"
9250 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
9256 (zero_extract:SI (match_operand 1 "ext_register_operand" "%0")
9260 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9262 (const_int 8)) 0)) 0))
9263 (clobber (reg:CC FLAGS_REG))]
9264 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9265 /* FIXME: without this LRA can't reload this pattern, see PR82524. */
9266 && (rtx_equal_p (operands[0], operands[1])
9267 || rtx_equal_p (operands[0], operands[2]))"
9268 "<logic>{b}\t{%h2, %h0|%h0, %h2}"
9269 [(set_attr "type" "alu")
9270 (set_attr "mode" "QI")])
9272 ;; Convert wide OR instructions with immediate operand to shorter QImode
9273 ;; equivalents when possible.
9274 ;; Don't do the splitting with memory operands, since it introduces risk
9275 ;; of memory mismatch stalls. We may want to do the splitting for optimizing
9276 ;; for size, but that can (should?) be handled by generic code instead.
9278 [(set (match_operand:SWI248 0 "QIreg_operand")
9279 (any_or:SWI248 (match_operand:SWI248 1 "register_operand")
9280 (match_operand:SWI248 2 "const_int_operand")))
9281 (clobber (reg:CC FLAGS_REG))]
9283 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9284 && !(INTVAL (operands[2]) & ~(255 << 8))"
9286 [(set (zero_extract:SI (match_dup 0)
9292 (zero_extract:SI (match_dup 1)
9296 (clobber (reg:CC FLAGS_REG))])]
9298 operands[0] = gen_lowpart (SImode, operands[0]);
9299 operands[1] = gen_lowpart (SImode, operands[1]);
9300 operands[2] = gen_int_mode (INTVAL (operands[2]) >> 8, QImode);
9303 ;; Since OR can be encoded with sign extended immediate, this is only
9304 ;; profitable when 7th bit is set.
9306 [(set (match_operand:SWI248 0 "any_QIreg_operand")
9307 (any_or:SWI248 (match_operand:SWI248 1 "general_operand")
9308 (match_operand:SWI248 2 "const_int_operand")))
9309 (clobber (reg:CC FLAGS_REG))]
9311 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9312 && !(INTVAL (operands[2]) & ~255)
9313 && (INTVAL (operands[2]) & 128)"
9314 [(parallel [(set (strict_low_part (match_dup 0))
9315 (any_or:QI (match_dup 1)
9317 (clobber (reg:CC FLAGS_REG))])]
9319 operands[0] = gen_lowpart (QImode, operands[0]);
9320 operands[1] = gen_lowpart (QImode, operands[1]);
9321 operands[2] = gen_int_mode (INTVAL (operands[2]), QImode);
9324 (define_expand "xorqi_ext_1_cc"
9326 (set (reg:CCNO FLAGS_REG)
9330 (zero_extract:SI (match_operand 1 "ext_register_operand")
9333 (match_operand 2 "const_int_operand"))
9335 (set (zero_extract:SI (match_operand 0 "ext_register_operand")
9341 (zero_extract:SI (match_dup 1)
9344 (match_dup 2)) 0))])])
9346 (define_insn "*xorqi_ext_1_cc"
9347 [(set (reg FLAGS_REG)
9351 (zero_extract:SI (match_operand 1 "ext_register_operand" "0,0")
9354 (match_operand:QI 2 "general_operand" "QnBc,m"))
9356 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q,Q")
9362 (zero_extract:SI (match_dup 1)
9366 "ix86_match_ccmode (insn, CCNOmode)
9367 /* FIXME: without this LRA can't reload this pattern, see PR82524. */
9368 && rtx_equal_p (operands[0], operands[1])"
9369 "xor{b}\t{%2, %h0|%h0, %2}"
9370 [(set_attr "isa" "*,nox64")
9371 (set_attr "type" "alu")
9372 (set_attr "mode" "QI")])
9374 ;; Negation instructions
9376 (define_expand "neg<mode>2"
9377 [(set (match_operand:SDWIM 0 "nonimmediate_operand")
9378 (neg:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")))]
9380 "ix86_expand_unary_operator (NEG, <MODE>mode, operands); DONE;")
9382 (define_insn_and_split "*neg<dwi>2_doubleword"
9383 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro")
9384 (neg:<DWI> (match_operand:<DWI> 1 "nonimmediate_operand" "0")))
9385 (clobber (reg:CC FLAGS_REG))]
9386 "ix86_unary_operator_ok (NEG, <DWI>mode, operands)"
9390 [(set (reg:CCZ FLAGS_REG)
9391 (compare:CCZ (neg:DWIH (match_dup 1)) (const_int 0)))
9392 (set (match_dup 0) (neg:DWIH (match_dup 1)))])
9395 (plus:DWIH (plus:DWIH (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
9398 (clobber (reg:CC FLAGS_REG))])
9401 (neg:DWIH (match_dup 2)))
9402 (clobber (reg:CC FLAGS_REG))])]
9403 "split_double_mode (<DWI>mode, &operands[0], 2, &operands[0], &operands[2]);")
9405 (define_insn "*neg<mode>2_1"
9406 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9407 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")))
9408 (clobber (reg:CC FLAGS_REG))]
9409 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
9410 "neg{<imodesuffix>}\t%0"
9411 [(set_attr "type" "negnot")
9412 (set_attr "mode" "<MODE>")])
9414 ;; Combine is quite creative about this pattern.
9415 (define_insn "*negsi2_1_zext"
9416 [(set (match_operand:DI 0 "register_operand" "=r")
9418 (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
9421 (clobber (reg:CC FLAGS_REG))]
9422 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9424 [(set_attr "type" "negnot")
9425 (set_attr "mode" "SI")])
9427 ;; The problem with neg is that it does not perform (compare x 0),
9428 ;; it really performs (compare 0 x), which leaves us with the zero
9429 ;; flag being the only useful item.
9431 (define_insn "*neg<mode>2_cmpz"
9432 [(set (reg:CCZ FLAGS_REG)
9434 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
9436 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9437 (neg:SWI (match_dup 1)))]
9438 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
9439 "neg{<imodesuffix>}\t%0"
9440 [(set_attr "type" "negnot")
9441 (set_attr "mode" "<MODE>")])
9443 (define_insn "*negsi2_cmpz_zext"
9444 [(set (reg:CCZ FLAGS_REG)
9448 (match_operand:DI 1 "register_operand" "0")
9452 (set (match_operand:DI 0 "register_operand" "=r")
9453 (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
9456 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9458 [(set_attr "type" "negnot")
9459 (set_attr "mode" "SI")])
9461 ;; Negate with jump on overflow.
9462 (define_expand "negv<mode>3"
9463 [(parallel [(set (reg:CCO FLAGS_REG)
9464 (ne:CCO (match_operand:SWI 1 "register_operand")
9466 (set (match_operand:SWI 0 "register_operand")
9467 (neg:SWI (match_dup 1)))])
9468 (set (pc) (if_then_else
9469 (eq (reg:CCO FLAGS_REG) (const_int 0))
9470 (label_ref (match_operand 2))
9475 = gen_int_mode (HOST_WIDE_INT_1U << (GET_MODE_BITSIZE (<MODE>mode) - 1),
9479 (define_insn "*negv<mode>3"
9480 [(set (reg:CCO FLAGS_REG)
9481 (ne:CCO (match_operand:SWI 1 "nonimmediate_operand" "0")
9482 (match_operand:SWI 2 "const_int_operand")))
9483 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9484 (neg:SWI (match_dup 1)))]
9485 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)
9486 && mode_signbit_p (<MODE>mode, operands[2])"
9487 "neg{<imodesuffix>}\t%0"
9488 [(set_attr "type" "negnot")
9489 (set_attr "mode" "<MODE>")])
9491 ;; Changing of sign for FP values is doable using integer unit too.
9493 (define_expand "<code><mode>2"
9494 [(set (match_operand:X87MODEF 0 "register_operand")
9495 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand")))]
9496 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
9497 "ix86_expand_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
9499 (define_insn "*absneg<mode>2"
9500 [(set (match_operand:MODEF 0 "register_operand" "=Yv,Yv,f,!r")
9501 (match_operator:MODEF 3 "absneg_operator"
9502 [(match_operand:MODEF 1 "register_operand" "0,Yv,0,0")]))
9503 (use (match_operand:<ssevecmode> 2 "nonimmediate_operand" "Yvm,0,X,X"))
9504 (clobber (reg:CC FLAGS_REG))]
9505 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
9507 [(set (attr "enabled")
9509 (match_test ("SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"))
9511 (eq_attr "alternative" "2")
9512 (symbol_ref "TARGET_MIX_SSE_I387")
9513 (symbol_ref "true"))
9515 (eq_attr "alternative" "2,3")
9517 (symbol_ref "false"))))])
9519 (define_insn "*absnegxf2_i387"
9520 [(set (match_operand:XF 0 "register_operand" "=f,!r")
9521 (match_operator:XF 3 "absneg_operator"
9522 [(match_operand:XF 1 "register_operand" "0,0")]))
9523 (use (match_operand 2))
9524 (clobber (reg:CC FLAGS_REG))]
9528 (define_expand "<code>tf2"
9529 [(set (match_operand:TF 0 "register_operand")
9530 (absneg:TF (match_operand:TF 1 "register_operand")))]
9532 "ix86_expand_fp_absneg_operator (<CODE>, TFmode, operands); DONE;")
9534 (define_insn "*absnegtf2_sse"
9535 [(set (match_operand:TF 0 "register_operand" "=Yv,Yv")
9536 (match_operator:TF 3 "absneg_operator"
9537 [(match_operand:TF 1 "register_operand" "0,Yv")]))
9538 (use (match_operand:TF 2 "nonimmediate_operand" "Yvm,0"))
9539 (clobber (reg:CC FLAGS_REG))]
9543 ;; Splitters for fp abs and neg.
9546 [(set (match_operand 0 "fp_register_operand")
9547 (match_operator 1 "absneg_operator" [(match_dup 0)]))
9548 (use (match_operand 2))
9549 (clobber (reg:CC FLAGS_REG))]
9551 [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
9554 [(set (match_operand 0 "sse_reg_operand")
9555 (match_operator 3 "absneg_operator"
9556 [(match_operand 1 "register_operand")]))
9557 (use (match_operand 2 "nonimmediate_operand"))
9558 (clobber (reg:CC FLAGS_REG))]
9560 [(set (match_dup 0) (match_dup 3))]
9562 machine_mode mode = GET_MODE (operands[0]);
9563 machine_mode vmode = GET_MODE (operands[2]);
9566 operands[0] = lowpart_subreg (vmode, operands[0], mode);
9567 operands[1] = lowpart_subreg (vmode, operands[1], mode);
9568 if (operands_match_p (operands[0], operands[2]))
9569 std::swap (operands[1], operands[2]);
9570 if (GET_CODE (operands[3]) == ABS)
9571 tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
9573 tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
9578 [(set (match_operand:SF 0 "general_reg_operand")
9579 (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
9580 (use (match_operand:V4SF 2))
9581 (clobber (reg:CC FLAGS_REG))]
9583 [(parallel [(set (match_dup 0) (match_dup 1))
9584 (clobber (reg:CC FLAGS_REG))])]
9587 operands[0] = gen_lowpart (SImode, operands[0]);
9588 if (GET_CODE (operands[1]) == ABS)
9590 tmp = gen_int_mode (0x7fffffff, SImode);
9591 tmp = gen_rtx_AND (SImode, operands[0], tmp);
9595 tmp = gen_int_mode (0x80000000, SImode);
9596 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9602 [(set (match_operand:DF 0 "general_reg_operand")
9603 (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
9604 (use (match_operand 2))
9605 (clobber (reg:CC FLAGS_REG))]
9607 [(parallel [(set (match_dup 0) (match_dup 1))
9608 (clobber (reg:CC FLAGS_REG))])]
9613 tmp = gen_lowpart (DImode, operands[0]);
9614 tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
9617 if (GET_CODE (operands[1]) == ABS)
9620 tmp = gen_rtx_NOT (DImode, tmp);
9624 operands[0] = gen_highpart (SImode, operands[0]);
9625 if (GET_CODE (operands[1]) == ABS)
9627 tmp = gen_int_mode (0x7fffffff, SImode);
9628 tmp = gen_rtx_AND (SImode, operands[0], tmp);
9632 tmp = gen_int_mode (0x80000000, SImode);
9633 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9640 [(set (match_operand:XF 0 "general_reg_operand")
9641 (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
9642 (use (match_operand 2))
9643 (clobber (reg:CC FLAGS_REG))]
9645 [(parallel [(set (match_dup 0) (match_dup 1))
9646 (clobber (reg:CC FLAGS_REG))])]
9649 operands[0] = gen_rtx_REG (SImode,
9650 REGNO (operands[0]) + (TARGET_64BIT ? 1 : 2));
9651 if (GET_CODE (operands[1]) == ABS)
9653 tmp = GEN_INT (0x7fff);
9654 tmp = gen_rtx_AND (SImode, operands[0], tmp);
9658 tmp = GEN_INT (0x8000);
9659 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9664 ;; Conditionalize these after reload. If they match before reload, we
9665 ;; lose the clobber and ability to use integer instructions.
9667 (define_insn "*<code><mode>2_1"
9668 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
9669 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "0")))]
9671 && (reload_completed
9672 || !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
9674 [(set_attr "type" "fsgn")
9675 (set_attr "mode" "<MODE>")])
9677 ;; Copysign instructions
9679 (define_mode_iterator CSGNMODE [SF DF TF])
9680 (define_mode_attr CSGNVMODE [(SF "V4SF") (DF "V2DF") (TF "TF")])
9682 (define_expand "copysign<mode>3"
9683 [(match_operand:CSGNMODE 0 "register_operand")
9684 (match_operand:CSGNMODE 1 "nonmemory_operand")
9685 (match_operand:CSGNMODE 2 "register_operand")]
9686 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
9687 || (TARGET_SSE && (<MODE>mode == TFmode))"
9688 "ix86_expand_copysign (operands); DONE;")
9690 (define_insn_and_split "copysign<mode>3_const"
9691 [(set (match_operand:CSGNMODE 0 "register_operand" "=Yv")
9693 [(match_operand:<CSGNVMODE> 1 "nonimm_or_0_operand" "YvmC")
9694 (match_operand:CSGNMODE 2 "register_operand" "0")
9695 (match_operand:<CSGNVMODE> 3 "nonimmediate_operand" "Yvm")]
9697 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
9698 || (TARGET_SSE && (<MODE>mode == TFmode))"
9700 "&& reload_completed"
9702 "ix86_split_copysign_const (operands); DONE;")
9704 (define_insn "copysign<mode>3_var"
9705 [(set (match_operand:CSGNMODE 0 "register_operand" "=Yv,Yv,Yv,Yv,Yv")
9707 [(match_operand:CSGNMODE 2 "register_operand" "Yv,0,0,Yv,Yv")
9708 (match_operand:CSGNMODE 3 "register_operand" "1,1,Yv,1,Yv")
9709 (match_operand:<CSGNVMODE> 4
9710 "nonimmediate_operand" "X,Yvm,Yvm,0,0")
9711 (match_operand:<CSGNVMODE> 5
9712 "nonimmediate_operand" "0,Yvm,1,Yvm,1")]
9714 (clobber (match_scratch:<CSGNVMODE> 1 "=Yv,Yv,Yv,Yv,Yv"))]
9715 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
9716 || (TARGET_SSE && (<MODE>mode == TFmode))"
9720 [(set (match_operand:CSGNMODE 0 "register_operand")
9722 [(match_operand:CSGNMODE 2 "register_operand")
9723 (match_operand:CSGNMODE 3 "register_operand")
9724 (match_operand:<CSGNVMODE> 4)
9725 (match_operand:<CSGNVMODE> 5)]
9727 (clobber (match_scratch:<CSGNVMODE> 1))]
9728 "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
9729 || (TARGET_SSE && (<MODE>mode == TFmode)))
9730 && reload_completed"
9732 "ix86_split_copysign_var (operands); DONE;")
9734 (define_expand "xorsign<mode>3"
9735 [(match_operand:MODEF 0 "register_operand")
9736 (match_operand:MODEF 1 "register_operand")
9737 (match_operand:MODEF 2 "register_operand")]
9738 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
9739 "ix86_expand_xorsign (operands); DONE;")
9741 (define_insn_and_split "xorsign<mode>3_1"
9742 [(set (match_operand:MODEF 0 "register_operand" "=Yv")
9744 [(match_operand:MODEF 1 "register_operand" "Yv")
9745 (match_operand:MODEF 2 "register_operand" "0")
9746 (match_operand:<ssevecmode> 3 "nonimmediate_operand" "Yvm")]
9748 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
9750 "&& reload_completed"
9752 "ix86_split_xorsign (operands); DONE;")
9754 ;; One complement instructions
9756 (define_expand "one_cmpl<mode>2"
9757 [(set (match_operand:SWIM1248x 0 "nonimmediate_operand")
9758 (not:SWIM1248x (match_operand:SWIM1248x 1 "nonimmediate_operand")))]
9760 "ix86_expand_unary_operator (NOT, <MODE>mode, operands); DONE;")
9762 (define_insn_and_split "*one_cmpldi2_doubleword"
9763 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9764 (not:DI (match_operand:DI 1 "nonimmediate_operand" "0")))]
9765 "!TARGET_64BIT && TARGET_STV && TARGET_SSE2
9766 && ix86_unary_operator_ok (NOT, DImode, operands)"
9768 "&& reload_completed"
9770 (not:SI (match_dup 1)))
9772 (not:SI (match_dup 3)))]
9773 "split_double_mode (DImode, &operands[0], 2, &operands[0], &operands[2]);")
9775 (define_insn "*one_cmpl<mode>2_1"
9776 [(set (match_operand:SWI248 0 "nonimmediate_operand" "=rm")
9777 (not:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "0")))]
9778 "ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
9779 "not{<imodesuffix>}\t%0"
9780 [(set_attr "type" "negnot")
9781 (set_attr "mode" "<MODE>")])
9783 ;; ??? Currently never generated - xor is used instead.
9784 (define_insn "*one_cmplsi2_1_zext"
9785 [(set (match_operand:DI 0 "register_operand" "=r")
9787 (not:SI (match_operand:SI 1 "register_operand" "0"))))]
9788 "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
9790 [(set_attr "type" "negnot")
9791 (set_attr "mode" "SI")])
9793 (define_insn "*one_cmplqi2_1"
9794 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
9795 (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
9796 "ix86_unary_operator_ok (NOT, QImode, operands)"
9800 [(set_attr "type" "negnot")
9801 (set_attr "mode" "QI,SI")
9802 ;; Potential partial reg stall on alternative 1.
9803 (set (attr "preferred_for_speed")
9804 (cond [(eq_attr "alternative" "1")
9805 (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
9806 (symbol_ref "true")))])
9808 (define_insn "*one_cmpl<mode>2_2"
9809 [(set (reg FLAGS_REG)
9810 (compare (not:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
9812 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9813 (not:SWI (match_dup 1)))]
9814 "ix86_match_ccmode (insn, CCNOmode)
9815 && ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
9817 [(set_attr "type" "alu1")
9818 (set_attr "mode" "<MODE>")])
9821 [(set (match_operand 0 "flags_reg_operand")
9822 (match_operator 2 "compare_operator"
9823 [(not:SWI (match_operand:SWI 3 "nonimmediate_operand"))
9825 (set (match_operand:SWI 1 "nonimmediate_operand")
9826 (not:SWI (match_dup 3)))]
9827 "ix86_match_ccmode (insn, CCNOmode)"
9828 [(parallel [(set (match_dup 0)
9829 (match_op_dup 2 [(xor:SWI (match_dup 3) (const_int -1))
9832 (xor:SWI (match_dup 3) (const_int -1)))])])
9834 ;; ??? Currently never generated - xor is used instead.
9835 (define_insn "*one_cmplsi2_2_zext"
9836 [(set (reg FLAGS_REG)
9837 (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
9839 (set (match_operand:DI 0 "register_operand" "=r")
9840 (zero_extend:DI (not:SI (match_dup 1))))]
9841 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9842 && ix86_unary_operator_ok (NOT, SImode, operands)"
9844 [(set_attr "type" "alu1")
9845 (set_attr "mode" "SI")])
9848 [(set (match_operand 0 "flags_reg_operand")
9849 (match_operator 2 "compare_operator"
9850 [(not:SI (match_operand:SI 3 "register_operand"))
9852 (set (match_operand:DI 1 "register_operand")
9853 (zero_extend:DI (not:SI (match_dup 3))))]
9854 "ix86_match_ccmode (insn, CCNOmode)"
9855 [(parallel [(set (match_dup 0)
9856 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
9859 (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])])
9861 ;; Shift instructions
9863 ;; DImode shifts are implemented using the i386 "shift double" opcode,
9864 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem". If the shift count
9865 ;; is variable, then the count is in %cl and the "imm" operand is dropped
9866 ;; from the assembler input.
9868 ;; This instruction shifts the target reg/mem as usual, but instead of
9869 ;; shifting in zeros, bits are shifted in from reg operand. If the insn
9870 ;; is a left shift double, bits are taken from the high order bits of
9871 ;; reg, else if the insn is a shift right double, bits are taken from the
9872 ;; low order bits of reg. So if %eax is "1234" and %edx is "5678",
9873 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
9875 ;; Since sh[lr]d does not change the `reg' operand, that is done
9876 ;; separately, making all shifts emit pairs of shift double and normal
9877 ;; shift. Since sh[lr]d does not shift more than 31 bits, and we wish to
9878 ;; support a 63 bit shift, each shift where the count is in a reg expands
9879 ;; to a pair of shifts, a branch, a shift by 32 and a label.
9881 ;; If the shift count is a constant, we need never emit more than one
9882 ;; shift pair, instead using moves and sign extension for counts greater
9885 (define_expand "ashl<mode>3"
9886 [(set (match_operand:SDWIM 0 "<shift_operand>")
9887 (ashift:SDWIM (match_operand:SDWIM 1 "<ashl_input_operand>")
9888 (match_operand:QI 2 "nonmemory_operand")))]
9890 "ix86_expand_binary_operator (ASHIFT, <MODE>mode, operands); DONE;")
9892 (define_insn_and_split "*ashl<dwi>3_doubleword_mask"
9893 [(set (match_operand:<DWI> 0 "register_operand")
9895 (match_operand:<DWI> 1 "register_operand")
9898 (match_operand:SI 2 "register_operand" "c")
9899 (match_operand:SI 3 "const_int_operand")) 0)))
9900 (clobber (reg:CC FLAGS_REG))]
9901 "(INTVAL (operands[3]) & (<MODE_SIZE> * BITS_PER_UNIT)) == 0
9902 && can_create_pseudo_p ()"
9907 (ior:DWIH (ashift:DWIH (match_dup 6) (match_dup 2))
9908 (lshiftrt:DWIH (match_dup 5)
9909 (minus:QI (match_dup 8) (match_dup 2)))))
9910 (clobber (reg:CC FLAGS_REG))])
9913 (ashift:DWIH (match_dup 5) (match_dup 2)))
9914 (clobber (reg:CC FLAGS_REG))])]
9916 split_double_mode (<DWI>mode, &operands[0], 2, &operands[4], &operands[6]);
9918 operands[8] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT);
9920 if ((INTVAL (operands[3]) & ((<MODE_SIZE> * BITS_PER_UNIT) - 1))
9921 != ((<MODE_SIZE> * BITS_PER_UNIT) - 1))
9923 rtx tem = gen_reg_rtx (SImode);
9924 emit_insn (gen_andsi3 (tem, operands[2], operands[3]));
9928 operands[2] = gen_lowpart (QImode, operands[2]);
9930 if (!rtx_equal_p (operands[6], operands[7]))
9931 emit_move_insn (operands[6], operands[7]);
9934 (define_insn_and_split "*ashl<dwi>3_doubleword_mask_1"
9935 [(set (match_operand:<DWI> 0 "register_operand")
9937 (match_operand:<DWI> 1 "register_operand")
9939 (match_operand:QI 2 "register_operand" "c")
9940 (match_operand:QI 3 "const_int_operand"))))
9941 (clobber (reg:CC FLAGS_REG))]
9942 "(INTVAL (operands[3]) & (<MODE_SIZE> * BITS_PER_UNIT)) == 0
9943 && can_create_pseudo_p ()"
9948 (ior:DWIH (ashift:DWIH (match_dup 6) (match_dup 2))
9949 (lshiftrt:DWIH (match_dup 5)
9950 (minus:QI (match_dup 8) (match_dup 2)))))
9951 (clobber (reg:CC FLAGS_REG))])
9954 (ashift:DWIH (match_dup 5) (match_dup 2)))
9955 (clobber (reg:CC FLAGS_REG))])]
9957 split_double_mode (<DWI>mode, &operands[0], 2, &operands[4], &operands[6]);
9959 operands[8] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT);
9961 if ((INTVAL (operands[3]) & ((<MODE_SIZE> * BITS_PER_UNIT) - 1))
9962 != ((<MODE_SIZE> * BITS_PER_UNIT) - 1))
9964 rtx tem = gen_reg_rtx (QImode);
9965 emit_insn (gen_andqi3 (tem, operands[2], operands[3]));
9969 if (!rtx_equal_p (operands[6], operands[7]))
9970 emit_move_insn (operands[6], operands[7]);
9973 (define_insn "*ashl<mode>3_doubleword"
9974 [(set (match_operand:DWI 0 "register_operand" "=&r")
9975 (ashift:DWI (match_operand:DWI 1 "reg_or_pm1_operand" "0n")
9976 (match_operand:QI 2 "nonmemory_operand" "<S>c")))
9977 (clobber (reg:CC FLAGS_REG))]
9980 [(set_attr "type" "multi")])
9983 [(set (match_operand:DWI 0 "register_operand")
9984 (ashift:DWI (match_operand:DWI 1 "nonmemory_operand")
9985 (match_operand:QI 2 "nonmemory_operand")))
9986 (clobber (reg:CC FLAGS_REG))]
9987 "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
9989 "ix86_split_ashl (operands, NULL_RTX, <MODE>mode); DONE;")
9991 ;; By default we don't ask for a scratch register, because when DWImode
9992 ;; values are manipulated, registers are already at a premium. But if
9993 ;; we have one handy, we won't turn it away.
9996 [(match_scratch:DWIH 3 "r")
9997 (parallel [(set (match_operand:<DWI> 0 "register_operand")
9999 (match_operand:<DWI> 1 "nonmemory_operand")
10000 (match_operand:QI 2 "nonmemory_operand")))
10001 (clobber (reg:CC FLAGS_REG))])
10005 "ix86_split_ashl (operands, operands[3], <DWI>mode); DONE;")
10007 (define_insn "x86_64_shld"
10008 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
10009 (ior:DI (ashift:DI (match_dup 0)
10010 (match_operand:QI 2 "nonmemory_operand" "Jc"))
10011 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
10012 (minus:QI (const_int 64) (match_dup 2)))))
10013 (clobber (reg:CC FLAGS_REG))]
10015 "shld{q}\t{%s2%1, %0|%0, %1, %2}"
10016 [(set_attr "type" "ishift")
10017 (set_attr "prefix_0f" "1")
10018 (set_attr "mode" "DI")
10019 (set_attr "athlon_decode" "vector")
10020 (set_attr "amdfam10_decode" "vector")
10021 (set_attr "bdver1_decode" "vector")])
10023 (define_insn "x86_shld"
10024 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
10025 (ior:SI (ashift:SI (match_dup 0)
10026 (match_operand:QI 2 "nonmemory_operand" "Ic"))
10027 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
10028 (minus:QI (const_int 32) (match_dup 2)))))
10029 (clobber (reg:CC FLAGS_REG))]
10031 "shld{l}\t{%s2%1, %0|%0, %1, %2}"
10032 [(set_attr "type" "ishift")
10033 (set_attr "prefix_0f" "1")
10034 (set_attr "mode" "SI")
10035 (set_attr "pent_pair" "np")
10036 (set_attr "athlon_decode" "vector")
10037 (set_attr "amdfam10_decode" "vector")
10038 (set_attr "bdver1_decode" "vector")])
10040 (define_expand "x86_shift<mode>_adj_1"
10041 [(set (reg:CCZ FLAGS_REG)
10042 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand")
10045 (set (match_operand:SWI48 0 "register_operand")
10046 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
10047 (match_operand:SWI48 1 "register_operand")
10050 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
10051 (match_operand:SWI48 3 "register_operand")
10054 "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
10056 (define_expand "x86_shift<mode>_adj_2"
10057 [(use (match_operand:SWI48 0 "register_operand"))
10058 (use (match_operand:SWI48 1 "register_operand"))
10059 (use (match_operand:QI 2 "register_operand"))]
10062 rtx_code_label *label = gen_label_rtx ();
10065 emit_insn (gen_testqi_ccz_1 (operands[2],
10066 GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
10068 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
10069 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
10070 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
10071 gen_rtx_LABEL_REF (VOIDmode, label),
10073 tmp = emit_jump_insn (gen_rtx_SET (pc_rtx, tmp));
10074 JUMP_LABEL (tmp) = label;
10076 emit_move_insn (operands[0], operands[1]);
10077 ix86_expand_clear (operands[1]);
10079 emit_label (label);
10080 LABEL_NUSES (label) = 1;
10085 ;; Avoid useless masking of count operand.
10086 (define_insn_and_split "*ashl<mode>3_mask"
10087 [(set (match_operand:SWI48 0 "nonimmediate_operand")
10089 (match_operand:SWI48 1 "nonimmediate_operand")
10092 (match_operand:SI 2 "register_operand" "c,r")
10093 (match_operand:SI 3 "const_int_operand")) 0)))
10094 (clobber (reg:CC FLAGS_REG))]
10095 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)
10096 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10097 == GET_MODE_BITSIZE (<MODE>mode)-1
10098 && can_create_pseudo_p ()"
10102 [(set (match_dup 0)
10103 (ashift:SWI48 (match_dup 1)
10105 (clobber (reg:CC FLAGS_REG))])]
10106 "operands[2] = gen_lowpart (QImode, operands[2]);"
10107 [(set_attr "isa" "*,bmi2")])
10109 (define_insn_and_split "*ashl<mode>3_mask_1"
10110 [(set (match_operand:SWI48 0 "nonimmediate_operand")
10112 (match_operand:SWI48 1 "nonimmediate_operand")
10114 (match_operand:QI 2 "register_operand" "c,r")
10115 (match_operand:QI 3 "const_int_operand"))))
10116 (clobber (reg:CC FLAGS_REG))]
10117 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)
10118 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10119 == GET_MODE_BITSIZE (<MODE>mode)-1
10120 && can_create_pseudo_p ()"
10124 [(set (match_dup 0)
10125 (ashift:SWI48 (match_dup 1)
10127 (clobber (reg:CC FLAGS_REG))])]
10129 [(set_attr "isa" "*,bmi2")])
10131 (define_insn "*bmi2_ashl<mode>3_1"
10132 [(set (match_operand:SWI48 0 "register_operand" "=r")
10133 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
10134 (match_operand:SWI48 2 "register_operand" "r")))]
10136 "shlx\t{%2, %1, %0|%0, %1, %2}"
10137 [(set_attr "type" "ishiftx")
10138 (set_attr "mode" "<MODE>")])
10140 (define_insn "*ashl<mode>3_1"
10141 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r,r")
10142 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,l,rm")
10143 (match_operand:QI 2 "nonmemory_operand" "c<S>,M,r")))
10144 (clobber (reg:CC FLAGS_REG))]
10145 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
10147 switch (get_attr_type (insn))
10154 gcc_assert (operands[2] == const1_rtx);
10155 gcc_assert (rtx_equal_p (operands[0], operands[1]));
10156 return "add{<imodesuffix>}\t%0, %0";
10159 if (operands[2] == const1_rtx
10160 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10161 return "sal{<imodesuffix>}\t%0";
10163 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
10166 [(set_attr "isa" "*,*,bmi2")
10168 (cond [(eq_attr "alternative" "1")
10169 (const_string "lea")
10170 (eq_attr "alternative" "2")
10171 (const_string "ishiftx")
10172 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
10173 (match_operand 0 "register_operand"))
10174 (match_operand 2 "const1_operand"))
10175 (const_string "alu")
10177 (const_string "ishift")))
10178 (set (attr "length_immediate")
10180 (ior (eq_attr "type" "alu")
10181 (and (eq_attr "type" "ishift")
10182 (and (match_operand 2 "const1_operand")
10183 (ior (match_test "TARGET_SHIFT1")
10184 (match_test "optimize_function_for_size_p (cfun)")))))
10186 (const_string "*")))
10187 (set_attr "mode" "<MODE>")])
10189 ;; Convert shift to the shiftx pattern to avoid flags dependency.
10191 [(set (match_operand:SWI48 0 "register_operand")
10192 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
10193 (match_operand:QI 2 "register_operand")))
10194 (clobber (reg:CC FLAGS_REG))]
10195 "TARGET_BMI2 && reload_completed"
10196 [(set (match_dup 0)
10197 (ashift:SWI48 (match_dup 1) (match_dup 2)))]
10198 "operands[2] = gen_lowpart (<MODE>mode, operands[2]);")
10200 (define_insn "*bmi2_ashlsi3_1_zext"
10201 [(set (match_operand:DI 0 "register_operand" "=r")
10203 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
10204 (match_operand:SI 2 "register_operand" "r"))))]
10205 "TARGET_64BIT && TARGET_BMI2"
10206 "shlx\t{%2, %1, %k0|%k0, %1, %2}"
10207 [(set_attr "type" "ishiftx")
10208 (set_attr "mode" "SI")])
10210 (define_insn "*ashlsi3_1_zext"
10211 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
10213 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l,rm")
10214 (match_operand:QI 2 "nonmemory_operand" "cI,M,r"))))
10215 (clobber (reg:CC FLAGS_REG))]
10216 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10218 switch (get_attr_type (insn))
10225 gcc_assert (operands[2] == const1_rtx);
10226 return "add{l}\t%k0, %k0";
10229 if (operands[2] == const1_rtx
10230 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10231 return "sal{l}\t%k0";
10233 return "sal{l}\t{%2, %k0|%k0, %2}";
10236 [(set_attr "isa" "*,*,bmi2")
10238 (cond [(eq_attr "alternative" "1")
10239 (const_string "lea")
10240 (eq_attr "alternative" "2")
10241 (const_string "ishiftx")
10242 (and (match_test "TARGET_DOUBLE_WITH_ADD")
10243 (match_operand 2 "const1_operand"))
10244 (const_string "alu")
10246 (const_string "ishift")))
10247 (set (attr "length_immediate")
10249 (ior (eq_attr "type" "alu")
10250 (and (eq_attr "type" "ishift")
10251 (and (match_operand 2 "const1_operand")
10252 (ior (match_test "TARGET_SHIFT1")
10253 (match_test "optimize_function_for_size_p (cfun)")))))
10255 (const_string "*")))
10256 (set_attr "mode" "SI")])
10258 ;; Convert shift to the shiftx pattern to avoid flags dependency.
10260 [(set (match_operand:DI 0 "register_operand")
10262 (ashift:SI (match_operand:SI 1 "nonimmediate_operand")
10263 (match_operand:QI 2 "register_operand"))))
10264 (clobber (reg:CC FLAGS_REG))]
10265 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
10266 [(set (match_dup 0)
10267 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
10268 "operands[2] = gen_lowpart (SImode, operands[2]);")
10270 (define_insn "*ashlhi3_1"
10271 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,Yp")
10272 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
10273 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10274 (clobber (reg:CC FLAGS_REG))]
10275 "ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10277 switch (get_attr_type (insn))
10283 gcc_assert (operands[2] == const1_rtx);
10284 return "add{w}\t%0, %0";
10287 if (operands[2] == const1_rtx
10288 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10289 return "sal{w}\t%0";
10291 return "sal{w}\t{%2, %0|%0, %2}";
10294 [(set (attr "type")
10295 (cond [(eq_attr "alternative" "1")
10296 (const_string "lea")
10297 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
10298 (match_operand 0 "register_operand"))
10299 (match_operand 2 "const1_operand"))
10300 (const_string "alu")
10302 (const_string "ishift")))
10303 (set (attr "length_immediate")
10305 (ior (eq_attr "type" "alu")
10306 (and (eq_attr "type" "ishift")
10307 (and (match_operand 2 "const1_operand")
10308 (ior (match_test "TARGET_SHIFT1")
10309 (match_test "optimize_function_for_size_p (cfun)")))))
10311 (const_string "*")))
10312 (set_attr "mode" "HI,SI")])
10314 (define_insn "*ashlqi3_1"
10315 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,Yp")
10316 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
10317 (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
10318 (clobber (reg:CC FLAGS_REG))]
10319 "ix86_binary_operator_ok (ASHIFT, QImode, operands)"
10321 switch (get_attr_type (insn))
10327 gcc_assert (operands[2] == const1_rtx);
10328 if (REG_P (operands[1]) && !ANY_QI_REGNO_P (REGNO (operands[1])))
10329 return "add{l}\t%k0, %k0";
10331 return "add{b}\t%0, %0";
10334 if (operands[2] == const1_rtx
10335 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10337 if (get_attr_mode (insn) == MODE_SI)
10338 return "sal{l}\t%k0";
10340 return "sal{b}\t%0";
10344 if (get_attr_mode (insn) == MODE_SI)
10345 return "sal{l}\t{%2, %k0|%k0, %2}";
10347 return "sal{b}\t{%2, %0|%0, %2}";
10351 [(set (attr "type")
10352 (cond [(eq_attr "alternative" "2")
10353 (const_string "lea")
10354 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
10355 (match_operand 0 "register_operand"))
10356 (match_operand 2 "const1_operand"))
10357 (const_string "alu")
10359 (const_string "ishift")))
10360 (set (attr "length_immediate")
10362 (ior (eq_attr "type" "alu")
10363 (and (eq_attr "type" "ishift")
10364 (and (match_operand 2 "const1_operand")
10365 (ior (match_test "TARGET_SHIFT1")
10366 (match_test "optimize_function_for_size_p (cfun)")))))
10368 (const_string "*")))
10369 (set_attr "mode" "QI,SI,SI")
10370 ;; Potential partial reg stall on alternative 1.
10371 (set (attr "preferred_for_speed")
10372 (cond [(eq_attr "alternative" "1")
10373 (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
10374 (symbol_ref "true")))])
10376 (define_insn "*ashlqi3_1_slp"
10377 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10378 (ashift:QI (match_dup 0)
10379 (match_operand:QI 1 "nonmemory_operand" "cI")))
10380 (clobber (reg:CC FLAGS_REG))]
10381 "(optimize_function_for_size_p (cfun)
10382 || !TARGET_PARTIAL_FLAG_REG_STALL
10383 || (operands[1] == const1_rtx
10385 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
10387 switch (get_attr_type (insn))
10390 gcc_assert (operands[1] == const1_rtx);
10391 return "add{b}\t%0, %0";
10394 if (operands[1] == const1_rtx
10395 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10396 return "sal{b}\t%0";
10398 return "sal{b}\t{%1, %0|%0, %1}";
10401 [(set (attr "type")
10402 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
10403 (match_operand 0 "register_operand"))
10404 (match_operand 1 "const1_operand"))
10405 (const_string "alu1")
10407 (const_string "ishift1")))
10408 (set (attr "length_immediate")
10410 (ior (eq_attr "type" "alu1")
10411 (and (eq_attr "type" "ishift1")
10412 (and (match_operand 1 "const1_operand")
10413 (ior (match_test "TARGET_SHIFT1")
10414 (match_test "optimize_function_for_size_p (cfun)")))))
10416 (const_string "*")))
10417 (set_attr "mode" "QI")])
10419 ;; Convert ashift to the lea pattern to avoid flags dependency.
10421 [(set (match_operand:SWI 0 "register_operand")
10422 (ashift:SWI (match_operand:SWI 1 "index_register_operand")
10423 (match_operand 2 "const_0_to_3_operand")))
10424 (clobber (reg:CC FLAGS_REG))]
10426 && REGNO (operands[0]) != REGNO (operands[1])"
10427 [(set (match_dup 0)
10428 (mult:<LEAMODE> (match_dup 1) (match_dup 2)))]
10430 if (<MODE>mode != <LEAMODE>mode)
10432 operands[0] = gen_lowpart (<LEAMODE>mode, operands[0]);
10433 operands[1] = gen_lowpart (<LEAMODE>mode, operands[1]);
10435 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
10438 ;; Convert ashift to the lea pattern to avoid flags dependency.
10440 [(set (match_operand:DI 0 "register_operand")
10442 (ashift:SI (match_operand:SI 1 "index_register_operand")
10443 (match_operand 2 "const_0_to_3_operand"))))
10444 (clobber (reg:CC FLAGS_REG))]
10445 "TARGET_64BIT && reload_completed
10446 && REGNO (operands[0]) != REGNO (operands[1])"
10447 [(set (match_dup 0)
10448 (zero_extend:DI (mult:SI (match_dup 1) (match_dup 2))))]
10450 operands[1] = gen_lowpart (SImode, operands[1]);
10451 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
10454 ;; This pattern can't accept a variable shift count, since shifts by
10455 ;; zero don't affect the flags. We assume that shifts by constant
10456 ;; zero are optimized away.
10457 (define_insn "*ashl<mode>3_cmp"
10458 [(set (reg FLAGS_REG)
10460 (ashift:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
10461 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
10463 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
10464 (ashift:SWI (match_dup 1) (match_dup 2)))]
10465 "(optimize_function_for_size_p (cfun)
10466 || !TARGET_PARTIAL_FLAG_REG_STALL
10467 || (operands[2] == const1_rtx
10469 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
10470 && ix86_match_ccmode (insn, CCGOCmode)
10471 && ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
10473 switch (get_attr_type (insn))
10476 gcc_assert (operands[2] == const1_rtx);
10477 return "add{<imodesuffix>}\t%0, %0";
10480 if (operands[2] == const1_rtx
10481 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10482 return "sal{<imodesuffix>}\t%0";
10484 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
10487 [(set (attr "type")
10488 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
10489 (match_operand 0 "register_operand"))
10490 (match_operand 2 "const1_operand"))
10491 (const_string "alu")
10493 (const_string "ishift")))
10494 (set (attr "length_immediate")
10496 (ior (eq_attr "type" "alu")
10497 (and (eq_attr "type" "ishift")
10498 (and (match_operand 2 "const1_operand")
10499 (ior (match_test "TARGET_SHIFT1")
10500 (match_test "optimize_function_for_size_p (cfun)")))))
10502 (const_string "*")))
10503 (set_attr "mode" "<MODE>")])
10505 (define_insn "*ashlsi3_cmp_zext"
10506 [(set (reg FLAGS_REG)
10508 (ashift:SI (match_operand:SI 1 "register_operand" "0")
10509 (match_operand:QI 2 "const_1_to_31_operand" "I"))
10511 (set (match_operand:DI 0 "register_operand" "=r")
10512 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
10514 && (optimize_function_for_size_p (cfun)
10515 || !TARGET_PARTIAL_FLAG_REG_STALL
10516 || (operands[2] == const1_rtx
10518 || TARGET_DOUBLE_WITH_ADD)))
10519 && ix86_match_ccmode (insn, CCGOCmode)
10520 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10522 switch (get_attr_type (insn))
10525 gcc_assert (operands[2] == const1_rtx);
10526 return "add{l}\t%k0, %k0";
10529 if (operands[2] == const1_rtx
10530 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10531 return "sal{l}\t%k0";
10533 return "sal{l}\t{%2, %k0|%k0, %2}";
10536 [(set (attr "type")
10537 (cond [(and (match_test "TARGET_DOUBLE_WITH_ADD")
10538 (match_operand 2 "const1_operand"))
10539 (const_string "alu")
10541 (const_string "ishift")))
10542 (set (attr "length_immediate")
10544 (ior (eq_attr "type" "alu")
10545 (and (eq_attr "type" "ishift")
10546 (and (match_operand 2 "const1_operand")
10547 (ior (match_test "TARGET_SHIFT1")
10548 (match_test "optimize_function_for_size_p (cfun)")))))
10550 (const_string "*")))
10551 (set_attr "mode" "SI")])
10553 (define_insn "*ashl<mode>3_cconly"
10554 [(set (reg FLAGS_REG)
10556 (ashift:SWI (match_operand:SWI 1 "register_operand" "0")
10557 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
10559 (clobber (match_scratch:SWI 0 "=<r>"))]
10560 "(optimize_function_for_size_p (cfun)
10561 || !TARGET_PARTIAL_FLAG_REG_STALL
10562 || (operands[2] == const1_rtx
10564 || TARGET_DOUBLE_WITH_ADD)))
10565 && ix86_match_ccmode (insn, CCGOCmode)"
10567 switch (get_attr_type (insn))
10570 gcc_assert (operands[2] == const1_rtx);
10571 return "add{<imodesuffix>}\t%0, %0";
10574 if (operands[2] == const1_rtx
10575 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10576 return "sal{<imodesuffix>}\t%0";
10578 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
10581 [(set (attr "type")
10582 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
10583 (match_operand 0 "register_operand"))
10584 (match_operand 2 "const1_operand"))
10585 (const_string "alu")
10587 (const_string "ishift")))
10588 (set (attr "length_immediate")
10590 (ior (eq_attr "type" "alu")
10591 (and (eq_attr "type" "ishift")
10592 (and (match_operand 2 "const1_operand")
10593 (ior (match_test "TARGET_SHIFT1")
10594 (match_test "optimize_function_for_size_p (cfun)")))))
10596 (const_string "*")))
10597 (set_attr "mode" "<MODE>")])
10599 ;; See comment above `ashl<mode>3' about how this works.
10601 (define_expand "<shift_insn><mode>3"
10602 [(set (match_operand:SDWIM 0 "<shift_operand>")
10603 (any_shiftrt:SDWIM (match_operand:SDWIM 1 "<shift_operand>")
10604 (match_operand:QI 2 "nonmemory_operand")))]
10606 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
10608 ;; Avoid useless masking of count operand.
10609 (define_insn_and_split "*<shift_insn><mode>3_mask"
10610 [(set (match_operand:SWI48 0 "nonimmediate_operand")
10612 (match_operand:SWI48 1 "nonimmediate_operand")
10615 (match_operand:SI 2 "register_operand" "c,r")
10616 (match_operand:SI 3 "const_int_operand")) 0)))
10617 (clobber (reg:CC FLAGS_REG))]
10618 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
10619 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10620 == GET_MODE_BITSIZE (<MODE>mode)-1
10621 && can_create_pseudo_p ()"
10625 [(set (match_dup 0)
10626 (any_shiftrt:SWI48 (match_dup 1)
10628 (clobber (reg:CC FLAGS_REG))])]
10629 "operands[2] = gen_lowpart (QImode, operands[2]);"
10630 [(set_attr "isa" "*,bmi2")])
10632 (define_insn_and_split "*<shift_insn><mode>3_mask_1"
10633 [(set (match_operand:SWI48 0 "nonimmediate_operand")
10635 (match_operand:SWI48 1 "nonimmediate_operand")
10637 (match_operand:QI 2 "register_operand" "c,r")
10638 (match_operand:QI 3 "const_int_operand"))))
10639 (clobber (reg:CC FLAGS_REG))]
10640 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
10641 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10642 == GET_MODE_BITSIZE (<MODE>mode)-1
10643 && can_create_pseudo_p ()"
10647 [(set (match_dup 0)
10648 (any_shiftrt:SWI48 (match_dup 1)
10650 (clobber (reg:CC FLAGS_REG))])]
10652 [(set_attr "isa" "*,bmi2")])
10654 (define_insn_and_split "*<shift_insn><dwi>3_doubleword_mask"
10655 [(set (match_operand:<DWI> 0 "register_operand")
10657 (match_operand:<DWI> 1 "register_operand")
10660 (match_operand:SI 2 "register_operand" "c")
10661 (match_operand:SI 3 "const_int_operand")) 0)))
10662 (clobber (reg:CC FLAGS_REG))]
10663 "(INTVAL (operands[3]) & (<MODE_SIZE> * BITS_PER_UNIT)) == 0
10664 && can_create_pseudo_p ()"
10668 [(set (match_dup 4)
10669 (ior:DWIH (lshiftrt:DWIH (match_dup 4) (match_dup 2))
10670 (ashift:DWIH (match_dup 7)
10671 (minus:QI (match_dup 8) (match_dup 2)))))
10672 (clobber (reg:CC FLAGS_REG))])
10674 [(set (match_dup 6)
10675 (any_shiftrt:DWIH (match_dup 7) (match_dup 2)))
10676 (clobber (reg:CC FLAGS_REG))])]
10678 split_double_mode (<DWI>mode, &operands[0], 2, &operands[4], &operands[6]);
10680 operands[8] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT);
10682 if ((INTVAL (operands[3]) & ((<MODE_SIZE> * BITS_PER_UNIT) - 1))
10683 != ((<MODE_SIZE> * BITS_PER_UNIT) - 1))
10685 rtx tem = gen_reg_rtx (SImode);
10686 emit_insn (gen_andsi3 (tem, operands[2], operands[3]));
10690 operands[2] = gen_lowpart (QImode, operands[2]);
10692 if (!rtx_equal_p (operands[4], operands[5]))
10693 emit_move_insn (operands[4], operands[5]);
10696 (define_insn_and_split "*<shift_insn><dwi>3_doubleword_mask_1"
10697 [(set (match_operand:<DWI> 0 "register_operand")
10699 (match_operand:<DWI> 1 "register_operand")
10701 (match_operand:QI 2 "register_operand" "c")
10702 (match_operand:QI 3 "const_int_operand"))))
10703 (clobber (reg:CC FLAGS_REG))]
10704 "(INTVAL (operands[3]) & (<MODE_SIZE> * BITS_PER_UNIT)) == 0
10705 && can_create_pseudo_p ()"
10709 [(set (match_dup 4)
10710 (ior:DWIH (lshiftrt:DWIH (match_dup 4) (match_dup 2))
10711 (ashift:DWIH (match_dup 7)
10712 (minus:QI (match_dup 8) (match_dup 2)))))
10713 (clobber (reg:CC FLAGS_REG))])
10715 [(set (match_dup 6)
10716 (any_shiftrt:DWIH (match_dup 7) (match_dup 2)))
10717 (clobber (reg:CC FLAGS_REG))])]
10719 split_double_mode (<DWI>mode, &operands[0], 2, &operands[4], &operands[6]);
10721 operands[8] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT);
10723 if ((INTVAL (operands[3]) & ((<MODE_SIZE> * BITS_PER_UNIT) - 1))
10724 != ((<MODE_SIZE> * BITS_PER_UNIT) - 1))
10726 rtx tem = gen_reg_rtx (QImode);
10727 emit_insn (gen_andqi3 (tem, operands[2], operands[3]));
10731 if (!rtx_equal_p (operands[4], operands[5]))
10732 emit_move_insn (operands[4], operands[5]);
10735 (define_insn_and_split "*<shift_insn><mode>3_doubleword"
10736 [(set (match_operand:DWI 0 "register_operand" "=&r")
10737 (any_shiftrt:DWI (match_operand:DWI 1 "register_operand" "0")
10738 (match_operand:QI 2 "nonmemory_operand" "<S>c")))
10739 (clobber (reg:CC FLAGS_REG))]
10742 "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
10744 "ix86_split_<shift_insn> (operands, NULL_RTX, <MODE>mode); DONE;"
10745 [(set_attr "type" "multi")])
10747 ;; By default we don't ask for a scratch register, because when DWImode
10748 ;; values are manipulated, registers are already at a premium. But if
10749 ;; we have one handy, we won't turn it away.
10752 [(match_scratch:DWIH 3 "r")
10753 (parallel [(set (match_operand:<DWI> 0 "register_operand")
10755 (match_operand:<DWI> 1 "register_operand")
10756 (match_operand:QI 2 "nonmemory_operand")))
10757 (clobber (reg:CC FLAGS_REG))])
10761 "ix86_split_<shift_insn> (operands, operands[3], <DWI>mode); DONE;")
10763 (define_insn "x86_64_shrd"
10764 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
10765 (ior:DI (lshiftrt:DI (match_dup 0)
10766 (match_operand:QI 2 "nonmemory_operand" "Jc"))
10767 (ashift:DI (match_operand:DI 1 "register_operand" "r")
10768 (minus:QI (const_int 64) (match_dup 2)))))
10769 (clobber (reg:CC FLAGS_REG))]
10771 "shrd{q}\t{%s2%1, %0|%0, %1, %2}"
10772 [(set_attr "type" "ishift")
10773 (set_attr "prefix_0f" "1")
10774 (set_attr "mode" "DI")
10775 (set_attr "athlon_decode" "vector")
10776 (set_attr "amdfam10_decode" "vector")
10777 (set_attr "bdver1_decode" "vector")])
10779 (define_insn "x86_shrd"
10780 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
10781 (ior:SI (lshiftrt:SI (match_dup 0)
10782 (match_operand:QI 2 "nonmemory_operand" "Ic"))
10783 (ashift:SI (match_operand:SI 1 "register_operand" "r")
10784 (minus:QI (const_int 32) (match_dup 2)))))
10785 (clobber (reg:CC FLAGS_REG))]
10787 "shrd{l}\t{%s2%1, %0|%0, %1, %2}"
10788 [(set_attr "type" "ishift")
10789 (set_attr "prefix_0f" "1")
10790 (set_attr "mode" "SI")
10791 (set_attr "pent_pair" "np")
10792 (set_attr "athlon_decode" "vector")
10793 (set_attr "amdfam10_decode" "vector")
10794 (set_attr "bdver1_decode" "vector")])
10796 ;; Base name for insn mnemonic.
10797 (define_mode_attr cvt_mnemonic
10798 [(SI "{cltd|cdq}") (DI "{cqto|cqo}")])
10800 (define_insn "ashr<mode>3_cvt"
10801 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=*d,rm")
10803 (match_operand:SWI48 1 "nonimmediate_operand" "*a,0")
10804 (match_operand:QI 2 "const_int_operand")))
10805 (clobber (reg:CC FLAGS_REG))]
10806 "INTVAL (operands[2]) == GET_MODE_BITSIZE (<MODE>mode)-1
10807 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
10808 && ix86_binary_operator_ok (ASHIFTRT, <MODE>mode, operands)"
10811 sar{<imodesuffix>}\t{%2, %0|%0, %2}"
10812 [(set_attr "type" "imovx,ishift")
10813 (set_attr "prefix_0f" "0,*")
10814 (set_attr "length_immediate" "0,*")
10815 (set_attr "modrm" "0,1")
10816 (set_attr "mode" "<MODE>")])
10818 (define_insn "*ashrsi3_cvt_zext"
10819 [(set (match_operand:DI 0 "register_operand" "=*d,r")
10821 (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
10822 (match_operand:QI 2 "const_int_operand"))))
10823 (clobber (reg:CC FLAGS_REG))]
10824 "TARGET_64BIT && INTVAL (operands[2]) == 31
10825 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
10826 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
10829 sar{l}\t{%2, %k0|%k0, %2}"
10830 [(set_attr "type" "imovx,ishift")
10831 (set_attr "prefix_0f" "0,*")
10832 (set_attr "length_immediate" "0,*")
10833 (set_attr "modrm" "0,1")
10834 (set_attr "mode" "SI")])
10836 (define_expand "x86_shift<mode>_adj_3"
10837 [(use (match_operand:SWI48 0 "register_operand"))
10838 (use (match_operand:SWI48 1 "register_operand"))
10839 (use (match_operand:QI 2 "register_operand"))]
10842 rtx_code_label *label = gen_label_rtx ();
10845 emit_insn (gen_testqi_ccz_1 (operands[2],
10846 GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
10848 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
10849 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
10850 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
10851 gen_rtx_LABEL_REF (VOIDmode, label),
10853 tmp = emit_jump_insn (gen_rtx_SET (pc_rtx, tmp));
10854 JUMP_LABEL (tmp) = label;
10856 emit_move_insn (operands[0], operands[1]);
10857 emit_insn (gen_ashr<mode>3_cvt (operands[1], operands[1],
10858 GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1)));
10859 emit_label (label);
10860 LABEL_NUSES (label) = 1;
10865 (define_insn "*bmi2_<shift_insn><mode>3_1"
10866 [(set (match_operand:SWI48 0 "register_operand" "=r")
10867 (any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
10868 (match_operand:SWI48 2 "register_operand" "r")))]
10870 "<shift>x\t{%2, %1, %0|%0, %1, %2}"
10871 [(set_attr "type" "ishiftx")
10872 (set_attr "mode" "<MODE>")])
10874 (define_insn "*<shift_insn><mode>3_1"
10875 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
10877 (match_operand:SWI48 1 "nonimmediate_operand" "0,rm")
10878 (match_operand:QI 2 "nonmemory_operand" "c<S>,r")))
10879 (clobber (reg:CC FLAGS_REG))]
10880 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10882 switch (get_attr_type (insn))
10888 if (operands[2] == const1_rtx
10889 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10890 return "<shift>{<imodesuffix>}\t%0";
10892 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
10895 [(set_attr "isa" "*,bmi2")
10896 (set_attr "type" "ishift,ishiftx")
10897 (set (attr "length_immediate")
10899 (and (match_operand 2 "const1_operand")
10900 (ior (match_test "TARGET_SHIFT1")
10901 (match_test "optimize_function_for_size_p (cfun)")))
10903 (const_string "*")))
10904 (set_attr "mode" "<MODE>")])
10906 ;; Convert shift to the shiftx pattern to avoid flags dependency.
10908 [(set (match_operand:SWI48 0 "register_operand")
10909 (any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
10910 (match_operand:QI 2 "register_operand")))
10911 (clobber (reg:CC FLAGS_REG))]
10912 "TARGET_BMI2 && reload_completed"
10913 [(set (match_dup 0)
10914 (any_shiftrt:SWI48 (match_dup 1) (match_dup 2)))]
10915 "operands[2] = gen_lowpart (<MODE>mode, operands[2]);")
10917 (define_insn "*bmi2_<shift_insn>si3_1_zext"
10918 [(set (match_operand:DI 0 "register_operand" "=r")
10920 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
10921 (match_operand:SI 2 "register_operand" "r"))))]
10922 "TARGET_64BIT && TARGET_BMI2"
10923 "<shift>x\t{%2, %1, %k0|%k0, %1, %2}"
10924 [(set_attr "type" "ishiftx")
10925 (set_attr "mode" "SI")])
10927 (define_insn "*<shift_insn>si3_1_zext"
10928 [(set (match_operand:DI 0 "register_operand" "=r,r")
10930 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm")
10931 (match_operand:QI 2 "nonmemory_operand" "cI,r"))))
10932 (clobber (reg:CC FLAGS_REG))]
10933 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10935 switch (get_attr_type (insn))
10941 if (operands[2] == const1_rtx
10942 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10943 return "<shift>{l}\t%k0";
10945 return "<shift>{l}\t{%2, %k0|%k0, %2}";
10948 [(set_attr "isa" "*,bmi2")
10949 (set_attr "type" "ishift,ishiftx")
10950 (set (attr "length_immediate")
10952 (and (match_operand 2 "const1_operand")
10953 (ior (match_test "TARGET_SHIFT1")
10954 (match_test "optimize_function_for_size_p (cfun)")))
10956 (const_string "*")))
10957 (set_attr "mode" "SI")])
10959 ;; Convert shift to the shiftx pattern to avoid flags dependency.
10961 [(set (match_operand:DI 0 "register_operand")
10963 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand")
10964 (match_operand:QI 2 "register_operand"))))
10965 (clobber (reg:CC FLAGS_REG))]
10966 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
10967 [(set (match_dup 0)
10968 (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
10969 "operands[2] = gen_lowpart (SImode, operands[2]);")
10971 (define_insn "*<shift_insn><mode>3_1"
10972 [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m")
10974 (match_operand:SWI12 1 "nonimmediate_operand" "0")
10975 (match_operand:QI 2 "nonmemory_operand" "c<S>")))
10976 (clobber (reg:CC FLAGS_REG))]
10977 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10979 if (operands[2] == const1_rtx
10980 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10981 return "<shift>{<imodesuffix>}\t%0";
10983 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
10985 [(set_attr "type" "ishift")
10986 (set (attr "length_immediate")
10988 (and (match_operand 2 "const1_operand")
10989 (ior (match_test "TARGET_SHIFT1")
10990 (match_test "optimize_function_for_size_p (cfun)")))
10992 (const_string "*")))
10993 (set_attr "mode" "<MODE>")])
10995 (define_insn "*<shift_insn>qi3_1_slp"
10996 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10997 (any_shiftrt:QI (match_dup 0)
10998 (match_operand:QI 1 "nonmemory_operand" "cI")))
10999 (clobber (reg:CC FLAGS_REG))]
11000 "(optimize_function_for_size_p (cfun)
11001 || !TARGET_PARTIAL_REG_STALL
11002 || (operands[1] == const1_rtx
11003 && TARGET_SHIFT1))"
11005 if (operands[1] == const1_rtx
11006 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11007 return "<shift>{b}\t%0";
11009 return "<shift>{b}\t{%1, %0|%0, %1}";
11011 [(set_attr "type" "ishift1")
11012 (set (attr "length_immediate")
11014 (and (match_operand 1 "const1_operand")
11015 (ior (match_test "TARGET_SHIFT1")
11016 (match_test "optimize_function_for_size_p (cfun)")))
11018 (const_string "*")))
11019 (set_attr "mode" "QI")])
11021 ;; This pattern can't accept a variable shift count, since shifts by
11022 ;; zero don't affect the flags. We assume that shifts by constant
11023 ;; zero are optimized away.
11024 (define_insn "*<shift_insn><mode>3_cmp"
11025 [(set (reg FLAGS_REG)
11028 (match_operand:SWI 1 "nonimmediate_operand" "0")
11029 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
11031 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
11032 (any_shiftrt:SWI (match_dup 1) (match_dup 2)))]
11033 "(optimize_function_for_size_p (cfun)
11034 || !TARGET_PARTIAL_FLAG_REG_STALL
11035 || (operands[2] == const1_rtx
11037 && ix86_match_ccmode (insn, CCGOCmode)
11038 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
11040 if (operands[2] == const1_rtx
11041 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11042 return "<shift>{<imodesuffix>}\t%0";
11044 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
11046 [(set_attr "type" "ishift")
11047 (set (attr "length_immediate")
11049 (and (match_operand 2 "const1_operand")
11050 (ior (match_test "TARGET_SHIFT1")
11051 (match_test "optimize_function_for_size_p (cfun)")))
11053 (const_string "*")))
11054 (set_attr "mode" "<MODE>")])
11056 (define_insn "*<shift_insn>si3_cmp_zext"
11057 [(set (reg FLAGS_REG)
11059 (any_shiftrt:SI (match_operand:SI 1 "register_operand" "0")
11060 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11062 (set (match_operand:DI 0 "register_operand" "=r")
11063 (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
11065 && (optimize_function_for_size_p (cfun)
11066 || !TARGET_PARTIAL_FLAG_REG_STALL
11067 || (operands[2] == const1_rtx
11069 && ix86_match_ccmode (insn, CCGOCmode)
11070 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
11072 if (operands[2] == const1_rtx
11073 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11074 return "<shift>{l}\t%k0";
11076 return "<shift>{l}\t{%2, %k0|%k0, %2}";
11078 [(set_attr "type" "ishift")
11079 (set (attr "length_immediate")
11081 (and (match_operand 2 "const1_operand")
11082 (ior (match_test "TARGET_SHIFT1")
11083 (match_test "optimize_function_for_size_p (cfun)")))
11085 (const_string "*")))
11086 (set_attr "mode" "SI")])
11088 (define_insn "*<shift_insn><mode>3_cconly"
11089 [(set (reg FLAGS_REG)
11092 (match_operand:SWI 1 "register_operand" "0")
11093 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
11095 (clobber (match_scratch:SWI 0 "=<r>"))]
11096 "(optimize_function_for_size_p (cfun)
11097 || !TARGET_PARTIAL_FLAG_REG_STALL
11098 || (operands[2] == const1_rtx
11100 && ix86_match_ccmode (insn, CCGOCmode)"
11102 if (operands[2] == const1_rtx
11103 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11104 return "<shift>{<imodesuffix>}\t%0";
11106 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
11108 [(set_attr "type" "ishift")
11109 (set (attr "length_immediate")
11111 (and (match_operand 2 "const1_operand")
11112 (ior (match_test "TARGET_SHIFT1")
11113 (match_test "optimize_function_for_size_p (cfun)")))
11115 (const_string "*")))
11116 (set_attr "mode" "<MODE>")])
11118 ;; Rotate instructions
11120 (define_expand "<rotate_insn>ti3"
11121 [(set (match_operand:TI 0 "register_operand")
11122 (any_rotate:TI (match_operand:TI 1 "register_operand")
11123 (match_operand:QI 2 "nonmemory_operand")))]
11126 if (const_1_to_63_operand (operands[2], VOIDmode))
11127 emit_insn (gen_ix86_<rotate_insn>ti3_doubleword
11128 (operands[0], operands[1], operands[2]));
11135 (define_expand "<rotate_insn>di3"
11136 [(set (match_operand:DI 0 "shiftdi_operand")
11137 (any_rotate:DI (match_operand:DI 1 "shiftdi_operand")
11138 (match_operand:QI 2 "nonmemory_operand")))]
11142 ix86_expand_binary_operator (<CODE>, DImode, operands);
11143 else if (const_1_to_31_operand (operands[2], VOIDmode))
11144 emit_insn (gen_ix86_<rotate_insn>di3_doubleword
11145 (operands[0], operands[1], operands[2]));
11152 (define_expand "<rotate_insn><mode>3"
11153 [(set (match_operand:SWIM124 0 "nonimmediate_operand")
11154 (any_rotate:SWIM124 (match_operand:SWIM124 1 "nonimmediate_operand")
11155 (match_operand:QI 2 "nonmemory_operand")))]
11157 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
11159 ;; Avoid useless masking of count operand.
11160 (define_insn_and_split "*<rotate_insn><mode>3_mask"
11161 [(set (match_operand:SWI48 0 "nonimmediate_operand")
11163 (match_operand:SWI48 1 "nonimmediate_operand")
11166 (match_operand:SI 2 "register_operand" "c")
11167 (match_operand:SI 3 "const_int_operand")) 0)))
11168 (clobber (reg:CC FLAGS_REG))]
11169 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
11170 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
11171 == GET_MODE_BITSIZE (<MODE>mode)-1
11172 && can_create_pseudo_p ()"
11176 [(set (match_dup 0)
11177 (any_rotate:SWI48 (match_dup 1)
11179 (clobber (reg:CC FLAGS_REG))])]
11180 "operands[2] = gen_lowpart (QImode, operands[2]);")
11182 (define_insn_and_split "*<rotate_insn><mode>3_mask_1"
11183 [(set (match_operand:SWI48 0 "nonimmediate_operand")
11185 (match_operand:SWI48 1 "nonimmediate_operand")
11187 (match_operand:QI 2 "register_operand" "c")
11188 (match_operand:QI 3 "const_int_operand"))))
11189 (clobber (reg:CC FLAGS_REG))]
11190 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
11191 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
11192 == GET_MODE_BITSIZE (<MODE>mode)-1
11193 && can_create_pseudo_p ()"
11197 [(set (match_dup 0)
11198 (any_rotate:SWI48 (match_dup 1)
11200 (clobber (reg:CC FLAGS_REG))])])
11202 ;; Implement rotation using two double-precision
11203 ;; shift instructions and a scratch register.
11205 (define_insn_and_split "ix86_rotl<dwi>3_doubleword"
11206 [(set (match_operand:<DWI> 0 "register_operand" "=r")
11207 (rotate:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
11208 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
11209 (clobber (reg:CC FLAGS_REG))
11210 (clobber (match_scratch:DWIH 3 "=&r"))]
11214 [(set (match_dup 3) (match_dup 4))
11216 [(set (match_dup 4)
11217 (ior:DWIH (ashift:DWIH (match_dup 4) (match_dup 2))
11218 (lshiftrt:DWIH (match_dup 5)
11219 (minus:QI (match_dup 6) (match_dup 2)))))
11220 (clobber (reg:CC FLAGS_REG))])
11222 [(set (match_dup 5)
11223 (ior:DWIH (ashift:DWIH (match_dup 5) (match_dup 2))
11224 (lshiftrt:DWIH (match_dup 3)
11225 (minus:QI (match_dup 6) (match_dup 2)))))
11226 (clobber (reg:CC FLAGS_REG))])]
11228 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
11230 split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
11233 (define_insn_and_split "ix86_rotr<dwi>3_doubleword"
11234 [(set (match_operand:<DWI> 0 "register_operand" "=r")
11235 (rotatert:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
11236 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
11237 (clobber (reg:CC FLAGS_REG))
11238 (clobber (match_scratch:DWIH 3 "=&r"))]
11242 [(set (match_dup 3) (match_dup 4))
11244 [(set (match_dup 4)
11245 (ior:DWIH (lshiftrt:DWIH (match_dup 4) (match_dup 2))
11246 (ashift:DWIH (match_dup 5)
11247 (minus:QI (match_dup 6) (match_dup 2)))))
11248 (clobber (reg:CC FLAGS_REG))])
11250 [(set (match_dup 5)
11251 (ior:DWIH (lshiftrt:DWIH (match_dup 5) (match_dup 2))
11252 (ashift:DWIH (match_dup 3)
11253 (minus:QI (match_dup 6) (match_dup 2)))))
11254 (clobber (reg:CC FLAGS_REG))])]
11256 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
11258 split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
11261 (define_mode_attr rorx_immediate_operand
11262 [(SI "const_0_to_31_operand")
11263 (DI "const_0_to_63_operand")])
11265 (define_insn "*bmi2_rorx<mode>3_1"
11266 [(set (match_operand:SWI48 0 "register_operand" "=r")
11268 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11269 (match_operand:QI 2 "<rorx_immediate_operand>" "<S>")))]
11271 "rorx\t{%2, %1, %0|%0, %1, %2}"
11272 [(set_attr "type" "rotatex")
11273 (set_attr "mode" "<MODE>")])
11275 (define_insn "*<rotate_insn><mode>3_1"
11276 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
11278 (match_operand:SWI48 1 "nonimmediate_operand" "0,rm")
11279 (match_operand:QI 2 "nonmemory_operand" "c<S>,<S>")))
11280 (clobber (reg:CC FLAGS_REG))]
11281 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
11283 switch (get_attr_type (insn))
11289 if (operands[2] == const1_rtx
11290 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11291 return "<rotate>{<imodesuffix>}\t%0";
11293 return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
11296 [(set_attr "isa" "*,bmi2")
11297 (set_attr "type" "rotate,rotatex")
11298 (set (attr "length_immediate")
11300 (and (eq_attr "type" "rotate")
11301 (and (match_operand 2 "const1_operand")
11302 (ior (match_test "TARGET_SHIFT1")
11303 (match_test "optimize_function_for_size_p (cfun)"))))
11305 (const_string "*")))
11306 (set_attr "mode" "<MODE>")])
11308 ;; Convert rotate to the rotatex pattern to avoid flags dependency.
11310 [(set (match_operand:SWI48 0 "register_operand")
11311 (rotate:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
11312 (match_operand:QI 2 "const_int_operand")))
11313 (clobber (reg:CC FLAGS_REG))]
11314 "TARGET_BMI2 && reload_completed"
11315 [(set (match_dup 0)
11316 (rotatert:SWI48 (match_dup 1) (match_dup 2)))]
11318 int bitsize = GET_MODE_BITSIZE (<MODE>mode);
11320 operands[2] = GEN_INT ((bitsize - INTVAL (operands[2])) % bitsize);
11324 [(set (match_operand:SWI48 0 "register_operand")
11325 (rotatert:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
11326 (match_operand:QI 2 "const_int_operand")))
11327 (clobber (reg:CC FLAGS_REG))]
11328 "TARGET_BMI2 && reload_completed"
11329 [(set (match_dup 0)
11330 (rotatert:SWI48 (match_dup 1) (match_dup 2)))])
11332 (define_insn "*bmi2_rorxsi3_1_zext"
11333 [(set (match_operand:DI 0 "register_operand" "=r")
11335 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
11336 (match_operand:QI 2 "const_0_to_31_operand" "I"))))]
11337 "TARGET_64BIT && TARGET_BMI2"
11338 "rorx\t{%2, %1, %k0|%k0, %1, %2}"
11339 [(set_attr "type" "rotatex")
11340 (set_attr "mode" "SI")])
11342 (define_insn "*<rotate_insn>si3_1_zext"
11343 [(set (match_operand:DI 0 "register_operand" "=r,r")
11345 (any_rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm")
11346 (match_operand:QI 2 "nonmemory_operand" "cI,I"))))
11347 (clobber (reg:CC FLAGS_REG))]
11348 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
11350 switch (get_attr_type (insn))
11356 if (operands[2] == const1_rtx
11357 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11358 return "<rotate>{l}\t%k0";
11360 return "<rotate>{l}\t{%2, %k0|%k0, %2}";
11363 [(set_attr "isa" "*,bmi2")
11364 (set_attr "type" "rotate,rotatex")
11365 (set (attr "length_immediate")
11367 (and (eq_attr "type" "rotate")
11368 (and (match_operand 2 "const1_operand")
11369 (ior (match_test "TARGET_SHIFT1")
11370 (match_test "optimize_function_for_size_p (cfun)"))))
11372 (const_string "*")))
11373 (set_attr "mode" "SI")])
11375 ;; Convert rotate to the rotatex pattern to avoid flags dependency.
11377 [(set (match_operand:DI 0 "register_operand")
11379 (rotate:SI (match_operand:SI 1 "nonimmediate_operand")
11380 (match_operand:QI 2 "const_int_operand"))))
11381 (clobber (reg:CC FLAGS_REG))]
11382 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
11383 [(set (match_dup 0)
11384 (zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))]
11386 int bitsize = GET_MODE_BITSIZE (SImode);
11388 operands[2] = GEN_INT ((bitsize - INTVAL (operands[2])) % bitsize);
11392 [(set (match_operand:DI 0 "register_operand")
11394 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand")
11395 (match_operand:QI 2 "const_int_operand"))))
11396 (clobber (reg:CC FLAGS_REG))]
11397 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
11398 [(set (match_dup 0)
11399 (zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))])
11401 (define_insn "*<rotate_insn><mode>3_1"
11402 [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m")
11403 (any_rotate:SWI12 (match_operand:SWI12 1 "nonimmediate_operand" "0")
11404 (match_operand:QI 2 "nonmemory_operand" "c<S>")))
11405 (clobber (reg:CC FLAGS_REG))]
11406 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
11408 if (operands[2] == const1_rtx
11409 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11410 return "<rotate>{<imodesuffix>}\t%0";
11412 return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
11414 [(set_attr "type" "rotate")
11415 (set (attr "length_immediate")
11417 (and (match_operand 2 "const1_operand")
11418 (ior (match_test "TARGET_SHIFT1")
11419 (match_test "optimize_function_for_size_p (cfun)")))
11421 (const_string "*")))
11422 (set_attr "mode" "<MODE>")])
11424 (define_insn "*<rotate_insn>qi3_1_slp"
11425 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
11426 (any_rotate:QI (match_dup 0)
11427 (match_operand:QI 1 "nonmemory_operand" "cI")))
11428 (clobber (reg:CC FLAGS_REG))]
11429 "(optimize_function_for_size_p (cfun)
11430 || !TARGET_PARTIAL_REG_STALL
11431 || (operands[1] == const1_rtx
11432 && TARGET_SHIFT1))"
11434 if (operands[1] == const1_rtx
11435 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11436 return "<rotate>{b}\t%0";
11438 return "<rotate>{b}\t{%1, %0|%0, %1}";
11440 [(set_attr "type" "rotate1")
11441 (set (attr "length_immediate")
11443 (and (match_operand 1 "const1_operand")
11444 (ior (match_test "TARGET_SHIFT1")
11445 (match_test "optimize_function_for_size_p (cfun)")))
11447 (const_string "*")))
11448 (set_attr "mode" "QI")])
11451 [(set (match_operand:HI 0 "QIreg_operand")
11452 (any_rotate:HI (match_dup 0) (const_int 8)))
11453 (clobber (reg:CC FLAGS_REG))]
11455 && (TARGET_USE_XCHGB || optimize_function_for_size_p (cfun))"
11456 [(parallel [(set (strict_low_part (match_dup 0))
11457 (bswap:HI (match_dup 0)))
11458 (clobber (reg:CC FLAGS_REG))])])
11460 ;; Bit set / bit test instructions
11462 ;; %%% bts, btr, btc
11464 ;; These instructions are *slow* when applied to memory.
11466 (define_code_attr btsc [(ior "bts") (xor "btc")])
11468 (define_insn "*<btsc><mode>"
11469 [(set (match_operand:SWI48 0 "register_operand" "=r")
11471 (ashift:SWI48 (const_int 1)
11472 (match_operand:QI 2 "register_operand" "r"))
11473 (match_operand:SWI48 1 "register_operand" "0")))
11474 (clobber (reg:CC FLAGS_REG))]
11476 "<btsc>{<imodesuffix>}\t{%<k>2, %0|%0, %<k>2}"
11477 [(set_attr "type" "alu1")
11478 (set_attr "prefix_0f" "1")
11479 (set_attr "znver1_decode" "double")
11480 (set_attr "mode" "<MODE>")])
11482 ;; Avoid useless masking of count operand.
11483 (define_insn_and_split "*<btsc><mode>_mask"
11484 [(set (match_operand:SWI48 0 "register_operand")
11490 (match_operand:SI 1 "register_operand")
11491 (match_operand:SI 2 "const_int_operand")) 0))
11492 (match_operand:SWI48 3 "register_operand")))
11493 (clobber (reg:CC FLAGS_REG))]
11495 && (INTVAL (operands[2]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
11496 == GET_MODE_BITSIZE (<MODE>mode)-1
11497 && can_create_pseudo_p ()"
11501 [(set (match_dup 0)
11503 (ashift:SWI48 (const_int 1)
11506 (clobber (reg:CC FLAGS_REG))])]
11507 "operands[1] = gen_lowpart (QImode, operands[1]);")
11509 (define_insn_and_split "*<btsc><mode>_mask_1"
11510 [(set (match_operand:SWI48 0 "register_operand")
11515 (match_operand:QI 1 "register_operand")
11516 (match_operand:QI 2 "const_int_operand")))
11517 (match_operand:SWI48 3 "register_operand")))
11518 (clobber (reg:CC FLAGS_REG))]
11520 && (INTVAL (operands[2]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
11521 == GET_MODE_BITSIZE (<MODE>mode)-1
11522 && can_create_pseudo_p ()"
11526 [(set (match_dup 0)
11528 (ashift:SWI48 (const_int 1)
11531 (clobber (reg:CC FLAGS_REG))])])
11533 (define_insn "*btr<mode>"
11534 [(set (match_operand:SWI48 0 "register_operand" "=r")
11536 (rotate:SWI48 (const_int -2)
11537 (match_operand:QI 2 "register_operand" "r"))
11538 (match_operand:SWI48 1 "register_operand" "0")))
11539 (clobber (reg:CC FLAGS_REG))]
11541 "btr{<imodesuffix>}\t{%<k>2, %0|%0, %<k>2}"
11542 [(set_attr "type" "alu1")
11543 (set_attr "prefix_0f" "1")
11544 (set_attr "znver1_decode" "double")
11545 (set_attr "mode" "<MODE>")])
11547 ;; Avoid useless masking of count operand.
11548 (define_insn_and_split "*btr<mode>_mask"
11549 [(set (match_operand:SWI48 0 "register_operand")
11555 (match_operand:SI 1 "register_operand")
11556 (match_operand:SI 2 "const_int_operand")) 0))
11557 (match_operand:SWI48 3 "register_operand")))
11558 (clobber (reg:CC FLAGS_REG))]
11560 && (INTVAL (operands[2]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
11561 == GET_MODE_BITSIZE (<MODE>mode)-1
11562 && can_create_pseudo_p ()"
11566 [(set (match_dup 0)
11568 (rotate:SWI48 (const_int -2)
11571 (clobber (reg:CC FLAGS_REG))])]
11572 "operands[1] = gen_lowpart (QImode, operands[1]);")
11574 (define_insn_and_split "*btr<mode>_mask_1"
11575 [(set (match_operand:SWI48 0 "register_operand")
11580 (match_operand:QI 1 "register_operand")
11581 (match_operand:QI 2 "const_int_operand")))
11582 (match_operand:SWI48 3 "register_operand")))
11583 (clobber (reg:CC FLAGS_REG))]
11585 && (INTVAL (operands[2]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
11586 == GET_MODE_BITSIZE (<MODE>mode)-1
11587 && can_create_pseudo_p ()"
11591 [(set (match_dup 0)
11593 (rotate:SWI48 (const_int -2)
11596 (clobber (reg:CC FLAGS_REG))])])
11598 ;; These instructions are never faster than the corresponding
11599 ;; and/ior/xor operations when using immediate operand, so with
11600 ;; 32-bit there's no point. But in 64-bit, we can't hold the
11601 ;; relevant immediates within the instruction itself, so operating
11602 ;; on bits in the high 32-bits of a register becomes easier.
11604 ;; These are slow on Nocona, but fast on Athlon64. We do require the use
11605 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
11606 ;; negdf respectively, so they can never be disabled entirely.
11608 (define_insn "*btsq_imm"
11609 [(set (zero_extract:DI (match_operand:DI 0 "nonimmediate_operand" "+rm")
11611 (match_operand 1 "const_0_to_63_operand" "J"))
11613 (clobber (reg:CC FLAGS_REG))]
11614 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
11615 "bts{q}\t{%1, %0|%0, %1}"
11616 [(set_attr "type" "alu1")
11617 (set_attr "prefix_0f" "1")
11618 (set_attr "znver1_decode" "double")
11619 (set_attr "mode" "DI")])
11621 (define_insn "*btrq_imm"
11622 [(set (zero_extract:DI (match_operand:DI 0 "nonimmediate_operand" "+rm")
11624 (match_operand 1 "const_0_to_63_operand" "J"))
11626 (clobber (reg:CC FLAGS_REG))]
11627 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
11628 "btr{q}\t{%1, %0|%0, %1}"
11629 [(set_attr "type" "alu1")
11630 (set_attr "prefix_0f" "1")
11631 (set_attr "znver1_decode" "double")
11632 (set_attr "mode" "DI")])
11634 (define_insn "*btcq_imm"
11635 [(set (zero_extract:DI (match_operand:DI 0 "nonimmediate_operand" "+rm")
11637 (match_operand 1 "const_0_to_63_operand" "J"))
11638 (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
11639 (clobber (reg:CC FLAGS_REG))]
11640 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
11641 "btc{q}\t{%1, %0|%0, %1}"
11642 [(set_attr "type" "alu1")
11643 (set_attr "prefix_0f" "1")
11644 (set_attr "znver1_decode" "double")
11645 (set_attr "mode" "DI")])
11647 ;; Allow Nocona to avoid these instructions if a register is available.
11650 [(match_scratch:DI 2 "r")
11651 (parallel [(set (zero_extract:DI
11652 (match_operand:DI 0 "nonimmediate_operand")
11654 (match_operand 1 "const_0_to_63_operand"))
11656 (clobber (reg:CC FLAGS_REG))])]
11657 "TARGET_64BIT && !TARGET_USE_BT"
11658 [(parallel [(set (match_dup 0)
11659 (ior:DI (match_dup 0) (match_dup 3)))
11660 (clobber (reg:CC FLAGS_REG))])]
11662 int i = INTVAL (operands[1]);
11664 operands[3] = gen_int_mode (HOST_WIDE_INT_1U << i, DImode);
11666 if (!x86_64_immediate_operand (operands[3], DImode))
11668 emit_move_insn (operands[2], operands[3]);
11669 operands[3] = operands[2];
11674 [(match_scratch:DI 2 "r")
11675 (parallel [(set (zero_extract:DI
11676 (match_operand:DI 0 "nonimmediate_operand")
11678 (match_operand 1 "const_0_to_63_operand"))
11680 (clobber (reg:CC FLAGS_REG))])]
11681 "TARGET_64BIT && !TARGET_USE_BT"
11682 [(parallel [(set (match_dup 0)
11683 (and:DI (match_dup 0) (match_dup 3)))
11684 (clobber (reg:CC FLAGS_REG))])]
11686 int i = INTVAL (operands[1]);
11688 operands[3] = gen_int_mode (~(HOST_WIDE_INT_1U << i), DImode);
11690 if (!x86_64_immediate_operand (operands[3], DImode))
11692 emit_move_insn (operands[2], operands[3]);
11693 operands[3] = operands[2];
11698 [(match_scratch:DI 2 "r")
11699 (parallel [(set (zero_extract:DI
11700 (match_operand:DI 0 "nonimmediate_operand")
11702 (match_operand 1 "const_0_to_63_operand"))
11703 (not:DI (zero_extract:DI
11704 (match_dup 0) (const_int 1) (match_dup 1))))
11705 (clobber (reg:CC FLAGS_REG))])]
11706 "TARGET_64BIT && !TARGET_USE_BT"
11707 [(parallel [(set (match_dup 0)
11708 (xor:DI (match_dup 0) (match_dup 3)))
11709 (clobber (reg:CC FLAGS_REG))])]
11711 int i = INTVAL (operands[1]);
11713 operands[3] = gen_int_mode (HOST_WIDE_INT_1U << i, DImode);
11715 if (!x86_64_immediate_operand (operands[3], DImode))
11717 emit_move_insn (operands[2], operands[3]);
11718 operands[3] = operands[2];
11724 (define_insn "*bt<mode>"
11725 [(set (reg:CCC FLAGS_REG)
11727 (zero_extract:SWI48
11728 (match_operand:SWI48 0 "nonimmediate_operand" "r,m")
11730 (match_operand:SI 1 "nonmemory_operand" "r<S>,<S>"))
11734 switch (get_attr_mode (insn))
11737 return "bt{l}\t{%1, %k0|%k0, %1}";
11740 return "bt{q}\t{%q1, %0|%0, %q1}";
11743 gcc_unreachable ();
11746 [(set_attr "type" "alu1")
11747 (set_attr "prefix_0f" "1")
11750 (and (match_test "CONST_INT_P (operands[1])")
11751 (match_test "INTVAL (operands[1]) < 32"))
11752 (const_string "SI")
11753 (const_string "<MODE>")))])
11755 (define_insn_and_split "*jcc_bt<mode>"
11757 (if_then_else (match_operator 0 "bt_comparison_operator"
11758 [(zero_extract:SWI48
11759 (match_operand:SWI48 1 "nonimmediate_operand")
11761 (match_operand:SI 2 "nonmemory_operand"))
11763 (label_ref (match_operand 3))
11765 (clobber (reg:CC FLAGS_REG))]
11766 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
11767 && (CONST_INT_P (operands[2])
11768 ? (INTVAL (operands[2]) < GET_MODE_BITSIZE (<MODE>mode)
11769 && INTVAL (operands[2])
11770 >= (optimize_function_for_size_p (cfun) ? 8 : 32))
11771 : !memory_operand (operands[1], <MODE>mode))
11772 && can_create_pseudo_p ()"
11775 [(set (reg:CCC FLAGS_REG)
11777 (zero_extract:SWI48
11783 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
11784 (label_ref (match_dup 3))
11787 operands[0] = shallow_copy_rtx (operands[0]);
11788 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
11791 (define_insn_and_split "*jcc_bt<mode>_1"
11793 (if_then_else (match_operator 0 "bt_comparison_operator"
11794 [(zero_extract:SWI48
11795 (match_operand:SWI48 1 "register_operand")
11798 (match_operand:QI 2 "register_operand")))
11800 (label_ref (match_operand 3))
11802 (clobber (reg:CC FLAGS_REG))]
11803 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
11804 && can_create_pseudo_p ()"
11807 [(set (reg:CCC FLAGS_REG)
11809 (zero_extract:SWI48
11815 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
11816 (label_ref (match_dup 3))
11819 operands[2] = lowpart_subreg (SImode, operands[2], QImode);
11820 operands[0] = shallow_copy_rtx (operands[0]);
11821 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
11824 ;; Avoid useless masking of bit offset operand.
11825 (define_insn_and_split "*jcc_bt<mode>_mask"
11827 (if_then_else (match_operator 0 "bt_comparison_operator"
11828 [(zero_extract:SWI48
11829 (match_operand:SWI48 1 "register_operand")
11832 (match_operand:SI 2 "register_operand")
11833 (match_operand 3 "const_int_operand")))])
11834 (label_ref (match_operand 4))
11836 (clobber (reg:CC FLAGS_REG))]
11837 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
11838 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
11839 == GET_MODE_BITSIZE (<MODE>mode)-1
11840 && can_create_pseudo_p ()"
11843 [(set (reg:CCC FLAGS_REG)
11845 (zero_extract:SWI48
11851 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
11852 (label_ref (match_dup 4))
11855 operands[0] = shallow_copy_rtx (operands[0]);
11856 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
11859 ;; Store-flag instructions.
11861 ;; For all sCOND expanders, also expand the compare or test insn that
11862 ;; generates cc0. Generate an equality comparison if `seq' or `sne'.
11864 (define_insn_and_split "*setcc_di_1"
11865 [(set (match_operand:DI 0 "register_operand" "=q")
11866 (match_operator:DI 1 "ix86_comparison_operator"
11867 [(reg FLAGS_REG) (const_int 0)]))]
11868 "TARGET_64BIT && !TARGET_PARTIAL_REG_STALL"
11870 "&& reload_completed"
11871 [(set (match_dup 2) (match_dup 1))
11872 (set (match_dup 0) (zero_extend:DI (match_dup 2)))]
11874 operands[1] = shallow_copy_rtx (operands[1]);
11875 PUT_MODE (operands[1], QImode);
11876 operands[2] = gen_lowpart (QImode, operands[0]);
11879 (define_insn_and_split "*setcc_si_1_and"
11880 [(set (match_operand:SI 0 "register_operand" "=q")
11881 (match_operator:SI 1 "ix86_comparison_operator"
11882 [(reg FLAGS_REG) (const_int 0)]))
11883 (clobber (reg:CC FLAGS_REG))]
11884 "!TARGET_PARTIAL_REG_STALL
11885 && TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
11887 "&& reload_completed"
11888 [(set (match_dup 2) (match_dup 1))
11889 (parallel [(set (match_dup 0) (zero_extend:SI (match_dup 2)))
11890 (clobber (reg:CC FLAGS_REG))])]
11892 operands[1] = shallow_copy_rtx (operands[1]);
11893 PUT_MODE (operands[1], QImode);
11894 operands[2] = gen_lowpart (QImode, operands[0]);
11897 (define_insn_and_split "*setcc_si_1_movzbl"
11898 [(set (match_operand:SI 0 "register_operand" "=q")
11899 (match_operator:SI 1 "ix86_comparison_operator"
11900 [(reg FLAGS_REG) (const_int 0)]))]
11901 "!TARGET_PARTIAL_REG_STALL
11902 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
11904 "&& reload_completed"
11905 [(set (match_dup 2) (match_dup 1))
11906 (set (match_dup 0) (zero_extend:SI (match_dup 2)))]
11908 operands[1] = shallow_copy_rtx (operands[1]);
11909 PUT_MODE (operands[1], QImode);
11910 operands[2] = gen_lowpart (QImode, operands[0]);
11913 (define_insn "*setcc_qi"
11914 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11915 (match_operator:QI 1 "ix86_comparison_operator"
11916 [(reg FLAGS_REG) (const_int 0)]))]
11919 [(set_attr "type" "setcc")
11920 (set_attr "mode" "QI")])
11922 (define_insn "*setcc_qi_slp"
11923 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
11924 (match_operator:QI 1 "ix86_comparison_operator"
11925 [(reg FLAGS_REG) (const_int 0)]))]
11928 [(set_attr "type" "setcc")
11929 (set_attr "mode" "QI")])
11931 ;; In general it is not safe to assume too much about CCmode registers,
11932 ;; so simplify-rtx stops when it sees a second one. Under certain
11933 ;; conditions this is safe on x86, so help combine not create
11940 [(set (match_operand:QI 0 "nonimmediate_operand")
11941 (ne:QI (match_operator 1 "ix86_comparison_operator"
11942 [(reg FLAGS_REG) (const_int 0)])
11945 [(set (match_dup 0) (match_dup 1))]
11947 operands[1] = shallow_copy_rtx (operands[1]);
11948 PUT_MODE (operands[1], QImode);
11952 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand"))
11953 (ne:QI (match_operator 1 "ix86_comparison_operator"
11954 [(reg FLAGS_REG) (const_int 0)])
11957 [(set (match_dup 0) (match_dup 1))]
11959 operands[1] = shallow_copy_rtx (operands[1]);
11960 PUT_MODE (operands[1], QImode);
11964 [(set (match_operand:QI 0 "nonimmediate_operand")
11965 (eq:QI (match_operator 1 "ix86_comparison_operator"
11966 [(reg FLAGS_REG) (const_int 0)])
11969 [(set (match_dup 0) (match_dup 1))]
11971 operands[1] = shallow_copy_rtx (operands[1]);
11972 PUT_MODE (operands[1], QImode);
11973 PUT_CODE (operands[1],
11974 ix86_reverse_condition (GET_CODE (operands[1]),
11975 GET_MODE (XEXP (operands[1], 0))));
11977 /* Make sure that (a) the CCmode we have for the flags is strong
11978 enough for the reversed compare or (b) we have a valid FP compare. */
11979 if (! ix86_comparison_operator (operands[1], VOIDmode))
11984 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand"))
11985 (eq:QI (match_operator 1 "ix86_comparison_operator"
11986 [(reg FLAGS_REG) (const_int 0)])
11989 [(set (match_dup 0) (match_dup 1))]
11991 operands[1] = shallow_copy_rtx (operands[1]);
11992 PUT_MODE (operands[1], QImode);
11993 PUT_CODE (operands[1],
11994 ix86_reverse_condition (GET_CODE (operands[1]),
11995 GET_MODE (XEXP (operands[1], 0))));
11997 /* Make sure that (a) the CCmode we have for the flags is strong
11998 enough for the reversed compare or (b) we have a valid FP compare. */
11999 if (! ix86_comparison_operator (operands[1], VOIDmode))
12003 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
12004 ;; subsequent logical operations are used to imitate conditional moves.
12005 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
12008 (define_insn "setcc_<mode>_sse"
12009 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
12010 (match_operator:MODEF 3 "sse_comparison_operator"
12011 [(match_operand:MODEF 1 "register_operand" "0,x")
12012 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
12013 "SSE_FLOAT_MODE_P (<MODE>mode)"
12015 cmp%D3<ssemodesuffix>\t{%2, %0|%0, %2}
12016 vcmp%D3<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
12017 [(set_attr "isa" "noavx,avx")
12018 (set_attr "type" "ssecmp")
12019 (set_attr "length_immediate" "1")
12020 (set_attr "prefix" "orig,vex")
12021 (set_attr "mode" "<MODE>")])
12023 ;; Basic conditional jump instructions.
12024 ;; We ignore the overflow flag for signed branch instructions.
12026 (define_insn "*jcc"
12028 (if_then_else (match_operator 1 "ix86_comparison_operator"
12029 [(reg FLAGS_REG) (const_int 0)])
12030 (label_ref (match_operand 0))
12034 [(set_attr "type" "ibr")
12035 (set_attr "modrm" "0")
12036 (set (attr "length")
12038 (and (ge (minus (match_dup 0) (pc))
12040 (lt (minus (match_dup 0) (pc))
12045 ;; In general it is not safe to assume too much about CCmode registers,
12046 ;; so simplify-rtx stops when it sees a second one. Under certain
12047 ;; conditions this is safe on x86, so help combine not create
12055 (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
12056 [(reg FLAGS_REG) (const_int 0)])
12058 (label_ref (match_operand 1))
12062 (if_then_else (match_dup 0)
12063 (label_ref (match_dup 1))
12066 operands[0] = shallow_copy_rtx (operands[0]);
12067 PUT_MODE (operands[0], VOIDmode);
12072 (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
12073 [(reg FLAGS_REG) (const_int 0)])
12075 (label_ref (match_operand 1))
12079 (if_then_else (match_dup 0)
12080 (label_ref (match_dup 1))
12083 operands[0] = shallow_copy_rtx (operands[0]);
12084 PUT_MODE (operands[0], VOIDmode);
12085 PUT_CODE (operands[0],
12086 ix86_reverse_condition (GET_CODE (operands[0]),
12087 GET_MODE (XEXP (operands[0], 0))));
12089 /* Make sure that (a) the CCmode we have for the flags is strong
12090 enough for the reversed compare or (b) we have a valid FP compare. */
12091 if (! ix86_comparison_operator (operands[0], VOIDmode))
12095 ;; Unconditional and other jump instructions
12097 (define_insn "jump"
12099 (label_ref (match_operand 0)))]
12102 [(set_attr "type" "ibr")
12103 (set_attr "modrm" "0")
12104 (set (attr "length")
12106 (and (ge (minus (match_dup 0) (pc))
12108 (lt (minus (match_dup 0) (pc))
12113 (define_expand "indirect_jump"
12114 [(set (pc) (match_operand 0 "indirect_branch_operand"))]
12117 if (TARGET_X32 || TARGET_INDIRECT_BRANCH_REGISTER)
12118 operands[0] = convert_memory_address (word_mode, operands[0]);
12119 cfun->machine->has_local_indirect_jump = true;
12122 (define_insn "*indirect_jump"
12123 [(set (pc) (match_operand:W 0 "indirect_branch_operand" "rBw"))]
12125 "* return ix86_output_indirect_jmp (operands[0]);"
12126 [(set (attr "type")
12127 (if_then_else (match_test "(cfun->machine->indirect_branch_type
12128 != indirect_branch_keep)")
12129 (const_string "multi")
12130 (const_string "ibr")))
12131 (set_attr "length_immediate" "0")])
12133 (define_expand "tablejump"
12134 [(parallel [(set (pc) (match_operand 0 "indirect_branch_operand"))
12135 (use (label_ref (match_operand 1)))])]
12138 /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
12139 relative. Convert the relative address to an absolute address. */
12143 enum rtx_code code;
12145 /* We can't use @GOTOFF for text labels on VxWorks;
12146 see gotoff_operand. */
12147 if (TARGET_64BIT || TARGET_VXWORKS_RTP)
12151 op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
12153 else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
12157 op1 = pic_offset_table_rtx;
12162 op0 = pic_offset_table_rtx;
12166 operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
12170 if (TARGET_X32 || TARGET_INDIRECT_BRANCH_REGISTER)
12171 operands[0] = convert_memory_address (word_mode, operands[0]);
12172 cfun->machine->has_local_indirect_jump = true;
12175 (define_insn "*tablejump_1"
12176 [(set (pc) (match_operand:W 0 "indirect_branch_operand" "rBw"))
12177 (use (label_ref (match_operand 1)))]
12179 "* return ix86_output_indirect_jmp (operands[0]);"
12180 [(set (attr "type")
12181 (if_then_else (match_test "(cfun->machine->indirect_branch_type
12182 != indirect_branch_keep)")
12183 (const_string "multi")
12184 (const_string "ibr")))
12185 (set_attr "length_immediate" "0")])
12187 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
12190 [(set (reg FLAGS_REG) (match_operand 0))
12191 (set (match_operand:QI 1 "register_operand")
12192 (match_operator:QI 2 "ix86_comparison_operator"
12193 [(reg FLAGS_REG) (const_int 0)]))
12194 (set (match_operand 3 "any_QIreg_operand")
12195 (zero_extend (match_dup 1)))]
12196 "(peep2_reg_dead_p (3, operands[1])
12197 || operands_match_p (operands[1], operands[3]))
12198 && ! reg_overlap_mentioned_p (operands[3], operands[0])
12199 && peep2_regno_dead_p (0, FLAGS_REG)"
12200 [(set (match_dup 4) (match_dup 0))
12201 (set (strict_low_part (match_dup 5))
12204 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
12205 operands[5] = gen_lowpart (QImode, operands[3]);
12206 ix86_expand_clear (operands[3]);
12210 [(parallel [(set (reg FLAGS_REG) (match_operand 0))
12211 (match_operand 4)])
12212 (set (match_operand:QI 1 "register_operand")
12213 (match_operator:QI 2 "ix86_comparison_operator"
12214 [(reg FLAGS_REG) (const_int 0)]))
12215 (set (match_operand 3 "any_QIreg_operand")
12216 (zero_extend (match_dup 1)))]
12217 "(peep2_reg_dead_p (3, operands[1])
12218 || operands_match_p (operands[1], operands[3]))
12219 && ! reg_overlap_mentioned_p (operands[3], operands[0])
12220 && ! reg_overlap_mentioned_p (operands[3], operands[4])
12221 && ! reg_set_p (operands[3], operands[4])
12222 && peep2_regno_dead_p (0, FLAGS_REG)"
12223 [(parallel [(set (match_dup 5) (match_dup 0))
12225 (set (strict_low_part (match_dup 6))
12228 operands[5] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
12229 operands[6] = gen_lowpart (QImode, operands[3]);
12230 ix86_expand_clear (operands[3]);
12234 [(set (reg FLAGS_REG) (match_operand 0))
12235 (parallel [(set (reg FLAGS_REG) (match_operand 1))
12236 (match_operand 5)])
12237 (set (match_operand:QI 2 "register_operand")
12238 (match_operator:QI 3 "ix86_comparison_operator"
12239 [(reg FLAGS_REG) (const_int 0)]))
12240 (set (match_operand 4 "any_QIreg_operand")
12241 (zero_extend (match_dup 2)))]
12242 "(peep2_reg_dead_p (4, operands[2])
12243 || operands_match_p (operands[2], operands[4]))
12244 && ! reg_overlap_mentioned_p (operands[4], operands[0])
12245 && ! reg_overlap_mentioned_p (operands[4], operands[1])
12246 && ! reg_overlap_mentioned_p (operands[4], operands[5])
12247 && ! reg_set_p (operands[4], operands[5])
12248 && refers_to_regno_p (FLAGS_REG, operands[1], (rtx *)NULL)
12249 && peep2_regno_dead_p (0, FLAGS_REG)"
12250 [(set (match_dup 6) (match_dup 0))
12251 (parallel [(set (match_dup 7) (match_dup 1))
12253 (set (strict_low_part (match_dup 8))
12256 operands[6] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
12257 operands[7] = gen_rtx_REG (GET_MODE (operands[1]), FLAGS_REG);
12258 operands[8] = gen_lowpart (QImode, operands[4]);
12259 ix86_expand_clear (operands[4]);
12262 ;; Similar, but match zero extend with andsi3.
12265 [(set (reg FLAGS_REG) (match_operand 0))
12266 (set (match_operand:QI 1 "register_operand")
12267 (match_operator:QI 2 "ix86_comparison_operator"
12268 [(reg FLAGS_REG) (const_int 0)]))
12269 (parallel [(set (match_operand:SI 3 "any_QIreg_operand")
12270 (and:SI (match_dup 3) (const_int 255)))
12271 (clobber (reg:CC FLAGS_REG))])]
12272 "REGNO (operands[1]) == REGNO (operands[3])
12273 && ! reg_overlap_mentioned_p (operands[3], operands[0])
12274 && peep2_regno_dead_p (0, FLAGS_REG)"
12275 [(set (match_dup 4) (match_dup 0))
12276 (set (strict_low_part (match_dup 5))
12279 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
12280 operands[5] = gen_lowpart (QImode, operands[3]);
12281 ix86_expand_clear (operands[3]);
12285 [(parallel [(set (reg FLAGS_REG) (match_operand 0))
12286 (match_operand 4)])
12287 (set (match_operand:QI 1 "register_operand")
12288 (match_operator:QI 2 "ix86_comparison_operator"
12289 [(reg FLAGS_REG) (const_int 0)]))
12290 (parallel [(set (match_operand 3 "any_QIreg_operand")
12291 (zero_extend (match_dup 1)))
12292 (clobber (reg:CC FLAGS_REG))])]
12293 "(peep2_reg_dead_p (3, operands[1])
12294 || operands_match_p (operands[1], operands[3]))
12295 && ! reg_overlap_mentioned_p (operands[3], operands[0])
12296 && ! reg_overlap_mentioned_p (operands[3], operands[4])
12297 && ! reg_set_p (operands[3], operands[4])
12298 && peep2_regno_dead_p (0, FLAGS_REG)"
12299 [(parallel [(set (match_dup 5) (match_dup 0))
12301 (set (strict_low_part (match_dup 6))
12304 operands[5] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
12305 operands[6] = gen_lowpart (QImode, operands[3]);
12306 ix86_expand_clear (operands[3]);
12310 [(set (reg FLAGS_REG) (match_operand 0))
12311 (parallel [(set (reg FLAGS_REG) (match_operand 1))
12312 (match_operand 5)])
12313 (set (match_operand:QI 2 "register_operand")
12314 (match_operator:QI 3 "ix86_comparison_operator"
12315 [(reg FLAGS_REG) (const_int 0)]))
12316 (parallel [(set (match_operand 4 "any_QIreg_operand")
12317 (zero_extend (match_dup 2)))
12318 (clobber (reg:CC FLAGS_REG))])]
12319 "(peep2_reg_dead_p (4, operands[2])
12320 || operands_match_p (operands[2], operands[4]))
12321 && ! reg_overlap_mentioned_p (operands[4], operands[0])
12322 && ! reg_overlap_mentioned_p (operands[4], operands[1])
12323 && ! reg_overlap_mentioned_p (operands[4], operands[5])
12324 && ! reg_set_p (operands[4], operands[5])
12325 && refers_to_regno_p (FLAGS_REG, operands[1], (rtx *)NULL)
12326 && peep2_regno_dead_p (0, FLAGS_REG)"
12327 [(set (match_dup 6) (match_dup 0))
12328 (parallel [(set (match_dup 7) (match_dup 1))
12330 (set (strict_low_part (match_dup 8))
12333 operands[6] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
12334 operands[7] = gen_rtx_REG (GET_MODE (operands[1]), FLAGS_REG);
12335 operands[8] = gen_lowpart (QImode, operands[4]);
12336 ix86_expand_clear (operands[4]);
12339 ;; Call instructions.
12341 ;; The predicates normally associated with named expanders are not properly
12342 ;; checked for calls. This is a bug in the generic code, but it isn't that
12343 ;; easy to fix. Ignore it for now and be prepared to fix things up.
12345 ;; P6 processors will jump to the address after the decrement when %esp
12346 ;; is used as a call operand, so they will execute return address as a code.
12347 ;; See Pentium Pro errata 70, Pentium 2 errata A33 and Pentium 3 errata E17.
12349 ;; Register constraint for call instruction.
12350 (define_mode_attr c [(SI "l") (DI "r")])
12352 ;; Call subroutine returning no value.
12354 (define_expand "call"
12355 [(call (match_operand:QI 0)
12357 (use (match_operand 2))]
12360 ix86_expand_call (NULL, operands[0], operands[1],
12361 operands[2], NULL, false);
12365 (define_expand "sibcall"
12366 [(call (match_operand:QI 0)
12368 (use (match_operand 2))]
12371 ix86_expand_call (NULL, operands[0], operands[1],
12372 operands[2], NULL, true);
12376 (define_insn "*call"
12377 [(call (mem:QI (match_operand:W 0 "call_insn_operand" "<c>BwBz"))
12378 (match_operand 1))]
12379 "!SIBLING_CALL_P (insn)"
12380 "* return ix86_output_call_insn (insn, operands[0]);"
12381 [(set_attr "type" "call")])
12383 ;; This covers both call and sibcall since only GOT slot is allowed.
12384 (define_insn "*call_got_x32"
12385 [(call (mem:QI (zero_extend:DI
12386 (match_operand:SI 0 "GOT_memory_operand" "Bg")))
12387 (match_operand 1))]
12390 rtx fnaddr = gen_const_mem (DImode, XEXP (operands[0], 0));
12391 return ix86_output_call_insn (insn, fnaddr);
12393 [(set_attr "type" "call")])
12395 ;; Since sibcall never returns, we can only use call-clobbered register
12397 (define_insn "*sibcall_GOT_32"
12400 (match_operand:SI 0 "register_no_elim_operand" "U")
12401 (match_operand:SI 1 "GOT32_symbol_operand"))))
12402 (match_operand 2))]
12405 && !TARGET_INDIRECT_BRANCH_REGISTER
12406 && SIBLING_CALL_P (insn)"
12408 rtx fnaddr = gen_rtx_PLUS (SImode, operands[0], operands[1]);
12409 fnaddr = gen_const_mem (SImode, fnaddr);
12410 return ix86_output_call_insn (insn, fnaddr);
12412 [(set_attr "type" "call")])
12414 (define_insn "*sibcall"
12415 [(call (mem:QI (match_operand:W 0 "sibcall_insn_operand" "UBsBz"))
12416 (match_operand 1))]
12417 "SIBLING_CALL_P (insn)"
12418 "* return ix86_output_call_insn (insn, operands[0]);"
12419 [(set_attr "type" "call")])
12421 (define_insn "*sibcall_memory"
12422 [(call (mem:QI (match_operand:W 0 "memory_operand" "m"))
12424 (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
12425 "!TARGET_X32 && !TARGET_INDIRECT_BRANCH_REGISTER"
12426 "* return ix86_output_call_insn (insn, operands[0]);"
12427 [(set_attr "type" "call")])
12430 [(set (match_operand:W 0 "register_operand")
12431 (match_operand:W 1 "memory_operand"))
12432 (call (mem:QI (match_dup 0))
12433 (match_operand 3))]
12435 && !TARGET_INDIRECT_BRANCH_REGISTER
12436 && SIBLING_CALL_P (peep2_next_insn (1))
12437 && !reg_mentioned_p (operands[0],
12438 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (1)))"
12439 [(parallel [(call (mem:QI (match_dup 1))
12441 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
12444 [(set (match_operand:W 0 "register_operand")
12445 (match_operand:W 1 "memory_operand"))
12446 (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
12447 (call (mem:QI (match_dup 0))
12448 (match_operand 3))]
12450 && !TARGET_INDIRECT_BRANCH_REGISTER
12451 && SIBLING_CALL_P (peep2_next_insn (2))
12452 && !reg_mentioned_p (operands[0],
12453 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (2)))"
12454 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
12455 (parallel [(call (mem:QI (match_dup 1))
12457 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
12459 (define_expand "call_pop"
12460 [(parallel [(call (match_operand:QI 0)
12461 (match_operand:SI 1))
12462 (set (reg:SI SP_REG)
12463 (plus:SI (reg:SI SP_REG)
12464 (match_operand:SI 3)))])]
12467 ix86_expand_call (NULL, operands[0], operands[1],
12468 operands[2], operands[3], false);
12472 (define_insn "*call_pop"
12473 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lBwBz"))
12475 (set (reg:SI SP_REG)
12476 (plus:SI (reg:SI SP_REG)
12477 (match_operand:SI 2 "immediate_operand" "i")))]
12478 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
12479 "* return ix86_output_call_insn (insn, operands[0]);"
12480 [(set_attr "type" "call")])
12482 (define_insn "*sibcall_pop"
12483 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "UBsBz"))
12485 (set (reg:SI SP_REG)
12486 (plus:SI (reg:SI SP_REG)
12487 (match_operand:SI 2 "immediate_operand" "i")))]
12488 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
12489 "* return ix86_output_call_insn (insn, operands[0]);"
12490 [(set_attr "type" "call")])
12492 (define_insn "*sibcall_pop_memory"
12493 [(call (mem:QI (match_operand:SI 0 "memory_operand" "Bs"))
12495 (set (reg:SI SP_REG)
12496 (plus:SI (reg:SI SP_REG)
12497 (match_operand:SI 2 "immediate_operand" "i")))
12498 (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
12500 "* return ix86_output_call_insn (insn, operands[0]);"
12501 [(set_attr "type" "call")])
12504 [(set (match_operand:SI 0 "register_operand")
12505 (match_operand:SI 1 "memory_operand"))
12506 (parallel [(call (mem:QI (match_dup 0))
12508 (set (reg:SI SP_REG)
12509 (plus:SI (reg:SI SP_REG)
12510 (match_operand:SI 4 "immediate_operand")))])]
12511 "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (1))
12512 && !reg_mentioned_p (operands[0],
12513 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (1)))"
12514 [(parallel [(call (mem:QI (match_dup 1))
12516 (set (reg:SI SP_REG)
12517 (plus:SI (reg:SI SP_REG)
12519 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
12522 [(set (match_operand:SI 0 "register_operand")
12523 (match_operand:SI 1 "memory_operand"))
12524 (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
12525 (parallel [(call (mem:QI (match_dup 0))
12527 (set (reg:SI SP_REG)
12528 (plus:SI (reg:SI SP_REG)
12529 (match_operand:SI 4 "immediate_operand")))])]
12530 "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (2))
12531 && !reg_mentioned_p (operands[0],
12532 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (2)))"
12533 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
12534 (parallel [(call (mem:QI (match_dup 1))
12536 (set (reg:SI SP_REG)
12537 (plus:SI (reg:SI SP_REG)
12539 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
12541 ;; Combining simple memory jump instruction
12544 [(set (match_operand:W 0 "register_operand")
12545 (match_operand:W 1 "memory_operand"))
12546 (set (pc) (match_dup 0))]
12548 && !TARGET_INDIRECT_BRANCH_REGISTER
12549 && peep2_reg_dead_p (2, operands[0])"
12550 [(set (pc) (match_dup 1))])
12552 ;; Call subroutine, returning value in operand 0
12554 (define_expand "call_value"
12555 [(set (match_operand 0)
12556 (call (match_operand:QI 1)
12557 (match_operand 2)))
12558 (use (match_operand 3))]
12561 ix86_expand_call (operands[0], operands[1], operands[2],
12562 operands[3], NULL, false);
12566 (define_expand "sibcall_value"
12567 [(set (match_operand 0)
12568 (call (match_operand:QI 1)
12569 (match_operand 2)))
12570 (use (match_operand 3))]
12573 ix86_expand_call (operands[0], operands[1], operands[2],
12574 operands[3], NULL, true);
12578 (define_insn "*call_value"
12579 [(set (match_operand 0)
12580 (call (mem:QI (match_operand:W 1 "call_insn_operand" "<c>BwBz"))
12581 (match_operand 2)))]
12582 "!SIBLING_CALL_P (insn)"
12583 "* return ix86_output_call_insn (insn, operands[1]);"
12584 [(set_attr "type" "callv")])
12586 ;; This covers both call and sibcall since only GOT slot is allowed.
12587 (define_insn "*call_value_got_x32"
12588 [(set (match_operand 0)
12591 (match_operand:SI 1 "GOT_memory_operand" "Bg")))
12592 (match_operand 2)))]
12595 rtx fnaddr = gen_const_mem (DImode, XEXP (operands[1], 0));
12596 return ix86_output_call_insn (insn, fnaddr);
12598 [(set_attr "type" "callv")])
12600 ;; Since sibcall never returns, we can only use call-clobbered register
12602 (define_insn "*sibcall_value_GOT_32"
12603 [(set (match_operand 0)
12606 (match_operand:SI 1 "register_no_elim_operand" "U")
12607 (match_operand:SI 2 "GOT32_symbol_operand"))))
12608 (match_operand 3)))]
12611 && !TARGET_INDIRECT_BRANCH_REGISTER
12612 && SIBLING_CALL_P (insn)"
12614 rtx fnaddr = gen_rtx_PLUS (SImode, operands[1], operands[2]);
12615 fnaddr = gen_const_mem (SImode, fnaddr);
12616 return ix86_output_call_insn (insn, fnaddr);
12618 [(set_attr "type" "callv")])
12620 (define_insn "*sibcall_value"
12621 [(set (match_operand 0)
12622 (call (mem:QI (match_operand:W 1 "sibcall_insn_operand" "UBsBz"))
12623 (match_operand 2)))]
12624 "SIBLING_CALL_P (insn)"
12625 "* return ix86_output_call_insn (insn, operands[1]);"
12626 [(set_attr "type" "callv")])
12628 (define_insn "*sibcall_value_memory"
12629 [(set (match_operand 0)
12630 (call (mem:QI (match_operand:W 1 "memory_operand" "m"))
12631 (match_operand 2)))
12632 (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
12633 "!TARGET_X32 && !TARGET_INDIRECT_BRANCH_REGISTER"
12634 "* return ix86_output_call_insn (insn, operands[1]);"
12635 [(set_attr "type" "callv")])
12638 [(set (match_operand:W 0 "register_operand")
12639 (match_operand:W 1 "memory_operand"))
12640 (set (match_operand 2)
12641 (call (mem:QI (match_dup 0))
12642 (match_operand 3)))]
12644 && !TARGET_INDIRECT_BRANCH_REGISTER
12645 && SIBLING_CALL_P (peep2_next_insn (1))
12646 && !reg_mentioned_p (operands[0],
12647 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (1)))"
12648 [(parallel [(set (match_dup 2)
12649 (call (mem:QI (match_dup 1))
12651 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
12654 [(set (match_operand:W 0 "register_operand")
12655 (match_operand:W 1 "memory_operand"))
12656 (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
12657 (set (match_operand 2)
12658 (call (mem:QI (match_dup 0))
12659 (match_operand 3)))]
12661 && !TARGET_INDIRECT_BRANCH_REGISTER
12662 && SIBLING_CALL_P (peep2_next_insn (2))
12663 && !reg_mentioned_p (operands[0],
12664 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (2)))"
12665 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
12666 (parallel [(set (match_dup 2)
12667 (call (mem:QI (match_dup 1))
12669 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
12671 (define_expand "call_value_pop"
12672 [(parallel [(set (match_operand 0)
12673 (call (match_operand:QI 1)
12674 (match_operand:SI 2)))
12675 (set (reg:SI SP_REG)
12676 (plus:SI (reg:SI SP_REG)
12677 (match_operand:SI 4)))])]
12680 ix86_expand_call (operands[0], operands[1], operands[2],
12681 operands[3], operands[4], false);
12685 (define_insn "*call_value_pop"
12686 [(set (match_operand 0)
12687 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lBwBz"))
12688 (match_operand 2)))
12689 (set (reg:SI SP_REG)
12690 (plus:SI (reg:SI SP_REG)
12691 (match_operand:SI 3 "immediate_operand" "i")))]
12692 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
12693 "* return ix86_output_call_insn (insn, operands[1]);"
12694 [(set_attr "type" "callv")])
12696 (define_insn "*sibcall_value_pop"
12697 [(set (match_operand 0)
12698 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "UBsBz"))
12699 (match_operand 2)))
12700 (set (reg:SI SP_REG)
12701 (plus:SI (reg:SI SP_REG)
12702 (match_operand:SI 3 "immediate_operand" "i")))]
12703 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
12704 "* return ix86_output_call_insn (insn, operands[1]);"
12705 [(set_attr "type" "callv")])
12707 (define_insn "*sibcall_value_pop_memory"
12708 [(set (match_operand 0)
12709 (call (mem:QI (match_operand:SI 1 "memory_operand" "m"))
12710 (match_operand 2)))
12711 (set (reg:SI SP_REG)
12712 (plus:SI (reg:SI SP_REG)
12713 (match_operand:SI 3 "immediate_operand" "i")))
12714 (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
12716 "* return ix86_output_call_insn (insn, operands[1]);"
12717 [(set_attr "type" "callv")])
12720 [(set (match_operand:SI 0 "register_operand")
12721 (match_operand:SI 1 "memory_operand"))
12722 (parallel [(set (match_operand 2)
12723 (call (mem:QI (match_dup 0))
12724 (match_operand 3)))
12725 (set (reg:SI SP_REG)
12726 (plus:SI (reg:SI SP_REG)
12727 (match_operand:SI 4 "immediate_operand")))])]
12728 "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (1))
12729 && !reg_mentioned_p (operands[0],
12730 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (1)))"
12731 [(parallel [(set (match_dup 2)
12732 (call (mem:QI (match_dup 1))
12734 (set (reg:SI SP_REG)
12735 (plus:SI (reg:SI SP_REG)
12737 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
12740 [(set (match_operand:SI 0 "register_operand")
12741 (match_operand:SI 1 "memory_operand"))
12742 (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
12743 (parallel [(set (match_operand 2)
12744 (call (mem:QI (match_dup 0))
12745 (match_operand 3)))
12746 (set (reg:SI SP_REG)
12747 (plus:SI (reg:SI SP_REG)
12748 (match_operand:SI 4 "immediate_operand")))])]
12749 "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (2))
12750 && !reg_mentioned_p (operands[0],
12751 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (2)))"
12752 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
12753 (parallel [(set (match_dup 2)
12754 (call (mem:QI (match_dup 1))
12756 (set (reg:SI SP_REG)
12757 (plus:SI (reg:SI SP_REG)
12759 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
12761 ;; Call subroutine returning any type.
12763 (define_expand "untyped_call"
12764 [(parallel [(call (match_operand 0)
12767 (match_operand 2)])]
12772 /* In order to give reg-stack an easier job in validating two
12773 coprocessor registers as containing a possible return value,
12774 simply pretend the untyped call returns a complex long double
12777 We can't use SSE_REGPARM_MAX here since callee is unprototyped
12778 and should have the default ABI. */
12780 ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
12781 ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
12782 operands[0], const0_rtx,
12783 GEN_INT ((TARGET_64BIT
12784 ? (ix86_abi == SYSV_ABI
12785 ? X86_64_SSE_REGPARM_MAX
12786 : X86_64_MS_SSE_REGPARM_MAX)
12787 : X86_32_SSE_REGPARM_MAX)
12791 for (i = 0; i < XVECLEN (operands[2], 0); i++)
12793 rtx set = XVECEXP (operands[2], 0, i);
12794 emit_move_insn (SET_DEST (set), SET_SRC (set));
12797 /* The optimizer does not know that the call sets the function value
12798 registers we stored in the result block. We avoid problems by
12799 claiming that all hard registers are used and clobbered at this
12801 emit_insn (gen_blockage ());
12806 ;; Prologue and epilogue instructions
12808 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
12809 ;; all of memory. This blocks insns from being moved across this point.
12811 (define_insn "blockage"
12812 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
12815 [(set_attr "length" "0")])
12817 ;; Do not schedule instructions accessing memory across this point.
12819 (define_expand "memory_blockage"
12820 [(set (match_dup 0)
12821 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
12824 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
12825 MEM_VOLATILE_P (operands[0]) = 1;
12828 (define_insn "*memory_blockage"
12829 [(set (match_operand:BLK 0)
12830 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
12833 [(set_attr "length" "0")])
12835 ;; As USE insns aren't meaningful after reload, this is used instead
12836 ;; to prevent deleting instructions setting registers for PIC code
12837 (define_insn "prologue_use"
12838 [(unspec_volatile [(match_operand 0)] UNSPECV_PROLOGUE_USE)]
12841 [(set_attr "length" "0")])
12843 ;; Insn emitted into the body of a function to return from a function.
12844 ;; This is only done if the function's epilogue is known to be simple.
12845 ;; See comments for ix86_can_use_return_insn_p in i386.c.
12847 (define_expand "return"
12849 "ix86_can_use_return_insn_p ()"
12851 if (crtl->args.pops_args)
12853 rtx popc = GEN_INT (crtl->args.pops_args);
12854 emit_jump_insn (gen_simple_return_pop_internal (popc));
12859 ;; We need to disable this for TARGET_SEH, as otherwise
12860 ;; shrink-wrapped prologue gets enabled too. This might exceed
12861 ;; the maximum size of prologue in unwind information.
12862 ;; Also disallow shrink-wrapping if using stack slot to pass the
12863 ;; static chain pointer - the first instruction has to be pushl %esi
12864 ;; and it can't be moved around, as we use alternate entry points
12867 (define_expand "simple_return"
12869 "!TARGET_SEH && !ix86_static_chain_on_stack"
12871 if (crtl->args.pops_args)
12873 rtx popc = GEN_INT (crtl->args.pops_args);
12874 emit_jump_insn (gen_simple_return_pop_internal (popc));
12879 (define_insn "simple_return_internal"
12882 "* return ix86_output_function_return (false);"
12883 [(set_attr "length" "1")
12884 (set_attr "atom_unit" "jeu")
12885 (set_attr "length_immediate" "0")
12886 (set_attr "modrm" "0")])
12888 (define_insn "interrupt_return"
12890 (unspec [(const_int 0)] UNSPEC_INTERRUPT_RETURN)]
12893 return TARGET_64BIT ? "iretq" : "iret";
12896 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
12897 ;; instruction Athlon and K8 have.
12899 (define_insn "simple_return_internal_long"
12901 (unspec [(const_int 0)] UNSPEC_REP)]
12903 "* return ix86_output_function_return (true);"
12904 [(set_attr "length" "2")
12905 (set_attr "atom_unit" "jeu")
12906 (set_attr "length_immediate" "0")
12907 (set_attr "prefix_rep" "1")
12908 (set_attr "modrm" "0")])
12910 (define_insn_and_split "simple_return_pop_internal"
12912 (use (match_operand:SI 0 "const_int_operand"))]
12915 "&& cfun->machine->function_return_type != indirect_branch_keep"
12917 "ix86_split_simple_return_pop_internal (operands[0]); DONE;"
12918 [(set_attr "length" "3")
12919 (set_attr "atom_unit" "jeu")
12920 (set_attr "length_immediate" "2")
12921 (set_attr "modrm" "0")])
12923 (define_expand "simple_return_indirect_internal"
12926 (use (match_operand 0 "register_operand"))])])
12928 (define_insn "*simple_return_indirect_internal<mode>"
12930 (use (match_operand:W 0 "register_operand" "r"))]
12932 "* return ix86_output_indirect_function_return (operands[0]);"
12933 [(set (attr "type")
12934 (if_then_else (match_test "(cfun->machine->indirect_branch_type
12935 != indirect_branch_keep)")
12936 (const_string "multi")
12937 (const_string "ibr")))
12938 (set_attr "length_immediate" "0")])
12944 [(set_attr "length" "1")
12945 (set_attr "length_immediate" "0")
12946 (set_attr "modrm" "0")])
12948 ;; Generate nops. Operand 0 is the number of nops, up to 8.
12949 (define_insn "nops"
12950 [(unspec_volatile [(match_operand 0 "const_int_operand")]
12954 int num = INTVAL (operands[0]);
12956 gcc_assert (IN_RANGE (num, 1, 8));
12959 fputs ("\tnop\n", asm_out_file);
12963 [(set (attr "length") (symbol_ref "INTVAL (operands[0])"))
12964 (set_attr "length_immediate" "0")
12965 (set_attr "modrm" "0")])
12967 ;; Pad to 16-byte boundary, max skip in op0. Used to avoid
12968 ;; branch prediction penalty for the third jump in a 16-byte
12972 [(unspec_volatile [(match_operand 0)] UNSPECV_ALIGN)]
12975 #ifdef ASM_OUTPUT_MAX_SKIP_PAD
12976 ASM_OUTPUT_MAX_SKIP_PAD (asm_out_file, 4, (int)INTVAL (operands[0]));
12978 /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
12979 The align insn is used to avoid 3 jump instructions in the row to improve
12980 branch prediction and the benefits hardly outweigh the cost of extra 8
12981 nops on the average inserted by full alignment pseudo operation. */
12985 [(set_attr "length" "16")])
12987 (define_expand "prologue"
12990 "ix86_expand_prologue (); DONE;")
12992 (define_expand "set_got"
12994 [(set (match_operand:SI 0 "register_operand")
12995 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
12996 (clobber (reg:CC FLAGS_REG))])]
12999 if (flag_pic && !TARGET_VXWORKS_RTP)
13000 ix86_pc_thunk_call_expanded = true;
13003 (define_insn "*set_got"
13004 [(set (match_operand:SI 0 "register_operand" "=r")
13005 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
13006 (clobber (reg:CC FLAGS_REG))]
13008 "* return output_set_got (operands[0], NULL_RTX);"
13009 [(set_attr "type" "multi")
13010 (set_attr "length" "12")])
13012 (define_expand "set_got_labelled"
13014 [(set (match_operand:SI 0 "register_operand")
13015 (unspec:SI [(label_ref (match_operand 1))]
13017 (clobber (reg:CC FLAGS_REG))])]
13020 if (flag_pic && !TARGET_VXWORKS_RTP)
13021 ix86_pc_thunk_call_expanded = true;
13024 (define_insn "*set_got_labelled"
13025 [(set (match_operand:SI 0 "register_operand" "=r")
13026 (unspec:SI [(label_ref (match_operand 1))]
13028 (clobber (reg:CC FLAGS_REG))]
13030 "* return output_set_got (operands[0], operands[1]);"
13031 [(set_attr "type" "multi")
13032 (set_attr "length" "12")])
13034 (define_insn "set_got_rex64"
13035 [(set (match_operand:DI 0 "register_operand" "=r")
13036 (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
13038 "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}"
13039 [(set_attr "type" "lea")
13040 (set_attr "length_address" "4")
13041 (set_attr "mode" "DI")])
13043 (define_insn "set_rip_rex64"
13044 [(set (match_operand:DI 0 "register_operand" "=r")
13045 (unspec:DI [(label_ref (match_operand 1))] UNSPEC_SET_RIP))]
13047 "lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}"
13048 [(set_attr "type" "lea")
13049 (set_attr "length_address" "4")
13050 (set_attr "mode" "DI")])
13052 (define_insn "set_got_offset_rex64"
13053 [(set (match_operand:DI 0 "register_operand" "=r")
13055 [(label_ref (match_operand 1))]
13056 UNSPEC_SET_GOT_OFFSET))]
13058 "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}"
13059 [(set_attr "type" "imov")
13060 (set_attr "length_immediate" "0")
13061 (set_attr "length_address" "8")
13062 (set_attr "mode" "DI")])
13064 (define_expand "epilogue"
13067 "ix86_expand_epilogue (1); DONE;")
13069 (define_expand "sibcall_epilogue"
13072 "ix86_expand_epilogue (0); DONE;")
13074 (define_expand "eh_return"
13075 [(use (match_operand 0 "register_operand"))]
13078 rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
13080 /* Tricky bit: we write the address of the handler to which we will
13081 be returning into someone else's stack frame, one word below the
13082 stack address we wish to restore. */
13083 tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
13084 tmp = plus_constant (Pmode, tmp, -UNITS_PER_WORD);
13085 /* Return address is always in word_mode. */
13086 tmp = gen_rtx_MEM (word_mode, tmp);
13087 if (GET_MODE (ra) != word_mode)
13088 ra = convert_to_mode (word_mode, ra, 1);
13089 emit_move_insn (tmp, ra);
13091 emit_jump_insn (gen_eh_return_internal ());
13096 (define_insn_and_split "eh_return_internal"
13100 "epilogue_completed"
13102 "ix86_expand_epilogue (2); DONE;")
13104 (define_expand "@leave_<mode>"
13106 [(set (reg:W SP_REG) (plus:W (reg:W BP_REG) (match_dup 0)))
13107 (set (reg:W BP_REG) (mem:W (reg:W BP_REG)))
13108 (clobber (mem:BLK (scratch)))])]
13110 "operands[0] = GEN_INT (<MODE_SIZE>);")
13112 (define_insn "*leave"
13113 [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
13114 (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
13115 (clobber (mem:BLK (scratch)))]
13118 [(set_attr "type" "leave")])
13120 (define_insn "*leave_rex64"
13121 [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
13122 (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
13123 (clobber (mem:BLK (scratch)))]
13126 [(set_attr "type" "leave")])
13128 ;; Handle -fsplit-stack.
13130 (define_expand "split_stack_prologue"
13134 ix86_expand_split_stack_prologue ();
13138 ;; In order to support the call/return predictor, we use a return
13139 ;; instruction which the middle-end doesn't see.
13140 (define_insn "split_stack_return"
13141 [(unspec_volatile [(match_operand:SI 0 "const_int_operand")]
13142 UNSPECV_SPLIT_STACK_RETURN)]
13145 if (operands[0] == const0_rtx)
13150 [(set_attr "atom_unit" "jeu")
13151 (set_attr "modrm" "0")
13152 (set (attr "length")
13153 (if_then_else (match_operand:SI 0 "const0_operand")
13156 (set (attr "length_immediate")
13157 (if_then_else (match_operand:SI 0 "const0_operand")
13161 ;; If there are operand 0 bytes available on the stack, jump to
13164 (define_expand "split_stack_space_check"
13165 [(set (pc) (if_then_else
13166 (ltu (minus (reg SP_REG)
13167 (match_operand 0 "register_operand"))
13169 (label_ref (match_operand 1))
13173 rtx reg = gen_reg_rtx (Pmode);
13175 emit_insn (gen_sub3_insn (reg, stack_pointer_rtx, operands[0]));
13177 operands[2] = ix86_split_stack_guard ();
13178 ix86_expand_branch (GEU, reg, operands[2], operands[1]);
13183 ;; Bit manipulation instructions.
13185 (define_expand "ffs<mode>2"
13186 [(set (match_dup 2) (const_int -1))
13187 (parallel [(set (match_dup 3) (match_dup 4))
13188 (set (match_operand:SWI48 0 "register_operand")
13190 (match_operand:SWI48 1 "nonimmediate_operand")))])
13191 (set (match_dup 0) (if_then_else:SWI48
13192 (eq (match_dup 3) (const_int 0))
13195 (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (const_int 1)))
13196 (clobber (reg:CC FLAGS_REG))])]
13199 machine_mode flags_mode;
13201 if (<MODE>mode == SImode && !TARGET_CMOVE)
13203 emit_insn (gen_ffssi2_no_cmove (operands[0], operands [1]));
13207 flags_mode = TARGET_BMI ? CCCmode : CCZmode;
13209 operands[2] = gen_reg_rtx (<MODE>mode);
13210 operands[3] = gen_rtx_REG (flags_mode, FLAGS_REG);
13211 operands[4] = gen_rtx_COMPARE (flags_mode, operands[1], const0_rtx);
13214 (define_insn_and_split "ffssi2_no_cmove"
13215 [(set (match_operand:SI 0 "register_operand" "=r")
13216 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
13217 (clobber (match_scratch:SI 2 "=&q"))
13218 (clobber (reg:CC FLAGS_REG))]
13221 "&& reload_completed"
13222 [(parallel [(set (match_dup 4) (match_dup 5))
13223 (set (match_dup 0) (ctz:SI (match_dup 1)))])
13224 (set (strict_low_part (match_dup 3))
13225 (eq:QI (match_dup 4) (const_int 0)))
13226 (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
13227 (clobber (reg:CC FLAGS_REG))])
13228 (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
13229 (clobber (reg:CC FLAGS_REG))])
13230 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
13231 (clobber (reg:CC FLAGS_REG))])]
13233 machine_mode flags_mode = TARGET_BMI ? CCCmode : CCZmode;
13235 operands[3] = gen_lowpart (QImode, operands[2]);
13236 operands[4] = gen_rtx_REG (flags_mode, FLAGS_REG);
13237 operands[5] = gen_rtx_COMPARE (flags_mode, operands[1], const0_rtx);
13239 ix86_expand_clear (operands[2]);
13242 (define_insn_and_split "*tzcnt<mode>_1"
13243 [(set (reg:CCC FLAGS_REG)
13244 (compare:CCC (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13246 (set (match_operand:SWI48 0 "register_operand" "=r")
13247 (ctz:SWI48 (match_dup 1)))]
13249 "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
13250 "&& TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
13251 && optimize_function_for_speed_p (cfun)
13252 && !reg_mentioned_p (operands[0], operands[1])"
13254 [(set (reg:CCC FLAGS_REG)
13255 (compare:CCC (match_dup 1) (const_int 0)))
13257 (ctz:SWI48 (match_dup 1)))
13258 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)])]
13259 "ix86_expand_clear (operands[0]);"
13260 [(set_attr "type" "alu1")
13261 (set_attr "prefix_0f" "1")
13262 (set_attr "prefix_rep" "1")
13263 (set_attr "btver2_decode" "double")
13264 (set_attr "mode" "<MODE>")])
13266 ; False dependency happens when destination is only updated by tzcnt,
13267 ; lzcnt or popcnt. There is no false dependency when destination is
13268 ; also used in source.
13269 (define_insn "*tzcnt<mode>_1_falsedep"
13270 [(set (reg:CCC FLAGS_REG)
13271 (compare:CCC (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13273 (set (match_operand:SWI48 0 "register_operand" "=r")
13274 (ctz:SWI48 (match_dup 1)))
13275 (unspec [(match_operand:SWI48 2 "register_operand" "0")]
13276 UNSPEC_INSN_FALSE_DEP)]
13278 "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
13279 [(set_attr "type" "alu1")
13280 (set_attr "prefix_0f" "1")
13281 (set_attr "prefix_rep" "1")
13282 (set_attr "btver2_decode" "double")
13283 (set_attr "mode" "<MODE>")])
13285 (define_insn "*bsf<mode>_1"
13286 [(set (reg:CCZ FLAGS_REG)
13287 (compare:CCZ (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13289 (set (match_operand:SWI48 0 "register_operand" "=r")
13290 (ctz:SWI48 (match_dup 1)))]
13292 "bsf{<imodesuffix>}\t{%1, %0|%0, %1}"
13293 [(set_attr "type" "alu1")
13294 (set_attr "prefix_0f" "1")
13295 (set_attr "btver2_decode" "double")
13296 (set_attr "znver1_decode" "vector")
13297 (set_attr "mode" "<MODE>")])
13299 (define_insn_and_split "ctz<mode>2"
13300 [(set (match_operand:SWI48 0 "register_operand" "=r")
13302 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
13303 (clobber (reg:CC FLAGS_REG))]
13307 return "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
13308 else if (optimize_function_for_size_p (cfun))
13310 else if (TARGET_GENERIC)
13311 /* tzcnt expands to 'rep bsf' and we can use it even if !TARGET_BMI. */
13312 return "rep%; bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
13314 return "bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
13316 "(TARGET_BMI || TARGET_GENERIC)
13317 && TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
13318 && optimize_function_for_speed_p (cfun)
13319 && !reg_mentioned_p (operands[0], operands[1])"
13321 [(set (match_dup 0)
13322 (ctz:SWI48 (match_dup 1)))
13323 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
13324 (clobber (reg:CC FLAGS_REG))])]
13325 "ix86_expand_clear (operands[0]);"
13326 [(set_attr "type" "alu1")
13327 (set_attr "prefix_0f" "1")
13328 (set (attr "prefix_rep")
13330 (ior (match_test "TARGET_BMI")
13331 (and (not (match_test "optimize_function_for_size_p (cfun)"))
13332 (match_test "TARGET_GENERIC")))
13334 (const_string "0")))
13335 (set_attr "mode" "<MODE>")])
13337 ; False dependency happens when destination is only updated by tzcnt,
13338 ; lzcnt or popcnt. There is no false dependency when destination is
13339 ; also used in source.
13340 (define_insn "*ctz<mode>2_falsedep"
13341 [(set (match_operand:SWI48 0 "register_operand" "=r")
13343 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
13344 (unspec [(match_operand:SWI48 2 "register_operand" "0")]
13345 UNSPEC_INSN_FALSE_DEP)
13346 (clobber (reg:CC FLAGS_REG))]
13350 return "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
13351 else if (TARGET_GENERIC)
13352 /* tzcnt expands to 'rep bsf' and we can use it even if !TARGET_BMI. */
13353 return "rep%; bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
13355 gcc_unreachable ();
13357 [(set_attr "type" "alu1")
13358 (set_attr "prefix_0f" "1")
13359 (set_attr "prefix_rep" "1")
13360 (set_attr "mode" "<MODE>")])
13362 (define_insn "bsr_rex64"
13363 [(set (match_operand:DI 0 "register_operand" "=r")
13364 (minus:DI (const_int 63)
13365 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
13366 (clobber (reg:CC FLAGS_REG))]
13368 "bsr{q}\t{%1, %0|%0, %1}"
13369 [(set_attr "type" "alu1")
13370 (set_attr "prefix_0f" "1")
13371 (set_attr "znver1_decode" "vector")
13372 (set_attr "mode" "DI")])
13375 [(set (match_operand:SI 0 "register_operand" "=r")
13376 (minus:SI (const_int 31)
13377 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
13378 (clobber (reg:CC FLAGS_REG))]
13380 "bsr{l}\t{%1, %0|%0, %1}"
13381 [(set_attr "type" "alu1")
13382 (set_attr "prefix_0f" "1")
13383 (set_attr "znver1_decode" "vector")
13384 (set_attr "mode" "SI")])
13386 (define_insn "*bsrhi"
13387 [(set (match_operand:HI 0 "register_operand" "=r")
13388 (minus:HI (const_int 15)
13389 (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
13390 (clobber (reg:CC FLAGS_REG))]
13392 "bsr{w}\t{%1, %0|%0, %1}"
13393 [(set_attr "type" "alu1")
13394 (set_attr "prefix_0f" "1")
13395 (set_attr "znver1_decode" "vector")
13396 (set_attr "mode" "HI")])
13398 (define_expand "clz<mode>2"
13400 [(set (match_operand:SWI48 0 "register_operand")
13403 (clz:SWI48 (match_operand:SWI48 1 "nonimmediate_operand"))))
13404 (clobber (reg:CC FLAGS_REG))])
13406 [(set (match_dup 0) (xor:SWI48 (match_dup 0) (match_dup 2)))
13407 (clobber (reg:CC FLAGS_REG))])]
13412 emit_insn (gen_clz<mode>2_lzcnt (operands[0], operands[1]));
13415 operands[2] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
13418 (define_insn_and_split "clz<mode>2_lzcnt"
13419 [(set (match_operand:SWI48 0 "register_operand" "=r")
13421 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
13422 (clobber (reg:CC FLAGS_REG))]
13424 "lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
13425 "&& TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
13426 && optimize_function_for_speed_p (cfun)
13427 && !reg_mentioned_p (operands[0], operands[1])"
13429 [(set (match_dup 0)
13430 (clz:SWI48 (match_dup 1)))
13431 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
13432 (clobber (reg:CC FLAGS_REG))])]
13433 "ix86_expand_clear (operands[0]);"
13434 [(set_attr "prefix_rep" "1")
13435 (set_attr "type" "bitmanip")
13436 (set_attr "mode" "<MODE>")])
13438 ; False dependency happens when destination is only updated by tzcnt,
13439 ; lzcnt or popcnt. There is no false dependency when destination is
13440 ; also used in source.
13441 (define_insn "*clz<mode>2_lzcnt_falsedep"
13442 [(set (match_operand:SWI48 0 "register_operand" "=r")
13444 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
13445 (unspec [(match_operand:SWI48 2 "register_operand" "0")]
13446 UNSPEC_INSN_FALSE_DEP)
13447 (clobber (reg:CC FLAGS_REG))]
13449 "lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
13450 [(set_attr "prefix_rep" "1")
13451 (set_attr "type" "bitmanip")
13452 (set_attr "mode" "<MODE>")])
13454 (define_int_iterator LT_ZCNT
13455 [(UNSPEC_TZCNT "TARGET_BMI")
13456 (UNSPEC_LZCNT "TARGET_LZCNT")])
13458 (define_int_attr lt_zcnt
13459 [(UNSPEC_TZCNT "tzcnt")
13460 (UNSPEC_LZCNT "lzcnt")])
13462 (define_int_attr lt_zcnt_type
13463 [(UNSPEC_TZCNT "alu1")
13464 (UNSPEC_LZCNT "bitmanip")])
13466 ;; Version of lzcnt/tzcnt that is expanded from intrinsics. This version
13467 ;; provides operand size as output when source operand is zero.
13469 (define_insn_and_split "<lt_zcnt>_<mode>"
13470 [(set (match_operand:SWI48 0 "register_operand" "=r")
13472 [(match_operand:SWI48 1 "nonimmediate_operand" "rm")] LT_ZCNT))
13473 (clobber (reg:CC FLAGS_REG))]
13475 "<lt_zcnt>{<imodesuffix>}\t{%1, %0|%0, %1}"
13476 "&& TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
13477 && optimize_function_for_speed_p (cfun)
13478 && !reg_mentioned_p (operands[0], operands[1])"
13480 [(set (match_dup 0)
13481 (unspec:SWI48 [(match_dup 1)] LT_ZCNT))
13482 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
13483 (clobber (reg:CC FLAGS_REG))])]
13484 "ix86_expand_clear (operands[0]);"
13485 [(set_attr "type" "<lt_zcnt_type>")
13486 (set_attr "prefix_0f" "1")
13487 (set_attr "prefix_rep" "1")
13488 (set_attr "mode" "<MODE>")])
13490 ; False dependency happens when destination is only updated by tzcnt,
13491 ; lzcnt or popcnt. There is no false dependency when destination is
13492 ; also used in source.
13493 (define_insn "*<lt_zcnt>_<mode>_falsedep"
13494 [(set (match_operand:SWI48 0 "register_operand" "=r")
13496 [(match_operand:SWI48 1 "nonimmediate_operand" "rm")] LT_ZCNT))
13497 (unspec [(match_operand:SWI48 2 "register_operand" "0")]
13498 UNSPEC_INSN_FALSE_DEP)
13499 (clobber (reg:CC FLAGS_REG))]
13501 "<lt_zcnt>{<imodesuffix>}\t{%1, %0|%0, %1}"
13502 [(set_attr "type" "<lt_zcnt_type>")
13503 (set_attr "prefix_0f" "1")
13504 (set_attr "prefix_rep" "1")
13505 (set_attr "mode" "<MODE>")])
13507 (define_insn "<lt_zcnt>_hi"
13508 [(set (match_operand:HI 0 "register_operand" "=r")
13510 [(match_operand:HI 1 "nonimmediate_operand" "rm")] LT_ZCNT))
13511 (clobber (reg:CC FLAGS_REG))]
13513 "<lt_zcnt>{w}\t{%1, %0|%0, %1}"
13514 [(set_attr "type" "<lt_zcnt_type>")
13515 (set_attr "prefix_0f" "1")
13516 (set_attr "prefix_rep" "1")
13517 (set_attr "mode" "HI")])
13519 ;; BMI instructions.
13521 (define_insn "bmi_bextr_<mode>"
13522 [(set (match_operand:SWI48 0 "register_operand" "=r,r")
13523 (unspec:SWI48 [(match_operand:SWI48 1 "nonimmediate_operand" "r,m")
13524 (match_operand:SWI48 2 "register_operand" "r,r")]
13526 (clobber (reg:CC FLAGS_REG))]
13528 "bextr\t{%2, %1, %0|%0, %1, %2}"
13529 [(set_attr "type" "bitmanip")
13530 (set_attr "btver2_decode" "direct, double")
13531 (set_attr "mode" "<MODE>")])
13533 (define_insn "*bmi_bextr_<mode>_ccz"
13534 [(set (reg:CCZ FLAGS_REG)
13536 (unspec:SWI48 [(match_operand:SWI48 1 "nonimmediate_operand" "r,m")
13537 (match_operand:SWI48 2 "register_operand" "r,r")]
13540 (clobber (match_scratch:SWI48 0 "=r,r"))]
13542 "bextr\t{%2, %1, %0|%0, %1, %2}"
13543 [(set_attr "type" "bitmanip")
13544 (set_attr "btver2_decode" "direct, double")
13545 (set_attr "mode" "<MODE>")])
13547 (define_insn "*bmi_blsi_<mode>"
13548 [(set (match_operand:SWI48 0 "register_operand" "=r")
13551 (match_operand:SWI48 1 "nonimmediate_operand" "rm"))
13553 (clobber (reg:CC FLAGS_REG))]
13555 "blsi\t{%1, %0|%0, %1}"
13556 [(set_attr "type" "bitmanip")
13557 (set_attr "btver2_decode" "double")
13558 (set_attr "mode" "<MODE>")])
13560 (define_insn "*bmi_blsmsk_<mode>"
13561 [(set (match_operand:SWI48 0 "register_operand" "=r")
13564 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13567 (clobber (reg:CC FLAGS_REG))]
13569 "blsmsk\t{%1, %0|%0, %1}"
13570 [(set_attr "type" "bitmanip")
13571 (set_attr "btver2_decode" "double")
13572 (set_attr "mode" "<MODE>")])
13574 (define_insn "*bmi_blsr_<mode>"
13575 [(set (match_operand:SWI48 0 "register_operand" "=r")
13578 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13581 (clobber (reg:CC FLAGS_REG))]
13583 "blsr\t{%1, %0|%0, %1}"
13584 [(set_attr "type" "bitmanip")
13585 (set_attr "btver2_decode" "double")
13586 (set_attr "mode" "<MODE>")])
13588 (define_insn "*bmi_blsr_<mode>_cmp"
13589 [(set (reg:CCZ FLAGS_REG)
13593 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13597 (set (match_operand:SWI48 0 "register_operand" "=r")
13604 "blsr\t{%1, %0|%0, %1}"
13605 [(set_attr "type" "bitmanip")
13606 (set_attr "btver2_decode" "double")
13607 (set_attr "mode" "<MODE>")])
13609 (define_insn "*bmi_blsr_<mode>_ccz"
13610 [(set (reg:CCZ FLAGS_REG)
13614 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13618 (clobber (match_scratch:SWI48 0 "=r"))]
13620 "blsr\t{%1, %0|%0, %1}"
13621 [(set_attr "type" "bitmanip")
13622 (set_attr "btver2_decode" "double")
13623 (set_attr "mode" "<MODE>")])
13625 ;; BMI2 instructions.
13626 (define_expand "bmi2_bzhi_<mode>3"
13628 [(set (match_operand:SWI48 0 "register_operand")
13629 (if_then_else:SWI48
13630 (ne:QI (and:SWI48 (match_operand:SWI48 2 "register_operand")
13633 (zero_extract:SWI48
13634 (match_operand:SWI48 1 "nonimmediate_operand")
13635 (umin:SWI48 (and:SWI48 (match_dup 2) (const_int 255))
13639 (clobber (reg:CC FLAGS_REG))])]
13641 "operands[3] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT);")
13643 (define_insn "*bmi2_bzhi_<mode>3"
13644 [(set (match_operand:SWI48 0 "register_operand" "=r")
13645 (if_then_else:SWI48
13646 (ne:QI (and:SWI48 (match_operand:SWI48 2 "register_operand" "r")
13649 (zero_extract:SWI48
13650 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13651 (umin:SWI48 (and:SWI48 (match_dup 2) (const_int 255))
13652 (match_operand:SWI48 3 "const_int_operand" "n"))
13655 (clobber (reg:CC FLAGS_REG))]
13656 "TARGET_BMI2 && INTVAL (operands[3]) == <MODE_SIZE> * BITS_PER_UNIT"
13657 "bzhi\t{%2, %1, %0|%0, %1, %2}"
13658 [(set_attr "type" "bitmanip")
13659 (set_attr "prefix" "vex")
13660 (set_attr "mode" "<MODE>")])
13662 (define_insn "*bmi2_bzhi_<mode>3_1"
13663 [(set (match_operand:SWI48 0 "register_operand" "=r")
13664 (if_then_else:SWI48
13665 (ne:QI (match_operand:QI 2 "register_operand" "r") (const_int 0))
13666 (zero_extract:SWI48
13667 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13668 (umin:SWI48 (zero_extend:SWI48 (match_dup 2))
13669 (match_operand:SWI48 3 "const_int_operand" "n"))
13672 (clobber (reg:CC FLAGS_REG))]
13673 "TARGET_BMI2 && INTVAL (operands[3]) == <MODE_SIZE> * BITS_PER_UNIT"
13674 "bzhi\t{%<k>2, %1, %0|%0, %1, %<k>2}"
13675 [(set_attr "type" "bitmanip")
13676 (set_attr "prefix" "vex")
13677 (set_attr "mode" "<MODE>")])
13679 (define_insn "*bmi2_bzhi_<mode>3_1_ccz"
13680 [(set (reg:CCZ FLAGS_REG)
13682 (if_then_else:SWI48
13683 (ne:QI (match_operand:QI 2 "register_operand" "r") (const_int 0))
13684 (zero_extract:SWI48
13685 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13686 (umin:SWI48 (zero_extend:SWI48 (match_dup 2))
13687 (match_operand:SWI48 3 "const_int_operand" "n"))
13691 (clobber (match_scratch:SWI48 0 "=r"))]
13692 "TARGET_BMI2 && INTVAL (operands[3]) == <MODE_SIZE> * BITS_PER_UNIT"
13693 "bzhi\t{%<k>2, %1, %0|%0, %1, %<k>2}"
13694 [(set_attr "type" "bitmanip")
13695 (set_attr "prefix" "vex")
13696 (set_attr "mode" "<MODE>")])
13698 (define_insn "bmi2_pdep_<mode>3"
13699 [(set (match_operand:SWI48 0 "register_operand" "=r")
13700 (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
13701 (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
13704 "pdep\t{%2, %1, %0|%0, %1, %2}"
13705 [(set_attr "type" "bitmanip")
13706 (set_attr "prefix" "vex")
13707 (set_attr "mode" "<MODE>")])
13709 (define_insn "bmi2_pext_<mode>3"
13710 [(set (match_operand:SWI48 0 "register_operand" "=r")
13711 (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
13712 (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
13715 "pext\t{%2, %1, %0|%0, %1, %2}"
13716 [(set_attr "type" "bitmanip")
13717 (set_attr "prefix" "vex")
13718 (set_attr "mode" "<MODE>")])
13720 ;; TBM instructions.
13721 (define_expand "tbm_bextri_<mode>"
13723 [(set (match_operand:SWI48 0 "register_operand")
13724 (zero_extract:SWI48
13725 (match_operand:SWI48 1 "nonimmediate_operand")
13726 (match_operand 2 "const_0_to_255_operand" "N")
13727 (match_operand 3 "const_0_to_255_operand" "N")))
13728 (clobber (reg:CC FLAGS_REG))])]
13731 if (operands[2] == const0_rtx
13732 || INTVAL (operands[3]) >= <MODE_SIZE> * BITS_PER_UNIT)
13734 emit_move_insn (operands[0], const0_rtx);
13737 if (INTVAL (operands[2]) + INTVAL (operands[3])
13738 > <MODE_SIZE> * BITS_PER_UNIT)
13739 operands[2] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT - INTVAL (operands[3]));
13742 (define_insn "*tbm_bextri_<mode>"
13743 [(set (match_operand:SWI48 0 "register_operand" "=r")
13744 (zero_extract:SWI48
13745 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13746 (match_operand 2 "const_0_to_255_operand" "N")
13747 (match_operand 3 "const_0_to_255_operand" "N")))
13748 (clobber (reg:CC FLAGS_REG))]
13751 operands[2] = GEN_INT (INTVAL (operands[2]) << 8 | INTVAL (operands[3]));
13752 return "bextr\t{%2, %1, %0|%0, %1, %2}";
13754 [(set_attr "type" "bitmanip")
13755 (set_attr "mode" "<MODE>")])
13757 (define_insn "*tbm_blcfill_<mode>"
13758 [(set (match_operand:SWI48 0 "register_operand" "=r")
13761 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13764 (clobber (reg:CC FLAGS_REG))]
13766 "blcfill\t{%1, %0|%0, %1}"
13767 [(set_attr "type" "bitmanip")
13768 (set_attr "mode" "<MODE>")])
13770 (define_insn "*tbm_blci_<mode>"
13771 [(set (match_operand:SWI48 0 "register_operand" "=r")
13775 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13778 (clobber (reg:CC FLAGS_REG))]
13780 "blci\t{%1, %0|%0, %1}"
13781 [(set_attr "type" "bitmanip")
13782 (set_attr "mode" "<MODE>")])
13784 (define_insn "*tbm_blcic_<mode>"
13785 [(set (match_operand:SWI48 0 "register_operand" "=r")
13788 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13792 (clobber (reg:CC FLAGS_REG))]
13794 "blcic\t{%1, %0|%0, %1}"
13795 [(set_attr "type" "bitmanip")
13796 (set_attr "mode" "<MODE>")])
13798 (define_insn "*tbm_blcmsk_<mode>"
13799 [(set (match_operand:SWI48 0 "register_operand" "=r")
13802 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13805 (clobber (reg:CC FLAGS_REG))]
13807 "blcmsk\t{%1, %0|%0, %1}"
13808 [(set_attr "type" "bitmanip")
13809 (set_attr "mode" "<MODE>")])
13811 (define_insn "*tbm_blcs_<mode>"
13812 [(set (match_operand:SWI48 0 "register_operand" "=r")
13815 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13818 (clobber (reg:CC FLAGS_REG))]
13820 "blcs\t{%1, %0|%0, %1}"
13821 [(set_attr "type" "bitmanip")
13822 (set_attr "mode" "<MODE>")])
13824 (define_insn "*tbm_blsfill_<mode>"
13825 [(set (match_operand:SWI48 0 "register_operand" "=r")
13828 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13831 (clobber (reg:CC FLAGS_REG))]
13833 "blsfill\t{%1, %0|%0, %1}"
13834 [(set_attr "type" "bitmanip")
13835 (set_attr "mode" "<MODE>")])
13837 (define_insn "*tbm_blsic_<mode>"
13838 [(set (match_operand:SWI48 0 "register_operand" "=r")
13841 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13845 (clobber (reg:CC FLAGS_REG))]
13847 "blsic\t{%1, %0|%0, %1}"
13848 [(set_attr "type" "bitmanip")
13849 (set_attr "mode" "<MODE>")])
13851 (define_insn "*tbm_t1mskc_<mode>"
13852 [(set (match_operand:SWI48 0 "register_operand" "=r")
13855 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13859 (clobber (reg:CC FLAGS_REG))]
13861 "t1mskc\t{%1, %0|%0, %1}"
13862 [(set_attr "type" "bitmanip")
13863 (set_attr "mode" "<MODE>")])
13865 (define_insn "*tbm_tzmsk_<mode>"
13866 [(set (match_operand:SWI48 0 "register_operand" "=r")
13869 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13873 (clobber (reg:CC FLAGS_REG))]
13875 "tzmsk\t{%1, %0|%0, %1}"
13876 [(set_attr "type" "bitmanip")
13877 (set_attr "mode" "<MODE>")])
13879 (define_insn_and_split "popcount<mode>2"
13880 [(set (match_operand:SWI48 0 "register_operand" "=r")
13882 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
13883 (clobber (reg:CC FLAGS_REG))]
13887 return "popcnt\t{%1, %0|%0, %1}";
13889 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
13892 "&& TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
13893 && optimize_function_for_speed_p (cfun)
13894 && !reg_mentioned_p (operands[0], operands[1])"
13896 [(set (match_dup 0)
13897 (popcount:SWI48 (match_dup 1)))
13898 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
13899 (clobber (reg:CC FLAGS_REG))])]
13900 "ix86_expand_clear (operands[0]);"
13901 [(set_attr "prefix_rep" "1")
13902 (set_attr "type" "bitmanip")
13903 (set_attr "mode" "<MODE>")])
13905 ; False dependency happens when destination is only updated by tzcnt,
13906 ; lzcnt or popcnt. There is no false dependency when destination is
13907 ; also used in source.
13908 (define_insn "*popcount<mode>2_falsedep"
13909 [(set (match_operand:SWI48 0 "register_operand" "=r")
13911 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
13912 (unspec [(match_operand:SWI48 2 "register_operand" "0")]
13913 UNSPEC_INSN_FALSE_DEP)
13914 (clobber (reg:CC FLAGS_REG))]
13918 return "popcnt\t{%1, %0|%0, %1}";
13920 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
13923 [(set_attr "prefix_rep" "1")
13924 (set_attr "type" "bitmanip")
13925 (set_attr "mode" "<MODE>")])
13927 (define_insn_and_split "*popcounthi2_1"
13928 [(set (match_operand:SI 0 "register_operand")
13930 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand"))))
13931 (clobber (reg:CC FLAGS_REG))]
13933 && can_create_pseudo_p ()"
13938 rtx tmp = gen_reg_rtx (HImode);
13940 emit_insn (gen_popcounthi2 (tmp, operands[1]));
13941 emit_insn (gen_zero_extendhisi2 (operands[0], tmp));
13945 (define_insn "popcounthi2"
13946 [(set (match_operand:HI 0 "register_operand" "=r")
13948 (match_operand:HI 1 "nonimmediate_operand" "rm")))
13949 (clobber (reg:CC FLAGS_REG))]
13953 return "popcnt\t{%1, %0|%0, %1}";
13955 return "popcnt{w}\t{%1, %0|%0, %1}";
13958 [(set_attr "prefix_rep" "1")
13959 (set_attr "type" "bitmanip")
13960 (set_attr "mode" "HI")])
13962 (define_expand "bswapdi2"
13963 [(set (match_operand:DI 0 "register_operand")
13964 (bswap:DI (match_operand:DI 1 "nonimmediate_operand")))]
13968 operands[1] = force_reg (DImode, operands[1]);
13971 (define_expand "bswapsi2"
13972 [(set (match_operand:SI 0 "register_operand")
13973 (bswap:SI (match_operand:SI 1 "nonimmediate_operand")))]
13978 else if (TARGET_BSWAP)
13979 operands[1] = force_reg (SImode, operands[1]);
13982 rtx x = operands[0];
13984 emit_move_insn (x, operands[1]);
13985 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
13986 emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
13987 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
13992 (define_insn "*bswap<mode>2_movbe"
13993 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,r,m")
13994 (bswap:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,m,r")))]
13996 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
13999 movbe{<imodesuffix>}\t{%1, %0|%0, %1}
14000 movbe{<imodesuffix>}\t{%1, %0|%0, %1}"
14001 [(set_attr "type" "bitmanip,imov,imov")
14002 (set_attr "modrm" "0,1,1")
14003 (set_attr "prefix_0f" "*,1,1")
14004 (set_attr "prefix_extra" "*,1,1")
14005 (set_attr "mode" "<MODE>")])
14007 (define_insn "*bswap<mode>2"
14008 [(set (match_operand:SWI48 0 "register_operand" "=r")
14009 (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "0")))]
14012 [(set_attr "type" "bitmanip")
14013 (set_attr "modrm" "0")
14014 (set_attr "mode" "<MODE>")])
14016 (define_expand "bswaphi2"
14017 [(set (match_operand:HI 0 "register_operand")
14018 (bswap:HI (match_operand:HI 1 "nonimmediate_operand")))]
14021 (define_insn "*bswaphi2_movbe"
14022 [(set (match_operand:HI 0 "nonimmediate_operand" "=Q,r,m")
14023 (bswap:HI (match_operand:HI 1 "nonimmediate_operand" "0,m,r")))]
14025 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
14027 xchg{b}\t{%h0, %b0|%b0, %h0}
14028 movbe{w}\t{%1, %0|%0, %1}
14029 movbe{w}\t{%1, %0|%0, %1}"
14030 [(set_attr "type" "imov")
14031 (set_attr "modrm" "*,1,1")
14032 (set_attr "prefix_0f" "*,1,1")
14033 (set_attr "prefix_extra" "*,1,1")
14034 (set_attr "pent_pair" "np,*,*")
14035 (set_attr "athlon_decode" "vector,*,*")
14036 (set_attr "amdfam10_decode" "double,*,*")
14037 (set_attr "bdver1_decode" "double,*,*")
14038 (set_attr "mode" "QI,HI,HI")])
14041 [(set (match_operand:HI 0 "general_reg_operand")
14042 (bswap:HI (match_dup 0)))]
14044 && !(TARGET_USE_XCHGB || optimize_function_for_size_p (cfun))
14045 && peep2_regno_dead_p (0, FLAGS_REG)"
14046 [(parallel [(set (match_dup 0) (rotate:HI (match_dup 0) (const_int 8)))
14047 (clobber (reg:CC FLAGS_REG))])])
14049 (define_insn "bswaphi_lowpart"
14050 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
14051 (bswap:HI (match_dup 0)))
14052 (clobber (reg:CC FLAGS_REG))]
14055 xchg{b}\t{%h0, %b0|%b0, %h0}
14056 rol{w}\t{$8, %0|%0, 8}"
14057 [(set (attr "preferred_for_size")
14058 (cond [(eq_attr "alternative" "0")
14059 (symbol_ref "true")]
14060 (symbol_ref "false")))
14061 (set (attr "preferred_for_speed")
14062 (cond [(eq_attr "alternative" "0")
14063 (symbol_ref "TARGET_USE_XCHGB")]
14064 (symbol_ref "!TARGET_USE_XCHGB")))
14065 (set_attr "length" "2,4")
14066 (set_attr "mode" "QI,HI")])
14068 (define_expand "paritydi2"
14069 [(set (match_operand:DI 0 "register_operand")
14070 (parity:DI (match_operand:DI 1 "register_operand")))]
14073 rtx scratch = gen_reg_rtx (QImode);
14075 emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX,
14076 NULL_RTX, operands[1]));
14078 ix86_expand_setcc (scratch, ORDERED,
14079 gen_rtx_REG (CCmode, FLAGS_REG), const0_rtx);
14082 emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
14085 rtx tmp = gen_reg_rtx (SImode);
14087 emit_insn (gen_zero_extendqisi2 (tmp, scratch));
14088 emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
14093 (define_expand "paritysi2"
14094 [(set (match_operand:SI 0 "register_operand")
14095 (parity:SI (match_operand:SI 1 "register_operand")))]
14098 rtx scratch = gen_reg_rtx (QImode);
14100 emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1]));
14102 ix86_expand_setcc (scratch, ORDERED,
14103 gen_rtx_REG (CCmode, FLAGS_REG), const0_rtx);
14105 emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
14109 (define_insn_and_split "paritydi2_cmp"
14110 [(set (reg:CC FLAGS_REG)
14111 (unspec:CC [(match_operand:DI 3 "register_operand" "0")]
14113 (clobber (match_scratch:DI 0 "=r"))
14114 (clobber (match_scratch:SI 1 "=&r"))
14115 (clobber (match_scratch:HI 2 "=Q"))]
14118 "&& reload_completed"
14120 [(set (match_dup 1)
14121 (xor:SI (match_dup 1) (match_dup 4)))
14122 (clobber (reg:CC FLAGS_REG))])
14124 [(set (reg:CC FLAGS_REG)
14125 (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
14126 (clobber (match_dup 1))
14127 (clobber (match_dup 2))])]
14129 operands[4] = gen_lowpart (SImode, operands[3]);
14133 emit_move_insn (operands[1], gen_lowpart (SImode, operands[3]));
14134 emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32)));
14137 operands[1] = gen_highpart (SImode, operands[3]);
14140 (define_insn_and_split "paritysi2_cmp"
14141 [(set (reg:CC FLAGS_REG)
14142 (unspec:CC [(match_operand:SI 2 "register_operand" "0")]
14144 (clobber (match_scratch:SI 0 "=r"))
14145 (clobber (match_scratch:HI 1 "=&Q"))]
14148 "&& reload_completed"
14150 [(set (match_dup 1)
14151 (xor:HI (match_dup 1) (match_dup 3)))
14152 (clobber (reg:CC FLAGS_REG))])
14154 [(set (reg:CC FLAGS_REG)
14155 (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
14156 (clobber (match_dup 1))])]
14158 operands[3] = gen_lowpart (HImode, operands[2]);
14160 emit_move_insn (operands[1], gen_lowpart (HImode, operands[2]));
14161 emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16)));
14164 (define_insn "*parityhi2_cmp"
14165 [(set (reg:CC FLAGS_REG)
14166 (unspec:CC [(match_operand:HI 1 "register_operand" "0")]
14168 (clobber (match_scratch:HI 0 "=Q"))]
14170 "xor{b}\t{%h0, %b0|%b0, %h0}"
14171 [(set_attr "length" "2")
14172 (set_attr "mode" "HI")])
14175 ;; Thread-local storage patterns for ELF.
14177 ;; Note that these code sequences must appear exactly as shown
14178 ;; in order to allow linker relaxation.
14180 (define_insn "*tls_global_dynamic_32_gnu"
14181 [(set (match_operand:SI 0 "register_operand" "=a")
14183 [(match_operand:SI 1 "register_operand" "Yb")
14184 (match_operand 2 "tls_symbolic_operand")
14185 (match_operand 3 "constant_call_address_operand" "Bz")
14188 (clobber (match_scratch:SI 4 "=d"))
14189 (clobber (match_scratch:SI 5 "=c"))
14190 (clobber (reg:CC FLAGS_REG))]
14191 "!TARGET_64BIT && TARGET_GNU_TLS"
14193 if (TARGET_SUN_TLS || flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT)
14195 ("lea{l}\t{%E2@tlsgd(,%1,1), %0|%0, %E2@tlsgd[%1*1]}", operands);
14198 ("lea{l}\t{%E2@tlsgd(%1), %0|%0, %E2@tlsgd[%1]}", operands);
14199 if (TARGET_SUN_TLS)
14200 #ifdef HAVE_AS_IX86_TLSGDPLT
14201 return "call\t%a2@tlsgdplt";
14203 return "call\t%p3@plt";
14205 if (flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT)
14206 return "call\t%P3";
14207 return "call\t{*%p3@GOT(%1)|[DWORD PTR %p3@GOT[%1]]}";
14209 [(set_attr "type" "multi")
14210 (set_attr "length" "12")])
14212 (define_expand "tls_global_dynamic_32"
14214 [(set (match_operand:SI 0 "register_operand")
14215 (unspec:SI [(match_operand:SI 2 "register_operand")
14216 (match_operand 1 "tls_symbolic_operand")
14217 (match_operand 3 "constant_call_address_operand")
14220 (clobber (match_scratch:SI 4))
14221 (clobber (match_scratch:SI 5))
14222 (clobber (reg:CC FLAGS_REG))])]
14224 "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
14226 (define_insn "*tls_global_dynamic_64_<mode>"
14227 [(set (match_operand:P 0 "register_operand" "=a")
14229 (mem:QI (match_operand 2 "constant_call_address_operand" "Bz"))
14230 (match_operand 3)))
14231 (unspec:P [(match_operand 1 "tls_symbolic_operand")
14237 /* The .loc directive has effect for 'the immediately following assembly
14238 instruction'. So for a sequence:
14242 the 'immediately following assembly instruction' is insn1.
14243 We want to emit an insn prefix here, but if we use .byte (as shown in
14244 'ELF Handling For Thread-Local Storage'), a preceding .loc will point
14245 inside the insn sequence, rather than to the start. After relaxation
14246 of the sequence by the linker, the .loc might point inside an insn.
14247 Use data16 prefix instead, which doesn't have this problem. */
14248 fputs ("\tdata16", asm_out_file);
14250 ("lea{q}\t{%E1@tlsgd(%%rip), %%rdi|rdi, %E1@tlsgd[rip]}", operands);
14251 if (TARGET_SUN_TLS || flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT)
14252 fputs (ASM_SHORT "0x6666\n", asm_out_file);
14254 fputs (ASM_BYTE "0x66\n", asm_out_file);
14255 fputs ("\trex64\n", asm_out_file);
14256 if (TARGET_SUN_TLS)
14257 return "call\t%p2@plt";
14258 if (flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT)
14259 return "call\t%P2";
14260 return "call\t{*%p2@GOTPCREL(%%rip)|[QWORD PTR %p2@GOTPCREL[rip]]}";
14262 [(set_attr "type" "multi")
14263 (set (attr "length")
14264 (symbol_ref "TARGET_X32 ? 15 : 16"))])
14266 (define_insn "*tls_global_dynamic_64_largepic"
14267 [(set (match_operand:DI 0 "register_operand" "=a")
14269 (mem:QI (plus:DI (match_operand:DI 2 "register_operand" "b")
14270 (match_operand:DI 3 "immediate_operand" "i")))
14271 (match_operand 4)))
14272 (unspec:DI [(match_operand 1 "tls_symbolic_operand")
14275 "TARGET_64BIT && ix86_cmodel == CM_LARGE_PIC && !TARGET_PECOFF
14276 && GET_CODE (operands[3]) == CONST
14277 && GET_CODE (XEXP (operands[3], 0)) == UNSPEC
14278 && XINT (XEXP (operands[3], 0), 1) == UNSPEC_PLTOFF"
14281 ("lea{q}\t{%E1@tlsgd(%%rip), %%rdi|rdi, %E1@tlsgd[rip]}", operands);
14282 output_asm_insn ("movabs{q}\t{%3, %%rax|rax, %3}", operands);
14283 output_asm_insn ("add{q}\t{%2, %%rax|rax, %2}", operands);
14284 return "call\t{*%%rax|rax}";
14286 [(set_attr "type" "multi")
14287 (set_attr "length" "22")])
14289 (define_expand "@tls_global_dynamic_64_<mode>"
14291 [(set (match_operand:P 0 "register_operand")
14293 (mem:QI (match_operand 2))
14295 (unspec:P [(match_operand 1 "tls_symbolic_operand")
14299 "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
14301 (define_insn "*tls_local_dynamic_base_32_gnu"
14302 [(set (match_operand:SI 0 "register_operand" "=a")
14304 [(match_operand:SI 1 "register_operand" "Yb")
14305 (match_operand 2 "constant_call_address_operand" "Bz")
14307 UNSPEC_TLS_LD_BASE))
14308 (clobber (match_scratch:SI 3 "=d"))
14309 (clobber (match_scratch:SI 4 "=c"))
14310 (clobber (reg:CC FLAGS_REG))]
14311 "!TARGET_64BIT && TARGET_GNU_TLS"
14314 ("lea{l}\t{%&@tlsldm(%1), %0|%0, %&@tlsldm[%1]}", operands);
14315 if (TARGET_SUN_TLS)
14317 if (HAVE_AS_IX86_TLSLDMPLT)
14318 return "call\t%&@tlsldmplt";
14320 return "call\t%p2@plt";
14322 if (flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT)
14323 return "call\t%P2";
14324 return "call\t{*%p2@GOT(%1)|[DWORD PTR %p2@GOT[%1]]}";
14326 [(set_attr "type" "multi")
14327 (set_attr "length" "11")])
14329 (define_expand "tls_local_dynamic_base_32"
14331 [(set (match_operand:SI 0 "register_operand")
14333 [(match_operand:SI 1 "register_operand")
14334 (match_operand 2 "constant_call_address_operand")
14336 UNSPEC_TLS_LD_BASE))
14337 (clobber (match_scratch:SI 3))
14338 (clobber (match_scratch:SI 4))
14339 (clobber (reg:CC FLAGS_REG))])]
14341 "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
14343 (define_insn "*tls_local_dynamic_base_64_<mode>"
14344 [(set (match_operand:P 0 "register_operand" "=a")
14346 (mem:QI (match_operand 1 "constant_call_address_operand" "Bz"))
14347 (match_operand 2)))
14348 (unspec:P [(reg:P SP_REG)] UNSPEC_TLS_LD_BASE)]
14352 ("lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}", operands);
14353 if (TARGET_SUN_TLS)
14354 return "call\t%p1@plt";
14355 if (flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT)
14356 return "call\t%P1";
14357 return "call\t{*%p1@GOTPCREL(%%rip)|[QWORD PTR %p1@GOTPCREL[rip]]}";
14359 [(set_attr "type" "multi")
14360 (set_attr "length" "12")])
14362 (define_insn "*tls_local_dynamic_base_64_largepic"
14363 [(set (match_operand:DI 0 "register_operand" "=a")
14365 (mem:QI (plus:DI (match_operand:DI 1 "register_operand" "b")
14366 (match_operand:DI 2 "immediate_operand" "i")))
14367 (match_operand 3)))
14368 (unspec:DI [(reg:DI SP_REG)] UNSPEC_TLS_LD_BASE)]
14369 "TARGET_64BIT && ix86_cmodel == CM_LARGE_PIC && !TARGET_PECOFF
14370 && GET_CODE (operands[2]) == CONST
14371 && GET_CODE (XEXP (operands[2], 0)) == UNSPEC
14372 && XINT (XEXP (operands[2], 0), 1) == UNSPEC_PLTOFF"
14375 ("lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}", operands);
14376 output_asm_insn ("movabs{q}\t{%2, %%rax|rax, %2}", operands);
14377 output_asm_insn ("add{q}\t{%1, %%rax|rax, %1}", operands);
14378 return "call\t{*%%rax|rax}";
14380 [(set_attr "type" "multi")
14381 (set_attr "length" "22")])
14383 (define_expand "@tls_local_dynamic_base_64_<mode>"
14385 [(set (match_operand:P 0 "register_operand")
14387 (mem:QI (match_operand 1))
14389 (unspec:P [(reg:P SP_REG)] UNSPEC_TLS_LD_BASE)])]
14391 "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
14393 ;; Local dynamic of a single variable is a lose. Show combine how
14394 ;; to convert that back to global dynamic.
14396 (define_insn_and_split "*tls_local_dynamic_32_once"
14397 [(set (match_operand:SI 0 "register_operand" "=a")
14399 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14400 (match_operand 2 "constant_call_address_operand" "Bz")
14402 UNSPEC_TLS_LD_BASE)
14403 (const:SI (unspec:SI
14404 [(match_operand 3 "tls_symbolic_operand")]
14406 (clobber (match_scratch:SI 4 "=d"))
14407 (clobber (match_scratch:SI 5 "=c"))
14408 (clobber (reg:CC FLAGS_REG))]
14413 [(set (match_dup 0)
14414 (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)
14417 (clobber (match_dup 4))
14418 (clobber (match_dup 5))
14419 (clobber (reg:CC FLAGS_REG))])])
14421 ;; Load and add the thread base pointer from %<tp_seg>:0.
14422 (define_insn_and_split "*load_tp_<mode>"
14423 [(set (match_operand:PTR 0 "register_operand" "=r")
14424 (unspec:PTR [(const_int 0)] UNSPEC_TP))]
14428 [(set (match_dup 0)
14431 addr_space_t as = DEFAULT_TLS_SEG_REG;
14433 operands[1] = gen_const_mem (<MODE>mode, const0_rtx);
14434 set_mem_addr_space (operands[1], as);
14437 (define_insn_and_split "*load_tp_x32_zext"
14438 [(set (match_operand:DI 0 "register_operand" "=r")
14440 (unspec:SI [(const_int 0)] UNSPEC_TP)))]
14444 [(set (match_dup 0)
14445 (zero_extend:DI (match_dup 1)))]
14447 addr_space_t as = DEFAULT_TLS_SEG_REG;
14449 operands[1] = gen_const_mem (SImode, const0_rtx);
14450 set_mem_addr_space (operands[1], as);
14453 (define_insn_and_split "*add_tp_<mode>"
14454 [(set (match_operand:PTR 0 "register_operand" "=r")
14456 (unspec:PTR [(const_int 0)] UNSPEC_TP)
14457 (match_operand:PTR 1 "register_operand" "0")))
14458 (clobber (reg:CC FLAGS_REG))]
14463 [(set (match_dup 0)
14464 (plus:PTR (match_dup 1) (match_dup 2)))
14465 (clobber (reg:CC FLAGS_REG))])]
14467 addr_space_t as = DEFAULT_TLS_SEG_REG;
14469 operands[2] = gen_const_mem (<MODE>mode, const0_rtx);
14470 set_mem_addr_space (operands[2], as);
14473 (define_insn_and_split "*add_tp_x32_zext"
14474 [(set (match_operand:DI 0 "register_operand" "=r")
14476 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
14477 (match_operand:SI 1 "register_operand" "0"))))
14478 (clobber (reg:CC FLAGS_REG))]
14483 [(set (match_dup 0)
14485 (plus:SI (match_dup 1) (match_dup 2))))
14486 (clobber (reg:CC FLAGS_REG))])]
14488 addr_space_t as = DEFAULT_TLS_SEG_REG;
14490 operands[2] = gen_const_mem (SImode, const0_rtx);
14491 set_mem_addr_space (operands[2], as);
14494 ;; The Sun linker took the AMD64 TLS spec literally and can only handle
14495 ;; %rax as destination of the initial executable code sequence.
14496 (define_insn "tls_initial_exec_64_sun"
14497 [(set (match_operand:DI 0 "register_operand" "=a")
14499 [(match_operand 1 "tls_symbolic_operand")]
14500 UNSPEC_TLS_IE_SUN))
14501 (clobber (reg:CC FLAGS_REG))]
14502 "TARGET_64BIT && TARGET_SUN_TLS"
14505 ("mov{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}", operands);
14506 return "add{q}\t{%a1@gottpoff(%%rip), %0|%0, %a1@gottpoff[rip]}";
14508 [(set_attr "type" "multi")])
14510 ;; GNU2 TLS patterns can be split.
14512 (define_expand "tls_dynamic_gnu2_32"
14513 [(set (match_dup 3)
14514 (plus:SI (match_operand:SI 2 "register_operand")
14516 (unspec:SI [(match_operand 1 "tls_symbolic_operand")]
14519 [(set (match_operand:SI 0 "register_operand")
14520 (unspec:SI [(match_dup 1) (match_dup 3)
14521 (match_dup 2) (reg:SI SP_REG)]
14523 (clobber (reg:CC FLAGS_REG))])]
14524 "!TARGET_64BIT && TARGET_GNU2_TLS"
14526 operands[3] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
14527 ix86_tls_descriptor_calls_expanded_in_cfun = true;
14530 (define_insn "*tls_dynamic_gnu2_lea_32"
14531 [(set (match_operand:SI 0 "register_operand" "=r")
14532 (plus:SI (match_operand:SI 1 "register_operand" "b")
14534 (unspec:SI [(match_operand 2 "tls_symbolic_operand")]
14535 UNSPEC_TLSDESC))))]
14536 "!TARGET_64BIT && TARGET_GNU2_TLS"
14537 "lea{l}\t{%E2@TLSDESC(%1), %0|%0, %E2@TLSDESC[%1]}"
14538 [(set_attr "type" "lea")
14539 (set_attr "mode" "SI")
14540 (set_attr "length" "6")
14541 (set_attr "length_address" "4")])
14543 (define_insn "*tls_dynamic_gnu2_call_32"
14544 [(set (match_operand:SI 0 "register_operand" "=a")
14545 (unspec:SI [(match_operand 1 "tls_symbolic_operand")
14546 (match_operand:SI 2 "register_operand" "0")
14547 ;; we have to make sure %ebx still points to the GOT
14548 (match_operand:SI 3 "register_operand" "b")
14551 (clobber (reg:CC FLAGS_REG))]
14552 "!TARGET_64BIT && TARGET_GNU2_TLS"
14553 "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
14554 [(set_attr "type" "call")
14555 (set_attr "length" "2")
14556 (set_attr "length_address" "0")])
14558 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
14559 [(set (match_operand:SI 0 "register_operand" "=&a")
14561 (unspec:SI [(match_operand 3 "tls_modbase_operand")
14562 (match_operand:SI 4)
14563 (match_operand:SI 2 "register_operand" "b")
14566 (const:SI (unspec:SI
14567 [(match_operand 1 "tls_symbolic_operand")]
14569 (clobber (reg:CC FLAGS_REG))]
14570 "!TARGET_64BIT && TARGET_GNU2_TLS"
14573 [(set (match_dup 0) (match_dup 5))]
14575 operands[5] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
14576 emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
14579 (define_expand "tls_dynamic_gnu2_64"
14580 [(set (match_dup 2)
14581 (unspec:DI [(match_operand 1 "tls_symbolic_operand")]
14584 [(set (match_operand:DI 0 "register_operand")
14585 (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
14587 (clobber (reg:CC FLAGS_REG))])]
14588 "TARGET_64BIT && TARGET_GNU2_TLS"
14590 operands[2] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
14591 ix86_tls_descriptor_calls_expanded_in_cfun = true;
14594 (define_insn "*tls_dynamic_gnu2_lea_64"
14595 [(set (match_operand:DI 0 "register_operand" "=r")
14596 (unspec:DI [(match_operand 1 "tls_symbolic_operand")]
14598 "TARGET_64BIT && TARGET_GNU2_TLS"
14599 "lea{q}\t{%E1@TLSDESC(%%rip), %0|%0, %E1@TLSDESC[rip]}"
14600 [(set_attr "type" "lea")
14601 (set_attr "mode" "DI")
14602 (set_attr "length" "7")
14603 (set_attr "length_address" "4")])
14605 (define_insn "*tls_dynamic_gnu2_call_64"
14606 [(set (match_operand:DI 0 "register_operand" "=a")
14607 (unspec:DI [(match_operand 1 "tls_symbolic_operand")
14608 (match_operand:DI 2 "register_operand" "0")
14611 (clobber (reg:CC FLAGS_REG))]
14612 "TARGET_64BIT && TARGET_GNU2_TLS"
14613 "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
14614 [(set_attr "type" "call")
14615 (set_attr "length" "2")
14616 (set_attr "length_address" "0")])
14618 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
14619 [(set (match_operand:DI 0 "register_operand" "=&a")
14621 (unspec:DI [(match_operand 2 "tls_modbase_operand")
14622 (match_operand:DI 3)
14625 (const:DI (unspec:DI
14626 [(match_operand 1 "tls_symbolic_operand")]
14628 (clobber (reg:CC FLAGS_REG))]
14629 "TARGET_64BIT && TARGET_GNU2_TLS"
14632 [(set (match_dup 0) (match_dup 4))]
14634 operands[4] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
14635 emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
14639 [(match_operand 0 "tls_address_pattern")]
14640 "TARGET_TLS_DIRECT_SEG_REFS"
14642 "operands[0] = ix86_rewrite_tls_address (operands[0]);")
14645 ;; These patterns match the binary 387 instructions for addM3, subM3,
14646 ;; mulM3 and divM3. There are three patterns for each of DFmode and
14647 ;; SFmode. The first is the normal insn, the second the same insn but
14648 ;; with one operand a conversion, and the third the same insn but with
14649 ;; the other operand a conversion. The conversion may be SFmode or
14650 ;; SImode if the target mode DFmode, but only SImode if the target mode
14653 ;; Gcc is slightly more smart about handling normal two address instructions
14654 ;; so use special patterns for add and mull.
14656 (define_insn "*fop_xf_comm_i387"
14657 [(set (match_operand:XF 0 "register_operand" "=f")
14658 (match_operator:XF 3 "binary_fp_operator"
14659 [(match_operand:XF 1 "register_operand" "%0")
14660 (match_operand:XF 2 "register_operand" "f")]))]
14662 && COMMUTATIVE_ARITH_P (operands[3])"
14663 "* return output_387_binary_op (insn, operands);"
14664 [(set (attr "type")
14665 (if_then_else (match_operand:XF 3 "mult_operator")
14666 (const_string "fmul")
14667 (const_string "fop")))
14668 (set_attr "mode" "XF")])
14670 (define_insn "*fop_<mode>_comm"
14671 [(set (match_operand:MODEF 0 "register_operand" "=f,x,v")
14672 (match_operator:MODEF 3 "binary_fp_operator"
14673 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,0,v")
14674 (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm,vm")]))]
14675 "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14676 || (TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)))
14677 && COMMUTATIVE_ARITH_P (operands[3])
14678 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
14679 "* return output_387_binary_op (insn, operands);"
14680 [(set (attr "type")
14681 (if_then_else (eq_attr "alternative" "1,2")
14682 (if_then_else (match_operand:MODEF 3 "mult_operator")
14683 (const_string "ssemul")
14684 (const_string "sseadd"))
14685 (if_then_else (match_operand:MODEF 3 "mult_operator")
14686 (const_string "fmul")
14687 (const_string "fop"))))
14688 (set_attr "isa" "*,noavx,avx")
14689 (set_attr "prefix" "orig,orig,vex")
14690 (set_attr "mode" "<MODE>")
14691 (set (attr "enabled")
14693 (match_test ("SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"))
14695 (eq_attr "alternative" "0")
14696 (symbol_ref "TARGET_MIX_SSE_I387
14697 && X87_ENABLE_ARITH (<MODE>mode)")
14698 (const_string "*"))
14700 (eq_attr "alternative" "0")
14701 (symbol_ref "true")
14702 (symbol_ref "false"))))])
14704 (define_insn "*rcpsf2_sse"
14705 [(set (match_operand:SF 0 "register_operand" "=x,x,x")
14706 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "0,x,m")]
14708 "TARGET_SSE && TARGET_SSE_MATH"
14710 %vrcpss\t{%d1, %0|%0, %d1}
14711 %vrcpss\t{%d1, %0|%0, %d1}
14712 %vrcpss\t{%1, %d0|%d0, %1}"
14713 [(set_attr "type" "sse")
14714 (set_attr "atom_sse_attr" "rcp")
14715 (set_attr "btver2_sse_attr" "rcp")
14716 (set_attr "prefix" "maybe_vex")
14717 (set_attr "mode" "SF")
14718 (set (attr "preferred_for_speed")
14719 (cond [(eq_attr "alternative" "1")
14720 (symbol_ref "TARGET_AVX || !TARGET_SSE_PARTIAL_REG_DEPENDENCY")
14721 (eq_attr "alternative" "2")
14722 (symbol_ref "!TARGET_SSE_PARTIAL_REG_DEPENDENCY")
14724 (symbol_ref "true")))])
14726 (define_insn "*fop_xf_1_i387"
14727 [(set (match_operand:XF 0 "register_operand" "=f,f")
14728 (match_operator:XF 3 "binary_fp_operator"
14729 [(match_operand:XF 1 "register_operand" "0,f")
14730 (match_operand:XF 2 "register_operand" "f,0")]))]
14732 && !COMMUTATIVE_ARITH_P (operands[3])"
14733 "* return output_387_binary_op (insn, operands);"
14734 [(set (attr "type")
14735 (if_then_else (match_operand:XF 3 "div_operator")
14736 (const_string "fdiv")
14737 (const_string "fop")))
14738 (set_attr "mode" "XF")])
14740 (define_insn "*fop_<mode>_1"
14741 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,v")
14742 (match_operator:MODEF 3 "binary_fp_operator"
14743 [(match_operand:MODEF 1
14744 "x87nonimm_ssenomem_operand" "0,fm,0,v")
14745 (match_operand:MODEF 2
14746 "nonimmediate_operand" "fm,0,xm,vm")]))]
14747 "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14748 || (TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)))
14749 && !COMMUTATIVE_ARITH_P (operands[3])
14750 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
14751 "* return output_387_binary_op (insn, operands);"
14752 [(set (attr "type")
14753 (if_then_else (eq_attr "alternative" "2,3")
14754 (if_then_else (match_operand:MODEF 3 "div_operator")
14755 (const_string "ssediv")
14756 (const_string "sseadd"))
14757 (if_then_else (match_operand:MODEF 3 "div_operator")
14758 (const_string "fdiv")
14759 (const_string "fop"))))
14760 (set_attr "isa" "*,*,noavx,avx")
14761 (set_attr "prefix" "orig,orig,orig,vex")
14762 (set_attr "mode" "<MODE>")
14763 (set (attr "enabled")
14765 (match_test ("SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"))
14767 (eq_attr "alternative" "0,1")
14768 (symbol_ref "TARGET_MIX_SSE_I387
14769 && X87_ENABLE_ARITH (<MODE>mode)")
14770 (const_string "*"))
14772 (eq_attr "alternative" "0,1")
14773 (symbol_ref "true")
14774 (symbol_ref "false"))))])
14776 (define_insn "*fop_<X87MODEF:mode>_2_i387"
14777 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
14778 (match_operator:X87MODEF 3 "binary_fp_operator"
14780 (match_operand:SWI24 1 "nonimmediate_operand" "m"))
14781 (match_operand:X87MODEF 2 "register_operand" "0")]))]
14782 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI24:MODE>mode)
14783 && !(SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
14784 && (TARGET_USE_<SWI24:MODE>MODE_FIOP
14785 || optimize_function_for_size_p (cfun))"
14786 "* return output_387_binary_op (insn, operands);"
14787 [(set (attr "type")
14788 (cond [(match_operand:X87MODEF 3 "mult_operator")
14789 (const_string "fmul")
14790 (match_operand:X87MODEF 3 "div_operator")
14791 (const_string "fdiv")
14793 (const_string "fop")))
14794 (set_attr "fp_int_src" "true")
14795 (set_attr "mode" "<SWI24:MODE>")])
14797 (define_insn "*fop_<X87MODEF:mode>_3_i387"
14798 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
14799 (match_operator:X87MODEF 3 "binary_fp_operator"
14800 [(match_operand:X87MODEF 1 "register_operand" "0")
14802 (match_operand:SWI24 2 "nonimmediate_operand" "m"))]))]
14803 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI24:MODE>mode)
14804 && !(SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
14805 && (TARGET_USE_<SWI24:MODE>MODE_FIOP
14806 || optimize_function_for_size_p (cfun))"
14807 "* return output_387_binary_op (insn, operands);"
14808 [(set (attr "type")
14809 (cond [(match_operand:X87MODEF 3 "mult_operator")
14810 (const_string "fmul")
14811 (match_operand:X87MODEF 3 "div_operator")
14812 (const_string "fdiv")
14814 (const_string "fop")))
14815 (set_attr "fp_int_src" "true")
14816 (set_attr "mode" "<MODE>")])
14818 (define_insn "*fop_xf_4_i387"
14819 [(set (match_operand:XF 0 "register_operand" "=f,f")
14820 (match_operator:XF 3 "binary_fp_operator"
14822 (match_operand:MODEF 1 "nonimmediate_operand" "fm,0"))
14823 (match_operand:XF 2 "register_operand" "0,f")]))]
14825 "* return output_387_binary_op (insn, operands);"
14826 [(set (attr "type")
14827 (cond [(match_operand:XF 3 "mult_operator")
14828 (const_string "fmul")
14829 (match_operand:XF 3 "div_operator")
14830 (const_string "fdiv")
14832 (const_string "fop")))
14833 (set_attr "mode" "<MODE>")])
14835 (define_insn "*fop_df_4_i387"
14836 [(set (match_operand:DF 0 "register_operand" "=f,f")
14837 (match_operator:DF 3 "binary_fp_operator"
14839 (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
14840 (match_operand:DF 2 "register_operand" "0,f")]))]
14841 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
14842 && !(SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
14843 "* return output_387_binary_op (insn, operands);"
14844 [(set (attr "type")
14845 (cond [(match_operand:DF 3 "mult_operator")
14846 (const_string "fmul")
14847 (match_operand:DF 3 "div_operator")
14848 (const_string "fdiv")
14850 (const_string "fop")))
14851 (set_attr "mode" "SF")])
14853 (define_insn "*fop_xf_5_i387"
14854 [(set (match_operand:XF 0 "register_operand" "=f,f")
14855 (match_operator:XF 3 "binary_fp_operator"
14856 [(match_operand:XF 1 "register_operand" "0,f")
14858 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
14860 "* return output_387_binary_op (insn, operands);"
14861 [(set (attr "type")
14862 (cond [(match_operand:XF 3 "mult_operator")
14863 (const_string "fmul")
14864 (match_operand:XF 3 "div_operator")
14865 (const_string "fdiv")
14867 (const_string "fop")))
14868 (set_attr "mode" "<MODE>")])
14870 (define_insn "*fop_df_5_i387"
14871 [(set (match_operand:DF 0 "register_operand" "=f,f")
14872 (match_operator:DF 3 "binary_fp_operator"
14873 [(match_operand:DF 1 "register_operand" "0,f")
14875 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
14876 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
14877 && !(SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
14878 "* return output_387_binary_op (insn, operands);"
14879 [(set (attr "type")
14880 (cond [(match_operand:DF 3 "mult_operator")
14881 (const_string "fmul")
14882 (match_operand:DF 3 "div_operator")
14883 (const_string "fdiv")
14885 (const_string "fop")))
14886 (set_attr "mode" "SF")])
14888 (define_insn "*fop_xf_6_i387"
14889 [(set (match_operand:XF 0 "register_operand" "=f,f")
14890 (match_operator:XF 3 "binary_fp_operator"
14892 (match_operand:MODEF 1 "register_operand" "0,f"))
14894 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
14896 "* return output_387_binary_op (insn, operands);"
14897 [(set (attr "type")
14898 (cond [(match_operand:XF 3 "mult_operator")
14899 (const_string "fmul")
14900 (match_operand:XF 3 "div_operator")
14901 (const_string "fdiv")
14903 (const_string "fop")))
14904 (set_attr "mode" "<MODE>")])
14906 (define_insn "*fop_df_6_i387"
14907 [(set (match_operand:DF 0 "register_operand" "=f,f")
14908 (match_operator:DF 3 "binary_fp_operator"
14910 (match_operand:SF 1 "register_operand" "0,f"))
14912 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
14913 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
14914 && !(SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
14915 "* return output_387_binary_op (insn, operands);"
14916 [(set (attr "type")
14917 (cond [(match_operand:DF 3 "mult_operator")
14918 (const_string "fmul")
14919 (match_operand:DF 3 "div_operator")
14920 (const_string "fdiv")
14922 (const_string "fop")))
14923 (set_attr "mode" "SF")])
14925 ;; FPU special functions.
14927 ;; This pattern implements a no-op XFmode truncation for
14928 ;; all fancy i386 XFmode math functions.
14930 (define_insn "truncxf<mode>2_i387_noop_unspec"
14931 [(set (match_operand:MODEF 0 "nonimmediate_operand" "=mf")
14932 (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")]
14933 UNSPEC_TRUNC_NOOP))]
14934 "TARGET_USE_FANCY_MATH_387"
14935 "* return output_387_reg_move (insn, operands);"
14936 [(set_attr "type" "fmov")
14937 (set_attr "mode" "<MODE>")])
14939 (define_insn "sqrtxf2"
14940 [(set (match_operand:XF 0 "register_operand" "=f")
14941 (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
14942 "TARGET_USE_FANCY_MATH_387"
14944 [(set_attr "type" "fpspc")
14945 (set_attr "mode" "XF")
14946 (set_attr "athlon_decode" "direct")
14947 (set_attr "amdfam10_decode" "direct")
14948 (set_attr "bdver1_decode" "direct")])
14950 (define_insn "*rsqrtsf2_sse"
14951 [(set (match_operand:SF 0 "register_operand" "=x,x,x")
14952 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "0,x,m")]
14954 "TARGET_SSE && TARGET_SSE_MATH"
14956 %vrsqrtss\t{%d1, %0|%0, %d1}
14957 %vrsqrtss\t{%d1, %0|%0, %d1}
14958 %vrsqrtss\t{%1, %d0|%d0, %1}"
14959 [(set_attr "type" "sse")
14960 (set_attr "atom_sse_attr" "rcp")
14961 (set_attr "btver2_sse_attr" "rcp")
14962 (set_attr "prefix" "maybe_vex")
14963 (set_attr "mode" "SF")
14964 (set (attr "preferred_for_speed")
14965 (cond [(eq_attr "alternative" "1")
14966 (symbol_ref "TARGET_AVX || !TARGET_SSE_PARTIAL_REG_DEPENDENCY")
14967 (eq_attr "alternative" "2")
14968 (symbol_ref "!TARGET_SSE_PARTIAL_REG_DEPENDENCY")
14970 (symbol_ref "true")))])
14972 (define_expand "rsqrtsf2"
14973 [(set (match_operand:SF 0 "register_operand")
14974 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand")]
14976 "TARGET_SSE && TARGET_SSE_MATH"
14978 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
14982 (define_insn "*sqrt<mode>2_sse"
14983 [(set (match_operand:MODEF 0 "register_operand" "=v,v,v")
14985 (match_operand:MODEF 1 "nonimmediate_operand" "0,v,m")))]
14986 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
14988 %vsqrt<ssemodesuffix>\t{%d1, %0|%0, %d1}
14989 %vsqrt<ssemodesuffix>\t{%d1, %0|%0, %d1}
14990 %vsqrt<ssemodesuffix>\t{%1, %d0|%d0, %1}"
14991 [(set_attr "type" "sse")
14992 (set_attr "atom_sse_attr" "sqrt")
14993 (set_attr "btver2_sse_attr" "sqrt")
14994 (set_attr "prefix" "maybe_vex")
14995 (set_attr "mode" "<MODE>")
14996 (set (attr "preferred_for_speed")
14997 (cond [(eq_attr "alternative" "1")
14998 (symbol_ref "TARGET_AVX || !TARGET_SSE_PARTIAL_REG_DEPENDENCY")
14999 (eq_attr "alternative" "2")
15000 (symbol_ref "!TARGET_SSE_PARTIAL_REG_DEPENDENCY")
15002 (symbol_ref "true")))])
15004 (define_expand "sqrt<mode>2"
15005 [(set (match_operand:MODEF 0 "register_operand")
15007 (match_operand:MODEF 1 "nonimmediate_operand")))]
15008 "(TARGET_USE_FANCY_MATH_387 && X87_ENABLE_ARITH (<MODE>mode))
15009 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
15011 if (<MODE>mode == SFmode
15012 && TARGET_SSE && TARGET_SSE_MATH
15013 && TARGET_RECIP_SQRT
15014 && !optimize_function_for_size_p (cfun)
15015 && flag_finite_math_only && !flag_trapping_math
15016 && flag_unsafe_math_optimizations)
15018 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
15022 if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
15024 rtx op0 = gen_reg_rtx (XFmode);
15025 rtx op1 = gen_reg_rtx (XFmode);
15027 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15028 emit_insn (gen_sqrtxf2 (op0, op1));
15029 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
15034 (define_expand "hypot<mode>3"
15035 [(use (match_operand:MODEF 0 "register_operand"))
15036 (use (match_operand:MODEF 1 "general_operand"))
15037 (use (match_operand:MODEF 2 "general_operand"))]
15038 "TARGET_USE_FANCY_MATH_387
15039 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15040 || TARGET_MIX_SSE_I387)
15041 && flag_finite_math_only
15042 && flag_unsafe_math_optimizations"
15044 rtx op0 = gen_reg_rtx (XFmode);
15045 rtx op1 = gen_reg_rtx (XFmode);
15046 rtx op2 = gen_reg_rtx (XFmode);
15048 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
15049 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15051 emit_insn (gen_mulxf3 (op1, op1, op1));
15052 emit_insn (gen_mulxf3 (op2, op2, op2));
15053 emit_insn (gen_addxf3 (op0, op2, op1));
15054 emit_insn (gen_sqrtxf2 (op0, op0));
15056 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
15060 (define_insn "x86_fnstsw_1"
15061 [(set (match_operand:HI 0 "register_operand" "=a")
15062 (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
15065 [(set_attr "length" "2")
15066 (set_attr "mode" "SI")
15067 (set_attr "unit" "i387")])
15069 (define_insn "fpremxf4_i387"
15070 [(set (match_operand:XF 0 "register_operand" "=f")
15071 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15072 (match_operand:XF 3 "register_operand" "1")]
15074 (set (match_operand:XF 1 "register_operand" "=f")
15075 (unspec:XF [(match_dup 2) (match_dup 3)]
15077 (set (reg:CCFP FPSR_REG)
15078 (unspec:CCFP [(match_dup 2) (match_dup 3)]
15080 "TARGET_USE_FANCY_MATH_387
15081 && flag_finite_math_only"
15083 [(set_attr "type" "fpspc")
15084 (set_attr "znver1_decode" "vector")
15085 (set_attr "mode" "XF")])
15087 (define_expand "fmodxf3"
15088 [(use (match_operand:XF 0 "register_operand"))
15089 (use (match_operand:XF 1 "general_operand"))
15090 (use (match_operand:XF 2 "general_operand"))]
15091 "TARGET_USE_FANCY_MATH_387
15092 && flag_finite_math_only"
15094 rtx_code_label *label = gen_label_rtx ();
15096 rtx op1 = gen_reg_rtx (XFmode);
15097 rtx op2 = gen_reg_rtx (XFmode);
15099 emit_move_insn (op2, operands[2]);
15100 emit_move_insn (op1, operands[1]);
15102 emit_label (label);
15103 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
15104 ix86_emit_fp_unordered_jump (label);
15105 LABEL_NUSES (label) = 1;
15107 emit_move_insn (operands[0], op1);
15111 (define_expand "fmod<mode>3"
15112 [(use (match_operand:MODEF 0 "register_operand"))
15113 (use (match_operand:MODEF 1 "general_operand"))
15114 (use (match_operand:MODEF 2 "general_operand"))]
15115 "TARGET_USE_FANCY_MATH_387
15116 && flag_finite_math_only"
15118 rtx (*gen_truncxf) (rtx, rtx);
15120 rtx_code_label *label = gen_label_rtx ();
15122 rtx op1 = gen_reg_rtx (XFmode);
15123 rtx op2 = gen_reg_rtx (XFmode);
15125 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
15126 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15128 emit_label (label);
15129 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
15130 ix86_emit_fp_unordered_jump (label);
15131 LABEL_NUSES (label) = 1;
15133 /* Truncate the result properly for strict SSE math. */
15134 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15135 && !TARGET_MIX_SSE_I387)
15136 gen_truncxf = gen_truncxf<mode>2;
15138 gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
15140 emit_insn (gen_truncxf (operands[0], op1));
15144 (define_insn "fprem1xf4_i387"
15145 [(set (match_operand:XF 0 "register_operand" "=f")
15146 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15147 (match_operand:XF 3 "register_operand" "1")]
15149 (set (match_operand:XF 1 "register_operand" "=f")
15150 (unspec:XF [(match_dup 2) (match_dup 3)]
15152 (set (reg:CCFP FPSR_REG)
15153 (unspec:CCFP [(match_dup 2) (match_dup 3)]
15155 "TARGET_USE_FANCY_MATH_387
15156 && flag_finite_math_only"
15158 [(set_attr "type" "fpspc")
15159 (set_attr "znver1_decode" "vector")
15160 (set_attr "mode" "XF")])
15162 (define_expand "remainderxf3"
15163 [(use (match_operand:XF 0 "register_operand"))
15164 (use (match_operand:XF 1 "general_operand"))
15165 (use (match_operand:XF 2 "general_operand"))]
15166 "TARGET_USE_FANCY_MATH_387
15167 && flag_finite_math_only"
15169 rtx_code_label *label = gen_label_rtx ();
15171 rtx op1 = gen_reg_rtx (XFmode);
15172 rtx op2 = gen_reg_rtx (XFmode);
15174 emit_move_insn (op2, operands[2]);
15175 emit_move_insn (op1, operands[1]);
15177 emit_label (label);
15178 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
15179 ix86_emit_fp_unordered_jump (label);
15180 LABEL_NUSES (label) = 1;
15182 emit_move_insn (operands[0], op1);
15186 (define_expand "remainder<mode>3"
15187 [(use (match_operand:MODEF 0 "register_operand"))
15188 (use (match_operand:MODEF 1 "general_operand"))
15189 (use (match_operand:MODEF 2 "general_operand"))]
15190 "TARGET_USE_FANCY_MATH_387
15191 && flag_finite_math_only"
15193 rtx (*gen_truncxf) (rtx, rtx);
15195 rtx_code_label *label = gen_label_rtx ();
15197 rtx op1 = gen_reg_rtx (XFmode);
15198 rtx op2 = gen_reg_rtx (XFmode);
15200 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
15201 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15203 emit_label (label);
15205 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
15206 ix86_emit_fp_unordered_jump (label);
15207 LABEL_NUSES (label) = 1;
15209 /* Truncate the result properly for strict SSE math. */
15210 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15211 && !TARGET_MIX_SSE_I387)
15212 gen_truncxf = gen_truncxf<mode>2;
15214 gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
15216 emit_insn (gen_truncxf (operands[0], op1));
15220 (define_int_iterator SINCOS
15224 (define_int_attr sincos
15225 [(UNSPEC_SIN "sin")
15226 (UNSPEC_COS "cos")])
15228 (define_insn "<sincos>xf2"
15229 [(set (match_operand:XF 0 "register_operand" "=f")
15230 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15232 "TARGET_USE_FANCY_MATH_387
15233 && flag_unsafe_math_optimizations"
15235 [(set_attr "type" "fpspc")
15236 (set_attr "znver1_decode" "vector")
15237 (set_attr "mode" "XF")])
15239 (define_expand "<sincos><mode>2"
15240 [(set (match_operand:MODEF 0 "register_operand")
15241 (unspec:MODEF [(match_operand:MODEF 1 "general_operand")]
15243 "TARGET_USE_FANCY_MATH_387
15244 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15245 || TARGET_MIX_SSE_I387)
15246 && flag_unsafe_math_optimizations"
15248 rtx op0 = gen_reg_rtx (XFmode);
15249 rtx op1 = gen_reg_rtx (XFmode);
15251 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15252 emit_insn (gen_<sincos>xf2 (op0, op1));
15253 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
15257 (define_insn "sincosxf3"
15258 [(set (match_operand:XF 0 "register_operand" "=f")
15259 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15260 UNSPEC_SINCOS_COS))
15261 (set (match_operand:XF 1 "register_operand" "=f")
15262 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15263 "TARGET_USE_FANCY_MATH_387
15264 && flag_unsafe_math_optimizations"
15266 [(set_attr "type" "fpspc")
15267 (set_attr "znver1_decode" "vector")
15268 (set_attr "mode" "XF")])
15270 (define_expand "sincos<mode>3"
15271 [(use (match_operand:MODEF 0 "register_operand"))
15272 (use (match_operand:MODEF 1 "register_operand"))
15273 (use (match_operand:MODEF 2 "general_operand"))]
15274 "TARGET_USE_FANCY_MATH_387
15275 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15276 || TARGET_MIX_SSE_I387)
15277 && flag_unsafe_math_optimizations"
15279 rtx op0 = gen_reg_rtx (XFmode);
15280 rtx op1 = gen_reg_rtx (XFmode);
15281 rtx op2 = gen_reg_rtx (XFmode);
15283 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
15284 emit_insn (gen_sincosxf3 (op0, op1, op2));
15285 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
15286 emit_insn (gen_truncxf<mode>2 (operands[1], op1));
15290 (define_insn "fptanxf4_i387"
15291 [(set (match_operand:SF 0 "register_operand" "=f")
15292 (match_operand:SF 3 "const1_operand"))
15293 (set (match_operand:XF 1 "register_operand" "=f")
15294 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15296 "TARGET_USE_FANCY_MATH_387
15297 && flag_unsafe_math_optimizations"
15299 [(set_attr "type" "fpspc")
15300 (set_attr "znver1_decode" "vector")
15301 (set_attr "mode" "XF")])
15303 (define_expand "tanxf2"
15304 [(use (match_operand:XF 0 "register_operand"))
15305 (use (match_operand:XF 1 "register_operand"))]
15306 "TARGET_USE_FANCY_MATH_387
15307 && flag_unsafe_math_optimizations"
15309 rtx one = gen_reg_rtx (SFmode);
15310 emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1],
15311 CONST1_RTX (SFmode)));
15315 (define_expand "tan<mode>2"
15316 [(use (match_operand:MODEF 0 "register_operand"))
15317 (use (match_operand:MODEF 1 "general_operand"))]
15318 "TARGET_USE_FANCY_MATH_387
15319 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15320 || TARGET_MIX_SSE_I387)
15321 && flag_unsafe_math_optimizations"
15323 rtx op0 = gen_reg_rtx (XFmode);
15324 rtx op1 = gen_reg_rtx (XFmode);
15326 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15327 emit_insn (gen_tanxf2 (op0, op1));
15328 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
15332 (define_insn "atan2xf3"
15333 [(set (match_operand:XF 0 "register_operand" "=f")
15334 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
15335 (match_operand:XF 2 "register_operand" "f")]
15337 (clobber (match_scratch:XF 3 "=2"))]
15338 "TARGET_USE_FANCY_MATH_387
15339 && flag_unsafe_math_optimizations"
15341 [(set_attr "type" "fpspc")
15342 (set_attr "znver1_decode" "vector")
15343 (set_attr "mode" "XF")])
15345 (define_expand "atan2<mode>3"
15346 [(use (match_operand:MODEF 0 "register_operand"))
15347 (use (match_operand:MODEF 1 "general_operand"))
15348 (use (match_operand:MODEF 2 "general_operand"))]
15349 "TARGET_USE_FANCY_MATH_387
15350 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15351 || TARGET_MIX_SSE_I387)
15352 && flag_unsafe_math_optimizations"
15354 rtx op0 = gen_reg_rtx (XFmode);
15355 rtx op1 = gen_reg_rtx (XFmode);
15356 rtx op2 = gen_reg_rtx (XFmode);
15358 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
15359 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15361 emit_insn (gen_atan2xf3 (op0, op2, op1));
15362 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
15366 (define_expand "atanxf2"
15367 [(parallel [(set (match_operand:XF 0 "register_operand")
15368 (unspec:XF [(match_dup 2)
15369 (match_operand:XF 1 "register_operand")]
15371 (clobber (match_scratch:XF 3))])]
15372 "TARGET_USE_FANCY_MATH_387
15373 && flag_unsafe_math_optimizations"
15374 "operands[2] = force_reg (XFmode, CONST1_RTX (XFmode));")
15376 (define_expand "atan<mode>2"
15377 [(use (match_operand:MODEF 0 "register_operand"))
15378 (use (match_operand:MODEF 1 "general_operand"))]
15379 "TARGET_USE_FANCY_MATH_387
15380 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15381 || TARGET_MIX_SSE_I387)
15382 && flag_unsafe_math_optimizations"
15384 rtx op0 = gen_reg_rtx (XFmode);
15385 rtx op1 = gen_reg_rtx (XFmode);
15387 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15388 emit_insn (gen_atanxf2 (op0, op1));
15389 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
15393 (define_expand "asinxf2"
15394 [(set (match_dup 2)
15395 (mult:XF (match_operand:XF 1 "register_operand")
15397 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
15398 (set (match_dup 5) (sqrt:XF (match_dup 4)))
15399 (parallel [(set (match_operand:XF 0 "register_operand")
15400 (unspec:XF [(match_dup 5) (match_dup 1)]
15402 (clobber (match_scratch:XF 6))])]
15403 "TARGET_USE_FANCY_MATH_387
15404 && flag_unsafe_math_optimizations"
15408 for (i = 2; i < 6; i++)
15409 operands[i] = gen_reg_rtx (XFmode);
15411 emit_move_insn (operands[3], CONST1_RTX (XFmode));
15414 (define_expand "asin<mode>2"
15415 [(use (match_operand:MODEF 0 "register_operand"))
15416 (use (match_operand:MODEF 1 "general_operand"))]
15417 "TARGET_USE_FANCY_MATH_387
15418 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15419 || TARGET_MIX_SSE_I387)
15420 && flag_unsafe_math_optimizations"
15422 rtx op0 = gen_reg_rtx (XFmode);
15423 rtx op1 = gen_reg_rtx (XFmode);
15425 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15426 emit_insn (gen_asinxf2 (op0, op1));
15427 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
15431 (define_expand "acosxf2"
15432 [(set (match_dup 2)
15433 (mult:XF (match_operand:XF 1 "register_operand")
15435 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
15436 (set (match_dup 5) (sqrt:XF (match_dup 4)))
15437 (parallel [(set (match_operand:XF 0 "register_operand")
15438 (unspec:XF [(match_dup 1) (match_dup 5)]
15440 (clobber (match_scratch:XF 6))])]
15441 "TARGET_USE_FANCY_MATH_387
15442 && flag_unsafe_math_optimizations"
15446 for (i = 2; i < 6; i++)
15447 operands[i] = gen_reg_rtx (XFmode);
15449 emit_move_insn (operands[3], CONST1_RTX (XFmode));
15452 (define_expand "acos<mode>2"
15453 [(use (match_operand:MODEF 0 "register_operand"))
15454 (use (match_operand:MODEF 1 "general_operand"))]
15455 "TARGET_USE_FANCY_MATH_387
15456 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15457 || TARGET_MIX_SSE_I387)
15458 && flag_unsafe_math_optimizations"
15460 rtx op0 = gen_reg_rtx (XFmode);
15461 rtx op1 = gen_reg_rtx (XFmode);
15463 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15464 emit_insn (gen_acosxf2 (op0, op1));
15465 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
15469 (define_expand "sinhxf2"
15470 [(use (match_operand:XF 0 "register_operand"))
15471 (use (match_operand:XF 1 "register_operand"))]
15472 "TARGET_USE_FANCY_MATH_387
15473 && flag_finite_math_only
15474 && flag_unsafe_math_optimizations"
15476 ix86_emit_i387_sinh (operands[0], operands[1]);
15480 (define_expand "sinh<mode>2"
15481 [(use (match_operand:MODEF 0 "register_operand"))
15482 (use (match_operand:MODEF 1 "general_operand"))]
15483 "TARGET_USE_FANCY_MATH_387
15484 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15485 || TARGET_MIX_SSE_I387)
15486 && flag_finite_math_only
15487 && flag_unsafe_math_optimizations"
15489 rtx op0 = gen_reg_rtx (XFmode);
15490 rtx op1 = gen_reg_rtx (XFmode);
15492 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15493 emit_insn (gen_sinhxf2 (op0, op1));
15494 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
15498 (define_expand "coshxf2"
15499 [(use (match_operand:XF 0 "register_operand"))
15500 (use (match_operand:XF 1 "register_operand"))]
15501 "TARGET_USE_FANCY_MATH_387
15502 && flag_unsafe_math_optimizations"
15504 ix86_emit_i387_cosh (operands[0], operands[1]);
15508 (define_expand "cosh<mode>2"
15509 [(use (match_operand:MODEF 0 "register_operand"))
15510 (use (match_operand:MODEF 1 "general_operand"))]
15511 "TARGET_USE_FANCY_MATH_387
15512 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15513 || TARGET_MIX_SSE_I387)
15514 && flag_unsafe_math_optimizations"
15516 rtx op0 = gen_reg_rtx (XFmode);
15517 rtx op1 = gen_reg_rtx (XFmode);
15519 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15520 emit_insn (gen_coshxf2 (op0, op1));
15521 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
15525 (define_expand "tanhxf2"
15526 [(use (match_operand:XF 0 "register_operand"))
15527 (use (match_operand:XF 1 "register_operand"))]
15528 "TARGET_USE_FANCY_MATH_387
15529 && flag_unsafe_math_optimizations"
15531 ix86_emit_i387_tanh (operands[0], operands[1]);
15535 (define_expand "tanh<mode>2"
15536 [(use (match_operand:MODEF 0 "register_operand"))
15537 (use (match_operand:MODEF 1 "general_operand"))]
15538 "TARGET_USE_FANCY_MATH_387
15539 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15540 || TARGET_MIX_SSE_I387)
15541 && flag_unsafe_math_optimizations"
15543 rtx op0 = gen_reg_rtx (XFmode);
15544 rtx op1 = gen_reg_rtx (XFmode);
15546 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15547 emit_insn (gen_tanhxf2 (op0, op1));
15548 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
15552 (define_expand "asinhxf2"
15553 [(use (match_operand:XF 0 "register_operand"))
15554 (use (match_operand:XF 1 "register_operand"))]
15555 "TARGET_USE_FANCY_MATH_387
15556 && flag_finite_math_only
15557 && flag_unsafe_math_optimizations"
15559 ix86_emit_i387_asinh (operands[0], operands[1]);
15563 (define_expand "asinh<mode>2"
15564 [(use (match_operand:MODEF 0 "register_operand"))
15565 (use (match_operand:MODEF 1 "general_operand"))]
15566 "TARGET_USE_FANCY_MATH_387
15567 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15568 || TARGET_MIX_SSE_I387)
15569 && flag_finite_math_only
15570 && flag_unsafe_math_optimizations"
15572 rtx op0 = gen_reg_rtx (XFmode);
15573 rtx op1 = gen_reg_rtx (XFmode);
15575 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15576 emit_insn (gen_asinhxf2 (op0, op1));
15577 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
15581 (define_expand "acoshxf2"
15582 [(use (match_operand:XF 0 "register_operand"))
15583 (use (match_operand:XF 1 "register_operand"))]
15584 "TARGET_USE_FANCY_MATH_387
15585 && flag_unsafe_math_optimizations"
15587 ix86_emit_i387_acosh (operands[0], operands[1]);
15591 (define_expand "acosh<mode>2"
15592 [(use (match_operand:MODEF 0 "register_operand"))
15593 (use (match_operand:MODEF 1 "general_operand"))]
15594 "TARGET_USE_FANCY_MATH_387
15595 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15596 || TARGET_MIX_SSE_I387)
15597 && flag_unsafe_math_optimizations"
15599 rtx op0 = gen_reg_rtx (XFmode);
15600 rtx op1 = gen_reg_rtx (XFmode);
15602 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15603 emit_insn (gen_acoshxf2 (op0, op1));
15604 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
15608 (define_expand "atanhxf2"
15609 [(use (match_operand:XF 0 "register_operand"))
15610 (use (match_operand:XF 1 "register_operand"))]
15611 "TARGET_USE_FANCY_MATH_387
15612 && flag_unsafe_math_optimizations"
15614 ix86_emit_i387_atanh (operands[0], operands[1]);
15618 (define_expand "atanh<mode>2"
15619 [(use (match_operand:MODEF 0 "register_operand"))
15620 (use (match_operand:MODEF 1 "general_operand"))]
15621 "TARGET_USE_FANCY_MATH_387
15622 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15623 || TARGET_MIX_SSE_I387)
15624 && flag_unsafe_math_optimizations"
15626 rtx op0 = gen_reg_rtx (XFmode);
15627 rtx op1 = gen_reg_rtx (XFmode);
15629 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15630 emit_insn (gen_atanhxf2 (op0, op1));
15631 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
15635 (define_insn "fyl2xxf3_i387"
15636 [(set (match_operand:XF 0 "register_operand" "=f")
15637 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
15638 (match_operand:XF 2 "register_operand" "f")]
15640 (clobber (match_scratch:XF 3 "=2"))]
15641 "TARGET_USE_FANCY_MATH_387
15642 && flag_unsafe_math_optimizations"
15644 [(set_attr "type" "fpspc")
15645 (set_attr "znver1_decode" "vector")
15646 (set_attr "mode" "XF")])
15648 (define_expand "logxf2"
15649 [(parallel [(set (match_operand:XF 0 "register_operand")
15650 (unspec:XF [(match_operand:XF 1 "register_operand")
15651 (match_dup 2)] UNSPEC_FYL2X))
15652 (clobber (match_scratch:XF 3))])]
15653 "TARGET_USE_FANCY_MATH_387
15654 && flag_unsafe_math_optimizations"
15657 = force_reg (XFmode, standard_80387_constant_rtx (4)); /* fldln2 */
15660 (define_expand "log<mode>2"
15661 [(use (match_operand:MODEF 0 "register_operand"))
15662 (use (match_operand:MODEF 1 "general_operand"))]
15663 "TARGET_USE_FANCY_MATH_387
15664 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15665 || TARGET_MIX_SSE_I387)
15666 && flag_unsafe_math_optimizations"
15668 rtx op0 = gen_reg_rtx (XFmode);
15669 rtx op1 = gen_reg_rtx (XFmode);
15671 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15672 emit_insn (gen_logxf2 (op0, op1));
15673 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
15677 (define_expand "log10xf2"
15678 [(parallel [(set (match_operand:XF 0 "register_operand")
15679 (unspec:XF [(match_operand:XF 1 "register_operand")
15680 (match_dup 2)] UNSPEC_FYL2X))
15681 (clobber (match_scratch:XF 3))])]
15682 "TARGET_USE_FANCY_MATH_387
15683 && flag_unsafe_math_optimizations"
15686 = force_reg (XFmode, standard_80387_constant_rtx (3)); /* fldlg2 */
15689 (define_expand "log10<mode>2"
15690 [(use (match_operand:MODEF 0 "register_operand"))
15691 (use (match_operand:MODEF 1 "general_operand"))]
15692 "TARGET_USE_FANCY_MATH_387
15693 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15694 || TARGET_MIX_SSE_I387)
15695 && flag_unsafe_math_optimizations"
15697 rtx op0 = gen_reg_rtx (XFmode);
15698 rtx op1 = gen_reg_rtx (XFmode);
15700 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15701 emit_insn (gen_log10xf2 (op0, op1));
15702 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
15706 (define_expand "log2xf2"
15707 [(parallel [(set (match_operand:XF 0 "register_operand")
15708 (unspec:XF [(match_operand:XF 1 "register_operand")
15709 (match_dup 2)] UNSPEC_FYL2X))
15710 (clobber (match_scratch:XF 3))])]
15711 "TARGET_USE_FANCY_MATH_387
15712 && flag_unsafe_math_optimizations"
15713 "operands[2] = force_reg (XFmode, CONST1_RTX (XFmode));")
15715 (define_expand "log2<mode>2"
15716 [(use (match_operand:MODEF 0 "register_operand"))
15717 (use (match_operand:MODEF 1 "general_operand"))]
15718 "TARGET_USE_FANCY_MATH_387
15719 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15720 || TARGET_MIX_SSE_I387)
15721 && flag_unsafe_math_optimizations"
15723 rtx op0 = gen_reg_rtx (XFmode);
15724 rtx op1 = gen_reg_rtx (XFmode);
15726 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15727 emit_insn (gen_log2xf2 (op0, op1));
15728 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
15732 (define_insn "fyl2xp1xf3_i387"
15733 [(set (match_operand:XF 0 "register_operand" "=f")
15734 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
15735 (match_operand:XF 2 "register_operand" "f")]
15737 (clobber (match_scratch:XF 3 "=2"))]
15738 "TARGET_USE_FANCY_MATH_387
15739 && flag_unsafe_math_optimizations"
15741 [(set_attr "type" "fpspc")
15742 (set_attr "znver1_decode" "vector")
15743 (set_attr "mode" "XF")])
15745 (define_expand "log1pxf2"
15746 [(use (match_operand:XF 0 "register_operand"))
15747 (use (match_operand:XF 1 "register_operand"))]
15748 "TARGET_USE_FANCY_MATH_387
15749 && flag_unsafe_math_optimizations"
15751 ix86_emit_i387_log1p (operands[0], operands[1]);
15755 (define_expand "log1p<mode>2"
15756 [(use (match_operand:MODEF 0 "register_operand"))
15757 (use (match_operand:MODEF 1 "general_operand"))]
15758 "TARGET_USE_FANCY_MATH_387
15759 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15760 || TARGET_MIX_SSE_I387)
15761 && flag_unsafe_math_optimizations"
15763 rtx op0 = gen_reg_rtx (XFmode);
15764 rtx op1 = gen_reg_rtx (XFmode);
15766 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15767 emit_insn (gen_log1pxf2 (op0, op1));
15768 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
15772 (define_insn "fxtractxf3_i387"
15773 [(set (match_operand:XF 0 "register_operand" "=f")
15774 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15775 UNSPEC_XTRACT_FRACT))
15776 (set (match_operand:XF 1 "register_operand" "=f")
15777 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
15778 "TARGET_USE_FANCY_MATH_387
15779 && flag_unsafe_math_optimizations"
15781 [(set_attr "type" "fpspc")
15782 (set_attr "znver1_decode" "vector")
15783 (set_attr "mode" "XF")])
15785 (define_expand "logbxf2"
15786 [(parallel [(set (match_dup 2)
15787 (unspec:XF [(match_operand:XF 1 "register_operand")]
15788 UNSPEC_XTRACT_FRACT))
15789 (set (match_operand:XF 0 "register_operand")
15790 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
15791 "TARGET_USE_FANCY_MATH_387
15792 && flag_unsafe_math_optimizations"
15793 "operands[2] = gen_reg_rtx (XFmode);")
15795 (define_expand "logb<mode>2"
15796 [(use (match_operand:MODEF 0 "register_operand"))
15797 (use (match_operand:MODEF 1 "general_operand"))]
15798 "TARGET_USE_FANCY_MATH_387
15799 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15800 || TARGET_MIX_SSE_I387)
15801 && flag_unsafe_math_optimizations"
15803 rtx op0 = gen_reg_rtx (XFmode);
15804 rtx op1 = gen_reg_rtx (XFmode);
15806 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15807 emit_insn (gen_logbxf2 (op0, op1));
15808 emit_insn (gen_truncxf<mode>2 (operands[0], op1));
15812 (define_expand "ilogbxf2"
15813 [(use (match_operand:SI 0 "register_operand"))
15814 (use (match_operand:XF 1 "register_operand"))]
15815 "TARGET_USE_FANCY_MATH_387
15816 && flag_unsafe_math_optimizations"
15820 if (optimize_insn_for_size_p ())
15823 op0 = gen_reg_rtx (XFmode);
15824 op1 = gen_reg_rtx (XFmode);
15826 emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
15827 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
15831 (define_expand "ilogb<mode>2"
15832 [(use (match_operand:SI 0 "register_operand"))
15833 (use (match_operand:MODEF 1 "general_operand"))]
15834 "TARGET_USE_FANCY_MATH_387
15835 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15836 || TARGET_MIX_SSE_I387)
15837 && flag_unsafe_math_optimizations"
15841 if (optimize_insn_for_size_p ())
15844 op0 = gen_reg_rtx (XFmode);
15845 op1 = gen_reg_rtx (XFmode);
15846 op2 = gen_reg_rtx (XFmode);
15848 emit_insn (gen_extend<mode>xf2 (op2, operands[1]));
15849 emit_insn (gen_fxtractxf3_i387 (op0, op1, op2));
15850 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
15854 (define_insn "*f2xm1xf2_i387"
15855 [(set (match_operand:XF 0 "register_operand" "=f")
15856 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15858 "TARGET_USE_FANCY_MATH_387
15859 && flag_unsafe_math_optimizations"
15861 [(set_attr "type" "fpspc")
15862 (set_attr "znver1_decode" "vector")
15863 (set_attr "mode" "XF")])
15865 (define_insn "fscalexf4_i387"
15866 [(set (match_operand:XF 0 "register_operand" "=f")
15867 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15868 (match_operand:XF 3 "register_operand" "1")]
15869 UNSPEC_FSCALE_FRACT))
15870 (set (match_operand:XF 1 "register_operand" "=f")
15871 (unspec:XF [(match_dup 2) (match_dup 3)]
15872 UNSPEC_FSCALE_EXP))]
15873 "TARGET_USE_FANCY_MATH_387
15874 && flag_unsafe_math_optimizations"
15876 [(set_attr "type" "fpspc")
15877 (set_attr "znver1_decode" "vector")
15878 (set_attr "mode" "XF")])
15880 (define_expand "expNcorexf3"
15881 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand")
15882 (match_operand:XF 2 "register_operand")))
15883 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
15884 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
15885 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
15886 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
15887 (parallel [(set (match_operand:XF 0 "register_operand")
15888 (unspec:XF [(match_dup 8) (match_dup 4)]
15889 UNSPEC_FSCALE_FRACT))
15891 (unspec:XF [(match_dup 8) (match_dup 4)]
15892 UNSPEC_FSCALE_EXP))])]
15893 "TARGET_USE_FANCY_MATH_387
15894 && flag_unsafe_math_optimizations"
15898 for (i = 3; i < 10; i++)
15899 operands[i] = gen_reg_rtx (XFmode);
15901 emit_move_insn (operands[7], CONST1_RTX (XFmode));
15904 (define_expand "expxf2"
15905 [(use (match_operand:XF 0 "register_operand"))
15906 (use (match_operand:XF 1 "register_operand"))]
15907 "TARGET_USE_FANCY_MATH_387
15908 && flag_unsafe_math_optimizations"
15910 rtx op2 = force_reg (XFmode, standard_80387_constant_rtx (5)); /* fldl2e */
15912 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
15916 (define_expand "exp<mode>2"
15917 [(use (match_operand:MODEF 0 "register_operand"))
15918 (use (match_operand:MODEF 1 "general_operand"))]
15919 "TARGET_USE_FANCY_MATH_387
15920 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15921 || TARGET_MIX_SSE_I387)
15922 && flag_unsafe_math_optimizations"
15924 rtx op0 = gen_reg_rtx (XFmode);
15925 rtx op1 = gen_reg_rtx (XFmode);
15927 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15928 emit_insn (gen_expxf2 (op0, op1));
15929 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
15933 (define_expand "exp10xf2"
15934 [(use (match_operand:XF 0 "register_operand"))
15935 (use (match_operand:XF 1 "register_operand"))]
15936 "TARGET_USE_FANCY_MATH_387
15937 && flag_unsafe_math_optimizations"
15939 rtx op2 = force_reg (XFmode, standard_80387_constant_rtx (6)); /* fldl2t */
15941 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
15945 (define_expand "exp10<mode>2"
15946 [(use (match_operand:MODEF 0 "register_operand"))
15947 (use (match_operand:MODEF 1 "general_operand"))]
15948 "TARGET_USE_FANCY_MATH_387
15949 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15950 || TARGET_MIX_SSE_I387)
15951 && flag_unsafe_math_optimizations"
15953 rtx op0 = gen_reg_rtx (XFmode);
15954 rtx op1 = gen_reg_rtx (XFmode);
15956 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15957 emit_insn (gen_exp10xf2 (op0, op1));
15958 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
15962 (define_expand "exp2xf2"
15963 [(use (match_operand:XF 0 "register_operand"))
15964 (use (match_operand:XF 1 "register_operand"))]
15965 "TARGET_USE_FANCY_MATH_387
15966 && flag_unsafe_math_optimizations"
15968 rtx op2 = force_reg (XFmode, CONST1_RTX (XFmode));
15970 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
15974 (define_expand "exp2<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_exp2xf2 (op0, op1));
15987 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
15991 (define_expand "expm1xf2"
15992 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand")
15994 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
15995 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
15996 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
15997 (parallel [(set (match_dup 7)
15998 (unspec:XF [(match_dup 6) (match_dup 4)]
15999 UNSPEC_FSCALE_FRACT))
16001 (unspec:XF [(match_dup 6) (match_dup 4)]
16002 UNSPEC_FSCALE_EXP))])
16003 (parallel [(set (match_dup 10)
16004 (unspec:XF [(match_dup 9) (match_dup 8)]
16005 UNSPEC_FSCALE_FRACT))
16006 (set (match_dup 11)
16007 (unspec:XF [(match_dup 9) (match_dup 8)]
16008 UNSPEC_FSCALE_EXP))])
16009 (set (match_dup 12) (minus:XF (match_dup 10) (match_dup 9)))
16010 (set (match_operand:XF 0 "register_operand")
16011 (plus:XF (match_dup 12) (match_dup 7)))]
16012 "TARGET_USE_FANCY_MATH_387
16013 && flag_unsafe_math_optimizations"
16017 for (i = 2; i < 13; i++)
16018 operands[i] = gen_reg_rtx (XFmode);
16020 emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
16021 emit_move_insn (operands[9], CONST1_RTX (XFmode));
16024 (define_expand "expm1<mode>2"
16025 [(use (match_operand:MODEF 0 "register_operand"))
16026 (use (match_operand:MODEF 1 "general_operand"))]
16027 "TARGET_USE_FANCY_MATH_387
16028 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16029 || TARGET_MIX_SSE_I387)
16030 && flag_unsafe_math_optimizations"
16032 rtx op0 = gen_reg_rtx (XFmode);
16033 rtx op1 = gen_reg_rtx (XFmode);
16035 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16036 emit_insn (gen_expm1xf2 (op0, op1));
16037 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
16041 (define_expand "ldexpxf3"
16042 [(match_operand:XF 0 "register_operand")
16043 (match_operand:XF 1 "register_operand")
16044 (match_operand:SI 2 "register_operand")]
16045 "TARGET_USE_FANCY_MATH_387
16046 && flag_unsafe_math_optimizations"
16048 rtx tmp1 = gen_reg_rtx (XFmode);
16049 rtx tmp2 = gen_reg_rtx (XFmode);
16051 emit_insn (gen_floatsixf2 (tmp1, operands[2]));
16052 emit_insn (gen_fscalexf4_i387 (operands[0], tmp2,
16053 operands[1], tmp1));
16057 (define_expand "ldexp<mode>3"
16058 [(use (match_operand:MODEF 0 "register_operand"))
16059 (use (match_operand:MODEF 1 "general_operand"))
16060 (use (match_operand:SI 2 "register_operand"))]
16061 "TARGET_USE_FANCY_MATH_387
16062 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16063 || TARGET_MIX_SSE_I387)
16064 && flag_unsafe_math_optimizations"
16066 rtx op0 = gen_reg_rtx (XFmode);
16067 rtx op1 = gen_reg_rtx (XFmode);
16069 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16070 emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
16071 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
16075 (define_expand "scalbxf3"
16076 [(parallel [(set (match_operand:XF 0 " register_operand")
16077 (unspec:XF [(match_operand:XF 1 "register_operand")
16078 (match_operand:XF 2 "register_operand")]
16079 UNSPEC_FSCALE_FRACT))
16081 (unspec:XF [(match_dup 1) (match_dup 2)]
16082 UNSPEC_FSCALE_EXP))])]
16083 "TARGET_USE_FANCY_MATH_387
16084 && flag_unsafe_math_optimizations"
16085 "operands[3] = gen_reg_rtx (XFmode);")
16087 (define_expand "scalb<mode>3"
16088 [(use (match_operand:MODEF 0 "register_operand"))
16089 (use (match_operand:MODEF 1 "general_operand"))
16090 (use (match_operand:MODEF 2 "general_operand"))]
16091 "TARGET_USE_FANCY_MATH_387
16092 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16093 || TARGET_MIX_SSE_I387)
16094 && flag_unsafe_math_optimizations"
16096 rtx op0 = gen_reg_rtx (XFmode);
16097 rtx op1 = gen_reg_rtx (XFmode);
16098 rtx op2 = gen_reg_rtx (XFmode);
16100 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16101 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
16102 emit_insn (gen_scalbxf3 (op0, op1, op2));
16103 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
16107 (define_expand "significandxf2"
16108 [(parallel [(set (match_operand:XF 0 "register_operand")
16109 (unspec:XF [(match_operand:XF 1 "register_operand")]
16110 UNSPEC_XTRACT_FRACT))
16112 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
16113 "TARGET_USE_FANCY_MATH_387
16114 && flag_unsafe_math_optimizations"
16115 "operands[2] = gen_reg_rtx (XFmode);")
16117 (define_expand "significand<mode>2"
16118 [(use (match_operand:MODEF 0 "register_operand"))
16119 (use (match_operand:MODEF 1 "general_operand"))]
16120 "TARGET_USE_FANCY_MATH_387
16121 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16122 || TARGET_MIX_SSE_I387)
16123 && flag_unsafe_math_optimizations"
16125 rtx op0 = gen_reg_rtx (XFmode);
16126 rtx op1 = gen_reg_rtx (XFmode);
16128 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16129 emit_insn (gen_significandxf2 (op0, op1));
16130 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
16135 (define_insn "sse4_1_round<mode>2"
16136 [(set (match_operand:MODEF 0 "register_operand" "=x,x,x,v")
16138 [(match_operand:MODEF 1 "nonimmediate_operand" "0,x,m,vm")
16139 (match_operand:SI 2 "const_0_to_15_operand" "n,n,n,n")]
16143 %vround<ssemodesuffix>\t{%2, %d1, %0|%0, %d1, %2}
16144 %vround<ssemodesuffix>\t{%2, %d1, %0|%0, %d1, %2}
16145 %vround<ssemodesuffix>\t{%2, %1, %d0|%d0, %1, %2}
16146 vrndscale<ssemodesuffix>\t{%2, %1, %d0|%d0, %1, %2}"
16147 [(set_attr "type" "ssecvt")
16148 (set_attr "prefix_extra" "1,1,1,*")
16149 (set_attr "length_immediate" "*,*,*,1")
16150 (set_attr "prefix" "maybe_vex,maybe_vex,maybe_vex,evex")
16151 (set_attr "isa" "noavx512f,noavx512f,noavx512f,avx512f")
16152 (set_attr "mode" "<MODE>")
16153 (set (attr "preferred_for_speed")
16154 (cond [(eq_attr "alternative" "1")
16155 (symbol_ref "TARGET_AVX || !TARGET_SSE_PARTIAL_REG_DEPENDENCY")
16156 (eq_attr "alternative" "2")
16157 (symbol_ref "!TARGET_SSE_PARTIAL_REG_DEPENDENCY")
16159 (symbol_ref "true")))])
16161 (define_insn "rintxf2"
16162 [(set (match_operand:XF 0 "register_operand" "=f")
16163 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16165 "TARGET_USE_FANCY_MATH_387"
16167 [(set_attr "type" "fpspc")
16168 (set_attr "znver1_decode" "vector")
16169 (set_attr "mode" "XF")])
16171 (define_expand "rint<mode>2"
16172 [(use (match_operand:MODEF 0 "register_operand"))
16173 (use (match_operand:MODEF 1 "nonimmediate_operand"))]
16174 "TARGET_USE_FANCY_MATH_387
16175 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
16177 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16180 emit_insn (gen_sse4_1_round<mode>2
16181 (operands[0], operands[1], GEN_INT (ROUND_MXCSR)));
16183 ix86_expand_rint (operands[0], operands[1]);
16187 rtx op0 = gen_reg_rtx (XFmode);
16188 rtx op1 = gen_reg_rtx (XFmode);
16190 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16191 emit_insn (gen_rintxf2 (op0, op1));
16192 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
16197 (define_expand "nearbyintxf2"
16198 [(set (match_operand:XF 0 "register_operand")
16199 (unspec:XF [(match_operand:XF 1 "register_operand")]
16201 "TARGET_USE_FANCY_MATH_387
16202 && !flag_trapping_math")
16204 (define_expand "nearbyint<mode>2"
16205 [(use (match_operand:MODEF 0 "register_operand"))
16206 (use (match_operand:MODEF 1 "nonimmediate_operand"))]
16207 "(TARGET_USE_FANCY_MATH_387
16208 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16209 || TARGET_MIX_SSE_I387)
16210 && !flag_trapping_math)
16211 || (TARGET_SSE4_1 && TARGET_SSE_MATH)"
16213 if (TARGET_SSE4_1 && TARGET_SSE_MATH)
16214 emit_insn (gen_sse4_1_round<mode>2
16215 (operands[0], operands[1], GEN_INT (ROUND_MXCSR
16219 rtx op0 = gen_reg_rtx (XFmode);
16220 rtx op1 = gen_reg_rtx (XFmode);
16222 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16223 emit_insn (gen_nearbyintxf2 (op0, op1));
16224 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
16229 (define_expand "round<mode>2"
16230 [(match_operand:X87MODEF 0 "register_operand")
16231 (match_operand:X87MODEF 1 "nonimmediate_operand")]
16232 "(TARGET_USE_FANCY_MATH_387
16233 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16234 || TARGET_MIX_SSE_I387)
16235 && flag_unsafe_math_optimizations
16236 && (flag_fp_int_builtin_inexact || !flag_trapping_math))
16237 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16238 && !flag_trapping_math && !flag_rounding_math)"
16240 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16241 && !flag_trapping_math && !flag_rounding_math)
16245 operands[1] = force_reg (<MODE>mode, operands[1]);
16246 ix86_expand_round_sse4 (operands[0], operands[1]);
16248 else if (TARGET_64BIT || (<MODE>mode != DFmode))
16249 ix86_expand_round (operands[0], operands[1]);
16251 ix86_expand_rounddf_32 (operands[0], operands[1]);
16255 operands[1] = force_reg (<MODE>mode, operands[1]);
16256 ix86_emit_i387_round (operands[0], operands[1]);
16261 (define_insn "lrintxfdi2"
16262 [(set (match_operand:DI 0 "nonimmediate_operand" "=m")
16263 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
16265 (clobber (match_scratch:XF 2 "=&f"))]
16266 "TARGET_USE_FANCY_MATH_387"
16267 "* return output_fix_trunc (insn, operands, false);"
16268 [(set_attr "type" "fpspc")
16269 (set_attr "mode" "DI")])
16271 (define_insn "lrintxf<mode>2"
16272 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m")
16273 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
16275 "TARGET_USE_FANCY_MATH_387"
16276 "* return output_fix_trunc (insn, operands, false);"
16277 [(set_attr "type" "fpspc")
16278 (set_attr "mode" "<MODE>")])
16280 (define_expand "lrint<MODEF:mode><SWI48:mode>2"
16281 [(set (match_operand:SWI48 0 "nonimmediate_operand")
16282 (unspec:SWI48 [(match_operand:MODEF 1 "register_operand")]
16283 UNSPEC_FIX_NOTRUNC))]
16284 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH")
16286 (define_expand "lround<X87MODEF:mode><SWI248x:mode>2"
16287 [(match_operand:SWI248x 0 "nonimmediate_operand")
16288 (match_operand:X87MODEF 1 "register_operand")]
16289 "(TARGET_USE_FANCY_MATH_387
16290 && (!(SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
16291 || TARGET_MIX_SSE_I387)
16292 && flag_unsafe_math_optimizations)
16293 || (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
16294 && <SWI248x:MODE>mode != HImode
16295 && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT)
16296 && !flag_trapping_math && !flag_rounding_math)"
16298 if (optimize_insn_for_size_p ())
16301 if (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
16302 && <SWI248x:MODE>mode != HImode
16303 && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT)
16304 && !flag_trapping_math && !flag_rounding_math)
16305 ix86_expand_lround (operands[0], operands[1]);
16307 ix86_emit_i387_round (operands[0], operands[1]);
16311 (define_int_iterator FRNDINT_ROUNDING
16312 [UNSPEC_FRNDINT_FLOOR
16313 UNSPEC_FRNDINT_CEIL
16314 UNSPEC_FRNDINT_TRUNC])
16316 (define_int_iterator FIST_ROUNDING
16320 ;; Base name for define_insn
16321 (define_int_attr rounding_insn
16322 [(UNSPEC_FRNDINT_FLOOR "floor")
16323 (UNSPEC_FRNDINT_CEIL "ceil")
16324 (UNSPEC_FRNDINT_TRUNC "btrunc")
16325 (UNSPEC_FIST_FLOOR "floor")
16326 (UNSPEC_FIST_CEIL "ceil")])
16328 (define_int_attr rounding
16329 [(UNSPEC_FRNDINT_FLOOR "floor")
16330 (UNSPEC_FRNDINT_CEIL "ceil")
16331 (UNSPEC_FRNDINT_TRUNC "trunc")
16332 (UNSPEC_FIST_FLOOR "floor")
16333 (UNSPEC_FIST_CEIL "ceil")])
16335 (define_int_attr ROUNDING
16336 [(UNSPEC_FRNDINT_FLOOR "FLOOR")
16337 (UNSPEC_FRNDINT_CEIL "CEIL")
16338 (UNSPEC_FRNDINT_TRUNC "TRUNC")
16339 (UNSPEC_FIST_FLOOR "FLOOR")
16340 (UNSPEC_FIST_CEIL "CEIL")])
16342 ;; Rounding mode control word calculation could clobber FLAGS_REG.
16343 (define_insn_and_split "frndintxf2_<rounding>"
16344 [(set (match_operand:XF 0 "register_operand")
16345 (unspec:XF [(match_operand:XF 1 "register_operand")]
16347 (clobber (reg:CC FLAGS_REG))]
16348 "TARGET_USE_FANCY_MATH_387
16349 && (flag_fp_int_builtin_inexact || !flag_trapping_math)
16350 && can_create_pseudo_p ()"
16355 ix86_optimize_mode_switching[I387_<ROUNDING>] = 1;
16357 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
16358 operands[3] = assign_386_stack_local (HImode, SLOT_CW_<ROUNDING>);
16360 emit_insn (gen_frndintxf2_<rounding>_i387 (operands[0], operands[1],
16361 operands[2], operands[3]));
16364 [(set_attr "type" "frndint")
16365 (set_attr "i387_cw" "<rounding>")
16366 (set_attr "mode" "XF")])
16368 (define_insn "frndintxf2_<rounding>_i387"
16369 [(set (match_operand:XF 0 "register_operand" "=f")
16370 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16372 (use (match_operand:HI 2 "memory_operand" "m"))
16373 (use (match_operand:HI 3 "memory_operand" "m"))]
16374 "TARGET_USE_FANCY_MATH_387
16375 && (flag_fp_int_builtin_inexact || !flag_trapping_math)"
16376 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
16377 [(set_attr "type" "frndint")
16378 (set_attr "i387_cw" "<rounding>")
16379 (set_attr "mode" "XF")])
16381 (define_expand "<rounding_insn>xf2"
16382 [(parallel [(set (match_operand:XF 0 "register_operand")
16383 (unspec:XF [(match_operand:XF 1 "register_operand")]
16385 (clobber (reg:CC FLAGS_REG))])]
16386 "TARGET_USE_FANCY_MATH_387
16387 && (flag_fp_int_builtin_inexact || !flag_trapping_math)")
16389 (define_expand "<rounding_insn><mode>2"
16390 [(parallel [(set (match_operand:MODEF 0 "register_operand")
16391 (unspec:MODEF [(match_operand:MODEF 1 "register_operand")]
16393 (clobber (reg:CC FLAGS_REG))])]
16394 "(TARGET_USE_FANCY_MATH_387
16395 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16396 || TARGET_MIX_SSE_I387)
16397 && (flag_fp_int_builtin_inexact || !flag_trapping_math))
16398 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16399 && (TARGET_SSE4_1 || flag_fp_int_builtin_inexact
16400 || !flag_trapping_math))"
16402 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16403 && (TARGET_SSE4_1 || flag_fp_int_builtin_inexact || !flag_trapping_math))
16406 emit_insn (gen_sse4_1_round<mode>2
16407 (operands[0], operands[1], GEN_INT (ROUND_<ROUNDING>
16409 else if (TARGET_64BIT || (<MODE>mode != DFmode))
16411 if (ROUND_<ROUNDING> == ROUND_FLOOR)
16412 ix86_expand_floorceil (operands[0], operands[1], true);
16413 else if (ROUND_<ROUNDING> == ROUND_CEIL)
16414 ix86_expand_floorceil (operands[0], operands[1], false);
16415 else if (ROUND_<ROUNDING> == ROUND_TRUNC)
16416 ix86_expand_trunc (operands[0], operands[1]);
16418 gcc_unreachable ();
16422 if (ROUND_<ROUNDING> == ROUND_FLOOR)
16423 ix86_expand_floorceildf_32 (operands[0], operands[1], true);
16424 else if (ROUND_<ROUNDING> == ROUND_CEIL)
16425 ix86_expand_floorceildf_32 (operands[0], operands[1], false);
16426 else if (ROUND_<ROUNDING> == ROUND_TRUNC)
16427 ix86_expand_truncdf_32 (operands[0], operands[1]);
16429 gcc_unreachable ();
16434 rtx op0 = gen_reg_rtx (XFmode);
16435 rtx op1 = gen_reg_rtx (XFmode);
16437 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16438 emit_insn (gen_frndintxf2_<rounding> (op0, op1));
16439 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
16444 ;; Rounding mode control word calculation could clobber FLAGS_REG.
16445 (define_insn_and_split "*fist<mode>2_<rounding>_1"
16446 [(set (match_operand:SWI248x 0 "nonimmediate_operand")
16447 (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
16449 (clobber (reg:CC FLAGS_REG))]
16450 "TARGET_USE_FANCY_MATH_387
16451 && flag_unsafe_math_optimizations
16452 && can_create_pseudo_p ()"
16457 ix86_optimize_mode_switching[I387_<ROUNDING>] = 1;
16459 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
16460 operands[3] = assign_386_stack_local (HImode, SLOT_CW_<ROUNDING>);
16462 emit_insn (gen_fist<mode>2_<rounding> (operands[0], operands[1],
16463 operands[2], operands[3]));
16466 [(set_attr "type" "fistp")
16467 (set_attr "i387_cw" "<rounding>")
16468 (set_attr "mode" "<MODE>")])
16470 (define_insn "fistdi2_<rounding>"
16471 [(set (match_operand:DI 0 "nonimmediate_operand" "=m")
16472 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
16474 (use (match_operand:HI 2 "memory_operand" "m"))
16475 (use (match_operand:HI 3 "memory_operand" "m"))
16476 (clobber (match_scratch:XF 4 "=&f"))]
16477 "TARGET_USE_FANCY_MATH_387
16478 && flag_unsafe_math_optimizations"
16479 "* return output_fix_trunc (insn, operands, false);"
16480 [(set_attr "type" "fistp")
16481 (set_attr "i387_cw" "<rounding>")
16482 (set_attr "mode" "DI")])
16484 (define_insn "fist<mode>2_<rounding>"
16485 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m")
16486 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
16488 (use (match_operand:HI 2 "memory_operand" "m"))
16489 (use (match_operand:HI 3 "memory_operand" "m"))]
16490 "TARGET_USE_FANCY_MATH_387
16491 && flag_unsafe_math_optimizations"
16492 "* return output_fix_trunc (insn, operands, false);"
16493 [(set_attr "type" "fistp")
16494 (set_attr "i387_cw" "<rounding>")
16495 (set_attr "mode" "<MODE>")])
16497 (define_expand "l<rounding_insn>xf<mode>2"
16498 [(parallel [(set (match_operand:SWI248x 0 "nonimmediate_operand")
16499 (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
16501 (clobber (reg:CC FLAGS_REG))])]
16502 "TARGET_USE_FANCY_MATH_387
16503 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16504 && flag_unsafe_math_optimizations")
16506 (define_expand "l<rounding_insn><MODEF:mode><SWI48:mode>2"
16507 [(parallel [(set (match_operand:SWI48 0 "nonimmediate_operand")
16508 (unspec:SWI48 [(match_operand:MODEF 1 "register_operand")]
16510 (clobber (reg:CC FLAGS_REG))])]
16511 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
16512 && (TARGET_SSE4_1 || !flag_trapping_math)"
16516 rtx tmp = gen_reg_rtx (<MODEF:MODE>mode);
16518 emit_insn (gen_sse4_1_round<mode>2
16519 (tmp, operands[1], GEN_INT (ROUND_<ROUNDING>
16521 emit_insn (gen_fix_trunc<MODEF:mode><SWI48:mode>2
16522 (operands[0], tmp));
16524 else if (ROUND_<ROUNDING> == ROUND_FLOOR)
16525 ix86_expand_lfloorceil (operands[0], operands[1], true);
16526 else if (ROUND_<ROUNDING> == ROUND_CEIL)
16527 ix86_expand_lfloorceil (operands[0], operands[1], false);
16529 gcc_unreachable ();
16534 (define_insn "fxam<mode>2_i387"
16535 [(set (match_operand:HI 0 "register_operand" "=a")
16537 [(match_operand:X87MODEF 1 "register_operand" "f")]
16539 "TARGET_USE_FANCY_MATH_387"
16540 "fxam\n\tfnstsw\t%0"
16541 [(set_attr "type" "multi")
16542 (set_attr "length" "4")
16543 (set_attr "unit" "i387")
16544 (set_attr "mode" "<MODE>")])
16546 (define_expand "signbittf2"
16547 [(use (match_operand:SI 0 "register_operand"))
16548 (use (match_operand:TF 1 "register_operand"))]
16553 rtx mask = ix86_build_signbit_mask (TFmode, 0, 0);
16554 rtx scratch = gen_reg_rtx (QImode);
16556 emit_insn (gen_ptesttf2 (operands[1], mask));
16557 ix86_expand_setcc (scratch, NE,
16558 gen_rtx_REG (CCZmode, FLAGS_REG), const0_rtx);
16560 emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
16564 emit_insn (gen_sse_movmskps (operands[0],
16565 gen_lowpart (V4SFmode, operands[1])));
16566 emit_insn (gen_andsi3 (operands[0], operands[0], GEN_INT (0x8)));
16571 (define_expand "signbitxf2"
16572 [(use (match_operand:SI 0 "register_operand"))
16573 (use (match_operand:XF 1 "register_operand"))]
16574 "TARGET_USE_FANCY_MATH_387"
16576 rtx scratch = gen_reg_rtx (HImode);
16578 emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
16579 emit_insn (gen_andsi3 (operands[0],
16580 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
16584 (define_insn "movmsk_df"
16585 [(set (match_operand:SI 0 "register_operand" "=r")
16587 [(match_operand:DF 1 "register_operand" "x")]
16589 "SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH"
16590 "%vmovmskpd\t{%1, %0|%0, %1}"
16591 [(set_attr "type" "ssemov")
16592 (set_attr "prefix" "maybe_vex")
16593 (set_attr "mode" "DF")])
16595 ;; Use movmskpd in SSE mode to avoid store forwarding stall
16596 ;; for 32bit targets and movq+shrq sequence for 64bit targets.
16597 (define_expand "signbitdf2"
16598 [(use (match_operand:SI 0 "register_operand"))
16599 (use (match_operand:DF 1 "register_operand"))]
16600 "TARGET_USE_FANCY_MATH_387
16601 || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
16603 if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)
16605 emit_insn (gen_movmsk_df (operands[0], operands[1]));
16606 emit_insn (gen_andsi3 (operands[0], operands[0], const1_rtx));
16610 rtx scratch = gen_reg_rtx (HImode);
16612 emit_insn (gen_fxamdf2_i387 (scratch, operands[1]));
16613 emit_insn (gen_andsi3 (operands[0],
16614 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
16619 (define_expand "signbitsf2"
16620 [(use (match_operand:SI 0 "register_operand"))
16621 (use (match_operand:SF 1 "register_operand"))]
16622 "TARGET_USE_FANCY_MATH_387
16623 && !(SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH)"
16625 rtx scratch = gen_reg_rtx (HImode);
16627 emit_insn (gen_fxamsf2_i387 (scratch, operands[1]));
16628 emit_insn (gen_andsi3 (operands[0],
16629 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
16633 ;; Block operation instructions
16636 [(unspec_volatile [(const_int 0)] UNSPECV_CLD)]
16639 [(set_attr "length" "1")
16640 (set_attr "length_immediate" "0")
16641 (set_attr "modrm" "0")])
16643 (define_expand "movmem<mode>"
16644 [(use (match_operand:BLK 0 "memory_operand"))
16645 (use (match_operand:BLK 1 "memory_operand"))
16646 (use (match_operand:SWI48 2 "nonmemory_operand"))
16647 (use (match_operand:SWI48 3 "const_int_operand"))
16648 (use (match_operand:SI 4 "const_int_operand"))
16649 (use (match_operand:SI 5 "const_int_operand"))
16650 (use (match_operand:SI 6 ""))
16651 (use (match_operand:SI 7 ""))
16652 (use (match_operand:SI 8 ""))]
16655 if (ix86_expand_set_or_movmem (operands[0], operands[1],
16656 operands[2], NULL, operands[3],
16657 operands[4], operands[5],
16658 operands[6], operands[7],
16659 operands[8], false))
16665 ;; Most CPUs don't like single string operations
16666 ;; Handle this case here to simplify previous expander.
16668 (define_expand "strmov"
16669 [(set (match_dup 4) (match_operand 3 "memory_operand"))
16670 (set (match_operand 1 "memory_operand") (match_dup 4))
16671 (parallel [(set (match_operand 0 "register_operand") (match_dup 5))
16672 (clobber (reg:CC FLAGS_REG))])
16673 (parallel [(set (match_operand 2 "register_operand") (match_dup 6))
16674 (clobber (reg:CC FLAGS_REG))])]
16677 /* Can't use this for non-default address spaces. */
16678 if (!ADDR_SPACE_GENERIC_P (MEM_ADDR_SPACE (operands[3])))
16681 rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
16683 /* If .md ever supports :P for Pmode, these can be directly
16684 in the pattern above. */
16685 operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
16686 operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
16688 /* Can't use this if the user has appropriated esi or edi. */
16689 if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
16690 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG]))
16692 emit_insn (gen_strmov_singleop (operands[0], operands[1],
16693 operands[2], operands[3],
16694 operands[5], operands[6]));
16698 operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
16701 (define_expand "strmov_singleop"
16702 [(parallel [(set (match_operand 1 "memory_operand")
16703 (match_operand 3 "memory_operand"))
16704 (set (match_operand 0 "register_operand")
16706 (set (match_operand 2 "register_operand")
16707 (match_operand 5))])]
16711 ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
16714 (define_insn "*strmovdi_rex_1"
16715 [(set (mem:DI (match_operand:P 2 "register_operand" "0"))
16716 (mem:DI (match_operand:P 3 "register_operand" "1")))
16717 (set (match_operand:P 0 "register_operand" "=D")
16718 (plus:P (match_dup 2)
16720 (set (match_operand:P 1 "register_operand" "=S")
16721 (plus:P (match_dup 3)
16724 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG])
16725 && ix86_check_no_addr_space (insn)"
16727 [(set_attr "type" "str")
16728 (set_attr "memory" "both")
16729 (set_attr "mode" "DI")])
16731 (define_insn "*strmovsi_1"
16732 [(set (mem:SI (match_operand:P 2 "register_operand" "0"))
16733 (mem:SI (match_operand:P 3 "register_operand" "1")))
16734 (set (match_operand:P 0 "register_operand" "=D")
16735 (plus:P (match_dup 2)
16737 (set (match_operand:P 1 "register_operand" "=S")
16738 (plus:P (match_dup 3)
16740 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])
16741 && ix86_check_no_addr_space (insn)"
16743 [(set_attr "type" "str")
16744 (set_attr "memory" "both")
16745 (set_attr "mode" "SI")])
16747 (define_insn "*strmovhi_1"
16748 [(set (mem:HI (match_operand:P 2 "register_operand" "0"))
16749 (mem:HI (match_operand:P 3 "register_operand" "1")))
16750 (set (match_operand:P 0 "register_operand" "=D")
16751 (plus:P (match_dup 2)
16753 (set (match_operand:P 1 "register_operand" "=S")
16754 (plus:P (match_dup 3)
16756 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])
16757 && ix86_check_no_addr_space (insn)"
16759 [(set_attr "type" "str")
16760 (set_attr "memory" "both")
16761 (set_attr "mode" "HI")])
16763 (define_insn "*strmovqi_1"
16764 [(set (mem:QI (match_operand:P 2 "register_operand" "0"))
16765 (mem:QI (match_operand:P 3 "register_operand" "1")))
16766 (set (match_operand:P 0 "register_operand" "=D")
16767 (plus:P (match_dup 2)
16769 (set (match_operand:P 1 "register_operand" "=S")
16770 (plus:P (match_dup 3)
16772 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])
16773 && ix86_check_no_addr_space (insn)"
16775 [(set_attr "type" "str")
16776 (set_attr "memory" "both")
16777 (set (attr "prefix_rex")
16779 (match_test "<P:MODE>mode == DImode")
16781 (const_string "*")))
16782 (set_attr "mode" "QI")])
16784 (define_expand "rep_mov"
16785 [(parallel [(set (match_operand 4 "register_operand") (const_int 0))
16786 (set (match_operand 0 "register_operand")
16788 (set (match_operand 2 "register_operand")
16790 (set (match_operand 1 "memory_operand")
16791 (match_operand 3 "memory_operand"))
16792 (use (match_dup 4))])]
16796 ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
16799 (define_insn "*rep_movdi_rex64"
16800 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
16801 (set (match_operand:P 0 "register_operand" "=D")
16802 (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
16804 (match_operand:P 3 "register_operand" "0")))
16805 (set (match_operand:P 1 "register_operand" "=S")
16806 (plus:P (ashift:P (match_dup 5) (const_int 3))
16807 (match_operand:P 4 "register_operand" "1")))
16808 (set (mem:BLK (match_dup 3))
16809 (mem:BLK (match_dup 4)))
16810 (use (match_dup 5))]
16812 && !(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
16813 && ix86_check_no_addr_space (insn)"
16815 [(set_attr "type" "str")
16816 (set_attr "prefix_rep" "1")
16817 (set_attr "memory" "both")
16818 (set_attr "mode" "DI")])
16820 (define_insn "*rep_movsi"
16821 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
16822 (set (match_operand:P 0 "register_operand" "=D")
16823 (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
16825 (match_operand:P 3 "register_operand" "0")))
16826 (set (match_operand:P 1 "register_operand" "=S")
16827 (plus:P (ashift:P (match_dup 5) (const_int 2))
16828 (match_operand:P 4 "register_operand" "1")))
16829 (set (mem:BLK (match_dup 3))
16830 (mem:BLK (match_dup 4)))
16831 (use (match_dup 5))]
16832 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
16833 && ix86_check_no_addr_space (insn)"
16834 "%^rep{%;} movs{l|d}"
16835 [(set_attr "type" "str")
16836 (set_attr "prefix_rep" "1")
16837 (set_attr "memory" "both")
16838 (set_attr "mode" "SI")])
16840 (define_insn "*rep_movqi"
16841 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
16842 (set (match_operand:P 0 "register_operand" "=D")
16843 (plus:P (match_operand:P 3 "register_operand" "0")
16844 (match_operand:P 5 "register_operand" "2")))
16845 (set (match_operand:P 1 "register_operand" "=S")
16846 (plus:P (match_operand:P 4 "register_operand" "1") (match_dup 5)))
16847 (set (mem:BLK (match_dup 3))
16848 (mem:BLK (match_dup 4)))
16849 (use (match_dup 5))]
16850 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
16851 && ix86_check_no_addr_space (insn)"
16853 [(set_attr "type" "str")
16854 (set_attr "prefix_rep" "1")
16855 (set_attr "memory" "both")
16856 (set_attr "mode" "QI")])
16858 (define_expand "setmem<mode>"
16859 [(use (match_operand:BLK 0 "memory_operand"))
16860 (use (match_operand:SWI48 1 "nonmemory_operand"))
16861 (use (match_operand:QI 2 "nonmemory_operand"))
16862 (use (match_operand 3 "const_int_operand"))
16863 (use (match_operand:SI 4 "const_int_operand"))
16864 (use (match_operand:SI 5 "const_int_operand"))
16865 (use (match_operand:SI 6 ""))
16866 (use (match_operand:SI 7 ""))
16867 (use (match_operand:SI 8 ""))]
16870 if (ix86_expand_set_or_movmem (operands[0], NULL,
16871 operands[1], operands[2],
16872 operands[3], operands[4],
16873 operands[5], operands[6],
16874 operands[7], operands[8], true))
16880 ;; Most CPUs don't like single string operations
16881 ;; Handle this case here to simplify previous expander.
16883 (define_expand "strset"
16884 [(set (match_operand 1 "memory_operand")
16885 (match_operand 2 "register_operand"))
16886 (parallel [(set (match_operand 0 "register_operand")
16888 (clobber (reg:CC FLAGS_REG))])]
16891 /* Can't use this for non-default address spaces. */
16892 if (!ADDR_SPACE_GENERIC_P (MEM_ADDR_SPACE (operands[1])))
16895 if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
16896 operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
16898 /* If .md ever supports :P for Pmode, this can be directly
16899 in the pattern above. */
16900 operands[3] = gen_rtx_PLUS (Pmode, operands[0],
16901 GEN_INT (GET_MODE_SIZE (GET_MODE
16903 /* Can't use this if the user has appropriated eax or edi. */
16904 if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
16905 && !(fixed_regs[AX_REG] || fixed_regs[DI_REG]))
16907 emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
16913 (define_expand "strset_singleop"
16914 [(parallel [(set (match_operand 1 "memory_operand")
16915 (match_operand 2 "register_operand"))
16916 (set (match_operand 0 "register_operand")
16918 (unspec [(const_int 0)] UNSPEC_STOS)])]
16922 ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
16925 (define_insn "*strsetdi_rex_1"
16926 [(set (mem:DI (match_operand:P 1 "register_operand" "0"))
16927 (match_operand:DI 2 "register_operand" "a"))
16928 (set (match_operand:P 0 "register_operand" "=D")
16929 (plus:P (match_dup 1)
16931 (unspec [(const_int 0)] UNSPEC_STOS)]
16933 && !(fixed_regs[AX_REG] || fixed_regs[DI_REG])
16934 && ix86_check_no_addr_space (insn)"
16936 [(set_attr "type" "str")
16937 (set_attr "memory" "store")
16938 (set_attr "mode" "DI")])
16940 (define_insn "*strsetsi_1"
16941 [(set (mem:SI (match_operand:P 1 "register_operand" "0"))
16942 (match_operand:SI 2 "register_operand" "a"))
16943 (set (match_operand:P 0 "register_operand" "=D")
16944 (plus:P (match_dup 1)
16946 (unspec [(const_int 0)] UNSPEC_STOS)]
16947 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])
16948 && ix86_check_no_addr_space (insn)"
16950 [(set_attr "type" "str")
16951 (set_attr "memory" "store")
16952 (set_attr "mode" "SI")])
16954 (define_insn "*strsethi_1"
16955 [(set (mem:HI (match_operand:P 1 "register_operand" "0"))
16956 (match_operand:HI 2 "register_operand" "a"))
16957 (set (match_operand:P 0 "register_operand" "=D")
16958 (plus:P (match_dup 1)
16960 (unspec [(const_int 0)] UNSPEC_STOS)]
16961 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])
16962 && ix86_check_no_addr_space (insn)"
16964 [(set_attr "type" "str")
16965 (set_attr "memory" "store")
16966 (set_attr "mode" "HI")])
16968 (define_insn "*strsetqi_1"
16969 [(set (mem:QI (match_operand:P 1 "register_operand" "0"))
16970 (match_operand:QI 2 "register_operand" "a"))
16971 (set (match_operand:P 0 "register_operand" "=D")
16972 (plus:P (match_dup 1)
16974 (unspec [(const_int 0)] UNSPEC_STOS)]
16975 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])
16976 && ix86_check_no_addr_space (insn)"
16978 [(set_attr "type" "str")
16979 (set_attr "memory" "store")
16980 (set (attr "prefix_rex")
16982 (match_test "<P:MODE>mode == DImode")
16984 (const_string "*")))
16985 (set_attr "mode" "QI")])
16987 (define_expand "rep_stos"
16988 [(parallel [(set (match_operand 1 "register_operand") (const_int 0))
16989 (set (match_operand 0 "register_operand")
16991 (set (match_operand 2 "memory_operand") (const_int 0))
16992 (use (match_operand 3 "register_operand"))
16993 (use (match_dup 1))])]
16997 ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
17000 (define_insn "*rep_stosdi_rex64"
17001 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
17002 (set (match_operand:P 0 "register_operand" "=D")
17003 (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
17005 (match_operand:P 3 "register_operand" "0")))
17006 (set (mem:BLK (match_dup 3))
17008 (use (match_operand:DI 2 "register_operand" "a"))
17009 (use (match_dup 4))]
17011 && !(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])
17012 && ix86_check_no_addr_space (insn)"
17014 [(set_attr "type" "str")
17015 (set_attr "prefix_rep" "1")
17016 (set_attr "memory" "store")
17017 (set_attr "mode" "DI")])
17019 (define_insn "*rep_stossi"
17020 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
17021 (set (match_operand:P 0 "register_operand" "=D")
17022 (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
17024 (match_operand:P 3 "register_operand" "0")))
17025 (set (mem:BLK (match_dup 3))
17027 (use (match_operand:SI 2 "register_operand" "a"))
17028 (use (match_dup 4))]
17029 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])
17030 && ix86_check_no_addr_space (insn)"
17031 "%^rep{%;} stos{l|d}"
17032 [(set_attr "type" "str")
17033 (set_attr "prefix_rep" "1")
17034 (set_attr "memory" "store")
17035 (set_attr "mode" "SI")])
17037 (define_insn "*rep_stosqi"
17038 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
17039 (set (match_operand:P 0 "register_operand" "=D")
17040 (plus:P (match_operand:P 3 "register_operand" "0")
17041 (match_operand:P 4 "register_operand" "1")))
17042 (set (mem:BLK (match_dup 3))
17044 (use (match_operand:QI 2 "register_operand" "a"))
17045 (use (match_dup 4))]
17046 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])
17047 && ix86_check_no_addr_space (insn)"
17049 [(set_attr "type" "str")
17050 (set_attr "prefix_rep" "1")
17051 (set_attr "memory" "store")
17052 (set (attr "prefix_rex")
17054 (match_test "<P:MODE>mode == DImode")
17056 (const_string "*")))
17057 (set_attr "mode" "QI")])
17059 (define_expand "cmpstrnsi"
17060 [(set (match_operand:SI 0 "register_operand")
17061 (compare:SI (match_operand:BLK 1 "general_operand")
17062 (match_operand:BLK 2 "general_operand")))
17063 (use (match_operand 3 "general_operand"))
17064 (use (match_operand 4 "immediate_operand"))]
17067 rtx addr1, addr2, out, outlow, count, countreg, align;
17069 if (optimize_insn_for_size_p () && !TARGET_INLINE_ALL_STRINGOPS)
17072 /* Can't use this if the user has appropriated ecx, esi or edi. */
17073 if (fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
17076 /* One of the strings must be a constant. If so, expand_builtin_strncmp()
17077 will have rewritten the length arg to be the minimum of the const string
17078 length and the actual length arg. If both strings are the same and
17079 shorter than the length arg, repz cmpsb will not stop at the 0 byte and
17080 will incorrectly base the results on chars past the 0 byte. */
17081 tree t1 = MEM_EXPR (operands[1]);
17082 tree t2 = MEM_EXPR (operands[2]);
17083 if (!((t1 && TREE_CODE (t1) == MEM_REF
17084 && TREE_CODE (TREE_OPERAND (t1, 0)) == ADDR_EXPR
17085 && TREE_CODE (TREE_OPERAND (TREE_OPERAND (t1, 0), 0)) == STRING_CST)
17086 || (t2 && TREE_CODE (t2) == MEM_REF
17087 && TREE_CODE (TREE_OPERAND (t2, 0)) == ADDR_EXPR
17088 && TREE_CODE (TREE_OPERAND (TREE_OPERAND (t2, 0), 0)) == STRING_CST)))
17093 out = gen_reg_rtx (SImode);
17095 addr1 = copy_addr_to_reg (XEXP (operands[1], 0));
17096 addr2 = copy_addr_to_reg (XEXP (operands[2], 0));
17097 if (addr1 != XEXP (operands[1], 0))
17098 operands[1] = replace_equiv_address_nv (operands[1], addr1);
17099 if (addr2 != XEXP (operands[2], 0))
17100 operands[2] = replace_equiv_address_nv (operands[2], addr2);
17102 count = operands[3];
17103 countreg = ix86_zero_extend_to_Pmode (count);
17105 /* %%% Iff we are testing strict equality, we can use known alignment
17106 to good advantage. This may be possible with combine, particularly
17107 once cc0 is dead. */
17108 align = operands[4];
17110 if (CONST_INT_P (count))
17112 if (INTVAL (count) == 0)
17114 emit_move_insn (operands[0], const0_rtx);
17117 emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
17118 operands[1], operands[2]));
17122 rtx (*gen_cmp) (rtx, rtx);
17124 gen_cmp = (TARGET_64BIT
17125 ? gen_cmpdi_1 : gen_cmpsi_1);
17127 emit_insn (gen_cmp (countreg, countreg));
17128 emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
17129 operands[1], operands[2]));
17132 outlow = gen_lowpart (QImode, out);
17133 emit_insn (gen_cmpintqi (outlow));
17134 emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
17136 if (operands[0] != out)
17137 emit_move_insn (operands[0], out);
17142 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
17144 (define_expand "cmpintqi"
17145 [(set (match_dup 1)
17146 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
17148 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
17149 (parallel [(set (match_operand:QI 0 "register_operand")
17150 (minus:QI (match_dup 1)
17152 (clobber (reg:CC FLAGS_REG))])]
17155 operands[1] = gen_reg_rtx (QImode);
17156 operands[2] = gen_reg_rtx (QImode);
17159 ;; memcmp recognizers. The `cmpsb' opcode does nothing if the count is
17160 ;; zero. Emit extra code to make sure that a zero-length compare is EQ.
17162 (define_expand "cmpstrnqi_nz_1"
17163 [(parallel [(set (reg:CC FLAGS_REG)
17164 (compare:CC (match_operand 4 "memory_operand")
17165 (match_operand 5 "memory_operand")))
17166 (use (match_operand 2 "register_operand"))
17167 (use (match_operand:SI 3 "immediate_operand"))
17168 (clobber (match_operand 0 "register_operand"))
17169 (clobber (match_operand 1 "register_operand"))
17170 (clobber (match_dup 2))])]
17174 ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
17177 (define_insn "*cmpstrnqi_nz_1"
17178 [(set (reg:CC FLAGS_REG)
17179 (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
17180 (mem:BLK (match_operand:P 5 "register_operand" "1"))))
17181 (use (match_operand:P 6 "register_operand" "2"))
17182 (use (match_operand:SI 3 "immediate_operand" "i"))
17183 (clobber (match_operand:P 0 "register_operand" "=S"))
17184 (clobber (match_operand:P 1 "register_operand" "=D"))
17185 (clobber (match_operand:P 2 "register_operand" "=c"))]
17186 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
17187 && ix86_check_no_addr_space (insn)"
17189 [(set_attr "type" "str")
17190 (set_attr "mode" "QI")
17191 (set (attr "prefix_rex")
17193 (match_test "<P:MODE>mode == DImode")
17195 (const_string "*")))
17196 (set_attr "prefix_rep" "1")])
17198 ;; The same, but the count is not known to not be zero.
17200 (define_expand "cmpstrnqi_1"
17201 [(parallel [(set (reg:CC FLAGS_REG)
17202 (if_then_else:CC (ne (match_operand 2 "register_operand")
17204 (compare:CC (match_operand 4 "memory_operand")
17205 (match_operand 5 "memory_operand"))
17207 (use (match_operand:SI 3 "immediate_operand"))
17208 (use (reg:CC FLAGS_REG))
17209 (clobber (match_operand 0 "register_operand"))
17210 (clobber (match_operand 1 "register_operand"))
17211 (clobber (match_dup 2))])]
17215 ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
17218 (define_insn "*cmpstrnqi_1"
17219 [(set (reg:CC FLAGS_REG)
17220 (if_then_else:CC (ne (match_operand:P 6 "register_operand" "2")
17222 (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
17223 (mem:BLK (match_operand:P 5 "register_operand" "1")))
17225 (use (match_operand:SI 3 "immediate_operand" "i"))
17226 (use (reg:CC FLAGS_REG))
17227 (clobber (match_operand:P 0 "register_operand" "=S"))
17228 (clobber (match_operand:P 1 "register_operand" "=D"))
17229 (clobber (match_operand:P 2 "register_operand" "=c"))]
17230 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
17231 && ix86_check_no_addr_space (insn)"
17233 [(set_attr "type" "str")
17234 (set_attr "mode" "QI")
17235 (set (attr "prefix_rex")
17237 (match_test "<P:MODE>mode == DImode")
17239 (const_string "*")))
17240 (set_attr "prefix_rep" "1")])
17242 (define_expand "strlen<mode>"
17243 [(set (match_operand:P 0 "register_operand")
17244 (unspec:P [(match_operand:BLK 1 "general_operand")
17245 (match_operand:QI 2 "immediate_operand")
17246 (match_operand 3 "immediate_operand")]
17250 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
17256 (define_expand "strlenqi_1"
17257 [(parallel [(set (match_operand 0 "register_operand")
17259 (clobber (match_operand 1 "register_operand"))
17260 (clobber (reg:CC FLAGS_REG))])]
17264 ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
17267 (define_insn "*strlenqi_1"
17268 [(set (match_operand:P 0 "register_operand" "=&c")
17269 (unspec:P [(mem:BLK (match_operand:P 5 "register_operand" "1"))
17270 (match_operand:QI 2 "register_operand" "a")
17271 (match_operand:P 3 "immediate_operand" "i")
17272 (match_operand:P 4 "register_operand" "0")] UNSPEC_SCAS))
17273 (clobber (match_operand:P 1 "register_operand" "=D"))
17274 (clobber (reg:CC FLAGS_REG))]
17275 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])
17276 && ix86_check_no_addr_space (insn)"
17277 "%^repnz{%;} scasb"
17278 [(set_attr "type" "str")
17279 (set_attr "mode" "QI")
17280 (set (attr "prefix_rex")
17282 (match_test "<P:MODE>mode == DImode")
17284 (const_string "*")))
17285 (set_attr "prefix_rep" "1")])
17287 ;; Peephole optimizations to clean up after cmpstrn*. This should be
17288 ;; handled in combine, but it is not currently up to the task.
17289 ;; When used for their truth value, the cmpstrn* expanders generate
17298 ;; The intermediate three instructions are unnecessary.
17300 ;; This one handles cmpstrn*_nz_1...
17303 (set (reg:CC FLAGS_REG)
17304 (compare:CC (mem:BLK (match_operand 4 "register_operand"))
17305 (mem:BLK (match_operand 5 "register_operand"))))
17306 (use (match_operand 6 "register_operand"))
17307 (use (match_operand:SI 3 "immediate_operand"))
17308 (clobber (match_operand 0 "register_operand"))
17309 (clobber (match_operand 1 "register_operand"))
17310 (clobber (match_operand 2 "register_operand"))])
17311 (set (match_operand:QI 7 "register_operand")
17312 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
17313 (set (match_operand:QI 8 "register_operand")
17314 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
17315 (set (reg FLAGS_REG)
17316 (compare (match_dup 7) (match_dup 8)))
17318 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
17320 (set (reg:CC FLAGS_REG)
17321 (compare:CC (mem:BLK (match_dup 4))
17322 (mem:BLK (match_dup 5))))
17323 (use (match_dup 6))
17324 (use (match_dup 3))
17325 (clobber (match_dup 0))
17326 (clobber (match_dup 1))
17327 (clobber (match_dup 2))])])
17329 ;; ...and this one handles cmpstrn*_1.
17332 (set (reg:CC FLAGS_REG)
17333 (if_then_else:CC (ne (match_operand 6 "register_operand")
17335 (compare:CC (mem:BLK (match_operand 4 "register_operand"))
17336 (mem:BLK (match_operand 5 "register_operand")))
17338 (use (match_operand:SI 3 "immediate_operand"))
17339 (use (reg:CC FLAGS_REG))
17340 (clobber (match_operand 0 "register_operand"))
17341 (clobber (match_operand 1 "register_operand"))
17342 (clobber (match_operand 2 "register_operand"))])
17343 (set (match_operand:QI 7 "register_operand")
17344 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
17345 (set (match_operand:QI 8 "register_operand")
17346 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
17347 (set (reg FLAGS_REG)
17348 (compare (match_dup 7) (match_dup 8)))
17350 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
17352 (set (reg:CC FLAGS_REG)
17353 (if_then_else:CC (ne (match_dup 6)
17355 (compare:CC (mem:BLK (match_dup 4))
17356 (mem:BLK (match_dup 5)))
17358 (use (match_dup 3))
17359 (use (reg:CC FLAGS_REG))
17360 (clobber (match_dup 0))
17361 (clobber (match_dup 1))
17362 (clobber (match_dup 2))])])
17364 ;; Conditional move instructions.
17366 (define_expand "mov<mode>cc"
17367 [(set (match_operand:SWIM 0 "register_operand")
17368 (if_then_else:SWIM (match_operand 1 "comparison_operator")
17369 (match_operand:SWIM 2 "<general_operand>")
17370 (match_operand:SWIM 3 "<general_operand>")))]
17372 "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
17374 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
17375 ;; the register first winds up with `sbbl $0,reg', which is also weird.
17376 ;; So just document what we're doing explicitly.
17378 (define_expand "x86_mov<mode>cc_0_m1"
17380 [(set (match_operand:SWI48 0 "register_operand")
17381 (if_then_else:SWI48
17382 (match_operator:SWI48 2 "ix86_carry_flag_operator"
17383 [(match_operand 1 "flags_reg_operand")
17387 (clobber (reg:CC FLAGS_REG))])])
17389 (define_insn "*x86_mov<mode>cc_0_m1"
17390 [(set (match_operand:SWI48 0 "register_operand" "=r")
17391 (if_then_else:SWI48 (match_operator 1 "ix86_carry_flag_operator"
17392 [(reg FLAGS_REG) (const_int 0)])
17395 (clobber (reg:CC FLAGS_REG))]
17397 "sbb{<imodesuffix>}\t%0, %0"
17398 [(set_attr "type" "alu1")
17399 (set_attr "use_carry" "1")
17400 (set_attr "pent_pair" "pu")
17401 (set_attr "mode" "<MODE>")
17402 (set_attr "length_immediate" "0")])
17404 (define_insn "*x86_mov<mode>cc_0_m1_se"
17405 [(set (match_operand:SWI48 0 "register_operand" "=r")
17406 (sign_extract:SWI48 (match_operator 1 "ix86_carry_flag_operator"
17407 [(reg FLAGS_REG) (const_int 0)])
17410 (clobber (reg:CC FLAGS_REG))]
17412 "sbb{<imodesuffix>}\t%0, %0"
17413 [(set_attr "type" "alu1")
17414 (set_attr "use_carry" "1")
17415 (set_attr "pent_pair" "pu")
17416 (set_attr "mode" "<MODE>")
17417 (set_attr "length_immediate" "0")])
17419 (define_insn "*x86_mov<mode>cc_0_m1_neg"
17420 [(set (match_operand:SWI48 0 "register_operand" "=r")
17421 (neg:SWI48 (match_operator 1 "ix86_carry_flag_operator"
17422 [(reg FLAGS_REG) (const_int 0)])))
17423 (clobber (reg:CC FLAGS_REG))]
17425 "sbb{<imodesuffix>}\t%0, %0"
17426 [(set_attr "type" "alu1")
17427 (set_attr "use_carry" "1")
17428 (set_attr "pent_pair" "pu")
17429 (set_attr "mode" "<MODE>")
17430 (set_attr "length_immediate" "0")])
17432 (define_insn_and_split "*x86_mov<SWI48:mode>cc_0_m1_neg_leu<SWI:mode>"
17433 [(set (match_operand:SWI48 0 "register_operand" "=r")
17436 (match_operand:SWI 1 "nonimmediate_operand" "<SWI:r>m")
17437 (match_operand:SWI 2 "<SWI:immediate_operand>" "<SWI:i>"))))
17438 (clobber (reg:CC FLAGS_REG))]
17439 "CONST_INT_P (operands[2])
17440 && INTVAL (operands[2]) != -1
17441 && INTVAL (operands[2]) != 2147483647"
17444 [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
17445 (parallel [(set (match_dup 0)
17446 (neg:SWI48 (ltu:SWI48 (reg:CC FLAGS_REG) (const_int 0))))
17447 (clobber (reg:CC FLAGS_REG))])]
17448 "operands[2] = GEN_INT (INTVAL (operands[2]) + 1);")
17450 (define_insn "*mov<mode>cc_noc"
17451 [(set (match_operand:SWI248 0 "register_operand" "=r,r")
17452 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
17453 [(reg FLAGS_REG) (const_int 0)])
17454 (match_operand:SWI248 2 "nonimmediate_operand" "rm,0")
17455 (match_operand:SWI248 3 "nonimmediate_operand" "0,rm")))]
17456 "TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
17458 cmov%O2%C1\t{%2, %0|%0, %2}
17459 cmov%O2%c1\t{%3, %0|%0, %3}"
17460 [(set_attr "type" "icmov")
17461 (set_attr "mode" "<MODE>")])
17463 (define_insn "*movsicc_noc_zext"
17464 [(set (match_operand:DI 0 "register_operand" "=r,r")
17465 (if_then_else:DI (match_operator 1 "ix86_comparison_operator"
17466 [(reg FLAGS_REG) (const_int 0)])
17468 (match_operand:SI 2 "nonimmediate_operand" "rm,0"))
17470 (match_operand:SI 3 "nonimmediate_operand" "0,rm"))))]
17472 && TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
17474 cmov%O2%C1\t{%2, %k0|%k0, %2}
17475 cmov%O2%c1\t{%3, %k0|%k0, %3}"
17476 [(set_attr "type" "icmov")
17477 (set_attr "mode" "SI")])
17479 ;; Don't do conditional moves with memory inputs. This splitter helps
17480 ;; register starved x86_32 by forcing inputs into registers before reload.
17482 [(set (match_operand:SWI248 0 "register_operand")
17483 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
17484 [(reg FLAGS_REG) (const_int 0)])
17485 (match_operand:SWI248 2 "nonimmediate_operand")
17486 (match_operand:SWI248 3 "nonimmediate_operand")))]
17487 "!TARGET_64BIT && TARGET_CMOVE
17488 && TARGET_AVOID_MEM_OPND_FOR_CMOVE
17489 && (MEM_P (operands[2]) || MEM_P (operands[3]))
17490 && can_create_pseudo_p ()
17491 && optimize_insn_for_speed_p ()"
17492 [(set (match_dup 0)
17493 (if_then_else:SWI248 (match_dup 1) (match_dup 2) (match_dup 3)))]
17495 if (MEM_P (operands[2]))
17496 operands[2] = force_reg (<MODE>mode, operands[2]);
17497 if (MEM_P (operands[3]))
17498 operands[3] = force_reg (<MODE>mode, operands[3]);
17501 (define_insn "*movqicc_noc"
17502 [(set (match_operand:QI 0 "register_operand" "=r,r")
17503 (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
17504 [(reg FLAGS_REG) (const_int 0)])
17505 (match_operand:QI 2 "register_operand" "r,0")
17506 (match_operand:QI 3 "register_operand" "0,r")))]
17507 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
17509 [(set_attr "type" "icmov")
17510 (set_attr "mode" "QI")])
17513 [(set (match_operand:SWI12 0 "register_operand")
17514 (if_then_else:SWI12 (match_operator 1 "ix86_comparison_operator"
17515 [(reg FLAGS_REG) (const_int 0)])
17516 (match_operand:SWI12 2 "register_operand")
17517 (match_operand:SWI12 3 "register_operand")))]
17518 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL
17519 && reload_completed"
17520 [(set (match_dup 0)
17521 (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
17523 operands[0] = gen_lowpart (SImode, operands[0]);
17524 operands[2] = gen_lowpart (SImode, operands[2]);
17525 operands[3] = gen_lowpart (SImode, operands[3]);
17528 ;; Don't do conditional moves with memory inputs
17530 [(match_scratch:SWI248 4 "r")
17531 (set (match_operand:SWI248 0 "register_operand")
17532 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
17533 [(reg FLAGS_REG) (const_int 0)])
17534 (match_operand:SWI248 2 "nonimmediate_operand")
17535 (match_operand:SWI248 3 "nonimmediate_operand")))]
17536 "TARGET_CMOVE && TARGET_AVOID_MEM_OPND_FOR_CMOVE
17537 && (MEM_P (operands[2]) || MEM_P (operands[3]))
17538 && optimize_insn_for_speed_p ()"
17539 [(set (match_dup 4) (match_dup 5))
17541 (if_then_else:SWI248 (match_dup 1) (match_dup 2) (match_dup 3)))]
17543 if (MEM_P (operands[2]))
17545 operands[5] = operands[2];
17546 operands[2] = operands[4];
17548 else if (MEM_P (operands[3]))
17550 operands[5] = operands[3];
17551 operands[3] = operands[4];
17554 gcc_unreachable ();
17558 [(match_scratch:SI 4 "r")
17559 (set (match_operand:DI 0 "register_operand")
17560 (if_then_else:DI (match_operator 1 "ix86_comparison_operator"
17561 [(reg FLAGS_REG) (const_int 0)])
17563 (match_operand:SI 2 "nonimmediate_operand"))
17565 (match_operand:SI 3 "nonimmediate_operand"))))]
17567 && TARGET_CMOVE && TARGET_AVOID_MEM_OPND_FOR_CMOVE
17568 && (MEM_P (operands[2]) || MEM_P (operands[3]))
17569 && optimize_insn_for_speed_p ()"
17570 [(set (match_dup 4) (match_dup 5))
17572 (if_then_else:DI (match_dup 1)
17573 (zero_extend:DI (match_dup 2))
17574 (zero_extend:DI (match_dup 3))))]
17576 if (MEM_P (operands[2]))
17578 operands[5] = operands[2];
17579 operands[2] = operands[4];
17581 else if (MEM_P (operands[3]))
17583 operands[5] = operands[3];
17584 operands[3] = operands[4];
17587 gcc_unreachable ();
17590 (define_expand "mov<mode>cc"
17591 [(set (match_operand:X87MODEF 0 "register_operand")
17592 (if_then_else:X87MODEF
17593 (match_operand 1 "comparison_operator")
17594 (match_operand:X87MODEF 2 "register_operand")
17595 (match_operand:X87MODEF 3 "register_operand")))]
17596 "(TARGET_80387 && TARGET_CMOVE)
17597 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
17598 "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
17600 (define_insn "*movxfcc_1"
17601 [(set (match_operand:XF 0 "register_operand" "=f,f")
17602 (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
17603 [(reg FLAGS_REG) (const_int 0)])
17604 (match_operand:XF 2 "register_operand" "f,0")
17605 (match_operand:XF 3 "register_operand" "0,f")))]
17606 "TARGET_80387 && TARGET_CMOVE"
17608 fcmov%F1\t{%2, %0|%0, %2}
17609 fcmov%f1\t{%3, %0|%0, %3}"
17610 [(set_attr "type" "fcmov")
17611 (set_attr "mode" "XF")])
17613 (define_insn "*movdfcc_1"
17614 [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r,r ,r")
17615 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
17616 [(reg FLAGS_REG) (const_int 0)])
17617 (match_operand:DF 2 "nonimmediate_operand"
17619 (match_operand:DF 3 "nonimmediate_operand"
17620 "0 ,f,0 ,rm,0, rm")))]
17621 "TARGET_80387 && TARGET_CMOVE
17622 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
17624 fcmov%F1\t{%2, %0|%0, %2}
17625 fcmov%f1\t{%3, %0|%0, %3}
17628 cmov%O2%C1\t{%2, %0|%0, %2}
17629 cmov%O2%c1\t{%3, %0|%0, %3}"
17630 [(set_attr "isa" "*,*,nox64,nox64,x64,x64")
17631 (set_attr "type" "fcmov,fcmov,multi,multi,icmov,icmov")
17632 (set_attr "mode" "DF,DF,DI,DI,DI,DI")])
17635 [(set (match_operand:DF 0 "general_reg_operand")
17636 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
17637 [(reg FLAGS_REG) (const_int 0)])
17638 (match_operand:DF 2 "nonimmediate_operand")
17639 (match_operand:DF 3 "nonimmediate_operand")))]
17640 "!TARGET_64BIT && reload_completed"
17641 [(set (match_dup 2)
17642 (if_then_else:SI (match_dup 1) (match_dup 4) (match_dup 5)))
17644 (if_then_else:SI (match_dup 1) (match_dup 6) (match_dup 7)))]
17646 split_double_mode (DImode, &operands[2], 2, &operands[4], &operands[6]);
17647 split_double_mode (DImode, &operands[0], 1, &operands[2], &operands[3]);
17650 (define_insn "*movsfcc_1_387"
17651 [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
17652 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
17653 [(reg FLAGS_REG) (const_int 0)])
17654 (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
17655 (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
17656 "TARGET_80387 && TARGET_CMOVE
17657 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
17659 fcmov%F1\t{%2, %0|%0, %2}
17660 fcmov%f1\t{%3, %0|%0, %3}
17661 cmov%O2%C1\t{%2, %0|%0, %2}
17662 cmov%O2%c1\t{%3, %0|%0, %3}"
17663 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
17664 (set_attr "mode" "SF,SF,SI,SI")])
17666 ;; Don't do conditional moves with memory inputs. This splitter helps
17667 ;; register starved x86_32 by forcing inputs into registers before reload.
17669 [(set (match_operand:MODEF 0 "register_operand")
17670 (if_then_else:MODEF (match_operator 1 "ix86_comparison_operator"
17671 [(reg FLAGS_REG) (const_int 0)])
17672 (match_operand:MODEF 2 "nonimmediate_operand")
17673 (match_operand:MODEF 3 "nonimmediate_operand")))]
17674 "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
17675 && TARGET_AVOID_MEM_OPND_FOR_CMOVE
17676 && (MEM_P (operands[2]) || MEM_P (operands[3]))
17677 && can_create_pseudo_p ()
17678 && optimize_insn_for_speed_p ()"
17679 [(set (match_dup 0)
17680 (if_then_else:MODEF (match_dup 1) (match_dup 2) (match_dup 3)))]
17682 if (MEM_P (operands[2]))
17683 operands[2] = force_reg (<MODE>mode, operands[2]);
17684 if (MEM_P (operands[3]))
17685 operands[3] = force_reg (<MODE>mode, operands[3]);
17688 ;; Don't do conditional moves with memory inputs
17690 [(match_scratch:MODEF 4 "r")
17691 (set (match_operand:MODEF 0 "general_reg_operand")
17692 (if_then_else:MODEF (match_operator 1 "fcmov_comparison_operator"
17693 [(reg FLAGS_REG) (const_int 0)])
17694 (match_operand:MODEF 2 "nonimmediate_operand")
17695 (match_operand:MODEF 3 "nonimmediate_operand")))]
17696 "(<MODE>mode != DFmode || TARGET_64BIT)
17697 && TARGET_80387 && TARGET_CMOVE
17698 && TARGET_AVOID_MEM_OPND_FOR_CMOVE
17699 && (MEM_P (operands[2]) || MEM_P (operands[3]))
17700 && optimize_insn_for_speed_p ()"
17701 [(set (match_dup 4) (match_dup 5))
17703 (if_then_else:MODEF (match_dup 1) (match_dup 2) (match_dup 3)))]
17705 if (MEM_P (operands[2]))
17707 operands[5] = operands[2];
17708 operands[2] = operands[4];
17710 else if (MEM_P (operands[3]))
17712 operands[5] = operands[3];
17713 operands[3] = operands[4];
17716 gcc_unreachable ();
17719 ;; All moves in XOP pcmov instructions are 128 bits and hence we restrict
17720 ;; the scalar versions to have only XMM registers as operands.
17722 ;; XOP conditional move
17723 (define_insn "*xop_pcmov_<mode>"
17724 [(set (match_operand:MODEF 0 "register_operand" "=x")
17725 (if_then_else:MODEF
17726 (match_operand:MODEF 1 "register_operand" "x")
17727 (match_operand:MODEF 2 "register_operand" "x")
17728 (match_operand:MODEF 3 "register_operand" "x")))]
17730 "vpcmov\t{%1, %3, %2, %0|%0, %2, %3, %1}"
17731 [(set_attr "type" "sse4arg")])
17733 ;; These versions of the min/max patterns are intentionally ignorant of
17734 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
17735 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
17736 ;; are undefined in this condition, we're certain this is correct.
17738 (define_insn "<code><mode>3"
17739 [(set (match_operand:MODEF 0 "register_operand" "=x,v")
17741 (match_operand:MODEF 1 "nonimmediate_operand" "%0,v")
17742 (match_operand:MODEF 2 "nonimmediate_operand" "xm,vm")))]
17743 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
17745 <maxmin_float><ssemodesuffix>\t{%2, %0|%0, %2}
17746 v<maxmin_float><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
17747 [(set_attr "isa" "noavx,avx")
17748 (set_attr "prefix" "orig,vex")
17749 (set_attr "type" "sseadd")
17750 (set_attr "mode" "<MODE>")])
17752 ;; These versions of the min/max patterns implement exactly the operations
17753 ;; min = (op1 < op2 ? op1 : op2)
17754 ;; max = (!(op1 < op2) ? op1 : op2)
17755 ;; Their operands are not commutative, and thus they may be used in the
17756 ;; presence of -0.0 and NaN.
17758 (define_insn "*ieee_s<ieee_maxmin><mode>3"
17759 [(set (match_operand:MODEF 0 "register_operand" "=x,v")
17761 [(match_operand:MODEF 1 "register_operand" "0,v")
17762 (match_operand:MODEF 2 "nonimmediate_operand" "xm,vm")]
17764 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
17766 <ieee_maxmin><ssemodesuffix>\t{%2, %0|%0, %2}
17767 v<ieee_maxmin><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
17768 [(set_attr "isa" "noavx,avx")
17769 (set_attr "prefix" "orig,maybe_evex")
17770 (set_attr "type" "sseadd")
17771 (set_attr "mode" "<MODE>")])
17773 ;; Make two stack loads independent:
17775 ;; fld %st(0) -> fld bb
17776 ;; fmul bb fmul %st(1), %st
17778 ;; Actually we only match the last two instructions for simplicity.
17781 [(set (match_operand 0 "fp_register_operand")
17782 (match_operand 1 "fp_register_operand"))
17784 (match_operator 2 "binary_fp_operator"
17786 (match_operand 3 "memory_operand")]))]
17787 "REGNO (operands[0]) != REGNO (operands[1])"
17788 [(set (match_dup 0) (match_dup 3))
17791 [(match_dup 5) (match_dup 4)]))]
17793 operands[4] = operands[0];
17794 operands[5] = operands[1];
17796 /* The % modifier is not operational anymore in peephole2's, so we have to
17797 swap the operands manually in the case of addition and multiplication. */
17798 if (COMMUTATIVE_ARITH_P (operands[2]))
17799 std::swap (operands[4], operands[5]);
17803 [(set (match_operand 0 "fp_register_operand")
17804 (match_operand 1 "fp_register_operand"))
17806 (match_operator 2 "binary_fp_operator"
17807 [(match_operand 3 "memory_operand")
17809 "REGNO (operands[0]) != REGNO (operands[1])"
17810 [(set (match_dup 0) (match_dup 3))
17813 [(match_dup 4) (match_dup 5)]))]
17815 operands[4] = operands[0];
17816 operands[5] = operands[1];
17818 /* The % modifier is not operational anymore in peephole2's, so we have to
17819 swap the operands manually in the case of addition and multiplication. */
17820 if (COMMUTATIVE_ARITH_P (operands[2]))
17821 std::swap (operands[4], operands[5]);
17824 ;; Conditional addition patterns
17825 (define_expand "add<mode>cc"
17826 [(match_operand:SWI 0 "register_operand")
17827 (match_operand 1 "ordered_comparison_operator")
17828 (match_operand:SWI 2 "register_operand")
17829 (match_operand:SWI 3 "const_int_operand")]
17831 "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
17833 ;; Misc patterns (?)
17835 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
17836 ;; Otherwise there will be nothing to keep
17838 ;; [(set (reg ebp) (reg esp))]
17839 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
17840 ;; (clobber (eflags)]
17841 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
17843 ;; in proper program order.
17845 (define_insn "@pro_epilogue_adjust_stack_add_<mode>"
17846 [(set (match_operand:P 0 "register_operand" "=r,r")
17847 (plus:P (match_operand:P 1 "register_operand" "0,r")
17848 (match_operand:P 2 "<nonmemory_operand>" "r<i>,l<i>")))
17849 (clobber (reg:CC FLAGS_REG))
17850 (clobber (mem:BLK (scratch)))]
17853 switch (get_attr_type (insn))
17856 return "mov{<imodesuffix>}\t{%1, %0|%0, %1}";
17859 gcc_assert (rtx_equal_p (operands[0], operands[1]));
17860 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
17861 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
17863 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
17866 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
17867 return "lea{<imodesuffix>}\t{%E2, %0|%0, %E2}";
17870 [(set (attr "type")
17871 (cond [(and (eq_attr "alternative" "0")
17872 (not (match_test "TARGET_OPT_AGU")))
17873 (const_string "alu")
17874 (match_operand:<MODE> 2 "const0_operand")
17875 (const_string "imov")
17877 (const_string "lea")))
17878 (set (attr "length_immediate")
17879 (cond [(eq_attr "type" "imov")
17881 (and (eq_attr "type" "alu")
17882 (match_operand 2 "const128_operand"))
17885 (const_string "*")))
17886 (set_attr "mode" "<MODE>")])
17888 (define_insn "@pro_epilogue_adjust_stack_sub_<mode>"
17889 [(set (match_operand:P 0 "register_operand" "=r")
17890 (minus:P (match_operand:P 1 "register_operand" "0")
17891 (match_operand:P 2 "register_operand" "r")))
17892 (clobber (reg:CC FLAGS_REG))
17893 (clobber (mem:BLK (scratch)))]
17895 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
17896 [(set_attr "type" "alu")
17897 (set_attr "mode" "<MODE>")])
17899 (define_insn "@allocate_stack_worker_probe_<mode>"
17900 [(set (match_operand:P 0 "register_operand" "=a")
17901 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
17902 UNSPECV_STACK_PROBE))
17903 (clobber (reg:CC FLAGS_REG))]
17904 "ix86_target_stack_probe ()"
17905 "call\t___chkstk_ms"
17906 [(set_attr "type" "multi")
17907 (set_attr "length" "5")])
17909 (define_expand "allocate_stack"
17910 [(match_operand 0 "register_operand")
17911 (match_operand 1 "general_operand")]
17912 "ix86_target_stack_probe ()"
17916 #ifndef CHECK_STACK_LIMIT
17917 #define CHECK_STACK_LIMIT 0
17920 if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
17921 && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
17925 x = copy_to_mode_reg (Pmode, operands[1]);
17927 emit_insn (gen_allocate_stack_worker_probe (Pmode, x, x));
17930 x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, x,
17931 stack_pointer_rtx, 0, OPTAB_DIRECT);
17933 if (x != stack_pointer_rtx)
17934 emit_move_insn (stack_pointer_rtx, x);
17936 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
17940 (define_expand "probe_stack"
17941 [(match_operand 0 "memory_operand")]
17944 emit_insn (gen_probe_stack_1
17945 (word_mode, operands[0], const0_rtx));
17949 ;; Use OR for stack probes, this is shorter.
17950 (define_insn "@probe_stack_1_<mode>"
17951 [(set (match_operand:W 0 "memory_operand" "=m")
17952 (unspec:W [(match_operand:W 1 "const0_operand")]
17953 UNSPEC_PROBE_STACK))
17954 (clobber (reg:CC FLAGS_REG))]
17956 "or{<imodesuffix>}\t{%1, %0|%0, %1}"
17957 [(set_attr "type" "alu1")
17958 (set_attr "mode" "<MODE>")
17959 (set_attr "length_immediate" "1")])
17961 (define_insn "@adjust_stack_and_probe_<mode>"
17962 [(set (match_operand:P 0 "register_operand" "=r")
17963 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
17964 UNSPECV_PROBE_STACK_RANGE))
17965 (set (reg:P SP_REG)
17966 (minus:P (reg:P SP_REG) (match_operand:P 2 "const_int_operand" "n")))
17967 (clobber (reg:CC FLAGS_REG))
17968 (clobber (mem:BLK (scratch)))]
17970 "* return output_adjust_stack_and_probe (operands[0]);"
17971 [(set_attr "type" "multi")])
17973 (define_insn "@probe_stack_range_<mode>"
17974 [(set (match_operand:P 0 "register_operand" "=r")
17975 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
17976 (match_operand:P 2 "const_int_operand" "n")]
17977 UNSPECV_PROBE_STACK_RANGE))
17978 (clobber (reg:CC FLAGS_REG))]
17980 "* return output_probe_stack_range (operands[0], operands[2]);"
17981 [(set_attr "type" "multi")])
17983 (define_expand "builtin_setjmp_receiver"
17984 [(label_ref (match_operand 0))]
17985 "!TARGET_64BIT && flag_pic"
17991 rtx_code_label *label_rtx = gen_label_rtx ();
17992 emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
17993 xops[0] = xops[1] = pic_offset_table_rtx;
17994 xops[2] = machopic_gen_offset (gen_rtx_LABEL_REF (SImode, label_rtx));
17995 ix86_expand_binary_operator (MINUS, SImode, xops);
17999 emit_insn (gen_set_got (pic_offset_table_rtx));
18003 (define_expand "save_stack_nonlocal"
18004 [(set (match_operand 0 "memory_operand")
18005 (match_operand 1 "register_operand"))]
18009 if ((flag_cf_protection & CF_RETURN))
18011 /* Copy shadow stack pointer to the first slot and stack ppointer
18012 to the second slot. */
18013 rtx ssp_slot = adjust_address (operands[0], word_mode, 0);
18014 stack_slot = adjust_address (operands[0], Pmode, UNITS_PER_WORD);
18015 rtx ssp = gen_reg_rtx (word_mode);
18016 emit_insn ((word_mode == SImode)
18017 ? gen_rdsspsi (ssp)
18018 : gen_rdsspdi (ssp));
18019 emit_move_insn (ssp_slot, ssp);
18022 stack_slot = adjust_address (operands[0], Pmode, 0);
18023 emit_move_insn (stack_slot, operands[1]);
18027 (define_expand "restore_stack_nonlocal"
18028 [(set (match_operand 0 "register_operand" "")
18029 (match_operand 1 "memory_operand" ""))]
18033 if ((flag_cf_protection & CF_RETURN))
18035 /* Restore shadow stack pointer from the first slot and stack
18036 pointer from the second slot. */
18037 rtx ssp_slot = adjust_address (operands[1], word_mode, 0);
18038 stack_slot = adjust_address (operands[1], Pmode, UNITS_PER_WORD);
18040 rtx flags, jump, noadj_label, inc_label, loop_label;
18041 rtx reg_adj, reg_ssp, tmp, clob;
18043 /* Get the current shadow stack pointer. The code below will check if
18044 SHSTK feature is enabled. If it is not enabled the RDSSP instruction
18046 reg_ssp = gen_reg_rtx (word_mode);
18047 emit_insn (gen_rtx_SET (reg_ssp, const0_rtx));
18048 emit_insn ((word_mode == SImode)
18049 ? gen_rdsspsi (reg_ssp)
18050 : gen_rdsspdi (reg_ssp));
18052 /* Compare through substraction the saved and the current ssp to decide
18053 if ssp has to be adjusted. */
18054 tmp = gen_rtx_SET (reg_ssp, gen_rtx_MINUS (word_mode, reg_ssp,
18056 clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
18057 tmp = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, tmp, clob));
18060 /* Compare and jump over adjustment code. */
18061 noadj_label = gen_label_rtx ();
18062 flags = gen_rtx_REG (CCZmode, FLAGS_REG);
18063 tmp = gen_rtx_EQ (VOIDmode, flags, const0_rtx);
18064 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
18065 gen_rtx_LABEL_REF (VOIDmode, noadj_label),
18067 jump = emit_jump_insn (gen_rtx_SET (pc_rtx, tmp));
18068 JUMP_LABEL (jump) = noadj_label;
18070 /* Compute the numebr of frames to adjust. */
18071 reg_adj = gen_lowpart (ptr_mode, reg_ssp);
18072 tmp = gen_rtx_SET (reg_adj,
18073 gen_rtx_LSHIFTRT (ptr_mode,
18074 negate_rtx (ptr_mode, reg_adj),
18075 GEN_INT ((word_mode == SImode)
18078 clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
18079 tmp = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, tmp, clob));
18082 /* Check if number of frames <= 255 so no loop is needed. */
18083 tmp = gen_rtx_COMPARE (CCmode, reg_adj, GEN_INT (255));
18084 flags = gen_rtx_REG (CCmode, FLAGS_REG);
18085 emit_insn (gen_rtx_SET (flags, tmp));
18087 inc_label = gen_label_rtx ();
18088 tmp = gen_rtx_LEU (VOIDmode, flags, const0_rtx);
18089 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
18090 gen_rtx_LABEL_REF (VOIDmode, inc_label),
18092 jump = emit_jump_insn (gen_rtx_SET (pc_rtx, tmp));
18093 JUMP_LABEL (jump) = inc_label;
18095 rtx reg_255 = gen_reg_rtx (word_mode);
18096 emit_move_insn (reg_255, GEN_INT (255));
18098 /* Adjust the ssp in a loop. */
18099 loop_label = gen_label_rtx ();
18100 emit_label (loop_label);
18101 LABEL_NUSES (loop_label) = 1;
18103 emit_insn ((word_mode == SImode)
18104 ? gen_incsspsi (reg_255)
18105 : gen_incsspdi (reg_255));
18106 tmp = gen_rtx_SET (reg_adj, gen_rtx_MINUS (ptr_mode,
18109 clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
18110 tmp = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, tmp, clob));
18113 tmp = gen_rtx_COMPARE (CCmode, reg_adj, GEN_INT (255));
18114 flags = gen_rtx_REG (CCmode, FLAGS_REG);
18115 emit_insn (gen_rtx_SET (flags, tmp));
18117 /* Jump to the loop label. */
18118 tmp = gen_rtx_GTU (VOIDmode, flags, const0_rtx);
18119 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
18120 gen_rtx_LABEL_REF (VOIDmode, loop_label),
18122 jump = emit_jump_insn (gen_rtx_SET (pc_rtx, tmp));
18123 JUMP_LABEL (jump) = loop_label;
18125 emit_label (inc_label);
18126 LABEL_NUSES (inc_label) = 1;
18127 emit_insn ((word_mode == SImode)
18128 ? gen_incsspsi (reg_ssp)
18129 : gen_incsspdi (reg_ssp));
18131 emit_label (noadj_label);
18132 LABEL_NUSES (noadj_label) = 1;
18135 stack_slot = adjust_address (operands[1], Pmode, 0);
18136 emit_move_insn (operands[0], stack_slot);
18141 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
18142 ;; Do not split instructions with mask registers.
18144 [(set (match_operand 0 "general_reg_operand")
18145 (match_operator 3 "promotable_binary_operator"
18146 [(match_operand 1 "general_reg_operand")
18147 (match_operand 2 "aligned_operand")]))
18148 (clobber (reg:CC FLAGS_REG))]
18149 "! TARGET_PARTIAL_REG_STALL && reload_completed
18150 && ((GET_MODE (operands[0]) == HImode
18151 && ((optimize_function_for_speed_p (cfun) && !TARGET_FAST_PREFIX)
18152 /* ??? next two lines just !satisfies_constraint_K (...) */
18153 || !CONST_INT_P (operands[2])
18154 || satisfies_constraint_K (operands[2])))
18155 || (GET_MODE (operands[0]) == QImode
18156 && (TARGET_PROMOTE_QImode || optimize_function_for_size_p (cfun))))"
18157 [(parallel [(set (match_dup 0)
18158 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
18159 (clobber (reg:CC FLAGS_REG))])]
18161 operands[0] = gen_lowpart (SImode, operands[0]);
18162 operands[1] = gen_lowpart (SImode, operands[1]);
18163 if (GET_CODE (operands[3]) != ASHIFT)
18164 operands[2] = gen_lowpart (SImode, operands[2]);
18165 operands[3] = shallow_copy_rtx (operands[3]);
18166 PUT_MODE (operands[3], SImode);
18169 ; Promote the QImode tests, as i386 has encoding of the AND
18170 ; instruction with 32-bit sign-extended immediate and thus the
18171 ; instruction size is unchanged, except in the %eax case for
18172 ; which it is increased by one byte, hence the ! optimize_size.
18174 [(set (match_operand 0 "flags_reg_operand")
18175 (match_operator 2 "compare_operator"
18176 [(and (match_operand 3 "aligned_operand")
18177 (match_operand 4 "const_int_operand"))
18179 (set (match_operand 1 "register_operand")
18180 (and (match_dup 3) (match_dup 4)))]
18181 "! TARGET_PARTIAL_REG_STALL && reload_completed
18182 && optimize_insn_for_speed_p ()
18183 && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
18184 || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))
18185 /* Ensure that the operand will remain sign-extended immediate. */
18186 && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)"
18187 [(parallel [(set (match_dup 0)
18188 (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
18191 (and:SI (match_dup 3) (match_dup 4)))])]
18194 = gen_int_mode (INTVAL (operands[4])
18195 & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
18196 operands[1] = gen_lowpart (SImode, operands[1]);
18197 operands[3] = gen_lowpart (SImode, operands[3]);
18200 ; Don't promote the QImode tests, as i386 doesn't have encoding of
18201 ; the TEST instruction with 32-bit sign-extended immediate and thus
18202 ; the instruction size would at least double, which is not what we
18203 ; want even with ! optimize_size.
18205 [(set (match_operand 0 "flags_reg_operand")
18206 (match_operator 1 "compare_operator"
18207 [(and (match_operand:HI 2 "aligned_operand")
18208 (match_operand:HI 3 "const_int_operand"))
18210 "! TARGET_PARTIAL_REG_STALL && reload_completed
18211 && ! TARGET_FAST_PREFIX
18212 && optimize_insn_for_speed_p ()
18213 /* Ensure that the operand will remain sign-extended immediate. */
18214 && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)"
18215 [(set (match_dup 0)
18216 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
18220 = gen_int_mode (INTVAL (operands[3])
18221 & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
18222 operands[2] = gen_lowpart (SImode, operands[2]);
18226 [(set (match_operand 0 "register_operand")
18227 (neg (match_operand 1 "register_operand")))
18228 (clobber (reg:CC FLAGS_REG))]
18229 "! TARGET_PARTIAL_REG_STALL && reload_completed
18230 && (GET_MODE (operands[0]) == HImode
18231 || (GET_MODE (operands[0]) == QImode
18232 && (TARGET_PROMOTE_QImode
18233 || optimize_insn_for_size_p ())))"
18234 [(parallel [(set (match_dup 0)
18235 (neg:SI (match_dup 1)))
18236 (clobber (reg:CC FLAGS_REG))])]
18238 operands[0] = gen_lowpart (SImode, operands[0]);
18239 operands[1] = gen_lowpart (SImode, operands[1]);
18242 ;; Do not split instructions with mask regs.
18244 [(set (match_operand 0 "general_reg_operand")
18245 (not (match_operand 1 "general_reg_operand")))]
18246 "! TARGET_PARTIAL_REG_STALL && reload_completed
18247 && (GET_MODE (operands[0]) == HImode
18248 || (GET_MODE (operands[0]) == QImode
18249 && (TARGET_PROMOTE_QImode
18250 || optimize_insn_for_size_p ())))"
18251 [(set (match_dup 0)
18252 (not:SI (match_dup 1)))]
18254 operands[0] = gen_lowpart (SImode, operands[0]);
18255 operands[1] = gen_lowpart (SImode, operands[1]);
18258 ;; RTL Peephole optimizations, run before sched2. These primarily look to
18259 ;; transform a complex memory operation into two memory to register operations.
18261 ;; Don't push memory operands
18263 [(set (match_operand:SWI 0 "push_operand")
18264 (match_operand:SWI 1 "memory_operand"))
18265 (match_scratch:SWI 2 "<r>")]
18266 "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
18267 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
18268 [(set (match_dup 2) (match_dup 1))
18269 (set (match_dup 0) (match_dup 2))])
18271 ;; We need to handle SFmode only, because DFmode and XFmode are split to
18274 [(set (match_operand:SF 0 "push_operand")
18275 (match_operand:SF 1 "memory_operand"))
18276 (match_scratch:SF 2 "r")]
18277 "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
18278 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
18279 [(set (match_dup 2) (match_dup 1))
18280 (set (match_dup 0) (match_dup 2))])
18282 ;; Don't move an immediate directly to memory when the instruction
18283 ;; gets too big, or if LCP stalls are a problem for 16-bit moves.
18285 [(match_scratch:SWI124 1 "<r>")
18286 (set (match_operand:SWI124 0 "memory_operand")
18288 "optimize_insn_for_speed_p ()
18289 && ((<MODE>mode == HImode
18290 && TARGET_LCP_STALL)
18291 || (!TARGET_USE_MOV0
18292 && TARGET_SPLIT_LONG_MOVES
18293 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn))
18294 && peep2_regno_dead_p (0, FLAGS_REG)"
18295 [(parallel [(set (match_dup 2) (const_int 0))
18296 (clobber (reg:CC FLAGS_REG))])
18297 (set (match_dup 0) (match_dup 1))]
18298 "operands[2] = gen_lowpart (SImode, operands[1]);")
18301 [(match_scratch:SWI124 2 "<r>")
18302 (set (match_operand:SWI124 0 "memory_operand")
18303 (match_operand:SWI124 1 "immediate_operand"))]
18304 "optimize_insn_for_speed_p ()
18305 && ((<MODE>mode == HImode
18306 && TARGET_LCP_STALL)
18307 || (TARGET_SPLIT_LONG_MOVES
18308 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn))"
18309 [(set (match_dup 2) (match_dup 1))
18310 (set (match_dup 0) (match_dup 2))])
18312 ;; Don't compare memory with zero, load and use a test instead.
18314 [(set (match_operand 0 "flags_reg_operand")
18315 (match_operator 1 "compare_operator"
18316 [(match_operand:SI 2 "memory_operand")
18318 (match_scratch:SI 3 "r")]
18319 "optimize_insn_for_speed_p () && ix86_match_ccmode (insn, CCNOmode)"
18320 [(set (match_dup 3) (match_dup 2))
18321 (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))])
18323 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
18324 ;; Don't split NOTs with a displacement operand, because resulting XOR
18325 ;; will not be pairable anyway.
18327 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
18328 ;; represented using a modRM byte. The XOR replacement is long decoded,
18329 ;; so this split helps here as well.
18331 ;; Note: Can't do this as a regular split because we can't get proper
18332 ;; lifetime information then.
18335 [(set (match_operand:SWI124 0 "nonimmediate_gr_operand")
18336 (not:SWI124 (match_operand:SWI124 1 "nonimmediate_gr_operand")))]
18337 "optimize_insn_for_speed_p ()
18338 && ((TARGET_NOT_UNPAIRABLE
18339 && (!MEM_P (operands[0])
18340 || !memory_displacement_operand (operands[0], <MODE>mode)))
18341 || (TARGET_NOT_VECTORMODE
18342 && long_memory_operand (operands[0], <MODE>mode)))
18343 && peep2_regno_dead_p (0, FLAGS_REG)"
18344 [(parallel [(set (match_dup 0)
18345 (xor:SWI124 (match_dup 1) (const_int -1)))
18346 (clobber (reg:CC FLAGS_REG))])])
18348 ;; Non pairable "test imm, reg" instructions can be translated to
18349 ;; "and imm, reg" if reg dies. The "and" form is also shorter (one
18350 ;; byte opcode instead of two, have a short form for byte operands),
18351 ;; so do it for other CPUs as well. Given that the value was dead,
18352 ;; this should not create any new dependencies. Pass on the sub-word
18353 ;; versions if we're concerned about partial register stalls.
18356 [(set (match_operand 0 "flags_reg_operand")
18357 (match_operator 1 "compare_operator"
18358 [(and:SI (match_operand:SI 2 "register_operand")
18359 (match_operand:SI 3 "immediate_operand"))
18361 "ix86_match_ccmode (insn, CCNOmode)
18362 && (REGNO (operands[2]) != AX_REG
18363 || satisfies_constraint_K (operands[3]))
18364 && peep2_reg_dead_p (1, operands[2])"
18366 [(set (match_dup 0)
18367 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
18370 (and:SI (match_dup 2) (match_dup 3)))])])
18372 ;; We don't need to handle HImode case, because it will be promoted to SImode
18373 ;; on ! TARGET_PARTIAL_REG_STALL
18376 [(set (match_operand 0 "flags_reg_operand")
18377 (match_operator 1 "compare_operator"
18378 [(and:QI (match_operand:QI 2 "register_operand")
18379 (match_operand:QI 3 "immediate_operand"))
18381 "! TARGET_PARTIAL_REG_STALL
18382 && ix86_match_ccmode (insn, CCNOmode)
18383 && REGNO (operands[2]) != AX_REG
18384 && peep2_reg_dead_p (1, operands[2])"
18386 [(set (match_dup 0)
18387 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
18390 (and:QI (match_dup 2) (match_dup 3)))])])
18393 [(set (match_operand 0 "flags_reg_operand")
18394 (match_operator 1 "compare_operator"
18397 (zero_extract:SI (match_operand 2 "QIreg_operand")
18400 (match_operand 3 "const_int_operand"))
18402 "! TARGET_PARTIAL_REG_STALL
18403 && ix86_match_ccmode (insn, CCNOmode)
18404 && REGNO (operands[2]) != AX_REG
18405 && peep2_reg_dead_p (1, operands[2])"
18407 [(set (match_dup 0)
18411 (zero_extract:SI (match_dup 2)
18416 (set (zero_extract:SI (match_dup 2)
18422 (zero_extract:SI (match_dup 2)
18425 (match_dup 3)) 0))])])
18427 ;; Don't do logical operations with memory inputs.
18429 [(match_scratch:SWI 2 "<r>")
18430 (parallel [(set (match_operand:SWI 0 "register_operand")
18431 (match_operator:SWI 3 "arith_or_logical_operator"
18433 (match_operand:SWI 1 "memory_operand")]))
18434 (clobber (reg:CC FLAGS_REG))])]
18435 "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
18436 [(set (match_dup 2) (match_dup 1))
18437 (parallel [(set (match_dup 0)
18438 (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
18439 (clobber (reg:CC FLAGS_REG))])])
18442 [(match_scratch:SWI 2 "<r>")
18443 (parallel [(set (match_operand:SWI 0 "register_operand")
18444 (match_operator:SWI 3 "arith_or_logical_operator"
18445 [(match_operand:SWI 1 "memory_operand")
18447 (clobber (reg:CC FLAGS_REG))])]
18448 "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
18449 [(set (match_dup 2) (match_dup 1))
18450 (parallel [(set (match_dup 0)
18451 (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
18452 (clobber (reg:CC FLAGS_REG))])])
18454 ;; Prefer Load+RegOp to Mov+MemOp. Watch out for cases when
18455 ;; the memory address refers to the destination of the load!
18458 [(set (match_operand:SWI 0 "general_reg_operand")
18459 (match_operand:SWI 1 "general_reg_operand"))
18460 (parallel [(set (match_dup 0)
18461 (match_operator:SWI 3 "commutative_operator"
18463 (match_operand:SWI 2 "memory_operand")]))
18464 (clobber (reg:CC FLAGS_REG))])]
18465 "REGNO (operands[0]) != REGNO (operands[1])
18466 && (<MODE>mode != QImode
18467 || any_QIreg_operand (operands[1], QImode))"
18468 [(set (match_dup 0) (match_dup 4))
18469 (parallel [(set (match_dup 0)
18470 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))
18471 (clobber (reg:CC FLAGS_REG))])]
18472 "operands[4] = replace_rtx (operands[2], operands[0], operands[1], true);")
18475 [(set (match_operand 0 "mmx_reg_operand")
18476 (match_operand 1 "mmx_reg_operand"))
18478 (match_operator 3 "commutative_operator"
18480 (match_operand 2 "memory_operand")]))]
18481 "REGNO (operands[0]) != REGNO (operands[1])"
18482 [(set (match_dup 0) (match_dup 2))
18484 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))])
18487 [(set (match_operand 0 "sse_reg_operand")
18488 (match_operand 1 "sse_reg_operand"))
18490 (match_operator 3 "commutative_operator"
18492 (match_operand 2 "memory_operand")]))]
18493 "REGNO (operands[0]) != REGNO (operands[1])"
18494 [(set (match_dup 0) (match_dup 2))
18496 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))])
18498 ; Don't do logical operations with memory outputs
18500 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
18501 ; instruction into two 1-uop insns plus a 2-uop insn. That last has
18502 ; the same decoder scheduling characteristics as the original.
18505 [(match_scratch:SWI 2 "<r>")
18506 (parallel [(set (match_operand:SWI 0 "memory_operand")
18507 (match_operator:SWI 3 "arith_or_logical_operator"
18509 (match_operand:SWI 1 "<nonmemory_operand>")]))
18510 (clobber (reg:CC FLAGS_REG))])]
18511 "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())"
18512 [(set (match_dup 2) (match_dup 0))
18513 (parallel [(set (match_dup 2)
18514 (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
18515 (clobber (reg:CC FLAGS_REG))])
18516 (set (match_dup 0) (match_dup 2))])
18519 [(match_scratch:SWI 2 "<r>")
18520 (parallel [(set (match_operand:SWI 0 "memory_operand")
18521 (match_operator:SWI 3 "arith_or_logical_operator"
18522 [(match_operand:SWI 1 "<nonmemory_operand>")
18524 (clobber (reg:CC FLAGS_REG))])]
18525 "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())"
18526 [(set (match_dup 2) (match_dup 0))
18527 (parallel [(set (match_dup 2)
18528 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
18529 (clobber (reg:CC FLAGS_REG))])
18530 (set (match_dup 0) (match_dup 2))])
18532 ;; Attempt to use arith or logical operations with memory outputs with
18533 ;; setting of flags.
18535 [(set (match_operand:SWI 0 "register_operand")
18536 (match_operand:SWI 1 "memory_operand"))
18537 (parallel [(set (match_dup 0)
18538 (match_operator:SWI 3 "plusminuslogic_operator"
18540 (match_operand:SWI 2 "<nonmemory_operand>")]))
18541 (clobber (reg:CC FLAGS_REG))])
18542 (set (match_dup 1) (match_dup 0))
18543 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
18544 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
18545 && peep2_reg_dead_p (4, operands[0])
18546 && !reg_overlap_mentioned_p (operands[0], operands[1])
18547 && !reg_overlap_mentioned_p (operands[0], operands[2])
18548 && (<MODE>mode != QImode
18549 || immediate_operand (operands[2], QImode)
18550 || any_QIreg_operand (operands[2], QImode))
18551 && ix86_match_ccmode (peep2_next_insn (3),
18552 (GET_CODE (operands[3]) == PLUS
18553 || GET_CODE (operands[3]) == MINUS)
18554 ? CCGOCmode : CCNOmode)"
18555 [(parallel [(set (match_dup 4) (match_dup 6))
18556 (set (match_dup 1) (match_dup 5))])]
18558 operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
18560 = gen_rtx_fmt_ee (GET_CODE (operands[3]), GET_MODE (operands[3]),
18561 copy_rtx (operands[1]),
18564 = gen_rtx_COMPARE (GET_MODE (operands[4]),
18565 copy_rtx (operands[5]),
18569 ;; Likewise for cmpelim optimized pattern.
18571 [(set (match_operand:SWI 0 "register_operand")
18572 (match_operand:SWI 1 "memory_operand"))
18573 (parallel [(set (reg FLAGS_REG)
18574 (compare (match_operator:SWI 3 "plusminuslogic_operator"
18576 (match_operand:SWI 2 "<nonmemory_operand>")])
18578 (set (match_dup 0) (match_dup 3))])
18579 (set (match_dup 1) (match_dup 0))]
18580 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
18581 && peep2_reg_dead_p (3, operands[0])
18582 && !reg_overlap_mentioned_p (operands[0], operands[1])
18583 && !reg_overlap_mentioned_p (operands[0], operands[2])
18584 && ix86_match_ccmode (peep2_next_insn (1),
18585 (GET_CODE (operands[3]) == PLUS
18586 || GET_CODE (operands[3]) == MINUS)
18587 ? CCGOCmode : CCNOmode)"
18588 [(parallel [(set (match_dup 4) (match_dup 6))
18589 (set (match_dup 1) (match_dup 5))])]
18591 operands[4] = SET_DEST (XVECEXP (PATTERN (peep2_next_insn (1)), 0, 0));
18593 = gen_rtx_fmt_ee (GET_CODE (operands[3]), GET_MODE (operands[3]),
18594 copy_rtx (operands[1]), operands[2]);
18596 = gen_rtx_COMPARE (GET_MODE (operands[4]), copy_rtx (operands[5]),
18600 ;; Likewise for instances where we have a lea pattern.
18602 [(set (match_operand:SWI 0 "register_operand")
18603 (match_operand:SWI 1 "memory_operand"))
18604 (set (match_operand:<LEAMODE> 3 "register_operand")
18605 (plus:<LEAMODE> (match_operand:<LEAMODE> 4 "register_operand")
18606 (match_operand:<LEAMODE> 2 "<nonmemory_operand>")))
18607 (set (match_dup 1) (match_operand:SWI 5 "register_operand"))
18608 (set (reg FLAGS_REG) (compare (match_dup 5) (const_int 0)))]
18609 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
18610 && REGNO (operands[4]) == REGNO (operands[0])
18611 && REGNO (operands[5]) == REGNO (operands[3])
18612 && peep2_reg_dead_p (4, operands[3])
18613 && ((REGNO (operands[0]) == REGNO (operands[3]))
18614 || peep2_reg_dead_p (2, operands[0]))
18615 && !reg_overlap_mentioned_p (operands[0], operands[1])
18616 && !reg_overlap_mentioned_p (operands[3], operands[1])
18617 && !reg_overlap_mentioned_p (operands[0], operands[2])
18618 && (<MODE>mode != QImode
18619 || immediate_operand (operands[2], QImode)
18620 || any_QIreg_operand (operands[2], QImode))
18621 && ix86_match_ccmode (peep2_next_insn (3), CCGOCmode)"
18622 [(parallel [(set (match_dup 6) (match_dup 8))
18623 (set (match_dup 1) (match_dup 7))])]
18625 operands[6] = SET_DEST (PATTERN (peep2_next_insn (3)));
18627 = gen_rtx_PLUS (<MODE>mode,
18628 copy_rtx (operands[1]),
18629 gen_lowpart (<MODE>mode, operands[2]));
18631 = gen_rtx_COMPARE (GET_MODE (operands[6]),
18632 copy_rtx (operands[7]),
18637 [(parallel [(set (match_operand:SWI 0 "register_operand")
18638 (match_operator:SWI 2 "plusminuslogic_operator"
18640 (match_operand:SWI 1 "memory_operand")]))
18641 (clobber (reg:CC FLAGS_REG))])
18642 (set (match_dup 1) (match_dup 0))
18643 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
18644 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
18645 && COMMUTATIVE_ARITH_P (operands[2])
18646 && peep2_reg_dead_p (3, operands[0])
18647 && !reg_overlap_mentioned_p (operands[0], operands[1])
18648 && ix86_match_ccmode (peep2_next_insn (2),
18649 GET_CODE (operands[2]) == PLUS
18650 ? CCGOCmode : CCNOmode)"
18651 [(parallel [(set (match_dup 3) (match_dup 5))
18652 (set (match_dup 1) (match_dup 4))])]
18654 operands[3] = SET_DEST (PATTERN (peep2_next_insn (2)));
18656 = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
18657 copy_rtx (operands[1]),
18660 = gen_rtx_COMPARE (GET_MODE (operands[3]),
18661 copy_rtx (operands[4]),
18665 ;; Likewise for cmpelim optimized pattern.
18667 [(parallel [(set (reg FLAGS_REG)
18668 (compare (match_operator:SWI 2 "plusminuslogic_operator"
18669 [(match_operand:SWI 0 "register_operand")
18670 (match_operand:SWI 1 "memory_operand")])
18672 (set (match_dup 0) (match_dup 2))])
18673 (set (match_dup 1) (match_dup 0))]
18674 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
18675 && COMMUTATIVE_ARITH_P (operands[2])
18676 && peep2_reg_dead_p (2, operands[0])
18677 && !reg_overlap_mentioned_p (operands[0], operands[1])
18678 && ix86_match_ccmode (peep2_next_insn (0),
18679 GET_CODE (operands[2]) == PLUS
18680 ? CCGOCmode : CCNOmode)"
18681 [(parallel [(set (match_dup 3) (match_dup 5))
18682 (set (match_dup 1) (match_dup 4))])]
18684 operands[3] = SET_DEST (XVECEXP (PATTERN (peep2_next_insn (0)), 0, 0));
18686 = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
18687 copy_rtx (operands[1]), operands[0]);
18689 = gen_rtx_COMPARE (GET_MODE (operands[3]), copy_rtx (operands[4]),
18694 [(set (match_operand:SWI12 0 "register_operand")
18695 (match_operand:SWI12 1 "memory_operand"))
18696 (parallel [(set (match_operand:SI 4 "register_operand")
18697 (match_operator:SI 3 "plusminuslogic_operator"
18699 (match_operand:SI 2 "nonmemory_operand")]))
18700 (clobber (reg:CC FLAGS_REG))])
18701 (set (match_dup 1) (match_dup 0))
18702 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
18703 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
18704 && REGNO (operands[0]) == REGNO (operands[4])
18705 && peep2_reg_dead_p (4, operands[0])
18706 && (<MODE>mode != QImode
18707 || immediate_operand (operands[2], SImode)
18708 || any_QIreg_operand (operands[2], SImode))
18709 && !reg_overlap_mentioned_p (operands[0], operands[1])
18710 && !reg_overlap_mentioned_p (operands[0], operands[2])
18711 && ix86_match_ccmode (peep2_next_insn (3),
18712 (GET_CODE (operands[3]) == PLUS
18713 || GET_CODE (operands[3]) == MINUS)
18714 ? CCGOCmode : CCNOmode)"
18715 [(parallel [(set (match_dup 5) (match_dup 7))
18716 (set (match_dup 1) (match_dup 6))])]
18718 operands[5] = SET_DEST (PATTERN (peep2_next_insn (3)));
18720 = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
18721 copy_rtx (operands[1]),
18722 gen_lowpart (<MODE>mode, operands[2]));
18724 = gen_rtx_COMPARE (GET_MODE (operands[5]),
18725 copy_rtx (operands[6]),
18729 ;; peephole2 comes before regcprop, so deal also with a case that
18730 ;; would be cleaned up by regcprop.
18732 [(set (match_operand:SWI 0 "register_operand")
18733 (match_operand:SWI 1 "memory_operand"))
18734 (parallel [(set (match_dup 0)
18735 (match_operator:SWI 3 "plusminuslogic_operator"
18737 (match_operand:SWI 2 "<nonmemory_operand>")]))
18738 (clobber (reg:CC FLAGS_REG))])
18739 (set (match_operand:SWI 4 "register_operand") (match_dup 0))
18740 (set (match_dup 1) (match_dup 4))
18741 (set (reg FLAGS_REG) (compare (match_dup 4) (const_int 0)))]
18742 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
18743 && peep2_reg_dead_p (3, operands[0])
18744 && peep2_reg_dead_p (5, operands[4])
18745 && !reg_overlap_mentioned_p (operands[0], operands[1])
18746 && !reg_overlap_mentioned_p (operands[0], operands[2])
18747 && !reg_overlap_mentioned_p (operands[4], operands[1])
18748 && (<MODE>mode != QImode
18749 || immediate_operand (operands[2], QImode)
18750 || any_QIreg_operand (operands[2], QImode))
18751 && ix86_match_ccmode (peep2_next_insn (4),
18752 (GET_CODE (operands[3]) == PLUS
18753 || GET_CODE (operands[3]) == MINUS)
18754 ? CCGOCmode : CCNOmode)"
18755 [(parallel [(set (match_dup 5) (match_dup 7))
18756 (set (match_dup 1) (match_dup 6))])]
18758 operands[5] = SET_DEST (PATTERN (peep2_next_insn (4)));
18760 = gen_rtx_fmt_ee (GET_CODE (operands[3]), GET_MODE (operands[3]),
18761 copy_rtx (operands[1]),
18764 = gen_rtx_COMPARE (GET_MODE (operands[5]),
18765 copy_rtx (operands[6]),
18770 [(set (match_operand:SWI12 0 "register_operand")
18771 (match_operand:SWI12 1 "memory_operand"))
18772 (parallel [(set (match_operand:SI 4 "register_operand")
18773 (match_operator:SI 3 "plusminuslogic_operator"
18775 (match_operand:SI 2 "nonmemory_operand")]))
18776 (clobber (reg:CC FLAGS_REG))])
18777 (set (match_operand:SWI12 5 "register_operand") (match_dup 0))
18778 (set (match_dup 1) (match_dup 5))
18779 (set (reg FLAGS_REG) (compare (match_dup 5) (const_int 0)))]
18780 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
18781 && REGNO (operands[0]) == REGNO (operands[4])
18782 && peep2_reg_dead_p (3, operands[0])
18783 && peep2_reg_dead_p (5, operands[5])
18784 && (<MODE>mode != QImode
18785 || immediate_operand (operands[2], SImode)
18786 || any_QIreg_operand (operands[2], SImode))
18787 && !reg_overlap_mentioned_p (operands[0], operands[1])
18788 && !reg_overlap_mentioned_p (operands[0], operands[2])
18789 && !reg_overlap_mentioned_p (operands[5], operands[1])
18790 && ix86_match_ccmode (peep2_next_insn (4),
18791 (GET_CODE (operands[3]) == PLUS
18792 || GET_CODE (operands[3]) == MINUS)
18793 ? CCGOCmode : CCNOmode)"
18794 [(parallel [(set (match_dup 6) (match_dup 8))
18795 (set (match_dup 1) (match_dup 7))])]
18797 operands[6] = SET_DEST (PATTERN (peep2_next_insn (4)));
18799 = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
18800 copy_rtx (operands[1]),
18801 gen_lowpart (<MODE>mode, operands[2]));
18803 = gen_rtx_COMPARE (GET_MODE (operands[6]),
18804 copy_rtx (operands[7]),
18808 ;; Likewise for cmpelim optimized pattern.
18810 [(set (match_operand:SWI 0 "register_operand")
18811 (match_operand:SWI 1 "memory_operand"))
18812 (parallel [(set (reg FLAGS_REG)
18813 (compare (match_operator:SWI 3 "plusminuslogic_operator"
18815 (match_operand:SWI 2 "<nonmemory_operand>")])
18817 (set (match_dup 0) (match_dup 3))])
18818 (set (match_operand:SWI 4 "register_operand") (match_dup 0))
18819 (set (match_dup 1) (match_dup 4))]
18820 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
18821 && peep2_reg_dead_p (3, operands[0])
18822 && peep2_reg_dead_p (4, operands[4])
18823 && !reg_overlap_mentioned_p (operands[0], operands[1])
18824 && !reg_overlap_mentioned_p (operands[0], operands[2])
18825 && !reg_overlap_mentioned_p (operands[4], operands[1])
18826 && ix86_match_ccmode (peep2_next_insn (1),
18827 (GET_CODE (operands[3]) == PLUS
18828 || GET_CODE (operands[3]) == MINUS)
18829 ? CCGOCmode : CCNOmode)"
18830 [(parallel [(set (match_dup 5) (match_dup 7))
18831 (set (match_dup 1) (match_dup 6))])]
18833 operands[5] = SET_DEST (XVECEXP (PATTERN (peep2_next_insn (1)), 0, 0));
18835 = gen_rtx_fmt_ee (GET_CODE (operands[3]), GET_MODE (operands[3]),
18836 copy_rtx (operands[1]), operands[2]);
18838 = gen_rtx_COMPARE (GET_MODE (operands[5]), copy_rtx (operands[6]),
18842 ;; Special cases for xor, where (x ^= y) != 0 is (misoptimized)
18843 ;; into x = z; x ^= y; x != z
18845 [(set (match_operand:SWI 0 "register_operand")
18846 (match_operand:SWI 1 "memory_operand"))
18847 (set (match_operand:SWI 3 "register_operand") (match_dup 0))
18848 (parallel [(set (match_operand:SWI 4 "register_operand")
18849 (xor:SWI (match_dup 4)
18850 (match_operand:SWI 2 "<nonmemory_operand>")))
18851 (clobber (reg:CC FLAGS_REG))])
18852 (set (match_dup 1) (match_dup 4))
18853 (set (reg:CCZ FLAGS_REG)
18854 (compare:CCZ (match_operand:SWI 5 "register_operand")
18855 (match_operand:SWI 6 "<nonmemory_operand>")))]
18856 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
18857 && (REGNO (operands[4]) == REGNO (operands[0])
18858 || REGNO (operands[4]) == REGNO (operands[3]))
18859 && (rtx_equal_p (operands[REGNO (operands[4]) == REGNO (operands[0])
18860 ? 3 : 0], operands[5])
18861 ? rtx_equal_p (operands[2], operands[6])
18862 : rtx_equal_p (operands[2], operands[5])
18863 && rtx_equal_p (operands[REGNO (operands[4]) == REGNO (operands[0])
18864 ? 3 : 0], operands[6]))
18865 && peep2_reg_dead_p (4, operands[4])
18866 && peep2_reg_dead_p (5, operands[REGNO (operands[4]) == REGNO (operands[0])
18868 && !reg_overlap_mentioned_p (operands[0], operands[1])
18869 && !reg_overlap_mentioned_p (operands[0], operands[2])
18870 && !reg_overlap_mentioned_p (operands[3], operands[0])
18871 && !reg_overlap_mentioned_p (operands[3], operands[1])
18872 && !reg_overlap_mentioned_p (operands[3], operands[2])
18873 && (<MODE>mode != QImode
18874 || immediate_operand (operands[2], QImode)
18875 || any_QIreg_operand (operands[2], QImode))"
18876 [(parallel [(set (match_dup 7) (match_dup 9))
18877 (set (match_dup 1) (match_dup 8))])]
18879 operands[7] = SET_DEST (PATTERN (peep2_next_insn (4)));
18880 operands[8] = gen_rtx_XOR (<MODE>mode, copy_rtx (operands[1]),
18883 = gen_rtx_COMPARE (GET_MODE (operands[7]),
18884 copy_rtx (operands[8]),
18889 [(set (match_operand:SWI12 0 "register_operand")
18890 (match_operand:SWI12 1 "memory_operand"))
18891 (set (match_operand:SWI12 3 "register_operand") (match_dup 0))
18892 (parallel [(set (match_operand:SI 4 "register_operand")
18893 (xor:SI (match_dup 4)
18894 (match_operand:SI 2 "<nonmemory_operand>")))
18895 (clobber (reg:CC FLAGS_REG))])
18896 (set (match_dup 1) (match_operand:SWI12 5 "register_operand"))
18897 (set (reg:CCZ FLAGS_REG)
18898 (compare:CCZ (match_operand:SWI12 6 "register_operand")
18899 (match_operand:SWI12 7 "<nonmemory_operand>")))]
18900 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
18901 && (REGNO (operands[5]) == REGNO (operands[0])
18902 || REGNO (operands[5]) == REGNO (operands[3]))
18903 && REGNO (operands[5]) == REGNO (operands[4])
18904 && (rtx_equal_p (operands[REGNO (operands[5]) == REGNO (operands[0])
18905 ? 3 : 0], operands[6])
18906 ? (REG_P (operands[2])
18907 ? REG_P (operands[7]) && REGNO (operands[2]) == REGNO (operands[7])
18908 : rtx_equal_p (operands[2], operands[7]))
18909 : (rtx_equal_p (operands[REGNO (operands[5]) == REGNO (operands[0])
18910 ? 3 : 0], operands[7])
18911 && REG_P (operands[2])
18912 && REGNO (operands[2]) == REGNO (operands[6])))
18913 && peep2_reg_dead_p (4, operands[5])
18914 && peep2_reg_dead_p (5, operands[REGNO (operands[5]) == REGNO (operands[0])
18916 && !reg_overlap_mentioned_p (operands[0], operands[1])
18917 && !reg_overlap_mentioned_p (operands[0], operands[2])
18918 && !reg_overlap_mentioned_p (operands[3], operands[0])
18919 && !reg_overlap_mentioned_p (operands[3], operands[1])
18920 && !reg_overlap_mentioned_p (operands[3], operands[2])
18921 && (<MODE>mode != QImode
18922 || immediate_operand (operands[2], SImode)
18923 || any_QIreg_operand (operands[2], SImode))"
18924 [(parallel [(set (match_dup 8) (match_dup 10))
18925 (set (match_dup 1) (match_dup 9))])]
18927 operands[8] = SET_DEST (PATTERN (peep2_next_insn (4)));
18928 operands[9] = gen_rtx_XOR (<MODE>mode, copy_rtx (operands[1]),
18929 gen_lowpart (<MODE>mode, operands[2]));
18931 = gen_rtx_COMPARE (GET_MODE (operands[8]),
18932 copy_rtx (operands[9]),
18936 ;; Attempt to optimize away memory stores of values the memory already
18937 ;; has. See PR79593.
18939 [(set (match_operand 0 "register_operand")
18940 (match_operand 1 "memory_operand"))
18941 (set (match_operand 2 "memory_operand") (match_dup 0))]
18942 "!MEM_VOLATILE_P (operands[1])
18943 && !MEM_VOLATILE_P (operands[2])
18944 && rtx_equal_p (operands[1], operands[2])
18945 && !reg_overlap_mentioned_p (operands[0], operands[2])"
18946 [(set (match_dup 0) (match_dup 1))])
18948 ;; Attempt to always use XOR for zeroing registers (including FP modes).
18950 [(set (match_operand 0 "general_reg_operand")
18951 (match_operand 1 "const0_operand"))]
18952 "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
18953 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
18954 && peep2_regno_dead_p (0, FLAGS_REG)"
18955 [(parallel [(set (match_dup 0) (const_int 0))
18956 (clobber (reg:CC FLAGS_REG))])]
18957 "operands[0] = gen_lowpart (word_mode, operands[0]);")
18960 [(set (strict_low_part (match_operand:SWI12 0 "general_reg_operand"))
18962 "(! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
18963 && peep2_regno_dead_p (0, FLAGS_REG)"
18964 [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
18965 (clobber (reg:CC FLAGS_REG))])])
18967 ;; For HI, SI and DI modes, or $-1,reg is smaller than mov $-1,reg.
18969 [(set (match_operand:SWI248 0 "general_reg_operand")
18971 "(TARGET_MOVE_M1_VIA_OR || optimize_insn_for_size_p ())
18972 && peep2_regno_dead_p (0, FLAGS_REG)"
18973 [(parallel [(set (match_dup 0) (const_int -1))
18974 (clobber (reg:CC FLAGS_REG))])]
18976 if (<MODE_SIZE> < GET_MODE_SIZE (SImode))
18977 operands[0] = gen_lowpart (SImode, operands[0]);
18980 ;; Attempt to convert simple lea to add/shift.
18981 ;; These can be created by move expanders.
18982 ;; Disable PLUS peepholes on TARGET_OPT_AGU, since all
18983 ;; relevant lea instructions were already split.
18986 [(set (match_operand:SWI48 0 "register_operand")
18987 (plus:SWI48 (match_dup 0)
18988 (match_operand:SWI48 1 "<nonmemory_operand>")))]
18990 && peep2_regno_dead_p (0, FLAGS_REG)"
18991 [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1)))
18992 (clobber (reg:CC FLAGS_REG))])])
18995 [(set (match_operand:SWI48 0 "register_operand")
18996 (plus:SWI48 (match_operand:SWI48 1 "<nonmemory_operand>")
18999 && peep2_regno_dead_p (0, FLAGS_REG)"
19000 [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1)))
19001 (clobber (reg:CC FLAGS_REG))])])
19004 [(set (match_operand:DI 0 "register_operand")
19006 (plus:SI (match_operand:SI 1 "register_operand")
19007 (match_operand:SI 2 "nonmemory_operand"))))]
19008 "TARGET_64BIT && !TARGET_OPT_AGU
19009 && REGNO (operands[0]) == REGNO (operands[1])
19010 && peep2_regno_dead_p (0, FLAGS_REG)"
19011 [(parallel [(set (match_dup 0)
19012 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))
19013 (clobber (reg:CC FLAGS_REG))])])
19016 [(set (match_operand:DI 0 "register_operand")
19018 (plus:SI (match_operand:SI 1 "nonmemory_operand")
19019 (match_operand:SI 2 "register_operand"))))]
19020 "TARGET_64BIT && !TARGET_OPT_AGU
19021 && REGNO (operands[0]) == REGNO (operands[2])
19022 && peep2_regno_dead_p (0, FLAGS_REG)"
19023 [(parallel [(set (match_dup 0)
19024 (zero_extend:DI (plus:SI (match_dup 2) (match_dup 1))))
19025 (clobber (reg:CC FLAGS_REG))])])
19028 [(set (match_operand:SWI48 0 "register_operand")
19029 (mult:SWI48 (match_dup 0)
19030 (match_operand:SWI48 1 "const_int_operand")))]
19031 "pow2p_hwi (INTVAL (operands[1]))
19032 && peep2_regno_dead_p (0, FLAGS_REG)"
19033 [(parallel [(set (match_dup 0) (ashift:SWI48 (match_dup 0) (match_dup 1)))
19034 (clobber (reg:CC FLAGS_REG))])]
19035 "operands[1] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
19038 [(set (match_operand:DI 0 "register_operand")
19040 (mult:SI (match_operand:SI 1 "register_operand")
19041 (match_operand:SI 2 "const_int_operand"))))]
19043 && pow2p_hwi (INTVAL (operands[2]))
19044 && REGNO (operands[0]) == REGNO (operands[1])
19045 && peep2_regno_dead_p (0, FLAGS_REG)"
19046 [(parallel [(set (match_dup 0)
19047 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))
19048 (clobber (reg:CC FLAGS_REG))])]
19049 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
19051 ;; The ESP adjustments can be done by the push and pop instructions. Resulting
19052 ;; code is shorter, since push is only 1 byte, while add imm, %esp is 3 bytes.
19053 ;; On many CPUs it is also faster, since special hardware to avoid esp
19054 ;; dependencies is present.
19056 ;; While some of these conversions may be done using splitters, we use
19057 ;; peepholes in order to allow combine_stack_adjustments pass to see
19058 ;; nonobfuscated RTL.
19060 ;; Convert prologue esp subtractions to push.
19061 ;; We need register to push. In order to keep verify_flow_info happy we have
19063 ;; - use scratch and clobber it in order to avoid dependencies
19064 ;; - use already live register
19065 ;; We can't use the second way right now, since there is no reliable way how to
19066 ;; verify that given register is live. First choice will also most likely in
19067 ;; fewer dependencies. On the place of esp adjustments it is very likely that
19068 ;; call clobbered registers are dead. We may want to use base pointer as an
19069 ;; alternative when no register is available later.
19072 [(match_scratch:W 1 "r")
19073 (parallel [(set (reg:P SP_REG)
19074 (plus:P (reg:P SP_REG)
19075 (match_operand:P 0 "const_int_operand")))
19076 (clobber (reg:CC FLAGS_REG))
19077 (clobber (mem:BLK (scratch)))])]
19078 "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
19079 && INTVAL (operands[0]) == -GET_MODE_SIZE (word_mode)
19080 && ix86_red_zone_size == 0"
19081 [(clobber (match_dup 1))
19082 (parallel [(set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
19083 (clobber (mem:BLK (scratch)))])])
19086 [(match_scratch:W 1 "r")
19087 (parallel [(set (reg:P SP_REG)
19088 (plus:P (reg:P SP_REG)
19089 (match_operand:P 0 "const_int_operand")))
19090 (clobber (reg:CC FLAGS_REG))
19091 (clobber (mem:BLK (scratch)))])]
19092 "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
19093 && INTVAL (operands[0]) == -2*GET_MODE_SIZE (word_mode)
19094 && ix86_red_zone_size == 0"
19095 [(clobber (match_dup 1))
19096 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
19097 (parallel [(set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
19098 (clobber (mem:BLK (scratch)))])])
19100 ;; Convert esp subtractions to push.
19102 [(match_scratch:W 1 "r")
19103 (parallel [(set (reg:P SP_REG)
19104 (plus:P (reg:P SP_REG)
19105 (match_operand:P 0 "const_int_operand")))
19106 (clobber (reg:CC FLAGS_REG))])]
19107 "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
19108 && INTVAL (operands[0]) == -GET_MODE_SIZE (word_mode)
19109 && ix86_red_zone_size == 0"
19110 [(clobber (match_dup 1))
19111 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
19114 [(match_scratch:W 1 "r")
19115 (parallel [(set (reg:P SP_REG)
19116 (plus:P (reg:P SP_REG)
19117 (match_operand:P 0 "const_int_operand")))
19118 (clobber (reg:CC FLAGS_REG))])]
19119 "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
19120 && INTVAL (operands[0]) == -2*GET_MODE_SIZE (word_mode)
19121 && ix86_red_zone_size == 0"
19122 [(clobber (match_dup 1))
19123 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
19124 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
19126 ;; Convert epilogue deallocator to pop.
19128 [(match_scratch:W 1 "r")
19129 (parallel [(set (reg:P SP_REG)
19130 (plus:P (reg:P SP_REG)
19131 (match_operand:P 0 "const_int_operand")))
19132 (clobber (reg:CC FLAGS_REG))
19133 (clobber (mem:BLK (scratch)))])]
19134 "(TARGET_SINGLE_POP || optimize_insn_for_size_p ())
19135 && INTVAL (operands[0]) == GET_MODE_SIZE (word_mode)"
19136 [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
19137 (clobber (mem:BLK (scratch)))])])
19139 ;; Two pops case is tricky, since pop causes dependency
19140 ;; on destination register. We use two registers if available.
19142 [(match_scratch:W 1 "r")
19143 (match_scratch:W 2 "r")
19144 (parallel [(set (reg:P SP_REG)
19145 (plus:P (reg:P SP_REG)
19146 (match_operand:P 0 "const_int_operand")))
19147 (clobber (reg:CC FLAGS_REG))
19148 (clobber (mem:BLK (scratch)))])]
19149 "(TARGET_DOUBLE_POP || optimize_insn_for_size_p ())
19150 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
19151 [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
19152 (clobber (mem:BLK (scratch)))])
19153 (set (match_dup 2) (mem:W (post_inc:P (reg:P SP_REG))))])
19156 [(match_scratch:W 1 "r")
19157 (parallel [(set (reg:P SP_REG)
19158 (plus:P (reg:P SP_REG)
19159 (match_operand:P 0 "const_int_operand")))
19160 (clobber (reg:CC FLAGS_REG))
19161 (clobber (mem:BLK (scratch)))])]
19162 "optimize_insn_for_size_p ()
19163 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
19164 [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
19165 (clobber (mem:BLK (scratch)))])
19166 (set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
19168 ;; Convert esp additions to pop.
19170 [(match_scratch:W 1 "r")
19171 (parallel [(set (reg:P SP_REG)
19172 (plus:P (reg:P SP_REG)
19173 (match_operand:P 0 "const_int_operand")))
19174 (clobber (reg:CC FLAGS_REG))])]
19175 "INTVAL (operands[0]) == GET_MODE_SIZE (word_mode)"
19176 [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
19178 ;; Two pops case is tricky, since pop causes dependency
19179 ;; on destination register. We use two registers if available.
19181 [(match_scratch:W 1 "r")
19182 (match_scratch:W 2 "r")
19183 (parallel [(set (reg:P SP_REG)
19184 (plus:P (reg:P SP_REG)
19185 (match_operand:P 0 "const_int_operand")))
19186 (clobber (reg:CC FLAGS_REG))])]
19187 "INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
19188 [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
19189 (set (match_dup 2) (mem:W (post_inc:P (reg:P SP_REG))))])
19192 [(match_scratch:W 1 "r")
19193 (parallel [(set (reg:P SP_REG)
19194 (plus:P (reg:P SP_REG)
19195 (match_operand:P 0 "const_int_operand")))
19196 (clobber (reg:CC FLAGS_REG))])]
19197 "optimize_insn_for_size_p ()
19198 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
19199 [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
19200 (set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
19202 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
19203 ;; required and register dies. Similarly for 128 to -128.
19205 [(set (match_operand 0 "flags_reg_operand")
19206 (match_operator 1 "compare_operator"
19207 [(match_operand 2 "register_operand")
19208 (match_operand 3 "const_int_operand")]))]
19209 "(((!TARGET_FUSE_CMP_AND_BRANCH || optimize_insn_for_size_p ())
19210 && incdec_operand (operands[3], GET_MODE (operands[3])))
19211 || (!TARGET_FUSE_CMP_AND_BRANCH
19212 && INTVAL (operands[3]) == 128))
19213 && ix86_match_ccmode (insn, CCGCmode)
19214 && peep2_reg_dead_p (1, operands[2])"
19215 [(parallel [(set (match_dup 0)
19216 (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
19217 (clobber (match_dup 2))])])
19219 ;; Convert imul by three, five and nine into lea
19222 [(set (match_operand:SWI48 0 "register_operand")
19223 (mult:SWI48 (match_operand:SWI48 1 "register_operand")
19224 (match_operand:SWI48 2 "const359_operand")))
19225 (clobber (reg:CC FLAGS_REG))])]
19226 "!TARGET_PARTIAL_REG_STALL
19227 || <MODE>mode == SImode
19228 || optimize_function_for_size_p (cfun)"
19229 [(set (match_dup 0)
19230 (plus:SWI48 (mult:SWI48 (match_dup 1) (match_dup 2))
19232 "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
19236 [(set (match_operand:SWI48 0 "register_operand")
19237 (mult:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
19238 (match_operand:SWI48 2 "const359_operand")))
19239 (clobber (reg:CC FLAGS_REG))])]
19240 "optimize_insn_for_speed_p ()
19241 && (!TARGET_PARTIAL_REG_STALL || <MODE>mode == SImode)"
19242 [(set (match_dup 0) (match_dup 1))
19244 (plus:SWI48 (mult:SWI48 (match_dup 0) (match_dup 2))
19246 "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
19248 ;; imul $32bit_imm, mem, reg is vector decoded, while
19249 ;; imul $32bit_imm, reg, reg is direct decoded.
19251 [(match_scratch:SWI48 3 "r")
19252 (parallel [(set (match_operand:SWI48 0 "register_operand")
19253 (mult:SWI48 (match_operand:SWI48 1 "memory_operand")
19254 (match_operand:SWI48 2 "immediate_operand")))
19255 (clobber (reg:CC FLAGS_REG))])]
19256 "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
19257 && !satisfies_constraint_K (operands[2])"
19258 [(set (match_dup 3) (match_dup 1))
19259 (parallel [(set (match_dup 0) (mult:SWI48 (match_dup 3) (match_dup 2)))
19260 (clobber (reg:CC FLAGS_REG))])])
19263 [(match_scratch:SI 3 "r")
19264 (parallel [(set (match_operand:DI 0 "register_operand")
19266 (mult:SI (match_operand:SI 1 "memory_operand")
19267 (match_operand:SI 2 "immediate_operand"))))
19268 (clobber (reg:CC FLAGS_REG))])]
19270 && TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
19271 && !satisfies_constraint_K (operands[2])"
19272 [(set (match_dup 3) (match_dup 1))
19273 (parallel [(set (match_dup 0)
19274 (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
19275 (clobber (reg:CC FLAGS_REG))])])
19277 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
19278 ;; Convert it into imul reg, reg
19279 ;; It would be better to force assembler to encode instruction using long
19280 ;; immediate, but there is apparently no way to do so.
19282 [(parallel [(set (match_operand:SWI248 0 "register_operand")
19284 (match_operand:SWI248 1 "nonimmediate_operand")
19285 (match_operand:SWI248 2 "const_int_operand")))
19286 (clobber (reg:CC FLAGS_REG))])
19287 (match_scratch:SWI248 3 "r")]
19288 "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
19289 && satisfies_constraint_K (operands[2])"
19290 [(set (match_dup 3) (match_dup 2))
19291 (parallel [(set (match_dup 0) (mult:SWI248 (match_dup 0) (match_dup 3)))
19292 (clobber (reg:CC FLAGS_REG))])]
19294 if (!rtx_equal_p (operands[0], operands[1]))
19295 emit_move_insn (operands[0], operands[1]);
19298 ;; After splitting up read-modify operations, array accesses with memory
19299 ;; operands might end up in form:
19301 ;; movl 4(%esp), %edx
19303 ;; instead of pre-splitting:
19305 ;; addl 4(%esp), %eax
19307 ;; movl 4(%esp), %edx
19308 ;; leal (%edx,%eax,4), %eax
19311 [(match_scratch:W 5 "r")
19312 (parallel [(set (match_operand 0 "register_operand")
19313 (ashift (match_operand 1 "register_operand")
19314 (match_operand 2 "const_int_operand")))
19315 (clobber (reg:CC FLAGS_REG))])
19316 (parallel [(set (match_operand 3 "register_operand")
19317 (plus (match_dup 0)
19318 (match_operand 4 "x86_64_general_operand")))
19319 (clobber (reg:CC FLAGS_REG))])]
19320 "IN_RANGE (INTVAL (operands[2]), 1, 3)
19321 /* Validate MODE for lea. */
19322 && ((!TARGET_PARTIAL_REG_STALL
19323 && (GET_MODE (operands[0]) == QImode
19324 || GET_MODE (operands[0]) == HImode))
19325 || GET_MODE (operands[0]) == SImode
19326 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
19327 && (rtx_equal_p (operands[0], operands[3])
19328 || peep2_reg_dead_p (2, operands[0]))
19329 /* We reorder load and the shift. */
19330 && !reg_overlap_mentioned_p (operands[0], operands[4])"
19331 [(set (match_dup 5) (match_dup 4))
19332 (set (match_dup 0) (match_dup 1))]
19334 machine_mode op1mode = GET_MODE (operands[1]);
19335 machine_mode mode = op1mode == DImode ? DImode : SImode;
19336 int scale = 1 << INTVAL (operands[2]);
19337 rtx index = gen_lowpart (word_mode, operands[1]);
19338 rtx base = gen_lowpart (word_mode, operands[5]);
19339 rtx dest = gen_lowpart (mode, operands[3]);
19341 operands[1] = gen_rtx_PLUS (word_mode, base,
19342 gen_rtx_MULT (word_mode, index, GEN_INT (scale)));
19343 if (mode != word_mode)
19344 operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
19346 operands[5] = base;
19347 if (op1mode != word_mode)
19348 operands[5] = gen_lowpart (op1mode, operands[5]);
19350 operands[0] = dest;
19353 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
19354 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
19355 ;; caught for use by garbage collectors and the like. Using an insn that
19356 ;; maps to SIGILL makes it more likely the program will rightfully die.
19357 ;; Keeping with tradition, "6" is in honor of #UD.
19358 (define_insn "trap"
19359 [(trap_if (const_int 1) (const_int 6))]
19362 #ifdef HAVE_AS_IX86_UD2
19365 return ASM_SHORT "0x0b0f";
19368 [(set_attr "length" "2")])
19371 [(unspec_volatile [(const_int 0)] UNSPECV_UD2)]
19374 #ifdef HAVE_AS_IX86_UD2
19377 return ASM_SHORT "0x0b0f";
19380 [(set_attr "length" "2")])
19382 (define_expand "prefetch"
19383 [(prefetch (match_operand 0 "address_operand")
19384 (match_operand:SI 1 "const_int_operand")
19385 (match_operand:SI 2 "const_int_operand"))]
19386 "TARGET_3DNOW || TARGET_PREFETCH_SSE || TARGET_PRFCHW || TARGET_PREFETCHWT1"
19388 bool write = INTVAL (operands[1]) != 0;
19389 int locality = INTVAL (operands[2]);
19391 gcc_assert (IN_RANGE (locality, 0, 3));
19393 /* Use 3dNOW prefetch in case we are asking for write prefetch not
19394 supported by SSE counterpart (non-SSE2 athlon machines) or the
19395 SSE prefetch is not available (K6 machines). Otherwise use SSE
19396 prefetch as it allows specifying of locality. */
19400 if (TARGET_PREFETCHWT1)
19401 operands[2] = GEN_INT (MAX (locality, 2));
19402 else if (TARGET_PRFCHW)
19403 operands[2] = GEN_INT (3);
19404 else if (TARGET_3DNOW && !TARGET_SSE2)
19405 operands[2] = GEN_INT (3);
19406 else if (TARGET_PREFETCH_SSE)
19407 operands[1] = const0_rtx;
19410 gcc_assert (TARGET_3DNOW);
19411 operands[2] = GEN_INT (3);
19416 if (TARGET_PREFETCH_SSE)
19420 gcc_assert (TARGET_3DNOW);
19421 operands[2] = GEN_INT (3);
19426 (define_insn "*prefetch_sse"
19427 [(prefetch (match_operand 0 "address_operand" "p")
19429 (match_operand:SI 1 "const_int_operand"))]
19430 "TARGET_PREFETCH_SSE"
19432 static const char * const patterns[4] = {
19433 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
19436 int locality = INTVAL (operands[1]);
19437 gcc_assert (IN_RANGE (locality, 0, 3));
19439 return patterns[locality];
19441 [(set_attr "type" "sse")
19442 (set_attr "atom_sse_attr" "prefetch")
19443 (set (attr "length_address")
19444 (symbol_ref "memory_address_length (operands[0], false)"))
19445 (set_attr "memory" "none")])
19447 (define_insn "*prefetch_3dnow"
19448 [(prefetch (match_operand 0 "address_operand" "p")
19449 (match_operand:SI 1 "const_int_operand" "n")
19451 "TARGET_3DNOW || TARGET_PRFCHW || TARGET_PREFETCHWT1"
19453 if (INTVAL (operands[1]) == 0)
19454 return "prefetch\t%a0";
19456 return "prefetchw\t%a0";
19458 [(set_attr "type" "mmx")
19459 (set (attr "length_address")
19460 (symbol_ref "memory_address_length (operands[0], false)"))
19461 (set_attr "memory" "none")])
19463 (define_insn "*prefetch_prefetchwt1"
19464 [(prefetch (match_operand 0 "address_operand" "p")
19467 "TARGET_PREFETCHWT1"
19468 "prefetchwt1\t%a0";
19469 [(set_attr "type" "sse")
19470 (set (attr "length_address")
19471 (symbol_ref "memory_address_length (operands[0], false)"))
19472 (set_attr "memory" "none")])
19474 (define_expand "stack_protect_set"
19475 [(match_operand 0 "memory_operand")
19476 (match_operand 1 "memory_operand")]
19479 emit_insn (gen_stack_protect_set_1
19480 (ptr_mode, operands[0], operands[1]));
19484 (define_insn "@stack_protect_set_1_<mode>"
19485 [(set (match_operand:PTR 0 "memory_operand" "=m")
19486 (unspec:PTR [(match_operand:PTR 1 "memory_operand" "m")]
19488 (set (match_scratch:PTR 2 "=&r") (const_int 0))
19489 (clobber (reg:CC FLAGS_REG))]
19491 "mov{<imodesuffix>}\t{%1, %2|%2, %1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
19492 [(set_attr "type" "multi")])
19494 (define_expand "stack_protect_test"
19495 [(match_operand 0 "memory_operand")
19496 (match_operand 1 "memory_operand")
19500 rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
19502 emit_insn (gen_stack_protect_test_1
19503 (ptr_mode, flags, operands[0], operands[1]));
19505 emit_jump_insn (gen_cbranchcc4 (gen_rtx_EQ (VOIDmode, flags, const0_rtx),
19506 flags, const0_rtx, operands[2]));
19510 (define_insn "@stack_protect_test_1_<mode>"
19511 [(set (match_operand:CCZ 0 "flags_reg_operand")
19512 (unspec:CCZ [(match_operand:PTR 1 "memory_operand" "m")
19513 (match_operand:PTR 2 "memory_operand" "m")]
19515 (clobber (match_scratch:PTR 3 "=&r"))]
19517 "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;sub{<imodesuffix>}\t{%2, %3|%3, %2}"
19518 [(set_attr "type" "multi")])
19520 (define_insn "sse4_2_crc32<mode>"
19521 [(set (match_operand:SI 0 "register_operand" "=r")
19523 [(match_operand:SI 1 "register_operand" "0")
19524 (match_operand:SWI124 2 "nonimmediate_operand" "<r>m")]
19526 "TARGET_SSE4_2 || TARGET_CRC32"
19527 "crc32{<imodesuffix>}\t{%2, %0|%0, %2}"
19528 [(set_attr "type" "sselog1")
19529 (set_attr "prefix_rep" "1")
19530 (set_attr "prefix_extra" "1")
19531 (set (attr "prefix_data16")
19532 (if_then_else (match_operand:HI 2)
19534 (const_string "*")))
19535 (set (attr "prefix_rex")
19536 (if_then_else (match_operand:QI 2 "ext_QIreg_operand")
19538 (const_string "*")))
19539 (set_attr "mode" "SI")])
19541 (define_insn "sse4_2_crc32di"
19542 [(set (match_operand:DI 0 "register_operand" "=r")
19544 [(match_operand:DI 1 "register_operand" "0")
19545 (match_operand:DI 2 "nonimmediate_operand" "rm")]
19547 "TARGET_64BIT && (TARGET_SSE4_2 || TARGET_CRC32)"
19548 "crc32{q}\t{%2, %0|%0, %2}"
19549 [(set_attr "type" "sselog1")
19550 (set_attr "prefix_rep" "1")
19551 (set_attr "prefix_extra" "1")
19552 (set_attr "mode" "DI")])
19554 (define_insn "rdpmc"
19555 [(set (match_operand:DI 0 "register_operand" "=A")
19556 (unspec_volatile:DI [(match_operand:SI 1 "register_operand" "c")]
19560 [(set_attr "type" "other")
19561 (set_attr "length" "2")])
19563 (define_insn "rdpmc_rex64"
19564 [(set (match_operand:DI 0 "register_operand" "=a")
19565 (unspec_volatile:DI [(match_operand:SI 2 "register_operand" "c")]
19567 (set (match_operand:DI 1 "register_operand" "=d")
19568 (unspec_volatile:DI [(match_dup 2)] UNSPECV_RDPMC))]
19571 [(set_attr "type" "other")
19572 (set_attr "length" "2")])
19574 (define_insn "rdtsc"
19575 [(set (match_operand:DI 0 "register_operand" "=A")
19576 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
19579 [(set_attr "type" "other")
19580 (set_attr "length" "2")])
19582 (define_insn "rdtsc_rex64"
19583 [(set (match_operand:DI 0 "register_operand" "=a")
19584 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))
19585 (set (match_operand:DI 1 "register_operand" "=d")
19586 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
19589 [(set_attr "type" "other")
19590 (set_attr "length" "2")])
19592 (define_insn "rdtscp"
19593 [(set (match_operand:DI 0 "register_operand" "=A")
19594 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
19595 (set (match_operand:SI 1 "register_operand" "=c")
19596 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
19599 [(set_attr "type" "other")
19600 (set_attr "length" "3")])
19602 (define_insn "rdtscp_rex64"
19603 [(set (match_operand:DI 0 "register_operand" "=a")
19604 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
19605 (set (match_operand:DI 1 "register_operand" "=d")
19606 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
19607 (set (match_operand:SI 2 "register_operand" "=c")
19608 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
19611 [(set_attr "type" "other")
19612 (set_attr "length" "3")])
19614 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
19616 ;; FXSR, XSAVE and XSAVEOPT instructions
19618 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
19620 (define_insn "fxsave"
19621 [(set (match_operand:BLK 0 "memory_operand" "=m")
19622 (unspec_volatile:BLK [(const_int 0)] UNSPECV_FXSAVE))]
19625 [(set_attr "type" "other")
19626 (set_attr "memory" "store")
19627 (set (attr "length")
19628 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
19630 (define_insn "fxsave64"
19631 [(set (match_operand:BLK 0 "memory_operand" "=m")
19632 (unspec_volatile:BLK [(const_int 0)] UNSPECV_FXSAVE64))]
19633 "TARGET_64BIT && TARGET_FXSR"
19635 [(set_attr "type" "other")
19636 (set_attr "memory" "store")
19637 (set (attr "length")
19638 (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
19640 (define_insn "fxrstor"
19641 [(unspec_volatile [(match_operand:BLK 0 "memory_operand" "m")]
19645 [(set_attr "type" "other")
19646 (set_attr "memory" "load")
19647 (set (attr "length")
19648 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
19650 (define_insn "fxrstor64"
19651 [(unspec_volatile [(match_operand:BLK 0 "memory_operand" "m")]
19652 UNSPECV_FXRSTOR64)]
19653 "TARGET_64BIT && TARGET_FXSR"
19655 [(set_attr "type" "other")
19656 (set_attr "memory" "load")
19657 (set (attr "length")
19658 (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
19660 (define_int_iterator ANY_XSAVE
19662 (UNSPECV_XSAVEOPT "TARGET_XSAVEOPT")
19663 (UNSPECV_XSAVEC "TARGET_XSAVEC")
19664 (UNSPECV_XSAVES "TARGET_XSAVES")])
19666 (define_int_iterator ANY_XSAVE64
19668 (UNSPECV_XSAVEOPT64 "TARGET_XSAVEOPT")
19669 (UNSPECV_XSAVEC64 "TARGET_XSAVEC")
19670 (UNSPECV_XSAVES64 "TARGET_XSAVES")])
19672 (define_int_attr xsave
19673 [(UNSPECV_XSAVE "xsave")
19674 (UNSPECV_XSAVE64 "xsave64")
19675 (UNSPECV_XSAVEOPT "xsaveopt")
19676 (UNSPECV_XSAVEOPT64 "xsaveopt64")
19677 (UNSPECV_XSAVEC "xsavec")
19678 (UNSPECV_XSAVEC64 "xsavec64")
19679 (UNSPECV_XSAVES "xsaves")
19680 (UNSPECV_XSAVES64 "xsaves64")])
19682 (define_int_iterator ANY_XRSTOR
19684 (UNSPECV_XRSTORS "TARGET_XSAVES")])
19686 (define_int_iterator ANY_XRSTOR64
19688 (UNSPECV_XRSTORS64 "TARGET_XSAVES")])
19690 (define_int_attr xrstor
19691 [(UNSPECV_XRSTOR "xrstor")
19692 (UNSPECV_XRSTOR64 "xrstor")
19693 (UNSPECV_XRSTORS "xrstors")
19694 (UNSPECV_XRSTORS64 "xrstors")])
19696 (define_insn "<xsave>"
19697 [(set (match_operand:BLK 0 "memory_operand" "=m")
19698 (unspec_volatile:BLK
19699 [(match_operand:DI 1 "register_operand" "A")]
19701 "!TARGET_64BIT && TARGET_XSAVE"
19703 [(set_attr "type" "other")
19704 (set_attr "memory" "store")
19705 (set (attr "length")
19706 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
19708 (define_insn "<xsave>_rex64"
19709 [(set (match_operand:BLK 0 "memory_operand" "=m")
19710 (unspec_volatile:BLK
19711 [(match_operand:SI 1 "register_operand" "a")
19712 (match_operand:SI 2 "register_operand" "d")]
19714 "TARGET_64BIT && TARGET_XSAVE"
19716 [(set_attr "type" "other")
19717 (set_attr "memory" "store")
19718 (set (attr "length")
19719 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
19721 (define_insn "<xsave>"
19722 [(set (match_operand:BLK 0 "memory_operand" "=m")
19723 (unspec_volatile:BLK
19724 [(match_operand:SI 1 "register_operand" "a")
19725 (match_operand:SI 2 "register_operand" "d")]
19727 "TARGET_64BIT && TARGET_XSAVE"
19729 [(set_attr "type" "other")
19730 (set_attr "memory" "store")
19731 (set (attr "length")
19732 (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
19734 (define_insn "<xrstor>"
19735 [(unspec_volatile:BLK
19736 [(match_operand:BLK 0 "memory_operand" "m")
19737 (match_operand:DI 1 "register_operand" "A")]
19739 "!TARGET_64BIT && TARGET_XSAVE"
19741 [(set_attr "type" "other")
19742 (set_attr "memory" "load")
19743 (set (attr "length")
19744 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
19746 (define_insn "<xrstor>_rex64"
19747 [(unspec_volatile:BLK
19748 [(match_operand:BLK 0 "memory_operand" "m")
19749 (match_operand:SI 1 "register_operand" "a")
19750 (match_operand:SI 2 "register_operand" "d")]
19752 "TARGET_64BIT && TARGET_XSAVE"
19754 [(set_attr "type" "other")
19755 (set_attr "memory" "load")
19756 (set (attr "length")
19757 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
19759 (define_insn "<xrstor>64"
19760 [(unspec_volatile:BLK
19761 [(match_operand:BLK 0 "memory_operand" "m")
19762 (match_operand:SI 1 "register_operand" "a")
19763 (match_operand:SI 2 "register_operand" "d")]
19765 "TARGET_64BIT && TARGET_XSAVE"
19767 [(set_attr "type" "other")
19768 (set_attr "memory" "load")
19769 (set (attr "length")
19770 (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
19772 (define_insn "xsetbv"
19773 [(unspec_volatile:SI
19774 [(match_operand:SI 0 "register_operand" "c")
19775 (match_operand:DI 1 "register_operand" "A")]
19777 "!TARGET_64BIT && TARGET_XSAVE"
19779 [(set_attr "type" "other")])
19781 (define_insn "xsetbv_rex64"
19782 [(unspec_volatile:SI
19783 [(match_operand:SI 0 "register_operand" "c")
19784 (match_operand:SI 1 "register_operand" "a")
19785 (match_operand:SI 2 "register_operand" "d")]
19787 "TARGET_64BIT && TARGET_XSAVE"
19789 [(set_attr "type" "other")])
19791 (define_insn "xgetbv"
19792 [(set (match_operand:DI 0 "register_operand" "=A")
19793 (unspec_volatile:DI [(match_operand:SI 1 "register_operand" "c")]
19795 "!TARGET_64BIT && TARGET_XSAVE"
19797 [(set_attr "type" "other")])
19799 (define_insn "xgetbv_rex64"
19800 [(set (match_operand:DI 0 "register_operand" "=a")
19801 (unspec_volatile:DI [(match_operand:SI 2 "register_operand" "c")]
19803 (set (match_operand:DI 1 "register_operand" "=d")
19804 (unspec_volatile:DI [(match_dup 2)] UNSPECV_XGETBV))]
19805 "TARGET_64BIT && TARGET_XSAVE"
19807 [(set_attr "type" "other")])
19809 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
19811 ;; Floating-point instructions for atomic compound assignments
19813 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
19815 ; Clobber all floating-point registers on environment save and restore
19816 ; to ensure that the TOS value saved at fnstenv is valid after fldenv.
19817 (define_insn "fnstenv"
19818 [(set (match_operand:BLK 0 "memory_operand" "=m")
19819 (unspec_volatile:BLK [(const_int 0)] UNSPECV_FNSTENV))
19820 (clobber (reg:XF ST0_REG))
19821 (clobber (reg:XF ST1_REG))
19822 (clobber (reg:XF ST2_REG))
19823 (clobber (reg:XF ST3_REG))
19824 (clobber (reg:XF ST4_REG))
19825 (clobber (reg:XF ST5_REG))
19826 (clobber (reg:XF ST6_REG))
19827 (clobber (reg:XF ST7_REG))]
19830 [(set_attr "type" "other")
19831 (set_attr "memory" "store")
19832 (set (attr "length")
19833 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))])
19835 (define_insn "fldenv"
19836 [(unspec_volatile [(match_operand:BLK 0 "memory_operand" "m")]
19838 (clobber (reg:XF ST0_REG))
19839 (clobber (reg:XF ST1_REG))
19840 (clobber (reg:XF ST2_REG))
19841 (clobber (reg:XF ST3_REG))
19842 (clobber (reg:XF ST4_REG))
19843 (clobber (reg:XF ST5_REG))
19844 (clobber (reg:XF ST6_REG))
19845 (clobber (reg:XF ST7_REG))]
19848 [(set_attr "type" "other")
19849 (set_attr "memory" "load")
19850 (set (attr "length")
19851 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))])
19853 (define_insn "fnstsw"
19854 [(set (match_operand:HI 0 "nonimmediate_operand" "=a,m")
19855 (unspec_volatile:HI [(const_int 0)] UNSPECV_FNSTSW))]
19858 [(set_attr "type" "other,other")
19859 (set_attr "memory" "none,store")
19860 (set (attr "length")
19861 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))])
19863 (define_insn "fnclex"
19864 [(unspec_volatile [(const_int 0)] UNSPECV_FNCLEX)]
19867 [(set_attr "type" "other")
19868 (set_attr "memory" "none")
19869 (set_attr "length" "2")])
19871 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
19873 ;; LWP instructions
19875 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
19877 (define_expand "lwp_llwpcb"
19878 [(unspec_volatile [(match_operand 0 "register_operand")]
19879 UNSPECV_LLWP_INTRINSIC)]
19882 (define_insn "*lwp_llwpcb<mode>1"
19883 [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
19884 UNSPECV_LLWP_INTRINSIC)]
19887 [(set_attr "type" "lwp")
19888 (set_attr "mode" "<MODE>")
19889 (set_attr "length" "5")])
19891 (define_expand "lwp_slwpcb"
19892 [(set (match_operand 0 "register_operand")
19893 (unspec_volatile [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
19898 insn = (Pmode == DImode
19900 : gen_lwp_slwpcbsi);
19902 emit_insn (insn (operands[0]));
19906 (define_insn "lwp_slwpcb<mode>"
19907 [(set (match_operand:P 0 "register_operand" "=r")
19908 (unspec_volatile:P [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
19911 [(set_attr "type" "lwp")
19912 (set_attr "mode" "<MODE>")
19913 (set_attr "length" "5")])
19915 (define_expand "lwp_lwpval<mode>3"
19916 [(unspec_volatile [(match_operand:SWI48 1 "register_operand")
19917 (match_operand:SI 2 "nonimmediate_operand")
19918 (match_operand:SI 3 "const_int_operand")]
19919 UNSPECV_LWPVAL_INTRINSIC)]
19921 ;; Avoid unused variable warning.
19922 "(void) operands[0];")
19924 (define_insn "*lwp_lwpval<mode>3_1"
19925 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")
19926 (match_operand:SI 1 "nonimmediate_operand" "rm")
19927 (match_operand:SI 2 "const_int_operand" "i")]
19928 UNSPECV_LWPVAL_INTRINSIC)]
19930 "lwpval\t{%2, %1, %0|%0, %1, %2}"
19931 [(set_attr "type" "lwp")
19932 (set_attr "mode" "<MODE>")
19933 (set (attr "length")
19934 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
19936 (define_expand "lwp_lwpins<mode>3"
19937 [(set (reg:CCC FLAGS_REG)
19938 (unspec_volatile:CCC [(match_operand:SWI48 1 "register_operand")
19939 (match_operand:SI 2 "nonimmediate_operand")
19940 (match_operand:SI 3 "const_int_operand")]
19941 UNSPECV_LWPINS_INTRINSIC))
19942 (set (match_operand:QI 0 "nonimmediate_operand")
19943 (eq:QI (reg:CCC FLAGS_REG) (const_int 0)))]
19946 (define_insn "*lwp_lwpins<mode>3_1"
19947 [(set (reg:CCC FLAGS_REG)
19948 (unspec_volatile:CCC [(match_operand:SWI48 0 "register_operand" "r")
19949 (match_operand:SI 1 "nonimmediate_operand" "rm")
19950 (match_operand:SI 2 "const_int_operand" "i")]
19951 UNSPECV_LWPINS_INTRINSIC))]
19953 "lwpins\t{%2, %1, %0|%0, %1, %2}"
19954 [(set_attr "type" "lwp")
19955 (set_attr "mode" "<MODE>")
19956 (set (attr "length")
19957 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
19959 (define_int_iterator RDFSGSBASE
19963 (define_int_iterator WRFSGSBASE
19967 (define_int_attr fsgs
19968 [(UNSPECV_RDFSBASE "fs")
19969 (UNSPECV_RDGSBASE "gs")
19970 (UNSPECV_WRFSBASE "fs")
19971 (UNSPECV_WRGSBASE "gs")])
19973 (define_insn "rd<fsgs>base<mode>"
19974 [(set (match_operand:SWI48 0 "register_operand" "=r")
19975 (unspec_volatile:SWI48 [(const_int 0)] RDFSGSBASE))]
19976 "TARGET_64BIT && TARGET_FSGSBASE"
19978 [(set_attr "type" "other")
19979 (set_attr "prefix_extra" "2")])
19981 (define_insn "wr<fsgs>base<mode>"
19982 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
19984 "TARGET_64BIT && TARGET_FSGSBASE"
19986 [(set_attr "type" "other")
19987 (set_attr "prefix_extra" "2")])
19989 (define_insn "ptwrite<mode>"
19990 [(unspec_volatile [(match_operand:SWI48 0 "nonimmediate_operand" "rm")]
19994 [(set_attr "type" "other")
19995 (set_attr "prefix_extra" "2")])
19997 (define_insn "rdrand<mode>_1"
19998 [(set (match_operand:SWI248 0 "register_operand" "=r")
19999 (unspec_volatile:SWI248 [(const_int 0)] UNSPECV_RDRAND))
20000 (set (reg:CCC FLAGS_REG)
20001 (unspec_volatile:CCC [(const_int 0)] UNSPECV_RDRAND))]
20004 [(set_attr "type" "other")
20005 (set_attr "prefix_extra" "1")])
20007 (define_insn "rdseed<mode>_1"
20008 [(set (match_operand:SWI248 0 "register_operand" "=r")
20009 (unspec_volatile:SWI248 [(const_int 0)] UNSPECV_RDSEED))
20010 (set (reg:CCC FLAGS_REG)
20011 (unspec_volatile:CCC [(const_int 0)] UNSPECV_RDSEED))]
20014 [(set_attr "type" "other")
20015 (set_attr "prefix_extra" "1")])
20017 (define_expand "pause"
20018 [(set (match_dup 0)
20019 (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
20022 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
20023 MEM_VOLATILE_P (operands[0]) = 1;
20026 ;; Use "rep; nop", instead of "pause", to support older assemblers.
20027 ;; They have the same encoding.
20028 (define_insn "*pause"
20029 [(set (match_operand:BLK 0)
20030 (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
20033 [(set_attr "length" "2")
20034 (set_attr "memory" "unknown")])
20036 ;; CET instructions
20037 (define_insn "rdssp<mode>"
20038 [(set (match_operand:SWI48x 0 "register_operand" "=r")
20039 (unspec_volatile:SWI48x [(const_int 0)] UNSPECV_NOP_RDSSP))]
20040 "TARGET_SHSTK || (flag_cf_protection & CF_RETURN)"
20041 "xor{l}\t%k0, %k0\n\trdssp<mskmodesuffix>\t%0"
20042 [(set_attr "length" "6")
20043 (set_attr "type" "other")])
20045 (define_insn "incssp<mode>"
20046 [(unspec_volatile [(match_operand:SWI48x 0 "register_operand" "r")]
20048 "TARGET_SHSTK || (flag_cf_protection & CF_RETURN)"
20049 "incssp<mskmodesuffix>\t%0"
20050 [(set_attr "length" "4")
20051 (set_attr "type" "other")])
20053 (define_insn "saveprevssp"
20054 [(unspec_volatile [(const_int 0)] UNSPECV_SAVEPREVSSP)]
20057 [(set_attr "length" "5")
20058 (set_attr "type" "other")])
20060 (define_expand "rstorssp"
20061 [(unspec_volatile [(match_operand 0 "memory_operand")]
20065 (define_insn "*rstorssp<mode>"
20066 [(unspec_volatile [(match_operand:P 0 "memory_operand" "m")]
20070 [(set_attr "length" "5")
20071 (set_attr "type" "other")])
20073 (define_insn "wrss<mode>"
20074 [(unspec_volatile [(match_operand:SWI48x 0 "register_operand" "r")
20075 (match_operand:SWI48x 1 "memory_operand" "m")]
20078 "wrss<mskmodesuffix>\t%0, %1"
20079 [(set_attr "length" "3")
20080 (set_attr "type" "other")])
20082 (define_insn "wruss<mode>"
20083 [(unspec_volatile [(match_operand:SWI48x 0 "register_operand" "r")
20084 (match_operand:SWI48x 1 "memory_operand" "m")]
20087 "wruss<mskmodesuffix>\t%0, %1"
20088 [(set_attr "length" "4")
20089 (set_attr "type" "other")])
20091 (define_insn "setssbsy"
20092 [(unspec_volatile [(const_int 0)] UNSPECV_SETSSBSY)]
20095 [(set_attr "length" "4")
20096 (set_attr "type" "other")])
20098 (define_expand "clrssbsy"
20099 [(unspec_volatile [(match_operand 0 "memory_operand")]
20103 (define_insn "*clrssbsy<mode>"
20104 [(unspec_volatile [(match_operand:P 0 "memory_operand" "m")]
20108 [(set_attr "length" "4")
20109 (set_attr "type" "other")])
20111 (define_insn "nop_endbr"
20112 [(unspec_volatile [(const_int 0)] UNSPECV_NOP_ENDBR)]
20113 "(flag_cf_protection & CF_BRANCH)"
20115 return TARGET_64BIT ? "endbr64" : "endbr32";
20117 [(set_attr "length" "4")
20118 (set_attr "length_immediate" "0")
20119 (set_attr "modrm" "0")])
20122 (define_expand "xbegin"
20123 [(set (match_operand:SI 0 "register_operand")
20124 (unspec_volatile:SI [(const_int 0)] UNSPECV_XBEGIN))]
20127 rtx_code_label *label = gen_label_rtx ();
20129 /* xbegin is emitted as jump_insn, so reload won't be able
20130 to reload its operand. Force the value into AX hard register. */
20131 rtx ax_reg = gen_rtx_REG (SImode, AX_REG);
20132 emit_move_insn (ax_reg, constm1_rtx);
20134 emit_jump_insn (gen_xbegin_1 (ax_reg, label));
20136 emit_label (label);
20137 LABEL_NUSES (label) = 1;
20139 emit_move_insn (operands[0], ax_reg);
20144 (define_insn "xbegin_1"
20146 (if_then_else (ne (unspec [(const_int 0)] UNSPEC_XBEGIN_ABORT)
20148 (label_ref (match_operand 1))
20150 (set (match_operand:SI 0 "register_operand" "+a")
20151 (unspec_volatile:SI [(match_dup 0)] UNSPECV_XBEGIN))]
20154 [(set_attr "type" "other")
20155 (set_attr "length" "6")])
20157 (define_insn "xend"
20158 [(unspec_volatile [(const_int 0)] UNSPECV_XEND)]
20161 [(set_attr "type" "other")
20162 (set_attr "length" "3")])
20164 (define_insn "xabort"
20165 [(unspec_volatile [(match_operand:SI 0 "const_0_to_255_operand" "n")]
20169 [(set_attr "type" "other")
20170 (set_attr "length" "3")])
20172 (define_expand "xtest"
20173 [(set (match_operand:QI 0 "register_operand")
20174 (unspec_volatile:QI [(const_int 0)] UNSPECV_XTEST))]
20177 emit_insn (gen_xtest_1 ());
20179 ix86_expand_setcc (operands[0], NE,
20180 gen_rtx_REG (CCZmode, FLAGS_REG), const0_rtx);
20184 (define_insn "xtest_1"
20185 [(set (reg:CCZ FLAGS_REG)
20186 (unspec_volatile:CCZ [(const_int 0)] UNSPECV_XTEST))]
20189 [(set_attr "type" "other")
20190 (set_attr "length" "3")])
20192 (define_insn "clwb"
20193 [(unspec_volatile [(match_operand 0 "address_operand" "p")]
20197 [(set_attr "type" "sse")
20198 (set_attr "atom_sse_attr" "fence")
20199 (set_attr "memory" "unknown")])
20201 (define_insn "clflushopt"
20202 [(unspec_volatile [(match_operand 0 "address_operand" "p")]
20203 UNSPECV_CLFLUSHOPT)]
20204 "TARGET_CLFLUSHOPT"
20206 [(set_attr "type" "sse")
20207 (set_attr "atom_sse_attr" "fence")
20208 (set_attr "memory" "unknown")])
20210 ;; MONITORX and MWAITX
20211 (define_insn "mwaitx"
20212 [(unspec_volatile [(match_operand:SI 0 "register_operand" "c")
20213 (match_operand:SI 1 "register_operand" "a")
20214 (match_operand:SI 2 "register_operand" "b")]
20217 ;; 64bit version is "mwaitx %rax,%rcx,%rbx". But only lower 32bits are used.
20218 ;; Since 32bit register operands are implicitly zero extended to 64bit,
20219 ;; we only need to set up 32bit registers.
20221 [(set_attr "length" "3")])
20223 (define_insn "@monitorx_<mode>"
20224 [(unspec_volatile [(match_operand:P 0 "register_operand" "a")
20225 (match_operand:SI 1 "register_operand" "c")
20226 (match_operand:SI 2 "register_operand" "d")]
20229 ;; 64bit version is "monitorx %rax,%rcx,%rdx". But only lower 32bits in
20230 ;; RCX and RDX are used. Since 32bit register operands are implicitly
20231 ;; zero extended to 64bit, we only need to set up 32bit registers.
20233 [(set (attr "length")
20234 (symbol_ref ("(Pmode != word_mode) + 3")))])
20237 (define_insn "@clzero_<mode>"
20238 [(unspec_volatile [(match_operand: P 0 "register_operand" "a")]
20242 [(set_attr "length" "3")
20243 (set_attr "memory" "unknown")])
20245 ;; RDPKRU and WRPKRU
20247 (define_expand "rdpkru"
20249 [(set (match_operand:SI 0 "register_operand")
20250 (unspec_volatile:SI [(match_dup 1)] UNSPECV_PKU))
20251 (set (match_dup 2) (const_int 0))])]
20254 operands[1] = force_reg (SImode, const0_rtx);
20255 operands[2] = gen_reg_rtx (SImode);
20258 (define_insn "*rdpkru"
20259 [(set (match_operand:SI 0 "register_operand" "=a")
20260 (unspec_volatile:SI [(match_operand:SI 2 "register_operand" "c")]
20262 (set (match_operand:SI 1 "register_operand" "=d")
20266 [(set_attr "type" "other")])
20268 (define_expand "wrpkru"
20269 [(unspec_volatile:SI
20270 [(match_operand:SI 0 "register_operand")
20271 (match_dup 1) (match_dup 2)] UNSPECV_PKU)]
20274 operands[1] = force_reg (SImode, const0_rtx);
20275 operands[2] = force_reg (SImode, const0_rtx);
20278 (define_insn "*wrpkru"
20279 [(unspec_volatile:SI
20280 [(match_operand:SI 0 "register_operand" "a")
20281 (match_operand:SI 1 "register_operand" "d")
20282 (match_operand:SI 2 "register_operand" "c")] UNSPECV_PKU)]
20285 [(set_attr "type" "other")])
20287 (define_insn "rdpid"
20288 [(set (match_operand:SI 0 "register_operand" "=r")
20289 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDPID))]
20290 "!TARGET_64BIT && TARGET_RDPID"
20292 [(set_attr "type" "other")])
20294 (define_insn "rdpid_rex64"
20295 [(set (match_operand:DI 0 "register_operand" "=r")
20296 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDPID))]
20297 "TARGET_64BIT && TARGET_RDPID"
20299 [(set_attr "type" "other")])
20301 ;; Intirinsics for > i486
20303 (define_insn "wbinvd"
20304 [(unspec_volatile [(const_int 0)] UNSPECV_WBINVD)]
20307 [(set_attr "type" "other")])
20309 (define_insn "wbnoinvd"
20310 [(unspec_volatile [(const_int 0)] UNSPECV_WBNOINVD)]
20313 [(set_attr "type" "other")])
20315 ;; MOVDIRI and MOVDIR64B
20317 (define_insn "movdiri<mode>"
20318 [(unspec_volatile:SWI48 [(match_operand:SWI48 0 "memory_operand" "m")
20319 (match_operand:SWI48 1 "register_operand" "r")]
20322 "movdiri\t{%1, %0|%0, %1}"
20323 [(set_attr "type" "other")])
20325 (define_insn "@movdir64b_<mode>"
20326 [(unspec_volatile:XI [(match_operand:P 0 "register_operand" "r")
20327 (match_operand:XI 1 "memory_operand")]
20328 UNSPECV_MOVDIR64B)]
20330 "movdir64b\t{%1, %0|%0, %1}"
20331 [(set_attr "type" "other")])
20333 ;; ENQCMD and ENQCMDS
20335 (define_int_iterator ENQCMD [UNSPECV_ENQCMD UNSPECV_ENQCMDS])
20336 (define_int_attr enqcmd_sfx [(UNSPECV_ENQCMD "") (UNSPECV_ENQCMDS "s")])
20338 (define_insn "@enqcmd<enqcmd_sfx>_<mode>"
20339 [(set (reg:CCZ FLAGS_REG)
20340 (unspec_volatile:CCZ [(match_operand:P 0 "register_operand" "r")
20341 (match_operand:XI 1 "memory_operand" "m")]
20344 "enqcmd<enqcmd_sfx>\t{%1, %0|%0, %1}"
20345 [(set_attr "type" "other")])
20349 (define_insn "umwait"
20350 [(set (reg:CCC FLAGS_REG)
20351 (unspec_volatile:CCC [(match_operand:SI 0 "register_operand" "r")
20352 (match_operand:DI 1 "register_operand" "A")]
20354 "!TARGET_64BIT && TARGET_WAITPKG"
20356 [(set_attr "length" "3")])
20358 (define_insn "umwait_rex64"
20359 [(set (reg:CCC FLAGS_REG)
20360 (unspec_volatile:CCC [(match_operand:SI 0 "register_operand" "r")
20361 (match_operand:SI 1 "register_operand" "a")
20362 (match_operand:SI 2 "register_operand" "d")]
20364 "TARGET_64BIT && TARGET_WAITPKG"
20366 [(set_attr "length" "3")])
20368 (define_insn "umonitor_<mode>"
20369 [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
20373 [(set (attr "length")
20374 (symbol_ref ("(Pmode != word_mode) + 3")))])
20376 (define_insn "tpause"
20377 [(set (reg:CCC FLAGS_REG)
20378 (unspec_volatile:CCC [(match_operand:SI 0 "register_operand" "r")
20379 (match_operand:DI 1 "register_operand" "A")]
20381 "!TARGET_64BIT && TARGET_WAITPKG"
20383 [(set_attr "length" "3")])
20385 (define_insn "tpause_rex64"
20386 [(set (reg:CCC FLAGS_REG)
20387 (unspec_volatile:CCC [(match_operand:SI 0 "register_operand" "r")
20388 (match_operand:SI 1 "register_operand" "a")
20389 (match_operand:SI 2 "register_operand" "d")]
20391 "TARGET_64BIT && TARGET_WAITPKG"
20393 [(set_attr "length" "3")])
20395 (define_insn "cldemote"
20396 [(unspec_volatile[(match_operand 0 "address_operand" "p")]
20400 [(set_attr "type" "other")
20401 (set_attr "memory" "unknown")])
20403 (define_insn "speculation_barrier"
20404 [(unspec_volatile [(const_int 0)] UNSPECV_SPECULATION_BARRIER)]
20407 [(set_attr "type" "other")
20408 (set_attr "length" "3")])
20412 (include "sync.md")