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 (enabled for 32bit with STV).
1022 (define_mode_iterator SWIM1248s
1023 [(QI "TARGET_QIMODE_MATH")
1024 (HI "TARGET_HIMODE_MATH")
1025 SI (DI "TARGET_64BIT || (TARGET_STV && TARGET_SSE2)")])
1027 ;; Math-dependant single word integer modes without QImode.
1028 (define_mode_iterator SWIM248 [(HI "TARGET_HIMODE_MATH")
1029 SI (DI "TARGET_64BIT")])
1031 ;; Double word integer modes.
1032 (define_mode_iterator DWI [(DI "!TARGET_64BIT")
1033 (TI "TARGET_64BIT")])
1035 ;; GET_MODE_SIZE for selected modes. As GET_MODE_SIZE is not
1036 ;; compile time constant, it is faster to use <MODE_SIZE> than
1037 ;; GET_MODE_SIZE (<MODE>mode). For XFmode which depends on
1038 ;; command line options just use GET_MODE_SIZE macro.
1039 (define_mode_attr MODE_SIZE [(QI "1") (HI "2") (SI "4") (DI "8") (TI "16")
1040 (SF "4") (DF "8") (XF "GET_MODE_SIZE (XFmode)")
1041 (V16QI "16") (V32QI "32") (V64QI "64")
1042 (V8HI "16") (V16HI "32") (V32HI "64")
1043 (V4SI "16") (V8SI "32") (V16SI "64")
1044 (V2DI "16") (V4DI "32") (V8DI "64")
1045 (V1TI "16") (V2TI "32") (V4TI "64")
1046 (V2DF "16") (V4DF "32") (V8DF "64")
1047 (V4SF "16") (V8SF "32") (V16SF "64")])
1049 ;; Double word integer modes as mode attribute.
1050 (define_mode_attr DWI [(QI "HI") (HI "SI") (SI "DI") (DI "TI")])
1051 (define_mode_attr dwi [(QI "hi") (HI "si") (SI "di") (DI "ti")])
1053 ;; LEA mode corresponding to an integer mode
1054 (define_mode_attr LEAMODE [(QI "SI") (HI "SI") (SI "SI") (DI "DI")])
1056 ;; Half mode for double word integer modes.
1057 (define_mode_iterator DWIH [(SI "!TARGET_64BIT")
1058 (DI "TARGET_64BIT")])
1060 ;; Instruction suffix for integer modes.
1061 (define_mode_attr imodesuffix [(QI "b") (HI "w") (SI "l") (DI "q")])
1063 ;; Instruction suffix for masks.
1064 (define_mode_attr mskmodesuffix [(QI "b") (HI "w") (SI "d") (DI "q")])
1066 ;; Pointer size prefix for integer modes (Intel asm dialect)
1067 (define_mode_attr iptrsize [(QI "BYTE")
1072 ;; Register class for integer modes.
1073 (define_mode_attr r [(QI "q") (HI "r") (SI "r") (DI "r")])
1075 ;; Immediate operand constraint for integer modes.
1076 (define_mode_attr i [(QI "n") (HI "n") (SI "e") (DI "e")])
1078 ;; General operand constraint for word modes.
1079 (define_mode_attr g [(QI "qmn") (HI "rmn") (SI "rme") (DI "rme")])
1081 ;; Immediate operand constraint for double integer modes.
1082 (define_mode_attr di [(SI "nF") (DI "Wd")])
1084 ;; Immediate operand constraint for shifts.
1085 (define_mode_attr S [(QI "I") (HI "I") (SI "I") (DI "J") (TI "O")])
1087 ;; Print register name in the specified mode.
1088 (define_mode_attr k [(QI "b") (HI "w") (SI "k") (DI "q")])
1090 ;; General operand predicate for integer modes.
1091 (define_mode_attr general_operand
1092 [(QI "general_operand")
1093 (HI "general_operand")
1094 (SI "x86_64_general_operand")
1095 (DI "x86_64_general_operand")
1096 (TI "x86_64_general_operand")])
1098 ;; General operand predicate for integer modes, where for TImode
1099 ;; we need both words of the operand to be general operands.
1100 (define_mode_attr general_hilo_operand
1101 [(QI "general_operand")
1102 (HI "general_operand")
1103 (SI "x86_64_general_operand")
1104 (DI "x86_64_general_operand")
1105 (TI "x86_64_hilo_general_operand")])
1107 ;; General sign extend operand predicate for integer modes,
1108 ;; which disallows VOIDmode operands and thus it is suitable
1109 ;; for use inside sign_extend.
1110 (define_mode_attr general_sext_operand
1111 [(QI "sext_operand")
1113 (SI "x86_64_sext_operand")
1114 (DI "x86_64_sext_operand")])
1116 ;; General sign/zero extend operand predicate for integer modes.
1117 (define_mode_attr general_szext_operand
1118 [(QI "general_operand")
1119 (HI "general_operand")
1120 (SI "x86_64_szext_general_operand")
1121 (DI "x86_64_szext_general_operand")])
1123 ;; Immediate operand predicate for integer modes.
1124 (define_mode_attr immediate_operand
1125 [(QI "immediate_operand")
1126 (HI "immediate_operand")
1127 (SI "x86_64_immediate_operand")
1128 (DI "x86_64_immediate_operand")])
1130 ;; Nonmemory operand predicate for integer modes.
1131 (define_mode_attr nonmemory_operand
1132 [(QI "nonmemory_operand")
1133 (HI "nonmemory_operand")
1134 (SI "x86_64_nonmemory_operand")
1135 (DI "x86_64_nonmemory_operand")])
1137 ;; Operand predicate for shifts.
1138 (define_mode_attr shift_operand
1139 [(QI "nonimmediate_operand")
1140 (HI "nonimmediate_operand")
1141 (SI "nonimmediate_operand")
1142 (DI "shiftdi_operand")
1143 (TI "register_operand")])
1145 ;; Operand predicate for shift argument.
1146 (define_mode_attr shift_immediate_operand
1147 [(QI "const_1_to_31_operand")
1148 (HI "const_1_to_31_operand")
1149 (SI "const_1_to_31_operand")
1150 (DI "const_1_to_63_operand")])
1152 ;; Input operand predicate for arithmetic left shifts.
1153 (define_mode_attr ashl_input_operand
1154 [(QI "nonimmediate_operand")
1155 (HI "nonimmediate_operand")
1156 (SI "nonimmediate_operand")
1157 (DI "ashldi_input_operand")
1158 (TI "reg_or_pm1_operand")])
1160 ;; SSE and x87 SFmode and DFmode floating point modes
1161 (define_mode_iterator MODEF [SF DF])
1163 ;; All x87 floating point modes
1164 (define_mode_iterator X87MODEF [SF DF XF])
1166 ;; All SSE floating point modes
1167 (define_mode_iterator SSEMODEF [SF DF TF])
1168 (define_mode_attr ssevecmodef [(SF "V4SF") (DF "V2DF") (TF "TF")])
1170 ;; SSE instruction suffix for various modes
1171 (define_mode_attr ssemodesuffix
1172 [(SF "ss") (DF "sd")
1173 (V16SF "ps") (V8DF "pd")
1174 (V8SF "ps") (V4DF "pd")
1175 (V4SF "ps") (V2DF "pd")
1176 (V16QI "b") (V8HI "w") (V4SI "d") (V2DI "q")
1177 (V32QI "b") (V16HI "w") (V8SI "d") (V4DI "q")
1178 (V64QI "b") (V32HI "w") (V16SI "d") (V8DI "q")])
1180 ;; SSE vector suffix for floating point modes
1181 (define_mode_attr ssevecmodesuffix [(SF "ps") (DF "pd")])
1183 ;; SSE vector mode corresponding to a scalar mode
1184 (define_mode_attr ssevecmode
1185 [(QI "V16QI") (HI "V8HI") (SI "V4SI") (DI "V2DI") (SF "V4SF") (DF "V2DF")])
1186 (define_mode_attr ssevecmodelower
1187 [(QI "v16qi") (HI "v8hi") (SI "v4si") (DI "v2di") (SF "v4sf") (DF "v2df")])
1189 ;; AVX512F vector mode corresponding to a scalar mode
1190 (define_mode_attr avx512fvecmode
1191 [(QI "V64QI") (HI "V32HI") (SI "V16SI") (DI "V8DI") (SF "V16SF") (DF "V8DF")])
1193 ;; Instruction suffix for REX 64bit operators.
1194 (define_mode_attr rex64suffix [(SI "{l}") (DI "{q}")])
1195 (define_mode_attr rex64namesuffix [(SI "") (DI "q")])
1197 ;; This mode iterator allows :P to be used for patterns that operate on
1198 ;; pointer-sized quantities. Exactly one of the two alternatives will match.
1199 (define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
1201 ;; This mode iterator allows :W to be used for patterns that operate on
1202 ;; word_mode sized quantities.
1203 (define_mode_iterator W
1204 [(SI "word_mode == SImode") (DI "word_mode == DImode")])
1206 ;; This mode iterator allows :PTR to be used for patterns that operate on
1207 ;; ptr_mode sized quantities.
1208 (define_mode_iterator PTR
1209 [(SI "ptr_mode == SImode") (DI "ptr_mode == DImode")])
1211 ;; Scheduling descriptions
1213 (include "pentium.md")
1216 (include "athlon.md")
1217 (include "bdver1.md")
1218 (include "bdver3.md")
1219 (include "btver2.md")
1220 (include "znver1.md")
1221 (include "geode.md")
1225 (include "core2.md")
1226 (include "haswell.md")
1229 ;; Operand and operator predicates and constraints
1231 (include "predicates.md")
1232 (include "constraints.md")
1235 ;; Compare and branch/compare and store instructions.
1237 (define_expand "cbranch<mode>4"
1238 [(set (reg:CC FLAGS_REG)
1239 (compare:CC (match_operand:SDWIM 1 "nonimmediate_operand")
1240 (match_operand:SDWIM 2 "<general_operand>")))
1241 (set (pc) (if_then_else
1242 (match_operator 0 "ordered_comparison_operator"
1243 [(reg:CC FLAGS_REG) (const_int 0)])
1244 (label_ref (match_operand 3))
1248 if (MEM_P (operands[1]) && MEM_P (operands[2]))
1249 operands[1] = force_reg (<MODE>mode, operands[1]);
1250 ix86_expand_branch (GET_CODE (operands[0]),
1251 operands[1], operands[2], operands[3]);
1255 (define_expand "cstore<mode>4"
1256 [(set (reg:CC FLAGS_REG)
1257 (compare:CC (match_operand:SWIM 2 "nonimmediate_operand")
1258 (match_operand:SWIM 3 "<general_operand>")))
1259 (set (match_operand:QI 0 "register_operand")
1260 (match_operator 1 "ordered_comparison_operator"
1261 [(reg:CC FLAGS_REG) (const_int 0)]))]
1264 if (MEM_P (operands[2]) && MEM_P (operands[3]))
1265 operands[2] = force_reg (<MODE>mode, operands[2]);
1266 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1267 operands[2], operands[3]);
1271 (define_expand "cmp<mode>_1"
1272 [(set (reg:CC FLAGS_REG)
1273 (compare:CC (match_operand:SWI48 0 "nonimmediate_operand")
1274 (match_operand:SWI48 1 "<general_operand>")))])
1276 (define_mode_iterator SWI1248_AVX512BWDQ_64
1277 [(QI "TARGET_AVX512DQ") HI
1278 (SI "TARGET_AVX512BW") (DI "TARGET_AVX512BW && TARGET_64BIT")])
1280 (define_insn "*cmp<mode>_ccz_1"
1281 [(set (reg FLAGS_REG)
1282 (compare (match_operand:SWI1248_AVX512BWDQ_64 0
1283 "nonimmediate_operand" "<r>,?m<r>,$k")
1284 (match_operand:SWI1248_AVX512BWDQ_64 1 "const0_operand")))]
1285 "TARGET_AVX512F && ix86_match_ccmode (insn, CCZmode)"
1287 test{<imodesuffix>}\t%0, %0
1288 cmp{<imodesuffix>}\t{%1, %0|%0, %1}
1289 kortest<mskmodesuffix>\t%0, %0"
1290 [(set_attr "type" "test,icmp,msklog")
1291 (set_attr "length_immediate" "0,1,*")
1292 (set_attr "prefix" "*,*,vex")
1293 (set_attr "mode" "<MODE>")])
1295 (define_insn "*cmp<mode>_ccno_1"
1296 [(set (reg FLAGS_REG)
1297 (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>,?m<r>")
1298 (match_operand:SWI 1 "const0_operand")))]
1299 "ix86_match_ccmode (insn, CCNOmode)"
1301 test{<imodesuffix>}\t%0, %0
1302 cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1303 [(set_attr "type" "test,icmp")
1304 (set_attr "length_immediate" "0,1")
1305 (set_attr "mode" "<MODE>")])
1307 (define_insn "*cmp<mode>_1"
1308 [(set (reg FLAGS_REG)
1309 (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
1310 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m")))]
1311 "ix86_match_ccmode (insn, CCmode)"
1312 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1313 [(set_attr "type" "icmp")
1314 (set_attr "mode" "<MODE>")])
1316 (define_insn "*cmp<mode>_minus_1"
1317 [(set (reg FLAGS_REG)
1319 (minus:SWI (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
1320 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
1322 "ix86_match_ccmode (insn, CCGOCmode)"
1323 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1324 [(set_attr "type" "icmp")
1325 (set_attr "mode" "<MODE>")])
1327 (define_insn "*cmpqi_ext_1"
1328 [(set (reg FLAGS_REG)
1330 (match_operand:QI 0 "nonimmediate_operand" "QBc,m")
1333 (match_operand 1 "ext_register_operand" "Q,Q")
1335 (const_int 8)) 0)))]
1336 "ix86_match_ccmode (insn, CCmode)"
1337 "cmp{b}\t{%h1, %0|%0, %h1}"
1338 [(set_attr "isa" "*,nox64")
1339 (set_attr "type" "icmp")
1340 (set_attr "mode" "QI")])
1342 (define_insn "*cmpqi_ext_2"
1343 [(set (reg FLAGS_REG)
1347 (match_operand 0 "ext_register_operand" "Q")
1350 (match_operand:QI 1 "const0_operand")))]
1351 "ix86_match_ccmode (insn, CCNOmode)"
1353 [(set_attr "type" "test")
1354 (set_attr "length_immediate" "0")
1355 (set_attr "mode" "QI")])
1357 (define_expand "cmpqi_ext_3"
1358 [(set (reg:CC FLAGS_REG)
1362 (match_operand 0 "ext_register_operand")
1365 (match_operand:QI 1 "const_int_operand")))])
1367 (define_insn "*cmpqi_ext_3"
1368 [(set (reg FLAGS_REG)
1372 (match_operand 0 "ext_register_operand" "Q,Q")
1375 (match_operand:QI 1 "general_operand" "QnBc,m")))]
1376 "ix86_match_ccmode (insn, CCmode)"
1377 "cmp{b}\t{%1, %h0|%h0, %1}"
1378 [(set_attr "isa" "*,nox64")
1379 (set_attr "type" "icmp")
1380 (set_attr "mode" "QI")])
1382 (define_insn "*cmpqi_ext_4"
1383 [(set (reg FLAGS_REG)
1387 (match_operand 0 "ext_register_operand" "Q")
1392 (match_operand 1 "ext_register_operand" "Q")
1394 (const_int 8)) 0)))]
1395 "ix86_match_ccmode (insn, CCmode)"
1396 "cmp{b}\t{%h1, %h0|%h0, %h1}"
1397 [(set_attr "type" "icmp")
1398 (set_attr "mode" "QI")])
1400 ;; These implement float point compares.
1401 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
1402 ;; which would allow mix and match FP modes on the compares. Which is what
1403 ;; the old patterns did, but with many more of them.
1405 (define_expand "cbranchxf4"
1406 [(set (reg:CC FLAGS_REG)
1407 (compare:CC (match_operand:XF 1 "nonmemory_operand")
1408 (match_operand:XF 2 "nonmemory_operand")))
1409 (set (pc) (if_then_else
1410 (match_operator 0 "ix86_fp_comparison_operator"
1413 (label_ref (match_operand 3))
1417 ix86_expand_branch (GET_CODE (operands[0]),
1418 operands[1], operands[2], operands[3]);
1422 (define_expand "cstorexf4"
1423 [(set (reg:CC FLAGS_REG)
1424 (compare:CC (match_operand:XF 2 "nonmemory_operand")
1425 (match_operand:XF 3 "nonmemory_operand")))
1426 (set (match_operand:QI 0 "register_operand")
1427 (match_operator 1 "ix86_fp_comparison_operator"
1432 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1433 operands[2], operands[3]);
1437 (define_expand "cbranch<mode>4"
1438 [(set (reg:CC FLAGS_REG)
1439 (compare:CC (match_operand:MODEF 1 "cmp_fp_expander_operand")
1440 (match_operand:MODEF 2 "cmp_fp_expander_operand")))
1441 (set (pc) (if_then_else
1442 (match_operator 0 "ix86_fp_comparison_operator"
1445 (label_ref (match_operand 3))
1447 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1449 ix86_expand_branch (GET_CODE (operands[0]),
1450 operands[1], operands[2], operands[3]);
1454 (define_expand "cstore<mode>4"
1455 [(set (reg:CC FLAGS_REG)
1456 (compare:CC (match_operand:MODEF 2 "cmp_fp_expander_operand")
1457 (match_operand:MODEF 3 "cmp_fp_expander_operand")))
1458 (set (match_operand:QI 0 "register_operand")
1459 (match_operator 1 "ix86_fp_comparison_operator"
1462 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1464 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1465 operands[2], operands[3]);
1469 (define_expand "cbranchcc4"
1470 [(set (pc) (if_then_else
1471 (match_operator 0 "comparison_operator"
1472 [(match_operand 1 "flags_reg_operand")
1473 (match_operand 2 "const0_operand")])
1474 (label_ref (match_operand 3))
1478 ix86_expand_branch (GET_CODE (operands[0]),
1479 operands[1], operands[2], operands[3]);
1483 (define_expand "cstorecc4"
1484 [(set (match_operand:QI 0 "register_operand")
1485 (match_operator 1 "comparison_operator"
1486 [(match_operand 2 "flags_reg_operand")
1487 (match_operand 3 "const0_operand")]))]
1490 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1491 operands[2], operands[3]);
1495 ;; FP compares, step 1:
1496 ;; Set the FP condition codes and move fpsr to ax.
1498 ;; We may not use "#" to split and emit these
1499 ;; due to reg-stack pops killing fpsr.
1501 (define_insn "*cmpxf_i387"
1502 [(set (match_operand:HI 0 "register_operand" "=a")
1505 (match_operand:XF 1 "register_operand" "f")
1506 (match_operand:XF 2 "reg_or_0_operand" "fC"))]
1509 "* return output_fp_compare (insn, operands, false, false);"
1510 [(set_attr "type" "multi")
1511 (set_attr "unit" "i387")
1512 (set_attr "mode" "XF")])
1514 (define_insn "*cmp<mode>_i387"
1515 [(set (match_operand:HI 0 "register_operand" "=a")
1518 (match_operand:MODEF 1 "register_operand" "f")
1519 (match_operand:MODEF 2 "nonimm_or_0_operand" "fmC"))]
1522 "* return output_fp_compare (insn, operands, false, false);"
1523 [(set_attr "type" "multi")
1524 (set_attr "unit" "i387")
1525 (set_attr "mode" "<MODE>")])
1527 (define_insn "*cmp<X87MODEF:mode>_<SWI24:mode>_i387"
1528 [(set (match_operand:HI 0 "register_operand" "=a")
1531 (match_operand:X87MODEF 1 "register_operand" "f")
1533 (match_operand:SWI24 2 "nonimmediate_operand" "m")))]
1536 && (TARGET_USE_<SWI24:MODE>MODE_FIOP
1537 || optimize_function_for_size_p (cfun))"
1538 "* return output_fp_compare (insn, operands, false, false);"
1539 [(set_attr "type" "multi")
1540 (set_attr "unit" "i387")
1541 (set_attr "fp_int_src" "true")
1542 (set_attr "mode" "<SWI24:MODE>")])
1544 (define_insn "*cmpu<mode>_i387"
1545 [(set (match_operand:HI 0 "register_operand" "=a")
1549 (match_operand:X87MODEF 1 "register_operand" "f")
1550 (match_operand:X87MODEF 2 "register_operand" "f"))]
1554 "* return output_fp_compare (insn, operands, false, true);"
1555 [(set_attr "type" "multi")
1556 (set_attr "unit" "i387")
1557 (set_attr "mode" "<MODE>")])
1559 ;; FP compares, step 2:
1560 ;; Get ax into flags, general case.
1562 (define_insn "x86_sahf_1"
1563 [(set (reg:CC FLAGS_REG)
1564 (unspec:CC [(match_operand:HI 0 "register_operand" "a")]
1568 #ifndef HAVE_AS_IX86_SAHF
1570 return ASM_BYTE "0x9e";
1575 [(set_attr "length" "1")
1576 (set_attr "athlon_decode" "vector")
1577 (set_attr "amdfam10_decode" "direct")
1578 (set_attr "bdver1_decode" "direct")
1579 (set_attr "mode" "SI")])
1581 ;; Pentium Pro can do both steps in one go.
1582 ;; (these instructions set flags directly)
1584 (define_subst_attr "unord" "unord_subst" "" "u")
1585 (define_subst_attr "unordered" "unord_subst" "false" "true")
1587 (define_subst "unord_subst"
1588 [(set (match_operand:CCFP 0)
1589 (match_operand:CCFP 1))]
1596 (define_insn "*cmpi<unord>xf_i387"
1597 [(set (reg:CCFP FLAGS_REG)
1599 (match_operand:XF 0 "register_operand" "f")
1600 (match_operand:XF 1 "register_operand" "f")))]
1601 "TARGET_80387 && TARGET_CMOVE"
1602 "* return output_fp_compare (insn, operands, true, <unordered>);"
1603 [(set_attr "type" "fcmp")
1604 (set_attr "mode" "XF")
1605 (set_attr "athlon_decode" "vector")
1606 (set_attr "amdfam10_decode" "direct")
1607 (set_attr "bdver1_decode" "double")
1608 (set_attr "znver1_decode" "double")])
1610 (define_insn "*cmpi<unord><MODEF:mode>"
1611 [(set (reg:CCFP FLAGS_REG)
1613 (match_operand:MODEF 0 "register_operand" "f,v")
1614 (match_operand:MODEF 1 "register_ssemem_operand" "f,vm")))]
1615 "(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
1616 || (TARGET_80387 && TARGET_CMOVE)"
1618 * return output_fp_compare (insn, operands, true, <unordered>);
1619 %v<unord>comi<MODEF:ssemodesuffix>\t{%1, %0|%0, %1}"
1620 [(set_attr "type" "fcmp,ssecomi")
1621 (set_attr "prefix" "orig,maybe_vex")
1622 (set_attr "mode" "<MODEF:MODE>")
1623 (set_attr "prefix_rep" "*,0")
1624 (set (attr "prefix_data16")
1625 (cond [(eq_attr "alternative" "0")
1627 (eq_attr "mode" "DF")
1630 (const_string "0")))
1631 (set_attr "athlon_decode" "vector")
1632 (set_attr "amdfam10_decode" "direct")
1633 (set_attr "bdver1_decode" "double")
1634 (set_attr "znver1_decode" "double")
1635 (set (attr "enabled")
1637 (match_test ("SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"))
1639 (eq_attr "alternative" "0")
1640 (symbol_ref "TARGET_MIX_SSE_I387")
1641 (symbol_ref "true"))
1643 (eq_attr "alternative" "0")
1645 (symbol_ref "false"))))])
1647 ;; Push/pop instructions.
1649 (define_insn "*push<mode>2"
1650 [(set (match_operand:DWI 0 "push_operand" "=<")
1651 (match_operand:DWI 1 "general_no_elim_operand" "riF*o"))]
1654 [(set_attr "type" "multi")
1655 (set_attr "mode" "<MODE>")])
1658 [(set (match_operand:DWI 0 "push_operand")
1659 (match_operand:DWI 1 "general_gr_operand"))]
1662 "ix86_split_long_move (operands); DONE;")
1664 (define_insn "*pushdi2_rex64"
1665 [(set (match_operand:DI 0 "push_operand" "=<,!<")
1666 (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1671 [(set_attr "type" "push,multi")
1672 (set_attr "mode" "DI")])
1674 ;; Convert impossible pushes of immediate to existing instructions.
1675 ;; First try to get scratch register and go through it. In case this
1676 ;; fails, push sign extended lower part first and then overwrite
1677 ;; upper part by 32bit move.
1679 [(match_scratch:DI 2 "r")
1680 (set (match_operand:DI 0 "push_operand")
1681 (match_operand:DI 1 "immediate_operand"))]
1682 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1683 && !x86_64_immediate_operand (operands[1], DImode)"
1684 [(set (match_dup 2) (match_dup 1))
1685 (set (match_dup 0) (match_dup 2))])
1687 ;; We need to define this as both peepholer and splitter for case
1688 ;; peephole2 pass is not run.
1689 ;; "&& 1" is needed to keep it from matching the previous pattern.
1691 [(set (match_operand:DI 0 "push_operand")
1692 (match_operand:DI 1 "immediate_operand"))]
1693 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1694 && !x86_64_immediate_operand (operands[1], DImode) && 1"
1695 [(set (match_dup 0) (match_dup 1))
1696 (set (match_dup 2) (match_dup 3))]
1698 split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1700 operands[1] = gen_lowpart (DImode, operands[2]);
1701 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (Pmode, stack_pointer_rtx,
1706 [(set (match_operand:DI 0 "push_operand")
1707 (match_operand:DI 1 "immediate_operand"))]
1708 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
1709 ? epilogue_completed : reload_completed)
1710 && !symbolic_operand (operands[1], DImode)
1711 && !x86_64_immediate_operand (operands[1], DImode)"
1712 [(set (match_dup 0) (match_dup 1))
1713 (set (match_dup 2) (match_dup 3))]
1715 split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1717 operands[1] = gen_lowpart (DImode, operands[2]);
1718 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (Pmode, stack_pointer_rtx,
1722 (define_insn "*pushsi2"
1723 [(set (match_operand:SI 0 "push_operand" "=<")
1724 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1727 [(set_attr "type" "push")
1728 (set_attr "mode" "SI")])
1730 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1731 ;; "push a byte/word". But actually we use pushl, which has the effect
1732 ;; of rounding the amount pushed up to a word.
1734 ;; For TARGET_64BIT we always round up to 8 bytes.
1735 (define_insn "*push<mode>2_rex64"
1736 [(set (match_operand:SWI124 0 "push_operand" "=X")
1737 (match_operand:SWI124 1 "nonmemory_no_elim_operand" "r<i>"))]
1740 [(set_attr "type" "push")
1741 (set_attr "mode" "DI")])
1743 (define_insn "*push<mode>2"
1744 [(set (match_operand:SWI12 0 "push_operand" "=X")
1745 (match_operand:SWI12 1 "nonmemory_no_elim_operand" "rn"))]
1748 [(set_attr "type" "push")
1749 (set_attr "mode" "SI")])
1751 (define_insn "*push<mode>2_prologue"
1752 [(set (match_operand:W 0 "push_operand" "=<")
1753 (match_operand:W 1 "general_no_elim_operand" "r<i>*m"))
1754 (clobber (mem:BLK (scratch)))]
1756 "push{<imodesuffix>}\t%1"
1757 [(set_attr "type" "push")
1758 (set_attr "mode" "<MODE>")])
1760 (define_insn "*pop<mode>1"
1761 [(set (match_operand:W 0 "nonimmediate_operand" "=r*m")
1762 (match_operand:W 1 "pop_operand" ">"))]
1764 "pop{<imodesuffix>}\t%0"
1765 [(set_attr "type" "pop")
1766 (set_attr "mode" "<MODE>")])
1768 (define_insn "*pop<mode>1_epilogue"
1769 [(set (match_operand:W 0 "nonimmediate_operand" "=r*m")
1770 (match_operand:W 1 "pop_operand" ">"))
1771 (clobber (mem:BLK (scratch)))]
1773 "pop{<imodesuffix>}\t%0"
1774 [(set_attr "type" "pop")
1775 (set_attr "mode" "<MODE>")])
1777 (define_insn "*pushfl<mode>2"
1778 [(set (match_operand:W 0 "push_operand" "=<")
1779 (match_operand:W 1 "flags_reg_operand"))]
1781 "pushf{<imodesuffix>}"
1782 [(set_attr "type" "push")
1783 (set_attr "mode" "<MODE>")])
1785 (define_insn "*popfl<mode>1"
1786 [(set (match_operand:W 0 "flags_reg_operand")
1787 (match_operand:W 1 "pop_operand" ">"))]
1789 "popf{<imodesuffix>}"
1790 [(set_attr "type" "pop")
1791 (set_attr "mode" "<MODE>")])
1794 ;; Reload patterns to support multi-word load/store
1795 ;; with non-offsetable address.
1796 (define_expand "reload_noff_store"
1797 [(parallel [(match_operand 0 "memory_operand" "=m")
1798 (match_operand 1 "register_operand" "r")
1799 (match_operand:DI 2 "register_operand" "=&r")])]
1802 rtx mem = operands[0];
1803 rtx addr = XEXP (mem, 0);
1805 emit_move_insn (operands[2], addr);
1806 mem = replace_equiv_address_nv (mem, operands[2]);
1808 emit_insn (gen_rtx_SET (mem, operands[1]));
1812 (define_expand "reload_noff_load"
1813 [(parallel [(match_operand 0 "register_operand" "=r")
1814 (match_operand 1 "memory_operand" "m")
1815 (match_operand:DI 2 "register_operand" "=r")])]
1818 rtx mem = operands[1];
1819 rtx addr = XEXP (mem, 0);
1821 emit_move_insn (operands[2], addr);
1822 mem = replace_equiv_address_nv (mem, operands[2]);
1824 emit_insn (gen_rtx_SET (operands[0], mem));
1828 ;; Move instructions.
1830 (define_expand "movxi"
1831 [(set (match_operand:XI 0 "nonimmediate_operand")
1832 (match_operand:XI 1 "general_operand"))]
1834 "ix86_expand_vector_move (XImode, operands); DONE;")
1836 (define_expand "movoi"
1837 [(set (match_operand:OI 0 "nonimmediate_operand")
1838 (match_operand:OI 1 "general_operand"))]
1840 "ix86_expand_vector_move (OImode, operands); DONE;")
1842 (define_expand "movti"
1843 [(set (match_operand:TI 0 "nonimmediate_operand")
1844 (match_operand:TI 1 "general_operand"))]
1845 "TARGET_64BIT || TARGET_SSE"
1848 ix86_expand_move (TImode, operands);
1850 ix86_expand_vector_move (TImode, operands);
1854 ;; This expands to what emit_move_complex would generate if we didn't
1855 ;; have a movti pattern. Having this avoids problems with reload on
1856 ;; 32-bit targets when SSE is present, but doesn't seem to be harmful
1857 ;; to have around all the time.
1858 (define_expand "movcdi"
1859 [(set (match_operand:CDI 0 "nonimmediate_operand")
1860 (match_operand:CDI 1 "general_operand"))]
1863 if (push_operand (operands[0], CDImode))
1864 emit_move_complex_push (CDImode, operands[0], operands[1]);
1866 emit_move_complex_parts (operands[0], operands[1]);
1870 (define_expand "mov<mode>"
1871 [(set (match_operand:SWI1248x 0 "nonimmediate_operand")
1872 (match_operand:SWI1248x 1 "general_operand"))]
1874 "ix86_expand_move (<MODE>mode, operands); DONE;")
1876 (define_insn "*mov<mode>_xor"
1877 [(set (match_operand:SWI48 0 "register_operand" "=r")
1878 (match_operand:SWI48 1 "const0_operand"))
1879 (clobber (reg:CC FLAGS_REG))]
1882 [(set_attr "type" "alu1")
1883 (set_attr "mode" "SI")
1884 (set_attr "length_immediate" "0")])
1886 (define_insn "*mov<mode>_or"
1887 [(set (match_operand:SWI48 0 "register_operand" "=r")
1888 (match_operand:SWI48 1 "constm1_operand"))
1889 (clobber (reg:CC FLAGS_REG))]
1891 "or{<imodesuffix>}\t{%1, %0|%0, %1}"
1892 [(set_attr "type" "alu1")
1893 (set_attr "mode" "<MODE>")
1894 (set_attr "length_immediate" "1")])
1896 (define_insn "*movxi_internal_avx512f"
1897 [(set (match_operand:XI 0 "nonimmediate_operand" "=v,v ,v ,m")
1898 (match_operand:XI 1 "nonimmediate_or_sse_const_operand" " C,BC,vm,v"))]
1900 && (register_operand (operands[0], XImode)
1901 || register_operand (operands[1], XImode))"
1903 switch (get_attr_type (insn))
1906 return standard_sse_constant_opcode (insn, operands);
1909 if (misaligned_operand (operands[0], XImode)
1910 || misaligned_operand (operands[1], XImode))
1911 return "vmovdqu32\t{%1, %0|%0, %1}";
1913 return "vmovdqa32\t{%1, %0|%0, %1}";
1919 [(set_attr "type" "sselog1,sselog1,ssemov,ssemov")
1920 (set_attr "prefix" "evex")
1921 (set_attr "mode" "XI")])
1923 (define_insn "*movoi_internal_avx"
1924 [(set (match_operand:OI 0 "nonimmediate_operand" "=v,v ,v ,m")
1925 (match_operand:OI 1 "nonimmediate_or_sse_const_operand" " C,BC,vm,v"))]
1927 && (register_operand (operands[0], OImode)
1928 || register_operand (operands[1], OImode))"
1930 switch (get_attr_type (insn))
1933 return standard_sse_constant_opcode (insn, operands);
1936 if (misaligned_operand (operands[0], OImode)
1937 || misaligned_operand (operands[1], OImode))
1939 if (get_attr_mode (insn) == MODE_V8SF)
1940 return "vmovups\t{%1, %0|%0, %1}";
1941 else if (get_attr_mode (insn) == MODE_XI)
1942 return "vmovdqu32\t{%1, %0|%0, %1}";
1944 return "vmovdqu\t{%1, %0|%0, %1}";
1948 if (get_attr_mode (insn) == MODE_V8SF)
1949 return "vmovaps\t{%1, %0|%0, %1}";
1950 else if (get_attr_mode (insn) == MODE_XI)
1951 return "vmovdqa32\t{%1, %0|%0, %1}";
1953 return "vmovdqa\t{%1, %0|%0, %1}";
1960 [(set_attr "isa" "*,avx2,*,*")
1961 (set_attr "type" "sselog1,sselog1,ssemov,ssemov")
1962 (set_attr "prefix" "vex")
1964 (cond [(ior (match_operand 0 "ext_sse_reg_operand")
1965 (match_operand 1 "ext_sse_reg_operand"))
1967 (and (eq_attr "alternative" "1")
1968 (match_test "TARGET_AVX512VL"))
1970 (ior (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
1971 (and (eq_attr "alternative" "3")
1972 (match_test "TARGET_SSE_TYPELESS_STORES")))
1973 (const_string "V8SF")
1975 (const_string "OI")))])
1977 (define_insn "*movti_internal"
1978 [(set (match_operand:TI 0 "nonimmediate_operand" "=!r ,o ,v,v ,v ,m,?r,?Yd")
1979 (match_operand:TI 1 "general_operand" "riFo,re,C,BC,vm,v,Yd,r"))]
1981 && !(MEM_P (operands[0]) && MEM_P (operands[1])))
1983 && nonimmediate_or_sse_const_operand (operands[1], TImode)
1984 && (register_operand (operands[0], TImode)
1985 || register_operand (operands[1], TImode)))"
1987 switch (get_attr_type (insn))
1993 return standard_sse_constant_opcode (insn, operands);
1996 /* TDmode values are passed as TImode on the stack. Moving them
1997 to stack may result in unaligned memory access. */
1998 if (misaligned_operand (operands[0], TImode)
1999 || misaligned_operand (operands[1], TImode))
2001 if (get_attr_mode (insn) == MODE_V4SF)
2002 return "%vmovups\t{%1, %0|%0, %1}";
2003 else if (get_attr_mode (insn) == MODE_XI)
2004 return "vmovdqu32\t{%1, %0|%0, %1}";
2006 return "%vmovdqu\t{%1, %0|%0, %1}";
2010 if (get_attr_mode (insn) == MODE_V4SF)
2011 return "%vmovaps\t{%1, %0|%0, %1}";
2012 else if (get_attr_mode (insn) == MODE_XI)
2013 return "vmovdqa32\t{%1, %0|%0, %1}";
2015 return "%vmovdqa\t{%1, %0|%0, %1}";
2023 (cond [(eq_attr "alternative" "0,1,6,7")
2024 (const_string "x64")
2025 (eq_attr "alternative" "3")
2026 (const_string "sse2")
2028 (const_string "*")))
2030 (cond [(eq_attr "alternative" "0,1,6,7")
2031 (const_string "multi")
2032 (eq_attr "alternative" "2,3")
2033 (const_string "sselog1")
2035 (const_string "ssemov")))
2036 (set (attr "prefix")
2037 (if_then_else (eq_attr "type" "sselog1,ssemov")
2038 (const_string "maybe_vex")
2039 (const_string "orig")))
2041 (cond [(eq_attr "alternative" "0,1")
2043 (ior (match_operand 0 "ext_sse_reg_operand")
2044 (match_operand 1 "ext_sse_reg_operand"))
2046 (and (eq_attr "alternative" "3")
2047 (match_test "TARGET_AVX512VL"))
2049 (ior (not (match_test "TARGET_SSE2"))
2050 (ior (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
2051 (and (eq_attr "alternative" "5")
2052 (match_test "TARGET_SSE_TYPELESS_STORES"))))
2053 (const_string "V4SF")
2054 (match_test "TARGET_AVX")
2056 (match_test "optimize_function_for_size_p (cfun)")
2057 (const_string "V4SF")
2059 (const_string "TI")))
2060 (set (attr "preferred_for_speed")
2061 (cond [(eq_attr "alternative" "6")
2062 (symbol_ref "TARGET_INTER_UNIT_MOVES_FROM_VEC")
2063 (eq_attr "alternative" "7")
2064 (symbol_ref "TARGET_INTER_UNIT_MOVES_TO_VEC")
2066 (symbol_ref "true")))])
2069 [(set (match_operand:TI 0 "sse_reg_operand")
2070 (match_operand:TI 1 "general_reg_operand"))]
2071 "TARGET_64BIT && TARGET_SSE4_1
2072 && reload_completed"
2075 (vec_duplicate:V2DI (match_dup 3))
2079 operands[2] = lowpart_subreg (V2DImode, operands[0], TImode);
2080 operands[3] = gen_highpart (DImode, operands[1]);
2082 emit_move_insn (gen_lowpart (DImode, operands[0]),
2083 gen_lowpart (DImode, operands[1]));
2086 (define_insn "*movdi_internal"
2087 [(set (match_operand:DI 0 "nonimmediate_operand"
2088 "=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")
2089 (match_operand:DI 1 "general_operand"
2090 "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"))]
2091 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2093 switch (get_attr_type (insn))
2096 return "kmovq\t{%1, %0|%0, %1}";
2099 if (operands[1] == const0_rtx)
2100 return "kxorq\t%0, %0, %0";
2101 else if (operands[1] == constm1_rtx)
2102 return "kxnorq\t%0, %0, %0";
2109 return "pxor\t%0, %0";
2112 /* Handle broken assemblers that require movd instead of movq. */
2113 if (!HAVE_AS_IX86_INTERUNIT_MOVQ
2114 && (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1])))
2115 return "movd\t{%1, %0|%0, %1}";
2116 return "movq\t{%1, %0|%0, %1}";
2119 return standard_sse_constant_opcode (insn, operands);
2122 switch (get_attr_mode (insn))
2125 /* Handle broken assemblers that require movd instead of movq. */
2126 if (!HAVE_AS_IX86_INTERUNIT_MOVQ
2127 && (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1])))
2128 return "%vmovd\t{%1, %0|%0, %1}";
2129 return "%vmovq\t{%1, %0|%0, %1}";
2132 /* Handle AVX512 registers set. */
2133 if (EXT_REX_SSE_REG_P (operands[0])
2134 || EXT_REX_SSE_REG_P (operands[1]))
2135 return "vmovdqa64\t{%1, %0|%0, %1}";
2136 return "%vmovdqa\t{%1, %0|%0, %1}";
2139 gcc_assert (!TARGET_AVX);
2140 return "movlps\t{%1, %0|%0, %1}";
2142 return "%vmovaps\t{%1, %0|%0, %1}";
2149 if (SSE_REG_P (operands[0]))
2150 return "movq2dq\t{%1, %0|%0, %1}";
2152 return "movdq2q\t{%1, %0|%0, %1}";
2155 return "lea{q}\t{%E1, %0|%0, %E1}";
2158 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2159 if (get_attr_mode (insn) == MODE_SI)
2160 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2161 else if (which_alternative == 4)
2162 return "movabs{q}\t{%1, %0|%0, %1}";
2163 else if (ix86_use_lea_for_mov (insn, operands))
2164 return "lea{q}\t{%E1, %0|%0, %E1}";
2166 return "mov{q}\t{%1, %0|%0, %1}";
2173 (cond [(eq_attr "alternative" "0,1,17,18")
2174 (const_string "nox64")
2175 (eq_attr "alternative" "2,3,4,5,10,11,23,25")
2176 (const_string "x64")
2177 (eq_attr "alternative" "19,20")
2178 (const_string "x64_sse2")
2179 (eq_attr "alternative" "21,22")
2180 (const_string "sse2")
2182 (const_string "*")))
2184 (cond [(eq_attr "alternative" "0,1,17,18")
2185 (const_string "multi")
2186 (eq_attr "alternative" "6")
2187 (const_string "mmx")
2188 (eq_attr "alternative" "7,8,9,10,11")
2189 (const_string "mmxmov")
2190 (eq_attr "alternative" "12")
2191 (const_string "sselog1")
2192 (eq_attr "alternative" "13,14,15,16,19,20")
2193 (const_string "ssemov")
2194 (eq_attr "alternative" "21,22")
2195 (const_string "ssecvt")
2196 (eq_attr "alternative" "23,24,25,26")
2197 (const_string "mskmov")
2198 (eq_attr "alternative" "27")
2199 (const_string "msklog")
2200 (and (match_operand 0 "register_operand")
2201 (match_operand 1 "pic_32bit_operand"))
2202 (const_string "lea")
2204 (const_string "imov")))
2207 (and (eq_attr "alternative" "4") (eq_attr "type" "imov"))
2209 (const_string "*")))
2210 (set (attr "length_immediate")
2212 (and (eq_attr "alternative" "4") (eq_attr "type" "imov"))
2214 (const_string "*")))
2215 (set (attr "prefix_rex")
2217 (eq_attr "alternative" "10,11,19,20")
2219 (const_string "*")))
2220 (set (attr "prefix")
2221 (if_then_else (eq_attr "type" "sselog1,ssemov")
2222 (const_string "maybe_vex")
2223 (const_string "orig")))
2224 (set (attr "prefix_data16")
2225 (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "DI"))
2227 (const_string "*")))
2229 (cond [(eq_attr "alternative" "2")
2231 (eq_attr "alternative" "12,13")
2232 (cond [(ior (match_operand 0 "ext_sse_reg_operand")
2233 (match_operand 1 "ext_sse_reg_operand"))
2235 (ior (not (match_test "TARGET_SSE2"))
2236 (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL"))
2237 (const_string "V4SF")
2238 (match_test "TARGET_AVX")
2240 (match_test "optimize_function_for_size_p (cfun)")
2241 (const_string "V4SF")
2243 (const_string "TI"))
2245 (and (eq_attr "alternative" "14,15,16")
2246 (not (match_test "TARGET_SSE2")))
2247 (const_string "V2SF")
2249 (const_string "DI")))
2250 (set (attr "preferred_for_speed")
2251 (cond [(eq_attr "alternative" "10,17,19")
2252 (symbol_ref "TARGET_INTER_UNIT_MOVES_FROM_VEC")
2253 (eq_attr "alternative" "11,18,20")
2254 (symbol_ref "TARGET_INTER_UNIT_MOVES_TO_VEC")
2256 (symbol_ref "true")))
2257 (set (attr "enabled")
2258 (cond [(eq_attr "alternative" "15")
2260 (match_test "TARGET_STV && TARGET_SSE2")
2261 (symbol_ref "false")
2263 (eq_attr "alternative" "16")
2265 (match_test "TARGET_STV && TARGET_SSE2")
2267 (symbol_ref "false"))
2269 (const_string "*")))])
2272 [(set (match_operand:<DWI> 0 "general_reg_operand")
2273 (match_operand:<DWI> 1 "sse_reg_operand"))]
2275 && reload_completed"
2279 (parallel [(const_int 1)])))]
2281 operands[2] = gen_highpart (<MODE>mode, operands[0]);
2282 operands[3] = lowpart_subreg (<ssevecmode>mode, operands[1], <DWI>mode);
2284 emit_move_insn (gen_lowpart (<MODE>mode, operands[0]),
2285 gen_lowpart (<MODE>mode, operands[1]));
2289 [(set (match_operand:DWI 0 "nonimmediate_gr_operand")
2290 (match_operand:DWI 1 "general_gr_operand"))]
2293 "ix86_split_long_move (operands); DONE;")
2296 [(set (match_operand:DI 0 "sse_reg_operand")
2297 (match_operand:DI 1 "general_reg_operand"))]
2298 "!TARGET_64BIT && TARGET_SSE4_1
2299 && reload_completed"
2302 (vec_duplicate:V4SI (match_dup 3))
2306 operands[2] = lowpart_subreg (V4SImode, operands[0], DImode);
2307 operands[3] = gen_highpart (SImode, operands[1]);
2309 emit_move_insn (gen_lowpart (SImode, operands[0]),
2310 gen_lowpart (SImode, operands[1]));
2313 ;; movabsq $0x0012345678000000, %rax is longer
2314 ;; than movl $0x12345678, %eax; shlq $24, %rax.
2316 [(set (match_operand:DI 0 "register_operand")
2317 (match_operand:DI 1 "const_int_operand"))]
2319 && optimize_insn_for_size_p ()
2320 && LEGACY_INT_REG_P (operands[0])
2321 && !x86_64_immediate_operand (operands[1], DImode)
2322 && !x86_64_zext_immediate_operand (operands[1], DImode)
2323 && !((UINTVAL (operands[1]) >> ctz_hwi (UINTVAL (operands[1])))
2324 & ~(HOST_WIDE_INT) 0xffffffff)
2325 && peep2_regno_dead_p (0, FLAGS_REG)"
2326 [(set (match_dup 0) (match_dup 1))
2327 (parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
2328 (clobber (reg:CC FLAGS_REG))])]
2330 int shift = ctz_hwi (UINTVAL (operands[1]));
2331 operands[1] = gen_int_mode (UINTVAL (operands[1]) >> shift, DImode);
2332 operands[2] = gen_int_mode (shift, QImode);
2335 (define_insn "*movsi_internal"
2336 [(set (match_operand:SI 0 "nonimmediate_operand"
2337 "=r,m ,*y,*y,?*y,?m,?r,?*y,*v,*v,*v,m ,?r,?*v,*k,*k ,*rm,*k")
2338 (match_operand:SI 1 "general_operand"
2339 "g ,re,C ,*y,m ,*y,*y,r ,C ,*v,m ,*v,*v,r ,*r,*km,*k ,CBC"))]
2340 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2342 switch (get_attr_type (insn))
2345 return standard_sse_constant_opcode (insn, operands);
2348 return "kmovd\t{%1, %0|%0, %1}";
2351 if (operands[1] == const0_rtx)
2352 return "kxord\t%0, %0, %0";
2353 else if (operands[1] == constm1_rtx)
2354 return "kxnord\t%0, %0, %0";
2358 switch (get_attr_mode (insn))
2361 return "%vmovd\t{%1, %0|%0, %1}";
2363 return "%vmovdqa\t{%1, %0|%0, %1}";
2365 return "vmovdqa32\t{%g1, %g0|%g0, %g1}";
2368 return "%vmovaps\t{%1, %0|%0, %1}";
2371 gcc_assert (!TARGET_AVX);
2372 return "movss\t{%1, %0|%0, %1}";
2379 return "pxor\t%0, %0";
2382 switch (get_attr_mode (insn))
2385 return "movq\t{%1, %0|%0, %1}";
2387 return "movd\t{%1, %0|%0, %1}";
2394 return "lea{l}\t{%E1, %0|%0, %E1}";
2397 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2398 if (ix86_use_lea_for_mov (insn, operands))
2399 return "lea{l}\t{%E1, %0|%0, %E1}";
2401 return "mov{l}\t{%1, %0|%0, %1}";
2408 (cond [(eq_attr "alternative" "12,13")
2409 (const_string "sse2")
2411 (const_string "*")))
2413 (cond [(eq_attr "alternative" "2")
2414 (const_string "mmx")
2415 (eq_attr "alternative" "3,4,5,6,7")
2416 (const_string "mmxmov")
2417 (eq_attr "alternative" "8")
2418 (const_string "sselog1")
2419 (eq_attr "alternative" "9,10,11,12,13")
2420 (const_string "ssemov")
2421 (eq_attr "alternative" "14,15,16")
2422 (const_string "mskmov")
2423 (eq_attr "alternative" "17")
2424 (const_string "msklog")
2425 (and (match_operand 0 "register_operand")
2426 (match_operand 1 "pic_32bit_operand"))
2427 (const_string "lea")
2429 (const_string "imov")))
2430 (set (attr "prefix")
2431 (if_then_else (eq_attr "type" "sselog1,ssemov")
2432 (const_string "maybe_vex")
2433 (const_string "orig")))
2434 (set (attr "prefix_data16")
2435 (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
2437 (const_string "*")))
2439 (cond [(eq_attr "alternative" "2,3")
2441 (eq_attr "alternative" "8,9")
2442 (cond [(ior (match_operand 0 "ext_sse_reg_operand")
2443 (match_operand 1 "ext_sse_reg_operand"))
2445 (ior (not (match_test "TARGET_SSE2"))
2446 (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL"))
2447 (const_string "V4SF")
2448 (match_test "TARGET_AVX")
2450 (match_test "optimize_function_for_size_p (cfun)")
2451 (const_string "V4SF")
2453 (const_string "TI"))
2455 (and (eq_attr "alternative" "10,11")
2456 (not (match_test "TARGET_SSE2")))
2459 (const_string "SI")))
2460 (set (attr "preferred_for_speed")
2461 (cond [(eq_attr "alternative" "6,12")
2462 (symbol_ref "TARGET_INTER_UNIT_MOVES_FROM_VEC")
2463 (eq_attr "alternative" "7,13")
2464 (symbol_ref "TARGET_INTER_UNIT_MOVES_TO_VEC")
2466 (symbol_ref "true")))])
2468 (define_insn "*movhi_internal"
2469 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r ,r ,m ,k,k ,r,m,k")
2470 (match_operand:HI 1 "general_operand" "r ,rn,rm,rn,r,km,k,k,CBC"))]
2471 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2473 switch (get_attr_type (insn))
2476 /* movzwl is faster than movw on p2 due to partial word stalls,
2477 though not as fast as an aligned movl. */
2478 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
2481 switch (which_alternative)
2484 return "kmovw\t{%k1, %0|%0, %k1}";
2486 return "kmovw\t{%1, %k0|%k0, %1}";
2489 return "kmovw\t{%1, %0|%0, %1}";
2495 if (operands[1] == const0_rtx)
2496 return "kxorw\t%0, %0, %0";
2497 else if (operands[1] == constm1_rtx)
2498 return "kxnorw\t%0, %0, %0";
2502 if (get_attr_mode (insn) == MODE_SI)
2503 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2505 return "mov{w}\t{%1, %0|%0, %1}";
2509 (cond [(eq_attr "alternative" "4,5,6,7")
2510 (const_string "mskmov")
2511 (eq_attr "alternative" "8")
2512 (const_string "msklog")
2513 (match_test "optimize_function_for_size_p (cfun)")
2514 (const_string "imov")
2515 (and (eq_attr "alternative" "0")
2516 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2517 (not (match_test "TARGET_HIMODE_MATH"))))
2518 (const_string "imov")
2519 (and (eq_attr "alternative" "1,2")
2520 (match_operand:HI 1 "aligned_operand"))
2521 (const_string "imov")
2522 (and (match_test "TARGET_MOVX")
2523 (eq_attr "alternative" "0,2"))
2524 (const_string "imovx")
2526 (const_string "imov")))
2527 (set (attr "prefix")
2528 (if_then_else (eq_attr "alternative" "4,5,6,7,8")
2529 (const_string "vex")
2530 (const_string "orig")))
2532 (cond [(eq_attr "type" "imovx")
2534 (and (eq_attr "alternative" "1,2")
2535 (match_operand:HI 1 "aligned_operand"))
2537 (and (eq_attr "alternative" "0")
2538 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2539 (not (match_test "TARGET_HIMODE_MATH"))))
2542 (const_string "HI")))])
2544 ;; Situation is quite tricky about when to choose full sized (SImode) move
2545 ;; over QImode moves. For Q_REG -> Q_REG move we use full size only for
2546 ;; partial register dependency machines (such as AMD Athlon), where QImode
2547 ;; moves issue extra dependency and for partial register stalls machines
2548 ;; that don't use QImode patterns (and QImode move cause stall on the next
2551 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
2552 ;; register stall machines with, where we use QImode instructions, since
2553 ;; partial register stall can be caused there. Then we use movzx.
2555 (define_insn "*movqi_internal"
2556 [(set (match_operand:QI 0 "nonimmediate_operand"
2557 "=Q,R,r,q,q,r,r ,?r,m ,k,k,r,m,k,k,k")
2558 (match_operand:QI 1 "general_operand"
2559 "Q ,R,r,n,m,q,rn, m,qn,r,k,k,k,m,C,BC"))]
2560 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2566 switch (get_attr_type (insn))
2569 gcc_assert (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]));
2570 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
2573 switch (which_alternative)
2576 ops = "kmov%s\t{%%k1, %%0|%%0, %%k1}";
2579 ops = "kmov%s\t{%%1, %%k0|%%k0, %%1}";
2583 gcc_assert (TARGET_AVX512DQ);
2586 ops = "kmov%s\t{%%1, %%0|%%0, %%1}";
2592 suffix = (get_attr_mode (insn) == MODE_HI) ? "w" : "b";
2594 snprintf (buf, sizeof (buf), ops, suffix);
2595 output_asm_insn (buf, operands);
2599 if (operands[1] == const0_rtx)
2601 if (get_attr_mode (insn) == MODE_HI)
2602 return "kxorw\t%0, %0, %0";
2604 return "kxorb\t%0, %0, %0";
2606 else if (operands[1] == constm1_rtx)
2608 gcc_assert (TARGET_AVX512DQ);
2609 return "kxnorb\t%0, %0, %0";
2614 if (get_attr_mode (insn) == MODE_SI)
2615 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2617 return "mov{b}\t{%1, %0|%0, %1}";
2621 (cond [(eq_attr "alternative" "1,2")
2622 (const_string "x64")
2623 (eq_attr "alternative" "12,13,15")
2624 (const_string "avx512dq")
2626 (const_string "*")))
2628 (cond [(eq_attr "alternative" "9,10,11,12,13")
2629 (const_string "mskmov")
2630 (eq_attr "alternative" "14,15")
2631 (const_string "msklog")
2632 (and (eq_attr "alternative" "7")
2633 (not (match_operand:QI 1 "aligned_operand")))
2634 (const_string "imovx")
2635 (match_test "optimize_function_for_size_p (cfun)")
2636 (const_string "imov")
2637 (and (eq_attr "alternative" "5")
2638 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2639 (not (match_test "TARGET_QIMODE_MATH"))))
2640 (const_string "imov")
2641 (eq_attr "alternative" "5,7")
2642 (const_string "imovx")
2643 (and (match_test "TARGET_MOVX")
2644 (eq_attr "alternative" "4"))
2645 (const_string "imovx")
2647 (const_string "imov")))
2648 (set (attr "prefix")
2649 (if_then_else (eq_attr "alternative" "9,10,11,12,13,14,15")
2650 (const_string "vex")
2651 (const_string "orig")))
2653 (cond [(eq_attr "alternative" "5,6,7")
2655 (eq_attr "alternative" "8")
2657 (and (eq_attr "alternative" "9,10,11,14")
2658 (not (match_test "TARGET_AVX512DQ")))
2660 (eq_attr "type" "imovx")
2662 ;; For -Os, 8-bit immediates are always shorter than 32-bit
2664 (and (eq_attr "type" "imov")
2665 (and (eq_attr "alternative" "3")
2666 (match_test "optimize_function_for_size_p (cfun)")))
2668 ;; For -Os, movl where one or both operands are NON_Q_REGS
2669 ;; and both are LEGACY_REGS is shorter than movb.
2670 ;; Otherwise movb and movl sizes are the same, so decide purely
2671 ;; based on speed factors.
2672 (and (eq_attr "type" "imov")
2673 (and (eq_attr "alternative" "1")
2674 (match_test "optimize_function_for_size_p (cfun)")))
2676 (and (eq_attr "type" "imov")
2677 (and (eq_attr "alternative" "0,1,2,3")
2678 (and (match_test "TARGET_PARTIAL_REG_DEPENDENCY")
2679 (not (match_test "TARGET_PARTIAL_REG_STALL")))))
2681 ;; Avoid partial register stalls when not using QImode arithmetic
2682 (and (eq_attr "type" "imov")
2683 (and (eq_attr "alternative" "0,1,2,3")
2684 (and (match_test "TARGET_PARTIAL_REG_STALL")
2685 (not (match_test "TARGET_QIMODE_MATH")))))
2688 (const_string "QI")))])
2690 ;; Stores and loads of ax to arbitrary constant address.
2691 ;; We fake an second form of instruction to force reload to load address
2692 ;; into register when rax is not available
2693 (define_insn "*movabs<mode>_1"
2694 [(set (mem:SWI1248x (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2695 (match_operand:SWI1248x 1 "nonmemory_operand" "a,r<i>"))]
2696 "TARGET_LP64 && ix86_check_movabs (insn, 0)"
2698 /* Recover the full memory rtx. */
2699 operands[0] = SET_DEST (PATTERN (insn));
2700 switch (which_alternative)
2703 return "movabs{<imodesuffix>}\t{%1, %P0|<iptrsize> PTR [%P0], %1}";
2705 return "mov{<imodesuffix>}\t{%1, %0|%0, %1}";
2710 [(set_attr "type" "imov")
2711 (set_attr "modrm" "0,*")
2712 (set_attr "length_address" "8,0")
2713 (set_attr "length_immediate" "0,*")
2714 (set_attr "memory" "store")
2715 (set_attr "mode" "<MODE>")])
2717 (define_insn "*movabs<mode>_2"
2718 [(set (match_operand:SWI1248x 0 "register_operand" "=a,r")
2719 (mem:SWI1248x (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2720 "TARGET_LP64 && ix86_check_movabs (insn, 1)"
2722 /* Recover the full memory rtx. */
2723 operands[1] = SET_SRC (PATTERN (insn));
2724 switch (which_alternative)
2727 return "movabs{<imodesuffix>}\t{%P1, %0|%0, <iptrsize> PTR [%P1]}";
2729 return "mov{<imodesuffix>}\t{%1, %0|%0, %1}";
2734 [(set_attr "type" "imov")
2735 (set_attr "modrm" "0,*")
2736 (set_attr "length_address" "8,0")
2737 (set_attr "length_immediate" "0")
2738 (set_attr "memory" "load")
2739 (set_attr "mode" "<MODE>")])
2741 (define_insn "*swap<mode>"
2742 [(set (match_operand:SWI48 0 "register_operand" "+r")
2743 (match_operand:SWI48 1 "register_operand" "+r"))
2747 "xchg{<imodesuffix>}\t%1, %0"
2748 [(set_attr "type" "imov")
2749 (set_attr "mode" "<MODE>")
2750 (set_attr "pent_pair" "np")
2751 (set_attr "athlon_decode" "vector")
2752 (set_attr "amdfam10_decode" "double")
2753 (set_attr "bdver1_decode" "double")])
2755 (define_insn "*swap<mode>"
2756 [(set (match_operand:SWI12 0 "register_operand" "+<r>,r")
2757 (match_operand:SWI12 1 "register_operand" "+<r>,r"))
2762 xchg{<imodesuffix>}\t%1, %0
2764 [(set_attr "type" "imov")
2765 (set_attr "mode" "<MODE>,SI")
2766 (set (attr "preferred_for_size")
2767 (cond [(eq_attr "alternative" "0")
2768 (symbol_ref "false")]
2769 (symbol_ref "true")))
2770 ;; Potential partial reg stall on alternative 1.
2771 (set (attr "preferred_for_speed")
2772 (cond [(eq_attr "alternative" "1")
2773 (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
2774 (symbol_ref "true")))
2775 (set_attr "pent_pair" "np")
2776 (set_attr "athlon_decode" "vector")
2777 (set_attr "amdfam10_decode" "double")
2778 (set_attr "bdver1_decode" "double")])
2780 (define_expand "movstrict<mode>"
2781 [(set (strict_low_part (match_operand:SWI12 0 "nonimmediate_operand"))
2782 (match_operand:SWI12 1 "general_operand"))]
2785 if (TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun))
2787 if (SUBREG_P (operands[0])
2788 && GET_MODE_CLASS (GET_MODE (SUBREG_REG (operands[0]))) != MODE_INT)
2790 /* Don't generate memory->memory moves, go through a register */
2791 if (MEM_P (operands[0]) && MEM_P (operands[1]))
2792 operands[1] = force_reg (<MODE>mode, operands[1]);
2795 (define_insn "*movstrict<mode>_1"
2796 [(set (strict_low_part
2797 (match_operand:SWI12 0 "nonimmediate_operand" "+<r>m,<r>"))
2798 (match_operand:SWI12 1 "general_operand" "<r>n,m"))]
2799 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
2800 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2801 "mov{<imodesuffix>}\t{%1, %0|%0, %1}"
2802 [(set_attr "type" "imov")
2803 (set_attr "mode" "<MODE>")])
2805 (define_insn "*movstrict<mode>_xor"
2806 [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>"))
2807 (match_operand:SWI12 1 "const0_operand"))
2808 (clobber (reg:CC FLAGS_REG))]
2810 "xor{<imodesuffix>}\t%0, %0"
2811 [(set_attr "type" "alu1")
2812 (set_attr "mode" "<MODE>")
2813 (set_attr "length_immediate" "0")])
2815 (define_expand "extv<mode>"
2816 [(set (match_operand:SWI24 0 "register_operand")
2817 (sign_extract:SWI24 (match_operand:SWI24 1 "register_operand")
2818 (match_operand:SI 2 "const_int_operand")
2819 (match_operand:SI 3 "const_int_operand")))]
2822 /* Handle extractions from %ah et al. */
2823 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
2826 unsigned int regno = reg_or_subregno (operands[1]);
2828 /* Be careful to expand only with registers having upper parts. */
2829 if (regno <= LAST_VIRTUAL_REGISTER && !QI_REGNO_P (regno))
2830 operands[1] = copy_to_reg (operands[1]);
2833 (define_insn "*extv<mode>"
2834 [(set (match_operand:SWI24 0 "register_operand" "=R")
2835 (sign_extract:SWI24 (match_operand 1 "ext_register_operand" "Q")
2839 "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
2840 [(set_attr "type" "imovx")
2841 (set_attr "mode" "SI")])
2843 (define_expand "extzv<mode>"
2844 [(set (match_operand:SWI248 0 "register_operand")
2845 (zero_extract:SWI248 (match_operand:SWI248 1 "register_operand")
2846 (match_operand:SI 2 "const_int_operand")
2847 (match_operand:SI 3 "const_int_operand")))]
2850 if (ix86_expand_pextr (operands))
2853 /* Handle extractions from %ah et al. */
2854 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
2857 unsigned int regno = reg_or_subregno (operands[1]);
2859 /* Be careful to expand only with registers having upper parts. */
2860 if (regno <= LAST_VIRTUAL_REGISTER && !QI_REGNO_P (regno))
2861 operands[1] = copy_to_reg (operands[1]);
2864 (define_insn "*extzvqi_mem_rex64"
2865 [(set (match_operand:QI 0 "norex_memory_operand" "=Bn")
2867 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q")
2870 "TARGET_64BIT && reload_completed"
2871 "mov{b}\t{%h1, %0|%0, %h1}"
2872 [(set_attr "type" "imov")
2873 (set_attr "mode" "QI")])
2875 (define_insn "*extzv<mode>"
2876 [(set (match_operand:SWI248 0 "register_operand" "=R")
2877 (zero_extract:SWI248 (match_operand 1 "ext_register_operand" "Q")
2881 "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
2882 [(set_attr "type" "imovx")
2883 (set_attr "mode" "SI")])
2885 (define_insn "*extzvqi"
2886 [(set (match_operand:QI 0 "nonimmediate_operand" "=QBc,?R,m")
2888 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q,Q")
2893 switch (get_attr_type (insn))
2896 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2898 return "mov{b}\t{%h1, %0|%0, %h1}";
2901 [(set_attr "isa" "*,*,nox64")
2903 (if_then_else (and (match_operand:QI 0 "register_operand")
2904 (ior (not (match_operand:QI 0 "QIreg_operand"))
2905 (match_test "TARGET_MOVX")))
2906 (const_string "imovx")
2907 (const_string "imov")))
2909 (if_then_else (eq_attr "type" "imovx")
2911 (const_string "QI")))])
2914 [(set (match_operand:QI 0 "register_operand")
2916 (zero_extract:SI (match_operand 1 "ext_register_operand")
2919 (set (match_operand:QI 2 "norex_memory_operand") (match_dup 0))]
2921 && peep2_reg_dead_p (2, operands[0])"
2924 (zero_extract:SI (match_dup 1)
2926 (const_int 8)) 0))])
2928 (define_expand "insv<mode>"
2929 [(set (zero_extract:SWI248 (match_operand:SWI248 0 "register_operand")
2930 (match_operand:SI 1 "const_int_operand")
2931 (match_operand:SI 2 "const_int_operand"))
2932 (match_operand:SWI248 3 "register_operand"))]
2937 if (ix86_expand_pinsr (operands))
2940 /* Handle insertions to %ah et al. */
2941 if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
2944 unsigned int regno = reg_or_subregno (operands[0]);
2946 /* Be careful to expand only with registers having upper parts. */
2947 if (regno <= LAST_VIRTUAL_REGISTER && !QI_REGNO_P (regno))
2948 dst = copy_to_reg (operands[0]);
2952 emit_insn (gen_insv<mode>_1 (dst, operands[3]));
2954 /* Fix up the destination if needed. */
2955 if (dst != operands[0])
2956 emit_move_insn (operands[0], dst);
2961 (define_insn "*insvqi_1_mem_rex64"
2962 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2966 (match_operand:QI 1 "norex_memory_operand" "Bn") 0))]
2967 "TARGET_64BIT && reload_completed"
2968 "mov{b}\t{%1, %h0|%h0, %1}"
2969 [(set_attr "type" "imov")
2970 (set_attr "mode" "QI")])
2972 (define_insn "insv<mode>_1"
2973 [(set (zero_extract:SWI248 (match_operand 0 "ext_register_operand" "+Q,Q")
2976 (match_operand:SWI248 1 "general_operand" "QnBc,m"))]
2979 if (CONST_INT_P (operands[1]))
2980 operands[1] = gen_int_mode (INTVAL (operands[1]), QImode);
2981 return "mov{b}\t{%b1, %h0|%h0, %b1}";
2983 [(set_attr "isa" "*,nox64")
2984 (set_attr "type" "imov")
2985 (set_attr "mode" "QI")])
2987 (define_insn "*insvqi_1"
2988 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q,Q")
2992 (match_operand:QI 1 "general_operand" "QnBc,m") 0))]
2994 "mov{b}\t{%1, %h0|%h0, %1}"
2995 [(set_attr "isa" "*,nox64")
2996 (set_attr "type" "imov")
2997 (set_attr "mode" "QI")])
3000 [(set (match_operand:QI 0 "register_operand")
3001 (match_operand:QI 1 "norex_memory_operand"))
3002 (set (zero_extract:SI (match_operand 2 "ext_register_operand")
3005 (subreg:SI (match_dup 0) 0))]
3007 && peep2_reg_dead_p (2, operands[0])"
3008 [(set (zero_extract:SI (match_dup 2)
3011 (subreg:SI (match_dup 1) 0))])
3013 (define_code_iterator any_extract [sign_extract zero_extract])
3015 (define_insn "*insvqi_2"
3016 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
3019 (any_extract:SI (match_operand 1 "ext_register_operand" "Q")
3023 "mov{b}\t{%h1, %h0|%h0, %h1}"
3024 [(set_attr "type" "imov")
3025 (set_attr "mode" "QI")])
3027 (define_insn "*insvqi_3"
3028 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
3031 (any_shiftrt:SI (match_operand:SI 1 "register_operand" "Q")
3034 "mov{b}\t{%h1, %h0|%h0, %h1}"
3035 [(set_attr "type" "imov")
3036 (set_attr "mode" "QI")])
3038 ;; Floating point push instructions.
3040 (define_insn "*pushtf"
3041 [(set (match_operand:TF 0 "push_operand" "=<,<")
3042 (match_operand:TF 1 "general_no_elim_operand" "v,*roC"))]
3043 "TARGET_64BIT || TARGET_SSE"
3045 /* This insn should be already split before reg-stack. */
3048 [(set_attr "isa" "*,x64")
3049 (set_attr "type" "multi")
3050 (set_attr "unit" "sse,*")
3051 (set_attr "mode" "TF,DI")])
3053 ;; %%% Kill this when call knows how to work this out.
3055 [(set (match_operand:TF 0 "push_operand")
3056 (match_operand:TF 1 "sse_reg_operand"))]
3057 "TARGET_SSE && reload_completed"
3058 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -16)))
3059 (set (match_dup 0) (match_dup 1))]
3061 /* Preserve memory attributes. */
3062 operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
3065 (define_insn_and_split "*pushxf_rounded"
3069 (plus:P (reg:P SP_REG) (const_int -16))))
3070 (match_operand:XF 0 "nonmemory_no_elim_operand" "f,r,*r,C"))]
3074 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -16)))
3075 (set (match_dup 1) (match_dup 0))]
3077 rtx pat = PATTERN (curr_insn);
3078 operands[1] = SET_DEST (pat);
3080 /* Preserve memory attributes. */
3081 operands[1] = replace_equiv_address (operands[1], stack_pointer_rtx);
3083 [(set_attr "type" "multi")
3084 (set_attr "unit" "i387,*,*,*")
3086 (cond [(eq_attr "alternative" "1,2,3")
3089 (const_string "XF")))
3090 (set (attr "preferred_for_size")
3091 (cond [(eq_attr "alternative" "1")
3092 (symbol_ref "false")]
3093 (symbol_ref "true")))])
3095 (define_insn "*pushxf"
3096 [(set (match_operand:XF 0 "push_operand" "=<,<,<,<,<")
3097 (match_operand:XF 1 "general_no_elim_operand" "f,r,*r,oF,oC"))]
3100 /* This insn should be already split before reg-stack. */
3103 [(set_attr "isa" "*,*,*,nox64,x64")
3104 (set_attr "type" "multi")
3105 (set_attr "unit" "i387,*,*,*,*")
3107 (cond [(eq_attr "alternative" "1,2,3,4")
3108 (if_then_else (match_test "TARGET_64BIT")
3110 (const_string "SI"))
3112 (const_string "XF")))
3113 (set (attr "preferred_for_size")
3114 (cond [(eq_attr "alternative" "1")
3115 (symbol_ref "false")]
3116 (symbol_ref "true")))])
3118 ;; %%% Kill this when call knows how to work this out.
3120 [(set (match_operand:XF 0 "push_operand")
3121 (match_operand:XF 1 "fp_register_operand"))]
3123 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
3124 (set (match_dup 0) (match_dup 1))]
3126 operands[2] = GEN_INT (-PUSH_ROUNDING (GET_MODE_SIZE (XFmode)));
3127 /* Preserve memory attributes. */
3128 operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
3131 (define_insn "*pushdf"
3132 [(set (match_operand:DF 0 "push_operand" "=<,<,<,<,<,<")
3133 (match_operand:DF 1 "general_no_elim_operand" "f,r,*r,oF,rmC,x"))]
3136 /* This insn should be already split before reg-stack. */
3139 [(set_attr "isa" "*,nox64,nox64,nox64,x64,sse2")
3140 (set_attr "type" "multi")
3141 (set_attr "unit" "i387,*,*,*,*,sse")
3142 (set_attr "mode" "DF,SI,SI,SI,DI,DF")
3143 (set (attr "preferred_for_size")
3144 (cond [(eq_attr "alternative" "1")
3145 (symbol_ref "false")]
3146 (symbol_ref "true")))
3147 (set (attr "preferred_for_speed")
3148 (cond [(eq_attr "alternative" "1")
3149 (symbol_ref "TARGET_INTEGER_DFMODE_MOVES")]
3150 (symbol_ref "true")))])
3152 ;; %%% Kill this when call knows how to work this out.
3154 [(set (match_operand:DF 0 "push_operand")
3155 (match_operand:DF 1 "any_fp_register_operand"))]
3157 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
3158 (set (match_dup 0) (match_dup 1))]
3160 /* Preserve memory attributes. */
3161 operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
3164 (define_insn "*pushsf_rex64"
3165 [(set (match_operand:SF 0 "push_operand" "=X,X,X")
3166 (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
3169 /* Anything else should be already split before reg-stack. */
3170 gcc_assert (which_alternative == 1);
3171 return "push{q}\t%q1";
3173 [(set_attr "type" "multi,push,multi")
3174 (set_attr "unit" "i387,*,*")
3175 (set_attr "mode" "SF,DI,SF")])
3177 (define_insn "*pushsf"
3178 [(set (match_operand:SF 0 "push_operand" "=<,<,<")
3179 (match_operand:SF 1 "general_no_elim_operand" "f,rmF,x"))]
3182 /* Anything else should be already split before reg-stack. */
3183 gcc_assert (which_alternative == 1);
3184 return "push{l}\t%1";
3186 [(set_attr "type" "multi,push,multi")
3187 (set_attr "unit" "i387,*,*")
3188 (set_attr "mode" "SF,SI,SF")])
3190 ;; %%% Kill this when call knows how to work this out.
3192 [(set (match_operand:SF 0 "push_operand")
3193 (match_operand:SF 1 "any_fp_register_operand"))]
3195 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
3196 (set (match_dup 0) (match_dup 1))]
3198 rtx op = XEXP (operands[0], 0);
3199 if (GET_CODE (op) == PRE_DEC)
3201 gcc_assert (!TARGET_64BIT);
3206 op = XEXP (XEXP (op, 1), 1);
3207 gcc_assert (CONST_INT_P (op));
3210 /* Preserve memory attributes. */
3211 operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
3215 [(set (match_operand:SF 0 "push_operand")
3216 (match_operand:SF 1 "memory_operand"))]
3218 && find_constant_src (insn)"
3219 [(set (match_dup 0) (match_dup 2))]
3220 "operands[2] = find_constant_src (curr_insn);")
3223 [(set (match_operand 0 "push_operand")
3224 (match_operand 1 "general_gr_operand"))]
3226 && (GET_MODE (operands[0]) == TFmode
3227 || GET_MODE (operands[0]) == XFmode
3228 || GET_MODE (operands[0]) == DFmode)"
3230 "ix86_split_long_move (operands); DONE;")
3232 ;; Floating point move instructions.
3234 (define_expand "movtf"
3235 [(set (match_operand:TF 0 "nonimmediate_operand")
3236 (match_operand:TF 1 "nonimmediate_operand"))]
3237 "TARGET_64BIT || TARGET_SSE"
3238 "ix86_expand_move (TFmode, operands); DONE;")
3240 (define_expand "mov<mode>"
3241 [(set (match_operand:X87MODEF 0 "nonimmediate_operand")
3242 (match_operand:X87MODEF 1 "general_operand"))]
3244 "ix86_expand_move (<MODE>mode, operands); DONE;")
3246 (define_insn "*movtf_internal"
3247 [(set (match_operand:TF 0 "nonimmediate_operand" "=v,v ,m,?*r ,!o")
3248 (match_operand:TF 1 "general_operand" "C ,vm,v,*roF,*rC"))]
3249 "(TARGET_64BIT || TARGET_SSE)
3250 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3251 && (lra_in_progress || reload_completed
3252 || !CONST_DOUBLE_P (operands[1])
3253 || ((optimize_function_for_size_p (cfun)
3254 || (ix86_cmodel == CM_LARGE || ix86_cmodel == CM_LARGE_PIC))
3255 && standard_sse_constant_p (operands[1], TFmode) == 1
3256 && !memory_operand (operands[0], TFmode))
3257 || (!TARGET_MEMORY_MISMATCH_STALL
3258 && memory_operand (operands[0], TFmode)))"
3260 switch (get_attr_type (insn))
3263 return standard_sse_constant_opcode (insn, operands);
3266 /* Handle misaligned load/store since we
3267 don't have movmisaligntf pattern. */
3268 if (misaligned_operand (operands[0], TFmode)
3269 || misaligned_operand (operands[1], TFmode))
3271 if (get_attr_mode (insn) == MODE_V4SF)
3272 return "%vmovups\t{%1, %0|%0, %1}";
3273 else if (TARGET_AVX512VL
3274 && (EXT_REX_SSE_REG_P (operands[0])
3275 || EXT_REX_SSE_REG_P (operands[1])))
3276 return "vmovdqu64\t{%1, %0|%0, %1}";
3278 return "%vmovdqu\t{%1, %0|%0, %1}";
3282 if (get_attr_mode (insn) == MODE_V4SF)
3283 return "%vmovaps\t{%1, %0|%0, %1}";
3284 else if (TARGET_AVX512VL
3285 && (EXT_REX_SSE_REG_P (operands[0])
3286 || EXT_REX_SSE_REG_P (operands[1])))
3287 return "vmovdqa64\t{%1, %0|%0, %1}";
3289 return "%vmovdqa\t{%1, %0|%0, %1}";
3299 [(set_attr "isa" "*,*,*,x64,x64")
3300 (set_attr "type" "sselog1,ssemov,ssemov,multi,multi")
3301 (set (attr "prefix")
3302 (if_then_else (eq_attr "type" "sselog1,ssemov")
3303 (const_string "maybe_vex")
3304 (const_string "orig")))
3306 (cond [(eq_attr "alternative" "3,4")
3308 (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
3309 (const_string "V4SF")
3310 (and (eq_attr "alternative" "2")
3311 (match_test "TARGET_SSE_TYPELESS_STORES"))
3312 (const_string "V4SF")
3313 (match_test "TARGET_AVX")
3315 (ior (not (match_test "TARGET_SSE2"))
3316 (match_test "optimize_function_for_size_p (cfun)"))
3317 (const_string "V4SF")
3319 (const_string "TI")))])
3322 [(set (match_operand:TF 0 "nonimmediate_gr_operand")
3323 (match_operand:TF 1 "general_gr_operand"))]
3326 "ix86_split_long_move (operands); DONE;")
3328 ;; Possible store forwarding (partial memory) stall
3329 ;; in alternatives 4, 6, 7 and 8.
3330 (define_insn "*movxf_internal"
3331 [(set (match_operand:XF 0 "nonimmediate_operand"
3332 "=f,m,f,?r ,!o,?*r ,!o,!o,!o,r ,o ,o")
3333 (match_operand:XF 1 "general_operand"
3334 "fm,f,G,roF,r ,*roF,*r,F ,C ,roF,rF,rC"))]
3335 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3336 && (lra_in_progress || reload_completed
3337 || !CONST_DOUBLE_P (operands[1])
3338 || ((optimize_function_for_size_p (cfun)
3339 || (ix86_cmodel == CM_LARGE || ix86_cmodel == CM_LARGE_PIC))
3340 && standard_80387_constant_p (operands[1]) > 0
3341 && !memory_operand (operands[0], XFmode))
3342 || (!TARGET_MEMORY_MISMATCH_STALL
3343 && memory_operand (operands[0], XFmode))
3344 || !TARGET_HARD_XF_REGS)"
3346 switch (get_attr_type (insn))
3349 if (which_alternative == 2)
3350 return standard_80387_constant_opcode (operands[1]);
3351 return output_387_reg_move (insn, operands);
3361 (cond [(eq_attr "alternative" "7,10")
3362 (const_string "nox64")
3363 (eq_attr "alternative" "8,11")
3364 (const_string "x64")
3366 (const_string "*")))
3368 (cond [(eq_attr "alternative" "3,4,5,6,7,8,9,10,11")
3369 (const_string "multi")
3371 (const_string "fmov")))
3373 (cond [(eq_attr "alternative" "3,4,5,6,7,8,9,10,11")
3374 (if_then_else (match_test "TARGET_64BIT")
3376 (const_string "SI"))
3378 (const_string "XF")))
3379 (set (attr "preferred_for_size")
3380 (cond [(eq_attr "alternative" "3,4")
3381 (symbol_ref "false")]
3382 (symbol_ref "true")))
3383 (set (attr "enabled")
3384 (cond [(eq_attr "alternative" "9,10,11")
3386 (match_test "TARGET_HARD_XF_REGS")
3387 (symbol_ref "false")
3389 (not (match_test "TARGET_HARD_XF_REGS"))
3390 (symbol_ref "false")
3392 (const_string "*")))])
3395 [(set (match_operand:XF 0 "nonimmediate_gr_operand")
3396 (match_operand:XF 1 "general_gr_operand"))]
3399 "ix86_split_long_move (operands); DONE;")
3401 ;; Possible store forwarding (partial memory) stall in alternatives 4, 6 and 7.
3402 (define_insn "*movdf_internal"
3403 [(set (match_operand:DF 0 "nonimmediate_operand"
3404 "=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")
3405 (match_operand:DF 1 "general_operand"
3406 "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"))]
3407 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3408 && (lra_in_progress || reload_completed
3409 || !CONST_DOUBLE_P (operands[1])
3410 || ((optimize_function_for_size_p (cfun)
3411 || (ix86_cmodel == CM_LARGE || ix86_cmodel == CM_LARGE_PIC))
3412 && ((IS_STACK_MODE (DFmode)
3413 && standard_80387_constant_p (operands[1]) > 0)
3414 || (TARGET_SSE2 && TARGET_SSE_MATH
3415 && standard_sse_constant_p (operands[1], DFmode) == 1))
3416 && !memory_operand (operands[0], DFmode))
3417 || ((TARGET_64BIT || !TARGET_MEMORY_MISMATCH_STALL)
3418 && memory_operand (operands[0], DFmode))
3419 || !TARGET_HARD_DF_REGS)"
3421 switch (get_attr_type (insn))
3424 if (which_alternative == 2)
3425 return standard_80387_constant_opcode (operands[1]);
3426 return output_387_reg_move (insn, operands);
3432 if (get_attr_mode (insn) == MODE_SI)
3433 return "mov{l}\t{%1, %k0|%k0, %1}";
3434 else if (which_alternative == 11)
3435 return "movabs{q}\t{%1, %0|%0, %1}";
3437 return "mov{q}\t{%1, %0|%0, %1}";
3440 return standard_sse_constant_opcode (insn, operands);
3443 switch (get_attr_mode (insn))
3446 if (TARGET_AVX && REG_P (operands[0]) && REG_P (operands[1]))
3447 return "vmovsd\t{%d1, %0|%0, %d1}";
3448 return "%vmovsd\t{%1, %0|%0, %1}";
3451 return "%vmovaps\t{%1, %0|%0, %1}";
3453 return "vmovapd\t{%g1, %g0|%g0, %g1}";
3455 return "%vmovapd\t{%1, %0|%0, %1}";
3458 gcc_assert (!TARGET_AVX);
3459 return "movlps\t{%1, %0|%0, %1}";
3461 gcc_assert (!TARGET_AVX);
3462 return "movlpd\t{%1, %0|%0, %1}";
3465 /* Handle broken assemblers that require movd instead of movq. */
3466 if (!HAVE_AS_IX86_INTERUNIT_MOVQ
3467 && (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1])))
3468 return "%vmovd\t{%1, %0|%0, %1}";
3469 return "%vmovq\t{%1, %0|%0, %1}";
3480 (cond [(eq_attr "alternative" "3,4,5,6,7,22,23")
3481 (const_string "nox64")
3482 (eq_attr "alternative" "8,9,10,11,24,25")
3483 (const_string "x64")
3484 (eq_attr "alternative" "12,13,14,15")
3485 (const_string "sse2")
3486 (eq_attr "alternative" "20,21")
3487 (const_string "x64_sse2")
3489 (const_string "*")))
3491 (cond [(eq_attr "alternative" "0,1,2")
3492 (const_string "fmov")
3493 (eq_attr "alternative" "3,4,5,6,7,22,23")
3494 (const_string "multi")
3495 (eq_attr "alternative" "8,9,10,11,24,25")
3496 (const_string "imov")
3497 (eq_attr "alternative" "12,16")
3498 (const_string "sselog1")
3500 (const_string "ssemov")))
3502 (if_then_else (eq_attr "alternative" "11")
3504 (const_string "*")))
3505 (set (attr "length_immediate")
3506 (if_then_else (eq_attr "alternative" "11")
3508 (const_string "*")))
3509 (set (attr "prefix")
3510 (if_then_else (eq_attr "type" "sselog1,ssemov")
3511 (const_string "maybe_vex")
3512 (const_string "orig")))
3513 (set (attr "prefix_data16")
3515 (ior (and (eq_attr "type" "ssemov") (eq_attr "mode" "DI"))
3516 (eq_attr "mode" "V1DF"))
3518 (const_string "*")))
3520 (cond [(eq_attr "alternative" "3,4,5,6,7,10,22,23")
3522 (eq_attr "alternative" "8,9,11,20,21,24,25")
3525 /* xorps is one byte shorter for non-AVX targets. */
3526 (eq_attr "alternative" "12,16")
3527 (cond [(not (match_test "TARGET_SSE2"))
3528 (const_string "V4SF")
3529 (and (match_test "TARGET_AVX512F")
3530 (not (match_test "TARGET_PREFER_AVX256")))
3532 (match_test "TARGET_AVX")
3533 (const_string "V2DF")
3534 (match_test "optimize_function_for_size_p (cfun)")
3535 (const_string "V4SF")
3536 (match_test "TARGET_SSE_LOAD0_BY_PXOR")
3539 (const_string "V2DF"))
3541 /* For architectures resolving dependencies on
3542 whole SSE registers use movapd to break dependency
3543 chains, otherwise use short move to avoid extra work. */
3545 /* movaps is one byte shorter for non-AVX targets. */
3546 (eq_attr "alternative" "13,17")
3547 (cond [(and (ior (not (match_test "TARGET_PREFER_AVX256"))
3548 (not (match_test "TARGET_AVX512VL")))
3549 (ior (match_operand 0 "ext_sse_reg_operand")
3550 (match_operand 1 "ext_sse_reg_operand")))
3551 (const_string "V8DF")
3552 (ior (not (match_test "TARGET_SSE2"))
3553 (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL"))
3554 (const_string "V4SF")
3555 (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3556 (const_string "V2DF")
3557 (match_test "TARGET_AVX")
3559 (match_test "optimize_function_for_size_p (cfun)")
3560 (const_string "V4SF")
3562 (const_string "DF"))
3564 /* For architectures resolving dependencies on register
3565 parts we may avoid extra work to zero out upper part
3567 (eq_attr "alternative" "14,18")
3568 (cond [(not (match_test "TARGET_SSE2"))
3569 (const_string "V2SF")
3570 (match_test "TARGET_AVX")
3572 (match_test "TARGET_SSE_SPLIT_REGS")
3573 (const_string "V1DF")
3575 (const_string "DF"))
3577 (and (eq_attr "alternative" "15,19")
3578 (not (match_test "TARGET_SSE2")))
3579 (const_string "V2SF")
3581 (const_string "DF")))
3582 (set (attr "preferred_for_size")
3583 (cond [(eq_attr "alternative" "3,4")
3584 (symbol_ref "false")]
3585 (symbol_ref "true")))
3586 (set (attr "preferred_for_speed")
3587 (cond [(eq_attr "alternative" "3,4")
3588 (symbol_ref "TARGET_INTEGER_DFMODE_MOVES")
3589 (eq_attr "alternative" "20")
3590 (symbol_ref "TARGET_INTER_UNIT_MOVES_FROM_VEC")
3591 (eq_attr "alternative" "21")
3592 (symbol_ref "TARGET_INTER_UNIT_MOVES_TO_VEC")
3594 (symbol_ref "true")))
3595 (set (attr "enabled")
3596 (cond [(eq_attr "alternative" "22,23,24,25")
3598 (match_test "TARGET_HARD_DF_REGS")
3599 (symbol_ref "false")
3601 (not (match_test "TARGET_HARD_DF_REGS"))
3602 (symbol_ref "false")
3604 (const_string "*")))])
3607 [(set (match_operand:DF 0 "nonimmediate_gr_operand")
3608 (match_operand:DF 1 "general_gr_operand"))]
3609 "!TARGET_64BIT && reload_completed"
3611 "ix86_split_long_move (operands); DONE;")
3613 (define_insn "*movsf_internal"
3614 [(set (match_operand:SF 0 "nonimmediate_operand"
3615 "=Yf*f,m ,Yf*f,?r ,?m,v,v,v,m,?r,?v,!*y,!*y,!m,!r,!*y,r ,m")
3616 (match_operand:SF 1 "general_operand"
3617 "Yf*fm,Yf*f,G ,rmF,rF,C,v,m,v,v ,r ,*y ,m ,*y,*y,r ,rmF,rF"))]
3618 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3619 && (lra_in_progress || reload_completed
3620 || !CONST_DOUBLE_P (operands[1])
3621 || ((optimize_function_for_size_p (cfun)
3622 || (ix86_cmodel == CM_LARGE || ix86_cmodel == CM_LARGE_PIC))
3623 && ((IS_STACK_MODE (SFmode)
3624 && standard_80387_constant_p (operands[1]) > 0)
3625 || (TARGET_SSE && TARGET_SSE_MATH
3626 && standard_sse_constant_p (operands[1], SFmode) == 1)))
3627 || memory_operand (operands[0], SFmode)
3628 || !TARGET_HARD_SF_REGS)"
3630 switch (get_attr_type (insn))
3633 if (which_alternative == 2)
3634 return standard_80387_constant_opcode (operands[1]);
3635 return output_387_reg_move (insn, operands);
3638 return "mov{l}\t{%1, %0|%0, %1}";
3641 return standard_sse_constant_opcode (insn, operands);
3644 switch (get_attr_mode (insn))
3647 if (TARGET_AVX && REG_P (operands[0]) && REG_P (operands[1]))
3648 return "vmovss\t{%d1, %0|%0, %d1}";
3649 return "%vmovss\t{%1, %0|%0, %1}";
3652 return "vmovaps\t{%g1, %g0|%g0, %g1}";
3654 return "%vmovaps\t{%1, %0|%0, %1}";
3657 return "%vmovd\t{%1, %0|%0, %1}";
3664 switch (get_attr_mode (insn))
3667 return "movq\t{%1, %0|%0, %1}";
3669 return "movd\t{%1, %0|%0, %1}";
3680 (cond [(eq_attr "alternative" "14,15")
3681 (const_string "sse2")
3683 (const_string "*")))
3685 (cond [(eq_attr "alternative" "0,1,2")
3686 (const_string "fmov")
3687 (eq_attr "alternative" "3,4,16,17")
3688 (const_string "imov")
3689 (eq_attr "alternative" "5")
3690 (const_string "sselog1")
3691 (eq_attr "alternative" "11,12,13,14,15")
3692 (const_string "mmxmov")
3694 (const_string "ssemov")))
3695 (set (attr "prefix")
3696 (if_then_else (eq_attr "type" "sselog1,ssemov")
3697 (const_string "maybe_vex")
3698 (const_string "orig")))
3699 (set (attr "prefix_data16")
3700 (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
3702 (const_string "*")))
3704 (cond [(eq_attr "alternative" "3,4,9,10,12,13,14,15,16,17")
3706 (eq_attr "alternative" "11")
3708 (eq_attr "alternative" "5")
3709 (cond [(not (match_test "TARGET_SSE2"))
3710 (const_string "V4SF")
3711 (and (match_test "TARGET_AVX512F")
3712 (not (match_test "TARGET_PREFER_AVX256")))
3713 (const_string "V16SF")
3714 (match_test "TARGET_AVX")
3715 (const_string "V4SF")
3716 (match_test "optimize_function_for_size_p (cfun)")
3717 (const_string "V4SF")
3718 (match_test "TARGET_SSE_LOAD0_BY_PXOR")
3721 (const_string "V4SF"))
3723 /* For architectures resolving dependencies on
3724 whole SSE registers use APS move to break dependency
3725 chains, otherwise use short move to avoid extra work.
3727 Do the same for architectures resolving dependencies on
3728 the parts. While in DF mode it is better to always handle
3729 just register parts, the SF mode is different due to lack
3730 of instructions to load just part of the register. It is
3731 better to maintain the whole registers in single format
3732 to avoid problems on using packed logical operations. */
3733 (eq_attr "alternative" "6")
3734 (cond [(and (ior (not (match_test "TARGET_PREFER_AVX256"))
3735 (not (match_test "TARGET_AVX512VL")))
3736 (ior (match_operand 0 "ext_sse_reg_operand")
3737 (match_operand 1 "ext_sse_reg_operand")))
3738 (const_string "V16SF")
3739 (ior (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3740 (match_test "TARGET_SSE_SPLIT_REGS"))
3741 (const_string "V4SF")
3743 (const_string "SF"))
3745 (const_string "SF")))
3746 (set (attr "preferred_for_speed")
3747 (cond [(eq_attr "alternative" "9,14")
3748 (symbol_ref "TARGET_INTER_UNIT_MOVES_FROM_VEC")
3749 (eq_attr "alternative" "10,15")
3750 (symbol_ref "TARGET_INTER_UNIT_MOVES_TO_VEC")
3752 (symbol_ref "true")))
3753 (set (attr "enabled")
3754 (cond [(eq_attr "alternative" "16,17")
3756 (match_test "TARGET_HARD_SF_REGS")
3757 (symbol_ref "false")
3759 (not (match_test "TARGET_HARD_SF_REGS"))
3760 (symbol_ref "false")
3762 (const_string "*")))])
3765 [(set (match_operand 0 "any_fp_register_operand")
3766 (match_operand 1 "memory_operand"))]
3768 && (GET_MODE (operands[0]) == TFmode
3769 || GET_MODE (operands[0]) == XFmode
3770 || GET_MODE (operands[0]) == DFmode
3771 || GET_MODE (operands[0]) == SFmode)
3772 && ix86_standard_x87sse_constant_load_p (insn, operands[0])"
3773 [(set (match_dup 0) (match_dup 2))]
3774 "operands[2] = find_constant_src (curr_insn);")
3777 [(set (match_operand 0 "any_fp_register_operand")
3778 (float_extend (match_operand 1 "memory_operand")))]
3780 && (GET_MODE (operands[0]) == TFmode
3781 || GET_MODE (operands[0]) == XFmode
3782 || GET_MODE (operands[0]) == DFmode)
3783 && ix86_standard_x87sse_constant_load_p (insn, operands[0])"
3784 [(set (match_dup 0) (match_dup 2))]
3785 "operands[2] = find_constant_src (curr_insn);")
3787 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
3789 [(set (match_operand:X87MODEF 0 "fp_register_operand")
3790 (match_operand:X87MODEF 1 "immediate_operand"))]
3792 && (standard_80387_constant_p (operands[1]) == 8
3793 || standard_80387_constant_p (operands[1]) == 9)"
3794 [(set (match_dup 0)(match_dup 1))
3796 (neg:X87MODEF (match_dup 0)))]
3798 if (real_isnegzero (CONST_DOUBLE_REAL_VALUE (operands[1])))
3799 operands[1] = CONST0_RTX (<MODE>mode);
3801 operands[1] = CONST1_RTX (<MODE>mode);
3804 (define_insn "*swapxf"
3805 [(set (match_operand:XF 0 "register_operand" "+f")
3806 (match_operand:XF 1 "register_operand" "+f"))
3811 if (STACK_TOP_P (operands[0]))
3816 [(set_attr "type" "fxch")
3817 (set_attr "mode" "XF")])
3820 ;; Zero extension instructions
3822 (define_expand "zero_extendsidi2"
3823 [(set (match_operand:DI 0 "nonimmediate_operand")
3824 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand")))])
3826 (define_insn "*zero_extendsidi2"
3827 [(set (match_operand:DI 0 "nonimmediate_operand"
3828 "=r,?r,?o,r ,o,?*y,?!*y,$r,$v,$x,*x,*v,*r,*k")
3830 (match_operand:SI 1 "x86_64_zext_operand"
3831 "0 ,rm,r ,rmWz,0,r ,m ,v ,r ,m ,*x,*v,*k,*km")))]
3834 switch (get_attr_type (insn))
3837 if (ix86_use_lea_for_mov (insn, operands))
3838 return "lea{l}\t{%E1, %k0|%k0, %E1}";
3840 return "mov{l}\t{%1, %k0|%k0, %1}";
3846 return "movd\t{%1, %0|%0, %1}";
3849 if (SSE_REG_P (operands[0]) && SSE_REG_P (operands[1]))
3851 if (EXT_REX_SSE_REG_P (operands[0])
3852 || EXT_REX_SSE_REG_P (operands[1]))
3853 return "vpmovzxdq\t{%t1, %g0|%g0, %t1}";
3855 return "%vpmovzxdq\t{%1, %0|%0, %1}";
3858 if (GENERAL_REG_P (operands[0]))
3859 return "%vmovd\t{%1, %k0|%k0, %1}";
3861 return "%vmovd\t{%1, %0|%0, %1}";
3864 return "kmovd\t{%1, %k0|%k0, %1}";
3871 (cond [(eq_attr "alternative" "0,1,2")
3872 (const_string "nox64")
3873 (eq_attr "alternative" "3")
3874 (const_string "x64")
3875 (eq_attr "alternative" "7,8,9")
3876 (const_string "sse2")
3877 (eq_attr "alternative" "10")
3878 (const_string "sse4")
3879 (eq_attr "alternative" "11")
3880 (const_string "avx512f")
3881 (eq_attr "alternative" "12")
3882 (const_string "x64_avx512bw")
3883 (eq_attr "alternative" "13")
3884 (const_string "avx512bw")
3886 (const_string "*")))
3887 (set (attr "mmx_isa")
3888 (if_then_else (eq_attr "alternative" "5,6")
3889 (const_string "native")
3890 (const_string "*")))
3892 (cond [(eq_attr "alternative" "0,1,2,4")
3893 (const_string "multi")
3894 (eq_attr "alternative" "5,6")
3895 (const_string "mmxmov")
3896 (eq_attr "alternative" "7")
3897 (if_then_else (match_test "TARGET_64BIT")
3898 (const_string "ssemov")
3899 (const_string "multi"))
3900 (eq_attr "alternative" "8,9,10,11")
3901 (const_string "ssemov")
3902 (eq_attr "alternative" "12,13")
3903 (const_string "mskmov")
3905 (const_string "imovx")))
3906 (set (attr "prefix_extra")
3907 (if_then_else (eq_attr "alternative" "10,11")
3909 (const_string "*")))
3910 (set (attr "prefix")
3911 (if_then_else (eq_attr "type" "ssemov")
3912 (const_string "maybe_vex")
3913 (const_string "orig")))
3914 (set (attr "prefix_0f")
3915 (if_then_else (eq_attr "type" "imovx")
3917 (const_string "*")))
3919 (cond [(eq_attr "alternative" "5,6")
3921 (and (eq_attr "alternative" "7")
3922 (match_test "TARGET_64BIT"))
3924 (eq_attr "alternative" "8,10,11")
3927 (const_string "SI")))
3928 (set (attr "preferred_for_speed")
3929 (cond [(eq_attr "alternative" "7")
3930 (symbol_ref "TARGET_INTER_UNIT_MOVES_FROM_VEC")
3931 (eq_attr "alternative" "5,8")
3932 (symbol_ref "TARGET_INTER_UNIT_MOVES_TO_VEC")
3934 (symbol_ref "true")))])
3937 [(set (match_operand:DI 0 "memory_operand")
3938 (zero_extend:DI (match_operand:SI 1 "memory_operand")))]
3940 [(set (match_dup 4) (const_int 0))]
3941 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3944 [(set (match_operand:DI 0 "general_reg_operand")
3945 (zero_extend:DI (match_operand:SI 1 "general_reg_operand")))]
3946 "!TARGET_64BIT && reload_completed
3947 && REGNO (operands[0]) == REGNO (operands[1])"
3948 [(set (match_dup 4) (const_int 0))]
3949 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3952 [(set (match_operand:DI 0 "nonimmediate_gr_operand")
3953 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand")))]
3954 "!TARGET_64BIT && reload_completed
3955 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
3956 [(set (match_dup 3) (match_dup 1))
3957 (set (match_dup 4) (const_int 0))]
3958 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3960 (define_mode_attr kmov_isa
3961 [(QI "avx512dq") (HI "avx512f") (SI "avx512bw") (DI "avx512bw")])
3963 (define_insn "zero_extend<mode>di2"
3964 [(set (match_operand:DI 0 "register_operand" "=r,*r,*k")
3966 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m,*k,*km")))]
3969 movz{<imodesuffix>l|x}\t{%1, %k0|%k0, %1}
3970 kmov<mskmodesuffix>\t{%1, %k0|%k0, %1}
3971 kmov<mskmodesuffix>\t{%1, %k0|%k0, %1}"
3972 [(set_attr "isa" "*,<kmov_isa>,<kmov_isa>")
3973 (set_attr "type" "imovx,mskmov,mskmov")
3974 (set_attr "mode" "SI,<MODE>,<MODE>")])
3976 (define_expand "zero_extend<mode>si2"
3977 [(set (match_operand:SI 0 "register_operand")
3978 (zero_extend:SI (match_operand:SWI12 1 "nonimmediate_operand")))]
3981 if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3983 operands[1] = force_reg (<MODE>mode, operands[1]);
3984 emit_insn (gen_zero_extend<mode>si2_and (operands[0], operands[1]));
3989 (define_insn_and_split "zero_extend<mode>si2_and"
3990 [(set (match_operand:SI 0 "register_operand" "=r,?&<r>")
3992 (match_operand:SWI12 1 "nonimmediate_operand" "0,<r>m")))
3993 (clobber (reg:CC FLAGS_REG))]
3994 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3996 "&& reload_completed"
3997 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (match_dup 2)))
3998 (clobber (reg:CC FLAGS_REG))])]
4000 if (!REG_P (operands[1])
4001 || REGNO (operands[0]) != REGNO (operands[1]))
4003 ix86_expand_clear (operands[0]);
4005 gcc_assert (!TARGET_PARTIAL_REG_STALL);
4006 emit_insn (gen_movstrict<mode>
4007 (gen_lowpart (<MODE>mode, operands[0]), operands[1]));
4011 operands[2] = GEN_INT (GET_MODE_MASK (<MODE>mode));
4013 [(set_attr "type" "alu1")
4014 (set_attr "mode" "SI")])
4016 (define_insn "*zero_extend<mode>si2"
4017 [(set (match_operand:SI 0 "register_operand" "=r,*r,*k")
4019 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m,*k,*km")))]
4020 "!(TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))"
4022 movz{<imodesuffix>l|x}\t{%1, %0|%0, %1}
4023 kmov<mskmodesuffix>\t{%1, %0|%0, %1}
4024 kmov<mskmodesuffix>\t{%1, %0|%0, %1}"
4025 [(set_attr "isa" "*,<kmov_isa>,<kmov_isa>")
4026 (set_attr "type" "imovx,mskmov,mskmov")
4027 (set_attr "mode" "SI,<MODE>,<MODE>")])
4029 (define_expand "zero_extendqihi2"
4030 [(set (match_operand:HI 0 "register_operand")
4031 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand")))]
4034 if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
4036 operands[1] = force_reg (QImode, operands[1]);
4037 emit_insn (gen_zero_extendqihi2_and (operands[0], operands[1]));
4042 (define_insn_and_split "zero_extendqihi2_and"
4043 [(set (match_operand:HI 0 "register_operand" "=r,?&q")
4044 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
4045 (clobber (reg:CC FLAGS_REG))]
4046 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
4048 "&& reload_completed"
4049 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
4050 (clobber (reg:CC FLAGS_REG))])]
4052 if (!REG_P (operands[1])
4053 || REGNO (operands[0]) != REGNO (operands[1]))
4055 ix86_expand_clear (operands[0]);
4057 gcc_assert (!TARGET_PARTIAL_REG_STALL);
4058 emit_insn (gen_movstrictqi
4059 (gen_lowpart (QImode, operands[0]), operands[1]));
4063 operands[0] = gen_lowpart (SImode, operands[0]);
4065 [(set_attr "type" "alu1")
4066 (set_attr "mode" "SI")])
4068 ; zero extend to SImode to avoid partial register stalls
4069 (define_insn "*zero_extendqihi2"
4070 [(set (match_operand:HI 0 "register_operand" "=r,*r,*k")
4071 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,*k,*km")))]
4072 "!(TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))"
4074 movz{bl|x}\t{%1, %k0|%k0, %1}
4075 kmovb\t{%1, %k0|%k0, %1}
4076 kmovb\t{%1, %0|%0, %1}"
4077 [(set_attr "isa" "*,avx512dq,avx512dq")
4078 (set_attr "type" "imovx,mskmov,mskmov")
4079 (set_attr "mode" "SI,QI,QI")])
4081 ;; Sign extension instructions
4083 (define_expand "extendsidi2"
4084 [(set (match_operand:DI 0 "register_operand")
4085 (sign_extend:DI (match_operand:SI 1 "register_operand")))]
4090 emit_insn (gen_extendsidi2_1 (operands[0], operands[1]));
4095 (define_insn "*extendsidi2_rex64"
4096 [(set (match_operand:DI 0 "register_operand" "=*a,r")
4097 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
4101 movs{lq|x}\t{%1, %0|%0, %1}"
4102 [(set_attr "type" "imovx")
4103 (set_attr "mode" "DI")
4104 (set_attr "prefix_0f" "0")
4105 (set_attr "modrm" "0,1")])
4107 (define_insn "extendsidi2_1"
4108 [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
4109 (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
4110 (clobber (reg:CC FLAGS_REG))
4111 (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
4115 ;; Split the memory case. If the source register doesn't die, it will stay
4116 ;; this way, if it does die, following peephole2s take care of it.
4118 [(set (match_operand:DI 0 "memory_operand")
4119 (sign_extend:DI (match_operand:SI 1 "register_operand")))
4120 (clobber (reg:CC FLAGS_REG))
4121 (clobber (match_operand:SI 2 "register_operand"))]
4125 split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
4127 emit_move_insn (operands[3], operands[1]);
4129 /* Generate a cltd if possible and doing so it profitable. */
4130 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
4131 && REGNO (operands[1]) == AX_REG
4132 && REGNO (operands[2]) == DX_REG)
4134 emit_insn (gen_ashrsi3_cvt (operands[2], operands[1], GEN_INT (31)));
4138 emit_move_insn (operands[2], operands[1]);
4139 emit_insn (gen_ashrsi3_cvt (operands[2], operands[2], GEN_INT (31)));
4141 emit_move_insn (operands[4], operands[2]);
4145 ;; Peepholes for the case where the source register does die, after
4146 ;; being split with the above splitter.
4148 [(set (match_operand:SI 0 "memory_operand")
4149 (match_operand:SI 1 "general_reg_operand"))
4150 (set (match_operand:SI 2 "general_reg_operand") (match_dup 1))
4151 (parallel [(set (match_dup 2)
4152 (ashiftrt:SI (match_dup 2) (const_int 31)))
4153 (clobber (reg:CC FLAGS_REG))])
4154 (set (match_operand:SI 3 "memory_operand") (match_dup 2))]
4155 "REGNO (operands[1]) != REGNO (operands[2])
4156 && peep2_reg_dead_p (2, operands[1])
4157 && peep2_reg_dead_p (4, operands[2])
4158 && !reg_mentioned_p (operands[2], operands[3])"
4159 [(set (match_dup 0) (match_dup 1))
4160 (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
4161 (clobber (reg:CC FLAGS_REG))])
4162 (set (match_dup 3) (match_dup 1))])
4165 [(set (match_operand:SI 0 "memory_operand")
4166 (match_operand:SI 1 "general_reg_operand"))
4167 (parallel [(set (match_operand:SI 2 "general_reg_operand")
4168 (ashiftrt:SI (match_dup 1) (const_int 31)))
4169 (clobber (reg:CC FLAGS_REG))])
4170 (set (match_operand:SI 3 "memory_operand") (match_dup 2))]
4171 "/* cltd is shorter than sarl $31, %eax */
4172 !optimize_function_for_size_p (cfun)
4173 && REGNO (operands[1]) == AX_REG
4174 && REGNO (operands[2]) == DX_REG
4175 && peep2_reg_dead_p (2, operands[1])
4176 && peep2_reg_dead_p (3, operands[2])
4177 && !reg_mentioned_p (operands[2], operands[3])"
4178 [(set (match_dup 0) (match_dup 1))
4179 (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
4180 (clobber (reg:CC FLAGS_REG))])
4181 (set (match_dup 3) (match_dup 1))])
4183 ;; Extend to register case. Optimize case where source and destination
4184 ;; registers match and cases where we can use cltd.
4186 [(set (match_operand:DI 0 "register_operand")
4187 (sign_extend:DI (match_operand:SI 1 "register_operand")))
4188 (clobber (reg:CC FLAGS_REG))
4189 (clobber (match_scratch:SI 2))]
4193 split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
4195 if (REGNO (operands[3]) != REGNO (operands[1]))
4196 emit_move_insn (operands[3], operands[1]);
4198 /* Generate a cltd if possible and doing so it profitable. */
4199 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
4200 && REGNO (operands[3]) == AX_REG
4201 && REGNO (operands[4]) == DX_REG)
4203 emit_insn (gen_ashrsi3_cvt (operands[4], operands[3], GEN_INT (31)));
4207 if (REGNO (operands[4]) != REGNO (operands[1]))
4208 emit_move_insn (operands[4], operands[1]);
4210 emit_insn (gen_ashrsi3_cvt (operands[4], operands[4], GEN_INT (31)));
4214 (define_insn "extend<mode>di2"
4215 [(set (match_operand:DI 0 "register_operand" "=r")
4217 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
4219 "movs{<imodesuffix>q|x}\t{%1, %0|%0, %1}"
4220 [(set_attr "type" "imovx")
4221 (set_attr "mode" "DI")])
4223 (define_insn "extendhisi2"
4224 [(set (match_operand:SI 0 "register_operand" "=*a,r")
4225 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
4228 switch (get_attr_prefix_0f (insn))
4231 return "{cwtl|cwde}";
4233 return "movs{wl|x}\t{%1, %0|%0, %1}";
4236 [(set_attr "type" "imovx")
4237 (set_attr "mode" "SI")
4238 (set (attr "prefix_0f")
4239 ;; movsx is short decodable while cwtl is vector decoded.
4240 (if_then_else (and (eq_attr "cpu" "!k6")
4241 (eq_attr "alternative" "0"))
4243 (const_string "1")))
4244 (set (attr "znver1_decode")
4245 (if_then_else (eq_attr "prefix_0f" "0")
4246 (const_string "double")
4247 (const_string "direct")))
4249 (if_then_else (eq_attr "prefix_0f" "0")
4251 (const_string "1")))])
4253 (define_insn "*extendhisi2_zext"
4254 [(set (match_operand:DI 0 "register_operand" "=*a,r")
4257 (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
4260 switch (get_attr_prefix_0f (insn))
4263 return "{cwtl|cwde}";
4265 return "movs{wl|x}\t{%1, %k0|%k0, %1}";
4268 [(set_attr "type" "imovx")
4269 (set_attr "mode" "SI")
4270 (set (attr "prefix_0f")
4271 ;; movsx is short decodable while cwtl is vector decoded.
4272 (if_then_else (and (eq_attr "cpu" "!k6")
4273 (eq_attr "alternative" "0"))
4275 (const_string "1")))
4277 (if_then_else (eq_attr "prefix_0f" "0")
4279 (const_string "1")))])
4281 (define_insn "extendqisi2"
4282 [(set (match_operand:SI 0 "register_operand" "=r")
4283 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
4285 "movs{bl|x}\t{%1, %0|%0, %1}"
4286 [(set_attr "type" "imovx")
4287 (set_attr "mode" "SI")])
4289 (define_insn "*extendqisi2_zext"
4290 [(set (match_operand:DI 0 "register_operand" "=r")
4292 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
4294 "movs{bl|x}\t{%1, %k0|%k0, %1}"
4295 [(set_attr "type" "imovx")
4296 (set_attr "mode" "SI")])
4298 (define_insn "extendqihi2"
4299 [(set (match_operand:HI 0 "register_operand" "=*a,r")
4300 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
4303 switch (get_attr_prefix_0f (insn))
4306 return "{cbtw|cbw}";
4308 return "movs{bw|x}\t{%1, %0|%0, %1}";
4311 [(set_attr "type" "imovx")
4312 (set_attr "mode" "HI")
4313 (set (attr "prefix_0f")
4314 ;; movsx is short decodable while cwtl is vector decoded.
4315 (if_then_else (and (eq_attr "cpu" "!k6")
4316 (eq_attr "alternative" "0"))
4318 (const_string "1")))
4320 (if_then_else (eq_attr "prefix_0f" "0")
4322 (const_string "1")))])
4324 ;; Conversions between float and double.
4326 ;; These are all no-ops in the model used for the 80387.
4327 ;; So just emit moves.
4329 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
4331 [(set (match_operand:DF 0 "push_operand")
4332 (float_extend:DF (match_operand:SF 1 "fp_register_operand")))]
4334 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
4335 (set (mem:DF (reg:P SP_REG)) (float_extend:DF (match_dup 1)))])
4338 [(set (match_operand:XF 0 "push_operand")
4339 (float_extend:XF (match_operand:MODEF 1 "fp_register_operand")))]
4341 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
4342 (set (mem:XF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
4343 "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
4345 (define_expand "extendsfdf2"
4346 [(set (match_operand:DF 0 "nonimm_ssenomem_operand")
4347 (float_extend:DF (match_operand:SF 1 "general_operand")))]
4348 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4350 /* ??? Needed for compress_float_constant since all fp constants
4351 are TARGET_LEGITIMATE_CONSTANT_P. */
4352 if (CONST_DOUBLE_P (operands[1]))
4354 if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
4355 && standard_80387_constant_p (operands[1]) > 0)
4357 operands[1] = simplify_const_unary_operation
4358 (FLOAT_EXTEND, DFmode, operands[1], SFmode);
4359 emit_move_insn_1 (operands[0], operands[1]);
4362 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
4366 (define_insn "*extendsfdf2"
4367 [(set (match_operand:DF 0 "nonimm_ssenomem_operand" "=f,m,v,v")
4369 (match_operand:SF 1 "nonimmediate_operand" "fm,f,v,m")))]
4370 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4372 switch (which_alternative)
4376 return output_387_reg_move (insn, operands);
4379 return "%vcvtss2sd\t{%d1, %0|%0, %d1}";
4381 return "%vcvtss2sd\t{%1, %d0|%d0, %1}";
4387 [(set_attr "type" "fmov,fmov,ssecvt,ssecvt")
4388 (set_attr "avx_partial_xmm_update" "false,false,false,true")
4389 (set_attr "prefix" "orig,orig,maybe_vex,maybe_vex")
4390 (set_attr "mode" "SF,XF,DF,DF")
4391 (set (attr "enabled")
4393 (match_test ("TARGET_SSE2 && TARGET_SSE_MATH"))
4395 (eq_attr "alternative" "0,1")
4396 (symbol_ref "TARGET_MIX_SSE_I387")
4397 (symbol_ref "true"))
4399 (eq_attr "alternative" "0,1")
4401 (symbol_ref "false"))))])
4403 /* For converting SF(xmm2) to DF(xmm1), use the following code instead of
4405 unpcklps xmm2,xmm2 ; packed conversion might crash on signaling NaNs
4407 We do the conversion post reload to avoid producing of 128bit spills
4408 that might lead to ICE on 32bit target. The sequence unlikely combine
4411 [(set (match_operand:DF 0 "sse_reg_operand")
4413 (match_operand:SF 1 "nonimmediate_operand")))]
4414 "TARGET_USE_VECTOR_FP_CONVERTS
4415 && optimize_insn_for_speed_p ()
4417 && (!EXT_REX_SSE_REG_P (operands[0])
4418 || TARGET_AVX512VL)"
4423 (parallel [(const_int 0) (const_int 1)]))))]
4425 operands[2] = lowpart_subreg (V2DFmode, operands[0], DFmode);
4426 operands[3] = lowpart_subreg (V4SFmode, operands[0], DFmode);
4427 /* Use movss for loading from memory, unpcklps reg, reg for registers.
4428 Try to avoid move when unpacking can be done in source. */
4429 if (REG_P (operands[1]))
4431 /* If it is unsafe to overwrite upper half of source, we need
4432 to move to destination and unpack there. */
4433 if (REGNO (operands[0]) != REGNO (operands[1])
4434 || (EXT_REX_SSE_REG_P (operands[1])
4435 && !TARGET_AVX512VL))
4437 rtx tmp = lowpart_subreg (SFmode, operands[0], DFmode);
4438 emit_move_insn (tmp, operands[1]);
4441 operands[3] = lowpart_subreg (V4SFmode, operands[1], SFmode);
4442 /* FIXME: vec_interleave_lowv4sf for AVX512VL should allow
4443 =v, v, then vbroadcastss will be only needed for AVX512F without
4445 if (!EXT_REX_SSE_REGNO_P (REGNO (operands[3])))
4446 emit_insn (gen_vec_interleave_lowv4sf (operands[3], operands[3],
4450 rtx tmp = lowpart_subreg (V16SFmode, operands[3], V4SFmode);
4451 emit_insn (gen_avx512f_vec_dupv16sf_1 (tmp, tmp));
4455 emit_insn (gen_vec_setv4sf_0 (operands[3],
4456 CONST0_RTX (V4SFmode), operands[1]));
4459 ;; It's more profitable to split and then extend in the same register.
4461 [(set (match_operand:DF 0 "sse_reg_operand")
4463 (match_operand:SF 1 "memory_operand")))]
4464 "TARGET_SPLIT_MEM_OPND_FOR_FP_CONVERTS
4465 && optimize_insn_for_speed_p ()"
4466 [(set (match_dup 2) (match_dup 1))
4467 (set (match_dup 0) (float_extend:DF (match_dup 2)))]
4468 "operands[2] = lowpart_subreg (SFmode, operands[0], DFmode);")
4470 ;; Break partial SSE register dependency stall. This splitter should split
4471 ;; late in the pass sequence (after register rename pass), so allocated
4472 ;; registers won't change anymore
4475 [(set (match_operand:DF 0 "sse_reg_operand")
4477 (match_operand:SF 1 "nonimmediate_operand")))]
4479 && TARGET_SSE_PARTIAL_REG_DEPENDENCY && epilogue_completed
4480 && optimize_function_for_speed_p (cfun)
4481 && (!REG_P (operands[1])
4482 || (!TARGET_AVX && REGNO (operands[0]) != REGNO (operands[1])))
4483 && (!EXT_REX_SSE_REG_P (operands[0])
4484 || TARGET_AVX512VL)"
4493 operands[0] = lowpart_subreg (V2DFmode, operands[0], DFmode);
4494 emit_move_insn (operands[0], CONST0_RTX (V2DFmode));
4497 (define_expand "extend<mode>xf2"
4498 [(set (match_operand:XF 0 "nonimmediate_operand")
4499 (float_extend:XF (match_operand:MODEF 1 "general_operand")))]
4502 /* ??? Needed for compress_float_constant since all fp constants
4503 are TARGET_LEGITIMATE_CONSTANT_P. */
4504 if (CONST_DOUBLE_P (operands[1]))
4506 if (standard_80387_constant_p (operands[1]) > 0)
4508 operands[1] = simplify_const_unary_operation
4509 (FLOAT_EXTEND, XFmode, operands[1], <MODE>mode);
4510 emit_move_insn_1 (operands[0], operands[1]);
4513 operands[1] = validize_mem (force_const_mem (<MODE>mode, operands[1]));
4517 (define_insn "*extend<mode>xf2_i387"
4518 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
4520 (match_operand:MODEF 1 "nonimmediate_operand" "fm,f")))]
4522 "* return output_387_reg_move (insn, operands);"
4523 [(set_attr "type" "fmov")
4524 (set_attr "mode" "<MODE>,XF")])
4526 ;; %%% This seems like bad news.
4527 ;; This cannot output into an f-reg because there is no way to be sure
4528 ;; of truncating in that case. Otherwise this is just like a simple move
4529 ;; insn. So we pretend we can output to a reg in order to get better
4530 ;; register preferencing, but we really use a stack slot.
4532 ;; Conversion from DFmode to SFmode.
4534 (define_insn "truncdfsf2"
4535 [(set (match_operand:SF 0 "nonimm_ssenomem_operand" "=m,f,v,v")
4537 (match_operand:DF 1 "register_ssemem_operand" "f,f,v,m")))]
4538 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4540 switch (which_alternative)
4544 return output_387_reg_move (insn, operands);
4547 return "%vcvtsd2ss\t{%d1, %0|%0, %d1}";
4549 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4555 [(set_attr "type" "fmov,fmov,ssecvt,ssecvt")
4556 (set_attr "avx_partial_xmm_update" "false,false,false,true")
4557 (set_attr "mode" "SF")
4558 (set (attr "enabled")
4560 (match_test ("TARGET_SSE2 && TARGET_SSE_MATH"))
4561 (cond [(eq_attr "alternative" "0")
4562 (symbol_ref "TARGET_MIX_SSE_I387")
4563 (eq_attr "alternative" "1")
4564 (symbol_ref "TARGET_MIX_SSE_I387
4565 && flag_unsafe_math_optimizations")
4567 (symbol_ref "true"))
4568 (cond [(eq_attr "alternative" "0")
4570 (eq_attr "alternative" "1")
4571 (symbol_ref "flag_unsafe_math_optimizations")
4573 (symbol_ref "false"))))])
4575 /* For converting DF(xmm2) to SF(xmm1), use the following code instead of
4577 unpcklpd xmm2,xmm2 ; packed conversion might crash on signaling NaNs
4579 We do the conversion post reload to avoid producing of 128bit spills
4580 that might lead to ICE on 32bit target. The sequence unlikely combine
4583 [(set (match_operand:SF 0 "sse_reg_operand")
4585 (match_operand:DF 1 "nonimmediate_operand")))]
4586 "TARGET_USE_VECTOR_FP_CONVERTS
4587 && optimize_insn_for_speed_p ()
4589 && (!EXT_REX_SSE_REG_P (operands[0])
4590 || TARGET_AVX512VL)"
4593 (float_truncate:V2SF
4597 operands[2] = lowpart_subreg (V4SFmode, operands[0], SFmode);
4598 operands[3] = CONST0_RTX (V2SFmode);
4599 operands[4] = lowpart_subreg (V2DFmode, operands[0], SFmode);
4600 /* Use movsd for loading from memory, unpcklpd for registers.
4601 Try to avoid move when unpacking can be done in source, or SSE3
4602 movddup is available. */
4603 if (REG_P (operands[1]))
4606 && REGNO (operands[0]) != REGNO (operands[1]))
4608 rtx tmp = lowpart_subreg (DFmode, operands[0], SFmode);
4609 emit_move_insn (tmp, operands[1]);
4612 else if (!TARGET_SSE3)
4613 operands[4] = lowpart_subreg (V2DFmode, operands[1], DFmode);
4614 emit_insn (gen_vec_dupv2df (operands[4], operands[1]));
4617 emit_insn (gen_vec_concatv2df (operands[4], operands[1],
4618 CONST0_RTX (DFmode)));
4621 ;; It's more profitable to split and then truncate in the same register.
4623 [(set (match_operand:SF 0 "sse_reg_operand")
4625 (match_operand:DF 1 "memory_operand")))]
4626 "TARGET_SPLIT_MEM_OPND_FOR_FP_CONVERTS
4627 && optimize_insn_for_speed_p ()"
4628 [(set (match_dup 2) (match_dup 1))
4629 (set (match_dup 0) (float_truncate:SF (match_dup 2)))]
4630 "operands[2] = lowpart_subreg (DFmode, operands[0], SFmode);")
4632 ;; Break partial SSE register dependency stall. This splitter should split
4633 ;; late in the pass sequence (after register rename pass), so allocated
4634 ;; registers won't change anymore
4637 [(set (match_operand:SF 0 "sse_reg_operand")
4639 (match_operand:DF 1 "nonimmediate_operand")))]
4641 && TARGET_SSE_PARTIAL_REG_DEPENDENCY && epilogue_completed
4642 && optimize_function_for_speed_p (cfun)
4643 && (!REG_P (operands[1])
4644 || (!TARGET_AVX && REGNO (operands[0]) != REGNO (operands[1])))
4645 && (!EXT_REX_SSE_REG_P (operands[0])
4646 || TARGET_AVX512VL)"
4655 operands[0] = lowpart_subreg (V4SFmode, operands[0], SFmode);
4656 emit_move_insn (operands[0], CONST0_RTX (V4SFmode));
4659 ;; Conversion from XFmode to {SF,DF}mode
4661 (define_insn "truncxf<mode>2"
4662 [(set (match_operand:MODEF 0 "nonimmediate_operand" "=m,f")
4663 (float_truncate:MODEF
4664 (match_operand:XF 1 "register_operand" "f,f")))]
4666 "* return output_387_reg_move (insn, operands);"
4667 [(set_attr "type" "fmov")
4668 (set_attr "mode" "<MODE>")
4669 (set (attr "enabled")
4670 (cond [(eq_attr "alternative" "1")
4671 (symbol_ref "flag_unsafe_math_optimizations")
4673 (symbol_ref "true")))])
4675 ;; Signed conversion to DImode.
4677 (define_expand "fix_truncxfdi2"
4678 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand")
4679 (fix:DI (match_operand:XF 1 "register_operand")))
4680 (clobber (reg:CC FLAGS_REG))])]
4685 emit_insn (gen_fix_truncdi_i387_fisttp (operands[0], operands[1]));
4690 (define_expand "fix_trunc<mode>di2"
4691 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand")
4692 (fix:DI (match_operand:MODEF 1 "register_operand")))
4693 (clobber (reg:CC FLAGS_REG))])]
4694 "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4697 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4699 emit_insn (gen_fix_truncdi_i387_fisttp (operands[0], operands[1]));
4702 if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4704 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4705 emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4706 if (out != operands[0])
4707 emit_move_insn (operands[0], out);
4712 ;; Signed conversion to SImode.
4714 (define_expand "fix_truncxfsi2"
4715 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand")
4716 (fix:SI (match_operand:XF 1 "register_operand")))
4717 (clobber (reg:CC FLAGS_REG))])]
4722 emit_insn (gen_fix_truncsi_i387_fisttp (operands[0], operands[1]));
4727 (define_expand "fix_trunc<mode>si2"
4728 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand")
4729 (fix:SI (match_operand:MODEF 1 "register_operand")))
4730 (clobber (reg:CC FLAGS_REG))])]
4731 "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4734 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4736 emit_insn (gen_fix_truncsi_i387_fisttp (operands[0], operands[1]));
4739 if (SSE_FLOAT_MODE_P (<MODE>mode))
4741 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4742 emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4743 if (out != operands[0])
4744 emit_move_insn (operands[0], out);
4749 ;; Signed conversion to HImode.
4751 (define_expand "fix_trunc<mode>hi2"
4752 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand")
4753 (fix:HI (match_operand:X87MODEF 1 "register_operand")))
4754 (clobber (reg:CC FLAGS_REG))])]
4756 && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4760 emit_insn (gen_fix_trunchi_i387_fisttp (operands[0], operands[1]));
4765 ;; Unsigned conversion to DImode
4767 (define_insn "fixuns_trunc<mode>di2"
4768 [(set (match_operand:DI 0 "register_operand" "=r")
4770 (match_operand:MODEF 1 "nonimmediate_operand" "vm")))]
4771 "TARGET_64BIT && TARGET_AVX512F && TARGET_SSE_MATH"
4772 "vcvtt<ssemodesuffix>2usi\t{%1, %0|%0, %1}"
4773 [(set_attr "type" "sseicvt")
4774 (set_attr "prefix" "evex")
4775 (set_attr "mode" "DI")])
4777 ;; Unsigned conversion to SImode.
4779 (define_expand "fixuns_trunc<mode>si2"
4781 [(set (match_operand:SI 0 "register_operand")
4783 (match_operand:MODEF 1 "nonimmediate_operand")))
4785 (clobber (match_scratch:<ssevecmode> 3))
4786 (clobber (match_scratch:<ssevecmode> 4))])]
4787 "(!TARGET_64BIT || TARGET_AVX512F) && TARGET_SSE2 && TARGET_SSE_MATH"
4789 machine_mode mode = <MODE>mode;
4790 machine_mode vecmode = <ssevecmode>mode;
4791 REAL_VALUE_TYPE TWO31r;
4796 emit_insn (gen_fixuns_trunc<mode>si2_avx512f (operands[0], operands[1]));
4800 if (optimize_insn_for_size_p ())
4803 real_ldexp (&TWO31r, &dconst1, 31);
4804 two31 = const_double_from_real_value (TWO31r, mode);
4805 two31 = ix86_build_const_vector (vecmode, true, two31);
4806 operands[2] = force_reg (vecmode, two31);
4809 (define_insn "fixuns_trunc<mode>si2_avx512f"
4810 [(set (match_operand:SI 0 "register_operand" "=r")
4812 (match_operand:MODEF 1 "nonimmediate_operand" "vm")))]
4813 "TARGET_AVX512F && TARGET_SSE_MATH"
4814 "vcvtt<ssemodesuffix>2usi\t{%1, %0|%0, %1}"
4815 [(set_attr "type" "sseicvt")
4816 (set_attr "prefix" "evex")
4817 (set_attr "mode" "SI")])
4819 (define_insn "*fixuns_trunc<mode>si2_avx512f_zext"
4820 [(set (match_operand:DI 0 "register_operand" "=r")
4823 (match_operand:MODEF 1 "nonimmediate_operand" "vm"))))]
4824 "TARGET_64BIT && TARGET_AVX512F && TARGET_SSE_MATH"
4825 "vcvtt<ssemodesuffix>2usi\t{%1, %k0|%k0, %1}"
4826 [(set_attr "type" "sseicvt")
4827 (set_attr "prefix" "evex")
4828 (set_attr "mode" "SI")])
4830 (define_insn_and_split "*fixuns_trunc<mode>_1"
4831 [(set (match_operand:SI 0 "register_operand" "=&x,&x")
4833 (match_operand:MODEF 3 "nonimmediate_operand" "xm,xm")))
4834 (use (match_operand:<ssevecmode> 4 "nonimmediate_operand" "m,x"))
4835 (clobber (match_scratch:<ssevecmode> 1 "=x,&x"))
4836 (clobber (match_scratch:<ssevecmode> 2 "=x,x"))]
4837 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH
4838 && optimize_function_for_speed_p (cfun)"
4840 "&& reload_completed"
4843 ix86_split_convert_uns_si_sse (operands);
4847 ;; Unsigned conversion to HImode.
4848 ;; Without these patterns, we'll try the unsigned SI conversion which
4849 ;; is complex for SSE, rather than the signed SI conversion, which isn't.
4851 (define_expand "fixuns_trunc<mode>hi2"
4853 (fix:SI (match_operand:MODEF 1 "nonimmediate_operand")))
4854 (set (match_operand:HI 0 "nonimmediate_operand")
4855 (subreg:HI (match_dup 2) 0))]
4856 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
4857 "operands[2] = gen_reg_rtx (SImode);")
4859 ;; When SSE is available, it is always faster to use it!
4860 (define_insn "fix_trunc<MODEF:mode><SWI48:mode>_sse"
4861 [(set (match_operand:SWI48 0 "register_operand" "=r,r")
4862 (fix:SWI48 (match_operand:MODEF 1 "nonimmediate_operand" "v,m")))]
4863 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode)
4864 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4865 "%vcvtt<MODEF:ssemodesuffix>2si<SWI48:rex64suffix>\t{%1, %0|%0, %1}"
4866 [(set_attr "type" "sseicvt")
4867 (set_attr "prefix" "maybe_vex")
4868 (set (attr "prefix_rex")
4870 (match_test "<SWI48:MODE>mode == DImode")
4872 (const_string "*")))
4873 (set_attr "mode" "<MODEF:MODE>")
4874 (set_attr "athlon_decode" "double,vector")
4875 (set_attr "amdfam10_decode" "double,double")
4876 (set_attr "bdver1_decode" "double,double")])
4878 ;; Avoid vector decoded forms of the instruction.
4880 [(match_scratch:MODEF 2 "x")
4881 (set (match_operand:SWI48 0 "register_operand")
4882 (fix:SWI48 (match_operand:MODEF 1 "memory_operand")))]
4883 "TARGET_AVOID_VECTOR_DECODE
4884 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode)
4885 && optimize_insn_for_speed_p ()"
4886 [(set (match_dup 2) (match_dup 1))
4887 (set (match_dup 0) (fix:SWI48 (match_dup 2)))])
4889 (define_insn "fix_trunc<mode>_i387_fisttp"
4890 [(set (match_operand:SWI248x 0 "nonimmediate_operand" "=m")
4891 (fix:SWI248x (match_operand 1 "register_operand" "f")))
4892 (clobber (match_scratch:XF 2 "=&f"))]
4893 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4895 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4896 && (TARGET_64BIT || <MODE>mode != DImode))
4897 && TARGET_SSE_MATH)"
4898 "* return output_fix_trunc (insn, operands, true);"
4899 [(set_attr "type" "fisttp")
4900 (set_attr "mode" "<MODE>")])
4902 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4903 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4904 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4905 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4906 ;; function in i386.c.
4907 (define_insn_and_split "*fix_trunc<mode>_i387_1"
4908 [(set (match_operand:SWI248x 0 "nonimmediate_operand")
4909 (fix:SWI248x (match_operand 1 "register_operand")))
4910 (clobber (reg:CC FLAGS_REG))]
4911 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4913 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4914 && (TARGET_64BIT || <MODE>mode != DImode))
4915 && can_create_pseudo_p ()"
4920 ix86_optimize_mode_switching[I387_TRUNC] = 1;
4922 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
4923 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
4925 emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4926 operands[2], operands[3]));
4929 [(set_attr "type" "fistp")
4930 (set_attr "i387_cw" "trunc")
4931 (set_attr "mode" "<MODE>")])
4933 (define_insn "fix_truncdi_i387"
4934 [(set (match_operand:DI 0 "nonimmediate_operand" "=m")
4935 (fix:DI (match_operand 1 "register_operand" "f")))
4936 (use (match_operand:HI 2 "memory_operand" "m"))
4937 (use (match_operand:HI 3 "memory_operand" "m"))
4938 (clobber (match_scratch:XF 4 "=&f"))]
4939 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4941 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4942 "* return output_fix_trunc (insn, operands, false);"
4943 [(set_attr "type" "fistp")
4944 (set_attr "i387_cw" "trunc")
4945 (set_attr "mode" "DI")])
4947 (define_insn "fix_trunc<mode>_i387"
4948 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m")
4949 (fix:SWI24 (match_operand 1 "register_operand" "f")))
4950 (use (match_operand:HI 2 "memory_operand" "m"))
4951 (use (match_operand:HI 3 "memory_operand" "m"))]
4952 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4954 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4955 "* return output_fix_trunc (insn, operands, false);"
4956 [(set_attr "type" "fistp")
4957 (set_attr "i387_cw" "trunc")
4958 (set_attr "mode" "<MODE>")])
4960 (define_insn "x86_fnstcw_1"
4961 [(set (match_operand:HI 0 "memory_operand" "=m")
4962 (unspec:HI [(const_int 0)] UNSPEC_FSTCW))]
4965 [(set (attr "length")
4966 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
4967 (set_attr "mode" "HI")
4968 (set_attr "unit" "i387")
4969 (set_attr "bdver1_decode" "vector")])
4971 ;; Conversion between fixed point and floating point.
4973 ;; Even though we only accept memory inputs, the backend _really_
4974 ;; wants to be able to do this between registers. Thankfully, LRA
4975 ;; will fix this up for us during register allocation.
4977 (define_insn "floathi<mode>2"
4978 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
4979 (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "m")))]
4981 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4982 || TARGET_MIX_SSE_I387)"
4984 [(set_attr "type" "fmov")
4985 (set_attr "mode" "<MODE>")
4986 (set_attr "znver1_decode" "double")
4987 (set_attr "fp_int_src" "true")])
4989 (define_insn "float<SWI48x:mode>xf2"
4990 [(set (match_operand:XF 0 "register_operand" "=f")
4991 (float:XF (match_operand:SWI48x 1 "nonimmediate_operand" "m")))]
4994 [(set_attr "type" "fmov")
4995 (set_attr "mode" "XF")
4996 (set_attr "znver1_decode" "double")
4997 (set_attr "fp_int_src" "true")])
4999 (define_expand "float<SWI48x:mode><MODEF:mode>2"
5000 [(set (match_operand:MODEF 0 "register_operand")
5001 (float:MODEF (match_operand:SWI48x 1 "nonimmediate_operand")))]
5002 "(TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI48x:MODE>mode))
5003 || (SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5004 && ((<SWI48x:MODE>mode != DImode) || TARGET_64BIT))")
5006 (define_insn "*float<SWI48:mode><MODEF:mode>2"
5007 [(set (match_operand:MODEF 0 "register_operand" "=f,v,v")
5009 (match_operand:SWI48 1 "nonimmediate_operand" "m,r,m")))]
5010 "(TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI48:MODE>mode))
5011 || (SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)"
5014 %vcvtsi2<MODEF:ssemodesuffix><SWI48:rex64suffix>\t{%1, %d0|%d0, %1}
5015 %vcvtsi2<MODEF:ssemodesuffix><SWI48:rex64suffix>\t{%1, %d0|%d0, %1}"
5016 [(set_attr "type" "fmov,sseicvt,sseicvt")
5017 (set_attr "avx_partial_xmm_update" "false,true,true")
5018 (set_attr "prefix" "orig,maybe_vex,maybe_vex")
5019 (set_attr "mode" "<MODEF:MODE>")
5020 (set (attr "prefix_rex")
5022 (and (eq_attr "prefix" "maybe_vex")
5023 (match_test "<SWI48:MODE>mode == DImode"))
5025 (const_string "*")))
5026 (set_attr "unit" "i387,*,*")
5027 (set_attr "athlon_decode" "*,double,direct")
5028 (set_attr "amdfam10_decode" "*,vector,double")
5029 (set_attr "bdver1_decode" "*,double,direct")
5030 (set_attr "znver1_decode" "double,*,*")
5031 (set_attr "fp_int_src" "true")
5032 (set (attr "enabled")
5034 (match_test ("SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"))
5036 (eq_attr "alternative" "0")
5037 (symbol_ref "TARGET_MIX_SSE_I387
5038 && X87_ENABLE_FLOAT (<MODEF:MODE>mode,
5040 (symbol_ref "true"))
5042 (eq_attr "alternative" "0")
5044 (symbol_ref "false"))))
5045 (set (attr "preferred_for_speed")
5046 (cond [(eq_attr "alternative" "1")
5047 (symbol_ref "TARGET_INTER_UNIT_CONVERSIONS")]
5048 (symbol_ref "true")))])
5050 (define_insn "*floatdi<MODEF:mode>2_i387"
5051 [(set (match_operand:MODEF 0 "register_operand" "=f")
5052 (float:MODEF (match_operand:DI 1 "nonimmediate_operand" "m")))]
5054 && TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, DImode)"
5056 [(set_attr "type" "fmov")
5057 (set_attr "mode" "<MODEF:MODE>")
5058 (set_attr "znver1_decode" "double")
5059 (set_attr "fp_int_src" "true")])
5061 ;; Try TARGET_USE_VECTOR_CONVERTS, but not so hard as to require extra memory
5062 ;; slots when !TARGET_INTER_UNIT_MOVES_TO_VEC disables the general_regs
5063 ;; alternative in sse2_loadld.
5065 [(set (match_operand:MODEF 0 "sse_reg_operand")
5066 (float:MODEF (match_operand:SI 1 "nonimmediate_operand")))]
5068 && TARGET_USE_VECTOR_CONVERTS
5069 && optimize_function_for_speed_p (cfun)
5071 && (MEM_P (operands[1]) || TARGET_INTER_UNIT_MOVES_TO_VEC)
5072 && (!EXT_REX_SSE_REG_P (operands[0])
5073 || TARGET_AVX512VL)"
5076 operands[3] = lowpart_subreg (<ssevecmode>mode, operands[0], <MODE>mode);
5077 operands[4] = lowpart_subreg (V4SImode, operands[0], <MODE>mode);
5079 emit_insn (gen_sse2_loadld (operands[4],
5080 CONST0_RTX (V4SImode), operands[1]));
5082 if (<ssevecmode>mode == V4SFmode)
5083 emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
5085 emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
5089 ;; Avoid store forwarding (partial memory) stall penalty
5090 ;; by passing DImode value through XMM registers. */
5093 [(set (match_operand:X87MODEF 0 "register_operand")
5095 (match_operand:DI 1 "register_operand")))]
5096 "!TARGET_64BIT && TARGET_INTER_UNIT_MOVES_TO_VEC
5097 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5098 && TARGET_SSE2 && optimize_function_for_speed_p (cfun)
5099 && can_create_pseudo_p ()"
5102 emit_insn (gen_floatdi<mode>2_i387_with_xmm
5103 (operands[0], operands[1],
5104 assign_386_stack_local (DImode, SLOT_TEMP)));
5108 (define_insn_and_split "floatdi<X87MODEF:mode>2_i387_with_xmm"
5109 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5111 (match_operand:DI 1 "register_operand" "r,r")))
5112 (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
5113 (clobber (match_scratch:V4SI 3 "=x,x"))
5114 (clobber (match_scratch:V4SI 4 "=X,x"))]
5115 "!TARGET_64BIT && TARGET_INTER_UNIT_MOVES_TO_VEC
5116 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5117 && TARGET_SSE2 && optimize_function_for_speed_p (cfun)"
5119 "&& reload_completed"
5120 [(set (match_dup 2) (match_dup 3))
5121 (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5123 /* The DImode arrived in a pair of integral registers (e.g. %edx:%eax).
5124 Assemble the 64-bit DImode value in an xmm register. */
5125 emit_insn (gen_sse2_loadld (operands[3], CONST0_RTX (V4SImode),
5126 gen_lowpart (SImode, operands[1])));
5128 emit_insn (gen_sse4_1_pinsrd (operands[3], operands[3],
5129 gen_highpart (SImode, operands[1]),
5133 emit_insn (gen_sse2_loadld (operands[4], CONST0_RTX (V4SImode),
5134 gen_highpart (SImode, operands[1])));
5135 emit_insn (gen_vec_interleave_lowv4si (operands[3], operands[3],
5138 operands[3] = gen_lowpart (DImode, operands[3]);
5140 [(set_attr "isa" "sse4,*")
5141 (set_attr "type" "multi")
5142 (set_attr "mode" "<X87MODEF:MODE>")
5143 (set_attr "unit" "i387")
5144 (set_attr "fp_int_src" "true")])
5146 ;; Break partial SSE register dependency stall. This splitter should split
5147 ;; late in the pass sequence (after register rename pass), so allocated
5148 ;; registers won't change anymore
5151 [(set (match_operand:MODEF 0 "sse_reg_operand")
5152 (float:MODEF (match_operand:SWI48 1 "nonimmediate_operand")))]
5154 && TARGET_SSE_PARTIAL_REG_DEPENDENCY && epilogue_completed
5155 && optimize_function_for_speed_p (cfun)
5156 && (!EXT_REX_SSE_REG_P (operands[0])
5157 || TARGET_AVX512VL)"
5159 (vec_merge:<MODEF:ssevecmode>
5160 (vec_duplicate:<MODEF:ssevecmode>
5166 const machine_mode vmode = <MODEF:ssevecmode>mode;
5168 operands[0] = lowpart_subreg (vmode, operands[0], <MODEF:MODE>mode);
5169 emit_move_insn (operands[0], CONST0_RTX (vmode));
5172 (define_expand "floatuns<SWI12:mode><MODEF:mode>2"
5173 [(set (match_operand:MODEF 0 "register_operand")
5174 (unsigned_float:MODEF
5175 (match_operand:SWI12 1 "nonimmediate_operand")))]
5177 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
5179 operands[1] = convert_to_mode (SImode, operands[1], 1);
5180 emit_insn (gen_floatsi<MODEF:mode>2 (operands[0], operands[1]));
5184 (define_insn "*floatuns<SWI48:mode><MODEF:mode>2_avx512"
5185 [(set (match_operand:MODEF 0 "register_operand" "=v")
5186 (unsigned_float:MODEF
5187 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))]
5188 "TARGET_AVX512F && TARGET_SSE_MATH"
5189 "vcvtusi2<MODEF:ssemodesuffix><SWI48:rex64suffix>\t{%1, %0, %0|%0, %0, %1}"
5190 [(set_attr "type" "sseicvt")
5191 (set_attr "prefix" "evex")
5192 (set_attr "mode" "<MODEF:MODE>")])
5194 ;; Avoid store forwarding (partial memory) stall penalty by extending
5195 ;; SImode value to DImode through XMM register instead of pushing two
5196 ;; SImode values to stack. Also note that fild loads from memory only.
5198 (define_insn_and_split "floatunssi<mode>2_i387_with_xmm"
5199 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5200 (unsigned_float:X87MODEF
5201 (match_operand:SI 1 "nonimmediate_operand" "rm")))
5202 (clobber (match_operand:DI 2 "memory_operand" "=m"))
5203 (clobber (match_scratch:DI 3 "=x"))]
5205 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5206 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC"
5208 "&& reload_completed"
5209 [(set (match_dup 3) (zero_extend:DI (match_dup 1)))
5210 (set (match_dup 2) (match_dup 3))
5212 (float:X87MODEF (match_dup 2)))]
5214 [(set_attr "type" "multi")
5215 (set_attr "mode" "<MODE>")])
5217 (define_expand "floatunssi<mode>2"
5218 [(set (match_operand:X87MODEF 0 "register_operand")
5219 (unsigned_float:X87MODEF
5220 (match_operand:SI 1 "nonimmediate_operand")))]
5222 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5223 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC)
5224 || ((!TARGET_64BIT || TARGET_AVX512F)
5225 && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
5227 if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
5229 emit_insn (gen_floatunssi<mode>2_i387_with_xmm
5230 (operands[0], operands[1],
5231 assign_386_stack_local (DImode, SLOT_TEMP)));
5234 if (!TARGET_AVX512F)
5236 ix86_expand_convert_uns_si<mode>_sse (operands[0], operands[1]);
5241 (define_expand "floatunsdisf2"
5242 [(set (match_operand:SF 0 "register_operand")
5244 (match_operand:DI 1 "nonimmediate_operand")))]
5245 "TARGET_64BIT && TARGET_SSE && TARGET_SSE_MATH"
5247 if (!TARGET_AVX512F)
5249 x86_emit_floatuns (operands);
5254 (define_expand "floatunsdidf2"
5255 [(set (match_operand:DF 0 "register_operand")
5257 (match_operand:DI 1 "nonimmediate_operand")))]
5258 "((TARGET_64BIT && TARGET_AVX512F)
5259 || TARGET_KEEPS_VECTOR_ALIGNED_STACK)
5260 && TARGET_SSE2 && TARGET_SSE_MATH"
5264 ix86_expand_convert_uns_didf_sse (operands[0], operands[1]);
5267 if (!TARGET_AVX512F)
5269 x86_emit_floatuns (operands);
5274 ;; Load effective address instructions
5276 (define_insn_and_split "*lea<mode>"
5277 [(set (match_operand:SWI48 0 "register_operand" "=r")
5278 (match_operand:SWI48 1 "address_no_seg_operand" "Ts"))]
5281 if (SImode_address_operand (operands[1], VOIDmode))
5283 gcc_assert (TARGET_64BIT);
5284 return "lea{l}\t{%E1, %k0|%k0, %E1}";
5287 return "lea{<imodesuffix>}\t{%E1, %0|%0, %E1}";
5289 "reload_completed && ix86_avoid_lea_for_addr (insn, operands)"
5292 machine_mode mode = <MODE>mode;
5295 /* ix86_avoid_lea_for_addr re-recognizes insn and may
5296 change operands[] array behind our back. */
5297 pat = PATTERN (curr_insn);
5299 operands[0] = SET_DEST (pat);
5300 operands[1] = SET_SRC (pat);
5302 /* Emit all operations in SImode for zero-extended addresses. */
5303 if (SImode_address_operand (operands[1], VOIDmode))
5306 ix86_split_lea_for_addr (curr_insn, operands, mode);
5308 /* Zero-extend return register to DImode for zero-extended addresses. */
5309 if (mode != <MODE>mode)
5310 emit_insn (gen_zero_extendsidi2
5311 (operands[0], gen_lowpart (mode, operands[0])));
5315 [(set_attr "type" "lea")
5318 (match_operand 1 "SImode_address_operand")
5320 (const_string "<MODE>")))])
5324 (define_expand "add<mode>3"
5325 [(set (match_operand:SDWIM 0 "nonimmediate_operand")
5326 (plus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")
5327 (match_operand:SDWIM 2 "<general_hilo_operand>")))]
5329 "ix86_expand_binary_operator (PLUS, <MODE>mode, operands); DONE;")
5331 (define_insn_and_split "*add<dwi>3_doubleword"
5332 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
5334 (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0")
5335 (match_operand:<DWI> 2 "x86_64_hilo_general_operand"
5337 (clobber (reg:CC FLAGS_REG))]
5338 "ix86_binary_operator_ok (PLUS, <DWI>mode, operands)"
5341 [(parallel [(set (reg:CCC FLAGS_REG)
5343 (plus:DWIH (match_dup 1) (match_dup 2))
5346 (plus:DWIH (match_dup 1) (match_dup 2)))])
5347 (parallel [(set (match_dup 3)
5350 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
5353 (clobber (reg:CC FLAGS_REG))])]
5355 split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
5356 if (operands[2] == const0_rtx)
5358 ix86_expand_binary_operator (PLUS, <MODE>mode, &operands[3]);
5363 (define_insn "*add<mode>_1"
5364 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,rm,r,r")
5366 (match_operand:SWI48 1 "nonimmediate_operand" "%0,0,r,r")
5367 (match_operand:SWI48 2 "x86_64_general_operand" "rme,re,0,le")))
5368 (clobber (reg:CC FLAGS_REG))]
5369 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5371 switch (get_attr_type (insn))
5377 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5378 if (operands[2] == const1_rtx)
5379 return "inc{<imodesuffix>}\t%0";
5382 gcc_assert (operands[2] == constm1_rtx);
5383 return "dec{<imodesuffix>}\t%0";
5387 /* For most processors, ADD is faster than LEA. This alternative
5388 was added to use ADD as much as possible. */
5389 if (which_alternative == 2)
5390 std::swap (operands[1], operands[2]);
5392 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5393 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5394 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5396 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5400 (cond [(eq_attr "alternative" "3")
5401 (const_string "lea")
5402 (match_operand:SWI48 2 "incdec_operand")
5403 (const_string "incdec")
5405 (const_string "alu")))
5406 (set (attr "length_immediate")
5408 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5410 (const_string "*")))
5411 (set_attr "mode" "<MODE>")])
5413 ;; It may seem that nonimmediate operand is proper one for operand 1.
5414 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5415 ;; we take care in ix86_binary_operator_ok to not allow two memory
5416 ;; operands so proper swapping will be done in reload. This allow
5417 ;; patterns constructed from addsi_1 to match.
5419 (define_insn "addsi_1_zext"
5420 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
5422 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r,r")
5423 (match_operand:SI 2 "x86_64_general_operand" "rme,0,le"))))
5424 (clobber (reg:CC FLAGS_REG))]
5425 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5427 switch (get_attr_type (insn))
5433 if (operands[2] == const1_rtx)
5434 return "inc{l}\t%k0";
5437 gcc_assert (operands[2] == constm1_rtx);
5438 return "dec{l}\t%k0";
5442 /* For most processors, ADD is faster than LEA. This alternative
5443 was added to use ADD as much as possible. */
5444 if (which_alternative == 1)
5445 std::swap (operands[1], operands[2]);
5447 if (x86_maybe_negate_const_int (&operands[2], SImode))
5448 return "sub{l}\t{%2, %k0|%k0, %2}";
5450 return "add{l}\t{%2, %k0|%k0, %2}";
5454 (cond [(eq_attr "alternative" "2")
5455 (const_string "lea")
5456 (match_operand:SI 2 "incdec_operand")
5457 (const_string "incdec")
5459 (const_string "alu")))
5460 (set (attr "length_immediate")
5462 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5464 (const_string "*")))
5465 (set_attr "mode" "SI")])
5467 (define_insn "*addhi_1"
5468 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r,Yp")
5469 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r,Yp")
5470 (match_operand:HI 2 "general_operand" "rn,rm,0,ln")))
5471 (clobber (reg:CC FLAGS_REG))]
5472 "ix86_binary_operator_ok (PLUS, HImode, operands)"
5474 switch (get_attr_type (insn))
5480 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5481 if (operands[2] == const1_rtx)
5482 return "inc{w}\t%0";
5485 gcc_assert (operands[2] == constm1_rtx);
5486 return "dec{w}\t%0";
5490 /* For most processors, ADD is faster than LEA. This alternative
5491 was added to use ADD as much as possible. */
5492 if (which_alternative == 2)
5493 std::swap (operands[1], operands[2]);
5495 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5496 if (x86_maybe_negate_const_int (&operands[2], HImode))
5497 return "sub{w}\t{%2, %0|%0, %2}";
5499 return "add{w}\t{%2, %0|%0, %2}";
5503 (cond [(eq_attr "alternative" "3")
5504 (const_string "lea")
5505 (match_operand:HI 2 "incdec_operand")
5506 (const_string "incdec")
5508 (const_string "alu")))
5509 (set (attr "length_immediate")
5511 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5513 (const_string "*")))
5514 (set_attr "mode" "HI,HI,HI,SI")])
5516 (define_insn "*addqi_1"
5517 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,q,r,r,Yp")
5518 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,q,0,r,Yp")
5519 (match_operand:QI 2 "general_operand" "qn,qm,0,rn,0,ln")))
5520 (clobber (reg:CC FLAGS_REG))]
5521 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5523 bool widen = (get_attr_mode (insn) != MODE_QI);
5525 switch (get_attr_type (insn))
5531 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5532 if (operands[2] == const1_rtx)
5533 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
5536 gcc_assert (operands[2] == constm1_rtx);
5537 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
5541 /* For most processors, ADD is faster than LEA. These alternatives
5542 were added to use ADD as much as possible. */
5543 if (which_alternative == 2 || which_alternative == 4)
5544 std::swap (operands[1], operands[2]);
5546 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5547 if (x86_maybe_negate_const_int (&operands[2], QImode))
5550 return "sub{l}\t{%2, %k0|%k0, %2}";
5552 return "sub{b}\t{%2, %0|%0, %2}";
5555 return "add{l}\t{%k2, %k0|%k0, %k2}";
5557 return "add{b}\t{%2, %0|%0, %2}";
5561 (cond [(eq_attr "alternative" "5")
5562 (const_string "lea")
5563 (match_operand:QI 2 "incdec_operand")
5564 (const_string "incdec")
5566 (const_string "alu")))
5567 (set (attr "length_immediate")
5569 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5571 (const_string "*")))
5572 (set_attr "mode" "QI,QI,QI,SI,SI,SI")
5573 ;; Potential partial reg stall on alternatives 3 and 4.
5574 (set (attr "preferred_for_speed")
5575 (cond [(eq_attr "alternative" "3,4")
5576 (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
5577 (symbol_ref "true")))])
5579 (define_insn "*addqi_1_slp"
5580 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
5581 (plus:QI (match_dup 0)
5582 (match_operand:QI 1 "general_operand" "qn,qm")))
5583 (clobber (reg:CC FLAGS_REG))]
5584 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
5585 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
5587 switch (get_attr_type (insn))
5590 if (operands[1] == const1_rtx)
5591 return "inc{b}\t%0";
5594 gcc_assert (operands[1] == constm1_rtx);
5595 return "dec{b}\t%0";
5599 if (x86_maybe_negate_const_int (&operands[1], QImode))
5600 return "sub{b}\t{%1, %0|%0, %1}";
5602 return "add{b}\t{%1, %0|%0, %1}";
5606 (if_then_else (match_operand:QI 1 "incdec_operand")
5607 (const_string "incdec")
5608 (const_string "alu1")))
5609 (set (attr "memory")
5610 (if_then_else (match_operand 1 "memory_operand")
5611 (const_string "load")
5612 (const_string "none")))
5613 (set_attr "mode" "QI")])
5615 ;; Split non destructive adds if we cannot use lea.
5617 [(set (match_operand:SWI48 0 "register_operand")
5618 (plus:SWI48 (match_operand:SWI48 1 "register_operand")
5619 (match_operand:SWI48 2 "x86_64_nonmemory_operand")))
5620 (clobber (reg:CC FLAGS_REG))]
5621 "reload_completed && ix86_avoid_lea_for_add (insn, operands)"
5622 [(set (match_dup 0) (match_dup 1))
5623 (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 2)))
5624 (clobber (reg:CC FLAGS_REG))])])
5626 ;; Split non destructive adds if we cannot use lea.
5628 [(set (match_operand:DI 0 "register_operand")
5630 (plus:SI (match_operand:SI 1 "register_operand")
5631 (match_operand:SI 2 "x86_64_nonmemory_operand"))))
5632 (clobber (reg:CC FLAGS_REG))]
5634 && reload_completed && ix86_avoid_lea_for_add (insn, operands)"
5635 [(set (match_dup 3) (match_dup 1))
5636 (parallel [(set (match_dup 0)
5637 (zero_extend:DI (plus:SI (match_dup 3) (match_dup 2))))
5638 (clobber (reg:CC FLAGS_REG))])]
5639 "operands[3] = gen_lowpart (SImode, operands[0]);")
5641 ;; Convert add to the lea pattern to avoid flags dependency.
5643 [(set (match_operand:SWI 0 "register_operand")
5644 (plus:SWI (match_operand:SWI 1 "register_operand")
5645 (match_operand:SWI 2 "<nonmemory_operand>")))
5646 (clobber (reg:CC FLAGS_REG))]
5647 "reload_completed && ix86_lea_for_add_ok (insn, operands)"
5649 (plus:<LEAMODE> (match_dup 1) (match_dup 2)))]
5651 if (<MODE>mode != <LEAMODE>mode)
5653 operands[0] = gen_lowpart (<LEAMODE>mode, operands[0]);
5654 operands[1] = gen_lowpart (<LEAMODE>mode, operands[1]);
5655 operands[2] = gen_lowpart (<LEAMODE>mode, operands[2]);
5659 ;; Convert add to the lea pattern to avoid flags dependency.
5661 [(set (match_operand:DI 0 "register_operand")
5663 (plus:SI (match_operand:SI 1 "register_operand")
5664 (match_operand:SI 2 "x86_64_nonmemory_operand"))))
5665 (clobber (reg:CC FLAGS_REG))]
5666 "TARGET_64BIT && reload_completed && ix86_lea_for_add_ok (insn, operands)"
5668 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))])
5670 (define_insn "*add<mode>_2"
5671 [(set (reg FLAGS_REG)
5674 (match_operand:SWI 1 "nonimmediate_operand" "%0,0,<r>")
5675 (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>,0"))
5677 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m,<r>")
5678 (plus:SWI (match_dup 1) (match_dup 2)))]
5679 "ix86_match_ccmode (insn, CCGOCmode)
5680 && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5682 switch (get_attr_type (insn))
5685 if (operands[2] == const1_rtx)
5686 return "inc{<imodesuffix>}\t%0";
5689 gcc_assert (operands[2] == constm1_rtx);
5690 return "dec{<imodesuffix>}\t%0";
5694 if (which_alternative == 2)
5695 std::swap (operands[1], operands[2]);
5697 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5698 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5699 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5701 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5705 (if_then_else (match_operand:SWI 2 "incdec_operand")
5706 (const_string "incdec")
5707 (const_string "alu")))
5708 (set (attr "length_immediate")
5710 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5712 (const_string "*")))
5713 (set_attr "mode" "<MODE>")])
5715 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5716 (define_insn "*addsi_2_zext"
5717 [(set (reg FLAGS_REG)
5719 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
5720 (match_operand:SI 2 "x86_64_general_operand" "rme,0"))
5722 (set (match_operand:DI 0 "register_operand" "=r,r")
5723 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5724 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5725 && ix86_binary_operator_ok (PLUS, SImode, operands)"
5727 switch (get_attr_type (insn))
5730 if (operands[2] == const1_rtx)
5731 return "inc{l}\t%k0";
5734 gcc_assert (operands[2] == constm1_rtx);
5735 return "dec{l}\t%k0";
5739 if (which_alternative == 1)
5740 std::swap (operands[1], operands[2]);
5742 if (x86_maybe_negate_const_int (&operands[2], SImode))
5743 return "sub{l}\t{%2, %k0|%k0, %2}";
5745 return "add{l}\t{%2, %k0|%k0, %2}";
5749 (if_then_else (match_operand:SI 2 "incdec_operand")
5750 (const_string "incdec")
5751 (const_string "alu")))
5752 (set (attr "length_immediate")
5754 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5756 (const_string "*")))
5757 (set_attr "mode" "SI")])
5759 (define_insn "*add<mode>_3"
5760 [(set (reg FLAGS_REG)
5762 (neg:SWI (match_operand:SWI 2 "<general_operand>" "<g>,0"))
5763 (match_operand:SWI 1 "nonimmediate_operand" "%0,<r>")))
5764 (clobber (match_scratch:SWI 0 "=<r>,<r>"))]
5765 "ix86_match_ccmode (insn, CCZmode)
5766 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
5768 switch (get_attr_type (insn))
5771 if (operands[2] == const1_rtx)
5772 return "inc{<imodesuffix>}\t%0";
5775 gcc_assert (operands[2] == constm1_rtx);
5776 return "dec{<imodesuffix>}\t%0";
5780 if (which_alternative == 1)
5781 std::swap (operands[1], operands[2]);
5783 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5784 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5785 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5787 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5791 (if_then_else (match_operand:SWI 2 "incdec_operand")
5792 (const_string "incdec")
5793 (const_string "alu")))
5794 (set (attr "length_immediate")
5796 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5798 (const_string "*")))
5799 (set_attr "mode" "<MODE>")])
5801 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5802 (define_insn "*addsi_3_zext"
5803 [(set (reg FLAGS_REG)
5805 (neg:SI (match_operand:SI 2 "x86_64_general_operand" "rme,0"))
5806 (match_operand:SI 1 "nonimmediate_operand" "%0,r")))
5807 (set (match_operand:DI 0 "register_operand" "=r,r")
5808 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5809 "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
5810 && ix86_binary_operator_ok (PLUS, SImode, operands)"
5812 switch (get_attr_type (insn))
5815 if (operands[2] == const1_rtx)
5816 return "inc{l}\t%k0";
5819 gcc_assert (operands[2] == constm1_rtx);
5820 return "dec{l}\t%k0";
5824 if (which_alternative == 1)
5825 std::swap (operands[1], operands[2]);
5827 if (x86_maybe_negate_const_int (&operands[2], SImode))
5828 return "sub{l}\t{%2, %k0|%k0, %2}";
5830 return "add{l}\t{%2, %k0|%k0, %2}";
5834 (if_then_else (match_operand:SI 2 "incdec_operand")
5835 (const_string "incdec")
5836 (const_string "alu")))
5837 (set (attr "length_immediate")
5839 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5841 (const_string "*")))
5842 (set_attr "mode" "SI")])
5844 ; For comparisons against 1, -1 and 128, we may generate better code
5845 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
5846 ; is matched then. We can't accept general immediate, because for
5847 ; case of overflows, the result is messed up.
5848 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5849 ; only for comparisons not depending on it.
5851 (define_insn "*adddi_4"
5852 [(set (reg FLAGS_REG)
5854 (match_operand:DI 1 "nonimmediate_operand" "0")
5855 (match_operand:DI 2 "x86_64_immediate_operand" "e")))
5856 (clobber (match_scratch:DI 0 "=rm"))]
5858 && ix86_match_ccmode (insn, CCGCmode)"
5860 switch (get_attr_type (insn))
5863 if (operands[2] == constm1_rtx)
5864 return "inc{q}\t%0";
5867 gcc_assert (operands[2] == const1_rtx);
5868 return "dec{q}\t%0";
5872 if (x86_maybe_negate_const_int (&operands[2], DImode))
5873 return "add{q}\t{%2, %0|%0, %2}";
5875 return "sub{q}\t{%2, %0|%0, %2}";
5879 (if_then_else (match_operand:DI 2 "incdec_operand")
5880 (const_string "incdec")
5881 (const_string "alu")))
5882 (set (attr "length_immediate")
5884 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5886 (const_string "*")))
5887 (set_attr "mode" "DI")])
5889 ; For comparisons against 1, -1 and 128, we may generate better code
5890 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
5891 ; is matched then. We can't accept general immediate, because for
5892 ; case of overflows, the result is messed up.
5893 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5894 ; only for comparisons not depending on it.
5896 (define_insn "*add<mode>_4"
5897 [(set (reg FLAGS_REG)
5899 (match_operand:SWI124 1 "nonimmediate_operand" "0")
5900 (match_operand:SWI124 2 "const_int_operand" "n")))
5901 (clobber (match_scratch:SWI124 0 "=<r>m"))]
5902 "ix86_match_ccmode (insn, CCGCmode)"
5904 switch (get_attr_type (insn))
5907 if (operands[2] == constm1_rtx)
5908 return "inc{<imodesuffix>}\t%0";
5911 gcc_assert (operands[2] == const1_rtx);
5912 return "dec{<imodesuffix>}\t%0";
5916 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5917 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5919 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5923 (if_then_else (match_operand:<MODE> 2 "incdec_operand")
5924 (const_string "incdec")
5925 (const_string "alu")))
5926 (set (attr "length_immediate")
5928 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5930 (const_string "*")))
5931 (set_attr "mode" "<MODE>")])
5933 (define_insn "*add<mode>_5"
5934 [(set (reg FLAGS_REG)
5937 (match_operand:SWI 1 "nonimmediate_operand" "%0,<r>")
5938 (match_operand:SWI 2 "<general_operand>" "<g>,0"))
5940 (clobber (match_scratch:SWI 0 "=<r>,<r>"))]
5941 "ix86_match_ccmode (insn, CCGOCmode)
5942 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
5944 switch (get_attr_type (insn))
5947 if (operands[2] == const1_rtx)
5948 return "inc{<imodesuffix>}\t%0";
5951 gcc_assert (operands[2] == constm1_rtx);
5952 return "dec{<imodesuffix>}\t%0";
5956 if (which_alternative == 1)
5957 std::swap (operands[1], operands[2]);
5959 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5960 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5961 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5963 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5967 (if_then_else (match_operand:SWI 2 "incdec_operand")
5968 (const_string "incdec")
5969 (const_string "alu")))
5970 (set (attr "length_immediate")
5972 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5974 (const_string "*")))
5975 (set_attr "mode" "<MODE>")])
5977 (define_insn "addqi_ext_1"
5978 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q,Q")
5984 (zero_extract:SI (match_operand 1 "ext_register_operand" "0,0")
5987 (match_operand:QI 2 "general_operand" "QnBc,m")) 0))
5988 (clobber (reg:CC FLAGS_REG))]
5989 "/* FIXME: without this LRA can't reload this pattern, see PR82524. */
5990 rtx_equal_p (operands[0], operands[1])"
5992 switch (get_attr_type (insn))
5995 if (operands[2] == const1_rtx)
5996 return "inc{b}\t%h0";
5999 gcc_assert (operands[2] == constm1_rtx);
6000 return "dec{b}\t%h0";
6004 return "add{b}\t{%2, %h0|%h0, %2}";
6007 [(set_attr "isa" "*,nox64")
6009 (if_then_else (match_operand:QI 2 "incdec_operand")
6010 (const_string "incdec")
6011 (const_string "alu")))
6012 (set_attr "mode" "QI")])
6014 (define_insn "*addqi_ext_2"
6015 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
6021 (zero_extract:SI (match_operand 1 "ext_register_operand" "%0")
6025 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
6027 (const_int 8)) 0)) 0))
6028 (clobber (reg:CC FLAGS_REG))]
6029 "/* FIXME: without this LRA can't reload this pattern, see PR82524. */
6030 rtx_equal_p (operands[0], operands[1])
6031 || rtx_equal_p (operands[0], operands[2])"
6032 "add{b}\t{%h2, %h0|%h0, %h2}"
6033 [(set_attr "type" "alu")
6034 (set_attr "mode" "QI")])
6036 ;; Add with jump on overflow.
6037 (define_expand "addv<mode>4"
6038 [(parallel [(set (reg:CCO FLAGS_REG)
6041 (match_operand:SWI 1 "nonimmediate_operand"))
6044 (plus:SWI (match_dup 1)
6045 (match_operand:SWI 2
6046 "<general_operand>")))))
6047 (set (match_operand:SWI 0 "register_operand")
6048 (plus:SWI (match_dup 1) (match_dup 2)))])
6049 (set (pc) (if_then_else
6050 (eq (reg:CCO FLAGS_REG) (const_int 0))
6051 (label_ref (match_operand 3))
6055 ix86_fixup_binary_operands_no_copy (PLUS, <MODE>mode, operands);
6056 if (CONST_INT_P (operands[2]))
6057 operands[4] = operands[2];
6059 operands[4] = gen_rtx_SIGN_EXTEND (<DWI>mode, operands[2]);
6062 (define_insn "*addv<mode>4"
6063 [(set (reg:CCO FLAGS_REG)
6066 (match_operand:SWI 1 "nonimmediate_operand" "%0,0"))
6068 (match_operand:SWI 2 "<general_sext_operand>"
6071 (plus:SWI (match_dup 1) (match_dup 2)))))
6072 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
6073 (plus:SWI (match_dup 1) (match_dup 2)))]
6074 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6075 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6076 [(set_attr "type" "alu")
6077 (set_attr "mode" "<MODE>")])
6079 (define_insn "*addv<mode>4_1"
6080 [(set (reg:CCO FLAGS_REG)
6083 (match_operand:SWI 1 "nonimmediate_operand" "0"))
6084 (match_operand:<DWI> 3 "const_int_operand" "i"))
6086 (plus:SWI (match_dup 1)
6087 (match_operand:SWI 2 "x86_64_immediate_operand"
6089 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
6090 (plus:SWI (match_dup 1) (match_dup 2)))]
6091 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)
6092 && CONST_INT_P (operands[2])
6093 && INTVAL (operands[2]) == INTVAL (operands[3])"
6094 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6095 [(set_attr "type" "alu")
6096 (set_attr "mode" "<MODE>")
6097 (set (attr "length_immediate")
6098 (cond [(match_test "IN_RANGE (INTVAL (operands[2]), -128, 127)")
6100 (match_test "<MODE_SIZE> == 8")
6102 (const_string "<MODE_SIZE>")))])
6104 (define_expand "uaddv<mode>4"
6105 [(parallel [(set (reg:CCC FLAGS_REG)
6108 (match_operand:SWI 1 "nonimmediate_operand")
6109 (match_operand:SWI 2 "<general_operand>"))
6111 (set (match_operand:SWI 0 "register_operand")
6112 (plus:SWI (match_dup 1) (match_dup 2)))])
6113 (set (pc) (if_then_else
6114 (ltu (reg:CCC FLAGS_REG) (const_int 0))
6115 (label_ref (match_operand 3))
6118 "ix86_fixup_binary_operands_no_copy (PLUS, <MODE>mode, operands);")
6120 ;; The lea patterns for modes less than 32 bits need to be matched by
6121 ;; several insns converted to real lea by splitters.
6123 (define_insn_and_split "*lea<mode>_general_1"
6124 [(set (match_operand:SWI12 0 "register_operand" "=r")
6126 (plus:SWI12 (match_operand:SWI12 1 "index_register_operand" "l")
6127 (match_operand:SWI12 2 "register_operand" "r"))
6128 (match_operand:SWI12 3 "immediate_operand" "i")))]
6129 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
6131 "&& reload_completed"
6134 (plus:SI (match_dup 1) (match_dup 2))
6137 operands[0] = gen_lowpart (SImode, operands[0]);
6138 operands[1] = gen_lowpart (SImode, operands[1]);
6139 operands[2] = gen_lowpart (SImode, operands[2]);
6140 operands[3] = gen_lowpart (SImode, operands[3]);
6142 [(set_attr "type" "lea")
6143 (set_attr "mode" "SI")])
6145 (define_insn_and_split "*lea<mode>_general_2"
6146 [(set (match_operand:SWI12 0 "register_operand" "=r")
6148 (mult:SWI12 (match_operand:SWI12 1 "index_register_operand" "l")
6149 (match_operand 2 "const248_operand" "n"))
6150 (match_operand:SWI12 3 "nonmemory_operand" "ri")))]
6151 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
6153 "&& reload_completed"
6156 (mult:SI (match_dup 1) (match_dup 2))
6159 operands[0] = gen_lowpart (SImode, operands[0]);
6160 operands[1] = gen_lowpart (SImode, operands[1]);
6161 operands[3] = gen_lowpart (SImode, operands[3]);
6163 [(set_attr "type" "lea")
6164 (set_attr "mode" "SI")])
6166 (define_insn_and_split "*lea<mode>_general_2b"
6167 [(set (match_operand:SWI12 0 "register_operand" "=r")
6169 (ashift:SWI12 (match_operand:SWI12 1 "index_register_operand" "l")
6170 (match_operand 2 "const123_operand" "n"))
6171 (match_operand:SWI12 3 "nonmemory_operand" "ri")))]
6172 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
6174 "&& reload_completed"
6177 (ashift:SI (match_dup 1) (match_dup 2))
6180 operands[0] = gen_lowpart (SImode, operands[0]);
6181 operands[1] = gen_lowpart (SImode, operands[1]);
6182 operands[3] = gen_lowpart (SImode, operands[3]);
6184 [(set_attr "type" "lea")
6185 (set_attr "mode" "SI")])
6187 (define_insn_and_split "*lea<mode>_general_3"
6188 [(set (match_operand:SWI12 0 "register_operand" "=r")
6191 (mult:SWI12 (match_operand:SWI12 1 "index_register_operand" "l")
6192 (match_operand 2 "const248_operand" "n"))
6193 (match_operand:SWI12 3 "register_operand" "r"))
6194 (match_operand:SWI12 4 "immediate_operand" "i")))]
6195 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
6197 "&& reload_completed"
6201 (mult:SI (match_dup 1) (match_dup 2))
6205 operands[0] = gen_lowpart (SImode, operands[0]);
6206 operands[1] = gen_lowpart (SImode, operands[1]);
6207 operands[3] = gen_lowpart (SImode, operands[3]);
6208 operands[4] = gen_lowpart (SImode, operands[4]);
6210 [(set_attr "type" "lea")
6211 (set_attr "mode" "SI")])
6213 (define_insn_and_split "*lea<mode>_general_3b"
6214 [(set (match_operand:SWI12 0 "register_operand" "=r")
6217 (ashift:SWI12 (match_operand:SWI12 1 "index_register_operand" "l")
6218 (match_operand 2 "const123_operand" "n"))
6219 (match_operand:SWI12 3 "register_operand" "r"))
6220 (match_operand:SWI12 4 "immediate_operand" "i")))]
6221 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
6223 "&& reload_completed"
6227 (ashift:SI (match_dup 1) (match_dup 2))
6231 operands[0] = gen_lowpart (SImode, operands[0]);
6232 operands[1] = gen_lowpart (SImode, operands[1]);
6233 operands[3] = gen_lowpart (SImode, operands[3]);
6234 operands[4] = gen_lowpart (SImode, operands[4]);
6236 [(set_attr "type" "lea")
6237 (set_attr "mode" "SI")])
6239 (define_insn_and_split "*lea<mode>_general_4"
6240 [(set (match_operand:SWI12 0 "register_operand" "=r")
6243 (match_operand:SWI12 1 "index_register_operand" "l")
6244 (match_operand 2 "const_0_to_3_operand" "n"))
6245 (match_operand 3 "const_int_operand" "n")))]
6246 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6247 && ((unsigned HOST_WIDE_INT) INTVAL (operands[3])
6248 < (HOST_WIDE_INT_1U << INTVAL (operands[2])))"
6250 "&& reload_completed"
6253 (mult:SI (match_dup 1) (match_dup 2))
6256 operands[0] = gen_lowpart (SImode, operands[0]);
6257 operands[1] = gen_lowpart (SImode, operands[1]);
6258 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
6260 [(set_attr "type" "lea")
6261 (set_attr "mode" "SI")])
6263 (define_insn_and_split "*lea<mode>_general_4"
6264 [(set (match_operand:SWI48 0 "register_operand" "=r")
6267 (match_operand:SWI48 1 "index_register_operand" "l")
6268 (match_operand 2 "const_0_to_3_operand" "n"))
6269 (match_operand 3 "const_int_operand" "n")))]
6270 "(unsigned HOST_WIDE_INT) INTVAL (operands[3])
6271 < (HOST_WIDE_INT_1U << INTVAL (operands[2]))"
6273 "&& reload_completed"
6276 (mult:SWI48 (match_dup 1) (match_dup 2))
6278 "operands[2] = GEN_INT (1 << INTVAL (operands[2]));"
6279 [(set_attr "type" "lea")
6280 (set_attr "mode" "<MODE>")])
6282 ;; Subtract instructions
6284 (define_expand "sub<mode>3"
6285 [(set (match_operand:SDWIM 0 "nonimmediate_operand")
6286 (minus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")
6287 (match_operand:SDWIM 2 "<general_hilo_operand>")))]
6289 "ix86_expand_binary_operator (MINUS, <MODE>mode, operands); DONE;")
6291 (define_insn_and_split "*sub<dwi>3_doubleword"
6292 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
6294 (match_operand:<DWI> 1 "nonimmediate_operand" "0,0")
6295 (match_operand:<DWI> 2 "x86_64_hilo_general_operand"
6297 (clobber (reg:CC FLAGS_REG))]
6298 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6301 [(parallel [(set (reg:CC FLAGS_REG)
6302 (compare:CC (match_dup 1) (match_dup 2)))
6304 (minus:DWIH (match_dup 1) (match_dup 2)))])
6305 (parallel [(set (match_dup 3)
6309 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0)))
6311 (clobber (reg:CC FLAGS_REG))])]
6313 split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);
6314 if (operands[2] == const0_rtx)
6316 ix86_expand_binary_operator (MINUS, <MODE>mode, &operands[3]);
6321 (define_insn "*sub<mode>_1"
6322 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6324 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6325 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6326 (clobber (reg:CC FLAGS_REG))]
6327 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6328 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6329 [(set_attr "type" "alu")
6330 (set_attr "mode" "<MODE>")])
6332 (define_insn "*subsi_1_zext"
6333 [(set (match_operand:DI 0 "register_operand" "=r")
6335 (minus:SI (match_operand:SI 1 "register_operand" "0")
6336 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
6337 (clobber (reg:CC FLAGS_REG))]
6338 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6339 "sub{l}\t{%2, %k0|%k0, %2}"
6340 [(set_attr "type" "alu")
6341 (set_attr "mode" "SI")])
6343 (define_insn "*subqi_1_slp"
6344 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6345 (minus:QI (match_dup 0)
6346 (match_operand:QI 1 "general_operand" "qn,qm")))
6347 (clobber (reg:CC FLAGS_REG))]
6348 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6349 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
6350 "sub{b}\t{%1, %0|%0, %1}"
6351 [(set_attr "type" "alu1")
6352 (set_attr "mode" "QI")])
6354 (define_insn "*sub<mode>_2"
6355 [(set (reg FLAGS_REG)
6358 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6359 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6361 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6362 (minus:SWI (match_dup 1) (match_dup 2)))]
6363 "ix86_match_ccmode (insn, CCGOCmode)
6364 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6365 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6366 [(set_attr "type" "alu")
6367 (set_attr "mode" "<MODE>")])
6369 (define_insn "*subsi_2_zext"
6370 [(set (reg FLAGS_REG)
6372 (minus:SI (match_operand:SI 1 "register_operand" "0")
6373 (match_operand:SI 2 "x86_64_general_operand" "rme"))
6375 (set (match_operand:DI 0 "register_operand" "=r")
6377 (minus:SI (match_dup 1)
6379 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6380 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6381 "sub{l}\t{%2, %k0|%k0, %2}"
6382 [(set_attr "type" "alu")
6383 (set_attr "mode" "SI")])
6385 ;; Subtract with jump on overflow.
6386 (define_expand "subv<mode>4"
6387 [(parallel [(set (reg:CCO FLAGS_REG)
6388 (eq:CCO (minus:<DWI>
6390 (match_operand:SWI 1 "nonimmediate_operand"))
6393 (minus:SWI (match_dup 1)
6394 (match_operand:SWI 2
6395 "<general_operand>")))))
6396 (set (match_operand:SWI 0 "register_operand")
6397 (minus:SWI (match_dup 1) (match_dup 2)))])
6398 (set (pc) (if_then_else
6399 (eq (reg:CCO FLAGS_REG) (const_int 0))
6400 (label_ref (match_operand 3))
6404 ix86_fixup_binary_operands_no_copy (MINUS, <MODE>mode, operands);
6405 if (CONST_INT_P (operands[2]))
6406 operands[4] = operands[2];
6408 operands[4] = gen_rtx_SIGN_EXTEND (<DWI>mode, operands[2]);
6411 (define_insn "*subv<mode>4"
6412 [(set (reg:CCO FLAGS_REG)
6413 (eq:CCO (minus:<DWI>
6415 (match_operand:SWI 1 "nonimmediate_operand" "0,0"))
6417 (match_operand:SWI 2 "<general_sext_operand>"
6420 (minus:SWI (match_dup 1) (match_dup 2)))))
6421 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6422 (minus:SWI (match_dup 1) (match_dup 2)))]
6423 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6424 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6425 [(set_attr "type" "alu")
6426 (set_attr "mode" "<MODE>")])
6428 (define_insn "*subv<mode>4_1"
6429 [(set (reg:CCO FLAGS_REG)
6430 (eq:CCO (minus:<DWI>
6432 (match_operand:SWI 1 "nonimmediate_operand" "0"))
6433 (match_operand:<DWI> 3 "const_int_operand" "i"))
6435 (minus:SWI (match_dup 1)
6436 (match_operand:SWI 2 "x86_64_immediate_operand"
6438 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
6439 (minus:SWI (match_dup 1) (match_dup 2)))]
6440 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)
6441 && CONST_INT_P (operands[2])
6442 && INTVAL (operands[2]) == INTVAL (operands[3])"
6443 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6444 [(set_attr "type" "alu")
6445 (set_attr "mode" "<MODE>")
6446 (set (attr "length_immediate")
6447 (cond [(match_test "IN_RANGE (INTVAL (operands[2]), -128, 127)")
6449 (match_test "<MODE_SIZE> == 8")
6451 (const_string "<MODE_SIZE>")))])
6453 (define_expand "usubv<mode>4"
6454 [(parallel [(set (reg:CC FLAGS_REG)
6456 (match_operand:SWI 1 "nonimmediate_operand")
6457 (match_operand:SWI 2 "<general_operand>")))
6458 (set (match_operand:SWI 0 "register_operand")
6459 (minus:SWI (match_dup 1) (match_dup 2)))])
6460 (set (pc) (if_then_else
6461 (ltu (reg:CC FLAGS_REG) (const_int 0))
6462 (label_ref (match_operand 3))
6465 "ix86_fixup_binary_operands_no_copy (MINUS, <MODE>mode, operands);")
6467 (define_insn "*sub<mode>_3"
6468 [(set (reg FLAGS_REG)
6469 (compare (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6470 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6471 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6472 (minus:SWI (match_dup 1) (match_dup 2)))]
6473 "ix86_match_ccmode (insn, CCmode)
6474 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6475 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6476 [(set_attr "type" "alu")
6477 (set_attr "mode" "<MODE>")])
6481 [(set (reg:CC FLAGS_REG)
6482 (compare:CC (match_operand:SWI 0 "general_reg_operand")
6483 (match_operand:SWI 1 "general_gr_operand")))
6485 (minus:SWI (match_dup 0) (match_dup 1)))])]
6486 "find_regno_note (peep2_next_insn (0), REG_UNUSED, REGNO (operands[0])) != 0"
6487 [(set (reg:CC FLAGS_REG)
6488 (compare:CC (match_dup 0) (match_dup 1)))])
6490 (define_insn "*subsi_3_zext"
6491 [(set (reg FLAGS_REG)
6492 (compare (match_operand:SI 1 "register_operand" "0")
6493 (match_operand:SI 2 "x86_64_general_operand" "rme")))
6494 (set (match_operand:DI 0 "register_operand" "=r")
6496 (minus:SI (match_dup 1)
6498 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6499 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6500 "sub{l}\t{%2, %1|%1, %2}"
6501 [(set_attr "type" "alu")
6502 (set_attr "mode" "SI")])
6504 ;; Add with carry and subtract with borrow
6506 (define_insn "add<mode>3_carry"
6507 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6510 (match_operator:SWI 4 "ix86_carry_flag_operator"
6511 [(match_operand 3 "flags_reg_operand") (const_int 0)])
6512 (match_operand:SWI 1 "nonimmediate_operand" "%0,0"))
6513 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6514 (clobber (reg:CC FLAGS_REG))]
6515 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6516 "adc{<imodesuffix>}\t{%2, %0|%0, %2}"
6517 [(set_attr "type" "alu")
6518 (set_attr "use_carry" "1")
6519 (set_attr "pent_pair" "pu")
6520 (set_attr "mode" "<MODE>")])
6522 (define_insn "*add<mode>3_carry_0"
6523 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
6525 (match_operator:SWI 3 "ix86_carry_flag_operator"
6526 [(match_operand 2 "flags_reg_operand") (const_int 0)])
6527 (match_operand:SWI 1 "nonimmediate_operand" "0")))
6528 (clobber (reg:CC FLAGS_REG))]
6529 "ix86_unary_operator_ok (PLUS, <MODE>mode, operands)"
6530 "adc{<imodesuffix>}\t{$0, %0|%0, 0}"
6531 [(set_attr "type" "alu")
6532 (set_attr "use_carry" "1")
6533 (set_attr "pent_pair" "pu")
6534 (set_attr "mode" "<MODE>")])
6536 (define_insn "*addsi3_carry_zext"
6537 [(set (match_operand:DI 0 "register_operand" "=r")
6540 (plus:SI (match_operator:SI 3 "ix86_carry_flag_operator"
6541 [(reg FLAGS_REG) (const_int 0)])
6542 (match_operand:SI 1 "register_operand" "%0"))
6543 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
6544 (clobber (reg:CC FLAGS_REG))]
6545 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6546 "adc{l}\t{%2, %k0|%k0, %2}"
6547 [(set_attr "type" "alu")
6548 (set_attr "use_carry" "1")
6549 (set_attr "pent_pair" "pu")
6550 (set_attr "mode" "SI")])
6552 (define_insn "*addsi3_carry_zext_0"
6553 [(set (match_operand:DI 0 "register_operand" "=r")
6555 (plus:SI (match_operator:SI 2 "ix86_carry_flag_operator"
6556 [(reg FLAGS_REG) (const_int 0)])
6557 (match_operand:SI 1 "register_operand" "0"))))
6558 (clobber (reg:CC FLAGS_REG))]
6560 "adc{l}\t{$0, %k0|%k0, 0}"
6561 [(set_attr "type" "alu")
6562 (set_attr "use_carry" "1")
6563 (set_attr "pent_pair" "pu")
6564 (set_attr "mode" "SI")])
6566 ;; There is no point to generate ADCX instruction. ADC is shorter and faster.
6568 (define_insn "addcarry<mode>"
6569 [(set (reg:CCC FLAGS_REG)
6574 (match_operator:SWI48 5 "ix86_carry_flag_operator"
6575 [(match_operand 3 "flags_reg_operand") (const_int 0)])
6576 (match_operand:SWI48 1 "nonimmediate_operand" "%0"))
6577 (match_operand:SWI48 2 "nonimmediate_operand" "rm")))
6579 (zero_extend:<DWI> (match_dup 2))
6580 (match_operator:<DWI> 4 "ix86_carry_flag_operator"
6581 [(match_dup 3) (const_int 0)]))))
6582 (set (match_operand:SWI48 0 "register_operand" "=r")
6583 (plus:SWI48 (plus:SWI48 (match_op_dup 5
6584 [(match_dup 3) (const_int 0)])
6587 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6588 "adc{<imodesuffix>}\t{%2, %0|%0, %2}"
6589 [(set_attr "type" "alu")
6590 (set_attr "use_carry" "1")
6591 (set_attr "pent_pair" "pu")
6592 (set_attr "mode" "<MODE>")])
6594 (define_expand "addcarry<mode>_0"
6596 [(set (reg:CCC FLAGS_REG)
6599 (match_operand:SWI48 1 "nonimmediate_operand")
6600 (match_operand:SWI48 2 "x86_64_general_operand"))
6602 (set (match_operand:SWI48 0 "register_operand")
6603 (plus:SWI48 (match_dup 1) (match_dup 2)))])]
6604 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)")
6606 (define_insn "@sub<mode>3_carry"
6607 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6610 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6611 (match_operator:SWI 4 "ix86_carry_flag_operator"
6612 [(match_operand 3 "flags_reg_operand") (const_int 0)]))
6613 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6614 (clobber (reg:CC FLAGS_REG))]
6615 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6616 "sbb{<imodesuffix>}\t{%2, %0|%0, %2}"
6617 [(set_attr "type" "alu")
6618 (set_attr "use_carry" "1")
6619 (set_attr "pent_pair" "pu")
6620 (set_attr "mode" "<MODE>")])
6622 (define_insn "*sub<mode>3_carry_0"
6623 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
6625 (match_operand:SWI 1 "nonimmediate_operand" "0")
6626 (match_operator:SWI 3 "ix86_carry_flag_operator"
6627 [(match_operand 2 "flags_reg_operand") (const_int 0)])))
6628 (clobber (reg:CC FLAGS_REG))]
6629 "ix86_unary_operator_ok (MINUS, <MODE>mode, operands)"
6630 "sbb{<imodesuffix>}\t{$0, %0|%0, 0}"
6631 [(set_attr "type" "alu")
6632 (set_attr "use_carry" "1")
6633 (set_attr "pent_pair" "pu")
6634 (set_attr "mode" "<MODE>")])
6636 (define_insn "*subsi3_carry_zext"
6637 [(set (match_operand:DI 0 "register_operand" "=r")
6641 (match_operand:SI 1 "register_operand" "0")
6642 (match_operator:SI 3 "ix86_carry_flag_operator"
6643 [(reg FLAGS_REG) (const_int 0)]))
6644 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
6645 (clobber (reg:CC FLAGS_REG))]
6646 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6647 "sbb{l}\t{%2, %k0|%k0, %2}"
6648 [(set_attr "type" "alu")
6649 (set_attr "use_carry" "1")
6650 (set_attr "pent_pair" "pu")
6651 (set_attr "mode" "SI")])
6653 (define_insn "*subsi3_carry_zext_0"
6654 [(set (match_operand:DI 0 "register_operand" "=r")
6657 (match_operand:SI 1 "register_operand" "0")
6658 (match_operator:SI 2 "ix86_carry_flag_operator"
6659 [(reg FLAGS_REG) (const_int 0)]))))
6660 (clobber (reg:CC FLAGS_REG))]
6662 "sbb{l}\t{$0, %k0|%k0, 0}"
6663 [(set_attr "type" "alu")
6664 (set_attr "use_carry" "1")
6665 (set_attr "pent_pair" "pu")
6666 (set_attr "mode" "SI")])
6668 (define_insn "sub<mode>3_carry_ccc"
6669 [(set (reg:CCC FLAGS_REG)
6671 (zero_extend:<DWI> (match_operand:DWIH 1 "register_operand" "0"))
6673 (ltu:<DWI> (reg:CC FLAGS_REG) (const_int 0))
6675 (match_operand:DWIH 2 "x86_64_sext_operand" "rmWe")))))
6676 (clobber (match_scratch:DWIH 0 "=r"))]
6678 "sbb{<imodesuffix>}\t{%2, %0|%0, %2}"
6679 [(set_attr "type" "alu")
6680 (set_attr "mode" "<MODE>")])
6682 (define_insn "*sub<mode>3_carry_ccc_1"
6683 [(set (reg:CCC FLAGS_REG)
6685 (zero_extend:<DWI> (match_operand:DWIH 1 "register_operand" "0"))
6687 (ltu:<DWI> (reg:CC FLAGS_REG) (const_int 0))
6688 (match_operand:<DWI> 2 "x86_64_dwzext_immediate_operand" "Wf"))))
6689 (clobber (match_scratch:DWIH 0 "=r"))]
6692 operands[3] = simplify_subreg (<MODE>mode, operands[2], <DWI>mode, 0);
6693 return "sbb{<imodesuffix>}\t{%3, %0|%0, %3}";
6695 [(set_attr "type" "alu")
6696 (set_attr "mode" "<MODE>")])
6698 ;; The sign flag is set from the
6699 ;; (compare (match_dup 1) (plus:DWIH (ltu:DWIH ...) (match_dup 2)))
6700 ;; result, the overflow flag likewise, but the overflow flag is also
6701 ;; set if the (plus:DWIH (ltu:DWIH ...) (match_dup 2)) overflows.
6702 (define_insn "sub<mode>3_carry_ccgz"
6703 [(set (reg:CCGZ FLAGS_REG)
6704 (unspec:CCGZ [(match_operand:DWIH 1 "register_operand" "0")
6705 (match_operand:DWIH 2 "x86_64_general_operand" "rme")
6706 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))]
6708 (clobber (match_scratch:DWIH 0 "=r"))]
6710 "sbb{<imodesuffix>}\t{%2, %0|%0, %2}"
6711 [(set_attr "type" "alu")
6712 (set_attr "mode" "<MODE>")])
6714 (define_insn "subborrow<mode>"
6715 [(set (reg:CCC FLAGS_REG)
6718 (match_operand:SWI48 1 "nonimmediate_operand" "0"))
6720 (match_operator:<DWI> 4 "ix86_carry_flag_operator"
6721 [(match_operand 3 "flags_reg_operand") (const_int 0)])
6723 (match_operand:SWI48 2 "nonimmediate_operand" "rm")))))
6724 (set (match_operand:SWI48 0 "register_operand" "=r")
6725 (minus:SWI48 (minus:SWI48
6727 (match_operator:SWI48 5 "ix86_carry_flag_operator"
6728 [(match_dup 3) (const_int 0)]))
6730 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6731 "sbb{<imodesuffix>}\t{%2, %0|%0, %2}"
6732 [(set_attr "type" "alu")
6733 (set_attr "use_carry" "1")
6734 (set_attr "pent_pair" "pu")
6735 (set_attr "mode" "<MODE>")])
6737 (define_expand "subborrow<mode>_0"
6739 [(set (reg:CC FLAGS_REG)
6741 (match_operand:SWI48 1 "nonimmediate_operand")
6742 (match_operand:SWI48 2 "<general_operand>")))
6743 (set (match_operand:SWI48 0 "register_operand")
6744 (minus:SWI48 (match_dup 1) (match_dup 2)))])]
6745 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)")
6747 ;; Overflow setting add instructions
6749 (define_expand "addqi3_cconly_overflow"
6751 [(set (reg:CCC FLAGS_REG)
6754 (match_operand:QI 0 "nonimmediate_operand")
6755 (match_operand:QI 1 "general_operand"))
6757 (clobber (match_scratch:QI 2))])]
6758 "!(MEM_P (operands[0]) && MEM_P (operands[1]))")
6760 (define_insn "*add<mode>3_cconly_overflow_1"
6761 [(set (reg:CCC FLAGS_REG)
6764 (match_operand:SWI 1 "nonimmediate_operand" "%0")
6765 (match_operand:SWI 2 "<general_operand>" "<g>"))
6767 (clobber (match_scratch:SWI 0 "=<r>"))]
6768 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6769 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6770 [(set_attr "type" "alu")
6771 (set_attr "mode" "<MODE>")])
6773 (define_insn "*add<mode>3_cc_overflow_1"
6774 [(set (reg:CCC FLAGS_REG)
6777 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
6778 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6780 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6781 (plus:SWI (match_dup 1) (match_dup 2)))]
6782 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6783 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6784 [(set_attr "type" "alu")
6785 (set_attr "mode" "<MODE>")])
6787 (define_insn "*addsi3_zext_cc_overflow_1"
6788 [(set (reg:CCC FLAGS_REG)
6791 (match_operand:SI 1 "nonimmediate_operand" "%0")
6792 (match_operand:SI 2 "x86_64_general_operand" "rme"))
6794 (set (match_operand:DI 0 "register_operand" "=r")
6795 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6796 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6797 "add{l}\t{%2, %k0|%k0, %2}"
6798 [(set_attr "type" "alu")
6799 (set_attr "mode" "SI")])
6801 (define_insn "*add<mode>3_cconly_overflow_2"
6802 [(set (reg:CCC FLAGS_REG)
6805 (match_operand:SWI 1 "nonimmediate_operand" "%0")
6806 (match_operand:SWI 2 "<general_operand>" "<g>"))
6808 (clobber (match_scratch:SWI 0 "=<r>"))]
6809 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6810 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6811 [(set_attr "type" "alu")
6812 (set_attr "mode" "<MODE>")])
6814 (define_insn "*add<mode>3_cc_overflow_2"
6815 [(set (reg:CCC FLAGS_REG)
6818 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
6819 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6821 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6822 (plus:SWI (match_dup 1) (match_dup 2)))]
6823 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6824 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6825 [(set_attr "type" "alu")
6826 (set_attr "mode" "<MODE>")])
6828 (define_insn "*addsi3_zext_cc_overflow_2"
6829 [(set (reg:CCC FLAGS_REG)
6832 (match_operand:SI 1 "nonimmediate_operand" "%0")
6833 (match_operand:SI 2 "x86_64_general_operand" "rme"))
6835 (set (match_operand:DI 0 "register_operand" "=r")
6836 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6837 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6838 "add{l}\t{%2, %k0|%k0, %2}"
6839 [(set_attr "type" "alu")
6840 (set_attr "mode" "SI")])
6842 ;; The patterns that match these are at the end of this file.
6844 (define_expand "<plusminus_insn>xf3"
6845 [(set (match_operand:XF 0 "register_operand")
6847 (match_operand:XF 1 "register_operand")
6848 (match_operand:XF 2 "register_operand")))]
6851 (define_expand "<plusminus_insn><mode>3"
6852 [(set (match_operand:MODEF 0 "register_operand")
6854 (match_operand:MODEF 1 "register_operand")
6855 (match_operand:MODEF 2 "nonimmediate_operand")))]
6856 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
6857 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
6859 ;; Multiply instructions
6861 (define_expand "mul<mode>3"
6862 [(parallel [(set (match_operand:SWIM248 0 "register_operand")
6864 (match_operand:SWIM248 1 "register_operand")
6865 (match_operand:SWIM248 2 "<general_operand>")))
6866 (clobber (reg:CC FLAGS_REG))])])
6868 (define_expand "mulqi3"
6869 [(parallel [(set (match_operand:QI 0 "register_operand")
6871 (match_operand:QI 1 "register_operand")
6872 (match_operand:QI 2 "nonimmediate_operand")))
6873 (clobber (reg:CC FLAGS_REG))])]
6874 "TARGET_QIMODE_MATH")
6877 ;; IMUL reg32/64, reg32/64, imm8 Direct
6878 ;; IMUL reg32/64, mem32/64, imm8 VectorPath
6879 ;; IMUL reg32/64, reg32/64, imm32 Direct
6880 ;; IMUL reg32/64, mem32/64, imm32 VectorPath
6881 ;; IMUL reg32/64, reg32/64 Direct
6882 ;; IMUL reg32/64, mem32/64 Direct
6884 ;; On BDVER1, all above IMULs use DirectPath
6887 ;; IMUL reg16, reg16, imm8 VectorPath
6888 ;; IMUL reg16, mem16, imm8 VectorPath
6889 ;; IMUL reg16, reg16, imm16 VectorPath
6890 ;; IMUL reg16, mem16, imm16 VectorPath
6891 ;; IMUL reg16, reg16 Direct
6892 ;; IMUL reg16, mem16 Direct
6894 ;; On BDVER1, all HI MULs use DoublePath
6896 (define_insn "*mul<mode>3_1"
6897 [(set (match_operand:SWIM248 0 "register_operand" "=r,r,r")
6899 (match_operand:SWIM248 1 "nonimmediate_operand" "%rm,rm,0")
6900 (match_operand:SWIM248 2 "<general_operand>" "K,<i>,mr")))
6901 (clobber (reg:CC FLAGS_REG))]
6902 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6904 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6905 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6906 imul{<imodesuffix>}\t{%2, %0|%0, %2}"
6907 [(set_attr "type" "imul")
6908 (set_attr "prefix_0f" "0,0,1")
6909 (set (attr "athlon_decode")
6910 (cond [(eq_attr "cpu" "athlon")
6911 (const_string "vector")
6912 (eq_attr "alternative" "1")
6913 (const_string "vector")
6914 (and (eq_attr "alternative" "2")
6915 (ior (match_test "<MODE>mode == HImode")
6916 (match_operand 1 "memory_operand")))
6917 (const_string "vector")]
6918 (const_string "direct")))
6919 (set (attr "amdfam10_decode")
6920 (cond [(and (eq_attr "alternative" "0,1")
6921 (ior (match_test "<MODE>mode == HImode")
6922 (match_operand 1 "memory_operand")))
6923 (const_string "vector")]
6924 (const_string "direct")))
6925 (set (attr "bdver1_decode")
6927 (match_test "<MODE>mode == HImode")
6928 (const_string "double")
6929 (const_string "direct")))
6930 (set_attr "mode" "<MODE>")])
6932 (define_insn "*mulsi3_1_zext"
6933 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6935 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6936 (match_operand:SI 2 "x86_64_general_operand" "K,e,mr"))))
6937 (clobber (reg:CC FLAGS_REG))]
6939 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6941 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6942 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6943 imul{l}\t{%2, %k0|%k0, %2}"
6944 [(set_attr "type" "imul")
6945 (set_attr "prefix_0f" "0,0,1")
6946 (set (attr "athlon_decode")
6947 (cond [(eq_attr "cpu" "athlon")
6948 (const_string "vector")
6949 (eq_attr "alternative" "1")
6950 (const_string "vector")
6951 (and (eq_attr "alternative" "2")
6952 (match_operand 1 "memory_operand"))
6953 (const_string "vector")]
6954 (const_string "direct")))
6955 (set (attr "amdfam10_decode")
6956 (cond [(and (eq_attr "alternative" "0,1")
6957 (match_operand 1 "memory_operand"))
6958 (const_string "vector")]
6959 (const_string "direct")))
6960 (set_attr "bdver1_decode" "direct")
6961 (set_attr "mode" "SI")])
6963 ;;On AMDFAM10 and BDVER1
6967 (define_insn "*mulqi3_1"
6968 [(set (match_operand:QI 0 "register_operand" "=a")
6969 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6970 (match_operand:QI 2 "nonimmediate_operand" "qm")))
6971 (clobber (reg:CC FLAGS_REG))]
6973 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6975 [(set_attr "type" "imul")
6976 (set_attr "length_immediate" "0")
6977 (set (attr "athlon_decode")
6978 (if_then_else (eq_attr "cpu" "athlon")
6979 (const_string "vector")
6980 (const_string "direct")))
6981 (set_attr "amdfam10_decode" "direct")
6982 (set_attr "bdver1_decode" "direct")
6983 (set_attr "mode" "QI")])
6985 ;; Multiply with jump on overflow.
6986 (define_expand "mulv<mode>4"
6987 [(parallel [(set (reg:CCO FLAGS_REG)
6990 (match_operand:SWI248 1 "register_operand"))
6993 (mult:SWI248 (match_dup 1)
6994 (match_operand:SWI248 2
6995 "<general_operand>")))))
6996 (set (match_operand:SWI248 0 "register_operand")
6997 (mult:SWI248 (match_dup 1) (match_dup 2)))])
6998 (set (pc) (if_then_else
6999 (eq (reg:CCO FLAGS_REG) (const_int 0))
7000 (label_ref (match_operand 3))
7004 if (CONST_INT_P (operands[2]))
7005 operands[4] = operands[2];
7007 operands[4] = gen_rtx_SIGN_EXTEND (<DWI>mode, operands[2]);
7010 (define_insn "*mulv<mode>4"
7011 [(set (reg:CCO FLAGS_REG)
7014 (match_operand:SWI48 1 "nonimmediate_operand" "%rm,0"))
7016 (match_operand:SWI48 2 "x86_64_sext_operand" "We,mr")))
7018 (mult:SWI48 (match_dup 1) (match_dup 2)))))
7019 (set (match_operand:SWI48 0 "register_operand" "=r,r")
7020 (mult:SWI48 (match_dup 1) (match_dup 2)))]
7021 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7023 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
7024 imul{<imodesuffix>}\t{%2, %0|%0, %2}"
7025 [(set_attr "type" "imul")
7026 (set_attr "prefix_0f" "0,1")
7027 (set (attr "athlon_decode")
7028 (cond [(eq_attr "cpu" "athlon")
7029 (const_string "vector")
7030 (eq_attr "alternative" "0")
7031 (const_string "vector")
7032 (and (eq_attr "alternative" "1")
7033 (match_operand 1 "memory_operand"))
7034 (const_string "vector")]
7035 (const_string "direct")))
7036 (set (attr "amdfam10_decode")
7037 (cond [(and (eq_attr "alternative" "1")
7038 (match_operand 1 "memory_operand"))
7039 (const_string "vector")]
7040 (const_string "direct")))
7041 (set_attr "bdver1_decode" "direct")
7042 (set_attr "mode" "<MODE>")])
7044 (define_insn "*mulvhi4"
7045 [(set (reg:CCO FLAGS_REG)
7048 (match_operand:HI 1 "nonimmediate_operand" "%0"))
7050 (match_operand:HI 2 "nonimmediate_operand" "mr")))
7052 (mult:HI (match_dup 1) (match_dup 2)))))
7053 (set (match_operand:HI 0 "register_operand" "=r")
7054 (mult:HI (match_dup 1) (match_dup 2)))]
7055 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7056 "imul{w}\t{%2, %0|%0, %2}"
7057 [(set_attr "type" "imul")
7058 (set_attr "prefix_0f" "1")
7059 (set_attr "athlon_decode" "vector")
7060 (set_attr "amdfam10_decode" "direct")
7061 (set_attr "bdver1_decode" "double")
7062 (set_attr "mode" "HI")])
7064 (define_insn "*mulv<mode>4_1"
7065 [(set (reg:CCO FLAGS_REG)
7068 (match_operand:SWI248 1 "nonimmediate_operand" "rm,rm"))
7069 (match_operand:<DWI> 3 "const_int_operand" "K,i"))
7071 (mult:SWI248 (match_dup 1)
7072 (match_operand:SWI248 2
7073 "<immediate_operand>" "K,<i>")))))
7074 (set (match_operand:SWI248 0 "register_operand" "=r,r")
7075 (mult:SWI248 (match_dup 1) (match_dup 2)))]
7076 "!(MEM_P (operands[1]) && MEM_P (operands[2]))
7077 && CONST_INT_P (operands[2])
7078 && INTVAL (operands[2]) == INTVAL (operands[3])"
7079 "imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}"
7080 [(set_attr "type" "imul")
7081 (set (attr "prefix_0f")
7083 (match_test "<MODE>mode == HImode")
7085 (const_string "*")))
7086 (set (attr "athlon_decode")
7087 (cond [(eq_attr "cpu" "athlon")
7088 (const_string "vector")
7089 (eq_attr "alternative" "1")
7090 (const_string "vector")]
7091 (const_string "direct")))
7092 (set (attr "amdfam10_decode")
7093 (cond [(ior (match_test "<MODE>mode == HImode")
7094 (match_operand 1 "memory_operand"))
7095 (const_string "vector")]
7096 (const_string "direct")))
7097 (set (attr "bdver1_decode")
7099 (match_test "<MODE>mode == HImode")
7100 (const_string "double")
7101 (const_string "direct")))
7102 (set_attr "mode" "<MODE>")
7103 (set (attr "length_immediate")
7104 (cond [(eq_attr "alternative" "0")
7106 (match_test "<MODE_SIZE> == 8")
7108 (const_string "<MODE_SIZE>")))])
7110 (define_expand "umulv<mode>4"
7111 [(parallel [(set (reg:CCO FLAGS_REG)
7114 (match_operand:SWI248 1
7115 "nonimmediate_operand"))
7117 (match_operand:SWI248 2
7118 "nonimmediate_operand")))
7120 (mult:SWI248 (match_dup 1) (match_dup 2)))))
7121 (set (match_operand:SWI248 0 "register_operand")
7122 (mult:SWI248 (match_dup 1) (match_dup 2)))
7123 (clobber (match_scratch:SWI248 4))])
7124 (set (pc) (if_then_else
7125 (eq (reg:CCO FLAGS_REG) (const_int 0))
7126 (label_ref (match_operand 3))
7130 if (MEM_P (operands[1]) && MEM_P (operands[2]))
7131 operands[1] = force_reg (<MODE>mode, operands[1]);
7134 (define_insn "*umulv<mode>4"
7135 [(set (reg:CCO FLAGS_REG)
7138 (match_operand:SWI248 1 "nonimmediate_operand" "%0"))
7140 (match_operand:SWI248 2 "nonimmediate_operand" "rm")))
7142 (mult:SWI248 (match_dup 1) (match_dup 2)))))
7143 (set (match_operand:SWI248 0 "register_operand" "=a")
7144 (mult:SWI248 (match_dup 1) (match_dup 2)))
7145 (clobber (match_scratch:SWI248 3 "=d"))]
7146 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7147 "mul{<imodesuffix>}\t%2"
7148 [(set_attr "type" "imul")
7149 (set_attr "length_immediate" "0")
7150 (set (attr "athlon_decode")
7151 (if_then_else (eq_attr "cpu" "athlon")
7152 (const_string "vector")
7153 (const_string "double")))
7154 (set_attr "amdfam10_decode" "double")
7155 (set_attr "bdver1_decode" "direct")
7156 (set_attr "mode" "<MODE>")])
7158 (define_expand "<u>mulvqi4"
7159 [(parallel [(set (reg:CCO FLAGS_REG)
7162 (match_operand:QI 1 "nonimmediate_operand"))
7164 (match_operand:QI 2 "nonimmediate_operand")))
7166 (mult:QI (match_dup 1) (match_dup 2)))))
7167 (set (match_operand:QI 0 "register_operand")
7168 (mult:QI (match_dup 1) (match_dup 2)))])
7169 (set (pc) (if_then_else
7170 (eq (reg:CCO FLAGS_REG) (const_int 0))
7171 (label_ref (match_operand 3))
7173 "TARGET_QIMODE_MATH"
7175 if (MEM_P (operands[1]) && MEM_P (operands[2]))
7176 operands[1] = force_reg (QImode, operands[1]);
7179 (define_insn "*<u>mulvqi4"
7180 [(set (reg:CCO FLAGS_REG)
7183 (match_operand:QI 1 "nonimmediate_operand" "%0"))
7185 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7187 (mult:QI (match_dup 1) (match_dup 2)))))
7188 (set (match_operand:QI 0 "register_operand" "=a")
7189 (mult:QI (match_dup 1) (match_dup 2)))]
7191 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7192 "<sgnprefix>mul{b}\t%2"
7193 [(set_attr "type" "imul")
7194 (set_attr "length_immediate" "0")
7195 (set (attr "athlon_decode")
7196 (if_then_else (eq_attr "cpu" "athlon")
7197 (const_string "vector")
7198 (const_string "direct")))
7199 (set_attr "amdfam10_decode" "direct")
7200 (set_attr "bdver1_decode" "direct")
7201 (set_attr "mode" "QI")])
7203 (define_expand "<u>mul<mode><dwi>3"
7204 [(parallel [(set (match_operand:<DWI> 0 "register_operand")
7207 (match_operand:DWIH 1 "nonimmediate_operand"))
7209 (match_operand:DWIH 2 "register_operand"))))
7210 (clobber (reg:CC FLAGS_REG))])])
7212 (define_expand "<u>mulqihi3"
7213 [(parallel [(set (match_operand:HI 0 "register_operand")
7216 (match_operand:QI 1 "nonimmediate_operand"))
7218 (match_operand:QI 2 "register_operand"))))
7219 (clobber (reg:CC FLAGS_REG))])]
7220 "TARGET_QIMODE_MATH")
7222 (define_insn "*bmi2_umul<mode><dwi>3_1"
7223 [(set (match_operand:DWIH 0 "register_operand" "=r")
7225 (match_operand:DWIH 2 "nonimmediate_operand" "%d")
7226 (match_operand:DWIH 3 "nonimmediate_operand" "rm")))
7227 (set (match_operand:DWIH 1 "register_operand" "=r")
7230 (mult:<DWI> (zero_extend:<DWI> (match_dup 2))
7231 (zero_extend:<DWI> (match_dup 3)))
7232 (match_operand:QI 4 "const_int_operand" "n"))))]
7233 "TARGET_BMI2 && INTVAL (operands[4]) == <MODE_SIZE> * BITS_PER_UNIT
7234 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7235 "mulx\t{%3, %0, %1|%1, %0, %3}"
7236 [(set_attr "type" "imulx")
7237 (set_attr "prefix" "vex")
7238 (set_attr "mode" "<MODE>")])
7240 (define_insn "*umul<mode><dwi>3_1"
7241 [(set (match_operand:<DWI> 0 "register_operand" "=r,A")
7244 (match_operand:DWIH 1 "nonimmediate_operand" "%d,0"))
7246 (match_operand:DWIH 2 "nonimmediate_operand" "rm,rm"))))
7247 (clobber (reg:CC FLAGS_REG))]
7248 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7251 mul{<imodesuffix>}\t%2"
7252 [(set_attr "isa" "bmi2,*")
7253 (set_attr "type" "imulx,imul")
7254 (set_attr "length_immediate" "*,0")
7255 (set (attr "athlon_decode")
7256 (cond [(eq_attr "alternative" "1")
7257 (if_then_else (eq_attr "cpu" "athlon")
7258 (const_string "vector")
7259 (const_string "double"))]
7260 (const_string "*")))
7261 (set_attr "amdfam10_decode" "*,double")
7262 (set_attr "bdver1_decode" "*,direct")
7263 (set_attr "prefix" "vex,orig")
7264 (set_attr "mode" "<MODE>")])
7266 ;; Convert mul to the mulx pattern to avoid flags dependency.
7268 [(set (match_operand:<DWI> 0 "register_operand")
7271 (match_operand:DWIH 1 "register_operand"))
7273 (match_operand:DWIH 2 "nonimmediate_operand"))))
7274 (clobber (reg:CC FLAGS_REG))]
7275 "TARGET_BMI2 && reload_completed
7276 && REGNO (operands[1]) == DX_REG"
7277 [(parallel [(set (match_dup 3)
7278 (mult:DWIH (match_dup 1) (match_dup 2)))
7282 (mult:<DWI> (zero_extend:<DWI> (match_dup 1))
7283 (zero_extend:<DWI> (match_dup 2)))
7286 split_double_mode (<DWI>mode, &operands[0], 1, &operands[3], &operands[4]);
7288 operands[5] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT);
7291 (define_insn "*mul<mode><dwi>3_1"
7292 [(set (match_operand:<DWI> 0 "register_operand" "=A")
7295 (match_operand:DWIH 1 "nonimmediate_operand" "%0"))
7297 (match_operand:DWIH 2 "nonimmediate_operand" "rm"))))
7298 (clobber (reg:CC FLAGS_REG))]
7299 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7300 "imul{<imodesuffix>}\t%2"
7301 [(set_attr "type" "imul")
7302 (set_attr "length_immediate" "0")
7303 (set (attr "athlon_decode")
7304 (if_then_else (eq_attr "cpu" "athlon")
7305 (const_string "vector")
7306 (const_string "double")))
7307 (set_attr "amdfam10_decode" "double")
7308 (set_attr "bdver1_decode" "direct")
7309 (set_attr "mode" "<MODE>")])
7311 (define_insn "*<u>mulqihi3_1"
7312 [(set (match_operand:HI 0 "register_operand" "=a")
7315 (match_operand:QI 1 "nonimmediate_operand" "%0"))
7317 (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7318 (clobber (reg:CC FLAGS_REG))]
7320 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7321 "<sgnprefix>mul{b}\t%2"
7322 [(set_attr "type" "imul")
7323 (set_attr "length_immediate" "0")
7324 (set (attr "athlon_decode")
7325 (if_then_else (eq_attr "cpu" "athlon")
7326 (const_string "vector")
7327 (const_string "direct")))
7328 (set_attr "amdfam10_decode" "direct")
7329 (set_attr "bdver1_decode" "direct")
7330 (set_attr "mode" "QI")])
7332 (define_expand "<s>mul<mode>3_highpart"
7333 [(parallel [(set (match_operand:DWIH 0 "register_operand")
7338 (match_operand:DWIH 1 "nonimmediate_operand"))
7340 (match_operand:DWIH 2 "register_operand")))
7342 (clobber (match_scratch:DWIH 4))
7343 (clobber (reg:CC FLAGS_REG))])]
7345 "operands[3] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
7347 (define_insn "*<s>muldi3_highpart_1"
7348 [(set (match_operand:DI 0 "register_operand" "=d")
7353 (match_operand:DI 1 "nonimmediate_operand" "%a"))
7355 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7357 (clobber (match_scratch:DI 3 "=1"))
7358 (clobber (reg:CC FLAGS_REG))]
7360 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7361 "<sgnprefix>mul{q}\t%2"
7362 [(set_attr "type" "imul")
7363 (set_attr "length_immediate" "0")
7364 (set (attr "athlon_decode")
7365 (if_then_else (eq_attr "cpu" "athlon")
7366 (const_string "vector")
7367 (const_string "double")))
7368 (set_attr "amdfam10_decode" "double")
7369 (set_attr "bdver1_decode" "direct")
7370 (set_attr "mode" "DI")])
7372 (define_insn "*<s>mulsi3_highpart_zext"
7373 [(set (match_operand:DI 0 "register_operand" "=d")
7374 (zero_extend:DI (truncate:SI
7376 (mult:DI (any_extend:DI
7377 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7379 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7381 (clobber (match_scratch:SI 3 "=1"))
7382 (clobber (reg:CC FLAGS_REG))]
7384 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7385 "<sgnprefix>mul{l}\t%2"
7386 [(set_attr "type" "imul")
7387 (set_attr "length_immediate" "0")
7388 (set (attr "athlon_decode")
7389 (if_then_else (eq_attr "cpu" "athlon")
7390 (const_string "vector")
7391 (const_string "double")))
7392 (set_attr "amdfam10_decode" "double")
7393 (set_attr "bdver1_decode" "direct")
7394 (set_attr "mode" "SI")])
7396 (define_insn "*<s>mulsi3_highpart_1"
7397 [(set (match_operand:SI 0 "register_operand" "=d")
7402 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7404 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7406 (clobber (match_scratch:SI 3 "=1"))
7407 (clobber (reg:CC FLAGS_REG))]
7408 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7409 "<sgnprefix>mul{l}\t%2"
7410 [(set_attr "type" "imul")
7411 (set_attr "length_immediate" "0")
7412 (set (attr "athlon_decode")
7413 (if_then_else (eq_attr "cpu" "athlon")
7414 (const_string "vector")
7415 (const_string "double")))
7416 (set_attr "amdfam10_decode" "double")
7417 (set_attr "bdver1_decode" "direct")
7418 (set_attr "mode" "SI")])
7420 ;; The patterns that match these are at the end of this file.
7422 (define_expand "mulxf3"
7423 [(set (match_operand:XF 0 "register_operand")
7424 (mult:XF (match_operand:XF 1 "register_operand")
7425 (match_operand:XF 2 "register_operand")))]
7428 (define_expand "mul<mode>3"
7429 [(set (match_operand:MODEF 0 "register_operand")
7430 (mult:MODEF (match_operand:MODEF 1 "register_operand")
7431 (match_operand:MODEF 2 "nonimmediate_operand")))]
7432 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
7433 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
7435 ;; Divide instructions
7437 ;; The patterns that match these are at the end of this file.
7439 (define_expand "divxf3"
7440 [(set (match_operand:XF 0 "register_operand")
7441 (div:XF (match_operand:XF 1 "register_operand")
7442 (match_operand:XF 2 "register_operand")))]
7445 (define_expand "div<mode>3"
7446 [(set (match_operand:MODEF 0 "register_operand")
7447 (div:MODEF (match_operand:MODEF 1 "register_operand")
7448 (match_operand:MODEF 2 "nonimmediate_operand")))]
7449 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
7450 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
7452 if (<MODE>mode == SFmode
7453 && TARGET_SSE && TARGET_SSE_MATH
7455 && optimize_insn_for_speed_p ()
7456 && flag_finite_math_only && !flag_trapping_math
7457 && flag_unsafe_math_optimizations)
7459 ix86_emit_swdivsf (operands[0], operands[1],
7460 operands[2], SFmode);
7465 ;; Divmod instructions.
7467 (define_code_iterator any_div [div udiv])
7468 (define_code_attr paired_mod [(div "mod") (udiv "umod")])
7470 (define_expand "<u>divmod<mode>4"
7471 [(parallel [(set (match_operand:SWIM248 0 "register_operand")
7473 (match_operand:SWIM248 1 "register_operand")
7474 (match_operand:SWIM248 2 "nonimmediate_operand")))
7475 (set (match_operand:SWIM248 3 "register_operand")
7476 (<paired_mod>:SWIM248 (match_dup 1) (match_dup 2)))
7477 (clobber (reg:CC FLAGS_REG))])])
7479 ;; Split with 8bit unsigned divide:
7480 ;; if (dividend an divisor are in [0-255])
7481 ;; use 8bit unsigned integer divide
7483 ;; use original integer divide
7485 [(set (match_operand:SWI48 0 "register_operand")
7486 (any_div:SWI48 (match_operand:SWI48 2 "register_operand")
7487 (match_operand:SWI48 3 "nonimmediate_operand")))
7488 (set (match_operand:SWI48 1 "register_operand")
7489 (<paired_mod>:SWI48 (match_dup 2) (match_dup 3)))
7490 (clobber (reg:CC FLAGS_REG))]
7491 "TARGET_USE_8BIT_IDIV
7492 && TARGET_QIMODE_MATH
7493 && can_create_pseudo_p ()
7494 && !optimize_insn_for_size_p ()"
7496 "ix86_split_idivmod (<MODE>mode, operands, <u_bool>); DONE;")
7499 [(set (match_operand:DI 0 "register_operand")
7501 (any_div:SI (match_operand:SI 2 "register_operand")
7502 (match_operand:SI 3 "nonimmediate_operand"))))
7503 (set (match_operand:SI 1 "register_operand")
7504 (<paired_mod>:SI (match_dup 2) (match_dup 3)))
7505 (clobber (reg:CC FLAGS_REG))]
7507 && TARGET_USE_8BIT_IDIV
7508 && TARGET_QIMODE_MATH
7509 && can_create_pseudo_p ()
7510 && !optimize_insn_for_size_p ()"
7512 "ix86_split_idivmod (SImode, operands, <u_bool>); DONE;")
7515 [(set (match_operand:DI 1 "register_operand")
7517 (<paired_mod>:SI (match_operand:SI 2 "register_operand")
7518 (match_operand:SI 3 "nonimmediate_operand"))))
7519 (set (match_operand:SI 0 "register_operand")
7520 (any_div:SI (match_dup 2) (match_dup 3)))
7521 (clobber (reg:CC FLAGS_REG))]
7523 && TARGET_USE_8BIT_IDIV
7524 && TARGET_QIMODE_MATH
7525 && can_create_pseudo_p ()
7526 && !optimize_insn_for_size_p ()"
7528 "ix86_split_idivmod (SImode, operands, <u_bool>); DONE;")
7530 (define_insn_and_split "divmod<mode>4_1"
7531 [(set (match_operand:SWI48 0 "register_operand" "=a")
7532 (div:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7533 (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
7534 (set (match_operand:SWI48 1 "register_operand" "=&d")
7535 (mod:SWI48 (match_dup 2) (match_dup 3)))
7536 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7537 (clobber (reg:CC FLAGS_REG))]
7541 [(parallel [(set (match_dup 1)
7542 (ashiftrt:SWI48 (match_dup 4) (match_dup 5)))
7543 (clobber (reg:CC FLAGS_REG))])
7544 (parallel [(set (match_dup 0)
7545 (div:SWI48 (match_dup 2) (match_dup 3)))
7547 (mod:SWI48 (match_dup 2) (match_dup 3)))
7549 (clobber (reg:CC FLAGS_REG))])]
7551 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7553 if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
7554 operands[4] = operands[2];
7557 /* Avoid use of cltd in favor of a mov+shift. */
7558 emit_move_insn (operands[1], operands[2]);
7559 operands[4] = operands[1];
7562 [(set_attr "type" "multi")
7563 (set_attr "mode" "<MODE>")])
7565 (define_insn_and_split "udivmod<mode>4_1"
7566 [(set (match_operand:SWI48 0 "register_operand" "=a")
7567 (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7568 (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
7569 (set (match_operand:SWI48 1 "register_operand" "=&d")
7570 (umod:SWI48 (match_dup 2) (match_dup 3)))
7571 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7572 (clobber (reg:CC FLAGS_REG))]
7576 [(set (match_dup 1) (const_int 0))
7577 (parallel [(set (match_dup 0)
7578 (udiv:SWI48 (match_dup 2) (match_dup 3)))
7580 (umod:SWI48 (match_dup 2) (match_dup 3)))
7582 (clobber (reg:CC FLAGS_REG))])]
7584 [(set_attr "type" "multi")
7585 (set_attr "mode" "<MODE>")])
7587 (define_insn_and_split "divmodsi4_zext_1"
7588 [(set (match_operand:DI 0 "register_operand" "=a")
7590 (div:SI (match_operand:SI 2 "register_operand" "0")
7591 (match_operand:SI 3 "nonimmediate_operand" "rm"))))
7592 (set (match_operand:SI 1 "register_operand" "=&d")
7593 (mod:SI (match_dup 2) (match_dup 3)))
7594 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7595 (clobber (reg:CC FLAGS_REG))]
7598 "&& reload_completed"
7599 [(parallel [(set (match_dup 1)
7600 (ashiftrt:SI (match_dup 4) (match_dup 5)))
7601 (clobber (reg:CC FLAGS_REG))])
7602 (parallel [(set (match_dup 0)
7603 (zero_extend:DI (div:SI (match_dup 2) (match_dup 3))))
7605 (mod:SI (match_dup 2) (match_dup 3)))
7607 (clobber (reg:CC FLAGS_REG))])]
7609 operands[5] = GEN_INT (GET_MODE_BITSIZE (SImode)-1);
7611 if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
7612 operands[4] = operands[2];
7615 /* Avoid use of cltd in favor of a mov+shift. */
7616 emit_move_insn (operands[1], operands[2]);
7617 operands[4] = operands[1];
7620 [(set_attr "type" "multi")
7621 (set_attr "mode" "SI")])
7623 (define_insn_and_split "udivmodsi4_zext_1"
7624 [(set (match_operand:DI 0 "register_operand" "=a")
7626 (udiv:SI (match_operand:SI 2 "register_operand" "0")
7627 (match_operand:SI 3 "nonimmediate_operand" "rm"))))
7628 (set (match_operand:SI 1 "register_operand" "=&d")
7629 (umod:SI (match_dup 2) (match_dup 3)))
7630 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7631 (clobber (reg:CC FLAGS_REG))]
7634 "&& reload_completed"
7635 [(set (match_dup 1) (const_int 0))
7636 (parallel [(set (match_dup 0)
7637 (zero_extend:DI (udiv:SI (match_dup 2) (match_dup 3))))
7639 (umod:SI (match_dup 2) (match_dup 3)))
7641 (clobber (reg:CC FLAGS_REG))])]
7643 [(set_attr "type" "multi")
7644 (set_attr "mode" "SI")])
7646 (define_insn_and_split "divmodsi4_zext_2"
7647 [(set (match_operand:DI 1 "register_operand" "=&d")
7649 (mod:SI (match_operand:SI 2 "register_operand" "0")
7650 (match_operand:SI 3 "nonimmediate_operand" "rm"))))
7651 (set (match_operand:SI 0 "register_operand" "=a")
7652 (div:SI (match_dup 2) (match_dup 3)))
7653 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7654 (clobber (reg:CC FLAGS_REG))]
7657 "&& reload_completed"
7658 [(parallel [(set (match_dup 6)
7659 (ashiftrt:SI (match_dup 4) (match_dup 5)))
7660 (clobber (reg:CC FLAGS_REG))])
7661 (parallel [(set (match_dup 1)
7662 (zero_extend:DI (mod:SI (match_dup 2) (match_dup 3))))
7664 (div:SI (match_dup 2) (match_dup 3)))
7666 (clobber (reg:CC FLAGS_REG))])]
7668 operands[5] = GEN_INT (GET_MODE_BITSIZE (SImode)-1);
7669 operands[6] = gen_lowpart (SImode, operands[1]);
7671 if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
7672 operands[4] = operands[2];
7675 /* Avoid use of cltd in favor of a mov+shift. */
7676 emit_move_insn (operands[6], operands[2]);
7677 operands[4] = operands[6];
7680 [(set_attr "type" "multi")
7681 (set_attr "mode" "SI")])
7683 (define_insn_and_split "udivmodsi4_zext_2"
7684 [(set (match_operand:DI 1 "register_operand" "=&d")
7686 (umod:SI (match_operand:SI 2 "register_operand" "0")
7687 (match_operand:SI 3 "nonimmediate_operand" "rm"))))
7688 (set (match_operand:SI 0 "register_operand" "=a")
7689 (udiv:SI (match_dup 2) (match_dup 3)))
7690 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7691 (clobber (reg:CC FLAGS_REG))]
7694 "&& reload_completed"
7695 [(set (match_dup 4) (const_int 0))
7696 (parallel [(set (match_dup 1)
7697 (zero_extend:DI (umod:SI (match_dup 2) (match_dup 3))))
7699 (udiv:SI (match_dup 2) (match_dup 3)))
7701 (clobber (reg:CC FLAGS_REG))])]
7702 "operands[4] = gen_lowpart (SImode, operands[1]);"
7703 [(set_attr "type" "multi")
7704 (set_attr "mode" "SI")])
7706 (define_insn_and_split "*divmod<mode>4"
7707 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7708 (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7709 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7710 (set (match_operand:SWIM248 1 "register_operand" "=&d")
7711 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7712 (clobber (reg:CC FLAGS_REG))]
7716 [(parallel [(set (match_dup 1)
7717 (ashiftrt:SWIM248 (match_dup 4) (match_dup 5)))
7718 (clobber (reg:CC FLAGS_REG))])
7719 (parallel [(set (match_dup 0)
7720 (div:SWIM248 (match_dup 2) (match_dup 3)))
7722 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7724 (clobber (reg:CC FLAGS_REG))])]
7726 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7728 if (<MODE>mode != HImode
7729 && (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD))
7730 operands[4] = operands[2];
7733 /* Avoid use of cltd in favor of a mov+shift. */
7734 emit_move_insn (operands[1], operands[2]);
7735 operands[4] = operands[1];
7738 [(set_attr "type" "multi")
7739 (set_attr "mode" "<MODE>")])
7741 (define_insn_and_split "*udivmod<mode>4"
7742 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7743 (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7744 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7745 (set (match_operand:SWIM248 1 "register_operand" "=&d")
7746 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7747 (clobber (reg:CC FLAGS_REG))]
7751 [(set (match_dup 1) (const_int 0))
7752 (parallel [(set (match_dup 0)
7753 (udiv:SWIM248 (match_dup 2) (match_dup 3)))
7755 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7757 (clobber (reg:CC FLAGS_REG))])]
7759 [(set_attr "type" "multi")
7760 (set_attr "mode" "<MODE>")])
7762 ;; Optimize division or modulo by constant power of 2, if the constant
7763 ;; materializes only after expansion.
7764 (define_insn_and_split "*udivmod<mode>4_pow2"
7765 [(set (match_operand:SWI48 0 "register_operand" "=r")
7766 (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7767 (match_operand:SWI48 3 "const_int_operand" "n")))
7768 (set (match_operand:SWI48 1 "register_operand" "=r")
7769 (umod:SWI48 (match_dup 2) (match_dup 3)))
7770 (clobber (reg:CC FLAGS_REG))]
7771 "IN_RANGE (exact_log2 (UINTVAL (operands[3])), 1, 31)"
7773 "&& reload_completed"
7774 [(set (match_dup 1) (match_dup 2))
7775 (parallel [(set (match_dup 0) (lshiftrt:<MODE> (match_dup 2) (match_dup 4)))
7776 (clobber (reg:CC FLAGS_REG))])
7777 (parallel [(set (match_dup 1) (and:<MODE> (match_dup 1) (match_dup 5)))
7778 (clobber (reg:CC FLAGS_REG))])]
7780 int v = exact_log2 (UINTVAL (operands[3]));
7781 operands[4] = GEN_INT (v);
7782 operands[5] = GEN_INT ((HOST_WIDE_INT_1U << v) - 1);
7784 [(set_attr "type" "multi")
7785 (set_attr "mode" "<MODE>")])
7787 (define_insn_and_split "*divmodsi4_zext_1"
7788 [(set (match_operand:DI 0 "register_operand" "=a")
7790 (div:SI (match_operand:SI 2 "register_operand" "0")
7791 (match_operand:SI 3 "nonimmediate_operand" "rm"))))
7792 (set (match_operand:SI 1 "register_operand" "=&d")
7793 (mod:SI (match_dup 2) (match_dup 3)))
7794 (clobber (reg:CC FLAGS_REG))]
7797 "&& reload_completed"
7798 [(parallel [(set (match_dup 1)
7799 (ashiftrt:SI (match_dup 4) (match_dup 5)))
7800 (clobber (reg:CC FLAGS_REG))])
7801 (parallel [(set (match_dup 0)
7802 (zero_extend:DI (div:SI (match_dup 2) (match_dup 3))))
7804 (mod:SI (match_dup 2) (match_dup 3)))
7806 (clobber (reg:CC FLAGS_REG))])]
7808 operands[5] = GEN_INT (GET_MODE_BITSIZE (SImode)-1);
7810 if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
7811 operands[4] = operands[2];
7814 /* Avoid use of cltd in favor of a mov+shift. */
7815 emit_move_insn (operands[1], operands[2]);
7816 operands[4] = operands[1];
7819 [(set_attr "type" "multi")
7820 (set_attr "mode" "SI")])
7822 (define_insn_and_split "*udivmodsi4_zext_1"
7823 [(set (match_operand:DI 0 "register_operand" "=a")
7825 (udiv:SI (match_operand:SI 2 "register_operand" "0")
7826 (match_operand:SI 3 "nonimmediate_operand" "rm"))))
7827 (set (match_operand:SI 1 "register_operand" "=&d")
7828 (umod:SI (match_dup 2) (match_dup 3)))
7829 (clobber (reg:CC FLAGS_REG))]
7832 "&& reload_completed"
7833 [(set (match_dup 1) (const_int 0))
7834 (parallel [(set (match_dup 0)
7835 (zero_extend:DI (udiv:SI (match_dup 2) (match_dup 3))))
7837 (umod:SI (match_dup 2) (match_dup 3)))
7839 (clobber (reg:CC FLAGS_REG))])]
7841 [(set_attr "type" "multi")
7842 (set_attr "mode" "SI")])
7844 (define_insn_and_split "*udivmodsi4_pow2_zext_1"
7845 [(set (match_operand:DI 0 "register_operand" "=r")
7847 (udiv:SI (match_operand:SI 2 "register_operand" "0")
7848 (match_operand:SI 3 "const_int_operand" "n"))))
7849 (set (match_operand:SI 1 "register_operand" "=r")
7850 (umod:SI (match_dup 2) (match_dup 3)))
7851 (clobber (reg:CC FLAGS_REG))]
7853 && exact_log2 (UINTVAL (operands[3])) > 0"
7855 "&& reload_completed"
7856 [(set (match_dup 1) (match_dup 2))
7857 (parallel [(set (match_dup 0)
7858 (zero_extend:DI (lshiftrt:SI (match_dup 2) (match_dup 4))))
7859 (clobber (reg:CC FLAGS_REG))])
7860 (parallel [(set (match_dup 1) (and:SI (match_dup 1) (match_dup 5)))
7861 (clobber (reg:CC FLAGS_REG))])]
7863 int v = exact_log2 (UINTVAL (operands[3]));
7864 operands[4] = GEN_INT (v);
7865 operands[5] = GEN_INT ((HOST_WIDE_INT_1U << v) - 1);
7867 [(set_attr "type" "multi")
7868 (set_attr "mode" "SI")])
7870 (define_insn_and_split "*divmodsi4_zext_2"
7871 [(set (match_operand:DI 1 "register_operand" "=&d")
7873 (mod:SI (match_operand:SI 2 "register_operand" "0")
7874 (match_operand:SI 3 "nonimmediate_operand" "rm"))))
7875 (set (match_operand:SI 0 "register_operand" "=a")
7876 (div:SI (match_dup 2) (match_dup 3)))
7877 (clobber (reg:CC FLAGS_REG))]
7880 "&& reload_completed"
7881 [(parallel [(set (match_dup 6)
7882 (ashiftrt:SI (match_dup 4) (match_dup 5)))
7883 (clobber (reg:CC FLAGS_REG))])
7884 (parallel [(set (match_dup 1)
7885 (zero_extend:DI (mod:SI (match_dup 2) (match_dup 3))))
7887 (div:SI (match_dup 2) (match_dup 3)))
7889 (clobber (reg:CC FLAGS_REG))])]
7891 operands[5] = GEN_INT (GET_MODE_BITSIZE (SImode)-1);
7892 operands[6] = gen_lowpart (SImode, operands[1]);
7894 if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
7895 operands[4] = operands[2];
7898 /* Avoid use of cltd in favor of a mov+shift. */
7899 emit_move_insn (operands[6], operands[2]);
7900 operands[4] = operands[6];
7903 [(set_attr "type" "multi")
7904 (set_attr "mode" "SI")])
7906 (define_insn_and_split "*udivmodsi4_zext_2"
7907 [(set (match_operand:DI 1 "register_operand" "=&d")
7909 (umod:SI (match_operand:SI 2 "register_operand" "0")
7910 (match_operand:SI 3 "nonimmediate_operand" "rm"))))
7911 (set (match_operand:SI 0 "register_operand" "=a")
7912 (udiv:SI (match_dup 2) (match_dup 3)))
7913 (clobber (reg:CC FLAGS_REG))]
7916 "&& reload_completed"
7917 [(set (match_dup 4) (const_int 0))
7918 (parallel [(set (match_dup 1)
7919 (zero_extend:DI (umod:SI (match_dup 2) (match_dup 3))))
7921 (udiv:SI (match_dup 2) (match_dup 3)))
7923 (clobber (reg:CC FLAGS_REG))])]
7924 "operands[4] = gen_lowpart (SImode, operands[1]);"
7925 [(set_attr "type" "multi")
7926 (set_attr "mode" "SI")])
7928 (define_insn_and_split "*udivmodsi4_pow2_zext_2"
7929 [(set (match_operand:DI 1 "register_operand" "=r")
7931 (umod:SI (match_operand:SI 2 "register_operand" "0")
7932 (match_operand:SI 3 "const_int_operand" "n"))))
7933 (set (match_operand:SI 0 "register_operand" "=r")
7934 (umod:SI (match_dup 2) (match_dup 3)))
7935 (clobber (reg:CC FLAGS_REG))]
7937 && exact_log2 (UINTVAL (operands[3])) > 0"
7939 "&& reload_completed"
7940 [(set (match_dup 1) (match_dup 2))
7941 (parallel [(set (match_dup 0) (lshiftrt:SI (match_dup 2) (match_dup 4)))
7942 (clobber (reg:CC FLAGS_REG))])
7943 (parallel [(set (match_dup 1)
7944 (zero_extend:DI (and:SI (match_dup 1) (match_dup 5))))
7945 (clobber (reg:CC FLAGS_REG))])]
7947 int v = exact_log2 (UINTVAL (operands[3]));
7948 operands[4] = GEN_INT (v);
7949 operands[5] = GEN_INT ((HOST_WIDE_INT_1U << v) - 1);
7951 [(set_attr "type" "multi")
7952 (set_attr "mode" "SI")])
7954 (define_insn "*<u>divmod<mode>4_noext"
7955 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7957 (match_operand:SWIM248 2 "register_operand" "0")
7958 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7959 (set (match_operand:SWIM248 1 "register_operand" "=d")
7960 (<paired_mod>:SWIM248 (match_dup 2) (match_dup 3)))
7961 (use (match_operand:SWIM248 4 "register_operand" "1"))
7962 (clobber (reg:CC FLAGS_REG))]
7964 "<sgnprefix>div{<imodesuffix>}\t%3"
7965 [(set_attr "type" "idiv")
7966 (set_attr "mode" "<MODE>")])
7968 (define_insn "*<u>divmodsi4_noext_zext_1"
7969 [(set (match_operand:DI 0 "register_operand" "=a")
7971 (any_div:SI (match_operand:SI 2 "register_operand" "0")
7972 (match_operand:SI 3 "nonimmediate_operand" "rm"))))
7973 (set (match_operand:SI 1 "register_operand" "=d")
7974 (<paired_mod>:SI (match_dup 2) (match_dup 3)))
7975 (use (match_operand:SI 4 "register_operand" "1"))
7976 (clobber (reg:CC FLAGS_REG))]
7978 "<sgnprefix>div{l}\t%3"
7979 [(set_attr "type" "idiv")
7980 (set_attr "mode" "SI")])
7982 (define_insn "*<u>divmodsi4_noext_zext_2"
7983 [(set (match_operand:DI 1 "register_operand" "=d")
7985 (<paired_mod>:SI (match_operand:SI 2 "register_operand" "0")
7986 (match_operand:SI 3 "nonimmediate_operand" "rm"))))
7987 (set (match_operand:SI 0 "register_operand" "=a")
7988 (any_div:SI (match_dup 2) (match_dup 3)))
7989 (use (match_operand:SI 4 "register_operand" "1"))
7990 (clobber (reg:CC FLAGS_REG))]
7992 "<sgnprefix>div{l}\t%3"
7993 [(set_attr "type" "idiv")
7994 (set_attr "mode" "SI")])
7996 (define_expand "divmodqi4"
7997 [(parallel [(set (match_operand:QI 0 "register_operand")
7999 (match_operand:QI 1 "register_operand")
8000 (match_operand:QI 2 "nonimmediate_operand")))
8001 (set (match_operand:QI 3 "register_operand")
8002 (mod:QI (match_dup 1) (match_dup 2)))
8003 (clobber (reg:CC FLAGS_REG))])]
8004 "TARGET_QIMODE_MATH"
8009 tmp0 = gen_reg_rtx (HImode);
8010 tmp1 = gen_reg_rtx (HImode);
8012 /* Extend operands[1] to HImode. Generate 8bit divide. Result is in AX. */
8013 emit_insn (gen_extendqihi2 (tmp1, operands[1]));
8014 emit_insn (gen_divmodhiqi3 (tmp0, tmp1, operands[2]));
8016 /* Extract remainder from AH. */
8017 tmp1 = gen_rtx_ZERO_EXTRACT (SImode, tmp0, GEN_INT (8), GEN_INT (8));
8018 tmp1 = lowpart_subreg (QImode, tmp1, SImode);
8019 rtx_insn *insn = emit_move_insn (operands[3], tmp1);
8021 mod = gen_rtx_MOD (QImode, operands[1], operands[2]);
8022 set_unique_reg_note (insn, REG_EQUAL, mod);
8024 /* Extract quotient from AL. */
8025 insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
8027 div = gen_rtx_DIV (QImode, operands[1], operands[2]);
8028 set_unique_reg_note (insn, REG_EQUAL, div);
8033 (define_expand "udivmodqi4"
8034 [(parallel [(set (match_operand:QI 0 "register_operand")
8036 (match_operand:QI 1 "register_operand")
8037 (match_operand:QI 2 "nonimmediate_operand")))
8038 (set (match_operand:QI 3 "register_operand")
8039 (umod:QI (match_dup 1) (match_dup 2)))
8040 (clobber (reg:CC FLAGS_REG))])]
8041 "TARGET_QIMODE_MATH"
8046 tmp0 = gen_reg_rtx (HImode);
8047 tmp1 = gen_reg_rtx (HImode);
8049 /* Extend operands[1] to HImode. Generate 8bit divide. Result is in AX. */
8050 emit_insn (gen_zero_extendqihi2 (tmp1, operands[1]));
8051 emit_insn (gen_udivmodhiqi3 (tmp0, tmp1, operands[2]));
8053 /* Extract remainder from AH. */
8054 tmp1 = gen_rtx_ZERO_EXTRACT (SImode, tmp0, GEN_INT (8), GEN_INT (8));
8055 tmp1 = lowpart_subreg (QImode, tmp1, SImode);
8056 rtx_insn *insn = emit_move_insn (operands[3], tmp1);
8058 mod = gen_rtx_UMOD (QImode, operands[1], operands[2]);
8059 set_unique_reg_note (insn, REG_EQUAL, mod);
8061 /* Extract quotient from AL. */
8062 insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
8064 div = gen_rtx_UDIV (QImode, operands[1], operands[2]);
8065 set_unique_reg_note (insn, REG_EQUAL, div);
8070 ;; Divide AX by r/m8, with result stored in
8073 ;; Change div/mod to HImode and extend the second argument to HImode
8074 ;; so that mode of div/mod matches with mode of arguments. Otherwise
8075 ;; combine may fail.
8076 (define_insn "<u>divmodhiqi3"
8077 [(set (match_operand:HI 0 "register_operand" "=a")
8082 (mod:HI (match_operand:HI 1 "register_operand" "0")
8084 (match_operand:QI 2 "nonimmediate_operand" "qm")))))
8088 (div:HI (match_dup 1) (any_extend:HI (match_dup 2)))))))
8089 (clobber (reg:CC FLAGS_REG))]
8090 "TARGET_QIMODE_MATH"
8091 "<sgnprefix>div{b}\t%2"
8092 [(set_attr "type" "idiv")
8093 (set_attr "mode" "QI")])
8095 ;; We cannot use div/idiv for double division, because it causes
8096 ;; "division by zero" on the overflow and that's not what we expect
8097 ;; from truncate. Because true (non truncating) double division is
8098 ;; never generated, we can't create this insn anyway.
8101 ; [(set (match_operand:SI 0 "register_operand" "=a")
8103 ; (udiv:DI (match_operand:DI 1 "register_operand" "A")
8105 ; (match_operand:SI 2 "nonimmediate_operand" "rm")))))
8106 ; (set (match_operand:SI 3 "register_operand" "=d")
8108 ; (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
8109 ; (clobber (reg:CC FLAGS_REG))]
8111 ; "div{l}\t{%2, %0|%0, %2}"
8112 ; [(set_attr "type" "idiv")])
8114 ;;- Logical AND instructions
8116 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
8117 ;; Note that this excludes ah.
8119 (define_expand "testsi_ccno_1"
8120 [(set (reg:CCNO FLAGS_REG)
8122 (and:SI (match_operand:SI 0 "nonimmediate_operand")
8123 (match_operand:SI 1 "x86_64_nonmemory_operand"))
8126 (define_expand "testqi_ccz_1"
8127 [(set (reg:CCZ FLAGS_REG)
8128 (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand")
8129 (match_operand:QI 1 "nonmemory_operand"))
8132 (define_expand "testdi_ccno_1"
8133 [(set (reg:CCNO FLAGS_REG)
8135 (and:DI (match_operand:DI 0 "nonimmediate_operand")
8136 (match_operand:DI 1 "x86_64_szext_general_operand"))
8138 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))")
8140 (define_insn "*testdi_1"
8141 [(set (reg FLAGS_REG)
8144 (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
8145 (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
8147 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8148 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8150 test{l}\t{%k1, %k0|%k0, %k1}
8151 test{l}\t{%k1, %k0|%k0, %k1}
8152 test{q}\t{%1, %0|%0, %1}
8153 test{q}\t{%1, %0|%0, %1}
8154 test{q}\t{%1, %0|%0, %1}"
8155 [(set_attr "type" "test")
8156 (set_attr "modrm" "0,1,0,1,1")
8157 (set_attr "mode" "SI,SI,DI,DI,DI")])
8159 (define_insn "*testqi_1_maybe_si"
8160 [(set (reg FLAGS_REG)
8163 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
8164 (match_operand:QI 1 "general_operand" "n,n,qn,n"))
8166 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
8167 && ix86_match_ccmode (insn,
8168 CONST_INT_P (operands[1])
8169 && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
8171 if (which_alternative == 3)
8173 if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
8174 operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
8175 return "test{l}\t{%1, %k0|%k0, %1}";
8177 return "test{b}\t{%1, %0|%0, %1}";
8179 [(set_attr "type" "test")
8180 (set_attr "modrm" "0,1,1,1")
8181 (set_attr "mode" "QI,QI,QI,SI")
8182 (set_attr "pent_pair" "uv,np,uv,np")])
8184 (define_insn "*test<mode>_1"
8185 [(set (reg FLAGS_REG)
8188 (match_operand:SWI124 0 "nonimmediate_operand" "%!*a,<r>,<r>m")
8189 (match_operand:SWI124 1 "<general_operand>" "<i>,<i>,<r><i>"))
8191 "ix86_match_ccmode (insn, CCNOmode)
8192 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8193 "test{<imodesuffix>}\t{%1, %0|%0, %1}"
8194 [(set_attr "type" "test")
8195 (set_attr "modrm" "0,1,1")
8196 (set_attr "mode" "<MODE>")
8197 (set_attr "pent_pair" "uv,np,uv")])
8199 (define_expand "testqi_ext_1_ccno"
8200 [(set (reg:CCNO FLAGS_REG)
8204 (zero_extract:SI (match_operand 0 "ext_register_operand")
8207 (match_operand 1 "const_int_operand"))
8210 (define_insn "*testqi_ext_1"
8211 [(set (reg FLAGS_REG)
8215 (zero_extract:SI (match_operand 0 "ext_register_operand" "Q,Q")
8218 (match_operand:QI 1 "general_operand" "QnBc,m"))
8220 "ix86_match_ccmode (insn, CCNOmode)"
8221 "test{b}\t{%1, %h0|%h0, %1}"
8222 [(set_attr "isa" "*,nox64")
8223 (set_attr "type" "test")
8224 (set_attr "mode" "QI")])
8226 (define_insn "*testqi_ext_2"
8227 [(set (reg FLAGS_REG)
8231 (zero_extract:SI (match_operand 0 "ext_register_operand" "Q")
8235 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q")
8239 "ix86_match_ccmode (insn, CCNOmode)"
8240 "test{b}\t{%h1, %h0|%h0, %h1}"
8241 [(set_attr "type" "test")
8242 (set_attr "mode" "QI")])
8244 ;; Combine likes to form bit extractions for some tests. Humor it.
8245 (define_insn_and_split "*testqi_ext_3"
8246 [(set (match_operand 0 "flags_reg_operand")
8247 (match_operator 1 "compare_operator"
8248 [(zero_extract:SWI248
8249 (match_operand 2 "nonimmediate_operand" "rm")
8250 (match_operand 3 "const_int_operand" "n")
8251 (match_operand 4 "const_int_operand" "n"))
8253 "ix86_match_ccmode (insn, CCNOmode)
8254 && ((TARGET_64BIT && GET_MODE (operands[2]) == DImode)
8255 || GET_MODE (operands[2]) == SImode
8256 || GET_MODE (operands[2]) == HImode
8257 || GET_MODE (operands[2]) == QImode)
8258 /* Ensure that resulting mask is zero or sign extended operand. */
8259 && INTVAL (operands[4]) >= 0
8260 && ((INTVAL (operands[3]) > 0
8261 && INTVAL (operands[3]) + INTVAL (operands[4]) <= 32)
8262 || (<MODE>mode == DImode
8263 && INTVAL (operands[3]) > 32
8264 && INTVAL (operands[3]) + INTVAL (operands[4]) == 64))"
8267 [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
8269 rtx val = operands[2];
8270 HOST_WIDE_INT len = INTVAL (operands[3]);
8271 HOST_WIDE_INT pos = INTVAL (operands[4]);
8272 machine_mode mode = GET_MODE (val);
8276 machine_mode submode = GET_MODE (SUBREG_REG (val));
8278 /* Narrow paradoxical subregs to prevent partial register stalls. */
8279 if (GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode)
8280 && GET_MODE_CLASS (submode) == MODE_INT)
8282 val = SUBREG_REG (val);
8287 /* Small HImode tests can be converted to QImode. */
8288 if (register_operand (val, HImode) && pos + len <= 8)
8290 val = gen_lowpart (QImode, val);
8294 gcc_assert (pos + len <= GET_MODE_PRECISION (mode));
8297 = wi::shifted_mask (pos, len, false, GET_MODE_PRECISION (mode));
8299 operands[2] = gen_rtx_AND (mode, val, immed_wide_int_const (mask, mode));
8302 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
8303 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
8304 ;; this is relatively important trick.
8305 ;; Do the conversion only post-reload to avoid limiting of the register class
8308 [(set (match_operand 0 "flags_reg_operand")
8309 (match_operator 1 "compare_operator"
8310 [(and (match_operand 2 "QIreg_operand")
8311 (match_operand 3 "const_int_operand"))
8314 && GET_MODE (operands[2]) != QImode
8315 && ((ix86_match_ccmode (insn, CCZmode)
8316 && !(INTVAL (operands[3]) & ~(255 << 8)))
8317 || (ix86_match_ccmode (insn, CCNOmode)
8318 && !(INTVAL (operands[3]) & ~(127 << 8))))"
8323 (zero_extract:SI (match_dup 2)
8329 operands[2] = gen_lowpart (SImode, operands[2]);
8330 operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, QImode);
8334 [(set (match_operand 0 "flags_reg_operand")
8335 (match_operator 1 "compare_operator"
8336 [(and (match_operand 2 "nonimmediate_operand")
8337 (match_operand 3 "const_int_operand"))
8340 && GET_MODE (operands[2]) != QImode
8341 && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
8342 && ((ix86_match_ccmode (insn, CCZmode)
8343 && !(INTVAL (operands[3]) & ~255))
8344 || (ix86_match_ccmode (insn, CCNOmode)
8345 && !(INTVAL (operands[3]) & ~127)))"
8347 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
8350 operands[2] = gen_lowpart (QImode, operands[2]);
8351 operands[3] = gen_int_mode (INTVAL (operands[3]), QImode);
8354 ;; %%% This used to optimize known byte-wide and operations to memory,
8355 ;; and sometimes to QImode registers. If this is considered useful,
8356 ;; it should be done with splitters.
8358 (define_expand "and<mode>3"
8359 [(set (match_operand:SWIM1248s 0 "nonimmediate_operand")
8360 (and:SWIM1248s (match_operand:SWIM1248s 1 "nonimmediate_operand")
8361 (match_operand:SWIM1248s 2 "<general_szext_operand>")))]
8364 machine_mode mode = <MODE>mode;
8366 if (<MODE>mode == DImode && !TARGET_64BIT)
8368 else if (const_int_operand (operands[2], <MODE>mode)
8369 && register_operand (operands[0], <MODE>mode)
8370 && !(TARGET_ZERO_EXTEND_WITH_AND
8371 && optimize_function_for_speed_p (cfun)))
8373 unsigned HOST_WIDE_INT ival = UINTVAL (operands[2]);
8375 if (ival == GET_MODE_MASK (SImode))
8377 else if (ival == GET_MODE_MASK (HImode))
8379 else if (ival == GET_MODE_MASK (QImode))
8383 if (mode != <MODE>mode)
8384 emit_insn (gen_extend_insn
8385 (operands[0], gen_lowpart (mode, operands[1]),
8386 <MODE>mode, mode, 1));
8388 ix86_expand_binary_operator (AND, <MODE>mode, operands);
8393 (define_insn_and_split "*anddi3_doubleword"
8394 [(set (match_operand:DI 0 "nonimmediate_operand")
8396 (match_operand:DI 1 "nonimmediate_operand")
8397 (match_operand:DI 2 "x86_64_szext_general_operand")))
8398 (clobber (reg:CC FLAGS_REG))]
8399 "!TARGET_64BIT && TARGET_STV && TARGET_SSE2
8400 && ix86_binary_operator_ok (AND, DImode, operands)
8401 && can_create_pseudo_p ()"
8406 split_double_mode (DImode, &operands[0], 3, &operands[0], &operands[3]);
8408 if (operands[2] == const0_rtx)
8409 emit_move_insn (operands[0], const0_rtx);
8410 else if (operands[2] == constm1_rtx)
8411 emit_move_insn (operands[0], operands[1]);
8413 emit_insn (gen_andsi3 (operands[0], operands[1], operands[2]));
8415 if (operands[5] == const0_rtx)
8416 emit_move_insn (operands[3], const0_rtx);
8417 else if (operands[5] == constm1_rtx)
8418 emit_move_insn (operands[3], operands[4]);
8420 emit_insn (gen_andsi3 (operands[3], operands[4], operands[5]));
8425 (define_insn "*anddi_1"
8426 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
8428 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
8429 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
8430 (clobber (reg:CC FLAGS_REG))]
8431 "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
8433 and{l}\t{%k2, %k0|%k0, %k2}
8434 and{q}\t{%2, %0|%0, %2}
8435 and{q}\t{%2, %0|%0, %2}
8437 [(set_attr "type" "alu,alu,alu,imovx")
8438 (set_attr "length_immediate" "*,*,*,0")
8439 (set (attr "prefix_rex")
8441 (and (eq_attr "type" "imovx")
8442 (and (match_test "INTVAL (operands[2]) == 0xff")
8443 (match_operand 1 "ext_QIreg_operand")))
8445 (const_string "*")))
8446 (set_attr "mode" "SI,DI,DI,SI")])
8448 (define_insn_and_split "*anddi_1_btr"
8449 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
8451 (match_operand:DI 1 "nonimmediate_operand" "%0")
8452 (match_operand:DI 2 "const_int_operand" "n")))
8453 (clobber (reg:CC FLAGS_REG))]
8454 "TARGET_64BIT && TARGET_USE_BT
8455 && ix86_binary_operator_ok (AND, DImode, operands)
8456 && IN_RANGE (exact_log2 (~INTVAL (operands[2])), 31, 63)"
8458 "&& reload_completed"
8459 [(parallel [(set (zero_extract:DI (match_dup 0)
8463 (clobber (reg:CC FLAGS_REG))])]
8464 "operands[3] = GEN_INT (exact_log2 (~INTVAL (operands[2])));"
8465 [(set_attr "type" "alu1")
8466 (set_attr "prefix_0f" "1")
8467 (set_attr "znver1_decode" "double")
8468 (set_attr "mode" "DI")])
8470 ;; Turn *anddi_1 into *andsi_1_zext if possible.
8472 [(set (match_operand:DI 0 "register_operand")
8473 (and:DI (subreg:DI (match_operand:SI 1 "register_operand") 0)
8474 (match_operand:DI 2 "x86_64_zext_immediate_operand")))
8475 (clobber (reg:CC FLAGS_REG))]
8477 [(parallel [(set (match_dup 0)
8478 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))
8479 (clobber (reg:CC FLAGS_REG))])]
8481 if (GET_CODE (operands[2]) == SYMBOL_REF
8482 || GET_CODE (operands[2]) == LABEL_REF)
8484 operands[2] = shallow_copy_rtx (operands[2]);
8485 PUT_MODE (operands[2], SImode);
8487 else if (GET_CODE (operands[2]) == CONST)
8489 /* (const:DI (plus:DI (symbol_ref:DI ("...")) (const_int N))) */
8490 operands[2] = copy_rtx (operands[2]);
8491 PUT_MODE (operands[2], SImode);
8492 PUT_MODE (XEXP (operands[2], 0), SImode);
8493 PUT_MODE (XEXP (XEXP (operands[2], 0), 0), SImode);
8496 operands[2] = gen_lowpart (SImode, operands[2]);
8499 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8500 (define_insn "*andsi_1_zext"
8501 [(set (match_operand:DI 0 "register_operand" "=r")
8503 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8504 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
8505 (clobber (reg:CC FLAGS_REG))]
8506 "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
8507 "and{l}\t{%2, %k0|%k0, %2}"
8508 [(set_attr "type" "alu")
8509 (set_attr "mode" "SI")])
8511 (define_insn "*and<mode>_1"
8512 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=rm,r,Ya")
8513 (and:SWI24 (match_operand:SWI24 1 "nonimmediate_operand" "%0,0,qm")
8514 (match_operand:SWI24 2 "<general_operand>" "r<i>,rm,L")))
8515 (clobber (reg:CC FLAGS_REG))]
8516 "ix86_binary_operator_ok (AND, <MODE>mode, operands)"
8518 and{<imodesuffix>}\t{%2, %0|%0, %2}
8519 and{<imodesuffix>}\t{%2, %0|%0, %2}
8521 [(set_attr "type" "alu,alu,imovx")
8522 (set_attr "length_immediate" "*,*,0")
8523 (set (attr "prefix_rex")
8525 (and (eq_attr "type" "imovx")
8526 (and (match_test "INTVAL (operands[2]) == 0xff")
8527 (match_operand 1 "ext_QIreg_operand")))
8529 (const_string "*")))
8530 (set_attr "mode" "<MODE>,<MODE>,SI")])
8532 (define_insn "*andqi_1"
8533 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
8534 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8535 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
8536 (clobber (reg:CC FLAGS_REG))]
8537 "ix86_binary_operator_ok (AND, QImode, operands)"
8539 and{b}\t{%2, %0|%0, %2}
8540 and{b}\t{%2, %0|%0, %2}
8541 and{l}\t{%k2, %k0|%k0, %k2}"
8542 [(set_attr "type" "alu")
8543 (set_attr "mode" "QI,QI,SI")
8544 ;; Potential partial reg stall on alternative 2.
8545 (set (attr "preferred_for_speed")
8546 (cond [(eq_attr "alternative" "2")
8547 (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
8548 (symbol_ref "true")))])
8550 (define_insn "*andqi_1_slp"
8551 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
8552 (and:QI (match_dup 0)
8553 (match_operand:QI 1 "general_operand" "qn,qmn")))
8554 (clobber (reg:CC FLAGS_REG))]
8555 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8556 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8557 "and{b}\t{%1, %0|%0, %1}"
8558 [(set_attr "type" "alu1")
8559 (set_attr "mode" "QI")])
8562 [(set (match_operand:SWI248 0 "register_operand")
8563 (and:SWI248 (match_operand:SWI248 1 "nonimmediate_operand")
8564 (match_operand:SWI248 2 "const_int_operand")))
8565 (clobber (reg:CC FLAGS_REG))]
8567 && (!REG_P (operands[1])
8568 || REGNO (operands[0]) != REGNO (operands[1]))"
8571 unsigned HOST_WIDE_INT ival = UINTVAL (operands[2]);
8574 if (ival == GET_MODE_MASK (SImode))
8576 else if (ival == GET_MODE_MASK (HImode))
8578 else if (ival == GET_MODE_MASK (QImode))
8583 /* Zero extend to SImode to avoid partial register stalls. */
8584 if (<MODE_SIZE> < GET_MODE_SIZE (SImode))
8585 operands[0] = gen_lowpart (SImode, operands[0]);
8587 emit_insn (gen_extend_insn
8588 (operands[0], gen_lowpart (mode, operands[1]),
8589 GET_MODE (operands[0]), mode, 1));
8594 [(set (match_operand:SWI48 0 "register_operand")
8595 (and:SWI48 (match_dup 0)
8596 (const_int -65536)))
8597 (clobber (reg:CC FLAGS_REG))]
8598 "(TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)
8599 || optimize_function_for_size_p (cfun)"
8600 [(set (strict_low_part (match_dup 1)) (const_int 0))]
8601 "operands[1] = gen_lowpart (HImode, operands[0]);")
8604 [(set (match_operand:SWI248 0 "any_QIreg_operand")
8605 (and:SWI248 (match_dup 0)
8607 (clobber (reg:CC FLAGS_REG))]
8608 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8609 && reload_completed"
8610 [(set (strict_low_part (match_dup 1)) (const_int 0))]
8611 "operands[1] = gen_lowpart (QImode, operands[0]);")
8614 [(set (match_operand:SWI248 0 "QIreg_operand")
8615 (and:SWI248 (match_dup 0)
8616 (const_int -65281)))
8617 (clobber (reg:CC FLAGS_REG))]
8618 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8619 && reload_completed"
8621 [(set (zero_extract:SI (match_dup 0)
8627 (zero_extract:SI (match_dup 0)
8631 (zero_extract:SI (match_dup 0)
8633 (const_int 8)) 0)) 0))
8634 (clobber (reg:CC FLAGS_REG))])]
8635 "operands[0] = gen_lowpart (SImode, operands[0]);")
8637 (define_insn "*anddi_2"
8638 [(set (reg FLAGS_REG)
8641 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8642 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
8644 (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
8645 (and:DI (match_dup 1) (match_dup 2)))]
8647 && ix86_match_ccmode
8649 /* If we are going to emit andl instead of andq, and the operands[2]
8650 constant might have the SImode sign bit set, make sure the sign
8651 flag isn't tested, because the instruction will set the sign flag
8652 based on bit 31 rather than bit 63. If it isn't CONST_INT,
8653 conservatively assume it might have bit 31 set. */
8654 (satisfies_constraint_Z (operands[2])
8655 && (!CONST_INT_P (operands[2])
8656 || val_signbit_known_set_p (SImode, INTVAL (operands[2]))))
8657 ? CCZmode : CCNOmode)
8658 && ix86_binary_operator_ok (AND, DImode, operands)"
8660 and{l}\t{%k2, %k0|%k0, %k2}
8661 and{q}\t{%2, %0|%0, %2}
8662 and{q}\t{%2, %0|%0, %2}"
8663 [(set_attr "type" "alu")
8664 (set_attr "mode" "SI,DI,DI")])
8666 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8667 (define_insn "*andsi_2_zext"
8668 [(set (reg FLAGS_REG)
8670 (match_operand:SI 1 "nonimmediate_operand" "%0")
8671 (match_operand:SI 2 "x86_64_general_operand" "rme"))
8673 (set (match_operand:DI 0 "register_operand" "=r")
8674 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
8675 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8676 && ix86_binary_operator_ok (AND, SImode, operands)"
8677 "and{l}\t{%2, %k0|%k0, %2}"
8678 [(set_attr "type" "alu")
8679 (set_attr "mode" "SI")])
8681 (define_insn "*andqi_2_maybe_si"
8682 [(set (reg FLAGS_REG)
8684 (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8685 (match_operand:QI 2 "general_operand" "qmn,qn,n"))
8687 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
8688 (and:QI (match_dup 1) (match_dup 2)))]
8689 "ix86_binary_operator_ok (AND, QImode, operands)
8690 && ix86_match_ccmode (insn,
8691 CONST_INT_P (operands[2])
8692 && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
8694 if (which_alternative == 2)
8696 if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
8697 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
8698 return "and{l}\t{%2, %k0|%k0, %2}";
8700 return "and{b}\t{%2, %0|%0, %2}";
8702 [(set_attr "type" "alu")
8703 (set_attr "mode" "QI,QI,SI")])
8705 (define_insn "*and<mode>_2"
8706 [(set (reg FLAGS_REG)
8707 (compare (and:SWI124
8708 (match_operand:SWI124 1 "nonimmediate_operand" "%0,0")
8709 (match_operand:SWI124 2 "<general_operand>" "<g>,<r><i>"))
8711 (set (match_operand:SWI124 0 "nonimmediate_operand" "=<r>,<r>m")
8712 (and:SWI124 (match_dup 1) (match_dup 2)))]
8713 "ix86_match_ccmode (insn, CCNOmode)
8714 && ix86_binary_operator_ok (AND, <MODE>mode, operands)"
8715 "and{<imodesuffix>}\t{%2, %0|%0, %2}"
8716 [(set_attr "type" "alu")
8717 (set_attr "mode" "<MODE>")])
8719 (define_insn "*andqi_2_slp"
8720 [(set (reg FLAGS_REG)
8722 (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8723 (match_operand:QI 1 "nonimmediate_operand" "qmn,qn"))
8725 (set (strict_low_part (match_dup 0))
8726 (and:QI (match_dup 0) (match_dup 1)))]
8727 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8728 && ix86_match_ccmode (insn, CCNOmode)
8729 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8730 "and{b}\t{%1, %0|%0, %1}"
8731 [(set_attr "type" "alu1")
8732 (set_attr "mode" "QI")])
8734 (define_insn "andqi_ext_1"
8735 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q,Q")
8741 (zero_extract:SI (match_operand 1 "ext_register_operand" "0,0")
8744 (match_operand:QI 2 "general_operand" "QnBc,m")) 0))
8745 (clobber (reg:CC FLAGS_REG))]
8746 "/* FIXME: without this LRA can't reload this pattern, see PR82524. */
8747 rtx_equal_p (operands[0], operands[1])"
8748 "and{b}\t{%2, %h0|%h0, %2}"
8749 [(set_attr "isa" "*,nox64")
8750 (set_attr "type" "alu")
8751 (set_attr "mode" "QI")])
8753 ;; Generated by peephole translating test to and. This shows up
8754 ;; often in fp comparisons.
8755 (define_insn "*andqi_ext_1_cc"
8756 [(set (reg FLAGS_REG)
8760 (zero_extract:SI (match_operand 1 "ext_register_operand" "0,0")
8763 (match_operand:QI 2 "general_operand" "QnBc,m"))
8765 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q,Q")
8771 (zero_extract:SI (match_dup 1)
8775 "ix86_match_ccmode (insn, CCNOmode)
8776 /* FIXME: without this LRA can't reload this pattern, see PR82524. */
8777 && rtx_equal_p (operands[0], operands[1])"
8778 "and{b}\t{%2, %h0|%h0, %2}"
8779 [(set_attr "isa" "*,nox64")
8780 (set_attr "type" "alu")
8781 (set_attr "mode" "QI")])
8783 (define_insn "*andqi_ext_2"
8784 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
8790 (zero_extract:SI (match_operand 1 "ext_register_operand" "%0")
8794 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
8796 (const_int 8)) 0)) 0))
8797 (clobber (reg:CC FLAGS_REG))]
8798 "/* FIXME: without this LRA can't reload this pattern, see PR82524. */
8799 rtx_equal_p (operands[0], operands[1])
8800 || rtx_equal_p (operands[0], operands[2])"
8801 "and{b}\t{%h2, %h0|%h0, %h2}"
8802 [(set_attr "type" "alu")
8803 (set_attr "mode" "QI")])
8805 ;; Convert wide AND instructions with immediate operand to shorter QImode
8806 ;; equivalents when possible.
8807 ;; Don't do the splitting with memory operands, since it introduces risk
8808 ;; of memory mismatch stalls. We may want to do the splitting for optimizing
8809 ;; for size, but that can (should?) be handled by generic code instead.
8811 [(set (match_operand:SWI248 0 "QIreg_operand")
8812 (and:SWI248 (match_operand:SWI248 1 "register_operand")
8813 (match_operand:SWI248 2 "const_int_operand")))
8814 (clobber (reg:CC FLAGS_REG))]
8816 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8817 && !(~INTVAL (operands[2]) & ~(255 << 8))"
8819 [(set (zero_extract:SI (match_dup 0)
8825 (zero_extract:SI (match_dup 1)
8829 (clobber (reg:CC FLAGS_REG))])]
8831 operands[0] = gen_lowpart (SImode, operands[0]);
8832 operands[1] = gen_lowpart (SImode, operands[1]);
8833 operands[2] = gen_int_mode (INTVAL (operands[2]) >> 8, QImode);
8836 ;; Since AND can be encoded with sign extended immediate, this is only
8837 ;; profitable when 7th bit is not set.
8839 [(set (match_operand:SWI248 0 "any_QIreg_operand")
8840 (and:SWI248 (match_operand:SWI248 1 "general_operand")
8841 (match_operand:SWI248 2 "const_int_operand")))
8842 (clobber (reg:CC FLAGS_REG))]
8844 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8845 && !(~INTVAL (operands[2]) & ~255)
8846 && !(INTVAL (operands[2]) & 128)"
8847 [(parallel [(set (strict_low_part (match_dup 0))
8848 (and:QI (match_dup 1)
8850 (clobber (reg:CC FLAGS_REG))])]
8852 operands[0] = gen_lowpart (QImode, operands[0]);
8853 operands[1] = gen_lowpart (QImode, operands[1]);
8854 operands[2] = gen_int_mode (INTVAL (operands[2]), QImode);
8857 (define_insn "*andndi3_doubleword"
8858 [(set (match_operand:DI 0 "register_operand")
8860 (not:DI (match_operand:DI 1 "register_operand"))
8861 (match_operand:DI 2 "nonimmediate_operand")))
8862 (clobber (reg:CC FLAGS_REG))]
8863 "!TARGET_64BIT && TARGET_STV && TARGET_SSE2
8864 && can_create_pseudo_p ()"
8868 [(set (match_operand:DI 0 "register_operand")
8870 (not:DI (match_operand:DI 1 "register_operand"))
8871 (match_operand:DI 2 "nonimmediate_operand")))
8872 (clobber (reg:CC FLAGS_REG))]
8873 "!TARGET_64BIT && TARGET_BMI && TARGET_STV && TARGET_SSE2
8874 && can_create_pseudo_p ()"
8875 [(parallel [(set (match_dup 0)
8876 (and:SI (not:SI (match_dup 1)) (match_dup 2)))
8877 (clobber (reg:CC FLAGS_REG))])
8878 (parallel [(set (match_dup 3)
8879 (and:SI (not:SI (match_dup 4)) (match_dup 5)))
8880 (clobber (reg:CC FLAGS_REG))])]
8881 "split_double_mode (DImode, &operands[0], 3, &operands[0], &operands[3]);")
8884 [(set (match_operand:DI 0 "register_operand")
8886 (not:DI (match_operand:DI 1 "register_operand"))
8887 (match_operand:DI 2 "nonimmediate_operand")))
8888 (clobber (reg:CC FLAGS_REG))]
8889 "!TARGET_64BIT && !TARGET_BMI && TARGET_STV && TARGET_SSE2
8890 && can_create_pseudo_p ()"
8891 [(set (match_dup 6) (not:SI (match_dup 1)))
8892 (parallel [(set (match_dup 0)
8893 (and:SI (match_dup 6) (match_dup 2)))
8894 (clobber (reg:CC FLAGS_REG))])
8895 (set (match_dup 7) (not:SI (match_dup 4)))
8896 (parallel [(set (match_dup 3)
8897 (and:SI (match_dup 7) (match_dup 5)))
8898 (clobber (reg:CC FLAGS_REG))])]
8900 operands[6] = gen_reg_rtx (SImode);
8901 operands[7] = gen_reg_rtx (SImode);
8903 split_double_mode (DImode, &operands[0], 3, &operands[0], &operands[3]);
8906 (define_insn "*andn<mode>_1"
8907 [(set (match_operand:SWI48 0 "register_operand" "=r,r")
8909 (not:SWI48 (match_operand:SWI48 1 "register_operand" "r,r"))
8910 (match_operand:SWI48 2 "nonimmediate_operand" "r,m")))
8911 (clobber (reg:CC FLAGS_REG))]
8913 "andn\t{%2, %1, %0|%0, %1, %2}"
8914 [(set_attr "type" "bitmanip")
8915 (set_attr "btver2_decode" "direct, double")
8916 (set_attr "mode" "<MODE>")])
8918 (define_insn "*andn<mode>_1"
8919 [(set (match_operand:SWI12 0 "register_operand" "=r")
8921 (not:SWI12 (match_operand:SWI12 1 "register_operand" "r"))
8922 (match_operand:SWI12 2 "register_operand" "r")))
8923 (clobber (reg:CC FLAGS_REG))]
8925 "andn\t{%k2, %k1, %k0|%k0, %k1, %k2}"
8926 [(set_attr "type" "bitmanip")
8927 (set_attr "btver2_decode" "direct")
8928 (set_attr "mode" "SI")])
8930 (define_insn "*andn_<mode>_ccno"
8931 [(set (reg FLAGS_REG)
8934 (not:SWI48 (match_operand:SWI48 1 "register_operand" "r,r"))
8935 (match_operand:SWI48 2 "nonimmediate_operand" "r,m"))
8937 (clobber (match_scratch:SWI48 0 "=r,r"))]
8938 "TARGET_BMI && ix86_match_ccmode (insn, CCNOmode)"
8939 "andn\t{%2, %1, %0|%0, %1, %2}"
8940 [(set_attr "type" "bitmanip")
8941 (set_attr "btver2_decode" "direct, double")
8942 (set_attr "mode" "<MODE>")])
8944 ;; Logical inclusive and exclusive OR instructions
8946 ;; %%% This used to optimize known byte-wide and operations to memory.
8947 ;; If this is considered useful, it should be done with splitters.
8949 (define_expand "<code><mode>3"
8950 [(set (match_operand:SWIM1248s 0 "nonimmediate_operand")
8951 (any_or:SWIM1248s (match_operand:SWIM1248s 1 "nonimmediate_operand")
8952 (match_operand:SWIM1248s 2 "<general_operand>")))]
8954 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
8956 (define_insn_and_split "*<code>di3_doubleword"
8957 [(set (match_operand:DI 0 "nonimmediate_operand")
8959 (match_operand:DI 1 "nonimmediate_operand")
8960 (match_operand:DI 2 "x86_64_szext_general_operand")))
8961 (clobber (reg:CC FLAGS_REG))]
8962 "!TARGET_64BIT && TARGET_STV && TARGET_SSE2
8963 && ix86_binary_operator_ok (<CODE>, DImode, operands)
8964 && can_create_pseudo_p ()"
8969 split_double_mode (DImode, &operands[0], 3, &operands[0], &operands[3]);
8971 if (operands[2] == const0_rtx)
8972 emit_move_insn (operands[0], operands[1]);
8973 else if (operands[2] == constm1_rtx)
8976 emit_move_insn (operands[0], constm1_rtx);
8978 ix86_expand_unary_operator (NOT, SImode, &operands[0]);
8981 ix86_expand_binary_operator (<CODE>, SImode, &operands[0]);
8983 if (operands[5] == const0_rtx)
8984 emit_move_insn (operands[3], operands[4]);
8985 else if (operands[5] == constm1_rtx)
8988 emit_move_insn (operands[3], constm1_rtx);
8990 ix86_expand_unary_operator (NOT, SImode, &operands[3]);
8993 ix86_expand_binary_operator (<CODE>, SImode, &operands[3]);
8998 (define_insn "*<code><mode>_1"
8999 [(set (match_operand:SWI248 0 "nonimmediate_operand" "=r,rm")
9001 (match_operand:SWI248 1 "nonimmediate_operand" "%0,0")
9002 (match_operand:SWI248 2 "<general_operand>" "<g>,r<i>")))
9003 (clobber (reg:CC FLAGS_REG))]
9004 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9005 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
9006 [(set_attr "type" "alu")
9007 (set_attr "mode" "<MODE>")])
9009 (define_insn_and_split "*iordi_1_bts"
9010 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9012 (match_operand:DI 1 "nonimmediate_operand" "%0")
9013 (match_operand:DI 2 "const_int_operand" "n")))
9014 (clobber (reg:CC FLAGS_REG))]
9015 "TARGET_64BIT && TARGET_USE_BT
9016 && ix86_binary_operator_ok (IOR, DImode, operands)
9017 && IN_RANGE (exact_log2 (INTVAL (operands[2])), 31, 63)"
9019 "&& reload_completed"
9020 [(parallel [(set (zero_extract:DI (match_dup 0)
9024 (clobber (reg:CC FLAGS_REG))])]
9025 "operands[3] = GEN_INT (exact_log2 (INTVAL (operands[2])));"
9026 [(set_attr "type" "alu1")
9027 (set_attr "prefix_0f" "1")
9028 (set_attr "znver1_decode" "double")
9029 (set_attr "mode" "DI")])
9031 (define_insn_and_split "*xordi_1_btc"
9032 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9034 (match_operand:DI 1 "nonimmediate_operand" "%0")
9035 (match_operand:DI 2 "const_int_operand" "n")))
9036 (clobber (reg:CC FLAGS_REG))]
9037 "TARGET_64BIT && TARGET_USE_BT
9038 && ix86_binary_operator_ok (XOR, DImode, operands)
9039 && IN_RANGE (exact_log2 (INTVAL (operands[2])), 31, 63)"
9041 "&& reload_completed"
9042 [(parallel [(set (zero_extract:DI (match_dup 0)
9045 (not:DI (zero_extract:DI (match_dup 0)
9048 (clobber (reg:CC FLAGS_REG))])]
9049 "operands[3] = GEN_INT (exact_log2 (INTVAL (operands[2])));"
9050 [(set_attr "type" "alu1")
9051 (set_attr "prefix_0f" "1")
9052 (set_attr "znver1_decode" "double")
9053 (set_attr "mode" "DI")])
9055 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9056 (define_insn "*<code>si_1_zext"
9057 [(set (match_operand:DI 0 "register_operand" "=r")
9059 (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9060 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
9061 (clobber (reg:CC FLAGS_REG))]
9062 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
9063 "<logic>{l}\t{%2, %k0|%k0, %2}"
9064 [(set_attr "type" "alu")
9065 (set_attr "mode" "SI")])
9067 (define_insn "*<code>si_1_zext_imm"
9068 [(set (match_operand:DI 0 "register_operand" "=r")
9070 (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
9071 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
9072 (clobber (reg:CC FLAGS_REG))]
9073 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
9074 "<logic>{l}\t{%2, %k0|%k0, %2}"
9075 [(set_attr "type" "alu")
9076 (set_attr "mode" "SI")])
9078 (define_insn "*<code>qi_1"
9079 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
9080 (any_or:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9081 (match_operand:QI 2 "general_operand" "qmn,qn,rn")))
9082 (clobber (reg:CC FLAGS_REG))]
9083 "ix86_binary_operator_ok (<CODE>, QImode, operands)"
9085 <logic>{b}\t{%2, %0|%0, %2}
9086 <logic>{b}\t{%2, %0|%0, %2}
9087 <logic>{l}\t{%k2, %k0|%k0, %k2}"
9088 [(set_attr "type" "alu")
9089 (set_attr "mode" "QI,QI,SI")
9090 ;; Potential partial reg stall on alternative 2.
9091 (set (attr "preferred_for_speed")
9092 (cond [(eq_attr "alternative" "2")
9093 (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
9094 (symbol_ref "true")))])
9096 (define_insn "*<code>qi_1_slp"
9097 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
9098 (any_or:QI (match_dup 0)
9099 (match_operand:QI 1 "general_operand" "qmn,qn")))
9100 (clobber (reg:CC FLAGS_REG))]
9101 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9102 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9103 "<logic>{b}\t{%1, %0|%0, %1}"
9104 [(set_attr "type" "alu1")
9105 (set_attr "mode" "QI")])
9107 (define_insn "*<code><mode>_2"
9108 [(set (reg FLAGS_REG)
9109 (compare (any_or:SWI
9110 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
9111 (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>"))
9113 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
9114 (any_or:SWI (match_dup 1) (match_dup 2)))]
9115 "ix86_match_ccmode (insn, CCNOmode)
9116 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9117 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
9118 [(set_attr "type" "alu")
9119 (set_attr "mode" "<MODE>")])
9121 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9122 ;; ??? Special case for immediate operand is missing - it is tricky.
9123 (define_insn "*<code>si_2_zext"
9124 [(set (reg FLAGS_REG)
9125 (compare (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9126 (match_operand:SI 2 "x86_64_general_operand" "rme"))
9128 (set (match_operand:DI 0 "register_operand" "=r")
9129 (zero_extend:DI (any_or:SI (match_dup 1) (match_dup 2))))]
9130 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9131 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
9132 "<logic>{l}\t{%2, %k0|%k0, %2}"
9133 [(set_attr "type" "alu")
9134 (set_attr "mode" "SI")])
9136 (define_insn "*<code>si_2_zext_imm"
9137 [(set (reg FLAGS_REG)
9139 (match_operand:SI 1 "nonimmediate_operand" "%0")
9140 (match_operand:SI 2 "x86_64_zext_immediate_operand" "Z"))
9142 (set (match_operand:DI 0 "register_operand" "=r")
9143 (any_or:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
9144 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9145 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
9146 "<logic>{l}\t{%2, %k0|%k0, %2}"
9147 [(set_attr "type" "alu")
9148 (set_attr "mode" "SI")])
9150 (define_insn "*<code>qi_2_slp"
9151 [(set (reg FLAGS_REG)
9152 (compare (any_or:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9153 (match_operand:QI 1 "general_operand" "qmn,qn"))
9155 (set (strict_low_part (match_dup 0))
9156 (any_or:QI (match_dup 0) (match_dup 1)))]
9157 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9158 && ix86_match_ccmode (insn, CCNOmode)
9159 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9160 "<logic>{b}\t{%1, %0|%0, %1}"
9161 [(set_attr "type" "alu1")
9162 (set_attr "mode" "QI")])
9164 (define_insn "*<code><mode>_3"
9165 [(set (reg FLAGS_REG)
9166 (compare (any_or:SWI
9167 (match_operand:SWI 1 "nonimmediate_operand" "%0")
9168 (match_operand:SWI 2 "<general_operand>" "<g>"))
9170 (clobber (match_scratch:SWI 0 "=<r>"))]
9171 "ix86_match_ccmode (insn, CCNOmode)
9172 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9173 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
9174 [(set_attr "type" "alu")
9175 (set_attr "mode" "<MODE>")])
9177 (define_insn "*<code>qi_ext_1"
9178 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q,Q")
9184 (zero_extract:SI (match_operand 1 "ext_register_operand" "0,0")
9187 (match_operand:QI 2 "general_operand" "QnBc,m")) 0))
9188 (clobber (reg:CC FLAGS_REG))]
9189 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9190 /* FIXME: without this LRA can't reload this pattern, see PR82524. */
9191 && rtx_equal_p (operands[0], operands[1])"
9192 "<logic>{b}\t{%2, %h0|%h0, %2}"
9193 [(set_attr "isa" "*,nox64")
9194 (set_attr "type" "alu")
9195 (set_attr "mode" "QI")])
9197 (define_insn "*<code>qi_ext_2"
9198 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
9204 (zero_extract:SI (match_operand 1 "ext_register_operand" "%0")
9208 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9210 (const_int 8)) 0)) 0))
9211 (clobber (reg:CC FLAGS_REG))]
9212 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9213 /* FIXME: without this LRA can't reload this pattern, see PR82524. */
9214 && (rtx_equal_p (operands[0], operands[1])
9215 || rtx_equal_p (operands[0], operands[2]))"
9216 "<logic>{b}\t{%h2, %h0|%h0, %h2}"
9217 [(set_attr "type" "alu")
9218 (set_attr "mode" "QI")])
9220 ;; Convert wide OR instructions with immediate operand to shorter QImode
9221 ;; equivalents when possible.
9222 ;; Don't do the splitting with memory operands, since it introduces risk
9223 ;; of memory mismatch stalls. We may want to do the splitting for optimizing
9224 ;; for size, but that can (should?) be handled by generic code instead.
9226 [(set (match_operand:SWI248 0 "QIreg_operand")
9227 (any_or:SWI248 (match_operand:SWI248 1 "register_operand")
9228 (match_operand:SWI248 2 "const_int_operand")))
9229 (clobber (reg:CC FLAGS_REG))]
9231 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9232 && !(INTVAL (operands[2]) & ~(255 << 8))"
9234 [(set (zero_extract:SI (match_dup 0)
9240 (zero_extract:SI (match_dup 1)
9244 (clobber (reg:CC FLAGS_REG))])]
9246 operands[0] = gen_lowpart (SImode, operands[0]);
9247 operands[1] = gen_lowpart (SImode, operands[1]);
9248 operands[2] = gen_int_mode (INTVAL (operands[2]) >> 8, QImode);
9251 ;; Since OR can be encoded with sign extended immediate, this is only
9252 ;; profitable when 7th bit is set.
9254 [(set (match_operand:SWI248 0 "any_QIreg_operand")
9255 (any_or:SWI248 (match_operand:SWI248 1 "general_operand")
9256 (match_operand:SWI248 2 "const_int_operand")))
9257 (clobber (reg:CC FLAGS_REG))]
9259 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9260 && !(INTVAL (operands[2]) & ~255)
9261 && (INTVAL (operands[2]) & 128)"
9262 [(parallel [(set (strict_low_part (match_dup 0))
9263 (any_or:QI (match_dup 1)
9265 (clobber (reg:CC FLAGS_REG))])]
9267 operands[0] = gen_lowpart (QImode, operands[0]);
9268 operands[1] = gen_lowpart (QImode, operands[1]);
9269 operands[2] = gen_int_mode (INTVAL (operands[2]), QImode);
9272 (define_expand "xorqi_ext_1_cc"
9274 (set (reg:CCNO FLAGS_REG)
9278 (zero_extract:SI (match_operand 1 "ext_register_operand")
9281 (match_operand 2 "const_int_operand"))
9283 (set (zero_extract:SI (match_operand 0 "ext_register_operand")
9289 (zero_extract:SI (match_dup 1)
9292 (match_dup 2)) 0))])])
9294 (define_insn "*xorqi_ext_1_cc"
9295 [(set (reg FLAGS_REG)
9299 (zero_extract:SI (match_operand 1 "ext_register_operand" "0,0")
9302 (match_operand:QI 2 "general_operand" "QnBc,m"))
9304 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q,Q")
9310 (zero_extract:SI (match_dup 1)
9314 "ix86_match_ccmode (insn, CCNOmode)
9315 /* FIXME: without this LRA can't reload this pattern, see PR82524. */
9316 && rtx_equal_p (operands[0], operands[1])"
9317 "xor{b}\t{%2, %h0|%h0, %2}"
9318 [(set_attr "isa" "*,nox64")
9319 (set_attr "type" "alu")
9320 (set_attr "mode" "QI")])
9322 ;; Negation instructions
9324 (define_expand "neg<mode>2"
9325 [(set (match_operand:SDWIM 0 "nonimmediate_operand")
9326 (neg:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")))]
9328 "ix86_expand_unary_operator (NEG, <MODE>mode, operands); DONE;")
9330 (define_insn_and_split "*neg<dwi>2_doubleword"
9331 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro")
9332 (neg:<DWI> (match_operand:<DWI> 1 "nonimmediate_operand" "0")))
9333 (clobber (reg:CC FLAGS_REG))]
9334 "ix86_unary_operator_ok (NEG, <DWI>mode, operands)"
9338 [(set (reg:CCZ FLAGS_REG)
9339 (compare:CCZ (neg:DWIH (match_dup 1)) (const_int 0)))
9340 (set (match_dup 0) (neg:DWIH (match_dup 1)))])
9343 (plus:DWIH (plus:DWIH (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
9346 (clobber (reg:CC FLAGS_REG))])
9349 (neg:DWIH (match_dup 2)))
9350 (clobber (reg:CC FLAGS_REG))])]
9351 "split_double_mode (<DWI>mode, &operands[0], 2, &operands[0], &operands[2]);")
9353 (define_insn "*neg<mode>2_1"
9354 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9355 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")))
9356 (clobber (reg:CC FLAGS_REG))]
9357 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
9358 "neg{<imodesuffix>}\t%0"
9359 [(set_attr "type" "negnot")
9360 (set_attr "mode" "<MODE>")])
9362 ;; Combine is quite creative about this pattern.
9363 (define_insn "*negsi2_1_zext"
9364 [(set (match_operand:DI 0 "register_operand" "=r")
9366 (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
9369 (clobber (reg:CC FLAGS_REG))]
9370 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9372 [(set_attr "type" "negnot")
9373 (set_attr "mode" "SI")])
9375 ;; The problem with neg is that it does not perform (compare x 0),
9376 ;; it really performs (compare 0 x), which leaves us with the zero
9377 ;; flag being the only useful item.
9379 (define_insn "*neg<mode>2_cmpz"
9380 [(set (reg:CCZ FLAGS_REG)
9382 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
9384 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9385 (neg:SWI (match_dup 1)))]
9386 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
9387 "neg{<imodesuffix>}\t%0"
9388 [(set_attr "type" "negnot")
9389 (set_attr "mode" "<MODE>")])
9391 (define_insn "*negsi2_cmpz_zext"
9392 [(set (reg:CCZ FLAGS_REG)
9396 (match_operand:DI 1 "register_operand" "0")
9400 (set (match_operand:DI 0 "register_operand" "=r")
9401 (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
9404 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9406 [(set_attr "type" "negnot")
9407 (set_attr "mode" "SI")])
9409 ;; Negate with jump on overflow.
9410 (define_expand "negv<mode>3"
9411 [(parallel [(set (reg:CCO FLAGS_REG)
9412 (ne:CCO (match_operand:SWI 1 "register_operand")
9414 (set (match_operand:SWI 0 "register_operand")
9415 (neg:SWI (match_dup 1)))])
9416 (set (pc) (if_then_else
9417 (eq (reg:CCO FLAGS_REG) (const_int 0))
9418 (label_ref (match_operand 2))
9423 = gen_int_mode (HOST_WIDE_INT_1U << (GET_MODE_BITSIZE (<MODE>mode) - 1),
9427 (define_insn "*negv<mode>3"
9428 [(set (reg:CCO FLAGS_REG)
9429 (ne:CCO (match_operand:SWI 1 "nonimmediate_operand" "0")
9430 (match_operand:SWI 2 "const_int_operand")))
9431 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9432 (neg:SWI (match_dup 1)))]
9433 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)
9434 && mode_signbit_p (<MODE>mode, operands[2])"
9435 "neg{<imodesuffix>}\t%0"
9436 [(set_attr "type" "negnot")
9437 (set_attr "mode" "<MODE>")])
9439 (define_expand "<code>tf2"
9440 [(set (match_operand:TF 0 "register_operand")
9441 (absneg:TF (match_operand:TF 1 "register_operand")))]
9443 "ix86_expand_fp_absneg_operator (<CODE>, TFmode, operands); DONE;")
9445 (define_insn "*<code>tf2_1"
9446 [(set (match_operand:TF 0 "register_operand" "=x,x,Yv,Yv")
9448 (match_operand:TF 1 "vector_operand" "0,xBm,Yv,m")))
9449 (use (match_operand:TF 2 "vector_operand" "xBm,0,Yvm,Yv"))
9450 (clobber (reg:CC FLAGS_REG))]
9453 [(set_attr "isa" "noavx,noavx,avx,avx")])
9455 (define_expand "<code><mode>2"
9456 [(set (match_operand:X87MODEF 0 "register_operand")
9457 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand")))]
9458 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
9459 "ix86_expand_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
9461 ;; Changing of sign for FP values is doable using integer unit too.
9462 (define_insn "*<code><mode>2_i387_1"
9463 [(set (match_operand:X87MODEF 0 "register_operand" "=f,!r")
9465 (match_operand:X87MODEF 1 "register_operand" "0,0")))
9466 (clobber (reg:CC FLAGS_REG))]
9471 [(set (match_operand:X87MODEF 0 "fp_register_operand")
9472 (absneg:X87MODEF (match_operand:X87MODEF 1 "fp_register_operand")))
9473 (clobber (reg:CC FLAGS_REG))]
9474 "TARGET_80387 && reload_completed"
9475 [(set (match_dup 0) (absneg:X87MODEF (match_dup 1)))])
9478 [(set (match_operand:X87MODEF 0 "general_reg_operand")
9479 (absneg:X87MODEF (match_operand:X87MODEF 1 "general_reg_operand")))
9480 (clobber (reg:CC FLAGS_REG))]
9481 "TARGET_80387 && reload_completed"
9483 "ix86_split_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
9485 (define_insn "*<code><mode>2_1"
9486 [(set (match_operand:MODEF 0 "register_operand" "=x,x,Yv,f,!r")
9488 (match_operand:MODEF 1 "register_operand" "0,x,Yv,0,0")))
9489 (use (match_operand:<ssevecmode> 2 "vector_operand" "xBm,0,Yvm,X,X"))
9490 (clobber (reg:CC FLAGS_REG))]
9491 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
9493 [(set_attr "isa" "noavx,noavx,avx,*,*")
9494 (set (attr "enabled")
9496 (match_test ("SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"))
9498 (eq_attr "alternative" "3,4")
9499 (symbol_ref "TARGET_MIX_SSE_I387")
9502 (eq_attr "alternative" "3,4")
9504 (symbol_ref "false"))))])
9507 [(set (match_operand:SSEMODEF 0 "sse_reg_operand")
9509 (match_operand:SSEMODEF 1 "vector_operand")))
9510 (use (match_operand:<ssevecmodef> 2 "vector_operand"))
9511 (clobber (reg:CC FLAGS_REG))]
9512 "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
9513 || (TARGET_SSE && (<MODE>mode == TFmode)))
9514 && reload_completed"
9515 [(set (match_dup 0) (match_dup 3))]
9517 machine_mode mode = <MODE>mode;
9518 machine_mode vmode = <ssevecmodef>mode;
9519 enum rtx_code absneg_op = <CODE> == ABS ? AND : XOR;
9521 operands[0] = lowpart_subreg (vmode, operands[0], mode);
9522 operands[1] = lowpart_subreg (vmode, operands[1], mode);
9526 if (MEM_P (operands[1]))
9527 std::swap (operands[1], operands[2]);
9531 if (operands_match_p (operands[0], operands[2]))
9532 std::swap (operands[1], operands[2]);
9536 = gen_rtx_fmt_ee (absneg_op, vmode, operands[1], operands[2]);
9540 [(set (match_operand:MODEF 0 "fp_register_operand")
9541 (absneg:MODEF (match_operand:MODEF 1 "fp_register_operand")))
9542 (use (match_operand 2))
9543 (clobber (reg:CC FLAGS_REG))]
9544 "TARGET_80387 && reload_completed"
9545 [(set (match_dup 0) (absneg:MODEF (match_dup 1)))])
9548 [(set (match_operand:MODEF 0 "general_reg_operand")
9549 (absneg:MODEF (match_operand:MODEF 1 "general_reg_operand")))
9550 (use (match_operand 2))
9551 (clobber (reg:CC FLAGS_REG))]
9552 "TARGET_80387 && reload_completed"
9554 "ix86_split_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
9556 ;; Conditionalize these after reload. If they match before reload, we
9557 ;; lose the clobber and ability to use integer instructions.
9559 (define_insn "*<code><mode>2_i387"
9560 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
9561 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "0")))]
9562 "TARGET_80387 && reload_completed"
9564 [(set_attr "type" "fsgn")
9565 (set_attr "mode" "<MODE>")])
9567 ;; Copysign instructions
9569 (define_expand "copysign<mode>3"
9570 [(match_operand:SSEMODEF 0 "register_operand")
9571 (match_operand:SSEMODEF 1 "nonmemory_operand")
9572 (match_operand:SSEMODEF 2 "register_operand")]
9573 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
9574 || (TARGET_SSE && (<MODE>mode == TFmode))"
9575 "ix86_expand_copysign (operands); DONE;")
9577 (define_insn_and_split "copysign<mode>3_const"
9578 [(set (match_operand:SSEMODEF 0 "register_operand" "=Yv")
9580 [(match_operand:<ssevecmodef> 1 "nonimm_or_0_operand" "YvmC")
9581 (match_operand:SSEMODEF 2 "register_operand" "0")
9582 (match_operand:<ssevecmodef> 3 "nonimmediate_operand" "Yvm")]
9584 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
9585 || (TARGET_SSE && (<MODE>mode == TFmode))"
9587 "&& reload_completed"
9589 "ix86_split_copysign_const (operands); DONE;")
9591 (define_insn "copysign<mode>3_var"
9592 [(set (match_operand:SSEMODEF 0 "register_operand" "=Yv,Yv,Yv,Yv,Yv")
9594 [(match_operand:SSEMODEF 2 "register_operand" "Yv,0,0,Yv,Yv")
9595 (match_operand:SSEMODEF 3 "register_operand" "1,1,Yv,1,Yv")
9596 (match_operand:<ssevecmodef> 4
9597 "nonimmediate_operand" "X,Yvm,Yvm,0,0")
9598 (match_operand:<ssevecmodef> 5
9599 "nonimmediate_operand" "0,Yvm,1,Yvm,1")]
9601 (clobber (match_scratch:<ssevecmodef> 1 "=Yv,Yv,Yv,Yv,Yv"))]
9602 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
9603 || (TARGET_SSE && (<MODE>mode == TFmode))"
9607 [(set (match_operand:SSEMODEF 0 "register_operand")
9609 [(match_operand:SSEMODEF 2 "register_operand")
9610 (match_operand:SSEMODEF 3 "register_operand")
9611 (match_operand:<ssevecmodef> 4)
9612 (match_operand:<ssevecmodef> 5)]
9614 (clobber (match_scratch:<ssevecmodef> 1))]
9615 "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
9616 || (TARGET_SSE && (<MODE>mode == TFmode)))
9617 && reload_completed"
9619 "ix86_split_copysign_var (operands); DONE;")
9621 (define_expand "xorsign<mode>3"
9622 [(match_operand:MODEF 0 "register_operand")
9623 (match_operand:MODEF 1 "register_operand")
9624 (match_operand:MODEF 2 "register_operand")]
9625 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
9626 "ix86_expand_xorsign (operands); DONE;")
9628 (define_insn_and_split "xorsign<mode>3_1"
9629 [(set (match_operand:MODEF 0 "register_operand" "=Yv")
9631 [(match_operand:MODEF 1 "register_operand" "Yv")
9632 (match_operand:MODEF 2 "register_operand" "0")
9633 (match_operand:<ssevecmode> 3 "nonimmediate_operand" "Yvm")]
9635 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
9637 "&& reload_completed"
9639 "ix86_split_xorsign (operands); DONE;")
9641 ;; One complement instructions
9643 (define_expand "one_cmpl<mode>2"
9644 [(set (match_operand:SWIM1248s 0 "nonimmediate_operand")
9645 (not:SWIM1248s (match_operand:SWIM1248s 1 "nonimmediate_operand")))]
9647 "ix86_expand_unary_operator (NOT, <MODE>mode, operands); DONE;")
9649 (define_insn_and_split "*one_cmpldi2_doubleword"
9650 [(set (match_operand:DI 0 "nonimmediate_operand")
9651 (not:DI (match_operand:DI 1 "nonimmediate_operand")))]
9652 "!TARGET_64BIT && TARGET_STV && TARGET_SSE2
9653 && ix86_unary_operator_ok (NOT, DImode, operands)
9654 && can_create_pseudo_p ()"
9658 (not:SI (match_dup 1)))
9660 (not:SI (match_dup 3)))]
9661 "split_double_mode (DImode, &operands[0], 2, &operands[0], &operands[2]);")
9663 (define_insn "*one_cmpl<mode>2_1"
9664 [(set (match_operand:SWI248 0 "nonimmediate_operand" "=rm")
9665 (not:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "0")))]
9666 "ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
9667 "not{<imodesuffix>}\t%0"
9668 [(set_attr "type" "negnot")
9669 (set_attr "mode" "<MODE>")])
9671 ;; ??? Currently never generated - xor is used instead.
9672 (define_insn "*one_cmplsi2_1_zext"
9673 [(set (match_operand:DI 0 "register_operand" "=r")
9675 (not:SI (match_operand:SI 1 "register_operand" "0"))))]
9676 "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
9678 [(set_attr "type" "negnot")
9679 (set_attr "mode" "SI")])
9681 (define_insn "*one_cmplqi2_1"
9682 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
9683 (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
9684 "ix86_unary_operator_ok (NOT, QImode, operands)"
9688 [(set_attr "type" "negnot")
9689 (set_attr "mode" "QI,SI")
9690 ;; Potential partial reg stall on alternative 1.
9691 (set (attr "preferred_for_speed")
9692 (cond [(eq_attr "alternative" "1")
9693 (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
9694 (symbol_ref "true")))])
9696 (define_insn "*one_cmpl<mode>2_2"
9697 [(set (reg FLAGS_REG)
9698 (compare (not:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
9700 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9701 (not:SWI (match_dup 1)))]
9702 "ix86_match_ccmode (insn, CCNOmode)
9703 && ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
9705 [(set_attr "type" "alu1")
9706 (set_attr "mode" "<MODE>")])
9709 [(set (match_operand 0 "flags_reg_operand")
9710 (match_operator 2 "compare_operator"
9711 [(not:SWI (match_operand:SWI 3 "nonimmediate_operand"))
9713 (set (match_operand:SWI 1 "nonimmediate_operand")
9714 (not:SWI (match_dup 3)))]
9715 "ix86_match_ccmode (insn, CCNOmode)"
9716 [(parallel [(set (match_dup 0)
9717 (match_op_dup 2 [(xor:SWI (match_dup 3) (const_int -1))
9720 (xor:SWI (match_dup 3) (const_int -1)))])])
9722 ;; ??? Currently never generated - xor is used instead.
9723 (define_insn "*one_cmplsi2_2_zext"
9724 [(set (reg FLAGS_REG)
9725 (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
9727 (set (match_operand:DI 0 "register_operand" "=r")
9728 (zero_extend:DI (not:SI (match_dup 1))))]
9729 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9730 && ix86_unary_operator_ok (NOT, SImode, operands)"
9732 [(set_attr "type" "alu1")
9733 (set_attr "mode" "SI")])
9736 [(set (match_operand 0 "flags_reg_operand")
9737 (match_operator 2 "compare_operator"
9738 [(not:SI (match_operand:SI 3 "register_operand"))
9740 (set (match_operand:DI 1 "register_operand")
9741 (zero_extend:DI (not:SI (match_dup 3))))]
9742 "ix86_match_ccmode (insn, CCNOmode)"
9743 [(parallel [(set (match_dup 0)
9744 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
9747 (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])])
9749 ;; Shift instructions
9751 ;; DImode shifts are implemented using the i386 "shift double" opcode,
9752 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem". If the shift count
9753 ;; is variable, then the count is in %cl and the "imm" operand is dropped
9754 ;; from the assembler input.
9756 ;; This instruction shifts the target reg/mem as usual, but instead of
9757 ;; shifting in zeros, bits are shifted in from reg operand. If the insn
9758 ;; is a left shift double, bits are taken from the high order bits of
9759 ;; reg, else if the insn is a shift right double, bits are taken from the
9760 ;; low order bits of reg. So if %eax is "1234" and %edx is "5678",
9761 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
9763 ;; Since sh[lr]d does not change the `reg' operand, that is done
9764 ;; separately, making all shifts emit pairs of shift double and normal
9765 ;; shift. Since sh[lr]d does not shift more than 31 bits, and we wish to
9766 ;; support a 63 bit shift, each shift where the count is in a reg expands
9767 ;; to a pair of shifts, a branch, a shift by 32 and a label.
9769 ;; If the shift count is a constant, we need never emit more than one
9770 ;; shift pair, instead using moves and sign extension for counts greater
9773 (define_expand "ashl<mode>3"
9774 [(set (match_operand:SDWIM 0 "<shift_operand>")
9775 (ashift:SDWIM (match_operand:SDWIM 1 "<ashl_input_operand>")
9776 (match_operand:QI 2 "nonmemory_operand")))]
9778 "ix86_expand_binary_operator (ASHIFT, <MODE>mode, operands); DONE;")
9780 (define_insn_and_split "*ashl<dwi>3_doubleword_mask"
9781 [(set (match_operand:<DWI> 0 "register_operand")
9783 (match_operand:<DWI> 1 "register_operand")
9786 (match_operand:SI 2 "register_operand" "c")
9787 (match_operand:SI 3 "const_int_operand")) 0)))
9788 (clobber (reg:CC FLAGS_REG))]
9789 "(INTVAL (operands[3]) & (<MODE_SIZE> * BITS_PER_UNIT)) == 0
9790 && can_create_pseudo_p ()"
9795 (ior:DWIH (ashift:DWIH (match_dup 6) (match_dup 2))
9796 (lshiftrt:DWIH (match_dup 5)
9797 (minus:QI (match_dup 8) (match_dup 2)))))
9798 (clobber (reg:CC FLAGS_REG))])
9801 (ashift:DWIH (match_dup 5) (match_dup 2)))
9802 (clobber (reg:CC FLAGS_REG))])]
9804 split_double_mode (<DWI>mode, &operands[0], 2, &operands[4], &operands[6]);
9806 operands[8] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT);
9808 if ((INTVAL (operands[3]) & ((<MODE_SIZE> * BITS_PER_UNIT) - 1))
9809 != ((<MODE_SIZE> * BITS_PER_UNIT) - 1))
9811 rtx tem = gen_reg_rtx (SImode);
9812 emit_insn (gen_andsi3 (tem, operands[2], operands[3]));
9816 operands[2] = gen_lowpart (QImode, operands[2]);
9818 if (!rtx_equal_p (operands[6], operands[7]))
9819 emit_move_insn (operands[6], operands[7]);
9822 (define_insn_and_split "*ashl<dwi>3_doubleword_mask_1"
9823 [(set (match_operand:<DWI> 0 "register_operand")
9825 (match_operand:<DWI> 1 "register_operand")
9827 (match_operand:QI 2 "register_operand" "c")
9828 (match_operand:QI 3 "const_int_operand"))))
9829 (clobber (reg:CC FLAGS_REG))]
9830 "(INTVAL (operands[3]) & (<MODE_SIZE> * BITS_PER_UNIT)) == 0
9831 && can_create_pseudo_p ()"
9836 (ior:DWIH (ashift:DWIH (match_dup 6) (match_dup 2))
9837 (lshiftrt:DWIH (match_dup 5)
9838 (minus:QI (match_dup 8) (match_dup 2)))))
9839 (clobber (reg:CC FLAGS_REG))])
9842 (ashift:DWIH (match_dup 5) (match_dup 2)))
9843 (clobber (reg:CC FLAGS_REG))])]
9845 split_double_mode (<DWI>mode, &operands[0], 2, &operands[4], &operands[6]);
9847 operands[8] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT);
9849 if ((INTVAL (operands[3]) & ((<MODE_SIZE> * BITS_PER_UNIT) - 1))
9850 != ((<MODE_SIZE> * BITS_PER_UNIT) - 1))
9852 rtx tem = gen_reg_rtx (QImode);
9853 emit_insn (gen_andqi3 (tem, operands[2], operands[3]));
9857 if (!rtx_equal_p (operands[6], operands[7]))
9858 emit_move_insn (operands[6], operands[7]);
9861 (define_insn "*ashl<mode>3_doubleword"
9862 [(set (match_operand:DWI 0 "register_operand" "=&r")
9863 (ashift:DWI (match_operand:DWI 1 "reg_or_pm1_operand" "0n")
9864 (match_operand:QI 2 "nonmemory_operand" "<S>c")))
9865 (clobber (reg:CC FLAGS_REG))]
9868 [(set_attr "type" "multi")])
9871 [(set (match_operand:DWI 0 "register_operand")
9872 (ashift:DWI (match_operand:DWI 1 "nonmemory_operand")
9873 (match_operand:QI 2 "nonmemory_operand")))
9874 (clobber (reg:CC FLAGS_REG))]
9875 "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
9877 "ix86_split_ashl (operands, NULL_RTX, <MODE>mode); DONE;")
9879 ;; By default we don't ask for a scratch register, because when DWImode
9880 ;; values are manipulated, registers are already at a premium. But if
9881 ;; we have one handy, we won't turn it away.
9884 [(match_scratch:DWIH 3 "r")
9885 (parallel [(set (match_operand:<DWI> 0 "register_operand")
9887 (match_operand:<DWI> 1 "nonmemory_operand")
9888 (match_operand:QI 2 "nonmemory_operand")))
9889 (clobber (reg:CC FLAGS_REG))])
9893 "ix86_split_ashl (operands, operands[3], <DWI>mode); DONE;")
9895 (define_insn "x86_64_shld"
9896 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
9897 (ior:DI (ashift:DI (match_dup 0)
9898 (match_operand:QI 2 "nonmemory_operand" "Jc"))
9899 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
9900 (minus:QI (const_int 64) (match_dup 2)))))
9901 (clobber (reg:CC FLAGS_REG))]
9903 "shld{q}\t{%s2%1, %0|%0, %1, %2}"
9904 [(set_attr "type" "ishift")
9905 (set_attr "prefix_0f" "1")
9906 (set_attr "mode" "DI")
9907 (set_attr "athlon_decode" "vector")
9908 (set_attr "amdfam10_decode" "vector")
9909 (set_attr "bdver1_decode" "vector")])
9911 (define_insn "x86_shld"
9912 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
9913 (ior:SI (ashift:SI (match_dup 0)
9914 (match_operand:QI 2 "nonmemory_operand" "Ic"))
9915 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
9916 (minus:QI (const_int 32) (match_dup 2)))))
9917 (clobber (reg:CC FLAGS_REG))]
9919 "shld{l}\t{%s2%1, %0|%0, %1, %2}"
9920 [(set_attr "type" "ishift")
9921 (set_attr "prefix_0f" "1")
9922 (set_attr "mode" "SI")
9923 (set_attr "pent_pair" "np")
9924 (set_attr "athlon_decode" "vector")
9925 (set_attr "amdfam10_decode" "vector")
9926 (set_attr "bdver1_decode" "vector")])
9928 (define_expand "x86_shift<mode>_adj_1"
9929 [(set (reg:CCZ FLAGS_REG)
9930 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand")
9933 (set (match_operand:SWI48 0 "register_operand")
9934 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
9935 (match_operand:SWI48 1 "register_operand")
9938 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
9939 (match_operand:SWI48 3 "register_operand")
9942 "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
9944 (define_expand "x86_shift<mode>_adj_2"
9945 [(use (match_operand:SWI48 0 "register_operand"))
9946 (use (match_operand:SWI48 1 "register_operand"))
9947 (use (match_operand:QI 2 "register_operand"))]
9950 rtx_code_label *label = gen_label_rtx ();
9953 emit_insn (gen_testqi_ccz_1 (operands[2],
9954 GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
9956 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
9957 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
9958 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
9959 gen_rtx_LABEL_REF (VOIDmode, label),
9961 tmp = emit_jump_insn (gen_rtx_SET (pc_rtx, tmp));
9962 JUMP_LABEL (tmp) = label;
9964 emit_move_insn (operands[0], operands[1]);
9965 ix86_expand_clear (operands[1]);
9968 LABEL_NUSES (label) = 1;
9973 ;; Avoid useless masking of count operand.
9974 (define_insn_and_split "*ashl<mode>3_mask"
9975 [(set (match_operand:SWI48 0 "nonimmediate_operand")
9977 (match_operand:SWI48 1 "nonimmediate_operand")
9980 (match_operand:SI 2 "register_operand" "c,r")
9981 (match_operand:SI 3 "const_int_operand")) 0)))
9982 (clobber (reg:CC FLAGS_REG))]
9983 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)
9984 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
9985 == GET_MODE_BITSIZE (<MODE>mode)-1
9986 && can_create_pseudo_p ()"
9991 (ashift:SWI48 (match_dup 1)
9993 (clobber (reg:CC FLAGS_REG))])]
9994 "operands[2] = gen_lowpart (QImode, operands[2]);"
9995 [(set_attr "isa" "*,bmi2")])
9997 (define_insn_and_split "*ashl<mode>3_mask_1"
9998 [(set (match_operand:SWI48 0 "nonimmediate_operand")
10000 (match_operand:SWI48 1 "nonimmediate_operand")
10002 (match_operand:QI 2 "register_operand" "c,r")
10003 (match_operand:QI 3 "const_int_operand"))))
10004 (clobber (reg:CC FLAGS_REG))]
10005 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)
10006 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10007 == GET_MODE_BITSIZE (<MODE>mode)-1
10008 && can_create_pseudo_p ()"
10012 [(set (match_dup 0)
10013 (ashift:SWI48 (match_dup 1)
10015 (clobber (reg:CC FLAGS_REG))])]
10017 [(set_attr "isa" "*,bmi2")])
10019 (define_insn "*bmi2_ashl<mode>3_1"
10020 [(set (match_operand:SWI48 0 "register_operand" "=r")
10021 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
10022 (match_operand:SWI48 2 "register_operand" "r")))]
10024 "shlx\t{%2, %1, %0|%0, %1, %2}"
10025 [(set_attr "type" "ishiftx")
10026 (set_attr "mode" "<MODE>")])
10028 (define_insn "*ashl<mode>3_1"
10029 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r,r")
10030 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,l,rm")
10031 (match_operand:QI 2 "nonmemory_operand" "c<S>,M,r")))
10032 (clobber (reg:CC FLAGS_REG))]
10033 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
10035 switch (get_attr_type (insn))
10042 gcc_assert (operands[2] == const1_rtx);
10043 gcc_assert (rtx_equal_p (operands[0], operands[1]));
10044 return "add{<imodesuffix>}\t%0, %0";
10047 if (operands[2] == const1_rtx
10048 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10049 return "sal{<imodesuffix>}\t%0";
10051 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
10054 [(set_attr "isa" "*,*,bmi2")
10056 (cond [(eq_attr "alternative" "1")
10057 (const_string "lea")
10058 (eq_attr "alternative" "2")
10059 (const_string "ishiftx")
10060 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
10061 (match_operand 0 "register_operand"))
10062 (match_operand 2 "const1_operand"))
10063 (const_string "alu")
10065 (const_string "ishift")))
10066 (set (attr "length_immediate")
10068 (ior (eq_attr "type" "alu")
10069 (and (eq_attr "type" "ishift")
10070 (and (match_operand 2 "const1_operand")
10071 (ior (match_test "TARGET_SHIFT1")
10072 (match_test "optimize_function_for_size_p (cfun)")))))
10074 (const_string "*")))
10075 (set_attr "mode" "<MODE>")])
10077 ;; Convert shift to the shiftx pattern to avoid flags dependency.
10079 [(set (match_operand:SWI48 0 "register_operand")
10080 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
10081 (match_operand:QI 2 "register_operand")))
10082 (clobber (reg:CC FLAGS_REG))]
10083 "TARGET_BMI2 && reload_completed"
10084 [(set (match_dup 0)
10085 (ashift:SWI48 (match_dup 1) (match_dup 2)))]
10086 "operands[2] = gen_lowpart (<MODE>mode, operands[2]);")
10088 (define_insn "*bmi2_ashlsi3_1_zext"
10089 [(set (match_operand:DI 0 "register_operand" "=r")
10091 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
10092 (match_operand:SI 2 "register_operand" "r"))))]
10093 "TARGET_64BIT && TARGET_BMI2"
10094 "shlx\t{%2, %1, %k0|%k0, %1, %2}"
10095 [(set_attr "type" "ishiftx")
10096 (set_attr "mode" "SI")])
10098 (define_insn "*ashlsi3_1_zext"
10099 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
10101 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l,rm")
10102 (match_operand:QI 2 "nonmemory_operand" "cI,M,r"))))
10103 (clobber (reg:CC FLAGS_REG))]
10104 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10106 switch (get_attr_type (insn))
10113 gcc_assert (operands[2] == const1_rtx);
10114 return "add{l}\t%k0, %k0";
10117 if (operands[2] == const1_rtx
10118 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10119 return "sal{l}\t%k0";
10121 return "sal{l}\t{%2, %k0|%k0, %2}";
10124 [(set_attr "isa" "*,*,bmi2")
10126 (cond [(eq_attr "alternative" "1")
10127 (const_string "lea")
10128 (eq_attr "alternative" "2")
10129 (const_string "ishiftx")
10130 (and (match_test "TARGET_DOUBLE_WITH_ADD")
10131 (match_operand 2 "const1_operand"))
10132 (const_string "alu")
10134 (const_string "ishift")))
10135 (set (attr "length_immediate")
10137 (ior (eq_attr "type" "alu")
10138 (and (eq_attr "type" "ishift")
10139 (and (match_operand 2 "const1_operand")
10140 (ior (match_test "TARGET_SHIFT1")
10141 (match_test "optimize_function_for_size_p (cfun)")))))
10143 (const_string "*")))
10144 (set_attr "mode" "SI")])
10146 ;; Convert shift to the shiftx pattern to avoid flags dependency.
10148 [(set (match_operand:DI 0 "register_operand")
10150 (ashift:SI (match_operand:SI 1 "nonimmediate_operand")
10151 (match_operand:QI 2 "register_operand"))))
10152 (clobber (reg:CC FLAGS_REG))]
10153 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
10154 [(set (match_dup 0)
10155 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
10156 "operands[2] = gen_lowpart (SImode, operands[2]);")
10158 (define_insn "*ashlhi3_1"
10159 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,Yp")
10160 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
10161 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10162 (clobber (reg:CC FLAGS_REG))]
10163 "ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10165 switch (get_attr_type (insn))
10171 gcc_assert (operands[2] == const1_rtx);
10172 return "add{w}\t%0, %0";
10175 if (operands[2] == const1_rtx
10176 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10177 return "sal{w}\t%0";
10179 return "sal{w}\t{%2, %0|%0, %2}";
10182 [(set (attr "type")
10183 (cond [(eq_attr "alternative" "1")
10184 (const_string "lea")
10185 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
10186 (match_operand 0 "register_operand"))
10187 (match_operand 2 "const1_operand"))
10188 (const_string "alu")
10190 (const_string "ishift")))
10191 (set (attr "length_immediate")
10193 (ior (eq_attr "type" "alu")
10194 (and (eq_attr "type" "ishift")
10195 (and (match_operand 2 "const1_operand")
10196 (ior (match_test "TARGET_SHIFT1")
10197 (match_test "optimize_function_for_size_p (cfun)")))))
10199 (const_string "*")))
10200 (set_attr "mode" "HI,SI")])
10202 (define_insn "*ashlqi3_1"
10203 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,Yp")
10204 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
10205 (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
10206 (clobber (reg:CC FLAGS_REG))]
10207 "ix86_binary_operator_ok (ASHIFT, QImode, operands)"
10209 switch (get_attr_type (insn))
10215 gcc_assert (operands[2] == const1_rtx);
10216 if (REG_P (operands[1]) && !ANY_QI_REGNO_P (REGNO (operands[1])))
10217 return "add{l}\t%k0, %k0";
10219 return "add{b}\t%0, %0";
10222 if (operands[2] == const1_rtx
10223 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10225 if (get_attr_mode (insn) == MODE_SI)
10226 return "sal{l}\t%k0";
10228 return "sal{b}\t%0";
10232 if (get_attr_mode (insn) == MODE_SI)
10233 return "sal{l}\t{%2, %k0|%k0, %2}";
10235 return "sal{b}\t{%2, %0|%0, %2}";
10239 [(set (attr "type")
10240 (cond [(eq_attr "alternative" "2")
10241 (const_string "lea")
10242 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
10243 (match_operand 0 "register_operand"))
10244 (match_operand 2 "const1_operand"))
10245 (const_string "alu")
10247 (const_string "ishift")))
10248 (set (attr "length_immediate")
10250 (ior (eq_attr "type" "alu")
10251 (and (eq_attr "type" "ishift")
10252 (and (match_operand 2 "const1_operand")
10253 (ior (match_test "TARGET_SHIFT1")
10254 (match_test "optimize_function_for_size_p (cfun)")))))
10256 (const_string "*")))
10257 (set_attr "mode" "QI,SI,SI")
10258 ;; Potential partial reg stall on alternative 1.
10259 (set (attr "preferred_for_speed")
10260 (cond [(eq_attr "alternative" "1")
10261 (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
10262 (symbol_ref "true")))])
10264 (define_insn "*ashlqi3_1_slp"
10265 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10266 (ashift:QI (match_dup 0)
10267 (match_operand:QI 1 "nonmemory_operand" "cI")))
10268 (clobber (reg:CC FLAGS_REG))]
10269 "(optimize_function_for_size_p (cfun)
10270 || !TARGET_PARTIAL_FLAG_REG_STALL
10271 || (operands[1] == const1_rtx
10273 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
10275 switch (get_attr_type (insn))
10278 gcc_assert (operands[1] == const1_rtx);
10279 return "add{b}\t%0, %0";
10282 if (operands[1] == const1_rtx
10283 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10284 return "sal{b}\t%0";
10286 return "sal{b}\t{%1, %0|%0, %1}";
10289 [(set (attr "type")
10290 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
10291 (match_operand 0 "register_operand"))
10292 (match_operand 1 "const1_operand"))
10293 (const_string "alu1")
10295 (const_string "ishift1")))
10296 (set (attr "length_immediate")
10298 (ior (eq_attr "type" "alu1")
10299 (and (eq_attr "type" "ishift1")
10300 (and (match_operand 1 "const1_operand")
10301 (ior (match_test "TARGET_SHIFT1")
10302 (match_test "optimize_function_for_size_p (cfun)")))))
10304 (const_string "*")))
10305 (set_attr "mode" "QI")])
10307 ;; Convert ashift to the lea pattern to avoid flags dependency.
10309 [(set (match_operand:SWI 0 "register_operand")
10310 (ashift:SWI (match_operand:SWI 1 "index_register_operand")
10311 (match_operand 2 "const_0_to_3_operand")))
10312 (clobber (reg:CC FLAGS_REG))]
10314 && REGNO (operands[0]) != REGNO (operands[1])"
10315 [(set (match_dup 0)
10316 (mult:<LEAMODE> (match_dup 1) (match_dup 2)))]
10318 if (<MODE>mode != <LEAMODE>mode)
10320 operands[0] = gen_lowpart (<LEAMODE>mode, operands[0]);
10321 operands[1] = gen_lowpart (<LEAMODE>mode, operands[1]);
10323 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
10326 ;; Convert ashift to the lea pattern to avoid flags dependency.
10328 [(set (match_operand:DI 0 "register_operand")
10330 (ashift:SI (match_operand:SI 1 "index_register_operand")
10331 (match_operand 2 "const_0_to_3_operand"))))
10332 (clobber (reg:CC FLAGS_REG))]
10333 "TARGET_64BIT && reload_completed
10334 && REGNO (operands[0]) != REGNO (operands[1])"
10335 [(set (match_dup 0)
10336 (zero_extend:DI (mult:SI (match_dup 1) (match_dup 2))))]
10338 operands[1] = gen_lowpart (SImode, operands[1]);
10339 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
10342 ;; This pattern can't accept a variable shift count, since shifts by
10343 ;; zero don't affect the flags. We assume that shifts by constant
10344 ;; zero are optimized away.
10345 (define_insn "*ashl<mode>3_cmp"
10346 [(set (reg FLAGS_REG)
10348 (ashift:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
10349 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
10351 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
10352 (ashift:SWI (match_dup 1) (match_dup 2)))]
10353 "(optimize_function_for_size_p (cfun)
10354 || !TARGET_PARTIAL_FLAG_REG_STALL
10355 || (operands[2] == const1_rtx
10357 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
10358 && ix86_match_ccmode (insn, CCGOCmode)
10359 && ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
10361 switch (get_attr_type (insn))
10364 gcc_assert (operands[2] == const1_rtx);
10365 return "add{<imodesuffix>}\t%0, %0";
10368 if (operands[2] == const1_rtx
10369 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10370 return "sal{<imodesuffix>}\t%0";
10372 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
10375 [(set (attr "type")
10376 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
10377 (match_operand 0 "register_operand"))
10378 (match_operand 2 "const1_operand"))
10379 (const_string "alu")
10381 (const_string "ishift")))
10382 (set (attr "length_immediate")
10384 (ior (eq_attr "type" "alu")
10385 (and (eq_attr "type" "ishift")
10386 (and (match_operand 2 "const1_operand")
10387 (ior (match_test "TARGET_SHIFT1")
10388 (match_test "optimize_function_for_size_p (cfun)")))))
10390 (const_string "*")))
10391 (set_attr "mode" "<MODE>")])
10393 (define_insn "*ashlsi3_cmp_zext"
10394 [(set (reg FLAGS_REG)
10396 (ashift:SI (match_operand:SI 1 "register_operand" "0")
10397 (match_operand:QI 2 "const_1_to_31_operand" "I"))
10399 (set (match_operand:DI 0 "register_operand" "=r")
10400 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
10402 && (optimize_function_for_size_p (cfun)
10403 || !TARGET_PARTIAL_FLAG_REG_STALL
10404 || (operands[2] == const1_rtx
10406 || TARGET_DOUBLE_WITH_ADD)))
10407 && ix86_match_ccmode (insn, CCGOCmode)
10408 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10410 switch (get_attr_type (insn))
10413 gcc_assert (operands[2] == const1_rtx);
10414 return "add{l}\t%k0, %k0";
10417 if (operands[2] == const1_rtx
10418 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10419 return "sal{l}\t%k0";
10421 return "sal{l}\t{%2, %k0|%k0, %2}";
10424 [(set (attr "type")
10425 (cond [(and (match_test "TARGET_DOUBLE_WITH_ADD")
10426 (match_operand 2 "const1_operand"))
10427 (const_string "alu")
10429 (const_string "ishift")))
10430 (set (attr "length_immediate")
10432 (ior (eq_attr "type" "alu")
10433 (and (eq_attr "type" "ishift")
10434 (and (match_operand 2 "const1_operand")
10435 (ior (match_test "TARGET_SHIFT1")
10436 (match_test "optimize_function_for_size_p (cfun)")))))
10438 (const_string "*")))
10439 (set_attr "mode" "SI")])
10441 (define_insn "*ashl<mode>3_cconly"
10442 [(set (reg FLAGS_REG)
10444 (ashift:SWI (match_operand:SWI 1 "register_operand" "0")
10445 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
10447 (clobber (match_scratch:SWI 0 "=<r>"))]
10448 "(optimize_function_for_size_p (cfun)
10449 || !TARGET_PARTIAL_FLAG_REG_STALL
10450 || (operands[2] == const1_rtx
10452 || TARGET_DOUBLE_WITH_ADD)))
10453 && ix86_match_ccmode (insn, CCGOCmode)"
10455 switch (get_attr_type (insn))
10458 gcc_assert (operands[2] == const1_rtx);
10459 return "add{<imodesuffix>}\t%0, %0";
10462 if (operands[2] == const1_rtx
10463 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10464 return "sal{<imodesuffix>}\t%0";
10466 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
10469 [(set (attr "type")
10470 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
10471 (match_operand 0 "register_operand"))
10472 (match_operand 2 "const1_operand"))
10473 (const_string "alu")
10475 (const_string "ishift")))
10476 (set (attr "length_immediate")
10478 (ior (eq_attr "type" "alu")
10479 (and (eq_attr "type" "ishift")
10480 (and (match_operand 2 "const1_operand")
10481 (ior (match_test "TARGET_SHIFT1")
10482 (match_test "optimize_function_for_size_p (cfun)")))))
10484 (const_string "*")))
10485 (set_attr "mode" "<MODE>")])
10487 ;; See comment above `ashl<mode>3' about how this works.
10489 (define_expand "<shift_insn><mode>3"
10490 [(set (match_operand:SDWIM 0 "<shift_operand>")
10491 (any_shiftrt:SDWIM (match_operand:SDWIM 1 "<shift_operand>")
10492 (match_operand:QI 2 "nonmemory_operand")))]
10494 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
10496 ;; Avoid useless masking of count operand.
10497 (define_insn_and_split "*<shift_insn><mode>3_mask"
10498 [(set (match_operand:SWI48 0 "nonimmediate_operand")
10500 (match_operand:SWI48 1 "nonimmediate_operand")
10503 (match_operand:SI 2 "register_operand" "c,r")
10504 (match_operand:SI 3 "const_int_operand")) 0)))
10505 (clobber (reg:CC FLAGS_REG))]
10506 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
10507 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10508 == GET_MODE_BITSIZE (<MODE>mode)-1
10509 && can_create_pseudo_p ()"
10513 [(set (match_dup 0)
10514 (any_shiftrt:SWI48 (match_dup 1)
10516 (clobber (reg:CC FLAGS_REG))])]
10517 "operands[2] = gen_lowpart (QImode, operands[2]);"
10518 [(set_attr "isa" "*,bmi2")])
10520 (define_insn_and_split "*<shift_insn><mode>3_mask_1"
10521 [(set (match_operand:SWI48 0 "nonimmediate_operand")
10523 (match_operand:SWI48 1 "nonimmediate_operand")
10525 (match_operand:QI 2 "register_operand" "c,r")
10526 (match_operand:QI 3 "const_int_operand"))))
10527 (clobber (reg:CC FLAGS_REG))]
10528 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
10529 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10530 == GET_MODE_BITSIZE (<MODE>mode)-1
10531 && can_create_pseudo_p ()"
10535 [(set (match_dup 0)
10536 (any_shiftrt:SWI48 (match_dup 1)
10538 (clobber (reg:CC FLAGS_REG))])]
10540 [(set_attr "isa" "*,bmi2")])
10542 (define_insn_and_split "*<shift_insn><dwi>3_doubleword_mask"
10543 [(set (match_operand:<DWI> 0 "register_operand")
10545 (match_operand:<DWI> 1 "register_operand")
10548 (match_operand:SI 2 "register_operand" "c")
10549 (match_operand:SI 3 "const_int_operand")) 0)))
10550 (clobber (reg:CC FLAGS_REG))]
10551 "(INTVAL (operands[3]) & (<MODE_SIZE> * BITS_PER_UNIT)) == 0
10552 && can_create_pseudo_p ()"
10556 [(set (match_dup 4)
10557 (ior:DWIH (lshiftrt:DWIH (match_dup 4) (match_dup 2))
10558 (ashift:DWIH (match_dup 7)
10559 (minus:QI (match_dup 8) (match_dup 2)))))
10560 (clobber (reg:CC FLAGS_REG))])
10562 [(set (match_dup 6)
10563 (any_shiftrt:DWIH (match_dup 7) (match_dup 2)))
10564 (clobber (reg:CC FLAGS_REG))])]
10566 split_double_mode (<DWI>mode, &operands[0], 2, &operands[4], &operands[6]);
10568 operands[8] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT);
10570 if ((INTVAL (operands[3]) & ((<MODE_SIZE> * BITS_PER_UNIT) - 1))
10571 != ((<MODE_SIZE> * BITS_PER_UNIT) - 1))
10573 rtx tem = gen_reg_rtx (SImode);
10574 emit_insn (gen_andsi3 (tem, operands[2], operands[3]));
10578 operands[2] = gen_lowpart (QImode, operands[2]);
10580 if (!rtx_equal_p (operands[4], operands[5]))
10581 emit_move_insn (operands[4], operands[5]);
10584 (define_insn_and_split "*<shift_insn><dwi>3_doubleword_mask_1"
10585 [(set (match_operand:<DWI> 0 "register_operand")
10587 (match_operand:<DWI> 1 "register_operand")
10589 (match_operand:QI 2 "register_operand" "c")
10590 (match_operand:QI 3 "const_int_operand"))))
10591 (clobber (reg:CC FLAGS_REG))]
10592 "(INTVAL (operands[3]) & (<MODE_SIZE> * BITS_PER_UNIT)) == 0
10593 && can_create_pseudo_p ()"
10597 [(set (match_dup 4)
10598 (ior:DWIH (lshiftrt:DWIH (match_dup 4) (match_dup 2))
10599 (ashift:DWIH (match_dup 7)
10600 (minus:QI (match_dup 8) (match_dup 2)))))
10601 (clobber (reg:CC FLAGS_REG))])
10603 [(set (match_dup 6)
10604 (any_shiftrt:DWIH (match_dup 7) (match_dup 2)))
10605 (clobber (reg:CC FLAGS_REG))])]
10607 split_double_mode (<DWI>mode, &operands[0], 2, &operands[4], &operands[6]);
10609 operands[8] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT);
10611 if ((INTVAL (operands[3]) & ((<MODE_SIZE> * BITS_PER_UNIT) - 1))
10612 != ((<MODE_SIZE> * BITS_PER_UNIT) - 1))
10614 rtx tem = gen_reg_rtx (QImode);
10615 emit_insn (gen_andqi3 (tem, operands[2], operands[3]));
10619 if (!rtx_equal_p (operands[4], operands[5]))
10620 emit_move_insn (operands[4], operands[5]);
10623 (define_insn_and_split "*<shift_insn><mode>3_doubleword"
10624 [(set (match_operand:DWI 0 "register_operand" "=&r")
10625 (any_shiftrt:DWI (match_operand:DWI 1 "register_operand" "0")
10626 (match_operand:QI 2 "nonmemory_operand" "<S>c")))
10627 (clobber (reg:CC FLAGS_REG))]
10630 "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
10632 "ix86_split_<shift_insn> (operands, NULL_RTX, <MODE>mode); DONE;"
10633 [(set_attr "type" "multi")])
10635 ;; By default we don't ask for a scratch register, because when DWImode
10636 ;; values are manipulated, registers are already at a premium. But if
10637 ;; we have one handy, we won't turn it away.
10640 [(match_scratch:DWIH 3 "r")
10641 (parallel [(set (match_operand:<DWI> 0 "register_operand")
10643 (match_operand:<DWI> 1 "register_operand")
10644 (match_operand:QI 2 "nonmemory_operand")))
10645 (clobber (reg:CC FLAGS_REG))])
10649 "ix86_split_<shift_insn> (operands, operands[3], <DWI>mode); DONE;")
10651 (define_insn "x86_64_shrd"
10652 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
10653 (ior:DI (lshiftrt:DI (match_dup 0)
10654 (match_operand:QI 2 "nonmemory_operand" "Jc"))
10655 (ashift:DI (match_operand:DI 1 "register_operand" "r")
10656 (minus:QI (const_int 64) (match_dup 2)))))
10657 (clobber (reg:CC FLAGS_REG))]
10659 "shrd{q}\t{%s2%1, %0|%0, %1, %2}"
10660 [(set_attr "type" "ishift")
10661 (set_attr "prefix_0f" "1")
10662 (set_attr "mode" "DI")
10663 (set_attr "athlon_decode" "vector")
10664 (set_attr "amdfam10_decode" "vector")
10665 (set_attr "bdver1_decode" "vector")])
10667 (define_insn "x86_shrd"
10668 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
10669 (ior:SI (lshiftrt:SI (match_dup 0)
10670 (match_operand:QI 2 "nonmemory_operand" "Ic"))
10671 (ashift:SI (match_operand:SI 1 "register_operand" "r")
10672 (minus:QI (const_int 32) (match_dup 2)))))
10673 (clobber (reg:CC FLAGS_REG))]
10675 "shrd{l}\t{%s2%1, %0|%0, %1, %2}"
10676 [(set_attr "type" "ishift")
10677 (set_attr "prefix_0f" "1")
10678 (set_attr "mode" "SI")
10679 (set_attr "pent_pair" "np")
10680 (set_attr "athlon_decode" "vector")
10681 (set_attr "amdfam10_decode" "vector")
10682 (set_attr "bdver1_decode" "vector")])
10684 ;; Base name for insn mnemonic.
10685 (define_mode_attr cvt_mnemonic
10686 [(SI "{cltd|cdq}") (DI "{cqto|cqo}")])
10688 (define_insn "ashr<mode>3_cvt"
10689 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=*d,rm")
10691 (match_operand:SWI48 1 "nonimmediate_operand" "*a,0")
10692 (match_operand:QI 2 "const_int_operand")))
10693 (clobber (reg:CC FLAGS_REG))]
10694 "INTVAL (operands[2]) == GET_MODE_BITSIZE (<MODE>mode)-1
10695 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
10696 && ix86_binary_operator_ok (ASHIFTRT, <MODE>mode, operands)"
10699 sar{<imodesuffix>}\t{%2, %0|%0, %2}"
10700 [(set_attr "type" "imovx,ishift")
10701 (set_attr "prefix_0f" "0,*")
10702 (set_attr "length_immediate" "0,*")
10703 (set_attr "modrm" "0,1")
10704 (set_attr "mode" "<MODE>")])
10706 (define_insn "*ashrsi3_cvt_zext"
10707 [(set (match_operand:DI 0 "register_operand" "=*d,r")
10709 (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
10710 (match_operand:QI 2 "const_int_operand"))))
10711 (clobber (reg:CC FLAGS_REG))]
10712 "TARGET_64BIT && INTVAL (operands[2]) == 31
10713 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
10714 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
10717 sar{l}\t{%2, %k0|%k0, %2}"
10718 [(set_attr "type" "imovx,ishift")
10719 (set_attr "prefix_0f" "0,*")
10720 (set_attr "length_immediate" "0,*")
10721 (set_attr "modrm" "0,1")
10722 (set_attr "mode" "SI")])
10724 (define_expand "x86_shift<mode>_adj_3"
10725 [(use (match_operand:SWI48 0 "register_operand"))
10726 (use (match_operand:SWI48 1 "register_operand"))
10727 (use (match_operand:QI 2 "register_operand"))]
10730 rtx_code_label *label = gen_label_rtx ();
10733 emit_insn (gen_testqi_ccz_1 (operands[2],
10734 GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
10736 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
10737 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
10738 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
10739 gen_rtx_LABEL_REF (VOIDmode, label),
10741 tmp = emit_jump_insn (gen_rtx_SET (pc_rtx, tmp));
10742 JUMP_LABEL (tmp) = label;
10744 emit_move_insn (operands[0], operands[1]);
10745 emit_insn (gen_ashr<mode>3_cvt (operands[1], operands[1],
10746 GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1)));
10747 emit_label (label);
10748 LABEL_NUSES (label) = 1;
10753 (define_insn "*bmi2_<shift_insn><mode>3_1"
10754 [(set (match_operand:SWI48 0 "register_operand" "=r")
10755 (any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
10756 (match_operand:SWI48 2 "register_operand" "r")))]
10758 "<shift>x\t{%2, %1, %0|%0, %1, %2}"
10759 [(set_attr "type" "ishiftx")
10760 (set_attr "mode" "<MODE>")])
10762 (define_insn "*<shift_insn><mode>3_1"
10763 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
10765 (match_operand:SWI48 1 "nonimmediate_operand" "0,rm")
10766 (match_operand:QI 2 "nonmemory_operand" "c<S>,r")))
10767 (clobber (reg:CC FLAGS_REG))]
10768 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10770 switch (get_attr_type (insn))
10776 if (operands[2] == const1_rtx
10777 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10778 return "<shift>{<imodesuffix>}\t%0";
10780 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
10783 [(set_attr "isa" "*,bmi2")
10784 (set_attr "type" "ishift,ishiftx")
10785 (set (attr "length_immediate")
10787 (and (match_operand 2 "const1_operand")
10788 (ior (match_test "TARGET_SHIFT1")
10789 (match_test "optimize_function_for_size_p (cfun)")))
10791 (const_string "*")))
10792 (set_attr "mode" "<MODE>")])
10794 ;; Convert shift to the shiftx pattern to avoid flags dependency.
10796 [(set (match_operand:SWI48 0 "register_operand")
10797 (any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
10798 (match_operand:QI 2 "register_operand")))
10799 (clobber (reg:CC FLAGS_REG))]
10800 "TARGET_BMI2 && reload_completed"
10801 [(set (match_dup 0)
10802 (any_shiftrt:SWI48 (match_dup 1) (match_dup 2)))]
10803 "operands[2] = gen_lowpart (<MODE>mode, operands[2]);")
10805 (define_insn "*bmi2_<shift_insn>si3_1_zext"
10806 [(set (match_operand:DI 0 "register_operand" "=r")
10808 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
10809 (match_operand:SI 2 "register_operand" "r"))))]
10810 "TARGET_64BIT && TARGET_BMI2"
10811 "<shift>x\t{%2, %1, %k0|%k0, %1, %2}"
10812 [(set_attr "type" "ishiftx")
10813 (set_attr "mode" "SI")])
10815 (define_insn "*<shift_insn>si3_1_zext"
10816 [(set (match_operand:DI 0 "register_operand" "=r,r")
10818 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm")
10819 (match_operand:QI 2 "nonmemory_operand" "cI,r"))))
10820 (clobber (reg:CC FLAGS_REG))]
10821 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10823 switch (get_attr_type (insn))
10829 if (operands[2] == const1_rtx
10830 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10831 return "<shift>{l}\t%k0";
10833 return "<shift>{l}\t{%2, %k0|%k0, %2}";
10836 [(set_attr "isa" "*,bmi2")
10837 (set_attr "type" "ishift,ishiftx")
10838 (set (attr "length_immediate")
10840 (and (match_operand 2 "const1_operand")
10841 (ior (match_test "TARGET_SHIFT1")
10842 (match_test "optimize_function_for_size_p (cfun)")))
10844 (const_string "*")))
10845 (set_attr "mode" "SI")])
10847 ;; Convert shift to the shiftx pattern to avoid flags dependency.
10849 [(set (match_operand:DI 0 "register_operand")
10851 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand")
10852 (match_operand:QI 2 "register_operand"))))
10853 (clobber (reg:CC FLAGS_REG))]
10854 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
10855 [(set (match_dup 0)
10856 (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
10857 "operands[2] = gen_lowpart (SImode, operands[2]);")
10859 (define_insn "*<shift_insn><mode>3_1"
10860 [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m")
10862 (match_operand:SWI12 1 "nonimmediate_operand" "0")
10863 (match_operand:QI 2 "nonmemory_operand" "c<S>")))
10864 (clobber (reg:CC FLAGS_REG))]
10865 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10867 if (operands[2] == const1_rtx
10868 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10869 return "<shift>{<imodesuffix>}\t%0";
10871 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
10873 [(set_attr "type" "ishift")
10874 (set (attr "length_immediate")
10876 (and (match_operand 2 "const1_operand")
10877 (ior (match_test "TARGET_SHIFT1")
10878 (match_test "optimize_function_for_size_p (cfun)")))
10880 (const_string "*")))
10881 (set_attr "mode" "<MODE>")])
10883 (define_insn "*<shift_insn>qi3_1_slp"
10884 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10885 (any_shiftrt:QI (match_dup 0)
10886 (match_operand:QI 1 "nonmemory_operand" "cI")))
10887 (clobber (reg:CC FLAGS_REG))]
10888 "(optimize_function_for_size_p (cfun)
10889 || !TARGET_PARTIAL_REG_STALL
10890 || (operands[1] == const1_rtx
10891 && TARGET_SHIFT1))"
10893 if (operands[1] == const1_rtx
10894 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10895 return "<shift>{b}\t%0";
10897 return "<shift>{b}\t{%1, %0|%0, %1}";
10899 [(set_attr "type" "ishift1")
10900 (set (attr "length_immediate")
10902 (and (match_operand 1 "const1_operand")
10903 (ior (match_test "TARGET_SHIFT1")
10904 (match_test "optimize_function_for_size_p (cfun)")))
10906 (const_string "*")))
10907 (set_attr "mode" "QI")])
10909 ;; This pattern can't accept a variable shift count, since shifts by
10910 ;; zero don't affect the flags. We assume that shifts by constant
10911 ;; zero are optimized away.
10912 (define_insn "*<shift_insn><mode>3_cmp"
10913 [(set (reg FLAGS_REG)
10916 (match_operand:SWI 1 "nonimmediate_operand" "0")
10917 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
10919 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
10920 (any_shiftrt:SWI (match_dup 1) (match_dup 2)))]
10921 "(optimize_function_for_size_p (cfun)
10922 || !TARGET_PARTIAL_FLAG_REG_STALL
10923 || (operands[2] == const1_rtx
10925 && ix86_match_ccmode (insn, CCGOCmode)
10926 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10928 if (operands[2] == const1_rtx
10929 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10930 return "<shift>{<imodesuffix>}\t%0";
10932 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
10934 [(set_attr "type" "ishift")
10935 (set (attr "length_immediate")
10937 (and (match_operand 2 "const1_operand")
10938 (ior (match_test "TARGET_SHIFT1")
10939 (match_test "optimize_function_for_size_p (cfun)")))
10941 (const_string "*")))
10942 (set_attr "mode" "<MODE>")])
10944 (define_insn "*<shift_insn>si3_cmp_zext"
10945 [(set (reg FLAGS_REG)
10947 (any_shiftrt:SI (match_operand:SI 1 "register_operand" "0")
10948 (match_operand:QI 2 "const_1_to_31_operand" "I"))
10950 (set (match_operand:DI 0 "register_operand" "=r")
10951 (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
10953 && (optimize_function_for_size_p (cfun)
10954 || !TARGET_PARTIAL_FLAG_REG_STALL
10955 || (operands[2] == const1_rtx
10957 && ix86_match_ccmode (insn, CCGOCmode)
10958 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10960 if (operands[2] == const1_rtx
10961 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10962 return "<shift>{l}\t%k0";
10964 return "<shift>{l}\t{%2, %k0|%k0, %2}";
10966 [(set_attr "type" "ishift")
10967 (set (attr "length_immediate")
10969 (and (match_operand 2 "const1_operand")
10970 (ior (match_test "TARGET_SHIFT1")
10971 (match_test "optimize_function_for_size_p (cfun)")))
10973 (const_string "*")))
10974 (set_attr "mode" "SI")])
10976 (define_insn "*<shift_insn><mode>3_cconly"
10977 [(set (reg FLAGS_REG)
10980 (match_operand:SWI 1 "register_operand" "0")
10981 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
10983 (clobber (match_scratch:SWI 0 "=<r>"))]
10984 "(optimize_function_for_size_p (cfun)
10985 || !TARGET_PARTIAL_FLAG_REG_STALL
10986 || (operands[2] == const1_rtx
10988 && ix86_match_ccmode (insn, CCGOCmode)"
10990 if (operands[2] == const1_rtx
10991 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10992 return "<shift>{<imodesuffix>}\t%0";
10994 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
10996 [(set_attr "type" "ishift")
10997 (set (attr "length_immediate")
10999 (and (match_operand 2 "const1_operand")
11000 (ior (match_test "TARGET_SHIFT1")
11001 (match_test "optimize_function_for_size_p (cfun)")))
11003 (const_string "*")))
11004 (set_attr "mode" "<MODE>")])
11006 ;; Rotate instructions
11008 (define_expand "<rotate_insn>ti3"
11009 [(set (match_operand:TI 0 "register_operand")
11010 (any_rotate:TI (match_operand:TI 1 "register_operand")
11011 (match_operand:QI 2 "nonmemory_operand")))]
11014 if (const_1_to_63_operand (operands[2], VOIDmode))
11015 emit_insn (gen_ix86_<rotate_insn>ti3_doubleword
11016 (operands[0], operands[1], operands[2]));
11023 (define_expand "<rotate_insn>di3"
11024 [(set (match_operand:DI 0 "shiftdi_operand")
11025 (any_rotate:DI (match_operand:DI 1 "shiftdi_operand")
11026 (match_operand:QI 2 "nonmemory_operand")))]
11030 ix86_expand_binary_operator (<CODE>, DImode, operands);
11031 else if (const_1_to_31_operand (operands[2], VOIDmode))
11032 emit_insn (gen_ix86_<rotate_insn>di3_doubleword
11033 (operands[0], operands[1], operands[2]));
11040 (define_expand "<rotate_insn><mode>3"
11041 [(set (match_operand:SWIM124 0 "nonimmediate_operand")
11042 (any_rotate:SWIM124 (match_operand:SWIM124 1 "nonimmediate_operand")
11043 (match_operand:QI 2 "nonmemory_operand")))]
11045 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
11047 ;; Avoid useless masking of count operand.
11048 (define_insn_and_split "*<rotate_insn><mode>3_mask"
11049 [(set (match_operand:SWI48 0 "nonimmediate_operand")
11051 (match_operand:SWI48 1 "nonimmediate_operand")
11054 (match_operand:SI 2 "register_operand" "c")
11055 (match_operand:SI 3 "const_int_operand")) 0)))
11056 (clobber (reg:CC FLAGS_REG))]
11057 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
11058 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
11059 == GET_MODE_BITSIZE (<MODE>mode)-1
11060 && can_create_pseudo_p ()"
11064 [(set (match_dup 0)
11065 (any_rotate:SWI48 (match_dup 1)
11067 (clobber (reg:CC FLAGS_REG))])]
11068 "operands[2] = gen_lowpart (QImode, operands[2]);")
11070 (define_insn_and_split "*<rotate_insn><mode>3_mask_1"
11071 [(set (match_operand:SWI48 0 "nonimmediate_operand")
11073 (match_operand:SWI48 1 "nonimmediate_operand")
11075 (match_operand:QI 2 "register_operand" "c")
11076 (match_operand:QI 3 "const_int_operand"))))
11077 (clobber (reg:CC FLAGS_REG))]
11078 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
11079 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
11080 == GET_MODE_BITSIZE (<MODE>mode)-1
11081 && can_create_pseudo_p ()"
11085 [(set (match_dup 0)
11086 (any_rotate:SWI48 (match_dup 1)
11088 (clobber (reg:CC FLAGS_REG))])])
11090 ;; Implement rotation using two double-precision
11091 ;; shift instructions and a scratch register.
11093 (define_insn_and_split "ix86_rotl<dwi>3_doubleword"
11094 [(set (match_operand:<DWI> 0 "register_operand" "=r")
11095 (rotate:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
11096 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
11097 (clobber (reg:CC FLAGS_REG))
11098 (clobber (match_scratch:DWIH 3 "=&r"))]
11102 [(set (match_dup 3) (match_dup 4))
11104 [(set (match_dup 4)
11105 (ior:DWIH (ashift:DWIH (match_dup 4) (match_dup 2))
11106 (lshiftrt:DWIH (match_dup 5)
11107 (minus:QI (match_dup 6) (match_dup 2)))))
11108 (clobber (reg:CC FLAGS_REG))])
11110 [(set (match_dup 5)
11111 (ior:DWIH (ashift:DWIH (match_dup 5) (match_dup 2))
11112 (lshiftrt:DWIH (match_dup 3)
11113 (minus:QI (match_dup 6) (match_dup 2)))))
11114 (clobber (reg:CC FLAGS_REG))])]
11116 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
11118 split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
11121 (define_insn_and_split "ix86_rotr<dwi>3_doubleword"
11122 [(set (match_operand:<DWI> 0 "register_operand" "=r")
11123 (rotatert:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
11124 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
11125 (clobber (reg:CC FLAGS_REG))
11126 (clobber (match_scratch:DWIH 3 "=&r"))]
11130 [(set (match_dup 3) (match_dup 4))
11132 [(set (match_dup 4)
11133 (ior:DWIH (lshiftrt:DWIH (match_dup 4) (match_dup 2))
11134 (ashift:DWIH (match_dup 5)
11135 (minus:QI (match_dup 6) (match_dup 2)))))
11136 (clobber (reg:CC FLAGS_REG))])
11138 [(set (match_dup 5)
11139 (ior:DWIH (lshiftrt:DWIH (match_dup 5) (match_dup 2))
11140 (ashift:DWIH (match_dup 3)
11141 (minus:QI (match_dup 6) (match_dup 2)))))
11142 (clobber (reg:CC FLAGS_REG))])]
11144 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
11146 split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
11149 (define_mode_attr rorx_immediate_operand
11150 [(SI "const_0_to_31_operand")
11151 (DI "const_0_to_63_operand")])
11153 (define_insn "*bmi2_rorx<mode>3_1"
11154 [(set (match_operand:SWI48 0 "register_operand" "=r")
11156 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11157 (match_operand:QI 2 "<rorx_immediate_operand>" "<S>")))]
11159 "rorx\t{%2, %1, %0|%0, %1, %2}"
11160 [(set_attr "type" "rotatex")
11161 (set_attr "mode" "<MODE>")])
11163 (define_insn "*<rotate_insn><mode>3_1"
11164 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
11166 (match_operand:SWI48 1 "nonimmediate_operand" "0,rm")
11167 (match_operand:QI 2 "nonmemory_operand" "c<S>,<S>")))
11168 (clobber (reg:CC FLAGS_REG))]
11169 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
11171 switch (get_attr_type (insn))
11177 if (operands[2] == const1_rtx
11178 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11179 return "<rotate>{<imodesuffix>}\t%0";
11181 return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
11184 [(set_attr "isa" "*,bmi2")
11185 (set_attr "type" "rotate,rotatex")
11186 (set (attr "length_immediate")
11188 (and (eq_attr "type" "rotate")
11189 (and (match_operand 2 "const1_operand")
11190 (ior (match_test "TARGET_SHIFT1")
11191 (match_test "optimize_function_for_size_p (cfun)"))))
11193 (const_string "*")))
11194 (set_attr "mode" "<MODE>")])
11196 ;; Convert rotate to the rotatex pattern to avoid flags dependency.
11198 [(set (match_operand:SWI48 0 "register_operand")
11199 (rotate:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
11200 (match_operand:QI 2 "const_int_operand")))
11201 (clobber (reg:CC FLAGS_REG))]
11202 "TARGET_BMI2 && reload_completed"
11203 [(set (match_dup 0)
11204 (rotatert:SWI48 (match_dup 1) (match_dup 2)))]
11206 int bitsize = GET_MODE_BITSIZE (<MODE>mode);
11208 operands[2] = GEN_INT ((bitsize - INTVAL (operands[2])) % bitsize);
11212 [(set (match_operand:SWI48 0 "register_operand")
11213 (rotatert:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
11214 (match_operand:QI 2 "const_int_operand")))
11215 (clobber (reg:CC FLAGS_REG))]
11216 "TARGET_BMI2 && reload_completed"
11217 [(set (match_dup 0)
11218 (rotatert:SWI48 (match_dup 1) (match_dup 2)))])
11220 (define_insn "*bmi2_rorxsi3_1_zext"
11221 [(set (match_operand:DI 0 "register_operand" "=r")
11223 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
11224 (match_operand:QI 2 "const_0_to_31_operand" "I"))))]
11225 "TARGET_64BIT && TARGET_BMI2"
11226 "rorx\t{%2, %1, %k0|%k0, %1, %2}"
11227 [(set_attr "type" "rotatex")
11228 (set_attr "mode" "SI")])
11230 (define_insn "*<rotate_insn>si3_1_zext"
11231 [(set (match_operand:DI 0 "register_operand" "=r,r")
11233 (any_rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm")
11234 (match_operand:QI 2 "nonmemory_operand" "cI,I"))))
11235 (clobber (reg:CC FLAGS_REG))]
11236 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
11238 switch (get_attr_type (insn))
11244 if (operands[2] == const1_rtx
11245 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11246 return "<rotate>{l}\t%k0";
11248 return "<rotate>{l}\t{%2, %k0|%k0, %2}";
11251 [(set_attr "isa" "*,bmi2")
11252 (set_attr "type" "rotate,rotatex")
11253 (set (attr "length_immediate")
11255 (and (eq_attr "type" "rotate")
11256 (and (match_operand 2 "const1_operand")
11257 (ior (match_test "TARGET_SHIFT1")
11258 (match_test "optimize_function_for_size_p (cfun)"))))
11260 (const_string "*")))
11261 (set_attr "mode" "SI")])
11263 ;; Convert rotate to the rotatex pattern to avoid flags dependency.
11265 [(set (match_operand:DI 0 "register_operand")
11267 (rotate:SI (match_operand:SI 1 "nonimmediate_operand")
11268 (match_operand:QI 2 "const_int_operand"))))
11269 (clobber (reg:CC FLAGS_REG))]
11270 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
11271 [(set (match_dup 0)
11272 (zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))]
11274 int bitsize = GET_MODE_BITSIZE (SImode);
11276 operands[2] = GEN_INT ((bitsize - INTVAL (operands[2])) % bitsize);
11280 [(set (match_operand:DI 0 "register_operand")
11282 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand")
11283 (match_operand:QI 2 "const_int_operand"))))
11284 (clobber (reg:CC FLAGS_REG))]
11285 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
11286 [(set (match_dup 0)
11287 (zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))])
11289 (define_insn "*<rotate_insn><mode>3_1"
11290 [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m")
11291 (any_rotate:SWI12 (match_operand:SWI12 1 "nonimmediate_operand" "0")
11292 (match_operand:QI 2 "nonmemory_operand" "c<S>")))
11293 (clobber (reg:CC FLAGS_REG))]
11294 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
11296 if (operands[2] == const1_rtx
11297 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11298 return "<rotate>{<imodesuffix>}\t%0";
11300 return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
11302 [(set_attr "type" "rotate")
11303 (set (attr "length_immediate")
11305 (and (match_operand 2 "const1_operand")
11306 (ior (match_test "TARGET_SHIFT1")
11307 (match_test "optimize_function_for_size_p (cfun)")))
11309 (const_string "*")))
11310 (set_attr "mode" "<MODE>")])
11312 (define_insn "*<rotate_insn>qi3_1_slp"
11313 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
11314 (any_rotate:QI (match_dup 0)
11315 (match_operand:QI 1 "nonmemory_operand" "cI")))
11316 (clobber (reg:CC FLAGS_REG))]
11317 "(optimize_function_for_size_p (cfun)
11318 || !TARGET_PARTIAL_REG_STALL
11319 || (operands[1] == const1_rtx
11320 && TARGET_SHIFT1))"
11322 if (operands[1] == const1_rtx
11323 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11324 return "<rotate>{b}\t%0";
11326 return "<rotate>{b}\t{%1, %0|%0, %1}";
11328 [(set_attr "type" "rotate1")
11329 (set (attr "length_immediate")
11331 (and (match_operand 1 "const1_operand")
11332 (ior (match_test "TARGET_SHIFT1")
11333 (match_test "optimize_function_for_size_p (cfun)")))
11335 (const_string "*")))
11336 (set_attr "mode" "QI")])
11339 [(set (match_operand:HI 0 "QIreg_operand")
11340 (any_rotate:HI (match_dup 0) (const_int 8)))
11341 (clobber (reg:CC FLAGS_REG))]
11343 && (TARGET_USE_XCHGB || optimize_function_for_size_p (cfun))"
11344 [(parallel [(set (strict_low_part (match_dup 0))
11345 (bswap:HI (match_dup 0)))
11346 (clobber (reg:CC FLAGS_REG))])])
11348 ;; Bit set / bit test instructions
11350 ;; %%% bts, btr, btc
11352 ;; These instructions are *slow* when applied to memory.
11354 (define_code_attr btsc [(ior "bts") (xor "btc")])
11356 (define_insn "*<btsc><mode>"
11357 [(set (match_operand:SWI48 0 "register_operand" "=r")
11359 (ashift:SWI48 (const_int 1)
11360 (match_operand:QI 2 "register_operand" "r"))
11361 (match_operand:SWI48 1 "register_operand" "0")))
11362 (clobber (reg:CC FLAGS_REG))]
11364 "<btsc>{<imodesuffix>}\t{%<k>2, %0|%0, %<k>2}"
11365 [(set_attr "type" "alu1")
11366 (set_attr "prefix_0f" "1")
11367 (set_attr "znver1_decode" "double")
11368 (set_attr "mode" "<MODE>")])
11370 ;; Avoid useless masking of count operand.
11371 (define_insn_and_split "*<btsc><mode>_mask"
11372 [(set (match_operand:SWI48 0 "register_operand")
11378 (match_operand:SI 1 "register_operand")
11379 (match_operand:SI 2 "const_int_operand")) 0))
11380 (match_operand:SWI48 3 "register_operand")))
11381 (clobber (reg:CC FLAGS_REG))]
11383 && (INTVAL (operands[2]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
11384 == GET_MODE_BITSIZE (<MODE>mode)-1
11385 && can_create_pseudo_p ()"
11389 [(set (match_dup 0)
11391 (ashift:SWI48 (const_int 1)
11394 (clobber (reg:CC FLAGS_REG))])]
11395 "operands[1] = gen_lowpart (QImode, operands[1]);")
11397 (define_insn_and_split "*<btsc><mode>_mask_1"
11398 [(set (match_operand:SWI48 0 "register_operand")
11403 (match_operand:QI 1 "register_operand")
11404 (match_operand:QI 2 "const_int_operand")))
11405 (match_operand:SWI48 3 "register_operand")))
11406 (clobber (reg:CC FLAGS_REG))]
11408 && (INTVAL (operands[2]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
11409 == GET_MODE_BITSIZE (<MODE>mode)-1
11410 && can_create_pseudo_p ()"
11414 [(set (match_dup 0)
11416 (ashift:SWI48 (const_int 1)
11419 (clobber (reg:CC FLAGS_REG))])])
11421 (define_insn "*btr<mode>"
11422 [(set (match_operand:SWI48 0 "register_operand" "=r")
11424 (rotate:SWI48 (const_int -2)
11425 (match_operand:QI 2 "register_operand" "r"))
11426 (match_operand:SWI48 1 "register_operand" "0")))
11427 (clobber (reg:CC FLAGS_REG))]
11429 "btr{<imodesuffix>}\t{%<k>2, %0|%0, %<k>2}"
11430 [(set_attr "type" "alu1")
11431 (set_attr "prefix_0f" "1")
11432 (set_attr "znver1_decode" "double")
11433 (set_attr "mode" "<MODE>")])
11435 ;; Avoid useless masking of count operand.
11436 (define_insn_and_split "*btr<mode>_mask"
11437 [(set (match_operand:SWI48 0 "register_operand")
11443 (match_operand:SI 1 "register_operand")
11444 (match_operand:SI 2 "const_int_operand")) 0))
11445 (match_operand:SWI48 3 "register_operand")))
11446 (clobber (reg:CC FLAGS_REG))]
11448 && (INTVAL (operands[2]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
11449 == GET_MODE_BITSIZE (<MODE>mode)-1
11450 && can_create_pseudo_p ()"
11454 [(set (match_dup 0)
11456 (rotate:SWI48 (const_int -2)
11459 (clobber (reg:CC FLAGS_REG))])]
11460 "operands[1] = gen_lowpart (QImode, operands[1]);")
11462 (define_insn_and_split "*btr<mode>_mask_1"
11463 [(set (match_operand:SWI48 0 "register_operand")
11468 (match_operand:QI 1 "register_operand")
11469 (match_operand:QI 2 "const_int_operand")))
11470 (match_operand:SWI48 3 "register_operand")))
11471 (clobber (reg:CC FLAGS_REG))]
11473 && (INTVAL (operands[2]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
11474 == GET_MODE_BITSIZE (<MODE>mode)-1
11475 && can_create_pseudo_p ()"
11479 [(set (match_dup 0)
11481 (rotate:SWI48 (const_int -2)
11484 (clobber (reg:CC FLAGS_REG))])])
11486 ;; These instructions are never faster than the corresponding
11487 ;; and/ior/xor operations when using immediate operand, so with
11488 ;; 32-bit there's no point. But in 64-bit, we can't hold the
11489 ;; relevant immediates within the instruction itself, so operating
11490 ;; on bits in the high 32-bits of a register becomes easier.
11492 ;; These are slow on Nocona, but fast on Athlon64. We do require the use
11493 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
11494 ;; negdf respectively, so they can never be disabled entirely.
11496 (define_insn "*btsq_imm"
11497 [(set (zero_extract:DI (match_operand:DI 0 "nonimmediate_operand" "+rm")
11499 (match_operand 1 "const_0_to_63_operand" "J"))
11501 (clobber (reg:CC FLAGS_REG))]
11502 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
11503 "bts{q}\t{%1, %0|%0, %1}"
11504 [(set_attr "type" "alu1")
11505 (set_attr "prefix_0f" "1")
11506 (set_attr "znver1_decode" "double")
11507 (set_attr "mode" "DI")])
11509 (define_insn "*btrq_imm"
11510 [(set (zero_extract:DI (match_operand:DI 0 "nonimmediate_operand" "+rm")
11512 (match_operand 1 "const_0_to_63_operand" "J"))
11514 (clobber (reg:CC FLAGS_REG))]
11515 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
11516 "btr{q}\t{%1, %0|%0, %1}"
11517 [(set_attr "type" "alu1")
11518 (set_attr "prefix_0f" "1")
11519 (set_attr "znver1_decode" "double")
11520 (set_attr "mode" "DI")])
11522 (define_insn "*btcq_imm"
11523 [(set (zero_extract:DI (match_operand:DI 0 "nonimmediate_operand" "+rm")
11525 (match_operand 1 "const_0_to_63_operand" "J"))
11526 (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
11527 (clobber (reg:CC FLAGS_REG))]
11528 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
11529 "btc{q}\t{%1, %0|%0, %1}"
11530 [(set_attr "type" "alu1")
11531 (set_attr "prefix_0f" "1")
11532 (set_attr "znver1_decode" "double")
11533 (set_attr "mode" "DI")])
11535 ;; Allow Nocona to avoid these instructions if a register is available.
11538 [(match_scratch:DI 2 "r")
11539 (parallel [(set (zero_extract:DI
11540 (match_operand:DI 0 "nonimmediate_operand")
11542 (match_operand 1 "const_0_to_63_operand"))
11544 (clobber (reg:CC FLAGS_REG))])]
11545 "TARGET_64BIT && !TARGET_USE_BT"
11546 [(parallel [(set (match_dup 0)
11547 (ior:DI (match_dup 0) (match_dup 3)))
11548 (clobber (reg:CC FLAGS_REG))])]
11550 int i = INTVAL (operands[1]);
11552 operands[3] = gen_int_mode (HOST_WIDE_INT_1U << i, DImode);
11554 if (!x86_64_immediate_operand (operands[3], DImode))
11556 emit_move_insn (operands[2], operands[3]);
11557 operands[3] = operands[2];
11562 [(match_scratch:DI 2 "r")
11563 (parallel [(set (zero_extract:DI
11564 (match_operand:DI 0 "nonimmediate_operand")
11566 (match_operand 1 "const_0_to_63_operand"))
11568 (clobber (reg:CC FLAGS_REG))])]
11569 "TARGET_64BIT && !TARGET_USE_BT"
11570 [(parallel [(set (match_dup 0)
11571 (and:DI (match_dup 0) (match_dup 3)))
11572 (clobber (reg:CC FLAGS_REG))])]
11574 int i = INTVAL (operands[1]);
11576 operands[3] = gen_int_mode (~(HOST_WIDE_INT_1U << i), DImode);
11578 if (!x86_64_immediate_operand (operands[3], DImode))
11580 emit_move_insn (operands[2], operands[3]);
11581 operands[3] = operands[2];
11586 [(match_scratch:DI 2 "r")
11587 (parallel [(set (zero_extract:DI
11588 (match_operand:DI 0 "nonimmediate_operand")
11590 (match_operand 1 "const_0_to_63_operand"))
11591 (not:DI (zero_extract:DI
11592 (match_dup 0) (const_int 1) (match_dup 1))))
11593 (clobber (reg:CC FLAGS_REG))])]
11594 "TARGET_64BIT && !TARGET_USE_BT"
11595 [(parallel [(set (match_dup 0)
11596 (xor:DI (match_dup 0) (match_dup 3)))
11597 (clobber (reg:CC FLAGS_REG))])]
11599 int i = INTVAL (operands[1]);
11601 operands[3] = gen_int_mode (HOST_WIDE_INT_1U << i, DImode);
11603 if (!x86_64_immediate_operand (operands[3], DImode))
11605 emit_move_insn (operands[2], operands[3]);
11606 operands[3] = operands[2];
11612 (define_insn "*bt<mode>"
11613 [(set (reg:CCC FLAGS_REG)
11615 (zero_extract:SWI48
11616 (match_operand:SWI48 0 "nonimmediate_operand" "r,m")
11618 (match_operand:SI 1 "nonmemory_operand" "r<S>,<S>"))
11622 switch (get_attr_mode (insn))
11625 return "bt{l}\t{%1, %k0|%k0, %1}";
11628 return "bt{q}\t{%q1, %0|%0, %q1}";
11631 gcc_unreachable ();
11634 [(set_attr "type" "alu1")
11635 (set_attr "prefix_0f" "1")
11638 (and (match_test "CONST_INT_P (operands[1])")
11639 (match_test "INTVAL (operands[1]) < 32"))
11640 (const_string "SI")
11641 (const_string "<MODE>")))])
11643 (define_insn_and_split "*jcc_bt<mode>"
11645 (if_then_else (match_operator 0 "bt_comparison_operator"
11646 [(zero_extract:SWI48
11647 (match_operand:SWI48 1 "nonimmediate_operand")
11649 (match_operand:SI 2 "nonmemory_operand"))
11651 (label_ref (match_operand 3))
11653 (clobber (reg:CC FLAGS_REG))]
11654 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
11655 && (CONST_INT_P (operands[2])
11656 ? (INTVAL (operands[2]) < GET_MODE_BITSIZE (<MODE>mode)
11657 && INTVAL (operands[2])
11658 >= (optimize_function_for_size_p (cfun) ? 8 : 32))
11659 : !memory_operand (operands[1], <MODE>mode))
11660 && can_create_pseudo_p ()"
11663 [(set (reg:CCC FLAGS_REG)
11665 (zero_extract:SWI48
11671 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
11672 (label_ref (match_dup 3))
11675 operands[0] = shallow_copy_rtx (operands[0]);
11676 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
11679 (define_insn_and_split "*jcc_bt<mode>_1"
11681 (if_then_else (match_operator 0 "bt_comparison_operator"
11682 [(zero_extract:SWI48
11683 (match_operand:SWI48 1 "register_operand")
11686 (match_operand:QI 2 "register_operand")))
11688 (label_ref (match_operand 3))
11690 (clobber (reg:CC FLAGS_REG))]
11691 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
11692 && can_create_pseudo_p ()"
11695 [(set (reg:CCC FLAGS_REG)
11697 (zero_extract:SWI48
11703 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
11704 (label_ref (match_dup 3))
11707 operands[2] = lowpart_subreg (SImode, operands[2], QImode);
11708 operands[0] = shallow_copy_rtx (operands[0]);
11709 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
11712 ;; Avoid useless masking of bit offset operand.
11713 (define_insn_and_split "*jcc_bt<mode>_mask"
11715 (if_then_else (match_operator 0 "bt_comparison_operator"
11716 [(zero_extract:SWI48
11717 (match_operand:SWI48 1 "register_operand")
11720 (match_operand:SI 2 "register_operand")
11721 (match_operand 3 "const_int_operand")))])
11722 (label_ref (match_operand 4))
11724 (clobber (reg:CC FLAGS_REG))]
11725 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
11726 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
11727 == GET_MODE_BITSIZE (<MODE>mode)-1
11728 && can_create_pseudo_p ()"
11731 [(set (reg:CCC FLAGS_REG)
11733 (zero_extract:SWI48
11739 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
11740 (label_ref (match_dup 4))
11743 operands[0] = shallow_copy_rtx (operands[0]);
11744 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
11747 ;; Store-flag instructions.
11749 ;; For all sCOND expanders, also expand the compare or test insn that
11750 ;; generates cc0. Generate an equality comparison if `seq' or `sne'.
11752 (define_insn_and_split "*setcc_di_1"
11753 [(set (match_operand:DI 0 "register_operand" "=q")
11754 (match_operator:DI 1 "ix86_comparison_operator"
11755 [(reg FLAGS_REG) (const_int 0)]))]
11756 "TARGET_64BIT && !TARGET_PARTIAL_REG_STALL"
11758 "&& reload_completed"
11759 [(set (match_dup 2) (match_dup 1))
11760 (set (match_dup 0) (zero_extend:DI (match_dup 2)))]
11762 operands[1] = shallow_copy_rtx (operands[1]);
11763 PUT_MODE (operands[1], QImode);
11764 operands[2] = gen_lowpart (QImode, operands[0]);
11767 (define_insn_and_split "*setcc_si_1_and"
11768 [(set (match_operand:SI 0 "register_operand" "=q")
11769 (match_operator:SI 1 "ix86_comparison_operator"
11770 [(reg FLAGS_REG) (const_int 0)]))
11771 (clobber (reg:CC FLAGS_REG))]
11772 "!TARGET_PARTIAL_REG_STALL
11773 && TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
11775 "&& reload_completed"
11776 [(set (match_dup 2) (match_dup 1))
11777 (parallel [(set (match_dup 0) (zero_extend:SI (match_dup 2)))
11778 (clobber (reg:CC FLAGS_REG))])]
11780 operands[1] = shallow_copy_rtx (operands[1]);
11781 PUT_MODE (operands[1], QImode);
11782 operands[2] = gen_lowpart (QImode, operands[0]);
11785 (define_insn_and_split "*setcc_si_1_movzbl"
11786 [(set (match_operand:SI 0 "register_operand" "=q")
11787 (match_operator:SI 1 "ix86_comparison_operator"
11788 [(reg FLAGS_REG) (const_int 0)]))]
11789 "!TARGET_PARTIAL_REG_STALL
11790 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
11792 "&& reload_completed"
11793 [(set (match_dup 2) (match_dup 1))
11794 (set (match_dup 0) (zero_extend:SI (match_dup 2)))]
11796 operands[1] = shallow_copy_rtx (operands[1]);
11797 PUT_MODE (operands[1], QImode);
11798 operands[2] = gen_lowpart (QImode, operands[0]);
11801 (define_insn "*setcc_qi"
11802 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11803 (match_operator:QI 1 "ix86_comparison_operator"
11804 [(reg FLAGS_REG) (const_int 0)]))]
11807 [(set_attr "type" "setcc")
11808 (set_attr "mode" "QI")])
11810 (define_insn "*setcc_qi_slp"
11811 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
11812 (match_operator:QI 1 "ix86_comparison_operator"
11813 [(reg FLAGS_REG) (const_int 0)]))]
11816 [(set_attr "type" "setcc")
11817 (set_attr "mode" "QI")])
11819 ;; In general it is not safe to assume too much about CCmode registers,
11820 ;; so simplify-rtx stops when it sees a second one. Under certain
11821 ;; conditions this is safe on x86, so help combine not create
11828 [(set (match_operand:QI 0 "nonimmediate_operand")
11829 (ne:QI (match_operator 1 "ix86_comparison_operator"
11830 [(reg FLAGS_REG) (const_int 0)])
11833 [(set (match_dup 0) (match_dup 1))]
11835 operands[1] = shallow_copy_rtx (operands[1]);
11836 PUT_MODE (operands[1], QImode);
11840 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand"))
11841 (ne:QI (match_operator 1 "ix86_comparison_operator"
11842 [(reg FLAGS_REG) (const_int 0)])
11845 [(set (match_dup 0) (match_dup 1))]
11847 operands[1] = shallow_copy_rtx (operands[1]);
11848 PUT_MODE (operands[1], QImode);
11852 [(set (match_operand:QI 0 "nonimmediate_operand")
11853 (eq:QI (match_operator 1 "ix86_comparison_operator"
11854 [(reg FLAGS_REG) (const_int 0)])
11857 [(set (match_dup 0) (match_dup 1))]
11859 operands[1] = shallow_copy_rtx (operands[1]);
11860 PUT_MODE (operands[1], QImode);
11861 PUT_CODE (operands[1],
11862 ix86_reverse_condition (GET_CODE (operands[1]),
11863 GET_MODE (XEXP (operands[1], 0))));
11865 /* Make sure that (a) the CCmode we have for the flags is strong
11866 enough for the reversed compare or (b) we have a valid FP compare. */
11867 if (! ix86_comparison_operator (operands[1], VOIDmode))
11872 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand"))
11873 (eq:QI (match_operator 1 "ix86_comparison_operator"
11874 [(reg FLAGS_REG) (const_int 0)])
11877 [(set (match_dup 0) (match_dup 1))]
11879 operands[1] = shallow_copy_rtx (operands[1]);
11880 PUT_MODE (operands[1], QImode);
11881 PUT_CODE (operands[1],
11882 ix86_reverse_condition (GET_CODE (operands[1]),
11883 GET_MODE (XEXP (operands[1], 0))));
11885 /* Make sure that (a) the CCmode we have for the flags is strong
11886 enough for the reversed compare or (b) we have a valid FP compare. */
11887 if (! ix86_comparison_operator (operands[1], VOIDmode))
11891 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
11892 ;; subsequent logical operations are used to imitate conditional moves.
11893 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
11896 (define_insn "setcc_<mode>_sse"
11897 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
11898 (match_operator:MODEF 3 "sse_comparison_operator"
11899 [(match_operand:MODEF 1 "register_operand" "0,x")
11900 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
11901 "SSE_FLOAT_MODE_P (<MODE>mode)"
11903 cmp%D3<ssemodesuffix>\t{%2, %0|%0, %2}
11904 vcmp%D3<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
11905 [(set_attr "isa" "noavx,avx")
11906 (set_attr "type" "ssecmp")
11907 (set_attr "length_immediate" "1")
11908 (set_attr "prefix" "orig,vex")
11909 (set_attr "mode" "<MODE>")])
11911 ;; Basic conditional jump instructions.
11912 ;; We ignore the overflow flag for signed branch instructions.
11914 (define_insn "*jcc"
11916 (if_then_else (match_operator 1 "ix86_comparison_operator"
11917 [(reg FLAGS_REG) (const_int 0)])
11918 (label_ref (match_operand 0))
11922 [(set_attr "type" "ibr")
11923 (set_attr "modrm" "0")
11924 (set (attr "length")
11926 (and (ge (minus (match_dup 0) (pc))
11928 (lt (minus (match_dup 0) (pc))
11933 ;; In general it is not safe to assume too much about CCmode registers,
11934 ;; so simplify-rtx stops when it sees a second one. Under certain
11935 ;; conditions this is safe on x86, so help combine not create
11943 (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
11944 [(reg FLAGS_REG) (const_int 0)])
11946 (label_ref (match_operand 1))
11950 (if_then_else (match_dup 0)
11951 (label_ref (match_dup 1))
11954 operands[0] = shallow_copy_rtx (operands[0]);
11955 PUT_MODE (operands[0], VOIDmode);
11960 (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
11961 [(reg FLAGS_REG) (const_int 0)])
11963 (label_ref (match_operand 1))
11967 (if_then_else (match_dup 0)
11968 (label_ref (match_dup 1))
11971 operands[0] = shallow_copy_rtx (operands[0]);
11972 PUT_MODE (operands[0], VOIDmode);
11973 PUT_CODE (operands[0],
11974 ix86_reverse_condition (GET_CODE (operands[0]),
11975 GET_MODE (XEXP (operands[0], 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[0], VOIDmode))
11983 ;; Unconditional and other jump instructions
11985 (define_insn "jump"
11987 (label_ref (match_operand 0)))]
11990 [(set_attr "type" "ibr")
11991 (set_attr "modrm" "0")
11992 (set (attr "length")
11994 (and (ge (minus (match_dup 0) (pc))
11996 (lt (minus (match_dup 0) (pc))
12001 (define_expand "indirect_jump"
12002 [(set (pc) (match_operand 0 "indirect_branch_operand"))]
12005 if (TARGET_X32 || TARGET_INDIRECT_BRANCH_REGISTER)
12006 operands[0] = convert_memory_address (word_mode, operands[0]);
12007 cfun->machine->has_local_indirect_jump = true;
12010 (define_insn "*indirect_jump"
12011 [(set (pc) (match_operand:W 0 "indirect_branch_operand" "rBw"))]
12013 "* return ix86_output_indirect_jmp (operands[0]);"
12014 [(set (attr "type")
12015 (if_then_else (match_test "(cfun->machine->indirect_branch_type
12016 != indirect_branch_keep)")
12017 (const_string "multi")
12018 (const_string "ibr")))
12019 (set_attr "length_immediate" "0")])
12021 (define_expand "tablejump"
12022 [(parallel [(set (pc) (match_operand 0 "indirect_branch_operand"))
12023 (use (label_ref (match_operand 1)))])]
12026 /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
12027 relative. Convert the relative address to an absolute address. */
12031 enum rtx_code code;
12033 /* We can't use @GOTOFF for text labels on VxWorks;
12034 see gotoff_operand. */
12035 if (TARGET_64BIT || TARGET_VXWORKS_RTP)
12039 op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
12041 else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
12045 op1 = pic_offset_table_rtx;
12050 op0 = pic_offset_table_rtx;
12054 operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
12058 if (TARGET_X32 || TARGET_INDIRECT_BRANCH_REGISTER)
12059 operands[0] = convert_memory_address (word_mode, operands[0]);
12060 cfun->machine->has_local_indirect_jump = true;
12063 (define_insn "*tablejump_1"
12064 [(set (pc) (match_operand:W 0 "indirect_branch_operand" "rBw"))
12065 (use (label_ref (match_operand 1)))]
12067 "* return ix86_output_indirect_jmp (operands[0]);"
12068 [(set (attr "type")
12069 (if_then_else (match_test "(cfun->machine->indirect_branch_type
12070 != indirect_branch_keep)")
12071 (const_string "multi")
12072 (const_string "ibr")))
12073 (set_attr "length_immediate" "0")])
12075 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
12078 [(set (reg FLAGS_REG) (match_operand 0))
12079 (set (match_operand:QI 1 "register_operand")
12080 (match_operator:QI 2 "ix86_comparison_operator"
12081 [(reg FLAGS_REG) (const_int 0)]))
12082 (set (match_operand 3 "any_QIreg_operand")
12083 (zero_extend (match_dup 1)))]
12084 "(peep2_reg_dead_p (3, operands[1])
12085 || operands_match_p (operands[1], operands[3]))
12086 && ! reg_overlap_mentioned_p (operands[3], operands[0])
12087 && peep2_regno_dead_p (0, FLAGS_REG)"
12088 [(set (match_dup 4) (match_dup 0))
12089 (set (strict_low_part (match_dup 5))
12092 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
12093 operands[5] = gen_lowpart (QImode, operands[3]);
12094 ix86_expand_clear (operands[3]);
12098 [(parallel [(set (reg FLAGS_REG) (match_operand 0))
12099 (match_operand 4)])
12100 (set (match_operand:QI 1 "register_operand")
12101 (match_operator:QI 2 "ix86_comparison_operator"
12102 [(reg FLAGS_REG) (const_int 0)]))
12103 (set (match_operand 3 "any_QIreg_operand")
12104 (zero_extend (match_dup 1)))]
12105 "(peep2_reg_dead_p (3, operands[1])
12106 || operands_match_p (operands[1], operands[3]))
12107 && ! reg_overlap_mentioned_p (operands[3], operands[0])
12108 && ! reg_overlap_mentioned_p (operands[3], operands[4])
12109 && ! reg_set_p (operands[3], operands[4])
12110 && peep2_regno_dead_p (0, FLAGS_REG)"
12111 [(parallel [(set (match_dup 5) (match_dup 0))
12113 (set (strict_low_part (match_dup 6))
12116 operands[5] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
12117 operands[6] = gen_lowpart (QImode, operands[3]);
12118 ix86_expand_clear (operands[3]);
12122 [(set (reg FLAGS_REG) (match_operand 0))
12123 (parallel [(set (reg FLAGS_REG) (match_operand 1))
12124 (match_operand 5)])
12125 (set (match_operand:QI 2 "register_operand")
12126 (match_operator:QI 3 "ix86_comparison_operator"
12127 [(reg FLAGS_REG) (const_int 0)]))
12128 (set (match_operand 4 "any_QIreg_operand")
12129 (zero_extend (match_dup 2)))]
12130 "(peep2_reg_dead_p (4, operands[2])
12131 || operands_match_p (operands[2], operands[4]))
12132 && ! reg_overlap_mentioned_p (operands[4], operands[0])
12133 && ! reg_overlap_mentioned_p (operands[4], operands[1])
12134 && ! reg_overlap_mentioned_p (operands[4], operands[5])
12135 && ! reg_set_p (operands[4], operands[5])
12136 && refers_to_regno_p (FLAGS_REG, operands[1], (rtx *)NULL)
12137 && peep2_regno_dead_p (0, FLAGS_REG)"
12138 [(set (match_dup 6) (match_dup 0))
12139 (parallel [(set (match_dup 7) (match_dup 1))
12141 (set (strict_low_part (match_dup 8))
12144 operands[6] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
12145 operands[7] = gen_rtx_REG (GET_MODE (operands[1]), FLAGS_REG);
12146 operands[8] = gen_lowpart (QImode, operands[4]);
12147 ix86_expand_clear (operands[4]);
12150 ;; Similar, but match zero extend with andsi3.
12153 [(set (reg FLAGS_REG) (match_operand 0))
12154 (set (match_operand:QI 1 "register_operand")
12155 (match_operator:QI 2 "ix86_comparison_operator"
12156 [(reg FLAGS_REG) (const_int 0)]))
12157 (parallel [(set (match_operand:SI 3 "any_QIreg_operand")
12158 (and:SI (match_dup 3) (const_int 255)))
12159 (clobber (reg:CC FLAGS_REG))])]
12160 "REGNO (operands[1]) == REGNO (operands[3])
12161 && ! reg_overlap_mentioned_p (operands[3], operands[0])
12162 && peep2_regno_dead_p (0, FLAGS_REG)"
12163 [(set (match_dup 4) (match_dup 0))
12164 (set (strict_low_part (match_dup 5))
12167 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
12168 operands[5] = gen_lowpart (QImode, operands[3]);
12169 ix86_expand_clear (operands[3]);
12173 [(parallel [(set (reg FLAGS_REG) (match_operand 0))
12174 (match_operand 4)])
12175 (set (match_operand:QI 1 "register_operand")
12176 (match_operator:QI 2 "ix86_comparison_operator"
12177 [(reg FLAGS_REG) (const_int 0)]))
12178 (parallel [(set (match_operand 3 "any_QIreg_operand")
12179 (zero_extend (match_dup 1)))
12180 (clobber (reg:CC FLAGS_REG))])]
12181 "(peep2_reg_dead_p (3, operands[1])
12182 || operands_match_p (operands[1], operands[3]))
12183 && ! reg_overlap_mentioned_p (operands[3], operands[0])
12184 && ! reg_overlap_mentioned_p (operands[3], operands[4])
12185 && ! reg_set_p (operands[3], operands[4])
12186 && peep2_regno_dead_p (0, FLAGS_REG)"
12187 [(parallel [(set (match_dup 5) (match_dup 0))
12189 (set (strict_low_part (match_dup 6))
12192 operands[5] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
12193 operands[6] = gen_lowpart (QImode, operands[3]);
12194 ix86_expand_clear (operands[3]);
12198 [(set (reg FLAGS_REG) (match_operand 0))
12199 (parallel [(set (reg FLAGS_REG) (match_operand 1))
12200 (match_operand 5)])
12201 (set (match_operand:QI 2 "register_operand")
12202 (match_operator:QI 3 "ix86_comparison_operator"
12203 [(reg FLAGS_REG) (const_int 0)]))
12204 (parallel [(set (match_operand 4 "any_QIreg_operand")
12205 (zero_extend (match_dup 2)))
12206 (clobber (reg:CC FLAGS_REG))])]
12207 "(peep2_reg_dead_p (4, operands[2])
12208 || operands_match_p (operands[2], operands[4]))
12209 && ! reg_overlap_mentioned_p (operands[4], operands[0])
12210 && ! reg_overlap_mentioned_p (operands[4], operands[1])
12211 && ! reg_overlap_mentioned_p (operands[4], operands[5])
12212 && ! reg_set_p (operands[4], operands[5])
12213 && refers_to_regno_p (FLAGS_REG, operands[1], (rtx *)NULL)
12214 && peep2_regno_dead_p (0, FLAGS_REG)"
12215 [(set (match_dup 6) (match_dup 0))
12216 (parallel [(set (match_dup 7) (match_dup 1))
12218 (set (strict_low_part (match_dup 8))
12221 operands[6] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
12222 operands[7] = gen_rtx_REG (GET_MODE (operands[1]), FLAGS_REG);
12223 operands[8] = gen_lowpart (QImode, operands[4]);
12224 ix86_expand_clear (operands[4]);
12227 ;; Call instructions.
12229 ;; The predicates normally associated with named expanders are not properly
12230 ;; checked for calls. This is a bug in the generic code, but it isn't that
12231 ;; easy to fix. Ignore it for now and be prepared to fix things up.
12233 ;; P6 processors will jump to the address after the decrement when %esp
12234 ;; is used as a call operand, so they will execute return address as a code.
12235 ;; See Pentium Pro errata 70, Pentium 2 errata A33 and Pentium 3 errata E17.
12237 ;; Register constraint for call instruction.
12238 (define_mode_attr c [(SI "l") (DI "r")])
12240 ;; Call subroutine returning no value.
12242 (define_expand "call"
12243 [(call (match_operand:QI 0)
12245 (use (match_operand 2))]
12248 ix86_expand_call (NULL, operands[0], operands[1],
12249 operands[2], NULL, false);
12253 (define_expand "sibcall"
12254 [(call (match_operand:QI 0)
12256 (use (match_operand 2))]
12259 ix86_expand_call (NULL, operands[0], operands[1],
12260 operands[2], NULL, true);
12264 (define_insn "*call"
12265 [(call (mem:QI (match_operand:W 0 "call_insn_operand" "<c>BwBz"))
12266 (match_operand 1))]
12267 "!SIBLING_CALL_P (insn)"
12268 "* return ix86_output_call_insn (insn, operands[0]);"
12269 [(set_attr "type" "call")])
12271 ;; This covers both call and sibcall since only GOT slot is allowed.
12272 (define_insn "*call_got_x32"
12273 [(call (mem:QI (zero_extend:DI
12274 (match_operand:SI 0 "GOT_memory_operand" "Bg")))
12275 (match_operand 1))]
12278 rtx fnaddr = gen_const_mem (DImode, XEXP (operands[0], 0));
12279 return ix86_output_call_insn (insn, fnaddr);
12281 [(set_attr "type" "call")])
12283 ;; Since sibcall never returns, we can only use call-clobbered register
12285 (define_insn "*sibcall_GOT_32"
12288 (match_operand:SI 0 "register_no_elim_operand" "U")
12289 (match_operand:SI 1 "GOT32_symbol_operand"))))
12290 (match_operand 2))]
12293 && !TARGET_INDIRECT_BRANCH_REGISTER
12294 && SIBLING_CALL_P (insn)"
12296 rtx fnaddr = gen_rtx_PLUS (SImode, operands[0], operands[1]);
12297 fnaddr = gen_const_mem (SImode, fnaddr);
12298 return ix86_output_call_insn (insn, fnaddr);
12300 [(set_attr "type" "call")])
12302 (define_insn "*sibcall"
12303 [(call (mem:QI (match_operand:W 0 "sibcall_insn_operand" "UBsBz"))
12304 (match_operand 1))]
12305 "SIBLING_CALL_P (insn)"
12306 "* return ix86_output_call_insn (insn, operands[0]);"
12307 [(set_attr "type" "call")])
12309 (define_insn "*sibcall_memory"
12310 [(call (mem:QI (match_operand:W 0 "memory_operand" "m"))
12312 (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
12313 "!TARGET_X32 && !TARGET_INDIRECT_BRANCH_REGISTER"
12314 "* return ix86_output_call_insn (insn, operands[0]);"
12315 [(set_attr "type" "call")])
12318 [(set (match_operand:W 0 "register_operand")
12319 (match_operand:W 1 "memory_operand"))
12320 (call (mem:QI (match_dup 0))
12321 (match_operand 3))]
12323 && !TARGET_INDIRECT_BRANCH_REGISTER
12324 && SIBLING_CALL_P (peep2_next_insn (1))
12325 && !reg_mentioned_p (operands[0],
12326 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (1)))"
12327 [(parallel [(call (mem:QI (match_dup 1))
12329 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
12332 [(set (match_operand:W 0 "register_operand")
12333 (match_operand:W 1 "memory_operand"))
12334 (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
12335 (call (mem:QI (match_dup 0))
12336 (match_operand 3))]
12338 && !TARGET_INDIRECT_BRANCH_REGISTER
12339 && SIBLING_CALL_P (peep2_next_insn (2))
12340 && !reg_mentioned_p (operands[0],
12341 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (2)))"
12342 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
12343 (parallel [(call (mem:QI (match_dup 1))
12345 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
12347 (define_expand "call_pop"
12348 [(parallel [(call (match_operand:QI 0)
12349 (match_operand:SI 1))
12350 (set (reg:SI SP_REG)
12351 (plus:SI (reg:SI SP_REG)
12352 (match_operand:SI 3)))])]
12355 ix86_expand_call (NULL, operands[0], operands[1],
12356 operands[2], operands[3], false);
12360 (define_insn "*call_pop"
12361 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lBwBz"))
12363 (set (reg:SI SP_REG)
12364 (plus:SI (reg:SI SP_REG)
12365 (match_operand:SI 2 "immediate_operand" "i")))]
12366 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
12367 "* return ix86_output_call_insn (insn, operands[0]);"
12368 [(set_attr "type" "call")])
12370 (define_insn "*sibcall_pop"
12371 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "UBsBz"))
12373 (set (reg:SI SP_REG)
12374 (plus:SI (reg:SI SP_REG)
12375 (match_operand:SI 2 "immediate_operand" "i")))]
12376 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
12377 "* return ix86_output_call_insn (insn, operands[0]);"
12378 [(set_attr "type" "call")])
12380 (define_insn "*sibcall_pop_memory"
12381 [(call (mem:QI (match_operand:SI 0 "memory_operand" "Bs"))
12383 (set (reg:SI SP_REG)
12384 (plus:SI (reg:SI SP_REG)
12385 (match_operand:SI 2 "immediate_operand" "i")))
12386 (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
12388 "* return ix86_output_call_insn (insn, operands[0]);"
12389 [(set_attr "type" "call")])
12392 [(set (match_operand:SI 0 "register_operand")
12393 (match_operand:SI 1 "memory_operand"))
12394 (parallel [(call (mem:QI (match_dup 0))
12396 (set (reg:SI SP_REG)
12397 (plus:SI (reg:SI SP_REG)
12398 (match_operand:SI 4 "immediate_operand")))])]
12399 "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (1))
12400 && !reg_mentioned_p (operands[0],
12401 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (1)))"
12402 [(parallel [(call (mem:QI (match_dup 1))
12404 (set (reg:SI SP_REG)
12405 (plus:SI (reg:SI SP_REG)
12407 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
12410 [(set (match_operand:SI 0 "register_operand")
12411 (match_operand:SI 1 "memory_operand"))
12412 (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
12413 (parallel [(call (mem:QI (match_dup 0))
12415 (set (reg:SI SP_REG)
12416 (plus:SI (reg:SI SP_REG)
12417 (match_operand:SI 4 "immediate_operand")))])]
12418 "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (2))
12419 && !reg_mentioned_p (operands[0],
12420 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (2)))"
12421 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
12422 (parallel [(call (mem:QI (match_dup 1))
12424 (set (reg:SI SP_REG)
12425 (plus:SI (reg:SI SP_REG)
12427 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
12429 ;; Combining simple memory jump instruction
12432 [(set (match_operand:W 0 "register_operand")
12433 (match_operand:W 1 "memory_operand"))
12434 (set (pc) (match_dup 0))]
12436 && !TARGET_INDIRECT_BRANCH_REGISTER
12437 && peep2_reg_dead_p (2, operands[0])"
12438 [(set (pc) (match_dup 1))])
12440 ;; Call subroutine, returning value in operand 0
12442 (define_expand "call_value"
12443 [(set (match_operand 0)
12444 (call (match_operand:QI 1)
12445 (match_operand 2)))
12446 (use (match_operand 3))]
12449 ix86_expand_call (operands[0], operands[1], operands[2],
12450 operands[3], NULL, false);
12454 (define_expand "sibcall_value"
12455 [(set (match_operand 0)
12456 (call (match_operand:QI 1)
12457 (match_operand 2)))
12458 (use (match_operand 3))]
12461 ix86_expand_call (operands[0], operands[1], operands[2],
12462 operands[3], NULL, true);
12466 (define_insn "*call_value"
12467 [(set (match_operand 0)
12468 (call (mem:QI (match_operand:W 1 "call_insn_operand" "<c>BwBz"))
12469 (match_operand 2)))]
12470 "!SIBLING_CALL_P (insn)"
12471 "* return ix86_output_call_insn (insn, operands[1]);"
12472 [(set_attr "type" "callv")])
12474 ;; This covers both call and sibcall since only GOT slot is allowed.
12475 (define_insn "*call_value_got_x32"
12476 [(set (match_operand 0)
12479 (match_operand:SI 1 "GOT_memory_operand" "Bg")))
12480 (match_operand 2)))]
12483 rtx fnaddr = gen_const_mem (DImode, XEXP (operands[1], 0));
12484 return ix86_output_call_insn (insn, fnaddr);
12486 [(set_attr "type" "callv")])
12488 ;; Since sibcall never returns, we can only use call-clobbered register
12490 (define_insn "*sibcall_value_GOT_32"
12491 [(set (match_operand 0)
12494 (match_operand:SI 1 "register_no_elim_operand" "U")
12495 (match_operand:SI 2 "GOT32_symbol_operand"))))
12496 (match_operand 3)))]
12499 && !TARGET_INDIRECT_BRANCH_REGISTER
12500 && SIBLING_CALL_P (insn)"
12502 rtx fnaddr = gen_rtx_PLUS (SImode, operands[1], operands[2]);
12503 fnaddr = gen_const_mem (SImode, fnaddr);
12504 return ix86_output_call_insn (insn, fnaddr);
12506 [(set_attr "type" "callv")])
12508 (define_insn "*sibcall_value"
12509 [(set (match_operand 0)
12510 (call (mem:QI (match_operand:W 1 "sibcall_insn_operand" "UBsBz"))
12511 (match_operand 2)))]
12512 "SIBLING_CALL_P (insn)"
12513 "* return ix86_output_call_insn (insn, operands[1]);"
12514 [(set_attr "type" "callv")])
12516 (define_insn "*sibcall_value_memory"
12517 [(set (match_operand 0)
12518 (call (mem:QI (match_operand:W 1 "memory_operand" "m"))
12519 (match_operand 2)))
12520 (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
12521 "!TARGET_X32 && !TARGET_INDIRECT_BRANCH_REGISTER"
12522 "* return ix86_output_call_insn (insn, operands[1]);"
12523 [(set_attr "type" "callv")])
12526 [(set (match_operand:W 0 "register_operand")
12527 (match_operand:W 1 "memory_operand"))
12528 (set (match_operand 2)
12529 (call (mem:QI (match_dup 0))
12530 (match_operand 3)))]
12532 && !TARGET_INDIRECT_BRANCH_REGISTER
12533 && SIBLING_CALL_P (peep2_next_insn (1))
12534 && !reg_mentioned_p (operands[0],
12535 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (1)))"
12536 [(parallel [(set (match_dup 2)
12537 (call (mem:QI (match_dup 1))
12539 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
12542 [(set (match_operand:W 0 "register_operand")
12543 (match_operand:W 1 "memory_operand"))
12544 (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
12545 (set (match_operand 2)
12546 (call (mem:QI (match_dup 0))
12547 (match_operand 3)))]
12549 && !TARGET_INDIRECT_BRANCH_REGISTER
12550 && SIBLING_CALL_P (peep2_next_insn (2))
12551 && !reg_mentioned_p (operands[0],
12552 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (2)))"
12553 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
12554 (parallel [(set (match_dup 2)
12555 (call (mem:QI (match_dup 1))
12557 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
12559 (define_expand "call_value_pop"
12560 [(parallel [(set (match_operand 0)
12561 (call (match_operand:QI 1)
12562 (match_operand:SI 2)))
12563 (set (reg:SI SP_REG)
12564 (plus:SI (reg:SI SP_REG)
12565 (match_operand:SI 4)))])]
12568 ix86_expand_call (operands[0], operands[1], operands[2],
12569 operands[3], operands[4], false);
12573 (define_insn "*call_value_pop"
12574 [(set (match_operand 0)
12575 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lBwBz"))
12576 (match_operand 2)))
12577 (set (reg:SI SP_REG)
12578 (plus:SI (reg:SI SP_REG)
12579 (match_operand:SI 3 "immediate_operand" "i")))]
12580 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
12581 "* return ix86_output_call_insn (insn, operands[1]);"
12582 [(set_attr "type" "callv")])
12584 (define_insn "*sibcall_value_pop"
12585 [(set (match_operand 0)
12586 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "UBsBz"))
12587 (match_operand 2)))
12588 (set (reg:SI SP_REG)
12589 (plus:SI (reg:SI SP_REG)
12590 (match_operand:SI 3 "immediate_operand" "i")))]
12591 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
12592 "* return ix86_output_call_insn (insn, operands[1]);"
12593 [(set_attr "type" "callv")])
12595 (define_insn "*sibcall_value_pop_memory"
12596 [(set (match_operand 0)
12597 (call (mem:QI (match_operand:SI 1 "memory_operand" "m"))
12598 (match_operand 2)))
12599 (set (reg:SI SP_REG)
12600 (plus:SI (reg:SI SP_REG)
12601 (match_operand:SI 3 "immediate_operand" "i")))
12602 (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
12604 "* return ix86_output_call_insn (insn, operands[1]);"
12605 [(set_attr "type" "callv")])
12608 [(set (match_operand:SI 0 "register_operand")
12609 (match_operand:SI 1 "memory_operand"))
12610 (parallel [(set (match_operand 2)
12611 (call (mem:QI (match_dup 0))
12612 (match_operand 3)))
12613 (set (reg:SI SP_REG)
12614 (plus:SI (reg:SI SP_REG)
12615 (match_operand:SI 4 "immediate_operand")))])]
12616 "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (1))
12617 && !reg_mentioned_p (operands[0],
12618 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (1)))"
12619 [(parallel [(set (match_dup 2)
12620 (call (mem:QI (match_dup 1))
12622 (set (reg:SI SP_REG)
12623 (plus:SI (reg:SI SP_REG)
12625 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
12628 [(set (match_operand:SI 0 "register_operand")
12629 (match_operand:SI 1 "memory_operand"))
12630 (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
12631 (parallel [(set (match_operand 2)
12632 (call (mem:QI (match_dup 0))
12633 (match_operand 3)))
12634 (set (reg:SI SP_REG)
12635 (plus:SI (reg:SI SP_REG)
12636 (match_operand:SI 4 "immediate_operand")))])]
12637 "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (2))
12638 && !reg_mentioned_p (operands[0],
12639 CALL_INSN_FUNCTION_USAGE (peep2_next_insn (2)))"
12640 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
12641 (parallel [(set (match_dup 2)
12642 (call (mem:QI (match_dup 1))
12644 (set (reg:SI SP_REG)
12645 (plus:SI (reg:SI SP_REG)
12647 (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
12649 ;; Call subroutine returning any type.
12651 (define_expand "untyped_call"
12652 [(parallel [(call (match_operand 0)
12655 (match_operand 2)])]
12660 /* In order to give reg-stack an easier job in validating two
12661 coprocessor registers as containing a possible return value,
12662 simply pretend the untyped call returns a complex long double
12665 We can't use SSE_REGPARM_MAX here since callee is unprototyped
12666 and should have the default ABI. */
12668 ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
12669 ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
12670 operands[0], const0_rtx,
12671 GEN_INT ((TARGET_64BIT
12672 ? (ix86_abi == SYSV_ABI
12673 ? X86_64_SSE_REGPARM_MAX
12674 : X86_64_MS_SSE_REGPARM_MAX)
12675 : X86_32_SSE_REGPARM_MAX)
12679 for (i = 0; i < XVECLEN (operands[2], 0); i++)
12681 rtx set = XVECEXP (operands[2], 0, i);
12682 emit_move_insn (SET_DEST (set), SET_SRC (set));
12685 /* The optimizer does not know that the call sets the function value
12686 registers we stored in the result block. We avoid problems by
12687 claiming that all hard registers are used and clobbered at this
12689 emit_insn (gen_blockage ());
12694 ;; Prologue and epilogue instructions
12696 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
12697 ;; all of memory. This blocks insns from being moved across this point.
12699 (define_insn "blockage"
12700 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
12703 [(set_attr "length" "0")])
12705 ;; Do not schedule instructions accessing memory across this point.
12707 (define_expand "memory_blockage"
12708 [(set (match_dup 0)
12709 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
12712 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
12713 MEM_VOLATILE_P (operands[0]) = 1;
12716 (define_insn "*memory_blockage"
12717 [(set (match_operand:BLK 0)
12718 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
12721 [(set_attr "length" "0")])
12723 ;; As USE insns aren't meaningful after reload, this is used instead
12724 ;; to prevent deleting instructions setting registers for PIC code
12725 (define_insn "prologue_use"
12726 [(unspec_volatile [(match_operand 0)] UNSPECV_PROLOGUE_USE)]
12729 [(set_attr "length" "0")])
12731 ;; Insn emitted into the body of a function to return from a function.
12732 ;; This is only done if the function's epilogue is known to be simple.
12733 ;; See comments for ix86_can_use_return_insn_p in i386.c.
12735 (define_expand "return"
12737 "ix86_can_use_return_insn_p ()"
12739 if (crtl->args.pops_args)
12741 rtx popc = GEN_INT (crtl->args.pops_args);
12742 emit_jump_insn (gen_simple_return_pop_internal (popc));
12747 ;; We need to disable this for TARGET_SEH, as otherwise
12748 ;; shrink-wrapped prologue gets enabled too. This might exceed
12749 ;; the maximum size of prologue in unwind information.
12750 ;; Also disallow shrink-wrapping if using stack slot to pass the
12751 ;; static chain pointer - the first instruction has to be pushl %esi
12752 ;; and it can't be moved around, as we use alternate entry points
12755 (define_expand "simple_return"
12757 "!TARGET_SEH && !ix86_static_chain_on_stack"
12759 if (crtl->args.pops_args)
12761 rtx popc = GEN_INT (crtl->args.pops_args);
12762 emit_jump_insn (gen_simple_return_pop_internal (popc));
12767 (define_insn "simple_return_internal"
12770 "* return ix86_output_function_return (false);"
12771 [(set_attr "length" "1")
12772 (set_attr "atom_unit" "jeu")
12773 (set_attr "length_immediate" "0")
12774 (set_attr "modrm" "0")])
12776 (define_insn "interrupt_return"
12778 (unspec [(const_int 0)] UNSPEC_INTERRUPT_RETURN)]
12781 return TARGET_64BIT ? "iretq" : "iret";
12784 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
12785 ;; instruction Athlon and K8 have.
12787 (define_insn "simple_return_internal_long"
12789 (unspec [(const_int 0)] UNSPEC_REP)]
12791 "* return ix86_output_function_return (true);"
12792 [(set_attr "length" "2")
12793 (set_attr "atom_unit" "jeu")
12794 (set_attr "length_immediate" "0")
12795 (set_attr "prefix_rep" "1")
12796 (set_attr "modrm" "0")])
12798 (define_insn_and_split "simple_return_pop_internal"
12800 (use (match_operand:SI 0 "const_int_operand"))]
12803 "&& cfun->machine->function_return_type != indirect_branch_keep"
12805 "ix86_split_simple_return_pop_internal (operands[0]); DONE;"
12806 [(set_attr "length" "3")
12807 (set_attr "atom_unit" "jeu")
12808 (set_attr "length_immediate" "2")
12809 (set_attr "modrm" "0")])
12811 (define_expand "simple_return_indirect_internal"
12814 (use (match_operand 0 "register_operand"))])])
12816 (define_insn "*simple_return_indirect_internal<mode>"
12818 (use (match_operand:W 0 "register_operand" "r"))]
12820 "* return ix86_output_indirect_function_return (operands[0]);"
12821 [(set (attr "type")
12822 (if_then_else (match_test "(cfun->machine->indirect_branch_type
12823 != indirect_branch_keep)")
12824 (const_string "multi")
12825 (const_string "ibr")))
12826 (set_attr "length_immediate" "0")])
12832 [(set_attr "length" "1")
12833 (set_attr "length_immediate" "0")
12834 (set_attr "modrm" "0")])
12836 ;; Generate nops. Operand 0 is the number of nops, up to 8.
12837 (define_insn "nops"
12838 [(unspec_volatile [(match_operand 0 "const_int_operand")]
12842 int num = INTVAL (operands[0]);
12844 gcc_assert (IN_RANGE (num, 1, 8));
12847 fputs ("\tnop\n", asm_out_file);
12851 [(set (attr "length") (symbol_ref "INTVAL (operands[0])"))
12852 (set_attr "length_immediate" "0")
12853 (set_attr "modrm" "0")])
12855 ;; Pad to 16-byte boundary, max skip in op0. Used to avoid
12856 ;; branch prediction penalty for the third jump in a 16-byte
12860 [(unspec_volatile [(match_operand 0)] UNSPECV_ALIGN)]
12863 #ifdef ASM_OUTPUT_MAX_SKIP_PAD
12864 ASM_OUTPUT_MAX_SKIP_PAD (asm_out_file, 4, (int)INTVAL (operands[0]));
12866 /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
12867 The align insn is used to avoid 3 jump instructions in the row to improve
12868 branch prediction and the benefits hardly outweigh the cost of extra 8
12869 nops on the average inserted by full alignment pseudo operation. */
12873 [(set_attr "length" "16")])
12875 (define_expand "prologue"
12878 "ix86_expand_prologue (); DONE;")
12880 (define_expand "set_got"
12882 [(set (match_operand:SI 0 "register_operand")
12883 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
12884 (clobber (reg:CC FLAGS_REG))])]
12887 if (flag_pic && !TARGET_VXWORKS_RTP)
12888 ix86_pc_thunk_call_expanded = true;
12891 (define_insn "*set_got"
12892 [(set (match_operand:SI 0 "register_operand" "=r")
12893 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
12894 (clobber (reg:CC FLAGS_REG))]
12896 "* return output_set_got (operands[0], NULL_RTX);"
12897 [(set_attr "type" "multi")
12898 (set_attr "length" "12")])
12900 (define_expand "set_got_labelled"
12902 [(set (match_operand:SI 0 "register_operand")
12903 (unspec:SI [(label_ref (match_operand 1))]
12905 (clobber (reg:CC FLAGS_REG))])]
12908 if (flag_pic && !TARGET_VXWORKS_RTP)
12909 ix86_pc_thunk_call_expanded = true;
12912 (define_insn "*set_got_labelled"
12913 [(set (match_operand:SI 0 "register_operand" "=r")
12914 (unspec:SI [(label_ref (match_operand 1))]
12916 (clobber (reg:CC FLAGS_REG))]
12918 "* return output_set_got (operands[0], operands[1]);"
12919 [(set_attr "type" "multi")
12920 (set_attr "length" "12")])
12922 (define_insn "set_got_rex64"
12923 [(set (match_operand:DI 0 "register_operand" "=r")
12924 (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
12926 "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}"
12927 [(set_attr "type" "lea")
12928 (set_attr "length_address" "4")
12929 (set_attr "mode" "DI")])
12931 (define_insn "set_rip_rex64"
12932 [(set (match_operand:DI 0 "register_operand" "=r")
12933 (unspec:DI [(label_ref (match_operand 1))] UNSPEC_SET_RIP))]
12935 "lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}"
12936 [(set_attr "type" "lea")
12937 (set_attr "length_address" "4")
12938 (set_attr "mode" "DI")])
12940 (define_insn "set_got_offset_rex64"
12941 [(set (match_operand:DI 0 "register_operand" "=r")
12943 [(label_ref (match_operand 1))]
12944 UNSPEC_SET_GOT_OFFSET))]
12946 "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}"
12947 [(set_attr "type" "imov")
12948 (set_attr "length_immediate" "0")
12949 (set_attr "length_address" "8")
12950 (set_attr "mode" "DI")])
12952 (define_expand "epilogue"
12955 "ix86_expand_epilogue (1); DONE;")
12957 (define_expand "sibcall_epilogue"
12960 "ix86_expand_epilogue (0); DONE;")
12962 (define_expand "eh_return"
12963 [(use (match_operand 0 "register_operand"))]
12966 rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
12968 /* Tricky bit: we write the address of the handler to which we will
12969 be returning into someone else's stack frame, one word below the
12970 stack address we wish to restore. */
12971 tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
12972 tmp = plus_constant (Pmode, tmp, -UNITS_PER_WORD);
12973 /* Return address is always in word_mode. */
12974 tmp = gen_rtx_MEM (word_mode, tmp);
12975 if (GET_MODE (ra) != word_mode)
12976 ra = convert_to_mode (word_mode, ra, 1);
12977 emit_move_insn (tmp, ra);
12979 emit_jump_insn (gen_eh_return_internal ());
12984 (define_insn_and_split "eh_return_internal"
12988 "epilogue_completed"
12990 "ix86_expand_epilogue (2); DONE;")
12992 (define_expand "@leave_<mode>"
12994 [(set (reg:W SP_REG) (plus:W (reg:W BP_REG) (match_dup 0)))
12995 (set (reg:W BP_REG) (mem:W (reg:W BP_REG)))
12996 (clobber (mem:BLK (scratch)))])]
12998 "operands[0] = GEN_INT (<MODE_SIZE>);")
13000 (define_insn "*leave"
13001 [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
13002 (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
13003 (clobber (mem:BLK (scratch)))]
13006 [(set_attr "type" "leave")])
13008 (define_insn "*leave_rex64"
13009 [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
13010 (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
13011 (clobber (mem:BLK (scratch)))]
13014 [(set_attr "type" "leave")])
13016 ;; Handle -fsplit-stack.
13018 (define_expand "split_stack_prologue"
13022 ix86_expand_split_stack_prologue ();
13026 ;; In order to support the call/return predictor, we use a return
13027 ;; instruction which the middle-end doesn't see.
13028 (define_insn "split_stack_return"
13029 [(unspec_volatile [(match_operand:SI 0 "const_int_operand")]
13030 UNSPECV_SPLIT_STACK_RETURN)]
13033 if (operands[0] == const0_rtx)
13038 [(set_attr "atom_unit" "jeu")
13039 (set_attr "modrm" "0")
13040 (set (attr "length")
13041 (if_then_else (match_operand:SI 0 "const0_operand")
13044 (set (attr "length_immediate")
13045 (if_then_else (match_operand:SI 0 "const0_operand")
13049 ;; If there are operand 0 bytes available on the stack, jump to
13052 (define_expand "split_stack_space_check"
13053 [(set (pc) (if_then_else
13054 (ltu (minus (reg SP_REG)
13055 (match_operand 0 "register_operand"))
13057 (label_ref (match_operand 1))
13061 rtx reg = gen_reg_rtx (Pmode);
13063 emit_insn (gen_sub3_insn (reg, stack_pointer_rtx, operands[0]));
13065 operands[2] = ix86_split_stack_guard ();
13066 ix86_expand_branch (GEU, reg, operands[2], operands[1]);
13071 ;; Bit manipulation instructions.
13073 (define_expand "ffs<mode>2"
13074 [(set (match_dup 2) (const_int -1))
13075 (parallel [(set (match_dup 3) (match_dup 4))
13076 (set (match_operand:SWI48 0 "register_operand")
13078 (match_operand:SWI48 1 "nonimmediate_operand")))])
13079 (set (match_dup 0) (if_then_else:SWI48
13080 (eq (match_dup 3) (const_int 0))
13083 (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (const_int 1)))
13084 (clobber (reg:CC FLAGS_REG))])]
13087 machine_mode flags_mode;
13089 if (<MODE>mode == SImode && !TARGET_CMOVE)
13091 emit_insn (gen_ffssi2_no_cmove (operands[0], operands [1]));
13095 flags_mode = TARGET_BMI ? CCCmode : CCZmode;
13097 operands[2] = gen_reg_rtx (<MODE>mode);
13098 operands[3] = gen_rtx_REG (flags_mode, FLAGS_REG);
13099 operands[4] = gen_rtx_COMPARE (flags_mode, operands[1], const0_rtx);
13102 (define_insn_and_split "ffssi2_no_cmove"
13103 [(set (match_operand:SI 0 "register_operand" "=r")
13104 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
13105 (clobber (match_scratch:SI 2 "=&q"))
13106 (clobber (reg:CC FLAGS_REG))]
13109 "&& reload_completed"
13110 [(parallel [(set (match_dup 4) (match_dup 5))
13111 (set (match_dup 0) (ctz:SI (match_dup 1)))])
13112 (set (strict_low_part (match_dup 3))
13113 (eq:QI (match_dup 4) (const_int 0)))
13114 (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
13115 (clobber (reg:CC FLAGS_REG))])
13116 (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
13117 (clobber (reg:CC FLAGS_REG))])
13118 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
13119 (clobber (reg:CC FLAGS_REG))])]
13121 machine_mode flags_mode = TARGET_BMI ? CCCmode : CCZmode;
13123 operands[3] = gen_lowpart (QImode, operands[2]);
13124 operands[4] = gen_rtx_REG (flags_mode, FLAGS_REG);
13125 operands[5] = gen_rtx_COMPARE (flags_mode, operands[1], const0_rtx);
13127 ix86_expand_clear (operands[2]);
13130 (define_insn_and_split "*tzcnt<mode>_1"
13131 [(set (reg:CCC FLAGS_REG)
13132 (compare:CCC (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13134 (set (match_operand:SWI48 0 "register_operand" "=r")
13135 (ctz:SWI48 (match_dup 1)))]
13137 "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
13138 "&& TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
13139 && optimize_function_for_speed_p (cfun)
13140 && !reg_mentioned_p (operands[0], operands[1])"
13142 [(set (reg:CCC FLAGS_REG)
13143 (compare:CCC (match_dup 1) (const_int 0)))
13145 (ctz:SWI48 (match_dup 1)))
13146 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)])]
13147 "ix86_expand_clear (operands[0]);"
13148 [(set_attr "type" "alu1")
13149 (set_attr "prefix_0f" "1")
13150 (set_attr "prefix_rep" "1")
13151 (set_attr "btver2_decode" "double")
13152 (set_attr "mode" "<MODE>")])
13154 ; False dependency happens when destination is only updated by tzcnt,
13155 ; lzcnt or popcnt. There is no false dependency when destination is
13156 ; also used in source.
13157 (define_insn "*tzcnt<mode>_1_falsedep"
13158 [(set (reg:CCC FLAGS_REG)
13159 (compare:CCC (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13161 (set (match_operand:SWI48 0 "register_operand" "=r")
13162 (ctz:SWI48 (match_dup 1)))
13163 (unspec [(match_operand:SWI48 2 "register_operand" "0")]
13164 UNSPEC_INSN_FALSE_DEP)]
13166 "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
13167 [(set_attr "type" "alu1")
13168 (set_attr "prefix_0f" "1")
13169 (set_attr "prefix_rep" "1")
13170 (set_attr "btver2_decode" "double")
13171 (set_attr "mode" "<MODE>")])
13173 (define_insn "*bsf<mode>_1"
13174 [(set (reg:CCZ FLAGS_REG)
13175 (compare:CCZ (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13177 (set (match_operand:SWI48 0 "register_operand" "=r")
13178 (ctz:SWI48 (match_dup 1)))]
13180 "bsf{<imodesuffix>}\t{%1, %0|%0, %1}"
13181 [(set_attr "type" "alu1")
13182 (set_attr "prefix_0f" "1")
13183 (set_attr "btver2_decode" "double")
13184 (set_attr "znver1_decode" "vector")
13185 (set_attr "mode" "<MODE>")])
13187 (define_insn_and_split "ctz<mode>2"
13188 [(set (match_operand:SWI48 0 "register_operand" "=r")
13190 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
13191 (clobber (reg:CC FLAGS_REG))]
13195 return "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
13196 else if (optimize_function_for_size_p (cfun))
13198 else if (TARGET_GENERIC)
13199 /* tzcnt expands to 'rep bsf' and we can use it even if !TARGET_BMI. */
13200 return "rep%; bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
13202 return "bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
13204 "(TARGET_BMI || TARGET_GENERIC)
13205 && TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
13206 && optimize_function_for_speed_p (cfun)
13207 && !reg_mentioned_p (operands[0], operands[1])"
13209 [(set (match_dup 0)
13210 (ctz:SWI48 (match_dup 1)))
13211 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
13212 (clobber (reg:CC FLAGS_REG))])]
13213 "ix86_expand_clear (operands[0]);"
13214 [(set_attr "type" "alu1")
13215 (set_attr "prefix_0f" "1")
13216 (set (attr "prefix_rep")
13218 (ior (match_test "TARGET_BMI")
13219 (and (not (match_test "optimize_function_for_size_p (cfun)"))
13220 (match_test "TARGET_GENERIC")))
13222 (const_string "0")))
13223 (set_attr "mode" "<MODE>")])
13225 ; False dependency happens when destination is only updated by tzcnt,
13226 ; lzcnt or popcnt. There is no false dependency when destination is
13227 ; also used in source.
13228 (define_insn "*ctz<mode>2_falsedep"
13229 [(set (match_operand:SWI48 0 "register_operand" "=r")
13231 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
13232 (unspec [(match_operand:SWI48 2 "register_operand" "0")]
13233 UNSPEC_INSN_FALSE_DEP)
13234 (clobber (reg:CC FLAGS_REG))]
13238 return "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
13239 else if (TARGET_GENERIC)
13240 /* tzcnt expands to 'rep bsf' and we can use it even if !TARGET_BMI. */
13241 return "rep%; bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
13243 gcc_unreachable ();
13245 [(set_attr "type" "alu1")
13246 (set_attr "prefix_0f" "1")
13247 (set_attr "prefix_rep" "1")
13248 (set_attr "mode" "<MODE>")])
13250 (define_insn "bsr_rex64"
13251 [(set (match_operand:DI 0 "register_operand" "=r")
13252 (minus:DI (const_int 63)
13253 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
13254 (clobber (reg:CC FLAGS_REG))]
13256 "bsr{q}\t{%1, %0|%0, %1}"
13257 [(set_attr "type" "alu1")
13258 (set_attr "prefix_0f" "1")
13259 (set_attr "znver1_decode" "vector")
13260 (set_attr "mode" "DI")])
13263 [(set (match_operand:SI 0 "register_operand" "=r")
13264 (minus:SI (const_int 31)
13265 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
13266 (clobber (reg:CC FLAGS_REG))]
13268 "bsr{l}\t{%1, %0|%0, %1}"
13269 [(set_attr "type" "alu1")
13270 (set_attr "prefix_0f" "1")
13271 (set_attr "znver1_decode" "vector")
13272 (set_attr "mode" "SI")])
13274 (define_insn "*bsrhi"
13275 [(set (match_operand:HI 0 "register_operand" "=r")
13276 (minus:HI (const_int 15)
13277 (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
13278 (clobber (reg:CC FLAGS_REG))]
13280 "bsr{w}\t{%1, %0|%0, %1}"
13281 [(set_attr "type" "alu1")
13282 (set_attr "prefix_0f" "1")
13283 (set_attr "znver1_decode" "vector")
13284 (set_attr "mode" "HI")])
13286 (define_expand "clz<mode>2"
13288 [(set (match_operand:SWI48 0 "register_operand")
13291 (clz:SWI48 (match_operand:SWI48 1 "nonimmediate_operand"))))
13292 (clobber (reg:CC FLAGS_REG))])
13294 [(set (match_dup 0) (xor:SWI48 (match_dup 0) (match_dup 2)))
13295 (clobber (reg:CC FLAGS_REG))])]
13300 emit_insn (gen_clz<mode>2_lzcnt (operands[0], operands[1]));
13303 operands[2] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
13306 (define_insn_and_split "clz<mode>2_lzcnt"
13307 [(set (match_operand:SWI48 0 "register_operand" "=r")
13309 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
13310 (clobber (reg:CC FLAGS_REG))]
13312 "lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
13313 "&& TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
13314 && optimize_function_for_speed_p (cfun)
13315 && !reg_mentioned_p (operands[0], operands[1])"
13317 [(set (match_dup 0)
13318 (clz:SWI48 (match_dup 1)))
13319 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
13320 (clobber (reg:CC FLAGS_REG))])]
13321 "ix86_expand_clear (operands[0]);"
13322 [(set_attr "prefix_rep" "1")
13323 (set_attr "type" "bitmanip")
13324 (set_attr "mode" "<MODE>")])
13326 ; False dependency happens when destination is only updated by tzcnt,
13327 ; lzcnt or popcnt. There is no false dependency when destination is
13328 ; also used in source.
13329 (define_insn "*clz<mode>2_lzcnt_falsedep"
13330 [(set (match_operand:SWI48 0 "register_operand" "=r")
13332 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
13333 (unspec [(match_operand:SWI48 2 "register_operand" "0")]
13334 UNSPEC_INSN_FALSE_DEP)
13335 (clobber (reg:CC FLAGS_REG))]
13337 "lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
13338 [(set_attr "prefix_rep" "1")
13339 (set_attr "type" "bitmanip")
13340 (set_attr "mode" "<MODE>")])
13342 (define_int_iterator LT_ZCNT
13343 [(UNSPEC_TZCNT "TARGET_BMI")
13344 (UNSPEC_LZCNT "TARGET_LZCNT")])
13346 (define_int_attr lt_zcnt
13347 [(UNSPEC_TZCNT "tzcnt")
13348 (UNSPEC_LZCNT "lzcnt")])
13350 (define_int_attr lt_zcnt_type
13351 [(UNSPEC_TZCNT "alu1")
13352 (UNSPEC_LZCNT "bitmanip")])
13354 ;; Version of lzcnt/tzcnt that is expanded from intrinsics. This version
13355 ;; provides operand size as output when source operand is zero.
13357 (define_insn_and_split "<lt_zcnt>_<mode>"
13358 [(set (match_operand:SWI48 0 "register_operand" "=r")
13360 [(match_operand:SWI48 1 "nonimmediate_operand" "rm")] LT_ZCNT))
13361 (clobber (reg:CC FLAGS_REG))]
13363 "<lt_zcnt>{<imodesuffix>}\t{%1, %0|%0, %1}"
13364 "&& TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
13365 && optimize_function_for_speed_p (cfun)
13366 && !reg_mentioned_p (operands[0], operands[1])"
13368 [(set (match_dup 0)
13369 (unspec:SWI48 [(match_dup 1)] LT_ZCNT))
13370 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
13371 (clobber (reg:CC FLAGS_REG))])]
13372 "ix86_expand_clear (operands[0]);"
13373 [(set_attr "type" "<lt_zcnt_type>")
13374 (set_attr "prefix_0f" "1")
13375 (set_attr "prefix_rep" "1")
13376 (set_attr "mode" "<MODE>")])
13378 ; False dependency happens when destination is only updated by tzcnt,
13379 ; lzcnt or popcnt. There is no false dependency when destination is
13380 ; also used in source.
13381 (define_insn "*<lt_zcnt>_<mode>_falsedep"
13382 [(set (match_operand:SWI48 0 "register_operand" "=r")
13384 [(match_operand:SWI48 1 "nonimmediate_operand" "rm")] LT_ZCNT))
13385 (unspec [(match_operand:SWI48 2 "register_operand" "0")]
13386 UNSPEC_INSN_FALSE_DEP)
13387 (clobber (reg:CC FLAGS_REG))]
13389 "<lt_zcnt>{<imodesuffix>}\t{%1, %0|%0, %1}"
13390 [(set_attr "type" "<lt_zcnt_type>")
13391 (set_attr "prefix_0f" "1")
13392 (set_attr "prefix_rep" "1")
13393 (set_attr "mode" "<MODE>")])
13395 (define_insn "<lt_zcnt>_hi"
13396 [(set (match_operand:HI 0 "register_operand" "=r")
13398 [(match_operand:HI 1 "nonimmediate_operand" "rm")] LT_ZCNT))
13399 (clobber (reg:CC FLAGS_REG))]
13401 "<lt_zcnt>{w}\t{%1, %0|%0, %1}"
13402 [(set_attr "type" "<lt_zcnt_type>")
13403 (set_attr "prefix_0f" "1")
13404 (set_attr "prefix_rep" "1")
13405 (set_attr "mode" "HI")])
13407 ;; BMI instructions.
13409 (define_insn "bmi_bextr_<mode>"
13410 [(set (match_operand:SWI48 0 "register_operand" "=r,r")
13411 (unspec:SWI48 [(match_operand:SWI48 1 "nonimmediate_operand" "r,m")
13412 (match_operand:SWI48 2 "register_operand" "r,r")]
13414 (clobber (reg:CC FLAGS_REG))]
13416 "bextr\t{%2, %1, %0|%0, %1, %2}"
13417 [(set_attr "type" "bitmanip")
13418 (set_attr "btver2_decode" "direct, double")
13419 (set_attr "mode" "<MODE>")])
13421 (define_insn "*bmi_bextr_<mode>_ccz"
13422 [(set (reg:CCZ FLAGS_REG)
13424 (unspec:SWI48 [(match_operand:SWI48 1 "nonimmediate_operand" "r,m")
13425 (match_operand:SWI48 2 "register_operand" "r,r")]
13428 (clobber (match_scratch:SWI48 0 "=r,r"))]
13430 "bextr\t{%2, %1, %0|%0, %1, %2}"
13431 [(set_attr "type" "bitmanip")
13432 (set_attr "btver2_decode" "direct, double")
13433 (set_attr "mode" "<MODE>")])
13435 (define_insn "*bmi_blsi_<mode>"
13436 [(set (match_operand:SWI48 0 "register_operand" "=r")
13439 (match_operand:SWI48 1 "nonimmediate_operand" "rm"))
13441 (clobber (reg:CC FLAGS_REG))]
13443 "blsi\t{%1, %0|%0, %1}"
13444 [(set_attr "type" "bitmanip")
13445 (set_attr "btver2_decode" "double")
13446 (set_attr "mode" "<MODE>")])
13448 (define_insn "*bmi_blsmsk_<mode>"
13449 [(set (match_operand:SWI48 0 "register_operand" "=r")
13452 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13455 (clobber (reg:CC FLAGS_REG))]
13457 "blsmsk\t{%1, %0|%0, %1}"
13458 [(set_attr "type" "bitmanip")
13459 (set_attr "btver2_decode" "double")
13460 (set_attr "mode" "<MODE>")])
13462 (define_insn "*bmi_blsr_<mode>"
13463 [(set (match_operand:SWI48 0 "register_operand" "=r")
13466 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13469 (clobber (reg:CC FLAGS_REG))]
13471 "blsr\t{%1, %0|%0, %1}"
13472 [(set_attr "type" "bitmanip")
13473 (set_attr "btver2_decode" "double")
13474 (set_attr "mode" "<MODE>")])
13476 (define_insn "*bmi_blsr_<mode>_cmp"
13477 [(set (reg:CCZ FLAGS_REG)
13481 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13485 (set (match_operand:SWI48 0 "register_operand" "=r")
13492 "blsr\t{%1, %0|%0, %1}"
13493 [(set_attr "type" "bitmanip")
13494 (set_attr "btver2_decode" "double")
13495 (set_attr "mode" "<MODE>")])
13497 (define_insn "*bmi_blsr_<mode>_ccz"
13498 [(set (reg:CCZ FLAGS_REG)
13502 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13506 (clobber (match_scratch:SWI48 0 "=r"))]
13508 "blsr\t{%1, %0|%0, %1}"
13509 [(set_attr "type" "bitmanip")
13510 (set_attr "btver2_decode" "double")
13511 (set_attr "mode" "<MODE>")])
13513 ;; BMI2 instructions.
13514 (define_expand "bmi2_bzhi_<mode>3"
13516 [(set (match_operand:SWI48 0 "register_operand")
13517 (if_then_else:SWI48
13518 (ne:QI (and:SWI48 (match_operand:SWI48 2 "register_operand")
13521 (zero_extract:SWI48
13522 (match_operand:SWI48 1 "nonimmediate_operand")
13523 (umin:SWI48 (and:SWI48 (match_dup 2) (const_int 255))
13527 (clobber (reg:CC FLAGS_REG))])]
13529 "operands[3] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT);")
13531 (define_insn "*bmi2_bzhi_<mode>3"
13532 [(set (match_operand:SWI48 0 "register_operand" "=r")
13533 (if_then_else:SWI48
13534 (ne:QI (and:SWI48 (match_operand:SWI48 2 "register_operand" "r")
13537 (zero_extract:SWI48
13538 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13539 (umin:SWI48 (and:SWI48 (match_dup 2) (const_int 255))
13540 (match_operand:SWI48 3 "const_int_operand" "n"))
13543 (clobber (reg:CC FLAGS_REG))]
13544 "TARGET_BMI2 && INTVAL (operands[3]) == <MODE_SIZE> * BITS_PER_UNIT"
13545 "bzhi\t{%2, %1, %0|%0, %1, %2}"
13546 [(set_attr "type" "bitmanip")
13547 (set_attr "prefix" "vex")
13548 (set_attr "mode" "<MODE>")])
13550 (define_insn "*bmi2_bzhi_<mode>3_1"
13551 [(set (match_operand:SWI48 0 "register_operand" "=r")
13552 (if_then_else:SWI48
13553 (ne:QI (match_operand:QI 2 "register_operand" "r") (const_int 0))
13554 (zero_extract:SWI48
13555 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13556 (umin:SWI48 (zero_extend:SWI48 (match_dup 2))
13557 (match_operand:SWI48 3 "const_int_operand" "n"))
13560 (clobber (reg:CC FLAGS_REG))]
13561 "TARGET_BMI2 && INTVAL (operands[3]) == <MODE_SIZE> * BITS_PER_UNIT"
13562 "bzhi\t{%<k>2, %1, %0|%0, %1, %<k>2}"
13563 [(set_attr "type" "bitmanip")
13564 (set_attr "prefix" "vex")
13565 (set_attr "mode" "<MODE>")])
13567 (define_insn "*bmi2_bzhi_<mode>3_1_ccz"
13568 [(set (reg:CCZ FLAGS_REG)
13570 (if_then_else:SWI48
13571 (ne:QI (match_operand:QI 2 "register_operand" "r") (const_int 0))
13572 (zero_extract:SWI48
13573 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13574 (umin:SWI48 (zero_extend:SWI48 (match_dup 2))
13575 (match_operand:SWI48 3 "const_int_operand" "n"))
13579 (clobber (match_scratch:SWI48 0 "=r"))]
13580 "TARGET_BMI2 && INTVAL (operands[3]) == <MODE_SIZE> * BITS_PER_UNIT"
13581 "bzhi\t{%<k>2, %1, %0|%0, %1, %<k>2}"
13582 [(set_attr "type" "bitmanip")
13583 (set_attr "prefix" "vex")
13584 (set_attr "mode" "<MODE>")])
13586 (define_insn "bmi2_pdep_<mode>3"
13587 [(set (match_operand:SWI48 0 "register_operand" "=r")
13588 (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
13589 (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
13592 "pdep\t{%2, %1, %0|%0, %1, %2}"
13593 [(set_attr "type" "bitmanip")
13594 (set_attr "prefix" "vex")
13595 (set_attr "mode" "<MODE>")])
13597 (define_insn "bmi2_pext_<mode>3"
13598 [(set (match_operand:SWI48 0 "register_operand" "=r")
13599 (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
13600 (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
13603 "pext\t{%2, %1, %0|%0, %1, %2}"
13604 [(set_attr "type" "bitmanip")
13605 (set_attr "prefix" "vex")
13606 (set_attr "mode" "<MODE>")])
13608 ;; TBM instructions.
13609 (define_expand "tbm_bextri_<mode>"
13611 [(set (match_operand:SWI48 0 "register_operand")
13612 (zero_extract:SWI48
13613 (match_operand:SWI48 1 "nonimmediate_operand")
13614 (match_operand 2 "const_0_to_255_operand" "N")
13615 (match_operand 3 "const_0_to_255_operand" "N")))
13616 (clobber (reg:CC FLAGS_REG))])]
13619 if (operands[2] == const0_rtx
13620 || INTVAL (operands[3]) >= <MODE_SIZE> * BITS_PER_UNIT)
13622 emit_move_insn (operands[0], const0_rtx);
13625 if (INTVAL (operands[2]) + INTVAL (operands[3])
13626 > <MODE_SIZE> * BITS_PER_UNIT)
13627 operands[2] = GEN_INT (<MODE_SIZE> * BITS_PER_UNIT - INTVAL (operands[3]));
13630 (define_insn "*tbm_bextri_<mode>"
13631 [(set (match_operand:SWI48 0 "register_operand" "=r")
13632 (zero_extract:SWI48
13633 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13634 (match_operand 2 "const_0_to_255_operand" "N")
13635 (match_operand 3 "const_0_to_255_operand" "N")))
13636 (clobber (reg:CC FLAGS_REG))]
13639 operands[2] = GEN_INT (INTVAL (operands[2]) << 8 | INTVAL (operands[3]));
13640 return "bextr\t{%2, %1, %0|%0, %1, %2}";
13642 [(set_attr "type" "bitmanip")
13643 (set_attr "mode" "<MODE>")])
13645 (define_insn "*tbm_blcfill_<mode>"
13646 [(set (match_operand:SWI48 0 "register_operand" "=r")
13649 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13652 (clobber (reg:CC FLAGS_REG))]
13654 "blcfill\t{%1, %0|%0, %1}"
13655 [(set_attr "type" "bitmanip")
13656 (set_attr "mode" "<MODE>")])
13658 (define_insn "*tbm_blci_<mode>"
13659 [(set (match_operand:SWI48 0 "register_operand" "=r")
13663 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13666 (clobber (reg:CC FLAGS_REG))]
13668 "blci\t{%1, %0|%0, %1}"
13669 [(set_attr "type" "bitmanip")
13670 (set_attr "mode" "<MODE>")])
13672 (define_insn "*tbm_blcic_<mode>"
13673 [(set (match_operand:SWI48 0 "register_operand" "=r")
13676 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13680 (clobber (reg:CC FLAGS_REG))]
13682 "blcic\t{%1, %0|%0, %1}"
13683 [(set_attr "type" "bitmanip")
13684 (set_attr "mode" "<MODE>")])
13686 (define_insn "*tbm_blcmsk_<mode>"
13687 [(set (match_operand:SWI48 0 "register_operand" "=r")
13690 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13693 (clobber (reg:CC FLAGS_REG))]
13695 "blcmsk\t{%1, %0|%0, %1}"
13696 [(set_attr "type" "bitmanip")
13697 (set_attr "mode" "<MODE>")])
13699 (define_insn "*tbm_blcs_<mode>"
13700 [(set (match_operand:SWI48 0 "register_operand" "=r")
13703 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13706 (clobber (reg:CC FLAGS_REG))]
13708 "blcs\t{%1, %0|%0, %1}"
13709 [(set_attr "type" "bitmanip")
13710 (set_attr "mode" "<MODE>")])
13712 (define_insn "*tbm_blsfill_<mode>"
13713 [(set (match_operand:SWI48 0 "register_operand" "=r")
13716 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13719 (clobber (reg:CC FLAGS_REG))]
13721 "blsfill\t{%1, %0|%0, %1}"
13722 [(set_attr "type" "bitmanip")
13723 (set_attr "mode" "<MODE>")])
13725 (define_insn "*tbm_blsic_<mode>"
13726 [(set (match_operand:SWI48 0 "register_operand" "=r")
13729 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13733 (clobber (reg:CC FLAGS_REG))]
13735 "blsic\t{%1, %0|%0, %1}"
13736 [(set_attr "type" "bitmanip")
13737 (set_attr "mode" "<MODE>")])
13739 (define_insn "*tbm_t1mskc_<mode>"
13740 [(set (match_operand:SWI48 0 "register_operand" "=r")
13743 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13747 (clobber (reg:CC FLAGS_REG))]
13749 "t1mskc\t{%1, %0|%0, %1}"
13750 [(set_attr "type" "bitmanip")
13751 (set_attr "mode" "<MODE>")])
13753 (define_insn "*tbm_tzmsk_<mode>"
13754 [(set (match_operand:SWI48 0 "register_operand" "=r")
13757 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
13761 (clobber (reg:CC FLAGS_REG))]
13763 "tzmsk\t{%1, %0|%0, %1}"
13764 [(set_attr "type" "bitmanip")
13765 (set_attr "mode" "<MODE>")])
13767 (define_insn_and_split "popcount<mode>2"
13768 [(set (match_operand:SWI48 0 "register_operand" "=r")
13770 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
13771 (clobber (reg:CC FLAGS_REG))]
13775 return "popcnt\t{%1, %0|%0, %1}";
13777 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
13780 "&& TARGET_AVOID_FALSE_DEP_FOR_BMI && epilogue_completed
13781 && optimize_function_for_speed_p (cfun)
13782 && !reg_mentioned_p (operands[0], operands[1])"
13784 [(set (match_dup 0)
13785 (popcount:SWI48 (match_dup 1)))
13786 (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
13787 (clobber (reg:CC FLAGS_REG))])]
13788 "ix86_expand_clear (operands[0]);"
13789 [(set_attr "prefix_rep" "1")
13790 (set_attr "type" "bitmanip")
13791 (set_attr "mode" "<MODE>")])
13793 ; False dependency happens when destination is only updated by tzcnt,
13794 ; lzcnt or popcnt. There is no false dependency when destination is
13795 ; also used in source.
13796 (define_insn "*popcount<mode>2_falsedep"
13797 [(set (match_operand:SWI48 0 "register_operand" "=r")
13799 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
13800 (unspec [(match_operand:SWI48 2 "register_operand" "0")]
13801 UNSPEC_INSN_FALSE_DEP)
13802 (clobber (reg:CC FLAGS_REG))]
13806 return "popcnt\t{%1, %0|%0, %1}";
13808 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
13811 [(set_attr "prefix_rep" "1")
13812 (set_attr "type" "bitmanip")
13813 (set_attr "mode" "<MODE>")])
13815 (define_insn_and_split "*popcounthi2_1"
13816 [(set (match_operand:SI 0 "register_operand")
13818 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand"))))
13819 (clobber (reg:CC FLAGS_REG))]
13821 && can_create_pseudo_p ()"
13826 rtx tmp = gen_reg_rtx (HImode);
13828 emit_insn (gen_popcounthi2 (tmp, operands[1]));
13829 emit_insn (gen_zero_extendhisi2 (operands[0], tmp));
13833 (define_insn "popcounthi2"
13834 [(set (match_operand:HI 0 "register_operand" "=r")
13836 (match_operand:HI 1 "nonimmediate_operand" "rm")))
13837 (clobber (reg:CC FLAGS_REG))]
13841 return "popcnt\t{%1, %0|%0, %1}";
13843 return "popcnt{w}\t{%1, %0|%0, %1}";
13846 [(set_attr "prefix_rep" "1")
13847 (set_attr "type" "bitmanip")
13848 (set_attr "mode" "HI")])
13850 (define_expand "bswapdi2"
13851 [(set (match_operand:DI 0 "register_operand")
13852 (bswap:DI (match_operand:DI 1 "nonimmediate_operand")))]
13856 operands[1] = force_reg (DImode, operands[1]);
13859 (define_expand "bswapsi2"
13860 [(set (match_operand:SI 0 "register_operand")
13861 (bswap:SI (match_operand:SI 1 "nonimmediate_operand")))]
13866 else if (TARGET_BSWAP)
13867 operands[1] = force_reg (SImode, operands[1]);
13870 rtx x = operands[0];
13872 emit_move_insn (x, operands[1]);
13873 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
13874 emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
13875 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
13880 (define_insn "*bswap<mode>2_movbe"
13881 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,r,m")
13882 (bswap:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,m,r")))]
13884 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
13887 movbe{<imodesuffix>}\t{%1, %0|%0, %1}
13888 movbe{<imodesuffix>}\t{%1, %0|%0, %1}"
13889 [(set_attr "type" "bitmanip,imov,imov")
13890 (set_attr "modrm" "0,1,1")
13891 (set_attr "prefix_0f" "*,1,1")
13892 (set_attr "prefix_extra" "*,1,1")
13893 (set_attr "mode" "<MODE>")])
13895 (define_insn "*bswap<mode>2"
13896 [(set (match_operand:SWI48 0 "register_operand" "=r")
13897 (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "0")))]
13900 [(set_attr "type" "bitmanip")
13901 (set_attr "modrm" "0")
13902 (set_attr "mode" "<MODE>")])
13904 (define_expand "bswaphi2"
13905 [(set (match_operand:HI 0 "register_operand")
13906 (bswap:HI (match_operand:HI 1 "nonimmediate_operand")))]
13909 (define_insn "*bswaphi2_movbe"
13910 [(set (match_operand:HI 0 "nonimmediate_operand" "=Q,r,m")
13911 (bswap:HI (match_operand:HI 1 "nonimmediate_operand" "0,m,r")))]
13913 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
13915 xchg{b}\t{%h0, %b0|%b0, %h0}
13916 movbe{w}\t{%1, %0|%0, %1}
13917 movbe{w}\t{%1, %0|%0, %1}"
13918 [(set_attr "type" "imov")
13919 (set_attr "modrm" "*,1,1")
13920 (set_attr "prefix_0f" "*,1,1")
13921 (set_attr "prefix_extra" "*,1,1")
13922 (set_attr "pent_pair" "np,*,*")
13923 (set_attr "athlon_decode" "vector,*,*")
13924 (set_attr "amdfam10_decode" "double,*,*")
13925 (set_attr "bdver1_decode" "double,*,*")
13926 (set_attr "mode" "QI,HI,HI")])
13929 [(set (match_operand:HI 0 "general_reg_operand")
13930 (bswap:HI (match_dup 0)))]
13932 && !(TARGET_USE_XCHGB || optimize_function_for_size_p (cfun))
13933 && peep2_regno_dead_p (0, FLAGS_REG)"
13934 [(parallel [(set (match_dup 0) (rotate:HI (match_dup 0) (const_int 8)))
13935 (clobber (reg:CC FLAGS_REG))])])
13937 (define_insn "bswaphi_lowpart"
13938 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
13939 (bswap:HI (match_dup 0)))
13940 (clobber (reg:CC FLAGS_REG))]
13943 xchg{b}\t{%h0, %b0|%b0, %h0}
13944 rol{w}\t{$8, %0|%0, 8}"
13945 [(set (attr "preferred_for_size")
13946 (cond [(eq_attr "alternative" "0")
13947 (symbol_ref "true")]
13948 (symbol_ref "false")))
13949 (set (attr "preferred_for_speed")
13950 (cond [(eq_attr "alternative" "0")
13951 (symbol_ref "TARGET_USE_XCHGB")]
13952 (symbol_ref "!TARGET_USE_XCHGB")))
13953 (set_attr "length" "2,4")
13954 (set_attr "mode" "QI,HI")])
13956 (define_expand "paritydi2"
13957 [(set (match_operand:DI 0 "register_operand")
13958 (parity:DI (match_operand:DI 1 "register_operand")))]
13961 rtx scratch = gen_reg_rtx (QImode);
13963 emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX,
13964 NULL_RTX, operands[1]));
13966 ix86_expand_setcc (scratch, ORDERED,
13967 gen_rtx_REG (CCmode, FLAGS_REG), const0_rtx);
13970 emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
13973 rtx tmp = gen_reg_rtx (SImode);
13975 emit_insn (gen_zero_extendqisi2 (tmp, scratch));
13976 emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
13981 (define_expand "paritysi2"
13982 [(set (match_operand:SI 0 "register_operand")
13983 (parity:SI (match_operand:SI 1 "register_operand")))]
13986 rtx scratch = gen_reg_rtx (QImode);
13988 emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1]));
13990 ix86_expand_setcc (scratch, ORDERED,
13991 gen_rtx_REG (CCmode, FLAGS_REG), const0_rtx);
13993 emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
13997 (define_insn_and_split "paritydi2_cmp"
13998 [(set (reg:CC FLAGS_REG)
13999 (unspec:CC [(match_operand:DI 3 "register_operand" "0")]
14001 (clobber (match_scratch:DI 0 "=r"))
14002 (clobber (match_scratch:SI 1 "=&r"))
14003 (clobber (match_scratch:HI 2 "=Q"))]
14006 "&& reload_completed"
14008 [(set (match_dup 1)
14009 (xor:SI (match_dup 1) (match_dup 4)))
14010 (clobber (reg:CC FLAGS_REG))])
14012 [(set (reg:CC FLAGS_REG)
14013 (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
14014 (clobber (match_dup 1))
14015 (clobber (match_dup 2))])]
14017 operands[4] = gen_lowpart (SImode, operands[3]);
14021 emit_move_insn (operands[1], gen_lowpart (SImode, operands[3]));
14022 emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32)));
14025 operands[1] = gen_highpart (SImode, operands[3]);
14028 (define_insn_and_split "paritysi2_cmp"
14029 [(set (reg:CC FLAGS_REG)
14030 (unspec:CC [(match_operand:SI 2 "register_operand" "0")]
14032 (clobber (match_scratch:SI 0 "=r"))
14033 (clobber (match_scratch:HI 1 "=&Q"))]
14036 "&& reload_completed"
14038 [(set (match_dup 1)
14039 (xor:HI (match_dup 1) (match_dup 3)))
14040 (clobber (reg:CC FLAGS_REG))])
14042 [(set (reg:CC FLAGS_REG)
14043 (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
14044 (clobber (match_dup 1))])]
14046 operands[3] = gen_lowpart (HImode, operands[2]);
14048 emit_move_insn (operands[1], gen_lowpart (HImode, operands[2]));
14049 emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16)));
14052 (define_insn "*parityhi2_cmp"
14053 [(set (reg:CC FLAGS_REG)
14054 (unspec:CC [(match_operand:HI 1 "register_operand" "0")]
14056 (clobber (match_scratch:HI 0 "=Q"))]
14058 "xor{b}\t{%h0, %b0|%b0, %h0}"
14059 [(set_attr "length" "2")
14060 (set_attr "mode" "HI")])
14063 ;; Thread-local storage patterns for ELF.
14065 ;; Note that these code sequences must appear exactly as shown
14066 ;; in order to allow linker relaxation.
14068 (define_insn "*tls_global_dynamic_32_gnu"
14069 [(set (match_operand:SI 0 "register_operand" "=a")
14071 [(match_operand:SI 1 "register_operand" "Yb")
14072 (match_operand 2 "tls_symbolic_operand")
14073 (match_operand 3 "constant_call_address_operand" "Bz")
14076 (clobber (match_scratch:SI 4 "=d"))
14077 (clobber (match_scratch:SI 5 "=c"))
14078 (clobber (reg:CC FLAGS_REG))]
14079 "!TARGET_64BIT && TARGET_GNU_TLS"
14081 if (TARGET_SUN_TLS || flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT)
14083 ("lea{l}\t{%E2@tlsgd(,%1,1), %0|%0, %E2@tlsgd[%1*1]}", operands);
14086 ("lea{l}\t{%E2@tlsgd(%1), %0|%0, %E2@tlsgd[%1]}", operands);
14087 if (TARGET_SUN_TLS)
14088 #ifdef HAVE_AS_IX86_TLSGDPLT
14089 return "call\t%a2@tlsgdplt";
14091 return "call\t%p3@plt";
14093 if (flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT)
14094 return "call\t%P3";
14095 return "call\t{*%p3@GOT(%1)|[DWORD PTR %p3@GOT[%1]]}";
14097 [(set_attr "type" "multi")
14098 (set_attr "length" "12")])
14100 (define_expand "tls_global_dynamic_32"
14102 [(set (match_operand:SI 0 "register_operand")
14103 (unspec:SI [(match_operand:SI 2 "register_operand")
14104 (match_operand 1 "tls_symbolic_operand")
14105 (match_operand 3 "constant_call_address_operand")
14108 (clobber (match_scratch:SI 4))
14109 (clobber (match_scratch:SI 5))
14110 (clobber (reg:CC FLAGS_REG))])]
14112 "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
14114 (define_insn "*tls_global_dynamic_64_<mode>"
14115 [(set (match_operand:P 0 "register_operand" "=a")
14117 (mem:QI (match_operand 2 "constant_call_address_operand" "Bz"))
14118 (match_operand 3)))
14119 (unspec:P [(match_operand 1 "tls_symbolic_operand")
14125 /* The .loc directive has effect for 'the immediately following assembly
14126 instruction'. So for a sequence:
14130 the 'immediately following assembly instruction' is insn1.
14131 We want to emit an insn prefix here, but if we use .byte (as shown in
14132 'ELF Handling For Thread-Local Storage'), a preceding .loc will point
14133 inside the insn sequence, rather than to the start. After relaxation
14134 of the sequence by the linker, the .loc might point inside an insn.
14135 Use data16 prefix instead, which doesn't have this problem. */
14136 fputs ("\tdata16", asm_out_file);
14138 ("lea{q}\t{%E1@tlsgd(%%rip), %%rdi|rdi, %E1@tlsgd[rip]}", operands);
14139 if (TARGET_SUN_TLS || flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT)
14140 fputs (ASM_SHORT "0x6666\n", asm_out_file);
14142 fputs (ASM_BYTE "0x66\n", asm_out_file);
14143 fputs ("\trex64\n", asm_out_file);
14144 if (TARGET_SUN_TLS)
14145 return "call\t%p2@plt";
14146 if (flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT)
14147 return "call\t%P2";
14148 return "call\t{*%p2@GOTPCREL(%%rip)|[QWORD PTR %p2@GOTPCREL[rip]]}";
14150 [(set_attr "type" "multi")
14151 (set (attr "length")
14152 (symbol_ref "TARGET_X32 ? 15 : 16"))])
14154 (define_insn "*tls_global_dynamic_64_largepic"
14155 [(set (match_operand:DI 0 "register_operand" "=a")
14157 (mem:QI (plus:DI (match_operand:DI 2 "register_operand" "b")
14158 (match_operand:DI 3 "immediate_operand" "i")))
14159 (match_operand 4)))
14160 (unspec:DI [(match_operand 1 "tls_symbolic_operand")
14163 "TARGET_64BIT && ix86_cmodel == CM_LARGE_PIC && !TARGET_PECOFF
14164 && GET_CODE (operands[3]) == CONST
14165 && GET_CODE (XEXP (operands[3], 0)) == UNSPEC
14166 && XINT (XEXP (operands[3], 0), 1) == UNSPEC_PLTOFF"
14169 ("lea{q}\t{%E1@tlsgd(%%rip), %%rdi|rdi, %E1@tlsgd[rip]}", operands);
14170 output_asm_insn ("movabs{q}\t{%3, %%rax|rax, %3}", operands);
14171 output_asm_insn ("add{q}\t{%2, %%rax|rax, %2}", operands);
14172 return "call\t{*%%rax|rax}";
14174 [(set_attr "type" "multi")
14175 (set_attr "length" "22")])
14177 (define_expand "@tls_global_dynamic_64_<mode>"
14179 [(set (match_operand:P 0 "register_operand")
14181 (mem:QI (match_operand 2))
14183 (unspec:P [(match_operand 1 "tls_symbolic_operand")
14187 "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
14189 (define_insn "*tls_local_dynamic_base_32_gnu"
14190 [(set (match_operand:SI 0 "register_operand" "=a")
14192 [(match_operand:SI 1 "register_operand" "Yb")
14193 (match_operand 2 "constant_call_address_operand" "Bz")
14195 UNSPEC_TLS_LD_BASE))
14196 (clobber (match_scratch:SI 3 "=d"))
14197 (clobber (match_scratch:SI 4 "=c"))
14198 (clobber (reg:CC FLAGS_REG))]
14199 "!TARGET_64BIT && TARGET_GNU_TLS"
14202 ("lea{l}\t{%&@tlsldm(%1), %0|%0, %&@tlsldm[%1]}", operands);
14203 if (TARGET_SUN_TLS)
14205 if (HAVE_AS_IX86_TLSLDMPLT)
14206 return "call\t%&@tlsldmplt";
14208 return "call\t%p2@plt";
14210 if (flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT)
14211 return "call\t%P2";
14212 return "call\t{*%p2@GOT(%1)|[DWORD PTR %p2@GOT[%1]]}";
14214 [(set_attr "type" "multi")
14215 (set_attr "length" "11")])
14217 (define_expand "tls_local_dynamic_base_32"
14219 [(set (match_operand:SI 0 "register_operand")
14221 [(match_operand:SI 1 "register_operand")
14222 (match_operand 2 "constant_call_address_operand")
14224 UNSPEC_TLS_LD_BASE))
14225 (clobber (match_scratch:SI 3))
14226 (clobber (match_scratch:SI 4))
14227 (clobber (reg:CC FLAGS_REG))])]
14229 "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
14231 (define_insn "*tls_local_dynamic_base_64_<mode>"
14232 [(set (match_operand:P 0 "register_operand" "=a")
14234 (mem:QI (match_operand 1 "constant_call_address_operand" "Bz"))
14235 (match_operand 2)))
14236 (unspec:P [(reg:P SP_REG)] UNSPEC_TLS_LD_BASE)]
14240 ("lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}", operands);
14241 if (TARGET_SUN_TLS)
14242 return "call\t%p1@plt";
14243 if (flag_plt || !HAVE_AS_IX86_TLS_GET_ADDR_GOT)
14244 return "call\t%P1";
14245 return "call\t{*%p1@GOTPCREL(%%rip)|[QWORD PTR %p1@GOTPCREL[rip]]}";
14247 [(set_attr "type" "multi")
14248 (set_attr "length" "12")])
14250 (define_insn "*tls_local_dynamic_base_64_largepic"
14251 [(set (match_operand:DI 0 "register_operand" "=a")
14253 (mem:QI (plus:DI (match_operand:DI 1 "register_operand" "b")
14254 (match_operand:DI 2 "immediate_operand" "i")))
14255 (match_operand 3)))
14256 (unspec:DI [(reg:DI SP_REG)] UNSPEC_TLS_LD_BASE)]
14257 "TARGET_64BIT && ix86_cmodel == CM_LARGE_PIC && !TARGET_PECOFF
14258 && GET_CODE (operands[2]) == CONST
14259 && GET_CODE (XEXP (operands[2], 0)) == UNSPEC
14260 && XINT (XEXP (operands[2], 0), 1) == UNSPEC_PLTOFF"
14263 ("lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}", operands);
14264 output_asm_insn ("movabs{q}\t{%2, %%rax|rax, %2}", operands);
14265 output_asm_insn ("add{q}\t{%1, %%rax|rax, %1}", operands);
14266 return "call\t{*%%rax|rax}";
14268 [(set_attr "type" "multi")
14269 (set_attr "length" "22")])
14271 (define_expand "@tls_local_dynamic_base_64_<mode>"
14273 [(set (match_operand:P 0 "register_operand")
14275 (mem:QI (match_operand 1))
14277 (unspec:P [(reg:P SP_REG)] UNSPEC_TLS_LD_BASE)])]
14279 "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
14281 ;; Local dynamic of a single variable is a lose. Show combine how
14282 ;; to convert that back to global dynamic.
14284 (define_insn_and_split "*tls_local_dynamic_32_once"
14285 [(set (match_operand:SI 0 "register_operand" "=a")
14287 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14288 (match_operand 2 "constant_call_address_operand" "Bz")
14290 UNSPEC_TLS_LD_BASE)
14291 (const:SI (unspec:SI
14292 [(match_operand 3 "tls_symbolic_operand")]
14294 (clobber (match_scratch:SI 4 "=d"))
14295 (clobber (match_scratch:SI 5 "=c"))
14296 (clobber (reg:CC FLAGS_REG))]
14301 [(set (match_dup 0)
14302 (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)
14305 (clobber (match_dup 4))
14306 (clobber (match_dup 5))
14307 (clobber (reg:CC FLAGS_REG))])])
14309 ;; Load and add the thread base pointer from %<tp_seg>:0.
14310 (define_insn_and_split "*load_tp_<mode>"
14311 [(set (match_operand:PTR 0 "register_operand" "=r")
14312 (unspec:PTR [(const_int 0)] UNSPEC_TP))]
14316 [(set (match_dup 0)
14319 addr_space_t as = DEFAULT_TLS_SEG_REG;
14321 operands[1] = gen_const_mem (<MODE>mode, const0_rtx);
14322 set_mem_addr_space (operands[1], as);
14325 (define_insn_and_split "*load_tp_x32_zext"
14326 [(set (match_operand:DI 0 "register_operand" "=r")
14328 (unspec:SI [(const_int 0)] UNSPEC_TP)))]
14332 [(set (match_dup 0)
14333 (zero_extend:DI (match_dup 1)))]
14335 addr_space_t as = DEFAULT_TLS_SEG_REG;
14337 operands[1] = gen_const_mem (SImode, const0_rtx);
14338 set_mem_addr_space (operands[1], as);
14341 (define_insn_and_split "*add_tp_<mode>"
14342 [(set (match_operand:PTR 0 "register_operand" "=r")
14344 (unspec:PTR [(const_int 0)] UNSPEC_TP)
14345 (match_operand:PTR 1 "register_operand" "0")))
14346 (clobber (reg:CC FLAGS_REG))]
14351 [(set (match_dup 0)
14352 (plus:PTR (match_dup 1) (match_dup 2)))
14353 (clobber (reg:CC FLAGS_REG))])]
14355 addr_space_t as = DEFAULT_TLS_SEG_REG;
14357 operands[2] = gen_const_mem (<MODE>mode, const0_rtx);
14358 set_mem_addr_space (operands[2], as);
14361 (define_insn_and_split "*add_tp_x32_zext"
14362 [(set (match_operand:DI 0 "register_operand" "=r")
14364 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
14365 (match_operand:SI 1 "register_operand" "0"))))
14366 (clobber (reg:CC FLAGS_REG))]
14371 [(set (match_dup 0)
14373 (plus:SI (match_dup 1) (match_dup 2))))
14374 (clobber (reg:CC FLAGS_REG))])]
14376 addr_space_t as = DEFAULT_TLS_SEG_REG;
14378 operands[2] = gen_const_mem (SImode, const0_rtx);
14379 set_mem_addr_space (operands[2], as);
14382 ;; The Sun linker took the AMD64 TLS spec literally and can only handle
14383 ;; %rax as destination of the initial executable code sequence.
14384 (define_insn "tls_initial_exec_64_sun"
14385 [(set (match_operand:DI 0 "register_operand" "=a")
14387 [(match_operand 1 "tls_symbolic_operand")]
14388 UNSPEC_TLS_IE_SUN))
14389 (clobber (reg:CC FLAGS_REG))]
14390 "TARGET_64BIT && TARGET_SUN_TLS"
14393 ("mov{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}", operands);
14394 return "add{q}\t{%a1@gottpoff(%%rip), %0|%0, %a1@gottpoff[rip]}";
14396 [(set_attr "type" "multi")])
14398 ;; GNU2 TLS patterns can be split.
14400 (define_expand "tls_dynamic_gnu2_32"
14401 [(set (match_dup 3)
14402 (plus:SI (match_operand:SI 2 "register_operand")
14404 (unspec:SI [(match_operand 1 "tls_symbolic_operand")]
14407 [(set (match_operand:SI 0 "register_operand")
14408 (unspec:SI [(match_dup 1) (match_dup 3)
14409 (match_dup 2) (reg:SI SP_REG)]
14411 (clobber (reg:CC FLAGS_REG))])]
14412 "!TARGET_64BIT && TARGET_GNU2_TLS"
14414 operands[3] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
14415 ix86_tls_descriptor_calls_expanded_in_cfun = true;
14418 (define_insn "*tls_dynamic_gnu2_lea_32"
14419 [(set (match_operand:SI 0 "register_operand" "=r")
14420 (plus:SI (match_operand:SI 1 "register_operand" "b")
14422 (unspec:SI [(match_operand 2 "tls_symbolic_operand")]
14423 UNSPEC_TLSDESC))))]
14424 "!TARGET_64BIT && TARGET_GNU2_TLS"
14425 "lea{l}\t{%E2@TLSDESC(%1), %0|%0, %E2@TLSDESC[%1]}"
14426 [(set_attr "type" "lea")
14427 (set_attr "mode" "SI")
14428 (set_attr "length" "6")
14429 (set_attr "length_address" "4")])
14431 (define_insn "*tls_dynamic_gnu2_call_32"
14432 [(set (match_operand:SI 0 "register_operand" "=a")
14433 (unspec:SI [(match_operand 1 "tls_symbolic_operand")
14434 (match_operand:SI 2 "register_operand" "0")
14435 ;; we have to make sure %ebx still points to the GOT
14436 (match_operand:SI 3 "register_operand" "b")
14439 (clobber (reg:CC FLAGS_REG))]
14440 "!TARGET_64BIT && TARGET_GNU2_TLS"
14441 "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
14442 [(set_attr "type" "call")
14443 (set_attr "length" "2")
14444 (set_attr "length_address" "0")])
14446 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
14447 [(set (match_operand:SI 0 "register_operand" "=&a")
14449 (unspec:SI [(match_operand 3 "tls_modbase_operand")
14450 (match_operand:SI 4)
14451 (match_operand:SI 2 "register_operand" "b")
14454 (const:SI (unspec:SI
14455 [(match_operand 1 "tls_symbolic_operand")]
14457 (clobber (reg:CC FLAGS_REG))]
14458 "!TARGET_64BIT && TARGET_GNU2_TLS"
14461 [(set (match_dup 0) (match_dup 5))]
14463 operands[5] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
14464 emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
14467 (define_expand "tls_dynamic_gnu2_64"
14468 [(set (match_dup 2)
14469 (unspec:DI [(match_operand 1 "tls_symbolic_operand")]
14472 [(set (match_operand:DI 0 "register_operand")
14473 (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
14475 (clobber (reg:CC FLAGS_REG))])]
14476 "TARGET_64BIT && TARGET_GNU2_TLS"
14478 operands[2] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
14479 ix86_tls_descriptor_calls_expanded_in_cfun = true;
14482 (define_insn "*tls_dynamic_gnu2_lea_64"
14483 [(set (match_operand:DI 0 "register_operand" "=r")
14484 (unspec:DI [(match_operand 1 "tls_symbolic_operand")]
14486 "TARGET_64BIT && TARGET_GNU2_TLS"
14487 "lea{q}\t{%E1@TLSDESC(%%rip), %0|%0, %E1@TLSDESC[rip]}"
14488 [(set_attr "type" "lea")
14489 (set_attr "mode" "DI")
14490 (set_attr "length" "7")
14491 (set_attr "length_address" "4")])
14493 (define_insn "*tls_dynamic_gnu2_call_64"
14494 [(set (match_operand:DI 0 "register_operand" "=a")
14495 (unspec:DI [(match_operand 1 "tls_symbolic_operand")
14496 (match_operand:DI 2 "register_operand" "0")
14499 (clobber (reg:CC FLAGS_REG))]
14500 "TARGET_64BIT && TARGET_GNU2_TLS"
14501 "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
14502 [(set_attr "type" "call")
14503 (set_attr "length" "2")
14504 (set_attr "length_address" "0")])
14506 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
14507 [(set (match_operand:DI 0 "register_operand" "=&a")
14509 (unspec:DI [(match_operand 2 "tls_modbase_operand")
14510 (match_operand:DI 3)
14513 (const:DI (unspec:DI
14514 [(match_operand 1 "tls_symbolic_operand")]
14516 (clobber (reg:CC FLAGS_REG))]
14517 "TARGET_64BIT && TARGET_GNU2_TLS"
14520 [(set (match_dup 0) (match_dup 4))]
14522 operands[4] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
14523 emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
14527 [(match_operand 0 "tls_address_pattern")]
14528 "TARGET_TLS_DIRECT_SEG_REFS"
14530 "operands[0] = ix86_rewrite_tls_address (operands[0]);")
14533 ;; These patterns match the binary 387 instructions for addM3, subM3,
14534 ;; mulM3 and divM3. There are three patterns for each of DFmode and
14535 ;; SFmode. The first is the normal insn, the second the same insn but
14536 ;; with one operand a conversion, and the third the same insn but with
14537 ;; the other operand a conversion. The conversion may be SFmode or
14538 ;; SImode if the target mode DFmode, but only SImode if the target mode
14541 ;; Gcc is slightly more smart about handling normal two address instructions
14542 ;; so use special patterns for add and mull.
14544 (define_insn "*fop_xf_comm_i387"
14545 [(set (match_operand:XF 0 "register_operand" "=f")
14546 (match_operator:XF 3 "binary_fp_operator"
14547 [(match_operand:XF 1 "register_operand" "%0")
14548 (match_operand:XF 2 "register_operand" "f")]))]
14550 && COMMUTATIVE_ARITH_P (operands[3])"
14551 "* return output_387_binary_op (insn, operands);"
14552 [(set (attr "type")
14553 (if_then_else (match_operand:XF 3 "mult_operator")
14554 (const_string "fmul")
14555 (const_string "fop")))
14556 (set_attr "mode" "XF")])
14558 (define_insn "*fop_<mode>_comm"
14559 [(set (match_operand:MODEF 0 "register_operand" "=f,x,v")
14560 (match_operator:MODEF 3 "binary_fp_operator"
14561 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,0,v")
14562 (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm,vm")]))]
14563 "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14564 || (TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)))
14565 && COMMUTATIVE_ARITH_P (operands[3])
14566 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
14567 "* return output_387_binary_op (insn, operands);"
14568 [(set (attr "type")
14569 (if_then_else (eq_attr "alternative" "1,2")
14570 (if_then_else (match_operand:MODEF 3 "mult_operator")
14571 (const_string "ssemul")
14572 (const_string "sseadd"))
14573 (if_then_else (match_operand:MODEF 3 "mult_operator")
14574 (const_string "fmul")
14575 (const_string "fop"))))
14576 (set_attr "isa" "*,noavx,avx")
14577 (set_attr "prefix" "orig,orig,vex")
14578 (set_attr "mode" "<MODE>")
14579 (set (attr "enabled")
14581 (match_test ("SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"))
14583 (eq_attr "alternative" "0")
14584 (symbol_ref "TARGET_MIX_SSE_I387
14585 && X87_ENABLE_ARITH (<MODE>mode)")
14586 (const_string "*"))
14588 (eq_attr "alternative" "0")
14589 (symbol_ref "true")
14590 (symbol_ref "false"))))])
14592 (define_insn "*rcpsf2_sse"
14593 [(set (match_operand:SF 0 "register_operand" "=x,x,x")
14594 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "0,x,m")]
14596 "TARGET_SSE && TARGET_SSE_MATH"
14598 %vrcpss\t{%d1, %0|%0, %d1}
14599 %vrcpss\t{%d1, %0|%0, %d1}
14600 %vrcpss\t{%1, %d0|%d0, %1}"
14601 [(set_attr "type" "sse")
14602 (set_attr "atom_sse_attr" "rcp")
14603 (set_attr "btver2_sse_attr" "rcp")
14604 (set_attr "prefix" "maybe_vex")
14605 (set_attr "mode" "SF")
14606 (set (attr "preferred_for_speed")
14607 (cond [(eq_attr "alternative" "1")
14608 (symbol_ref "TARGET_AVX || !TARGET_SSE_PARTIAL_REG_DEPENDENCY")
14609 (eq_attr "alternative" "2")
14610 (symbol_ref "!TARGET_SSE_PARTIAL_REG_DEPENDENCY")
14612 (symbol_ref "true")))])
14614 (define_insn "*fop_xf_1_i387"
14615 [(set (match_operand:XF 0 "register_operand" "=f,f")
14616 (match_operator:XF 3 "binary_fp_operator"
14617 [(match_operand:XF 1 "register_operand" "0,f")
14618 (match_operand:XF 2 "register_operand" "f,0")]))]
14620 && !COMMUTATIVE_ARITH_P (operands[3])"
14621 "* return output_387_binary_op (insn, operands);"
14622 [(set (attr "type")
14623 (if_then_else (match_operand:XF 3 "div_operator")
14624 (const_string "fdiv")
14625 (const_string "fop")))
14626 (set_attr "mode" "XF")])
14628 (define_insn "*fop_<mode>_1"
14629 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,v")
14630 (match_operator:MODEF 3 "binary_fp_operator"
14631 [(match_operand:MODEF 1
14632 "x87nonimm_ssenomem_operand" "0,fm,0,v")
14633 (match_operand:MODEF 2
14634 "nonimmediate_operand" "fm,0,xm,vm")]))]
14635 "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14636 || (TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)))
14637 && !COMMUTATIVE_ARITH_P (operands[3])
14638 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
14639 "* return output_387_binary_op (insn, operands);"
14640 [(set (attr "type")
14641 (if_then_else (eq_attr "alternative" "2,3")
14642 (if_then_else (match_operand:MODEF 3 "div_operator")
14643 (const_string "ssediv")
14644 (const_string "sseadd"))
14645 (if_then_else (match_operand:MODEF 3 "div_operator")
14646 (const_string "fdiv")
14647 (const_string "fop"))))
14648 (set_attr "isa" "*,*,noavx,avx")
14649 (set_attr "prefix" "orig,orig,orig,vex")
14650 (set_attr "mode" "<MODE>")
14651 (set (attr "enabled")
14653 (match_test ("SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"))
14655 (eq_attr "alternative" "0,1")
14656 (symbol_ref "TARGET_MIX_SSE_I387
14657 && X87_ENABLE_ARITH (<MODE>mode)")
14658 (const_string "*"))
14660 (eq_attr "alternative" "0,1")
14661 (symbol_ref "true")
14662 (symbol_ref "false"))))])
14664 (define_insn "*fop_<X87MODEF:mode>_2_i387"
14665 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
14666 (match_operator:X87MODEF 3 "binary_fp_operator"
14668 (match_operand:SWI24 1 "nonimmediate_operand" "m"))
14669 (match_operand:X87MODEF 2 "register_operand" "0")]))]
14670 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI24:MODE>mode)
14671 && !(SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
14672 && (TARGET_USE_<SWI24:MODE>MODE_FIOP
14673 || optimize_function_for_size_p (cfun))"
14674 "* return output_387_binary_op (insn, operands);"
14675 [(set (attr "type")
14676 (cond [(match_operand:X87MODEF 3 "mult_operator")
14677 (const_string "fmul")
14678 (match_operand:X87MODEF 3 "div_operator")
14679 (const_string "fdiv")
14681 (const_string "fop")))
14682 (set_attr "fp_int_src" "true")
14683 (set_attr "mode" "<SWI24:MODE>")])
14685 (define_insn "*fop_<X87MODEF:mode>_3_i387"
14686 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
14687 (match_operator:X87MODEF 3 "binary_fp_operator"
14688 [(match_operand:X87MODEF 1 "register_operand" "0")
14690 (match_operand:SWI24 2 "nonimmediate_operand" "m"))]))]
14691 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI24:MODE>mode)
14692 && !(SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
14693 && (TARGET_USE_<SWI24:MODE>MODE_FIOP
14694 || optimize_function_for_size_p (cfun))"
14695 "* return output_387_binary_op (insn, operands);"
14696 [(set (attr "type")
14697 (cond [(match_operand:X87MODEF 3 "mult_operator")
14698 (const_string "fmul")
14699 (match_operand:X87MODEF 3 "div_operator")
14700 (const_string "fdiv")
14702 (const_string "fop")))
14703 (set_attr "fp_int_src" "true")
14704 (set_attr "mode" "<MODE>")])
14706 (define_insn "*fop_xf_4_i387"
14707 [(set (match_operand:XF 0 "register_operand" "=f,f")
14708 (match_operator:XF 3 "binary_fp_operator"
14710 (match_operand:MODEF 1 "nonimmediate_operand" "fm,0"))
14711 (match_operand:XF 2 "register_operand" "0,f")]))]
14713 "* return output_387_binary_op (insn, operands);"
14714 [(set (attr "type")
14715 (cond [(match_operand:XF 3 "mult_operator")
14716 (const_string "fmul")
14717 (match_operand:XF 3 "div_operator")
14718 (const_string "fdiv")
14720 (const_string "fop")))
14721 (set_attr "mode" "<MODE>")])
14723 (define_insn "*fop_df_4_i387"
14724 [(set (match_operand:DF 0 "register_operand" "=f,f")
14725 (match_operator:DF 3 "binary_fp_operator"
14727 (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
14728 (match_operand:DF 2 "register_operand" "0,f")]))]
14729 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
14730 && !(SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
14731 "* return output_387_binary_op (insn, operands);"
14732 [(set (attr "type")
14733 (cond [(match_operand:DF 3 "mult_operator")
14734 (const_string "fmul")
14735 (match_operand:DF 3 "div_operator")
14736 (const_string "fdiv")
14738 (const_string "fop")))
14739 (set_attr "mode" "SF")])
14741 (define_insn "*fop_xf_5_i387"
14742 [(set (match_operand:XF 0 "register_operand" "=f,f")
14743 (match_operator:XF 3 "binary_fp_operator"
14744 [(match_operand:XF 1 "register_operand" "0,f")
14746 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
14748 "* return output_387_binary_op (insn, operands);"
14749 [(set (attr "type")
14750 (cond [(match_operand:XF 3 "mult_operator")
14751 (const_string "fmul")
14752 (match_operand:XF 3 "div_operator")
14753 (const_string "fdiv")
14755 (const_string "fop")))
14756 (set_attr "mode" "<MODE>")])
14758 (define_insn "*fop_df_5_i387"
14759 [(set (match_operand:DF 0 "register_operand" "=f,f")
14760 (match_operator:DF 3 "binary_fp_operator"
14761 [(match_operand:DF 1 "register_operand" "0,f")
14763 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
14764 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
14765 && !(SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
14766 "* return output_387_binary_op (insn, operands);"
14767 [(set (attr "type")
14768 (cond [(match_operand:DF 3 "mult_operator")
14769 (const_string "fmul")
14770 (match_operand:DF 3 "div_operator")
14771 (const_string "fdiv")
14773 (const_string "fop")))
14774 (set_attr "mode" "SF")])
14776 (define_insn "*fop_xf_6_i387"
14777 [(set (match_operand:XF 0 "register_operand" "=f,f")
14778 (match_operator:XF 3 "binary_fp_operator"
14780 (match_operand:MODEF 1 "register_operand" "0,f"))
14782 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
14784 "* return output_387_binary_op (insn, operands);"
14785 [(set (attr "type")
14786 (cond [(match_operand:XF 3 "mult_operator")
14787 (const_string "fmul")
14788 (match_operand:XF 3 "div_operator")
14789 (const_string "fdiv")
14791 (const_string "fop")))
14792 (set_attr "mode" "<MODE>")])
14794 (define_insn "*fop_df_6_i387"
14795 [(set (match_operand:DF 0 "register_operand" "=f,f")
14796 (match_operator:DF 3 "binary_fp_operator"
14798 (match_operand:SF 1 "register_operand" "0,f"))
14800 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
14801 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
14802 && !(SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
14803 "* return output_387_binary_op (insn, operands);"
14804 [(set (attr "type")
14805 (cond [(match_operand:DF 3 "mult_operator")
14806 (const_string "fmul")
14807 (match_operand:DF 3 "div_operator")
14808 (const_string "fdiv")
14810 (const_string "fop")))
14811 (set_attr "mode" "SF")])
14813 ;; FPU special functions.
14815 ;; This pattern implements a no-op XFmode truncation for
14816 ;; all fancy i386 XFmode math functions.
14818 (define_insn "truncxf<mode>2_i387_noop_unspec"
14819 [(set (match_operand:MODEF 0 "nonimmediate_operand" "=mf")
14820 (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")]
14821 UNSPEC_TRUNC_NOOP))]
14822 "TARGET_USE_FANCY_MATH_387"
14823 "* return output_387_reg_move (insn, operands);"
14824 [(set_attr "type" "fmov")
14825 (set_attr "mode" "<MODE>")])
14827 (define_insn "sqrtxf2"
14828 [(set (match_operand:XF 0 "register_operand" "=f")
14829 (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
14830 "TARGET_USE_FANCY_MATH_387"
14832 [(set_attr "type" "fpspc")
14833 (set_attr "mode" "XF")
14834 (set_attr "athlon_decode" "direct")
14835 (set_attr "amdfam10_decode" "direct")
14836 (set_attr "bdver1_decode" "direct")])
14838 (define_insn "*rsqrtsf2_sse"
14839 [(set (match_operand:SF 0 "register_operand" "=x,x,x")
14840 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "0,x,m")]
14842 "TARGET_SSE && TARGET_SSE_MATH"
14844 %vrsqrtss\t{%d1, %0|%0, %d1}
14845 %vrsqrtss\t{%d1, %0|%0, %d1}
14846 %vrsqrtss\t{%1, %d0|%d0, %1}"
14847 [(set_attr "type" "sse")
14848 (set_attr "atom_sse_attr" "rcp")
14849 (set_attr "btver2_sse_attr" "rcp")
14850 (set_attr "prefix" "maybe_vex")
14851 (set_attr "mode" "SF")
14852 (set (attr "preferred_for_speed")
14853 (cond [(eq_attr "alternative" "1")
14854 (symbol_ref "TARGET_AVX || !TARGET_SSE_PARTIAL_REG_DEPENDENCY")
14855 (eq_attr "alternative" "2")
14856 (symbol_ref "!TARGET_SSE_PARTIAL_REG_DEPENDENCY")
14858 (symbol_ref "true")))])
14860 (define_expand "rsqrtsf2"
14861 [(set (match_operand:SF 0 "register_operand")
14862 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand")]
14864 "TARGET_SSE && TARGET_SSE_MATH"
14866 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
14870 (define_insn "*sqrt<mode>2_sse"
14871 [(set (match_operand:MODEF 0 "register_operand" "=v,v,v")
14873 (match_operand:MODEF 1 "nonimmediate_operand" "0,v,m")))]
14874 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
14876 %vsqrt<ssemodesuffix>\t{%d1, %0|%0, %d1}
14877 %vsqrt<ssemodesuffix>\t{%d1, %0|%0, %d1}
14878 %vsqrt<ssemodesuffix>\t{%1, %d0|%d0, %1}"
14879 [(set_attr "type" "sse")
14880 (set_attr "atom_sse_attr" "sqrt")
14881 (set_attr "btver2_sse_attr" "sqrt")
14882 (set_attr "prefix" "maybe_vex")
14883 (set_attr "mode" "<MODE>")
14884 (set (attr "preferred_for_speed")
14885 (cond [(eq_attr "alternative" "1")
14886 (symbol_ref "TARGET_AVX || !TARGET_SSE_PARTIAL_REG_DEPENDENCY")
14887 (eq_attr "alternative" "2")
14888 (symbol_ref "!TARGET_SSE_PARTIAL_REG_DEPENDENCY")
14890 (symbol_ref "true")))])
14892 (define_expand "sqrt<mode>2"
14893 [(set (match_operand:MODEF 0 "register_operand")
14895 (match_operand:MODEF 1 "nonimmediate_operand")))]
14896 "(TARGET_USE_FANCY_MATH_387 && X87_ENABLE_ARITH (<MODE>mode))
14897 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
14899 if (<MODE>mode == SFmode
14900 && TARGET_SSE && TARGET_SSE_MATH
14901 && TARGET_RECIP_SQRT
14902 && !optimize_function_for_size_p (cfun)
14903 && flag_finite_math_only && !flag_trapping_math
14904 && flag_unsafe_math_optimizations)
14906 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
14910 if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
14912 rtx op0 = gen_reg_rtx (XFmode);
14913 rtx op1 = gen_reg_rtx (XFmode);
14915 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14916 emit_insn (gen_sqrtxf2 (op0, op1));
14917 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
14922 (define_expand "hypot<mode>3"
14923 [(use (match_operand:MODEF 0 "register_operand"))
14924 (use (match_operand:MODEF 1 "general_operand"))
14925 (use (match_operand:MODEF 2 "general_operand"))]
14926 "TARGET_USE_FANCY_MATH_387
14927 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14928 || TARGET_MIX_SSE_I387)
14929 && flag_finite_math_only
14930 && flag_unsafe_math_optimizations"
14932 rtx op0 = gen_reg_rtx (XFmode);
14933 rtx op1 = gen_reg_rtx (XFmode);
14934 rtx op2 = gen_reg_rtx (XFmode);
14936 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
14937 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14939 emit_insn (gen_mulxf3 (op1, op1, op1));
14940 emit_insn (gen_mulxf3 (op2, op2, op2));
14941 emit_insn (gen_addxf3 (op0, op2, op1));
14942 emit_insn (gen_sqrtxf2 (op0, op0));
14944 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
14948 (define_insn "x86_fnstsw_1"
14949 [(set (match_operand:HI 0 "register_operand" "=a")
14950 (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
14953 [(set_attr "length" "2")
14954 (set_attr "mode" "SI")
14955 (set_attr "unit" "i387")])
14957 (define_insn "fpremxf4_i387"
14958 [(set (match_operand:XF 0 "register_operand" "=f")
14959 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
14960 (match_operand:XF 3 "register_operand" "1")]
14962 (set (match_operand:XF 1 "register_operand" "=f")
14963 (unspec:XF [(match_dup 2) (match_dup 3)]
14965 (set (reg:CCFP FPSR_REG)
14966 (unspec:CCFP [(match_dup 2) (match_dup 3)]
14968 "TARGET_USE_FANCY_MATH_387
14969 && flag_finite_math_only"
14971 [(set_attr "type" "fpspc")
14972 (set_attr "znver1_decode" "vector")
14973 (set_attr "mode" "XF")])
14975 (define_expand "fmodxf3"
14976 [(use (match_operand:XF 0 "register_operand"))
14977 (use (match_operand:XF 1 "general_operand"))
14978 (use (match_operand:XF 2 "general_operand"))]
14979 "TARGET_USE_FANCY_MATH_387
14980 && flag_finite_math_only"
14982 rtx_code_label *label = gen_label_rtx ();
14984 rtx op1 = gen_reg_rtx (XFmode);
14985 rtx op2 = gen_reg_rtx (XFmode);
14987 emit_move_insn (op2, operands[2]);
14988 emit_move_insn (op1, operands[1]);
14990 emit_label (label);
14991 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
14992 ix86_emit_fp_unordered_jump (label);
14993 LABEL_NUSES (label) = 1;
14995 emit_move_insn (operands[0], op1);
14999 (define_expand "fmod<mode>3"
15000 [(use (match_operand:MODEF 0 "register_operand"))
15001 (use (match_operand:MODEF 1 "general_operand"))
15002 (use (match_operand:MODEF 2 "general_operand"))]
15003 "TARGET_USE_FANCY_MATH_387
15004 && flag_finite_math_only"
15006 rtx (*gen_truncxf) (rtx, rtx);
15008 rtx_code_label *label = gen_label_rtx ();
15010 rtx op1 = gen_reg_rtx (XFmode);
15011 rtx op2 = gen_reg_rtx (XFmode);
15013 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
15014 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15016 emit_label (label);
15017 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
15018 ix86_emit_fp_unordered_jump (label);
15019 LABEL_NUSES (label) = 1;
15021 /* Truncate the result properly for strict SSE math. */
15022 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15023 && !TARGET_MIX_SSE_I387)
15024 gen_truncxf = gen_truncxf<mode>2;
15026 gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
15028 emit_insn (gen_truncxf (operands[0], op1));
15032 (define_insn "fprem1xf4_i387"
15033 [(set (match_operand:XF 0 "register_operand" "=f")
15034 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15035 (match_operand:XF 3 "register_operand" "1")]
15037 (set (match_operand:XF 1 "register_operand" "=f")
15038 (unspec:XF [(match_dup 2) (match_dup 3)]
15040 (set (reg:CCFP FPSR_REG)
15041 (unspec:CCFP [(match_dup 2) (match_dup 3)]
15043 "TARGET_USE_FANCY_MATH_387
15044 && flag_finite_math_only"
15046 [(set_attr "type" "fpspc")
15047 (set_attr "znver1_decode" "vector")
15048 (set_attr "mode" "XF")])
15050 (define_expand "remainderxf3"
15051 [(use (match_operand:XF 0 "register_operand"))
15052 (use (match_operand:XF 1 "general_operand"))
15053 (use (match_operand:XF 2 "general_operand"))]
15054 "TARGET_USE_FANCY_MATH_387
15055 && flag_finite_math_only"
15057 rtx_code_label *label = gen_label_rtx ();
15059 rtx op1 = gen_reg_rtx (XFmode);
15060 rtx op2 = gen_reg_rtx (XFmode);
15062 emit_move_insn (op2, operands[2]);
15063 emit_move_insn (op1, operands[1]);
15065 emit_label (label);
15066 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
15067 ix86_emit_fp_unordered_jump (label);
15068 LABEL_NUSES (label) = 1;
15070 emit_move_insn (operands[0], op1);
15074 (define_expand "remainder<mode>3"
15075 [(use (match_operand:MODEF 0 "register_operand"))
15076 (use (match_operand:MODEF 1 "general_operand"))
15077 (use (match_operand:MODEF 2 "general_operand"))]
15078 "TARGET_USE_FANCY_MATH_387
15079 && flag_finite_math_only"
15081 rtx (*gen_truncxf) (rtx, rtx);
15083 rtx_code_label *label = gen_label_rtx ();
15085 rtx op1 = gen_reg_rtx (XFmode);
15086 rtx op2 = gen_reg_rtx (XFmode);
15088 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
15089 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15091 emit_label (label);
15093 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
15094 ix86_emit_fp_unordered_jump (label);
15095 LABEL_NUSES (label) = 1;
15097 /* Truncate the result properly for strict SSE math. */
15098 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15099 && !TARGET_MIX_SSE_I387)
15100 gen_truncxf = gen_truncxf<mode>2;
15102 gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
15104 emit_insn (gen_truncxf (operands[0], op1));
15108 (define_int_iterator SINCOS
15112 (define_int_attr sincos
15113 [(UNSPEC_SIN "sin")
15114 (UNSPEC_COS "cos")])
15116 (define_insn "<sincos>xf2"
15117 [(set (match_operand:XF 0 "register_operand" "=f")
15118 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15120 "TARGET_USE_FANCY_MATH_387
15121 && flag_unsafe_math_optimizations"
15123 [(set_attr "type" "fpspc")
15124 (set_attr "znver1_decode" "vector")
15125 (set_attr "mode" "XF")])
15127 (define_expand "<sincos><mode>2"
15128 [(set (match_operand:MODEF 0 "register_operand")
15129 (unspec:MODEF [(match_operand:MODEF 1 "general_operand")]
15131 "TARGET_USE_FANCY_MATH_387
15132 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15133 || TARGET_MIX_SSE_I387)
15134 && flag_unsafe_math_optimizations"
15136 rtx op0 = gen_reg_rtx (XFmode);
15137 rtx op1 = gen_reg_rtx (XFmode);
15139 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15140 emit_insn (gen_<sincos>xf2 (op0, op1));
15141 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
15145 (define_insn "sincosxf3"
15146 [(set (match_operand:XF 0 "register_operand" "=f")
15147 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15148 UNSPEC_SINCOS_COS))
15149 (set (match_operand:XF 1 "register_operand" "=f")
15150 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15151 "TARGET_USE_FANCY_MATH_387
15152 && flag_unsafe_math_optimizations"
15154 [(set_attr "type" "fpspc")
15155 (set_attr "znver1_decode" "vector")
15156 (set_attr "mode" "XF")])
15158 (define_expand "sincos<mode>3"
15159 [(use (match_operand:MODEF 0 "register_operand"))
15160 (use (match_operand:MODEF 1 "register_operand"))
15161 (use (match_operand:MODEF 2 "general_operand"))]
15162 "TARGET_USE_FANCY_MATH_387
15163 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15164 || TARGET_MIX_SSE_I387)
15165 && flag_unsafe_math_optimizations"
15167 rtx op0 = gen_reg_rtx (XFmode);
15168 rtx op1 = gen_reg_rtx (XFmode);
15169 rtx op2 = gen_reg_rtx (XFmode);
15171 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
15172 emit_insn (gen_sincosxf3 (op0, op1, op2));
15173 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
15174 emit_insn (gen_truncxf<mode>2 (operands[1], op1));
15178 (define_insn "fptanxf4_i387"
15179 [(set (match_operand:SF 0 "register_operand" "=f")
15180 (match_operand:SF 3 "const1_operand"))
15181 (set (match_operand:XF 1 "register_operand" "=f")
15182 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15184 "TARGET_USE_FANCY_MATH_387
15185 && flag_unsafe_math_optimizations"
15187 [(set_attr "type" "fpspc")
15188 (set_attr "znver1_decode" "vector")
15189 (set_attr "mode" "XF")])
15191 (define_expand "tanxf2"
15192 [(use (match_operand:XF 0 "register_operand"))
15193 (use (match_operand:XF 1 "register_operand"))]
15194 "TARGET_USE_FANCY_MATH_387
15195 && flag_unsafe_math_optimizations"
15197 rtx one = gen_reg_rtx (SFmode);
15198 emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1],
15199 CONST1_RTX (SFmode)));
15203 (define_expand "tan<mode>2"
15204 [(use (match_operand:MODEF 0 "register_operand"))
15205 (use (match_operand:MODEF 1 "general_operand"))]
15206 "TARGET_USE_FANCY_MATH_387
15207 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15208 || TARGET_MIX_SSE_I387)
15209 && flag_unsafe_math_optimizations"
15211 rtx op0 = gen_reg_rtx (XFmode);
15212 rtx op1 = gen_reg_rtx (XFmode);
15214 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15215 emit_insn (gen_tanxf2 (op0, op1));
15216 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
15220 (define_insn "atan2xf3"
15221 [(set (match_operand:XF 0 "register_operand" "=f")
15222 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
15223 (match_operand:XF 2 "register_operand" "f")]
15225 (clobber (match_scratch:XF 3 "=2"))]
15226 "TARGET_USE_FANCY_MATH_387
15227 && flag_unsafe_math_optimizations"
15229 [(set_attr "type" "fpspc")
15230 (set_attr "znver1_decode" "vector")
15231 (set_attr "mode" "XF")])
15233 (define_expand "atan2<mode>3"
15234 [(use (match_operand:MODEF 0 "register_operand"))
15235 (use (match_operand:MODEF 1 "general_operand"))
15236 (use (match_operand:MODEF 2 "general_operand"))]
15237 "TARGET_USE_FANCY_MATH_387
15238 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15239 || TARGET_MIX_SSE_I387)
15240 && flag_unsafe_math_optimizations"
15242 rtx op0 = gen_reg_rtx (XFmode);
15243 rtx op1 = gen_reg_rtx (XFmode);
15244 rtx op2 = gen_reg_rtx (XFmode);
15246 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
15247 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15249 emit_insn (gen_atan2xf3 (op0, op2, op1));
15250 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
15254 (define_expand "atanxf2"
15255 [(parallel [(set (match_operand:XF 0 "register_operand")
15256 (unspec:XF [(match_dup 2)
15257 (match_operand:XF 1 "register_operand")]
15259 (clobber (match_scratch:XF 3))])]
15260 "TARGET_USE_FANCY_MATH_387
15261 && flag_unsafe_math_optimizations"
15262 "operands[2] = force_reg (XFmode, CONST1_RTX (XFmode));")
15264 (define_expand "atan<mode>2"
15265 [(use (match_operand:MODEF 0 "register_operand"))
15266 (use (match_operand:MODEF 1 "general_operand"))]
15267 "TARGET_USE_FANCY_MATH_387
15268 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15269 || TARGET_MIX_SSE_I387)
15270 && flag_unsafe_math_optimizations"
15272 rtx op0 = gen_reg_rtx (XFmode);
15273 rtx op1 = gen_reg_rtx (XFmode);
15275 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15276 emit_insn (gen_atanxf2 (op0, op1));
15277 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
15281 (define_expand "asinxf2"
15282 [(set (match_dup 2)
15283 (mult:XF (match_operand:XF 1 "register_operand")
15285 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
15286 (set (match_dup 5) (sqrt:XF (match_dup 4)))
15287 (parallel [(set (match_operand:XF 0 "register_operand")
15288 (unspec:XF [(match_dup 5) (match_dup 1)]
15290 (clobber (match_scratch:XF 6))])]
15291 "TARGET_USE_FANCY_MATH_387
15292 && flag_unsafe_math_optimizations"
15296 for (i = 2; i < 6; i++)
15297 operands[i] = gen_reg_rtx (XFmode);
15299 emit_move_insn (operands[3], CONST1_RTX (XFmode));
15302 (define_expand "asin<mode>2"
15303 [(use (match_operand:MODEF 0 "register_operand"))
15304 (use (match_operand:MODEF 1 "general_operand"))]
15305 "TARGET_USE_FANCY_MATH_387
15306 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15307 || TARGET_MIX_SSE_I387)
15308 && flag_unsafe_math_optimizations"
15310 rtx op0 = gen_reg_rtx (XFmode);
15311 rtx op1 = gen_reg_rtx (XFmode);
15313 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15314 emit_insn (gen_asinxf2 (op0, op1));
15315 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
15319 (define_expand "acosxf2"
15320 [(set (match_dup 2)
15321 (mult:XF (match_operand:XF 1 "register_operand")
15323 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
15324 (set (match_dup 5) (sqrt:XF (match_dup 4)))
15325 (parallel [(set (match_operand:XF 0 "register_operand")
15326 (unspec:XF [(match_dup 1) (match_dup 5)]
15328 (clobber (match_scratch:XF 6))])]
15329 "TARGET_USE_FANCY_MATH_387
15330 && flag_unsafe_math_optimizations"
15334 for (i = 2; i < 6; i++)
15335 operands[i] = gen_reg_rtx (XFmode);
15337 emit_move_insn (operands[3], CONST1_RTX (XFmode));
15340 (define_expand "acos<mode>2"
15341 [(use (match_operand:MODEF 0 "register_operand"))
15342 (use (match_operand:MODEF 1 "general_operand"))]
15343 "TARGET_USE_FANCY_MATH_387
15344 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15345 || TARGET_MIX_SSE_I387)
15346 && flag_unsafe_math_optimizations"
15348 rtx op0 = gen_reg_rtx (XFmode);
15349 rtx op1 = gen_reg_rtx (XFmode);
15351 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15352 emit_insn (gen_acosxf2 (op0, op1));
15353 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
15357 (define_expand "sinhxf2"
15358 [(use (match_operand:XF 0 "register_operand"))
15359 (use (match_operand:XF 1 "register_operand"))]
15360 "TARGET_USE_FANCY_MATH_387
15361 && flag_finite_math_only
15362 && flag_unsafe_math_optimizations"
15364 ix86_emit_i387_sinh (operands[0], operands[1]);
15368 (define_expand "sinh<mode>2"
15369 [(use (match_operand:MODEF 0 "register_operand"))
15370 (use (match_operand:MODEF 1 "general_operand"))]
15371 "TARGET_USE_FANCY_MATH_387
15372 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15373 || TARGET_MIX_SSE_I387)
15374 && flag_finite_math_only
15375 && flag_unsafe_math_optimizations"
15377 rtx op0 = gen_reg_rtx (XFmode);
15378 rtx op1 = gen_reg_rtx (XFmode);
15380 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15381 emit_insn (gen_sinhxf2 (op0, op1));
15382 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
15386 (define_expand "coshxf2"
15387 [(use (match_operand:XF 0 "register_operand"))
15388 (use (match_operand:XF 1 "register_operand"))]
15389 "TARGET_USE_FANCY_MATH_387
15390 && flag_unsafe_math_optimizations"
15392 ix86_emit_i387_cosh (operands[0], operands[1]);
15396 (define_expand "cosh<mode>2"
15397 [(use (match_operand:MODEF 0 "register_operand"))
15398 (use (match_operand:MODEF 1 "general_operand"))]
15399 "TARGET_USE_FANCY_MATH_387
15400 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15401 || TARGET_MIX_SSE_I387)
15402 && flag_unsafe_math_optimizations"
15404 rtx op0 = gen_reg_rtx (XFmode);
15405 rtx op1 = gen_reg_rtx (XFmode);
15407 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15408 emit_insn (gen_coshxf2 (op0, op1));
15409 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
15413 (define_expand "tanhxf2"
15414 [(use (match_operand:XF 0 "register_operand"))
15415 (use (match_operand:XF 1 "register_operand"))]
15416 "TARGET_USE_FANCY_MATH_387
15417 && flag_unsafe_math_optimizations"
15419 ix86_emit_i387_tanh (operands[0], operands[1]);
15423 (define_expand "tanh<mode>2"
15424 [(use (match_operand:MODEF 0 "register_operand"))
15425 (use (match_operand:MODEF 1 "general_operand"))]
15426 "TARGET_USE_FANCY_MATH_387
15427 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15428 || TARGET_MIX_SSE_I387)
15429 && flag_unsafe_math_optimizations"
15431 rtx op0 = gen_reg_rtx (XFmode);
15432 rtx op1 = gen_reg_rtx (XFmode);
15434 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15435 emit_insn (gen_tanhxf2 (op0, op1));
15436 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
15440 (define_expand "asinhxf2"
15441 [(use (match_operand:XF 0 "register_operand"))
15442 (use (match_operand:XF 1 "register_operand"))]
15443 "TARGET_USE_FANCY_MATH_387
15444 && flag_finite_math_only
15445 && flag_unsafe_math_optimizations"
15447 ix86_emit_i387_asinh (operands[0], operands[1]);
15451 (define_expand "asinh<mode>2"
15452 [(use (match_operand:MODEF 0 "register_operand"))
15453 (use (match_operand:MODEF 1 "general_operand"))]
15454 "TARGET_USE_FANCY_MATH_387
15455 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15456 || TARGET_MIX_SSE_I387)
15457 && flag_finite_math_only
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_asinhxf2 (op0, op1));
15465 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
15469 (define_expand "acoshxf2"
15470 [(use (match_operand:XF 0 "register_operand"))
15471 (use (match_operand:XF 1 "register_operand"))]
15472 "TARGET_USE_FANCY_MATH_387
15473 && flag_unsafe_math_optimizations"
15475 ix86_emit_i387_acosh (operands[0], operands[1]);
15479 (define_expand "acosh<mode>2"
15480 [(use (match_operand:MODEF 0 "register_operand"))
15481 (use (match_operand:MODEF 1 "general_operand"))]
15482 "TARGET_USE_FANCY_MATH_387
15483 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15484 || TARGET_MIX_SSE_I387)
15485 && flag_unsafe_math_optimizations"
15487 rtx op0 = gen_reg_rtx (XFmode);
15488 rtx op1 = gen_reg_rtx (XFmode);
15490 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15491 emit_insn (gen_acoshxf2 (op0, op1));
15492 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
15496 (define_expand "atanhxf2"
15497 [(use (match_operand:XF 0 "register_operand"))
15498 (use (match_operand:XF 1 "register_operand"))]
15499 "TARGET_USE_FANCY_MATH_387
15500 && flag_unsafe_math_optimizations"
15502 ix86_emit_i387_atanh (operands[0], operands[1]);
15506 (define_expand "atanh<mode>2"
15507 [(use (match_operand:MODEF 0 "register_operand"))
15508 (use (match_operand:MODEF 1 "general_operand"))]
15509 "TARGET_USE_FANCY_MATH_387
15510 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15511 || TARGET_MIX_SSE_I387)
15512 && flag_unsafe_math_optimizations"
15514 rtx op0 = gen_reg_rtx (XFmode);
15515 rtx op1 = gen_reg_rtx (XFmode);
15517 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15518 emit_insn (gen_atanhxf2 (op0, op1));
15519 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
15523 (define_insn "fyl2xxf3_i387"
15524 [(set (match_operand:XF 0 "register_operand" "=f")
15525 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
15526 (match_operand:XF 2 "register_operand" "f")]
15528 (clobber (match_scratch:XF 3 "=2"))]
15529 "TARGET_USE_FANCY_MATH_387
15530 && flag_unsafe_math_optimizations"
15532 [(set_attr "type" "fpspc")
15533 (set_attr "znver1_decode" "vector")
15534 (set_attr "mode" "XF")])
15536 (define_expand "logxf2"
15537 [(parallel [(set (match_operand:XF 0 "register_operand")
15538 (unspec:XF [(match_operand:XF 1 "register_operand")
15539 (match_dup 2)] UNSPEC_FYL2X))
15540 (clobber (match_scratch:XF 3))])]
15541 "TARGET_USE_FANCY_MATH_387
15542 && flag_unsafe_math_optimizations"
15545 = force_reg (XFmode, standard_80387_constant_rtx (4)); /* fldln2 */
15548 (define_expand "log<mode>2"
15549 [(use (match_operand:MODEF 0 "register_operand"))
15550 (use (match_operand:MODEF 1 "general_operand"))]
15551 "TARGET_USE_FANCY_MATH_387
15552 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15553 || TARGET_MIX_SSE_I387)
15554 && flag_unsafe_math_optimizations"
15556 rtx op0 = gen_reg_rtx (XFmode);
15557 rtx op1 = gen_reg_rtx (XFmode);
15559 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15560 emit_insn (gen_logxf2 (op0, op1));
15561 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
15565 (define_expand "log10xf2"
15566 [(parallel [(set (match_operand:XF 0 "register_operand")
15567 (unspec:XF [(match_operand:XF 1 "register_operand")
15568 (match_dup 2)] UNSPEC_FYL2X))
15569 (clobber (match_scratch:XF 3))])]
15570 "TARGET_USE_FANCY_MATH_387
15571 && flag_unsafe_math_optimizations"
15574 = force_reg (XFmode, standard_80387_constant_rtx (3)); /* fldlg2 */
15577 (define_expand "log10<mode>2"
15578 [(use (match_operand:MODEF 0 "register_operand"))
15579 (use (match_operand:MODEF 1 "general_operand"))]
15580 "TARGET_USE_FANCY_MATH_387
15581 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15582 || TARGET_MIX_SSE_I387)
15583 && flag_unsafe_math_optimizations"
15585 rtx op0 = gen_reg_rtx (XFmode);
15586 rtx op1 = gen_reg_rtx (XFmode);
15588 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15589 emit_insn (gen_log10xf2 (op0, op1));
15590 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
15594 (define_expand "log2xf2"
15595 [(parallel [(set (match_operand:XF 0 "register_operand")
15596 (unspec:XF [(match_operand:XF 1 "register_operand")
15597 (match_dup 2)] UNSPEC_FYL2X))
15598 (clobber (match_scratch:XF 3))])]
15599 "TARGET_USE_FANCY_MATH_387
15600 && flag_unsafe_math_optimizations"
15601 "operands[2] = force_reg (XFmode, CONST1_RTX (XFmode));")
15603 (define_expand "log2<mode>2"
15604 [(use (match_operand:MODEF 0 "register_operand"))
15605 (use (match_operand:MODEF 1 "general_operand"))]
15606 "TARGET_USE_FANCY_MATH_387
15607 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15608 || TARGET_MIX_SSE_I387)
15609 && flag_unsafe_math_optimizations"
15611 rtx op0 = gen_reg_rtx (XFmode);
15612 rtx op1 = gen_reg_rtx (XFmode);
15614 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15615 emit_insn (gen_log2xf2 (op0, op1));
15616 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
15620 (define_insn "fyl2xp1xf3_i387"
15621 [(set (match_operand:XF 0 "register_operand" "=f")
15622 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
15623 (match_operand:XF 2 "register_operand" "f")]
15625 (clobber (match_scratch:XF 3 "=2"))]
15626 "TARGET_USE_FANCY_MATH_387
15627 && flag_unsafe_math_optimizations"
15629 [(set_attr "type" "fpspc")
15630 (set_attr "znver1_decode" "vector")
15631 (set_attr "mode" "XF")])
15633 (define_expand "log1pxf2"
15634 [(use (match_operand:XF 0 "register_operand"))
15635 (use (match_operand:XF 1 "register_operand"))]
15636 "TARGET_USE_FANCY_MATH_387
15637 && flag_unsafe_math_optimizations"
15639 ix86_emit_i387_log1p (operands[0], operands[1]);
15643 (define_expand "log1p<mode>2"
15644 [(use (match_operand:MODEF 0 "register_operand"))
15645 (use (match_operand:MODEF 1 "general_operand"))]
15646 "TARGET_USE_FANCY_MATH_387
15647 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15648 || TARGET_MIX_SSE_I387)
15649 && flag_unsafe_math_optimizations"
15651 rtx op0 = gen_reg_rtx (XFmode);
15652 rtx op1 = gen_reg_rtx (XFmode);
15654 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15655 emit_insn (gen_log1pxf2 (op0, op1));
15656 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
15660 (define_insn "fxtractxf3_i387"
15661 [(set (match_operand:XF 0 "register_operand" "=f")
15662 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15663 UNSPEC_XTRACT_FRACT))
15664 (set (match_operand:XF 1 "register_operand" "=f")
15665 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
15666 "TARGET_USE_FANCY_MATH_387
15667 && flag_unsafe_math_optimizations"
15669 [(set_attr "type" "fpspc")
15670 (set_attr "znver1_decode" "vector")
15671 (set_attr "mode" "XF")])
15673 (define_expand "logbxf2"
15674 [(parallel [(set (match_dup 2)
15675 (unspec:XF [(match_operand:XF 1 "register_operand")]
15676 UNSPEC_XTRACT_FRACT))
15677 (set (match_operand:XF 0 "register_operand")
15678 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
15679 "TARGET_USE_FANCY_MATH_387
15680 && flag_unsafe_math_optimizations"
15681 "operands[2] = gen_reg_rtx (XFmode);")
15683 (define_expand "logb<mode>2"
15684 [(use (match_operand:MODEF 0 "register_operand"))
15685 (use (match_operand:MODEF 1 "general_operand"))]
15686 "TARGET_USE_FANCY_MATH_387
15687 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15688 || TARGET_MIX_SSE_I387)
15689 && flag_unsafe_math_optimizations"
15691 rtx op0 = gen_reg_rtx (XFmode);
15692 rtx op1 = gen_reg_rtx (XFmode);
15694 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15695 emit_insn (gen_logbxf2 (op0, op1));
15696 emit_insn (gen_truncxf<mode>2 (operands[0], op1));
15700 (define_expand "ilogbxf2"
15701 [(use (match_operand:SI 0 "register_operand"))
15702 (use (match_operand:XF 1 "register_operand"))]
15703 "TARGET_USE_FANCY_MATH_387
15704 && flag_unsafe_math_optimizations"
15708 if (optimize_insn_for_size_p ())
15711 op0 = gen_reg_rtx (XFmode);
15712 op1 = gen_reg_rtx (XFmode);
15714 emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
15715 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
15719 (define_expand "ilogb<mode>2"
15720 [(use (match_operand:SI 0 "register_operand"))
15721 (use (match_operand:MODEF 1 "general_operand"))]
15722 "TARGET_USE_FANCY_MATH_387
15723 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15724 || TARGET_MIX_SSE_I387)
15725 && flag_unsafe_math_optimizations"
15729 if (optimize_insn_for_size_p ())
15732 op0 = gen_reg_rtx (XFmode);
15733 op1 = gen_reg_rtx (XFmode);
15734 op2 = gen_reg_rtx (XFmode);
15736 emit_insn (gen_extend<mode>xf2 (op2, operands[1]));
15737 emit_insn (gen_fxtractxf3_i387 (op0, op1, op2));
15738 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
15742 (define_insn "*f2xm1xf2_i387"
15743 [(set (match_operand:XF 0 "register_operand" "=f")
15744 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15746 "TARGET_USE_FANCY_MATH_387
15747 && flag_unsafe_math_optimizations"
15749 [(set_attr "type" "fpspc")
15750 (set_attr "znver1_decode" "vector")
15751 (set_attr "mode" "XF")])
15753 (define_insn "fscalexf4_i387"
15754 [(set (match_operand:XF 0 "register_operand" "=f")
15755 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15756 (match_operand:XF 3 "register_operand" "1")]
15757 UNSPEC_FSCALE_FRACT))
15758 (set (match_operand:XF 1 "register_operand" "=f")
15759 (unspec:XF [(match_dup 2) (match_dup 3)]
15760 UNSPEC_FSCALE_EXP))]
15761 "TARGET_USE_FANCY_MATH_387
15762 && flag_unsafe_math_optimizations"
15764 [(set_attr "type" "fpspc")
15765 (set_attr "znver1_decode" "vector")
15766 (set_attr "mode" "XF")])
15768 (define_expand "expNcorexf3"
15769 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand")
15770 (match_operand:XF 2 "register_operand")))
15771 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
15772 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
15773 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
15774 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
15775 (parallel [(set (match_operand:XF 0 "register_operand")
15776 (unspec:XF [(match_dup 8) (match_dup 4)]
15777 UNSPEC_FSCALE_FRACT))
15779 (unspec:XF [(match_dup 8) (match_dup 4)]
15780 UNSPEC_FSCALE_EXP))])]
15781 "TARGET_USE_FANCY_MATH_387
15782 && flag_unsafe_math_optimizations"
15786 for (i = 3; i < 10; i++)
15787 operands[i] = gen_reg_rtx (XFmode);
15789 emit_move_insn (operands[7], CONST1_RTX (XFmode));
15792 (define_expand "expxf2"
15793 [(use (match_operand:XF 0 "register_operand"))
15794 (use (match_operand:XF 1 "register_operand"))]
15795 "TARGET_USE_FANCY_MATH_387
15796 && flag_unsafe_math_optimizations"
15798 rtx op2 = force_reg (XFmode, standard_80387_constant_rtx (5)); /* fldl2e */
15800 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
15804 (define_expand "exp<mode>2"
15805 [(use (match_operand:MODEF 0 "register_operand"))
15806 (use (match_operand:MODEF 1 "general_operand"))]
15807 "TARGET_USE_FANCY_MATH_387
15808 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15809 || TARGET_MIX_SSE_I387)
15810 && flag_unsafe_math_optimizations"
15812 rtx op0 = gen_reg_rtx (XFmode);
15813 rtx op1 = gen_reg_rtx (XFmode);
15815 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15816 emit_insn (gen_expxf2 (op0, op1));
15817 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
15821 (define_expand "exp10xf2"
15822 [(use (match_operand:XF 0 "register_operand"))
15823 (use (match_operand:XF 1 "register_operand"))]
15824 "TARGET_USE_FANCY_MATH_387
15825 && flag_unsafe_math_optimizations"
15827 rtx op2 = force_reg (XFmode, standard_80387_constant_rtx (6)); /* fldl2t */
15829 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
15833 (define_expand "exp10<mode>2"
15834 [(use (match_operand:MODEF 0 "register_operand"))
15835 (use (match_operand:MODEF 1 "general_operand"))]
15836 "TARGET_USE_FANCY_MATH_387
15837 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15838 || TARGET_MIX_SSE_I387)
15839 && flag_unsafe_math_optimizations"
15841 rtx op0 = gen_reg_rtx (XFmode);
15842 rtx op1 = gen_reg_rtx (XFmode);
15844 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15845 emit_insn (gen_exp10xf2 (op0, op1));
15846 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
15850 (define_expand "exp2xf2"
15851 [(use (match_operand:XF 0 "register_operand"))
15852 (use (match_operand:XF 1 "register_operand"))]
15853 "TARGET_USE_FANCY_MATH_387
15854 && flag_unsafe_math_optimizations"
15856 rtx op2 = force_reg (XFmode, CONST1_RTX (XFmode));
15858 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
15862 (define_expand "exp2<mode>2"
15863 [(use (match_operand:MODEF 0 "register_operand"))
15864 (use (match_operand:MODEF 1 "general_operand"))]
15865 "TARGET_USE_FANCY_MATH_387
15866 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15867 || TARGET_MIX_SSE_I387)
15868 && flag_unsafe_math_optimizations"
15870 rtx op0 = gen_reg_rtx (XFmode);
15871 rtx op1 = gen_reg_rtx (XFmode);
15873 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15874 emit_insn (gen_exp2xf2 (op0, op1));
15875 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
15879 (define_expand "expm1xf2"
15880 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand")
15882 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
15883 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
15884 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
15885 (parallel [(set (match_dup 7)
15886 (unspec:XF [(match_dup 6) (match_dup 4)]
15887 UNSPEC_FSCALE_FRACT))
15889 (unspec:XF [(match_dup 6) (match_dup 4)]
15890 UNSPEC_FSCALE_EXP))])
15891 (parallel [(set (match_dup 10)
15892 (unspec:XF [(match_dup 9) (match_dup 8)]
15893 UNSPEC_FSCALE_FRACT))
15894 (set (match_dup 11)
15895 (unspec:XF [(match_dup 9) (match_dup 8)]
15896 UNSPEC_FSCALE_EXP))])
15897 (set (match_dup 12) (minus:XF (match_dup 10) (match_dup 9)))
15898 (set (match_operand:XF 0 "register_operand")
15899 (plus:XF (match_dup 12) (match_dup 7)))]
15900 "TARGET_USE_FANCY_MATH_387
15901 && flag_unsafe_math_optimizations"
15905 for (i = 2; i < 13; i++)
15906 operands[i] = gen_reg_rtx (XFmode);
15908 emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
15909 emit_move_insn (operands[9], CONST1_RTX (XFmode));
15912 (define_expand "expm1<mode>2"
15913 [(use (match_operand:MODEF 0 "register_operand"))
15914 (use (match_operand:MODEF 1 "general_operand"))]
15915 "TARGET_USE_FANCY_MATH_387
15916 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15917 || TARGET_MIX_SSE_I387)
15918 && flag_unsafe_math_optimizations"
15920 rtx op0 = gen_reg_rtx (XFmode);
15921 rtx op1 = gen_reg_rtx (XFmode);
15923 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15924 emit_insn (gen_expm1xf2 (op0, op1));
15925 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
15929 (define_expand "ldexpxf3"
15930 [(match_operand:XF 0 "register_operand")
15931 (match_operand:XF 1 "register_operand")
15932 (match_operand:SI 2 "register_operand")]
15933 "TARGET_USE_FANCY_MATH_387
15934 && flag_unsafe_math_optimizations"
15936 rtx tmp1 = gen_reg_rtx (XFmode);
15937 rtx tmp2 = gen_reg_rtx (XFmode);
15939 emit_insn (gen_floatsixf2 (tmp1, operands[2]));
15940 emit_insn (gen_fscalexf4_i387 (operands[0], tmp2,
15941 operands[1], tmp1));
15945 (define_expand "ldexp<mode>3"
15946 [(use (match_operand:MODEF 0 "register_operand"))
15947 (use (match_operand:MODEF 1 "general_operand"))
15948 (use (match_operand:SI 2 "register_operand"))]
15949 "TARGET_USE_FANCY_MATH_387
15950 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15951 || TARGET_MIX_SSE_I387)
15952 && flag_unsafe_math_optimizations"
15954 rtx op0 = gen_reg_rtx (XFmode);
15955 rtx op1 = gen_reg_rtx (XFmode);
15957 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15958 emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
15959 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
15963 (define_expand "scalbxf3"
15964 [(parallel [(set (match_operand:XF 0 " register_operand")
15965 (unspec:XF [(match_operand:XF 1 "register_operand")
15966 (match_operand:XF 2 "register_operand")]
15967 UNSPEC_FSCALE_FRACT))
15969 (unspec:XF [(match_dup 1) (match_dup 2)]
15970 UNSPEC_FSCALE_EXP))])]
15971 "TARGET_USE_FANCY_MATH_387
15972 && flag_unsafe_math_optimizations"
15973 "operands[3] = gen_reg_rtx (XFmode);")
15975 (define_expand "scalb<mode>3"
15976 [(use (match_operand:MODEF 0 "register_operand"))
15977 (use (match_operand:MODEF 1 "general_operand"))
15978 (use (match_operand:MODEF 2 "general_operand"))]
15979 "TARGET_USE_FANCY_MATH_387
15980 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15981 || TARGET_MIX_SSE_I387)
15982 && flag_unsafe_math_optimizations"
15984 rtx op0 = gen_reg_rtx (XFmode);
15985 rtx op1 = gen_reg_rtx (XFmode);
15986 rtx op2 = gen_reg_rtx (XFmode);
15988 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15989 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
15990 emit_insn (gen_scalbxf3 (op0, op1, op2));
15991 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
15995 (define_expand "significandxf2"
15996 [(parallel [(set (match_operand:XF 0 "register_operand")
15997 (unspec:XF [(match_operand:XF 1 "register_operand")]
15998 UNSPEC_XTRACT_FRACT))
16000 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
16001 "TARGET_USE_FANCY_MATH_387
16002 && flag_unsafe_math_optimizations"
16003 "operands[2] = gen_reg_rtx (XFmode);")
16005 (define_expand "significand<mode>2"
16006 [(use (match_operand:MODEF 0 "register_operand"))
16007 (use (match_operand:MODEF 1 "general_operand"))]
16008 "TARGET_USE_FANCY_MATH_387
16009 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16010 || TARGET_MIX_SSE_I387)
16011 && flag_unsafe_math_optimizations"
16013 rtx op0 = gen_reg_rtx (XFmode);
16014 rtx op1 = gen_reg_rtx (XFmode);
16016 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16017 emit_insn (gen_significandxf2 (op0, op1));
16018 emit_insn (gen_truncxf<mode>2 (operands[0], op0));
16023 (define_insn "sse4_1_round<mode>2"
16024 [(set (match_operand:MODEF 0 "register_operand" "=x,x,x,v")
16026 [(match_operand:MODEF 1 "nonimmediate_operand" "0,x,m,vm")
16027 (match_operand:SI 2 "const_0_to_15_operand" "n,n,n,n")]
16031 %vround<ssemodesuffix>\t{%2, %d1, %0|%0, %d1, %2}
16032 %vround<ssemodesuffix>\t{%2, %d1, %0|%0, %d1, %2}
16033 %vround<ssemodesuffix>\t{%2, %1, %d0|%d0, %1, %2}
16034 vrndscale<ssemodesuffix>\t{%2, %1, %d0|%d0, %1, %2}"
16035 [(set_attr "type" "ssecvt")
16036 (set_attr "prefix_extra" "1,1,1,*")
16037 (set_attr "length_immediate" "*,*,*,1")
16038 (set_attr "prefix" "maybe_vex,maybe_vex,maybe_vex,evex")
16039 (set_attr "isa" "noavx512f,noavx512f,noavx512f,avx512f")
16040 (set_attr "mode" "<MODE>")
16041 (set (attr "preferred_for_speed")
16042 (cond [(eq_attr "alternative" "1")
16043 (symbol_ref "TARGET_AVX || !TARGET_SSE_PARTIAL_REG_DEPENDENCY")
16044 (eq_attr "alternative" "2")
16045 (symbol_ref "!TARGET_SSE_PARTIAL_REG_DEPENDENCY")
16047 (symbol_ref "true")))])
16049 (define_insn "rintxf2"
16050 [(set (match_operand:XF 0 "register_operand" "=f")
16051 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16053 "TARGET_USE_FANCY_MATH_387"
16055 [(set_attr "type" "fpspc")
16056 (set_attr "znver1_decode" "vector")
16057 (set_attr "mode" "XF")])
16059 (define_expand "rint<mode>2"
16060 [(use (match_operand:MODEF 0 "register_operand"))
16061 (use (match_operand:MODEF 1 "nonimmediate_operand"))]
16062 "TARGET_USE_FANCY_MATH_387
16063 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
16065 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16068 emit_insn (gen_sse4_1_round<mode>2
16069 (operands[0], operands[1], GEN_INT (ROUND_MXCSR)));
16071 ix86_expand_rint (operands[0], operands[1]);
16075 rtx op0 = gen_reg_rtx (XFmode);
16076 rtx op1 = gen_reg_rtx (XFmode);
16078 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16079 emit_insn (gen_rintxf2 (op0, op1));
16080 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
16085 (define_expand "nearbyintxf2"
16086 [(set (match_operand:XF 0 "register_operand")
16087 (unspec:XF [(match_operand:XF 1 "register_operand")]
16089 "TARGET_USE_FANCY_MATH_387
16090 && !flag_trapping_math")
16092 (define_expand "nearbyint<mode>2"
16093 [(use (match_operand:MODEF 0 "register_operand"))
16094 (use (match_operand:MODEF 1 "nonimmediate_operand"))]
16095 "(TARGET_USE_FANCY_MATH_387
16096 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16097 || TARGET_MIX_SSE_I387)
16098 && !flag_trapping_math)
16099 || (TARGET_SSE4_1 && TARGET_SSE_MATH)"
16101 if (TARGET_SSE4_1 && TARGET_SSE_MATH)
16102 emit_insn (gen_sse4_1_round<mode>2
16103 (operands[0], operands[1], GEN_INT (ROUND_MXCSR
16107 rtx op0 = gen_reg_rtx (XFmode);
16108 rtx op1 = gen_reg_rtx (XFmode);
16110 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16111 emit_insn (gen_nearbyintxf2 (op0, op1));
16112 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
16117 (define_expand "round<mode>2"
16118 [(match_operand:X87MODEF 0 "register_operand")
16119 (match_operand:X87MODEF 1 "nonimmediate_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
16124 && (flag_fp_int_builtin_inexact || !flag_trapping_math))
16125 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16126 && !flag_trapping_math && !flag_rounding_math)"
16128 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16129 && !flag_trapping_math && !flag_rounding_math)
16133 operands[1] = force_reg (<MODE>mode, operands[1]);
16134 ix86_expand_round_sse4 (operands[0], operands[1]);
16136 else if (TARGET_64BIT || (<MODE>mode != DFmode))
16137 ix86_expand_round (operands[0], operands[1]);
16139 ix86_expand_rounddf_32 (operands[0], operands[1]);
16143 operands[1] = force_reg (<MODE>mode, operands[1]);
16144 ix86_emit_i387_round (operands[0], operands[1]);
16149 (define_insn "lrintxfdi2"
16150 [(set (match_operand:DI 0 "nonimmediate_operand" "=m")
16151 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
16153 (clobber (match_scratch:XF 2 "=&f"))]
16154 "TARGET_USE_FANCY_MATH_387"
16155 "* return output_fix_trunc (insn, operands, false);"
16156 [(set_attr "type" "fpspc")
16157 (set_attr "mode" "DI")])
16159 (define_insn "lrintxf<mode>2"
16160 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m")
16161 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
16163 "TARGET_USE_FANCY_MATH_387"
16164 "* return output_fix_trunc (insn, operands, false);"
16165 [(set_attr "type" "fpspc")
16166 (set_attr "mode" "<MODE>")])
16168 (define_expand "lrint<MODEF:mode><SWI48:mode>2"
16169 [(set (match_operand:SWI48 0 "nonimmediate_operand")
16170 (unspec:SWI48 [(match_operand:MODEF 1 "register_operand")]
16171 UNSPEC_FIX_NOTRUNC))]
16172 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH")
16174 (define_expand "lround<X87MODEF:mode><SWI248x:mode>2"
16175 [(match_operand:SWI248x 0 "nonimmediate_operand")
16176 (match_operand:X87MODEF 1 "register_operand")]
16177 "(TARGET_USE_FANCY_MATH_387
16178 && (!(SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
16179 || TARGET_MIX_SSE_I387)
16180 && flag_unsafe_math_optimizations)
16181 || (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
16182 && <SWI248x:MODE>mode != HImode
16183 && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT)
16184 && !flag_trapping_math && !flag_rounding_math)"
16186 if (optimize_insn_for_size_p ())
16189 if (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
16190 && <SWI248x:MODE>mode != HImode
16191 && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT)
16192 && !flag_trapping_math && !flag_rounding_math)
16193 ix86_expand_lround (operands[0], operands[1]);
16195 ix86_emit_i387_round (operands[0], operands[1]);
16199 (define_int_iterator FRNDINT_ROUNDING
16200 [UNSPEC_FRNDINT_FLOOR
16201 UNSPEC_FRNDINT_CEIL
16202 UNSPEC_FRNDINT_TRUNC])
16204 (define_int_iterator FIST_ROUNDING
16208 ;; Base name for define_insn
16209 (define_int_attr rounding_insn
16210 [(UNSPEC_FRNDINT_FLOOR "floor")
16211 (UNSPEC_FRNDINT_CEIL "ceil")
16212 (UNSPEC_FRNDINT_TRUNC "btrunc")
16213 (UNSPEC_FIST_FLOOR "floor")
16214 (UNSPEC_FIST_CEIL "ceil")])
16216 (define_int_attr rounding
16217 [(UNSPEC_FRNDINT_FLOOR "floor")
16218 (UNSPEC_FRNDINT_CEIL "ceil")
16219 (UNSPEC_FRNDINT_TRUNC "trunc")
16220 (UNSPEC_FIST_FLOOR "floor")
16221 (UNSPEC_FIST_CEIL "ceil")])
16223 (define_int_attr ROUNDING
16224 [(UNSPEC_FRNDINT_FLOOR "FLOOR")
16225 (UNSPEC_FRNDINT_CEIL "CEIL")
16226 (UNSPEC_FRNDINT_TRUNC "TRUNC")
16227 (UNSPEC_FIST_FLOOR "FLOOR")
16228 (UNSPEC_FIST_CEIL "CEIL")])
16230 ;; Rounding mode control word calculation could clobber FLAGS_REG.
16231 (define_insn_and_split "frndintxf2_<rounding>"
16232 [(set (match_operand:XF 0 "register_operand")
16233 (unspec:XF [(match_operand:XF 1 "register_operand")]
16235 (clobber (reg:CC FLAGS_REG))]
16236 "TARGET_USE_FANCY_MATH_387
16237 && (flag_fp_int_builtin_inexact || !flag_trapping_math)
16238 && can_create_pseudo_p ()"
16243 ix86_optimize_mode_switching[I387_<ROUNDING>] = 1;
16245 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
16246 operands[3] = assign_386_stack_local (HImode, SLOT_CW_<ROUNDING>);
16248 emit_insn (gen_frndintxf2_<rounding>_i387 (operands[0], operands[1],
16249 operands[2], operands[3]));
16252 [(set_attr "type" "frndint")
16253 (set_attr "i387_cw" "<rounding>")
16254 (set_attr "mode" "XF")])
16256 (define_insn "frndintxf2_<rounding>_i387"
16257 [(set (match_operand:XF 0 "register_operand" "=f")
16258 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16260 (use (match_operand:HI 2 "memory_operand" "m"))
16261 (use (match_operand:HI 3 "memory_operand" "m"))]
16262 "TARGET_USE_FANCY_MATH_387
16263 && (flag_fp_int_builtin_inexact || !flag_trapping_math)"
16264 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
16265 [(set_attr "type" "frndint")
16266 (set_attr "i387_cw" "<rounding>")
16267 (set_attr "mode" "XF")])
16269 (define_expand "<rounding_insn>xf2"
16270 [(parallel [(set (match_operand:XF 0 "register_operand")
16271 (unspec:XF [(match_operand:XF 1 "register_operand")]
16273 (clobber (reg:CC FLAGS_REG))])]
16274 "TARGET_USE_FANCY_MATH_387
16275 && (flag_fp_int_builtin_inexact || !flag_trapping_math)")
16277 (define_expand "<rounding_insn><mode>2"
16278 [(parallel [(set (match_operand:MODEF 0 "register_operand")
16279 (unspec:MODEF [(match_operand:MODEF 1 "register_operand")]
16281 (clobber (reg:CC FLAGS_REG))])]
16282 "(TARGET_USE_FANCY_MATH_387
16283 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16284 || TARGET_MIX_SSE_I387)
16285 && (flag_fp_int_builtin_inexact || !flag_trapping_math))
16286 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16287 && (TARGET_SSE4_1 || flag_fp_int_builtin_inexact
16288 || !flag_trapping_math))"
16290 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16291 && (TARGET_SSE4_1 || flag_fp_int_builtin_inexact || !flag_trapping_math))
16294 emit_insn (gen_sse4_1_round<mode>2
16295 (operands[0], operands[1], GEN_INT (ROUND_<ROUNDING>
16297 else if (TARGET_64BIT || (<MODE>mode != DFmode))
16299 if (ROUND_<ROUNDING> == ROUND_FLOOR)
16300 ix86_expand_floorceil (operands[0], operands[1], true);
16301 else if (ROUND_<ROUNDING> == ROUND_CEIL)
16302 ix86_expand_floorceil (operands[0], operands[1], false);
16303 else if (ROUND_<ROUNDING> == ROUND_TRUNC)
16304 ix86_expand_trunc (operands[0], operands[1]);
16306 gcc_unreachable ();
16310 if (ROUND_<ROUNDING> == ROUND_FLOOR)
16311 ix86_expand_floorceildf_32 (operands[0], operands[1], true);
16312 else if (ROUND_<ROUNDING> == ROUND_CEIL)
16313 ix86_expand_floorceildf_32 (operands[0], operands[1], false);
16314 else if (ROUND_<ROUNDING> == ROUND_TRUNC)
16315 ix86_expand_truncdf_32 (operands[0], operands[1]);
16317 gcc_unreachable ();
16322 rtx op0 = gen_reg_rtx (XFmode);
16323 rtx op1 = gen_reg_rtx (XFmode);
16325 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16326 emit_insn (gen_frndintxf2_<rounding> (op0, op1));
16327 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
16332 ;; Rounding mode control word calculation could clobber FLAGS_REG.
16333 (define_insn_and_split "*fist<mode>2_<rounding>_1"
16334 [(set (match_operand:SWI248x 0 "nonimmediate_operand")
16335 (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
16337 (clobber (reg:CC FLAGS_REG))]
16338 "TARGET_USE_FANCY_MATH_387
16339 && flag_unsafe_math_optimizations
16340 && can_create_pseudo_p ()"
16345 ix86_optimize_mode_switching[I387_<ROUNDING>] = 1;
16347 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
16348 operands[3] = assign_386_stack_local (HImode, SLOT_CW_<ROUNDING>);
16350 emit_insn (gen_fist<mode>2_<rounding> (operands[0], operands[1],
16351 operands[2], operands[3]));
16354 [(set_attr "type" "fistp")
16355 (set_attr "i387_cw" "<rounding>")
16356 (set_attr "mode" "<MODE>")])
16358 (define_insn "fistdi2_<rounding>"
16359 [(set (match_operand:DI 0 "nonimmediate_operand" "=m")
16360 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
16362 (use (match_operand:HI 2 "memory_operand" "m"))
16363 (use (match_operand:HI 3 "memory_operand" "m"))
16364 (clobber (match_scratch:XF 4 "=&f"))]
16365 "TARGET_USE_FANCY_MATH_387
16366 && flag_unsafe_math_optimizations"
16367 "* return output_fix_trunc (insn, operands, false);"
16368 [(set_attr "type" "fistp")
16369 (set_attr "i387_cw" "<rounding>")
16370 (set_attr "mode" "DI")])
16372 (define_insn "fist<mode>2_<rounding>"
16373 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m")
16374 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
16376 (use (match_operand:HI 2 "memory_operand" "m"))
16377 (use (match_operand:HI 3 "memory_operand" "m"))]
16378 "TARGET_USE_FANCY_MATH_387
16379 && flag_unsafe_math_optimizations"
16380 "* return output_fix_trunc (insn, operands, false);"
16381 [(set_attr "type" "fistp")
16382 (set_attr "i387_cw" "<rounding>")
16383 (set_attr "mode" "<MODE>")])
16385 (define_expand "l<rounding_insn>xf<mode>2"
16386 [(parallel [(set (match_operand:SWI248x 0 "nonimmediate_operand")
16387 (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
16389 (clobber (reg:CC FLAGS_REG))])]
16390 "TARGET_USE_FANCY_MATH_387
16391 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16392 && flag_unsafe_math_optimizations")
16394 (define_expand "l<rounding_insn><MODEF:mode><SWI48:mode>2"
16395 [(parallel [(set (match_operand:SWI48 0 "nonimmediate_operand")
16396 (unspec:SWI48 [(match_operand:MODEF 1 "register_operand")]
16398 (clobber (reg:CC FLAGS_REG))])]
16399 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
16400 && (TARGET_SSE4_1 || !flag_trapping_math)"
16404 rtx tmp = gen_reg_rtx (<MODEF:MODE>mode);
16406 emit_insn (gen_sse4_1_round<mode>2
16407 (tmp, operands[1], GEN_INT (ROUND_<ROUNDING>
16409 emit_insn (gen_fix_trunc<MODEF:mode><SWI48:mode>2
16410 (operands[0], tmp));
16412 else if (ROUND_<ROUNDING> == ROUND_FLOOR)
16413 ix86_expand_lfloorceil (operands[0], operands[1], true);
16414 else if (ROUND_<ROUNDING> == ROUND_CEIL)
16415 ix86_expand_lfloorceil (operands[0], operands[1], false);
16417 gcc_unreachable ();
16422 (define_insn "fxam<mode>2_i387"
16423 [(set (match_operand:HI 0 "register_operand" "=a")
16425 [(match_operand:X87MODEF 1 "register_operand" "f")]
16427 "TARGET_USE_FANCY_MATH_387"
16428 "fxam\n\tfnstsw\t%0"
16429 [(set_attr "type" "multi")
16430 (set_attr "length" "4")
16431 (set_attr "unit" "i387")
16432 (set_attr "mode" "<MODE>")])
16434 (define_expand "signbittf2"
16435 [(use (match_operand:SI 0 "register_operand"))
16436 (use (match_operand:TF 1 "register_operand"))]
16441 rtx mask = ix86_build_signbit_mask (TFmode, 0, 0);
16442 rtx scratch = gen_reg_rtx (QImode);
16444 emit_insn (gen_ptesttf2 (operands[1], mask));
16445 ix86_expand_setcc (scratch, NE,
16446 gen_rtx_REG (CCZmode, FLAGS_REG), const0_rtx);
16448 emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
16452 emit_insn (gen_sse_movmskps (operands[0],
16453 gen_lowpart (V4SFmode, operands[1])));
16454 emit_insn (gen_andsi3 (operands[0], operands[0], GEN_INT (0x8)));
16459 (define_expand "signbitxf2"
16460 [(use (match_operand:SI 0 "register_operand"))
16461 (use (match_operand:XF 1 "register_operand"))]
16462 "TARGET_USE_FANCY_MATH_387"
16464 rtx scratch = gen_reg_rtx (HImode);
16466 emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
16467 emit_insn (gen_andsi3 (operands[0],
16468 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
16472 (define_insn "movmsk_df"
16473 [(set (match_operand:SI 0 "register_operand" "=r")
16475 [(match_operand:DF 1 "register_operand" "x")]
16477 "SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH"
16478 "%vmovmskpd\t{%1, %0|%0, %1}"
16479 [(set_attr "type" "ssemov")
16480 (set_attr "prefix" "maybe_vex")
16481 (set_attr "mode" "DF")])
16483 ;; Use movmskpd in SSE mode to avoid store forwarding stall
16484 ;; for 32bit targets and movq+shrq sequence for 64bit targets.
16485 (define_expand "signbitdf2"
16486 [(use (match_operand:SI 0 "register_operand"))
16487 (use (match_operand:DF 1 "register_operand"))]
16488 "TARGET_USE_FANCY_MATH_387
16489 || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
16491 if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)
16493 emit_insn (gen_movmsk_df (operands[0], operands[1]));
16494 emit_insn (gen_andsi3 (operands[0], operands[0], const1_rtx));
16498 rtx scratch = gen_reg_rtx (HImode);
16500 emit_insn (gen_fxamdf2_i387 (scratch, operands[1]));
16501 emit_insn (gen_andsi3 (operands[0],
16502 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
16507 (define_expand "signbitsf2"
16508 [(use (match_operand:SI 0 "register_operand"))
16509 (use (match_operand:SF 1 "register_operand"))]
16510 "TARGET_USE_FANCY_MATH_387
16511 && !(SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH)"
16513 rtx scratch = gen_reg_rtx (HImode);
16515 emit_insn (gen_fxamsf2_i387 (scratch, operands[1]));
16516 emit_insn (gen_andsi3 (operands[0],
16517 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
16521 ;; Block operation instructions
16524 [(unspec_volatile [(const_int 0)] UNSPECV_CLD)]
16527 [(set_attr "length" "1")
16528 (set_attr "length_immediate" "0")
16529 (set_attr "modrm" "0")])
16531 (define_expand "movmem<mode>"
16532 [(use (match_operand:BLK 0 "memory_operand"))
16533 (use (match_operand:BLK 1 "memory_operand"))
16534 (use (match_operand:SWI48 2 "nonmemory_operand"))
16535 (use (match_operand:SWI48 3 "const_int_operand"))
16536 (use (match_operand:SI 4 "const_int_operand"))
16537 (use (match_operand:SI 5 "const_int_operand"))
16538 (use (match_operand:SI 6 ""))
16539 (use (match_operand:SI 7 ""))
16540 (use (match_operand:SI 8 ""))]
16543 if (ix86_expand_set_or_movmem (operands[0], operands[1],
16544 operands[2], NULL, operands[3],
16545 operands[4], operands[5],
16546 operands[6], operands[7],
16547 operands[8], false))
16553 ;; Most CPUs don't like single string operations
16554 ;; Handle this case here to simplify previous expander.
16556 (define_expand "strmov"
16557 [(set (match_dup 4) (match_operand 3 "memory_operand"))
16558 (set (match_operand 1 "memory_operand") (match_dup 4))
16559 (parallel [(set (match_operand 0 "register_operand") (match_dup 5))
16560 (clobber (reg:CC FLAGS_REG))])
16561 (parallel [(set (match_operand 2 "register_operand") (match_dup 6))
16562 (clobber (reg:CC FLAGS_REG))])]
16565 /* Can't use this for non-default address spaces. */
16566 if (!ADDR_SPACE_GENERIC_P (MEM_ADDR_SPACE (operands[3])))
16569 rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
16571 /* If .md ever supports :P for Pmode, these can be directly
16572 in the pattern above. */
16573 operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
16574 operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
16576 /* Can't use this if the user has appropriated esi or edi. */
16577 if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
16578 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG]))
16580 emit_insn (gen_strmov_singleop (operands[0], operands[1],
16581 operands[2], operands[3],
16582 operands[5], operands[6]));
16586 operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
16589 (define_expand "strmov_singleop"
16590 [(parallel [(set (match_operand 1 "memory_operand")
16591 (match_operand 3 "memory_operand"))
16592 (set (match_operand 0 "register_operand")
16594 (set (match_operand 2 "register_operand")
16595 (match_operand 5))])]
16599 ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
16602 (define_insn "*strmovdi_rex_1"
16603 [(set (mem:DI (match_operand:P 2 "register_operand" "0"))
16604 (mem:DI (match_operand:P 3 "register_operand" "1")))
16605 (set (match_operand:P 0 "register_operand" "=D")
16606 (plus:P (match_dup 2)
16608 (set (match_operand:P 1 "register_operand" "=S")
16609 (plus:P (match_dup 3)
16612 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG])
16613 && ix86_check_no_addr_space (insn)"
16615 [(set_attr "type" "str")
16616 (set_attr "memory" "both")
16617 (set_attr "mode" "DI")])
16619 (define_insn "*strmovsi_1"
16620 [(set (mem:SI (match_operand:P 2 "register_operand" "0"))
16621 (mem:SI (match_operand:P 3 "register_operand" "1")))
16622 (set (match_operand:P 0 "register_operand" "=D")
16623 (plus:P (match_dup 2)
16625 (set (match_operand:P 1 "register_operand" "=S")
16626 (plus:P (match_dup 3)
16628 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])
16629 && ix86_check_no_addr_space (insn)"
16631 [(set_attr "type" "str")
16632 (set_attr "memory" "both")
16633 (set_attr "mode" "SI")])
16635 (define_insn "*strmovhi_1"
16636 [(set (mem:HI (match_operand:P 2 "register_operand" "0"))
16637 (mem:HI (match_operand:P 3 "register_operand" "1")))
16638 (set (match_operand:P 0 "register_operand" "=D")
16639 (plus:P (match_dup 2)
16641 (set (match_operand:P 1 "register_operand" "=S")
16642 (plus:P (match_dup 3)
16644 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])
16645 && ix86_check_no_addr_space (insn)"
16647 [(set_attr "type" "str")
16648 (set_attr "memory" "both")
16649 (set_attr "mode" "HI")])
16651 (define_insn "*strmovqi_1"
16652 [(set (mem:QI (match_operand:P 2 "register_operand" "0"))
16653 (mem:QI (match_operand:P 3 "register_operand" "1")))
16654 (set (match_operand:P 0 "register_operand" "=D")
16655 (plus:P (match_dup 2)
16657 (set (match_operand:P 1 "register_operand" "=S")
16658 (plus:P (match_dup 3)
16660 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])
16661 && ix86_check_no_addr_space (insn)"
16663 [(set_attr "type" "str")
16664 (set_attr "memory" "both")
16665 (set (attr "prefix_rex")
16667 (match_test "<P:MODE>mode == DImode")
16669 (const_string "*")))
16670 (set_attr "mode" "QI")])
16672 (define_expand "rep_mov"
16673 [(parallel [(set (match_operand 4 "register_operand") (const_int 0))
16674 (set (match_operand 0 "register_operand")
16676 (set (match_operand 2 "register_operand")
16678 (set (match_operand 1 "memory_operand")
16679 (match_operand 3 "memory_operand"))
16680 (use (match_dup 4))])]
16684 ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
16687 (define_insn "*rep_movdi_rex64"
16688 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
16689 (set (match_operand:P 0 "register_operand" "=D")
16690 (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
16692 (match_operand:P 3 "register_operand" "0")))
16693 (set (match_operand:P 1 "register_operand" "=S")
16694 (plus:P (ashift:P (match_dup 5) (const_int 3))
16695 (match_operand:P 4 "register_operand" "1")))
16696 (set (mem:BLK (match_dup 3))
16697 (mem:BLK (match_dup 4)))
16698 (use (match_dup 5))]
16700 && !(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
16701 && ix86_check_no_addr_space (insn)"
16703 [(set_attr "type" "str")
16704 (set_attr "prefix_rep" "1")
16705 (set_attr "memory" "both")
16706 (set_attr "mode" "DI")])
16708 (define_insn "*rep_movsi"
16709 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
16710 (set (match_operand:P 0 "register_operand" "=D")
16711 (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
16713 (match_operand:P 3 "register_operand" "0")))
16714 (set (match_operand:P 1 "register_operand" "=S")
16715 (plus:P (ashift:P (match_dup 5) (const_int 2))
16716 (match_operand:P 4 "register_operand" "1")))
16717 (set (mem:BLK (match_dup 3))
16718 (mem:BLK (match_dup 4)))
16719 (use (match_dup 5))]
16720 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
16721 && ix86_check_no_addr_space (insn)"
16722 "%^rep{%;} movs{l|d}"
16723 [(set_attr "type" "str")
16724 (set_attr "prefix_rep" "1")
16725 (set_attr "memory" "both")
16726 (set_attr "mode" "SI")])
16728 (define_insn "*rep_movqi"
16729 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
16730 (set (match_operand:P 0 "register_operand" "=D")
16731 (plus:P (match_operand:P 3 "register_operand" "0")
16732 (match_operand:P 5 "register_operand" "2")))
16733 (set (match_operand:P 1 "register_operand" "=S")
16734 (plus:P (match_operand:P 4 "register_operand" "1") (match_dup 5)))
16735 (set (mem:BLK (match_dup 3))
16736 (mem:BLK (match_dup 4)))
16737 (use (match_dup 5))]
16738 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
16739 && ix86_check_no_addr_space (insn)"
16741 [(set_attr "type" "str")
16742 (set_attr "prefix_rep" "1")
16743 (set_attr "memory" "both")
16744 (set_attr "mode" "QI")])
16746 (define_expand "setmem<mode>"
16747 [(use (match_operand:BLK 0 "memory_operand"))
16748 (use (match_operand:SWI48 1 "nonmemory_operand"))
16749 (use (match_operand:QI 2 "nonmemory_operand"))
16750 (use (match_operand 3 "const_int_operand"))
16751 (use (match_operand:SI 4 "const_int_operand"))
16752 (use (match_operand:SI 5 "const_int_operand"))
16753 (use (match_operand:SI 6 ""))
16754 (use (match_operand:SI 7 ""))
16755 (use (match_operand:SI 8 ""))]
16758 if (ix86_expand_set_or_movmem (operands[0], NULL,
16759 operands[1], operands[2],
16760 operands[3], operands[4],
16761 operands[5], operands[6],
16762 operands[7], operands[8], true))
16768 ;; Most CPUs don't like single string operations
16769 ;; Handle this case here to simplify previous expander.
16771 (define_expand "strset"
16772 [(set (match_operand 1 "memory_operand")
16773 (match_operand 2 "register_operand"))
16774 (parallel [(set (match_operand 0 "register_operand")
16776 (clobber (reg:CC FLAGS_REG))])]
16779 /* Can't use this for non-default address spaces. */
16780 if (!ADDR_SPACE_GENERIC_P (MEM_ADDR_SPACE (operands[1])))
16783 if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
16784 operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
16786 /* If .md ever supports :P for Pmode, this can be directly
16787 in the pattern above. */
16788 operands[3] = gen_rtx_PLUS (Pmode, operands[0],
16789 GEN_INT (GET_MODE_SIZE (GET_MODE
16791 /* Can't use this if the user has appropriated eax or edi. */
16792 if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
16793 && !(fixed_regs[AX_REG] || fixed_regs[DI_REG]))
16795 emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
16801 (define_expand "strset_singleop"
16802 [(parallel [(set (match_operand 1 "memory_operand")
16803 (match_operand 2 "register_operand"))
16804 (set (match_operand 0 "register_operand")
16806 (unspec [(const_int 0)] UNSPEC_STOS)])]
16810 ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
16813 (define_insn "*strsetdi_rex_1"
16814 [(set (mem:DI (match_operand:P 1 "register_operand" "0"))
16815 (match_operand:DI 2 "register_operand" "a"))
16816 (set (match_operand:P 0 "register_operand" "=D")
16817 (plus:P (match_dup 1)
16819 (unspec [(const_int 0)] UNSPEC_STOS)]
16821 && !(fixed_regs[AX_REG] || fixed_regs[DI_REG])
16822 && ix86_check_no_addr_space (insn)"
16824 [(set_attr "type" "str")
16825 (set_attr "memory" "store")
16826 (set_attr "mode" "DI")])
16828 (define_insn "*strsetsi_1"
16829 [(set (mem:SI (match_operand:P 1 "register_operand" "0"))
16830 (match_operand:SI 2 "register_operand" "a"))
16831 (set (match_operand:P 0 "register_operand" "=D")
16832 (plus:P (match_dup 1)
16834 (unspec [(const_int 0)] UNSPEC_STOS)]
16835 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])
16836 && ix86_check_no_addr_space (insn)"
16838 [(set_attr "type" "str")
16839 (set_attr "memory" "store")
16840 (set_attr "mode" "SI")])
16842 (define_insn "*strsethi_1"
16843 [(set (mem:HI (match_operand:P 1 "register_operand" "0"))
16844 (match_operand:HI 2 "register_operand" "a"))
16845 (set (match_operand:P 0 "register_operand" "=D")
16846 (plus:P (match_dup 1)
16848 (unspec [(const_int 0)] UNSPEC_STOS)]
16849 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])
16850 && ix86_check_no_addr_space (insn)"
16852 [(set_attr "type" "str")
16853 (set_attr "memory" "store")
16854 (set_attr "mode" "HI")])
16856 (define_insn "*strsetqi_1"
16857 [(set (mem:QI (match_operand:P 1 "register_operand" "0"))
16858 (match_operand:QI 2 "register_operand" "a"))
16859 (set (match_operand:P 0 "register_operand" "=D")
16860 (plus:P (match_dup 1)
16862 (unspec [(const_int 0)] UNSPEC_STOS)]
16863 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])
16864 && ix86_check_no_addr_space (insn)"
16866 [(set_attr "type" "str")
16867 (set_attr "memory" "store")
16868 (set (attr "prefix_rex")
16870 (match_test "<P:MODE>mode == DImode")
16872 (const_string "*")))
16873 (set_attr "mode" "QI")])
16875 (define_expand "rep_stos"
16876 [(parallel [(set (match_operand 1 "register_operand") (const_int 0))
16877 (set (match_operand 0 "register_operand")
16879 (set (match_operand 2 "memory_operand") (const_int 0))
16880 (use (match_operand 3 "register_operand"))
16881 (use (match_dup 1))])]
16885 ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
16888 (define_insn "*rep_stosdi_rex64"
16889 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
16890 (set (match_operand:P 0 "register_operand" "=D")
16891 (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
16893 (match_operand:P 3 "register_operand" "0")))
16894 (set (mem:BLK (match_dup 3))
16896 (use (match_operand:DI 2 "register_operand" "a"))
16897 (use (match_dup 4))]
16899 && !(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])
16900 && ix86_check_no_addr_space (insn)"
16902 [(set_attr "type" "str")
16903 (set_attr "prefix_rep" "1")
16904 (set_attr "memory" "store")
16905 (set_attr "mode" "DI")])
16907 (define_insn "*rep_stossi"
16908 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
16909 (set (match_operand:P 0 "register_operand" "=D")
16910 (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
16912 (match_operand:P 3 "register_operand" "0")))
16913 (set (mem:BLK (match_dup 3))
16915 (use (match_operand:SI 2 "register_operand" "a"))
16916 (use (match_dup 4))]
16917 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])
16918 && ix86_check_no_addr_space (insn)"
16919 "%^rep{%;} stos{l|d}"
16920 [(set_attr "type" "str")
16921 (set_attr "prefix_rep" "1")
16922 (set_attr "memory" "store")
16923 (set_attr "mode" "SI")])
16925 (define_insn "*rep_stosqi"
16926 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
16927 (set (match_operand:P 0 "register_operand" "=D")
16928 (plus:P (match_operand:P 3 "register_operand" "0")
16929 (match_operand:P 4 "register_operand" "1")))
16930 (set (mem:BLK (match_dup 3))
16932 (use (match_operand:QI 2 "register_operand" "a"))
16933 (use (match_dup 4))]
16934 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])
16935 && ix86_check_no_addr_space (insn)"
16937 [(set_attr "type" "str")
16938 (set_attr "prefix_rep" "1")
16939 (set_attr "memory" "store")
16940 (set (attr "prefix_rex")
16942 (match_test "<P:MODE>mode == DImode")
16944 (const_string "*")))
16945 (set_attr "mode" "QI")])
16947 (define_expand "cmpstrnsi"
16948 [(set (match_operand:SI 0 "register_operand")
16949 (compare:SI (match_operand:BLK 1 "general_operand")
16950 (match_operand:BLK 2 "general_operand")))
16951 (use (match_operand 3 "general_operand"))
16952 (use (match_operand 4 "immediate_operand"))]
16955 rtx addr1, addr2, out, outlow, count, countreg, align;
16957 if (optimize_insn_for_size_p () && !TARGET_INLINE_ALL_STRINGOPS)
16960 /* Can't use this if the user has appropriated ecx, esi or edi. */
16961 if (fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
16964 /* One of the strings must be a constant. If so, expand_builtin_strncmp()
16965 will have rewritten the length arg to be the minimum of the const string
16966 length and the actual length arg. If both strings are the same and
16967 shorter than the length arg, repz cmpsb will not stop at the 0 byte and
16968 will incorrectly base the results on chars past the 0 byte. */
16969 tree t1 = MEM_EXPR (operands[1]);
16970 tree t2 = MEM_EXPR (operands[2]);
16971 if (!((t1 && TREE_CODE (t1) == MEM_REF
16972 && TREE_CODE (TREE_OPERAND (t1, 0)) == ADDR_EXPR
16973 && TREE_CODE (TREE_OPERAND (TREE_OPERAND (t1, 0), 0)) == STRING_CST)
16974 || (t2 && TREE_CODE (t2) == MEM_REF
16975 && TREE_CODE (TREE_OPERAND (t2, 0)) == ADDR_EXPR
16976 && TREE_CODE (TREE_OPERAND (TREE_OPERAND (t2, 0), 0)) == STRING_CST)))
16981 out = gen_reg_rtx (SImode);
16983 addr1 = copy_addr_to_reg (XEXP (operands[1], 0));
16984 addr2 = copy_addr_to_reg (XEXP (operands[2], 0));
16985 if (addr1 != XEXP (operands[1], 0))
16986 operands[1] = replace_equiv_address_nv (operands[1], addr1);
16987 if (addr2 != XEXP (operands[2], 0))
16988 operands[2] = replace_equiv_address_nv (operands[2], addr2);
16990 count = operands[3];
16991 countreg = ix86_zero_extend_to_Pmode (count);
16993 /* %%% Iff we are testing strict equality, we can use known alignment
16994 to good advantage. This may be possible with combine, particularly
16995 once cc0 is dead. */
16996 align = operands[4];
16998 if (CONST_INT_P (count))
17000 if (INTVAL (count) == 0)
17002 emit_move_insn (operands[0], const0_rtx);
17005 emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
17006 operands[1], operands[2]));
17010 rtx (*gen_cmp) (rtx, rtx);
17012 gen_cmp = (TARGET_64BIT
17013 ? gen_cmpdi_1 : gen_cmpsi_1);
17015 emit_insn (gen_cmp (countreg, countreg));
17016 emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
17017 operands[1], operands[2]));
17020 outlow = gen_lowpart (QImode, out);
17021 emit_insn (gen_cmpintqi (outlow));
17022 emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
17024 if (operands[0] != out)
17025 emit_move_insn (operands[0], out);
17030 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
17032 (define_expand "cmpintqi"
17033 [(set (match_dup 1)
17034 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
17036 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
17037 (parallel [(set (match_operand:QI 0 "register_operand")
17038 (minus:QI (match_dup 1)
17040 (clobber (reg:CC FLAGS_REG))])]
17043 operands[1] = gen_reg_rtx (QImode);
17044 operands[2] = gen_reg_rtx (QImode);
17047 ;; memcmp recognizers. The `cmpsb' opcode does nothing if the count is
17048 ;; zero. Emit extra code to make sure that a zero-length compare is EQ.
17050 (define_expand "cmpstrnqi_nz_1"
17051 [(parallel [(set (reg:CC FLAGS_REG)
17052 (compare:CC (match_operand 4 "memory_operand")
17053 (match_operand 5 "memory_operand")))
17054 (use (match_operand 2 "register_operand"))
17055 (use (match_operand:SI 3 "immediate_operand"))
17056 (clobber (match_operand 0 "register_operand"))
17057 (clobber (match_operand 1 "register_operand"))
17058 (clobber (match_dup 2))])]
17062 ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
17065 (define_insn "*cmpstrnqi_nz_1"
17066 [(set (reg:CC FLAGS_REG)
17067 (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
17068 (mem:BLK (match_operand:P 5 "register_operand" "1"))))
17069 (use (match_operand:P 6 "register_operand" "2"))
17070 (use (match_operand:SI 3 "immediate_operand" "i"))
17071 (clobber (match_operand:P 0 "register_operand" "=S"))
17072 (clobber (match_operand:P 1 "register_operand" "=D"))
17073 (clobber (match_operand:P 2 "register_operand" "=c"))]
17074 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
17075 && ix86_check_no_addr_space (insn)"
17077 [(set_attr "type" "str")
17078 (set_attr "mode" "QI")
17079 (set (attr "prefix_rex")
17081 (match_test "<P:MODE>mode == DImode")
17083 (const_string "*")))
17084 (set_attr "prefix_rep" "1")])
17086 ;; The same, but the count is not known to not be zero.
17088 (define_expand "cmpstrnqi_1"
17089 [(parallel [(set (reg:CC FLAGS_REG)
17090 (if_then_else:CC (ne (match_operand 2 "register_operand")
17092 (compare:CC (match_operand 4 "memory_operand")
17093 (match_operand 5 "memory_operand"))
17095 (use (match_operand:SI 3 "immediate_operand"))
17096 (use (reg:CC FLAGS_REG))
17097 (clobber (match_operand 0 "register_operand"))
17098 (clobber (match_operand 1 "register_operand"))
17099 (clobber (match_dup 2))])]
17103 ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
17106 (define_insn "*cmpstrnqi_1"
17107 [(set (reg:CC FLAGS_REG)
17108 (if_then_else:CC (ne (match_operand:P 6 "register_operand" "2")
17110 (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
17111 (mem:BLK (match_operand:P 5 "register_operand" "1")))
17113 (use (match_operand:SI 3 "immediate_operand" "i"))
17114 (use (reg:CC FLAGS_REG))
17115 (clobber (match_operand:P 0 "register_operand" "=S"))
17116 (clobber (match_operand:P 1 "register_operand" "=D"))
17117 (clobber (match_operand:P 2 "register_operand" "=c"))]
17118 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
17119 && ix86_check_no_addr_space (insn)"
17121 [(set_attr "type" "str")
17122 (set_attr "mode" "QI")
17123 (set (attr "prefix_rex")
17125 (match_test "<P:MODE>mode == DImode")
17127 (const_string "*")))
17128 (set_attr "prefix_rep" "1")])
17130 (define_expand "strlen<mode>"
17131 [(set (match_operand:P 0 "register_operand")
17132 (unspec:P [(match_operand:BLK 1 "general_operand")
17133 (match_operand:QI 2 "immediate_operand")
17134 (match_operand 3 "immediate_operand")]
17138 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
17144 (define_expand "strlenqi_1"
17145 [(parallel [(set (match_operand 0 "register_operand")
17147 (clobber (match_operand 1 "register_operand"))
17148 (clobber (reg:CC FLAGS_REG))])]
17152 ix86_optimize_mode_switching[X86_DIRFLAG] = 1;
17155 (define_insn "*strlenqi_1"
17156 [(set (match_operand:P 0 "register_operand" "=&c")
17157 (unspec:P [(mem:BLK (match_operand:P 5 "register_operand" "1"))
17158 (match_operand:QI 2 "register_operand" "a")
17159 (match_operand:P 3 "immediate_operand" "i")
17160 (match_operand:P 4 "register_operand" "0")] UNSPEC_SCAS))
17161 (clobber (match_operand:P 1 "register_operand" "=D"))
17162 (clobber (reg:CC FLAGS_REG))]
17163 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])
17164 && ix86_check_no_addr_space (insn)"
17165 "%^repnz{%;} scasb"
17166 [(set_attr "type" "str")
17167 (set_attr "mode" "QI")
17168 (set (attr "prefix_rex")
17170 (match_test "<P:MODE>mode == DImode")
17172 (const_string "*")))
17173 (set_attr "prefix_rep" "1")])
17175 ;; Peephole optimizations to clean up after cmpstrn*. This should be
17176 ;; handled in combine, but it is not currently up to the task.
17177 ;; When used for their truth value, the cmpstrn* expanders generate
17186 ;; The intermediate three instructions are unnecessary.
17188 ;; This one handles cmpstrn*_nz_1...
17191 (set (reg:CC FLAGS_REG)
17192 (compare:CC (mem:BLK (match_operand 4 "register_operand"))
17193 (mem:BLK (match_operand 5 "register_operand"))))
17194 (use (match_operand 6 "register_operand"))
17195 (use (match_operand:SI 3 "immediate_operand"))
17196 (clobber (match_operand 0 "register_operand"))
17197 (clobber (match_operand 1 "register_operand"))
17198 (clobber (match_operand 2 "register_operand"))])
17199 (set (match_operand:QI 7 "register_operand")
17200 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
17201 (set (match_operand:QI 8 "register_operand")
17202 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
17203 (set (reg FLAGS_REG)
17204 (compare (match_dup 7) (match_dup 8)))
17206 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
17208 (set (reg:CC FLAGS_REG)
17209 (compare:CC (mem:BLK (match_dup 4))
17210 (mem:BLK (match_dup 5))))
17211 (use (match_dup 6))
17212 (use (match_dup 3))
17213 (clobber (match_dup 0))
17214 (clobber (match_dup 1))
17215 (clobber (match_dup 2))])])
17217 ;; ...and this one handles cmpstrn*_1.
17220 (set (reg:CC FLAGS_REG)
17221 (if_then_else:CC (ne (match_operand 6 "register_operand")
17223 (compare:CC (mem:BLK (match_operand 4 "register_operand"))
17224 (mem:BLK (match_operand 5 "register_operand")))
17226 (use (match_operand:SI 3 "immediate_operand"))
17227 (use (reg:CC FLAGS_REG))
17228 (clobber (match_operand 0 "register_operand"))
17229 (clobber (match_operand 1 "register_operand"))
17230 (clobber (match_operand 2 "register_operand"))])
17231 (set (match_operand:QI 7 "register_operand")
17232 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
17233 (set (match_operand:QI 8 "register_operand")
17234 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
17235 (set (reg FLAGS_REG)
17236 (compare (match_dup 7) (match_dup 8)))
17238 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
17240 (set (reg:CC FLAGS_REG)
17241 (if_then_else:CC (ne (match_dup 6)
17243 (compare:CC (mem:BLK (match_dup 4))
17244 (mem:BLK (match_dup 5)))
17246 (use (match_dup 3))
17247 (use (reg:CC FLAGS_REG))
17248 (clobber (match_dup 0))
17249 (clobber (match_dup 1))
17250 (clobber (match_dup 2))])])
17252 ;; Conditional move instructions.
17254 (define_expand "mov<mode>cc"
17255 [(set (match_operand:SWIM 0 "register_operand")
17256 (if_then_else:SWIM (match_operand 1 "comparison_operator")
17257 (match_operand:SWIM 2 "<general_operand>")
17258 (match_operand:SWIM 3 "<general_operand>")))]
17260 "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
17262 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
17263 ;; the register first winds up with `sbbl $0,reg', which is also weird.
17264 ;; So just document what we're doing explicitly.
17266 (define_expand "x86_mov<mode>cc_0_m1"
17268 [(set (match_operand:SWI48 0 "register_operand")
17269 (if_then_else:SWI48
17270 (match_operator:SWI48 2 "ix86_carry_flag_operator"
17271 [(match_operand 1 "flags_reg_operand")
17275 (clobber (reg:CC FLAGS_REG))])])
17277 (define_insn "*x86_mov<mode>cc_0_m1"
17278 [(set (match_operand:SWI48 0 "register_operand" "=r")
17279 (if_then_else:SWI48 (match_operator 1 "ix86_carry_flag_operator"
17280 [(reg FLAGS_REG) (const_int 0)])
17283 (clobber (reg:CC FLAGS_REG))]
17285 "sbb{<imodesuffix>}\t%0, %0"
17286 [(set_attr "type" "alu1")
17287 (set_attr "use_carry" "1")
17288 (set_attr "pent_pair" "pu")
17289 (set_attr "mode" "<MODE>")
17290 (set_attr "length_immediate" "0")])
17292 (define_insn "*x86_mov<mode>cc_0_m1_se"
17293 [(set (match_operand:SWI48 0 "register_operand" "=r")
17294 (sign_extract:SWI48 (match_operator 1 "ix86_carry_flag_operator"
17295 [(reg FLAGS_REG) (const_int 0)])
17298 (clobber (reg:CC FLAGS_REG))]
17300 "sbb{<imodesuffix>}\t%0, %0"
17301 [(set_attr "type" "alu1")
17302 (set_attr "use_carry" "1")
17303 (set_attr "pent_pair" "pu")
17304 (set_attr "mode" "<MODE>")
17305 (set_attr "length_immediate" "0")])
17307 (define_insn "*x86_mov<mode>cc_0_m1_neg"
17308 [(set (match_operand:SWI48 0 "register_operand" "=r")
17309 (neg:SWI48 (match_operator 1 "ix86_carry_flag_operator"
17310 [(reg FLAGS_REG) (const_int 0)])))
17311 (clobber (reg:CC FLAGS_REG))]
17313 "sbb{<imodesuffix>}\t%0, %0"
17314 [(set_attr "type" "alu1")
17315 (set_attr "use_carry" "1")
17316 (set_attr "pent_pair" "pu")
17317 (set_attr "mode" "<MODE>")
17318 (set_attr "length_immediate" "0")])
17320 (define_insn_and_split "*x86_mov<SWI48:mode>cc_0_m1_neg_leu<SWI:mode>"
17321 [(set (match_operand:SWI48 0 "register_operand" "=r")
17324 (match_operand:SWI 1 "nonimmediate_operand" "<SWI:r>m")
17325 (match_operand:SWI 2 "<SWI:immediate_operand>" "<SWI:i>"))))
17326 (clobber (reg:CC FLAGS_REG))]
17327 "CONST_INT_P (operands[2])
17328 && INTVAL (operands[2]) != -1
17329 && INTVAL (operands[2]) != 2147483647"
17332 [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
17333 (parallel [(set (match_dup 0)
17334 (neg:SWI48 (ltu:SWI48 (reg:CC FLAGS_REG) (const_int 0))))
17335 (clobber (reg:CC FLAGS_REG))])]
17336 "operands[2] = GEN_INT (INTVAL (operands[2]) + 1);")
17338 (define_insn "*mov<mode>cc_noc"
17339 [(set (match_operand:SWI248 0 "register_operand" "=r,r")
17340 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
17341 [(reg FLAGS_REG) (const_int 0)])
17342 (match_operand:SWI248 2 "nonimmediate_operand" "rm,0")
17343 (match_operand:SWI248 3 "nonimmediate_operand" "0,rm")))]
17344 "TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
17346 cmov%O2%C1\t{%2, %0|%0, %2}
17347 cmov%O2%c1\t{%3, %0|%0, %3}"
17348 [(set_attr "type" "icmov")
17349 (set_attr "mode" "<MODE>")])
17351 (define_insn "*movsicc_noc_zext"
17352 [(set (match_operand:DI 0 "register_operand" "=r,r")
17353 (if_then_else:DI (match_operator 1 "ix86_comparison_operator"
17354 [(reg FLAGS_REG) (const_int 0)])
17356 (match_operand:SI 2 "nonimmediate_operand" "rm,0"))
17358 (match_operand:SI 3 "nonimmediate_operand" "0,rm"))))]
17360 && TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
17362 cmov%O2%C1\t{%2, %k0|%k0, %2}
17363 cmov%O2%c1\t{%3, %k0|%k0, %3}"
17364 [(set_attr "type" "icmov")
17365 (set_attr "mode" "SI")])
17367 ;; Don't do conditional moves with memory inputs. This splitter helps
17368 ;; register starved x86_32 by forcing inputs into registers before reload.
17370 [(set (match_operand:SWI248 0 "register_operand")
17371 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
17372 [(reg FLAGS_REG) (const_int 0)])
17373 (match_operand:SWI248 2 "nonimmediate_operand")
17374 (match_operand:SWI248 3 "nonimmediate_operand")))]
17375 "!TARGET_64BIT && TARGET_CMOVE
17376 && TARGET_AVOID_MEM_OPND_FOR_CMOVE
17377 && (MEM_P (operands[2]) || MEM_P (operands[3]))
17378 && can_create_pseudo_p ()
17379 && optimize_insn_for_speed_p ()"
17380 [(set (match_dup 0)
17381 (if_then_else:SWI248 (match_dup 1) (match_dup 2) (match_dup 3)))]
17383 if (MEM_P (operands[2]))
17384 operands[2] = force_reg (<MODE>mode, operands[2]);
17385 if (MEM_P (operands[3]))
17386 operands[3] = force_reg (<MODE>mode, operands[3]);
17389 (define_insn "*movqicc_noc"
17390 [(set (match_operand:QI 0 "register_operand" "=r,r")
17391 (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
17392 [(reg FLAGS_REG) (const_int 0)])
17393 (match_operand:QI 2 "register_operand" "r,0")
17394 (match_operand:QI 3 "register_operand" "0,r")))]
17395 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
17397 [(set_attr "type" "icmov")
17398 (set_attr "mode" "QI")])
17401 [(set (match_operand:SWI12 0 "register_operand")
17402 (if_then_else:SWI12 (match_operator 1 "ix86_comparison_operator"
17403 [(reg FLAGS_REG) (const_int 0)])
17404 (match_operand:SWI12 2 "register_operand")
17405 (match_operand:SWI12 3 "register_operand")))]
17406 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL
17407 && reload_completed"
17408 [(set (match_dup 0)
17409 (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
17411 operands[0] = gen_lowpart (SImode, operands[0]);
17412 operands[2] = gen_lowpart (SImode, operands[2]);
17413 operands[3] = gen_lowpart (SImode, operands[3]);
17416 ;; Don't do conditional moves with memory inputs
17418 [(match_scratch:SWI248 4 "r")
17419 (set (match_operand:SWI248 0 "register_operand")
17420 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
17421 [(reg FLAGS_REG) (const_int 0)])
17422 (match_operand:SWI248 2 "nonimmediate_operand")
17423 (match_operand:SWI248 3 "nonimmediate_operand")))]
17424 "TARGET_CMOVE && TARGET_AVOID_MEM_OPND_FOR_CMOVE
17425 && (MEM_P (operands[2]) || MEM_P (operands[3]))
17426 && optimize_insn_for_speed_p ()"
17427 [(set (match_dup 4) (match_dup 5))
17429 (if_then_else:SWI248 (match_dup 1) (match_dup 2) (match_dup 3)))]
17431 if (MEM_P (operands[2]))
17433 operands[5] = operands[2];
17434 operands[2] = operands[4];
17436 else if (MEM_P (operands[3]))
17438 operands[5] = operands[3];
17439 operands[3] = operands[4];
17442 gcc_unreachable ();
17446 [(match_scratch:SI 4 "r")
17447 (set (match_operand:DI 0 "register_operand")
17448 (if_then_else:DI (match_operator 1 "ix86_comparison_operator"
17449 [(reg FLAGS_REG) (const_int 0)])
17451 (match_operand:SI 2 "nonimmediate_operand"))
17453 (match_operand:SI 3 "nonimmediate_operand"))))]
17455 && TARGET_CMOVE && TARGET_AVOID_MEM_OPND_FOR_CMOVE
17456 && (MEM_P (operands[2]) || MEM_P (operands[3]))
17457 && optimize_insn_for_speed_p ()"
17458 [(set (match_dup 4) (match_dup 5))
17460 (if_then_else:DI (match_dup 1)
17461 (zero_extend:DI (match_dup 2))
17462 (zero_extend:DI (match_dup 3))))]
17464 if (MEM_P (operands[2]))
17466 operands[5] = operands[2];
17467 operands[2] = operands[4];
17469 else if (MEM_P (operands[3]))
17471 operands[5] = operands[3];
17472 operands[3] = operands[4];
17475 gcc_unreachable ();
17478 (define_expand "mov<mode>cc"
17479 [(set (match_operand:X87MODEF 0 "register_operand")
17480 (if_then_else:X87MODEF
17481 (match_operand 1 "comparison_operator")
17482 (match_operand:X87MODEF 2 "register_operand")
17483 (match_operand:X87MODEF 3 "register_operand")))]
17484 "(TARGET_80387 && TARGET_CMOVE)
17485 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
17486 "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
17488 (define_insn "*movxfcc_1"
17489 [(set (match_operand:XF 0 "register_operand" "=f,f")
17490 (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
17491 [(reg FLAGS_REG) (const_int 0)])
17492 (match_operand:XF 2 "register_operand" "f,0")
17493 (match_operand:XF 3 "register_operand" "0,f")))]
17494 "TARGET_80387 && TARGET_CMOVE"
17496 fcmov%F1\t{%2, %0|%0, %2}
17497 fcmov%f1\t{%3, %0|%0, %3}"
17498 [(set_attr "type" "fcmov")
17499 (set_attr "mode" "XF")])
17501 (define_insn "*movdfcc_1"
17502 [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r,r ,r")
17503 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
17504 [(reg FLAGS_REG) (const_int 0)])
17505 (match_operand:DF 2 "nonimmediate_operand"
17507 (match_operand:DF 3 "nonimmediate_operand"
17508 "0 ,f,0 ,rm,0, rm")))]
17509 "TARGET_80387 && TARGET_CMOVE
17510 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
17512 fcmov%F1\t{%2, %0|%0, %2}
17513 fcmov%f1\t{%3, %0|%0, %3}
17516 cmov%O2%C1\t{%2, %0|%0, %2}
17517 cmov%O2%c1\t{%3, %0|%0, %3}"
17518 [(set_attr "isa" "*,*,nox64,nox64,x64,x64")
17519 (set_attr "type" "fcmov,fcmov,multi,multi,icmov,icmov")
17520 (set_attr "mode" "DF,DF,DI,DI,DI,DI")])
17523 [(set (match_operand:DF 0 "general_reg_operand")
17524 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
17525 [(reg FLAGS_REG) (const_int 0)])
17526 (match_operand:DF 2 "nonimmediate_operand")
17527 (match_operand:DF 3 "nonimmediate_operand")))]
17528 "!TARGET_64BIT && reload_completed"
17529 [(set (match_dup 2)
17530 (if_then_else:SI (match_dup 1) (match_dup 4) (match_dup 5)))
17532 (if_then_else:SI (match_dup 1) (match_dup 6) (match_dup 7)))]
17534 split_double_mode (DImode, &operands[2], 2, &operands[4], &operands[6]);
17535 split_double_mode (DImode, &operands[0], 1, &operands[2], &operands[3]);
17538 (define_insn "*movsfcc_1_387"
17539 [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
17540 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
17541 [(reg FLAGS_REG) (const_int 0)])
17542 (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
17543 (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
17544 "TARGET_80387 && TARGET_CMOVE
17545 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
17547 fcmov%F1\t{%2, %0|%0, %2}
17548 fcmov%f1\t{%3, %0|%0, %3}
17549 cmov%O2%C1\t{%2, %0|%0, %2}
17550 cmov%O2%c1\t{%3, %0|%0, %3}"
17551 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
17552 (set_attr "mode" "SF,SF,SI,SI")])
17554 ;; Don't do conditional moves with memory inputs. This splitter helps
17555 ;; register starved x86_32 by forcing inputs into registers before reload.
17557 [(set (match_operand:MODEF 0 "register_operand")
17558 (if_then_else:MODEF (match_operator 1 "ix86_comparison_operator"
17559 [(reg FLAGS_REG) (const_int 0)])
17560 (match_operand:MODEF 2 "nonimmediate_operand")
17561 (match_operand:MODEF 3 "nonimmediate_operand")))]
17562 "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
17563 && TARGET_AVOID_MEM_OPND_FOR_CMOVE
17564 && (MEM_P (operands[2]) || MEM_P (operands[3]))
17565 && can_create_pseudo_p ()
17566 && optimize_insn_for_speed_p ()"
17567 [(set (match_dup 0)
17568 (if_then_else:MODEF (match_dup 1) (match_dup 2) (match_dup 3)))]
17570 if (MEM_P (operands[2]))
17571 operands[2] = force_reg (<MODE>mode, operands[2]);
17572 if (MEM_P (operands[3]))
17573 operands[3] = force_reg (<MODE>mode, operands[3]);
17576 ;; Don't do conditional moves with memory inputs
17578 [(match_scratch:MODEF 4 "r")
17579 (set (match_operand:MODEF 0 "general_reg_operand")
17580 (if_then_else:MODEF (match_operator 1 "fcmov_comparison_operator"
17581 [(reg FLAGS_REG) (const_int 0)])
17582 (match_operand:MODEF 2 "nonimmediate_operand")
17583 (match_operand:MODEF 3 "nonimmediate_operand")))]
17584 "(<MODE>mode != DFmode || TARGET_64BIT)
17585 && TARGET_80387 && TARGET_CMOVE
17586 && TARGET_AVOID_MEM_OPND_FOR_CMOVE
17587 && (MEM_P (operands[2]) || MEM_P (operands[3]))
17588 && optimize_insn_for_speed_p ()"
17589 [(set (match_dup 4) (match_dup 5))
17591 (if_then_else:MODEF (match_dup 1) (match_dup 2) (match_dup 3)))]
17593 if (MEM_P (operands[2]))
17595 operands[5] = operands[2];
17596 operands[2] = operands[4];
17598 else if (MEM_P (operands[3]))
17600 operands[5] = operands[3];
17601 operands[3] = operands[4];
17604 gcc_unreachable ();
17607 ;; All moves in XOP pcmov instructions are 128 bits and hence we restrict
17608 ;; the scalar versions to have only XMM registers as operands.
17610 ;; XOP conditional move
17611 (define_insn "*xop_pcmov_<mode>"
17612 [(set (match_operand:MODEF 0 "register_operand" "=x")
17613 (if_then_else:MODEF
17614 (match_operand:MODEF 1 "register_operand" "x")
17615 (match_operand:MODEF 2 "register_operand" "x")
17616 (match_operand:MODEF 3 "register_operand" "x")))]
17618 "vpcmov\t{%1, %3, %2, %0|%0, %2, %3, %1}"
17619 [(set_attr "type" "sse4arg")])
17621 ;; These versions of the min/max patterns are intentionally ignorant of
17622 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
17623 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
17624 ;; are undefined in this condition, we're certain this is correct.
17626 (define_insn "<code><mode>3"
17627 [(set (match_operand:MODEF 0 "register_operand" "=x,v")
17629 (match_operand:MODEF 1 "nonimmediate_operand" "%0,v")
17630 (match_operand:MODEF 2 "nonimmediate_operand" "xm,vm")))]
17631 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
17633 <maxmin_float><ssemodesuffix>\t{%2, %0|%0, %2}
17634 v<maxmin_float><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
17635 [(set_attr "isa" "noavx,avx")
17636 (set_attr "prefix" "orig,vex")
17637 (set_attr "type" "sseadd")
17638 (set_attr "mode" "<MODE>")])
17640 ;; These versions of the min/max patterns implement exactly the operations
17641 ;; min = (op1 < op2 ? op1 : op2)
17642 ;; max = (!(op1 < op2) ? op1 : op2)
17643 ;; Their operands are not commutative, and thus they may be used in the
17644 ;; presence of -0.0 and NaN.
17646 (define_insn "*ieee_s<ieee_maxmin><mode>3"
17647 [(set (match_operand:MODEF 0 "register_operand" "=x,v")
17649 [(match_operand:MODEF 1 "register_operand" "0,v")
17650 (match_operand:MODEF 2 "nonimmediate_operand" "xm,vm")]
17652 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
17654 <ieee_maxmin><ssemodesuffix>\t{%2, %0|%0, %2}
17655 v<ieee_maxmin><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
17656 [(set_attr "isa" "noavx,avx")
17657 (set_attr "prefix" "orig,maybe_evex")
17658 (set_attr "type" "sseadd")
17659 (set_attr "mode" "<MODE>")])
17661 ;; Make two stack loads independent:
17663 ;; fld %st(0) -> fld bb
17664 ;; fmul bb fmul %st(1), %st
17666 ;; Actually we only match the last two instructions for simplicity.
17669 [(set (match_operand 0 "fp_register_operand")
17670 (match_operand 1 "fp_register_operand"))
17672 (match_operator 2 "binary_fp_operator"
17674 (match_operand 3 "memory_operand")]))]
17675 "REGNO (operands[0]) != REGNO (operands[1])"
17676 [(set (match_dup 0) (match_dup 3))
17679 [(match_dup 5) (match_dup 4)]))]
17681 operands[4] = operands[0];
17682 operands[5] = operands[1];
17684 /* The % modifier is not operational anymore in peephole2's, so we have to
17685 swap the operands manually in the case of addition and multiplication. */
17686 if (COMMUTATIVE_ARITH_P (operands[2]))
17687 std::swap (operands[4], operands[5]);
17691 [(set (match_operand 0 "fp_register_operand")
17692 (match_operand 1 "fp_register_operand"))
17694 (match_operator 2 "binary_fp_operator"
17695 [(match_operand 3 "memory_operand")
17697 "REGNO (operands[0]) != REGNO (operands[1])"
17698 [(set (match_dup 0) (match_dup 3))
17701 [(match_dup 4) (match_dup 5)]))]
17703 operands[4] = operands[0];
17704 operands[5] = operands[1];
17706 /* The % modifier is not operational anymore in peephole2's, so we have to
17707 swap the operands manually in the case of addition and multiplication. */
17708 if (COMMUTATIVE_ARITH_P (operands[2]))
17709 std::swap (operands[4], operands[5]);
17712 ;; Conditional addition patterns
17713 (define_expand "add<mode>cc"
17714 [(match_operand:SWI 0 "register_operand")
17715 (match_operand 1 "ordered_comparison_operator")
17716 (match_operand:SWI 2 "register_operand")
17717 (match_operand:SWI 3 "const_int_operand")]
17719 "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
17721 ;; Misc patterns (?)
17723 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
17724 ;; Otherwise there will be nothing to keep
17726 ;; [(set (reg ebp) (reg esp))]
17727 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
17728 ;; (clobber (eflags)]
17729 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
17731 ;; in proper program order.
17733 (define_insn "@pro_epilogue_adjust_stack_add_<mode>"
17734 [(set (match_operand:P 0 "register_operand" "=r,r")
17735 (plus:P (match_operand:P 1 "register_operand" "0,r")
17736 (match_operand:P 2 "<nonmemory_operand>" "r<i>,l<i>")))
17737 (clobber (reg:CC FLAGS_REG))
17738 (clobber (mem:BLK (scratch)))]
17741 switch (get_attr_type (insn))
17744 return "mov{<imodesuffix>}\t{%1, %0|%0, %1}";
17747 gcc_assert (rtx_equal_p (operands[0], operands[1]));
17748 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
17749 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
17751 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
17754 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
17755 return "lea{<imodesuffix>}\t{%E2, %0|%0, %E2}";
17758 [(set (attr "type")
17759 (cond [(and (eq_attr "alternative" "0")
17760 (not (match_test "TARGET_OPT_AGU")))
17761 (const_string "alu")
17762 (match_operand:<MODE> 2 "const0_operand")
17763 (const_string "imov")
17765 (const_string "lea")))
17766 (set (attr "length_immediate")
17767 (cond [(eq_attr "type" "imov")
17769 (and (eq_attr "type" "alu")
17770 (match_operand 2 "const128_operand"))
17773 (const_string "*")))
17774 (set_attr "mode" "<MODE>")])
17776 (define_insn "@pro_epilogue_adjust_stack_sub_<mode>"
17777 [(set (match_operand:P 0 "register_operand" "=r")
17778 (minus:P (match_operand:P 1 "register_operand" "0")
17779 (match_operand:P 2 "register_operand" "r")))
17780 (clobber (reg:CC FLAGS_REG))
17781 (clobber (mem:BLK (scratch)))]
17783 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
17784 [(set_attr "type" "alu")
17785 (set_attr "mode" "<MODE>")])
17787 (define_insn "@allocate_stack_worker_probe_<mode>"
17788 [(set (match_operand:P 0 "register_operand" "=a")
17789 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
17790 UNSPECV_STACK_PROBE))
17791 (clobber (reg:CC FLAGS_REG))]
17792 "ix86_target_stack_probe ()"
17793 "call\t___chkstk_ms"
17794 [(set_attr "type" "multi")
17795 (set_attr "length" "5")])
17797 (define_expand "allocate_stack"
17798 [(match_operand 0 "register_operand")
17799 (match_operand 1 "general_operand")]
17800 "ix86_target_stack_probe ()"
17804 #ifndef CHECK_STACK_LIMIT
17805 #define CHECK_STACK_LIMIT 0
17808 if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
17809 && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
17813 x = copy_to_mode_reg (Pmode, operands[1]);
17815 emit_insn (gen_allocate_stack_worker_probe (Pmode, x, x));
17818 x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, x,
17819 stack_pointer_rtx, 0, OPTAB_DIRECT);
17821 if (x != stack_pointer_rtx)
17822 emit_move_insn (stack_pointer_rtx, x);
17824 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
17828 (define_expand "probe_stack"
17829 [(match_operand 0 "memory_operand")]
17832 emit_insn (gen_probe_stack_1
17833 (word_mode, operands[0], const0_rtx));
17837 ;; Use OR for stack probes, this is shorter.
17838 (define_insn "@probe_stack_1_<mode>"
17839 [(set (match_operand:W 0 "memory_operand" "=m")
17840 (unspec:W [(match_operand:W 1 "const0_operand")]
17841 UNSPEC_PROBE_STACK))
17842 (clobber (reg:CC FLAGS_REG))]
17844 "or{<imodesuffix>}\t{%1, %0|%0, %1}"
17845 [(set_attr "type" "alu1")
17846 (set_attr "mode" "<MODE>")
17847 (set_attr "length_immediate" "1")])
17849 (define_insn "@adjust_stack_and_probe_<mode>"
17850 [(set (match_operand:P 0 "register_operand" "=r")
17851 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
17852 UNSPECV_PROBE_STACK_RANGE))
17853 (set (reg:P SP_REG)
17854 (minus:P (reg:P SP_REG) (match_operand:P 2 "const_int_operand" "n")))
17855 (clobber (reg:CC FLAGS_REG))
17856 (clobber (mem:BLK (scratch)))]
17858 "* return output_adjust_stack_and_probe (operands[0]);"
17859 [(set_attr "type" "multi")])
17861 (define_insn "@probe_stack_range_<mode>"
17862 [(set (match_operand:P 0 "register_operand" "=r")
17863 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
17864 (match_operand:P 2 "const_int_operand" "n")]
17865 UNSPECV_PROBE_STACK_RANGE))
17866 (clobber (reg:CC FLAGS_REG))]
17868 "* return output_probe_stack_range (operands[0], operands[2]);"
17869 [(set_attr "type" "multi")])
17871 (define_expand "builtin_setjmp_receiver"
17872 [(label_ref (match_operand 0))]
17873 "!TARGET_64BIT && flag_pic"
17879 rtx_code_label *label_rtx = gen_label_rtx ();
17880 emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
17881 xops[0] = xops[1] = pic_offset_table_rtx;
17882 xops[2] = machopic_gen_offset (gen_rtx_LABEL_REF (SImode, label_rtx));
17883 ix86_expand_binary_operator (MINUS, SImode, xops);
17887 emit_insn (gen_set_got (pic_offset_table_rtx));
17891 (define_expand "save_stack_nonlocal"
17892 [(set (match_operand 0 "memory_operand")
17893 (match_operand 1 "register_operand"))]
17897 if ((flag_cf_protection & CF_RETURN))
17899 /* Copy shadow stack pointer to the first slot and stack ppointer
17900 to the second slot. */
17901 rtx ssp_slot = adjust_address (operands[0], word_mode, 0);
17902 stack_slot = adjust_address (operands[0], Pmode, UNITS_PER_WORD);
17903 rtx ssp = gen_reg_rtx (word_mode);
17904 emit_insn ((word_mode == SImode)
17905 ? gen_rdsspsi (ssp)
17906 : gen_rdsspdi (ssp));
17907 emit_move_insn (ssp_slot, ssp);
17910 stack_slot = adjust_address (operands[0], Pmode, 0);
17911 emit_move_insn (stack_slot, operands[1]);
17915 (define_expand "restore_stack_nonlocal"
17916 [(set (match_operand 0 "register_operand" "")
17917 (match_operand 1 "memory_operand" ""))]
17921 if ((flag_cf_protection & CF_RETURN))
17923 /* Restore shadow stack pointer from the first slot and stack
17924 pointer from the second slot. */
17925 rtx ssp_slot = adjust_address (operands[1], word_mode, 0);
17926 stack_slot = adjust_address (operands[1], Pmode, UNITS_PER_WORD);
17928 rtx flags, jump, noadj_label, inc_label, loop_label;
17929 rtx reg_adj, reg_ssp, tmp, clob;
17931 /* Get the current shadow stack pointer. The code below will check if
17932 SHSTK feature is enabled. If it is not enabled the RDSSP instruction
17934 reg_ssp = gen_reg_rtx (word_mode);
17935 emit_insn (gen_rtx_SET (reg_ssp, const0_rtx));
17936 emit_insn ((word_mode == SImode)
17937 ? gen_rdsspsi (reg_ssp)
17938 : gen_rdsspdi (reg_ssp));
17940 /* Compare through substraction the saved and the current ssp to decide
17941 if ssp has to be adjusted. */
17942 tmp = gen_rtx_SET (reg_ssp, gen_rtx_MINUS (word_mode, reg_ssp,
17944 clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
17945 tmp = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, tmp, clob));
17948 /* Compare and jump over adjustment code. */
17949 noadj_label = gen_label_rtx ();
17950 flags = gen_rtx_REG (CCZmode, FLAGS_REG);
17951 tmp = gen_rtx_EQ (VOIDmode, flags, const0_rtx);
17952 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
17953 gen_rtx_LABEL_REF (VOIDmode, noadj_label),
17955 jump = emit_jump_insn (gen_rtx_SET (pc_rtx, tmp));
17956 JUMP_LABEL (jump) = noadj_label;
17958 /* Compute the numebr of frames to adjust. */
17959 reg_adj = gen_lowpart (ptr_mode, reg_ssp);
17960 tmp = gen_rtx_SET (reg_adj,
17961 gen_rtx_LSHIFTRT (ptr_mode,
17962 negate_rtx (ptr_mode, reg_adj),
17963 GEN_INT ((word_mode == SImode)
17966 clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
17967 tmp = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, tmp, clob));
17970 /* Check if number of frames <= 255 so no loop is needed. */
17971 tmp = gen_rtx_COMPARE (CCmode, reg_adj, GEN_INT (255));
17972 flags = gen_rtx_REG (CCmode, FLAGS_REG);
17973 emit_insn (gen_rtx_SET (flags, tmp));
17975 inc_label = gen_label_rtx ();
17976 tmp = gen_rtx_LEU (VOIDmode, flags, const0_rtx);
17977 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
17978 gen_rtx_LABEL_REF (VOIDmode, inc_label),
17980 jump = emit_jump_insn (gen_rtx_SET (pc_rtx, tmp));
17981 JUMP_LABEL (jump) = inc_label;
17983 rtx reg_255 = gen_reg_rtx (word_mode);
17984 emit_move_insn (reg_255, GEN_INT (255));
17986 /* Adjust the ssp in a loop. */
17987 loop_label = gen_label_rtx ();
17988 emit_label (loop_label);
17989 LABEL_NUSES (loop_label) = 1;
17991 emit_insn ((word_mode == SImode)
17992 ? gen_incsspsi (reg_255)
17993 : gen_incsspdi (reg_255));
17994 tmp = gen_rtx_SET (reg_adj, gen_rtx_MINUS (ptr_mode,
17997 clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
17998 tmp = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, tmp, clob));
18001 tmp = gen_rtx_COMPARE (CCmode, reg_adj, GEN_INT (255));
18002 flags = gen_rtx_REG (CCmode, FLAGS_REG);
18003 emit_insn (gen_rtx_SET (flags, tmp));
18005 /* Jump to the loop label. */
18006 tmp = gen_rtx_GTU (VOIDmode, flags, const0_rtx);
18007 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
18008 gen_rtx_LABEL_REF (VOIDmode, loop_label),
18010 jump = emit_jump_insn (gen_rtx_SET (pc_rtx, tmp));
18011 JUMP_LABEL (jump) = loop_label;
18013 emit_label (inc_label);
18014 LABEL_NUSES (inc_label) = 1;
18015 emit_insn ((word_mode == SImode)
18016 ? gen_incsspsi (reg_ssp)
18017 : gen_incsspdi (reg_ssp));
18019 emit_label (noadj_label);
18020 LABEL_NUSES (noadj_label) = 1;
18023 stack_slot = adjust_address (operands[1], Pmode, 0);
18024 emit_move_insn (operands[0], stack_slot);
18029 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
18030 ;; Do not split instructions with mask registers.
18032 [(set (match_operand 0 "general_reg_operand")
18033 (match_operator 3 "promotable_binary_operator"
18034 [(match_operand 1 "general_reg_operand")
18035 (match_operand 2 "aligned_operand")]))
18036 (clobber (reg:CC FLAGS_REG))]
18037 "! TARGET_PARTIAL_REG_STALL && reload_completed
18038 && ((GET_MODE (operands[0]) == HImode
18039 && ((optimize_function_for_speed_p (cfun) && !TARGET_FAST_PREFIX)
18040 /* ??? next two lines just !satisfies_constraint_K (...) */
18041 || !CONST_INT_P (operands[2])
18042 || satisfies_constraint_K (operands[2])))
18043 || (GET_MODE (operands[0]) == QImode
18044 && (TARGET_PROMOTE_QImode || optimize_function_for_size_p (cfun))))"
18045 [(parallel [(set (match_dup 0)
18046 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
18047 (clobber (reg:CC FLAGS_REG))])]
18049 operands[0] = gen_lowpart (SImode, operands[0]);
18050 operands[1] = gen_lowpart (SImode, operands[1]);
18051 if (GET_CODE (operands[3]) != ASHIFT)
18052 operands[2] = gen_lowpart (SImode, operands[2]);
18053 operands[3] = shallow_copy_rtx (operands[3]);
18054 PUT_MODE (operands[3], SImode);
18057 ; Promote the QImode tests, as i386 has encoding of the AND
18058 ; instruction with 32-bit sign-extended immediate and thus the
18059 ; instruction size is unchanged, except in the %eax case for
18060 ; which it is increased by one byte, hence the ! optimize_size.
18062 [(set (match_operand 0 "flags_reg_operand")
18063 (match_operator 2 "compare_operator"
18064 [(and (match_operand 3 "aligned_operand")
18065 (match_operand 4 "const_int_operand"))
18067 (set (match_operand 1 "register_operand")
18068 (and (match_dup 3) (match_dup 4)))]
18069 "! TARGET_PARTIAL_REG_STALL && reload_completed
18070 && optimize_insn_for_speed_p ()
18071 && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
18072 || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))
18073 /* Ensure that the operand will remain sign-extended immediate. */
18074 && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)"
18075 [(parallel [(set (match_dup 0)
18076 (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
18079 (and:SI (match_dup 3) (match_dup 4)))])]
18082 = gen_int_mode (INTVAL (operands[4])
18083 & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
18084 operands[1] = gen_lowpart (SImode, operands[1]);
18085 operands[3] = gen_lowpart (SImode, operands[3]);
18088 ; Don't promote the QImode tests, as i386 doesn't have encoding of
18089 ; the TEST instruction with 32-bit sign-extended immediate and thus
18090 ; the instruction size would at least double, which is not what we
18091 ; want even with ! optimize_size.
18093 [(set (match_operand 0 "flags_reg_operand")
18094 (match_operator 1 "compare_operator"
18095 [(and (match_operand:HI 2 "aligned_operand")
18096 (match_operand:HI 3 "const_int_operand"))
18098 "! TARGET_PARTIAL_REG_STALL && reload_completed
18099 && ! TARGET_FAST_PREFIX
18100 && optimize_insn_for_speed_p ()
18101 /* Ensure that the operand will remain sign-extended immediate. */
18102 && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)"
18103 [(set (match_dup 0)
18104 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
18108 = gen_int_mode (INTVAL (operands[3])
18109 & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
18110 operands[2] = gen_lowpart (SImode, operands[2]);
18114 [(set (match_operand 0 "register_operand")
18115 (neg (match_operand 1 "register_operand")))
18116 (clobber (reg:CC FLAGS_REG))]
18117 "! TARGET_PARTIAL_REG_STALL && reload_completed
18118 && (GET_MODE (operands[0]) == HImode
18119 || (GET_MODE (operands[0]) == QImode
18120 && (TARGET_PROMOTE_QImode
18121 || optimize_insn_for_size_p ())))"
18122 [(parallel [(set (match_dup 0)
18123 (neg:SI (match_dup 1)))
18124 (clobber (reg:CC FLAGS_REG))])]
18126 operands[0] = gen_lowpart (SImode, operands[0]);
18127 operands[1] = gen_lowpart (SImode, operands[1]);
18130 ;; Do not split instructions with mask regs.
18132 [(set (match_operand 0 "general_reg_operand")
18133 (not (match_operand 1 "general_reg_operand")))]
18134 "! TARGET_PARTIAL_REG_STALL && reload_completed
18135 && (GET_MODE (operands[0]) == HImode
18136 || (GET_MODE (operands[0]) == QImode
18137 && (TARGET_PROMOTE_QImode
18138 || optimize_insn_for_size_p ())))"
18139 [(set (match_dup 0)
18140 (not:SI (match_dup 1)))]
18142 operands[0] = gen_lowpart (SImode, operands[0]);
18143 operands[1] = gen_lowpart (SImode, operands[1]);
18146 ;; RTL Peephole optimizations, run before sched2. These primarily look to
18147 ;; transform a complex memory operation into two memory to register operations.
18149 ;; Don't push memory operands
18151 [(set (match_operand:SWI 0 "push_operand")
18152 (match_operand:SWI 1 "memory_operand"))
18153 (match_scratch:SWI 2 "<r>")]
18154 "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
18155 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
18156 [(set (match_dup 2) (match_dup 1))
18157 (set (match_dup 0) (match_dup 2))])
18159 ;; We need to handle SFmode only, because DFmode and XFmode are split to
18162 [(set (match_operand:SF 0 "push_operand")
18163 (match_operand:SF 1 "memory_operand"))
18164 (match_scratch:SF 2 "r")]
18165 "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
18166 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
18167 [(set (match_dup 2) (match_dup 1))
18168 (set (match_dup 0) (match_dup 2))])
18170 ;; Don't move an immediate directly to memory when the instruction
18171 ;; gets too big, or if LCP stalls are a problem for 16-bit moves.
18173 [(match_scratch:SWI124 1 "<r>")
18174 (set (match_operand:SWI124 0 "memory_operand")
18176 "optimize_insn_for_speed_p ()
18177 && ((<MODE>mode == HImode
18178 && TARGET_LCP_STALL)
18179 || (!TARGET_USE_MOV0
18180 && TARGET_SPLIT_LONG_MOVES
18181 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn))
18182 && peep2_regno_dead_p (0, FLAGS_REG)"
18183 [(parallel [(set (match_dup 2) (const_int 0))
18184 (clobber (reg:CC FLAGS_REG))])
18185 (set (match_dup 0) (match_dup 1))]
18186 "operands[2] = gen_lowpart (SImode, operands[1]);")
18189 [(match_scratch:SWI124 2 "<r>")
18190 (set (match_operand:SWI124 0 "memory_operand")
18191 (match_operand:SWI124 1 "immediate_operand"))]
18192 "optimize_insn_for_speed_p ()
18193 && ((<MODE>mode == HImode
18194 && TARGET_LCP_STALL)
18195 || (TARGET_SPLIT_LONG_MOVES
18196 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn))"
18197 [(set (match_dup 2) (match_dup 1))
18198 (set (match_dup 0) (match_dup 2))])
18200 ;; Don't compare memory with zero, load and use a test instead.
18202 [(set (match_operand 0 "flags_reg_operand")
18203 (match_operator 1 "compare_operator"
18204 [(match_operand:SI 2 "memory_operand")
18206 (match_scratch:SI 3 "r")]
18207 "optimize_insn_for_speed_p () && ix86_match_ccmode (insn, CCNOmode)"
18208 [(set (match_dup 3) (match_dup 2))
18209 (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))])
18211 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
18212 ;; Don't split NOTs with a displacement operand, because resulting XOR
18213 ;; will not be pairable anyway.
18215 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
18216 ;; represented using a modRM byte. The XOR replacement is long decoded,
18217 ;; so this split helps here as well.
18219 ;; Note: Can't do this as a regular split because we can't get proper
18220 ;; lifetime information then.
18223 [(set (match_operand:SWI124 0 "nonimmediate_gr_operand")
18224 (not:SWI124 (match_operand:SWI124 1 "nonimmediate_gr_operand")))]
18225 "optimize_insn_for_speed_p ()
18226 && ((TARGET_NOT_UNPAIRABLE
18227 && (!MEM_P (operands[0])
18228 || !memory_displacement_operand (operands[0], <MODE>mode)))
18229 || (TARGET_NOT_VECTORMODE
18230 && long_memory_operand (operands[0], <MODE>mode)))
18231 && peep2_regno_dead_p (0, FLAGS_REG)"
18232 [(parallel [(set (match_dup 0)
18233 (xor:SWI124 (match_dup 1) (const_int -1)))
18234 (clobber (reg:CC FLAGS_REG))])])
18236 ;; Non pairable "test imm, reg" instructions can be translated to
18237 ;; "and imm, reg" if reg dies. The "and" form is also shorter (one
18238 ;; byte opcode instead of two, have a short form for byte operands),
18239 ;; so do it for other CPUs as well. Given that the value was dead,
18240 ;; this should not create any new dependencies. Pass on the sub-word
18241 ;; versions if we're concerned about partial register stalls.
18244 [(set (match_operand 0 "flags_reg_operand")
18245 (match_operator 1 "compare_operator"
18246 [(and:SI (match_operand:SI 2 "register_operand")
18247 (match_operand:SI 3 "immediate_operand"))
18249 "ix86_match_ccmode (insn, CCNOmode)
18250 && (REGNO (operands[2]) != AX_REG
18251 || satisfies_constraint_K (operands[3]))
18252 && peep2_reg_dead_p (1, operands[2])"
18254 [(set (match_dup 0)
18255 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
18258 (and:SI (match_dup 2) (match_dup 3)))])])
18260 ;; We don't need to handle HImode case, because it will be promoted to SImode
18261 ;; on ! TARGET_PARTIAL_REG_STALL
18264 [(set (match_operand 0 "flags_reg_operand")
18265 (match_operator 1 "compare_operator"
18266 [(and:QI (match_operand:QI 2 "register_operand")
18267 (match_operand:QI 3 "immediate_operand"))
18269 "! TARGET_PARTIAL_REG_STALL
18270 && ix86_match_ccmode (insn, CCNOmode)
18271 && REGNO (operands[2]) != AX_REG
18272 && peep2_reg_dead_p (1, operands[2])"
18274 [(set (match_dup 0)
18275 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
18278 (and:QI (match_dup 2) (match_dup 3)))])])
18281 [(set (match_operand 0 "flags_reg_operand")
18282 (match_operator 1 "compare_operator"
18285 (zero_extract:SI (match_operand 2 "QIreg_operand")
18288 (match_operand 3 "const_int_operand"))
18290 "! TARGET_PARTIAL_REG_STALL
18291 && ix86_match_ccmode (insn, CCNOmode)
18292 && REGNO (operands[2]) != AX_REG
18293 && peep2_reg_dead_p (1, operands[2])"
18295 [(set (match_dup 0)
18299 (zero_extract:SI (match_dup 2)
18304 (set (zero_extract:SI (match_dup 2)
18310 (zero_extract:SI (match_dup 2)
18313 (match_dup 3)) 0))])])
18315 ;; Don't do logical operations with memory inputs.
18317 [(match_scratch:SWI 2 "<r>")
18318 (parallel [(set (match_operand:SWI 0 "register_operand")
18319 (match_operator:SWI 3 "arith_or_logical_operator"
18321 (match_operand:SWI 1 "memory_operand")]))
18322 (clobber (reg:CC FLAGS_REG))])]
18323 "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
18324 [(set (match_dup 2) (match_dup 1))
18325 (parallel [(set (match_dup 0)
18326 (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
18327 (clobber (reg:CC FLAGS_REG))])])
18330 [(match_scratch:SWI 2 "<r>")
18331 (parallel [(set (match_operand:SWI 0 "register_operand")
18332 (match_operator:SWI 3 "arith_or_logical_operator"
18333 [(match_operand:SWI 1 "memory_operand")
18335 (clobber (reg:CC FLAGS_REG))])]
18336 "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
18337 [(set (match_dup 2) (match_dup 1))
18338 (parallel [(set (match_dup 0)
18339 (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
18340 (clobber (reg:CC FLAGS_REG))])])
18342 ;; Prefer Load+RegOp to Mov+MemOp. Watch out for cases when
18343 ;; the memory address refers to the destination of the load!
18346 [(set (match_operand:SWI 0 "general_reg_operand")
18347 (match_operand:SWI 1 "general_reg_operand"))
18348 (parallel [(set (match_dup 0)
18349 (match_operator:SWI 3 "commutative_operator"
18351 (match_operand:SWI 2 "memory_operand")]))
18352 (clobber (reg:CC FLAGS_REG))])]
18353 "REGNO (operands[0]) != REGNO (operands[1])
18354 && (<MODE>mode != QImode
18355 || any_QIreg_operand (operands[1], QImode))"
18356 [(set (match_dup 0) (match_dup 4))
18357 (parallel [(set (match_dup 0)
18358 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))
18359 (clobber (reg:CC FLAGS_REG))])]
18360 "operands[4] = replace_rtx (operands[2], operands[0], operands[1], true);")
18363 [(set (match_operand 0 "mmx_reg_operand")
18364 (match_operand 1 "mmx_reg_operand"))
18366 (match_operator 3 "commutative_operator"
18368 (match_operand 2 "memory_operand")]))]
18369 "REGNO (operands[0]) != REGNO (operands[1])"
18370 [(set (match_dup 0) (match_dup 2))
18372 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))])
18375 [(set (match_operand 0 "sse_reg_operand")
18376 (match_operand 1 "sse_reg_operand"))
18378 (match_operator 3 "commutative_operator"
18380 (match_operand 2 "memory_operand")]))]
18381 "REGNO (operands[0]) != REGNO (operands[1])"
18382 [(set (match_dup 0) (match_dup 2))
18384 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))])
18386 ; Don't do logical operations with memory outputs
18388 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
18389 ; instruction into two 1-uop insns plus a 2-uop insn. That last has
18390 ; the same decoder scheduling characteristics as the original.
18393 [(match_scratch:SWI 2 "<r>")
18394 (parallel [(set (match_operand:SWI 0 "memory_operand")
18395 (match_operator:SWI 3 "arith_or_logical_operator"
18397 (match_operand:SWI 1 "<nonmemory_operand>")]))
18398 (clobber (reg:CC FLAGS_REG))])]
18399 "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())"
18400 [(set (match_dup 2) (match_dup 0))
18401 (parallel [(set (match_dup 2)
18402 (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
18403 (clobber (reg:CC FLAGS_REG))])
18404 (set (match_dup 0) (match_dup 2))])
18407 [(match_scratch:SWI 2 "<r>")
18408 (parallel [(set (match_operand:SWI 0 "memory_operand")
18409 (match_operator:SWI 3 "arith_or_logical_operator"
18410 [(match_operand:SWI 1 "<nonmemory_operand>")
18412 (clobber (reg:CC FLAGS_REG))])]
18413 "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())"
18414 [(set (match_dup 2) (match_dup 0))
18415 (parallel [(set (match_dup 2)
18416 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
18417 (clobber (reg:CC FLAGS_REG))])
18418 (set (match_dup 0) (match_dup 2))])
18420 ;; Attempt to use arith or logical operations with memory outputs with
18421 ;; setting of flags.
18423 [(set (match_operand:SWI 0 "register_operand")
18424 (match_operand:SWI 1 "memory_operand"))
18425 (parallel [(set (match_dup 0)
18426 (match_operator:SWI 3 "plusminuslogic_operator"
18428 (match_operand:SWI 2 "<nonmemory_operand>")]))
18429 (clobber (reg:CC FLAGS_REG))])
18430 (set (match_dup 1) (match_dup 0))
18431 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
18432 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
18433 && peep2_reg_dead_p (4, operands[0])
18434 && !reg_overlap_mentioned_p (operands[0], operands[1])
18435 && !reg_overlap_mentioned_p (operands[0], operands[2])
18436 && (<MODE>mode != QImode
18437 || immediate_operand (operands[2], QImode)
18438 || any_QIreg_operand (operands[2], QImode))
18439 && ix86_match_ccmode (peep2_next_insn (3),
18440 (GET_CODE (operands[3]) == PLUS
18441 || GET_CODE (operands[3]) == MINUS)
18442 ? CCGOCmode : CCNOmode)"
18443 [(parallel [(set (match_dup 4) (match_dup 6))
18444 (set (match_dup 1) (match_dup 5))])]
18446 operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
18448 = gen_rtx_fmt_ee (GET_CODE (operands[3]), GET_MODE (operands[3]),
18449 copy_rtx (operands[1]),
18452 = gen_rtx_COMPARE (GET_MODE (operands[4]),
18453 copy_rtx (operands[5]),
18457 ;; Likewise for cmpelim optimized pattern.
18459 [(set (match_operand:SWI 0 "register_operand")
18460 (match_operand:SWI 1 "memory_operand"))
18461 (parallel [(set (reg FLAGS_REG)
18462 (compare (match_operator:SWI 3 "plusminuslogic_operator"
18464 (match_operand:SWI 2 "<nonmemory_operand>")])
18466 (set (match_dup 0) (match_dup 3))])
18467 (set (match_dup 1) (match_dup 0))]
18468 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
18469 && peep2_reg_dead_p (3, operands[0])
18470 && !reg_overlap_mentioned_p (operands[0], operands[1])
18471 && !reg_overlap_mentioned_p (operands[0], operands[2])
18472 && ix86_match_ccmode (peep2_next_insn (1),
18473 (GET_CODE (operands[3]) == PLUS
18474 || GET_CODE (operands[3]) == MINUS)
18475 ? CCGOCmode : CCNOmode)"
18476 [(parallel [(set (match_dup 4) (match_dup 6))
18477 (set (match_dup 1) (match_dup 5))])]
18479 operands[4] = SET_DEST (XVECEXP (PATTERN (peep2_next_insn (1)), 0, 0));
18481 = gen_rtx_fmt_ee (GET_CODE (operands[3]), GET_MODE (operands[3]),
18482 copy_rtx (operands[1]), operands[2]);
18484 = gen_rtx_COMPARE (GET_MODE (operands[4]), copy_rtx (operands[5]),
18488 ;; Likewise for instances where we have a lea pattern.
18490 [(set (match_operand:SWI 0 "register_operand")
18491 (match_operand:SWI 1 "memory_operand"))
18492 (set (match_operand:<LEAMODE> 3 "register_operand")
18493 (plus:<LEAMODE> (match_operand:<LEAMODE> 4 "register_operand")
18494 (match_operand:<LEAMODE> 2 "<nonmemory_operand>")))
18495 (set (match_dup 1) (match_operand:SWI 5 "register_operand"))
18496 (set (reg FLAGS_REG) (compare (match_dup 5) (const_int 0)))]
18497 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
18498 && REGNO (operands[4]) == REGNO (operands[0])
18499 && REGNO (operands[5]) == REGNO (operands[3])
18500 && peep2_reg_dead_p (4, operands[3])
18501 && ((REGNO (operands[0]) == REGNO (operands[3]))
18502 || peep2_reg_dead_p (2, operands[0]))
18503 && !reg_overlap_mentioned_p (operands[0], operands[1])
18504 && !reg_overlap_mentioned_p (operands[3], operands[1])
18505 && !reg_overlap_mentioned_p (operands[0], operands[2])
18506 && (<MODE>mode != QImode
18507 || immediate_operand (operands[2], QImode)
18508 || any_QIreg_operand (operands[2], QImode))
18509 && ix86_match_ccmode (peep2_next_insn (3), CCGOCmode)"
18510 [(parallel [(set (match_dup 6) (match_dup 8))
18511 (set (match_dup 1) (match_dup 7))])]
18513 operands[6] = SET_DEST (PATTERN (peep2_next_insn (3)));
18515 = gen_rtx_PLUS (<MODE>mode,
18516 copy_rtx (operands[1]),
18517 gen_lowpart (<MODE>mode, operands[2]));
18519 = gen_rtx_COMPARE (GET_MODE (operands[6]),
18520 copy_rtx (operands[7]),
18525 [(parallel [(set (match_operand:SWI 0 "register_operand")
18526 (match_operator:SWI 2 "plusminuslogic_operator"
18528 (match_operand:SWI 1 "memory_operand")]))
18529 (clobber (reg:CC FLAGS_REG))])
18530 (set (match_dup 1) (match_dup 0))
18531 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
18532 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
18533 && COMMUTATIVE_ARITH_P (operands[2])
18534 && peep2_reg_dead_p (3, operands[0])
18535 && !reg_overlap_mentioned_p (operands[0], operands[1])
18536 && ix86_match_ccmode (peep2_next_insn (2),
18537 GET_CODE (operands[2]) == PLUS
18538 ? CCGOCmode : CCNOmode)"
18539 [(parallel [(set (match_dup 3) (match_dup 5))
18540 (set (match_dup 1) (match_dup 4))])]
18542 operands[3] = SET_DEST (PATTERN (peep2_next_insn (2)));
18544 = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
18545 copy_rtx (operands[1]),
18548 = gen_rtx_COMPARE (GET_MODE (operands[3]),
18549 copy_rtx (operands[4]),
18553 ;; Likewise for cmpelim optimized pattern.
18555 [(parallel [(set (reg FLAGS_REG)
18556 (compare (match_operator:SWI 2 "plusminuslogic_operator"
18557 [(match_operand:SWI 0 "register_operand")
18558 (match_operand:SWI 1 "memory_operand")])
18560 (set (match_dup 0) (match_dup 2))])
18561 (set (match_dup 1) (match_dup 0))]
18562 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
18563 && COMMUTATIVE_ARITH_P (operands[2])
18564 && peep2_reg_dead_p (2, operands[0])
18565 && !reg_overlap_mentioned_p (operands[0], operands[1])
18566 && ix86_match_ccmode (peep2_next_insn (0),
18567 GET_CODE (operands[2]) == PLUS
18568 ? CCGOCmode : CCNOmode)"
18569 [(parallel [(set (match_dup 3) (match_dup 5))
18570 (set (match_dup 1) (match_dup 4))])]
18572 operands[3] = SET_DEST (XVECEXP (PATTERN (peep2_next_insn (0)), 0, 0));
18574 = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
18575 copy_rtx (operands[1]), operands[0]);
18577 = gen_rtx_COMPARE (GET_MODE (operands[3]), copy_rtx (operands[4]),
18582 [(set (match_operand:SWI12 0 "register_operand")
18583 (match_operand:SWI12 1 "memory_operand"))
18584 (parallel [(set (match_operand:SI 4 "register_operand")
18585 (match_operator:SI 3 "plusminuslogic_operator"
18587 (match_operand:SI 2 "nonmemory_operand")]))
18588 (clobber (reg:CC FLAGS_REG))])
18589 (set (match_dup 1) (match_dup 0))
18590 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
18591 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
18592 && REGNO (operands[0]) == REGNO (operands[4])
18593 && peep2_reg_dead_p (4, operands[0])
18594 && (<MODE>mode != QImode
18595 || immediate_operand (operands[2], SImode)
18596 || any_QIreg_operand (operands[2], SImode))
18597 && !reg_overlap_mentioned_p (operands[0], operands[1])
18598 && !reg_overlap_mentioned_p (operands[0], operands[2])
18599 && ix86_match_ccmode (peep2_next_insn (3),
18600 (GET_CODE (operands[3]) == PLUS
18601 || GET_CODE (operands[3]) == MINUS)
18602 ? CCGOCmode : CCNOmode)"
18603 [(parallel [(set (match_dup 5) (match_dup 7))
18604 (set (match_dup 1) (match_dup 6))])]
18606 operands[5] = SET_DEST (PATTERN (peep2_next_insn (3)));
18608 = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
18609 copy_rtx (operands[1]),
18610 gen_lowpart (<MODE>mode, operands[2]));
18612 = gen_rtx_COMPARE (GET_MODE (operands[5]),
18613 copy_rtx (operands[6]),
18617 ;; peephole2 comes before regcprop, so deal also with a case that
18618 ;; would be cleaned up by regcprop.
18620 [(set (match_operand:SWI 0 "register_operand")
18621 (match_operand:SWI 1 "memory_operand"))
18622 (parallel [(set (match_dup 0)
18623 (match_operator:SWI 3 "plusminuslogic_operator"
18625 (match_operand:SWI 2 "<nonmemory_operand>")]))
18626 (clobber (reg:CC FLAGS_REG))])
18627 (set (match_operand:SWI 4 "register_operand") (match_dup 0))
18628 (set (match_dup 1) (match_dup 4))
18629 (set (reg FLAGS_REG) (compare (match_dup 4) (const_int 0)))]
18630 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
18631 && peep2_reg_dead_p (3, operands[0])
18632 && peep2_reg_dead_p (5, operands[4])
18633 && !reg_overlap_mentioned_p (operands[0], operands[1])
18634 && !reg_overlap_mentioned_p (operands[0], operands[2])
18635 && !reg_overlap_mentioned_p (operands[4], operands[1])
18636 && (<MODE>mode != QImode
18637 || immediate_operand (operands[2], QImode)
18638 || any_QIreg_operand (operands[2], QImode))
18639 && ix86_match_ccmode (peep2_next_insn (4),
18640 (GET_CODE (operands[3]) == PLUS
18641 || GET_CODE (operands[3]) == MINUS)
18642 ? CCGOCmode : CCNOmode)"
18643 [(parallel [(set (match_dup 5) (match_dup 7))
18644 (set (match_dup 1) (match_dup 6))])]
18646 operands[5] = SET_DEST (PATTERN (peep2_next_insn (4)));
18648 = gen_rtx_fmt_ee (GET_CODE (operands[3]), GET_MODE (operands[3]),
18649 copy_rtx (operands[1]),
18652 = gen_rtx_COMPARE (GET_MODE (operands[5]),
18653 copy_rtx (operands[6]),
18658 [(set (match_operand:SWI12 0 "register_operand")
18659 (match_operand:SWI12 1 "memory_operand"))
18660 (parallel [(set (match_operand:SI 4 "register_operand")
18661 (match_operator:SI 3 "plusminuslogic_operator"
18663 (match_operand:SI 2 "nonmemory_operand")]))
18664 (clobber (reg:CC FLAGS_REG))])
18665 (set (match_operand:SWI12 5 "register_operand") (match_dup 0))
18666 (set (match_dup 1) (match_dup 5))
18667 (set (reg FLAGS_REG) (compare (match_dup 5) (const_int 0)))]
18668 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
18669 && REGNO (operands[0]) == REGNO (operands[4])
18670 && peep2_reg_dead_p (3, operands[0])
18671 && peep2_reg_dead_p (5, operands[5])
18672 && (<MODE>mode != QImode
18673 || immediate_operand (operands[2], SImode)
18674 || any_QIreg_operand (operands[2], SImode))
18675 && !reg_overlap_mentioned_p (operands[0], operands[1])
18676 && !reg_overlap_mentioned_p (operands[0], operands[2])
18677 && !reg_overlap_mentioned_p (operands[5], operands[1])
18678 && ix86_match_ccmode (peep2_next_insn (4),
18679 (GET_CODE (operands[3]) == PLUS
18680 || GET_CODE (operands[3]) == MINUS)
18681 ? CCGOCmode : CCNOmode)"
18682 [(parallel [(set (match_dup 6) (match_dup 8))
18683 (set (match_dup 1) (match_dup 7))])]
18685 operands[6] = SET_DEST (PATTERN (peep2_next_insn (4)));
18687 = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
18688 copy_rtx (operands[1]),
18689 gen_lowpart (<MODE>mode, operands[2]));
18691 = gen_rtx_COMPARE (GET_MODE (operands[6]),
18692 copy_rtx (operands[7]),
18696 ;; Likewise for cmpelim optimized pattern.
18698 [(set (match_operand:SWI 0 "register_operand")
18699 (match_operand:SWI 1 "memory_operand"))
18700 (parallel [(set (reg FLAGS_REG)
18701 (compare (match_operator:SWI 3 "plusminuslogic_operator"
18703 (match_operand:SWI 2 "<nonmemory_operand>")])
18705 (set (match_dup 0) (match_dup 3))])
18706 (set (match_operand:SWI 4 "register_operand") (match_dup 0))
18707 (set (match_dup 1) (match_dup 4))]
18708 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
18709 && peep2_reg_dead_p (3, operands[0])
18710 && peep2_reg_dead_p (4, operands[4])
18711 && !reg_overlap_mentioned_p (operands[0], operands[1])
18712 && !reg_overlap_mentioned_p (operands[0], operands[2])
18713 && !reg_overlap_mentioned_p (operands[4], operands[1])
18714 && ix86_match_ccmode (peep2_next_insn (1),
18715 (GET_CODE (operands[3]) == PLUS
18716 || GET_CODE (operands[3]) == MINUS)
18717 ? CCGOCmode : CCNOmode)"
18718 [(parallel [(set (match_dup 5) (match_dup 7))
18719 (set (match_dup 1) (match_dup 6))])]
18721 operands[5] = SET_DEST (XVECEXP (PATTERN (peep2_next_insn (1)), 0, 0));
18723 = gen_rtx_fmt_ee (GET_CODE (operands[3]), GET_MODE (operands[3]),
18724 copy_rtx (operands[1]), operands[2]);
18726 = gen_rtx_COMPARE (GET_MODE (operands[5]), copy_rtx (operands[6]),
18730 ;; Special cases for xor, where (x ^= y) != 0 is (misoptimized)
18731 ;; into x = z; x ^= y; x != z
18733 [(set (match_operand:SWI 0 "register_operand")
18734 (match_operand:SWI 1 "memory_operand"))
18735 (set (match_operand:SWI 3 "register_operand") (match_dup 0))
18736 (parallel [(set (match_operand:SWI 4 "register_operand")
18737 (xor:SWI (match_dup 4)
18738 (match_operand:SWI 2 "<nonmemory_operand>")))
18739 (clobber (reg:CC FLAGS_REG))])
18740 (set (match_dup 1) (match_dup 4))
18741 (set (reg:CCZ FLAGS_REG)
18742 (compare:CCZ (match_operand:SWI 5 "register_operand")
18743 (match_operand:SWI 6 "<nonmemory_operand>")))]
18744 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
18745 && (REGNO (operands[4]) == REGNO (operands[0])
18746 || REGNO (operands[4]) == REGNO (operands[3]))
18747 && (rtx_equal_p (operands[REGNO (operands[4]) == REGNO (operands[0])
18748 ? 3 : 0], operands[5])
18749 ? rtx_equal_p (operands[2], operands[6])
18750 : rtx_equal_p (operands[2], operands[5])
18751 && rtx_equal_p (operands[REGNO (operands[4]) == REGNO (operands[0])
18752 ? 3 : 0], operands[6]))
18753 && peep2_reg_dead_p (4, operands[4])
18754 && peep2_reg_dead_p (5, operands[REGNO (operands[4]) == REGNO (operands[0])
18756 && !reg_overlap_mentioned_p (operands[0], operands[1])
18757 && !reg_overlap_mentioned_p (operands[0], operands[2])
18758 && !reg_overlap_mentioned_p (operands[3], operands[0])
18759 && !reg_overlap_mentioned_p (operands[3], operands[1])
18760 && !reg_overlap_mentioned_p (operands[3], operands[2])
18761 && (<MODE>mode != QImode
18762 || immediate_operand (operands[2], QImode)
18763 || any_QIreg_operand (operands[2], QImode))"
18764 [(parallel [(set (match_dup 7) (match_dup 9))
18765 (set (match_dup 1) (match_dup 8))])]
18767 operands[7] = SET_DEST (PATTERN (peep2_next_insn (4)));
18768 operands[8] = gen_rtx_XOR (<MODE>mode, copy_rtx (operands[1]),
18771 = gen_rtx_COMPARE (GET_MODE (operands[7]),
18772 copy_rtx (operands[8]),
18777 [(set (match_operand:SWI12 0 "register_operand")
18778 (match_operand:SWI12 1 "memory_operand"))
18779 (set (match_operand:SWI12 3 "register_operand") (match_dup 0))
18780 (parallel [(set (match_operand:SI 4 "register_operand")
18781 (xor:SI (match_dup 4)
18782 (match_operand:SI 2 "<nonmemory_operand>")))
18783 (clobber (reg:CC FLAGS_REG))])
18784 (set (match_dup 1) (match_operand:SWI12 5 "register_operand"))
18785 (set (reg:CCZ FLAGS_REG)
18786 (compare:CCZ (match_operand:SWI12 6 "register_operand")
18787 (match_operand:SWI12 7 "<nonmemory_operand>")))]
18788 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
18789 && (REGNO (operands[5]) == REGNO (operands[0])
18790 || REGNO (operands[5]) == REGNO (operands[3]))
18791 && REGNO (operands[5]) == REGNO (operands[4])
18792 && (rtx_equal_p (operands[REGNO (operands[5]) == REGNO (operands[0])
18793 ? 3 : 0], operands[6])
18794 ? (REG_P (operands[2])
18795 ? REG_P (operands[7]) && REGNO (operands[2]) == REGNO (operands[7])
18796 : rtx_equal_p (operands[2], operands[7]))
18797 : (rtx_equal_p (operands[REGNO (operands[5]) == REGNO (operands[0])
18798 ? 3 : 0], operands[7])
18799 && REG_P (operands[2])
18800 && REGNO (operands[2]) == REGNO (operands[6])))
18801 && peep2_reg_dead_p (4, operands[5])
18802 && peep2_reg_dead_p (5, operands[REGNO (operands[5]) == REGNO (operands[0])
18804 && !reg_overlap_mentioned_p (operands[0], operands[1])
18805 && !reg_overlap_mentioned_p (operands[0], operands[2])
18806 && !reg_overlap_mentioned_p (operands[3], operands[0])
18807 && !reg_overlap_mentioned_p (operands[3], operands[1])
18808 && !reg_overlap_mentioned_p (operands[3], operands[2])
18809 && (<MODE>mode != QImode
18810 || immediate_operand (operands[2], SImode)
18811 || any_QIreg_operand (operands[2], SImode))"
18812 [(parallel [(set (match_dup 8) (match_dup 10))
18813 (set (match_dup 1) (match_dup 9))])]
18815 operands[8] = SET_DEST (PATTERN (peep2_next_insn (4)));
18816 operands[9] = gen_rtx_XOR (<MODE>mode, copy_rtx (operands[1]),
18817 gen_lowpart (<MODE>mode, operands[2]));
18819 = gen_rtx_COMPARE (GET_MODE (operands[8]),
18820 copy_rtx (operands[9]),
18824 ;; Attempt to optimize away memory stores of values the memory already
18825 ;; has. See PR79593.
18827 [(set (match_operand 0 "register_operand")
18828 (match_operand 1 "memory_operand"))
18829 (set (match_operand 2 "memory_operand") (match_dup 0))]
18830 "!MEM_VOLATILE_P (operands[1])
18831 && !MEM_VOLATILE_P (operands[2])
18832 && rtx_equal_p (operands[1], operands[2])
18833 && !reg_overlap_mentioned_p (operands[0], operands[2])"
18834 [(set (match_dup 0) (match_dup 1))])
18836 ;; Attempt to always use XOR for zeroing registers (including FP modes).
18838 [(set (match_operand 0 "general_reg_operand")
18839 (match_operand 1 "const0_operand"))]
18840 "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
18841 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
18842 && peep2_regno_dead_p (0, FLAGS_REG)"
18843 [(parallel [(set (match_dup 0) (const_int 0))
18844 (clobber (reg:CC FLAGS_REG))])]
18845 "operands[0] = gen_lowpart (word_mode, operands[0]);")
18848 [(set (strict_low_part (match_operand:SWI12 0 "general_reg_operand"))
18850 "(! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
18851 && peep2_regno_dead_p (0, FLAGS_REG)"
18852 [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
18853 (clobber (reg:CC FLAGS_REG))])])
18855 ;; For HI, SI and DI modes, or $-1,reg is smaller than mov $-1,reg.
18857 [(set (match_operand:SWI248 0 "general_reg_operand")
18859 "(TARGET_MOVE_M1_VIA_OR || optimize_insn_for_size_p ())
18860 && peep2_regno_dead_p (0, FLAGS_REG)"
18861 [(parallel [(set (match_dup 0) (const_int -1))
18862 (clobber (reg:CC FLAGS_REG))])]
18864 if (<MODE_SIZE> < GET_MODE_SIZE (SImode))
18865 operands[0] = gen_lowpart (SImode, operands[0]);
18868 ;; Attempt to convert simple lea to add/shift.
18869 ;; These can be created by move expanders.
18870 ;; Disable PLUS peepholes on TARGET_OPT_AGU, since all
18871 ;; relevant lea instructions were already split.
18874 [(set (match_operand:SWI48 0 "register_operand")
18875 (plus:SWI48 (match_dup 0)
18876 (match_operand:SWI48 1 "<nonmemory_operand>")))]
18878 && peep2_regno_dead_p (0, FLAGS_REG)"
18879 [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1)))
18880 (clobber (reg:CC FLAGS_REG))])])
18883 [(set (match_operand:SWI48 0 "register_operand")
18884 (plus:SWI48 (match_operand:SWI48 1 "<nonmemory_operand>")
18887 && peep2_regno_dead_p (0, FLAGS_REG)"
18888 [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1)))
18889 (clobber (reg:CC FLAGS_REG))])])
18892 [(set (match_operand:DI 0 "register_operand")
18894 (plus:SI (match_operand:SI 1 "register_operand")
18895 (match_operand:SI 2 "nonmemory_operand"))))]
18896 "TARGET_64BIT && !TARGET_OPT_AGU
18897 && REGNO (operands[0]) == REGNO (operands[1])
18898 && peep2_regno_dead_p (0, FLAGS_REG)"
18899 [(parallel [(set (match_dup 0)
18900 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))
18901 (clobber (reg:CC FLAGS_REG))])])
18904 [(set (match_operand:DI 0 "register_operand")
18906 (plus:SI (match_operand:SI 1 "nonmemory_operand")
18907 (match_operand:SI 2 "register_operand"))))]
18908 "TARGET_64BIT && !TARGET_OPT_AGU
18909 && REGNO (operands[0]) == REGNO (operands[2])
18910 && peep2_regno_dead_p (0, FLAGS_REG)"
18911 [(parallel [(set (match_dup 0)
18912 (zero_extend:DI (plus:SI (match_dup 2) (match_dup 1))))
18913 (clobber (reg:CC FLAGS_REG))])])
18916 [(set (match_operand:SWI48 0 "register_operand")
18917 (mult:SWI48 (match_dup 0)
18918 (match_operand:SWI48 1 "const_int_operand")))]
18919 "pow2p_hwi (INTVAL (operands[1]))
18920 && peep2_regno_dead_p (0, FLAGS_REG)"
18921 [(parallel [(set (match_dup 0) (ashift:SWI48 (match_dup 0) (match_dup 1)))
18922 (clobber (reg:CC FLAGS_REG))])]
18923 "operands[1] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
18926 [(set (match_operand:DI 0 "register_operand")
18928 (mult:SI (match_operand:SI 1 "register_operand")
18929 (match_operand:SI 2 "const_int_operand"))))]
18931 && pow2p_hwi (INTVAL (operands[2]))
18932 && REGNO (operands[0]) == REGNO (operands[1])
18933 && peep2_regno_dead_p (0, FLAGS_REG)"
18934 [(parallel [(set (match_dup 0)
18935 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))
18936 (clobber (reg:CC FLAGS_REG))])]
18937 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
18939 ;; The ESP adjustments can be done by the push and pop instructions. Resulting
18940 ;; code is shorter, since push is only 1 byte, while add imm, %esp is 3 bytes.
18941 ;; On many CPUs it is also faster, since special hardware to avoid esp
18942 ;; dependencies is present.
18944 ;; While some of these conversions may be done using splitters, we use
18945 ;; peepholes in order to allow combine_stack_adjustments pass to see
18946 ;; nonobfuscated RTL.
18948 ;; Convert prologue esp subtractions to push.
18949 ;; We need register to push. In order to keep verify_flow_info happy we have
18951 ;; - use scratch and clobber it in order to avoid dependencies
18952 ;; - use already live register
18953 ;; We can't use the second way right now, since there is no reliable way how to
18954 ;; verify that given register is live. First choice will also most likely in
18955 ;; fewer dependencies. On the place of esp adjustments it is very likely that
18956 ;; call clobbered registers are dead. We may want to use base pointer as an
18957 ;; alternative when no register is available later.
18960 [(match_scratch:W 1 "r")
18961 (parallel [(set (reg:P SP_REG)
18962 (plus:P (reg:P SP_REG)
18963 (match_operand:P 0 "const_int_operand")))
18964 (clobber (reg:CC FLAGS_REG))
18965 (clobber (mem:BLK (scratch)))])]
18966 "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
18967 && INTVAL (operands[0]) == -GET_MODE_SIZE (word_mode)
18968 && ix86_red_zone_size == 0"
18969 [(clobber (match_dup 1))
18970 (parallel [(set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
18971 (clobber (mem:BLK (scratch)))])])
18974 [(match_scratch:W 1 "r")
18975 (parallel [(set (reg:P SP_REG)
18976 (plus:P (reg:P SP_REG)
18977 (match_operand:P 0 "const_int_operand")))
18978 (clobber (reg:CC FLAGS_REG))
18979 (clobber (mem:BLK (scratch)))])]
18980 "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
18981 && INTVAL (operands[0]) == -2*GET_MODE_SIZE (word_mode)
18982 && ix86_red_zone_size == 0"
18983 [(clobber (match_dup 1))
18984 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
18985 (parallel [(set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
18986 (clobber (mem:BLK (scratch)))])])
18988 ;; Convert esp subtractions to push.
18990 [(match_scratch:W 1 "r")
18991 (parallel [(set (reg:P SP_REG)
18992 (plus:P (reg:P SP_REG)
18993 (match_operand:P 0 "const_int_operand")))
18994 (clobber (reg:CC FLAGS_REG))])]
18995 "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
18996 && INTVAL (operands[0]) == -GET_MODE_SIZE (word_mode)
18997 && ix86_red_zone_size == 0"
18998 [(clobber (match_dup 1))
18999 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
19002 [(match_scratch:W 1 "r")
19003 (parallel [(set (reg:P SP_REG)
19004 (plus:P (reg:P SP_REG)
19005 (match_operand:P 0 "const_int_operand")))
19006 (clobber (reg:CC FLAGS_REG))])]
19007 "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
19008 && INTVAL (operands[0]) == -2*GET_MODE_SIZE (word_mode)
19009 && ix86_red_zone_size == 0"
19010 [(clobber (match_dup 1))
19011 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
19012 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
19014 ;; Convert epilogue deallocator to pop.
19016 [(match_scratch:W 1 "r")
19017 (parallel [(set (reg:P SP_REG)
19018 (plus:P (reg:P SP_REG)
19019 (match_operand:P 0 "const_int_operand")))
19020 (clobber (reg:CC FLAGS_REG))
19021 (clobber (mem:BLK (scratch)))])]
19022 "(TARGET_SINGLE_POP || optimize_insn_for_size_p ())
19023 && INTVAL (operands[0]) == GET_MODE_SIZE (word_mode)"
19024 [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
19025 (clobber (mem:BLK (scratch)))])])
19027 ;; Two pops case is tricky, since pop causes dependency
19028 ;; on destination register. We use two registers if available.
19030 [(match_scratch:W 1 "r")
19031 (match_scratch:W 2 "r")
19032 (parallel [(set (reg:P SP_REG)
19033 (plus:P (reg:P SP_REG)
19034 (match_operand:P 0 "const_int_operand")))
19035 (clobber (reg:CC FLAGS_REG))
19036 (clobber (mem:BLK (scratch)))])]
19037 "(TARGET_DOUBLE_POP || optimize_insn_for_size_p ())
19038 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
19039 [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
19040 (clobber (mem:BLK (scratch)))])
19041 (set (match_dup 2) (mem:W (post_inc:P (reg:P SP_REG))))])
19044 [(match_scratch:W 1 "r")
19045 (parallel [(set (reg:P SP_REG)
19046 (plus:P (reg:P SP_REG)
19047 (match_operand:P 0 "const_int_operand")))
19048 (clobber (reg:CC FLAGS_REG))
19049 (clobber (mem:BLK (scratch)))])]
19050 "optimize_insn_for_size_p ()
19051 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
19052 [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
19053 (clobber (mem:BLK (scratch)))])
19054 (set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
19056 ;; Convert esp additions to pop.
19058 [(match_scratch:W 1 "r")
19059 (parallel [(set (reg:P SP_REG)
19060 (plus:P (reg:P SP_REG)
19061 (match_operand:P 0 "const_int_operand")))
19062 (clobber (reg:CC FLAGS_REG))])]
19063 "INTVAL (operands[0]) == GET_MODE_SIZE (word_mode)"
19064 [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
19066 ;; Two pops case is tricky, since pop causes dependency
19067 ;; on destination register. We use two registers if available.
19069 [(match_scratch:W 1 "r")
19070 (match_scratch:W 2 "r")
19071 (parallel [(set (reg:P SP_REG)
19072 (plus:P (reg:P SP_REG)
19073 (match_operand:P 0 "const_int_operand")))
19074 (clobber (reg:CC FLAGS_REG))])]
19075 "INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
19076 [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
19077 (set (match_dup 2) (mem:W (post_inc:P (reg:P SP_REG))))])
19080 [(match_scratch:W 1 "r")
19081 (parallel [(set (reg:P SP_REG)
19082 (plus:P (reg:P SP_REG)
19083 (match_operand:P 0 "const_int_operand")))
19084 (clobber (reg:CC FLAGS_REG))])]
19085 "optimize_insn_for_size_p ()
19086 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
19087 [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
19088 (set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
19090 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
19091 ;; required and register dies. Similarly for 128 to -128.
19093 [(set (match_operand 0 "flags_reg_operand")
19094 (match_operator 1 "compare_operator"
19095 [(match_operand 2 "register_operand")
19096 (match_operand 3 "const_int_operand")]))]
19097 "(((!TARGET_FUSE_CMP_AND_BRANCH || optimize_insn_for_size_p ())
19098 && incdec_operand (operands[3], GET_MODE (operands[3])))
19099 || (!TARGET_FUSE_CMP_AND_BRANCH
19100 && INTVAL (operands[3]) == 128))
19101 && ix86_match_ccmode (insn, CCGCmode)
19102 && peep2_reg_dead_p (1, operands[2])"
19103 [(parallel [(set (match_dup 0)
19104 (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
19105 (clobber (match_dup 2))])])
19107 ;; Convert imul by three, five and nine into lea
19110 [(set (match_operand:SWI48 0 "register_operand")
19111 (mult:SWI48 (match_operand:SWI48 1 "register_operand")
19112 (match_operand:SWI48 2 "const359_operand")))
19113 (clobber (reg:CC FLAGS_REG))])]
19114 "!TARGET_PARTIAL_REG_STALL
19115 || <MODE>mode == SImode
19116 || optimize_function_for_size_p (cfun)"
19117 [(set (match_dup 0)
19118 (plus:SWI48 (mult:SWI48 (match_dup 1) (match_dup 2))
19120 "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
19124 [(set (match_operand:SWI48 0 "register_operand")
19125 (mult:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
19126 (match_operand:SWI48 2 "const359_operand")))
19127 (clobber (reg:CC FLAGS_REG))])]
19128 "optimize_insn_for_speed_p ()
19129 && (!TARGET_PARTIAL_REG_STALL || <MODE>mode == SImode)"
19130 [(set (match_dup 0) (match_dup 1))
19132 (plus:SWI48 (mult:SWI48 (match_dup 0) (match_dup 2))
19134 "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
19136 ;; imul $32bit_imm, mem, reg is vector decoded, while
19137 ;; imul $32bit_imm, reg, reg is direct decoded.
19139 [(match_scratch:SWI48 3 "r")
19140 (parallel [(set (match_operand:SWI48 0 "register_operand")
19141 (mult:SWI48 (match_operand:SWI48 1 "memory_operand")
19142 (match_operand:SWI48 2 "immediate_operand")))
19143 (clobber (reg:CC FLAGS_REG))])]
19144 "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
19145 && !satisfies_constraint_K (operands[2])"
19146 [(set (match_dup 3) (match_dup 1))
19147 (parallel [(set (match_dup 0) (mult:SWI48 (match_dup 3) (match_dup 2)))
19148 (clobber (reg:CC FLAGS_REG))])])
19151 [(match_scratch:SI 3 "r")
19152 (parallel [(set (match_operand:DI 0 "register_operand")
19154 (mult:SI (match_operand:SI 1 "memory_operand")
19155 (match_operand:SI 2 "immediate_operand"))))
19156 (clobber (reg:CC FLAGS_REG))])]
19158 && TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
19159 && !satisfies_constraint_K (operands[2])"
19160 [(set (match_dup 3) (match_dup 1))
19161 (parallel [(set (match_dup 0)
19162 (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
19163 (clobber (reg:CC FLAGS_REG))])])
19165 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
19166 ;; Convert it into imul reg, reg
19167 ;; It would be better to force assembler to encode instruction using long
19168 ;; immediate, but there is apparently no way to do so.
19170 [(parallel [(set (match_operand:SWI248 0 "register_operand")
19172 (match_operand:SWI248 1 "nonimmediate_operand")
19173 (match_operand:SWI248 2 "const_int_operand")))
19174 (clobber (reg:CC FLAGS_REG))])
19175 (match_scratch:SWI248 3 "r")]
19176 "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
19177 && satisfies_constraint_K (operands[2])"
19178 [(set (match_dup 3) (match_dup 2))
19179 (parallel [(set (match_dup 0) (mult:SWI248 (match_dup 0) (match_dup 3)))
19180 (clobber (reg:CC FLAGS_REG))])]
19182 if (!rtx_equal_p (operands[0], operands[1]))
19183 emit_move_insn (operands[0], operands[1]);
19186 ;; After splitting up read-modify operations, array accesses with memory
19187 ;; operands might end up in form:
19189 ;; movl 4(%esp), %edx
19191 ;; instead of pre-splitting:
19193 ;; addl 4(%esp), %eax
19195 ;; movl 4(%esp), %edx
19196 ;; leal (%edx,%eax,4), %eax
19199 [(match_scratch:W 5 "r")
19200 (parallel [(set (match_operand 0 "register_operand")
19201 (ashift (match_operand 1 "register_operand")
19202 (match_operand 2 "const_int_operand")))
19203 (clobber (reg:CC FLAGS_REG))])
19204 (parallel [(set (match_operand 3 "register_operand")
19205 (plus (match_dup 0)
19206 (match_operand 4 "x86_64_general_operand")))
19207 (clobber (reg:CC FLAGS_REG))])]
19208 "IN_RANGE (INTVAL (operands[2]), 1, 3)
19209 /* Validate MODE for lea. */
19210 && ((!TARGET_PARTIAL_REG_STALL
19211 && (GET_MODE (operands[0]) == QImode
19212 || GET_MODE (operands[0]) == HImode))
19213 || GET_MODE (operands[0]) == SImode
19214 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
19215 && (rtx_equal_p (operands[0], operands[3])
19216 || peep2_reg_dead_p (2, operands[0]))
19217 /* We reorder load and the shift. */
19218 && !reg_overlap_mentioned_p (operands[0], operands[4])"
19219 [(set (match_dup 5) (match_dup 4))
19220 (set (match_dup 0) (match_dup 1))]
19222 machine_mode op1mode = GET_MODE (operands[1]);
19223 machine_mode mode = op1mode == DImode ? DImode : SImode;
19224 int scale = 1 << INTVAL (operands[2]);
19225 rtx index = gen_lowpart (word_mode, operands[1]);
19226 rtx base = gen_lowpart (word_mode, operands[5]);
19227 rtx dest = gen_lowpart (mode, operands[3]);
19229 operands[1] = gen_rtx_PLUS (word_mode, base,
19230 gen_rtx_MULT (word_mode, index, GEN_INT (scale)));
19231 if (mode != word_mode)
19232 operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
19234 operands[5] = base;
19235 if (op1mode != word_mode)
19236 operands[5] = gen_lowpart (op1mode, operands[5]);
19238 operands[0] = dest;
19241 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
19242 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
19243 ;; caught for use by garbage collectors and the like. Using an insn that
19244 ;; maps to SIGILL makes it more likely the program will rightfully die.
19245 ;; Keeping with tradition, "6" is in honor of #UD.
19246 (define_insn "trap"
19247 [(trap_if (const_int 1) (const_int 6))]
19250 #ifdef HAVE_AS_IX86_UD2
19253 return ASM_SHORT "0x0b0f";
19256 [(set_attr "length" "2")])
19259 [(unspec_volatile [(const_int 0)] UNSPECV_UD2)]
19262 #ifdef HAVE_AS_IX86_UD2
19265 return ASM_SHORT "0x0b0f";
19268 [(set_attr "length" "2")])
19270 (define_expand "prefetch"
19271 [(prefetch (match_operand 0 "address_operand")
19272 (match_operand:SI 1 "const_int_operand")
19273 (match_operand:SI 2 "const_int_operand"))]
19274 "TARGET_3DNOW || TARGET_PREFETCH_SSE || TARGET_PRFCHW || TARGET_PREFETCHWT1"
19276 bool write = INTVAL (operands[1]) != 0;
19277 int locality = INTVAL (operands[2]);
19279 gcc_assert (IN_RANGE (locality, 0, 3));
19281 /* Use 3dNOW prefetch in case we are asking for write prefetch not
19282 supported by SSE counterpart (non-SSE2 athlon machines) or the
19283 SSE prefetch is not available (K6 machines). Otherwise use SSE
19284 prefetch as it allows specifying of locality. */
19288 if (TARGET_PREFETCHWT1)
19289 operands[2] = GEN_INT (MAX (locality, 2));
19290 else if (TARGET_PRFCHW)
19291 operands[2] = GEN_INT (3);
19292 else if (TARGET_3DNOW && !TARGET_SSE2)
19293 operands[2] = GEN_INT (3);
19294 else if (TARGET_PREFETCH_SSE)
19295 operands[1] = const0_rtx;
19298 gcc_assert (TARGET_3DNOW);
19299 operands[2] = GEN_INT (3);
19304 if (TARGET_PREFETCH_SSE)
19308 gcc_assert (TARGET_3DNOW);
19309 operands[2] = GEN_INT (3);
19314 (define_insn "*prefetch_sse"
19315 [(prefetch (match_operand 0 "address_operand" "p")
19317 (match_operand:SI 1 "const_int_operand"))]
19318 "TARGET_PREFETCH_SSE"
19320 static const char * const patterns[4] = {
19321 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
19324 int locality = INTVAL (operands[1]);
19325 gcc_assert (IN_RANGE (locality, 0, 3));
19327 return patterns[locality];
19329 [(set_attr "type" "sse")
19330 (set_attr "atom_sse_attr" "prefetch")
19331 (set (attr "length_address")
19332 (symbol_ref "memory_address_length (operands[0], false)"))
19333 (set_attr "memory" "none")])
19335 (define_insn "*prefetch_3dnow"
19336 [(prefetch (match_operand 0 "address_operand" "p")
19337 (match_operand:SI 1 "const_int_operand" "n")
19339 "TARGET_3DNOW || TARGET_PRFCHW || TARGET_PREFETCHWT1"
19341 if (INTVAL (operands[1]) == 0)
19342 return "prefetch\t%a0";
19344 return "prefetchw\t%a0";
19346 [(set_attr "type" "mmx")
19347 (set (attr "length_address")
19348 (symbol_ref "memory_address_length (operands[0], false)"))
19349 (set_attr "memory" "none")])
19351 (define_insn "*prefetch_prefetchwt1"
19352 [(prefetch (match_operand 0 "address_operand" "p")
19355 "TARGET_PREFETCHWT1"
19356 "prefetchwt1\t%a0";
19357 [(set_attr "type" "sse")
19358 (set (attr "length_address")
19359 (symbol_ref "memory_address_length (operands[0], false)"))
19360 (set_attr "memory" "none")])
19362 (define_expand "stack_protect_set"
19363 [(match_operand 0 "memory_operand")
19364 (match_operand 1 "memory_operand")]
19367 emit_insn (gen_stack_protect_set_1
19368 (ptr_mode, operands[0], operands[1]));
19372 (define_insn "@stack_protect_set_1_<mode>"
19373 [(set (match_operand:PTR 0 "memory_operand" "=m")
19374 (unspec:PTR [(match_operand:PTR 1 "memory_operand" "m")]
19376 (set (match_scratch:PTR 2 "=&r") (const_int 0))
19377 (clobber (reg:CC FLAGS_REG))]
19379 "mov{<imodesuffix>}\t{%1, %2|%2, %1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
19380 [(set_attr "type" "multi")])
19382 (define_expand "stack_protect_test"
19383 [(match_operand 0 "memory_operand")
19384 (match_operand 1 "memory_operand")
19388 rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
19390 emit_insn (gen_stack_protect_test_1
19391 (ptr_mode, flags, operands[0], operands[1]));
19393 emit_jump_insn (gen_cbranchcc4 (gen_rtx_EQ (VOIDmode, flags, const0_rtx),
19394 flags, const0_rtx, operands[2]));
19398 (define_insn "@stack_protect_test_1_<mode>"
19399 [(set (match_operand:CCZ 0 "flags_reg_operand")
19400 (unspec:CCZ [(match_operand:PTR 1 "memory_operand" "m")
19401 (match_operand:PTR 2 "memory_operand" "m")]
19403 (clobber (match_scratch:PTR 3 "=&r"))]
19405 "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;sub{<imodesuffix>}\t{%2, %3|%3, %2}"
19406 [(set_attr "type" "multi")])
19408 (define_insn "sse4_2_crc32<mode>"
19409 [(set (match_operand:SI 0 "register_operand" "=r")
19411 [(match_operand:SI 1 "register_operand" "0")
19412 (match_operand:SWI124 2 "nonimmediate_operand" "<r>m")]
19414 "TARGET_SSE4_2 || TARGET_CRC32"
19415 "crc32{<imodesuffix>}\t{%2, %0|%0, %2}"
19416 [(set_attr "type" "sselog1")
19417 (set_attr "prefix_rep" "1")
19418 (set_attr "prefix_extra" "1")
19419 (set (attr "prefix_data16")
19420 (if_then_else (match_operand:HI 2)
19422 (const_string "*")))
19423 (set (attr "prefix_rex")
19424 (if_then_else (match_operand:QI 2 "ext_QIreg_operand")
19426 (const_string "*")))
19427 (set_attr "mode" "SI")])
19429 (define_insn "sse4_2_crc32di"
19430 [(set (match_operand:DI 0 "register_operand" "=r")
19432 [(match_operand:DI 1 "register_operand" "0")
19433 (match_operand:DI 2 "nonimmediate_operand" "rm")]
19435 "TARGET_64BIT && (TARGET_SSE4_2 || TARGET_CRC32)"
19436 "crc32{q}\t{%2, %0|%0, %2}"
19437 [(set_attr "type" "sselog1")
19438 (set_attr "prefix_rep" "1")
19439 (set_attr "prefix_extra" "1")
19440 (set_attr "mode" "DI")])
19442 (define_insn "rdpmc"
19443 [(set (match_operand:DI 0 "register_operand" "=A")
19444 (unspec_volatile:DI [(match_operand:SI 1 "register_operand" "c")]
19448 [(set_attr "type" "other")
19449 (set_attr "length" "2")])
19451 (define_insn "rdpmc_rex64"
19452 [(set (match_operand:DI 0 "register_operand" "=a")
19453 (unspec_volatile:DI [(match_operand:SI 2 "register_operand" "c")]
19455 (set (match_operand:DI 1 "register_operand" "=d")
19456 (unspec_volatile:DI [(match_dup 2)] UNSPECV_RDPMC))]
19459 [(set_attr "type" "other")
19460 (set_attr "length" "2")])
19462 (define_insn "rdtsc"
19463 [(set (match_operand:DI 0 "register_operand" "=A")
19464 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
19467 [(set_attr "type" "other")
19468 (set_attr "length" "2")])
19470 (define_insn "rdtsc_rex64"
19471 [(set (match_operand:DI 0 "register_operand" "=a")
19472 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))
19473 (set (match_operand:DI 1 "register_operand" "=d")
19474 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
19477 [(set_attr "type" "other")
19478 (set_attr "length" "2")])
19480 (define_insn "rdtscp"
19481 [(set (match_operand:DI 0 "register_operand" "=A")
19482 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
19483 (set (match_operand:SI 1 "register_operand" "=c")
19484 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
19487 [(set_attr "type" "other")
19488 (set_attr "length" "3")])
19490 (define_insn "rdtscp_rex64"
19491 [(set (match_operand:DI 0 "register_operand" "=a")
19492 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
19493 (set (match_operand:DI 1 "register_operand" "=d")
19494 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
19495 (set (match_operand:SI 2 "register_operand" "=c")
19496 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
19499 [(set_attr "type" "other")
19500 (set_attr "length" "3")])
19502 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
19504 ;; FXSR, XSAVE and XSAVEOPT instructions
19506 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
19508 (define_insn "fxsave"
19509 [(set (match_operand:BLK 0 "memory_operand" "=m")
19510 (unspec_volatile:BLK [(const_int 0)] UNSPECV_FXSAVE))]
19513 [(set_attr "type" "other")
19514 (set_attr "memory" "store")
19515 (set (attr "length")
19516 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
19518 (define_insn "fxsave64"
19519 [(set (match_operand:BLK 0 "memory_operand" "=m")
19520 (unspec_volatile:BLK [(const_int 0)] UNSPECV_FXSAVE64))]
19521 "TARGET_64BIT && TARGET_FXSR"
19523 [(set_attr "type" "other")
19524 (set_attr "memory" "store")
19525 (set (attr "length")
19526 (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
19528 (define_insn "fxrstor"
19529 [(unspec_volatile [(match_operand:BLK 0 "memory_operand" "m")]
19533 [(set_attr "type" "other")
19534 (set_attr "memory" "load")
19535 (set (attr "length")
19536 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
19538 (define_insn "fxrstor64"
19539 [(unspec_volatile [(match_operand:BLK 0 "memory_operand" "m")]
19540 UNSPECV_FXRSTOR64)]
19541 "TARGET_64BIT && TARGET_FXSR"
19543 [(set_attr "type" "other")
19544 (set_attr "memory" "load")
19545 (set (attr "length")
19546 (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
19548 (define_int_iterator ANY_XSAVE
19550 (UNSPECV_XSAVEOPT "TARGET_XSAVEOPT")
19551 (UNSPECV_XSAVEC "TARGET_XSAVEC")
19552 (UNSPECV_XSAVES "TARGET_XSAVES")])
19554 (define_int_iterator ANY_XSAVE64
19556 (UNSPECV_XSAVEOPT64 "TARGET_XSAVEOPT")
19557 (UNSPECV_XSAVEC64 "TARGET_XSAVEC")
19558 (UNSPECV_XSAVES64 "TARGET_XSAVES")])
19560 (define_int_attr xsave
19561 [(UNSPECV_XSAVE "xsave")
19562 (UNSPECV_XSAVE64 "xsave64")
19563 (UNSPECV_XSAVEOPT "xsaveopt")
19564 (UNSPECV_XSAVEOPT64 "xsaveopt64")
19565 (UNSPECV_XSAVEC "xsavec")
19566 (UNSPECV_XSAVEC64 "xsavec64")
19567 (UNSPECV_XSAVES "xsaves")
19568 (UNSPECV_XSAVES64 "xsaves64")])
19570 (define_int_iterator ANY_XRSTOR
19572 (UNSPECV_XRSTORS "TARGET_XSAVES")])
19574 (define_int_iterator ANY_XRSTOR64
19576 (UNSPECV_XRSTORS64 "TARGET_XSAVES")])
19578 (define_int_attr xrstor
19579 [(UNSPECV_XRSTOR "xrstor")
19580 (UNSPECV_XRSTOR64 "xrstor")
19581 (UNSPECV_XRSTORS "xrstors")
19582 (UNSPECV_XRSTORS64 "xrstors")])
19584 (define_insn "<xsave>"
19585 [(set (match_operand:BLK 0 "memory_operand" "=m")
19586 (unspec_volatile:BLK
19587 [(match_operand:DI 1 "register_operand" "A")]
19589 "!TARGET_64BIT && TARGET_XSAVE"
19591 [(set_attr "type" "other")
19592 (set_attr "memory" "store")
19593 (set (attr "length")
19594 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
19596 (define_insn "<xsave>_rex64"
19597 [(set (match_operand:BLK 0 "memory_operand" "=m")
19598 (unspec_volatile:BLK
19599 [(match_operand:SI 1 "register_operand" "a")
19600 (match_operand:SI 2 "register_operand" "d")]
19602 "TARGET_64BIT && TARGET_XSAVE"
19604 [(set_attr "type" "other")
19605 (set_attr "memory" "store")
19606 (set (attr "length")
19607 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
19609 (define_insn "<xsave>"
19610 [(set (match_operand:BLK 0 "memory_operand" "=m")
19611 (unspec_volatile:BLK
19612 [(match_operand:SI 1 "register_operand" "a")
19613 (match_operand:SI 2 "register_operand" "d")]
19615 "TARGET_64BIT && TARGET_XSAVE"
19617 [(set_attr "type" "other")
19618 (set_attr "memory" "store")
19619 (set (attr "length")
19620 (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
19622 (define_insn "<xrstor>"
19623 [(unspec_volatile:BLK
19624 [(match_operand:BLK 0 "memory_operand" "m")
19625 (match_operand:DI 1 "register_operand" "A")]
19627 "!TARGET_64BIT && TARGET_XSAVE"
19629 [(set_attr "type" "other")
19630 (set_attr "memory" "load")
19631 (set (attr "length")
19632 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
19634 (define_insn "<xrstor>_rex64"
19635 [(unspec_volatile:BLK
19636 [(match_operand:BLK 0 "memory_operand" "m")
19637 (match_operand:SI 1 "register_operand" "a")
19638 (match_operand:SI 2 "register_operand" "d")]
19640 "TARGET_64BIT && TARGET_XSAVE"
19642 [(set_attr "type" "other")
19643 (set_attr "memory" "load")
19644 (set (attr "length")
19645 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
19647 (define_insn "<xrstor>64"
19648 [(unspec_volatile:BLK
19649 [(match_operand:BLK 0 "memory_operand" "m")
19650 (match_operand:SI 1 "register_operand" "a")
19651 (match_operand:SI 2 "register_operand" "d")]
19653 "TARGET_64BIT && TARGET_XSAVE"
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_insn "xsetbv"
19661 [(unspec_volatile:SI
19662 [(match_operand:SI 0 "register_operand" "c")
19663 (match_operand:DI 1 "register_operand" "A")]
19665 "!TARGET_64BIT && TARGET_XSAVE"
19667 [(set_attr "type" "other")])
19669 (define_insn "xsetbv_rex64"
19670 [(unspec_volatile:SI
19671 [(match_operand:SI 0 "register_operand" "c")
19672 (match_operand:SI 1 "register_operand" "a")
19673 (match_operand:SI 2 "register_operand" "d")]
19675 "TARGET_64BIT && TARGET_XSAVE"
19677 [(set_attr "type" "other")])
19679 (define_insn "xgetbv"
19680 [(set (match_operand:DI 0 "register_operand" "=A")
19681 (unspec_volatile:DI [(match_operand:SI 1 "register_operand" "c")]
19683 "!TARGET_64BIT && TARGET_XSAVE"
19685 [(set_attr "type" "other")])
19687 (define_insn "xgetbv_rex64"
19688 [(set (match_operand:DI 0 "register_operand" "=a")
19689 (unspec_volatile:DI [(match_operand:SI 2 "register_operand" "c")]
19691 (set (match_operand:DI 1 "register_operand" "=d")
19692 (unspec_volatile:DI [(match_dup 2)] UNSPECV_XGETBV))]
19693 "TARGET_64BIT && TARGET_XSAVE"
19695 [(set_attr "type" "other")])
19697 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
19699 ;; Floating-point instructions for atomic compound assignments
19701 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
19703 ; Clobber all floating-point registers on environment save and restore
19704 ; to ensure that the TOS value saved at fnstenv is valid after fldenv.
19705 (define_insn "fnstenv"
19706 [(set (match_operand:BLK 0 "memory_operand" "=m")
19707 (unspec_volatile:BLK [(const_int 0)] UNSPECV_FNSTENV))
19708 (clobber (reg:XF ST0_REG))
19709 (clobber (reg:XF ST1_REG))
19710 (clobber (reg:XF ST2_REG))
19711 (clobber (reg:XF ST3_REG))
19712 (clobber (reg:XF ST4_REG))
19713 (clobber (reg:XF ST5_REG))
19714 (clobber (reg:XF ST6_REG))
19715 (clobber (reg:XF ST7_REG))]
19718 [(set_attr "type" "other")
19719 (set_attr "memory" "store")
19720 (set (attr "length")
19721 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))])
19723 (define_insn "fldenv"
19724 [(unspec_volatile [(match_operand:BLK 0 "memory_operand" "m")]
19726 (clobber (reg:XF ST0_REG))
19727 (clobber (reg:XF ST1_REG))
19728 (clobber (reg:XF ST2_REG))
19729 (clobber (reg:XF ST3_REG))
19730 (clobber (reg:XF ST4_REG))
19731 (clobber (reg:XF ST5_REG))
19732 (clobber (reg:XF ST6_REG))
19733 (clobber (reg:XF ST7_REG))]
19736 [(set_attr "type" "other")
19737 (set_attr "memory" "load")
19738 (set (attr "length")
19739 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))])
19741 (define_insn "fnstsw"
19742 [(set (match_operand:HI 0 "nonimmediate_operand" "=a,m")
19743 (unspec_volatile:HI [(const_int 0)] UNSPECV_FNSTSW))]
19746 [(set_attr "type" "other,other")
19747 (set_attr "memory" "none,store")
19748 (set (attr "length")
19749 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))])
19751 (define_insn "fnclex"
19752 [(unspec_volatile [(const_int 0)] UNSPECV_FNCLEX)]
19755 [(set_attr "type" "other")
19756 (set_attr "memory" "none")
19757 (set_attr "length" "2")])
19759 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
19761 ;; LWP instructions
19763 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
19765 (define_expand "lwp_llwpcb"
19766 [(unspec_volatile [(match_operand 0 "register_operand")]
19767 UNSPECV_LLWP_INTRINSIC)]
19770 (define_insn "*lwp_llwpcb<mode>1"
19771 [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
19772 UNSPECV_LLWP_INTRINSIC)]
19775 [(set_attr "type" "lwp")
19776 (set_attr "mode" "<MODE>")
19777 (set_attr "length" "5")])
19779 (define_expand "lwp_slwpcb"
19780 [(set (match_operand 0 "register_operand")
19781 (unspec_volatile [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
19786 insn = (Pmode == DImode
19788 : gen_lwp_slwpcbsi);
19790 emit_insn (insn (operands[0]));
19794 (define_insn "lwp_slwpcb<mode>"
19795 [(set (match_operand:P 0 "register_operand" "=r")
19796 (unspec_volatile:P [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
19799 [(set_attr "type" "lwp")
19800 (set_attr "mode" "<MODE>")
19801 (set_attr "length" "5")])
19803 (define_expand "lwp_lwpval<mode>3"
19804 [(unspec_volatile [(match_operand:SWI48 1 "register_operand")
19805 (match_operand:SI 2 "nonimmediate_operand")
19806 (match_operand:SI 3 "const_int_operand")]
19807 UNSPECV_LWPVAL_INTRINSIC)]
19809 ;; Avoid unused variable warning.
19810 "(void) operands[0];")
19812 (define_insn "*lwp_lwpval<mode>3_1"
19813 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")
19814 (match_operand:SI 1 "nonimmediate_operand" "rm")
19815 (match_operand:SI 2 "const_int_operand" "i")]
19816 UNSPECV_LWPVAL_INTRINSIC)]
19818 "lwpval\t{%2, %1, %0|%0, %1, %2}"
19819 [(set_attr "type" "lwp")
19820 (set_attr "mode" "<MODE>")
19821 (set (attr "length")
19822 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
19824 (define_expand "lwp_lwpins<mode>3"
19825 [(set (reg:CCC FLAGS_REG)
19826 (unspec_volatile:CCC [(match_operand:SWI48 1 "register_operand")
19827 (match_operand:SI 2 "nonimmediate_operand")
19828 (match_operand:SI 3 "const_int_operand")]
19829 UNSPECV_LWPINS_INTRINSIC))
19830 (set (match_operand:QI 0 "nonimmediate_operand")
19831 (eq:QI (reg:CCC FLAGS_REG) (const_int 0)))]
19834 (define_insn "*lwp_lwpins<mode>3_1"
19835 [(set (reg:CCC FLAGS_REG)
19836 (unspec_volatile:CCC [(match_operand:SWI48 0 "register_operand" "r")
19837 (match_operand:SI 1 "nonimmediate_operand" "rm")
19838 (match_operand:SI 2 "const_int_operand" "i")]
19839 UNSPECV_LWPINS_INTRINSIC))]
19841 "lwpins\t{%2, %1, %0|%0, %1, %2}"
19842 [(set_attr "type" "lwp")
19843 (set_attr "mode" "<MODE>")
19844 (set (attr "length")
19845 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
19847 (define_int_iterator RDFSGSBASE
19851 (define_int_iterator WRFSGSBASE
19855 (define_int_attr fsgs
19856 [(UNSPECV_RDFSBASE "fs")
19857 (UNSPECV_RDGSBASE "gs")
19858 (UNSPECV_WRFSBASE "fs")
19859 (UNSPECV_WRGSBASE "gs")])
19861 (define_insn "rd<fsgs>base<mode>"
19862 [(set (match_operand:SWI48 0 "register_operand" "=r")
19863 (unspec_volatile:SWI48 [(const_int 0)] RDFSGSBASE))]
19864 "TARGET_64BIT && TARGET_FSGSBASE"
19866 [(set_attr "type" "other")
19867 (set_attr "prefix_extra" "2")])
19869 (define_insn "wr<fsgs>base<mode>"
19870 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
19872 "TARGET_64BIT && TARGET_FSGSBASE"
19874 [(set_attr "type" "other")
19875 (set_attr "prefix_extra" "2")])
19877 (define_insn "ptwrite<mode>"
19878 [(unspec_volatile [(match_operand:SWI48 0 "nonimmediate_operand" "rm")]
19882 [(set_attr "type" "other")
19883 (set_attr "prefix_extra" "2")])
19885 (define_insn "rdrand<mode>_1"
19886 [(set (match_operand:SWI248 0 "register_operand" "=r")
19887 (unspec_volatile:SWI248 [(const_int 0)] UNSPECV_RDRAND))
19888 (set (reg:CCC FLAGS_REG)
19889 (unspec_volatile:CCC [(const_int 0)] UNSPECV_RDRAND))]
19892 [(set_attr "type" "other")
19893 (set_attr "prefix_extra" "1")])
19895 (define_insn "rdseed<mode>_1"
19896 [(set (match_operand:SWI248 0 "register_operand" "=r")
19897 (unspec_volatile:SWI248 [(const_int 0)] UNSPECV_RDSEED))
19898 (set (reg:CCC FLAGS_REG)
19899 (unspec_volatile:CCC [(const_int 0)] UNSPECV_RDSEED))]
19902 [(set_attr "type" "other")
19903 (set_attr "prefix_extra" "1")])
19905 (define_expand "pause"
19906 [(set (match_dup 0)
19907 (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
19910 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
19911 MEM_VOLATILE_P (operands[0]) = 1;
19914 ;; Use "rep; nop", instead of "pause", to support older assemblers.
19915 ;; They have the same encoding.
19916 (define_insn "*pause"
19917 [(set (match_operand:BLK 0)
19918 (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
19921 [(set_attr "length" "2")
19922 (set_attr "memory" "unknown")])
19924 ;; CET instructions
19925 (define_insn "rdssp<mode>"
19926 [(set (match_operand:SWI48x 0 "register_operand" "=r")
19927 (unspec_volatile:SWI48x [(const_int 0)] UNSPECV_NOP_RDSSP))]
19928 "TARGET_SHSTK || (flag_cf_protection & CF_RETURN)"
19929 "xor{l}\t%k0, %k0\n\trdssp<mskmodesuffix>\t%0"
19930 [(set_attr "length" "6")
19931 (set_attr "type" "other")])
19933 (define_insn "incssp<mode>"
19934 [(unspec_volatile [(match_operand:SWI48x 0 "register_operand" "r")]
19936 "TARGET_SHSTK || (flag_cf_protection & CF_RETURN)"
19937 "incssp<mskmodesuffix>\t%0"
19938 [(set_attr "length" "4")
19939 (set_attr "type" "other")])
19941 (define_insn "saveprevssp"
19942 [(unspec_volatile [(const_int 0)] UNSPECV_SAVEPREVSSP)]
19945 [(set_attr "length" "5")
19946 (set_attr "type" "other")])
19948 (define_expand "rstorssp"
19949 [(unspec_volatile [(match_operand 0 "memory_operand")]
19953 (define_insn "*rstorssp<mode>"
19954 [(unspec_volatile [(match_operand:P 0 "memory_operand" "m")]
19958 [(set_attr "length" "5")
19959 (set_attr "type" "other")])
19961 (define_insn "wrss<mode>"
19962 [(unspec_volatile [(match_operand:SWI48x 0 "register_operand" "r")
19963 (match_operand:SWI48x 1 "memory_operand" "m")]
19966 "wrss<mskmodesuffix>\t%0, %1"
19967 [(set_attr "length" "3")
19968 (set_attr "type" "other")])
19970 (define_insn "wruss<mode>"
19971 [(unspec_volatile [(match_operand:SWI48x 0 "register_operand" "r")
19972 (match_operand:SWI48x 1 "memory_operand" "m")]
19975 "wruss<mskmodesuffix>\t%0, %1"
19976 [(set_attr "length" "4")
19977 (set_attr "type" "other")])
19979 (define_insn "setssbsy"
19980 [(unspec_volatile [(const_int 0)] UNSPECV_SETSSBSY)]
19983 [(set_attr "length" "4")
19984 (set_attr "type" "other")])
19986 (define_expand "clrssbsy"
19987 [(unspec_volatile [(match_operand 0 "memory_operand")]
19991 (define_insn "*clrssbsy<mode>"
19992 [(unspec_volatile [(match_operand:P 0 "memory_operand" "m")]
19996 [(set_attr "length" "4")
19997 (set_attr "type" "other")])
19999 (define_insn "nop_endbr"
20000 [(unspec_volatile [(const_int 0)] UNSPECV_NOP_ENDBR)]
20001 "(flag_cf_protection & CF_BRANCH)"
20003 return TARGET_64BIT ? "endbr64" : "endbr32";
20005 [(set_attr "length" "4")
20006 (set_attr "length_immediate" "0")
20007 (set_attr "modrm" "0")])
20010 (define_expand "xbegin"
20011 [(set (match_operand:SI 0 "register_operand")
20012 (unspec_volatile:SI [(const_int 0)] UNSPECV_XBEGIN))]
20015 rtx_code_label *label = gen_label_rtx ();
20017 /* xbegin is emitted as jump_insn, so reload won't be able
20018 to reload its operand. Force the value into AX hard register. */
20019 rtx ax_reg = gen_rtx_REG (SImode, AX_REG);
20020 emit_move_insn (ax_reg, constm1_rtx);
20022 emit_jump_insn (gen_xbegin_1 (ax_reg, label));
20024 emit_label (label);
20025 LABEL_NUSES (label) = 1;
20027 emit_move_insn (operands[0], ax_reg);
20032 (define_insn "xbegin_1"
20034 (if_then_else (ne (unspec [(const_int 0)] UNSPEC_XBEGIN_ABORT)
20036 (label_ref (match_operand 1))
20038 (set (match_operand:SI 0 "register_operand" "+a")
20039 (unspec_volatile:SI [(match_dup 0)] UNSPECV_XBEGIN))]
20042 [(set_attr "type" "other")
20043 (set_attr "length" "6")])
20045 (define_insn "xend"
20046 [(unspec_volatile [(const_int 0)] UNSPECV_XEND)]
20049 [(set_attr "type" "other")
20050 (set_attr "length" "3")])
20052 (define_insn "xabort"
20053 [(unspec_volatile [(match_operand:SI 0 "const_0_to_255_operand" "n")]
20057 [(set_attr "type" "other")
20058 (set_attr "length" "3")])
20060 (define_expand "xtest"
20061 [(set (match_operand:QI 0 "register_operand")
20062 (unspec_volatile:QI [(const_int 0)] UNSPECV_XTEST))]
20065 emit_insn (gen_xtest_1 ());
20067 ix86_expand_setcc (operands[0], NE,
20068 gen_rtx_REG (CCZmode, FLAGS_REG), const0_rtx);
20072 (define_insn "xtest_1"
20073 [(set (reg:CCZ FLAGS_REG)
20074 (unspec_volatile:CCZ [(const_int 0)] UNSPECV_XTEST))]
20077 [(set_attr "type" "other")
20078 (set_attr "length" "3")])
20080 (define_insn "clwb"
20081 [(unspec_volatile [(match_operand 0 "address_operand" "p")]
20085 [(set_attr "type" "sse")
20086 (set_attr "atom_sse_attr" "fence")
20087 (set_attr "memory" "unknown")])
20089 (define_insn "clflushopt"
20090 [(unspec_volatile [(match_operand 0 "address_operand" "p")]
20091 UNSPECV_CLFLUSHOPT)]
20092 "TARGET_CLFLUSHOPT"
20094 [(set_attr "type" "sse")
20095 (set_attr "atom_sse_attr" "fence")
20096 (set_attr "memory" "unknown")])
20098 ;; MONITORX and MWAITX
20099 (define_insn "mwaitx"
20100 [(unspec_volatile [(match_operand:SI 0 "register_operand" "c")
20101 (match_operand:SI 1 "register_operand" "a")
20102 (match_operand:SI 2 "register_operand" "b")]
20105 ;; 64bit version is "mwaitx %rax,%rcx,%rbx". But only lower 32bits are used.
20106 ;; Since 32bit register operands are implicitly zero extended to 64bit,
20107 ;; we only need to set up 32bit registers.
20109 [(set_attr "length" "3")])
20111 (define_insn "@monitorx_<mode>"
20112 [(unspec_volatile [(match_operand:P 0 "register_operand" "a")
20113 (match_operand:SI 1 "register_operand" "c")
20114 (match_operand:SI 2 "register_operand" "d")]
20117 ;; 64bit version is "monitorx %rax,%rcx,%rdx". But only lower 32bits in
20118 ;; RCX and RDX are used. Since 32bit register operands are implicitly
20119 ;; zero extended to 64bit, we only need to set up 32bit registers.
20121 [(set (attr "length")
20122 (symbol_ref ("(Pmode != word_mode) + 3")))])
20125 (define_insn "@clzero_<mode>"
20126 [(unspec_volatile [(match_operand: P 0 "register_operand" "a")]
20130 [(set_attr "length" "3")
20131 (set_attr "memory" "unknown")])
20133 ;; RDPKRU and WRPKRU
20135 (define_expand "rdpkru"
20137 [(set (match_operand:SI 0 "register_operand")
20138 (unspec_volatile:SI [(match_dup 1)] UNSPECV_PKU))
20139 (set (match_dup 2) (const_int 0))])]
20142 operands[1] = force_reg (SImode, const0_rtx);
20143 operands[2] = gen_reg_rtx (SImode);
20146 (define_insn "*rdpkru"
20147 [(set (match_operand:SI 0 "register_operand" "=a")
20148 (unspec_volatile:SI [(match_operand:SI 2 "register_operand" "c")]
20150 (set (match_operand:SI 1 "register_operand" "=d")
20154 [(set_attr "type" "other")])
20156 (define_expand "wrpkru"
20157 [(unspec_volatile:SI
20158 [(match_operand:SI 0 "register_operand")
20159 (match_dup 1) (match_dup 2)] UNSPECV_PKU)]
20162 operands[1] = force_reg (SImode, const0_rtx);
20163 operands[2] = force_reg (SImode, const0_rtx);
20166 (define_insn "*wrpkru"
20167 [(unspec_volatile:SI
20168 [(match_operand:SI 0 "register_operand" "a")
20169 (match_operand:SI 1 "register_operand" "d")
20170 (match_operand:SI 2 "register_operand" "c")] UNSPECV_PKU)]
20173 [(set_attr "type" "other")])
20175 (define_insn "rdpid"
20176 [(set (match_operand:SI 0 "register_operand" "=r")
20177 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDPID))]
20178 "!TARGET_64BIT && TARGET_RDPID"
20180 [(set_attr "type" "other")])
20182 (define_insn "rdpid_rex64"
20183 [(set (match_operand:DI 0 "register_operand" "=r")
20184 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDPID))]
20185 "TARGET_64BIT && TARGET_RDPID"
20187 [(set_attr "type" "other")])
20189 ;; Intirinsics for > i486
20191 (define_insn "wbinvd"
20192 [(unspec_volatile [(const_int 0)] UNSPECV_WBINVD)]
20195 [(set_attr "type" "other")])
20197 (define_insn "wbnoinvd"
20198 [(unspec_volatile [(const_int 0)] UNSPECV_WBNOINVD)]
20201 [(set_attr "type" "other")])
20203 ;; MOVDIRI and MOVDIR64B
20205 (define_insn "movdiri<mode>"
20206 [(unspec_volatile:SWI48 [(match_operand:SWI48 0 "memory_operand" "m")
20207 (match_operand:SWI48 1 "register_operand" "r")]
20210 "movdiri\t{%1, %0|%0, %1}"
20211 [(set_attr "type" "other")])
20213 (define_insn "@movdir64b_<mode>"
20214 [(unspec_volatile:XI [(match_operand:P 0 "register_operand" "r")
20215 (match_operand:XI 1 "memory_operand")]
20216 UNSPECV_MOVDIR64B)]
20218 "movdir64b\t{%1, %0|%0, %1}"
20219 [(set_attr "type" "other")])
20221 ;; ENQCMD and ENQCMDS
20223 (define_int_iterator ENQCMD [UNSPECV_ENQCMD UNSPECV_ENQCMDS])
20224 (define_int_attr enqcmd_sfx [(UNSPECV_ENQCMD "") (UNSPECV_ENQCMDS "s")])
20226 (define_insn "@enqcmd<enqcmd_sfx>_<mode>"
20227 [(set (reg:CCZ FLAGS_REG)
20228 (unspec_volatile:CCZ [(match_operand:P 0 "register_operand" "r")
20229 (match_operand:XI 1 "memory_operand" "m")]
20232 "enqcmd<enqcmd_sfx>\t{%1, %0|%0, %1}"
20233 [(set_attr "type" "other")])
20237 (define_insn "umwait"
20238 [(set (reg:CCC FLAGS_REG)
20239 (unspec_volatile:CCC [(match_operand:SI 0 "register_operand" "r")
20240 (match_operand:DI 1 "register_operand" "A")]
20242 "!TARGET_64BIT && TARGET_WAITPKG"
20244 [(set_attr "length" "3")])
20246 (define_insn "umwait_rex64"
20247 [(set (reg:CCC FLAGS_REG)
20248 (unspec_volatile:CCC [(match_operand:SI 0 "register_operand" "r")
20249 (match_operand:SI 1 "register_operand" "a")
20250 (match_operand:SI 2 "register_operand" "d")]
20252 "TARGET_64BIT && TARGET_WAITPKG"
20254 [(set_attr "length" "3")])
20256 (define_insn "umonitor_<mode>"
20257 [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
20261 [(set (attr "length")
20262 (symbol_ref ("(Pmode != word_mode) + 3")))])
20264 (define_insn "tpause"
20265 [(set (reg:CCC FLAGS_REG)
20266 (unspec_volatile:CCC [(match_operand:SI 0 "register_operand" "r")
20267 (match_operand:DI 1 "register_operand" "A")]
20269 "!TARGET_64BIT && TARGET_WAITPKG"
20271 [(set_attr "length" "3")])
20273 (define_insn "tpause_rex64"
20274 [(set (reg:CCC FLAGS_REG)
20275 (unspec_volatile:CCC [(match_operand:SI 0 "register_operand" "r")
20276 (match_operand:SI 1 "register_operand" "a")
20277 (match_operand:SI 2 "register_operand" "d")]
20279 "TARGET_64BIT && TARGET_WAITPKG"
20281 [(set_attr "length" "3")])
20283 (define_insn "cldemote"
20284 [(unspec_volatile[(match_operand 0 "address_operand" "p")]
20288 [(set_attr "type" "other")
20289 (set_attr "memory" "unknown")])
20291 (define_insn "speculation_barrier"
20292 [(unspec_volatile [(const_int 0)] UNSPECV_SPECULATION_BARRIER)]
20295 [(set_attr "type" "other")
20296 (set_attr "length" "3")])
20300 (include "sync.md")